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:
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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')
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: "",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user