Subfolder functionality (#1194)

* Added functionality for sub-folders

* Edit Request name only. Drag and drop to move requests

* Refactor

* Move requests between folder or collections

* Functionality to save request in multiple folders

* Unnecessary Lang

Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
This commit is contained in:
Farhan Tariq
2020-10-21 06:11:45 +05:00
committed by GitHub
parent b179731359
commit 7e30a4a3d4
11 changed files with 362 additions and 345 deletions

View File

@@ -21,7 +21,7 @@
type="text"
v-model="name"
:placeholder="$t('my_new_folder')"
@keyup.enter="addNewFolder"
@keyup.enter="addFolder"
/>
</li>
</ul>
@@ -33,7 +33,7 @@
<button class="icon" @click="hideModal">
{{ $t("cancel") }}
</button>
<button class="icon primary" @click="addNewFolder">
<button class="icon primary" @click="addFolder">
{{ $t("save") }}
</button>
</span>
@@ -45,14 +45,13 @@
<script>
import { fb } from "~/helpers/fb"
import closeIcon from "~/static/icons/close-24px.svg?inline"
export default {
components: {
closeIcon,
},
props: {
show: Boolean,
collection: Object,
folder: Object,
collectionIndex: Number,
},
data() {
@@ -61,10 +60,10 @@ export default {
}
},
methods: {
addNewFolder() {
this.$store.commit("postwoman/addNewFolder", {
folder: { name: this.$data.name },
collectionIndex: this.$props.collectionIndex,
addFolder() {
this.$store.commit("postwoman/addFolder", {
name: this.$data.name,
folder: this.$props.folder,
})
this.hideModal()
this.syncCollections()

View File

@@ -1,6 +1,13 @@
<template>
<div>
<div class="row-wrapper">
<div :class="['row-wrapper', dragging ? 'drop-zone':'' ]"
@dragover.prevent
@drop.prevent="dropEvent"
@dragover="dragging=true"
@drop="dragging=false"
@dragleave="dragging=false"
@dragend="dragging=false"
>
<button class="icon" @click="toggleShowChildren">
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
<i class="material-icons" v-show="showChildren || isFiltered">arrow_drop_down</i>
@@ -22,7 +29,7 @@
</button>
<template slot="popover">
<div>
<button class="icon" @click="$emit('add-folder')" v-close-popover>
<button class="icon" @click="$emit('add-folder', {folder: collection})" v-close-popover>
<i class="material-icons">create_new_folder</i>
<span>{{ $t("new_folder") }}</span>
</button>
@@ -53,18 +60,16 @@
>
<folder
:folder="folder"
:folderIndex="index"
:folder-index="index"
:collection-index="collectionIndex"
:doc="doc"
:isFiltered="isFiltered"
@edit-folder="editFolder(collectionIndex, folder, index)"
@add-folder="$emit('add-folder', $event)"
@edit-folder="$emit('edit-folder', $event)"
@edit-request="$emit('edit-request', $event)"
/>
</li>
<li
v-if="collection.folders.length === 0 && collection.requests.length === 0"
class="ml-8 border-l border-brdColor"
>
<li v-if="collection.folders.length === 0 && collection.requests.length === 0">
<label>{{ $t("collection_empty") }}</label>
</li>
</ul>
@@ -78,16 +83,10 @@
:request="request"
:collection-index="collectionIndex"
:folder-index="-1"
:folder-name="collection.name"
:request-index="index"
:doc="doc"
@edit-request="
$emit('edit-request', {
request,
collectionIndex,
folderIndex: undefined,
requestIndex: index,
})
"
@edit-request="$emit('edit-request', $event)"
/>
</li>
</ul>
@@ -111,6 +110,7 @@ export default {
data() {
return {
showChildren: false,
dragging: false,
selectedFolder: {},
}
},
@@ -135,8 +135,22 @@ export default {
})
this.syncCollections()
},
editFolder(collectionIndex, folder, folderIndex) {
this.$emit("edit-folder", { collectionIndex, folder, folderIndex })
dropEvent(event) {
this.dragging = !this.dragging;
const oldCollectionIndex = event.dataTransfer.getData('oldCollectionIndex');
const oldFolderIndex = event.dataTransfer.getData('oldFolderIndex');
const oldFolderName = event.dataTransfer.getData('oldFolderName');
const requestIndex = event.dataTransfer.getData('requestIndex');
this.$store.commit("postwoman/moveRequest", {
oldCollectionIndex: oldCollectionIndex,
newCollectionIndex: this.$props.collectionIndex,
newFolderIndex: -1,
newFolderName: this.$props.collection.name,
oldFolderIndex: oldFolderIndex,
oldFolderName: oldFolderName,
requestIndex: requestIndex
})
this.syncCollections()
},
},
}

View File

@@ -47,7 +47,6 @@ export default {
},
props: {
show: Boolean,
collection: Object,
collectionIndex: Number,
folder: Object,
folderIndex: Number,
@@ -70,6 +69,7 @@ export default {
collectionIndex: this.$props.collectionIndex,
folder: { ...this.$props.folder, name: this.$data.name },
folderIndex: this.$props.folderIndex,
folderName: this.$props.folder.name,
})
this.hideModal()
this.syncCollections()

View File

@@ -15,42 +15,14 @@
</ul>
</div>
<div slot="body">
<ul>
<li>
<label for="selectLabel">{{ $t("label") }}</label>
<input
type="text"
id="selectLabel"
v-model="requestUpdateData.name"
@keyup.enter="saveRequest"
:placeholder="request.name"
/>
<label for="selectCollection">{{ $t("collection") }}</label>
<span class="select-wrapper">
<select type="text" id="selectCollection" v-model="requestUpdateData.collectionIndex">
<option :key="undefined" :value="undefined" hidden disabled selected>
{{ $t("current_collection") }}
</option>
<option
v-for="(collection, index) in $store.state.postwoman.collections"
:key="index"
:value="index"
>
{{ collection.name }}
</option>
</select>
</span>
<label for="selectFolder">{{ $t("folder") }}</label>
<span class="select-wrapper">
<select type="text" id="selectFolder" v-model="requestUpdateData.folderIndex">
<option :key="undefined" :value="undefined">/</option>
<option v-for="(folder, index) in folders" :key="index" :value="index">
{{ folder.name }}
</option>
</select>
</span>
</li>
</ul>
<label for="selectLabel">{{ $t("label") }}</label>
<input
type="text"
id="selectLabel"
v-model="requestUpdateData.name"
@keyup.enter="saveRequest"
:placeholder="request.name"
/>
</div>
<div slot="footer">
<div class="row-wrapper">
@@ -80,6 +52,7 @@ export default {
show: Boolean,
collectionIndex: Number,
folderIndex: Number,
folderName: String,
request: Object,
requestIndex: Number,
},
@@ -87,27 +60,9 @@ export default {
return {
requestUpdateData: {
name: undefined,
collectionIndex: undefined,
folderIndex: undefined,
},
}
},
watch: {
"requestUpdateData.collectionIndex": function resetFolderIndex() {
// if user choosen some folder, than selected other collection, which doesn't have any folders
// than `requestUpdateData.folderIndex` won't be reseted
this.$data.requestUpdateData.folderIndex = undefined
},
},
computed: {
folders() {
const userSelectedAnyCollection = this.$data.requestUpdateData.collectionIndex !== undefined
if (!userSelectedAnyCollection) return []
return this.$store.state.postwoman.collections[this.$data.requestUpdateData.collectionIndex]
.folders
},
},
methods: {
syncCollections() {
if (fb.currentUser !== null) {
@@ -117,26 +72,17 @@ export default {
}
},
saveRequest() {
const userSelectedAnyCollection = this.$data.requestUpdateData.collectionIndex !== undefined
const requestUpdated = {
...this.$props.request,
name: this.$data.requestUpdateData.name || this.$props.request.name,
collection: userSelectedAnyCollection
? this.$data.requestUpdateData.collectionIndex
: this.$props.collectionIndex,
folder: this.$data.requestUpdateData.folderIndex,
}
// pass data separately to don't depend on request's collection, folder fields
// probably, they should be deprecated because they don't describe request itself
this.$store.commit("postwoman/editRequest", {
requestOldCollectionIndex: this.$props.collectionIndex,
requestOldFolderIndex: this.$props.folderIndex,
requestOldIndex: this.$props.requestIndex,
requestCollectionIndex: this.$props.collectionIndex,
requestFolderName: this.$props.folderName,
requestFolderIndex: this.$props.folderIndex,
requestNew: requestUpdated,
requestNewCollectionIndex: requestUpdated.collection,
requestNewFolderIndex: requestUpdated.folder,
requestIndex: this.$props.requestIndex,
})
this.hideModal()

View File

@@ -1,6 +1,14 @@
<template>
<div>
<div class="row-wrapper">
<div
:class="['row-wrapper', dragging ? 'drop-zone':'' ]"
@dragover.prevent
@drop.prevent="dropEvent"
@dragover="dragging=true"
@drop="dragging=false"
@dragleave="dragging=false"
@dragend="dragging=false"
>
<div>
<button class="icon" @click="toggleShowChildren">
<i class="material-icons" v-show="!showChildren && !isFiltered">arrow_right</i>
@@ -15,7 +23,13 @@
</button>
<template slot="popover">
<div>
<button class="icon" @click="editFolder" v-close-popover>
<button class="icon" @click="$emit('add-folder', { folder })" v-close-popover>
<i class="material-icons">create_new_folder</i>
<span>{{ $t("new_folder") }}</span>
</button>
</div>
<div>
<button class="icon" @click="$emit('edit-folder', { folder, folderIndex, collectionIndex })" v-close-popover>
<i class="material-icons">edit</i>
<span>{{ $t("edit") }}</span>
</button>
@@ -41,20 +55,24 @@
:request="request"
:collection-index="collectionIndex"
:folder-index="folderIndex"
:folder-name="folder.name"
:request-index="index"
:doc="doc"
@edit-request="
$emit('edit-request', {
request,
collectionIndex,
folderIndex,
requestIndex: index,
})
"
@edit-request="$emit('edit-request', $event)"
/>
</li>
<li v-if="folder.requests.length === 0" class="flex ml-8 border-l border-brdColor">
<label>{{ $t("folder_empty") }}</label>
</ul>
<ul v-if="folder.folders && folder.folders.length" class="flex-col">
<li v-for="(subFolder, subFolderIndex) in folder.folders" :key="subFolder.name" >
<folder
:folder="subFolder"
:folder-index="subFolderIndex"
:collection-index="collectionIndex"
:doc="doc"
@add-folder="$emit('add-folder', $event)"
@edit-folder="$emit('edit-folder', $event)"
@edit-request="$emit('edit-request', $event)"
/>
</li>
</ul>
</div>
@@ -67,16 +85,18 @@ import deleteIcon from "~/static/icons/delete-24px.svg?inline"
export default {
components: { deleteIcon },
name: "folder",
props: {
folder: Object,
collectionIndex: Number,
folderIndex: Number,
collectionIndex: Number,
doc: Boolean,
isFiltered: Boolean,
},
data() {
return {
showChildren: false,
dragging: false,
}
},
methods: {
@@ -90,23 +110,36 @@ export default {
toggleShowChildren() {
this.showChildren = !this.showChildren
},
selectRequest(request) {
this.$store.commit("postwoman/selectRequest", { request })
},
removeFolder() {
if (!confirm(this.$t("are_you_sure_remove_folder"))) return
this.$store.commit("postwoman/removeFolder", {
collectionIndex: this.collectionIndex,
folderIndex: this.folderIndex,
collectionIndex: this.$props.collectionIndex,
folderName: this.$props.folder.name,
folderIndex: this.$props.folderIndex
})
this.syncCollections()
this.$toast.error(this.$t("deleted"), {
icon: "delete",
})
},
editFolder() {
this.$emit("edit-folder")
dropEvent(event) {
this.dragging = !this.dragging;
const oldCollectionIndex = event.dataTransfer.getData('oldCollectionIndex');
const oldFolderIndex = event.dataTransfer.getData('oldFolderIndex');
const oldFolderName = event.dataTransfer.getData('oldFolderName');
const requestIndex = event.dataTransfer.getData('requestIndex');
this.$store.commit("postwoman/moveRequest", {
oldCollectionIndex: oldCollectionIndex,
newCollectionIndex: this.$props.collectionIndex,
newFolderIndex: this.$props.folderIndex,
newFolderName: this.$props.folder.name,
oldFolderIndex: oldFolderIndex,
oldFolderName: oldFolderName,
requestIndex: requestIndex
})
this.syncCollections()
},
},
}
}
</script>

View File

@@ -117,7 +117,7 @@ export default {
// Do nothing
}
} else if (collections.info && collections.info.schema.includes("v2.1.0")) {
collections = this.parsePostmanCollection(collections)
collections = [this.parsePostmanCollection(collections)]
} else {
return this.failedImport()
}
@@ -141,8 +141,7 @@ export default {
} else if (collections.info && collections.info.schema.includes("v2.1.0")) {
//replace the variables, postman uses {{var}}, Hoppscotch uses <<var>>
collections = JSON.parse(content.replaceAll(/{{([a-z]+)}}/gi, "<<$1>>"))
collections.item = this.flattenPostmanFolders(collections)
collections = this.parsePostmanCollection(collections)
collections = [this.parsePostmanCollection(collections)]
} else {
return this.failedImport()
}
@@ -192,36 +191,31 @@ export default {
icon: "error",
})
},
parsePostmanCollection(collection, folders = true) {
let postwomanCollection = folders
? [
{
name: "",
folders: [],
requests: [],
},
]
: {
name: "",
requests: [],
}
if (folders) {
//pick up collection name even when all children are folders
postwomanCollection[0].name = collection.info ? collection.info.name : ""
}
for (let collectionItem of collection.item) {
if (collectionItem.request) {
if (postwomanCollection[0]) {
postwomanCollection[0].name = collection.info ? collection.info.name : ""
postwomanCollection[0].requests.push(this.parsePostmanRequest(collectionItem))
parsePostmanCollection(collection) {
let postwomanCollection =
{
name: "",
folders: [],
requests: [],
}
postwomanCollection.name = collection.info ? collection.info.name : collection.name
if (collection.item && collection.item.length > 0) {
for (let collectionItem of collection.item) {
if (collectionItem.request) {
if (postwomanCollection.hasOwnProperty('folders')) {
postwomanCollection.name = collection.info ? collection.info.name : collection.name
postwomanCollection.requests.push(this.parsePostmanRequest(collectionItem))
} else {
postwomanCollection.name = collection.name ? collection.name : ""
postwomanCollection.requests.push(this.parsePostmanRequest(collectionItem))
}
} else if (this.hasFolder(collectionItem)) {
postwomanCollection.folders.push(this.parsePostmanCollection(collectionItem))
} else {
postwomanCollection.name = collection.name ? collection.name : ""
postwomanCollection.requests.push(this.parsePostmanRequest(collectionItem))
}
} else if (collectionItem.item) {
if (collectionItem.item[0]) {
postwomanCollection[0].folders.push(this.parsePostmanCollection(collectionItem, false))
}
}
}
return postwomanCollection
@@ -300,46 +294,8 @@ export default {
}
return pwRequest
},
flattenPostmanFolders(collection) {
let items = []
for (let collectionItem of collection.item) {
if (this.hasFolder(collectionItem)) {
let newFolderItems = []
for (let folderItem of collectionItem.item) {
if (this.isSubFolder(folderItem)) {
newFolderItems = newFolderItems.concat(this.flattenPostmanItem(folderItem))
} else {
newFolderItems.push(folderItem)
}
}
collectionItem.item = newFolderItems
}
items.push(collectionItem)
}
return items
},
hasFolder(item) {
return Object.prototype.hasOwnProperty.call(item, "item")
},
isSubFolder(item) {
return (
Object.prototype.hasOwnProperty.call(item, "_postman_isSubFolder") &&
item._postman_isSubFolder
)
},
flattenPostmanItem(subFolder, subFolderGlue = " -- ") {
delete subFolder._postman_isSubFolder
let flattenedItems = []
for (let subFolderItem of subFolder.item) {
subFolderItem.name = subFolder.name + subFolderGlue + subFolderItem.name
if (this.isSubFolder(subFolderItem)) {
flattenedItems = flattenedItems.concat(this.flattenPostmanItem(subFolderItem))
} else {
flattenedItems.push(subFolderItem)
}
}
return flattenedItems
return item.hasOwnProperty('item')
},
},
}

View File

@@ -14,30 +14,29 @@ TODO:
<add-collection :show="showModalAdd" @hide-modal="displayModalAdd(false)" />
<edit-collection
:show="showModalEdit"
:editingCollection="editingCollection"
:editingCollectionIndex="editingCollectionIndex"
:editing-collection="editingCollection"
:editing-collection-index="editingCollectionIndex"
@hide-modal="displayModalEdit(false)"
/>
<add-folder
:show="showModalAddFolder"
:collection="editingCollection"
:collectionIndex="editingCollectionIndex"
:folder="editingFolder"
@hide-modal="displayModalAddFolder(false)"
/>
<edit-folder
:show="showModalEditFolder"
:collection="editingCollection"
:collectionIndex="editingCollectionIndex"
:collection-index="editingCollectionIndex"
:folder="editingFolder"
:folderIndex="editingFolderIndex"
:folder-index="editingFolderIndex"
@hide-modal="displayModalEditFolder(false)"
/>
<edit-request
:show="showModalEditRequest"
:collectionIndex="editingCollectionIndex"
:folderIndex="editingFolderIndex"
:collection-index="editingCollectionIndex"
:folder-index="editingFolderIndex"
:folder-name="editingFolderName"
:request="editingRequest"
:requestIndex="editingRequestIndex"
:request-index="editingRequestIndex"
@hide-modal="displayModalEditRequest(false)"
/>
<import-export-collections
@@ -74,12 +73,13 @@ TODO:
<ul class="flex-col">
<li v-for="(collection, index) in filteredCollections" :key="collection.name">
<collection
:name="collection.name"
:collection-index="index"
:collection="collection"
:doc="doc"
:isFiltered="filterText.length > 0"
@edit-collection="editCollection(collection, index)"
@add-folder="addFolder(collection, index)"
@add-folder="addFolder($event)"
@edit-folder="editFolder($event)"
@edit-request="editRequest($event)"
@select-collection="$emit('use-collection', collection)"
@@ -119,6 +119,7 @@ export default {
editingCollection: undefined,
editingCollectionIndex: undefined,
editingFolder: undefined,
editingFolderName:undefined,
editingFolderIndex: undefined,
editingRequest: undefined,
editingRequestIndex: undefined,
@@ -212,15 +213,14 @@ export default {
this.displayModalEdit(true)
this.syncCollections()
},
addFolder(collection, collectionIndex) {
this.$data.editingCollection = collection
this.$data.editingCollectionIndex = collectionIndex
addFolder(payload) {
const { folder } = payload
this.$data.editingFolder = folder
this.displayModalAddFolder(true)
this.syncCollections()
},
editFolder(payload) {
const { collection, collectionIndex, folder, folderIndex } = payload
this.$data.editingCollection = collection
const { collectionIndex, folder, folderIndex } = payload
this.$data.editingCollectionIndex = collectionIndex
this.$data.editingFolder = folder
this.$data.editingFolderIndex = folderIndex
@@ -228,9 +228,10 @@ export default {
this.syncCollections()
},
editRequest(payload) {
const { request, collectionIndex, folderIndex, requestIndex } = payload
const { collectionIndex, folderIndex, folderName, request, requestIndex } = payload
this.$data.editingCollectionIndex = collectionIndex
this.$data.editingFolderIndex = folderIndex
this.$data.editingFolderName = folderName
this.$data.editingRequest = request
this.$data.editingRequestIndex = requestIndex
this.displayModalEditRequest(true)

View File

@@ -1,5 +1,12 @@
<template>
<div class="row-wrapper">
<div
:class="['row-wrapper', dragging ? 'drag-el' : '']"
draggable="true"
@dragstart="dragStart"
@dragover.stop
@dragleave="dragging=false"
@dragend="dragging=false"
>
<div>
<button
class="icon"
@@ -16,7 +23,11 @@
</button>
<template slot="popover">
<div>
<button class="icon" @click="$emit('edit-request')" v-close-popover>
<button class="icon" @click="$emit('edit-request',{ collectionIndex,
folderIndex,
folderName,
request,
requestIndex } )" v-close-popover>
<i class="material-icons">edit</i>
<span>{{ $t("edit") }}</span>
</button>
@@ -42,9 +53,15 @@ export default {
request: Object,
collectionIndex: Number,
folderIndex: Number,
folderName: String,
requestIndex: Number,
doc: Boolean,
},
data() {
return {
dragging: false,
}
},
methods: {
syncCollections() {
if (fb.currentUser !== null) {
@@ -56,12 +73,19 @@ export default {
selectRequest() {
this.$store.commit("postwoman/selectRequest", { request: this.request })
},
dragStart(event) {
this.dragging = !this.dragging;
event.dataTransfer.setData('oldCollectionIndex', this.$props.collectionIndex);
event.dataTransfer.setData('oldFolderIndex', this.$props.folderIndex)
event.dataTransfer.setData('oldFolderName', this.$props.folderName);
event.dataTransfer.setData('requestIndex', this.$props.requestIndex);
},
removeRequest() {
if (!confirm(this.$t("are_you_sure_remove_request"))) return
this.$store.commit("postwoman/removeRequest", {
collectionIndex: this.collectionIndex,
folderIndex: this.folderIndex,
requestIndex: this.requestIndex,
collectionIndex: this.$props.collectionIndex,
folderName: this.$props.folderName,
requestIndex: this.$props.requestIndex,
})
this.$toast.error(this.$t("deleted"), {
icon: "delete",

View File

@@ -40,15 +40,13 @@
</option>
</select>
</span>
<label for="selectFolder">{{ $t("folder") }}</label>
<span class="select-wrapper">
<select type="text" id="selectFolder" v-model="requestData.folderIndex">
<option :key="undefined" :value="undefined">/</option>
<option v-for="(folder, index) in folders" :key="index" :value="index">
{{ folder.name }}
</option>
</select>
</span>
<label>{{ $t("folder") }}</label>
<autocomplete
:placeholder="$t('search')"
:source="folders"
:spellcheck="false"
v-model="requestData.folderName"
/>
<label for="selectRequest">{{ $t("request") }}</label>
<span class="select-wrapper">
<select type="text" id="selectRequest" v-model="requestData.requestIndex">
@@ -95,19 +93,19 @@ export default {
requestData: {
name: undefined,
collectionIndex: undefined,
folderIndex: undefined,
folderName: undefined,
requestIndex: undefined,
},
}
},
watch: {
"requestData.collectionIndex": function resetFolderAndRequestIndex() {
// if user choosen some folder, than selected other collection, which doesn't have any folders
// than `requestUpdateData.folderIndex` won't be reseted
this.$data.requestData.folderIndex = undefined
// if user has chosen some folder, than selected other collection, which doesn't have any folders
// than `requestUpdateData.folderName` won't be reseted
this.$data.requestData.folderName = undefined
this.$data.requestData.requestIndex = undefined
},
"requestData.folderIndex": function resetRequestIndex() {
"requestData.folderName": function resetRequestIndex() {
this.$data.requestData.requestIndex = undefined
},
editingRequest(request) {
@@ -116,39 +114,41 @@ export default {
},
computed: {
folders() {
const userSelectedAnyCollection = this.$data.requestData.collectionIndex !== undefined
const collections = this.$store.state.postwoman.collections
const collectionIndex = this.$data.requestData.collectionIndex
const userSelectedAnyCollection = collectionIndex !== undefined
if (!userSelectedAnyCollection) return []
const noCollectionAvailable =
this.$store.state.postwoman.collections[this.$data.requestData.collectionIndex] !==
undefined
const noCollectionAvailable = collections[collectionIndex] !== undefined
if (!noCollectionAvailable) return []
return this.$store.state.postwoman.collections[this.$data.requestData.collectionIndex].folders
return getFolderNames(collections[collectionIndex].folders, [])
},
requests() {
const userSelectedAnyCollection = this.$data.requestData.collectionIndex !== undefined
if (!userSelectedAnyCollection) return []
const collections = this.$store.state.postwoman.collections
const collectionIndex = this.$data.requestData.collectionIndex
const folderName = this.$data.requestData.folderName
const userSelectedAnyCollection = collectionIndex !== undefined
if (!userSelectedAnyCollection) {
return []
}
const userSelectedAnyFolder = folderName !== undefined && folderName !== ''
const userSelectedAnyFolder = this.$data.requestData.folderIndex !== undefined
if (userSelectedAnyFolder) {
const collection = this.$store.state.postwoman.collections[
this.$data.requestData.collectionIndex
]
const folder = collection.folders[this.$data.requestData.folderIndex]
const requests = folder.requests
return requests
const collection = collections[collectionIndex]
const folder = findFolder(folderName, collection)
return folder.requests
} else {
const collection = this.$store.state.postwoman.collections[
this.$data.requestData.collectionIndex
]
const noCollectionAvailable =
this.$store.state.postwoman.collections[this.$data.requestData.collectionIndex] !==
undefined
if (!noCollectionAvailable) return []
const collection = collections[collectionIndex]
const noCollectionAvailable = collection !== undefined
const requests = collection.requests
return requests
if (!noCollectionAvailable){
return []
}
return collection.requests
}
},
},
@@ -178,7 +178,7 @@ export default {
this.$store.commit("postwoman/saveRequestAs", {
request: requestUpdated,
collectionIndex: this.$data.requestData.collectionIndex,
folderIndex: this.$data.requestData.folderIndex,
folderName: this.$data.requestData.folderName,
requestIndex: this.$data.requestData.requestIndex,
})
@@ -191,4 +191,35 @@ export default {
},
},
}
function getFolderNames(folders, namesList) {
if (folders.length) {
folders.forEach(folder => {
namesList.push(folder.name)
if (folder.folders && folder.folders.length) {
getFolderNames(folder.folders, namesList)
}
})
}
return namesList
}
function findFolder(folderName, currentFolder) {
let selectedFolder, result;
if (folderName === currentFolder.name){
return currentFolder
}
for (let i = 0; i < currentFolder.folders.length; i++) {
selectedFolder = currentFolder.folders[i];
result = findFolder(folderName, selectedFolder)
if (result !== false) {
return result
}
}
return false
}
</script>

View File

@@ -10,7 +10,7 @@
@keydown="handleKeystroke"
ref="acInput"
:spellcheck="spellcheck"
:autocapitalize="spellcheck"
:autocapitalize="autocapitalize"
:autocorrect="spellcheck"
/>
<ul
@@ -86,6 +86,12 @@ export default {
required: false,
},
autocapitalize: {
type: String,
default: "off",
required: false,
},
placeholder: {
type: String,
default: "",

View File

@@ -205,86 +205,64 @@ export const mutations = {
collections[collectionIndex] = collection
},
addNewFolder({ collections }, payload) {
const { collectionIndex, folder } = payload
collections[collectionIndex].folders.push({
name: "",
addFolder({collections}, payload) {
const {name, folder} = payload;
const newFolder = {
name: name,
requests: [],
...folder,
})
folders: [],
}
folder.folders.push(newFolder)
},
editFolder({ collections }, payload) {
const { collectionIndex, folder, folderIndex } = payload
Vue.set(collections[collectionIndex].folders, folderIndex, folder)
const { collectionIndex, folder, folderIndex, folderName } = payload
const collection = collections[collectionIndex];
let parentFolder = findFolder(folderName, collection, true);
if (parentFolder && parentFolder.folders) {
Vue.set(parentFolder.folders, folderIndex, folder);
}
},
removeFolder({ collections }, payload) {
const { collectionIndex, folderIndex } = payload
collections[collectionIndex].folders.splice(folderIndex, 1)
},
const { collectionIndex, folderIndex, folderName } = payload
const collection = collections[collectionIndex];
addRequest({ collections }, payload) {
const { request } = payload
// Request that is directly attached to collection
if (request.folder === -1) {
collections[request.collection].requests.push(request)
return
let parentFolder = findFolder(folderName, collection, true);
if (parentFolder && parentFolder.folders) {
parentFolder.folders.splice(folderIndex, 1)
}
collections[request.collection].folders[request.folder].requests.push(request)
},
editRequest({ collections }, payload) {
const {
requestOldCollectionIndex,
requestOldFolderIndex,
requestOldIndex,
requestNew,
requestNewCollectionIndex,
requestNewFolderIndex,
} = payload
const { requestCollectionIndex, requestFolderName, requestFolderIndex, requestNew, requestIndex } = payload
const changedCollection = requestOldCollectionIndex !== requestNewCollectionIndex
const changedFolder = requestOldFolderIndex !== requestNewFolderIndex
const changedPlace = changedCollection || changedFolder
let collection = collections[requestCollectionIndex];
// set new request
if (requestNewFolderIndex !== undefined) {
Vue.set(
collections[requestNewCollectionIndex].folders[requestNewFolderIndex].requests,
requestOldIndex,
requestNew
)
} else {
Vue.set(collections[requestNewCollectionIndex].requests, requestOldIndex, requestNew)
if (requestFolderIndex === -1) {
Vue.set(collection.requests, requestIndex, requestNew)
return
}
// remove old request
if (changedPlace) {
if (requestOldFolderIndex !== undefined) {
collections[requestOldCollectionIndex].folders[requestOldFolderIndex].requests.splice(
requestOldIndex,
1
)
} else {
collections[requestOldCollectionIndex].requests.splice(requestOldIndex, 1)
}
}
let folder = findFolder(requestFolderName, collection, false)
Vue.set(folder.requests, requestIndex, requestNew)
},
saveRequestAs({ collections }, payload) {
const { request, collectionIndex, folderIndex, requestIndex } = payload
const { request, collectionIndex, folderName, requestIndex } = payload
const specifiedCollection = collectionIndex !== undefined
const specifiedFolder = folderIndex !== undefined
const specifiedFolder = folderName !== undefined
const specifiedRequest = requestIndex !== undefined
if (specifiedCollection && specifiedFolder && specifiedRequest) {
Vue.set(collections[collectionIndex].folders[folderIndex].requests, requestIndex, request)
const folder = findFolder(folderName, collections[collectionIndex])
Vue.set(folder.requests, requestIndex, request)
} else if (specifiedCollection && specifiedFolder && !specifiedRequest) {
const requests = collections[collectionIndex].folders[folderIndex].requests
const folder = findFolder(folderName, collections[collectionIndex])
const requests = folder.requests
const lastRequestIndex = requests.length - 1
Vue.set(requests, lastRequestIndex + 1, request)
} else if (specifiedCollection && !specifiedFolder && specifiedRequest) {
@@ -297,61 +275,46 @@ export const mutations = {
}
},
saveRequest({ collections }, payload) {
const { request } = payload
// Remove the old request from collection
if (
Object.prototype.hasOwnProperty.call(request, "oldCollection") &&
request.oldCollection > -1
) {
const folder =
Object.prototype.hasOwnProperty.call(request, "oldFolder") && request.oldFolder >= -1
? request.oldFolder
: request.folder
if (folder > -1) {
collections[request.oldCollection].folders[folder].requests.splice(request.requestIndex, 1)
} else {
collections[request.oldCollection].requests.splice(request.requestIndex, 1)
}
} else if (
Object.prototype.hasOwnProperty.call(request, "oldFolder") &&
request.oldFolder !== -1
) {
collections[request.collection].folders[folder].requests.splice(request.requestIndex, 1)
}
delete request.oldCollection
delete request.oldFolder
// Request that is directly attached to collection
if (request.folder === -1) {
Vue.set(collections[request.collection].requests, request.requestIndex, request)
return
}
Vue.set(
collections[request.collection].folders[request.folder].requests,
request.requestIndex,
request
)
},
removeRequest({ collections }, payload) {
const { collectionIndex, folderIndex, requestIndex } = payload
const { collectionIndex, folderName, requestIndex } = payload
let collection = collections[collectionIndex];
// Request that is directly attached to collection
if (folderIndex === -1) {
collections[collectionIndex].requests.splice(requestIndex, 1)
if (collection.name === folderName) {
collection.requests.splice(requestIndex, 1)
return
}
let folder = findFolder(folderName, collection, false)
collections[collectionIndex].folders[folderIndex].requests.splice(requestIndex, 1)
if (folder) {
folder.requests.splice(requestIndex, 1)
}
},
selectRequest(state, { request }) {
state.selectedRequest = Object.assign({}, request)
},
moveRequest({ collections }, payload) {
const { oldCollectionIndex, newCollectionIndex, newFolderIndex, newFolderName, oldFolderName, requestIndex } = payload;
const isCollection = newFolderIndex === -1;
const oldCollection = collections[oldCollectionIndex];
const newCollection = collections[newCollectionIndex];
const request = findRequest(oldFolderName, oldCollection, requestIndex)
if (isCollection) {
newCollection.requests.push(request)
return
}
if (!isCollection) {
const folder = findFolder(newFolderName, newCollection, false);
if (folder) {
folder.requests.push(request)
return
}
}
},
}
function testValue(myValue) {
@@ -362,3 +325,47 @@ function testValue(myValue) {
return myValue
}
}
function findRequest(folderName, currentFolder, requestIndex) {
let selectedFolder, result;
if (folderName === currentFolder.name) {
let request = currentFolder.requests[requestIndex];
currentFolder.requests.splice(requestIndex, 1)
return request;
} else {
for (let i = 0; i < currentFolder.folders.length; i += 1) {
selectedFolder = currentFolder.folders[i];
result = findRequest(folderName, selectedFolder, requestIndex);
if (result !== false) {
return result;
}
}
return false;
}
}
function findFolder(folderName, currentFolder, returnParent, parentFolder) {
let selectedFolder, result;
if (folderName === currentFolder.name && returnParent) {
return parentFolder;
} else if (folderName === currentFolder.name && !returnParent) {
return currentFolder;
} else {
for (let i = 0; i < currentFolder.folders.length; i++) {
selectedFolder = currentFolder.folders[i];
result = findFolder(folderName, selectedFolder, returnParent, currentFolder);
if (result !== false) {
return result;
}
}
return false;
}
}