migrate transaction tag sheet to composition API and typescript
This commit is contained in:
@@ -5,17 +5,17 @@
|
||||
<f7-toolbar>
|
||||
<div class="swipe-handler"></div>
|
||||
<div class="left">
|
||||
<f7-link sheet-close :text="$t('Cancel')"></f7-link>
|
||||
<f7-link sheet-close :text="tt('Cancel')"></f7-link>
|
||||
</div>
|
||||
<div class="right">
|
||||
<f7-link :text="$t('Done')" v-if="allTags && allTags.length && !noAvailableTag" @click="save"></f7-link>
|
||||
<f7-link :text="tt('Done')" v-if="allTags && allTags.length && !noAvailableTag" @click="save"></f7-link>
|
||||
<f7-link :class="{'disabled': newTag}"
|
||||
:text="$t('Add')" v-if="!allTags || !allTags.length || noAvailableTag" @click="addNewTag"></f7-link>
|
||||
:text="tt('Add')" v-if="!allTags || !allTags.length || noAvailableTag" @click="addNewTag"></f7-link>
|
||||
</div>
|
||||
</f7-toolbar>
|
||||
<f7-page-content>
|
||||
<f7-list class="no-margin-top no-margin-bottom" v-if="(!allTags || !allTags.length || noAvailableTag) && !newTag">
|
||||
<f7-list-item :title="$t('No available tag')"></f7-list-item>
|
||||
<f7-list-item :title="tt('No available tag')"></f7-list-item>
|
||||
</f7-list>
|
||||
<f7-list dividers class="no-margin-top no-margin-bottom tag-selection-list" v-else-if="(allTags && allTags.length && !noAvailableTag) || newTag">
|
||||
<f7-list-item checkbox
|
||||
@@ -37,7 +37,7 @@
|
||||
</f7-block>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
<f7-list-item :title="$t('Add new tag')"
|
||||
<f7-list-item :title="tt('Add new tag')"
|
||||
v-if="allowAddNewTag && !newTag"
|
||||
@click="addNewTag()">
|
||||
</f7-list-item>
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="display-flex">
|
||||
<f7-input class="list-title-input padding-left-half"
|
||||
type="text"
|
||||
:placeholder="$t('Tag Title')"
|
||||
:placeholder="tt('Tag Title')"
|
||||
v-model:value="newTag.name"
|
||||
@keyup.enter="saveNewTag()">
|
||||
</f7-input>
|
||||
@@ -75,131 +75,126 @@
|
||||
</f7-sheet>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapStores } from 'pinia';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
import { useI18nUIComponents, showLoading, hideLoading } from '@/lib/ui/mobile.ts';
|
||||
|
||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
|
||||
import { copyArrayTo } from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
||||
import { type Framework7Dom, scrollToSelectedItem } from '@/lib/ui/mobile.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'modelValue',
|
||||
'allowAddNewTag',
|
||||
'show'
|
||||
],
|
||||
emits: [
|
||||
'update:modelValue',
|
||||
'update:show'
|
||||
],
|
||||
data() {
|
||||
const self = this;
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
const props = defineProps<{
|
||||
modelValue: string[];
|
||||
allowAddNewTag?: boolean;
|
||||
show: boolean;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: string[]): void;
|
||||
(e: 'update:show', value: boolean): void;
|
||||
}>();
|
||||
|
||||
return {
|
||||
heightClass: self.getHeightClass(transactionTagsStore.allTransactionTags),
|
||||
selectedItemIds: copyArrayTo(self.modelValue, []),
|
||||
newTag: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useTransactionTagsStore),
|
||||
allTags() {
|
||||
return this.transactionTagsStore.allTransactionTags;
|
||||
},
|
||||
noAvailableTag() {
|
||||
for (let i = 0; i < this.allTags.length; i++) {
|
||||
if (!this.allTags[i].hidden) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const { tt } = useI18n();
|
||||
const { showToast } = useI18nUIComponents();
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
this.$emit('update:modelValue', this.selectedItemIds);
|
||||
this.$emit('update:show', false);
|
||||
},
|
||||
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);
|
||||
},
|
||||
changeTagSelection(e) {
|
||||
const tagId = e.target.value;
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
|
||||
if (e.target.checked) {
|
||||
for (let i = 0; i < this.selectedItemIds.length; i++) {
|
||||
if (this.selectedItemIds[i] === tagId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const selectedItemIds = ref<string[]>(copyArrayTo(props.modelValue, []));
|
||||
const newTag = ref<TransactionTag | null>(null);
|
||||
|
||||
this.selectedItemIds.push(tagId);
|
||||
} else {
|
||||
for (let i = 0; i < this.selectedItemIds.length; i++) {
|
||||
if (this.selectedItemIds[i] === tagId) {
|
||||
this.selectedItemIds.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
addNewTag() {
|
||||
this.newTag = TransactionTag.createNewTag();
|
||||
},
|
||||
saveNewTag() {
|
||||
const self = this;
|
||||
const allTags = computed(() => transactionTagsStore.allTransactionTags);
|
||||
|
||||
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) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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 '';
|
||||
const noAvailableTag = computed<boolean>(() => {
|
||||
if (transactionTagsStore.allTransactionTags) {
|
||||
for (let i = 0; i < transactionTagsStore.allTransactionTags.length; i++) {
|
||||
if (!transactionTagsStore.allTransactionTags[i].hidden) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
const heightClass = computed<string>(() => {
|
||||
if (transactionTagsStore.allTransactionTags && transactionTagsStore.allTransactionTags.length > 10) {
|
||||
return 'tag-selection-huge-sheet';
|
||||
} else if (transactionTagsStore.allTransactionTags && transactionTagsStore.allTransactionTags.length > 6) {
|
||||
return 'tag-selection-large-sheet';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
function isChecked(itemId: string): boolean {
|
||||
return selectedItemIds.value.indexOf(itemId) >= 0;
|
||||
}
|
||||
|
||||
function changeTagSelection(e: Event): void {
|
||||
const target = e.target as HTMLInputElement;
|
||||
const tagId = target.value;
|
||||
const index = selectedItemIds.value.indexOf(tagId);
|
||||
|
||||
if (target.checked) {
|
||||
if (index < 0) {
|
||||
selectedItemIds.value.push(tagId);
|
||||
}
|
||||
} else {
|
||||
if (index >= 0) {
|
||||
selectedItemIds.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function save(): void {
|
||||
emit('update:modelValue', selectedItemIds.value);
|
||||
emit('update:show', false);
|
||||
}
|
||||
|
||||
function addNewTag(): void {
|
||||
newTag.value = TransactionTag.createNewTag();
|
||||
}
|
||||
|
||||
function saveNewTag(): void {
|
||||
if (!newTag.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
showLoading();
|
||||
|
||||
transactionTagsStore.saveTag({
|
||||
tag: newTag.value
|
||||
}).then(tag => {
|
||||
hideLoading();
|
||||
newTag.value = null;
|
||||
|
||||
if (tag && tag.id) {
|
||||
selectedItemIds.value.push(tag.id);
|
||||
}
|
||||
}).catch(error => {
|
||||
hideLoading();
|
||||
|
||||
if (!error.processed) {
|
||||
showToast(error.message || error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancelSaveNewTag(): void {
|
||||
newTag.value = null;
|
||||
}
|
||||
|
||||
function onSheetOpen(event: { $el: Framework7Dom }): void {
|
||||
selectedItemIds.value = copyArrayTo(props.modelValue, []);
|
||||
newTag.value = null;
|
||||
scrollToSelectedItem(event.$el, '.page-content', 'li.list-item-selected');
|
||||
}
|
||||
|
||||
function onSheetClosed(): void {
|
||||
emit('update:show', false);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
+5
-5
@@ -394,7 +394,7 @@ export function copyObjectTo(fromObject: Record<string, unknown> | undefined, to
|
||||
return (toObject as Record<string, unknown>);
|
||||
}
|
||||
|
||||
export function copyArrayTo(fromArray: unknown[], toArray: unknown[]): unknown[] {
|
||||
export function copyArrayTo<T>(fromArray: T[], toArray: T[]): T[] {
|
||||
if (!isArray(fromArray)) {
|
||||
return toArray;
|
||||
}
|
||||
@@ -410,9 +410,9 @@ export function copyArrayTo(fromArray: unknown[], toArray: unknown[]): unknown[]
|
||||
const toValue = toArray[i];
|
||||
|
||||
if (isArray(fromValue)) {
|
||||
toArray[i] = copyArrayTo(fromValue as unknown[], toValue as unknown[]);
|
||||
toArray[i] = copyArrayTo(fromValue as unknown[], toValue as unknown[]) as T;
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray[i] = copyObjectTo(fromValue as Record<string, unknown>, toValue as Record<string, unknown>);
|
||||
toArray[i] = copyObjectTo(fromValue as Record<string, unknown>, toValue as Record<string, unknown>) as T;
|
||||
} else {
|
||||
if (fromValue !== toValue) {
|
||||
toArray[i] = fromValue;
|
||||
@@ -420,9 +420,9 @@ export function copyArrayTo(fromArray: unknown[], toArray: unknown[]): unknown[]
|
||||
}
|
||||
} else {
|
||||
if (isArray(fromValue)) {
|
||||
toArray.push(copyArrayTo(fromValue as unknown[], []));
|
||||
toArray.push(copyArrayTo(fromValue as unknown[], []) as T);
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray.push(copyObjectTo(fromValue as Record<string, unknown>, {}));
|
||||
toArray.push(copyObjectTo(fromValue as Record<string, unknown>, {}) as T);
|
||||
} else {
|
||||
toArray.push(fromValue);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export function showToast(message: string, timeout: number | undefined, translat
|
||||
});
|
||||
}
|
||||
|
||||
export function showLoading(delayConditionFunc: () => boolean, delayMills: number): void {
|
||||
export function showLoading(delayConditionFunc?: () => boolean, delayMills?: number): void {
|
||||
if (!delayConditionFunc) {
|
||||
f7ready((f7) => {
|
||||
return f7.preloader.show();
|
||||
|
||||
Reference in New Issue
Block a user