mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-21 02:04:26 +08:00
migrate transaction template store to composition API and typescript
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ export function isObject(val: unknown): val is object {
|
|||||||
return val != null && typeof(val) === 'object' && !isArray(val);
|
return val != null && typeof(val) === 'object' && !isArray(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isArray(val: unknown): val is [] {
|
export function isArray<T>(val: unknown): val is T[] {
|
||||||
if (isFunction(Array.isArray)) {
|
if (isFunction(Array.isArray)) {
|
||||||
return Array.isArray(val);
|
return Array.isArray(val);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export function isNoAvailableTemplate(templates, showHidden) {
|
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||||
|
|
||||||
|
export function isNoAvailableTemplate(templates: TransactionTemplate[], showHidden: boolean): boolean {
|
||||||
for (let i = 0; i < templates.length; i++) {
|
for (let i = 0; i < templates.length; i++) {
|
||||||
if (showHidden || !templates[i].hidden) {
|
if (showHidden || !templates[i].hidden) {
|
||||||
return false;
|
return false;
|
||||||
@@ -8,7 +10,7 @@ export function isNoAvailableTemplate(templates, showHidden) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAvailableTemplateCount(templates, showHidden) {
|
export function getAvailableTemplateCount(templates: TransactionTemplate[], showHidden: boolean): number {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
for (let i = 0; i < templates.length; i++) {
|
for (let i = 0; i < templates.length; i++) {
|
||||||
@@ -20,7 +22,7 @@ export function getAvailableTemplateCount(templates, showHidden) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFirstShowingId(templates, showHidden) {
|
export function getFirstShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
|
||||||
for (let i = 0; i < templates.length; i++) {
|
for (let i = 0; i < templates.length; i++) {
|
||||||
if (showHidden || !templates[i].hidden) {
|
if (showHidden || !templates[i].hidden) {
|
||||||
return templates[i].id;
|
return templates[i].id;
|
||||||
@@ -30,7 +32,7 @@ export function getFirstShowingId(templates, showHidden) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLastShowingId(templates, showHidden) {
|
export function getLastShowingId(templates: TransactionTemplate[], showHidden: boolean): string | null {
|
||||||
for (let i = templates.length - 1; i >= 0; i--) {
|
for (let i = templates.length - 1; i >= 0; i--) {
|
||||||
if (showHidden || !templates[i].hidden) {
|
if (showHidden || !templates[i].hidden) {
|
||||||
return templates[i].id;
|
return templates[i].id;
|
||||||
@@ -38,7 +38,7 @@ export class Transaction implements TransactionInfoResponse {
|
|||||||
private _day?: number = undefined; // only for displaying transaction in transaction list
|
private _day?: number = undefined; // only for displaying transaction in transaction list
|
||||||
private _dayOfWeek?: string = undefined; // only for displaying transaction in transaction list
|
private _dayOfWeek?: string = undefined; // only for displaying transaction in transaction list
|
||||||
|
|
||||||
private constructor(id: string, timeSequenceId: string, type: number, categoryId: string, time: number, timeZone: string | undefined, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, tagIds: string[], comment: string, editable: boolean) {
|
protected constructor(id: string, timeSequenceId: string, type: number, categoryId: string, time: number, timeZone: string | undefined, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, tagIds: string[], comment: string, editable: boolean) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.timeSequenceId = timeSequenceId;
|
this.timeSequenceId = timeSequenceId;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|||||||
@@ -1,4 +1,125 @@
|
|||||||
import type { TransactionInfoResponse } from './transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
import { TemplateType } from '@/core/template.ts';
|
||||||
|
|
||||||
|
import { Transaction, type TransactionInfoResponse } from './transaction.ts';
|
||||||
|
|
||||||
|
export class TransactionTemplate extends Transaction implements TransactionTemplateInfoResponse {
|
||||||
|
public templateType: number;
|
||||||
|
public name: string;
|
||||||
|
public scheduledFrequencyType?: number;
|
||||||
|
public scheduledFrequency?: string;
|
||||||
|
public scheduledAt?: number;
|
||||||
|
public displayOrder: number;
|
||||||
|
public hidden: boolean;
|
||||||
|
|
||||||
|
private constructor(id: string, templateType: number, name: string, type: number, categoryId: string, utcOffset: number, sourceAccountId: string, destinationAccountId: string, sourceAmount: number, destinationAmount: number, hideAmount: boolean, scheduledFrequencyType: number | undefined, scheduledFrequency: string | undefined, scheduledAt: number | undefined, tagIds: string[], comment: string, editable: boolean, displayOrder: number, hidden: boolean) {
|
||||||
|
super(id, '', type, categoryId, 0, undefined, utcOffset, sourceAccountId, destinationAccountId, sourceAmount, destinationAmount, hideAmount, tagIds, comment, editable);
|
||||||
|
this.templateType = templateType;
|
||||||
|
this.name = name;
|
||||||
|
this.scheduledFrequencyType = scheduledFrequencyType;
|
||||||
|
this.scheduledFrequency = scheduledFrequency;
|
||||||
|
this.scheduledAt = scheduledAt;
|
||||||
|
this.displayOrder = displayOrder;
|
||||||
|
this.hidden = hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toTemplateCreateRequest(clientSessionId: string): TransactionTemplateCreateRequest {
|
||||||
|
return {
|
||||||
|
templateType: this.templateType,
|
||||||
|
name: this.name,
|
||||||
|
type: this.type,
|
||||||
|
categoryId: this.getCategoryId(),
|
||||||
|
sourceAccountId: this.sourceAccountId,
|
||||||
|
destinationAccountId: this.type === TransactionType.Transfer ? this.destinationAccountId : '0',
|
||||||
|
sourceAmount: this.sourceAmount,
|
||||||
|
destinationAmount: this.type === TransactionType.Transfer ? this.destinationAmount : 0,
|
||||||
|
hideAmount: this.hideAmount,
|
||||||
|
tagIds: this.tagIds,
|
||||||
|
comment: this.comment,
|
||||||
|
scheduledFrequencyType: this.templateType === TemplateType.Schedule.type ? this.scheduledFrequencyType : undefined,
|
||||||
|
scheduledFrequency: this.templateType === TemplateType.Schedule.type ? this.scheduledFrequency : undefined,
|
||||||
|
utcOffset: this.templateType === TemplateType.Schedule.type ? this.utcOffset : undefined,
|
||||||
|
clientSessionId: clientSessionId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public toTemplateModifyRequest(): TransactionTemplateModifyRequest {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
type: this.type,
|
||||||
|
categoryId: this.getCategoryId(),
|
||||||
|
sourceAccountId: this.sourceAccountId,
|
||||||
|
destinationAccountId: this.type === TransactionType.Transfer ? this.destinationAccountId : '0',
|
||||||
|
sourceAmount: this.sourceAmount,
|
||||||
|
destinationAmount: this.type === TransactionType.Transfer ? this.destinationAmount : 0,
|
||||||
|
hideAmount: this.hideAmount,
|
||||||
|
tagIds: this.tagIds,
|
||||||
|
comment: this.comment,
|
||||||
|
scheduledFrequencyType: this.templateType === TemplateType.Schedule.type ? this.scheduledFrequencyType : undefined,
|
||||||
|
scheduledFrequency: this.templateType === TemplateType.Schedule.type ? this.scheduledFrequency : undefined,
|
||||||
|
utcOffset: this.templateType === TemplateType.Schedule.type ? this.utcOffset : undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static createNewTransactionTemplate(transaction: Transaction): TransactionTemplate {
|
||||||
|
return new TransactionTemplate(
|
||||||
|
transaction.id,
|
||||||
|
0, // templateType
|
||||||
|
'', // name
|
||||||
|
transaction.type,
|
||||||
|
transaction.categoryId,
|
||||||
|
transaction.utcOffset,
|
||||||
|
transaction.sourceAccountId,
|
||||||
|
transaction.destinationAccountId,
|
||||||
|
transaction.sourceAmount,
|
||||||
|
transaction.destinationAmount,
|
||||||
|
transaction.hideAmount,
|
||||||
|
undefined, // scheduledFrequencyType
|
||||||
|
undefined, // scheduledFrequency
|
||||||
|
undefined, // scheduledAt
|
||||||
|
transaction.tagIds,
|
||||||
|
transaction.comment,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ofTemplate(templateResponse: TransactionTemplateInfoResponse): TransactionTemplate {
|
||||||
|
return new TransactionTemplate(
|
||||||
|
templateResponse.id,
|
||||||
|
templateResponse.templateType,
|
||||||
|
templateResponse.name,
|
||||||
|
templateResponse.type,
|
||||||
|
templateResponse.categoryId,
|
||||||
|
templateResponse.utcOffset ?? 0,
|
||||||
|
templateResponse.sourceAccountId,
|
||||||
|
templateResponse.destinationAccountId,
|
||||||
|
templateResponse.sourceAmount,
|
||||||
|
templateResponse.destinationAmount,
|
||||||
|
templateResponse.hideAmount,
|
||||||
|
templateResponse.scheduledFrequencyType,
|
||||||
|
templateResponse.scheduledFrequency,
|
||||||
|
templateResponse.scheduledAt,
|
||||||
|
templateResponse.tagIds,
|
||||||
|
templateResponse.comment,
|
||||||
|
true, // editable
|
||||||
|
templateResponse.displayOrder,
|
||||||
|
templateResponse.hidden
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ofManyTemplates(templateResponses: TransactionTemplateInfoResponse[]): TransactionTemplate[] {
|
||||||
|
const templates: TransactionTemplate[] = [];
|
||||||
|
|
||||||
|
for (const templateResponse of templateResponses) {
|
||||||
|
templates.push(TransactionTemplate.ofTemplate(templateResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface TransactionTemplateCreateRequest {
|
export interface TransactionTemplateCreateRequest {
|
||||||
readonly templateType: number;
|
readonly templateType: number;
|
||||||
|
|||||||
+1
-2
@@ -6,8 +6,7 @@ import { useUserStore } from './user.ts';
|
|||||||
import { useAccountsStore } from './account.ts';
|
import { useAccountsStore } from './account.ts';
|
||||||
import { useTransactionCategoriesStore } from './transactionCategory.ts';
|
import { useTransactionCategoriesStore } from './transactionCategory.ts';
|
||||||
import { useTransactionTagsStore } from './transactionTag.ts';
|
import { useTransactionTagsStore } from './transactionTag.ts';
|
||||||
// @ts-expect-error the above file is migrating to ts
|
import { useTransactionTemplatesStore } from './transactionTemplate.ts';
|
||||||
import { useTransactionTemplatesStore } from './transactionTemplate.js';
|
|
||||||
import { useTransactionsStore } from './transaction.ts';
|
import { useTransactionsStore } from './transaction.ts';
|
||||||
import { useOverviewStore } from './overview.ts';
|
import { useOverviewStore } from './overview.ts';
|
||||||
import { useStatisticsStore } from './statistics.ts';
|
import { useStatisticsStore } from './statistics.ts';
|
||||||
|
|||||||
@@ -1,459 +0,0 @@
|
|||||||
import { defineStore } from 'pinia';
|
|
||||||
|
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
|
||||||
import { TemplateType } from '@/core/template.ts';
|
|
||||||
import { isDefined, isObject, isArray, isEquals } from '@/lib/common.ts';
|
|
||||||
import services from '@/lib/services.ts';
|
|
||||||
import logger from '@/lib/logger.ts';
|
|
||||||
|
|
||||||
function loadTransactionTemplateList(state, templateType, templates) {
|
|
||||||
state.allTransactionTemplates[templateType] = templates;
|
|
||||||
state.allTransactionTemplatesMap[templateType] = {};
|
|
||||||
|
|
||||||
for (let i = 0; i < templates.length; i++) {
|
|
||||||
const template = templates[i];
|
|
||||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addTemplateToTransactionTemplateList(state, templateType, template) {
|
|
||||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
|
||||||
state.allTransactionTemplates[templateType].push(template);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
|
||||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTemplateInTransactionTemplateList(state, templateType, template) {
|
|
||||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
|
||||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
|
||||||
if (state.allTransactionTemplates[templateType][i].id === template.id) {
|
|
||||||
state.allTransactionTemplates[templateType].splice(i, 1, template);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
|
||||||
state.allTransactionTemplatesMap[templateType][template.id] = template;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTemplateDisplayOrderInTransactionTemplateList(state, templateType, { from, to }) {
|
|
||||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
|
||||||
state.allTransactionTemplates[templateType].splice(to, 0, state.allTransactionTemplates[templateType].splice(from, 1)[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTemplateVisibilityInTransactionTemplateList(state, templateType, { template, hidden }) {
|
|
||||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
|
||||||
if (state.allTransactionTemplatesMap[templateType][template.id]) {
|
|
||||||
state.allTransactionTemplatesMap[templateType][template.id].hidden = hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeTemplateFromTransactionTemplateList(state, templateType, template) {
|
|
||||||
if (isArray(state.allTransactionTemplates[templateType])) {
|
|
||||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
|
||||||
if (state.allTransactionTemplates[templateType][i].id === template.id) {
|
|
||||||
state.allTransactionTemplates[templateType].splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isObject(state.allTransactionTemplatesMap[templateType])) {
|
|
||||||
if (state.allTransactionTemplatesMap[templateType][template.id]) {
|
|
||||||
delete state.allTransactionTemplatesMap[templateType][template.id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useTransactionTemplatesStore = defineStore('transactionTemplates', {
|
|
||||||
state: () => ({
|
|
||||||
allTransactionTemplates: {},
|
|
||||||
allTransactionTemplatesMap: {},
|
|
||||||
transactionTemplateListStatesInvalid: {},
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
allVisibleTemplates(state) {
|
|
||||||
const allVisibleTemplates = {};
|
|
||||||
|
|
||||||
for (const templateType in state.allTransactionTemplates) {
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(state.allTransactionTemplates, templateType)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const visibleTemplates = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < state.allTransactionTemplates[templateType].length; i++) {
|
|
||||||
const template = state.allTransactionTemplates[templateType][i];
|
|
||||||
|
|
||||||
if (!template.hidden) {
|
|
||||||
visibleTemplates.push(template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allVisibleTemplates[templateType] = visibleTemplates;
|
|
||||||
}
|
|
||||||
|
|
||||||
return allVisibleTemplates;
|
|
||||||
},
|
|
||||||
allAvailableTemplatesCount(state) {
|
|
||||||
const allAvailableTemplateCounts = {};
|
|
||||||
|
|
||||||
for (const templateType in state.allTransactionTemplates) {
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(state.allTransactionTemplates, templateType)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
allAvailableTemplateCounts[templateType] = state.allTransactionTemplates[templateType].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return allAvailableTemplateCounts;
|
|
||||||
},
|
|
||||||
allVisibleTemplatesCount(state) {
|
|
||||||
const allVisibleTemplateCounts = {};
|
|
||||||
|
|
||||||
for (const templateType in state.allVisibleTemplates) {
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(state.allVisibleTemplates, templateType)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
allVisibleTemplateCounts[templateType] = state.allVisibleTemplates[templateType].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return allVisibleTemplateCounts;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
updateTransactionTemplateListInvalidState(templateType, invalidState) {
|
|
||||||
this.transactionTemplateListStatesInvalid[templateType] = invalidState;
|
|
||||||
},
|
|
||||||
resetTransactionTemplates() {
|
|
||||||
this.allTransactionTemplates = {};
|
|
||||||
this.allTransactionTemplatesMap = {};
|
|
||||||
this.transactionTemplateListStatesInvalid = {};
|
|
||||||
},
|
|
||||||
loadAllTemplates({ templateType, force }) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
if (!force && isDefined(self.transactionTemplateListStatesInvalid[templateType]) && !self.transactionTemplateListStatesInvalid[templateType]) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
resolve(self.allTransactionTemplates[templateType] || []);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
services.getAllTransactionTemplates({ templateType }).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
reject({ message: 'Unable to retrieve template list' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(self.transactionTemplateListStatesInvalid[templateType]) || self.transactionTemplateListStatesInvalid[templateType]) {
|
|
||||||
self.updateTransactionTemplateListInvalidState(templateType, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force && data.result && isEquals(self.allTransactionTemplates[templateType], data.result)) {
|
|
||||||
reject({ message: 'Template list is up to date', isUpToDate: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadTransactionTemplateList(self, templateType, data.result);
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
if (force) {
|
|
||||||
logger.error('failed to force load template list', error);
|
|
||||||
} else {
|
|
||||||
logger.error('failed to load template list', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
reject({ message: 'Unable to retrieve template list' });
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getTemplate({ templateId }) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
services.getTransactionTemplate({
|
|
||||||
id: templateId
|
|
||||||
}).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
reject({ message: 'Unable to retrieve template' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
logger.error('failed to load template info', error);
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
reject({ message: 'Unable to retrieve template' });
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveTemplateContent({ template, isEdit, clientSessionId }) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
const submitTemplate = {
|
|
||||||
templateType: template.templateType,
|
|
||||||
name: template.name,
|
|
||||||
type: template.type,
|
|
||||||
sourceAccountId: template.sourceAccountId,
|
|
||||||
sourceAmount: template.sourceAmount,
|
|
||||||
destinationAccountId: '0',
|
|
||||||
destinationAmount: 0,
|
|
||||||
hideAmount: template.hideAmount,
|
|
||||||
tagIds: template.tagIds,
|
|
||||||
comment: template.comment
|
|
||||||
};
|
|
||||||
|
|
||||||
if (clientSessionId) {
|
|
||||||
submitTemplate.clientSessionId = clientSessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (template.templateType === TemplateType.Schedule.type) {
|
|
||||||
submitTemplate.scheduledFrequencyType = template.scheduledFrequencyType;
|
|
||||||
submitTemplate.scheduledFrequency = template.scheduledFrequency;
|
|
||||||
submitTemplate.utcOffset = template.utcOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (template.type === TransactionType.Expense) {
|
|
||||||
submitTemplate.categoryId = template.expenseCategoryId;
|
|
||||||
} else if (template.type === TransactionType.Income) {
|
|
||||||
submitTemplate.categoryId = template.incomeCategoryId;
|
|
||||||
} else if (template.type === TransactionType.Transfer) {
|
|
||||||
submitTemplate.categoryId = template.transferCategoryId;
|
|
||||||
submitTemplate.destinationAccountId = template.destinationAccountId;
|
|
||||||
submitTemplate.destinationAmount = template.destinationAmount;
|
|
||||||
} else {
|
|
||||||
return Promise.reject('An error occurred');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEdit) {
|
|
||||||
submitTemplate.id = template.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let promise = null;
|
|
||||||
|
|
||||||
if (!submitTemplate.id) {
|
|
||||||
promise = services.addTransactionTemplate(submitTemplate);
|
|
||||||
} else {
|
|
||||||
promise = services.modifyTransactionTemplate(submitTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
promise.then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
if (!submitTemplate.id) {
|
|
||||||
reject({ message: 'Unable to add template' });
|
|
||||||
} else {
|
|
||||||
reject({ message: 'Unable to save template' });
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!submitTemplate.id) {
|
|
||||||
addTemplateToTransactionTemplateList(self, template.templateType, data.result);
|
|
||||||
} else {
|
|
||||||
updateTemplateInTransactionTemplateList(self, template.templateType, data.result);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
logger.error('failed to save template', error);
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
if (!submitTemplate.id) {
|
|
||||||
reject({ message: 'Unable to add template' });
|
|
||||||
} else {
|
|
||||||
reject({ message: 'Unable to save template' });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
changeTemplateDisplayOrder({ templateType, templateId, from, to }) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let template = null;
|
|
||||||
|
|
||||||
if (!isArray(self.allTransactionTemplates[templateType])) {
|
|
||||||
reject({ message: 'Unable to move template' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < self.allTransactionTemplates[templateType].length; i++) {
|
|
||||||
if (self.allTransactionTemplates[templateType][i].id === templateId) {
|
|
||||||
template = self.allTransactionTemplates[templateType][i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!template || !self.allTransactionTemplates[templateType][to]) {
|
|
||||||
reject({ message: 'Unable to move template' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(self.transactionTemplateListStatesInvalid[templateType]) && !self.transactionTemplateListStatesInvalid[templateType]) {
|
|
||||||
self.updateTransactionTemplateListInvalidState(templateType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTemplateDisplayOrderInTransactionTemplateList(self, templateType, {
|
|
||||||
template: template,
|
|
||||||
from: from,
|
|
||||||
to: to
|
|
||||||
});
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updateTemplateDisplayOrders({ templateType }) {
|
|
||||||
const self = this;
|
|
||||||
const newDisplayOrders = [];
|
|
||||||
|
|
||||||
if (isArray(self.allTransactionTemplates[templateType])) {
|
|
||||||
for (let i = 0; i < self.allTransactionTemplates[templateType].length; i++) {
|
|
||||||
newDisplayOrders.push({
|
|
||||||
id: self.allTransactionTemplates[templateType][i].id,
|
|
||||||
displayOrder: i + 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
services.moveTransactionTemplate({
|
|
||||||
newDisplayOrders: newDisplayOrders
|
|
||||||
}).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
reject({ message: 'Unable to move template' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(self.transactionTemplateListStatesInvalid[templateType]) || self.transactionTemplateListStatesInvalid[templateType]) {
|
|
||||||
self.updateTransactionTemplateListInvalidState(templateType, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
logger.error('failed to save templates display order', error);
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
reject({ message: 'Unable to move template' });
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hideTemplate({ template, hidden }) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
services.hideTransactionTemplate({
|
|
||||||
id: template.id,
|
|
||||||
hidden: hidden
|
|
||||||
}).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
if (hidden) {
|
|
||||||
reject({ message: 'Unable to hide this template' });
|
|
||||||
} else {
|
|
||||||
reject({ message: 'Unable to unhide this template' });
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTemplateVisibilityInTransactionTemplateList(self, template.templateType, {
|
|
||||||
template: template,
|
|
||||||
hidden: hidden
|
|
||||||
});
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
logger.error('failed to change template visibility', error);
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
if (hidden) {
|
|
||||||
reject({ message: 'Unable to hide this template' });
|
|
||||||
} else {
|
|
||||||
reject({ message: 'Unable to unhide this template' });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deleteTemplate({ template, beforeResolve }) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
services.deleteTransactionTemplate({
|
|
||||||
id: template.id
|
|
||||||
}).then(response => {
|
|
||||||
const data = response.data;
|
|
||||||
|
|
||||||
if (!data || !data.success || !data.result) {
|
|
||||||
reject({ message: 'Unable to delete this template' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (beforeResolve) {
|
|
||||||
beforeResolve(() => {
|
|
||||||
removeTemplateFromTransactionTemplateList(self, template.templateType, template);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
removeTemplateFromTransactionTemplateList(self, template.templateType, template);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(data.result);
|
|
||||||
}).catch(error => {
|
|
||||||
logger.error('failed to delete template', error);
|
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
|
||||||
reject({ error: error.response.data });
|
|
||||||
} else if (!error.processed) {
|
|
||||||
reject({ message: 'Unable to delete this template' });
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,469 @@
|
|||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
|
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||||
|
|
||||||
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
type TransactionTemplateInfoResponse,
|
||||||
|
type TransactionTemplateNewDisplayOrderRequest,
|
||||||
|
TransactionTemplate
|
||||||
|
} from '@/models/transaction_template.ts';
|
||||||
|
|
||||||
|
import { isDefined, isObject, isArray, isEquals } from '@/lib/common.ts';
|
||||||
|
|
||||||
|
import logger from '@/lib/logger.ts';
|
||||||
|
import services, { type ApiResponsePromise } from '@/lib/services.ts';
|
||||||
|
|
||||||
|
export const useTransactionTemplatesStore = defineStore('transactionTemplates', () =>{
|
||||||
|
const allTransactionTemplates = ref<Record<number, TransactionTemplate[]>>({});
|
||||||
|
const allTransactionTemplatesMap = ref<Record<number, Record<string, TransactionTemplate>>>({});
|
||||||
|
const transactionTemplateListStatesInvalid = ref<Record<number, boolean>>({});
|
||||||
|
|
||||||
|
const allVisibleTemplates = computed<Record<number, TransactionTemplate[]>>(() => {
|
||||||
|
const allVisibleTemplates: Record<number, TransactionTemplate[]> = {};
|
||||||
|
|
||||||
|
for (const templateType in allTransactionTemplates.value) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allTemplates = allTransactionTemplates.value[templateType];
|
||||||
|
const visibleTemplates: TransactionTemplate[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < allTemplates.length; i++) {
|
||||||
|
const template = allTemplates[i];
|
||||||
|
|
||||||
|
if (!template.hidden) {
|
||||||
|
visibleTemplates.push(template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allVisibleTemplates[templateType] = visibleTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allVisibleTemplates;
|
||||||
|
});
|
||||||
|
|
||||||
|
const allAvailableTemplatesCount = computed<Record<number, number>>(() => {
|
||||||
|
const allAvailableTemplateCounts: Record<number, number> = {};
|
||||||
|
|
||||||
|
for (const templateType in allTransactionTemplates.value) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
allAvailableTemplateCounts[templateType] = allTransactionTemplates.value[templateType].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allAvailableTemplateCounts;
|
||||||
|
});
|
||||||
|
|
||||||
|
const allVisibleTemplatesCount = computed<Record<number, number>>(() => {
|
||||||
|
const allVisibleTemplateCounts: Record<number, number> = {};
|
||||||
|
|
||||||
|
for (const templateType in allVisibleTemplates.value) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(allVisibleTemplates.value, templateType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
allVisibleTemplateCounts[templateType] = allVisibleTemplates.value[templateType].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return allVisibleTemplateCounts;
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadTransactionTemplateList(templateType: number, templates: TransactionTemplate[]): void {
|
||||||
|
allTransactionTemplates.value[templateType] = templates;
|
||||||
|
allTransactionTemplatesMap.value[templateType] = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < templates.length; i++) {
|
||||||
|
const template = templates[i];
|
||||||
|
allTransactionTemplatesMap.value[templateType][template.id] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTemplateToTransactionTemplateList(templateType: number, template: TransactionTemplate): void {
|
||||||
|
const templates = allTransactionTemplates.value[templateType];
|
||||||
|
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||||
|
|
||||||
|
if (isArray(templates)) {
|
||||||
|
templates.push(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObject(templateMap)) {
|
||||||
|
templateMap[template.id] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTemplateInTransactionTemplateList(templateType: number, template: TransactionTemplate): void {
|
||||||
|
const templates = allTransactionTemplates.value[templateType];
|
||||||
|
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||||
|
|
||||||
|
if (isArray(templates)) {
|
||||||
|
for (let i = 0; i < templates.length; i++) {
|
||||||
|
if (templates[i].id === template.id) {
|
||||||
|
templates.splice(i, 1, template);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObject(templateMap)) {
|
||||||
|
templateMap[template.id] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTemplateDisplayOrderInTransactionTemplateList(templateType: number, { from, to }: { from: number, to: number }): void {
|
||||||
|
const templates = allTransactionTemplates.value[templateType];
|
||||||
|
|
||||||
|
if (isArray(templates)) {
|
||||||
|
templates.splice(to, 0, templates.splice(from, 1)[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTemplateVisibilityInTransactionTemplateList(templateType: number, { template, hidden }: { template: TransactionTemplate, hidden: boolean }): void {
|
||||||
|
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||||
|
|
||||||
|
if (isObject(templateMap)) {
|
||||||
|
if (templateMap[template.id]) {
|
||||||
|
templateMap[template.id].hidden = hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeTemplateFromTransactionTemplateList(templateType: number, template: TransactionTemplate): void {
|
||||||
|
const templates = allTransactionTemplates.value[templateType];
|
||||||
|
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||||
|
|
||||||
|
if (isArray(templates)) {
|
||||||
|
for (let i = 0; i < templates.length; i++) {
|
||||||
|
if (templates[i].id === template.id) {
|
||||||
|
templates.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObject(templateMap)) {
|
||||||
|
if (templateMap[template.id]) {
|
||||||
|
delete templateMap[template.id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTransactionTemplateListInvalidState(templateType: number, invalidState: boolean): void {
|
||||||
|
transactionTemplateListStatesInvalid.value[templateType] = invalidState;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetTransactionTemplates(): void {
|
||||||
|
allTransactionTemplates.value = {};
|
||||||
|
allTransactionTemplatesMap.value = {};
|
||||||
|
transactionTemplateListStatesInvalid.value = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAllTemplates({ templateType, force }: { templateType: number, force?: boolean }): Promise<TransactionTemplate[]> {
|
||||||
|
if (!force && isDefined(transactionTemplateListStatesInvalid.value[templateType]) && !transactionTemplateListStatesInvalid.value[templateType]) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
resolve(allTransactionTemplates.value[templateType] || []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.getAllTransactionTemplates({ templateType }).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
reject({ message: 'Unable to retrieve template list' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefined(transactionTemplateListStatesInvalid.value[templateType]) || transactionTemplateListStatesInvalid.value[templateType]) {
|
||||||
|
updateTransactionTemplateListInvalidState(templateType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const templates = TransactionTemplate.ofManyTemplates(data.result);
|
||||||
|
|
||||||
|
if (force && data.result && isEquals(allTransactionTemplates.value[templateType], templates)) {
|
||||||
|
reject({ message: 'Template list is up to date', isUpToDate: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadTransactionTemplateList(templateType, templates);
|
||||||
|
|
||||||
|
resolve(templates);
|
||||||
|
}).catch(error => {
|
||||||
|
if (force) {
|
||||||
|
logger.error('failed to force load template list', error);
|
||||||
|
} else {
|
||||||
|
logger.error('failed to load template list', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
reject({ message: 'Unable to retrieve template list' });
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTemplate({ templateId }: { templateId: string }): Promise<TransactionTemplate> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.getTransactionTemplate({
|
||||||
|
id: templateId
|
||||||
|
}).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
reject({ message: 'Unable to retrieve template' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = TransactionTemplate.ofTemplate(data.result);
|
||||||
|
|
||||||
|
resolve(template);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to load template info', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
reject({ message: 'Unable to retrieve template' });
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTemplateContent({ template, isEdit, clientSessionId }: { template: TransactionTemplate, isEdit: boolean, clientSessionId: string }): Promise<TransactionTemplate> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let promise: ApiResponsePromise<TransactionTemplateInfoResponse>;
|
||||||
|
|
||||||
|
if (template.type !== TransactionType.Expense &&
|
||||||
|
template.type !== TransactionType.Income &&
|
||||||
|
template.type !== TransactionType.Transfer) {
|
||||||
|
reject({ message: 'An error occurred' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEdit) {
|
||||||
|
promise = services.addTransactionTemplate(template.toTemplateCreateRequest(clientSessionId));
|
||||||
|
} else {
|
||||||
|
promise = services.modifyTransactionTemplate(template.toTemplateModifyRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
if (!isEdit) {
|
||||||
|
reject({ message: 'Unable to add template' });
|
||||||
|
} else {
|
||||||
|
reject({ message: 'Unable to save template' });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = TransactionTemplate.ofTemplate(data.result);
|
||||||
|
|
||||||
|
if (!isEdit) {
|
||||||
|
addTemplateToTransactionTemplateList(template.templateType, template);
|
||||||
|
} else {
|
||||||
|
updateTemplateInTransactionTemplateList(template.templateType, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(template);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to save template', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
if (!isEdit) {
|
||||||
|
reject({ message: 'Unable to add template' });
|
||||||
|
} else {
|
||||||
|
reject({ message: 'Unable to save template' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTemplateDisplayOrder({ templateType, templateId, from, to }: { templateType: number, templateId: string, from: number, to: number }): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let template: TransactionTemplate | null = null;
|
||||||
|
|
||||||
|
if (!isArray(allTransactionTemplates.value[templateType])) {
|
||||||
|
reject({ message: 'Unable to move template' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) {
|
||||||
|
if (allTransactionTemplates.value[templateType][i].id === templateId) {
|
||||||
|
template = allTransactionTemplates.value[templateType][i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!template || !allTransactionTemplates.value[templateType][to]) {
|
||||||
|
reject({ message: 'Unable to move template' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(transactionTemplateListStatesInvalid.value[templateType]) && !transactionTemplateListStatesInvalid.value[templateType]) {
|
||||||
|
updateTransactionTemplateListInvalidState(templateType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTemplateDisplayOrderInTransactionTemplateList(templateType, { from, to });
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTemplateDisplayOrders({ templateType }: { templateType: number }): Promise<boolean> {
|
||||||
|
const newDisplayOrders: TransactionTemplateNewDisplayOrderRequest[] = [];
|
||||||
|
|
||||||
|
if (isArray(allTransactionTemplates.value[templateType])) {
|
||||||
|
for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) {
|
||||||
|
newDisplayOrders.push({
|
||||||
|
id: allTransactionTemplates.value[templateType][i].id,
|
||||||
|
displayOrder: i + 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.moveTransactionTemplate({
|
||||||
|
newDisplayOrders: newDisplayOrders
|
||||||
|
}).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
reject({ message: 'Unable to move template' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefined(transactionTemplateListStatesInvalid.value[templateType]) || transactionTemplateListStatesInvalid.value[templateType]) {
|
||||||
|
updateTransactionTemplateListInvalidState(templateType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(data.result);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to save templates display order', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
reject({ message: 'Unable to move template' });
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideTemplate({ template, hidden }: { template: TransactionTemplate, hidden: boolean }): Promise<boolean> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.hideTransactionTemplate({
|
||||||
|
id: template.id,
|
||||||
|
hidden: hidden
|
||||||
|
}).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
if (hidden) {
|
||||||
|
reject({ message: 'Unable to hide this template' });
|
||||||
|
} else {
|
||||||
|
reject({ message: 'Unable to unhide this template' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTemplateVisibilityInTransactionTemplateList(template.templateType, {
|
||||||
|
template: template,
|
||||||
|
hidden: hidden
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve(data.result);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to change template visibility', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
if (hidden) {
|
||||||
|
reject({ message: 'Unable to hide this template' });
|
||||||
|
} else {
|
||||||
|
reject({ message: 'Unable to unhide this template' });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTemplate({ template, beforeResolve }: { template: TransactionTemplate, beforeResolve?: BeforeResolveFunction }): Promise<boolean> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
services.deleteTransactionTemplate({
|
||||||
|
id: template.id
|
||||||
|
}).then(response => {
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
|
if (!data || !data.success || !data.result) {
|
||||||
|
reject({ message: 'Unable to delete this template' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beforeResolve) {
|
||||||
|
beforeResolve(() => {
|
||||||
|
removeTemplateFromTransactionTemplateList(template.templateType, template);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
removeTemplateFromTransactionTemplateList(template.templateType, template);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(data.result);
|
||||||
|
}).catch(error => {
|
||||||
|
logger.error('failed to delete template', error);
|
||||||
|
|
||||||
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
|
reject({ error: error.response.data });
|
||||||
|
} else if (!error.processed) {
|
||||||
|
reject({ message: 'Unable to delete this template' });
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// states
|
||||||
|
allTransactionTemplates,
|
||||||
|
allTransactionTemplatesMap,
|
||||||
|
transactionTemplateListStatesInvalid,
|
||||||
|
// computed states
|
||||||
|
allVisibleTemplates,
|
||||||
|
allAvailableTemplatesCount,
|
||||||
|
allVisibleTemplatesCount,
|
||||||
|
// functions
|
||||||
|
updateTransactionTemplateListInvalidState,
|
||||||
|
resetTransactionTemplates,
|
||||||
|
loadAllTemplates,
|
||||||
|
getTemplate,
|
||||||
|
saveTemplateContent,
|
||||||
|
changeTemplateDisplayOrder,
|
||||||
|
updateTemplateDisplayOrders,
|
||||||
|
hideTemplate,
|
||||||
|
deleteTemplate
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -149,13 +149,13 @@
|
|||||||
import EditDialog from '@/views/desktop/transactions/list/dialogs/EditDialog.vue';
|
import EditDialog from '@/views/desktop/transactions/list/dialogs/EditDialog.vue';
|
||||||
|
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
|
|
||||||
import { TemplateType } from '@/core/template.ts';
|
import { TemplateType } from '@/core/template.ts';
|
||||||
import {
|
import {
|
||||||
isNoAvailableTemplate,
|
isNoAvailableTemplate,
|
||||||
getAvailableTemplateCount
|
getAvailableTemplateCount
|
||||||
} from '@/lib/template.js';
|
} from '@/lib/template.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiRefresh,
|
mdiRefresh,
|
||||||
|
|||||||
@@ -594,7 +594,7 @@ import { useAccountsStore } from '@/stores/account.ts';
|
|||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
|
|
||||||
import { DateRangeScene, DateRange } from '@/core/datetime.ts';
|
import { DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||||
import { AmountFilterType } from '@/core/numeral.ts';
|
import { AmountFilterType } from '@/core/numeral.ts';
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ import { useAccountsStore } from '@/stores/account.ts';
|
|||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
import { CategoryType } from '@/core/category.ts';
|
import { CategoryType } from '@/core/category.ts';
|
||||||
@@ -407,6 +407,7 @@ import { TRANSACTION_MAX_PICTURE_COUNT } from '@/consts/transaction.ts';
|
|||||||
import { KnownErrorCode } from '@/consts/api.ts';
|
import { KnownErrorCode } from '@/consts/api.ts';
|
||||||
import { SUPPORTED_IMAGE_EXTENSIONS } from '@/consts/file.ts';
|
import { SUPPORTED_IMAGE_EXTENSIONS } from '@/consts/file.ts';
|
||||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isArray,
|
isArray,
|
||||||
@@ -836,6 +837,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (self.type === 'template') {
|
} else if (self.type === 'template') {
|
||||||
|
self.transaction = TransactionTemplate.createNewTransactionTemplate(self.transaction);
|
||||||
self.transaction.name = '';
|
self.transaction.name = '';
|
||||||
|
|
||||||
if (options && options.templateType) {
|
if (options && options.templateType) {
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
import { useOverviewStore } from '@/stores/overview.ts';
|
import { useOverviewStore } from '@/stores/overview.ts';
|
||||||
|
|
||||||
import { DateRange } from '@/core/datetime.ts';
|
import { DateRange } from '@/core/datetime.ts';
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
|
|
||||||
import { TemplateType } from '@/core/template.ts';
|
import { TemplateType } from '@/core/template.ts';
|
||||||
import { isDefined } from '@/lib/common.ts';
|
import { isDefined } from '@/lib/common.ts';
|
||||||
@@ -94,7 +94,7 @@ import {
|
|||||||
isNoAvailableTemplate,
|
isNoAvailableTemplate,
|
||||||
getFirstShowingId,
|
getFirstShowingId,
|
||||||
getLastShowingId
|
getLastShowingId
|
||||||
} from '@/lib/template.js';
|
} from '@/lib/template.ts';
|
||||||
import { onSwipeoutDeleted } from '@/lib/ui/mobile.ts';
|
import { onSwipeoutDeleted } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ import { useAccountsStore } from '@/stores/account.ts';
|
|||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.js';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
import { CategoryType } from '@/core/category.ts';
|
import { CategoryType } from '@/core/category.ts';
|
||||||
@@ -446,6 +446,7 @@ import { TemplateType, ScheduledTemplateFrequencyType } from '@/core/template.ts
|
|||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT, TRANSACTION_MAX_PICTURE_COUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT, TRANSACTION_MAX_PICTURE_COUNT } from '@/consts/transaction.ts';
|
||||||
import { KnownErrorCode } from '@/consts/api.ts';
|
import { KnownErrorCode } from '@/consts/api.ts';
|
||||||
import { SUPPORTED_IMAGE_EXTENSIONS } from '@/consts/file.ts';
|
import { SUPPORTED_IMAGE_EXTENSIONS } from '@/consts/file.ts';
|
||||||
|
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||||
|
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
import {
|
import {
|
||||||
@@ -950,6 +951,7 @@ export default {
|
|||||||
promises.push(self.transactionsStore.getTransaction({ transactionId: query.id, withPictures: self.mode !== 'add' }));
|
promises.push(self.transactionsStore.getTransaction({ transactionId: query.id, withPictures: self.mode !== 'add' }));
|
||||||
}
|
}
|
||||||
} else if (self.type === 'template') {
|
} else if (self.type === 'template') {
|
||||||
|
self.transaction = TransactionTemplate.createNewTransactionTemplate(self.transaction);
|
||||||
self.transaction.name = '';
|
self.transaction.name = '';
|
||||||
|
|
||||||
if (query.templateType) {
|
if (query.templateType) {
|
||||||
|
|||||||
Reference in New Issue
Block a user