edit ledger

This commit is contained in:
Sirttas
2026-05-18 21:19:01 +02:00
parent 02466eea14
commit 3ca0cf23f1
5 changed files with 402 additions and 75 deletions
+63 -19
View File
@@ -2,23 +2,32 @@
import {computed, ref} from "vue";
import {storeToRefs} from "pinia";
import {COMBINING_LEDGER, Ledger, LedgerType, MAIN_LEDGER, useLedgersStore} from "./ledger";
import {isCombining, Ledger, LedgerType, LedgerTypes, useLedgersStore} from "./ledger";
import {Modal} from "@/components";
import LedgerLabel from "./LedgerLabel.vue";
import {PlusIcon, TrashIcon} from '@heroicons/vue/24/outline';
interface Props {
ledgerId?: number;
}
const props = withDefaults(defineProps<Props>(), {
ledgerId: 0
});
const ledgersStore = useLedgersStore();
const {ledgers} = storeToRefs(ledgersStore);
const {createMain, createCombining} = ledgersStore;
const {findById, findAllById, createMain, createCombining, updateMain, updateCombining} = ledgersStore;
const modalOpen = ref<boolean>(false);
const type = ref<LedgerType>(MAIN_LEDGER);
const type = ref<LedgerType>(LedgerTypes.Main);
const name = ref("");
const members = ref<Ledger[]>([]);
const selectedLedger = ref<Ledger>();
const availableLedgers = computed(() => ledgers.value.filter(l => !members.value.includes(l)));
const addMember = () => {
if (selectedLedger.value && !members.value.includes(selectedLedger.value)) {
members.value = [...members.value, selectedLedger.value];
@@ -27,21 +36,54 @@ const addMember = () => {
}
const open = () => {
type.value = MAIN_LEDGER;
name.value = "";
members.value = [];
const ledger = isCreating.value ? undefined : findById(props.ledgerId);
if (ledger) {
type.value = ledger.type;
name.value = ledger.name;
members.value = isCombining(ledger) ? findAllById(ledger.memberLedgerIds) : [];
} else {
type.value = LedgerTypes.Main;
name.value = "";
members.value = [];
}
modalOpen.value = true;
}
const canCreate = computed(() => name.value.trim().length > 0);
const canSave = computed(() => name.value.trim().length > 0);
const isCreating = computed(() => props.ledgerId === 0)
const title = computed(() => {
if (isCreating.value) {
return `Creating ${type.value === LedgerTypes.Main ? 'Main' : 'Combining'} Ledger`
}
return `Updating ${name.value}`
})
const create = () => {
if (!canCreate.value) {
return;
} else if (type.value === MAIN_LEDGER) {
createMain({ name: name.value })
if (type.value === LedgerTypes.Main) {
createMain({name: name.value})
} else {
createCombining({ name: name.value, memberLedgerIds: members.value.map(l => l.ledgerId) })
createCombining({name: name.value, memberLedgerIds: members.value.map(l => l.ledgerId)})
}
}
const update = () => {
if (type.value === LedgerTypes.Main) {
updateMain(props.ledgerId, {name: name.value})
} else {
updateCombining(props.ledgerId, {name: name.value, memberLedgerIds: members.value.map(l => l.ledgerId)})
}
}
const save = () => {
if (!canSave.value) {
return;
}
if (isCreating.value) {
create();
} else {
update();
}
modalOpen.value = false;
}
@@ -51,24 +93,26 @@ defineExpose({ open });
<template>
<Modal v-model:open="modalOpen">
<div class="bg-slate-800 rounded pb-4">
<span class="m-2">Creating {{ type === MAIN_LEDGER ? 'Main' : 'Combining' }} Ledger</span>
<div class="bg-slate-800 rounded pb-4 w-96">
<span class="m-2">{{ title }}</span>
<hr />
<div class="mt-4">
<div class="flex justify-center">
<div class="flex bg-slate-600 rounded-s-md p-1">
<button class="switch" :class="{active: type === MAIN_LEDGER}" @click="type = MAIN_LEDGER">Main</button>
<button class="switch" :class="{active: type === LedgerTypes.Main}" @click="type = LedgerTypes.Main">Main</button>
</div>
<div class="switch flex bg-slate-600 rounded-e-md p-1">
<button class="switch" :class="{active: type === COMBINING_LEDGER}" @click="type = COMBINING_LEDGER">Combining</button>
<button class="switch" :class="{active: type === LedgerTypes.Combining}" @click="type = LedgerTypes.Combining">Combining</button>
</div>
</div>
<div class="m-4">
Name:
<input type="text" v-model="name" />
<div class="flex">
<input type="text" class="flex grow" v-model="name" />
</div>
</div>
</div>
<div v-if="type === COMBINING_LEDGER" class="ms-4 mb-4">
<div v-if="type === LedgerTypes.Combining" class="ms-4 mb-4">
Member Ledgers:
<div v-for="ledger in members" :key="ledger.ledgerId" class="flex">
<LedgerLabel class="flex grow mb-2" :ledger="ledger" />
@@ -86,7 +130,7 @@ defineExpose({ open });
</div>
</div>
<div class="flex justify-end">
<button class="me-4" @click="create" :disabled="!canCreate">Create</button>
<button class="me-4" @click="save" :disabled="!canSave">Save</button>
</div>
</div>
</Modal>
+2 -2
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import {COMBINING_LEDGER, Ledger} from "@/ledger/ledger.ts";
import {isCombining, Ledger} from "@/ledger/ledger.ts";
import {FolderOpenIcon} from '@heroicons/vue/24/outline';
interface Props {
@@ -12,7 +12,7 @@ const props = defineProps<Props>();
<template>
<div class="flex">
<FolderOpenIcon v-if="ledger.type === COMBINING_LEDGER" class="w-4 me-1" />
<FolderOpenIcon v-if="isCombining(ledger)" class="w-4 me-1" />
<div v-else class="w-4 me-1"/>
<span>{{ ledger.name }}</span>
</div>
+46 -17
View File
@@ -1,34 +1,63 @@
import {CreateCombiningLedgerCommand, CreateMainLedgerCommand, FindAll200ResponseInner} from "@/generated/mammon";
import {
CombiningLedgerResponse,
CombiningLedgerResponseTypeEnum,
CreateCombiningLedgerRequest,
CreateMainLedgerRequest,
LedgerResponseTypeEnum,
MainLedgerResponse,
MainLedgerResponseTypeEnum,
UpdateCombiningLedgerRequest,
UpdateMainLedgerRequest
} from "@/generated/mammon";
import {defineStore} from "pinia";
import {ref} from "vue";
import {ref, triggerRef} from "vue";
import {ledgerControllerApi} from "@/mammon";
export const MAIN_LEDGER = "MAIN";
export const COMBINING_LEDGER = "COMBINING";
export const LedgerTypes = LedgerResponseTypeEnum;
export type LedgerType = typeof MAIN_LEDGER | typeof COMBINING_LEDGER;
export type Ledger = FindAll200ResponseInner;
export type LedgerType = LedgerResponseTypeEnum;
export type MainLedger = MainLedgerResponse & {type: MainLedgerResponseTypeEnum}
export type CombiningLedger = CombiningLedgerResponse & {type: CombiningLedgerResponseTypeEnum}
export type Ledger = MainLedger | CombiningLedger;
export const isMain = (ledger: Ledger): ledger is MainLedger => {
return ledger.type === LedgerTypes.Main;
}
export const isCombining = (ledger: Ledger): ledger is CombiningLedger => {
return ledger.type === LedgerTypes.Combining;
}
export const useLedgersStore = defineStore('ledgers', () => {
const ledgers = ref<Ledger[]>([]);
const createMain = (ledger: CreateMainLedgerCommand) => ledgerControllerApi.createMainLedger(ledger).then(response => {
const ledger = response.data;
const addLedger = (ledger: Ledger) => {
ledgers.value.push(ledger);
triggerRef(ledgers);
return ledger;
});
};
const createCombining = (ledger: CreateCombiningLedgerCommand) => ledgerControllerApi.createCombiningLedger(ledger).then(response => {
const ledger = response.data;
const replaceLedger = (ledger: Ledger) => {
const index = ledgers.value.findIndex(l => l.ledgerId === ledger.ledgerId);
ledgers.value.push(ledger);
if (index !== -1) {
ledgers.value[index] = ledger;
}
triggerRef(ledgers);
return ledger;
});
};
const refresh = () => ledgerControllerApi.findAll().then(response => ledgers.value = response.data);
const findById = (ledgerId: number): Ledger | undefined => ledgers.value.find(l => l.ledgerId === ledgerId);
const findAllById = (ledgerIds: number[]): Ledger[] => ledgerIds.map(findById).filter((x): x is Ledger => x !== undefined)
const createMain = (ledger: CreateMainLedgerRequest) => ledgerControllerApi.createMainLedger(ledger).then(response => addLedger(response.data as Ledger));
const createCombining = (ledger: CreateCombiningLedgerRequest) => ledgerControllerApi.createCombiningLedger(ledger).then(response => addLedger(response.data as Ledger));
const updateMain = (ledgerId: number, ledger: UpdateMainLedgerRequest) => ledgerControllerApi.updateMainLedger(ledgerId, ledger).then(response => replaceLedger(response.data as Ledger));
const updateCombining = (ledgerId: number, ledger: UpdateCombiningLedgerRequest) => ledgerControllerApi.updateCombiningLedger(ledgerId, ledger).then(response => replaceLedger(response.data as Ledger));
const refresh = () => ledgerControllerApi.findAll().then(response => ledgers.value = response.data as Ledger[]);
refresh();
return {ledgers, createMain, createCombining, refresh};
})
return {ledgers, findById, findAllById, createMain, createCombining, updateMain, updateCombining, refresh};
})