@zeniai/client-epic-state 5.2.75 → 5.2.76-betaNB1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonStateTypes/common.d.ts +3 -0
- package/lib/commonStateTypes/common.js +10 -1
- package/lib/entity/reconciliationReport/reconciliationReportPayload.d.ts +124 -0
- package/lib/entity/reconciliationReport/reconciliationReportPayload.js +2 -0
- package/lib/entity/reconciliationReport/reconciliationReportReducer.d.ts +7 -0
- package/lib/entity/reconciliationReport/reconciliationReportReducer.js +173 -0
- package/lib/entity/reconciliationReport/reconciliationReportSelector.d.ts +3 -0
- package/lib/entity/reconciliationReport/reconciliationReportSelector.js +10 -0
- package/lib/entity/reconciliationReport/reconciliationReportState.d.ts +133 -0
- package/lib/entity/reconciliationReport/reconciliationReportState.js +15 -0
- package/lib/epic.d.ts +2 -1
- package/lib/epic.js +2 -0
- package/lib/esm/commonStateTypes/common.js +8 -0
- package/lib/esm/entity/reconciliationReport/reconciliationReportPayload.js +1 -0
- package/lib/esm/entity/reconciliationReport/reconciliationReportReducer.js +168 -0
- package/lib/esm/entity/reconciliationReport/reconciliationReportSelector.js +4 -0
- package/lib/esm/entity/reconciliationReport/reconciliationReportState.js +10 -0
- package/lib/esm/epic.js +2 -0
- package/lib/esm/index.js +5 -2
- package/lib/esm/reducer.js +7 -1
- package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +140 -9
- package/lib/esm/view/reconciliationReportView/epic/fetchReconciliationReportEpic.js +29 -0
- package/lib/esm/view/reconciliationReportView/reconciliationReportViewPayload.js +1 -0
- package/lib/esm/view/reconciliationReportView/reconciliationReportViewReducer.js +44 -0
- package/lib/esm/view/reconciliationReportView/reconciliationReportViewSelector.js +10 -0
- package/lib/esm/view/reconciliationReportView/reconciliationReportViewState.js +1 -0
- package/lib/esm/view/taskManager/taskListView/taskListSelector.js +70 -19
- package/lib/index.d.ts +6 -2
- package/lib/index.js +40 -34
- package/lib/reducer.d.ts +2 -0
- package/lib/reducer.js +7 -1
- package/lib/rootStateTypes.d.ts +5 -1
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.d.ts +1 -1
- package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +140 -9
- package/lib/view/reconciliationReportView/epic/fetchReconciliationReportEpic.d.ts +19 -0
- package/lib/view/reconciliationReportView/epic/fetchReconciliationReportEpic.js +33 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewPayload.d.ts +3 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewPayload.js +2 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewReducer.d.ts +13 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewReducer.js +48 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewSelector.d.ts +9 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewSelector.js +13 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewState.d.ts +4 -0
- package/lib/view/reconciliationReportView/reconciliationReportViewState.js +2 -0
- package/lib/view/taskManager/taskListView/taskListSelector.d.ts +13 -2
- package/lib/view/taskManager/taskListView/taskListSelector.js +70 -19
- package/package.json +1 -1
package/lib/reducer.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ declare const reducers: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
139
139
|
profitAndLossState: import("./view/profitAndLoss/profitAndLossState").ProfitAndLossWithForecastState;
|
|
140
140
|
projectListState: import("./view/projectList/projectListState").ProjectListState;
|
|
141
141
|
realTimeApprovalState: import("./view/spendManagement/realTimeApprovalView/realTimeApprovalState").RealTimeApprovalState;
|
|
142
|
+
reconciliationReportViewState: import("./view/reconciliationReportView/reconciliationReportViewState").ReconciliationReportViewState;
|
|
142
143
|
referralViewState: import(".").ReferralViewState;
|
|
143
144
|
reimbursementCardState: import("./view/reimbursementCard/reimbursementCardState").ReimbursementCardState;
|
|
144
145
|
reimbursementConfigState: import("./view/spendManagement/reimbursement/reimbursementConfig/reimbursementConfigState").ReimbursementConfigState;
|
|
@@ -249,6 +250,7 @@ declare const reducers: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
249
250
|
notificationState: import("./entity/notification/notificationState").NotificationState;
|
|
250
251
|
onboardingCustomerState: import("./entity/onboardingCustomer/onboardingCustomerState").OnboardingCustomerState;
|
|
251
252
|
paymentInstrumentState: import("./entity/paymentInstrument/paymentInstrument").PaymentInstrumentState;
|
|
253
|
+
reconciliationReportState: import("./entity/reconciliationReport/reconciliationReportState").ReconciliationReportState;
|
|
252
254
|
recurringBillState: import("./entity/billPay/recurringBills/recurringBillsState").RecurringBillState;
|
|
253
255
|
reimbursementState: import("./entity/reimbursement/reimbursementState").ReimbursementState;
|
|
254
256
|
sectionAccountsViewState: import("./entity/sectionAccountsView/sectionAccountsViewState").SectionAccountsViewState;
|
package/lib/reducer.js
CHANGED
|
@@ -77,10 +77,10 @@ const couponReducer_1 = __importStar(require("./entity/invoicing/coupon/couponRe
|
|
|
77
77
|
const creditNoteReducer_1 = __importStar(require("./entity/invoicing/creditNote/creditNoteReducer"));
|
|
78
78
|
const dunningCaseReducer_1 = __importStar(require("./entity/invoicing/dunningCase/dunningCaseReducer"));
|
|
79
79
|
const invoiceReducer_1 = __importStar(require("./entity/invoicing/invoice/invoiceReducer"));
|
|
80
|
+
const invoicingCatalogReducer_1 = __importStar(require("./entity/invoicing/invoicingCatalog/invoicingCatalogReducer"));
|
|
80
81
|
const invoicingCustomerReducer_1 = __importStar(require("./entity/invoicing/invoicingCustomer/invoicingCustomerReducer"));
|
|
81
82
|
const invoicingSubscriptionReducer_1 = __importStar(require("./entity/invoicing/invoicingSubscription/invoicingSubscriptionReducer"));
|
|
82
83
|
const invoicingTransactionReducer_1 = __importStar(require("./entity/invoicing/invoicingTransaction/invoicingTransactionReducer"));
|
|
83
|
-
const invoicingCatalogReducer_1 = __importStar(require("./entity/invoicing/invoicingCatalog/invoicingCatalogReducer"));
|
|
84
84
|
const jeSchedulesReducer_1 = __importStar(require("./entity/jeSchedules/jeSchedulesReducer"));
|
|
85
85
|
const merchantReducer_1 = __importStar(require("./entity/merchant/merchantReducer"));
|
|
86
86
|
const monthEndCloseChecksReducer_1 = __importStar(require("./entity/monthEndCloseChecks/monthEndCloseChecksReducer"));
|
|
@@ -91,6 +91,7 @@ const paymentAccountReducer_1 = __importStar(require("./entity/paymentAccount/pa
|
|
|
91
91
|
const paymentInstrumentReducer_1 = __importStar(require("./entity/paymentInstrument/paymentInstrumentReducer"));
|
|
92
92
|
const accountingSummaryReducer_1 = __importStar(require("./entity/portfolio/accountingSummary/accountingSummaryReducer"));
|
|
93
93
|
const projectReducer_1 = __importStar(require("./entity/project/projectReducer"));
|
|
94
|
+
const reconciliationReportReducer_1 = __importStar(require("./entity/reconciliationReport/reconciliationReportReducer"));
|
|
94
95
|
const reimbursementReducer_1 = __importStar(require("./entity/reimbursement/reimbursementReducer"));
|
|
95
96
|
const sectionAccountsViewReducer_1 = __importStar(require("./entity/sectionAccountsView/sectionAccountsViewReducer"));
|
|
96
97
|
const sectionClassesViewReducer_1 = __importStar(require("./entity/sectionClassesViewV2/sectionClassesViewReducer"));
|
|
@@ -218,6 +219,7 @@ const profitAndLossClassesViewReducer_1 = __importStar(require("./view/profitAnd
|
|
|
218
219
|
const profitAndLossProjectViewReducer_1 = __importStar(require("./view/profitAndLossProjectView/profitAndLossProjectViewReducer"));
|
|
219
220
|
const projectListReducer_1 = __importStar(require("./view/projectList/projectListReducer"));
|
|
220
221
|
const recommendationReducer_1 = __importStar(require("./view/recommendation/recommendationReducer"));
|
|
222
|
+
const reconciliationReportViewReducer_1 = __importStar(require("./view/reconciliationReportView/reconciliationReportViewReducer"));
|
|
221
223
|
const referralReducer_1 = __importStar(require("./view/referralView/referralReducer"));
|
|
222
224
|
const reimbursementCardReducer_1 = __importStar(require("./view/reimbursementCard/reimbursementCardReducer"));
|
|
223
225
|
const reportUIOptionsReducer_1 = __importStar(require("./view/reportUIOptions/reportUIOptionsReducer"));
|
|
@@ -364,6 +366,7 @@ const initialEntitiesState = {
|
|
|
364
366
|
onboardingCustomerState: onboardingCustomerReducer_1.initialState,
|
|
365
367
|
paymentAccountState: paymentAccountReducer_1.initialState,
|
|
366
368
|
paymentInstrumentState: paymentInstrumentReducer_1.initialState,
|
|
369
|
+
reconciliationReportState: reconciliationReportReducer_1.initialState,
|
|
367
370
|
recurringBillState: recurringBillsReducer_1.initialState,
|
|
368
371
|
reimbursementConfigState: reimbursementConfigReducer_1.initialState,
|
|
369
372
|
reimbursementState: reimbursementReducer_1.initialState,
|
|
@@ -532,6 +535,7 @@ const initialViewsState = {
|
|
|
532
535
|
profitAndLossState: profitAndLossReducer_1.initialState,
|
|
533
536
|
projectListState: projectListReducer_1.initialState,
|
|
534
537
|
realTimeApprovalState: realTimeApprovalReducer_1.initialState,
|
|
538
|
+
reconciliationReportViewState: reconciliationReportViewReducer_1.initialState,
|
|
535
539
|
referralViewState: referralReducer_1.initialState,
|
|
536
540
|
reimbursementCardState: reimbursementCardReducer_1.initialState,
|
|
537
541
|
reimbursementConfigState: reimbursementConfigReducer_1.initialState,
|
|
@@ -650,6 +654,7 @@ const entityReducers = {
|
|
|
650
654
|
onboardingCustomerState: onboardingCustomerReducer_1.default,
|
|
651
655
|
paymentAccountState: paymentAccountReducer_1.default,
|
|
652
656
|
paymentInstrumentState: paymentInstrumentReducer_1.default,
|
|
657
|
+
reconciliationReportState: reconciliationReportReducer_1.default,
|
|
653
658
|
recurringBillState: recurringBillsReducer_1.default,
|
|
654
659
|
reimbursementConfigState: reimbursementConfigReducer_1.default,
|
|
655
660
|
reimbursementState: reimbursementReducer_1.default,
|
|
@@ -818,6 +823,7 @@ const viewReducers = {
|
|
|
818
823
|
profitAndLossState: profitAndLossReducer_1.default,
|
|
819
824
|
projectListState: projectListReducer_1.default,
|
|
820
825
|
realTimeApprovalState: realTimeApprovalReducer_1.default,
|
|
826
|
+
reconciliationReportViewState: reconciliationReportViewReducer_1.default,
|
|
821
827
|
referralViewState: referralReducer_1.default,
|
|
822
828
|
reimbursementCardState: reimbursementCardReducer_1.default,
|
|
823
829
|
reimbursementConfigState: reimbursementConfigReducer_1.default,
|
package/lib/rootStateTypes.d.ts
CHANGED
|
@@ -37,10 +37,10 @@ import { InvoicingCouponState } from './entity/invoicing/coupon/couponState';
|
|
|
37
37
|
import { InvoicingCreditNoteState } from './entity/invoicing/creditNote/creditNoteState';
|
|
38
38
|
import { InvoicingDunningCaseState } from './entity/invoicing/dunningCase/dunningCaseState';
|
|
39
39
|
import { InvoiceState as InvoicingInvoiceState } from './entity/invoicing/invoice/invoiceState';
|
|
40
|
+
import { InvoicingCatalogState } from './entity/invoicing/invoicingCatalog/invoicingCatalogState';
|
|
40
41
|
import { InvoicingCustomerState } from './entity/invoicing/invoicingCustomer/invoicingCustomerState';
|
|
41
42
|
import { InvoicingSubscriptionState } from './entity/invoicing/invoicingSubscription/invoicingSubscriptionState';
|
|
42
43
|
import { InvoicingTransactionState } from './entity/invoicing/invoicingTransaction/invoicingTransactionState';
|
|
43
|
-
import { InvoicingCatalogState } from './entity/invoicing/invoicingCatalog/invoicingCatalogState';
|
|
44
44
|
import { JESchedulesState } from './entity/jeSchedules/jeSchedulesState';
|
|
45
45
|
import { MerchantState } from './entity/merchant/merchant';
|
|
46
46
|
import { MonthEndCloseChecksState } from './entity/monthEndCloseChecks/monthEndCloseChecksState';
|
|
@@ -51,6 +51,7 @@ import { PaymentAccountState } from './entity/paymentAccount/paymentAccountState
|
|
|
51
51
|
import { PaymentInstrumentState } from './entity/paymentInstrument/paymentInstrument';
|
|
52
52
|
import { AccountingSummaryState } from './entity/portfolio/accountingSummary/accountingSummaryState';
|
|
53
53
|
import { ProjectState } from './entity/project/projectState';
|
|
54
|
+
import { ReconciliationReportState } from './entity/reconciliationReport/reconciliationReportState';
|
|
54
55
|
import { ReimbursementState } from './entity/reimbursement/reimbursementState';
|
|
55
56
|
import { SectionAccountsViewState } from './entity/sectionAccountsView/sectionAccountsViewState';
|
|
56
57
|
import { SectionClassesViewStateV2 } from './entity/sectionClassesViewV2/sectionClassesViewState';
|
|
@@ -176,6 +177,7 @@ import { ProfitAndLossClassesViewState } from './view/profitAndLossClassesView/p
|
|
|
176
177
|
import { ProfitAndLossProjectViewState } from './view/profitAndLossProjectView/profitAndLossProjectViewState';
|
|
177
178
|
import { ProjectListState } from './view/projectList/projectListState';
|
|
178
179
|
import { EntityRecommendationState } from './view/recommendation/recommendationState';
|
|
180
|
+
import { ReconciliationReportViewState } from './view/reconciliationReportView/reconciliationReportViewState';
|
|
179
181
|
import { ReferralViewState } from './view/referralView/referralState';
|
|
180
182
|
import { ReimbursementCardState } from './view/reimbursementCard/reimbursementCardState';
|
|
181
183
|
import { ReportUIOptionsState } from './view/reportUIOptions/reportUIOptionsState';
|
|
@@ -321,6 +323,7 @@ export type EntitiesState = {
|
|
|
321
323
|
paymentAccountState: PaymentAccountState;
|
|
322
324
|
paymentInstrumentState: PaymentInstrumentState;
|
|
323
325
|
projectState: ProjectState;
|
|
326
|
+
reconciliationReportState: ReconciliationReportState;
|
|
324
327
|
recurringBillState: RecurringBillState;
|
|
325
328
|
reimbursementConfigState: ReimbursementConfigState;
|
|
326
329
|
reimbursementState: ReimbursementState;
|
|
@@ -489,6 +492,7 @@ export type ViewsState = {
|
|
|
489
492
|
profitAndLossState: ProfitAndLossWithForecastState;
|
|
490
493
|
projectListState: ProjectListState;
|
|
491
494
|
realTimeApprovalState: RealTimeApprovalState;
|
|
495
|
+
reconciliationReportViewState: ReconciliationReportViewState;
|
|
492
496
|
referralViewState: ReferralViewState;
|
|
493
497
|
reimbursementCardState: ReimbursementCardState;
|
|
494
498
|
reimbursementConfigState: ReimbursementConfigState;
|
|
@@ -6,4 +6,4 @@ import { RootState } from '../../../rootStateTypes';
|
|
|
6
6
|
import { ZeniAPI } from '../../../zeniAPI';
|
|
7
7
|
import { fetchCompanyTaskManagerView, updateCompanyTaskManagerViewOnFailure, updateCompanyTaskManagerViewOnSuccess } from '../companyTaskManagerViewReducer';
|
|
8
8
|
export type ActionType = ReturnType<typeof fetchCompanyTaskManagerView> | ReturnType<typeof updateCompanyTaskManagerViewOnSuccess> | ReturnType<typeof updateTasks> | ReturnType<typeof updateTags> | ReturnType<typeof updateCompanyTaskManagerViewOnFailure>;
|
|
9
|
-
export declare const fetchCompanyTaskManagerViewEpic: (actions$: ActionsObservable<ActionType>,
|
|
9
|
+
export declare const fetchCompanyTaskManagerViewEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
|
|
@@ -7,19 +7,41 @@ const sortOrderPayload_1 = require("../../../commonPayloadTypes/sortOrderPayload
|
|
|
7
7
|
const tagReducer_1 = require("../../../entity/tag/tagReducer");
|
|
8
8
|
const taskReducer_1 = require("../../../entity/task/taskReducer");
|
|
9
9
|
const responsePayload_1 = require("../../../responsePayload");
|
|
10
|
+
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
10
11
|
const companyTaskManagerViewReducer_1 = require("../companyTaskManagerViewReducer");
|
|
11
12
|
const DEFAULT_PAGE_SIZE = 100;
|
|
12
|
-
|
|
13
|
+
// Mutates the accumulator rather than spreading it: spreading rebuilds the whole
|
|
14
|
+
// map on every entry, which is O(n^2) over a tenant's tag list.
|
|
15
|
+
const toTagNameByID = (state) => Object.entries(state.tagState.tagByID).reduce((result, [tagId, tag]) => {
|
|
16
|
+
const name = tag?.name;
|
|
17
|
+
if (name != null && name !== '') {
|
|
18
|
+
result[tagId] = name;
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}, {});
|
|
22
|
+
const hasTagCategory = (filters) => (filters?.categories ?? []).some((category) => category.field === 'tag');
|
|
23
|
+
const fetchCompanyTaskManagerViewEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(companyTaskManagerViewReducer_1.fetchCompanyTaskManagerView.match), (0, operators_1.switchMap)((action) => {
|
|
13
24
|
const { from: fromOffset, searchString, sortKey, sortOrder, filters, } = action.payload;
|
|
14
25
|
const queryValue = {
|
|
15
26
|
size: DEFAULT_PAGE_SIZE,
|
|
16
27
|
from: fromOffset,
|
|
17
28
|
global_search: searchString ?? '',
|
|
29
|
+
// TasksEsSearch defaults this to true, which AND-injects an
|
|
30
|
+
// `assignees = <caller>` filter. Cockpit's task list is a cross-tenant
|
|
31
|
+
// view grouped by company (and offers an Assignee filter), so it must
|
|
32
|
+
// NOT be scoped to the operator — otherwise every category filter
|
|
33
|
+
// AND's down to their own tasks and returns nothing. The metrics panel
|
|
34
|
+
// deliberately passes `true`; this list deliberately passes `false`.
|
|
35
|
+
is_filter_by_logged_in_user: false,
|
|
18
36
|
sort_by: toSortKeyPayload(sortKey),
|
|
19
37
|
sort_order: (0, sortOrderPayload_1.getSortOrder)(sortOrder),
|
|
20
38
|
filter_join: filters?.categoryCombinationOperator === 'AND' ? 'and' : 'or',
|
|
21
39
|
...(filters?.categories != null && filters.categories.length > 0
|
|
22
|
-
? {
|
|
40
|
+
? {
|
|
41
|
+
// Only walk the tag map when a tag filter is actually in play;
|
|
42
|
+
// otherwise every dispatch pays for a map nothing reads.
|
|
43
|
+
filter_by: toFilterByPayload(filters, hasTagCategory(filters) ? toTagNameByID(state$.value) : {}),
|
|
44
|
+
}
|
|
23
45
|
: {}),
|
|
24
46
|
task_group_scopes: filters?.taskGroupScopes != null && filters.taskGroupScopes.length > 0
|
|
25
47
|
? filters.taskGroupScopes
|
|
@@ -67,14 +89,123 @@ const toSortKeyPayload = (sortKey) => {
|
|
|
67
89
|
return sortKey;
|
|
68
90
|
}
|
|
69
91
|
};
|
|
70
|
-
|
|
92
|
+
// Cockpit filter-category keys are UI identifiers; the ES index uses its own
|
|
93
|
+
// field names (see TasksEsSearch.get). Anything not listed here already matches
|
|
94
|
+
// the contract (assignees, priority, status, company_id).
|
|
95
|
+
const ES_FIELD_BY_CATEGORY = {
|
|
96
|
+
creationDate: 'create_time',
|
|
97
|
+
dueDate: 'due_date',
|
|
98
|
+
tag: 'tags',
|
|
99
|
+
};
|
|
100
|
+
// ES rejects `is` / `is_not` on date fields — they only accept `between`, whose
|
|
101
|
+
// values are the [start, end] pair the dateRange picker already emits.
|
|
102
|
+
const ES_DATE_FIELDS = new Set(['create_time', 'due_date']);
|
|
103
|
+
// The cockpit date picker hands over ZeniDate objects; once filters have round-
|
|
104
|
+
// tripped through redux they can arrive as ISO or date-only strings instead.
|
|
105
|
+
// Both have to reach ES as instants: `create_time`/`update_time` carry a real
|
|
106
|
+
// timestamp, so a date-only upper bound lands on midnight and drops everything
|
|
107
|
+
// created later that day — a single-day Created filter would return almost
|
|
108
|
+
// nothing, which is the empty state this epic exists to fix.
|
|
109
|
+
// A real check rather than `value as ZeniDate`: the cast would silently lie
|
|
110
|
+
// about a raw Date, a number, or anything else redux hands back, leaving the
|
|
111
|
+
// runtime guard as the only thing standing between us and a crash.
|
|
112
|
+
const isZeniDateLike = (value) => value != null &&
|
|
113
|
+
typeof value.isValid === 'function' &&
|
|
114
|
+
typeof value.format === 'function';
|
|
115
|
+
const CALENDAR_DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
|
|
116
|
+
const toDateBound = (value, edge) => {
|
|
117
|
+
// A bare `YYYY-MM-DD` carries no instant to misread — use it verbatim. This
|
|
118
|
+
// is the only genuinely timezone-proof shape, which is why it is worth a
|
|
119
|
+
// fast path of its own.
|
|
120
|
+
if (typeof value === 'string' && CALENDAR_DATE_ONLY.test(value)) {
|
|
121
|
+
return edge === 'start'
|
|
122
|
+
? `${value}T00:00:00.000Z`
|
|
123
|
+
: `${value}T23:59:59.999Z`;
|
|
124
|
+
}
|
|
125
|
+
// Everything else came from the picker, and the picker emits LOCAL midnight:
|
|
126
|
+
// `ZeniDatePicker` hands react-datepicker's local-midnight Date to
|
|
127
|
+
// `zeniDate(date.toISOString())`. So the instant encodes "midnight on the day
|
|
128
|
+
// the user clicked, in the user's zone" — and the day they clicked is
|
|
129
|
+
// recovered by reading it locally, never in UTC.
|
|
130
|
+
//
|
|
131
|
+
// Reading it in UTC subtracts the offset for every UTC+ operator: clicking
|
|
132
|
+
// "Mar 4" in Asia/Kolkata stores 2026-03-03T18:30:00Z, which is the 3rd in
|
|
133
|
+
// UTC. A single-day filter then returns the wrong day's tasks rather than
|
|
134
|
+
// none, and US-based testing never sees it.
|
|
135
|
+
const parsed = typeof value === 'string' ? (0, zeniDayJS_1.date)(value) : value;
|
|
136
|
+
if (!isZeniDateLike(parsed) || !parsed.isValid()) {
|
|
137
|
+
// Drop the row rather than send garbage: ES rejects the whole request on
|
|
138
|
+
// one bad bound, taking the other filters down with it.
|
|
139
|
+
return '';
|
|
140
|
+
}
|
|
141
|
+
const ymd = parsed.format('YYYY-MM-DD');
|
|
142
|
+
return edge === 'start' ? `${ymd}T00:00:00.000Z` : `${ymd}T23:59:59.999Z`;
|
|
143
|
+
};
|
|
144
|
+
const toFilterByPayload = (filters, tagNameByID) => {
|
|
71
145
|
if (filters.categories == null) {
|
|
72
146
|
return [];
|
|
73
147
|
}
|
|
74
|
-
return filters.categories.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
148
|
+
return filters.categories.flatMap((category) => {
|
|
149
|
+
const categoryField = category.field ?? '';
|
|
150
|
+
const field = ES_FIELD_BY_CATEGORY[categoryField] ?? categoryField;
|
|
151
|
+
// The dropdown is keyed by tagId, but ES matches `tags` on the tag NAME,
|
|
152
|
+
// so resolve through the tag entity this epic itself populates. Unknown ids
|
|
153
|
+
// fall through unchanged rather than being dropped.
|
|
154
|
+
const isDateField = ES_DATE_FIELDS.has(field);
|
|
155
|
+
// `between` is exactly [from, to]. A half-filled picker (one value) makes ES
|
|
156
|
+
// reject the query outright, and a longer array would quietly bind extras to
|
|
157
|
+
// `end` — both land the user back on an unexplained empty page, which is the
|
|
158
|
+
// failure this epic exists to remove. Drop the row instead.
|
|
159
|
+
if (isDateField && category.values.length !== 2) {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
const values = category.values.map((value, index) => {
|
|
163
|
+
if (isDateField) {
|
|
164
|
+
// [from, to] — widen the upper bound to the end of its day.
|
|
165
|
+
return toDateBound(value, index === 0 ? 'start' : 'end');
|
|
166
|
+
}
|
|
167
|
+
const raw = String(value);
|
|
168
|
+
if (field !== 'tags') {
|
|
169
|
+
return raw;
|
|
170
|
+
}
|
|
171
|
+
// An id we cannot resolve would reach ES verbatim and match nothing —
|
|
172
|
+
// another silent empty page. Can happen when a filter is hydrated from the
|
|
173
|
+
// URL before `updateTags` has populated `tagByID`, so keep the value
|
|
174
|
+
// (dropping it would widen the result set) but make it visible in logs.
|
|
175
|
+
const tagName = tagNameByID[raw];
|
|
176
|
+
if (tagName == null) {
|
|
177
|
+
console.debug(`[taskManager] unresolved tagId "${raw}" sent to ES verbatim; expect no matches`);
|
|
178
|
+
}
|
|
179
|
+
return tagName ?? raw;
|
|
180
|
+
});
|
|
181
|
+
// `toDateBound` returns '' for a value it cannot parse. Honour that here:
|
|
182
|
+
// emitting a `between` with an empty bound fails the whole ES query, which
|
|
183
|
+
// takes every OTHER filter in the same request down with it — the silent
|
|
184
|
+
// empty page this epic exists to remove, from one unparseable value that a
|
|
185
|
+
// URL-hydrated filter can supply.
|
|
186
|
+
if (isDateField && values.some((value) => value === '')) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
// ES has no date-exclusion operator: `is`/`is_not` are rejected on date
|
|
190
|
+
// fields, and `between` can only select a range, never exclude one. The
|
|
191
|
+
// operator dropdown still offers "is not" for every category, so an excluded
|
|
192
|
+
// date range would otherwise be sent as a plain `between` — returning exactly
|
|
193
|
+
// the rows the user asked to hide. Drop the row instead: a superset is
|
|
194
|
+
// wrong-but-obvious, an inverted result is wrong-and-invisible.
|
|
195
|
+
if (isDateField && category.matchingOperator !== 'equal') {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
return [
|
|
199
|
+
{
|
|
200
|
+
field,
|
|
201
|
+
operator: isDateField
|
|
202
|
+
? 'between'
|
|
203
|
+
: category.matchingOperator === 'equal'
|
|
204
|
+
? 'is'
|
|
205
|
+
: 'is_not',
|
|
206
|
+
values,
|
|
207
|
+
join: category.valuesCombinationOperator === 'ALL' ? 'and' : 'or',
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
});
|
|
80
211
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ActionsObservable, StateObservable } from 'redux-observable';
|
|
2
|
+
import { updateReconciliationReport } from '../../../entity/reconciliationReport/reconciliationReportReducer';
|
|
3
|
+
import { RootState } from '../../../rootStateTypes';
|
|
4
|
+
import { ZeniAPI } from '../../../zeniAPI';
|
|
5
|
+
import { fetchReconciliationReport, fetchReconciliationReportFailure, fetchReconciliationReportSuccess } from '../reconciliationReportViewReducer';
|
|
6
|
+
export type ActionType = ReturnType<typeof fetchReconciliationReport> | ReturnType<typeof updateReconciliationReport> | ReturnType<typeof fetchReconciliationReportSuccess> | ReturnType<typeof fetchReconciliationReportFailure>;
|
|
7
|
+
export declare const fetchReconciliationReportEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
|
|
8
|
+
payload: import("../../../entity/reconciliationReport/reconciliationReportPayload").ReconciliationReportPayload;
|
|
9
|
+
type: "reconciliationReport/updateReconciliationReport";
|
|
10
|
+
} | {
|
|
11
|
+
payload: string;
|
|
12
|
+
type: "reconciliationReportView/fetchReconciliationReportSuccess";
|
|
13
|
+
} | {
|
|
14
|
+
payload: {
|
|
15
|
+
reconciliationId: import("../../..").ID;
|
|
16
|
+
status: import("../../../zeniAPIStatus").ZeniAPIStatus;
|
|
17
|
+
};
|
|
18
|
+
type: "reconciliationReportView/fetchReconciliationReportFailure";
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchReconciliationReportEpic = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const reconciliationReportReducer_1 = require("../../../entity/reconciliationReport/reconciliationReportReducer");
|
|
7
|
+
const reconciliationReportSelector_1 = require("../../../entity/reconciliationReport/reconciliationReportSelector");
|
|
8
|
+
const responsePayload_1 = require("../../../responsePayload");
|
|
9
|
+
const reconciliationReportViewReducer_1 = require("../reconciliationReportViewReducer");
|
|
10
|
+
const fetchReconciliationReportEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(reconciliationReportViewReducer_1.fetchReconciliationReport.match), (0, operators_1.switchMap)((action) => {
|
|
11
|
+
const { reconciliationId, cacheOverride } = action.payload;
|
|
12
|
+
const cachedReport = (0, reconciliationReportSelector_1.getReconciliationReportByReconciliationId)(state$.value.reconciliationReportState, reconciliationId);
|
|
13
|
+
if (cacheOverride === true || cachedReport == null) {
|
|
14
|
+
return zeniAPI
|
|
15
|
+
.getJSON(`${zeniAPI.apiEndPoints.reconciliationMicroServiceBaseUrl}/2.0/reconciliation/${reconciliationId}/report`)
|
|
16
|
+
.pipe((0, operators_1.mergeMap)((response) => {
|
|
17
|
+
if ((0, responsePayload_1.isSuccessResponse)(response) === true &&
|
|
18
|
+
response.data != null) {
|
|
19
|
+
return (0, rxjs_1.of)((0, reconciliationReportReducer_1.updateReconciliationReport)(response.data), (0, reconciliationReportViewReducer_1.fetchReconciliationReportSuccess)(reconciliationId));
|
|
20
|
+
}
|
|
21
|
+
return (0, rxjs_1.of)((0, reconciliationReportViewReducer_1.fetchReconciliationReportFailure)({
|
|
22
|
+
reconciliationId,
|
|
23
|
+
status: response.status,
|
|
24
|
+
}));
|
|
25
|
+
}), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, reconciliationReportViewReducer_1.fetchReconciliationReportFailure)({
|
|
26
|
+
reconciliationId,
|
|
27
|
+
status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch Reconciliation Report REST API call errored out' +
|
|
28
|
+
JSON.stringify(error)),
|
|
29
|
+
}))));
|
|
30
|
+
}
|
|
31
|
+
return (0, rxjs_1.of)((0, reconciliationReportViewReducer_1.fetchReconciliationReportSuccess)(reconciliationId));
|
|
32
|
+
}));
|
|
33
|
+
exports.fetchReconciliationReportEpic = fetchReconciliationReportEpic;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ID } from '../../commonStateTypes/common';
|
|
2
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
3
|
+
import { ReconciliationReportViewState } from './reconciliationReportViewState';
|
|
4
|
+
export declare const initialState: ReconciliationReportViewState;
|
|
5
|
+
export declare const fetchReconciliationReport: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[reconciliationId: string, cacheOverride?: any], {
|
|
6
|
+
reconciliationId: string;
|
|
7
|
+
cacheOverride: any;
|
|
8
|
+
}, "reconciliationReportView/fetchReconciliationReport", never, never>, fetchReconciliationReportSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "reconciliationReportView/fetchReconciliationReportSuccess">, fetchReconciliationReportFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
9
|
+
reconciliationId: ID;
|
|
10
|
+
status: ZeniAPIStatus;
|
|
11
|
+
}, "reconciliationReportView/fetchReconciliationReportFailure">;
|
|
12
|
+
declare const _default: import("redux").Reducer<ReconciliationReportViewState>;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.fetchReconciliationReportFailure = exports.fetchReconciliationReportSuccess = exports.fetchReconciliationReport = exports.initialState = void 0;
|
|
5
|
+
const toolkit_1 = require("@reduxjs/toolkit");
|
|
6
|
+
const rootActions_1 = require("../../rootActions");
|
|
7
|
+
exports.initialState = {
|
|
8
|
+
fetchReconciliationReportState: {},
|
|
9
|
+
};
|
|
10
|
+
const reconciliationReportView = (0, toolkit_1.createSlice)({
|
|
11
|
+
name: 'reconciliationReportView',
|
|
12
|
+
initialState: exports.initialState,
|
|
13
|
+
reducers: {
|
|
14
|
+
fetchReconciliationReport: {
|
|
15
|
+
prepare(reconciliationId, cacheOverride = false) {
|
|
16
|
+
return { payload: { reconciliationId, cacheOverride } };
|
|
17
|
+
},
|
|
18
|
+
reducer(draft, action) {
|
|
19
|
+
const { reconciliationId } = action.payload;
|
|
20
|
+
draft.fetchReconciliationReportState[reconciliationId] = {
|
|
21
|
+
fetchState: 'In-Progress',
|
|
22
|
+
error: undefined,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
fetchReconciliationReportSuccess(draft, action) {
|
|
27
|
+
const reconciliationId = action.payload;
|
|
28
|
+
draft.fetchReconciliationReportState[reconciliationId] = {
|
|
29
|
+
fetchState: 'Completed',
|
|
30
|
+
error: undefined,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
fetchReconciliationReportFailure(draft, action) {
|
|
34
|
+
const { reconciliationId, status } = action.payload;
|
|
35
|
+
draft.fetchReconciliationReportState[reconciliationId] = {
|
|
36
|
+
fetchState: 'Error',
|
|
37
|
+
error: status,
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
extraReducers: (builder) => {
|
|
42
|
+
builder.addCase(rootActions_1.clearAll, (draft) => {
|
|
43
|
+
Object.assign(draft, exports.initialState);
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
_a = reconciliationReportView.actions, exports.fetchReconciliationReport = _a.fetchReconciliationReport, exports.fetchReconciliationReportSuccess = _a.fetchReconciliationReportSuccess, exports.fetchReconciliationReportFailure = _a.fetchReconciliationReportFailure;
|
|
48
|
+
exports.default = reconciliationReportView.reducer;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FetchState, ID } from '../../commonStateTypes/common';
|
|
2
|
+
import { ReconciliationReport } from '../../entity/reconciliationReport/reconciliationReportState';
|
|
3
|
+
import { ZeniAPIStatus } from '../../responsePayload';
|
|
4
|
+
import { RootState } from '../../rootStateTypes';
|
|
5
|
+
export declare function getReconciliationReport(state: RootState, reconciliationId: ID): {
|
|
6
|
+
fetchState: FetchState;
|
|
7
|
+
fetchError?: ZeniAPIStatus;
|
|
8
|
+
report?: ReconciliationReport;
|
|
9
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReconciliationReport = getReconciliationReport;
|
|
4
|
+
const reconciliationReportSelector_1 = require("../../entity/reconciliationReport/reconciliationReportSelector");
|
|
5
|
+
function getReconciliationReport(state, reconciliationId) {
|
|
6
|
+
const fetchReconciliationReportState = state.reconciliationReportViewState.fetchReconciliationReportState[reconciliationId];
|
|
7
|
+
const report = (0, reconciliationReportSelector_1.getReconciliationReportByReconciliationId)(state.reconciliationReportState, reconciliationId);
|
|
8
|
+
return {
|
|
9
|
+
fetchState: fetchReconciliationReportState?.fetchState ?? 'Not-Started',
|
|
10
|
+
fetchError: fetchReconciliationReportState?.error,
|
|
11
|
+
report,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -38,10 +38,20 @@ export interface TaskListSelectorView extends SelectorView {
|
|
|
38
38
|
userGroupList: UserGroupListSelectorView;
|
|
39
39
|
userList: UserListSelectorView;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Exactly the parts of `TaskListState` the grouping pipeline reads.
|
|
43
|
+
*
|
|
44
|
+
* `TaskListState` also carries `localData` — the current selection and the
|
|
45
|
+
* group name being typed — which changes on every checkbox click and every
|
|
46
|
+
* keystroke. None of the work below looks at it, so naming the real inputs is
|
|
47
|
+
* what lets the pipeline be memoised against them instead of against the whole
|
|
48
|
+
* slice. `TaskListState` still satisfies this, so callers are unaffected.
|
|
49
|
+
*/
|
|
50
|
+
type TaskListGroupingInputs = Pick<TaskListState, 'filters' | 'taskIdsByAssignees' | 'taskIdsByDueDate' | 'taskIdsByGroupsIds' | 'taskIdsByPriority' | 'taskIdsByStatus' | 'taskIdsByTags' | 'uiState'>;
|
|
41
51
|
export declare const getTaskListGroupedByAssignees: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }: {
|
|
42
52
|
addressState: AddressState;
|
|
43
53
|
tagState: TagState;
|
|
44
|
-
taskListState:
|
|
54
|
+
taskListState: TaskListGroupingInputs;
|
|
45
55
|
taskState: TaskState;
|
|
46
56
|
userGroupsState: UserGroupsState;
|
|
47
57
|
userRoleState: UserRoleState;
|
|
@@ -55,7 +65,7 @@ export declare const getTaskListGroupedByAssignees: ({ taskListState, taskState,
|
|
|
55
65
|
export declare const getTaskListGroupedByPriority: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }: {
|
|
56
66
|
addressState: AddressState;
|
|
57
67
|
tagState: TagState;
|
|
58
|
-
taskListState:
|
|
68
|
+
taskListState: TaskListGroupingInputs;
|
|
59
69
|
taskState: TaskState;
|
|
60
70
|
userGroupsState: UserGroupsState;
|
|
61
71
|
userRoleState: UserRoleState;
|
|
@@ -67,3 +77,4 @@ export declare const getTaskListGroupedByPriority: ({ taskListState, taskState,
|
|
|
67
77
|
tasks: TaskWithUserDetails[];
|
|
68
78
|
}[];
|
|
69
79
|
export declare const getAllTasks: (state: RootState, isTaskTemplatesEnabled: boolean) => TaskListSelectorView;
|
|
80
|
+
export {};
|