2308 lines
92 KiB
TypeScript
2308 lines
92 KiB
TypeScript
import { useI18n as useVueI18n } from 'vue-i18n';
|
|
import moment from 'moment-timezone';
|
|
import 'moment-timezone/moment-timezone-utils';
|
|
|
|
import type { PartialRecord, NameValue, TypeAndName, TypeAndDisplayName, LocalizedSwitchOption } from '@/core/base.ts';
|
|
|
|
import {
|
|
type LanguageInfo,
|
|
type LanguageOption,
|
|
ALL_LANGUAGES,
|
|
DEFAULT_LANGUAGE
|
|
} from '@/locales/index.ts';
|
|
|
|
import {
|
|
TextDirection
|
|
} from '@/core/text.ts';
|
|
|
|
import {
|
|
CalendarType,
|
|
CalendarDisplayType,
|
|
DateDisplayType
|
|
} from '@/core/calendar.ts';
|
|
|
|
import {
|
|
type DateTimeFormatOptions,
|
|
type DateTimeLocaleData,
|
|
type TextualYearMonth,
|
|
type TextualYearMonthDay,
|
|
type DateFormat,
|
|
type TimeFormat,
|
|
type LocalizedDateTimeFormat,
|
|
type LocalizedDateRange,
|
|
type LocalizedRecentMonthDateRange,
|
|
type UnixTimeRange,
|
|
type WeekDayValue,
|
|
Month,
|
|
WeekDay,
|
|
MeridiemIndicator,
|
|
KnownDateTimeFormat,
|
|
LongDateFormat,
|
|
ShortDateFormat,
|
|
LongTimeFormat,
|
|
ShortTimeFormat,
|
|
DateRange,
|
|
DateRangeScene,
|
|
LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE
|
|
} from '@/core/datetime.ts';
|
|
|
|
import {
|
|
type LocalizedTimezoneInfo,
|
|
TimezoneTypeForStatistics
|
|
} from '@/core/timezone.ts';
|
|
|
|
import {
|
|
type HiddenAmount,
|
|
type NumberFormatOptions,
|
|
type NumberWithSuffix,
|
|
type NumeralSymbolType,
|
|
type LocalizedNumeralSymbolType,
|
|
type LocalizedDigitGroupingType,
|
|
NumeralSystem,
|
|
DecimalSeparator,
|
|
DigitGroupingSymbol,
|
|
DigitGroupingType
|
|
} from '@/core/numeral.ts';
|
|
|
|
import {
|
|
type LocalizedCurrencyInfo,
|
|
type CurrencyPrependAndAppendText,
|
|
CurrencyDisplayType,
|
|
CurrencySortingType
|
|
} from '@/core/currency.ts';
|
|
|
|
import {
|
|
FiscalYearStart,
|
|
FiscalYearFormat,
|
|
FiscalYearUnixTime,
|
|
LANGUAGE_DEFAULT_FISCAL_YEAR_FORMAT_VALUE,
|
|
} from '@/core/fiscalyear.ts';
|
|
|
|
import {
|
|
CoordinateDisplayType
|
|
} from '@/core/coordinate.ts';
|
|
|
|
import {
|
|
PresetAmountColor
|
|
} from '@/core/color.ts';
|
|
|
|
import {
|
|
type LocalizedAccountCategory,
|
|
AccountType,
|
|
AccountCategory
|
|
} from '@/core/account.ts';
|
|
|
|
import {
|
|
type PresetCategory,
|
|
type LocalizedPresetCategory,
|
|
type LocalizedPresetSubCategory,
|
|
CategoryType,
|
|
ALL_CATEGORY_TYPES
|
|
} from '@/core/category.ts';
|
|
|
|
import {
|
|
TransactionEditScopeType,
|
|
TransactionTagFilterType
|
|
} from '@/core/transaction.ts';
|
|
|
|
import {
|
|
ImportTransactionColumnType
|
|
} from '@/core/import_transaction.ts';
|
|
|
|
import {
|
|
ScheduledTemplateFrequencyType
|
|
} from '@/core/template.ts';
|
|
|
|
import {
|
|
StatisticsAnalysisType,
|
|
CategoricalChartType,
|
|
TrendChartType,
|
|
AccountBalanceTrendChartType,
|
|
ChartDataType,
|
|
ChartSortingType,
|
|
ChartDateAggregationType
|
|
} from '@/core/statistics.ts';
|
|
|
|
import {
|
|
type LocalizedImportFileCategoryAndTypes,
|
|
type LocalizedImportFileType,
|
|
type LocalizedImportFileTypeSubType,
|
|
type LocalizedImportFileTypeSupportedEncodings,
|
|
type LocalizedImportFileDocument
|
|
} from '@/core/file.ts';
|
|
|
|
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
|
import type { ErrorResponse } from '@/core/api.ts';
|
|
|
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
|
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
|
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
|
import { KnownErrorCode, SPECIFIED_API_NOT_FOUND_ERRORS, PARAMETERIZED_ERRORS } from '@/consts/api.ts';
|
|
import { DEFAULT_DOCUMENT_LANGUAGE_FOR_IMPORT_FILE, SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE, SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES } from '@/consts/file.ts';
|
|
|
|
import {
|
|
type CategorizedAccount,
|
|
Account,
|
|
AccountWithDisplayBalance,
|
|
CategorizedAccountWithDisplayBalance
|
|
} from '@/models/account.ts';
|
|
import type { LatestExchangeRateResponse, LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
|
|
|
import {
|
|
isDefined,
|
|
isObject,
|
|
isString,
|
|
isNumber,
|
|
isBoolean
|
|
} from '@/lib/common.ts';
|
|
|
|
import {
|
|
formatCurrentTime,
|
|
formatGregorianCalendarYearDashMonthDashDay,
|
|
formatGregorianCalendarMonthDashDay,
|
|
formatUnixTime,
|
|
getBrowserTimezoneOffset,
|
|
getBrowserTimezoneOffsetMinutes,
|
|
getCurrentUnixTime,
|
|
parseDateTimeFromUnixTime,
|
|
getDateTimeFormatType,
|
|
getFiscalYearTimeRangeFromUnixTime,
|
|
getFiscalYearTimeRangeFromYear,
|
|
getRecentMonthDateRanges,
|
|
getTimeDifferenceHoursAndMinutes,
|
|
getTimezoneOffset,
|
|
getTimezoneOffsetMinutes,
|
|
isDateRangeMatchFullMonths,
|
|
isDateRangeMatchFullYears,
|
|
isPM
|
|
} from '@/lib/datetime.ts';
|
|
|
|
import {
|
|
appendDigitGroupingSymbolAndDecimalSeparator,
|
|
parseAmount,
|
|
formatAmount,
|
|
formatHiddenAmount,
|
|
formatNumber,
|
|
formatPercent,
|
|
formatExchangeRateAmount,
|
|
getAdaptiveDisplayAmountRate
|
|
} from '@/lib/numeral.ts';
|
|
|
|
import {
|
|
getCurrencyFraction,
|
|
appendCurrencySymbol,
|
|
getAmountPrependAndAppendCurrencySymbol
|
|
} from '@/lib/currency.ts';
|
|
|
|
import {
|
|
getCategorizedAccountsMap,
|
|
getAllFilteredAccountsBalance
|
|
} from '@/lib/account.ts';
|
|
|
|
import {
|
|
getSessionCurrentLanguageKey,
|
|
setSessionCurrentLanguageKey
|
|
} from '@/lib/settings.ts';
|
|
|
|
import services from '@/lib/services.ts';
|
|
import logger from '@/lib/logger.ts';
|
|
|
|
import { useSettingsStore } from '@/stores/setting.ts';
|
|
import { useUserStore } from '@/stores/user.ts';
|
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
|
|
|
export interface LocalizedErrorParameter {
|
|
readonly key: string;
|
|
readonly localized: boolean;
|
|
readonly value: string;
|
|
}
|
|
|
|
export interface LocalizedError {
|
|
readonly message: string;
|
|
readonly parameters?: LocalizedErrorParameter[];
|
|
}
|
|
|
|
export function getI18nOptions(): object {
|
|
return {
|
|
legacy: false,
|
|
locale: DEFAULT_LANGUAGE,
|
|
fallbackLocale: DEFAULT_LANGUAGE,
|
|
formatFallbackMessages: true,
|
|
messages: (function () {
|
|
const messages: Record<string, object> = {};
|
|
|
|
for (const languageKey in ALL_LANGUAGES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
|
continue;
|
|
}
|
|
|
|
const languageInfo = ALL_LANGUAGES[languageKey];
|
|
messages[languageKey] = languageInfo.content;
|
|
}
|
|
|
|
return messages;
|
|
})()
|
|
};
|
|
}
|
|
|
|
export function getRtlLocales(): Record<string, boolean> {
|
|
const rtlLocales: Record<string, boolean> = {};
|
|
|
|
for (const languageKey in ALL_LANGUAGES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
|
continue;
|
|
}
|
|
|
|
const languageInfo = ALL_LANGUAGES[languageKey];
|
|
|
|
if (languageInfo.textDirection === 'rtl') {
|
|
rtlLocales[languageKey] = true;
|
|
}
|
|
}
|
|
|
|
return rtlLocales;
|
|
}
|
|
|
|
export function useI18n() {
|
|
const { t, locale } = useVueI18n();
|
|
|
|
const settingsStore = useSettingsStore();
|
|
const userStore = useUserStore();
|
|
const exchangeRatesStore = useExchangeRatesStore();
|
|
|
|
// private functions
|
|
function getLanguageDisplayName(languageName: string): string {
|
|
return t(`language.${languageName}`);
|
|
}
|
|
|
|
function getDefaultLanguage(): string {
|
|
if (!window || !window.navigator) {
|
|
return DEFAULT_LANGUAGE;
|
|
}
|
|
|
|
let browserLanguage = window.navigator.browserLanguage || window.navigator.language;
|
|
|
|
if (!browserLanguage) {
|
|
return DEFAULT_LANGUAGE;
|
|
}
|
|
|
|
// try to match the full browser language tag with full language tag in i18n file
|
|
if (ALL_LANGUAGES[browserLanguage]) {
|
|
return browserLanguage;
|
|
}
|
|
|
|
// try to match the full browser language tag with language alias tags in i18n file
|
|
let alternativeLanguage = getLanguageKeyFromLanguageAlias(browserLanguage);
|
|
|
|
if (alternativeLanguage && ALL_LANGUAGES[alternativeLanguage]) {
|
|
return alternativeLanguage;
|
|
}
|
|
|
|
const languageTagParts = browserLanguage.split('-');
|
|
|
|
// maybe browser language is language-script-region format
|
|
if (languageTagParts.length > 2) {
|
|
// fallback to use language tag with language-script / language-region format
|
|
browserLanguage = languageTagParts[0] + '-' + languageTagParts[1];
|
|
|
|
// try to match language tag in language-script / language-region format with full language tag in i18n file
|
|
if (ALL_LANGUAGES[browserLanguage]) {
|
|
return browserLanguage;
|
|
}
|
|
|
|
// try to match language tag in language-script / language-region format with language alias tags in i18n file
|
|
alternativeLanguage = getLanguageKeyFromLanguageAlias(browserLanguage);
|
|
|
|
if (alternativeLanguage && ALL_LANGUAGES[alternativeLanguage]) {
|
|
return alternativeLanguage;
|
|
}
|
|
}
|
|
|
|
// fallback to use marco language tag
|
|
if (languageTagParts.length > 1) {
|
|
browserLanguage = languageTagParts[0];
|
|
|
|
// try to match marco language tag with full language tag in i18n file
|
|
if (ALL_LANGUAGES[browserLanguage]) {
|
|
return browserLanguage;
|
|
}
|
|
|
|
// try to match marco language tag with language alias tags in i18n file
|
|
alternativeLanguage = getLanguageKeyFromLanguageAlias(browserLanguage);
|
|
|
|
if (alternativeLanguage && ALL_LANGUAGES[alternativeLanguage]) {
|
|
return alternativeLanguage;
|
|
}
|
|
}
|
|
|
|
// fallback to match marco language tag with marco language tag in i18n file
|
|
alternativeLanguage = getLanguageKeyFromMarcoLanguageTag(browserLanguage);
|
|
|
|
if (alternativeLanguage && ALL_LANGUAGES[alternativeLanguage]) {
|
|
return alternativeLanguage;
|
|
}
|
|
|
|
// fallback to use the default language
|
|
return DEFAULT_LANGUAGE;
|
|
}
|
|
|
|
function getLanguageKeyFromLanguageAlias(alias: string): string | null {
|
|
for (const languageKey in ALL_LANGUAGES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
|
continue;
|
|
}
|
|
|
|
if (languageKey.toLowerCase() === alias.toLowerCase()) {
|
|
return languageKey;
|
|
}
|
|
|
|
const langInfo = ALL_LANGUAGES[languageKey];
|
|
const aliases = langInfo.aliases;
|
|
|
|
if (!aliases || aliases.length < 1) {
|
|
continue;
|
|
}
|
|
|
|
for (let i = 0; i < aliases.length; i++) {
|
|
if (aliases[i].toLowerCase() === alias.toLowerCase()) {
|
|
return languageKey;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getLanguageKeyFromMarcoLanguageTag(languageTag: string): string | null {
|
|
for (const languageKey in ALL_LANGUAGES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageKey)) {
|
|
continue;
|
|
}
|
|
|
|
if (languageKey.indexOf('-') < 0) {
|
|
continue;
|
|
}
|
|
|
|
const marcoLanguageTag = languageKey.split('-')[0];
|
|
|
|
if (marcoLanguageTag.toLowerCase() === languageTag.toLowerCase()) {
|
|
return languageKey;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function getLocalizedError(error: ErrorResponse): LocalizedError {
|
|
if (error.errorCode === KnownErrorCode.ApiNotFound && SPECIFIED_API_NOT_FOUND_ERRORS[error.path]) {
|
|
return {
|
|
message: `${SPECIFIED_API_NOT_FOUND_ERRORS[error.path].message}`
|
|
};
|
|
}
|
|
|
|
if (error.errorCode !== KnownErrorCode.ValidatorError) {
|
|
return {
|
|
message: `error.${error.errorMessage}`
|
|
};
|
|
}
|
|
|
|
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) {
|
|
return {
|
|
message: `parameterizedError.${errorInfo.localeKey}`,
|
|
parameters: errorInfo.parameters.map((param, index) => {
|
|
return {
|
|
key: param.field,
|
|
localized: param.localized,
|
|
value: matches[index + 1]
|
|
}
|
|
})
|
|
};
|
|
}
|
|
}
|
|
|
|
return {
|
|
message: `error.${error.errorMessage}`
|
|
};
|
|
}
|
|
|
|
function getLocalizedErrorParameters(parameters?: LocalizedErrorParameter[]): Record<string, string> {
|
|
const localizedParameters: Record<string, string> = {};
|
|
|
|
if (parameters) {
|
|
for (let i = 0; i < parameters.length; i++) {
|
|
const parameter = parameters[i];
|
|
|
|
if (parameter.localized) {
|
|
localizedParameters[parameter.key] = t(`parameter.${parameter.value}`);
|
|
} else {
|
|
localizedParameters[parameter.key] = parameter.value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return localizedParameters;
|
|
}
|
|
|
|
function getDateTimeLocaleData(): DateTimeLocaleData {
|
|
return moment.localeData();
|
|
}
|
|
|
|
function getAllCurrencyDisplayTypes(numeralSystem: NumeralSystem, decimalSeparator: string): TypeAndDisplayName[] {
|
|
const defaultCurrencyDisplayTypeName = t('default.currencyDisplayType');
|
|
let defaultCurrencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
|
|
|
if (!defaultCurrencyDisplayType) {
|
|
defaultCurrencyDisplayType = CurrencyDisplayType.Default;
|
|
}
|
|
|
|
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
|
|
|
const ret = [];
|
|
const defaultSampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, defaultCurrencyDisplayType, numeralSystem, decimalSeparator);
|
|
|
|
ret.push({
|
|
type: CurrencyDisplayType.LanguageDefaultType,
|
|
displayName: `${t('Language Default')} (${defaultSampleValue})`
|
|
});
|
|
|
|
const allCurrencyDisplayTypes = CurrencyDisplayType.values();
|
|
|
|
for (let i = 0; i < allCurrencyDisplayTypes.length; i++) {
|
|
const type = allCurrencyDisplayTypes[i];
|
|
const sampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, type, numeralSystem, decimalSeparator);
|
|
const displayName = `${t(type.name)} (${sampleValue})`
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
displayName: displayName
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllLocalizedCalendarTypes(allTypeAndNameArray: CalendarDisplayType[] | DateDisplayType[], localeDefaultType: CalendarDisplayType | DateDisplayType | undefined, systemDefaultType: CalendarDisplayType | DateDisplayType, languageDefaultValue: number): TypeAndDisplayName[] {
|
|
let defaultType: TypeAndName | undefined = localeDefaultType;
|
|
|
|
if (!defaultType) {
|
|
defaultType = systemDefaultType;
|
|
}
|
|
|
|
const ret: TypeAndDisplayName[] = [];
|
|
|
|
ret.push({
|
|
type: languageDefaultValue,
|
|
displayName: `${t('Language Default')} (${t('calendar.' + defaultType.name)})`
|
|
});
|
|
|
|
for (let i = 0; i < allTypeAndNameArray.length; i++) {
|
|
const type = allTypeAndNameArray[i];
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
displayName: t('calendar.' + type.name)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedDisplayNameAndType(typeAndNames: TypeAndName[]): TypeAndDisplayName[] {
|
|
const ret: TypeAndDisplayName[] = [];
|
|
|
|
for (let i = 0; i < typeAndNames.length; i++) {
|
|
const nameAndType = typeAndNames[i];
|
|
|
|
ret.push({
|
|
type: nameAndType.type,
|
|
displayName: t(nameAndType.name)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedDisplayNameAndTypeWithSystemDefault(typeAndNames: TypeAndName[], defaultValue: number, defaultType: TypeAndName): TypeAndDisplayName[] {
|
|
const ret: TypeAndDisplayName[] = [];
|
|
|
|
ret.push({
|
|
type: defaultValue,
|
|
displayName: t('System Default') + (defaultType.name ? ` (${t(defaultType.name)})` : '')
|
|
});
|
|
|
|
for (let i = 0; i < typeAndNames.length; i++) {
|
|
const nameAndType = typeAndNames[i];
|
|
|
|
ret.push({
|
|
type: nameAndType.type,
|
|
displayName: t(nameAndType.name)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedNumeralSeparatorFormats<T extends NumeralSymbolType>(allSeparatorArray: T[], localeDefaultType: T | undefined, systemDefaultType: T, languageDefaultValue: number): LocalizedNumeralSymbolType[] {
|
|
let defaultSeparatorType: T | undefined = localeDefaultType;
|
|
|
|
if (!defaultSeparatorType) {
|
|
defaultSeparatorType = systemDefaultType;
|
|
}
|
|
|
|
const ret: LocalizedNumeralSymbolType[] = [];
|
|
|
|
ret.push({
|
|
type: languageDefaultValue,
|
|
symbol: defaultSeparatorType.symbol,
|
|
displayName: `${t('Language Default')} (${defaultSeparatorType.symbol})`
|
|
});
|
|
|
|
for (let i = 0; i < allSeparatorArray.length; i++) {
|
|
const type = allSeparatorArray[i];
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
symbol: type.symbol,
|
|
displayName: `${t('numeral.' + type.name)} (${type.symbol})`
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedChartDateAggregationTypeAndDisplayName(fullName: boolean): TypeAndDisplayName[] {
|
|
const ret: TypeAndDisplayName[] = [];
|
|
const allTypes: ChartDateAggregationType[] = ChartDateAggregationType.values();
|
|
|
|
for (let i = 0; i < allTypes.length; i++) {
|
|
const type = allTypes[i];
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
displayName: t(fullName ? type.fullName : `granularity.${type.shortName}`)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllMonthNames(type: string): string[] {
|
|
const ret = [];
|
|
const allMonths = Month.values();
|
|
|
|
for (let i = 0; i < allMonths.length; i++) {
|
|
const month = allMonths[i];
|
|
ret.push(t(`datetime.${month.name}.${type}`));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllWeekdayNames(type: string): string[] {
|
|
const ret = [];
|
|
const allWeekDays = WeekDay.values();
|
|
|
|
for (let i = 0; i < allWeekDays.length; i++) {
|
|
const weekDay = allWeekDays[i];
|
|
ret.push(t(`datetime.${weekDay.name}.${type}`));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedDateTimeType<T extends DateFormat | TimeFormat>(allFormatMap: Record<string, T>, allFormatArray: T[], formatTypeValue: number, languageDefaultTypeNameKey: string, systemDefaultFormatType: T): T {
|
|
return getDateTimeFormatType(allFormatMap, allFormatArray, formatTypeValue, t(`default.${languageDefaultTypeNameKey}`), systemDefaultFormatType);
|
|
}
|
|
|
|
function getLocalizedDateTimeFormat<T extends DateFormat | TimeFormat>(type: string, allFormatMap: Record<string, T>, allFormatArray: T[], formatTypeValue: number, languageDefaultTypeNameKey: string, systemDefaultFormatType: T): string {
|
|
const formatType = getLocalizedDateTimeType(allFormatMap, allFormatArray, formatTypeValue, languageDefaultTypeNameKey, systemDefaultFormatType);
|
|
return t(`format.${type}.${formatType.key}`);
|
|
}
|
|
|
|
function getLocalizedLongDateFormat(): string {
|
|
return getLocalizedDateTimeFormat<LongDateFormat>('longDate', LongDateFormat.all(), LongDateFormat.values(), userStore.currentUserLongDateFormat, 'longDateFormat', LongDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortDateFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortDateFormat>('shortDate', ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedLongYearFormat(): string {
|
|
return getLocalizedDateTimeFormat<LongDateFormat>('longYear', LongDateFormat.all(), LongDateFormat.values(), userStore.currentUserLongDateFormat, 'longDateFormat', LongDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortYearFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortDateFormat>('shortYear', ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedLongYearMonthFormat(): string {
|
|
return getLocalizedDateTimeFormat<LongDateFormat>('longYearMonth', LongDateFormat.all(), LongDateFormat.values(), userStore.currentUserLongDateFormat, 'longDateFormat', LongDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortYearMonthFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortDateFormat>('shortYearMonth', ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedLongMonthDayFormat(): string {
|
|
return getLocalizedDateTimeFormat<LongDateFormat>('longMonthDay', LongDateFormat.all(), LongDateFormat.values(), userStore.currentUserLongDateFormat, 'longDateFormat', LongDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortMonthDayFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortDateFormat>('shortMonthDay', ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortDayFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortDateFormat>('shortDay', ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default);
|
|
}
|
|
|
|
function getLocalizedLongTimeFormat(): string {
|
|
return getLocalizedDateTimeFormat<LongTimeFormat>('longTime', LongTimeFormat.all(), LongTimeFormat.values(), userStore.currentUserLongTimeFormat, 'longTimeFormat', LongTimeFormat.Default);
|
|
}
|
|
|
|
function getLocalizedShortTimeFormat(): string {
|
|
return getLocalizedDateTimeFormat<ShortTimeFormat>('shortTime', ShortTimeFormat.all(), ShortTimeFormat.values(), userStore.currentUserShortTimeFormat, 'shortTimeFormat', ShortTimeFormat.Default);
|
|
}
|
|
|
|
function getDateTimeFormatOptions(options?: { calendarType?: CalendarType, numeralSystem?: NumeralSystem }): DateTimeFormatOptions {
|
|
let calendarType: CalendarType | undefined = options?.calendarType;
|
|
let numeralSystem: NumeralSystem | undefined = options?.numeralSystem;
|
|
|
|
if (!isDefined(calendarType)) {
|
|
calendarType = getCurrentDateDisplayType().calendarType;
|
|
}
|
|
|
|
if (!isDefined(numeralSystem)) {
|
|
numeralSystem = getCurrentNumeralSystemType();
|
|
}
|
|
|
|
return {
|
|
calendarType: calendarType,
|
|
numeralSystem: numeralSystem,
|
|
localeData: getDateTimeLocaleData()
|
|
};
|
|
}
|
|
|
|
function getNumberFormatOptions({numeralSystem, digitGrouping, decimalSeparator, currencyCode}: {
|
|
numeralSystem?: NumeralSystem,
|
|
digitGrouping?: DigitGroupingType,
|
|
decimalSeparator?: string,
|
|
currencyCode?: string
|
|
}): NumberFormatOptions {
|
|
if (!isDefined(numeralSystem)) {
|
|
numeralSystem = getCurrentNumeralSystemType();
|
|
}
|
|
|
|
if (!isDefined(digitGrouping)) {
|
|
digitGrouping = getCurrentDigitGroupingType();
|
|
}
|
|
|
|
if (!isDefined(decimalSeparator)) {
|
|
decimalSeparator = getCurrentDecimalSeparator();
|
|
}
|
|
|
|
return {
|
|
numeralSystem: numeralSystem,
|
|
digitGrouping: digitGrouping,
|
|
digitGroupingSymbol: getCurrentDigitGroupingSymbol(),
|
|
decimalSeparator: decimalSeparator,
|
|
decimalNumberCount: getCurrencyFraction(currencyCode),
|
|
};
|
|
}
|
|
|
|
function getCurrencyUnitName(currencyCode: string, isPlural: boolean): string {
|
|
const currencyInfo = ALL_CURRENCIES[currencyCode];
|
|
|
|
if (currencyInfo && currencyInfo.unit) {
|
|
if (isPlural) {
|
|
return t(`currency.unit.${currencyInfo.unit}.plural`);
|
|
} else {
|
|
return t(`currency.unit.${currencyInfo.unit}.normal`);
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
function getCurrentCurrencyDisplayType(): CurrencyDisplayType {
|
|
let currencyDisplayType = CurrencyDisplayType.valueOf(userStore.currentUserCurrencyDisplayType);
|
|
|
|
if (!currencyDisplayType) {
|
|
const defaultCurrencyDisplayTypeName = t('default.currencyDisplayType');
|
|
currencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
|
}
|
|
|
|
if (!currencyDisplayType) {
|
|
currencyDisplayType = CurrencyDisplayType.Default;
|
|
}
|
|
|
|
return currencyDisplayType;
|
|
}
|
|
|
|
// public functions
|
|
function translateIf(text: string | undefined, isTranslate?: boolean): string {
|
|
if (!isDefined(text)) {
|
|
return '';
|
|
}
|
|
|
|
if (isTranslate) {
|
|
return t(text);
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
function translateError(message: string | { error: ErrorResponse }): string {
|
|
let finalMessage = '';
|
|
let parameters = {};
|
|
|
|
if (isObject(message) && isObject(message.error)) {
|
|
const localizedError = getLocalizedError(message.error);
|
|
finalMessage = localizedError.message;
|
|
parameters = getLocalizedErrorParameters(localizedError.parameters);
|
|
} else if (isString(message)) {
|
|
finalMessage = message;
|
|
} else {
|
|
return '';
|
|
}
|
|
|
|
return t(finalMessage, parameters);
|
|
}
|
|
|
|
function joinMultiText(textArray: string[]): string {
|
|
if (!textArray || !textArray.length) {
|
|
return '';
|
|
}
|
|
|
|
const separator = t('format.misc.multiTextJoinSeparator');
|
|
|
|
return textArray.join(separator);
|
|
}
|
|
|
|
function getServerTipContent(tipConfig: Record<string, string>): string {
|
|
if (!tipConfig) {
|
|
return '';
|
|
}
|
|
|
|
const currentLanguage = getCurrentLanguageTag();
|
|
|
|
if (isString(tipConfig[currentLanguage])) {
|
|
return tipConfig[currentLanguage];
|
|
}
|
|
|
|
return tipConfig['default'] || '';
|
|
}
|
|
|
|
function getCurrentLanguageTag(): string {
|
|
return locale.value;
|
|
}
|
|
|
|
function getCurrentLanguageInfo(): LanguageInfo {
|
|
const languageInfo = getLanguageInfo(locale.value);
|
|
|
|
if (languageInfo) {
|
|
return languageInfo;
|
|
}
|
|
|
|
return getLanguageInfo(getDefaultLanguage()) as LanguageInfo;
|
|
}
|
|
|
|
function getCurrentLanguageDisplayName(): string {
|
|
const currentLanguageInfo = getCurrentLanguageInfo();
|
|
return currentLanguageInfo.displayName;
|
|
}
|
|
|
|
function getCurrentLanguageTextDirection(): TextDirection {
|
|
const currentLanguageInfo = getCurrentLanguageInfo();
|
|
|
|
if (currentLanguageInfo.textDirection === 'rtl') {
|
|
return TextDirection.RTL;
|
|
} else {
|
|
return TextDirection.LTR;
|
|
}
|
|
}
|
|
|
|
function getDefaultCurrency(): string {
|
|
return t('default.currency');
|
|
}
|
|
|
|
function getDefaultFirstDayOfWeek(): string {
|
|
return t('default.firstDayOfWeek');
|
|
}
|
|
|
|
function getAllLanguageOptions(includeSystemDefault: boolean): LanguageOption[] {
|
|
const ret: LanguageOption[] = [];
|
|
|
|
for (const languageTag in ALL_LANGUAGES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_LANGUAGES, languageTag)) {
|
|
continue;
|
|
}
|
|
|
|
const languageInfo = ALL_LANGUAGES[languageTag];
|
|
const displayName = languageInfo.displayName;
|
|
const languageNameInCurrentLanguage = getLanguageDisplayName(languageInfo.name);
|
|
|
|
ret.push({
|
|
languageTag: languageTag,
|
|
displayName: languageNameInCurrentLanguage,
|
|
nativeDisplayName: displayName
|
|
});
|
|
}
|
|
|
|
ret.sort(function (lang1, lang2) {
|
|
return lang1.languageTag.localeCompare(lang2.languageTag);
|
|
});
|
|
|
|
if (includeSystemDefault) {
|
|
ret.splice(0, 0, {
|
|
languageTag: '',
|
|
displayName: '',
|
|
nativeDisplayName: t('System Default')
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllEnableDisableOptions(): LocalizedSwitchOption[] {
|
|
return [{
|
|
value: true,
|
|
displayName: t('Enable')
|
|
}, {
|
|
value: false,
|
|
displayName: t('Disable')
|
|
}];
|
|
}
|
|
|
|
function getAllCurrencies(): LocalizedCurrencyInfo[] {
|
|
const allCurrencies: LocalizedCurrencyInfo[] = [];
|
|
|
|
for (const currencyCode in ALL_CURRENCIES) {
|
|
if (!Object.prototype.hasOwnProperty.call(ALL_CURRENCIES, currencyCode)) {
|
|
continue;
|
|
}
|
|
|
|
const localizedCurrencyInfo: LocalizedCurrencyInfo = {
|
|
currencyCode: currencyCode,
|
|
displayName: getCurrencyName(currencyCode)
|
|
};
|
|
|
|
allCurrencies.push(localizedCurrencyInfo);
|
|
}
|
|
|
|
allCurrencies.sort(function (c1, c2) {
|
|
return c1.displayName.localeCompare(c2.displayName);
|
|
})
|
|
|
|
return allCurrencies;
|
|
}
|
|
|
|
function getAllMeridiemIndicators(): NameValue[] {
|
|
const allMeridiemIndicators = MeridiemIndicator.values();
|
|
const localizedMeridiemIndicatorNames = [];
|
|
|
|
for (let i = 0; i < allMeridiemIndicators.length; i++) {
|
|
const indicator = allMeridiemIndicators[i];
|
|
|
|
localizedMeridiemIndicatorNames.push({
|
|
name: t(`datetime.${indicator.name}.content`),
|
|
value: indicator.name
|
|
});
|
|
}
|
|
|
|
return localizedMeridiemIndicatorNames;
|
|
}
|
|
|
|
function getAllLongMonthNames(): string[] {
|
|
return getAllMonthNames('long');
|
|
}
|
|
|
|
function getAllShortMonthNames(): string[] {
|
|
return getAllMonthNames('short');
|
|
}
|
|
|
|
function getAllLongWeekdayNames(): string[] {
|
|
return getAllWeekdayNames('long');
|
|
}
|
|
|
|
function getAllShortWeekdayNames(): string[] {
|
|
return getAllWeekdayNames('short');
|
|
}
|
|
|
|
function getAllMinWeekdayNames(): string[] {
|
|
return getAllWeekdayNames('min');
|
|
}
|
|
|
|
function getAllWeekDays(firstDayOfWeek?: WeekDayValue): TypeAndDisplayName[] {
|
|
const ret: TypeAndDisplayName[] = [];
|
|
const allWeekDays = WeekDay.values();
|
|
|
|
if (!isNumber(firstDayOfWeek)) {
|
|
firstDayOfWeek = WeekDay.DefaultFirstDay.type;
|
|
}
|
|
|
|
for (let i = firstDayOfWeek; i < allWeekDays.length; i++) {
|
|
const weekDay = allWeekDays[i];
|
|
|
|
ret.push({
|
|
type: weekDay.type,
|
|
displayName: t(`datetime.${weekDay.name}.long`)
|
|
});
|
|
}
|
|
|
|
for (let i = 0; i < firstDayOfWeek; i++) {
|
|
const weekDay = allWeekDays[i];
|
|
|
|
ret.push({
|
|
type: weekDay.type,
|
|
displayName: t(`datetime.${weekDay.name}.long`)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getLocalizedDateTimeFormats<T extends DateFormat | TimeFormat>(type: string, allFormatMap: Record<string, T>, allFormatArray: T[], languageDefaultTypeNameKey: string, systemDefaultFormatType: T, calendarType?: CalendarType): LocalizedDateTimeFormat[] {
|
|
const defaultFormat = getLocalizedDateTimeFormat<T>(type, allFormatMap, allFormatArray, LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE, languageDefaultTypeNameKey, systemDefaultFormatType);
|
|
const ret: LocalizedDateTimeFormat[] = [];
|
|
const dateTimeFormatOptions = getDateTimeFormatOptions({ calendarType: calendarType });
|
|
|
|
ret.push({
|
|
type: LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE,
|
|
format: defaultFormat,
|
|
displayName: `${t('Language Default')} (${formatCurrentTime(defaultFormat, dateTimeFormatOptions)})`
|
|
});
|
|
|
|
for (let i = 0; i < allFormatArray.length; i++) {
|
|
const formatType = allFormatArray[i];
|
|
const format = t(`format.${type}.${formatType.key}`);
|
|
|
|
ret.push({
|
|
type: formatType.type,
|
|
format: format,
|
|
displayName: formatCurrentTime(format, dateTimeFormatOptions)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllDateRanges(scene: DateRangeScene, includeCustom?: boolean, includeBillingCycle?: boolean): LocalizedDateRange[] {
|
|
const ret: LocalizedDateRange[] = [];
|
|
const allDateRanges = DateRange.values();
|
|
|
|
for (let i = 0; i < allDateRanges.length; i++) {
|
|
const dateRange = allDateRanges[i];
|
|
|
|
if (!dateRange.isAvailableForScene(scene)) {
|
|
continue;
|
|
}
|
|
|
|
if (dateRange.isBillingCycle) {
|
|
if (includeBillingCycle) {
|
|
ret.push({
|
|
type: dateRange.type,
|
|
displayName: t(dateRange.name),
|
|
isBillingCycle: dateRange.isBillingCycle,
|
|
isUserCustomRange: dateRange.isUserCustomRange
|
|
});
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (includeCustom || dateRange.type !== DateRange.Custom.type) {
|
|
ret.push({
|
|
type: dateRange.type,
|
|
displayName: t(dateRange.name),
|
|
isBillingCycle: dateRange.isBillingCycle,
|
|
isUserCustomRange: dateRange.isUserCustomRange
|
|
});
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllRecentMonthDateRanges(includeAll: boolean, includeCustom: boolean): LocalizedRecentMonthDateRange[] {
|
|
const allRecentMonthDateRanges: LocalizedRecentMonthDateRange[] = [];
|
|
const recentDateRanges = getRecentMonthDateRanges(12);
|
|
const dateTimeFormatOptions = getDateTimeFormatOptions();
|
|
|
|
if (includeAll) {
|
|
allRecentMonthDateRanges.push({
|
|
dateType: DateRange.All.type,
|
|
minTime: 0,
|
|
maxTime: 0,
|
|
displayName: t('All')
|
|
});
|
|
}
|
|
|
|
for (let i = 0; i < recentDateRanges.length; i++) {
|
|
const recentDateRange = recentDateRanges[i];
|
|
|
|
allRecentMonthDateRanges.push({
|
|
dateType: recentDateRange.dateType,
|
|
minTime: recentDateRange.minTime,
|
|
maxTime: recentDateRange.maxTime,
|
|
year: recentDateRange.year,
|
|
month: recentDateRange.month,
|
|
isPreset: true,
|
|
displayName: formatUnixTime(recentDateRange.minTime, getLocalizedLongYearMonthFormat(), dateTimeFormatOptions)
|
|
});
|
|
}
|
|
|
|
if (includeCustom) {
|
|
allRecentMonthDateRanges.push({
|
|
dateType: DateRange.Custom.type,
|
|
minTime: 0,
|
|
maxTime: 0,
|
|
displayName: t('Custom Date')
|
|
});
|
|
}
|
|
|
|
return allRecentMonthDateRanges;
|
|
}
|
|
|
|
function getAllTimezones(includeSystemDefault?: boolean): LocalizedTimezoneInfo[] {
|
|
const defaultTimezoneOffset = getBrowserTimezoneOffset();
|
|
const defaultTimezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
|
const allTimezoneInfos: LocalizedTimezoneInfo[] = [];
|
|
|
|
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 = t(`timezone.${ALL_TIMEZONES[i].displayName}`);
|
|
|
|
allTimezoneInfos.push({
|
|
name: ALL_TIMEZONES[i].timezoneName,
|
|
utcOffset: utcOffset,
|
|
utcOffsetMinutes: getTimezoneOffsetMinutes(ALL_TIMEZONES[i].timezoneName),
|
|
displayName: displayName,
|
|
displayNameWithUtcOffset: `(UTC${utcOffset}) ${displayName}`
|
|
});
|
|
}
|
|
|
|
if (includeSystemDefault) {
|
|
const defaultDisplayName = t('System Default');
|
|
|
|
allTimezoneInfos.push({
|
|
name: '',
|
|
utcOffset: defaultTimezoneOffset,
|
|
utcOffsetMinutes: defaultTimezoneOffsetMinutes,
|
|
displayName: defaultDisplayName,
|
|
displayNameWithUtcOffset: `(UTC${defaultTimezoneOffset}) ${defaultDisplayName}`
|
|
});
|
|
}
|
|
|
|
allTimezoneInfos.sort(function (c1, c2) {
|
|
const utcOffset1 = parseInt(c1.utcOffset.replace(':', ''));
|
|
const utcOffset2 = parseInt(c2.utcOffset.replace(':', ''));
|
|
|
|
if (utcOffset1 !== utcOffset2) {
|
|
return utcOffset1 - utcOffset2;
|
|
}
|
|
|
|
return c1.displayName.localeCompare(c2.displayName);
|
|
})
|
|
|
|
return allTimezoneInfos;
|
|
}
|
|
|
|
function getAllTimezoneTypesUsedForStatistics(currentTimezone?: string): TypeAndDisplayName[] {
|
|
const currentTimezoneOffset = getTimezoneOffset(currentTimezone);
|
|
|
|
return [
|
|
{
|
|
type: TimezoneTypeForStatistics.ApplicationTimezone.type,
|
|
displayName: t(TimezoneTypeForStatistics.ApplicationTimezone.name) + ` (UTC${currentTimezoneOffset})`
|
|
},
|
|
{
|
|
type: TimezoneTypeForStatistics.TransactionTimezone.type,
|
|
displayName: t(TimezoneTypeForStatistics.TransactionTimezone.name)
|
|
}
|
|
];
|
|
}
|
|
|
|
function getAllFiscalYearFormats(): TypeAndDisplayName[] {
|
|
const now = getCurrentUnixTime();
|
|
let fiscalYearStart = userStore.currentUserFiscalYearStart;
|
|
|
|
if (!fiscalYearStart) {
|
|
fiscalYearStart = FiscalYearStart.Default.value;
|
|
}
|
|
|
|
const currentFiscalYearRange = getFiscalYearTimeRangeFromUnixTime(now, fiscalYearStart);
|
|
let defaultFiscalYearFormat = FiscalYearFormat.parse(t('default.fiscalYearFormat'));
|
|
|
|
if (!defaultFiscalYearFormat) {
|
|
defaultFiscalYearFormat = FiscalYearFormat.Default;
|
|
}
|
|
|
|
const ret: TypeAndDisplayName[] = [];
|
|
|
|
ret.push({
|
|
type: LANGUAGE_DEFAULT_FISCAL_YEAR_FORMAT_VALUE,
|
|
displayName: `${t('Language Default')} (${formatTimeRangeToFiscalYearFormat(defaultFiscalYearFormat, currentFiscalYearRange)})`
|
|
});
|
|
|
|
const allFiscalYearFormats = FiscalYearFormat.values();
|
|
|
|
for (let i = 0; i < allFiscalYearFormats.length; i++) {
|
|
const fiscalYearFormat = allFiscalYearFormats[i];
|
|
|
|
ret.push({
|
|
type: fiscalYearFormat.type,
|
|
displayName: formatTimeRangeToFiscalYearFormat(fiscalYearFormat, currentFiscalYearRange),
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllNumeralSystemTypes(): TypeAndDisplayName[] {
|
|
const defaultNumeralSystemTypeName = t('default.numeralSystem');
|
|
let defaultNumeralSystemType = NumeralSystem.parse(defaultNumeralSystemTypeName);
|
|
|
|
if (!defaultNumeralSystemType) {
|
|
defaultNumeralSystemType = NumeralSystem.Default;
|
|
}
|
|
|
|
const ret: TypeAndDisplayName[] = [];
|
|
|
|
ret.push({
|
|
type: NumeralSystem.LanguageDefaultType,
|
|
displayName: `${t('Language Default')} (${defaultNumeralSystemType.textualAllDigits})`
|
|
});
|
|
|
|
const allNumeralSystemTypes = NumeralSystem.values();
|
|
|
|
for (let i = 0; i < allNumeralSystemTypes.length; i++) {
|
|
const type = allNumeralSystemTypes[i];
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
displayName: `${t('numeral.' + type.name)} (${type.textualAllDigits})`
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllDigitGroupingTypes(numeralSystem: NumeralSystem, digitGroupingSymbol: string): LocalizedDigitGroupingType[] {
|
|
const defaultDigitGroupingTypeName = t('default.digitGrouping');
|
|
let defaultDigitGroupingType = DigitGroupingType.parse(defaultDigitGroupingTypeName);
|
|
|
|
if (!defaultDigitGroupingType) {
|
|
defaultDigitGroupingType = DigitGroupingType.Default;
|
|
}
|
|
|
|
const ret: LocalizedDigitGroupingType[] = [];
|
|
|
|
ret.push({
|
|
type: DigitGroupingType.LanguageDefaultType,
|
|
enabled: defaultDigitGroupingType.enabled,
|
|
displayName: `${t('Language Default')} (${t('numeral.' + defaultDigitGroupingType.name)})`
|
|
});
|
|
|
|
const allDigitGroupingTypes = DigitGroupingType.values();
|
|
const numberCharacters = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits('123456789').split('');
|
|
|
|
for (let i = 0; i < allDigitGroupingTypes.length; i++) {
|
|
const type = allDigitGroupingTypes[i];
|
|
const sampleValue = type.format(numberCharacters, digitGroupingSymbol);
|
|
|
|
ret.push({
|
|
type: type.type,
|
|
enabled: type.enabled,
|
|
displayName: `${t('numeral.' + type.name)} (${sampleValue})`
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllExpenseIncomeAmountColors(categoryType: CategoryType): TypeAndDisplayName[] {
|
|
const ret: TypeAndDisplayName[] = [];
|
|
let defaultAmountName = '';
|
|
|
|
if (categoryType === CategoryType.Expense) {
|
|
defaultAmountName = PresetAmountColor.DefaultExpenseColor.name;
|
|
} else if (categoryType === CategoryType.Income) { // income
|
|
defaultAmountName = PresetAmountColor.DefaultIncomeColor.name;
|
|
}
|
|
|
|
if (defaultAmountName) {
|
|
defaultAmountName = t('color.amount.' + defaultAmountName);
|
|
}
|
|
|
|
ret.push({
|
|
type: PresetAmountColor.SystemDefaultType,
|
|
displayName: t('System Default') + (defaultAmountName ? ` (${defaultAmountName})` : '')
|
|
});
|
|
|
|
const allPresetAmountColors = PresetAmountColor.values();
|
|
|
|
for (let i = 0; i < allPresetAmountColors.length; i++) {
|
|
const amountColor = allPresetAmountColors[i];
|
|
|
|
ret.push({
|
|
type: amountColor.type,
|
|
displayName: t('color.amount.' + amountColor.name)
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllAccountCategories(): LocalizedAccountCategory[] {
|
|
const ret: LocalizedAccountCategory[] = [];
|
|
const allCategories = AccountCategory.values();
|
|
|
|
for (let i = 0; i < allCategories.length; i++) {
|
|
const accountCategory = allCategories[i];
|
|
|
|
ret.push({
|
|
type: accountCategory.type,
|
|
displayName: t(accountCategory.name),
|
|
defaultAccountIconId: accountCategory.defaultAccountIconId
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function getAllTransactionDefaultCategories(categoryType: 0 | CategoryType, locale: string): PartialRecord<CategoryType, LocalizedPresetCategory[]> {
|
|
const allCategories: PartialRecord<CategoryType, LocalizedPresetCategory[]> = {};
|
|
const categoryTypes: CategoryType[] = [];
|
|
|
|
if (categoryType === 0) {
|
|
categoryTypes.push(...ALL_CATEGORY_TYPES);
|
|
} else {
|
|
categoryTypes.push(categoryType);
|
|
}
|
|
|
|
for (let i = 0; i < categoryTypes.length; i++) {
|
|
const categories: LocalizedPresetCategory[] = [];
|
|
const categoryType = categoryTypes[i];
|
|
let defaultCategories: PresetCategory[] = [];
|
|
|
|
if (categoryType === CategoryType.Income) {
|
|
defaultCategories = DEFAULT_INCOME_CATEGORIES;
|
|
} else if (categoryType === CategoryType.Expense) {
|
|
defaultCategories = DEFAULT_EXPENSE_CATEGORIES;
|
|
} else if (categoryType === CategoryType.Transfer) {
|
|
defaultCategories = DEFAULT_TRANSFER_CATEGORIES;
|
|
}
|
|
|
|
for (let j = 0; j < defaultCategories.length; j++) {
|
|
const category = defaultCategories[j];
|
|
|
|
const submitCategory: LocalizedPresetCategory = {
|
|
name: t('category.' + category.name, {}, { locale: locale }),
|
|
type: categoryType,
|
|
icon: category.categoryIconId,
|
|
color: category.color,
|
|
subCategories: []
|
|
};
|
|
|
|
for (let k = 0; k < category.subCategories.length; k++) {
|
|
const subCategory = category.subCategories[k];
|
|
const submitSubCategory: LocalizedPresetSubCategory = {
|
|
name: t('category.' + subCategory.name, {}, { locale: locale }),
|
|
type: categoryType,
|
|
icon: subCategory.categoryIconId,
|
|
color: subCategory.color
|
|
};
|
|
|
|
submitCategory.subCategories.push(submitSubCategory);
|
|
}
|
|
|
|
categories.push(submitCategory);
|
|
}
|
|
|
|
allCategories[categoryType] = categories;
|
|
}
|
|
|
|
return allCategories;
|
|
}
|
|
|
|
function getAllDisplayExchangeRates(exchangeRatesData?: LatestExchangeRateResponse): LocalizedLatestExchangeRate[] {
|
|
const availableExchangeRates: LocalizedLatestExchangeRate[] = [];
|
|
|
|
if (!exchangeRatesData || !exchangeRatesData.exchangeRates) {
|
|
return availableExchangeRates;
|
|
}
|
|
|
|
for (let i = 0; i < exchangeRatesData.exchangeRates.length; i++) {
|
|
const exchangeRate = exchangeRatesData.exchangeRates[i];
|
|
|
|
availableExchangeRates.push({
|
|
currencyCode: exchangeRate.currency,
|
|
currencyDisplayName: getCurrencyName(exchangeRate.currency),
|
|
rate: exchangeRate.rate
|
|
});
|
|
}
|
|
|
|
if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.Name.type) {
|
|
availableExchangeRates.sort(function (c1, c2) {
|
|
return c1.currencyDisplayName.localeCompare(c2.currencyDisplayName);
|
|
});
|
|
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.CurrencyCode.type) {
|
|
availableExchangeRates.sort(function (c1, c2) {
|
|
return c1.currencyCode.localeCompare(c2.currencyCode);
|
|
});
|
|
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.ExchangeRate.type) {
|
|
availableExchangeRates.sort(function (c1, c2) {
|
|
const rate1 = parseFloat(c1.rate);
|
|
const rate2 = parseFloat(c2.rate);
|
|
|
|
if (rate1 > rate2) {
|
|
return 1;
|
|
} else if (rate1 < rate2) {
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
});
|
|
}
|
|
|
|
return availableExchangeRates;
|
|
}
|
|
|
|
function getAllSupportedImportFileCagtegoryAndTypes(): LocalizedImportFileCategoryAndTypes[] {
|
|
const allSupportedImportFileCategoryAndTypes: LocalizedImportFileCategoryAndTypes[] = [];
|
|
|
|
for (let i = 0; i < SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES.length; i++) {
|
|
const categoryAndTypes = SUPPORTED_IMPORT_FILE_CATEGORY_AND_TYPES[i];
|
|
|
|
const localizedCategoryAndTypes: LocalizedImportFileCategoryAndTypes = {
|
|
displayCategoryName: t(categoryAndTypes.categoryName),
|
|
fileTypes: []
|
|
};
|
|
|
|
for (let j = 0; j < categoryAndTypes.fileTypes.length; j++) {
|
|
const fileType = categoryAndTypes.fileTypes[j];
|
|
let document: LocalizedImportFileDocument | undefined;
|
|
|
|
if (fileType.document) {
|
|
let documentLanguage = '';
|
|
let documentDisplayLanguageName = '';
|
|
let documentAnchor = '';
|
|
|
|
if (fileType.document.supportMultiLanguages === true) {
|
|
documentLanguage = getCurrentLanguageTag();
|
|
|
|
if (SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage] === documentLanguage) {
|
|
documentAnchor = t(`document.anchor.export_and_import.${fileType.document.anchor}`);
|
|
} else if (SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage]) {
|
|
documentLanguage = SUPPORTED_DOCUMENT_LANGUAGES_FOR_IMPORT_FILE[documentLanguage];
|
|
documentAnchor = t(`document.anchor.export_and_import.${fileType.document.anchor}`, {}, { locale: documentLanguage });
|
|
} else {
|
|
documentLanguage = DEFAULT_DOCUMENT_LANGUAGE_FOR_IMPORT_FILE;
|
|
documentAnchor = t(`document.anchor.export_and_import.${fileType.document.anchor}`, {}, { locale: documentLanguage });
|
|
}
|
|
} else if (isString(fileType.document.supportMultiLanguages) && ALL_LANGUAGES[fileType.document.supportMultiLanguages]) {
|
|
documentLanguage = fileType.document.supportMultiLanguages;
|
|
documentAnchor = fileType.document.anchor;
|
|
}
|
|
|
|
if (documentLanguage && documentLanguage !== getCurrentLanguageTag()) {
|
|
documentDisplayLanguageName = getLanguageDisplayName(ALL_LANGUAGES[documentLanguage].name);
|
|
}
|
|
|
|
if (documentLanguage) {
|
|
documentLanguage = documentLanguage.replace(/-/g, '_');
|
|
}
|
|
|
|
if (documentAnchor) {
|
|
documentAnchor = documentAnchor.toLowerCase().replace(/ /g, '-');
|
|
}
|
|
|
|
if (documentLanguage === DEFAULT_LANGUAGE) {
|
|
documentLanguage = '';
|
|
}
|
|
|
|
document = {
|
|
language: documentLanguage,
|
|
displayLanguageName: documentDisplayLanguageName,
|
|
anchor: documentAnchor
|
|
};
|
|
} else {
|
|
document = undefined;
|
|
}
|
|
|
|
const subTypes: LocalizedImportFileTypeSubType[] = [];
|
|
|
|
if (fileType.subTypes) {
|
|
for (let k = 0; k < fileType.subTypes.length; k++) {
|
|
const subType = fileType.subTypes[k];
|
|
const localizedSubType: LocalizedImportFileTypeSubType = {
|
|
type: subType.type,
|
|
displayName: t(subType.name),
|
|
extensions: subType.extensions
|
|
};
|
|
|
|
subTypes.push(localizedSubType);
|
|
}
|
|
}
|
|
|
|
const supportedEncodings: LocalizedImportFileTypeSupportedEncodings[] = [];
|
|
|
|
if (fileType.supportedEncodings) {
|
|
for (let k = 0; k < fileType.supportedEncodings.length; k++) {
|
|
const encoding = fileType.supportedEncodings[k];
|
|
const localizedEncoding: LocalizedImportFileTypeSupportedEncodings = {
|
|
encoding: encoding,
|
|
displayName: t(`encoding.${encoding}`)
|
|
};
|
|
|
|
supportedEncodings.push(localizedEncoding);
|
|
}
|
|
}
|
|
|
|
const localizedFileType: LocalizedImportFileType = {
|
|
type: fileType.type,
|
|
displayName: t(fileType.name),
|
|
extensions: fileType.extensions,
|
|
subTypes: subTypes.length ? subTypes : undefined,
|
|
supportedEncodings: supportedEncodings.length ? supportedEncodings : undefined,
|
|
dataFromTextbox: fileType.dataFromTextbox,
|
|
document: document
|
|
};
|
|
|
|
localizedCategoryAndTypes.fileTypes.push(localizedFileType);
|
|
}
|
|
|
|
allSupportedImportFileCategoryAndTypes.push(localizedCategoryAndTypes);
|
|
}
|
|
|
|
return allSupportedImportFileCategoryAndTypes;
|
|
}
|
|
|
|
function getLanguageInfo(languageKey: string): LanguageInfo | undefined {
|
|
return ALL_LANGUAGES[languageKey];
|
|
}
|
|
|
|
function getMonthShortName(monthName: string): string {
|
|
return t(`datetime.${monthName}.short`);
|
|
}
|
|
|
|
function getMonthLongName(monthName: string): string {
|
|
return t(`datetime.${monthName}.long`);
|
|
}
|
|
|
|
function getMonthdayOrdinal(monthDay: number): string {
|
|
return t(`datetime.monthDayOrdinal.${monthDay}`);
|
|
}
|
|
|
|
function getMonthdayShortName(monthDay: number): string {
|
|
return t('format.misc.monthDay', {
|
|
ordinal: getMonthdayOrdinal(monthDay)
|
|
});
|
|
}
|
|
|
|
function getWeekdayShortName(weekDay: WeekDay): string {
|
|
return t(`datetime.${weekDay.name}.short`);
|
|
}
|
|
|
|
function getWeekdayLongName(weekDay: WeekDay): string {
|
|
return t(`datetime.${weekDay.name}.long`);
|
|
}
|
|
|
|
function getMultiMonthdayShortNames(monthDays: number[]): string {
|
|
if (!monthDays) {
|
|
return '';
|
|
}
|
|
|
|
if (monthDays.length === 1) {
|
|
return t('format.misc.monthDay', {
|
|
ordinal: getMonthdayOrdinal(monthDays[0])
|
|
});
|
|
} else {
|
|
return t('format.misc.monthDays', {
|
|
multiMonthDays: joinMultiText(monthDays.map(monthDay =>
|
|
t('format.misc.eachMonthDayInMonthDays', {
|
|
ordinal: getMonthdayOrdinal(monthDay)
|
|
})))
|
|
});
|
|
}
|
|
}
|
|
|
|
function getMultiWeekdayLongNames(weekdayTypes: number[], firstDayOfWeek?: WeekDayValue): string {
|
|
const weekdayTypesMap: Record<number, boolean> = {};
|
|
|
|
if (!isNumber(firstDayOfWeek)) {
|
|
firstDayOfWeek = WeekDay.DefaultFirstDay.type;
|
|
}
|
|
|
|
for (let i = 0; i < weekdayTypes.length; i++) {
|
|
weekdayTypesMap[weekdayTypes[i]] = true;
|
|
}
|
|
|
|
const allWeekDays = getAllWeekDays(firstDayOfWeek);
|
|
const finalWeekdayNames = [];
|
|
|
|
for (let i = 0; i < allWeekDays.length; i++) {
|
|
const weekDay = allWeekDays[i];
|
|
|
|
if (weekdayTypesMap[weekDay.type]) {
|
|
finalWeekdayNames.push(weekDay.displayName);
|
|
}
|
|
}
|
|
|
|
return joinMultiText(finalWeekdayNames);
|
|
}
|
|
|
|
function getAllLocalizedDigits(): string[] {
|
|
const numeralSystem = getCurrentNumeralSystemType();
|
|
return numeralSystem.getAllDigits();
|
|
}
|
|
|
|
function getCurrentCalendarDisplayType(): CalendarDisplayType {
|
|
let calendarDisplayType = CalendarDisplayType.valueOf(userStore.currentUserCalendarDisplayType);
|
|
|
|
if (!calendarDisplayType) {
|
|
const defaultCalendarDisplayTypeName = t('default.calendarDisplayType');
|
|
calendarDisplayType = CalendarDisplayType.parse(defaultCalendarDisplayTypeName);
|
|
|
|
if (!calendarDisplayType) {
|
|
calendarDisplayType = CalendarDisplayType.Default;
|
|
}
|
|
}
|
|
|
|
return calendarDisplayType;
|
|
}
|
|
|
|
function getCurrentDateDisplayType(): DateDisplayType {
|
|
let dateDisplayType = DateDisplayType.valueOf(userStore.currentUserDateDisplayType);
|
|
|
|
if (!dateDisplayType) {
|
|
const defaultDateDisplayTypeName = t('default.dateDisplayType');
|
|
dateDisplayType = DateDisplayType.parse(defaultDateDisplayTypeName);
|
|
|
|
if (!dateDisplayType) {
|
|
dateDisplayType = DateDisplayType.Default;
|
|
}
|
|
}
|
|
|
|
return dateDisplayType;
|
|
}
|
|
|
|
function getCurrentNumeralSystemType(): NumeralSystem {
|
|
let numeralSystemType = NumeralSystem.valueOf(userStore.currentUserNumeralSystem);
|
|
|
|
if (!numeralSystemType) {
|
|
const defaultNumeralSystemTypeName = t('default.numeralSystem');
|
|
numeralSystemType = NumeralSystem.parse(defaultNumeralSystemTypeName);
|
|
|
|
if (!numeralSystemType) {
|
|
numeralSystemType = NumeralSystem.Default;
|
|
}
|
|
}
|
|
|
|
return numeralSystemType;
|
|
}
|
|
|
|
function getCurrentDecimalSeparator(): string {
|
|
let decimalSeparatorType = DecimalSeparator.valueOf(userStore.currentUserDecimalSeparator);
|
|
|
|
if (!decimalSeparatorType) {
|
|
const defaultDecimalSeparatorTypeName = t('default.decimalSeparator');
|
|
decimalSeparatorType = DecimalSeparator.parse(defaultDecimalSeparatorTypeName);
|
|
|
|
if (!decimalSeparatorType) {
|
|
decimalSeparatorType = DecimalSeparator.Default;
|
|
}
|
|
}
|
|
|
|
return decimalSeparatorType.symbol;
|
|
}
|
|
|
|
function getCurrentDigitGroupingSymbol(): string {
|
|
let digitGroupingSymbolType = DigitGroupingSymbol.valueOf(userStore.currentUserDigitGroupingSymbol);
|
|
|
|
if (!digitGroupingSymbolType) {
|
|
const defaultDigitGroupingSymbolTypeName = t('default.digitGroupingSymbol');
|
|
digitGroupingSymbolType = DigitGroupingSymbol.parse(defaultDigitGroupingSymbolTypeName);
|
|
|
|
if (!digitGroupingSymbolType) {
|
|
digitGroupingSymbolType = DigitGroupingSymbol.Default;
|
|
}
|
|
}
|
|
|
|
return digitGroupingSymbolType.symbol;
|
|
}
|
|
|
|
function getCurrentDigitGroupingType(): DigitGroupingType {
|
|
let digitGroupingType = DigitGroupingType.valueOf(userStore.currentUserDigitGrouping);
|
|
|
|
if (!digitGroupingType) {
|
|
const defaultDigitGroupingTypeName = t('default.digitGrouping');
|
|
digitGroupingType = DigitGroupingType.parse(defaultDigitGroupingTypeName);
|
|
|
|
if (!digitGroupingType) {
|
|
digitGroupingType = DigitGroupingType.Default;
|
|
}
|
|
}
|
|
|
|
return digitGroupingType;
|
|
}
|
|
|
|
function getCurrentFiscalYearFormatType(): number {
|
|
let fiscalYearFormat = FiscalYearFormat.valueOf(userStore.currentUserFiscalYearFormat);
|
|
|
|
if (!fiscalYearFormat) {
|
|
const defaultFiscalYearFormatTypeName = t('default.fiscalYearFormat');
|
|
fiscalYearFormat = FiscalYearFormat.parse(defaultFiscalYearFormatTypeName);
|
|
|
|
if (!fiscalYearFormat) {
|
|
fiscalYearFormat = FiscalYearFormat.Default;
|
|
}
|
|
}
|
|
|
|
return fiscalYearFormat.type;
|
|
}
|
|
|
|
function getCurrencyName(currencyCode: string): string {
|
|
if (!currencyCode) {
|
|
return '';
|
|
}
|
|
|
|
return t(`currency.name.${currencyCode}`);
|
|
}
|
|
|
|
function isLongDateMonthAfterYear(): boolean {
|
|
return getLocalizedDateTimeType(LongDateFormat.all(), LongDateFormat.values(), userStore.currentUserLongDateFormat, 'longDateFormat', LongDateFormat.Default).isMonthAfterYear;
|
|
}
|
|
|
|
function isShortDateMonthAfterYear(): boolean {
|
|
return getLocalizedDateTimeType(ShortDateFormat.all(), ShortDateFormat.values(), userStore.currentUserShortDateFormat, 'shortDateFormat', ShortDateFormat.Default).isMonthAfterYear;
|
|
}
|
|
|
|
function isLongTime24HourFormat(): boolean {
|
|
return getLocalizedDateTimeType(LongTimeFormat.all(), LongTimeFormat.values(), userStore.currentUserLongTimeFormat, 'longTimeFormat', LongTimeFormat.Default).is24HourFormat;
|
|
}
|
|
|
|
function isLongTimeMeridiemIndicatorFirst(): boolean {
|
|
return getLocalizedDateTimeType(LongTimeFormat.all(), LongTimeFormat.values(), userStore.currentUserLongTimeFormat, 'longTimeFormat', LongTimeFormat.Default).isMeridiemIndicatorFirst || false;
|
|
}
|
|
|
|
function isShortTime24HourFormat(): boolean {
|
|
return getLocalizedDateTimeType(ShortTimeFormat.all(), ShortTimeFormat.values(), userStore.currentUserShortTimeFormat, 'shortTimeFormat', ShortTimeFormat.Default).is24HourFormat;
|
|
}
|
|
|
|
function isShortTimeMeridiemIndicatorFirst(): boolean {
|
|
return getLocalizedDateTimeType(ShortTimeFormat.all(), ShortTimeFormat.values(), userStore.currentUserShortTimeFormat, 'shortTimeFormat', ShortTimeFormat.Default).isMeridiemIndicatorFirst || false;
|
|
}
|
|
|
|
function isLongTimeHourTwoDigits(): boolean {
|
|
const longTimeFormat = getLocalizedLongTimeFormat();
|
|
return longTimeFormat.indexOf('HH') >= 0 || longTimeFormat.indexOf('hh') >= 0;
|
|
}
|
|
|
|
function isLongTimeMinuteTwoDigits(): boolean {
|
|
return getLocalizedLongTimeFormat().indexOf('mm') >= 0;
|
|
}
|
|
|
|
function isLongTimeSecondTwoDigits(): boolean {
|
|
return getLocalizedLongTimeFormat().indexOf('ss') >= 0;
|
|
}
|
|
|
|
function formatGregorianCalendarYearDashMonthDashDayToLongDate(date: TextualYearMonthDay): string {
|
|
return formatGregorianCalendarYearDashMonthDashDay(date, getLocalizedLongDateFormat(), getDateTimeFormatOptions());
|
|
}
|
|
|
|
function formatGregorianCalendarMonthDashDayToLongMonthDay(monthDay: TextualYearMonth): string {
|
|
return formatGregorianCalendarMonthDashDay(monthDay, getLocalizedLongMonthDayFormat(), getDateTimeFormatOptions());
|
|
}
|
|
|
|
function formatUnixTimeToYearQuarter(unixTime: number): string {
|
|
const dateTimeFormatOptions = getDateTimeFormatOptions();
|
|
const date = parseDateTimeFromUnixTime(unixTime);
|
|
const year = date.getLocalizedCalendarYear(dateTimeFormatOptions);
|
|
const quarter = date.getLocalizedCalendarQuarter(dateTimeFormatOptions);
|
|
return formatYearQuarter(year, quarter);
|
|
}
|
|
|
|
function formatYearQuarter(year: number, quarter: number): string {
|
|
if (1 <= quarter && quarter <= 4) {
|
|
return t('format.yearQuarter.q' + quarter, {
|
|
year: year,
|
|
quarter: quarter
|
|
});
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function formatDateRange(dateType: number, startTime: number, endTime: number): string {
|
|
if (dateType === DateRange.All.type) {
|
|
return t(DateRange.All.name);
|
|
}
|
|
|
|
const allDateRanges = DateRange.values();
|
|
const dateTimeFormatOptions = getDateTimeFormatOptions();
|
|
|
|
for (let i = 0; i < allDateRanges.length; i++) {
|
|
const dateRange = allDateRanges[i];
|
|
|
|
if (dateRange && dateRange.type !== DateRange.Custom.type && dateRange.type === dateType && dateRange.name) {
|
|
return t(dateRange.name);
|
|
}
|
|
}
|
|
|
|
if (isDateRangeMatchFullYears(startTime, endTime)) {
|
|
const format = getLocalizedShortYearFormat();
|
|
const displayStartTime = formatUnixTime(startTime, format, dateTimeFormatOptions);
|
|
const displayEndTime = formatUnixTime(endTime, format, dateTimeFormatOptions);
|
|
|
|
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
|
|
}
|
|
|
|
if (isDateRangeMatchFullMonths(startTime, endTime)) {
|
|
const format = getLocalizedShortYearMonthFormat();
|
|
const displayStartTime = formatUnixTime(startTime, format, dateTimeFormatOptions);
|
|
const displayEndTime = formatUnixTime(endTime, format, dateTimeFormatOptions);
|
|
|
|
return displayStartTime !== displayEndTime ? `${displayStartTime} ~ ${displayEndTime}` : displayStartTime;
|
|
}
|
|
|
|
const startTimeYear = parseDateTimeFromUnixTime(startTime).getLocalizedCalendarYear(dateTimeFormatOptions);
|
|
const endTimeYear = parseDateTimeFromUnixTime(endTime).getLocalizedCalendarYear(dateTimeFormatOptions);
|
|
|
|
const format = getLocalizedShortDateFormat();
|
|
const displayStartTime = formatUnixTime(startTime, format, dateTimeFormatOptions);
|
|
const displayEndTime = formatUnixTime(endTime, format, dateTimeFormatOptions);
|
|
|
|
if (displayStartTime === displayEndTime) {
|
|
return displayStartTime;
|
|
} else if (startTimeYear === endTimeYear) {
|
|
const displayShortEndTime = formatUnixTime(endTime, getLocalizedShortMonthDayFormat(), dateTimeFormatOptions);
|
|
return `${displayStartTime} ~ ${displayShortEndTime}`;
|
|
}
|
|
|
|
return `${displayStartTime} ~ ${displayEndTime}`;
|
|
}
|
|
|
|
function formatTimeRangeToFiscalYearFormat(format: FiscalYearFormat, timeRange: FiscalYearUnixTime | UnixTimeRange): string {
|
|
if (!format) {
|
|
format = FiscalYearFormat.Default;
|
|
}
|
|
|
|
const dateTimeFormatOptions = getDateTimeFormatOptions();
|
|
|
|
return t('format.fiscalYear.' + format.typeName, {
|
|
StartYYYY: formatUnixTime(timeRange.minUnixTime, 'YYYY', dateTimeFormatOptions),
|
|
StartYY: formatUnixTime(timeRange.minUnixTime, 'YY', dateTimeFormatOptions),
|
|
EndYYYY: formatUnixTime(timeRange.maxUnixTime, 'YYYY', dateTimeFormatOptions),
|
|
EndYY: formatUnixTime(timeRange.maxUnixTime, 'YY', dateTimeFormatOptions),
|
|
});
|
|
}
|
|
|
|
function formatUnixTimeToFiscalYear(unixTime: number): string {
|
|
let fiscalYearFormat = FiscalYearFormat.valueOf(getCurrentFiscalYearFormatType());
|
|
|
|
if (!fiscalYearFormat) {
|
|
fiscalYearFormat = FiscalYearFormat.Default;
|
|
}
|
|
|
|
const timeRange = getFiscalYearTimeRangeFromUnixTime(unixTime, userStore.currentUserFiscalYearStart);
|
|
return formatTimeRangeToFiscalYearFormat(fiscalYearFormat, timeRange);
|
|
}
|
|
|
|
function formatYearToFiscalYear(year: number) {
|
|
let fiscalYearFormat = FiscalYearFormat.valueOf(getCurrentFiscalYearFormatType());
|
|
|
|
if (!fiscalYearFormat) {
|
|
fiscalYearFormat = FiscalYearFormat.Default;
|
|
}
|
|
|
|
const timeRange = getFiscalYearTimeRangeFromYear(year, userStore.currentUserFiscalYearStart);
|
|
return formatTimeRangeToFiscalYearFormat(fiscalYearFormat, timeRange);
|
|
}
|
|
|
|
function formatFiscalYearStartToLongDay(fiscalYearStartValue: number) {
|
|
let fiscalYearStart = FiscalYearStart.valueOf(fiscalYearStartValue);
|
|
|
|
if (!fiscalYearStart) {
|
|
fiscalYearStart = FiscalYearStart.Default;
|
|
}
|
|
|
|
return formatGregorianCalendarMonthDashDayToLongMonthDay(fiscalYearStart.toMonthDashDayString());
|
|
}
|
|
|
|
function getTimezoneDifferenceDisplayText(utcOffset: number): string {
|
|
const defaultTimezoneOffset = getTimezoneOffsetMinutes();
|
|
const offsetTime = getTimeDifferenceHoursAndMinutes(utcOffset - defaultTimezoneOffset);
|
|
|
|
if (utcOffset > defaultTimezoneOffset) {
|
|
if (offsetTime.offsetMinutes) {
|
|
return t('format.misc.hoursMinutesAheadOfDefaultTimezone', {
|
|
hours: offsetTime.offsetHours,
|
|
minutes: offsetTime.offsetMinutes
|
|
});
|
|
} else {
|
|
return t('format.misc.hoursAheadOfDefaultTimezone', {
|
|
hours: offsetTime.offsetHours
|
|
});
|
|
}
|
|
} else if (utcOffset < defaultTimezoneOffset) {
|
|
if (offsetTime.offsetMinutes) {
|
|
return t('format.misc.hoursMinutesBehindDefaultTimezone', {
|
|
hours: offsetTime.offsetHours,
|
|
minutes: offsetTime.offsetMinutes
|
|
});
|
|
} else {
|
|
return t('format.misc.hoursBehindDefaultTimezone', {
|
|
hours: offsetTime.offsetHours
|
|
});
|
|
}
|
|
} else {
|
|
return t('Same time as default timezone');
|
|
}
|
|
}
|
|
|
|
function getParsedAmountNumber(value: string, numeralSystem?: NumeralSystem): number {
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
|
return parseAmount(value, numberFormatOptions);
|
|
}
|
|
|
|
function getFormattedAmount(value: number, numeralSystem?: NumeralSystem, digitGrouping?: DigitGroupingType, currencyCode?: string): string {
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, digitGrouping, currencyCode });
|
|
return formatAmount(value, numberFormatOptions);
|
|
}
|
|
|
|
function getFormattedAmountWithCurrency(value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType, numeralSystem?: NumeralSystem, decimalSeparator?: string): string {
|
|
let finalCurrencyCode = '';
|
|
|
|
if (!isBoolean(currencyCode) && !currencyCode) {
|
|
finalCurrencyCode = userStore.currentUserDefaultCurrency;
|
|
} else if (isBoolean(currencyCode) && !currencyCode) {
|
|
finalCurrencyCode = '';
|
|
} else {
|
|
finalCurrencyCode = currencyCode;
|
|
}
|
|
|
|
if (!currencyDisplayType) {
|
|
currencyDisplayType = getCurrentCurrencyDisplayType();
|
|
}
|
|
|
|
if (!numeralSystem) {
|
|
numeralSystem = getCurrentNumeralSystemType();
|
|
}
|
|
|
|
let suffix = '';
|
|
|
|
if (isObject(value) && isNumber(value.value) && isString(value.suffix)) {
|
|
suffix = value.suffix;
|
|
value = value.value;
|
|
}
|
|
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, decimalSeparator, currencyCode: finalCurrencyCode });
|
|
const currencyName = getCurrencyName(finalCurrencyCode);
|
|
|
|
if (isNumber(value)) {
|
|
const isPlural: boolean = value !== 100 && value !== -100;
|
|
const textualValue = formatAmount(value, numberFormatOptions);
|
|
|
|
if (!finalCurrencyCode) {
|
|
return textualValue;
|
|
}
|
|
|
|
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
|
|
const ret = appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
|
|
|
|
if (suffix) {
|
|
return ret + suffix;
|
|
} else {
|
|
return ret;
|
|
}
|
|
} else if (isString(value)) {
|
|
const isPlural: boolean = true;
|
|
const textualValue = formatHiddenAmount(value, numberFormatOptions);
|
|
|
|
if (!finalCurrencyCode) {
|
|
return textualValue;
|
|
}
|
|
|
|
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
|
|
return appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function getFormattedNumber(value: number, numeralSystem?: NumeralSystem, precision?: number): string {
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, digitGrouping: DigitGroupingType.None });
|
|
return formatNumber(value, numberFormatOptions, precision);
|
|
}
|
|
|
|
function getFormattedPercentValue(value: number, precision: number, lowPrecisionValue: string, numeralSystem?: NumeralSystem): string {
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
|
return formatPercent(value, precision, lowPrecisionValue, numberFormatOptions);
|
|
}
|
|
|
|
function getFormattedExchangeRateAmount(value: number, numeralSystem?: NumeralSystem): string {
|
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
|
return formatExchangeRateAmount(value, numberFormatOptions);
|
|
}
|
|
|
|
function getAdaptiveAmountRate(amount1: number, amount2: number, fromExchangeRate: {
|
|
rate: string
|
|
}, toExchangeRate: { rate: string }): string | null {
|
|
const numberFormatOptions = getNumberFormatOptions({});
|
|
return getAdaptiveDisplayAmountRate(amount1, amount2, fromExchangeRate, toExchangeRate, numberFormatOptions);
|
|
}
|
|
|
|
function getAmountPrependAndAppendText(currencyCode: string, isPlural: boolean): CurrencyPrependAndAppendText | null {
|
|
const currencyDisplayType = getCurrentCurrencyDisplayType();
|
|
const currencyUnit = getCurrencyUnitName(currencyCode, isPlural);
|
|
const currencyName = getCurrencyName(currencyCode);
|
|
return getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
|
|
}
|
|
|
|
function getCategorizedAccountsWithDisplayBalance(allVisibleAccounts: Account[], showAccountBalance: boolean): CategorizedAccountWithDisplayBalance[] {
|
|
const ret: CategorizedAccountWithDisplayBalance[] = [];
|
|
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
|
const allCategories = AccountCategory.values();
|
|
const categorizedAccounts: Record<number, CategorizedAccount> = getCategorizedAccountsMap(Account.cloneAccounts(allVisibleAccounts));
|
|
|
|
for (let i = 0; i < allCategories.length; i++) {
|
|
const category = allCategories[i];
|
|
|
|
if (!categorizedAccounts[category.type]) {
|
|
continue;
|
|
}
|
|
|
|
const accountCategory = categorizedAccounts[category.type];
|
|
const accountsWithDisplayBalance: AccountWithDisplayBalance[] = [];
|
|
|
|
if (accountCategory.accounts) {
|
|
for (let i = 0; i < accountCategory.accounts.length; i++) {
|
|
const account = accountCategory.accounts[i];
|
|
let accountWithDisplaceBalance: AccountWithDisplayBalance;
|
|
|
|
if (showAccountBalance && account.isAsset) {
|
|
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, getFormattedAmountWithCurrency(account.balance, account.currency));
|
|
} else if (showAccountBalance && account.isLiability) {
|
|
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, getFormattedAmountWithCurrency(-account.balance, account.currency));
|
|
} else {
|
|
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, DISPLAY_HIDDEN_AMOUNT);
|
|
}
|
|
|
|
accountsWithDisplayBalance.push(accountWithDisplaceBalance);
|
|
}
|
|
}
|
|
|
|
let finalTotalBalance = '';
|
|
|
|
if (showAccountBalance) {
|
|
const accountsBalance = getAllFilteredAccountsBalance(categorizedAccounts, account => account.category === accountCategory.category);
|
|
let totalBalance = 0;
|
|
let hasUnCalculatedAmount = false;
|
|
|
|
for (let i = 0; i < accountsBalance.length; i++) {
|
|
if (accountsBalance[i].currency === defaultCurrency) {
|
|
if (accountsBalance[i].isAsset) {
|
|
totalBalance += accountsBalance[i].balance;
|
|
} else if (accountsBalance[i].isLiability) {
|
|
totalBalance -= accountsBalance[i].balance;
|
|
}
|
|
} else {
|
|
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, defaultCurrency);
|
|
|
|
if (!isNumber(balance)) {
|
|
hasUnCalculatedAmount = true;
|
|
continue;
|
|
}
|
|
|
|
if (accountsBalance[i].isAsset) {
|
|
totalBalance += Math.floor(balance);
|
|
} else if (accountsBalance[i].isLiability) {
|
|
totalBalance -= Math.floor(balance);
|
|
}
|
|
}
|
|
}
|
|
|
|
finalTotalBalance = getFormattedAmountWithCurrency(totalBalance, defaultCurrency);
|
|
|
|
if (hasUnCalculatedAmount) {
|
|
finalTotalBalance = finalTotalBalance + INCOMPLETE_AMOUNT_SUFFIX;
|
|
}
|
|
} else {
|
|
finalTotalBalance = DISPLAY_HIDDEN_AMOUNT;
|
|
}
|
|
|
|
const accountCategoryWithDisplayBalance = CategorizedAccountWithDisplayBalance.of(accountCategory, accountsWithDisplayBalance, finalTotalBalance);
|
|
ret.push(accountCategoryWithDisplayBalance);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function setLanguage(languageKey: string | null, force?: boolean): LocaleDefaultSettings | null {
|
|
if (!languageKey) {
|
|
languageKey = getDefaultLanguage();
|
|
logger.info(`No specified language, use browser default language ${languageKey}`);
|
|
}
|
|
|
|
const languageInfo = getLanguageInfo(languageKey);
|
|
|
|
if (!languageInfo) {
|
|
languageKey = getDefaultLanguage();
|
|
logger.warn(`Not found language ${languageKey}, use browser default language ${languageKey}`);
|
|
}
|
|
|
|
if (!force && locale.value === languageKey) {
|
|
logger.info(`Current locale is already ${languageKey}`);
|
|
return null;
|
|
}
|
|
|
|
logger.info(`Apply current language to ${languageKey}`);
|
|
|
|
locale.value = languageKey;
|
|
moment.updateLocale(languageKey, {
|
|
months: getAllLongMonthNames(),
|
|
monthsShort: getAllShortMonthNames(),
|
|
weekdays: getAllLongWeekdayNames(),
|
|
weekdaysShort: getAllShortWeekdayNames(),
|
|
weekdaysMin: getAllMinWeekdayNames(),
|
|
meridiem: function (hours) {
|
|
if (isPM(hours)) {
|
|
return t(`datetime.${MeridiemIndicator.PM.name}.content`);
|
|
} else {
|
|
return t(`datetime.${MeridiemIndicator.AM.name}.content`);
|
|
}
|
|
}
|
|
});
|
|
|
|
setSessionCurrentLanguageKey(languageKey);
|
|
services.setLocale(languageKey);
|
|
document.querySelector('html')?.setAttribute('lang', languageKey);
|
|
|
|
if (document.querySelector('html')?.getAttribute('data-dir-mode') === 'static') {
|
|
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
|
if (location.search.includes('rtl')) {
|
|
const url = new URL(window.location.href);
|
|
url.search = '';
|
|
url.hash = '#/';
|
|
window.location.replace(url.toString());
|
|
}
|
|
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
|
|
if (!location.search.includes('rtl')) {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.set('rtl', '');
|
|
url.hash = '#/';
|
|
window.location.replace(url.toString());
|
|
}
|
|
}
|
|
} else {
|
|
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
|
document.querySelector('html')?.removeAttribute('dir');
|
|
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
|
|
document.querySelector('html')?.setAttribute('dir', 'rtl');
|
|
}
|
|
}
|
|
|
|
const defaultCurrency = getDefaultCurrency();
|
|
const defaultFirstDayOfWeekName = getDefaultFirstDayOfWeek();
|
|
let defaultFirstDayOfWeek = WeekDay.DefaultFirstDay.type;
|
|
|
|
if (WeekDay.parse(defaultFirstDayOfWeekName)) {
|
|
defaultFirstDayOfWeek = (WeekDay.parse(defaultFirstDayOfWeekName) as WeekDay).type;
|
|
}
|
|
|
|
const localeDefaultSettings: LocaleDefaultSettings = {
|
|
currency: defaultCurrency,
|
|
firstDayOfWeek: defaultFirstDayOfWeek
|
|
};
|
|
|
|
return localeDefaultSettings;
|
|
}
|
|
|
|
function setTimeZone(timezone: string): void {
|
|
let timezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
|
|
|
if (timezone) {
|
|
timezoneOffsetMinutes = getTimezoneOffsetMinutes(timezone);
|
|
}
|
|
|
|
moment.tz.add(moment.tz.pack({
|
|
name: 'Fixed/Timezone',
|
|
abbrs: ['FIX'],
|
|
offsets: [-timezoneOffsetMinutes],
|
|
untils: [0]
|
|
}));
|
|
moment.tz.setDefault('Fixed/Timezone');
|
|
}
|
|
|
|
function initLocale(lastUserLanguage?: string, timezone?: string): LocaleDefaultSettings | null {
|
|
const sessionLanguageKey: string = getSessionCurrentLanguageKey();
|
|
let localeDefaultSettings: LocaleDefaultSettings | null = null;
|
|
|
|
if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
|
|
logger.info(`Last user language is ${lastUserLanguage}`);
|
|
localeDefaultSettings = setLanguage(lastUserLanguage, true);
|
|
} else if (sessionLanguageKey && getLanguageInfo(sessionLanguageKey)) {
|
|
logger.info(`Session language is ${sessionLanguageKey}`);
|
|
localeDefaultSettings = setLanguage(sessionLanguageKey, true);
|
|
} else {
|
|
localeDefaultSettings = setLanguage(null, true);
|
|
}
|
|
|
|
if (timezone) {
|
|
logger.info(`Current timezone is ${timezone}`);
|
|
setTimeZone(timezone);
|
|
} else {
|
|
logger.info(`No timezone is set, use browser default ${getTimezoneOffset()} (maybe ${moment.tz.guess(true)})`);
|
|
setTimeZone('');
|
|
}
|
|
|
|
return localeDefaultSettings;
|
|
}
|
|
|
|
return {
|
|
// common functions
|
|
tt: t,
|
|
ti: translateIf,
|
|
te: translateError,
|
|
joinMultiText,
|
|
getServerTipContent,
|
|
// get current language info
|
|
getCurrentLanguageTag,
|
|
getCurrentLanguageInfo,
|
|
getCurrentLanguageDisplayName,
|
|
getCurrentLanguageTextDirection,
|
|
// get localization default type
|
|
getDefaultCurrency,
|
|
getDefaultFirstDayOfWeek,
|
|
// get all localized info of specified type
|
|
getAllLanguageOptions,
|
|
getAllEnableDisableOptions,
|
|
getAllCurrencies,
|
|
getAllMeridiemIndicators,
|
|
getAllLongMonthNames,
|
|
getAllShortMonthNames,
|
|
getAllLongWeekdayNames,
|
|
getAllShortWeekdayNames,
|
|
getAllMinWeekdayNames,
|
|
getAllWeekDays,
|
|
getAllCalendarDisplayTypes: () => getAllLocalizedCalendarTypes(CalendarDisplayType.values(), CalendarDisplayType.parse(t('default.calendarDisplayType')), CalendarDisplayType.Default, CalendarDisplayType.LanguageDefaultType),
|
|
getAllDateDisplayTypes: () => getAllLocalizedCalendarTypes(DateDisplayType.values(), DateDisplayType.parse(t('default.dateDisplayType')), DateDisplayType.Default, DateDisplayType.LanguageDefaultType),
|
|
getAllLongDateFormats: (calendarType?: CalendarType) => getLocalizedDateTimeFormats<LongDateFormat>('longDate', LongDateFormat.all(), LongDateFormat.values(), 'longDateFormat', LongDateFormat.Default, calendarType),
|
|
getAllShortDateFormats: (calendarType?: CalendarType) => getLocalizedDateTimeFormats<ShortDateFormat>('shortDate', ShortDateFormat.all(), ShortDateFormat.values(), 'shortDateFormat', ShortDateFormat.Default, calendarType),
|
|
getAllLongTimeFormats: (calendarType?: CalendarType) => getLocalizedDateTimeFormats<LongTimeFormat>('longTime', LongTimeFormat.all(), LongTimeFormat.values(), 'longTimeFormat', LongTimeFormat.Default, calendarType),
|
|
getAllShortTimeFormats: (calendarType?: CalendarType) => getLocalizedDateTimeFormats<ShortTimeFormat>('shortTime', ShortTimeFormat.all(), ShortTimeFormat.values(), 'shortTimeFormat', ShortTimeFormat.Default, calendarType),
|
|
getAllFiscalYearFormats,
|
|
getAllDateRanges,
|
|
getAllRecentMonthDateRanges,
|
|
getAllTimezones,
|
|
getAllTimezoneTypesUsedForStatistics,
|
|
getAllNumeralSystemTypes,
|
|
getAllDecimalSeparators: () => getLocalizedNumeralSeparatorFormats(DecimalSeparator.values(), DecimalSeparator.parse(t('default.decimalSeparator')), DecimalSeparator.Default, DecimalSeparator.LanguageDefaultType),
|
|
getAllDigitGroupingSymbols: () => getLocalizedNumeralSeparatorFormats(DigitGroupingSymbol.values(), DigitGroupingSymbol.parse(t('default.digitGroupingSymbol')), DigitGroupingSymbol.Default, DigitGroupingSymbol.LanguageDefaultType),
|
|
getAllDigitGroupingTypes,
|
|
getAllCurrencyDisplayTypes,
|
|
getAllCurrencySortingTypes: () => getLocalizedDisplayNameAndType(CurrencySortingType.values()),
|
|
getAllCoordinateDisplayTypes: () => getLocalizedDisplayNameAndTypeWithSystemDefault(CoordinateDisplayType.values(), CoordinateDisplayType.SystemDefaultType, CoordinateDisplayType.Default),
|
|
getAllExpenseAmountColors: () => getAllExpenseIncomeAmountColors(CategoryType.Expense),
|
|
getAllIncomeAmountColors: () => getAllExpenseIncomeAmountColors(CategoryType.Income),
|
|
getAllAccountCategories,
|
|
getAllAccountTypes: () => getLocalizedDisplayNameAndType(AccountType.values()),
|
|
getAllCategoricalChartTypes: () => getLocalizedDisplayNameAndType(CategoricalChartType.values()),
|
|
getAllTrendChartTypes: () => getLocalizedDisplayNameAndType(TrendChartType.values()),
|
|
getAllAccountBalanceTrendChartTypes: () => getLocalizedDisplayNameAndType(AccountBalanceTrendChartType.values()),
|
|
getAllStatisticsChartDataTypes: (analysisType: StatisticsAnalysisType) => getLocalizedDisplayNameAndType(ChartDataType.values(analysisType)),
|
|
getAllStatisticsSortingTypes: () => getLocalizedDisplayNameAndType(ChartSortingType.values()),
|
|
getAllStatisticsDateAggregationTypes: () => getLocalizedChartDateAggregationTypeAndDisplayName(true),
|
|
getAllStatisticsDateAggregationTypesWithShortName: () => getLocalizedChartDateAggregationTypeAndDisplayName(false),
|
|
getAllTransactionEditScopeTypes: () => getLocalizedDisplayNameAndType(TransactionEditScopeType.values()),
|
|
getAllTransactionTagFilterTypes: () => getLocalizedDisplayNameAndType(TransactionTagFilterType.values()),
|
|
getAllTransactionScheduledFrequencyTypes: () => getLocalizedDisplayNameAndType(ScheduledTemplateFrequencyType.values()),
|
|
getAllImportTransactionColumnTypes: () => getLocalizedDisplayNameAndType(ImportTransactionColumnType.values()),
|
|
getAllTransactionDefaultCategories,
|
|
getAllDisplayExchangeRates,
|
|
getAllSupportedImportFileCagtegoryAndTypes,
|
|
// get localized info
|
|
getLanguageInfo,
|
|
getMonthShortName,
|
|
getMonthLongName,
|
|
getMonthdayOrdinal,
|
|
getMonthdayShortName,
|
|
getWeekdayShortName,
|
|
getWeekdayLongName,
|
|
getMultiMonthdayShortNames,
|
|
getMultiWeekdayLongNames,
|
|
getAllLocalizedDigits,
|
|
getCurrentCalendarDisplayType,
|
|
getCurrentDateDisplayType,
|
|
getCurrentNumeralSystemType,
|
|
getCurrentDecimalSeparator,
|
|
getCurrentDigitGroupingSymbol,
|
|
getCurrentDigitGroupingType,
|
|
getCurrentFiscalYearFormatType,
|
|
getCurrencyName,
|
|
isLongDateMonthAfterYear,
|
|
isShortDateMonthAfterYear,
|
|
isLongTime24HourFormat,
|
|
isLongTimeMeridiemIndicatorFirst,
|
|
isShortTime24HourFormat,
|
|
isShortTimeMeridiemIndicatorFirst,
|
|
isLongTimeHourTwoDigits,
|
|
isLongTimeMinuteTwoDigits,
|
|
isLongTimeSecondTwoDigits,
|
|
// format functions
|
|
formatUnixTimeToDefaultDateTimeWithoutLocaleOptions: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, KnownDateTimeFormat.DefaultDateTime.format, getDateTimeFormatOptions({ calendarType: CalendarType.Gregorian, numeralSystem: NumeralSystem.WesternArabicNumerals }), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongDateTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongDateFormat() + ' ' + getLocalizedLongTimeFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortDateTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortDateFormat() + ' ' + getLocalizedShortTimeFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongDate: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongDateFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortDate: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortDateFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongYear: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongYearFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortYear: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortYearFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongMonth: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, 'MMMM', getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortMonth: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, 'MMM', getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongYearMonth: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongYearMonthFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortYearMonth: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortYearMonthFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongMonthDay: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongMonthDayFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortMonthDay: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortMonthDayFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToLongTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedLongTimeFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToShortTime: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortTimeFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatUnixTimeToDayOfMonth: (unixTime: number, utcOffset?: number, currentUtcOffset?: number) => formatUnixTime(unixTime, getLocalizedShortDayFormat(), getDateTimeFormatOptions(), utcOffset, currentUtcOffset),
|
|
formatGregorianCalendarYearDashMonthDashDayToLongDate,
|
|
formatGregorianCalendarMonthDashDayToLongMonthDay,
|
|
formatUnixTimeToYearQuarter,
|
|
formatYearQuarter,
|
|
formatDateRange,
|
|
formatFiscalYearStartToLongDay,
|
|
formatTimeRangeToFiscalYearFormat,
|
|
formatUnixTimeToFiscalYear,
|
|
formatYearToFiscalYear,
|
|
getTimezoneDifferenceDisplayText,
|
|
parseAmountFromLocalizedNumerals: (value: string) => getParsedAmountNumber(value),
|
|
parseAmountFromWesternArabicNumerals: (value: string) => getParsedAmountNumber(value, NumeralSystem.WesternArabicNumerals),
|
|
formatAmountToLocalizedNumerals: (value: number, currencyCode?: string) => getFormattedAmount(value, undefined, undefined, currencyCode),
|
|
formatAmountToWesternArabicNumerals: (value: number, currencyCode?: string) => getFormattedAmount(value, NumeralSystem.WesternArabicNumerals, undefined, currencyCode),
|
|
formatAmountToLocalizedNumeralsWithoutDigitGrouping: (value: number, currencyCode?: string) => getFormattedAmount(value, undefined, DigitGroupingType.None, currencyCode),
|
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping: (value: number, currencyCode?: string) => getFormattedAmount(value, NumeralSystem.WesternArabicNumerals, DigitGroupingType.None, currencyCode),
|
|
formatAmountToLocalizedNumeralsWithCurrency: (value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType) => getFormattedAmountWithCurrency(value, currencyCode, currencyDisplayType),
|
|
formatAmountToWesternArabicNumeralsWithCurrency: (value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType) => getFormattedAmountWithCurrency(value, currencyCode, currencyDisplayType, NumeralSystem.WesternArabicNumerals),
|
|
formatNumberToLocalizedNumerals: (value: number, precision?: number) => getFormattedNumber(value, undefined, precision),
|
|
formatNumberToWesternArabicNumerals: (value: number, precision?: number) => getFormattedNumber(value, NumeralSystem.WesternArabicNumerals, precision),
|
|
formatPercentToLocalizedNumerals: (value: number, precision: number, lowPrecisionValue: string) => getFormattedPercentValue(value, precision, lowPrecisionValue),
|
|
formatPercentToWesternArabicNumerals: (value: number, precision: number, lowPrecisionValue: string) => getFormattedPercentValue(value, precision, lowPrecisionValue, NumeralSystem.WesternArabicNumerals),
|
|
formatExchangeRateAmountToWesternArabicNumerals: (value: number) => getFormattedExchangeRateAmount(value, NumeralSystem.WesternArabicNumerals),
|
|
appendDigitGroupingSymbolAndDecimalSeparator: (value: string) => appendDigitGroupingSymbolAndDecimalSeparator(value, getNumberFormatOptions({})),
|
|
getAdaptiveAmountRate,
|
|
getAmountPrependAndAppendText,
|
|
getCategorizedAccountsWithDisplayBalance,
|
|
// localization setting functions
|
|
setLanguage,
|
|
setTimeZone,
|
|
initLocale
|
|
};
|
|
}
|