add new tag in transaction edit page / dialog

This commit is contained in:
MaysWind
2024-12-08 21:04:42 +08:00
parent db94282207
commit 5a9141e10c
6 changed files with 146 additions and 20 deletions
@@ -1,6 +1,6 @@
<template>
<f7-sheet swipe-to-close swipe-handler=".swipe-handler"
:opened="show" :class="{ 'tag-selection-huge-sheet': hugeListItemRows }"
:class="heightClass" :opened="show"
@sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
<f7-toolbar>
<div class="swipe-handler"></div>
@@ -12,42 +12,78 @@
</div>
</f7-toolbar>
<f7-page-content>
<f7-list class="no-margin-top no-margin-bottom" v-if="!items || !items.length || noAvailableTag">
<f7-list class="no-margin-top no-margin-bottom" v-if="!allTags || !allTags.length || noAvailableTag">
<f7-list-item :title="$t('No available tag')"></f7-list-item>
</f7-list>
<f7-list dividers class="no-margin-top no-margin-bottom" v-else-if="items && items.length && !noAvailableTag">
<f7-list dividers class="no-margin-top no-margin-bottom tag-selection-list" v-else-if="allTags && allTags.length && !noAvailableTag">
<f7-list-item checkbox
:class="isChecked(item.id) ? 'list-item-selected' : ''"
:value="item.id"
:checked="isChecked(item.id)"
:key="item.id"
v-for="item in items"
v-show="!item.hidden || isChecked(item.id)"
@change="changeItemSelection">
:class="isChecked(tag.id) ? 'list-item-selected' : ''"
:value="tag.id"
:checked="isChecked(tag.id)"
:key="tag.id"
v-for="tag in allTags"
v-show="!tag.hidden || isChecked(tag.id)"
@change="changeTagSelection">
<template #title>
<f7-block class="no-padding no-margin">
<div class="display-flex">
<f7-icon f7="number"></f7-icon>
<div class="tag-selection-list-item list-item-valign-middle padding-left-half">
{{ item.name }}
{{ tag.name }}
</div>
</div>
</f7-block>
</template>
</f7-list-item>
<f7-list-item :title="$t('Add new tag')"
v-if="allowAddNewTag && !newTag"
@click="addNewTag()">
</f7-list-item>
<f7-list-item checkbox indeterminate disabled v-if="allowAddNewTag && newTag">
<template #media>
<f7-icon f7="number"></f7-icon>
</template>
<template #title>
<div class="display-flex">
<f7-input class="list-title-input padding-left-half"
type="text"
:placeholder="$t('Tag Title')"
v-model:value="newTag.name"
@keyup.enter="saveNewTag()">
</f7-input>
</div>
</template>
<template #after>
<f7-button class="no-padding"
raised fill
icon-f7="checkmark_alt"
color="blue"
@click="saveNewTag()">
</f7-button>
<f7-button class="no-padding margin-left-half"
raised fill
icon-f7="xmark"
color="gray"
@click="cancelSaveNewTag()">
</f7-button>
</template>
</f7-list-item>
</f7-list>
</f7-page-content>
</f7-sheet>
</template>
<script>
import { mapStores } from 'pinia';
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
import { copyArrayTo } from '@/lib/common.js';
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
export default {
props: [
'modelValue',
'items',
'allowAddNewTag',
'show'
],
emits: [
@@ -56,18 +92,22 @@ export default {
],
data() {
const self = this;
const transactionTagsStore = useTransactionTagsStore();
return {
selectedItemIds: copyArrayTo(self.modelValue, [])
heightClass: self.getHeightClass(transactionTagsStore.allTransactionTags),
selectedItemIds: copyArrayTo(self.modelValue, []),
newTag: null
}
},
computed: {
hugeListItemRows() {
return this.items.length > 10;
...mapStores(useTransactionTagsStore),
allTags() {
return this.transactionTagsStore.allTransactionTags;
},
noAvailableTag() {
for (let i = 0; i < this.items.length; i++) {
if (!this.items[i].hidden) {
for (let i = 0; i < this.allTags.length; i++) {
if (!this.allTags[i].hidden) {
return false;
}
}
@@ -82,12 +122,14 @@ export default {
},
onSheetOpen(event) {
this.selectedItemIds = copyArrayTo(this.modelValue, []);
this.newTag = null;
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
},
onSheetClosed() {
this.$emit('update:show', false);
this.heightClass = this.getHeightClass(this.allTags);
},
changeItemSelection(e) {
changeTagSelection(e) {
const tagId = e.target.value;
if (e.target.checked) {
@@ -107,6 +149,36 @@ export default {
}
}
},
addNewTag() {
this.newTag = {
name: ''
};
},
saveNewTag() {
const self = this;
self.$showLoading();
self.transactionTagsStore.saveTag({
tag: self.newTag
}).then(tag => {
self.$hideLoading();
self.newTag = null;
if (tag && tag.id) {
self.selectedItemIds.push(tag.id);
}
}).catch(error => {
self.$hideLoading();
if (!error.processed) {
self.$toast(error.message || error);
}
});
},
cancelSaveNewTag() {
this.newTag = null;
},
isChecked(itemId) {
for (let i = 0; i < this.selectedItemIds.length; i++) {
if (this.selectedItemIds[i] === itemId) {
@@ -115,6 +187,15 @@ export default {
}
return false;
},
getHeightClass(allTags) {
if (allTags && allTags.length > 10) {
return 'tag-selection-huge-sheet';
} else if (allTags && allTags.length > 6) {
return 'tag-selection-large-sheet';
} else {
return '';
}
}
}
}
@@ -122,11 +203,19 @@ export default {
<style>
@media (min-height: 630px) {
.tag-selection-large-sheet {
height: 310px;
}
.tag-selection-huge-sheet {
height: 400px;
}
}
.tag-selection-list.list .item-media + .item-inner {
margin-left: 0;
}
.tag-selection-list-item {
overflow: hidden;
text-overflow: ellipsis;