migrate to typescript
This commit is contained in:
+35
-32
@@ -1,36 +1,39 @@
|
||||
import globals from 'globals';
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import vueTsEslintConfig from '@vue/eslint-config-typescript';
|
||||
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import js from '@eslint/js';
|
||||
import { FlatCompat } from '@eslint/eslintrc';
|
||||
import { includeIgnoreFile } from '@eslint/compat';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const gitignorePath = path.resolve(__dirname, '.gitignore');
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all
|
||||
});
|
||||
|
||||
export default [...compat.extends('eslint:recommended', 'plugin:vue/vue3-essential'),
|
||||
includeIgnoreFile(gitignorePath), {
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
export default [
|
||||
...pluginVue.configs['flat/essential'],
|
||||
...vueTsEslintConfig(),
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
}
|
||||
},
|
||||
},
|
||||
files: [
|
||||
"**/*.{vue,js,jsx,cjs,mjs}"
|
||||
],
|
||||
rules: {
|
||||
'vue/no-use-v-if-with-v-for': 'off',
|
||||
'vue/valid-v-slot': ['error', {
|
||||
allowModifiers: true,
|
||||
}],
|
||||
{
|
||||
ignores: [
|
||||
'dist/**',
|
||||
'**/*.{js,jsx,cjs,mjs}'
|
||||
]
|
||||
},
|
||||
}];
|
||||
{
|
||||
files: [
|
||||
'**/*.{vue,ts,tsx,mts,js,jsx,cjs,mjs}'
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-this-alias': ['error', {
|
||||
allowedNames: ['self']
|
||||
}],
|
||||
'vue/valid-v-slot': ['error', {
|
||||
allowModifiers: true
|
||||
}],
|
||||
'vue/block-lang': ['error', {
|
||||
script: {
|
||||
lang: ['ts', 'js']
|
||||
}
|
||||
}],
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
Generated
+875
-235
File diff suppressed because it is too large
Load Diff
+11
-6
@@ -15,7 +15,7 @@
|
||||
"serve": "cross-env NODE_ENV=development vite",
|
||||
"build": "cross-env NODE_ENV=production vite build",
|
||||
"serve:dist": "vite preview",
|
||||
"lint": "eslint . --fix"
|
||||
"lint": "tsc --noEmit && eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/js": "^7.4.47",
|
||||
@@ -47,20 +47,25 @@
|
||||
"vuetify": "^3.7.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.4",
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
"@eslint/js": "^9.17.0",
|
||||
"@tsconfig/node22": "^22.0.0",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/git-rev-sync": "^2.0.2",
|
||||
"@types/node": "^22.10.2",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/eslint-config-typescript": "^14.1.3",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"git-rev-sync": "^3.0.2",
|
||||
"globals": "^15.14.0",
|
||||
"postcss-preset-env": "^10.1.2",
|
||||
"sass": "^1.83.0",
|
||||
"typescript": "^5.7.2",
|
||||
"vite": "^6.0.5",
|
||||
"vite-plugin-pwa": "^0.21.1",
|
||||
"vite-plugin-vuetify": "^2.0.4"
|
||||
"vite-plugin-vuetify": "^2.0.4",
|
||||
"vue-tsc": "^2.1.10"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
||||
+11
-10
@@ -26,10 +26,11 @@ import { useUserStore } from '@/stores/user.js';
|
||||
import { useTokensStore } from '@/stores/token.js';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
|
||||
|
||||
import assetConstants from '@/consts/asset.js';
|
||||
import { isProduction } from '@/lib/version.js';
|
||||
import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { isProduction } from '@/lib/version.ts';
|
||||
import { loadMapAssets } from '@/lib/map/index.js';
|
||||
import { getSystemTheme, setExpenseAndIncomeAmountColor } from '@/lib/ui.js';
|
||||
import { getSystemTheme, setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -40,7 +41,7 @@ export default {
|
||||
computed: {
|
||||
...mapStores(useRootStore, useSettingsStore, useUserStore, useTokensStore, useExchangeRatesStore),
|
||||
ezBookkeepingLogoPath() {
|
||||
return assetConstants.ezBookkeepingLogoPath;
|
||||
return APPLICATION_LOGO_PATH;
|
||||
},
|
||||
currentNotificationContent() {
|
||||
return this.rootStore.currentNotification;
|
||||
@@ -55,10 +56,10 @@ export default {
|
||||
const self = this;
|
||||
const theme = useTheme();
|
||||
|
||||
if (self.settingsStore.appSettings.theme === 'light') {
|
||||
theme.global.name.value = 'light';
|
||||
} else if (self.settingsStore.appSettings.theme === 'dark') {
|
||||
theme.global.name.value = 'dark';
|
||||
if (self.settingsStore.appSettings.theme === ThemeType.Light) {
|
||||
theme.global.name.value = ThemeType.Light;
|
||||
} else if (self.settingsStore.appSettings.theme === ThemeType.Dark) {
|
||||
theme.global.name.value = ThemeType.Dark;
|
||||
} else {
|
||||
theme.global.name.value = getSystemTheme();
|
||||
}
|
||||
@@ -66,9 +67,9 @@ export default {
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function (e) {
|
||||
if (self.settingsStore.appSettings.theme === 'auto') {
|
||||
if (e.matches) {
|
||||
theme.global.name.value = 'dark';
|
||||
theme.global.name.value = ThemeType.Dark;
|
||||
} else {
|
||||
theme.global.name.value = 'light';
|
||||
theme.global.name.value = ThemeType.Light;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+8
-7
@@ -15,21 +15,22 @@ import { useUserStore } from '@/stores/user.js';
|
||||
import { useTokensStore } from '@/stores/token.js';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
|
||||
|
||||
import assetConstants from '@/consts/asset.js';
|
||||
import { isProduction } from '@/lib/version.js';
|
||||
import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { isProduction } from '@/lib/version.ts';
|
||||
import { getTheme, isEnableAnimate } from '@/lib/settings.js';
|
||||
import { loadMapAssets } from '@/lib/map/index.js';
|
||||
import { setExpenseAndIncomeAmountColor } from '@/lib/ui.js';
|
||||
import { isModalShowing, setAppFontSize } from '@/lib/ui.mobile.js';
|
||||
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
|
||||
import { isModalShowing, setAppFontSize } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
const self = this;
|
||||
let darkMode = 'auto';
|
||||
|
||||
if (getTheme() === 'light') {
|
||||
if (getTheme() === ThemeType.Light) {
|
||||
darkMode = false;
|
||||
} else if (getTheme() === 'dark') {
|
||||
} else if (getTheme() === ThemeType.Dark) {
|
||||
darkMode = true;
|
||||
}
|
||||
|
||||
@@ -112,7 +113,7 @@ export default {
|
||||
if (newValue) {
|
||||
f7ready((f7) => {
|
||||
self.notification = f7.notification.create({
|
||||
icon: `<img alt="logo" src="${assetConstants.ezBookkeepingLogoPath}" />`,
|
||||
icon: `<img alt="logo" src="${APPLICATION_LOGO_PATH}" />`,
|
||||
title: self.$t('global.app.title'),
|
||||
text: newValue,
|
||||
closeOnClick: true,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<script>
|
||||
import {
|
||||
copyObjectTo
|
||||
} from '@/lib/common.js';
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
createMapHolder,
|
||||
initMapInstance,
|
||||
|
||||
@@ -34,8 +34,8 @@ import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.js';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import transactionConstants from '@/consts/transaction.js';
|
||||
import { removeAll } from '@/lib/common.js';
|
||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||
import { removeAll } from '@/lib/common.ts';
|
||||
import logger from '@/lib/logger.js';
|
||||
|
||||
export default {
|
||||
@@ -76,7 +76,7 @@ export default {
|
||||
return self.$t('Amount value is not number');
|
||||
}
|
||||
|
||||
return (val >= transactionConstants.minAmountNumber && val <= transactionConstants.maxAmountNumber) || self.$t('Amount value exceeds limitation');
|
||||
return (val >= TRANSACTION_MIN_AMOUNT && val <= TRANSACTION_MAX_AMOUNT) || self.$t('Amount value exceeds limitation');
|
||||
} catch (ex) {
|
||||
logger.warn('cannot parse amount in amount input, original value is ' + v, ex);
|
||||
return self.$t('Amount value is not number');
|
||||
@@ -222,7 +222,7 @@ export default {
|
||||
}
|
||||
|
||||
let decimalLength = 0;
|
||||
let decimalIndex = str.indexOf(decimalSeparator);
|
||||
const decimalIndex = str.indexOf(decimalSeparator);
|
||||
|
||||
if (decimalIndex >= 0) {
|
||||
decimalLength = str.length - str.indexOf(decimalSeparator) - 1;
|
||||
@@ -285,16 +285,16 @@ export default {
|
||||
e.preventDefault();
|
||||
},
|
||||
getValidFormattedValue(value, textualValue, hasDecimalSeparator) {
|
||||
let maxLength = transactionConstants.maxAmountNumber.toString().length;
|
||||
let maxLength = TRANSACTION_MAX_AMOUNT.toString().length;
|
||||
|
||||
if (value < 0) {
|
||||
maxLength = transactionConstants.minAmountNumber.toString().length;
|
||||
maxLength = TRANSACTION_MIN_AMOUNT.toString().length;
|
||||
}
|
||||
|
||||
if (value < transactionConstants.minAmountNumber) {
|
||||
return this.getFormattedValue(this.userStore, transactionConstants.minAmountNumber);
|
||||
} else if (value > transactionConstants.maxAmountNumber) {
|
||||
return this.getFormattedValue(this.userStore, transactionConstants.maxAmountNumber);
|
||||
if (value < TRANSACTION_MIN_AMOUNT) {
|
||||
return this.getFormattedValue(this.userStore, TRANSACTION_MIN_AMOUNT);
|
||||
} else if (value > TRANSACTION_MAX_AMOUNT) {
|
||||
return this.getFormattedValue(this.userStore, TRANSACTION_MAX_AMOUNT);
|
||||
}
|
||||
|
||||
if (!hasDecimalSeparator && textualValue.length > maxLength) {
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { arrayContainsFieldValue } from '@/lib/common.js';
|
||||
import { getColorsInRows } from '@/lib/color.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.desktop.js';
|
||||
import { DEFAULT_ICON_COLOR } from '@/consts/color.ts';
|
||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||
import { getColorsInRows } from '@/lib/color.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.js';
|
||||
|
||||
import {
|
||||
mdiSquareRounded,
|
||||
@@ -89,7 +89,7 @@ export default {
|
||||
return arrayContainsFieldValue(row, 'id', this.modelValue);
|
||||
},
|
||||
getFinalColor(color) {
|
||||
if (color && color !== colorConstants.defaultAccountColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
return '#' + color;
|
||||
} else {
|
||||
return 'var(--default-icon-color)';
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isString } from '@/lib/common.js';
|
||||
import { isString } from '@/lib/common.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -60,7 +60,8 @@ import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.js';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
getCurrentYear,
|
||||
@@ -122,7 +123,7 @@ export default {
|
||||
}
|
||||
},
|
||||
isDarkMode() {
|
||||
return this.globalTheme.global.name.value === 'dark';
|
||||
return this.globalTheme.global.name.value === ThemeType.Dark;
|
||||
},
|
||||
firstDayOfWeek() {
|
||||
return this.userStore.currentUserFirstDayOfWeek;
|
||||
|
||||
@@ -43,7 +43,8 @@ import { useTheme } from 'vuetify';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.js';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentYear,
|
||||
getTimezoneOffsetMinutes,
|
||||
@@ -90,7 +91,7 @@ export default {
|
||||
}
|
||||
},
|
||||
isDarkMode() {
|
||||
return this.globalTheme.global.name.value === 'dark';
|
||||
return this.globalTheme.global.name.value === ThemeType.Dark;
|
||||
},
|
||||
firstDayOfWeek() {
|
||||
return this.userStore.currentUserFirstDayOfWeek;
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { arrayContainsFieldValue } from '@/lib/common.js';
|
||||
import { getIconsInRows } from '@/lib/icon.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.desktop.js';
|
||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||
import { getIconsInRows } from '@/lib/icon.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.js';
|
||||
|
||||
import {
|
||||
mdiCheck
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import iconConstants from '@/consts/icon.js';
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { isNumber } from '@/lib/common.js';
|
||||
import { ALL_ACCOUNT_ICONS, DEFAULT_ACCOUNT_ICON, ALL_CATEGORY_ICONS, DEFAULT_CATEGORY_ICON } from '@/consts/icon.ts';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_ACCOUNT_COLOR, DEFAULT_CATEGORY_COLOR } from '@/consts/color.ts';
|
||||
import { isNumber } from '@/lib/common.ts';
|
||||
|
||||
import {
|
||||
mdiEyeOffOutline
|
||||
@@ -74,25 +74,25 @@ export default {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!iconConstants.allAccountIcons[iconId]) {
|
||||
return iconConstants.defaultAccountIcon.icon;
|
||||
if (!ALL_ACCOUNT_ICONS[iconId]) {
|
||||
return DEFAULT_ACCOUNT_ICON.icon;
|
||||
}
|
||||
|
||||
return iconConstants.allAccountIcons[iconId].icon;
|
||||
return ALL_ACCOUNT_ICONS[iconId].icon;
|
||||
},
|
||||
getCategoryIcon(iconId) {
|
||||
if (isNumber(iconId)) {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!iconConstants.allCategoryIcons[iconId]) {
|
||||
return iconConstants.defaultCategoryIcon.icon;
|
||||
if (!ALL_CATEGORY_ICONS[iconId]) {
|
||||
return DEFAULT_CATEGORY_ICON.icon;
|
||||
}
|
||||
|
||||
return iconConstants.allCategoryIcons[iconId].icon;
|
||||
return ALL_CATEGORY_ICONS[iconId].icon;
|
||||
},
|
||||
getAccountIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultAccountColor) {
|
||||
if (color && color !== DEFAULT_ACCOUNT_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
@@ -113,7 +113,7 @@ export default {
|
||||
return ret;
|
||||
},
|
||||
getCategoryIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultCategoryColor) {
|
||||
if (color && color !== DEFAULT_CATEGORY_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
@@ -134,7 +134,7 @@ export default {
|
||||
return ret;
|
||||
},
|
||||
getDefaultIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
|
||||
@@ -69,6 +69,7 @@ import { useTheme } from 'vuetify';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import {
|
||||
getYearMonthObjectFromString,
|
||||
getYearMonthStringFromObject,
|
||||
@@ -125,7 +126,7 @@ export default {
|
||||
}
|
||||
},
|
||||
isDarkMode() {
|
||||
return this.globalTheme.global.name.value === 'dark';
|
||||
return this.globalTheme.global.name.value === ThemeType.Dark;
|
||||
},
|
||||
isYearFirst() {
|
||||
return this.$locale.isLongDateMonthAfterYear(this.userStore);
|
||||
|
||||
@@ -10,7 +10,8 @@ import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.js';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_CHART_COLORS } from '@/consts/color.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { formatPercent } from '@/lib/numeral.js';
|
||||
|
||||
export default {
|
||||
@@ -40,7 +41,7 @@ export default {
|
||||
computed: {
|
||||
...mapStores(useSettingsStore, useUserStore),
|
||||
isDarkMode() {
|
||||
return this.globalTheme.global.name.value === 'dark';
|
||||
return this.globalTheme.global.name.value === ThemeType.Dark;
|
||||
},
|
||||
itemsMap: function () {
|
||||
const map = {};
|
||||
@@ -87,7 +88,7 @@ export default {
|
||||
percent: (item[this.percentField] > 0 || item[this.percentField] === 0 || item[this.percentField] === '0') ? item[this.percentField] : (item[this.valueField] / totalValidValue * 100),
|
||||
actualPercent: item[this.valueField] / totalValidValue,
|
||||
itemStyle: {
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : colorConstants.defaultChartColors[validItems.length % colorConstants.defaultChartColors.length]),
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : DEFAULT_CHART_COLORS[validItems.length % DEFAULT_CHART_COLORS.length]),
|
||||
},
|
||||
selected: true,
|
||||
sourceItem: item
|
||||
@@ -283,7 +284,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getColor: function (color) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import templateConstants from '@/consts/template.js';
|
||||
import { sortNumbersArray } from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.desktop.js';
|
||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||
import { sortNumbersArray } from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -85,7 +85,7 @@ export default {
|
||||
return this.$locale.getAllTransactionScheduledFrequencyTypes();
|
||||
},
|
||||
allTemplateScheduledFrequencyTypes() {
|
||||
return templateConstants.allTemplateScheduledFrequencyTypes;
|
||||
return ScheduledTemplateFrequencyType.all();
|
||||
},
|
||||
allWeekDays() {
|
||||
return this.$locale.getAllWeekDays(this.firstDayOfWeek);
|
||||
@@ -113,9 +113,9 @@ export default {
|
||||
if (this.type !== value) {
|
||||
this.$emit('update:type', value);
|
||||
|
||||
if (value === templateConstants.allTemplateScheduledFrequencyTypes.Weekly.type) {
|
||||
if (value === ScheduledTemplateFrequencyType.Weekly.type) {
|
||||
this.frequencyValue = [this.firstDayOfWeek];
|
||||
} else if (value === templateConstants.allTemplateScheduledFrequencyTypes.Monthly.type) {
|
||||
} else if (value === ScheduledTemplateFrequencyType.Monthly.type) {
|
||||
this.frequencyValue = [1];
|
||||
} else {
|
||||
this.frequencyValue = [];
|
||||
@@ -141,9 +141,9 @@ export default {
|
||||
}
|
||||
},
|
||||
displayFrequency() {
|
||||
if (this.type === templateConstants.allTemplateScheduledFrequencyTypes.Disabled.type) {
|
||||
if (this.type === ScheduledTemplateFrequencyType.Disabled.type) {
|
||||
return this.$t('Disabled');
|
||||
} else if (this.type === templateConstants.allTemplateScheduledFrequencyTypes.Weekly.type) {
|
||||
} else if (this.type === ScheduledTemplateFrequencyType.Weekly.type) {
|
||||
if (this.frequencyValue.length) {
|
||||
return this.$t('format.misc.everyMultiDaysOfWeek', {
|
||||
days: this.$locale.getMultiWeekdayLongNames(this.frequencyValue, this.firstDayOfWeek)
|
||||
@@ -151,7 +151,7 @@ export default {
|
||||
} else {
|
||||
return this.$t('Weekly');
|
||||
}
|
||||
} else if (this.type === templateConstants.allTemplateScheduledFrequencyTypes.Monthly.type) {
|
||||
} else if (this.type === ScheduledTemplateFrequencyType.Monthly.type) {
|
||||
if (this.frequencyValue.length) {
|
||||
return this.$t('format.misc.everyMultiDaysOfMonth', {
|
||||
days: this.$locale.getMultiMonthdayShortNames(this.frequencyValue)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
<script>
|
||||
import { getMobileUrlQrCodePath } from '@/lib/qrcode.js';
|
||||
import { getMobileVersionPath } from '@/lib/version.js';
|
||||
import { getMobileVersionPath } from '@/lib/version.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -10,13 +10,14 @@ import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.js';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_CHART_COLORS } from '@/consts/color.ts';
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import statisticsConstants from '@/consts/statistics.js';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import {
|
||||
isArray,
|
||||
isNumber
|
||||
} from '@/lib/common.js';
|
||||
} from '@/lib/common.ts';
|
||||
import {
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
@@ -59,7 +60,7 @@ export default {
|
||||
computed: {
|
||||
...mapStores(useSettingsStore, useUserStore),
|
||||
isDarkMode() {
|
||||
return this.globalTheme.global.name.value === 'dark';
|
||||
return this.globalTheme.global.name.value === ThemeType.Dark;
|
||||
},
|
||||
itemsMap: function () {
|
||||
const map = {};
|
||||
@@ -167,7 +168,7 @@ export default {
|
||||
id: (this.idField && item[this.idField]) ? item[this.idField] : this.getItemName(item[this.nameField]),
|
||||
name: (this.idField && item[this.idField]) ? item[this.idField] : this.getItemName(item[this.nameField]),
|
||||
itemStyle: {
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : colorConstants.defaultChartColors[i % colorConstants.defaultChartColors.length]),
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : DEFAULT_CHART_COLORS[i % DEFAULT_CHART_COLORS.length]),
|
||||
},
|
||||
selected: true,
|
||||
type: 'line',
|
||||
@@ -212,7 +213,7 @@ export default {
|
||||
|
||||
const maxValueText = this.getDisplayCurrency(maxValue, this.defaultCurrency);
|
||||
const minValueText = this.getDisplayCurrency(minValue, this.defaultCurrency);
|
||||
let maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
||||
const maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
@@ -387,7 +388,7 @@ export default {
|
||||
});
|
||||
},
|
||||
getColor: function (color) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ import {
|
||||
getItemByKeyValue,
|
||||
getNameByKeyValue,
|
||||
getPrimaryValueBySecondaryValue
|
||||
} from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.desktop.js';
|
||||
} from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/desktop.js';
|
||||
|
||||
import {
|
||||
mdiChevronRight
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { arrayContainsFieldValue } from '@/lib/common.js';
|
||||
import { getColorsInRows } from '@/lib/color.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||
import { getColorsInRows } from '@/lib/color.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -57,7 +57,7 @@ import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.js';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
getCurrentYear,
|
||||
|
||||
@@ -53,7 +53,7 @@ import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.js';
|
||||
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
|
||||
import {
|
||||
getCurrentUnixTime,
|
||||
getCurrentYear,
|
||||
@@ -65,7 +65,7 @@ import {
|
||||
getTimeValues,
|
||||
getCombinedDateAndTimeValues
|
||||
} from '@/lib/datetime.js';
|
||||
import { createInlinePicker } from '@/lib/ui.mobile.js';
|
||||
import { createInlinePicker } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { arrayContainsFieldValue } from '@/lib/common.js';
|
||||
import { getIconsInRows } from '@/lib/icon.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { arrayContainsFieldValue } from '@/lib/common.ts';
|
||||
import { getIconsInRows } from '@/lib/icon.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { makeButtonCopyToClipboard, changeClipboardObjectText } from '@/lib/misc.js';
|
||||
import { ClipboardHolder } from '@/lib/clipboard.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -54,7 +54,7 @@ export default {
|
||||
watch: {
|
||||
'information': function (newValue) {
|
||||
if (this.clipboardHolder) {
|
||||
changeClipboardObjectText(this.clipboardHolder, newValue);
|
||||
this.clipboardHolder.setClipboardText(newValue);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
}
|
||||
|
||||
if (self.$refs.copyToClipboardIcon) {
|
||||
self.clipboardHolder = makeButtonCopyToClipboard({
|
||||
self.clipboardHolder = ClipboardHolder.create({
|
||||
el: '#copy-to-clipboard-icon',
|
||||
text: self.information,
|
||||
successCallback: function () {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import iconConstants from '@/consts/icon.js';
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { isNumber } from '@/lib/common.js';
|
||||
import { ALL_ACCOUNT_ICONS, DEFAULT_ACCOUNT_ICON, ALL_CATEGORY_ICONS, DEFAULT_CATEGORY_ICON } from '@/consts/icon.ts';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_ACCOUNT_COLOR, DEFAULT_CATEGORY_COLOR } from '@/consts/color.ts';
|
||||
import { isNumber } from '@/lib/common.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -58,25 +58,25 @@ export default {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!iconConstants.allAccountIcons[iconId]) {
|
||||
return iconConstants.defaultAccountIcon.icon;
|
||||
if (!ALL_ACCOUNT_ICONS[iconId]) {
|
||||
return DEFAULT_ACCOUNT_ICON.icon;
|
||||
}
|
||||
|
||||
return iconConstants.allAccountIcons[iconId].icon;
|
||||
return ALL_ACCOUNT_ICONS[iconId].icon;
|
||||
},
|
||||
getCategoryIcon(iconId) {
|
||||
if (isNumber(iconId)) {
|
||||
iconId = iconId.toString();
|
||||
}
|
||||
|
||||
if (!iconConstants.allCategoryIcons[iconId]) {
|
||||
return iconConstants.defaultCategoryIcon.icon;
|
||||
if (!ALL_CATEGORY_ICONS[iconId]) {
|
||||
return DEFAULT_CATEGORY_ICON.icon;
|
||||
}
|
||||
|
||||
return iconConstants.allCategoryIcons[iconId].icon;
|
||||
return ALL_CATEGORY_ICONS[iconId].icon;
|
||||
},
|
||||
getAccountIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultAccountColor) {
|
||||
if (color && color !== DEFAULT_ACCOUNT_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
@@ -93,7 +93,7 @@ export default {
|
||||
return ret;
|
||||
},
|
||||
getCategoryIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultCategoryColor) {
|
||||
if (color && color !== DEFAULT_CATEGORY_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
@@ -110,7 +110,7 @@ export default {
|
||||
return ret;
|
||||
},
|
||||
getDefaultIconStyle(color, defaultColor, additionalColorAttr) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = defaultColor;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import currencyConstants from '@/consts/currency.js';
|
||||
import { isString, isNumber, removeAll } from '@/lib/common.js';
|
||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||
import { isString, isNumber, removeAll } from '@/lib/common.ts';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -100,11 +100,11 @@ export default {
|
||||
return this.$locale.getCurrentDecimalSeparator(this.userStore);
|
||||
},
|
||||
supportDecimalSeparator() {
|
||||
if (!this.currency || !currencyConstants.all[this.currency] || !isNumber(currencyConstants.all[this.currency].fraction)) {
|
||||
if (!this.currency || !ALL_CURRENCIES[this.currency] || !isNumber(ALL_CURRENCIES[this.currency].fraction)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return currencyConstants.all[this.currency].fraction > 0;
|
||||
return ALL_CURRENCIES[this.currency].fraction > 0;
|
||||
},
|
||||
currentDisplay() {
|
||||
const previousValue = this.$locale.appendDigitGroupingSymbol(this.userStore, this.previousValue);
|
||||
@@ -160,8 +160,8 @@ export default {
|
||||
return str;
|
||||
}
|
||||
|
||||
let integer = str.substring(0, decimalSeparatorPos);
|
||||
let decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
||||
const integer = str.substring(0, decimalSeparatorPos);
|
||||
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
||||
let newDecimals = '';
|
||||
|
||||
for (let i = decimals.length - 1; i >= 0; i--) {
|
||||
|
||||
@@ -81,7 +81,7 @@ import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.js';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_CHART_COLORS } from '@/consts/color.ts';
|
||||
import { formatPercent } from '@/lib/numeral.js';
|
||||
|
||||
export default {
|
||||
@@ -139,7 +139,7 @@ export default {
|
||||
value: item[this.valueField],
|
||||
percent: (item[this.percentField] > 0 || item[this.percentField] === 0 || item[this.percentField] === '0') ? item[this.percentField] : (item[this.valueField] / totalValidValue * 100),
|
||||
actualPercent: item[this.valueField] / totalValidValue,
|
||||
color: item[this.colorField] ? item[this.colorField] : colorConstants.defaultChartColors[validItems.length % colorConstants.defaultChartColors.length],
|
||||
color: item[this.colorField] ? item[this.colorField] : DEFAULT_CHART_COLORS[validItems.length % DEFAULT_CHART_COLORS.length],
|
||||
sourceItem: item
|
||||
};
|
||||
|
||||
@@ -223,7 +223,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getColor: function (color) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
} else {
|
||||
color = 'var(--default-icon-color)';
|
||||
|
||||
@@ -68,9 +68,9 @@
|
||||
import { mapStores } from 'pinia';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import templateConstants from '@/consts/template.js';
|
||||
import { sortNumbersArray } from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||
import { sortNumbersArray } from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -100,7 +100,7 @@ export default {
|
||||
return this.$locale.getAllTransactionScheduledFrequencyTypes();
|
||||
},
|
||||
allTemplateScheduledFrequencyTypes() {
|
||||
return templateConstants.allTemplateScheduledFrequencyTypes;
|
||||
return ScheduledTemplateFrequencyType.all();
|
||||
},
|
||||
allWeekDays() {
|
||||
return this.$locale.getAllWeekDays(this.firstDayOfWeek);
|
||||
@@ -134,9 +134,9 @@ export default {
|
||||
if (this.currentFrequencyType !== value) {
|
||||
this.currentFrequencyType = value;
|
||||
|
||||
if (value === templateConstants.allTemplateScheduledFrequencyTypes.Weekly.type) {
|
||||
if (value === ScheduledTemplateFrequencyType.Weekly.type) {
|
||||
this.currentFrequencyValue = [this.firstDayOfWeek];
|
||||
} else if (value === templateConstants.allTemplateScheduledFrequencyTypes.Monthly.type) {
|
||||
} else if (value === ScheduledTemplateFrequencyType.Monthly.type) {
|
||||
this.currentFrequencyValue = [1];
|
||||
} else {
|
||||
this.currentFrequencyValue = [];
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
import { mapStores } from 'pinia';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
||||
|
||||
import { copyArrayTo } from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { copyArrayTo } from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isArray } from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
import { isArray } from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
@@ -85,7 +85,7 @@ export default {
|
||||
if (isArray(this.items)) {
|
||||
count = this.items.length;
|
||||
} else {
|
||||
for (let field in this.items) {
|
||||
for (const field in this.items) {
|
||||
if (!Object.prototype.hasOwnProperty.call(this.items, field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -93,10 +93,10 @@ import { mapStores } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/setting.js';
|
||||
import { useUserStore } from '@/stores/user.js';
|
||||
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { DEFAULT_ICON_COLOR, DEFAULT_CHART_COLORS } from '@/consts/color.ts';
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import statisticsConstants from '@/consts/statistics.js';
|
||||
import { isNumber } from '@/lib/common.js';
|
||||
import { isNumber } from '@/lib/common.ts';
|
||||
import {
|
||||
getYearMonthFirstUnixTime,
|
||||
getYearMonthLastUnixTime,
|
||||
@@ -154,7 +154,7 @@ export default {
|
||||
const legend = {
|
||||
id: id,
|
||||
name: (this.nameField && item[this.nameField]) ? this.getItemName(item[this.nameField]) : id,
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : colorConstants.defaultChartColors[i % colorConstants.defaultChartColors.length]),
|
||||
color: this.getColor(item[this.colorField] ? item[this.colorField] : DEFAULT_CHART_COLORS[i % DEFAULT_CHART_COLORS.length]),
|
||||
displayOrders: (this.displayOrdersField && item[this.displayOrdersField]) ? item[this.displayOrdersField] : [0]
|
||||
};
|
||||
|
||||
@@ -322,7 +322,7 @@ export default {
|
||||
}
|
||||
},
|
||||
getColor: function (color) {
|
||||
if (color && color !== colorConstants.defaultColor) {
|
||||
if (color && color !== DEFAULT_ICON_COLOR) {
|
||||
color = '#' + color;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
import {
|
||||
getItemByKeyValue,
|
||||
getPrimaryValueBySecondaryValue
|
||||
} from '@/lib/common.js';
|
||||
import { scrollToSelectedItem } from '@/lib/ui.mobile.js';
|
||||
} from '@/lib/common.ts';
|
||||
import { scrollToSelectedItem } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
const allAccountCategories = {
|
||||
Cash: {
|
||||
id: 1,
|
||||
name: 'Cash',
|
||||
defaultAccountIconId: '1'
|
||||
},
|
||||
CheckingAccount: {
|
||||
id: 2,
|
||||
name: 'Checking Account',
|
||||
defaultAccountIconId: '100'
|
||||
},
|
||||
SavingsAccount: {
|
||||
id: 8,
|
||||
name: 'Savings Account',
|
||||
defaultAccountIconId: '100'
|
||||
},
|
||||
CreditCard: {
|
||||
id: 3,
|
||||
name: 'Credit Card',
|
||||
defaultAccountIconId: '100'
|
||||
},
|
||||
VirtualAccount: {
|
||||
id: 4,
|
||||
name: 'Virtual Account',
|
||||
defaultAccountIconId: '500'
|
||||
},
|
||||
DebtAccount: {
|
||||
id: 5,
|
||||
name: 'Debt Account',
|
||||
defaultAccountIconId: '600'
|
||||
},
|
||||
Receivables: {
|
||||
id: 6,
|
||||
name: 'Receivables',
|
||||
defaultAccountIconId: '700'
|
||||
},
|
||||
CertificatePfDeposit: {
|
||||
id: 9,
|
||||
name: 'Certificate of Deposit',
|
||||
defaultAccountIconId: '110'
|
||||
},
|
||||
InvestmentAccount: {
|
||||
id: 7,
|
||||
name: 'Investment Account',
|
||||
defaultAccountIconId: '800'
|
||||
}
|
||||
};
|
||||
|
||||
const allAccountCategoriesArray = [
|
||||
allAccountCategories.Cash,
|
||||
allAccountCategories.CheckingAccount,
|
||||
allAccountCategories.SavingsAccount,
|
||||
allAccountCategories.CreditCard,
|
||||
allAccountCategories.VirtualAccount,
|
||||
allAccountCategories.DebtAccount,
|
||||
allAccountCategories.Receivables,
|
||||
allAccountCategories.CertificatePfDeposit,
|
||||
allAccountCategories.InvestmentAccount
|
||||
];
|
||||
const allAccountTypes = {
|
||||
SingleAccount: 1,
|
||||
MultiSubAccounts: 2
|
||||
};
|
||||
const allAccountTypesArray = [
|
||||
{
|
||||
id: allAccountTypes.SingleAccount,
|
||||
name: 'Single Account'
|
||||
}, {
|
||||
id: allAccountTypes.MultiSubAccounts,
|
||||
name: 'Multiple Sub-accounts'
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
cashCategoryType: allAccountCategories.Cash.id,
|
||||
creditCardCategoryType: allAccountCategories.CreditCard.id,
|
||||
allCategories: allAccountCategoriesArray,
|
||||
allAccountTypes: allAccountTypes,
|
||||
allAccountTypesArray: allAccountTypesArray,
|
||||
};
|
||||
@@ -1,27 +1,45 @@
|
||||
const defaultTimeout = 10000; // 10s
|
||||
const uploadTimeout = 30000; // 30s
|
||||
const importTimeout = 1800000; // 1800s
|
||||
const baseApiUrlPath = '/api';
|
||||
const baseQrcodePath = '/qrcode';
|
||||
const baseProxyUrlPath = '/proxy';
|
||||
const baseAmapApiProxyUrlPath = '/_AMapService';
|
||||
const apiNotFoundErrorCode = 100001;
|
||||
const validatorErrorCode = 200000;
|
||||
const userEmailNotVerifiedErrorCode = 201020;
|
||||
const transactionCannotCreateInThisTimeErrorCode = 205017;
|
||||
const transactionCannotModifyInThisTimeErrorCode = 205018;
|
||||
const transactionPictureNotFoundErrorCode = 211001;
|
||||
const googleMapJavascriptUrl = 'https://maps.googleapis.com/maps/api/js';
|
||||
const baiduMapJavascriptUrl = 'https://api.map.baidu.com/api?v=3.0';
|
||||
const amapJavascriptUrl = 'https://webapi.amap.com/maps?v=2.0';
|
||||
export const BASE_API_URL_PATH: string = '/api';
|
||||
export const BASE_QRCODE_PATH: string = '/qrcode';
|
||||
export const BASE_PROXY_URL_PATH: string = '/proxy';
|
||||
export const BASE_AMAP_API_PROXY_URL_PATH: string = '/_AMapService';
|
||||
|
||||
const specifiedApiNotFoundErrors = {
|
||||
export const DEFAULT_API_TIMEOUT: number = 10000; // 10s
|
||||
export const DEFAULT_UPLOAD_API_TIMEOUT: number = 30000; // 30s
|
||||
export const DEFAULT_IMPORT_API_TIMEOUT: number = 1800000; // 1800s
|
||||
|
||||
export const GOOGLE_MAP_JAVASCRIPT_URL: string = 'https://maps.googleapis.com/maps/api/js';
|
||||
export const BAIDU_MAP_JAVASCRIPT_URL: string = 'https://api.map.baidu.com/api?v=3.0';
|
||||
export const AMAP_JAVASCRIPT_URL: string = 'https://webapi.amap.com/maps?v=2.0';
|
||||
|
||||
export enum KnownErrorCode {
|
||||
ApiNotFound = 100001,
|
||||
ValidatorError = 200000,
|
||||
UserEmailNotVerified = 201020,
|
||||
TransactionCannotCreateInThisTime = 205017,
|
||||
TransactionCannotModifyInThisTime = 205018,
|
||||
TransactionPictureNotFound = 211001
|
||||
}
|
||||
|
||||
export interface SpecifiedApiError {
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
export const SPECIFIED_API_NOT_FOUND_ERRORS: Record<string, SpecifiedApiError> = {
|
||||
'/api/register.json': {
|
||||
message: 'User registration is disabled'
|
||||
}
|
||||
};
|
||||
|
||||
const parameterizedErrors = [
|
||||
export interface ParameterizedError {
|
||||
readonly localeKey: string;
|
||||
readonly regex: RegExp;
|
||||
readonly parameters: {
|
||||
readonly field: string;
|
||||
readonly localized: boolean;
|
||||
}[];
|
||||
}
|
||||
|
||||
export const PARAMETERIZED_ERRORS: ParameterizedError[] = [
|
||||
{
|
||||
localeKey: 'parameter invalid',
|
||||
regex: /^parameter "(\w+)" is invalid$/,
|
||||
@@ -142,24 +160,3 @@ const parameterizedErrors = [
|
||||
}]
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
defaultTimeout: defaultTimeout,
|
||||
uploadTimeout: uploadTimeout,
|
||||
importTimeout: importTimeout,
|
||||
baseApiUrlPath: baseApiUrlPath,
|
||||
baseQrcodePath: baseQrcodePath,
|
||||
baseProxyUrlPath: baseProxyUrlPath,
|
||||
baseAmapApiProxyUrlPath: baseAmapApiProxyUrlPath,
|
||||
apiNotFoundErrorCode: apiNotFoundErrorCode,
|
||||
validatorErrorCode: validatorErrorCode,
|
||||
userEmailNotVerifiedErrorCode: userEmailNotVerifiedErrorCode,
|
||||
transactionCannotCreateInThisTimeErrorCode: transactionCannotCreateInThisTimeErrorCode,
|
||||
transactionCannotModifyInThisTimeErrorCode: transactionCannotModifyInThisTimeErrorCode,
|
||||
transactionPictureNotFoundErrorCode: transactionPictureNotFoundErrorCode,
|
||||
specifiedApiNotFoundErrors: specifiedApiNotFoundErrors,
|
||||
parameterizedErrors: parameterizedErrors,
|
||||
googleMapJavascriptUrl: googleMapJavascriptUrl,
|
||||
baiduMapJavascriptUrl: baiduMapJavascriptUrl,
|
||||
amapJavascriptUrl: amapJavascriptUrl
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
const baseImagePath = 'img';
|
||||
const ezBookkeepingLogoPath = baseImagePath + '/ezbookkeeping-192.png';
|
||||
|
||||
export default {
|
||||
ezBookkeepingLogoPath: ezBookkeepingLogoPath
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
const baseImagePath: string = 'img';
|
||||
export const APPLICATION_LOGO_PATH: string = baseImagePath + '/ezbookkeeping-192.png';
|
||||
@@ -1,10 +1,19 @@
|
||||
const allCategoryTypes = {
|
||||
Income: 1,
|
||||
Expense: 2,
|
||||
Transfer: 3
|
||||
};
|
||||
import type { ColorValue } from '@/core/color.ts';
|
||||
|
||||
const defaultExpenseCategories = [
|
||||
export interface PresetCategory {
|
||||
name: string;
|
||||
categoryIconId: string;
|
||||
color: ColorValue;
|
||||
subCategories: PresetSubCategory[];
|
||||
}
|
||||
|
||||
export interface PresetSubCategory {
|
||||
name: string;
|
||||
categoryIconId: string;
|
||||
color: ColorValue;
|
||||
}
|
||||
|
||||
export const DEFAULT_EXPENSE_CATEGORIES: PresetCategory[] = [
|
||||
{
|
||||
name: 'Food & Drink',
|
||||
categoryIconId: '1',
|
||||
@@ -294,7 +303,7 @@ const defaultExpenseCategories = [
|
||||
}
|
||||
];
|
||||
|
||||
const defaultIncomeCategories = [
|
||||
export const DEFAULT_INCOME_CATEGORIES: PresetCategory[] = [
|
||||
{
|
||||
name: 'Occupational Earnings',
|
||||
categoryIconId: '2000',
|
||||
@@ -373,7 +382,7 @@ const defaultIncomeCategories = [
|
||||
}
|
||||
];
|
||||
|
||||
const defaultTransferCategories = [
|
||||
export const DEFAULT_TRANSFER_CATEGORIES: PresetCategory[] = [
|
||||
{
|
||||
name: 'General Transfer',
|
||||
categoryIconId: '4000',
|
||||
@@ -447,10 +456,3 @@ const defaultTransferCategories = [
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
allCategoryTypes: allCategoryTypes,
|
||||
defaultExpenseCategories: defaultExpenseCategories,
|
||||
defaultIncomeCategories: defaultIncomeCategories,
|
||||
defaultTransferCategories: defaultTransferCategories,
|
||||
};
|
||||
@@ -1,98 +0,0 @@
|
||||
const defaultColor = '000000';
|
||||
const allAvailableColors = [
|
||||
'000000', // black
|
||||
'8e8e93', // gray
|
||||
'ff3b30', // red
|
||||
'ff2d55', // pink
|
||||
'ff6b22', // deep orange
|
||||
'ff9500', // orange
|
||||
'ffcc00', // yellow
|
||||
'cddc39', // lime
|
||||
'009688', // teal
|
||||
'4cd964', // green
|
||||
'5ac8fa', // light blue
|
||||
'2196f3', // blue
|
||||
'673ab7', // deep purple
|
||||
'9c27b0', // purple
|
||||
];
|
||||
|
||||
const defaultChartColors = [
|
||||
'cc4a66',
|
||||
'e3564a',
|
||||
'fc892c',
|
||||
'ffc349',
|
||||
'4dd291',
|
||||
'24ceb3',
|
||||
'2ab4d0',
|
||||
'065786',
|
||||
'713670',
|
||||
'8e1d51'
|
||||
];
|
||||
|
||||
const allAmountColors = {
|
||||
Green: {
|
||||
type: 1,
|
||||
name: 'Green',
|
||||
lightThemeColor: '#009688',
|
||||
darkThemeColor: '#009688',
|
||||
expenseClassName: 'expense-amount-color-green',
|
||||
incomeClassName: 'income-amount-color-green'
|
||||
},
|
||||
Red: {
|
||||
type: 2,
|
||||
name: 'Red',
|
||||
lightThemeColor: '#d43f3f',
|
||||
darkThemeColor: '#d43f3f',
|
||||
expenseClassName: 'expense-amount-color-red',
|
||||
incomeClassName: 'income-amount-color-red'
|
||||
},
|
||||
Yellow: {
|
||||
type: 3,
|
||||
name: 'Yellow',
|
||||
lightThemeColor: '#e2b60a',
|
||||
darkThemeColor: '#e2b60a',
|
||||
expenseClassName: 'expense-amount-color-yellow',
|
||||
incomeClassName: 'income-amount-color-yellow'
|
||||
},
|
||||
BlackOrWhite: {
|
||||
type: 4,
|
||||
name: 'Black or White',
|
||||
lightThemeColor: '#413935',
|
||||
darkThemeColor: '#fcf0e3',
|
||||
expenseClassName: 'expense-amount-color-blackorwhite',
|
||||
incomeClassName: 'income-amount-color-blackorwhite'
|
||||
}
|
||||
}
|
||||
|
||||
const allAmountColorsArray = [
|
||||
allAmountColors.Green,
|
||||
allAmountColors.Red,
|
||||
allAmountColors.Yellow,
|
||||
allAmountColors.BlackOrWhite
|
||||
];
|
||||
|
||||
const allAmountColorTypesMap = {
|
||||
[allAmountColors.Green.type]: allAmountColors.Green,
|
||||
[allAmountColors.Red.type]: allAmountColors.Red,
|
||||
[allAmountColors.Yellow.type]: allAmountColors.Yellow,
|
||||
[allAmountColors.BlackOrWhite.type]: allAmountColors.BlackOrWhite
|
||||
};
|
||||
|
||||
const defaultExpenseIncomeAmountValue = 0;
|
||||
const defaultExpenseAmountColor = allAmountColors.Green;
|
||||
const defaultIncomeAmountColor = allAmountColors.Red;
|
||||
|
||||
export default {
|
||||
defaultColor: defaultColor,
|
||||
allAccountColors: allAvailableColors,
|
||||
defaultAccountColor: defaultColor,
|
||||
allCategoryColors: allAvailableColors,
|
||||
defaultCategoryColor: defaultColor,
|
||||
defaultChartColors: defaultChartColors,
|
||||
allAmountColors: allAmountColors,
|
||||
allAmountColorsArray: allAmountColorsArray,
|
||||
allAmountColorTypesMap: allAmountColorTypesMap,
|
||||
defaultExpenseIncomeAmountValue: defaultExpenseIncomeAmountValue,
|
||||
defaultExpenseAmountColor: defaultExpenseAmountColor,
|
||||
defaultIncomeAmountColor: defaultIncomeAmountColor,
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { ColorValue } from '@/core/color.ts';
|
||||
|
||||
const defaultColor: ColorValue = '000000';
|
||||
|
||||
export const DEFAULT_ICON_COLOR: ColorValue = defaultColor;
|
||||
export const DEFAULT_ACCOUNT_COLOR: ColorValue = defaultColor;
|
||||
export const DEFAULT_CATEGORY_COLOR: ColorValue = defaultColor;
|
||||
|
||||
const allAvailableColors: ColorValue[] = [
|
||||
'000000', // black
|
||||
'8e8e93', // gray
|
||||
'ff3b30', // red
|
||||
'ff2d55', // pink
|
||||
'ff6b22', // deep orange
|
||||
'ff9500', // orange
|
||||
'ffcc00', // yellow
|
||||
'cddc39', // lime
|
||||
'009688', // teal
|
||||
'4cd964', // green
|
||||
'5ac8fa', // light blue
|
||||
'2196f3', // blue
|
||||
'673ab7', // deep purple
|
||||
'9c27b0', // purple
|
||||
];
|
||||
|
||||
export const ALL_ACCOUNT_COLORS: ColorValue[] = allAvailableColors;
|
||||
export const ALL_CATEGORY_COLORS: ColorValue[] = allAvailableColors;
|
||||
|
||||
export const DEFAULT_CHART_COLORS: ColorValue[] = [
|
||||
'cc4a66',
|
||||
'e3564a',
|
||||
'fc892c',
|
||||
'ffc349',
|
||||
'4dd291',
|
||||
'24ceb3',
|
||||
'2ab4d0',
|
||||
'065786',
|
||||
'713670',
|
||||
'8e1d51'
|
||||
];
|
||||
@@ -1,9 +1,16 @@
|
||||
const parentAccountCurrencyPlaceholder = '---';
|
||||
const defaultCurrencySymbol = '¤';
|
||||
export interface CurrencyInfo {
|
||||
readonly code: string,
|
||||
readonly fraction?: number,
|
||||
readonly symbol?: {
|
||||
readonly normal: string,
|
||||
readonly plural?: string
|
||||
},
|
||||
readonly unit: string
|
||||
}
|
||||
|
||||
// ISO 4217
|
||||
// Reference: https://www.six-group.com/dam/download/financial-information/data-center/iso-currrency/lists/list-one.xml
|
||||
const allCurrencies = {
|
||||
export const ALL_CURRENCIES: Record<string, CurrencyInfo> = {
|
||||
'AED': { // UAE Dirham
|
||||
code: 'AED',
|
||||
fraction: 2,
|
||||
@@ -1284,177 +1291,6 @@ const allCurrencies = {
|
||||
}
|
||||
};
|
||||
|
||||
const allCurrencyDisplaySymbol = {
|
||||
None: 0,
|
||||
Symbol: 1,
|
||||
Code: 2,
|
||||
Unit: 3,
|
||||
Name: 4
|
||||
};
|
||||
|
||||
const allCurrencyDisplayLocation = {
|
||||
BeforeAmount: 0,
|
||||
AfterAmount: 1
|
||||
};
|
||||
|
||||
const allCurrencyDisplayType = {
|
||||
None: {
|
||||
type: 1,
|
||||
name: 'None',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.None,
|
||||
separator: ''
|
||||
},
|
||||
SymbolBeforeAmount: {
|
||||
type: 2,
|
||||
name: 'Currency Symbol',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Symbol,
|
||||
location: allCurrencyDisplayLocation.BeforeAmount,
|
||||
separator: ' '
|
||||
},
|
||||
SymbolAfterAmount: {
|
||||
type: 3,
|
||||
name: 'Currency Symbol',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Symbol,
|
||||
location: allCurrencyDisplayLocation.AfterAmount,
|
||||
separator: ' '
|
||||
},
|
||||
SymbolBeforeAmountWithoutSpace: {
|
||||
type: 4,
|
||||
name: 'Currency Symbol',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Symbol,
|
||||
location: allCurrencyDisplayLocation.BeforeAmount,
|
||||
separator: ''
|
||||
},
|
||||
SymbolAfterAmountWithoutSpace: {
|
||||
type: 5,
|
||||
name: 'Currency Symbol',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Symbol,
|
||||
location: allCurrencyDisplayLocation.AfterAmount,
|
||||
separator: ''
|
||||
},
|
||||
CodeBeforeAmount: {
|
||||
type: 6,
|
||||
name: 'Currency Code',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Code,
|
||||
location: allCurrencyDisplayLocation.BeforeAmount,
|
||||
separator: ' '
|
||||
},
|
||||
CodeAfterAmount: {
|
||||
type: 7,
|
||||
name: 'Currency Code',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Code,
|
||||
location: allCurrencyDisplayLocation.AfterAmount,
|
||||
separator: ' '
|
||||
},
|
||||
UnitBeforeAmount: {
|
||||
type: 8,
|
||||
name: 'Currency Unit',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Unit,
|
||||
location: allCurrencyDisplayLocation.BeforeAmount,
|
||||
separator: ' '
|
||||
},
|
||||
UnitAfterAmount: {
|
||||
type: 9,
|
||||
name: 'Currency Unit',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Unit,
|
||||
location: allCurrencyDisplayLocation.AfterAmount,
|
||||
separator: ' '
|
||||
},
|
||||
NameBeforeAmount: {
|
||||
type: 10,
|
||||
name: 'Currency Name',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Name,
|
||||
location: allCurrencyDisplayLocation.BeforeAmount,
|
||||
separator: ' '
|
||||
},
|
||||
NameAfterAmount: {
|
||||
type: 11,
|
||||
name: 'Currency Name',
|
||||
fraction: 2,
|
||||
symbol: allCurrencyDisplaySymbol.Name,
|
||||
location: allCurrencyDisplayLocation.AfterAmount,
|
||||
separator: ' '
|
||||
}
|
||||
};
|
||||
|
||||
const allCurrencyDisplayTypeArray = [
|
||||
allCurrencyDisplayType.None,
|
||||
allCurrencyDisplayType.SymbolBeforeAmount,
|
||||
allCurrencyDisplayType.SymbolAfterAmount,
|
||||
allCurrencyDisplayType.SymbolBeforeAmountWithoutSpace,
|
||||
allCurrencyDisplayType.SymbolAfterAmountWithoutSpace,
|
||||
allCurrencyDisplayType.CodeBeforeAmount,
|
||||
allCurrencyDisplayType.CodeAfterAmount,
|
||||
allCurrencyDisplayType.UnitBeforeAmount,
|
||||
allCurrencyDisplayType.UnitAfterAmount,
|
||||
allCurrencyDisplayType.NameBeforeAmount,
|
||||
allCurrencyDisplayType.NameAfterAmount
|
||||
];
|
||||
|
||||
const allCurrencyDisplayTypeMap = {
|
||||
[allCurrencyDisplayType.None.type]: allCurrencyDisplayType.None,
|
||||
[allCurrencyDisplayType.SymbolBeforeAmount.type]: allCurrencyDisplayType.SymbolBeforeAmount,
|
||||
[allCurrencyDisplayType.SymbolAfterAmount.type]: allCurrencyDisplayType.SymbolAfterAmount,
|
||||
[allCurrencyDisplayType.SymbolBeforeAmountWithoutSpace.type]: allCurrencyDisplayType.SymbolBeforeAmountWithoutSpace,
|
||||
[allCurrencyDisplayType.SymbolAfterAmountWithoutSpace.type]: allCurrencyDisplayType.SymbolAfterAmountWithoutSpace,
|
||||
[allCurrencyDisplayType.CodeBeforeAmount.type]: allCurrencyDisplayType.CodeBeforeAmount,
|
||||
[allCurrencyDisplayType.CodeAfterAmount.type]: allCurrencyDisplayType.CodeAfterAmount,
|
||||
[allCurrencyDisplayType.UnitBeforeAmount.type]: allCurrencyDisplayType.UnitBeforeAmount,
|
||||
[allCurrencyDisplayType.UnitAfterAmount.type]: allCurrencyDisplayType.UnitAfterAmount,
|
||||
[allCurrencyDisplayType.NameBeforeAmount.type]: allCurrencyDisplayType.NameBeforeAmount,
|
||||
[allCurrencyDisplayType.NameAfterAmount.type]: allCurrencyDisplayType.NameAfterAmount
|
||||
};
|
||||
|
||||
const defaultCurrency = allCurrencies.USD.code;
|
||||
const defaultCurrencyDisplayType = allCurrencyDisplayType.SymbolBeforeAmount;
|
||||
const defaultCurrencyDisplayTypeValue = 0;
|
||||
|
||||
const allCurrencySortingTypes = {
|
||||
Name: {
|
||||
type: 0,
|
||||
name: 'Currency Name'
|
||||
},
|
||||
CurrencyCode: {
|
||||
type: 1,
|
||||
name: 'Currency Code'
|
||||
},
|
||||
ExchangeRate: {
|
||||
type: 2,
|
||||
name: 'Exchange Rate'
|
||||
}
|
||||
};
|
||||
|
||||
const allCurrencySortingTypesArray = [
|
||||
allCurrencySortingTypes.Name,
|
||||
allCurrencySortingTypes.CurrencyCode,
|
||||
allCurrencySortingTypes.ExchangeRate
|
||||
]
|
||||
|
||||
const defaultCurrencySortingType = allCurrencySortingTypes.Name.type;
|
||||
|
||||
export default {
|
||||
parentAccountCurrencyPlaceholder: parentAccountCurrencyPlaceholder,
|
||||
defaultCurrencySymbol: defaultCurrencySymbol,
|
||||
all: allCurrencies,
|
||||
defaultCurrency: defaultCurrency,
|
||||
allCurrencyDisplaySymbol: allCurrencyDisplaySymbol,
|
||||
allCurrencyDisplayLocation: allCurrencyDisplayLocation,
|
||||
allCurrencyDisplayType: allCurrencyDisplayType,
|
||||
allCurrencyDisplayTypeArray: allCurrencyDisplayTypeArray,
|
||||
allCurrencyDisplayTypeMap: allCurrencyDisplayTypeMap,
|
||||
defaultCurrencyDisplayType: defaultCurrencyDisplayType,
|
||||
defaultCurrencyDisplayTypeValue: defaultCurrencyDisplayTypeValue,
|
||||
allCurrencySortingTypes: allCurrencySortingTypes,
|
||||
allCurrencySortingTypesArray: allCurrencySortingTypesArray,
|
||||
defaultCurrencySortingType: defaultCurrencySortingType
|
||||
};
|
||||
export const DEFAULT_CURRENCY_SYMBOL: string = '¤';
|
||||
export const DEFAULT_CURRENCY_CODE: string = ALL_CURRENCIES.USD.code;
|
||||
export const PARENT_ACCOUNT_CURRENCY_PLACEHOLDER: string = '---';
|
||||
@@ -1,6 +1,23 @@
|
||||
const supportedImageExtensions = '.jpg,.jpeg,.png,.gif,.webp';
|
||||
export const SUPPORTED_IMAGE_EXTENSIONS: string = '.jpg,.jpeg,.png,.gif,.webp';
|
||||
|
||||
const supportedImportFileTypes = [
|
||||
export interface ImportFileType {
|
||||
readonly type: string;
|
||||
readonly name: string;
|
||||
readonly extensions: string;
|
||||
readonly subTypes?: ImportFileTypeSubType[];
|
||||
readonly document?: {
|
||||
readonly supportMultiLanguages: boolean | string;
|
||||
readonly anchor: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ImportFileTypeSubType {
|
||||
readonly type: string;
|
||||
readonly name: string;
|
||||
readonly extensions?: string;
|
||||
}
|
||||
|
||||
export const SUPPORTED_IMPORT_FILE_TYPES: ImportFileType[] = [
|
||||
{
|
||||
type: 'ezbookkeeping',
|
||||
name: 'ezbookkeeping Data Export File',
|
||||
@@ -120,8 +137,3 @@ const supportedImportFileTypes = [
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
supportedImageExtensions: supportedImageExtensions,
|
||||
supportedImportFileTypes: supportedImportFileTypes
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
const allFontSize = {
|
||||
Small: {
|
||||
type: 0,
|
||||
className: 'font-size-small'
|
||||
},
|
||||
Default: {
|
||||
type: 1,
|
||||
className: 'font-size-default'
|
||||
},
|
||||
Large: {
|
||||
type: 2,
|
||||
className: 'font-size-large'
|
||||
},
|
||||
XLarge: {
|
||||
type: 3,
|
||||
className: 'font-size-x-large'
|
||||
},
|
||||
XXLarge: {
|
||||
type: 4,
|
||||
className: 'font-size-xx-large'
|
||||
},
|
||||
XXXLarge: {
|
||||
type: 5,
|
||||
className: 'font-size-xxx-large'
|
||||
},
|
||||
XXXXLarge: {
|
||||
type: 6,
|
||||
className: 'font-size-xxxx-large'
|
||||
}
|
||||
}
|
||||
|
||||
const allFontSizeArray = [
|
||||
allFontSize.Small,
|
||||
allFontSize.Default,
|
||||
allFontSize.Large,
|
||||
allFontSize.XLarge,
|
||||
allFontSize.XXLarge,
|
||||
allFontSize.XXXLarge,
|
||||
allFontSize.XXXXLarge
|
||||
];
|
||||
|
||||
const defaultFontSize = allFontSize.Default;
|
||||
const fontSizePreviewClassNamePrefix = 'preview-';
|
||||
|
||||
export default {
|
||||
allFontSize: allFontSize,
|
||||
allFontSizeArray: allFontSizeArray,
|
||||
defaultFontSize: defaultFontSize,
|
||||
fontSizePreviewClassNamePrefix: fontSizePreviewClassNamePrefix
|
||||
};
|
||||
@@ -1,5 +1,8 @@
|
||||
const defaultAccountIconId = '1';
|
||||
const allAccountIcons = {
|
||||
import type { IconInfo } from '@/core/icon.ts';
|
||||
|
||||
export const DEFAULT_ACCOUNT_ICON_ID = '1';
|
||||
|
||||
export const ALL_ACCOUNT_ICONS: Record<string, IconInfo> = {
|
||||
// 1 - 99 : Cash Symbols
|
||||
'1': {
|
||||
icon: 'las la-wallet'
|
||||
@@ -158,8 +161,11 @@ const allAccountIcons = {
|
||||
}
|
||||
};
|
||||
|
||||
const defaultCategoryIconId = '1';
|
||||
const allCategoryIcons = {
|
||||
export const DEFAULT_ACCOUNT_ICON = ALL_ACCOUNT_ICONS[DEFAULT_ACCOUNT_ICON_ID];
|
||||
|
||||
export const DEFAULT_CATEGORY_ICON_ID = '1';
|
||||
|
||||
export const ALL_CATEGORY_ICONS = {
|
||||
// 1 - 99 : Expense - Food & Drink
|
||||
'1': {
|
||||
icon: 'las la-utensils'
|
||||
@@ -830,11 +836,4 @@ const allCategoryIcons = {
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
allAccountIcons: allAccountIcons,
|
||||
defaultAccountIconId: defaultAccountIconId,
|
||||
defaultAccountIcon: allAccountIcons[defaultAccountIconId],
|
||||
allCategoryIcons: allCategoryIcons,
|
||||
defaultCategoryIconId: defaultCategoryIconId,
|
||||
defaultCategoryIcon: allCategoryIcons[defaultCategoryIconId]
|
||||
};
|
||||
export const DEFAULT_CATEGORY_ICON = ALL_CATEGORY_ICONS[DEFAULT_CATEGORY_ICON_ID];
|
||||
@@ -1,4 +1,23 @@
|
||||
const leafletTileSources = {
|
||||
export interface PresetLeafletTileSource {
|
||||
readonly tileUrlFormat: string;
|
||||
readonly tileUrlSubDomains: string;
|
||||
readonly tileUrlExtraParams?: PresetLeafletTileSourceExtraParam[];
|
||||
readonly annotationUrlFormat?: string;
|
||||
readonly annotationUrlSubDomains?: string;
|
||||
readonly annotationUrlExtraParams?: PresetLeafletTileSourceExtraParam[];
|
||||
readonly minZoom: number;
|
||||
readonly maxZoom: number;
|
||||
readonly defaultZoomLevel: number;
|
||||
readonly website: string;
|
||||
readonly attribution: string;
|
||||
}
|
||||
|
||||
export interface PresetLeafletTileSourceExtraParam {
|
||||
readonly paramName: string;
|
||||
readonly paramValueType: string;
|
||||
}
|
||||
|
||||
export const LEAFLET_TILE_SOURCES: Record<string, PresetLeafletTileSource> = {
|
||||
'openstreetmap': {
|
||||
tileUrlFormat: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
tileUrlSubDomains: 'abc',
|
||||
@@ -96,7 +115,3 @@ const leafletTileSources = {
|
||||
attribution : '<a href="https://www.tianditu.gov.cn" class="external" target="_blank">天地图</a>'
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
leafletTileSources: leafletTileSources
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
const allTemplateTypes = {
|
||||
Normal: 1,
|
||||
Schedule: 2,
|
||||
};
|
||||
|
||||
const allTemplateScheduledFrequencyTypes = {
|
||||
Disabled: {
|
||||
type: 0,
|
||||
name: 'Disabled'
|
||||
},
|
||||
Weekly: {
|
||||
type: 1,
|
||||
name: 'Weekly'
|
||||
},
|
||||
Monthly: {
|
||||
type: 2,
|
||||
name: 'Monthly'
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
allTemplateTypes: allTemplateTypes,
|
||||
allTemplateScheduledFrequencyTypes: allTemplateScheduledFrequencyTypes,
|
||||
}
|
||||
@@ -1,5 +1,15 @@
|
||||
export interface TimezoneInfo {
|
||||
readonly displayName: string;
|
||||
readonly timezoneName: string;
|
||||
}
|
||||
|
||||
export const UTC_TIMEZONE: TimezoneInfo = {
|
||||
displayName: 'Coordinated Universal Time',
|
||||
timezoneName: 'Etc/GMT'
|
||||
};
|
||||
|
||||
// Reference: https://github.com/nodatime/nodatime/blob/main/data/cldr/windowsZones-45.xml
|
||||
const allAvailableTimezones = [
|
||||
export const ALL_TIMEZONES: TimezoneInfo[] = [
|
||||
// UTC-12:00
|
||||
{
|
||||
displayName: 'International Date Line West',
|
||||
@@ -591,17 +601,3 @@ const allAvailableTimezones = [
|
||||
timezoneName: 'Pacific/Kiritimati'
|
||||
}
|
||||
];
|
||||
|
||||
const allTimezoneTypesUsedForStatistics = {
|
||||
ApplicationTimezone: 0,
|
||||
TransactionTimezone: 1
|
||||
};
|
||||
|
||||
const defaultTimezoneTypesUsedForStatistics = allTimezoneTypesUsedForStatistics.ApplicationTimezone;
|
||||
|
||||
export default {
|
||||
all: allAvailableTimezones,
|
||||
utcTimezoneName: 'Etc/GMT',
|
||||
allTimezoneTypesUsedForStatistics: allTimezoneTypesUsedForStatistics,
|
||||
defaultTimezoneTypesUsedForStatistics: defaultTimezoneTypesUsedForStatistics
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
const allTransactionTypes = {
|
||||
ModifyBalance: 1,
|
||||
Income: 2,
|
||||
Expense: 3,
|
||||
Transfer: 4
|
||||
};
|
||||
|
||||
const allTransactionEditScopeTypes = {
|
||||
None: {
|
||||
type: 0,
|
||||
name: 'None'
|
||||
},
|
||||
All: {
|
||||
type: 1,
|
||||
name: 'All'
|
||||
},
|
||||
TodayOrLater: {
|
||||
type: 2,
|
||||
name: 'Today or later'
|
||||
},
|
||||
Recent24HoursOrLater: {
|
||||
type: 3,
|
||||
name: 'Recent 24 hours or later'
|
||||
},
|
||||
ThisWeekOrLater: {
|
||||
type: 4,
|
||||
name: 'This week or later'
|
||||
},
|
||||
ThisMonthOrLater: {
|
||||
type: 5,
|
||||
name: 'This month or later'
|
||||
},
|
||||
ThisYearOrLater: {
|
||||
type: 6,
|
||||
name: 'This year or later'
|
||||
}
|
||||
};
|
||||
|
||||
const allTransactionTagFilterTypes = {
|
||||
HasAny: {
|
||||
type: 0,
|
||||
name: 'With Any Selected Tags'
|
||||
},
|
||||
HasAll: {
|
||||
type: 1,
|
||||
name: 'With All Selected Tags'
|
||||
},
|
||||
NotHasAny: {
|
||||
type: 2,
|
||||
name: 'Without Any Selected Tags'
|
||||
},
|
||||
NotHasAll: {
|
||||
type: 3,
|
||||
name: 'Without All Selected Tags'
|
||||
}
|
||||
};
|
||||
|
||||
const defaultTransactionTagFilterType = allTransactionTagFilterTypes.HasAny;
|
||||
|
||||
const minAmountNumber = -99999999999; // -999999999.99
|
||||
const maxAmountNumber = 99999999999; // 999999999.99
|
||||
const maxPictureCount = 10;
|
||||
|
||||
export default {
|
||||
allTransactionTypes: allTransactionTypes,
|
||||
allTransactionEditScopeTypes: allTransactionEditScopeTypes,
|
||||
allTransactionTagFilterTypes: allTransactionTagFilterTypes,
|
||||
defaultTransactionTagFilterType: defaultTransactionTagFilterType,
|
||||
minAmountNumber: minAmountNumber,
|
||||
maxAmountNumber: maxAmountNumber,
|
||||
maxPictureCount: maxPictureCount,
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export const TRANSACTION_MIN_AMOUNT: number = -99999999999; // -999999999.99
|
||||
export const TRANSACTION_MAX_AMOUNT: number = 99999999999; // 999999999.99
|
||||
export const TRANSACTION_MAX_PICTURE_COUNT: number = 10;
|
||||
@@ -0,0 +1,80 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
type AccountTypeName = 'SingleAccount' | 'MultiSubAccounts';
|
||||
|
||||
export class AccountType implements TypeAndName {
|
||||
private static readonly allInstances: AccountType[] = [];
|
||||
private static readonly allInstancesByTypeName: Record<string, AccountType> = {};
|
||||
|
||||
public static readonly SingleAccount = new AccountType(1, 'SingleAccount', 'Single Account');
|
||||
public static readonly MultiSubAccounts = new AccountType(2, 'MultiSubAccounts', 'Multiple Sub-accounts');
|
||||
|
||||
public readonly type: number;
|
||||
public readonly typeName: AccountTypeName;
|
||||
public readonly name: string;
|
||||
|
||||
private constructor(type: number, typeName: AccountTypeName, name: string) {
|
||||
this.type = type;
|
||||
this.typeName = typeName;
|
||||
this.name = name;
|
||||
|
||||
AccountType.allInstances.push(this);
|
||||
AccountType.allInstancesByTypeName[typeName] = this;
|
||||
}
|
||||
|
||||
public static values(): AccountType[] {
|
||||
return AccountType.allInstances;
|
||||
}
|
||||
|
||||
public static all(): Record<AccountTypeName, AccountType> {
|
||||
return AccountType.allInstancesByTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
type AccountCategoryTypeName = 'Cash' | 'CheckingAccount' | 'SavingsAccount' | 'CreditCard' | 'VirtualAccount' | 'DebtAccount' | 'Receivables' | 'CertificateOfDeposit' | 'InvestmentAccount';
|
||||
|
||||
export class AccountCategory implements TypeAndName {
|
||||
private static readonly allInstances: AccountCategory[] = [];
|
||||
private static readonly allInstancesByType: Record<number, AccountCategory> = {};
|
||||
private static readonly allInstancesByTypeName: Record<string, AccountCategory> = {};
|
||||
|
||||
public static readonly Cash = new AccountCategory(1, 'Cash', 'Cash', '1');
|
||||
public static readonly CheckingAccount = new AccountCategory(2, 'CheckingAccount', 'Checking Account', '100');
|
||||
public static readonly SavingsAccount = new AccountCategory(8, 'SavingsAccount', 'Savings Account', '100');
|
||||
public static readonly CreditCard = new AccountCategory(3, 'CreditCard', 'Credit Card', '100');
|
||||
public static readonly VirtualAccount = new AccountCategory(4, 'VirtualAccount', 'Virtual Account', '500');
|
||||
public static readonly DebtAccount = new AccountCategory(5, 'DebtAccount', 'Debt Account', '600');
|
||||
public static readonly Receivables = new AccountCategory(6, 'Receivables', 'Receivables', '700');
|
||||
public static readonly CertificateOfDeposit = new AccountCategory(9, 'CertificateOfDeposit', 'Certificate of Deposit', '110');
|
||||
public static readonly InvestmentAccount = new AccountCategory(7, 'InvestmentAccount', 'Investment Account', '800');
|
||||
|
||||
public static readonly Default = AccountCategory.Cash;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly typeName: AccountCategoryTypeName;
|
||||
public readonly name: string;
|
||||
public readonly defaultAccountIconId: string;
|
||||
|
||||
private constructor(type: number, typeName: AccountCategoryTypeName, name: string, defaultAccountIconId: string) {
|
||||
this.type = type;
|
||||
this.typeName = typeName;
|
||||
this.name = name;
|
||||
this.defaultAccountIconId = defaultAccountIconId;
|
||||
|
||||
AccountCategory.allInstances.push(this);
|
||||
AccountCategory.allInstancesByType[type] = this;
|
||||
AccountCategory.allInstancesByTypeName[typeName] = this;
|
||||
}
|
||||
|
||||
public static values(): AccountCategory[] {
|
||||
return AccountCategory.allInstances;
|
||||
}
|
||||
|
||||
public static all(): Record<AccountCategoryTypeName, AccountCategory> {
|
||||
return AccountCategory.allInstancesByTypeName;
|
||||
}
|
||||
|
||||
public static valueOf(type: number): AccountCategory {
|
||||
return AccountCategory.allInstancesByType[type];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface TypeAndName {
|
||||
readonly type: number;
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
export interface TypeAndDisplayName {
|
||||
readonly type: number;
|
||||
readonly displayName: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export enum CategoryType {
|
||||
Income = 1,
|
||||
Expense = 2,
|
||||
Transfer = 3
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
export type ColorValue = string;
|
||||
|
||||
export interface ColorInfo {
|
||||
readonly color: ColorValue;
|
||||
}
|
||||
|
||||
export interface AmountColor {
|
||||
readonly expenseAmountColor: ColorValue;
|
||||
readonly incomeAmountColor: ColorValue;
|
||||
}
|
||||
|
||||
export class PresetAmountColor implements TypeAndName {
|
||||
private static readonly allInstances: PresetAmountColor[] = [];
|
||||
private static readonly allInstancesByType: Record<number, PresetAmountColor> = {};
|
||||
|
||||
public static readonly SystemDefaultType: number = 0;
|
||||
public static readonly Green = new PresetAmountColor(1, 'Green', '#009688', '#009688', 'expense-amount-color-green', 'income-amount-color-green');
|
||||
public static readonly Red = new PresetAmountColor(2, 'Red', '#d43f3f', '#d43f3f', 'expense-amount-color-red', 'income-amount-color-red');
|
||||
public static readonly Yellow = new PresetAmountColor(3, 'Yellow', '#e2b60a', '#e2b60a', 'expense-amount-color-yellow', 'income-amount-color-yellow');
|
||||
public static readonly BlackOrWhite = new PresetAmountColor(4, 'Black or White', '#413935', '#fcf0e3', 'expense-amount-color-blackorwhite', 'income-amount-color-blackorwhite');
|
||||
|
||||
public static readonly DefaultExpenseColor = PresetAmountColor.Green;
|
||||
public static readonly DefaultIncomeColor = PresetAmountColor.Red;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
public readonly lightThemeColor: string;
|
||||
public readonly darkThemeColor: string;
|
||||
public readonly expenseClassName: string;
|
||||
public readonly incomeClassName: string;
|
||||
|
||||
private constructor(type: number, name: string, lightThemeColor: string, darkThemeColor: string, expenseClassName: string, incomeClassName: string) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.lightThemeColor = lightThemeColor;
|
||||
this.darkThemeColor = darkThemeColor;
|
||||
this.expenseClassName = expenseClassName;
|
||||
this.incomeClassName = incomeClassName;
|
||||
|
||||
PresetAmountColor.allInstances.push(this);
|
||||
PresetAmountColor.allInstancesByType[type] = this;
|
||||
}
|
||||
|
||||
public static values(): PresetAmountColor[] {
|
||||
return PresetAmountColor.allInstances;
|
||||
}
|
||||
|
||||
public static valueOf(type: number): PresetAmountColor {
|
||||
return PresetAmountColor.allInstancesByType[type];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
export enum CurrencyDisplaySymbol {
|
||||
None = 0,
|
||||
Symbol = 1,
|
||||
Code = 2,
|
||||
Unit = 3,
|
||||
Name = 4
|
||||
}
|
||||
|
||||
export enum CurrencyDisplayLocation {
|
||||
BeforeAmount = 0,
|
||||
AfterAmount = 1
|
||||
}
|
||||
|
||||
export interface CurrencyPrependAndAppendText {
|
||||
prependText?: string;
|
||||
appendText?: string;
|
||||
}
|
||||
|
||||
export class CurrencyDisplayType implements TypeAndName {
|
||||
private static readonly allInstances: CurrencyDisplayType[] = [];
|
||||
private static readonly allInstancesByType: Record<number, CurrencyDisplayType> = {};
|
||||
private static readonly allInstancesByTypeName: Record<string, CurrencyDisplayType> = {};
|
||||
|
||||
public static readonly LanguageDefaultType = 0;
|
||||
public static readonly None = new CurrencyDisplayType(1, 'None', 'None', 2, CurrencyDisplaySymbol.None, undefined, '');
|
||||
public static readonly SymbolBeforeAmount = new CurrencyDisplayType(2, 'SymbolBeforeAmount', 'Currency Symbol', 2, CurrencyDisplaySymbol.Symbol, CurrencyDisplayLocation.BeforeAmount, ' ');
|
||||
public static readonly SymbolAfterAmount = new CurrencyDisplayType(3, 'SymbolAfterAmount', 'Currency Symbol', 2, CurrencyDisplaySymbol.Symbol, CurrencyDisplayLocation.AfterAmount, ' ');
|
||||
public static readonly SymbolBeforeAmountWithoutSpace = new CurrencyDisplayType(4, 'SymbolBeforeAmountWithoutSpace', 'Currency Symbol', 2, CurrencyDisplaySymbol.Symbol, CurrencyDisplayLocation.BeforeAmount, '');
|
||||
public static readonly SymbolAfterAmountWithoutSpace = new CurrencyDisplayType(5, 'SymbolAfterAmountWithoutSpace', 'Currency Symbol', 2, CurrencyDisplaySymbol.Symbol, CurrencyDisplayLocation.AfterAmount, '');
|
||||
public static readonly CodeBeforeAmount = new CurrencyDisplayType(6, 'CodeBeforeAmount', 'Currency Code', 2, CurrencyDisplaySymbol.Code, CurrencyDisplayLocation.BeforeAmount, ' ');
|
||||
public static readonly CodeAfterAmount = new CurrencyDisplayType(7, 'CodeAfterAmount', 'Currency Code', 2, CurrencyDisplaySymbol.Code, CurrencyDisplayLocation.AfterAmount, ' ');
|
||||
public static readonly UnitBeforeAmount = new CurrencyDisplayType(8, 'UnitBeforeAmount', 'Currency Unit', 2, CurrencyDisplaySymbol.Unit, CurrencyDisplayLocation.BeforeAmount, ' ');
|
||||
public static readonly UnitAfterAmount = new CurrencyDisplayType(9, 'UnitAfterAmount', 'Currency Unit', 2, CurrencyDisplaySymbol.Unit, CurrencyDisplayLocation.AfterAmount, ' ');
|
||||
public static readonly NameBeforeAmount = new CurrencyDisplayType(10, 'NameBeforeAmount', 'Currency Name', 2, CurrencyDisplaySymbol.Name, CurrencyDisplayLocation.BeforeAmount, ' ');
|
||||
public static readonly NameAfterAmount = new CurrencyDisplayType(11, 'NameAfterAmount', 'Currency Name', 2, CurrencyDisplaySymbol.Name, CurrencyDisplayLocation.AfterAmount, ' ');
|
||||
|
||||
public static readonly Default = CurrencyDisplayType.SymbolBeforeAmount;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly typeName: string;
|
||||
public readonly name: string;
|
||||
public readonly fraction: number;
|
||||
public readonly symbol: CurrencyDisplaySymbol;
|
||||
public readonly location: CurrencyDisplayLocation | undefined;
|
||||
public readonly separator: string;
|
||||
|
||||
private constructor(type: number, typeName: string, name: string, fraction: number, symbol: CurrencyDisplaySymbol, location: CurrencyDisplayLocation | undefined, separator: string) {
|
||||
this.type = type;
|
||||
this.typeName = typeName;
|
||||
this.name = name;
|
||||
this.fraction = fraction;
|
||||
this.symbol = symbol;
|
||||
this.location = location;
|
||||
this.separator = separator;
|
||||
|
||||
CurrencyDisplayType.allInstances.push(this);
|
||||
CurrencyDisplayType.allInstancesByType[type] = this;
|
||||
CurrencyDisplayType.allInstancesByTypeName[typeName] = this;
|
||||
}
|
||||
|
||||
public static values(): CurrencyDisplayType[] {
|
||||
return CurrencyDisplayType.allInstances;
|
||||
}
|
||||
|
||||
public static valueOf(type: number): CurrencyDisplayType {
|
||||
return CurrencyDisplayType.allInstancesByType[type];
|
||||
}
|
||||
|
||||
public static parse(typeName: string): CurrencyDisplayType {
|
||||
return CurrencyDisplayType.allInstancesByTypeName[typeName];
|
||||
}
|
||||
}
|
||||
|
||||
export class CurrencySortingType implements TypeAndName {
|
||||
private static readonly allInstances: CurrencySortingType[] = [];
|
||||
|
||||
public static readonly Name = new CurrencySortingType(0, 'Currency Name');
|
||||
public static readonly CurrencyCode = new CurrencySortingType(1, 'Currency Code');
|
||||
public static readonly ExchangeRate = new CurrencySortingType(2, 'Exchange Rate');
|
||||
|
||||
public static readonly Default = CurrencySortingType.Name;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
|
||||
private constructor(type: number, name: string) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
CurrencySortingType.allInstances.push(this);
|
||||
}
|
||||
|
||||
public static values(): CurrencySortingType[] {
|
||||
return CurrencySortingType.allInstances;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
export class MeridiemIndicator {
|
||||
private static readonly allInstances: MeridiemIndicator[] = [];
|
||||
|
||||
public static readonly AM = new MeridiemIndicator(0, 'AM');
|
||||
public static readonly PM = new MeridiemIndicator(1, 'PM');
|
||||
|
||||
public readonly type: number;
|
||||
public readonly value: string;
|
||||
|
||||
private constructor(type: number, value: string) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
|
||||
MeridiemIndicator.allInstances.push(this);
|
||||
}
|
||||
|
||||
public static values(): MeridiemIndicator[] {
|
||||
return MeridiemIndicator.allInstances;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
export class FontSize {
|
||||
private static readonly allInstances: FontSize[] = [];
|
||||
|
||||
public static readonly Small = new FontSize(0, 'font-size-small');
|
||||
public static readonly Default = new FontSize(1, 'font-size-default');
|
||||
public static readonly Large = new FontSize(2, 'font-size-large');
|
||||
public static readonly XLarge = new FontSize(3, 'font-size-x-large');
|
||||
public static readonly XXLarge = new FontSize(4, 'font-size-xx-large');
|
||||
public static readonly XXXLarge = new FontSize(5, 'font-size-xxx-large');
|
||||
public static readonly XXXXLarge = new FontSize(6, 'font-size-xxxx-large');
|
||||
|
||||
public static readonly MinimumFontSize = FontSize.Small;
|
||||
public static readonly MaximumFontSize = FontSize.XXXXLarge;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly className: string;
|
||||
|
||||
private constructor(type: number, className: string) {
|
||||
this.type = type;
|
||||
this.className = className;
|
||||
|
||||
FontSize.allInstances.push(this);
|
||||
}
|
||||
|
||||
public static values(): FontSize[] {
|
||||
return FontSize.allInstances;
|
||||
}
|
||||
}
|
||||
|
||||
export const FONT_SIZE_PREVIEW_CLASSNAME_PREFIX: string = 'preview-';
|
||||
@@ -0,0 +1,10 @@
|
||||
export type LineAwesomeIconClassName = string;
|
||||
|
||||
export interface IconInfo {
|
||||
readonly icon: LineAwesomeIconClassName;
|
||||
}
|
||||
|
||||
export interface IconInfoWithId {
|
||||
readonly id: string;
|
||||
readonly icon: LineAwesomeIconClassName;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
type TemplateTypeName = 'Normal' | 'Schedule';
|
||||
|
||||
export class TemplateType implements TypeAndName {
|
||||
private static readonly allInstances: TemplateType[] = [];
|
||||
private static readonly allInstancesByType: Record<number, TemplateType> = {};
|
||||
private static readonly allInstancesByTypeName: Record<string, TemplateType> = {};
|
||||
|
||||
public static readonly Normal = new TemplateType(1, 'Normal');
|
||||
public static readonly Schedule = new TemplateType(2, 'Schedule');
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: TemplateTypeName;
|
||||
|
||||
private constructor(type: number, name: TemplateTypeName) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
TemplateType.allInstances.push(this);
|
||||
TemplateType.allInstancesByType[type] = this;
|
||||
TemplateType.allInstancesByTypeName[name] = this;
|
||||
}
|
||||
|
||||
public static values(): TemplateType[] {
|
||||
return TemplateType.allInstances;
|
||||
}
|
||||
|
||||
public static all(): Record<TemplateTypeName, TemplateType> {
|
||||
return TemplateType.allInstancesByTypeName;
|
||||
}
|
||||
|
||||
public static valueOf(type: number): TemplateType {
|
||||
return TemplateType.allInstancesByType[type];
|
||||
}
|
||||
}
|
||||
|
||||
type ScheduledTemplateFrequencyTypeName = 'Disabled' | 'Weekly' | 'Monthly';
|
||||
|
||||
export class ScheduledTemplateFrequencyType implements TypeAndName {
|
||||
private static readonly allInstances: ScheduledTemplateFrequencyType[] = [];
|
||||
private static readonly allInstancesByType: Record<number, ScheduledTemplateFrequencyType> = {};
|
||||
private static readonly allInstancesByTypeName: Record<string, ScheduledTemplateFrequencyType> = {};
|
||||
|
||||
public static readonly Disabled = new ScheduledTemplateFrequencyType(0, 'Disabled');
|
||||
public static readonly Weekly = new ScheduledTemplateFrequencyType(1, 'Weekly');
|
||||
public static readonly Monthly = new ScheduledTemplateFrequencyType(2, 'Monthly');
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: ScheduledTemplateFrequencyTypeName;
|
||||
|
||||
private constructor(type: number, name: ScheduledTemplateFrequencyTypeName) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
ScheduledTemplateFrequencyType.allInstances.push(this);
|
||||
ScheduledTemplateFrequencyType.allInstancesByType[type] = this;
|
||||
ScheduledTemplateFrequencyType.allInstancesByTypeName[name] = this;
|
||||
}
|
||||
|
||||
public static values(): ScheduledTemplateFrequencyType[] {
|
||||
return ScheduledTemplateFrequencyType.allInstances;
|
||||
}
|
||||
|
||||
public static all(): Record<ScheduledTemplateFrequencyTypeName, ScheduledTemplateFrequencyType> {
|
||||
return ScheduledTemplateFrequencyType.allInstancesByTypeName;
|
||||
}
|
||||
|
||||
public static valueOf(type: number): ScheduledTemplateFrequencyType {
|
||||
return ScheduledTemplateFrequencyType.allInstancesByType[type];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum ThemeType {
|
||||
Light = 'light',
|
||||
Dark = 'dark'
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
export class TimezoneTypeForStatistics implements TypeAndName {
|
||||
public static readonly ApplicationTimezone = new TimezoneTypeForStatistics(0, 'Application Timezone');
|
||||
public static readonly TransactionTimezone = new TimezoneTypeForStatistics(1, 'Transaction Timezone');
|
||||
|
||||
public static readonly Default = TimezoneTypeForStatistics.ApplicationTimezone;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
|
||||
private constructor(type: number, name: string) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { TypeAndName } from './base.ts';
|
||||
|
||||
export enum TransactionType {
|
||||
ModifyBalance = 1,
|
||||
Income = 2,
|
||||
Expense = 3,
|
||||
Transfer = 4
|
||||
}
|
||||
|
||||
export class TransactionEditScopeType implements TypeAndName {
|
||||
private static readonly allInstances: TransactionEditScopeType[] = [];
|
||||
|
||||
public static readonly None = new TransactionEditScopeType(0, 'None');
|
||||
public static readonly All = new TransactionEditScopeType(1, 'All');
|
||||
public static readonly TodayOrLater = new TransactionEditScopeType(2, 'Today or later');
|
||||
public static readonly Recent24HoursOrLater = new TransactionEditScopeType(3, 'Recent 24 hours or later');
|
||||
public static readonly ThisWeekOrLater = new TransactionEditScopeType(4, 'This week or later');
|
||||
public static readonly ThisMonthOrLater = new TransactionEditScopeType(5, 'This month or later');
|
||||
public static readonly ThisYearOrLater = new TransactionEditScopeType(6, 'This year or later');
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
|
||||
private constructor(type: number, name: string) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
TransactionEditScopeType.allInstances.push(this);
|
||||
}
|
||||
|
||||
public static values(): TransactionEditScopeType[] {
|
||||
return TransactionEditScopeType.allInstances;
|
||||
}
|
||||
}
|
||||
|
||||
export class TransactionTagFilterType implements TypeAndName {
|
||||
private static readonly allInstances: TransactionTagFilterType[] = [];
|
||||
|
||||
public static readonly HasAny = new TransactionTagFilterType(0, 'With Any Selected Tags');
|
||||
public static readonly HasAll = new TransactionTagFilterType(1, 'With All Selected Tags');
|
||||
public static readonly NotHasAny = new TransactionTagFilterType(2, 'Without Any Selected Tags');
|
||||
public static readonly NotHasAll = new TransactionTagFilterType(3, 'Without All Selected Tags');
|
||||
|
||||
public static readonly Default = TransactionTagFilterType.HasAny;
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
|
||||
private constructor(type: number, name: string) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
TransactionTagFilterType.allInstances.push(this);
|
||||
}
|
||||
|
||||
public static values(): TransactionTagFilterType[] {
|
||||
return TransactionTagFilterType.allInstances;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -70,7 +70,7 @@ import draggable from 'vuedraggable';
|
||||
|
||||
import router from '@/router/desktop.js';
|
||||
|
||||
import { getVersion, getBuildTime } from '@/lib/version.js';
|
||||
import { getVersion, getBuildTime } from '@/lib/version.ts';
|
||||
import userstate from '@/lib/userstate.js';
|
||||
import {
|
||||
getI18nOptions,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { autoChangeTextareaSize } from '@/lib/ui.mobile.js';
|
||||
import { autoChangeTextareaSize } from '@/lib/ui/mobile.js';
|
||||
|
||||
export default {
|
||||
mounted(el) {
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
declare const __EZBOOKKEEPING_IS_PRODUCTION__: boolean;
|
||||
declare const __EZBOOKKEEPING_VERSION__: string;
|
||||
declare const __EZBOOKKEEPING_BUILD_UNIX_TIME__: string;
|
||||
declare const __EZBOOKKEEPING_BUILD_COMMIT_HASH__: string;
|
||||
declare const __EZBOOKKEEPING_LICENSE__: string;
|
||||
declare const __EZBOOKKEEPING_THIRD_PARTY_LICENSES__: string[];
|
||||
|
||||
interface Window {
|
||||
EZBOOKKEEPING_SERVER_SETTINGS?: {
|
||||
[key: string]: string | number | boolean | undefined | null;
|
||||
};
|
||||
}
|
||||
+41
-47
@@ -1,5 +1,5 @@
|
||||
import currencyConstants from '@/consts/currency.js';
|
||||
import accountConstants from '@/consts/account.js';
|
||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||
import { PARENT_ACCOUNT_CURRENCY_PLACEHOLDER } from '@/consts/currency.ts';
|
||||
|
||||
export function setAccountModelByAnotherAccount(account, account2) {
|
||||
account.id = account2.id;
|
||||
@@ -16,22 +16,12 @@ export function setAccountModelByAnotherAccount(account, account2) {
|
||||
account.visible = !account2.hidden;
|
||||
}
|
||||
|
||||
export function getAccountCategoryInfo(categoryId) {
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
if (accountConstants.allCategories[i].id === categoryId) {
|
||||
return accountConstants.allCategories[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getAccountOrSubAccountId(account, subAccountId) {
|
||||
if (account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
return account.id;
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && !subAccountId) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
return account.id;
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && subAccountId) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && subAccountId) {
|
||||
if (!account.subAccounts || !account.subAccounts.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -51,11 +41,11 @@ export function getAccountOrSubAccountId(account, subAccountId) {
|
||||
}
|
||||
|
||||
export function getAccountOrSubAccountComment(account, subAccountId) {
|
||||
if (account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
return account.comment;
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && !subAccountId) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
return account.comment;
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && subAccountId) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && subAccountId) {
|
||||
if (!account.subAccounts || !account.subAccounts.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -109,7 +99,7 @@ export function getCategorizedAccountsMap(allAccounts) {
|
||||
const account = allAccounts[i];
|
||||
|
||||
if (!ret[account.category]) {
|
||||
const categoryInfo = getAccountCategoryInfo(account.category);
|
||||
const categoryInfo = AccountCategory.valueOf(account.category);
|
||||
|
||||
if (categoryInfo) {
|
||||
ret[account.category] = {
|
||||
@@ -132,16 +122,17 @@ export function getCategorizedAccountsMap(allAccounts) {
|
||||
|
||||
export function getCategorizedAccounts(allAccounts) {
|
||||
const ret = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
const categorizedAccounts = getCategorizedAccountsMap(allAccounts);
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
const category = accountConstants.allCategories[i];
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const category = allCategories[i];
|
||||
|
||||
if (!categorizedAccounts[category.id]) {
|
||||
if (!categorizedAccounts[category.type]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountCategory = categorizedAccounts[category.id];
|
||||
const accountCategory = categorizedAccounts[category.type];
|
||||
ret.push(accountCategory);
|
||||
}
|
||||
|
||||
@@ -150,15 +141,16 @@ export function getCategorizedAccounts(allAccounts) {
|
||||
|
||||
export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap) {
|
||||
const ret = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
const accountCategory = accountConstants.allCategories[i];
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const accountCategory = allCategories[i];
|
||||
|
||||
if (!categorizedAccountsMap[accountCategory.id] || !categorizedAccountsMap[accountCategory.id].accounts) {
|
||||
if (!categorizedAccountsMap[accountCategory.type] || !categorizedAccountsMap[accountCategory.type].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const allAccounts = categorizedAccountsMap[accountCategory.id].accounts;
|
||||
const allAccounts = categorizedAccountsMap[accountCategory.type].accounts;
|
||||
const allSubAccounts = {};
|
||||
const allVisibleSubAccountCounts = {};
|
||||
const allFirstVisibleSubAccountIndexes = {};
|
||||
@@ -176,7 +168,7 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap) {
|
||||
}
|
||||
}
|
||||
|
||||
if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && account.subAccounts) {
|
||||
if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
|
||||
let visibleSubAccountCount = 0;
|
||||
let firstVisibleSubAccountIndex = -1;
|
||||
|
||||
@@ -202,7 +194,7 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap) {
|
||||
|
||||
if (allAccounts.length > 0) {
|
||||
ret.push({
|
||||
category: accountCategory.id,
|
||||
category: accountCategory.type,
|
||||
name: accountCategory.name,
|
||||
icon: accountCategory.defaultAccountIconId,
|
||||
allAccounts: allAccounts,
|
||||
@@ -219,31 +211,31 @@ export function getCategorizedAccountsWithVisibleCount(categorizedAccountsMap) {
|
||||
}
|
||||
|
||||
export function getAllFilteredAccountsBalance(categorizedAccounts, accountFilter) {
|
||||
const allAccountCategories = accountConstants.allCategories;
|
||||
const allAccountCategories = AccountCategory.values();
|
||||
const ret = [];
|
||||
|
||||
for (let categoryIdx = 0; categoryIdx < allAccountCategories.length; categoryIdx++) {
|
||||
const accountCategory = allAccountCategories[categoryIdx];
|
||||
|
||||
if (!categorizedAccounts[accountCategory.id] || !categorizedAccounts[accountCategory.id].accounts) {
|
||||
if (!categorizedAccounts[accountCategory.type] || !categorizedAccounts[accountCategory.type].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let accountIdx = 0; accountIdx < categorizedAccounts[accountCategory.id].accounts.length; accountIdx++) {
|
||||
const account = categorizedAccounts[accountCategory.id].accounts[accountIdx];
|
||||
for (let accountIdx = 0; accountIdx < categorizedAccounts[accountCategory.type].accounts.length; accountIdx++) {
|
||||
const account = categorizedAccounts[accountCategory.type].accounts[accountIdx];
|
||||
|
||||
if (account.hidden || !accountFilter(account)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
ret.push({
|
||||
balance: account.balance,
|
||||
isAsset: account.isAsset,
|
||||
isLiability: account.isLiability,
|
||||
currency: account.currency
|
||||
});
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts && account.subAccounts) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
|
||||
for (let subAccountIdx = 0; subAccountIdx < account.subAccounts.length; subAccountIdx++) {
|
||||
const subAccount = account.subAccounts[subAccountIdx];
|
||||
|
||||
@@ -307,7 +299,7 @@ export function getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccounts,
|
||||
|
||||
const account = allAccounts[accountId];
|
||||
|
||||
if (account.currency === currencyConstants.parentAccountCurrencyPlaceholder) {
|
||||
if (account.currency === PARENT_ACCOUNT_CURRENCY_PLACEHOLDER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -326,9 +318,9 @@ export function getUnifiedSelectedAccountsCurrencyOrDefaultCurrency(allAccounts,
|
||||
}
|
||||
|
||||
export function selectAccountOrSubAccounts(filterAccountIds, account, value) {
|
||||
if (account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
filterAccountIds[account.id] = value;
|
||||
} else if (account.type === accountConstants.allAccountTypes.MultiSubAccounts) {
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
||||
if (!account.subAccounts || !account.subAccounts.length) {
|
||||
return;
|
||||
}
|
||||
@@ -348,7 +340,7 @@ export function selectAll(filterAccountIds, allAccountsMap) {
|
||||
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (account && account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account && account.type === AccountType.SingleAccount.type) {
|
||||
filterAccountIds[account.id] = false;
|
||||
}
|
||||
}
|
||||
@@ -362,7 +354,7 @@ export function selectNone(filterAccountIds, allAccountsMap) {
|
||||
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (account && account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account && account.type === AccountType.SingleAccount.type) {
|
||||
filterAccountIds[account.id] = true;
|
||||
}
|
||||
}
|
||||
@@ -376,7 +368,7 @@ export function selectInvert(filterAccountIds, allAccountsMap) {
|
||||
|
||||
const account = allAccountsMap[accountId];
|
||||
|
||||
if (account && account.type === accountConstants.allAccountTypes.SingleAccount) {
|
||||
if (account && account.type === AccountType.SingleAccount.type) {
|
||||
filterAccountIds[account.id] = !filterAccountIds[account.id];
|
||||
}
|
||||
}
|
||||
@@ -415,9 +407,11 @@ export function isAccountOrSubAccountsHasButNotAllChecked(account, filterAccount
|
||||
}
|
||||
|
||||
export function setAccountSuitableIcon(account, oldCategory, newCategory) {
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
if (accountConstants.allCategories[i].id === oldCategory) {
|
||||
if (account.icon !== accountConstants.allCategories[i].defaultAccountIconId) {
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
if (allCategories[i].type === oldCategory) {
|
||||
if (account.icon !== allCategories[i].defaultAccountIconId) {
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
@@ -425,9 +419,9 @@ export function setAccountSuitableIcon(account, oldCategory, newCategory) {
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
if (accountConstants.allCategories[i].id === newCategory) {
|
||||
account.icon = accountConstants.allCategories[i].defaultAccountIconId;
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
if (allCategories[i].type === newCategory) {
|
||||
account.icon = allCategories[i].defaultAccountIconId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,5 +1,5 @@
|
||||
import categoryConstants from '@/consts/category.js';
|
||||
import transactionConstants from '@/consts/transaction.js';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
|
||||
export function setCategoryModelByAnotherCategory(category, category2) {
|
||||
category.id = category2.id;
|
||||
@@ -13,24 +13,24 @@ export function setCategoryModelByAnotherCategory(category, category2) {
|
||||
}
|
||||
|
||||
export function transactionTypeToCategoryType(transactionType) {
|
||||
if (transactionType === transactionConstants.allTransactionTypes.Income) {
|
||||
return categoryConstants.allCategoryTypes.Income;
|
||||
} else if (transactionType === transactionConstants.allTransactionTypes.Expense) {
|
||||
return categoryConstants.allCategoryTypes.Expense;
|
||||
} else if (transactionType === transactionConstants.allTransactionTypes.Transfer) {
|
||||
return categoryConstants.allCategoryTypes.Transfer;
|
||||
if (transactionType === TransactionType.Income) {
|
||||
return CategoryType.Income;
|
||||
} else if (transactionType === TransactionType.Expense) {
|
||||
return CategoryType.Expense;
|
||||
} else if (transactionType === TransactionType.Transfer) {
|
||||
return CategoryType.Transfer;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function categoryTypeToTransactionType(categoryType) {
|
||||
if (categoryType === categoryConstants.allCategoryTypes.Income) {
|
||||
return transactionConstants.allTransactionTypes.Income;
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Expense) {
|
||||
return transactionConstants.allTransactionTypes.Expense;
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Transfer) {
|
||||
return transactionConstants.allTransactionTypes.Transfer;
|
||||
if (categoryType === CategoryType.Income) {
|
||||
return TransactionType.Income;
|
||||
} else if (categoryType === CategoryType.Expense) {
|
||||
return TransactionType.Expense;
|
||||
} else if (categoryType === CategoryType.Transfer) {
|
||||
return TransactionType.Transfer;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -73,16 +73,16 @@ export function getTransactionSecondaryCategoryName(categoryId, allCategories) {
|
||||
export function allTransactionCategoriesWithVisibleCount(allTransactionCategories, allowCategoryTypes) {
|
||||
const ret = {};
|
||||
const hasAllowCategoryTypes = allowCategoryTypes
|
||||
&& (allowCategoryTypes[categoryConstants.allCategoryTypes.Income.toString()]
|
||||
|| allowCategoryTypes[categoryConstants.allCategoryTypes.Expense.toString()]
|
||||
|| allowCategoryTypes[categoryConstants.allCategoryTypes.Transfer.toString()]);
|
||||
&& (allowCategoryTypes[CategoryType.Income.toString()]
|
||||
|| allowCategoryTypes[CategoryType.Expense.toString()]
|
||||
|| allowCategoryTypes[CategoryType.Transfer.toString()]);
|
||||
|
||||
for (let key in categoryConstants.allCategoryTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(categoryConstants.allCategoryTypes, key)) {
|
||||
for (let key in CategoryType) {
|
||||
if (!Object.prototype.hasOwnProperty.call(CategoryType, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const categoryType = categoryConstants.allCategoryTypes[key];
|
||||
const categoryType = CategoryType[key];
|
||||
|
||||
if (!allTransactionCategories[categoryType]) {
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import Clipboard from 'clipboard';
|
||||
|
||||
export interface ClipboardCreateContext {
|
||||
readonly el: string | Element;
|
||||
readonly text: string;
|
||||
readonly successCallback?: (e: ClipboardEvent) => void;
|
||||
readonly errorCallback?: (e: ClipboardEvent) => void;
|
||||
}
|
||||
|
||||
export interface ClipboardEvent {
|
||||
readonly text: string;
|
||||
readonly action: string;
|
||||
}
|
||||
|
||||
export class ClipboardTextHolder {
|
||||
private text: string;
|
||||
|
||||
constructor(text: string) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public getText(): string {
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public setText(text: string): void {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
export class ClipboardHolder {
|
||||
private readonly textHolder: ClipboardTextHolder;
|
||||
private readonly clipboard: Clipboard;
|
||||
|
||||
private constructor(textHolder: ClipboardTextHolder, clipboard: Clipboard) {
|
||||
this.textHolder = textHolder;
|
||||
this.clipboard = clipboard;
|
||||
}
|
||||
|
||||
public setClipboardText(text: string): void {
|
||||
this.textHolder.setText(text);
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
this.clipboard.destroy();
|
||||
}
|
||||
|
||||
public static create({ el, text, successCallback, errorCallback }: ClipboardCreateContext): ClipboardHolder {
|
||||
const textHolder = new ClipboardTextHolder(text);
|
||||
const clipboard = new Clipboard(el, {
|
||||
text: function () {
|
||||
return textHolder.getText();
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
if (successCallback) {
|
||||
successCallback({
|
||||
text: e.text,
|
||||
action: e.action
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('error', (e) => {
|
||||
if (errorCallback) {
|
||||
errorCallback({
|
||||
text: e.text,
|
||||
action: e.action
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return new ClipboardHolder(textHolder, clipboard);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
export function getColorsInRows(allColorInfos, itemPerRow) {
|
||||
const ret = [];
|
||||
let rowCount = -1;
|
||||
|
||||
for (let i = 0; i < allColorInfos.length; i++) {
|
||||
if (i % itemPerRow === 0) {
|
||||
ret[++rowCount] = [];
|
||||
}
|
||||
|
||||
ret[rowCount].push({
|
||||
color: allColorInfos[i]
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { ColorValue, ColorInfo } from '@/core/color.ts';
|
||||
|
||||
export function getColorsInRows(allColorValues: ColorValue[], itemPerRow: number): ColorInfo[][] {
|
||||
const ret: ColorInfo[][] = [];
|
||||
let rowCount = -1;
|
||||
|
||||
for (let i = 0; i < allColorValues.length; i++) {
|
||||
if (i % itemPerRow === 0) {
|
||||
ret[++rowCount] = [];
|
||||
}
|
||||
|
||||
ret[rowCount].push({
|
||||
color: allColorValues[i]
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
export function isFunction(val) {
|
||||
export function isFunction(val: unknown): boolean {
|
||||
return typeof(val) === 'function';
|
||||
}
|
||||
|
||||
export function isDefined(val) {
|
||||
export function isDefined(val: unknown): boolean {
|
||||
return typeof val !== 'undefined';
|
||||
}
|
||||
|
||||
export function isObject(val) {
|
||||
export function isObject(val: unknown): boolean {
|
||||
return val != null && typeof(val) === 'object' && !isArray(val);
|
||||
}
|
||||
|
||||
export function isArray(val) {
|
||||
export function isArray(val: unknown): boolean {
|
||||
if (isFunction(Array.isArray)) {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
@@ -18,23 +18,23 @@ export function isArray(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Array]';
|
||||
}
|
||||
|
||||
export function isString(val) {
|
||||
export function isString(val: unknown): boolean {
|
||||
return typeof(val) === 'string';
|
||||
}
|
||||
|
||||
export function isNumber(val) {
|
||||
export function isNumber(val: unknown): boolean {
|
||||
return typeof(val) === 'number';
|
||||
}
|
||||
|
||||
export function isInteger(val) {
|
||||
export function isInteger(val: unknown): boolean {
|
||||
return Number.isInteger(val);
|
||||
}
|
||||
|
||||
export function isBoolean(val) {
|
||||
export function isBoolean(val: unknown): boolean {
|
||||
return typeof(val) === 'boolean';
|
||||
}
|
||||
|
||||
export function isYearMonth(val) {
|
||||
export function isYearMonth(val: unknown): boolean {
|
||||
if (typeof(val) !== 'string') {
|
||||
return false;
|
||||
}
|
||||
@@ -45,50 +45,53 @@ export function isYearMonth(val) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parseInt(items[0]) && parseInt(items[1]);
|
||||
return !!parseInt(items[0]) && !!parseInt(items[1]);
|
||||
}
|
||||
|
||||
export function isEquals(obj1, obj2) {
|
||||
export function isEquals(obj1: unknown, obj2: unknown): boolean {
|
||||
if (obj1 === obj2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isArray(obj1) && isArray(obj2)) {
|
||||
if (obj1.length !== obj2.length) {
|
||||
const arr1 = obj1 as unknown[];
|
||||
const arr2 = obj2 as unknown[];
|
||||
|
||||
if (arr1.length !== arr2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < obj1.length; i++) {
|
||||
if (!isEquals(obj1[i], obj2[i])) {
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
if (!isEquals(arr1[i], arr2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (isObject(obj1) && isObject(obj2)) {
|
||||
const keys1 = Object.keys(obj1);
|
||||
const keys2 = Object.keys(obj2);
|
||||
const keys1 = Object.keys(obj1 as Record<string, unknown>);
|
||||
const keys2 = Object.keys(obj2 as Record<string, unknown>);
|
||||
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const keyExistsMap2 = {};
|
||||
const keyExistsMap2 = new Map<string, boolean>();
|
||||
|
||||
for (let i = 0; i < keys2.length; i++) {
|
||||
const key = keys2[i];
|
||||
|
||||
keyExistsMap2[key] = true;
|
||||
keyExistsMap2.set(key, true);
|
||||
}
|
||||
|
||||
for (let i = 0; i < keys1.length; i++) {
|
||||
const key = keys1[i];
|
||||
|
||||
if (!keyExistsMap2[key]) {
|
||||
if (!keyExistsMap2.get(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isEquals(obj1[key], obj2[key])) {
|
||||
if (!isEquals((obj1 as Record<string, unknown>)[key], (obj2 as Record<string, unknown>)[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -99,7 +102,7 @@ export function isEquals(obj1, obj2) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isYearMonthEquals(val1, val2) {
|
||||
export function isYearMonthEquals(val1: unknown, val2: unknown): boolean {
|
||||
if (typeof(val1) !== 'string' || typeof(val2) !== 'string') {
|
||||
return false;
|
||||
}
|
||||
@@ -111,15 +114,15 @@ export function isYearMonthEquals(val1, val2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (parseInt(items1[0]) && parseInt(items1[1])) && (parseInt(items1[0]) === parseInt(items2[0])) && (parseInt(items1[1]) === parseInt(items2[1]));
|
||||
return (!!parseInt(items1[0]) && !!parseInt(items1[1])) && (parseInt(items1[0]) === parseInt(items2[0])) && (parseInt(items1[1]) === parseInt(items2[1]));
|
||||
}
|
||||
|
||||
export function isObjectEmpty(obj) {
|
||||
export function isObjectEmpty(obj: object): boolean {
|
||||
if (!obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (let field in obj) {
|
||||
for (const field in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
|
||||
continue;
|
||||
}
|
||||
@@ -130,20 +133,20 @@ export function isObjectEmpty(obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function sortNumbersArray(array) {
|
||||
export function sortNumbersArray(array: number[]): number[] {
|
||||
return array.sort(function (num1, num2) {
|
||||
return num1 - num2;
|
||||
});
|
||||
}
|
||||
|
||||
export function getObjectOwnFieldCount(object) {
|
||||
export function getObjectOwnFieldCount(object: object): number {
|
||||
let count = 0;
|
||||
|
||||
if (!object || !isObject(object)) {
|
||||
return count;
|
||||
}
|
||||
|
||||
for (let field in object) {
|
||||
for (const field in object) {
|
||||
if (!Object.prototype.hasOwnProperty.call(object, field)) {
|
||||
continue;
|
||||
}
|
||||
@@ -154,20 +157,20 @@ export function getObjectOwnFieldCount(object) {
|
||||
return count;
|
||||
}
|
||||
|
||||
export function replaceAll(value, originalValue, targetValue) {
|
||||
export function replaceAll(value: string, originalValue: string, targetValue: string): string {
|
||||
// Escape special characters in originalValue to safely use it in a regex pattern.
|
||||
// This ensures that characters like . (dot), * (asterisk), +, ?, etc. are treated literally,
|
||||
// rather than as special regex symbols.
|
||||
const escapedOriginalValue = originalValue.replace(/([.*+?^=!:${}()|\-/\\])/g, '\\$1');
|
||||
|
||||
|
||||
return value.replaceAll(new RegExp(escapedOriginalValue, 'g'), targetValue);
|
||||
}
|
||||
|
||||
export function removeAll(value, originalValue) {
|
||||
export function removeAll(value: string, originalValue: string): string {
|
||||
return replaceAll(value, originalValue, '');
|
||||
}
|
||||
|
||||
export function limitText(value, maxLength) {
|
||||
export function limitText(value: string, maxLength: number): string {
|
||||
let length = 0;
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
@@ -187,7 +190,7 @@ export function limitText(value, maxLength) {
|
||||
return value.substring(0, maxLength - 3) + '...';
|
||||
}
|
||||
|
||||
export function getTextBefore(fullText, text) {
|
||||
export function getTextBefore(fullText: string, text: string): string {
|
||||
if (!text) {
|
||||
return fullText;
|
||||
}
|
||||
@@ -201,7 +204,7 @@ export function getTextBefore(fullText, text) {
|
||||
return '';
|
||||
}
|
||||
|
||||
export function getTextAfter(fullText, text) {
|
||||
export function getTextAfter(fullText: string, text: string): string {
|
||||
if (!text) {
|
||||
return fullText;
|
||||
}
|
||||
@@ -216,15 +219,15 @@ export function getTextAfter(fullText, text) {
|
||||
return '';
|
||||
}
|
||||
|
||||
export function base64encode(arrayBuffer) {
|
||||
if (!arrayBuffer || arrayBuffer.length === 0) {
|
||||
export function base64encode(arrayBuffer: ArrayBuffer): string | null {
|
||||
if (!arrayBuffer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
|
||||
return btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(arrayBuffer))));
|
||||
}
|
||||
|
||||
export function base64decode(str) {
|
||||
export function base64decode(str: string): string | null {
|
||||
if (!str) {
|
||||
return '';
|
||||
}
|
||||
@@ -232,56 +235,64 @@ export function base64decode(str) {
|
||||
return atob(str);
|
||||
}
|
||||
|
||||
export function arrayBufferToString(arrayBuffer) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
|
||||
export function arrayBufferToString(arrayBuffer: ArrayBuffer): string {
|
||||
return String.fromCharCode.apply(null, Array.from(new Uint8Array(arrayBuffer)));
|
||||
}
|
||||
|
||||
export function stringToArrayBuffer(str){
|
||||
export function stringToArrayBuffer(str: string): ArrayBuffer {
|
||||
return Uint8Array.from(str, c => c.charCodeAt(0)).buffer;
|
||||
}
|
||||
|
||||
export function getFirstVisibleItem(items, hiddenField) {
|
||||
if (isArray(items) && items.length > 0) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (hiddenField && items[i][hiddenField]) {
|
||||
export function getFirstVisibleItem(items: Record<string, unknown>[] | Record<string, Record<string, unknown>>, hiddenField: string): unknown {
|
||||
if (isArray(items) && (items as Record<string, unknown>[]).length > 0) {
|
||||
const arr = items as Record<string, unknown>[];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (hiddenField && arr[i][hiddenField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return items[i];
|
||||
return arr[i];
|
||||
}
|
||||
} else if (isObject(items)) {
|
||||
for (let field in items) {
|
||||
if (!Object.prototype.hasOwnProperty.call(items, field)) {
|
||||
const obj = items as Record<string, Record<string, unknown>>;
|
||||
|
||||
for (const field in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hiddenField && items[field][hiddenField]) {
|
||||
if (hiddenField && obj[field][hiddenField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return items[field];
|
||||
return obj[field];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getItemByKeyValue(src, value, keyField) {
|
||||
export function getItemByKeyValue(src: Record<string, unknown>[] | Record<string, Record<string, unknown>>, value: unknown, keyField: string) {
|
||||
if (isArray(src)) {
|
||||
for (let i = 0; i < src.length; i++) {
|
||||
const item = src[i];
|
||||
const arr = src as Record<string, unknown>[];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const item = arr[i];
|
||||
|
||||
if (item[keyField] === value) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
} else if (isObject(src)) {
|
||||
for (let field in src) {
|
||||
const obj = src as Record<string, Record<string, unknown>>;
|
||||
|
||||
for (const field in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(src, field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const item = src[field];
|
||||
const item = obj[field];
|
||||
|
||||
if (item[keyField] === value) {
|
||||
return item;
|
||||
@@ -292,39 +303,47 @@ export function getItemByKeyValue(src, value, keyField) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getNameByKeyValue(src, value, keyField, nameField, defaultName) {
|
||||
export function getNameByKeyValue(src: Record<string, unknown>[] | Record<string, Record<string, unknown>>, value: unknown, keyField: string, nameField: string, defaultName: string): unknown {
|
||||
if (isArray(src)) {
|
||||
const arr = src as Record<string, unknown>[];
|
||||
|
||||
if (keyField) {
|
||||
for (let i = 0; i < src.length; i++) {
|
||||
const option = src[i];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const option = arr[i];
|
||||
|
||||
if (option[keyField] === value) {
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (src[value]) {
|
||||
const option = src[value];
|
||||
} else if (isNumber(value)) {
|
||||
const index = value as number;
|
||||
|
||||
if (arr[index]) {
|
||||
const option = arr[index];
|
||||
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else if (isObject(src)) {
|
||||
const obj = src as Record<string, Record<string, unknown>>;
|
||||
|
||||
if (keyField) {
|
||||
for (let key in src) {
|
||||
for (const key in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(src, key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const option = src[key];
|
||||
const option = obj[key];
|
||||
|
||||
if (option[keyField] === value) {
|
||||
return option[nameField];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (src[value]) {
|
||||
const option = src[value];
|
||||
} else if (isNumber(value)) {
|
||||
const index = value as number;
|
||||
|
||||
if (obj[index]) {
|
||||
const option = obj[index];
|
||||
|
||||
return option[nameField];
|
||||
}
|
||||
@@ -334,7 +353,7 @@ export function getNameByKeyValue(src, value, keyField, nameField, defaultName)
|
||||
return defaultName;
|
||||
}
|
||||
|
||||
export function copyObjectTo(fromObject, toObject) {
|
||||
export function copyObjectTo(fromObject: Record<string, unknown>, toObject: Record<string, unknown>): object {
|
||||
if (!isObject(fromObject)) {
|
||||
return toObject;
|
||||
}
|
||||
@@ -343,7 +362,7 @@ export function copyObjectTo(fromObject, toObject) {
|
||||
toObject = {};
|
||||
}
|
||||
|
||||
for (let key in fromObject) {
|
||||
for (const key in fromObject) {
|
||||
if (!Object.prototype.hasOwnProperty.call(fromObject, key)) {
|
||||
continue;
|
||||
}
|
||||
@@ -352,9 +371,9 @@ export function copyObjectTo(fromObject, toObject) {
|
||||
const toValue = toObject[key];
|
||||
|
||||
if (isArray(fromValue)) {
|
||||
toObject[key] = copyArrayTo(fromValue, toValue);
|
||||
toObject[key] = copyArrayTo(fromValue as unknown[], toValue as unknown[]);
|
||||
} else if (isObject(fromValue)) {
|
||||
toObject[key] = copyObjectTo(fromValue, toValue);
|
||||
toObject[key] = copyObjectTo(fromValue as Record<string, unknown>, toValue as Record<string, unknown>);
|
||||
} else {
|
||||
if (fromValue !== toValue) {
|
||||
toObject[key] = fromValue;
|
||||
@@ -365,7 +384,7 @@ export function copyObjectTo(fromObject, toObject) {
|
||||
return toObject;
|
||||
}
|
||||
|
||||
export function copyArrayTo(fromArray, toArray) {
|
||||
export function copyArrayTo(fromArray: unknown[], toArray: unknown[]) {
|
||||
if (!isArray(fromArray)) {
|
||||
return toArray;
|
||||
}
|
||||
@@ -381,9 +400,9 @@ export function copyArrayTo(fromArray, toArray) {
|
||||
const toValue = toArray[i];
|
||||
|
||||
if (isArray(fromValue)) {
|
||||
toArray[i] = copyArrayTo(fromValue, toValue);
|
||||
toArray[i] = copyArrayTo(fromValue as unknown[], toValue as unknown[]);
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray[i] = copyObjectTo(fromValue, toValue);
|
||||
toArray[i] = copyObjectTo(fromValue as Record<string, unknown>, toValue as Record<string, unknown>);
|
||||
} else {
|
||||
if (fromValue !== toValue) {
|
||||
toArray[i] = fromValue;
|
||||
@@ -391,9 +410,9 @@ export function copyArrayTo(fromArray, toArray) {
|
||||
}
|
||||
} else {
|
||||
if (isArray(fromValue)) {
|
||||
toArray.push(copyArrayTo(fromValue, []));
|
||||
toArray.push(copyArrayTo(fromValue as unknown[], []));
|
||||
} else if (isObject(fromValue)) {
|
||||
toArray.push(copyObjectTo(fromValue, {}));
|
||||
toArray.push(copyObjectTo(fromValue as Record<string, unknown>, {}));
|
||||
} else {
|
||||
toArray.push(fromValue);
|
||||
}
|
||||
@@ -403,7 +422,7 @@ export function copyArrayTo(fromArray, toArray) {
|
||||
return toArray;
|
||||
}
|
||||
|
||||
export function arrayContainsFieldValue(array, fieldName, value) {
|
||||
export function arrayContainsFieldValue(array: Record<string, unknown>[], fieldName: string, value: unknown): boolean {
|
||||
if (!value || !array || !array.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -417,10 +436,10 @@ export function arrayContainsFieldValue(array, fieldName, value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function objectFieldToArrayItem(object) {
|
||||
const ret = [];
|
||||
export function objectFieldToArrayItem(object: object): string[] {
|
||||
const ret: string[] = [];
|
||||
|
||||
for (let field in object) {
|
||||
for (const field in object) {
|
||||
if (!Object.prototype.hasOwnProperty.call(object, field)) {
|
||||
continue;
|
||||
}
|
||||
@@ -431,8 +450,8 @@ export function objectFieldToArrayItem(object) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function arrayItemToObjectField(array, value) {
|
||||
const ret = {};
|
||||
export function arrayItemToObjectField(array: string[], value: unknown): Record<string, unknown> {
|
||||
const ret: Record<string, unknown> = {};
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
ret[array[i]] = value;
|
||||
@@ -441,10 +460,10 @@ export function arrayItemToObjectField(array, value) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function categorizedArrayToPlainArray(object) {
|
||||
const ret = [];
|
||||
export function categorizedArrayToPlainArray(object: Record<string, unknown[]>): unknown[] {
|
||||
const ret: unknown[] = [];
|
||||
|
||||
for (let field in object) {
|
||||
for (const field in object) {
|
||||
if (!Object.prototype.hasOwnProperty.call(object, field)) {
|
||||
continue;
|
||||
}
|
||||
@@ -459,8 +478,8 @@ export function categorizedArrayToPlainArray(object) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function selectAll(filterItemIds, allItemsMap) {
|
||||
for (let itemId in filterItemIds) {
|
||||
export function selectAll(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
|
||||
for (const itemId in filterItemIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
|
||||
continue;
|
||||
}
|
||||
@@ -473,8 +492,8 @@ export function selectAll(filterItemIds, allItemsMap) {
|
||||
}
|
||||
}
|
||||
|
||||
export function selectNone(filterItemIds, allItemsMap) {
|
||||
for (let itemId in filterItemIds) {
|
||||
export function selectNone(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
|
||||
for (const itemId in filterItemIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
|
||||
continue;
|
||||
}
|
||||
@@ -487,8 +506,8 @@ export function selectNone(filterItemIds, allItemsMap) {
|
||||
}
|
||||
}
|
||||
|
||||
export function selectInvert(filterItemIds, allItemsMap) {
|
||||
for (let itemId in filterItemIds) {
|
||||
export function selectInvert(filterItemIds: Record<string, boolean>, allItemsMap: { [key: string]: { id: string } }): void {
|
||||
for (const itemId in filterItemIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(filterItemIds, itemId)) {
|
||||
continue;
|
||||
}
|
||||
@@ -501,7 +520,7 @@ export function selectInvert(filterItemIds, allItemsMap) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isPrimaryItemHasSecondaryValue(primaryItem, primarySubItemsField, secondaryValueField, secondaryHiddenField, secondaryValue) {
|
||||
export function isPrimaryItemHasSecondaryValue(primaryItem: Record<string, Record<string, unknown>[]>, primarySubItemsField: string, secondaryValueField: string, secondaryHiddenField: string, secondaryValue: unknown): boolean {
|
||||
for (let i = 0; i < primaryItem[primarySubItemsField].length; i++) {
|
||||
const secondaryItem = primaryItem[primarySubItemsField][i];
|
||||
|
||||
@@ -519,11 +538,13 @@ export function isPrimaryItemHasSecondaryValue(primaryItem, primarySubItemsField
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getPrimaryValueBySecondaryValue(items, primarySubItemsField, primaryValueField, primaryHiddenField, secondaryValueField, secondaryHiddenField, secondaryValue) {
|
||||
export function getPrimaryValueBySecondaryValue(items: Record<string, Record<string, unknown>[]>[] | Record<string, Record<string, Record<string, unknown>[]>>, primarySubItemsField: string, primaryValueField: string, primaryHiddenField: string, secondaryValueField: string, secondaryHiddenField: string, secondaryValue: unknown): unknown {
|
||||
if (primarySubItemsField) {
|
||||
if (isArray(items)) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const primaryItem = items[i];
|
||||
const arr = items as Record<string, Record<string, unknown>[]>[];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const primaryItem = arr[i];
|
||||
|
||||
if (primaryHiddenField && primaryItem[primaryHiddenField]) {
|
||||
continue;
|
||||
@@ -538,12 +559,14 @@ export function getPrimaryValueBySecondaryValue(items, primarySubItemsField, pri
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let field in items) {
|
||||
if (!Object.prototype.hasOwnProperty.call(items, field)) {
|
||||
const obj = items as Record<string, Record<string, Record<string, unknown>[]>>;
|
||||
|
||||
for (const field in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const primaryItem = items[field];
|
||||
const primaryItem = obj[field];
|
||||
|
||||
if (primaryHiddenField && primaryItem[primaryHiddenField]) {
|
||||
continue;
|
||||
@@ -563,7 +586,7 @@ export function getPrimaryValueBySecondaryValue(items, primarySubItemsField, pri
|
||||
return null;
|
||||
}
|
||||
|
||||
export function arrangeArrayWithNewStartIndex(array, startIndex) {
|
||||
export function arrangeArrayWithNewStartIndex(array: unknown[], startIndex: number): unknown[] {
|
||||
if (startIndex <= 0 || startIndex >= array.length) {
|
||||
return array;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
import currencyConstants from '@/consts/currency.js';
|
||||
|
||||
import { isString, isNumber } from './common.js';
|
||||
|
||||
export function getCurrencyFraction(currencyCode) {
|
||||
const currencyInfo = currencyConstants.all[currencyCode];
|
||||
|
||||
if (currencyInfo) {
|
||||
return currencyInfo.fraction;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function appendCurrencySymbol(value, currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural) {
|
||||
if (isNumber(value)) {
|
||||
value = value.toString();
|
||||
}
|
||||
|
||||
if (!isString(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const symbol = getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
|
||||
|
||||
if (!symbol) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const separator = currencyDisplayType.separator || '';
|
||||
|
||||
if (symbol.prependText) {
|
||||
value = symbol.prependText + separator + value;
|
||||
}
|
||||
|
||||
if (symbol.appendText) {
|
||||
value = value + separator + symbol.appendText;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural) {
|
||||
if (!currencyDisplayType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let symbol = '';
|
||||
|
||||
if (currencyDisplayType.symbol === currencyConstants.allCurrencyDisplaySymbol.Symbol) {
|
||||
const currencyInfo = currencyConstants.all[currencyCode];
|
||||
|
||||
if (currencyInfo && currencyInfo.symbol && currencyInfo.symbol.normal) {
|
||||
symbol = currencyInfo.symbol.normal;
|
||||
|
||||
if (isPlural && currencyInfo.symbol.plural) {
|
||||
symbol = currencyInfo.symbol.plural;
|
||||
}
|
||||
}
|
||||
|
||||
if (!symbol) {
|
||||
symbol = currencyConstants.defaultCurrencySymbol;
|
||||
}
|
||||
} else if (currencyDisplayType.symbol === currencyConstants.allCurrencyDisplaySymbol.Code) {
|
||||
symbol = currencyCode;
|
||||
} else if (currencyDisplayType.symbol === currencyConstants.allCurrencyDisplaySymbol.Unit) {
|
||||
symbol = currencyUnit;
|
||||
} else if (currencyDisplayType.symbol === currencyConstants.allCurrencyDisplaySymbol.Name) {
|
||||
symbol = currencyName;
|
||||
}
|
||||
|
||||
if (currencyDisplayType.location === currencyConstants.allCurrencyDisplayLocation.BeforeAmount) {
|
||||
return {
|
||||
prependText: symbol
|
||||
};
|
||||
} else if (currencyDisplayType.location === currencyConstants.allCurrencyDisplayLocation.AfterAmount) {
|
||||
return {
|
||||
appendText: symbol
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { CurrencyDisplaySymbol, CurrencyDisplayLocation, type CurrencyPrependAndAppendText, CurrencyDisplayType } from '@/core/currency.ts';
|
||||
import { ALL_CURRENCIES, DEFAULT_CURRENCY_SYMBOL } from '@/consts/currency.ts';
|
||||
|
||||
import { isString, isNumber } from './common.ts';
|
||||
|
||||
export function getCurrencyFraction(currencyCode: string): number | undefined {
|
||||
const currencyInfo = ALL_CURRENCIES[currencyCode];
|
||||
return currencyInfo?.fraction;
|
||||
}
|
||||
|
||||
export function appendCurrencySymbol(value: unknown, currencyDisplayType: CurrencyDisplayType, currencyCode: string, currencyUnit: string, currencyName: string, isPlural: boolean): string | null {
|
||||
if (isNumber(value)) {
|
||||
value = (value as number).toString();
|
||||
}
|
||||
|
||||
if (!isString(value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const symbol = getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
|
||||
|
||||
if (!symbol) {
|
||||
return value as string;
|
||||
}
|
||||
|
||||
const separator = currencyDisplayType.separator || '';
|
||||
let ret = value as string;
|
||||
|
||||
if (symbol.prependText) {
|
||||
ret = symbol.prependText + separator + ret;
|
||||
}
|
||||
|
||||
if (symbol.appendText) {
|
||||
ret = ret + separator + symbol.appendText;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getAmountPrependAndAppendCurrencySymbol(currencyDisplayType: CurrencyDisplayType, currencyCode: string, currencyUnit: string, currencyName: string, isPlural: boolean): CurrencyPrependAndAppendText | null {
|
||||
if (!currencyDisplayType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let symbol = '';
|
||||
|
||||
if (currencyDisplayType.symbol === CurrencyDisplaySymbol.Symbol) {
|
||||
const currencyInfo = ALL_CURRENCIES[currencyCode];
|
||||
|
||||
if (currencyInfo && currencyInfo.symbol && currencyInfo.symbol.normal) {
|
||||
symbol = currencyInfo.symbol.normal;
|
||||
|
||||
if (isPlural && currencyInfo.symbol.plural) {
|
||||
symbol = currencyInfo.symbol.plural;
|
||||
}
|
||||
}
|
||||
|
||||
if (!symbol) {
|
||||
symbol = DEFAULT_CURRENCY_SYMBOL;
|
||||
}
|
||||
} else if (currencyDisplayType.symbol === CurrencyDisplaySymbol.Code) {
|
||||
symbol = currencyCode;
|
||||
} else if (currencyDisplayType.symbol === CurrencyDisplaySymbol.Unit) {
|
||||
symbol = currencyUnit;
|
||||
} else if (currencyDisplayType.symbol === CurrencyDisplaySymbol.Name) {
|
||||
symbol = currencyName;
|
||||
}
|
||||
|
||||
if (currencyDisplayType.location === CurrencyDisplayLocation.BeforeAmount) {
|
||||
return {
|
||||
prependText: symbol
|
||||
};
|
||||
} else if (currencyDisplayType.location === CurrencyDisplayLocation.AfterAmount) {
|
||||
return {
|
||||
appendText: symbol
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import moment from 'moment';
|
||||
|
||||
import dateTimeConstants from '@/consts/datetime.js';
|
||||
import { isObject, isString, isNumber } from './common.js';
|
||||
import { isObject, isString, isNumber } from './common.ts';
|
||||
|
||||
export function isYearMonthValid(year, month) {
|
||||
if (!isNumber(year) || !isNumber(month)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { isString } from './common.js';
|
||||
import { isString } from './common.ts';
|
||||
|
||||
export function getFileExtension(filename) {
|
||||
export function getFileExtension(filename: string): string {
|
||||
if (!filename || !isString(filename)) {
|
||||
return '';
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export function getFileExtension(filename) {
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
|
||||
export function isFileExtensionSupported(filename, supportedExtensions) {
|
||||
export function isFileExtensionSupported(filename: string, supportedExtensions: string): boolean {
|
||||
if (!supportedExtensions) {
|
||||
return false;
|
||||
}
|
||||
+99
-146
@@ -1,18 +1,23 @@
|
||||
import moment from 'moment-timezone';
|
||||
|
||||
import { defaultLanguage, allLanguages } from '@/locales/index.js';
|
||||
import { defaultLanguage, allLanguages } from '@/locales/index.ts';
|
||||
|
||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||
import { CurrencyDisplayType, CurrencySortingType } from '@/core/currency.ts';
|
||||
import { PresetAmountColor } from '@/core/color.ts';
|
||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionEditScopeType, TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||
|
||||
import numeralConstants from '@/consts/numeral.js';
|
||||
import datetimeConstants from '@/consts/datetime.js';
|
||||
import timezoneConstants from '@/consts/timezone.js';
|
||||
import currencyConstants from '@/consts/currency.js';
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import accountConstants from '@/consts/account.js';
|
||||
import fileConstants from '@/consts/file.js';
|
||||
import categoryConstants from '@/consts/category.js';
|
||||
import transactionConstants from '@/consts/transaction.js';
|
||||
import templateConstants from '@/consts/template.js';
|
||||
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||
import { SUPPORTED_IMPORT_FILE_TYPES } from '@/consts/file.ts';
|
||||
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
||||
import statisticsConstants from '@/consts/statistics.js';
|
||||
import apiConstants from '@/consts/api.js';
|
||||
import { KnownErrorCode, SPECIFIED_API_NOT_FOUND_ERRORS, PARAMETERIZED_ERRORS } from '@/consts/api.ts';
|
||||
|
||||
import {
|
||||
isDefined,
|
||||
@@ -22,7 +27,7 @@ import {
|
||||
getNameByKeyValue,
|
||||
copyObjectTo,
|
||||
copyArrayTo
|
||||
} from './common.js';
|
||||
} from './common.ts';
|
||||
|
||||
import {
|
||||
isPM,
|
||||
@@ -53,7 +58,7 @@ import {
|
||||
getCurrencyFraction,
|
||||
appendCurrencySymbol,
|
||||
getAmountPrependAndAppendCurrencySymbol
|
||||
} from './currency.js';
|
||||
} from './currency.ts';
|
||||
|
||||
import {
|
||||
getCategorizedAccountsMap,
|
||||
@@ -201,6 +206,21 @@ function getCurrentLanguageDisplayName(i18nGlobal) {
|
||||
return currentLanguageInfo.displayName;
|
||||
}
|
||||
|
||||
function getLocalizedDisplayNameAndType(nameAndTypes, translateFn) {
|
||||
const ret = [];
|
||||
|
||||
for (let i = 0; i < nameAndTypes.length; i++) {
|
||||
const nameAndType = nameAndTypes[i];
|
||||
|
||||
ret.push({
|
||||
type: nameAndType.type,
|
||||
displayName: translateFn(nameAndType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getDefaultCurrency(translateFn) {
|
||||
return translateFn('default.currency');
|
||||
}
|
||||
@@ -214,7 +234,7 @@ function getCurrencyName(currencyCode, translateFn) {
|
||||
}
|
||||
|
||||
function getCurrencyUnitName(currencyCode, isPlural, translateFn) {
|
||||
const currencyInfo = currencyConstants.all[currencyCode];
|
||||
const currencyInfo = ALL_CURRENCIES[currencyCode];
|
||||
|
||||
if (currencyInfo && currencyInfo.unit) {
|
||||
if (isPlural) {
|
||||
@@ -521,17 +541,16 @@ function getDateTimeFormat(translateFn, allFormatMap, allFormatArray, localeForm
|
||||
function getAllTimezones(includeSystemDefault, translateFn) {
|
||||
const defaultTimezoneOffset = getBrowserTimezoneOffset();
|
||||
const defaultTimezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
||||
const allTimezones = timezoneConstants.all;
|
||||
const allTimezoneInfos = [];
|
||||
|
||||
for (let i = 0; i < allTimezones.length; i++) {
|
||||
const utcOffset = (allTimezones[i].timezoneName !== timezoneConstants.utcTimezoneName ? getTimezoneOffset(allTimezones[i].timezoneName) : '');
|
||||
const displayName = translateFn(`timezone.${allTimezones[i].displayName}`);
|
||||
for (let i = 0; i < ALL_TIMEZONES.length; i++) {
|
||||
const utcOffset = (ALL_TIMEZONES[i].timezoneName !== UTC_TIMEZONE.timezoneName ? getTimezoneOffset(ALL_TIMEZONES[i].timezoneName) : '');
|
||||
const displayName = translateFn(`timezone.${ALL_TIMEZONES[i].displayName}`);
|
||||
|
||||
allTimezoneInfos.push({
|
||||
name: allTimezones[i].timezoneName,
|
||||
name: ALL_TIMEZONES[i].timezoneName,
|
||||
utcOffset: utcOffset,
|
||||
utcOffsetMinutes: getTimezoneOffsetMinutes(allTimezones[i].timezoneName),
|
||||
utcOffsetMinutes: getTimezoneOffsetMinutes(ALL_TIMEZONES[i].timezoneName),
|
||||
displayName: displayName,
|
||||
displayNameWithUtcOffset: `(UTC${utcOffset}) ${displayName}`
|
||||
});
|
||||
@@ -595,11 +614,10 @@ function getTimezoneDifferenceDisplayText(utcOffset, translateFn) {
|
||||
}
|
||||
|
||||
function getAllCurrencies(translateFn) {
|
||||
const allCurrencyCodes = currencyConstants.all;
|
||||
const allCurrencies = [];
|
||||
|
||||
for (let currencyCode in allCurrencyCodes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCurrencyCodes, currencyCode)) {
|
||||
for (let currencyCode in ALL_CURRENCIES) {
|
||||
if (!Object.prototype.hasOwnProperty.call(ALL_CURRENCIES, currencyCode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -772,12 +790,12 @@ function getAllTimezoneTypesUsedForStatistics(currentTimezone, translateFn) {
|
||||
|
||||
return [
|
||||
{
|
||||
displayName: translateFn('Application Timezone') + ` (UTC${currentTimezoneOffset})`,
|
||||
type: timezoneConstants.allTimezoneTypesUsedForStatistics.ApplicationTimezone
|
||||
displayName: translateFn(TimezoneTypeForStatistics.ApplicationTimezone.name) + ` (UTC${currentTimezoneOffset})`,
|
||||
type: TimezoneTypeForStatistics.ApplicationTimezone.type
|
||||
},
|
||||
{
|
||||
displayName: translateFn('Transaction Timezone'),
|
||||
type: timezoneConstants.allTimezoneTypesUsedForStatistics.TransactionTimezone
|
||||
displayName: translateFn(TimezoneTypeForStatistics.TransactionTimezone.name),
|
||||
type: TimezoneTypeForStatistics.TransactionTimezone.type
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -851,10 +869,10 @@ function getAllDigitGroupingTypes(translateFn) {
|
||||
|
||||
function getAllCurrencyDisplayTypes(userStore, settingsStore, translateFn) {
|
||||
const defaultCurrencyDisplayTypeName = translateFn('default.currencyDisplayType');
|
||||
let defaultCurrencyDisplayType = currencyConstants.allCurrencyDisplayType[defaultCurrencyDisplayTypeName];
|
||||
let defaultCurrencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
||||
|
||||
if (!defaultCurrencyDisplayType) {
|
||||
defaultCurrencyDisplayType = currencyConstants.defaultCurrencyDisplayType;
|
||||
defaultCurrencyDisplayType = CurrencyDisplayType.Default;
|
||||
}
|
||||
|
||||
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
||||
@@ -863,12 +881,14 @@ function getAllCurrencyDisplayTypes(userStore, settingsStore, translateFn) {
|
||||
const defaultSampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, translateFn, userStore, settingsStore, false, defaultCurrencyDisplayType);
|
||||
|
||||
ret.push({
|
||||
type: currencyConstants.defaultCurrencyDisplayTypeValue,
|
||||
type: CurrencyDisplayType.LanguageDefaultType,
|
||||
displayName: `${translateFn('Language Default')} (${defaultSampleValue})`
|
||||
});
|
||||
|
||||
for (let i = 0; i < currencyConstants.allCurrencyDisplayTypeArray.length; i++) {
|
||||
const type = currencyConstants.allCurrencyDisplayTypeArray[i];
|
||||
const allCurrencyDisplayTypes = CurrencyDisplayType.values();
|
||||
|
||||
for (let i = 0; i < allCurrencyDisplayTypes.length; i++) {
|
||||
const type = allCurrencyDisplayTypes[i];
|
||||
const sampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, translateFn, userStore, settingsStore, false, type);
|
||||
const displayName = `${translateFn(type.name)} (${sampleValue})`
|
||||
|
||||
@@ -882,22 +902,7 @@ function getAllCurrencyDisplayTypes(userStore, settingsStore, translateFn) {
|
||||
}
|
||||
|
||||
function getAllCurrencySortingTypes(translateFn) {
|
||||
const allCurrencySortingTypes = [];
|
||||
|
||||
for (const sortingTypeField in currencyConstants.allCurrencySortingTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(currencyConstants.allCurrencySortingTypes, sortingTypeField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sortingType = currencyConstants.allCurrencySortingTypes[sortingTypeField];
|
||||
|
||||
allCurrencySortingTypes.push({
|
||||
type: sortingType.type,
|
||||
displayName: translateFn(sortingType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allCurrencySortingTypes;
|
||||
return getLocalizedDisplayNameAndType(CurrencySortingType.values(), translateFn);
|
||||
}
|
||||
|
||||
function getCurrentDecimalSeparator(translateFn, decimalSeparator) {
|
||||
@@ -970,15 +975,15 @@ function getFormattedAmount(value, translateFn, userStore, currencyCode) {
|
||||
}
|
||||
|
||||
function getCurrentCurrencyDisplayType(translateFn, userStore) {
|
||||
let currencyDisplayType = currencyConstants.allCurrencyDisplayTypeMap[userStore.currentUserCurrencyDisplayType];
|
||||
let currencyDisplayType = CurrencyDisplayType.valueOf(userStore.currentUserCurrencyDisplayType);
|
||||
|
||||
if (!currencyDisplayType) {
|
||||
const defaultCurrencyDisplayTypeName = translateFn('default.currencyDisplayType');
|
||||
currencyDisplayType = currencyConstants.allCurrencyDisplayType[defaultCurrencyDisplayTypeName];
|
||||
currencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
||||
}
|
||||
|
||||
if (!currencyDisplayType) {
|
||||
currencyDisplayType = currencyConstants.defaultCurrencyDisplayType;
|
||||
currencyDisplayType = CurrencyDisplayType.Default;
|
||||
}
|
||||
|
||||
return currencyDisplayType;
|
||||
@@ -1047,65 +1052,57 @@ function getAmountPrependAndAppendText(currencyCode, userStore, settingsStore, i
|
||||
}
|
||||
|
||||
function getAllExpenseIncomeAmountColors(translateFn, expenseOrIncome) {
|
||||
const allAmountColors = [];
|
||||
const ret = [];
|
||||
let defaultAmountName = '';
|
||||
|
||||
if (expenseOrIncome === 1) { // expense
|
||||
defaultAmountName = colorConstants.defaultExpenseAmountColor.name;
|
||||
defaultAmountName = PresetAmountColor.DefaultExpenseColor.name;
|
||||
} else if (expenseOrIncome === 2) { // income
|
||||
defaultAmountName = colorConstants.defaultIncomeAmountColor.name;
|
||||
defaultAmountName = PresetAmountColor.DefaultIncomeColor.name;
|
||||
}
|
||||
|
||||
if (defaultAmountName) {
|
||||
defaultAmountName = translateFn('color.amount.' + defaultAmountName);
|
||||
}
|
||||
|
||||
allAmountColors.push({
|
||||
type: colorConstants.defaultExpenseIncomeAmountValue,
|
||||
ret.push({
|
||||
type: PresetAmountColor.SystemDefaultType,
|
||||
displayName: translateFn('System Default') + (defaultAmountName ? ` (${defaultAmountName})` : '')
|
||||
});
|
||||
|
||||
for (let i = 0; i < colorConstants.allAmountColorsArray.length; i++) {
|
||||
const amountColor = colorConstants.allAmountColorsArray[i];
|
||||
const allPresetAmountColors = PresetAmountColor.values();
|
||||
|
||||
allAmountColors.push({
|
||||
for (let i = 0; i < allPresetAmountColors.length; i++) {
|
||||
const amountColor = allPresetAmountColors[i];
|
||||
|
||||
ret.push({
|
||||
type: amountColor.type,
|
||||
displayName: translateFn('color.amount.' + amountColor.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allAmountColors;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getAllAccountCategories(translateFn) {
|
||||
const allAccountCategories = [];
|
||||
const ret = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
const accountCategory = accountConstants.allCategories[i];
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const accountCategory = allCategories[i];
|
||||
|
||||
allAccountCategories.push({
|
||||
id: accountCategory.id,
|
||||
ret.push({
|
||||
type: accountCategory.type,
|
||||
displayName: translateFn(accountCategory.name),
|
||||
defaultAccountIconId: accountCategory.defaultAccountIconId
|
||||
});
|
||||
}
|
||||
|
||||
return allAccountCategories;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getAllAccountTypes(translateFn) {
|
||||
const allAccountTypes = [];
|
||||
|
||||
for (let i = 0; i < accountConstants.allAccountTypesArray.length; i++) {
|
||||
const accountType = accountConstants.allAccountTypesArray[i];
|
||||
|
||||
allAccountTypes.push({
|
||||
id: accountType.id,
|
||||
displayName: translateFn(accountType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allAccountTypes;
|
||||
return getLocalizedDisplayNameAndType(AccountType.values(), translateFn);
|
||||
}
|
||||
|
||||
function getAllCategoricalChartTypes(translateFn) {
|
||||
@@ -1202,60 +1199,15 @@ function getAllStatisticsDateAggregationTypes(translateFn) {
|
||||
}
|
||||
|
||||
function getAllTransactionEditScopeTypes(translateFn) {
|
||||
const allEditScopeTypes = [];
|
||||
|
||||
for (const typeName in transactionConstants.allTransactionEditScopeTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionConstants.allTransactionEditScopeTypes, typeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const editScopeType = transactionConstants.allTransactionEditScopeTypes[typeName];
|
||||
|
||||
allEditScopeTypes.push({
|
||||
type: editScopeType.type,
|
||||
displayName: translateFn(editScopeType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allEditScopeTypes;
|
||||
return getLocalizedDisplayNameAndType(TransactionEditScopeType.values(), translateFn);
|
||||
}
|
||||
|
||||
function getAllTransactionTagFilterTypes(translateFn) {
|
||||
const allTagFilterTypes = [];
|
||||
|
||||
for (const typeName in transactionConstants.allTransactionTagFilterTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionConstants.allTransactionTagFilterTypes, typeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tagFilterType = transactionConstants.allTransactionTagFilterTypes[typeName];
|
||||
|
||||
allTagFilterTypes.push({
|
||||
type: tagFilterType.type,
|
||||
displayName: translateFn(tagFilterType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allTagFilterTypes;
|
||||
return getLocalizedDisplayNameAndType(TransactionTagFilterType.values(), translateFn);
|
||||
}
|
||||
|
||||
function getAllTransactionScheduledFrequencyTypes(translateFn) {
|
||||
const allScheduledFrequencyTypes = [];
|
||||
|
||||
for (const typeName in templateConstants.allTemplateScheduledFrequencyTypes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(templateConstants.allTemplateScheduledFrequencyTypes, typeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const frequencyType = templateConstants.allTemplateScheduledFrequencyTypes[typeName];
|
||||
|
||||
allScheduledFrequencyTypes.push({
|
||||
type: frequencyType.type,
|
||||
displayName: translateFn(frequencyType.name)
|
||||
});
|
||||
}
|
||||
|
||||
return allScheduledFrequencyTypes;
|
||||
return getLocalizedDisplayNameAndType(ScheduledTemplateFrequencyType.values(), translateFn);
|
||||
}
|
||||
|
||||
function getAllTransactionDefaultCategories(categoryType, locale, translateFn) {
|
||||
@@ -1263,7 +1215,7 @@ function getAllTransactionDefaultCategories(categoryType, locale, translateFn) {
|
||||
const categoryTypes = [];
|
||||
|
||||
if (categoryType === 0) {
|
||||
for (let i = categoryConstants.allCategoryTypes.Income; i <= categoryConstants.allCategoryTypes.Transfer; i++) {
|
||||
for (let i = CategoryType.Income; i <= CategoryType.Transfer; i++) {
|
||||
categoryTypes.push(i);
|
||||
}
|
||||
} else {
|
||||
@@ -1275,12 +1227,12 @@ function getAllTransactionDefaultCategories(categoryType, locale, translateFn) {
|
||||
const categoryType = categoryTypes[i];
|
||||
let defaultCategories = [];
|
||||
|
||||
if (categoryType === categoryConstants.allCategoryTypes.Income) {
|
||||
defaultCategories = copyArrayTo(categoryConstants.defaultIncomeCategories, []);
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Expense) {
|
||||
defaultCategories = copyArrayTo(categoryConstants.defaultExpenseCategories, []);
|
||||
} else if (categoryType === categoryConstants.allCategoryTypes.Transfer) {
|
||||
defaultCategories = copyArrayTo(categoryConstants.defaultTransferCategories, []);
|
||||
if (categoryType === CategoryType.Income) {
|
||||
defaultCategories = copyArrayTo(DEFAULT_INCOME_CATEGORIES, []);
|
||||
} else if (categoryType === CategoryType.Expense) {
|
||||
defaultCategories = copyArrayTo(DEFAULT_EXPENSE_CATEGORIES, []);
|
||||
} else if (categoryType === CategoryType.Transfer) {
|
||||
defaultCategories = copyArrayTo(DEFAULT_TRANSFER_CATEGORIES, []);
|
||||
}
|
||||
|
||||
for (let j = 0; j < defaultCategories.length; j++) {
|
||||
@@ -1330,15 +1282,15 @@ function getAllDisplayExchangeRates(settingsStore, exchangeRatesData, translateF
|
||||
});
|
||||
}
|
||||
|
||||
if (settingsStore.appSettings.currencySortByInExchangeRatesPage === currencyConstants.allCurrencySortingTypes.Name.type) {
|
||||
if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.Name.type) {
|
||||
availableExchangeRates.sort(function(c1, c2) {
|
||||
return c1.currencyDisplayName.localeCompare(c2.currencyDisplayName);
|
||||
});
|
||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === currencyConstants.allCurrencySortingTypes.CurrencyCode.type) {
|
||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.CurrencyCode.type) {
|
||||
availableExchangeRates.sort(function(c1, c2) {
|
||||
return c1.currencyCode.localeCompare(c2.currencyCode);
|
||||
});
|
||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === currencyConstants.allCurrencySortingTypes.ExchangeRate.type) {
|
||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.ExchangeRate.type) {
|
||||
availableExchangeRates.sort(function(c1, c2) {
|
||||
const rate1 = parseFloat(c1.rate);
|
||||
const rate2 = parseFloat(c2.rate);
|
||||
@@ -1359,8 +1311,8 @@ function getAllDisplayExchangeRates(settingsStore, exchangeRatesData, translateF
|
||||
function getAllSupportedImportFileTypes(i18nGlobal, translateFn) {
|
||||
const allSupportedImportFileTypes = [];
|
||||
|
||||
for (let i = 0; i < fileConstants.supportedImportFileTypes.length; i++) {
|
||||
const fileType = fileConstants.supportedImportFileTypes[i];
|
||||
for (let i = 0; i < SUPPORTED_IMPORT_FILE_TYPES.length; i++) {
|
||||
const fileType = SUPPORTED_IMPORT_FILE_TYPES[i];
|
||||
let document = {
|
||||
language: '',
|
||||
displayLanguageName: '',
|
||||
@@ -1434,16 +1386,17 @@ function getEnableDisableOptions(translateFn) {
|
||||
|
||||
function getCategorizedAccountsWithDisplayBalance(allVisibleAccounts, showAccountBalance, defaultCurrency, userStore, settingsStore, exchangeRatesStore, translateFn) {
|
||||
const ret = [];
|
||||
const allCategories = AccountCategory.values();
|
||||
const categorizedAccounts = copyObjectTo(getCategorizedAccountsMap(allVisibleAccounts), {});
|
||||
|
||||
for (let i = 0; i < accountConstants.allCategories.length; i++) {
|
||||
const category = accountConstants.allCategories[i];
|
||||
for (let i = 0; i < allCategories.length; i++) {
|
||||
const category = allCategories[i];
|
||||
|
||||
if (!categorizedAccounts[category.id]) {
|
||||
if (!categorizedAccounts[category.type]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountCategory = categorizedAccounts[category.id];
|
||||
const accountCategory = categorizedAccounts[category.type];
|
||||
|
||||
if (accountCategory.accounts) {
|
||||
for (let i = 0; i < accountCategory.accounts.length; i++) {
|
||||
@@ -1527,20 +1480,20 @@ function joinMultiText(textArray, translateFn) {
|
||||
}
|
||||
|
||||
function getLocalizedError(error) {
|
||||
if (error.errorCode === apiConstants.apiNotFoundErrorCode && apiConstants.specifiedApiNotFoundErrors[error.path]) {
|
||||
if (error.errorCode === KnownErrorCode.ApiNotFound && SPECIFIED_API_NOT_FOUND_ERRORS[error.path]) {
|
||||
return {
|
||||
message: `${apiConstants.specifiedApiNotFoundErrors[error.path].message}`
|
||||
message: `${SPECIFIED_API_NOT_FOUND_ERRORS[error.path].message}`
|
||||
};
|
||||
}
|
||||
|
||||
if (error.errorCode !== apiConstants.validatorErrorCode) {
|
||||
if (error.errorCode !== KnownErrorCode.ValidatorError) {
|
||||
return {
|
||||
message: `error.${error.errorMessage}`
|
||||
};
|
||||
}
|
||||
|
||||
for (let i = 0; i < apiConstants.parameterizedErrors.length; i++) {
|
||||
const errorInfo = apiConstants.parameterizedErrors[i];
|
||||
for (let i = 0; i < PARAMETERIZED_ERRORS.length; i++) {
|
||||
const errorInfo = PARAMETERIZED_ERRORS[i];
|
||||
const matches = error.errorMessage.match(errorInfo.regex);
|
||||
|
||||
if (matches && matches.length === errorInfo.parameters.length + 1) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
export function getIconsInRows(allIconInfos, itemPerRow) {
|
||||
const ret = [];
|
||||
import type { IconInfo, IconInfoWithId } from '@/core/icon.ts';
|
||||
|
||||
export function getIconsInRows(allIconInfos: IconInfo[], itemPerRow: number): IconInfoWithId[][] {
|
||||
const ret: IconInfoWithId[][] = [];
|
||||
let rowCount = 0;
|
||||
|
||||
for (let iconInfoId in allIconInfos) {
|
||||
for (const iconInfoId in allIconInfos) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allIconInfos, iconInfoId)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export default {
|
||||
getLicense: () => {
|
||||
return __EZBOOKKEEPING_LICENSE__; // eslint-disable-line
|
||||
},
|
||||
getThirdPartyLicenses: () => {
|
||||
return __EZBOOKKEEPING_THIRD_PARTY_LICENSES__ || []; // eslint-disable-line
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export function getLicense(): string {
|
||||
return __EZBOOKKEEPING_LICENSE__;
|
||||
}
|
||||
|
||||
export function getThirdPartyLicenses(): string[] {
|
||||
return __EZBOOKKEEPING_THIRD_PARTY_LICENSES__ || [];
|
||||
}
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { asyncLoadAssets } from '@/lib/misc.js';
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.js';
|
||||
import {
|
||||
getAmapSecurityVerificationMethod,
|
||||
getAmapApiExternalProxyUrl,
|
||||
getAmapApplicationSecret
|
||||
} from '@/lib/server_settings.js';
|
||||
} from '@/lib/server_settings.ts';
|
||||
import logger from '@/lib/logger.js';
|
||||
|
||||
const amapHolder = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { asyncLoadAssets } from '@/lib/misc.js';
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.js';
|
||||
import logger from '@/lib/logger.js';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { asyncLoadAssets } from '@/lib/misc.js';
|
||||
import { asyncLoadAssets } from '@/lib/misc.ts';
|
||||
import services from '@/lib/services.js';
|
||||
|
||||
const googleMapHolder = {
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
import mapConstants from '@/consts/map.js';
|
||||
import { LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
|
||||
import {
|
||||
getMapProvider
|
||||
} from '@/lib/server_settings.js';
|
||||
} from '@/lib/server_settings.ts';
|
||||
|
||||
import {
|
||||
loadLeafletMapAssets,
|
||||
@@ -45,8 +45,8 @@ import {
|
||||
export function getMapWebsite() {
|
||||
if (getMapProvider() === 'custom') {
|
||||
return '';
|
||||
} else if (mapConstants.leafletTileSources[getMapProvider()]) {
|
||||
return mapConstants.leafletTileSources[getMapProvider()].website;
|
||||
} else if (LEAFLET_TILE_SOURCES[getMapProvider()]) {
|
||||
return LEAFLET_TILE_SOURCES[getMapProvider()].website;
|
||||
} else if (getMapProvider() === 'googlemap') {
|
||||
return getGoogleMapWebsite();
|
||||
} else if (getMapProvider() === 'baidumap') {
|
||||
@@ -57,7 +57,7 @@ export function getMapWebsite() {
|
||||
}
|
||||
|
||||
export function loadMapAssets(language) {
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
return loadLeafletMapAssets(language);
|
||||
} else if (getMapProvider() === 'googlemap') {
|
||||
return loadGoogleMapAssets(language);
|
||||
@@ -69,7 +69,7 @@ export function loadMapAssets(language) {
|
||||
}
|
||||
|
||||
export function createMapHolder() {
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
return createLeafletMapHolder(getMapProvider());
|
||||
} else if (getMapProvider() === 'googlemap') {
|
||||
return createGoogleMapHolder(getMapProvider());
|
||||
@@ -87,7 +87,7 @@ export function initMapInstance(mapHolder, mapContainer, options) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
createLeafletMapInstance(mapHolder, mapContainer, options);
|
||||
} else if (mapHolder.mapProvider === 'googlemap') {
|
||||
createGoogleMapInstance(mapHolder, mapContainer, options);
|
||||
@@ -103,7 +103,7 @@ export function setMapCenterTo(mapHolder, center, zoomLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
setLeafletMapCenterTo(mapHolder, center, zoomLevel);
|
||||
} else if (mapHolder.mapProvider === 'googlemap') {
|
||||
setGoogleMapCenterTo(mapHolder, center, zoomLevel);
|
||||
@@ -119,7 +119,7 @@ export function setMapCenterMarker(mapHolder, position) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
setLeafletMapCenterMaker(mapHolder, position);
|
||||
} else if (mapHolder.mapProvider === 'googlemap') {
|
||||
setGoogleMapCenterMaker(mapHolder, position);
|
||||
@@ -135,7 +135,7 @@ export function removeMapCenterMarker(mapHolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapConstants.leafletTileSources[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
if (LEAFLET_TILE_SOURCES[getMapProvider()] || getMapProvider() === 'custom') {
|
||||
removeLeafletMapCenterMaker(mapHolder);
|
||||
} else if (mapHolder.mapProvider === 'googlemap') {
|
||||
removeGoogleMapCenterMaker(mapHolder);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import mapConstants from '@/consts/map.js';
|
||||
import { LEAFLET_TILE_SOURCES } from '@/consts/map.ts';
|
||||
import {
|
||||
isMapDataFetchProxyEnabled,
|
||||
getCustomMapTileLayerUrl,
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
getCustomMapDefaultZoomLevel,
|
||||
getTomTomMapAPIKey,
|
||||
getTianDiTuMapAPIKey
|
||||
} from '@/lib/server_settings.js';
|
||||
} from '@/lib/server_settings.ts';
|
||||
import services from '@/lib/services.js';
|
||||
|
||||
const leafletHolder = {
|
||||
@@ -24,7 +24,7 @@ export function loadLeafletMapAssets() {
|
||||
}
|
||||
|
||||
export function createLeafletMapHolder(mapProvider) {
|
||||
const mapTileSource = mapConstants.leafletTileSources[mapProvider];
|
||||
const mapTileSource = LEAFLET_TILE_SOURCES[mapProvider];
|
||||
|
||||
if (mapProvider !== 'custom' && !mapTileSource) {
|
||||
return null;
|
||||
@@ -60,7 +60,7 @@ export function createLeafletMapInstance(mapHolder, mapContainer, options) {
|
||||
let mapTileSource = null;
|
||||
|
||||
if (mapHolder.mapProvider !== 'custom') {
|
||||
mapTileSource = Object.assign({}, mapConstants.leafletTileSources[mapHolder.mapProvider]);
|
||||
mapTileSource = Object.assign({}, LEAFLET_TILE_SOURCES[mapHolder.mapProvider]);
|
||||
} else {
|
||||
mapTileSource = createCustomMapSource();
|
||||
}
|
||||
|
||||
-229
@@ -1,229 +0,0 @@
|
||||
import Clipboard from 'clipboard';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import uaParser from 'ua-parser-js';
|
||||
|
||||
import { base64encode } from './common.js';
|
||||
|
||||
export function asyncLoadAssets(type, assetUrl) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
let addElement = false;
|
||||
let el = null;
|
||||
|
||||
if (type === 'js') {
|
||||
el = document.querySelector('script[src="' + assetUrl + '"]');
|
||||
} else if (type === 'css') {
|
||||
el = document.querySelector('link[href="' + assetUrl + '"]');
|
||||
} else {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'notsupport'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!el) {
|
||||
if (type === 'js') {
|
||||
el = document.createElement('script');
|
||||
el.setAttribute('type', 'text/javascript');
|
||||
el.setAttribute('async', 'true');
|
||||
el.setAttribute('src', assetUrl);
|
||||
} else if (type === 'css') {
|
||||
el = document.createElement('link');
|
||||
el.setAttribute('rel', 'stylesheet');
|
||||
el.setAttribute('type', 'text/css');
|
||||
el.setAttribute('href', assetUrl);
|
||||
}
|
||||
|
||||
addElement = true;
|
||||
} else if (el.hasAttribute('data-loaded')) {
|
||||
resolve({
|
||||
type: type,
|
||||
assetUrl: assetUrl
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
el.addEventListener('load', () => {
|
||||
el.setAttribute('data-loaded', true);
|
||||
resolve({
|
||||
type: type,
|
||||
assetUrl: assetUrl
|
||||
});
|
||||
});
|
||||
el.addEventListener('error', () => {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'error'
|
||||
});
|
||||
});
|
||||
el.addEventListener('abort', () => {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'abort'
|
||||
});
|
||||
});
|
||||
|
||||
if (addElement) {
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function generateRandomString() {
|
||||
let baseString = 'ebk_' + new Date().getTime();
|
||||
|
||||
if (crypto && crypto.getRandomValues) {
|
||||
const randoms = new Uint8Array(256);
|
||||
crypto.getRandomValues(randoms);
|
||||
baseString += '_' + base64encode(randoms);
|
||||
} else {
|
||||
baseString += '_' + Math.random();
|
||||
}
|
||||
|
||||
return CryptoJS.SHA256(baseString).toString();
|
||||
}
|
||||
|
||||
export function generateRandomUUID() {
|
||||
const randomString = generateRandomString();
|
||||
|
||||
// convert hash string to UUID Version 8
|
||||
const uuid = randomString.substring(0, 8) + '-'
|
||||
+ randomString.substring(8, 12) + '-'
|
||||
+ '8' + randomString.substring(13, 16) + '-'
|
||||
+ (0x8 | (parseInt(randomString.charAt(16), 16) & 0x3)).toString(16) + randomString.substring(17, 20) + '-'
|
||||
+ randomString.substring(20, 32);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
export function isSessionUserAgentCreatedByCli(ua) {
|
||||
return ua === 'ezbookkeeping Cli';
|
||||
}
|
||||
|
||||
export function parseUserAgent(ua) {
|
||||
const uaParseRet = uaParser(ua);
|
||||
|
||||
return {
|
||||
device: {
|
||||
vendor: uaParseRet.device.vendor,
|
||||
model: uaParseRet.device.model,
|
||||
type: uaParseRet.device.type
|
||||
},
|
||||
os: {
|
||||
name: uaParseRet.os.name,
|
||||
version: uaParseRet.os.version
|
||||
},
|
||||
browser: {
|
||||
name: uaParseRet.browser.name,
|
||||
version: uaParseRet.browser.version
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function parseDeviceInfo(uaInfo) {
|
||||
if (!uaInfo) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let result = '';
|
||||
|
||||
if (uaInfo.device && uaInfo.device.model) {
|
||||
result = uaInfo.device.model;
|
||||
} else if (uaInfo.os && uaInfo.os.name) {
|
||||
result = uaInfo.os.name;
|
||||
|
||||
if (uaInfo.os.version) {
|
||||
result += ' ' + uaInfo.os.version;
|
||||
}
|
||||
}
|
||||
|
||||
if (uaInfo.browser && uaInfo.browser.name) {
|
||||
let browserInfo = uaInfo.browser.name;
|
||||
|
||||
if (uaInfo.browser.version) {
|
||||
browserInfo += ' ' + uaInfo.browser.version;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result += ' (' + browserInfo + ')';
|
||||
} else {
|
||||
result = browserInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return 'Unknown Device';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseSessionInfo(token) {
|
||||
const isCreatedByCli = isSessionUserAgentCreatedByCli(token.userAgent);
|
||||
const uaInfo = parseUserAgent(token.userAgent);
|
||||
let deviceType = '';
|
||||
|
||||
if (isCreatedByCli) {
|
||||
deviceType = 'cli';
|
||||
} else {
|
||||
if (uaInfo && uaInfo.device) {
|
||||
if (uaInfo.device.type === 'mobile') {
|
||||
deviceType = 'phone';
|
||||
} else if (uaInfo.device.type === 'wearable') {
|
||||
deviceType = 'wearable';
|
||||
} else if (uaInfo.device.type === 'tablet') {
|
||||
deviceType = 'tablet';
|
||||
} else if (uaInfo.device.type === 'smarttv') {
|
||||
deviceType = 'tv';
|
||||
} else {
|
||||
deviceType = 'default';
|
||||
}
|
||||
} else {
|
||||
deviceType = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tokenId: token.tokenId,
|
||||
isCurrent: token.isCurrent,
|
||||
deviceType: deviceType,
|
||||
deviceInfo: isCreatedByCli ? token.userAgent : parseDeviceInfo(uaInfo),
|
||||
createdByCli: isCreatedByCli,
|
||||
lastSeen: token.lastSeen
|
||||
}
|
||||
}
|
||||
|
||||
export function makeButtonCopyToClipboard({ text, el, successCallback, errorCallback }) {
|
||||
const clipboard = new Clipboard(el, {
|
||||
text: function () {
|
||||
return text;
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
if (successCallback) {
|
||||
successCallback(e);
|
||||
}
|
||||
});
|
||||
|
||||
clipboard.on('error', (e) => {
|
||||
if (errorCallback) {
|
||||
errorCallback(e);
|
||||
}
|
||||
});
|
||||
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
export function changeClipboardObjectText(clipboard, text) {
|
||||
if (!clipboard) {
|
||||
return;
|
||||
}
|
||||
|
||||
clipboard.text = function () {
|
||||
return text;
|
||||
};
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
import { base64encode } from './common.ts';
|
||||
|
||||
export interface AsyncLoadAssetsResult {
|
||||
readonly type: string;
|
||||
readonly assetUrl: string;
|
||||
}
|
||||
|
||||
export function asyncLoadAssets(type: string, assetUrl: string): Promise<AsyncLoadAssetsResult> {
|
||||
return new Promise(function (resolve, reject) {
|
||||
let addElement = false;
|
||||
let el = null;
|
||||
|
||||
if (type === 'js') {
|
||||
el = document.querySelector('script[src="' + assetUrl + '"]');
|
||||
} else if (type === 'css') {
|
||||
el = document.querySelector('link[href="' + assetUrl + '"]');
|
||||
} else {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'notsupport'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!el) {
|
||||
if (type === 'js') {
|
||||
el = document.createElement('script');
|
||||
el.setAttribute('type', 'text/javascript');
|
||||
el.setAttribute('async', 'true');
|
||||
el.setAttribute('src', assetUrl);
|
||||
} else if (type === 'css') {
|
||||
el = document.createElement('link');
|
||||
el.setAttribute('rel', 'stylesheet');
|
||||
el.setAttribute('type', 'text/css');
|
||||
el.setAttribute('href', assetUrl);
|
||||
}
|
||||
|
||||
addElement = true;
|
||||
} else if (el.hasAttribute('data-loaded')) {
|
||||
resolve({
|
||||
type: type,
|
||||
assetUrl: assetUrl
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!el) {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'unexpected'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
el.addEventListener('load', () => {
|
||||
el.setAttribute('data-loaded', 'true');
|
||||
resolve({
|
||||
type: type,
|
||||
assetUrl: assetUrl
|
||||
});
|
||||
});
|
||||
el.addEventListener('error', () => {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'error'
|
||||
});
|
||||
});
|
||||
el.addEventListener('abort', () => {
|
||||
reject({
|
||||
type: type,
|
||||
assetUrl: assetUrl,
|
||||
error: 'abort'
|
||||
});
|
||||
});
|
||||
|
||||
if (addElement) {
|
||||
document.head.appendChild(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function generateRandomString(): string {
|
||||
let baseString = 'ebk_' + new Date().getTime();
|
||||
|
||||
if (crypto && crypto.getRandomValues) {
|
||||
const randoms = new Uint8Array(256);
|
||||
crypto.getRandomValues(randoms);
|
||||
baseString += '_' + base64encode(randoms.buffer);
|
||||
} else {
|
||||
baseString += '_' + Math.random();
|
||||
}
|
||||
|
||||
return CryptoJS.SHA256(baseString).toString();
|
||||
}
|
||||
|
||||
export function generateRandomUUID(): string {
|
||||
const randomString = generateRandomString();
|
||||
|
||||
// convert hash string to UUID Version 8
|
||||
const uuid = randomString.substring(0, 8) + '-'
|
||||
+ randomString.substring(8, 12) + '-'
|
||||
+ '8' + randomString.substring(13, 16) + '-'
|
||||
+ (0x8 | (parseInt(randomString.charAt(16), 16) & 0x3)).toString(16) + randomString.substring(17, 20) + '-'
|
||||
+ randomString.substring(20, 32);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import numeralConstants from '@/consts/numeral.js';
|
||||
|
||||
import { isString, isNumber, removeAll } from './common.js';
|
||||
import { isString, isNumber, removeAll } from './common.ts';
|
||||
|
||||
export function appendDigitGroupingSymbol(value, options) {
|
||||
if (isNumber(value)) {
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
const serverSettingsGlobalVariableName = 'EZBOOKKEEPING_SERVER_SETTINGS';
|
||||
|
||||
function getServerSetting(key) {
|
||||
const settings = window[serverSettingsGlobalVariableName] || {};
|
||||
return settings[key];
|
||||
}
|
||||
|
||||
export function isUserRegistrationEnabled() {
|
||||
return getServerSetting('r') === 1;
|
||||
}
|
||||
|
||||
export function isUserForgetPasswordEnabled() {
|
||||
return getServerSetting('f') === 1;
|
||||
}
|
||||
|
||||
export function isUserVerifyEmailEnabled() {
|
||||
return getServerSetting('v') === 1;
|
||||
}
|
||||
|
||||
export function isTransactionPicturesEnabled() {
|
||||
return getServerSetting('p') === 1;
|
||||
}
|
||||
|
||||
export function isUserScheduledTransactionEnabled() {
|
||||
return getServerSetting('s') === 1;
|
||||
}
|
||||
|
||||
export function isDataExportingEnabled() {
|
||||
return getServerSetting('e') === 1;
|
||||
}
|
||||
|
||||
export function isDataImportingEnabled() {
|
||||
return getServerSetting('i') === 1;
|
||||
}
|
||||
|
||||
export function getLoginPageTips() {
|
||||
return getServerSetting('lpt');
|
||||
}
|
||||
|
||||
export function getMapProvider() {
|
||||
return getServerSetting('m');
|
||||
}
|
||||
|
||||
export function isMapDataFetchProxyEnabled() {
|
||||
return getServerSetting('mp') === 1;
|
||||
}
|
||||
|
||||
export function getCustomMapTileLayerUrl() {
|
||||
return getServerSetting('cmsu');
|
||||
}
|
||||
|
||||
export function getCustomMapAnnotationLayerUrl() {
|
||||
return getServerSetting('cmau');
|
||||
}
|
||||
|
||||
export function isCustomMapAnnotationLayerDataFetchProxyEnabled() {
|
||||
return getServerSetting('cmap') === 1;
|
||||
}
|
||||
|
||||
export function getCustomMapMinZoomLevel() {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[0]) ? parseInt(zoomLevelSettings[0]) : 1;
|
||||
}
|
||||
|
||||
export function getCustomMapMaxZoomLevel() {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[1]) ? parseInt(zoomLevelSettings[1]) : 18;
|
||||
}
|
||||
|
||||
export function getCustomMapDefaultZoomLevel() {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[2]) ? parseInt(zoomLevelSettings[2]) : 14;
|
||||
}
|
||||
|
||||
export function getTomTomMapAPIKey() {
|
||||
return getServerSetting('tmak');
|
||||
}
|
||||
|
||||
export function getTianDiTuMapAPIKey() {
|
||||
return getServerSetting('tdak');
|
||||
}
|
||||
|
||||
export function getGoogleMapAPIKey() {
|
||||
return getServerSetting('gmak');
|
||||
}
|
||||
|
||||
export function getBaiduMapAK() {
|
||||
return getServerSetting('bmak');
|
||||
}
|
||||
|
||||
export function getAmapApplicationKey() {
|
||||
return getServerSetting('amak');
|
||||
}
|
||||
|
||||
export function getAmapSecurityVerificationMethod() {
|
||||
return getServerSetting('amsv');
|
||||
}
|
||||
|
||||
export function getAmapApiExternalProxyUrl() {
|
||||
return getServerSetting('amep');
|
||||
}
|
||||
|
||||
export function getAmapApplicationSecret() {
|
||||
return getServerSetting('amas');
|
||||
}
|
||||
|
||||
export function getExchangeRatesRequestTimeout() {
|
||||
return getServerSetting('errt');
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
function getServerSetting(key: string): string | number | boolean | undefined | null {
|
||||
const settings = window.EZBOOKKEEPING_SERVER_SETTINGS || {};
|
||||
return settings[key];
|
||||
}
|
||||
|
||||
export function isUserRegistrationEnabled(): boolean {
|
||||
return getServerSetting('r') === 1;
|
||||
}
|
||||
|
||||
export function isUserForgetPasswordEnabled(): boolean {
|
||||
return getServerSetting('f') === 1;
|
||||
}
|
||||
|
||||
export function isUserVerifyEmailEnabled(): boolean {
|
||||
return getServerSetting('v') === 1;
|
||||
}
|
||||
|
||||
export function isTransactionPicturesEnabled(): boolean {
|
||||
return getServerSetting('p') === 1;
|
||||
}
|
||||
|
||||
export function isUserScheduledTransactionEnabled(): boolean {
|
||||
return getServerSetting('s') === 1;
|
||||
}
|
||||
|
||||
export function isDataExportingEnabled(): boolean {
|
||||
return getServerSetting('e') === 1;
|
||||
}
|
||||
|
||||
export function isDataImportingEnabled(): boolean {
|
||||
return getServerSetting('i') === 1;
|
||||
}
|
||||
|
||||
export function getLoginPageTips(): string {
|
||||
return getServerSetting('lpt') as string;
|
||||
}
|
||||
|
||||
export function getMapProvider(): string {
|
||||
return getServerSetting('m') as string;
|
||||
}
|
||||
|
||||
export function isMapDataFetchProxyEnabled(): boolean {
|
||||
return getServerSetting('mp') === 1;
|
||||
}
|
||||
|
||||
export function getCustomMapTileLayerUrl(): string {
|
||||
return getServerSetting('cmsu') as string;
|
||||
}
|
||||
|
||||
export function getCustomMapAnnotationLayerUrl(): string {
|
||||
return getServerSetting('cmau') as string;
|
||||
}
|
||||
|
||||
export function isCustomMapAnnotationLayerDataFetchProxyEnabled(): boolean {
|
||||
return getServerSetting('cmap') === 1;
|
||||
}
|
||||
|
||||
export function getCustomMapMinZoomLevel(): number {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') as string || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[0]) ? parseInt(zoomLevelSettings[0]) : 1;
|
||||
}
|
||||
|
||||
export function getCustomMapMaxZoomLevel(): number {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') as string || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[1]) ? parseInt(zoomLevelSettings[1]) : 18;
|
||||
}
|
||||
|
||||
export function getCustomMapDefaultZoomLevel(): number {
|
||||
const zoomLevelSettings = (getServerSetting('cmzl') as string || '').split('-');
|
||||
return (zoomLevelSettings && zoomLevelSettings[2]) ? parseInt(zoomLevelSettings[2]) : 14;
|
||||
}
|
||||
|
||||
export function getTomTomMapAPIKey(): string {
|
||||
return getServerSetting('tmak') as string;
|
||||
}
|
||||
|
||||
export function getTianDiTuMapAPIKey(): string {
|
||||
return getServerSetting('tdak') as string;
|
||||
}
|
||||
|
||||
export function getGoogleMapAPIKey(): string {
|
||||
return getServerSetting('gmak') as string;
|
||||
}
|
||||
|
||||
export function getBaiduMapAK(): string {
|
||||
return getServerSetting('bmak') as string;
|
||||
}
|
||||
|
||||
export function getAmapApplicationKey(): string {
|
||||
return getServerSetting('amak') as string;
|
||||
}
|
||||
|
||||
export function getAmapSecurityVerificationMethod(): string {
|
||||
return getServerSetting('amsv') as string;
|
||||
}
|
||||
|
||||
export function getAmapApiExternalProxyUrl(): string {
|
||||
return getServerSetting('amep') as string;
|
||||
}
|
||||
|
||||
export function getAmapApplicationSecret(): string {
|
||||
return getServerSetting('amas') as string;
|
||||
}
|
||||
|
||||
export function getExchangeRatesRequestTimeout(): number {
|
||||
return getServerSetting('errt') as number;
|
||||
}
|
||||
+29
-18
@@ -1,25 +1,36 @@
|
||||
import axios from 'axios';
|
||||
|
||||
import apiConstants from '@/consts/api.js';
|
||||
import {
|
||||
BASE_API_URL_PATH,
|
||||
BASE_QRCODE_PATH,
|
||||
BASE_PROXY_URL_PATH,
|
||||
BASE_AMAP_API_PROXY_URL_PATH,
|
||||
DEFAULT_API_TIMEOUT,
|
||||
DEFAULT_UPLOAD_API_TIMEOUT,
|
||||
DEFAULT_IMPORT_API_TIMEOUT,
|
||||
GOOGLE_MAP_JAVASCRIPT_URL,
|
||||
BAIDU_MAP_JAVASCRIPT_URL,
|
||||
AMAP_JAVASCRIPT_URL
|
||||
} from '@/consts/api.ts';
|
||||
import userState from './userstate.js';
|
||||
import {
|
||||
isDefined,
|
||||
isBoolean
|
||||
} from './common.js';
|
||||
} from './common.ts';
|
||||
import {
|
||||
getGoogleMapAPIKey,
|
||||
getBaiduMapAK,
|
||||
getAmapApplicationKey,
|
||||
getExchangeRatesRequestTimeout
|
||||
} from './server_settings.js';
|
||||
} from './server_settings.ts';
|
||||
import { getTimezoneOffsetMinutes } from './datetime.js';
|
||||
import { generateRandomUUID } from './misc.js';
|
||||
import { generateRandomUUID } from './misc.ts';
|
||||
|
||||
let needBlockRequest = false;
|
||||
let blockedRequests = [];
|
||||
|
||||
axios.defaults.baseURL = apiConstants.baseApiUrlPath;
|
||||
axios.defaults.timeout = apiConstants.defaultTimeout;
|
||||
axios.defaults.baseURL = BASE_API_URL_PATH;
|
||||
axios.defaults.timeout = DEFAULT_API_TIMEOUT;
|
||||
axios.interceptors.request.use(config => {
|
||||
const token = userState.getToken();
|
||||
|
||||
@@ -202,7 +213,7 @@ export default {
|
||||
return axios.postForm('v1/users/avatar/update.json', {
|
||||
avatar: avatarFile
|
||||
}, {
|
||||
timeout: apiConstants.uploadTimeout
|
||||
timeout: DEFAULT_UPLOAD_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
removeAvatar: () => {
|
||||
@@ -471,7 +482,7 @@ export default {
|
||||
fileType: fileType,
|
||||
file: importFile
|
||||
}, {
|
||||
timeout: apiConstants.uploadTimeout
|
||||
timeout: DEFAULT_UPLOAD_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
importTransactions: ({ transactions, clientSessionId }) => {
|
||||
@@ -479,7 +490,7 @@ export default {
|
||||
transactions: transactions,
|
||||
clientSessionId: clientSessionId
|
||||
}, {
|
||||
timeout: apiConstants.importTimeout
|
||||
timeout: DEFAULT_IMPORT_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
uploadTransactionPicture: ({ pictureFile, clientSessionId }) => {
|
||||
@@ -487,7 +498,7 @@ export default {
|
||||
picture: pictureFile,
|
||||
clientSessionId: clientSessionId
|
||||
}, {
|
||||
timeout: apiConstants.uploadTimeout
|
||||
timeout: DEFAULT_UPLOAD_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
removeUnusedTransactionPicture: ({ id }) => {
|
||||
@@ -639,15 +650,15 @@ export default {
|
||||
getLatestExchangeRates: ({ ignoreError }) => {
|
||||
return axios.get('v1/exchange_rates/latest.json', {
|
||||
ignoreError: !!ignoreError,
|
||||
timeout: getExchangeRatesRequestTimeout() || apiConstants.defaultTimeout
|
||||
timeout: getExchangeRatesRequestTimeout() || DEFAULT_API_TIMEOUT
|
||||
});
|
||||
},
|
||||
generateQrCodeUrl: (qrCodeName) => {
|
||||
return `${apiConstants.baseQrcodePath}/${qrCodeName}.png`;
|
||||
return `${BASE_QRCODE_PATH}/${qrCodeName}.png`;
|
||||
},
|
||||
generateMapProxyTileImageUrl: (mapProvider, language) => {
|
||||
const token = userState.getToken();
|
||||
let url = `${apiConstants.baseProxyUrlPath}/map/tile/{z}/{x}/{y}.png?provider=${mapProvider}&token=${token}`;
|
||||
let url = `${BASE_PROXY_URL_PATH}/map/tile/{z}/{x}/{y}.png?provider=${mapProvider}&token=${token}`;
|
||||
|
||||
if (language) {
|
||||
url = url + `&language=${language}`;
|
||||
@@ -657,7 +668,7 @@ export default {
|
||||
},
|
||||
generateMapProxyAnnotationImageUrl: (mapProvider, language) => {
|
||||
const token = userState.getToken();
|
||||
let url = `${apiConstants.baseProxyUrlPath}/map/annotation/{z}/{x}/{y}.png?provider=${mapProvider}&token=${token}`;
|
||||
let url = `${BASE_PROXY_URL_PATH}/map/annotation/{z}/{x}/{y}.png?provider=${mapProvider}&token=${token}`;
|
||||
|
||||
if (language) {
|
||||
url = url + `&language=${language}`;
|
||||
@@ -666,7 +677,7 @@ export default {
|
||||
return url;
|
||||
},
|
||||
generateGoogleMapJavascriptUrl: (language, callbackFnName) => {
|
||||
let url = `${apiConstants.googleMapJavascriptUrl}?key=${getGoogleMapAPIKey()}&libraries=core,marker&callback=${callbackFnName}`;
|
||||
let url = `${GOOGLE_MAP_JAVASCRIPT_URL}?key=${getGoogleMapAPIKey()}&libraries=core,marker&callback=${callbackFnName}`;
|
||||
|
||||
if (language) {
|
||||
url = url + `&language=${language}`;
|
||||
@@ -675,13 +686,13 @@ export default {
|
||||
return url;
|
||||
},
|
||||
generateBaiduMapJavascriptUrl: (callbackFnName) => {
|
||||
return `${apiConstants.baiduMapJavascriptUrl}&ak=${getBaiduMapAK()}&callback=${callbackFnName}`;
|
||||
return `${BAIDU_MAP_JAVASCRIPT_URL}&ak=${getBaiduMapAK()}&callback=${callbackFnName}`;
|
||||
},
|
||||
generateAmapJavascriptUrl: (callbackFnName) => {
|
||||
return `${apiConstants.amapJavascriptUrl}&key=${getAmapApplicationKey()}&plugin=AMap.ToolBar&callback=${callbackFnName}`;
|
||||
return `${AMAP_JAVASCRIPT_URL}&key=${getAmapApplicationKey()}&plugin=AMap.ToolBar&callback=${callbackFnName}`;
|
||||
},
|
||||
generateAmapApiInternalProxyUrl: () => {
|
||||
return `${window.location.origin}${apiConstants.baseAmapApiProxyUrlPath}`;
|
||||
return `${window.location.origin}${BASE_AMAP_API_PROXY_URL_PATH}`;
|
||||
},
|
||||
getInternalAvatarUrlWithToken(avatarUrl, disableBrowserCache) {
|
||||
if (!avatarUrl) {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import uaParser from 'ua-parser-js';
|
||||
|
||||
import { CliUserAgent, type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
|
||||
|
||||
interface UserAgentInfo {
|
||||
device: {
|
||||
vendor?: string;
|
||||
model?: string;
|
||||
type?: string;
|
||||
};
|
||||
os: {
|
||||
name?: string;
|
||||
version?: string;
|
||||
};
|
||||
browser: {
|
||||
name?: string;
|
||||
version?: string;
|
||||
};
|
||||
}
|
||||
|
||||
function parseUserAgent(ua: string): UserAgentInfo {
|
||||
const uaParseRet = uaParser(ua);
|
||||
|
||||
return {
|
||||
device: {
|
||||
vendor: uaParseRet.device.vendor,
|
||||
model: uaParseRet.device.model,
|
||||
type: uaParseRet.device.type
|
||||
},
|
||||
os: {
|
||||
name: uaParseRet.os.name,
|
||||
version: uaParseRet.os.version
|
||||
},
|
||||
browser: {
|
||||
name: uaParseRet.browser.name,
|
||||
version: uaParseRet.browser.version
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isSessionUserAgentCreatedByCli(ua: string): boolean {
|
||||
return ua === CliUserAgent;
|
||||
}
|
||||
|
||||
function parseDeviceInfo(uaInfo: UserAgentInfo): string {
|
||||
if (!uaInfo) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let result = '';
|
||||
|
||||
if (uaInfo.device && uaInfo.device.model) {
|
||||
result = uaInfo.device.model;
|
||||
} else if (uaInfo.os && uaInfo.os.name) {
|
||||
result = uaInfo.os.name;
|
||||
|
||||
if (uaInfo.os.version) {
|
||||
result += ' ' + uaInfo.os.version;
|
||||
}
|
||||
}
|
||||
|
||||
if (uaInfo.browser && uaInfo.browser.name) {
|
||||
let browserInfo = uaInfo.browser.name;
|
||||
|
||||
if (uaInfo.browser.version) {
|
||||
browserInfo += ' ' + uaInfo.browser.version;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result += ' (' + browserInfo + ')';
|
||||
} else {
|
||||
result = browserInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
return 'Unknown Device';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function parseSessionInfo(token: TokenInfoResponse): SessionInfo {
|
||||
const isCreatedByCli = isSessionUserAgentCreatedByCli(token.userAgent);
|
||||
const uaInfo = parseUserAgent(token.userAgent);
|
||||
let deviceType = '';
|
||||
|
||||
if (isCreatedByCli) {
|
||||
deviceType = 'cli';
|
||||
} else {
|
||||
if (uaInfo && uaInfo.device) {
|
||||
if (uaInfo.device.type === 'mobile') {
|
||||
deviceType = 'phone';
|
||||
} else if (uaInfo.device.type === 'wearable') {
|
||||
deviceType = 'wearable';
|
||||
} else if (uaInfo.device.type === 'tablet') {
|
||||
deviceType = 'tablet';
|
||||
} else if (uaInfo.device.type === 'smarttv') {
|
||||
deviceType = 'tv';
|
||||
} else {
|
||||
deviceType = 'default';
|
||||
}
|
||||
} else {
|
||||
deviceType = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
return SessionInfo.of(
|
||||
token.tokenId,
|
||||
token.isCurrent,
|
||||
deviceType,
|
||||
isCreatedByCli ? token.userAgent : parseDeviceInfo(uaInfo),
|
||||
isCreatedByCli,
|
||||
token.lastSeen
|
||||
);
|
||||
}
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
import timezoneConstants from '@/consts/timezone.js';
|
||||
import currencyConstants from '@/consts/currency.js';
|
||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||
import { CurrencySortingType } from '@/core/currency.ts';
|
||||
import statisticsConstants from '@/consts/statistics.js';
|
||||
|
||||
const settingsLocalStorageKey = 'ebk_app_settings';
|
||||
@@ -15,15 +15,15 @@ const defaultSettings = {
|
||||
autoSaveTransactionDraft: 'disabled',
|
||||
autoGetCurrentGeoLocation: false,
|
||||
showAmountInHomePage: true,
|
||||
timezoneUsedForStatisticsInHomePage: timezoneConstants.defaultTimezoneTypesUsedForStatistics,
|
||||
timezoneUsedForStatisticsInHomePage: TimezoneTypeForStatistics.Default.type,
|
||||
itemsCountInTransactionListPage: 15,
|
||||
showTotalAmountInTransactionListPage: true,
|
||||
showTagInTransactionListPage: true,
|
||||
showAccountBalance: true,
|
||||
currencySortByInExchangeRatesPage: currencyConstants.defaultCurrencySortingType,
|
||||
currencySortByInExchangeRatesPage: CurrencySortingType.Default.type,
|
||||
statistics: {
|
||||
defaultChartDataType: statisticsConstants.defaultChartDataType,
|
||||
defaultTimezoneType: timezoneConstants.defaultTimezoneTypesUsedForStatistics,
|
||||
defaultTimezoneType: TimezoneTypeForStatistics.Default.type,
|
||||
defaultAccountFilter: {},
|
||||
defaultTransactionCategoryFilter: {},
|
||||
defaultSortingType: statisticsConstants.defaultSortingType,
|
||||
|
||||
+21
-21
@@ -1,8 +1,8 @@
|
||||
import categoryConstants from '@/consts/category.js';
|
||||
import transactionConstants from '@/consts/transaction.js';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import {
|
||||
isNumber
|
||||
} from './common.js';
|
||||
} from './common.ts';
|
||||
import {
|
||||
getBrowserTimezoneOffsetMinutes,
|
||||
getDummyUnixTimeForLocalUsage
|
||||
@@ -32,48 +32,48 @@ export function setTransactionModelByTransaction(transaction, transaction2, allC
|
||||
}
|
||||
}
|
||||
|
||||
if (allCategories[categoryConstants.allCategoryTypes.Expense] &&
|
||||
allCategories[categoryConstants.allCategoryTypes.Expense].length) {
|
||||
if (allCategories[CategoryType.Expense] &&
|
||||
allCategories[CategoryType.Expense].length) {
|
||||
if (options.categoryId && options.categoryId !== '0') {
|
||||
if (isSubCategoryIdAvailable(allCategories[categoryConstants.allCategoryTypes.Expense], options.categoryId)) {
|
||||
if (isSubCategoryIdAvailable(allCategories[CategoryType.Expense], options.categoryId)) {
|
||||
transaction.expenseCategory = options.categoryId;
|
||||
} else {
|
||||
transaction.expenseCategory = getFirstAvailableSubCategoryId(allCategories[categoryConstants.allCategoryTypes.Expense], options.categoryId);
|
||||
transaction.expenseCategory = getFirstAvailableSubCategoryId(allCategories[CategoryType.Expense], options.categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!transaction.expenseCategory) {
|
||||
transaction.expenseCategory = getFirstAvailableCategoryId(allCategories[categoryConstants.allCategoryTypes.Expense]);
|
||||
transaction.expenseCategory = getFirstAvailableCategoryId(allCategories[CategoryType.Expense]);
|
||||
}
|
||||
}
|
||||
|
||||
if (allCategories[categoryConstants.allCategoryTypes.Income] &&
|
||||
allCategories[categoryConstants.allCategoryTypes.Income].length) {
|
||||
if (allCategories[CategoryType.Income] &&
|
||||
allCategories[CategoryType.Income].length) {
|
||||
if (options.categoryId && options.categoryId !== '0') {
|
||||
if (isSubCategoryIdAvailable(allCategories[categoryConstants.allCategoryTypes.Income], options.categoryId)) {
|
||||
if (isSubCategoryIdAvailable(allCategories[CategoryType.Income], options.categoryId)) {
|
||||
transaction.incomeCategory = options.categoryId;
|
||||
} else {
|
||||
transaction.incomeCategory = getFirstAvailableSubCategoryId(allCategories[categoryConstants.allCategoryTypes.Income], options.categoryId);
|
||||
transaction.incomeCategory = getFirstAvailableSubCategoryId(allCategories[CategoryType.Income], options.categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!transaction.incomeCategory) {
|
||||
transaction.incomeCategory = getFirstAvailableCategoryId(allCategories[categoryConstants.allCategoryTypes.Income]);
|
||||
transaction.incomeCategory = getFirstAvailableCategoryId(allCategories[CategoryType.Income]);
|
||||
}
|
||||
}
|
||||
|
||||
if (allCategories[categoryConstants.allCategoryTypes.Transfer] &&
|
||||
allCategories[categoryConstants.allCategoryTypes.Transfer].length) {
|
||||
if (allCategories[CategoryType.Transfer] &&
|
||||
allCategories[CategoryType.Transfer].length) {
|
||||
if (options.categoryId && options.categoryId !== '0') {
|
||||
if (isSubCategoryIdAvailable(allCategories[categoryConstants.allCategoryTypes.Transfer], options.categoryId)) {
|
||||
if (isSubCategoryIdAvailable(allCategories[CategoryType.Transfer], options.categoryId)) {
|
||||
transaction.transferCategory = options.categoryId;
|
||||
} else {
|
||||
transaction.transferCategory = getFirstAvailableSubCategoryId(allCategories[categoryConstants.allCategoryTypes.Transfer], options.categoryId);
|
||||
transaction.transferCategory = getFirstAvailableSubCategoryId(allCategories[CategoryType.Transfer], options.categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!transaction.transferCategory) {
|
||||
transaction.transferCategory = getFirstAvailableCategoryId(allCategories[categoryConstants.allCategoryTypes.Transfer]);
|
||||
transaction.transferCategory = getFirstAvailableCategoryId(allCategories[CategoryType.Transfer]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,11 +128,11 @@ export function setTransactionModelByTransaction(transaction, transaction2, allC
|
||||
|
||||
transaction.type = transaction2.type;
|
||||
|
||||
if (transaction.type === transactionConstants.allTransactionTypes.Expense) {
|
||||
if (transaction.type === TransactionType.Expense) {
|
||||
transaction.expenseCategory = transaction2.categoryId || '';
|
||||
} else if (transaction.type === transactionConstants.allTransactionTypes.Income) {
|
||||
} else if (transaction.type === TransactionType.Income) {
|
||||
transaction.incomeCategory = transaction2.categoryId || '';
|
||||
} else if (transaction.type === transactionConstants.allTransactionTypes.Transfer) {
|
||||
} else if (transaction.type === TransactionType.Transfer) {
|
||||
transaction.transferCategory = transaction2.categoryId || '';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
import colorConstants from '@/consts/color.js';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
|
||||
export function getSystemTheme() {
|
||||
import { type AmountColor, PresetAmountColor } from '@/core/color.ts';
|
||||
|
||||
export function getSystemTheme(): ThemeType {
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return 'dark';
|
||||
return ThemeType.Dark;
|
||||
} else {
|
||||
return 'light';
|
||||
return ThemeType.Light;
|
||||
}
|
||||
}
|
||||
|
||||
export function getExpenseAndIncomeAmountColor(expenseAmountColorType, incomeAmountColorType, isDarkMode) {
|
||||
let expenseAmountColor = expenseAmountColorType ? colorConstants.allAmountColorTypesMap[expenseAmountColorType] : null;
|
||||
let incomeAmountColor = incomeAmountColorType ? colorConstants.allAmountColorTypesMap[incomeAmountColorType] : null;
|
||||
export function getExpenseAndIncomeAmountColor(expenseAmountColorType: number, incomeAmountColorType: number, isDarkMode: boolean): AmountColor {
|
||||
let expenseAmountColor = expenseAmountColorType ? PresetAmountColor.valueOf(expenseAmountColorType) : null;
|
||||
let incomeAmountColor = incomeAmountColorType ? PresetAmountColor.valueOf(incomeAmountColorType) : null;
|
||||
|
||||
if (!expenseAmountColor) {
|
||||
expenseAmountColor = colorConstants.defaultExpenseAmountColor;
|
||||
expenseAmountColor = PresetAmountColor.DefaultExpenseColor;
|
||||
}
|
||||
|
||||
if (!incomeAmountColor) {
|
||||
incomeAmountColor = colorConstants.defaultIncomeAmountColor;
|
||||
incomeAmountColor = PresetAmountColor.DefaultIncomeColor;
|
||||
}
|
||||
|
||||
if (isDarkMode) {
|
||||
@@ -33,22 +35,28 @@ export function getExpenseAndIncomeAmountColor(expenseAmountColorType, incomeAmo
|
||||
}
|
||||
}
|
||||
|
||||
export function setExpenseAndIncomeAmountColor(expenseAmountColorType, incomeAmountColorType) {
|
||||
let expenseAmountColor = expenseAmountColorType ? colorConstants.allAmountColorTypesMap[expenseAmountColorType] : null;
|
||||
let incomeAmountColor = incomeAmountColorType ? colorConstants.allAmountColorTypesMap[incomeAmountColorType] : null;
|
||||
export function setExpenseAndIncomeAmountColor(expenseAmountColorType: number, incomeAmountColorType: number): void {
|
||||
let expenseAmountColor = expenseAmountColorType ? PresetAmountColor.valueOf(expenseAmountColorType) : null;
|
||||
let incomeAmountColor = incomeAmountColorType ? PresetAmountColor.valueOf(incomeAmountColorType) : null;
|
||||
|
||||
if (!expenseAmountColor) {
|
||||
expenseAmountColor = colorConstants.defaultExpenseAmountColor;
|
||||
expenseAmountColor = PresetAmountColor.DefaultExpenseColor;
|
||||
}
|
||||
|
||||
if (!incomeAmountColor) {
|
||||
incomeAmountColor = colorConstants.defaultIncomeAmountColor;
|
||||
incomeAmountColor = PresetAmountColor.DefaultIncomeColor;
|
||||
}
|
||||
|
||||
const htmlElement = document.querySelector('html');
|
||||
|
||||
for (let i = 0; i < colorConstants.allAmountColorsArray.length; i++) {
|
||||
const amountColor = colorConstants.allAmountColorsArray[i];
|
||||
if (!htmlElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
const allPresetAmountColors = PresetAmountColor.values();
|
||||
|
||||
for (let i = 0; i < allPresetAmountColors.length; i++) {
|
||||
const amountColor = allPresetAmountColors[i];
|
||||
|
||||
if (amountColor.type === expenseAmountColor.type) {
|
||||
if (!htmlElement.classList.contains(amountColor.expenseClassName)) {
|
||||
@@ -68,7 +76,7 @@ export function setExpenseAndIncomeAmountColor(expenseAmountColorType, incomeAmo
|
||||
}
|
||||
}
|
||||
|
||||
export function startDownloadFile(fileName, fileData) {
|
||||
export function startDownloadFile(fileName: string, fileData: Blob): void {
|
||||
const dataObjectUrl = URL.createObjectURL(fileData);
|
||||
const dataLink = document.createElement('a');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { f7, f7ready } from 'framework7-vue';
|
||||
|
||||
import fontConstants from '@/consts/font.js';
|
||||
import { isEnableAnimate } from './settings.js';
|
||||
import { translateError } from './i18n.js';
|
||||
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
||||
import { isEnableAnimate } from '../settings.js';
|
||||
import { translateError } from '../i18n.js';
|
||||
|
||||
export function showAlert(message, confirmCallback, translateFn) {
|
||||
f7ready((f7) => {
|
||||
@@ -126,9 +126,10 @@ export function autoChangeTextareaSize(el) {
|
||||
|
||||
export function setAppFontSize(type) {
|
||||
const htmlElement = elements('html');
|
||||
const allFontSizes = FontSize.values();
|
||||
|
||||
for (let i = 0; i < fontConstants.allFontSizeArray.length; i++) {
|
||||
const fontSizeType = fontConstants.allFontSizeArray[i];
|
||||
for (let i = 0; i < allFontSizes.length; i++) {
|
||||
const fontSizeType = allFontSizes[i];
|
||||
|
||||
if (fontSizeType.type === type) {
|
||||
if (!htmlElement.hasClass(fontSizeType.className)) {
|
||||
@@ -141,15 +142,17 @@ export function setAppFontSize(type) {
|
||||
}
|
||||
|
||||
export function getFontSizePreviewClassName(type) {
|
||||
for (let i = 0; i < fontConstants.allFontSizeArray.length; i++) {
|
||||
const fontSizeType = fontConstants.allFontSizeArray[i];
|
||||
const allFontSizes = FontSize.values();
|
||||
|
||||
for (let i = 0; i < allFontSizes.length; i++) {
|
||||
const fontSizeType = allFontSizes[i];
|
||||
|
||||
if (fontSizeType.type === type) {
|
||||
return fontConstants.fontSizePreviewClassNamePrefix + fontSizeType.className;
|
||||
return FONT_SIZE_PREVIEW_CLASSNAME_PREFIX + fontSizeType.className;
|
||||
}
|
||||
}
|
||||
|
||||
return fontConstants.fontSizePreviewClassNamePrefix + fontConstants.defaultFontSize.className;
|
||||
return FONT_SIZE_PREVIEW_CLASSNAME_PREFIX + FontSize.Default.className;
|
||||
}
|
||||
|
||||
export function scrollToSelectedItem(parentEl, containerSelector, selectedItemSelector) {
|
||||
@@ -1,6 +1,6 @@
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
import { isString, isObject } from './common.js';
|
||||
import { isString, isObject } from './common.ts';
|
||||
import { isEnableApplicationLock } from './settings.js';
|
||||
import logger from './logger.js';
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export function isProduction() {
|
||||
return process.env.NODE_ENV === 'production';
|
||||
export function isProduction(): boolean {
|
||||
return __EZBOOKKEEPING_IS_PRODUCTION__;
|
||||
}
|
||||
|
||||
export function getVersion() {
|
||||
export function getVersion(): string {
|
||||
const isRelease = !getBuildTime();
|
||||
const commitHash = __EZBOOKKEEPING_BUILD_COMMIT_HASH__; // eslint-disable-line
|
||||
let version = __EZBOOKKEEPING_VERSION__; // eslint-disable-line
|
||||
const commitHash = __EZBOOKKEEPING_BUILD_COMMIT_HASH__;
|
||||
let version = __EZBOOKKEEPING_VERSION__;
|
||||
|
||||
if (version && (!isRelease || !isProduction())) {
|
||||
version += '-dev';
|
||||
@@ -22,18 +22,18 @@ export function getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
export function getBuildTime() {
|
||||
return __EZBOOKKEEPING_BUILD_UNIX_TIME__; // eslint-disable-line
|
||||
export function getBuildTime(): string {
|
||||
return __EZBOOKKEEPING_BUILD_UNIX_TIME__;
|
||||
}
|
||||
|
||||
export function getMobileVersionPath() {
|
||||
export function getMobileVersionPath(): string {
|
||||
if (isProduction()) {
|
||||
return '../mobile';
|
||||
} else {
|
||||
return 'mobile.html';
|
||||
}
|
||||
}
|
||||
export function getDesktopVersionPath() {
|
||||
export function getDesktopVersionPath(): string {
|
||||
if (isProduction()) {
|
||||
return '../desktop';
|
||||
} else {
|
||||
+2
-2
@@ -6,10 +6,10 @@ import {
|
||||
arrayBufferToString,
|
||||
base64encode,
|
||||
base64decode
|
||||
} from './common.js';
|
||||
} from './common.ts';
|
||||
import {
|
||||
generateRandomString
|
||||
} from './misc.js';
|
||||
} from './misc.ts';
|
||||
|
||||
const publicKeyCredentialCreationOptionsBaseTemplate = {
|
||||
attestation: "none",
|
||||
|
||||
@@ -2,10 +2,18 @@ import en from './en.json';
|
||||
import vi from './vi.json';
|
||||
import zhHans from './zh_Hans.json';
|
||||
|
||||
export const defaultLanguage = 'en';
|
||||
interface LanguageInfo {
|
||||
name: string,
|
||||
displayName: string,
|
||||
alternativeLanguageTag: string,
|
||||
aliases?: string[],
|
||||
content: object
|
||||
}
|
||||
|
||||
export const defaultLanguage: string = 'en';
|
||||
|
||||
// To add new languages, please refer to https://ezbookkeeping.mayswind.net/translating
|
||||
export const allLanguages = {
|
||||
export const allLanguages: Record<string, LanguageInfo> = {
|
||||
'en': {
|
||||
name: 'English',
|
||||
displayName: 'English',
|
||||
+2
-2
@@ -79,7 +79,7 @@ import 'line-awesome/dist/line-awesome/css/line-awesome.css';
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
import '@vuepic/vue-datepicker/dist/main.css';
|
||||
|
||||
import { getVersion, getBuildTime } from '@/lib/version.js';
|
||||
import { getVersion, getBuildTime } from '@/lib/version.ts';
|
||||
import userstate from '@/lib/userstate.js';
|
||||
import {
|
||||
getI18nOptions,
|
||||
@@ -93,7 +93,7 @@ import {
|
||||
showLoading,
|
||||
hideLoading,
|
||||
routeBackOnError
|
||||
} from '@/lib/ui.mobile.js';
|
||||
} from '@/lib/ui/mobile.js';
|
||||
|
||||
import PinCodeInput from '@/components/common/PinCodeInput.vue';
|
||||
import MapView from '@/components/common/MapView.vue';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user