mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
add new tag in transaction edit page / dialog
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<f7-sheet swipe-to-close swipe-handler=".swipe-handler"
|
<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">
|
@sheet:open="onSheetOpen" @sheet:closed="onSheetClosed">
|
||||||
<f7-toolbar>
|
<f7-toolbar>
|
||||||
<div class="swipe-handler"></div>
|
<div class="swipe-handler"></div>
|
||||||
@@ -12,42 +12,78 @@
|
|||||||
</div>
|
</div>
|
||||||
</f7-toolbar>
|
</f7-toolbar>
|
||||||
<f7-page-content>
|
<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-item :title="$t('No available tag')"></f7-list-item>
|
||||||
</f7-list>
|
</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
|
<f7-list-item checkbox
|
||||||
:class="isChecked(item.id) ? 'list-item-selected' : ''"
|
:class="isChecked(tag.id) ? 'list-item-selected' : ''"
|
||||||
:value="item.id"
|
:value="tag.id"
|
||||||
:checked="isChecked(item.id)"
|
:checked="isChecked(tag.id)"
|
||||||
:key="item.id"
|
:key="tag.id"
|
||||||
v-for="item in items"
|
v-for="tag in allTags"
|
||||||
v-show="!item.hidden || isChecked(item.id)"
|
v-show="!tag.hidden || isChecked(tag.id)"
|
||||||
@change="changeItemSelection">
|
@change="changeTagSelection">
|
||||||
<template #title>
|
<template #title>
|
||||||
<f7-block class="no-padding no-margin">
|
<f7-block class="no-padding no-margin">
|
||||||
<div class="display-flex">
|
<div class="display-flex">
|
||||||
<f7-icon f7="number"></f7-icon>
|
<f7-icon f7="number"></f7-icon>
|
||||||
<div class="tag-selection-list-item list-item-valign-middle padding-left-half">
|
<div class="tag-selection-list-item list-item-valign-middle padding-left-half">
|
||||||
{{ item.name }}
|
{{ tag.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</f7-block>
|
</f7-block>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</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-list>
|
||||||
</f7-page-content>
|
</f7-page-content>
|
||||||
</f7-sheet>
|
</f7-sheet>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapStores } from 'pinia';
|
||||||
|
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
||||||
|
|
||||||
import { copyArrayTo } from '@/lib/common.js';
|
import { copyArrayTo } from '@/lib/common.js';
|
||||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
'modelValue',
|
'modelValue',
|
||||||
'items',
|
'allowAddNewTag',
|
||||||
'show'
|
'show'
|
||||||
],
|
],
|
||||||
emits: [
|
emits: [
|
||||||
@@ -56,18 +92,22 @@ export default {
|
|||||||
],
|
],
|
||||||
data() {
|
data() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
const transactionTagsStore = useTransactionTagsStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedItemIds: copyArrayTo(self.modelValue, [])
|
heightClass: self.getHeightClass(transactionTagsStore.allTransactionTags),
|
||||||
|
selectedItemIds: copyArrayTo(self.modelValue, []),
|
||||||
|
newTag: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hugeListItemRows() {
|
...mapStores(useTransactionTagsStore),
|
||||||
return this.items.length > 10;
|
allTags() {
|
||||||
|
return this.transactionTagsStore.allTransactionTags;
|
||||||
},
|
},
|
||||||
noAvailableTag() {
|
noAvailableTag() {
|
||||||
for (let i = 0; i < this.items.length; i++) {
|
for (let i = 0; i < this.allTags.length; i++) {
|
||||||
if (!this.items[i].hidden) {
|
if (!this.allTags[i].hidden) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,12 +122,14 @@ export default {
|
|||||||
},
|
},
|
||||||
onSheetOpen(event) {
|
onSheetOpen(event) {
|
||||||
this.selectedItemIds = copyArrayTo(this.modelValue, []);
|
this.selectedItemIds = copyArrayTo(this.modelValue, []);
|
||||||
|
this.newTag = null;
|
||||||
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
|
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
|
||||||
},
|
},
|
||||||
onSheetClosed() {
|
onSheetClosed() {
|
||||||
this.$emit('update:show', false);
|
this.$emit('update:show', false);
|
||||||
|
this.heightClass = this.getHeightClass(this.allTags);
|
||||||
},
|
},
|
||||||
changeItemSelection(e) {
|
changeTagSelection(e) {
|
||||||
const tagId = e.target.value;
|
const tagId = e.target.value;
|
||||||
|
|
||||||
if (e.target.checked) {
|
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) {
|
isChecked(itemId) {
|
||||||
for (let i = 0; i < this.selectedItemIds.length; i++) {
|
for (let i = 0; i < this.selectedItemIds.length; i++) {
|
||||||
if (this.selectedItemIds[i] === itemId) {
|
if (this.selectedItemIds[i] === itemId) {
|
||||||
@@ -115,6 +187,15 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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>
|
<style>
|
||||||
@media (min-height: 630px) {
|
@media (min-height: 630px) {
|
||||||
|
.tag-selection-large-sheet {
|
||||||
|
height: 310px;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-selection-huge-sheet {
|
.tag-selection-huge-sheet {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag-selection-list.list .item-media + .item-inner {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-selection-list-item {
|
.tag-selection-list-item {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
"everyMultiDaysOfWeek": "Every {days}",
|
"everyMultiDaysOfWeek": "Every {days}",
|
||||||
"everyMultiDaysOfMonth": "Every {days} of month",
|
"everyMultiDaysOfMonth": "Every {days} of month",
|
||||||
"youHaveAccounts": "You have recorded {count} accounts",
|
"youHaveAccounts": "You have recorded {count} accounts",
|
||||||
|
"addNewTag": "Add new tag \"{tag}\"",
|
||||||
"clickToSelectedFile": "Click to select import file ({extensions})",
|
"clickToSelectedFile": "Click to select import file ({extensions})",
|
||||||
"selectedCount": "Selected {count} of {totalCount}",
|
"selectedCount": "Selected {count} of {totalCount}",
|
||||||
"youHaveUpdatedTransactions": "You have updated {count} transactions",
|
"youHaveUpdatedTransactions": "You have updated {count} transactions",
|
||||||
@@ -1809,6 +1810,7 @@
|
|||||||
"Unable to retrieve tag list": "Unable to retrieve tag list",
|
"Unable to retrieve tag list": "Unable to retrieve tag list",
|
||||||
"Tag list is up to date": "Tag list is up to date",
|
"Tag list is up to date": "Tag list is up to date",
|
||||||
"Tag list has been updated": "Tag list has been updated",
|
"Tag list has been updated": "Tag list has been updated",
|
||||||
|
"Add new tag": "Add new tag",
|
||||||
"Unable to add tag": "Unable to add tag",
|
"Unable to add tag": "Unable to add tag",
|
||||||
"Unable to save tag": "Unable to save tag",
|
"Unable to save tag": "Unable to save tag",
|
||||||
"Unable to move tag": "Unable to move tag",
|
"Unable to move tag": "Unable to move tag",
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
"everyMultiDaysOfWeek": "Mỗi {days}",
|
"everyMultiDaysOfWeek": "Mỗi {days}",
|
||||||
"everyMultiDaysOfMonth": "Mỗi ngày {days} trong tháng",
|
"everyMultiDaysOfMonth": "Mỗi ngày {days} trong tháng",
|
||||||
"youHaveAccounts": "Bạn đã ghi nhận {count} tài khoản",
|
"youHaveAccounts": "Bạn đã ghi nhận {count} tài khoản",
|
||||||
|
"addNewTag": "Add new tag \"{tag}\"",
|
||||||
"clickToSelectedFile": "Nhấp để chọn tệp nhập khẩu ({extensions})",
|
"clickToSelectedFile": "Nhấp để chọn tệp nhập khẩu ({extensions})",
|
||||||
"selectedCount": "Đã chọn {count} trên {totalCount}",
|
"selectedCount": "Đã chọn {count} trên {totalCount}",
|
||||||
"youHaveUpdatedTransactions": "Bạn đã cập nhật {count} giao dịch",
|
"youHaveUpdatedTransactions": "Bạn đã cập nhật {count} giao dịch",
|
||||||
@@ -1809,6 +1810,7 @@
|
|||||||
"Unable to retrieve tag list": "Không thể truy xuất danh sách thẻ",
|
"Unable to retrieve tag list": "Không thể truy xuất danh sách thẻ",
|
||||||
"Tag list is up to date": "Danh sách thẻ đã được cập nhật",
|
"Tag list is up to date": "Danh sách thẻ đã được cập nhật",
|
||||||
"Tag list has been updated": "Danh sách thẻ đã được cập nhật",
|
"Tag list has been updated": "Danh sách thẻ đã được cập nhật",
|
||||||
|
"Add new tag": "Add new tag",
|
||||||
"Unable to add tag": "Không thể thêm thẻ",
|
"Unable to add tag": "Không thể thêm thẻ",
|
||||||
"Unable to save tag": "Không thể lưu thẻ",
|
"Unable to save tag": "Không thể lưu thẻ",
|
||||||
"Unable to move tag": "Không thể di chuyển thẻ",
|
"Unable to move tag": "Không thể di chuyển thẻ",
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
"everyMultiDaysOfWeek": "每{days}",
|
"everyMultiDaysOfWeek": "每{days}",
|
||||||
"everyMultiDaysOfMonth": "每月{days}",
|
"everyMultiDaysOfMonth": "每月{days}",
|
||||||
"youHaveAccounts": "您已经记录了 {count} 个账户",
|
"youHaveAccounts": "您已经记录了 {count} 个账户",
|
||||||
|
"addNewTag": "添加新标签 \"{tag}\"",
|
||||||
"clickToSelectedFile": "点击选择导入文件 ({extensions})",
|
"clickToSelectedFile": "点击选择导入文件 ({extensions})",
|
||||||
"selectedCount": "已选择 {count} / {totalCount}",
|
"selectedCount": "已选择 {count} / {totalCount}",
|
||||||
"youHaveUpdatedTransactions": "您已经更新 {count} 个交易",
|
"youHaveUpdatedTransactions": "您已经更新 {count} 个交易",
|
||||||
@@ -1809,6 +1810,7 @@
|
|||||||
"Unable to retrieve tag list": "无法获取标签列表",
|
"Unable to retrieve tag list": "无法获取标签列表",
|
||||||
"Tag list is up to date": "标签列表已是最新",
|
"Tag list is up to date": "标签列表已是最新",
|
||||||
"Tag list has been updated": "标签列表已更新",
|
"Tag list has been updated": "标签列表已更新",
|
||||||
|
"Add new tag": "添加新标签",
|
||||||
"Unable to add tag": "无法添加标签",
|
"Unable to add tag": "无法添加标签",
|
||||||
"Unable to save tag": "无法保存标签",
|
"Unable to save tag": "无法保存标签",
|
||||||
"Unable to move tag": "无法移动标签",
|
"Unable to move tag": "无法移动标签",
|
||||||
|
|||||||
@@ -266,8 +266,8 @@
|
|||||||
:label="$t('Tags')"
|
:label="$t('Tags')"
|
||||||
:placeholder="$t('None')"
|
:placeholder="$t('None')"
|
||||||
:items="allTags"
|
:items="allTags"
|
||||||
:no-data-text="$t('No available tag')"
|
|
||||||
v-model="transaction.tagIds"
|
v-model="transaction.tagIds"
|
||||||
|
v-model:search="tagSearchContent"
|
||||||
>
|
>
|
||||||
<template #chip="{ props, item }">
|
<template #chip="{ props, item }">
|
||||||
<v-chip :prepend-icon="icons.tag" :text="item.title" v-bind="props"/>
|
<v-chip :prepend-icon="icons.tag" :text="item.title" v-bind="props"/>
|
||||||
@@ -285,6 +285,13 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #no-data>
|
||||||
|
<v-list class="py-0">
|
||||||
|
<v-list-item v-if="tagSearchContent" @click="saveNewTag(tagSearchContent)">{{ $t('format.misc.addNewTag', { tag: tagSearchContent }) }}</v-list-item>
|
||||||
|
<v-list-item v-else-if="!tagSearchContent">{{ $t('No available tag') }}</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</template>
|
||||||
</v-autocomplete>
|
</v-autocomplete>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" md="12">
|
<v-col cols="12" md="12">
|
||||||
@@ -458,6 +465,7 @@ export default {
|
|||||||
transaction: newTransaction,
|
transaction: newTransaction,
|
||||||
geoLocationStatus: null,
|
geoLocationStatus: null,
|
||||||
geoMenuState: false,
|
geoMenuState: false,
|
||||||
|
tagSearchContent: '',
|
||||||
submitting: false,
|
submitting: false,
|
||||||
uploadingPicture: false,
|
uploadingPicture: false,
|
||||||
removingPictureId: '',
|
removingPictureId: '',
|
||||||
@@ -1166,6 +1174,29 @@ export default {
|
|||||||
this.geoLocationStatus = null;
|
this.geoLocationStatus = null;
|
||||||
this.transaction.geoLocation = null;
|
this.transaction.geoLocation = null;
|
||||||
},
|
},
|
||||||
|
saveNewTag(tagName) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
self.submitting = true;
|
||||||
|
|
||||||
|
self.transactionTagsStore.saveTag({
|
||||||
|
tag: {
|
||||||
|
name: tagName
|
||||||
|
}
|
||||||
|
}).then(tag => {
|
||||||
|
self.submitting = false;
|
||||||
|
|
||||||
|
if (tag && tag.id) {
|
||||||
|
self.transaction.tagIds.push(tag.id);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
self.submitting = false;
|
||||||
|
|
||||||
|
if (!error.processed) {
|
||||||
|
self.$refs.snackbar.showError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
swapTransactionData(swapAccount, swapAmount) {
|
swapTransactionData(swapAccount, swapAmount) {
|
||||||
if (swapAccount) {
|
if (swapAccount) {
|
||||||
const oldSourceAccountId = this.transaction.sourceAccountId;
|
const oldSourceAccountId = this.transaction.sourceAccountId;
|
||||||
|
|||||||
@@ -313,7 +313,7 @@
|
|||||||
:header="$t('Tags')"
|
:header="$t('Tags')"
|
||||||
@click="showTransactionTagSheet = true"
|
@click="showTransactionTagSheet = true"
|
||||||
>
|
>
|
||||||
<transaction-tag-selection-sheet :items="allTags"
|
<transaction-tag-selection-sheet :allow-add-new-tag="true"
|
||||||
v-model:show="showTransactionTagSheet"
|
v-model:show="showTransactionTagSheet"
|
||||||
v-model="transaction.tagIds">
|
v-model="transaction.tagIds">
|
||||||
</transaction-tag-selection-sheet>
|
</transaction-tag-selection-sheet>
|
||||||
|
|||||||
Reference in New Issue
Block a user