Implements Add new Item functionality

This commit is contained in:
Alicia Sykes 2021-10-25 23:22:41 +01:00
parent 31e172befb
commit 06d08a8fff
No known key found for this signature in database
GPG Key ID: 3D0EA672EE9945ED
5 changed files with 59 additions and 6 deletions

View File

@ -94,6 +94,8 @@ export default {
}, },
props: { props: {
itemId: String, itemId: String,
isNew: Boolean,
parentSectionTitle: String, // If adding new item, which section to add it under
}, },
computed: {}, computed: {},
components: { components: {
@ -105,7 +107,9 @@ export default {
BinIcon, BinIcon,
}, },
mounted() { mounted() {
this.item = this.getItemFromState(this.itemId); if (!this.isNew) { // Get existing item data
this.item = this.getItemFromState(this.itemId);
}
this.formData = this.makeInitialFormData(); this.formData = this.makeInitialFormData();
this.$modal.show(modalNames.EDIT_ITEM); this.$modal.show(modalNames.EDIT_ITEM);
}, },
@ -187,8 +191,13 @@ export default {
this.formData.forEach((row) => { structured[row.name] = row.value; }); this.formData.forEach((row) => { structured[row.name] = row.value; });
// Some attributes need a little extra formatting // Some attributes need a little extra formatting
const newItem = this.formatBeforeSave(structured); const newItem = this.formatBeforeSave(structured);
// Update the data store, with new item data if (this.isNew) { // Insert new item into data store
this.$store.commit(StoreKeys.UPDATE_ITEM, { newItem, itemId: this.itemId }); newItem.id = `temp_${newItem.title}`;
const payload = { newItem, targetSection: this.parentSectionTitle };
this.$store.commit(StoreKeys.INSERT_ITEM, payload);
} else { // Update existing item from form data, in the store
this.$store.commit(StoreKeys.UPDATE_ITEM, { newItem, itemId: this.itemId });
}
// If we're not already in edit mode, enable it now // If we're not already in edit mode, enable it now
this.$store.commit(StoreKeys.SET_EDIT_MODE, true); this.$store.commit(StoreKeys.SET_EDIT_MODE, true);
// Close edit menu // Close edit menu

View File

@ -5,7 +5,7 @@
@contextmenu.prevent @contextmenu.prevent
:href="hyperLinkHref" :href="hyperLinkHref"
:target="anchorTarget" :target="anchorTarget"
:class="`item ${!icon? 'short': ''} size-${itemSize}`" :class="`item ${!icon? 'short': ''} size-${itemSize} ${isAddNew ? 'add-new' : ''}`"
v-tooltip="getTooltipOptions()" v-tooltip="getTooltipOptions()"
rel="noopener noreferrer" tabindex="0" rel="noopener noreferrer" tabindex="0"
:id="`link-${id}`" :id="`link-${id}`"
@ -44,7 +44,9 @@
@openDeleteItem="openDeleteItem" @openDeleteItem="openDeleteItem"
/> />
<MoveItemTo v-if="isEditMode" :itemId="id" /> <MoveItemTo v-if="isEditMode" :itemId="id" />
<EditItem v-if="editMenuOpen" :itemId="id" @closeEditMenu="closeEditMenu" /> <EditItem v-if="editMenuOpen" :itemId="id"
@closeEditMenu="closeEditMenu"
:isNew="isAddNew" :parentSectionTitle="parentSectionTitle" />
</div> </div>
</template> </template>
@ -90,6 +92,8 @@ export default {
statusCheckUrl: String, statusCheckUrl: String,
statusCheckInterval: Number, statusCheckInterval: Number,
statusCheckAllowInsecure: Boolean, statusCheckAllowInsecure: Boolean,
parentSectionTitle: String,
isAddNew: Boolean,
}, },
components: { components: {
Icon, Icon,
@ -360,6 +364,9 @@ export default {
&.short:not(.size-large) { &.short:not(.size-large) {
height: 2rem; height: 2rem;
} }
&.add-new {
border-style: dashed !important;
}
} }
/* Text in tile */ /* Text in tile */

View File

@ -11,13 +11,15 @@
@openEditSection="openEditSection" @openEditSection="openEditSection"
@openContextMenu="openContextMenu" @openContextMenu="openContextMenu"
> >
<!-- If no items, show message -->
<div v-if="!items || items.length < 1" class="no-items"> <div v-if="!items || items.length < 1" class="no-items">
No Items to Show Yet No Items to Show Yet
</div> </div>
<!-- Item Container -->
<div v-else <div v-else
:class="`there-are-items ${isGridLayout? 'item-group-grid': ''} inner-size-${itemSize}`" :class="`there-are-items ${isGridLayout? 'item-group-grid': ''} inner-size-${itemSize}`"
:style="gridStyle" :id="`section-${groupId}`" :style="gridStyle" :id="`section-${groupId}`"
> > <!-- Show for each item -->
<Item <Item
v-for="(item) in sortedItems" v-for="(item) in sortedItems"
:id="item.id" :id="item.id"
@ -34,24 +36,40 @@
:itemSize="newItemSize" :itemSize="newItemSize"
:hotkey="item.hotkey" :hotkey="item.hotkey"
:provider="item.provider" :provider="item.provider"
:parentSectionTitle="title"
:enableStatusCheck="shouldEnableStatusCheck(item.statusCheck)" :enableStatusCheck="shouldEnableStatusCheck(item.statusCheck)"
:statusCheckInterval="getStatusCheckInterval()" :statusCheckInterval="getStatusCheckInterval()"
:statusCheckAllowInsecure="item.statusCheckAllowInsecure" :statusCheckAllowInsecure="item.statusCheckAllowInsecure"
@itemClicked="$emit('itemClicked')" @itemClicked="$emit('itemClicked')"
@triggerModal="triggerModal" @triggerModal="triggerModal"
/> />
<!-- When in edit mode, show additional item, for Add New item -->
<Item v-if="isEditMode"
:isAddNew="true"
:parentSectionTitle="title"
icon=":heavy_plus_sign:"
id="add-new"
title="Add New Item"
description="Click to add new item"
key="add-new"
class="add-new-item"
:itemSize="newItemSize"
/>
<div ref="modalContainer"></div> <div ref="modalContainer"></div>
</div> </div>
<!-- Modal for opening in modal view -->
<IframeModal <IframeModal
:ref="`iframeModal-${groupId}`" :ref="`iframeModal-${groupId}`"
:name="`iframeModal-${groupId}`" :name="`iframeModal-${groupId}`"
@closed="$emit('itemClicked')" @closed="$emit('itemClicked')"
/> />
<!-- Edit item menu -->
<EditSection <EditSection
v-if="editMenuOpen" v-if="editMenuOpen"
@closeEditSection="closeEditSection" @closeEditSection="closeEditSection"
:sectionIndex="index" :sectionIndex="index"
/> />
<!-- Right-click item options context menu -->
<ContextMenu <ContextMenu
:show="contextMenuOpen" :show="contextMenuOpen"
:posX="contextPos.posX" :posX="contextPos.posX"
@ -300,4 +318,10 @@ export default {
} }
} }
.add-new-item {
display: flex;
a {
border-style: dashed;
}
}
</style> </style>

View File

@ -22,6 +22,7 @@ const {
REMOVE_SECTION, REMOVE_SECTION,
COPY_ITEM, COPY_ITEM,
REMOVE_ITEM, REMOVE_ITEM,
INSERT_ITEM,
} = Keys; } = Keys;
const store = new Vuex.Store({ const store = new Vuex.Store({
@ -122,6 +123,17 @@ const store = new Vuex.Store({
} }
state.config = newConfig; state.config = newConfig;
}, },
[INSERT_ITEM](state, payload) {
const { newItem, targetSection } = payload;
const config = { ...state.config };
config.sections.forEach((section) => {
if (section.name === targetSection) {
section.items.push(newItem);
}
});
config.sections = applyItemId(config.sections);
state.config = config;
},
[COPY_ITEM](state, payload) { [COPY_ITEM](state, payload) {
const { item, toSection, appendTo } = payload; const { item, toSection, appendTo } = payload;
const config = { ...state.config }; const config = { ...state.config };

View File

@ -12,6 +12,7 @@ const KEY_NAMES = [
'REMOVE_SECTION', 'REMOVE_SECTION',
'COPY_ITEM', 'COPY_ITEM',
'REMOVE_ITEM', 'REMOVE_ITEM',
'INSERT_ITEM',
]; ];
// Convert array of key names into an object, and export // Convert array of key names into an object, and export