update closing balance in reconciliation statement page / dialog

This commit is contained in:
MaysWind
2025-07-30 00:56:55 +08:00
parent f7bc4b3ab6
commit 8fa46281e0
15 changed files with 210 additions and 2 deletions
@@ -0,0 +1,102 @@
<template>
<v-dialog persistent min-width="320" width="auto" v-model="showState">
<v-card>
<v-toolbar :color="finalColor">
<v-toolbar-title>{{ titleContent }}</v-toolbar-title>
</v-toolbar>
<v-card-text v-if="textContent" class="pa-4 pb-6">{{ textContent }}</v-card-text>
<v-card-text>
<v-form>
<v-row>
<v-col cols="12">
<amount-input :persistent-placeholder="true"
:currency="dialogOptions?.currency"
:show-currency="!!dialogOptions?.currency"
:label="inputLabelContent"
:placeholder="inputPlaceholderContent"
v-model="amount" />
</v-col>
</v-row>
</v-form>
</v-card-text>
<v-card-actions class="px-4 pb-4">
<v-spacer></v-spacer>
<v-btn color="gray" @click="cancel">{{ tt('Cancel') }}</v-btn>
<v-btn :color="finalColor" @click="confirm">{{ tt('OK') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
interface AmountInputDialogOptions {
title?: string;
text?: string;
textI18nOptions?: Record<string, unknown>;
inputLabel?: string;
inputPlaceholder?: string;
color?: string;
currency?: string;
initAmount?: number;
}
const emit = defineEmits<{
(e: 'update:show', value: boolean): void;
}>();
const { tt } = useI18n();
const showState = ref<boolean>(false);
const dialogOptions = ref<AmountInputDialogOptions | undefined>(undefined);
const amount = ref<number>(0);
let resolveFunc: ((value: number) => void) | null = null;
let rejectFunc: ((reason?: unknown) => void) | null = null;
const titleContent = computed<string>(() => dialogOptions.value?.title ? tt(dialogOptions.value.title) : tt('global.app.title'));
const textContent = computed<string>(() => dialogOptions.value?.text ? tt(dialogOptions.value.text, dialogOptions.value.textI18nOptions ?? {}) : '');
const inputLabelContent = computed<string | undefined>(() => dialogOptions.value?.inputLabel ? tt(dialogOptions.value.inputLabel) : undefined);
const inputPlaceholderContent = computed<string | undefined>(() => dialogOptions.value?.inputPlaceholder ? tt(dialogOptions.value.inputPlaceholder) : undefined);
const finalColor = computed<string>(() => dialogOptions.value?.color || 'primary');
function open(options: AmountInputDialogOptions): Promise<number> {
showState.value = true;
dialogOptions.value = options;
amount.value = options.initAmount ?? 0;
return new Promise((resolve, reject) => {
resolveFunc = resolve;
rejectFunc = reject;
});
}
function confirm(): void {
if (resolveFunc) {
resolveFunc(amount.value);
}
showState.value = false;
emit('update:show', false);
}
function cancel(): void {
if (rejectFunc) {
rejectFunc();
}
showState.value = false;
emit('update:show', false);
}
watch(showState, newValue => {
emit('update:show', newValue);
});
defineExpose({
open
});
</script>