mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-17 16:24:25 +08:00
add insights & explore page
This commit is contained in:
+4
-4
@@ -21,7 +21,7 @@ export function* reversedItemAndIndex<T>(arr: T[]): Iterable<[T, number]> {
|
||||
}
|
||||
}
|
||||
|
||||
export function* entries<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<[string, V]> {
|
||||
export function* entries<K extends string | number | symbol, V>(obj: Record<K, V> | PartialRecord<K, V>): Iterable<[string, V]> {
|
||||
for (const key in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
continue;
|
||||
@@ -31,7 +31,7 @@ export function* entries<K extends string | number | symbol, V>(obj: Record<K, V
|
||||
}
|
||||
}
|
||||
|
||||
export function* keys<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<string> {
|
||||
export function* keys<K extends string | number | symbol, V>(obj: Record<K, V> | PartialRecord<K, V>): Iterable<string> {
|
||||
for (const key in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
continue;
|
||||
@@ -41,7 +41,7 @@ export function* keys<K extends string | number | symbol, V>(obj: Record<K, V>):
|
||||
}
|
||||
}
|
||||
|
||||
export function* keysIfValueEquals<K extends string | number | symbol, V>(obj: Record<K, V>, value: V): Iterable<string> {
|
||||
export function* keysIfValueEquals<K extends string | number | symbol, V>(obj: Record<K, V> | PartialRecord<K, V>, value: V): Iterable<string> {
|
||||
for (const key in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
continue;
|
||||
@@ -55,7 +55,7 @@ export function* keysIfValueEquals<K extends string | number | symbol, V>(obj: R
|
||||
}
|
||||
}
|
||||
|
||||
export function* values<K extends string | number | symbol, V>(obj: Record<K, V>): Iterable<V> {
|
||||
export function* values<K extends string | number | symbol, V>(obj: Record<K, V> | PartialRecord<K, V>): Iterable<V> {
|
||||
for (const key in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||
continue;
|
||||
|
||||
+22
-21
@@ -589,7 +589,8 @@ export class ShortTimeFormat implements TimeFormat {
|
||||
export enum DateRangeScene {
|
||||
Normal = 0,
|
||||
TrendAnalysis = 1,
|
||||
AssetTrends = 2
|
||||
AssetTrends = 2,
|
||||
InsightsExplore = 3
|
||||
}
|
||||
|
||||
export class DateRange implements TypeAndName {
|
||||
@@ -597,38 +598,38 @@ export class DateRange implements TypeAndName {
|
||||
private static readonly allInstancesByType: Record<number, DateRange> = {};
|
||||
|
||||
// All date range
|
||||
public static readonly All = new DateRange(0, 'All', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly All = new DateRange(0, 'All', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
|
||||
// Date ranges for normal scene only
|
||||
public static readonly Today = new DateRange(1, 'Today', false, false, DateRangeScene.Normal);
|
||||
public static readonly Yesterday = new DateRange(2, 'Yesterday', false, false, DateRangeScene.Normal);
|
||||
public static readonly LastSevenDays = new DateRange(3, 'Recent 7 days', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly LastThirtyDays = new DateRange(4, 'Recent 30 days', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly ThisWeek = new DateRange(5, 'This week', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly LastWeek = new DateRange(6, 'Last week', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly ThisMonth = new DateRange(7, 'This month', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly LastMonth = new DateRange(8, 'Last month', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends);
|
||||
public static readonly Today = new DateRange(1, 'Today', false, false, DateRangeScene.Normal, DateRangeScene.InsightsExplore);
|
||||
public static readonly Yesterday = new DateRange(2, 'Yesterday', false, false, DateRangeScene.Normal, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastSevenDays = new DateRange(3, 'Recent 7 days', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastThirtyDays = new DateRange(4, 'Recent 30 days', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly ThisWeek = new DateRange(5, 'This week', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastWeek = new DateRange(6, 'Last week', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly ThisMonth = new DateRange(7, 'This month', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastMonth = new DateRange(8, 'Last month', false, false, DateRangeScene.Normal, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
|
||||
// Date ranges for normal and trend analysis scene
|
||||
public static readonly ThisYear = new DateRange(9, 'This year', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly LastYear = new DateRange(10, 'Last year', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly ThisFiscalYear = new DateRange(11, 'This fiscal year', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly LastFiscalYear = new DateRange(12, 'Last fiscal year', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly ThisYear = new DateRange(9, 'This year', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastYear = new DateRange(10, 'Last year', false, false, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly ThisFiscalYear = new DateRange(11, 'This fiscal year', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly LastFiscalYear = new DateRange(12, 'Last fiscal year', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
|
||||
// Billing cycle date ranges for normal scene only
|
||||
public static readonly CurrentBillingCycle = new DateRange(51, 'Current Billing Cycle', true, true, DateRangeScene.Normal);
|
||||
public static readonly PreviousBillingCycle = new DateRange(52, 'Previous Billing Cycle', true, true, DateRangeScene.Normal);
|
||||
|
||||
// Date ranges for trend analysis scene only
|
||||
public static readonly RecentTwelveMonths = new DateRange(101, 'Recent 12 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentTwentyFourMonths = new DateRange(102, 'Recent 24 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentThirtySixMonths = new DateRange(103, 'Recent 36 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentTwoYears = new DateRange(104, 'Recent 2 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentThreeYears = new DateRange(105, 'Recent 3 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentFiveYears = new DateRange(106, 'Recent 5 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly RecentTwelveMonths = new DateRange(101, 'Recent 12 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly RecentTwentyFourMonths = new DateRange(102, 'Recent 24 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly RecentThirtySixMonths = new DateRange(103, 'Recent 36 months', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly RecentTwoYears = new DateRange(104, 'Recent 2 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly RecentThreeYears = new DateRange(105, 'Recent 3 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
public static readonly RecentFiveYears = new DateRange(106, 'Recent 5 years', false, false, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
|
||||
// Custom date range
|
||||
public static readonly Custom = new DateRange(255, 'Custom Date', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends);
|
||||
public static readonly Custom = new DateRange(255, 'Custom Date', false, true, DateRangeScene.Normal, DateRangeScene.TrendAnalysis, DateRangeScene.AssetTrends, DateRangeScene.InsightsExplore);
|
||||
|
||||
public readonly type: number;
|
||||
public readonly name: string;
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { type NameValue } from '@/core/base.ts';
|
||||
import { DateRange } from '@/core/datetime.ts';
|
||||
|
||||
export enum TransactionExploreConditionRelation {
|
||||
First = 'first',
|
||||
And = 'and',
|
||||
Or = 'or'
|
||||
}
|
||||
|
||||
export const TransactionExploreConditionRelationPriority: Record<TransactionExploreConditionRelation, number> = {
|
||||
[TransactionExploreConditionRelation.First]: 0,
|
||||
[TransactionExploreConditionRelation.Or]: 1,
|
||||
[TransactionExploreConditionRelation.And]: 2
|
||||
};
|
||||
|
||||
|
||||
export enum TransactionExploreConditionFieldType {
|
||||
TransactionType = 'transactionType',
|
||||
TransactionCategory = 'transactionCategory',
|
||||
SourceAccount = 'sourceAccount',
|
||||
DestinationAccount = 'destinationAccount',
|
||||
SourceAmount = 'sourceAmount',
|
||||
DestinationAmount = 'destinationAmount',
|
||||
TransactionTag = 'transactionTag',
|
||||
Description = 'description'
|
||||
}
|
||||
|
||||
export class TransactionExploreConditionField implements NameValue {
|
||||
private static readonly allInstances: TransactionExploreConditionField[] = [];
|
||||
private static readonly allInstancesByValue: Record<string, TransactionExploreConditionField> = {};
|
||||
|
||||
public static readonly TransactionType = new TransactionExploreConditionField('Transaction Type', TransactionExploreConditionFieldType.TransactionType);
|
||||
public static readonly TransactionCategory = new TransactionExploreConditionField('Category', TransactionExploreConditionFieldType.TransactionCategory);
|
||||
public static readonly SourceAccount = new TransactionExploreConditionField('Source Account', TransactionExploreConditionFieldType.SourceAccount);
|
||||
public static readonly DestinationAccount = new TransactionExploreConditionField('Destination Account', TransactionExploreConditionFieldType.DestinationAccount);
|
||||
public static readonly SourceAmount = new TransactionExploreConditionField('Amount', TransactionExploreConditionFieldType.SourceAmount);
|
||||
public static readonly DestinationAmount = new TransactionExploreConditionField('Transfer In Amount', TransactionExploreConditionFieldType.DestinationAmount);
|
||||
public static readonly TransactionTag = new TransactionExploreConditionField('Tags', TransactionExploreConditionFieldType.TransactionTag);
|
||||
public static readonly Description = new TransactionExploreConditionField('Description', TransactionExploreConditionFieldType.Description);
|
||||
|
||||
public readonly name: string;
|
||||
public readonly value: TransactionExploreConditionFieldType;
|
||||
|
||||
private constructor(name: string, value: TransactionExploreConditionFieldType) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
|
||||
TransactionExploreConditionField.allInstances.push(this);
|
||||
TransactionExploreConditionField.allInstancesByValue[value] = this;
|
||||
}
|
||||
|
||||
public static values(): TransactionExploreConditionField[] {
|
||||
return TransactionExploreConditionField.allInstances;
|
||||
}
|
||||
|
||||
public static valueOf(type: string): TransactionExploreConditionField | undefined {
|
||||
return TransactionExploreConditionField.allInstancesByValue[type];
|
||||
}
|
||||
}
|
||||
|
||||
export enum TransactionExploreConditionOperatorType {
|
||||
In = 'in',
|
||||
GreaterThan = 'greaterThan',
|
||||
LessThan = 'lessThan',
|
||||
Equals = 'equals',
|
||||
NotEquals = 'notEquals',
|
||||
Between = 'between',
|
||||
NotBetween = 'notBetween',
|
||||
HasAny = 'hasAny',
|
||||
HasAll = 'hasAll',
|
||||
NotHasAny = 'notHasAny',
|
||||
NotHasAll = 'notHasAll',
|
||||
IsEmpty = 'isEmpty',
|
||||
IsNotEmpty = 'isNotEmpty',
|
||||
Contains = 'contains',
|
||||
NotContains = 'notContains',
|
||||
StartsWith = 'startsWith',
|
||||
NotStartsWith = 'notStartsWith',
|
||||
EndsWith = 'endsWith',
|
||||
NotEndsWith = 'notEndsWith'
|
||||
}
|
||||
|
||||
export class TransactionExploreConditionOperator implements NameValue {
|
||||
private static readonly allInstances: TransactionExploreConditionOperator[] = [];
|
||||
private static readonly allInstancesByValue: Record<string, TransactionExploreConditionOperator> = {};
|
||||
|
||||
public static readonly In = new TransactionExploreConditionOperator('In', TransactionExploreConditionOperatorType.In);
|
||||
public static readonly GreaterThan = new TransactionExploreConditionOperator('Greater than', TransactionExploreConditionOperatorType.GreaterThan);
|
||||
public static readonly LessThan = new TransactionExploreConditionOperator('Less than', TransactionExploreConditionOperatorType.LessThan);
|
||||
public static readonly Equals = new TransactionExploreConditionOperator('Equal to', TransactionExploreConditionOperatorType.Equals);
|
||||
public static readonly NotEquals = new TransactionExploreConditionOperator('Not equal to', TransactionExploreConditionOperatorType.NotEquals);
|
||||
public static readonly Between = new TransactionExploreConditionOperator('Between', TransactionExploreConditionOperatorType.Between);
|
||||
public static readonly NotBetween = new TransactionExploreConditionOperator('Not between', TransactionExploreConditionOperatorType.NotBetween);
|
||||
public static readonly HasAny = new TransactionExploreConditionOperator('Has any', TransactionExploreConditionOperatorType.HasAny);
|
||||
public static readonly HasAll = new TransactionExploreConditionOperator('Has all', TransactionExploreConditionOperatorType.HasAll);
|
||||
public static readonly NotHasAny = new TransactionExploreConditionOperator('Not has any', TransactionExploreConditionOperatorType.NotHasAny);
|
||||
public static readonly NotHasAll = new TransactionExploreConditionOperator('Not has all', TransactionExploreConditionOperatorType.NotHasAll);
|
||||
public static readonly IsEmpty = new TransactionExploreConditionOperator('Is empty', TransactionExploreConditionOperatorType.IsEmpty);
|
||||
public static readonly IsNotEmpty = new TransactionExploreConditionOperator('Is not empty', TransactionExploreConditionOperatorType.IsNotEmpty);
|
||||
public static readonly Contains = new TransactionExploreConditionOperator('Contains', TransactionExploreConditionOperatorType.Contains);
|
||||
public static readonly NotContains = new TransactionExploreConditionOperator('Not contains', TransactionExploreConditionOperatorType.NotContains);
|
||||
public static readonly StartsWith = new TransactionExploreConditionOperator('Starts with', TransactionExploreConditionOperatorType.StartsWith);
|
||||
public static readonly NotStartsWith = new TransactionExploreConditionOperator('Not starts with', TransactionExploreConditionOperatorType.NotStartsWith);
|
||||
public static readonly EndsWith = new TransactionExploreConditionOperator('Ends with', TransactionExploreConditionOperatorType.EndsWith);
|
||||
public static readonly NotEndsWith = new TransactionExploreConditionOperator('Not ends with', TransactionExploreConditionOperatorType.NotEndsWith);
|
||||
|
||||
public readonly name: string;
|
||||
public readonly value: TransactionExploreConditionOperatorType;
|
||||
|
||||
private constructor(name: string, value: TransactionExploreConditionOperatorType) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
|
||||
TransactionExploreConditionOperator.allInstances.push(this);
|
||||
TransactionExploreConditionOperator.allInstancesByValue[value] = this;
|
||||
}
|
||||
|
||||
public static values(): TransactionExploreConditionOperator[] {
|
||||
return TransactionExploreConditionOperator.allInstances;
|
||||
}
|
||||
|
||||
public static valueOf(type: string): TransactionExploreConditionOperator | undefined {
|
||||
return TransactionExploreConditionOperator.allInstancesByValue[type];
|
||||
}
|
||||
}
|
||||
|
||||
export const DEFAULT_TRANSACTION_EXPLORE_DATE_RANGE: DateRange = DateRange.ThisMonth;
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
DEFAULT_TREND_CHART_DATA_RANGE,
|
||||
DEFAULT_ASSET_TRENDS_CHART_DATA_RANGE
|
||||
} from './statistics.ts';
|
||||
import { DEFAULT_TRANSACTION_EXPLORE_DATE_RANGE } from './explore.ts';
|
||||
import { DEFAULT_CURRENCY_CODE } from '@/consts/currency.ts';
|
||||
|
||||
export type ApplicationSettingKey = string;
|
||||
@@ -49,6 +50,9 @@ export interface ApplicationSettings extends BaseApplicationSetting {
|
||||
autoSaveTransactionDraft: string;
|
||||
autoGetCurrentGeoLocation: boolean;
|
||||
alwaysShowTransactionPicturesInMobileTransactionEditPage: boolean;
|
||||
// Insights & Explore Page
|
||||
insightsExploreDefaultDateRangeType: number;
|
||||
timezoneUsedForInsightsExplorePage: number;
|
||||
// Account List Page
|
||||
totalAmountExcludeAccountIds: Record<string, boolean>;
|
||||
// Exchange Rates Data Page
|
||||
@@ -111,6 +115,9 @@ export const ALL_ALLOWED_CLOUD_SYNC_APP_SETTING_KEY_TYPES: Record<string, UserAp
|
||||
'autoSaveTransactionDraft': UserApplicationCloudSettingType.String,
|
||||
'autoGetCurrentGeoLocation': UserApplicationCloudSettingType.Boolean,
|
||||
'alwaysShowTransactionPicturesInMobileTransactionEditPage': UserApplicationCloudSettingType.Boolean,
|
||||
// Insights & Explore Page
|
||||
'insightsExploreDefaultDateRangeType': UserApplicationCloudSettingType.Number,
|
||||
'timezoneUsedForInsightsExplorePage': UserApplicationCloudSettingType.Number,
|
||||
// Account List Page
|
||||
'totalAmountExcludeAccountIds': UserApplicationCloudSettingType.StringBooleanMap,
|
||||
// Exchange Rates Data Page
|
||||
@@ -158,6 +165,9 @@ export const DEFAULT_APPLICATION_SETTINGS: ApplicationSettings = {
|
||||
autoSaveTransactionDraft: 'disabled',
|
||||
autoGetCurrentGeoLocation: false,
|
||||
alwaysShowTransactionPicturesInMobileTransactionEditPage: false,
|
||||
// Insights & Explore Page
|
||||
insightsExploreDefaultDateRangeType: DEFAULT_TRANSACTION_EXPLORE_DATE_RANGE.type,
|
||||
timezoneUsedForInsightsExplorePage: TimezoneTypeForStatistics.Default.type,
|
||||
// Account List Page
|
||||
totalAmountExcludeAccountIds: {},
|
||||
// Exchange Rates Data Page
|
||||
|
||||
Reference in New Issue
Block a user