fix conflicts
This commit is contained in:
64
components/collections/addCollection.vue
Normal file
64
components/collections/addCollection.vue
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<modal v-if="show" @close="hideModal">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">New Collection</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModal" >
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="name" placeholder="My New Collection" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="addNewCollection">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
<span>Create</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: Boolean,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addNewCollection() {
|
||||||
|
this.$store.commit('postwoman/addNewCollection', { name: this.$data.name })
|
||||||
|
this.$emit('hide-modal')
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.$emit('hide-modal')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
64
components/collections/addFolder.vue
Normal file
64
components/collections/addFolder.vue
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<modal v-if="show" @close="show = false">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">New Folder</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModal">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="name" placeholder="My New Folder" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="addNewFolder">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
<span>Create</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show : Boolean,
|
||||||
|
collection : Object,
|
||||||
|
collectionIndex : Number,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addNewFolder() {
|
||||||
|
this.$store.commit('postwoman/addNewFolder', { folder: { name: this.$data.name }, collectionIndex: this.$props.collectionIndex })
|
||||||
|
this.hideModal()
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.$emit('hide-modal')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
103
components/collections/collection.vue
Normal file
103
components/collections/collection.vue
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="toggleShowChildren">
|
||||||
|
<i class="material-icons" v-show='!showChildren'>arrow_right</i>
|
||||||
|
<i class="material-icons" v-show='showChildren'>arrow_drop_down</i>
|
||||||
|
<i class="material-icons">folder</i>
|
||||||
|
<span>{{collection.name}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="removeCollection" v-tooltip="'Delete collection'">
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="$emit('edit-collection')" v-tooltip="'Edit collection'">
|
||||||
|
<i class="material-icons">create</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="$emit('add-folder')" v-tooltip="'New Folder'">
|
||||||
|
<i class="material-icons">create_new_folder</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="showChildren">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(folder, index) in collection.folders" :key="folder.name">
|
||||||
|
<folder
|
||||||
|
v-bind:folder = "folder"
|
||||||
|
v-bind:folderIndex = "index"
|
||||||
|
v-bind:collection-index = "collectionIndex"
|
||||||
|
v-on:edit-folder = "editFolder(collectionIndex, folder, index)"
|
||||||
|
v-on:edit-request = "$emit('edit-request', $event)"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li v-if="(collection.folders.length === 0) && (collection.requests.length === 0)">
|
||||||
|
<label>Collection is empty</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li v-for="(request, index) in collection.requests" :key="index">
|
||||||
|
<request
|
||||||
|
v-bind:request = "request"
|
||||||
|
v-bind:collection-index = "collectionIndex"
|
||||||
|
v-bind:folder-index = "-1"
|
||||||
|
v-bind:request-index = "index"
|
||||||
|
v-on:edit-request = "$emit('edit-request', { request, collectionIndex, folderIndex: undefined, requestIndex: index })"
|
||||||
|
></request>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
display: flex;
|
||||||
|
padding-left: 16px;
|
||||||
|
border-left: 1px solid var(--brd-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import folder from './folder';
|
||||||
|
import request from './request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
folder,
|
||||||
|
request,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
collectionIndex : Number,
|
||||||
|
collection : Object,
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
showChildren : false,
|
||||||
|
selectedFolder : {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleShowChildren() {
|
||||||
|
this.showChildren = !this.showChildren;
|
||||||
|
},
|
||||||
|
removeCollection() {
|
||||||
|
if (!confirm("Are you sure you want to remove this collection?")) return;
|
||||||
|
this.$store.commit('postwoman/removeCollection', {
|
||||||
|
collectionIndex: this.collectionIndex,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editFolder(collectionIndex, folder, folderIndex) {
|
||||||
|
this.$emit('edit-folder', { collectionIndex, folder, folderIndex })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
67
components/collections/editCollection.vue
Normal file
67
components/collections/editCollection.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<modal v-if="show" @close="hideModel">
|
||||||
|
<div slot='header'>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">Edit Collection</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModel" >
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="name" v-bind:placeholder="editingCollection.name" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="saveCollection">
|
||||||
|
<i class="material-icons">save</i>
|
||||||
|
<span>Save</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show : Boolean,
|
||||||
|
editingCollection : Object,
|
||||||
|
editingCollectionIndex : Number,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
saveCollection() {
|
||||||
|
const collectionUpdated = { ...this.$props.editingCollection, name: this.$data.name }
|
||||||
|
this.$store.commit('postwoman/editCollection', { collection: collectionUpdated, collectionIndex: this.$props.editingCollectionIndex })
|
||||||
|
this.$emit('hide-modal');
|
||||||
|
},
|
||||||
|
hideModel() {
|
||||||
|
this.$emit('hide-modal');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
70
components/collections/editFolder.vue
Normal file
70
components/collections/editFolder.vue
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<modal v-if="show" @close="show = false">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">Edit Folder</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModal">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="name" v-bind:placeholder="folder.name" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="editFolder">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
<span>Save</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show : Boolean,
|
||||||
|
collection : Object,
|
||||||
|
collectionIndex : Number,
|
||||||
|
folder : Object,
|
||||||
|
folderIndex : Number,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
name: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editFolder() {
|
||||||
|
this.$store.commit('postwoman/editFolder', {
|
||||||
|
collectionIndex : this.$props.collectionIndex,
|
||||||
|
folder : { ...this.$props.folder, name: this.$data.name },
|
||||||
|
folderIndex : this.$props.folderIndex,
|
||||||
|
})
|
||||||
|
this.hideModal()
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.$emit('hide-modal')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
132
components/collections/editRequest.vue
Normal file
132
components/collections/editRequest.vue
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<!--
|
||||||
|
Made this component to be separate from `saveRequest` as it handles request editing
|
||||||
|
only related to it's positioning and naming inside of collections.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<modal v-if="show" @close="hideModal">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">Edit Request</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModal">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="requestUpdateData.name" v-bind:placeholder="request.name" />
|
||||||
|
<select type="text" v-model="requestUpdateData.collectionIndex" >
|
||||||
|
<option
|
||||||
|
v-for="(collection, index) in $store.state.postwoman.collections"
|
||||||
|
:key = "index"
|
||||||
|
:value = "index">
|
||||||
|
{{ collection.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<select type="text" 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>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="saveRequest">
|
||||||
|
<i class="material-icons">save</i>
|
||||||
|
<span>Save</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show : Boolean,
|
||||||
|
collectionIndex : Number,
|
||||||
|
folderIndex : Number,
|
||||||
|
request : Object,
|
||||||
|
requestIndex : Number,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
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: {
|
||||||
|
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', {
|
||||||
|
requestOld : this.$props.request,
|
||||||
|
requestOldCollectionIndex : this.$props.collectionIndex,
|
||||||
|
requestOldFolderIndex : this.$props.folderIndex,
|
||||||
|
requestOldIndex : this.$props.requestIndex,
|
||||||
|
requestNew : requestUpdated,
|
||||||
|
requestNewCollectionIndex : requestUpdated.collection,
|
||||||
|
requestNewFolderIndex : requestUpdated.folder,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.hideModal()
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.$emit('hide-modal')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
90
components/collections/folder.vue
Normal file
90
components/collections/folder.vue
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="toggleShowChildren">
|
||||||
|
<i class="material-icons" v-show='!showChildren'>arrow_right</i>
|
||||||
|
<i class="material-icons" v-show='showChildren'>arrow_drop_down</i>
|
||||||
|
<i class="material-icons">folder_open</i>
|
||||||
|
<span>{{folder.name}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="removeFolder" v-tooltip="'Delete folder'">
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="editFolder" v-tooltip="'Edit folder'">
|
||||||
|
<i class="material-icons">edit</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="showChildren">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(request, index) in folder.requests" :key="index">
|
||||||
|
<request
|
||||||
|
v-bind:request = "request"
|
||||||
|
v-bind:collection-index = "collectionIndex"
|
||||||
|
v-bind:folder-index = "folderIndex"
|
||||||
|
v-bind:request-index = "index"
|
||||||
|
v-on:edit-request = "$emit('edit-request', { request, collectionIndex, folderIndex, requestIndex: index })"
|
||||||
|
></request>
|
||||||
|
</li>
|
||||||
|
<li v-if="folder.requests.length === 0">
|
||||||
|
<label>Folder is empty</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
display: flex;
|
||||||
|
padding-left: 16px;
|
||||||
|
border-left: 1px solid var(--brd-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import request from './request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
folder : Object,
|
||||||
|
collectionIndex : Number,
|
||||||
|
folderIndex : Number,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
request,
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
showChildren: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleShowChildren() {
|
||||||
|
this.showChildren = !this.showChildren;
|
||||||
|
},
|
||||||
|
selectRequest(request) {
|
||||||
|
this.$store.commit('postwoman/selectRequest', { request });
|
||||||
|
},
|
||||||
|
removeFolder() {
|
||||||
|
if (!confirm("Are you sure you want to remove this folder?")) return;
|
||||||
|
this.$store.commit('postwoman/removeFolder', {
|
||||||
|
collectionIndex: this.collectionIndex,
|
||||||
|
folderIndex: this.folderIndex,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editFolder() {
|
||||||
|
this.$emit('edit-folder')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
110
components/collections/importExportCollections.vue
Normal file
110
components/collections/importExportCollections.vue
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<modal v-if="show" @close="hideModel">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">Import / Export Collections</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModel">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<textarea v-model='collectionJson' rows="8">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="openDialogChooseFileToReplaceWith">
|
||||||
|
<i class="material-icons">get_app</i>
|
||||||
|
<span>Replace with JSON</span>
|
||||||
|
<input type="file" @change="replaceWithJSON" style="display: none;" ref="inputChooseFileToReplaceWith">
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="openDialogChooseFileToImportFrom">
|
||||||
|
<i class="material-icons">get_app</i>
|
||||||
|
<span>Import from JSON</span>
|
||||||
|
<input type="file" @change="importFromJSON" style="display: none;" ref="inputChooseFileToImportFrom">
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="exportJSON">
|
||||||
|
<i class="material-icons">get_app</i>
|
||||||
|
<span>Export JSON</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: Boolean,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
collectionJson () {
|
||||||
|
return JSON.stringify(this.$store.state.postwoman.collections, null, 2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hideModel() {
|
||||||
|
this.$emit('hide-modal');
|
||||||
|
},
|
||||||
|
openDialogChooseFileToReplaceWith() {
|
||||||
|
this.$refs.inputChooseFileToReplaceWith.click();
|
||||||
|
},
|
||||||
|
openDialogChooseFileToImportFrom() {
|
||||||
|
this.$refs.inputChooseFileToImportFrom.click();
|
||||||
|
},
|
||||||
|
replaceWithJSON() {
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
let content = event.target.result;
|
||||||
|
let collections = JSON.parse(content);
|
||||||
|
this.$store.commit('postwoman/replaceCollections', collections);
|
||||||
|
};
|
||||||
|
reader.readAsText(this.$refs.inputChooseFileToReplaceWith.files[0]);
|
||||||
|
},
|
||||||
|
importFromJSON() {
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
let content = event.target.result;
|
||||||
|
let collections = JSON.parse(content);
|
||||||
|
this.$store.commit('postwoman/importCollections', collections);
|
||||||
|
};
|
||||||
|
reader.readAsText(this.$refs.inputChooseFileToImportFrom.files[0]);
|
||||||
|
},
|
||||||
|
exportJSON() {
|
||||||
|
let text = this.collectionJson;
|
||||||
|
text = text.replace(/\n/g, '\r\n');
|
||||||
|
let blob = new Blob([text], {
|
||||||
|
type: 'text/json'
|
||||||
|
});
|
||||||
|
let anchor = document.createElement('a');
|
||||||
|
anchor.download = 'postwoman-collection.json';
|
||||||
|
anchor.href = window.URL.createObjectURL(blob);
|
||||||
|
anchor.target = '_blank';
|
||||||
|
anchor.style.display = 'none';
|
||||||
|
document.body.appendChild(anchor);
|
||||||
|
anchor.click();
|
||||||
|
document.body.removeChild(anchor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
201
components/collections/index.vue
Normal file
201
components/collections/index.vue
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<!--
|
||||||
|
TODO:
|
||||||
|
- probably refactor and pass event arguments to modals directly without unpacking
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="collections-wrapper">
|
||||||
|
<addCollection
|
||||||
|
v-bind:show = "showModalAdd"
|
||||||
|
v-on:hide-modal = 'displayModalAdd(false)'
|
||||||
|
>
|
||||||
|
</addCollection>
|
||||||
|
<editCollection
|
||||||
|
v-bind:show = "showModalEdit"
|
||||||
|
v-bind:editingCollection = "editingCollection"
|
||||||
|
v-bind:editingCollectionIndex = "editingCollectionIndex"
|
||||||
|
v-on:hide-modal = 'displayModalEdit(false)'
|
||||||
|
>
|
||||||
|
</editCollection>
|
||||||
|
<addFolder
|
||||||
|
v-bind:show = "showModalAddFolder"
|
||||||
|
v-bind:collection = "editingCollection"
|
||||||
|
v-bind:collectionIndex = "editingCollectionIndex"
|
||||||
|
v-on:hide-modal = 'displayModalAddFolder(false)'
|
||||||
|
>
|
||||||
|
</addFolder>
|
||||||
|
<editFolder
|
||||||
|
v-bind:show = "showModalEditFolder"
|
||||||
|
v-bind:collection = "editingCollection"
|
||||||
|
v-bind:collectionIndex = "editingCollectionIndex"
|
||||||
|
v-bind:folder = "editingFolder"
|
||||||
|
v-bind:folderIndex = "editingFolderIndex"
|
||||||
|
v-on:hide-modal = 'displayModalEditFolder(false)'
|
||||||
|
>
|
||||||
|
</editFolder>
|
||||||
|
<editRequest
|
||||||
|
v-bind:show = "showModalEditRequest"
|
||||||
|
v-bind:collectionIndex = "editingCollectionIndex"
|
||||||
|
v-bind:folderIndex = "editingFolderIndex"
|
||||||
|
v-bind:request = "editingRequest"
|
||||||
|
v-bind:requestIndex = "editingRequestIndex"
|
||||||
|
v-on:hide-modal = "displayModalEditRequest(false)"
|
||||||
|
>
|
||||||
|
</editRequest>
|
||||||
|
<importExportCollections
|
||||||
|
v-bind:show = "showModalImportExport"
|
||||||
|
v-on:hide-modal = 'displayModalImportExport(false)'
|
||||||
|
>
|
||||||
|
</importExportCollections>
|
||||||
|
|
||||||
|
<div class='flex-wrap'>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="displayModalAdd(true)">
|
||||||
|
<i class="material-icons">add</i>
|
||||||
|
<span>New</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="displayModalImportExport(true)">
|
||||||
|
<i class="material-icons">import_export</i>
|
||||||
|
<span>Import / Export</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li v-for="(collection, index) in collections" :key="collection.name">
|
||||||
|
<collection
|
||||||
|
v-bind:collection-index = "index"
|
||||||
|
v-bind:collection = "collection"
|
||||||
|
v-on:edit-collection = "editCollection(collection, index)"
|
||||||
|
v-on:add-folder = "addFolder(collection, index)"
|
||||||
|
v-on:edit-folder = "editFolder($event)"
|
||||||
|
v-on:edit-request = "editRequest($event)"
|
||||||
|
>
|
||||||
|
</collection>
|
||||||
|
</li>
|
||||||
|
<li v-if="collections.length === 0">
|
||||||
|
<label>Collections are empty</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import addCollection from "./addCollection";
|
||||||
|
import addFolder from "./addFolder";
|
||||||
|
import collection from './collection'
|
||||||
|
import editCollection from "./editCollection";
|
||||||
|
import editFolder from "./editFolder";
|
||||||
|
import editRequest from "./editRequest";
|
||||||
|
import importExportCollections from "./importExportCollections";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
addCollection,
|
||||||
|
addFolder,
|
||||||
|
collection,
|
||||||
|
editCollection,
|
||||||
|
editFolder,
|
||||||
|
editRequest,
|
||||||
|
importExportCollections,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showModalAdd : false,
|
||||||
|
showModalEdit : false,
|
||||||
|
showModalImportExport : false,
|
||||||
|
showModalAddFolder : false,
|
||||||
|
showModalEditFolder : false,
|
||||||
|
showModalEditRequest : false,
|
||||||
|
editingCollection : undefined,
|
||||||
|
editingCollectionIndex : undefined,
|
||||||
|
editingFolder : undefined,
|
||||||
|
editingFolderIndex : undefined,
|
||||||
|
editingRequest : undefined,
|
||||||
|
editingRequestIndex : undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
collections () {
|
||||||
|
return this.$store.state.postwoman.collections
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
displayModalAdd(shouldDisplay) {
|
||||||
|
this.showModalAdd = shouldDisplay
|
||||||
|
},
|
||||||
|
displayModalEdit(shouldDisplay) {
|
||||||
|
this.showModalEdit = shouldDisplay
|
||||||
|
|
||||||
|
if (!shouldDisplay)
|
||||||
|
this.resetSelectedData()
|
||||||
|
},
|
||||||
|
displayModalImportExport(shouldDisplay) {
|
||||||
|
this.showModalImportExport = shouldDisplay
|
||||||
|
},
|
||||||
|
displayModalAddFolder(shouldDisplay) {
|
||||||
|
this.showModalAddFolder = shouldDisplay
|
||||||
|
|
||||||
|
if (!shouldDisplay)
|
||||||
|
this.resetSelectedData()
|
||||||
|
},
|
||||||
|
displayModalEditFolder(shouldDisplay) {
|
||||||
|
this.showModalEditFolder = shouldDisplay
|
||||||
|
|
||||||
|
if (!shouldDisplay)
|
||||||
|
this.resetSelectedData()
|
||||||
|
},
|
||||||
|
displayModalEditRequest(shouldDisplay) {
|
||||||
|
this.showModalEditRequest = shouldDisplay
|
||||||
|
|
||||||
|
if (!shouldDisplay)
|
||||||
|
this.resetSelectedData()
|
||||||
|
},
|
||||||
|
editCollection(collection, collectionIndex) {
|
||||||
|
this.$data.editingCollection = collection
|
||||||
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
|
this.displayModalEdit(true)
|
||||||
|
},
|
||||||
|
addFolder(collection, collectionIndex) {
|
||||||
|
this.$data.editingCollection = collection
|
||||||
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
|
this.displayModalAddFolder(true)
|
||||||
|
},
|
||||||
|
editFolder(payload) {
|
||||||
|
const { collectionIndex, folder, folderIndex } = payload
|
||||||
|
this.$data.editingCollection = collection
|
||||||
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
|
this.$data.editingFolder = folder
|
||||||
|
this.$data.editingFolderIndex = folderIndex
|
||||||
|
this.displayModalEditFolder(true)
|
||||||
|
},
|
||||||
|
editRequest(payload) {
|
||||||
|
const { request, collectionIndex, folderIndex, requestIndex } = payload
|
||||||
|
this.$data.editingCollectionIndex = collectionIndex
|
||||||
|
this.$data.editingFolderIndex = folderIndex
|
||||||
|
this.$data.editingRequest = request
|
||||||
|
this.$data.editingRequestIndex = requestIndex
|
||||||
|
this.displayModalEditRequest(true)
|
||||||
|
|
||||||
|
},
|
||||||
|
resetSelectedData() {
|
||||||
|
this.$data.editingCollection = undefined
|
||||||
|
this.$data.editingCollectionIndex = undefined
|
||||||
|
this.$data.editingFolder = undefined
|
||||||
|
this.$data.editingFolderIndex = undefined
|
||||||
|
this.$data.editingRequest = undefined
|
||||||
|
this.$data.editingRequestIndex = undefined
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
55
components/collections/request.vue
Normal file
55
components/collections/request.vue
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="selectRequest()" v-tooltip="'Use request'">
|
||||||
|
<i class="material-icons">insert_drive_file</i>
|
||||||
|
<span>{{request.name}}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="removeRequest" v-tooltip="'Delete request'">
|
||||||
|
<i class="material-icons">delete</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="$emit('edit-request')" v-tooltip="'Edit request'">
|
||||||
|
<i class="material-icons">edit</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
display: flex;
|
||||||
|
padding-left: 16px;
|
||||||
|
border-left: 1px solid var(--brd-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
request : Object,
|
||||||
|
collectionIndex : Number,
|
||||||
|
folderIndex : Number,
|
||||||
|
requestIndex : Number,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectRequest() {
|
||||||
|
this.$store.commit('postwoman/selectRequest', { request: this.request });
|
||||||
|
},
|
||||||
|
removeRequest() {
|
||||||
|
if (!confirm("Are you sure you want to remove this request?")) return;
|
||||||
|
this.$store.commit('postwoman/removeRequest', {
|
||||||
|
collectionIndex : this.collectionIndex,
|
||||||
|
folderIndex : this.folderIndex,
|
||||||
|
requestIndex : this.requestIndex,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
158
components/collections/saveRequestAs.vue
Normal file
158
components/collections/saveRequestAs.vue
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<modal v-if="show" @close="hideModal">
|
||||||
|
<div slot="header">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="flex-wrap">
|
||||||
|
<h3 class="title">Save Request As</h3>
|
||||||
|
<div>
|
||||||
|
<button class="icon" @click="hideModal">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="body">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="text" v-model="requestData.name" v-bind:placeholder="defaultRequestName" />
|
||||||
|
<select type="text" v-model="requestData.collectionIndex" >
|
||||||
|
<option
|
||||||
|
v-for="(collection, index) in $store.state.postwoman.collections"
|
||||||
|
:key = "index"
|
||||||
|
:value = "index">
|
||||||
|
{{ collection.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<select type="text" 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>
|
||||||
|
<select type="text" v-model="requestData.requestIndex" >
|
||||||
|
<option
|
||||||
|
:key = "undefined"
|
||||||
|
:value = "undefined">
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
v-for ="(folder, index) in requests"
|
||||||
|
:key = "index"
|
||||||
|
:value = "index">
|
||||||
|
{{ folder.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div slot="footer">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<button class="icon" @click="saveRequestAs">
|
||||||
|
<i class="material-icons">save</i>
|
||||||
|
<span>Save</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from "../../components/modal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show : Boolean,
|
||||||
|
editingRequest : Object,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
modal,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
defaultRequestName : 'My New Request',
|
||||||
|
requestData : {
|
||||||
|
name : undefined,
|
||||||
|
collectionIndex : undefined,
|
||||||
|
folderIndex : 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
|
||||||
|
this.$data.requestData.requestIndex = undefined
|
||||||
|
},
|
||||||
|
'requestData.folderIndex': function resetRequestIndex() {
|
||||||
|
this.$data.requestData.requestIndex = undefined
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
folders() {
|
||||||
|
const userSelectedAnyCollection = this.$data.requestData.collectionIndex !== undefined
|
||||||
|
if (!userSelectedAnyCollection) return []
|
||||||
|
|
||||||
|
return this.$store.state.postwoman.collections[this.$data.requestData.collectionIndex].folders
|
||||||
|
},
|
||||||
|
requests() {
|
||||||
|
const userSelectedAnyCollection = this.$data.requestData.collectionIndex !== undefined
|
||||||
|
if (!userSelectedAnyCollection) return []
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const collection = this.$store.state.postwoman.collections[this.$data.requestData.collectionIndex]
|
||||||
|
const requests = collection.requests
|
||||||
|
return requests
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
saveRequestAs() {
|
||||||
|
const userDidntSpecifyCollection = this.$data.requestData.collectionIndex === undefined
|
||||||
|
if (userDidntSpecifyCollection) {
|
||||||
|
this.$toast.error('please, specify collection first', { icon: 'error' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestUpdated = {
|
||||||
|
...this.$props.editingRequest,
|
||||||
|
name : this.$data.requestData.name || this.$data.defaultRequestName,
|
||||||
|
collection : this.$data.requestData.collectionIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$store.commit('postwoman/saveRequestAs', {
|
||||||
|
request : requestUpdated,
|
||||||
|
collectionIndex : this.$data.requestData.collectionIndex,
|
||||||
|
folderIndex : this.$data.requestData.folderIndex,
|
||||||
|
requestIndex : this.$data.requestData.requestIndex,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.hideModal();
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.$emit('hide-modal');
|
||||||
|
this.$emit('hide-model'); // for backward compatibility // TODO: use fixed event
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<pw-section class="gray" label="History">
|
<pw-section class="green" icon="history" label="History">
|
||||||
<ul>
|
<ul>
|
||||||
<li id="filter-history">
|
<li id="filter-history">
|
||||||
<input aria-label="Search" type="text" placeholder="search history" :readonly="history.length === 0" v-model="filterText">
|
<input aria-label="Search" type="text" placeholder="search history" :readonly="history.length === 0" v-model="filterText">
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
</li>
|
</li>
|
||||||
<div class="show-on-small-screen">
|
<div class="show-on-small-screen">
|
||||||
<li>
|
<li>
|
||||||
<button v-tooltip="'Delete'" class="icon" :id="'delete-button#'+index" @click="deleteHistory(entry)" aria-label="Delete">
|
<button v-tooltip="'Delete entry'" class="icon" :id="'delete-button#'+index" @click="deleteHistory(entry)" aria-label="Delete">
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons">delete</i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button v-tooltip="'Edit'" class="icon" :id="'use-button#'+index" @click="useHistory(entry)" aria-label="Edit">
|
<button v-tooltip="'Edit entry'" class="icon" :id="'use-button#'+index" @click="useHistory(entry)" aria-label="Edit">
|
||||||
<i class="material-icons">edit</i>
|
<i class="material-icons">edit</i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<fieldset :id="label.toLowerCase()" :class="{ 'no-colored-frames': noFrameColors }">
|
<fieldset :id="label.toLowerCase()" :class="{ 'no-colored-frames': noFrameColors }">
|
||||||
<legend @click.prevent="collapse"><span>{{ label }}</span><i class="material-icons" v-if="isCollapsed">expand_more</i><i class="material-icons" v-if="!isCollapsed">expand_less</i></legend>
|
<legend @click.prevent="collapse"><i class="material-icons icon">{{ icon }}</i><span>{{ label }}</span><i class="material-icons" v-if="isCollapsed">expand_more</i><i class="material-icons" v-if="!isCollapsed">expand_less</i></legend>
|
||||||
<div class="collapsible" :class="{ hidden: collapsed }">
|
<div class="collapsible" :class="{ hidden: collapsed }">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
fieldset.no-colored-frames legend {
|
fieldset.no-colored-frames legend {
|
||||||
color: var(--fg-color);
|
color: var(--fg-color);
|
||||||
}
|
}
|
||||||
|
.icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -32,6 +35,10 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: "Section"
|
default: "Section"
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: "lens"
|
||||||
|
},
|
||||||
collapsed: {
|
collapsed: {
|
||||||
type: Boolean
|
type: Boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,8 +92,8 @@
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
this.$refs.toggle.classList.toggle("on");
|
const containsOnClass = this.$refs.toggle.classList.toggle("on");
|
||||||
this.$emit('change', this.$refs.toggle.classList.contains("on"));
|
this.$emit('change', containsOnClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
162
pages/index.vue
162
pages/index.vue
@@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
|
<save-request-as
|
||||||
|
v-bind:show="showRequestModal"
|
||||||
|
v-on:hide-model='hideRequestModal'
|
||||||
|
v-bind:editing-request='editRequest'
|
||||||
|
></save-request-as>
|
||||||
<pw-modal v-if="showModal" @close="showModal = false">
|
<pw-modal v-if="showModal" @close="showModal = false">
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -33,7 +38,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</pw-modal>
|
</pw-modal>
|
||||||
<pw-section class="blue" label="Request" ref="request">
|
<pw-section class="blue" icon="cloud_upload" label="Request" ref="request">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="method">Method</label>
|
<label for="method">Method</label>
|
||||||
@@ -56,19 +61,8 @@
|
|||||||
<input @keyup.enter="isValidURL ? sendRequest() : null" id="path" name="path" v-model="path" @input="pathInputHandler">
|
<input @keyup.enter="isValidURL ? sendRequest() : null" id="path" name="path" v-model="path" @input="pathInputHandler">
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<label class="hide-on-small-screen" for="copyRequest"> </label>
|
<label for="label">Label</label>
|
||||||
<button class="icon" @click="copyRequest" id="copyRequest" ref="copyRequest" :disabled="!isValidURL">
|
<input id="label" name="label" type="text" v-model="label" placeholder="(optional)">
|
||||||
<i class="material-icons">share</i>
|
|
||||||
<span>Permalink</span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label class="hide-on-small-screen" for="code"> </label>
|
|
||||||
<button class="icon" id="code" v-on:click="isHidden = !isHidden" :disabled="!isValidURL">
|
|
||||||
<i class="material-icons" v-if="isHidden">visibility</i>
|
|
||||||
<i class="material-icons" v-if="!isHidden">visibility_off</i>
|
|
||||||
<span>{{ isHidden ? 'Show Code' : 'Hide Code' }}</span>
|
|
||||||
</button>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<label class="hide-on-small-screen" for="send"> </label>
|
<label class="hide-on-small-screen" for="send"> </label>
|
||||||
@@ -88,7 +82,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<span>
|
<span>
|
||||||
<pw-toggle :on="rawInput" @change="rawInput = !rawInput">
|
<pw-toggle :on="rawInput" @change="rawInput = $event">
|
||||||
Raw Input {{ rawInput ? "Enabled" : "Disabled" }}
|
Raw Input {{ rawInput ? "Enabled" : "Disabled" }}
|
||||||
</pw-toggle>
|
</pw-toggle>
|
||||||
</span>
|
</span>
|
||||||
@@ -148,27 +142,30 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<input id="label" name="label" type="text" v-model="label" placeholder="Label request">
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
<button class="icon" id="show-modal" @click="showModal = true">
|
<div style="text-align: center;">
|
||||||
<i class="material-icons">import_export</i>
|
<button class="icon" id="show-modal" @click="showModal = true" v-tooltip.bottom='"Import cURL"'>
|
||||||
<span>Import cURL</span>
|
<i class="material-icons">import_export</i>
|
||||||
</button>
|
</button>
|
||||||
<button class="icon" id="goto-history" @click="gotoHistory()">
|
<button class="icon" id="code" v-on:click="isHidden = !isHidden" :disabled="!isValidURL" v-tooltip.bottom='{ content: isHidden ? "Show Code" : "Hide Code"}'>
|
||||||
<i class="material-icons">history</i>
|
<i class="material-icons" v-if="isHidden">visibility</i>
|
||||||
<span>History</span>
|
<i class="material-icons" v-if="!isHidden">visibility_off</i>
|
||||||
</button>
|
</button>
|
||||||
<button class="icon" @click="clearContent">
|
</div>
|
||||||
<i class="material-icons">clear_all</i>
|
<div style="text-align: center;">
|
||||||
<span>Clear all</span>
|
<button class="icon" @click="copyRequest" id="copyRequest" ref="copyRequest" :disabled="!isValidURL" v-tooltip.bottom='"Sharable request URL"'>
|
||||||
</button>
|
<i class="material-icons">share</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="saveRequest" id="saveRequest" ref="saveRequest" :disabled="!isValidURL" v-tooltip.bottom='"Save to Collections"'>
|
||||||
|
<i class="material-icons">save</i>
|
||||||
|
</button>
|
||||||
|
<button class="icon" @click="clearContent" v-tooltip.bottom='"Clear all"'>
|
||||||
|
<i class="material-icons">clear_all</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
<pw-section class="yellow" label="Code" ref="requestCode" v-if="!isHidden">
|
<pw-section class="yellow" icon="code" label="Code" ref="requestCode" v-if="!isHidden">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="requestType">Request Type</label>
|
<label for="requestType">Request Type</label>
|
||||||
@@ -194,7 +191,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
<pw-section class="purple" id="response" label="Response" ref="response">
|
<pw-section class="purple" icon="cloud_download" id="response" label="Response" ref="response">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="status">status</label>
|
<label for="status">status</label>
|
||||||
@@ -236,7 +233,7 @@
|
|||||||
<input id="tab-one" type="radio" name="grp" checked="checked">
|
<input id="tab-one" type="radio" name="grp" checked="checked">
|
||||||
<label for="tab-one">Authentication</label>
|
<label for="tab-one">Authentication</label>
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<pw-section class="cyan" label="Authentication">
|
<pw-section class="cyan" icon="vpn_key" label="Authentication">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
@@ -281,7 +278,7 @@
|
|||||||
<input id="tab-two" type="radio" name="grp">
|
<input id="tab-two" type="radio" name="grp">
|
||||||
<label for="tab-two">Headers</label>
|
<label for="tab-two">Headers</label>
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<pw-section class="orange" label="Headers">
|
<pw-section class="orange" icon="toc" label="Headers">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
@@ -337,7 +334,7 @@
|
|||||||
<input id="tab-three" type="radio" name="grp">
|
<input id="tab-three" type="radio" name="grp">
|
||||||
<label for="tab-three">Parameters</label>
|
<label for="tab-three">Parameters</label>
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<pw-section class="pink" label="Parameters">
|
<pw-section class="pink" icon="input" label="Parameters">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap">
|
||||||
@@ -390,6 +387,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<history @useHistory="handleUseHistory" ref="historyComponent"></history>
|
<history @useHistory="handleUseHistory" ref="historyComponent"></history>
|
||||||
|
<pw-section class="yellow" icon="folder_special" label="Collections" ref="Collections">
|
||||||
|
<collections></collections>
|
||||||
|
</pw-section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -401,6 +401,8 @@
|
|||||||
import textareaAutoHeight from "../directives/textareaAutoHeight";
|
import textareaAutoHeight from "../directives/textareaAutoHeight";
|
||||||
import toggle from "../components/toggle";
|
import toggle from "../components/toggle";
|
||||||
import modal from "../components/modal";
|
import modal from "../components/modal";
|
||||||
|
import collections from '../components/collections';
|
||||||
|
import saveRequestAs from '../components/collections/saveRequestAs';
|
||||||
import parseCurlCommand from '../assets/js/curlparser.js';
|
import parseCurlCommand from '../assets/js/curlparser.js';
|
||||||
import hljs from 'highlight.js';
|
import hljs from 'highlight.js';
|
||||||
import 'highlight.js/styles/dracula.css';
|
import 'highlight.js/styles/dracula.css';
|
||||||
@@ -463,6 +465,8 @@
|
|||||||
'pw-modal': modal,
|
'pw-modal': modal,
|
||||||
history,
|
history,
|
||||||
autocomplete,
|
autocomplete,
|
||||||
|
collections,
|
||||||
|
saveRequestAs,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -497,7 +501,9 @@
|
|||||||
'application/x-www-form-urlencoded',
|
'application/x-www-form-urlencoded',
|
||||||
'text/html',
|
'text/html',
|
||||||
'text/plain'
|
'text/plain'
|
||||||
]
|
],
|
||||||
|
showRequestModal: false,
|
||||||
|
editRequest: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -552,6 +558,29 @@
|
|||||||
this.path = path;
|
this.path = path;
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
|
},
|
||||||
|
selectedRequest (newValue, oldValue) {
|
||||||
|
// @TODO: Convert all variables to single request variable
|
||||||
|
if (!newValue) return;
|
||||||
|
this.url = newValue.url;
|
||||||
|
this.path = newValue.path;
|
||||||
|
this.method = newValue.method;
|
||||||
|
this.auth = newValue.auth;
|
||||||
|
this.httpUser = newValue.httpUser;
|
||||||
|
this.httpPassword = newValue.httpPassword;
|
||||||
|
this.passwordFieldType = newValue.passwordFieldType;
|
||||||
|
this.bearerToken = newValue.bearerToken;
|
||||||
|
this.headers = newValue.headers;
|
||||||
|
this.params = newValue.params;
|
||||||
|
this.bodyParams = newValue.bodyParams;
|
||||||
|
this.rawParams = newValue.rawParams;
|
||||||
|
this.rawInput = newValue.rawInput;
|
||||||
|
this.contentType = newValue.contentType;
|
||||||
|
this.requestType = newValue.requestType;
|
||||||
|
},
|
||||||
|
editingRequest (newValue) {
|
||||||
|
this.editRequest = newValue;
|
||||||
|
this.showRequestModal = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -617,7 +646,13 @@
|
|||||||
},
|
},
|
||||||
passwordFieldType: {
|
passwordFieldType: {
|
||||||
get() { return this.$store.state.request.passwordFieldType; },
|
get() { return this.$store.state.request.passwordFieldType; },
|
||||||
set(value) { this.$store.commit('setState', { value, 'attribute': 'passwordFieldType' })}
|
set(value) { this.$store.commit('setState', { value, 'attribute': 'passwordFieldType' }) }
|
||||||
|
},
|
||||||
|
selectedRequest() {
|
||||||
|
return this.$store.state.postwoman.selectedRequest;
|
||||||
|
},
|
||||||
|
editingRequest() {
|
||||||
|
return this.$store.state.postwoman.editingRequest;
|
||||||
},
|
},
|
||||||
requestName() {
|
requestName() {
|
||||||
return this.label
|
return this.label
|
||||||
@@ -909,6 +944,7 @@
|
|||||||
this.$refs.historyComponent.addEntry(entry);
|
this.$refs.historyComponent.addEntry(entry);
|
||||||
})();
|
})();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
this.response.headers = error.response.headers;
|
this.response.headers = error.response.headers;
|
||||||
this.response.status = error.response.status;
|
this.response.status = error.response.status;
|
||||||
@@ -929,7 +965,7 @@
|
|||||||
} else {
|
} else {
|
||||||
this.response.status = error.message;
|
this.response.status = error.message;
|
||||||
this.response.body = "See JavaScript console (F12) for details.";
|
this.response.body = "See JavaScript console (F12) for details.";
|
||||||
this.$toast.error('Something went wrong!', {
|
this.$toast.error(error + ' (F12 for details)', {
|
||||||
icon: 'error'
|
icon: 'error'
|
||||||
});
|
});
|
||||||
if(!this.$store.state.postwoman.settings.PROXY_ENABLED) {
|
if(!this.$store.state.postwoman.settings.PROXY_ENABLED) {
|
||||||
@@ -947,11 +983,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
gotoHistory() {
|
|
||||||
this.$refs.historyComponent.$el.scrollIntoView({
|
|
||||||
behavior: 'smooth'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getQueryStringFromPath() {
|
getQueryStringFromPath() {
|
||||||
let queryString,
|
let queryString,
|
||||||
pathParsed = url.parse(this.path);
|
pathParsed = url.parse(this.path);
|
||||||
@@ -1037,17 +1068,17 @@
|
|||||||
}).then(() => {})
|
}).then(() => {})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
} else {
|
} else {
|
||||||
this.$refs.copyRequest.innerHTML = this.copiedButton + '<span>Copied</span>';
|
|
||||||
this.$toast.success('Copied to clipboard', {
|
|
||||||
icon: 'done'
|
|
||||||
});
|
|
||||||
var dummy = document.createElement('input');
|
var dummy = document.createElement('input');
|
||||||
document.body.appendChild(dummy);
|
document.body.appendChild(dummy);
|
||||||
dummy.value = window.location.href;
|
dummy.value = window.location.href;
|
||||||
dummy.select();
|
dummy.select();
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
document.body.removeChild(dummy);
|
document.body.removeChild(dummy);
|
||||||
setTimeout(() => this.$refs.copyRequest.innerHTML = this.copyButton + '<span>Permalink</span>', 1000)
|
this.$refs.copyRequest.innerHTML = this.copiedButton;
|
||||||
|
this.$toast.success('Copied to clipboard', {
|
||||||
|
icon: 'done'
|
||||||
|
});
|
||||||
|
setTimeout(() => this.$refs.copyRequest.innerHTML = '<i class="material-icons">share</i>', 1000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
copyRequestCode() {
|
copyRequestCode() {
|
||||||
@@ -1199,7 +1230,36 @@
|
|||||||
this.$toast.info('Cleared', {
|
this.$toast.info('Cleared', {
|
||||||
icon: 'clear_all'
|
icon: 'clear_all'
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
saveRequest() {
|
||||||
|
this.editRequest = {
|
||||||
|
url: this.url,
|
||||||
|
path: this.path,
|
||||||
|
method: this.method,
|
||||||
|
auth: this.auth,
|
||||||
|
httpUser: this.httpUser,
|
||||||
|
httpPassword: this.httpPassword,
|
||||||
|
passwordFieldType: this.passwordFieldType,
|
||||||
|
bearerToken: this.bearerToken,
|
||||||
|
headers: this.headers,
|
||||||
|
params: this.params,
|
||||||
|
bodyParams: this.bodyParams,
|
||||||
|
rawParams: this.rawParams,
|
||||||
|
rawInput: this.rawInput,
|
||||||
|
contentType: this.contentType,
|
||||||
|
requestType: this.requestType,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.selectedRequest.url) {
|
||||||
|
this.editRequest = Object.assign({}, this.selectedRequest, this.editRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showRequestModal = true;
|
||||||
|
},
|
||||||
|
hideRequestModal() {
|
||||||
|
this.showRequestModal = false;
|
||||||
|
this.editRequest = {};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.observeRequestButton();
|
this.observeRequestButton();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<pw-section class="cyan" label="Theme">
|
<pw-section class="cyan" icon="color_lens" label="Theme">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<h3 class="title">Background</h3>
|
<h3 class="title">Background</h3>
|
||||||
@@ -25,17 +25,17 @@
|
|||||||
<li>
|
<li>
|
||||||
<h3 class="title">Frames</h3>
|
<h3 class="title">Frames</h3>
|
||||||
<span>
|
<span>
|
||||||
<pw-toggle :on="!settings.DISABLE_FRAME_COLORS" @change="toggleSetting('DISABLE_FRAME_COLORS')">
|
<pw-toggle :on="!settings.DISABLE_FRAME_COLORS" @change="applySetting('DISABLE_FRAME_COLORS', $event)">
|
||||||
Multi-color {{ settings.DISABLE_FRAME_COLORS ? "Disabled" : "Enabled" }}
|
Multi-color {{ settings.DISABLE_FRAME_COLORS ? "Disabled" : "Enabled" }}
|
||||||
</pw-toggle>
|
</pw-toggle>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
<pw-section class="blue" label="Proxy">
|
<pw-section class="blue" icon="public" label="Proxy">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<pw-toggle :on="settings.PROXY_ENABLED" @change="toggleSetting('PROXY_ENABLED')">
|
<pw-toggle :on="settings.PROXY_ENABLED" @change="applySetting('PROXY_ENABLED', $event)">
|
||||||
Proxy {{ settings.PROXY_ENABLED ? "enabled" : "disabled" }}
|
Proxy {{ settings.PROXY_ENABLED ? "enabled" : "disabled" }}
|
||||||
</pw-toggle>
|
</pw-toggle>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<pw-section class="blue" label="Request" ref="request">
|
<pw-section class="blue" icon="cloud_upload" label="Request" ref="request">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="url">URL</label>
|
<label for="url">URL</label>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</pw-section>
|
</pw-section>
|
||||||
<pw-section class="purple" label="Communication" id="response" ref="response">
|
<pw-section class="purple" icon="cloud_download" label="Communication" id="response" ref="response">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="log">Log</label>
|
<label for="log">Log</label>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
export const SETTINGS_KEYS = [
|
export const SETTINGS_KEYS = [
|
||||||
/**
|
/**
|
||||||
* The CSS class that should be applied to the root element.
|
* The CSS class that should be applied to the root element.
|
||||||
@@ -42,7 +44,14 @@ export const SETTINGS_KEYS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const state = () => ({
|
export const state = () => ({
|
||||||
settings: {}
|
settings : {},
|
||||||
|
collections : [{
|
||||||
|
name : 'My First Collection',
|
||||||
|
folders : [],
|
||||||
|
requests : [],
|
||||||
|
}],
|
||||||
|
selectedRequest : {},
|
||||||
|
editingRequest : {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
@@ -59,6 +68,174 @@ export const mutations = {
|
|||||||
if (!SETTINGS_KEYS.includes(key)) throw new Error("The settings structure does not include the key " + key);
|
if (!SETTINGS_KEYS.includes(key)) throw new Error("The settings structure does not include the key " + key);
|
||||||
|
|
||||||
state.settings[key] = value;
|
state.settings[key] = value;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
replaceCollections (state, collections) {
|
||||||
|
state.collections = collections;
|
||||||
|
},
|
||||||
|
|
||||||
|
importCollections (state, collections) {
|
||||||
|
state.collections = [...state.collections, ...collections];
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
for (let collection of collections) {
|
||||||
|
collection.collectionIndex = index;
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addNewCollection (state, collection) {
|
||||||
|
state.collections.push({
|
||||||
|
name : '',
|
||||||
|
folders : [],
|
||||||
|
requests : [],
|
||||||
|
...collection,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
removeCollection (state, payload) {
|
||||||
|
const { collectionIndex } = payload;
|
||||||
|
state.collections.splice(collectionIndex, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
editCollection (state, payload) {
|
||||||
|
const { collection, collectionIndex } = payload
|
||||||
|
state.collections[collectionIndex] = collection
|
||||||
|
},
|
||||||
|
|
||||||
|
addNewFolder (state, payload) {
|
||||||
|
const { collectionIndex, folder } = payload;
|
||||||
|
state.collections[collectionIndex].folders.push({
|
||||||
|
name : '',
|
||||||
|
requests : [],
|
||||||
|
...folder,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
editFolder (state, payload) {
|
||||||
|
const { collectionIndex, folder, folderIndex } = payload;
|
||||||
|
Vue.set(state.collections[collectionIndex].folders, folderIndex, folder)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFolder (state, payload) {
|
||||||
|
const { collectionIndex, folderIndex } = payload;
|
||||||
|
state.collections[collectionIndex].folders.splice(folderIndex, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
addRequest (state, payload) {
|
||||||
|
const { request } = payload;
|
||||||
|
|
||||||
|
// Request that is directly attached to collection
|
||||||
|
if (request.folder === -1) {
|
||||||
|
state.collections[request.collection].requests.push(request);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.collections[request.collection].folders[request.folder].requests.push(request);
|
||||||
|
},
|
||||||
|
|
||||||
|
editRequest (state, payload) {
|
||||||
|
const {
|
||||||
|
requestOld,
|
||||||
|
requestOldCollectionIndex,
|
||||||
|
requestOldFolderIndex,
|
||||||
|
requestOldIndex,
|
||||||
|
requestNew,
|
||||||
|
requestNewCollectionIndex,
|
||||||
|
requestNewFolderIndex,
|
||||||
|
} = payload
|
||||||
|
|
||||||
|
const changedCollection = requestOldCollectionIndex !== requestNewCollectionIndex
|
||||||
|
const changedFolder = requestOldFolderIndex !== requestNewFolderIndex
|
||||||
|
const changedPlace = changedCollection || changedFolder
|
||||||
|
|
||||||
|
// set new request
|
||||||
|
if (requestNewFolderIndex !== undefined)
|
||||||
|
Vue.set(state.collections[requestNewCollectionIndex].folders[requestNewFolderIndex].requests, requestOldIndex, requestNew)
|
||||||
|
else
|
||||||
|
Vue.set(state.collections[requestNewCollectionIndex].requests, requestOldIndex, requestNew)
|
||||||
|
|
||||||
|
// remove old request
|
||||||
|
if (changedPlace) {
|
||||||
|
if (requestOldFolderIndex !== undefined)
|
||||||
|
state.collections[requestOldCollectionIndex].folders[requestOldFolderIndex].requests.splice(requestOldIndex, 1)
|
||||||
|
else
|
||||||
|
state.collections[requestOldCollectionIndex].requests.splice(requestOldIndex, 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
saveRequestAs (state, payload) {
|
||||||
|
const {
|
||||||
|
request,
|
||||||
|
collectionIndex,
|
||||||
|
folderIndex,
|
||||||
|
requestIndex,
|
||||||
|
} = payload
|
||||||
|
|
||||||
|
const specifiedCollection = collectionIndex !== undefined
|
||||||
|
const specifiedFolder = folderIndex !== undefined
|
||||||
|
const specifiedRequest = requestIndex !== undefined
|
||||||
|
|
||||||
|
if (specifiedCollection && specifiedFolder && specifiedRequest)
|
||||||
|
Vue.set(state.collections[collectionIndex].folders[folderIndex].requests, requestIndex, request)
|
||||||
|
else if (specifiedCollection && specifiedFolder && !specifiedRequest) {
|
||||||
|
const requests = state.collections[collectionIndex].folders[folderIndex].requests
|
||||||
|
const lastRequestIndex = requests.length - 1;
|
||||||
|
Vue.set(requests, lastRequestIndex + 1, request)
|
||||||
|
}
|
||||||
|
else if (specifiedCollection && !specifiedFolder && specifiedRequest) {
|
||||||
|
const requests = state.collections[collectionIndex].requests
|
||||||
|
Vue.set(requests,requestIndex, request)
|
||||||
|
}
|
||||||
|
else if (specifiedCollection && !specifiedFolder && !specifiedRequest) {
|
||||||
|
const requests = state.collections[collectionIndex].requests
|
||||||
|
const lastRequestIndex = requests.length - 1;
|
||||||
|
Vue.set(requests, lastRequestIndex + 1, request)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
saveRequest (state, payload) {
|
||||||
|
const { request } = payload;
|
||||||
|
|
||||||
|
// Remove the old request from collection
|
||||||
|
if (request.hasOwnProperty('oldCollection') && request.oldCollection > -1) {
|
||||||
|
const folder = request.hasOwnProperty('oldFolder') && request.oldFolder >= -1 ? request.oldFolder : request.folder;
|
||||||
|
if (folder > -1) {
|
||||||
|
state.collections[request.oldCollection].folders[folder].requests.splice(request.requestIndex, 1)
|
||||||
|
} else {
|
||||||
|
state.collections[request.oldCollection].requests.splice(request.requestIndex, 1)
|
||||||
|
}
|
||||||
|
} else if (request.hasOwnProperty('oldFolder') && request.oldFolder !== -1) {
|
||||||
|
state.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(state.collections[request.collection].requests, request.requestIndex, request)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.set(state.collections[request.collection].folders[request.folder].requests, request.requestIndex, request)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRequest (state, payload) {
|
||||||
|
const { collectionIndex, folderIndex, requestIndex } = payload;
|
||||||
|
|
||||||
|
// Request that is directly attached to collection
|
||||||
|
if (folderIndex === -1) {
|
||||||
|
state.collections[collectionIndex].requests.splice(requestIndex, 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.collections[collectionIndex].folders[folderIndex].requests.splice(requestIndex, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
selectRequest (state, payload) {
|
||||||
|
state.selectedRequest = Object.assign({}, payload.request);
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user