mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 01:04:25 +08:00
support filtering transactions by time zone minute offset, day of week, day of month, month of year and transaction hour in insights explorer
This commit is contained in:
@@ -600,3 +600,6 @@ export const ALL_TIMEZONES: TimezoneInfo[] = [
|
|||||||
timezoneName: 'Pacific/Kiritimati'
|
timezoneName: 'Pacific/Kiritimati'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const WESTERNMOST_TIMEZONE_UTC_OFFSET: number = -720; // Etc/GMT+12 (UTC-12:00)
|
||||||
|
export const EASTERNMOST_TIMEZONE_UTC_OFFSET: number = 840; // Pacific/Kiritimati (UTC+14:00)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export interface DateTime {
|
|||||||
isLocalizedCalendarFirstDayOfMonth(options: DateTimeFormatOptions): boolean;
|
isLocalizedCalendarFirstDayOfMonth(options: DateTimeFormatOptions): boolean;
|
||||||
getGregorianCalendarYearDashMonthDashDay(): TextualYearMonthDay;
|
getGregorianCalendarYearDashMonthDashDay(): TextualYearMonthDay;
|
||||||
getGregorianCalendarYearDashMonth(): TextualYearMonth;
|
getGregorianCalendarYearDashMonth(): TextualYearMonth;
|
||||||
|
getMaxDayOfGregorianCalendarMonth(): number;
|
||||||
getWeekDay(): WeekDay;
|
getWeekDay(): WeekDay;
|
||||||
getWeekDayDisplayName(options: DateTimeFormatOptions): string
|
getWeekDayDisplayName(options: DateTimeFormatOptions): string
|
||||||
getWeekDayDisplayShortName(options: DateTimeFormatOptions): string;
|
getWeekDayDisplayShortName(options: DateTimeFormatOptions): string;
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ export const TransactionExplorerConditionRelationPriority: Record<TransactionExp
|
|||||||
|
|
||||||
export enum TransactionExplorerConditionFieldType {
|
export enum TransactionExplorerConditionFieldType {
|
||||||
Undefined = 'undefined',
|
Undefined = 'undefined',
|
||||||
|
TransactionTimeDayOfWeek = 'transactionTimeDayOfWeek',
|
||||||
|
TransactionTimeDayOfMonth = 'transactionTimeDayOfMonth',
|
||||||
|
TransactionTimeMonthOfYear = 'transactionTimeMonthOfYear',
|
||||||
|
TransactionTimeHourOfDay = 'transactionTimeHourOfDay',
|
||||||
|
TransactionTimezone = 'transactionTimezone',
|
||||||
TransactionType = 'transactionType',
|
TransactionType = 'transactionType',
|
||||||
TransactionCategory = 'transactionCategory',
|
TransactionCategory = 'transactionCategory',
|
||||||
SourceAccount = 'sourceAccount',
|
SourceAccount = 'sourceAccount',
|
||||||
@@ -41,6 +46,11 @@ export class TransactionExplorerConditionField implements NameValue {
|
|||||||
private static readonly allInstances: TransactionExplorerConditionField[] = [];
|
private static readonly allInstances: TransactionExplorerConditionField[] = [];
|
||||||
private static readonly allInstancesByValue: Record<string, TransactionExplorerConditionField> = {};
|
private static readonly allInstancesByValue: Record<string, TransactionExplorerConditionField> = {};
|
||||||
|
|
||||||
|
public static readonly TransactionTimeDayOfWeek = new TransactionExplorerConditionField('Transaction Day of Week', TransactionExplorerConditionFieldType.TransactionTimeDayOfWeek);
|
||||||
|
public static readonly TransactionTimeDayOfMonth = new TransactionExplorerConditionField('Transaction Day of Month', TransactionExplorerConditionFieldType.TransactionTimeDayOfMonth)
|
||||||
|
public static readonly TransactionTimeMonthOfYear = new TransactionExplorerConditionField('Transaction Month of Year', TransactionExplorerConditionFieldType.TransactionTimeMonthOfYear);
|
||||||
|
public static readonly TransactionTimeHourOfDay = new TransactionExplorerConditionField('Transaction Hour of Day', TransactionExplorerConditionFieldType.TransactionTimeHourOfDay);
|
||||||
|
public static readonly TransactionTimezone = new TransactionExplorerConditionField('Transaction Timezone', TransactionExplorerConditionFieldType.TransactionTimezone);
|
||||||
public static readonly TransactionType = new TransactionExplorerConditionField('Transaction Type', TransactionExplorerConditionFieldType.TransactionType);
|
public static readonly TransactionType = new TransactionExplorerConditionField('Transaction Type', TransactionExplorerConditionFieldType.TransactionType);
|
||||||
public static readonly TransactionCategory = new TransactionExplorerConditionField('Category', TransactionExplorerConditionFieldType.TransactionCategory);
|
public static readonly TransactionCategory = new TransactionExplorerConditionField('Category', TransactionExplorerConditionFieldType.TransactionCategory);
|
||||||
public static readonly SourceAccount = new TransactionExplorerConditionField('Source Account', TransactionExplorerConditionFieldType.SourceAccount);
|
public static readonly SourceAccount = new TransactionExplorerConditionField('Source Account', TransactionExplorerConditionFieldType.SourceAccount);
|
||||||
@@ -95,6 +105,8 @@ export enum TransactionExplorerConditionOperatorType {
|
|||||||
NotEndsWith = 'notEndsWith',
|
NotEndsWith = 'notEndsWith',
|
||||||
RegexMatch = 'regexMatch',
|
RegexMatch = 'regexMatch',
|
||||||
NotRegexMatch = 'notRegexMatch',
|
NotRegexMatch = 'notRegexMatch',
|
||||||
|
MinuteOffsetBetween = 'minuteOffsetBetween',
|
||||||
|
MinuteOffsetNotBetween = 'minuteOffsetNotBetween',
|
||||||
LatitudeBetween = 'latitudeBetween',
|
LatitudeBetween = 'latitudeBetween',
|
||||||
LatitudeNotBetween = 'latitudeNotBetween',
|
LatitudeNotBetween = 'latitudeNotBetween',
|
||||||
LongitudeBetween = 'longitudeBetween',
|
LongitudeBetween = 'longitudeBetween',
|
||||||
@@ -127,6 +139,8 @@ export class TransactionExplorerConditionOperator implements NameValue {
|
|||||||
public static readonly NotEndsWith = new TransactionExplorerConditionOperator('Does not end with', TransactionExplorerConditionOperatorType.NotEndsWith);
|
public static readonly NotEndsWith = new TransactionExplorerConditionOperator('Does not end with', TransactionExplorerConditionOperatorType.NotEndsWith);
|
||||||
public static readonly RegexMatch = new TransactionExplorerConditionOperator('Matches regex', TransactionExplorerConditionOperatorType.RegexMatch);
|
public static readonly RegexMatch = new TransactionExplorerConditionOperator('Matches regex', TransactionExplorerConditionOperatorType.RegexMatch);
|
||||||
public static readonly NotRegexMatch = new TransactionExplorerConditionOperator('Does not match regex', TransactionExplorerConditionOperatorType.NotRegexMatch);
|
public static readonly NotRegexMatch = new TransactionExplorerConditionOperator('Does not match regex', TransactionExplorerConditionOperatorType.NotRegexMatch);
|
||||||
|
public static readonly MinuteOffsetBetween = new TransactionExplorerConditionOperator('Minute offset is between', TransactionExplorerConditionOperatorType.MinuteOffsetBetween);
|
||||||
|
public static readonly MinuteOffsetNotBetween = new TransactionExplorerConditionOperator('Minute offset is not between', TransactionExplorerConditionOperatorType.MinuteOffsetNotBetween);
|
||||||
public static readonly LatitudeBetween = new TransactionExplorerConditionOperator('Latitude is between', TransactionExplorerConditionOperatorType.LatitudeBetween);
|
public static readonly LatitudeBetween = new TransactionExplorerConditionOperator('Latitude is between', TransactionExplorerConditionOperatorType.LatitudeBetween);
|
||||||
public static readonly LatitudeNotBetween = new TransactionExplorerConditionOperator('Latitude is not between', TransactionExplorerConditionOperatorType.LatitudeNotBetween);
|
public static readonly LatitudeNotBetween = new TransactionExplorerConditionOperator('Latitude is not between', TransactionExplorerConditionOperatorType.LatitudeNotBetween);
|
||||||
public static readonly LongitudeBetween = new TransactionExplorerConditionOperator('Longitude is between', TransactionExplorerConditionOperatorType.LongitudeBetween);
|
public static readonly LongitudeBetween = new TransactionExplorerConditionOperator('Longitude is between', TransactionExplorerConditionOperatorType.LongitudeBetween);
|
||||||
|
|||||||
+10
-4
@@ -51,6 +51,11 @@ import {
|
|||||||
NumeralSystem
|
NumeralSystem
|
||||||
} from '@/core/numeral.ts';
|
} from '@/core/numeral.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
WESTERNMOST_TIMEZONE_UTC_OFFSET,
|
||||||
|
EASTERNMOST_TIMEZONE_UTC_OFFSET,
|
||||||
|
} from '@/consts/timezone.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isFunction,
|
isFunction,
|
||||||
isDefined,
|
isDefined,
|
||||||
@@ -74,15 +79,12 @@ interface DateTimeFormatResult {
|
|||||||
|
|
||||||
type DateTimeTokenFormatFunction = (d: MomentDateTime, options: DateTimeFormatOptions) => DateTimeFormatResult;
|
type DateTimeTokenFormatFunction = (d: MomentDateTime, options: DateTimeFormatOptions) => DateTimeFormatResult;
|
||||||
|
|
||||||
const westernmostTimezoneUtcOffset: number = -720; // Etc/GMT+12 (UTC-12:00)
|
|
||||||
const easternmostTimezoneUtcOffset: number = 840; // Pacific/Kiritimati (UTC+14:00)
|
|
||||||
|
|
||||||
function getFixedTimezoneName(utcOffset: number): string {
|
function getFixedTimezoneName(utcOffset: number): string {
|
||||||
return `Fixed/Timezone${utcOffset}`;
|
return `Fixed/Timezone${utcOffset}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
(function initFixedTimezone(): void {
|
(function initFixedTimezone(): void {
|
||||||
for (let utcOffset = westernmostTimezoneUtcOffset; utcOffset <= easternmostTimezoneUtcOffset; utcOffset += 15) {
|
for (let utcOffset = WESTERNMOST_TIMEZONE_UTC_OFFSET; utcOffset <= EASTERNMOST_TIMEZONE_UTC_OFFSET; utcOffset += 15) {
|
||||||
const timezoneName = getFixedTimezoneName(utcOffset);
|
const timezoneName = getFixedTimezoneName(utcOffset);
|
||||||
|
|
||||||
if (moment.tz.zone(timezoneName)) {
|
if (moment.tz.zone(timezoneName)) {
|
||||||
@@ -254,6 +256,10 @@ class MomentDateTime implements DateTime {
|
|||||||
return (this.instance.year() + '-' + (this.instance.month() + 1).toString().padStart(2, NumeralSystem.WesternArabicNumerals.digitZero)) as TextualYearMonth;
|
return (this.instance.year() + '-' + (this.instance.month() + 1).toString().padStart(2, NumeralSystem.WesternArabicNumerals.digitZero)) as TextualYearMonth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMaxDayOfGregorianCalendarMonth(): number {
|
||||||
|
return this.instance.clone().endOf('month').date();
|
||||||
|
}
|
||||||
|
|
||||||
public getWeekDay(): WeekDay {
|
public getWeekDay(): WeekDay {
|
||||||
return WeekDay.valueOf(this.instance.day()) as WeekDay;
|
return WeekDay.valueOf(this.instance.day()) as WeekDay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} Stunde(n) und {minutes} Minute(n) hinter der Standardzeitzone",
|
"hoursMinutesBehindDefaultTimezone": "{hours} Stunde(n) und {minutes} Minute(n) hinter der Standardzeitzone",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} Stunde(n) und {minutes} Minute(n) vor der Standardzeitzone",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} Stunde(n) und {minutes} Minute(n) vor der Standardzeitzone",
|
||||||
"monthDay": "{ordinal} Tag",
|
"monthDay": "{ordinal} Tag",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} Tage",
|
"monthDays": "{multiMonthDays} Tage",
|
||||||
"everyMultiDaysOfWeek": "Jeden {days}",
|
"everyMultiDaysOfWeek": "Jeden {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Letzte 5 Jahre",
|
"Recent 5 years": "Letzte 5 Jahre",
|
||||||
"Previous Billing Cycle": "Vorheriger Abrechnungszeitraum",
|
"Previous Billing Cycle": "Vorheriger Abrechnungszeitraum",
|
||||||
"Current Billing Cycle": "Aktueller Abrechnungszeitraum",
|
"Current Billing Cycle": "Aktueller Abrechnungszeitraum",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Benutzerdefiniertes Datum",
|
"Custom Date": "Benutzerdefiniertes Datum",
|
||||||
"Start Date": "Startdatum",
|
"Start Date": "Startdatum",
|
||||||
"End Date": "Enddatum",
|
"End Date": "Enddatum",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Endet nicht mit",
|
"Does not end with": "Endet nicht mit",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Breitengrad zwischen",
|
"Latitude is between": "Breitengrad zwischen",
|
||||||
"Latitude is not between": "Breitengrad nicht zwischen",
|
"Latitude is not between": "Breitengrad nicht zwischen",
|
||||||
"Longitude is between": "Längengrad zwischen",
|
"Longitude is between": "Längengrad zwischen",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} hour(s) and {minutes} minutes behind default timezone",
|
"hoursMinutesBehindDefaultTimezone": "{hours} hour(s) and {minutes} minutes behind default timezone",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} hour(s) and {minutes} minutes ahead of default timezone",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} hour(s) and {minutes} minutes ahead of default timezone",
|
||||||
"monthDay": "{ordinal} day",
|
"monthDay": "{ordinal} day",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} days",
|
"monthDays": "{multiMonthDays} days",
|
||||||
"everyMultiDaysOfWeek": "Every {days}",
|
"everyMultiDaysOfWeek": "Every {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Recent 5 years",
|
"Recent 5 years": "Recent 5 years",
|
||||||
"Previous Billing Cycle": "Previous Billing Cycle",
|
"Previous Billing Cycle": "Previous Billing Cycle",
|
||||||
"Current Billing Cycle": "Current Billing Cycle",
|
"Current Billing Cycle": "Current Billing Cycle",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Custom Date",
|
"Custom Date": "Custom Date",
|
||||||
"Start Date": "Start Date",
|
"Start Date": "Start Date",
|
||||||
"End Date": "End Date",
|
"End Date": "End Date",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} hora(s) y {minutes} minutos de retraso en la zona horaria predeterminada",
|
"hoursMinutesBehindDefaultTimezone": "{hours} hora(s) y {minutes} minutos de retraso en la zona horaria predeterminada",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} hora(s) y {minutes} minutos antes de la zona horaria predeterminada",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} hora(s) y {minutes} minutos antes de la zona horaria predeterminada",
|
||||||
"monthDay": "día {ordinal}",
|
"monthDay": "día {ordinal}",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} días",
|
"monthDays": "{multiMonthDays} días",
|
||||||
"everyMultiDaysOfWeek": "Cada {days}",
|
"everyMultiDaysOfWeek": "Cada {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Últimos 5 años",
|
"Recent 5 years": "Últimos 5 años",
|
||||||
"Previous Billing Cycle": "Ciclo de facturación anterior",
|
"Previous Billing Cycle": "Ciclo de facturación anterior",
|
||||||
"Current Billing Cycle": "Ciclo de facturación actual",
|
"Current Billing Cycle": "Ciclo de facturación actual",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Fecha personalizada",
|
"Custom Date": "Fecha personalizada",
|
||||||
"Start Date": "Fecha de Inicio",
|
"Start Date": "Fecha de Inicio",
|
||||||
"End Date": "Fecha de Finalización",
|
"End Date": "Fecha de Finalización",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "No termina en",
|
"Does not end with": "No termina en",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} heure(s) et {minutes} minutes de retard sur le fuseau horaire par défaut",
|
"hoursMinutesBehindDefaultTimezone": "{hours} heure(s) et {minutes} minutes de retard sur le fuseau horaire par défaut",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} heure(s) et {minutes} minutes d'avance sur le fuseau horaire par défaut",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} heure(s) et {minutes} minutes d'avance sur le fuseau horaire par défaut",
|
||||||
"monthDay": "{ordinal}e jour",
|
"monthDay": "{ordinal}e jour",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} jours",
|
"monthDays": "{multiMonthDays} jours",
|
||||||
"everyMultiDaysOfWeek": "Tous les {days}",
|
"everyMultiDaysOfWeek": "Tous les {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "5 dernières années",
|
"Recent 5 years": "5 dernières années",
|
||||||
"Previous Billing Cycle": "Cycle de facturation précédent",
|
"Previous Billing Cycle": "Cycle de facturation précédent",
|
||||||
"Current Billing Cycle": "Cycle de facturation actuel",
|
"Current Billing Cycle": "Cycle de facturation actuel",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Date personnalisée",
|
"Custom Date": "Date personnalisée",
|
||||||
"Start Date": "Date de début",
|
"Start Date": "Date de début",
|
||||||
"End Date": "Date de fin",
|
"End Date": "Date de fin",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ import {
|
|||||||
} from '@/lib/common.ts';
|
} from '@/lib/common.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getCurrentDateTime,
|
||||||
formatCurrentTime,
|
formatCurrentTime,
|
||||||
formatGregorianCalendarYearDashMonthDashDay,
|
formatGregorianCalendarYearDashMonthDashDay,
|
||||||
formatGregorianCalendarMonthDashDay,
|
formatGregorianCalendarMonthDashDay,
|
||||||
@@ -1059,6 +1060,20 @@ export function useI18n() {
|
|||||||
return getAllWeekdayNames('min');
|
return getAllWeekdayNames('min');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllMonths(): TypeAndDisplayName[] {
|
||||||
|
const ret: TypeAndDisplayName[] = [];
|
||||||
|
const allMonths = Month.values();
|
||||||
|
|
||||||
|
for (const month of allMonths) {
|
||||||
|
ret.push({
|
||||||
|
type: month.month,
|
||||||
|
displayName: t(`datetime.${month.name}.long`)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function getAllWeekDays(firstDayOfWeek?: WeekDayValue): TypeAndDisplayName[] {
|
function getAllWeekDays(firstDayOfWeek?: WeekDayValue): TypeAndDisplayName[] {
|
||||||
const ret: TypeAndDisplayName[] = [];
|
const ret: TypeAndDisplayName[] = [];
|
||||||
const allWeekDays = WeekDay.values();
|
const allWeekDays = WeekDay.values();
|
||||||
@@ -1088,6 +1103,51 @@ export function useI18n() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllHours(): TypeAndDisplayName[] {
|
||||||
|
const ret: TypeAndDisplayName[] = [];
|
||||||
|
const now: DateTime = getCurrentDateTime();
|
||||||
|
const format: string = getLocalizedShortTimeFormat();
|
||||||
|
const options: DateTimeFormatOptions = getDateTimeFormatOptions();
|
||||||
|
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
const dateTime = now.set({
|
||||||
|
hour: i,
|
||||||
|
minute: 0,
|
||||||
|
second: 0,
|
||||||
|
millisecond: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
ret.push({
|
||||||
|
type: i,
|
||||||
|
displayName: dateTime.format(format, options)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAvailableMonthDays(daysInMonth: number, lastDaysOfMonth?: number): TypeAndDisplayName[] {
|
||||||
|
const ret: TypeAndDisplayName[] = [];
|
||||||
|
|
||||||
|
for (let i = 1; i <= daysInMonth; i++) {
|
||||||
|
ret.push({
|
||||||
|
type: i,
|
||||||
|
displayName: getMonthdayShortName(i),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNumber(lastDaysOfMonth) && lastDaysOfMonth > 0) {
|
||||||
|
for (let i = -lastDaysOfMonth; i < 0; i++) {
|
||||||
|
ret.push({
|
||||||
|
type: i,
|
||||||
|
displayName: (i === -1) ? t('Last day') : getMonthLastDayShortName(-i),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function getLocalizedDateTimeFormats<T extends DateFormat | TimeFormat>(type: string, allFormatMap: Record<string, T>, allFormatArray: T[], languageDefaultTypeNameKey: string, systemDefaultFormatType: T, numeralSystem: NumeralSystem, calendarType?: CalendarType): LocalizedDateTimeFormat[] {
|
function getLocalizedDateTimeFormats<T extends DateFormat | TimeFormat>(type: string, allFormatMap: Record<string, T>, allFormatArray: T[], languageDefaultTypeNameKey: string, systemDefaultFormatType: T, numeralSystem: NumeralSystem, calendarType?: CalendarType): LocalizedDateTimeFormat[] {
|
||||||
const defaultFormat = getLocalizedDateTimeFormat<T>(type, allFormatMap, allFormatArray, LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE, languageDefaultTypeNameKey, systemDefaultFormatType);
|
const defaultFormat = getLocalizedDateTimeFormat<T>(type, allFormatMap, allFormatArray, LANGUAGE_DEFAULT_DATE_TIME_FORMAT_VALUE, languageDefaultTypeNameKey, systemDefaultFormatType);
|
||||||
const ret: LocalizedDateTimeFormat[] = [];
|
const ret: LocalizedDateTimeFormat[] = [];
|
||||||
@@ -1606,6 +1666,12 @@ export function useI18n() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMonthLastDayShortName(ordinal: number): string {
|
||||||
|
return t('format.misc.lastMonthDay', {
|
||||||
|
ordinal: getMonthdayOrdinal(ordinal)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getWeekdayShortName(weekDay: WeekDay): string {
|
function getWeekdayShortName(weekDay: WeekDay): string {
|
||||||
return t(`datetime.${weekDay.name}.short`);
|
return t(`datetime.${weekDay.name}.short`);
|
||||||
}
|
}
|
||||||
@@ -2411,7 +2477,10 @@ export function useI18n() {
|
|||||||
getAllLongWeekdayNames,
|
getAllLongWeekdayNames,
|
||||||
getAllShortWeekdayNames,
|
getAllShortWeekdayNames,
|
||||||
getAllMinWeekdayNames,
|
getAllMinWeekdayNames,
|
||||||
|
getAllMonths,
|
||||||
getAllWeekDays,
|
getAllWeekDays,
|
||||||
|
getAllHours,
|
||||||
|
getAvailableMonthDays,
|
||||||
getAllCalendarDisplayTypes: () => getAllLocalizedCalendarTypes(CalendarDisplayType.values(), CalendarDisplayType.parse(t('default.calendarDisplayType')), CalendarDisplayType.Default, CalendarDisplayType.LanguageDefaultType),
|
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),
|
getAllDateDisplayTypes: () => getAllLocalizedCalendarTypes(DateDisplayType.values(), DateDisplayType.parse(t('default.dateDisplayType')), DateDisplayType.Default, DateDisplayType.LanguageDefaultType),
|
||||||
getAllLongDateFormats: (numeralSystem: NumeralSystem, calendarType: CalendarType) => getLocalizedDateTimeFormats<LongDateFormat>('longDate', LongDateFormat.all(), LongDateFormat.values(), 'longDateFormat', LongDateFormat.Default, numeralSystem, calendarType),
|
getAllLongDateFormats: (numeralSystem: NumeralSystem, calendarType: CalendarType) => getLocalizedDateTimeFormats<LongDateFormat>('longDate', LongDateFormat.all(), LongDateFormat.values(), 'longDateFormat', LongDateFormat.Default, numeralSystem, calendarType),
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "Indietro di {hours} ore e {minutes} minuti rispetto al fuso orario standard",
|
"hoursMinutesBehindDefaultTimezone": "Indietro di {hours} ore e {minutes} minuti rispetto al fuso orario standard",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "Avanti di {hours} ore e {minutes} minuti rispetto al fuso orario standard",
|
"hoursMinutesAheadOfDefaultTimezone": "Avanti di {hours} ore e {minutes} minuti rispetto al fuso orario standard",
|
||||||
"monthDay": "{ordinal} giorno",
|
"monthDay": "{ordinal} giorno",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} giorni",
|
"monthDays": "{multiMonthDays} giorni",
|
||||||
"everyMultiDaysOfWeek": "Ogni {days}",
|
"everyMultiDaysOfWeek": "Ogni {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Ultimi 5 anni",
|
"Recent 5 years": "Ultimi 5 anni",
|
||||||
"Previous Billing Cycle": "Ciclo di fatturazione precedente",
|
"Previous Billing Cycle": "Ciclo di fatturazione precedente",
|
||||||
"Current Billing Cycle": "Ciclo di fatturazione corrente",
|
"Current Billing Cycle": "Ciclo di fatturazione corrente",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Data personalizzata",
|
"Custom Date": "Data personalizzata",
|
||||||
"Start Date": "Data di inizio",
|
"Start Date": "Data di inizio",
|
||||||
"End Date": "Data di fine",
|
"End Date": "Data di fine",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "デフォルトのタイムゾーンより{hours}時間{minutes}分遅れています",
|
"hoursMinutesBehindDefaultTimezone": "デフォルトのタイムゾーンより{hours}時間{minutes}分遅れています",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "デフォルトのタイムゾーンから{hours}時間{minutes}分進んでいます",
|
"hoursMinutesAheadOfDefaultTimezone": "デフォルトのタイムゾーンから{hours}時間{minutes}分進んでいます",
|
||||||
"monthDay": "{ordinal}日",
|
"monthDay": "{ordinal}日",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays}日間",
|
"monthDays": "{multiMonthDays}日間",
|
||||||
"everyMultiDaysOfWeek": "毎{days}",
|
"everyMultiDaysOfWeek": "毎{days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "直近5年",
|
"Recent 5 years": "直近5年",
|
||||||
"Previous Billing Cycle": "以前の請求サイクル",
|
"Previous Billing Cycle": "以前の請求サイクル",
|
||||||
"Current Billing Cycle": "現在の請求サイクル",
|
"Current Billing Cycle": "現在の請求サイクル",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "カスタム日付",
|
"Custom Date": "カスタム日付",
|
||||||
"Start Date": "開始日",
|
"Start Date": "開始日",
|
||||||
"End Date": "終了日",
|
"End Date": "終了日",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "ಡೀಫಾಲ್ಟ್ ಸಮಯ ವಲಯಕ್ಕಿಂತ {hours} ಗಂಟೆ ಹಾಗೂ {minutes} ನಿಮಿಷಗಳು ಹಿಂದೆ",
|
"hoursMinutesBehindDefaultTimezone": "ಡೀಫಾಲ್ಟ್ ಸಮಯ ವಲಯಕ್ಕಿಂತ {hours} ಗಂಟೆ ಹಾಗೂ {minutes} ನಿಮಿಷಗಳು ಹಿಂದೆ",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "ಡೀಫಾಲ್ಟ್ ಸಮಯ ವಲಯಕ್ಕಿಂತ {hours} ಗಂಟೆ ಹಾಗೂ {minutes} ನಿಮಿಷಗಳು ಮುಂದೆ",
|
"hoursMinutesAheadOfDefaultTimezone": "ಡೀಫಾಲ್ಟ್ ಸಮಯ ವಲಯಕ್ಕಿಂತ {hours} ಗಂಟೆ ಹಾಗೂ {minutes} ನಿಮಿಷಗಳು ಮುಂದೆ",
|
||||||
"monthDay": "{ordinal} ದಿನ",
|
"monthDay": "{ordinal} ದಿನ",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} ದಿನಗಳು",
|
"monthDays": "{multiMonthDays} ದಿನಗಳು",
|
||||||
"everyMultiDaysOfWeek": "ಪ್ರತಿ {days}",
|
"everyMultiDaysOfWeek": "ಪ್ರತಿ {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "ಇತ್ತೀಚಿನ 5 ವರ್ಷಗಳು",
|
"Recent 5 years": "ಇತ್ತೀಚಿನ 5 ವರ್ಷಗಳು",
|
||||||
"Previous Billing Cycle": "ಹಿಂದಿನ ಬಿಲ್ಲಿಂಗ್ ಚಕ್ರ",
|
"Previous Billing Cycle": "ಹಿಂದಿನ ಬಿಲ್ಲಿಂಗ್ ಚಕ್ರ",
|
||||||
"Current Billing Cycle": "ಪ್ರಸ್ತುತ ಬಿಲ್ಲಿಂಗ್ ಚಕ್ರ",
|
"Current Billing Cycle": "ಪ್ರಸ್ತುತ ಬಿಲ್ಲಿಂಗ್ ಚಕ್ರ",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "ಕಸ್ಟಮ್ ದಿನಾಂಕ",
|
"Custom Date": "ಕಸ್ಟಮ್ ದಿನಾಂಕ",
|
||||||
"Start Date": "ಪ್ರಾರಂಭ ದಿನಾಂಕ",
|
"Start Date": "ಪ್ರಾರಂಭ ದಿನಾಂಕ",
|
||||||
"End Date": "ಅಂತ್ಯ ದಿನಾಂಕ",
|
"End Date": "ಅಂತ್ಯ ದಿನಾಂಕ",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "기본 시간대보다 {hours}시간 {minutes}분 느립니다",
|
"hoursMinutesBehindDefaultTimezone": "기본 시간대보다 {hours}시간 {minutes}분 느립니다",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "기본 시간대보다 {hours}시간 {minutes}분 빠릅니다",
|
"hoursMinutesAheadOfDefaultTimezone": "기본 시간대보다 {hours}시간 {minutes}분 빠릅니다",
|
||||||
"monthDay": "{ordinal}일",
|
"monthDay": "{ordinal}일",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays}일",
|
"monthDays": "{multiMonthDays}일",
|
||||||
"everyMultiDaysOfWeek": "매주 {days}",
|
"everyMultiDaysOfWeek": "매주 {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "최근 5년",
|
"Recent 5 years": "최근 5년",
|
||||||
"Previous Billing Cycle": "이전 청구 주기",
|
"Previous Billing Cycle": "이전 청구 주기",
|
||||||
"Current Billing Cycle": "현재 청구 주기",
|
"Current Billing Cycle": "현재 청구 주기",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "사용자 지정 날짜",
|
"Custom Date": "사용자 지정 날짜",
|
||||||
"Start Date": "시작 날짜",
|
"Start Date": "시작 날짜",
|
||||||
"End Date": "종료 날짜",
|
"End Date": "종료 날짜",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} uur en {minutes} minuten achter standaardtijdzone",
|
"hoursMinutesBehindDefaultTimezone": "{hours} uur en {minutes} minuten achter standaardtijdzone",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} uur en {minutes} minuten voor op standaardtijdzone",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} uur en {minutes} minuten voor op standaardtijdzone",
|
||||||
"monthDay": "{ordinal} dag",
|
"monthDay": "{ordinal} dag",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} dagen",
|
"monthDays": "{multiMonthDays} dagen",
|
||||||
"everyMultiDaysOfWeek": "Elke {days}",
|
"everyMultiDaysOfWeek": "Elke {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Afgelopen 5 jaar",
|
"Recent 5 years": "Afgelopen 5 jaar",
|
||||||
"Previous Billing Cycle": "Vorige factureringsperiode",
|
"Previous Billing Cycle": "Vorige factureringsperiode",
|
||||||
"Current Billing Cycle": "Huidige factureringsperiode",
|
"Current Billing Cycle": "Huidige factureringsperiode",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Aangepaste datum",
|
"Custom Date": "Aangepaste datum",
|
||||||
"Start Date": "Begindatum",
|
"Start Date": "Begindatum",
|
||||||
"End Date": "Einddatum",
|
"End Date": "Einddatum",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} hora(s) e {minutes} minutos atrás do fuso horário padrão",
|
"hoursMinutesBehindDefaultTimezone": "{hours} hora(s) e {minutes} minutos atrás do fuso horário padrão",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} hora(s) e {minutes} minutos à frente do fuso horário padrão",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} hora(s) e {minutes} minutos à frente do fuso horário padrão",
|
||||||
"monthDay": "{ordinal} dia",
|
"monthDay": "{ordinal} dia",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} dias",
|
"monthDays": "{multiMonthDays} dias",
|
||||||
"everyMultiDaysOfWeek": "A cada {days}",
|
"everyMultiDaysOfWeek": "A cada {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Últimos 5 anos",
|
"Recent 5 years": "Últimos 5 anos",
|
||||||
"Previous Billing Cycle": "Ciclo de Cobrança Anterior",
|
"Previous Billing Cycle": "Ciclo de Cobrança Anterior",
|
||||||
"Current Billing Cycle": "Ciclo de Cobrança Atual",
|
"Current Billing Cycle": "Ciclo de Cobrança Atual",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Data Personalizada",
|
"Custom Date": "Data Personalizada",
|
||||||
"Start Date": "Data de Início",
|
"Start Date": "Data de Início",
|
||||||
"End Date": "Data de Término",
|
"End Date": "Data de Término",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Não termina com",
|
"Does not end with": "Não termina com",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude entre",
|
"Latitude is between": "Latitude entre",
|
||||||
"Latitude is not between": "Latitude não entre",
|
"Latitude is not between": "Latitude não entre",
|
||||||
"Longitude is between": "Longitude entre",
|
"Longitude is between": "Longitude entre",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} час(ов) и {minutes} минут позади часового пояса по умолчанию",
|
"hoursMinutesBehindDefaultTimezone": "{hours} час(ов) и {minutes} минут позади часового пояса по умолчанию",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} час(ов) и {minutes} минут впереди часового пояса по умолчанию",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} час(ов) и {minutes} минут впереди часового пояса по умолчанию",
|
||||||
"monthDay": "{ordinal} день",
|
"monthDay": "{ordinal} день",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} дней",
|
"monthDays": "{multiMonthDays} дней",
|
||||||
"everyMultiDaysOfWeek": "Каждые {days}",
|
"everyMultiDaysOfWeek": "Каждые {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Последние 5 лет",
|
"Recent 5 years": "Последние 5 лет",
|
||||||
"Previous Billing Cycle": "Предыдущий расчетный период",
|
"Previous Billing Cycle": "Предыдущий расчетный период",
|
||||||
"Current Billing Cycle": "Текущий расчетный период",
|
"Current Billing Cycle": "Текущий расчетный период",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Выбрать дату",
|
"Custom Date": "Выбрать дату",
|
||||||
"Start Date": "Дата начала",
|
"Start Date": "Дата начала",
|
||||||
"End Date": "Дата конца",
|
"End Date": "Дата конца",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Не заканчивается с",
|
"Does not end with": "Не заканчивается с",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} ura(ur) in {minutes} minut za privzetim časovnim pasom",
|
"hoursMinutesBehindDefaultTimezone": "{hours} ura(ur) in {minutes} minut za privzetim časovnim pasom",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} ura(ur) in {minutes} minut po privzetem časovnem pasu",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} ura(ur) in {minutes} minut po privzetem časovnem pasu",
|
||||||
"monthDay": "{ordinal} dan",
|
"monthDay": "{ordinal} dan",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} dni",
|
"monthDays": "{multiMonthDays} dni",
|
||||||
"everyMultiDaysOfWeek": "Vsak {days}",
|
"everyMultiDaysOfWeek": "Vsak {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Zadnjih 5 let",
|
"Recent 5 years": "Zadnjih 5 let",
|
||||||
"Previous Billing Cycle": "Prejšnje obračunsko obdobje",
|
"Previous Billing Cycle": "Prejšnje obračunsko obdobje",
|
||||||
"Current Billing Cycle": "Trenutno obračunsko obdobje",
|
"Current Billing Cycle": "Trenutno obračunsko obdobje",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Datum po meri",
|
"Custom Date": "Datum po meri",
|
||||||
"Start Date": "Datum začetka",
|
"Start Date": "Datum začetka",
|
||||||
"End Date": "Datum konca",
|
"End Date": "Datum konca",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Se ne konča z",
|
"Does not end with": "Se ne konča z",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "இயல்பு நேர மண்டலத்தை விட {hours} மணி நேரம் {minutes} நிமிடங்கள் பின்னால்",
|
"hoursMinutesBehindDefaultTimezone": "இயல்பு நேர மண்டலத்தை விட {hours} மணி நேரம் {minutes} நிமிடங்கள் பின்னால்",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "இயல்பு நேர மண்டலத்தை விட {hours} மணி நேரம் {minutes} நிமிடங்கள் முன்னால்",
|
"hoursMinutesAheadOfDefaultTimezone": "இயல்பு நேர மண்டலத்தை விட {hours} மணி நேரம் {minutes} நிமிடங்கள் முன்னால்",
|
||||||
"monthDay": "{ordinal} நாள்",
|
"monthDay": "{ordinal} நாள்",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} நாட்கள்",
|
"monthDays": "{multiMonthDays} நாட்கள்",
|
||||||
"everyMultiDaysOfWeek": "ஒவ்வொரு {days}",
|
"everyMultiDaysOfWeek": "ஒவ்வொரு {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "சமீபத்திய 5 ஆண்டுகள்",
|
"Recent 5 years": "சமீபத்திய 5 ஆண்டுகள்",
|
||||||
"Previous Billing Cycle": "முந்தைய பில்லிங் சுழற்சி",
|
"Previous Billing Cycle": "முந்தைய பில்லிங் சுழற்சி",
|
||||||
"Current Billing Cycle": "தற்போதைய பில்லிங் சுழற்சி",
|
"Current Billing Cycle": "தற்போதைய பில்லிங் சுழற்சி",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "தனிப்பயன் தேதி",
|
"Custom Date": "தனிப்பயன் தேதி",
|
||||||
"Start Date": "தொடக்கம் தேதி",
|
"Start Date": "தொடக்கம் தேதி",
|
||||||
"End Date": "முடிவு தேதி",
|
"End Date": "முடிவு தேதி",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "முடியவில்லை",
|
"Does not end with": "முடியவில்லை",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "ช้ากว่าเขตเวลาเริ่มต้น {hours} ชั่วโมง {minutes} นาที",
|
"hoursMinutesBehindDefaultTimezone": "ช้ากว่าเขตเวลาเริ่มต้น {hours} ชั่วโมง {minutes} นาที",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "เร็วกว่าเขตเวลาเริ่มต้น {hours} ชั่วโมง {minutes} นาที",
|
"hoursMinutesAheadOfDefaultTimezone": "เร็วกว่าเขตเวลาเริ่มต้น {hours} ชั่วโมง {minutes} นาที",
|
||||||
"monthDay": "วันที่ {ordinal}",
|
"monthDay": "วันที่ {ordinal}",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} วัน",
|
"monthDays": "{multiMonthDays} วัน",
|
||||||
"everyMultiDaysOfWeek": "ทุกๆ {days}",
|
"everyMultiDaysOfWeek": "ทุกๆ {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "5 ปีที่ผ่านมา",
|
"Recent 5 years": "5 ปีที่ผ่านมา",
|
||||||
"Previous Billing Cycle": "รอบบิลก่อนหน้า",
|
"Previous Billing Cycle": "รอบบิลก่อนหน้า",
|
||||||
"Current Billing Cycle": "รอบบิลปัจจุบัน",
|
"Current Billing Cycle": "รอบบิลปัจจุบัน",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "วันที่กำหนดเอง",
|
"Custom Date": "วันที่กำหนดเอง",
|
||||||
"Start Date": "วันที่เริ่มต้น",
|
"Start Date": "วันที่เริ่มต้น",
|
||||||
"End Date": "วันที่สิ้นสุด",
|
"End Date": "วันที่สิ้นสุด",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "Varsayılan saat diliminin {hours} saat {minutes} dakika gerisinde",
|
"hoursMinutesBehindDefaultTimezone": "Varsayılan saat diliminin {hours} saat {minutes} dakika gerisinde",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "Varsayılan saat diliminin {hours} saat {minutes} dakika ilerisinde",
|
"hoursMinutesAheadOfDefaultTimezone": "Varsayılan saat diliminin {hours} saat {minutes} dakika ilerisinde",
|
||||||
"monthDay": "{ordinal} gün",
|
"monthDay": "{ordinal} gün",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} gün",
|
"monthDays": "{multiMonthDays} gün",
|
||||||
"everyMultiDaysOfWeek": "Her {days}",
|
"everyMultiDaysOfWeek": "Her {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Son 5 yıl",
|
"Recent 5 years": "Son 5 yıl",
|
||||||
"Previous Billing Cycle": "Önceki Fatura Dönemi",
|
"Previous Billing Cycle": "Önceki Fatura Dönemi",
|
||||||
"Current Billing Cycle": "Mevcut Fatura Dönemi",
|
"Current Billing Cycle": "Mevcut Fatura Dönemi",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Özel Tarih",
|
"Custom Date": "Özel Tarih",
|
||||||
"Start Date": "Başlangıç Tarihi",
|
"Start Date": "Başlangıç Tarihi",
|
||||||
"End Date": "Bitiş Tarihi",
|
"End Date": "Bitiş Tarihi",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} год і {minutes} хв позаду часового поясу за замовчуванням",
|
"hoursMinutesBehindDefaultTimezone": "{hours} год і {minutes} хв позаду часового поясу за замовчуванням",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} год і {minutes} хв попереду часового поясу за замовчуванням",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} год і {minutes} хв попереду часового поясу за замовчуванням",
|
||||||
"monthDay": "{ordinal} день",
|
"monthDay": "{ordinal} день",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} днів",
|
"monthDays": "{multiMonthDays} днів",
|
||||||
"everyMultiDaysOfWeek": "Кожні {days}",
|
"everyMultiDaysOfWeek": "Кожні {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "Останні 5 років",
|
"Recent 5 years": "Останні 5 років",
|
||||||
"Previous Billing Cycle": "Попередній розрахунковий період",
|
"Previous Billing Cycle": "Попередній розрахунковий період",
|
||||||
"Current Billing Cycle": "Поточний розрахунковий період",
|
"Current Billing Cycle": "Поточний розрахунковий період",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Обрати дату",
|
"Custom Date": "Обрати дату",
|
||||||
"Start Date": "Дата початку",
|
"Start Date": "Дата початку",
|
||||||
"End Date": "Дата завершення",
|
"End Date": "Дата завершення",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "{hours} giờ và {minutes} phút sau múi giờ mặc định",
|
"hoursMinutesBehindDefaultTimezone": "{hours} giờ và {minutes} phút sau múi giờ mặc định",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "{hours} giờ và {minutes} phút trước múi giờ mặc định",
|
"hoursMinutesAheadOfDefaultTimezone": "{hours} giờ và {minutes} phút trước múi giờ mặc định",
|
||||||
"monthDay": "Ngày {ordinal}",
|
"monthDay": "Ngày {ordinal}",
|
||||||
|
"lastMonthDay": "Last {ordinal} day",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}",
|
"eachMonthDayInMonthDays": "{ordinal}",
|
||||||
"monthDays": "{multiMonthDays} ngày",
|
"monthDays": "{multiMonthDays} ngày",
|
||||||
"everyMultiDaysOfWeek": "Mỗi {days}",
|
"everyMultiDaysOfWeek": "Mỗi {days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "5 năm gần đây",
|
"Recent 5 years": "5 năm gần đây",
|
||||||
"Previous Billing Cycle": "Previous Billing Cycle",
|
"Previous Billing Cycle": "Previous Billing Cycle",
|
||||||
"Current Billing Cycle": "Current Billing Cycle",
|
"Current Billing Cycle": "Current Billing Cycle",
|
||||||
|
"Last day": "Last day",
|
||||||
"Custom Date": "Ngày tùy chỉnh",
|
"Custom Date": "Ngày tùy chỉnh",
|
||||||
"Start Date": "Start Date",
|
"Start Date": "Start Date",
|
||||||
"End Date": "End Date",
|
"End Date": "End Date",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "Does not end with",
|
"Does not end with": "Does not end with",
|
||||||
"Matches regex": "Matches regex",
|
"Matches regex": "Matches regex",
|
||||||
"Does not match regex": "Does not match regex",
|
"Does not match regex": "Does not match regex",
|
||||||
|
"Minute offset is between": "Minute offset is between",
|
||||||
|
"Minute offset is not between": "Minute offset is not between",
|
||||||
"Latitude is between": "Latitude is between",
|
"Latitude is between": "Latitude is between",
|
||||||
"Latitude is not between": "Latitude is not between",
|
"Latitude is not between": "Latitude is not between",
|
||||||
"Longitude is between": "Longitude is between",
|
"Longitude is between": "Longitude is between",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "比默认时区晚{hours}小时{minutes}分",
|
"hoursMinutesBehindDefaultTimezone": "比默认时区晚{hours}小时{minutes}分",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "比默认时区早{hours}小时{minutes}分",
|
"hoursMinutesAheadOfDefaultTimezone": "比默认时区早{hours}小时{minutes}分",
|
||||||
"monthDay": "{ordinal}日",
|
"monthDay": "{ordinal}日",
|
||||||
|
"lastMonthDay": "倒数第{ordinal}日",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}日",
|
"eachMonthDayInMonthDays": "{ordinal}日",
|
||||||
"monthDays": "{multiMonthDays}",
|
"monthDays": "{multiMonthDays}",
|
||||||
"everyMultiDaysOfWeek": "每{days}",
|
"everyMultiDaysOfWeek": "每{days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "最近5年",
|
"Recent 5 years": "最近5年",
|
||||||
"Previous Billing Cycle": "上个账单周期",
|
"Previous Billing Cycle": "上个账单周期",
|
||||||
"Current Billing Cycle": "当前账单周期",
|
"Current Billing Cycle": "当前账单周期",
|
||||||
|
"Last day": "倒数第1日",
|
||||||
"Custom Date": "自定义日期",
|
"Custom Date": "自定义日期",
|
||||||
"Start Date": "开始日期",
|
"Start Date": "开始日期",
|
||||||
"End Date": "结束日期",
|
"End Date": "结束日期",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "结尾不是",
|
"Does not end with": "结尾不是",
|
||||||
"Matches regex": "正则匹配",
|
"Matches regex": "正则匹配",
|
||||||
"Does not match regex": "不匹配正则",
|
"Does not match regex": "不匹配正则",
|
||||||
|
"Minute offset is between": "分钟偏移量介于",
|
||||||
|
"Minute offset is not between": "分钟偏移量不介于",
|
||||||
"Latitude is between": "纬度介于",
|
"Latitude is between": "纬度介于",
|
||||||
"Latitude is not between": "纬度不介于",
|
"Latitude is not between": "纬度不介于",
|
||||||
"Longitude is between": "经度介于",
|
"Longitude is between": "经度介于",
|
||||||
|
|||||||
@@ -119,6 +119,7 @@
|
|||||||
"hoursMinutesBehindDefaultTimezone": "比預設時區晚{hours}小時{minutes}分",
|
"hoursMinutesBehindDefaultTimezone": "比預設時區晚{hours}小時{minutes}分",
|
||||||
"hoursMinutesAheadOfDefaultTimezone": "比預設時區早{hours}小時{minutes}分",
|
"hoursMinutesAheadOfDefaultTimezone": "比預設時區早{hours}小時{minutes}分",
|
||||||
"monthDay": "{ordinal}日",
|
"monthDay": "{ordinal}日",
|
||||||
|
"lastMonthDay": "倒數第{ordinal}日",
|
||||||
"eachMonthDayInMonthDays": "{ordinal}日",
|
"eachMonthDayInMonthDays": "{ordinal}日",
|
||||||
"monthDays": "{multiMonthDays}",
|
"monthDays": "{multiMonthDays}",
|
||||||
"everyMultiDaysOfWeek": "每{days}",
|
"everyMultiDaysOfWeek": "每{days}",
|
||||||
@@ -1540,6 +1541,7 @@
|
|||||||
"Recent 5 years": "最近5年",
|
"Recent 5 years": "最近5年",
|
||||||
"Previous Billing Cycle": "上個帳單週期",
|
"Previous Billing Cycle": "上個帳單週期",
|
||||||
"Current Billing Cycle": "當前帳單週期",
|
"Current Billing Cycle": "當前帳單週期",
|
||||||
|
"Last day": "倒數第1日",
|
||||||
"Custom Date": "自訂日期",
|
"Custom Date": "自訂日期",
|
||||||
"Start Date": "開始日期",
|
"Start Date": "開始日期",
|
||||||
"End Date": "結束日期",
|
"End Date": "結束日期",
|
||||||
@@ -1573,6 +1575,8 @@
|
|||||||
"Does not end with": "結尾不是",
|
"Does not end with": "結尾不是",
|
||||||
"Matches regex": "正則匹配",
|
"Matches regex": "正則匹配",
|
||||||
"Does not match regex": "不匹配正則",
|
"Does not match regex": "不匹配正則",
|
||||||
|
"Minute offset is between": "分钟偏移量介於",
|
||||||
|
"Minute offset is not between": "分钟偏移量不介於",
|
||||||
"Latitude is between": "緯度介於",
|
"Latitude is between": "緯度介於",
|
||||||
"Latitude is not between": "緯度不介於",
|
"Latitude is not between": "緯度不介於",
|
||||||
"Longitude is between": "經度介於",
|
"Longitude is between": "經度介於",
|
||||||
|
|||||||
+290
-3
@@ -1,4 +1,5 @@
|
|||||||
import { type PartialRecord, itemAndIndex, keysIfValueEquals } from '@/core/base.ts';
|
import { type PartialRecord, itemAndIndex, keysIfValueEquals } from '@/core/base.ts';
|
||||||
|
import { type DateTime } from '@/core/datetime.ts';
|
||||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||||
import { AccountType } from '@/core/account.ts';
|
import { AccountType } from '@/core/account.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
@@ -300,6 +301,21 @@ export class TransactionExplorerQuery {
|
|||||||
let condition: TransactionExplorerCondition;
|
let condition: TransactionExplorerCondition;
|
||||||
|
|
||||||
switch (field) {
|
switch (field) {
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfWeek:
|
||||||
|
condition = new TransactionExplorerTransactionTimeDayOfWeekCondition(TransactionExplorerConditionOperatorType.In, []);
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfMonth:
|
||||||
|
condition = new TransactionExplorerTransactionTimeDayOfMonthCondition(TransactionExplorerConditionOperatorType.In, []);
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeMonthOfYear:
|
||||||
|
condition = new TransactionExplorerTransactionTimeMonthOfYearCondition(TransactionExplorerConditionOperatorType.In, []);
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeHourOfDay:
|
||||||
|
condition = new TransactionExplorerTransactionTimeHourOfDayCondition(TransactionExplorerConditionOperatorType.In, []);
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimezone:
|
||||||
|
condition = new TransactionExplorerTransactionTimezoneCondition(TransactionExplorerConditionOperatorType.MinuteOffsetBetween, [ 0, 0 ]);
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionType:
|
case TransactionExplorerConditionField.TransactionType:
|
||||||
condition = new TransactionExplorerTransactionTypeCondition(TransactionExplorerConditionOperatorType.In, [ TransactionType.Expense, TransactionType.Income, TransactionType.Transfer ]);
|
condition = new TransactionExplorerTransactionTypeCondition(TransactionExplorerConditionOperatorType.In, [ TransactionType.Expense, TransactionType.Income, TransactionType.Transfer ]);
|
||||||
break;
|
break;
|
||||||
@@ -345,7 +361,7 @@ export class TransactionExplorerQuery {
|
|||||||
return new TransactionExplorerConditionWithRelation(new TransactionExplorerUndefinedCondition(), TransactionExplorerConditionRelation.SubEnd);
|
return new TransactionExplorerConditionWithRelation(new TransactionExplorerUndefinedCondition(), TransactionExplorerConditionRelation.SubEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public match(transaction: TransactionInsightDataItem): boolean {
|
public match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean {
|
||||||
if (!this.conditions || this.conditions.length < 1) {
|
if (!this.conditions || this.conditions.length < 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -370,7 +386,7 @@ export class TransactionExplorerQuery {
|
|||||||
throw new Error('invalid postfix expression');
|
throw new Error('invalid postfix expression');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stack.push(token.match(transaction));
|
stack.push(token.match(transaction, context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,6 +662,21 @@ export class TransactionExplorerConditionWithRelation {
|
|||||||
let operatorTypes: PartialRecord<TransactionExplorerConditionOperatorType, true> = {};
|
let operatorTypes: PartialRecord<TransactionExplorerConditionOperatorType, true> = {};
|
||||||
|
|
||||||
switch (this.condition.field) {
|
switch (this.condition.field) {
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfWeek.value:
|
||||||
|
operatorTypes = TransactionExplorerTransactionTimeDayOfWeekCondition.supportedOperators;
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfMonth.value:
|
||||||
|
operatorTypes = TransactionExplorerTransactionTimeDayOfMonthCondition.supportedOperators;
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeMonthOfYear.value:
|
||||||
|
operatorTypes = TransactionExplorerTransactionTimeMonthOfYearCondition.supportedOperators;
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeHourOfDay.value:
|
||||||
|
operatorTypes = TransactionExplorerTransactionTimeHourOfDayCondition.supportedOperators;
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimezone.value:
|
||||||
|
operatorTypes = TransactionExplorerTransactionTimezoneCondition.supportedOperators;
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionType.value:
|
case TransactionExplorerConditionField.TransactionType.value:
|
||||||
operatorTypes = TransactionExplorerTransactionTypeCondition.supportedOperators;
|
operatorTypes = TransactionExplorerTransactionTypeCondition.supportedOperators;
|
||||||
break;
|
break;
|
||||||
@@ -736,6 +767,31 @@ export class TransactionExplorerConditionWithRelation {
|
|||||||
const conditionValue = conditionObject['value'];
|
const conditionValue = conditionObject['value'];
|
||||||
|
|
||||||
switch (conditionField) {
|
switch (conditionField) {
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfWeek.value:
|
||||||
|
if (TransactionExplorerTransactionTimeDayOfWeekCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerTransactionTimeDayOfWeekCondition(conditionOperator as TransactionTimeDayOfWeekConditionOperator, conditionValue as number[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeDayOfMonth.value:
|
||||||
|
if (TransactionExplorerTransactionTimeDayOfMonthCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerTransactionTimeDayOfMonthCondition(conditionOperator as TransactionTimeDayOfMonthConditionOperator, conditionValue as number[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeMonthOfYear.value:
|
||||||
|
if (TransactionExplorerTransactionTimeMonthOfYearCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerTransactionTimeMonthOfYearCondition(conditionOperator as TransactionTimeMonthOfYearConditionOperator, conditionValue as number[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimeHourOfDay.value:
|
||||||
|
if (TransactionExplorerTransactionTimeHourOfDayCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
|
condition = new TransactionExplorerTransactionTimeHourOfDayCondition(conditionOperator as TransactionTimeHourOfDayConditionOperator, conditionValue as number[]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TransactionExplorerConditionField.TransactionTimezone.value:
|
||||||
|
if (TransactionExplorerTransactionTimezoneCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue) && conditionValue.length === 2) {
|
||||||
|
condition = new TransactionExplorerTransactionTimezoneCondition(conditionOperator as TransactionTimezoneConditionOperator, conditionValue as [number, number]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TransactionExplorerConditionField.TransactionType.value:
|
case TransactionExplorerConditionField.TransactionType.value:
|
||||||
if (TransactionExplorerTransactionTypeCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
if (TransactionExplorerTransactionTypeCondition.supportedOperators[conditionOperator] && Array.isArray(conditionValue)) {
|
||||||
condition = new TransactionExplorerTransactionTypeCondition(conditionOperator as TransactionTypeConditionOperator, conditionValue as number[]);
|
condition = new TransactionExplorerTransactionTypeCondition(conditionOperator as TransactionTypeConditionOperator, conditionValue as number[]);
|
||||||
@@ -803,13 +859,17 @@ export class TransactionExplorerConditionWithRelation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface InsightsExplorerMatchContext {
|
||||||
|
getTransactionDateTime(): DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TransactionExplorerCondition<T = TransactionExplorerConditionFieldType, V = string | string[] | number[]> {
|
export interface TransactionExplorerCondition<T = TransactionExplorerConditionFieldType, V = string | string[] | number[]> {
|
||||||
readonly field: T;
|
readonly field: T;
|
||||||
readonly operator: TransactionExplorerConditionOperatorType;
|
readonly operator: TransactionExplorerConditionOperatorType;
|
||||||
value: V;
|
value: V;
|
||||||
|
|
||||||
getValueForStore(): V;
|
getValueForStore(): V;
|
||||||
match(transaction: TransactionInsightDataItem): boolean;
|
match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean;
|
||||||
toExpression(allCategoriesMap: Record<string, TransactionCategory>, allAccountsMap: Record<string, Account>, allTagsMap: Record<string, TransactionTag>): string;
|
toExpression(allCategoriesMap: Record<string, TransactionCategory>, allAccountsMap: Record<string, Account>, allTagsMap: Record<string, TransactionTag>): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,6 +891,233 @@ export class TransactionExplorerUndefinedCondition implements TransactionExplore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TransactionTimeDayOfWeekConditionOperator = TransactionExplorerConditionOperatorType.In |
|
||||||
|
TransactionExplorerConditionOperatorType.NotIn;
|
||||||
|
|
||||||
|
export class TransactionExplorerTransactionTimeDayOfWeekCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.TransactionTimeDayOfWeek, number[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.In]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.NotIn]: true
|
||||||
|
};
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.TransactionTimeDayOfWeek;
|
||||||
|
public readonly operator: TransactionTimeDayOfWeekConditionOperator = TransactionExplorerConditionOperatorType.In;
|
||||||
|
public value: number[];
|
||||||
|
|
||||||
|
constructor(operator: TransactionTimeDayOfWeekConditionOperator, value: number[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): number[] {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean {
|
||||||
|
const transactionDateTime = context.getTransactionDateTime();
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return this.value.includes(transactionDateTime.getWeekDay().type);
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return !this.value.includes(transactionDateTime.getWeekDay().type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
const textualDayOfWeeks = this.value.join(', ');
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return `DAY_OF_WEEK(transaction_time) IN (${textualDayOfWeeks})`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return `DAY_OF_WEEK(transaction_time) NOT IN (${textualDayOfWeeks})`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionTimeDayOfMonthConditionOperator = TransactionExplorerConditionOperatorType.In |
|
||||||
|
TransactionExplorerConditionOperatorType.NotIn;
|
||||||
|
|
||||||
|
export class TransactionExplorerTransactionTimeDayOfMonthCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.TransactionTimeDayOfMonth, number[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.In]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.NotIn]: true
|
||||||
|
};
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.TransactionTimeDayOfMonth;
|
||||||
|
public readonly operator: TransactionTimeDayOfMonthConditionOperator = TransactionExplorerConditionOperatorType.In;
|
||||||
|
public value: number[];
|
||||||
|
|
||||||
|
constructor(operator: TransactionTimeDayOfMonthConditionOperator, value: number[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): number[] {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean {
|
||||||
|
const transactionDateTime = context.getTransactionDateTime();
|
||||||
|
const normalizedValue: number[] = this.value.map(day => day >= 0 ? day : transactionDateTime.getMaxDayOfGregorianCalendarMonth() + day + 1);
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return normalizedValue.includes(transactionDateTime.getGregorianCalendarDay());
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return !normalizedValue.includes(transactionDateTime.getGregorianCalendarDay());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
const textualDayOfMonths = this.value.join(', ');
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return `DAY(transaction_time) IN (${textualDayOfMonths})`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return `DAY(transaction_time) NOT IN (${textualDayOfMonths})`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionTimeMonthOfYearConditionOperator = TransactionExplorerConditionOperatorType.In |
|
||||||
|
TransactionExplorerConditionOperatorType.NotIn;
|
||||||
|
|
||||||
|
export class TransactionExplorerTransactionTimeMonthOfYearCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.TransactionTimeMonthOfYear, number[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.In]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.NotIn]: true
|
||||||
|
};
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.TransactionTimeMonthOfYear;
|
||||||
|
public readonly operator: TransactionTimeMonthOfYearConditionOperator = TransactionExplorerConditionOperatorType.In;
|
||||||
|
public value: number[];
|
||||||
|
|
||||||
|
constructor(operator: TransactionTimeMonthOfYearConditionOperator, value: number[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): number[] {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean {
|
||||||
|
const transactionDateTime = context.getTransactionDateTime();
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return this.value.includes(transactionDateTime.getGregorianCalendarMonth());
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return !this.value.includes(transactionDateTime.getGregorianCalendarMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
const textualMonthOfYears = this.value.join(', ');
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return `MONTH(transaction_time) IN (${textualMonthOfYears})`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return `MONTH(transaction_time) NOT IN (${textualMonthOfYears})`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionTimeHourOfDayConditionOperator = TransactionExplorerConditionOperatorType.In |
|
||||||
|
TransactionExplorerConditionOperatorType.NotIn;
|
||||||
|
|
||||||
|
export class TransactionExplorerTransactionTimeHourOfDayCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.TransactionTimeHourOfDay, number[]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.In]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.NotIn]: true
|
||||||
|
};
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.TransactionTimeHourOfDay;
|
||||||
|
public readonly operator: TransactionTimeHourOfDayConditionOperator = TransactionExplorerConditionOperatorType.In;
|
||||||
|
public value: number[];
|
||||||
|
|
||||||
|
constructor(operator: TransactionTimeHourOfDayConditionOperator, value: number[]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): number[] {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem, context: InsightsExplorerMatchContext): boolean {
|
||||||
|
const transactionDateTime = context.getTransactionDateTime();
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return this.value.includes(transactionDateTime.getHour());
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return !this.value.includes(transactionDateTime.getHour());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
const textualHourOfDays = this.value.join(', ');
|
||||||
|
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.In) {
|
||||||
|
return `HOUR(transaction_time) IN (${textualHourOfDays})`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.NotIn) {
|
||||||
|
return `HOUR(transaction_time) NOT IN (${textualHourOfDays})`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionTimezoneConditionOperator = TransactionExplorerConditionOperatorType.MinuteOffsetBetween |
|
||||||
|
TransactionExplorerConditionOperatorType.MinuteOffsetNotBetween;
|
||||||
|
|
||||||
|
export class TransactionExplorerTransactionTimezoneCondition implements TransactionExplorerCondition<TransactionExplorerConditionFieldType.TransactionTimezone, [number, number]> {
|
||||||
|
public static readonly supportedOperators: PartialRecord<TransactionExplorerConditionOperatorType, true> = {
|
||||||
|
[TransactionExplorerConditionOperatorType.MinuteOffsetBetween]: true,
|
||||||
|
[TransactionExplorerConditionOperatorType.MinuteOffsetNotBetween]: true
|
||||||
|
};
|
||||||
|
public readonly field = TransactionExplorerConditionFieldType.TransactionTimezone;
|
||||||
|
public readonly operator: TransactionTimezoneConditionOperator = TransactionExplorerConditionOperatorType.MinuteOffsetBetween;
|
||||||
|
public value: [number, number];
|
||||||
|
|
||||||
|
constructor(operator: TransactionTimezoneConditionOperator, value: [number, number]) {
|
||||||
|
this.operator = operator;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValueForStore(): [number, number] {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public match(transaction: TransactionInsightDataItem): boolean {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.MinuteOffsetBetween) {
|
||||||
|
return transaction.utcOffset >= this.value[0] && transaction.utcOffset <= this.value[1];
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.MinuteOffsetNotBetween) {
|
||||||
|
return transaction.utcOffset < this.value[0] || transaction.utcOffset > this.value[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toExpression(): string {
|
||||||
|
if (this.operator === TransactionExplorerConditionOperatorType.MinuteOffsetBetween) {
|
||||||
|
return `(UTC_OFFSET(timezone) >= ${this.value[0]} AND UTC_OFFSET(timezone) <= ${this.value[1]})`;
|
||||||
|
} else if (this.operator === TransactionExplorerConditionOperatorType.MinuteOffsetNotBetween) {
|
||||||
|
return `(UTC_OFFSET(timezone) < ${this.value[0]} OR UTC_OFFSET(timezone) > ${this.value[1]})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type TransactionTypeConditionOperator = TransactionExplorerConditionOperatorType.In |
|
type TransactionTypeConditionOperator = TransactionExplorerConditionOperatorType.In |
|
||||||
TransactionExplorerConditionOperatorType.NotIn;
|
TransactionExplorerConditionOperatorType.NotIn;
|
||||||
|
|
||||||
|
|||||||
+22
-3
@@ -10,7 +10,7 @@ import { useExchangeRatesStore } from './exchangeRates.ts';
|
|||||||
|
|
||||||
import { type BeforeResolveFunction, itemAndIndex, reversed, keys, values } from '@/core/base.ts';
|
import { type BeforeResolveFunction, itemAndIndex, reversed, keys, values } from '@/core/base.ts';
|
||||||
import { NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
import { NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
||||||
import { DateRangeScene, DateRange } from '@/core/datetime.ts';
|
import { type DateTime, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||||
import { AccountCategory } from '@/core/account.ts';
|
import { AccountCategory } from '@/core/account.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
type InsightsExplorerNewDisplayOrderRequest,
|
type InsightsExplorerNewDisplayOrderRequest,
|
||||||
type InsightsExplorerInfoResponse,
|
type InsightsExplorerInfoResponse,
|
||||||
|
type InsightsExplorerMatchContext,
|
||||||
InsightsExplorer,
|
InsightsExplorer,
|
||||||
InsightsExplorerBasicInfo
|
InsightsExplorerBasicInfo
|
||||||
} from '@/models/explorer.ts';
|
} from '@/models/explorer.ts';
|
||||||
@@ -151,6 +152,20 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
return result;
|
return result;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function buildInsightsExplorerMatchContext(insightsExplorer: InsightsExplorer, transaction: TransactionInsightDataItem): InsightsExplorerMatchContext {
|
||||||
|
return {
|
||||||
|
getTransactionDateTime(): DateTime {
|
||||||
|
let transactionTimeUtfOffset: number | undefined = undefined;
|
||||||
|
|
||||||
|
if (insightsExplorer.timezoneUsedForDateRange === TimezoneTypeForStatistics.TransactionTimezone.type) {
|
||||||
|
transactionTimeUtfOffset = transaction.utcOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isDefined(transactionTimeUtfOffset) ? parseDateTimeFromUnixTimeWithTimezoneOffset(transaction.time, transactionTimeUtfOffset) : parseDateTimeFromUnixTime(transaction.time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getDataCategoryInfo(timezoneUsedForDateRange: number, dimension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): CategoriedInfo {
|
function getDataCategoryInfo(timezoneUsedForDateRange: number, dimension: TransactionExplorerDataDimension, queryName: string, queryIndex: number, transaction: TransactionInsightDataItem): CategoriedInfo {
|
||||||
let transactionTimeUtfOffset: number | undefined = undefined;
|
let transactionTimeUtfOffset: number | undefined = undefined;
|
||||||
|
|
||||||
@@ -600,12 +615,14 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
const result: TransactionInsightDataItem[] = [];
|
const result: TransactionInsightDataItem[] = [];
|
||||||
|
|
||||||
for (const transaction of allTransactions.value) {
|
for (const transaction of allTransactions.value) {
|
||||||
|
const matchOptions: InsightsExplorerMatchContext = buildInsightsExplorerMatchContext(currentInsightsExplorer.value, transaction);
|
||||||
|
|
||||||
for (const query of currentInsightsExplorer.value.queries) {
|
for (const query of currentInsightsExplorer.value.queries) {
|
||||||
if (currentInsightsExplorer.value.datatableQuerySource && currentInsightsExplorer.value.datatableQuerySource !== query.id) {
|
if (currentInsightsExplorer.value.datatableQuerySource && currentInsightsExplorer.value.datatableQuerySource !== query.id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.match(transaction)) {
|
if (query.match(transaction, matchOptions)) {
|
||||||
result.push(transaction);
|
result.push(transaction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -751,8 +768,10 @@ export const useExplorersStore = defineStore('explorers', () => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const matchContext: InsightsExplorerMatchContext = buildInsightsExplorerMatchContext(currentInsightsExplorer.value, transaction);
|
||||||
|
|
||||||
for (const [query, index] of itemAndIndex(currentInsightsExplorer.value.queries)) {
|
for (const [query, index] of itemAndIndex(currentInsightsExplorer.value.queries)) {
|
||||||
if (query.match(transaction)) {
|
if (query.match(transaction, matchContext)) {
|
||||||
addTransactionToCategoriedDataMap(currentInsightsExplorer.value.timezoneUsedForDateRange, categoriedDataMap, categoryDimension, seriesDimension, query.name, index, transaction);
|
addTransactionToCategoriedDataMap(currentInsightsExplorer.value.timezoneUsedForDateRange, categoriedDataMap, categoryDimension, seriesDimension, query.name, index, transaction);
|
||||||
|
|
||||||
if (categoryDimension !== TransactionExplorerDataDimension.Query) {
|
if (categoryDimension !== TransactionExplorerDataDimension.Query) {
|
||||||
|
|||||||
@@ -153,6 +153,119 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="d-flex w-100 flex-1-1" style="min-width: 280px;">
|
<div class="d-flex w-100 flex-1-1" style="min-width: 280px;">
|
||||||
|
<v-select
|
||||||
|
multiple chips closable-chips
|
||||||
|
density="compact"
|
||||||
|
item-title="displayName"
|
||||||
|
item-value="type"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
:items="allAvailableDayOfWeekOptions"
|
||||||
|
v-model="conditionWithRelation.condition.value"
|
||||||
|
v-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTimeDayOfWeek.value"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item :value="item.value" v-bind="props">
|
||||||
|
<template #title>
|
||||||
|
<v-list-item-title>
|
||||||
|
<div class="d-flex align-center">{{ item.title }}</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
|
||||||
|
<v-select
|
||||||
|
multiple chips closable-chips
|
||||||
|
density="compact"
|
||||||
|
item-title="displayName"
|
||||||
|
item-value="type"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
:items="allAvailableDayOfMonthOptions"
|
||||||
|
v-model="conditionWithRelation.condition.value"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTimeDayOfMonth.value"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item :value="item.value" v-bind="props">
|
||||||
|
<template #title>
|
||||||
|
<v-list-item-title>
|
||||||
|
<div class="d-flex align-center">{{ item.title }}</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
|
||||||
|
<v-select
|
||||||
|
multiple chips closable-chips
|
||||||
|
density="compact"
|
||||||
|
item-title="displayName"
|
||||||
|
item-value="type"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
:items="allAvailableMonthOfYearOptions"
|
||||||
|
v-model="conditionWithRelation.condition.value"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTimeMonthOfYear.value"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item :value="item.value" v-bind="props">
|
||||||
|
<template #title>
|
||||||
|
<v-list-item-title>
|
||||||
|
<div class="d-flex align-center">{{ item.title }}</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
|
||||||
|
<v-select
|
||||||
|
multiple chips closable-chips
|
||||||
|
density="compact"
|
||||||
|
item-title="displayName"
|
||||||
|
item-value="type"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:placeholder="tt('None')"
|
||||||
|
:items="allAvailableHourOfDayOptions"
|
||||||
|
v-model="conditionWithRelation.condition.value"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTimeHourOfDay.value"
|
||||||
|
>
|
||||||
|
<template #item="{ props, item }">
|
||||||
|
<v-list-item :value="item.value" v-bind="props">
|
||||||
|
<template #title>
|
||||||
|
<v-list-item-title>
|
||||||
|
<div class="d-flex align-center">{{ item.title }}</div>
|
||||||
|
</v-list-item-title>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
|
||||||
|
<div class="d-flex w-100 align-center gap-2"
|
||||||
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionTimezone.value">
|
||||||
|
<number-input density="compact"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:min-value="WESTERNMOST_TIMEZONE_UTC_OFFSET"
|
||||||
|
:max-value="EASTERNMOST_TIMEZONE_UTC_OFFSET"
|
||||||
|
:max-decimal-count="0"
|
||||||
|
v-model="conditionWithRelation.condition.value[0]"
|
||||||
|
v-if="conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetBetween.value ||
|
||||||
|
conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetNotBetween.value"
|
||||||
|
/>
|
||||||
|
<span class="ms-2 me-2"
|
||||||
|
v-if="conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetBetween.value ||
|
||||||
|
conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetNotBetween.value">~</span>
|
||||||
|
<number-input density="compact"
|
||||||
|
:disabled="loading || disabled || !!editingQuery"
|
||||||
|
:min-value="WESTERNMOST_TIMEZONE_UTC_OFFSET"
|
||||||
|
:max-value="EASTERNMOST_TIMEZONE_UTC_OFFSET"
|
||||||
|
:max-decimal-count="0"
|
||||||
|
v-model="conditionWithRelation.condition.value[1]"
|
||||||
|
v-if="conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetBetween.value ||
|
||||||
|
conditionWithRelation.condition.operator === TransactionExplorerConditionOperator.MinuteOffsetNotBetween.value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<v-select
|
<v-select
|
||||||
multiple chips closable-chips
|
multiple chips closable-chips
|
||||||
density="compact"
|
density="compact"
|
||||||
@@ -166,7 +279,7 @@
|
|||||||
{ type: TransactionType.Transfer, displayName: tt('Transfer') }
|
{ type: TransactionType.Transfer, displayName: tt('Transfer') }
|
||||||
]"
|
]"
|
||||||
v-model="conditionWithRelation.condition.value"
|
v-model="conditionWithRelation.condition.value"
|
||||||
v-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionType.value"
|
v-else-if="conditionWithRelation.condition.field === TransactionExplorerConditionField.TransactionType.value"
|
||||||
>
|
>
|
||||||
<template #item="{ props, item }">
|
<template #item="{ props, item }">
|
||||||
<v-list-item :value="item.value" v-bind="props">
|
<v-list-item :value="item.value" v-bind="props">
|
||||||
@@ -410,7 +523,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
|||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
import { useExplorersStore } from '@/stores/explorer.ts';
|
import { useExplorersStore } from '@/stores/explorer.ts';
|
||||||
|
|
||||||
import { type NameValue, values } from '@/core/base.ts';
|
import { type NameValue, type TypeAndDisplayName, values } from '@/core/base.ts';
|
||||||
import { AccountType } from '@/core/account.ts';
|
import { AccountType } from '@/core/account.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
import {
|
import {
|
||||||
@@ -419,6 +532,11 @@ import {
|
|||||||
TransactionExplorerConditionOperator
|
TransactionExplorerConditionOperator
|
||||||
} from '@/core/explorer.ts';
|
} from '@/core/explorer.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
WESTERNMOST_TIMEZONE_UTC_OFFSET,
|
||||||
|
EASTERNMOST_TIMEZONE_UTC_OFFSET,
|
||||||
|
} from '@/consts/timezone.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type TransactionExplorerCondition,
|
type TransactionExplorerCondition,
|
||||||
TransactionExplorerQuery,
|
TransactionExplorerQuery,
|
||||||
@@ -457,6 +575,10 @@ const props = defineProps<ExplorerQueryTabProps>();
|
|||||||
const {
|
const {
|
||||||
tt,
|
tt,
|
||||||
joinMultiText,
|
joinMultiText,
|
||||||
|
getAllMonths,
|
||||||
|
getAllWeekDays,
|
||||||
|
getAllHours,
|
||||||
|
getAvailableMonthDays,
|
||||||
getAllTransactionExplorerConditionFields,
|
getAllTransactionExplorerConditionFields,
|
||||||
getAllTransactionExplorerConditionOperators
|
getAllTransactionExplorerConditionOperators
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -489,6 +611,10 @@ const hasAnyAccount = computed<boolean>(() => accountsStore.allPlainAccounts.len
|
|||||||
const hasAnyTransactionCategory = computed<boolean>(() => !isObjectEmpty(transactionCategoriesStore.allTransactionCategoriesMap));
|
const hasAnyTransactionCategory = computed<boolean>(() => !isObjectEmpty(transactionCategoriesStore.allTransactionCategoriesMap));
|
||||||
|
|
||||||
const allTransactionExplorerConditionFields = computed<NameValue[]>(() => getAllTransactionExplorerConditionFields());
|
const allTransactionExplorerConditionFields = computed<NameValue[]>(() => getAllTransactionExplorerConditionFields());
|
||||||
|
const allAvailableDayOfWeekOptions = computed<TypeAndDisplayName[]>(() => getAllWeekDays(userStore.currentUserFirstDayOfWeek));
|
||||||
|
const allAvailableDayOfMonthOptions = computed<TypeAndDisplayName[]>(() => getAvailableMonthDays(31, 3));
|
||||||
|
const allAvailableMonthOfYearOptions = computed<TypeAndDisplayName[]>(() => getAllMonths());
|
||||||
|
const allAvailableHourOfDayOptions = computed<TypeAndDisplayName[]>(() => getAllHours());
|
||||||
|
|
||||||
function getFilteredAccountsDisplayContent(filterAccountIds?: Record<string, boolean>): string {
|
function getFilteredAccountsDisplayContent(filterAccountIds?: Record<string, boolean>): string {
|
||||||
if ((props.loading && !hasAnyAccount.value) || !accountsStore.allVisiblePlainAccounts || !accountsStore.allVisiblePlainAccounts.length) {
|
if ((props.loading && !hasAnyAccount.value) || !accountsStore.allVisiblePlainAccounts || !accountsStore.allVisiblePlainAccounts.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user