@zeniai/client-epic-state 5.2.75 → 5.2.76

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.
@@ -29,3 +29,6 @@ export interface FullName {
29
29
  lastName: string;
30
30
  }
31
31
  export declare const getUnderScoreKey: (keys: string[]) => string;
32
+ /** Early-exit emptiness check: `Object.keys(x).length > 0` allocates an array
33
+ * on every call, and this one runs inside selector inputs. */
34
+ export declare const hasAnyKey: (record: object) => boolean;
@@ -1,9 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUnderScoreKey = exports.toCompletionStatusType = void 0;
3
+ exports.hasAnyKey = exports.getUnderScoreKey = exports.toCompletionStatusType = void 0;
4
4
  const stringToUnion_1 = require("./stringToUnion");
5
5
  const COMPLETION_STATUS_TYPES = ['incomplete', 'complete'];
6
6
  const toCompletionStatusType = (v) => (0, stringToUnion_1.stringToUnion)(v, COMPLETION_STATUS_TYPES);
7
7
  exports.toCompletionStatusType = toCompletionStatusType;
8
8
  const getUnderScoreKey = (keys) => keys.join('_');
9
9
  exports.getUnderScoreKey = getUnderScoreKey;
10
+ /** Early-exit emptiness check: `Object.keys(x).length > 0` allocates an array
11
+ * on every call, and this one runs inside selector inputs. */
12
+ const hasAnyKey = (record) => {
13
+ for (const _key in record) {
14
+ return true;
15
+ }
16
+ return false;
17
+ };
18
+ exports.hasAnyKey = hasAnyKey;
@@ -2,3 +2,11 @@ import { stringToUnion } from './stringToUnion';
2
2
  const COMPLETION_STATUS_TYPES = ['incomplete', 'complete'];
3
3
  export const toCompletionStatusType = (v) => stringToUnion(v, COMPLETION_STATUS_TYPES);
4
4
  export const getUnderScoreKey = (keys) => keys.join('_');
5
+ /** Early-exit emptiness check: `Object.keys(x).length > 0` allocates an array
6
+ * on every call, and this one runs inside selector inputs. */
7
+ export const hasAnyKey = (record) => {
8
+ for (const _key in record) {
9
+ return true;
10
+ }
11
+ return false;
12
+ };
package/lib/esm/index.js CHANGED
@@ -416,7 +416,7 @@ import { allTaskPriority, allTaskStatus, getTaskDetail, } from './view/taskManag
416
416
  import { createTaskFromTaskGroupTemplate } from './view/taskManager/taskGroupTemplateView/taskGroupTemplateViewReducer';
417
417
  import { createNewTaskGroup, deleteTaskGroup, fetchAllTaskGroups, updateTaskGroupName, } from './view/taskManager/taskGroupView/taskGroupViewReducer';
418
418
  import { ALL_TASK_LIST_TABS, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, toDueDateGroupKeyType, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict, } from './view/taskManager/taskListView/taskList';
419
- import { bulkUpdateTaskList, dragNDropTasks, fetchTaskListPage, initiateTaskListLocalData, removeTaskFromList, updateTaskFilters, updateTaskFromListView, updateTaskListLocalData, updateTaskListSearchText, updateTaskListTab, updateTaskListUIState, } from './view/taskManager/taskListView/taskListReducer';
419
+ import { bulkUpdateTaskList, dragNDropTasks, fetchTaskList, fetchTaskListPage, initiateTaskListLocalData, removeTaskFromList, updateTaskFilters, updateTaskFromListView, updateTaskListLocalData, updateTaskListSearchText, updateTaskListTab, updateTaskListUIState, } from './view/taskManager/taskListView/taskListReducer';
420
420
  import { getAllTasks, } from './view/taskManager/taskListView/taskListSelector';
421
421
  import { getDueDateValueFromDueDateGroupId, getTaskUpdates, sortSubtasks, } from './view/taskManager/taskListView/taskListViewHelpers';
422
422
  import { fetchTasksCard } from './view/tasksCard/tasksCardReducer';
@@ -671,7 +671,7 @@ export { fetchGlobalMerchantRecommendation, createGlobalMerchant, updateCreateGl
671
671
  export { approveVendorGlobalReview, rejectVendorGlobalReview, fetchVendorGlobalReviewView, updateSelectedGlobalMerchant, updateVendorGlobalReviewViewUIState, getVendorGlobalReviewView, getTenantMerchantByMerchantId, toVendorGlobalReviewColumnSortKeyType, updateVendorGlobalReviewViewLocalData, };
672
672
  export { fetchArAging, updateArAgingUIState, fetchArAgingDetail, updateArAgingDetailUIState, getArAgingReport, getArAgingDetailForCustomer, updateArAgingNodeCollapseState, };
673
673
  export { toRecurringBillFrequency, toRecurringBillFrequencyStrict, };
674
- export { getTaskGroupById, getAllTasks, fetchTaskListPage, getTaskDetail, fetchTaskDetailPage, saveTaskUpdatesToLocalStore, saveTaskDetail, createSubTask, resetSubTaskCreateStatus, fetchSubTasks, archiveTask, fetchCannedResponses, saveCannedResponse, deleteCannedResponse, getCannedResponsesView, updateTaskListSearchText, updateTaskListUIState, allTaskStatus, allTaskPriority, updateTaskFilters, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, deleteTask, discardTaskUpdatesInLocalStore, bulkUpdateTaskList, createNewTaskGroup, initiateTaskListLocalData, deleteTaskGroup, updateTaskListLocalData, dragNDropTasks, updateTaskGroupName, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict, getTaskUpdates, sortSubtasks, fetchAllTaskGroups, initialTaskDetail, getDueDateValueFromDueDateGroupId, toPriorityCodeType, toTaskStatusCodeType, toDueDateGroupKeyType, updateTaskFromListView, updateTaskListTab, removeTaskFromList, snoozeTask, unsnoozeTask, convertHHMMStrToMinutes, initialTaskDetailLocalData, ALL_TASK_LIST_TABS, };
674
+ export { getTaskGroupById, getAllTasks, fetchTaskList, fetchTaskListPage, getTaskDetail, fetchTaskDetailPage, saveTaskUpdatesToLocalStore, saveTaskDetail, createSubTask, resetSubTaskCreateStatus, fetchSubTasks, archiveTask, fetchCannedResponses, saveCannedResponse, deleteCannedResponse, getCannedResponsesView, updateTaskListSearchText, updateTaskListUIState, allTaskStatus, allTaskPriority, updateTaskFilters, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, deleteTask, discardTaskUpdatesInLocalStore, bulkUpdateTaskList, createNewTaskGroup, initiateTaskListLocalData, deleteTaskGroup, updateTaskListLocalData, dragNDropTasks, updateTaskGroupName, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict, getTaskUpdates, sortSubtasks, fetchAllTaskGroups, initialTaskDetail, getDueDateValueFromDueDateGroupId, toPriorityCodeType, toTaskStatusCodeType, toDueDateGroupKeyType, updateTaskFromListView, updateTaskListTab, removeTaskFromList, snoozeTask, unsnoozeTask, convertHHMMStrToMinutes, initialTaskDetailLocalData, ALL_TASK_LIST_TABS, };
675
675
  export { getAllTags, fetchTagList, createTag, deleteTag, };
676
676
  export { getAllCardsAndBankPaymentMethods, createCardSetupIntent, confirmCardSetupIntent, addCardPaymentSource, fetchPaymentSources, resetCardPaymentErrorStatuses, clearCardPaymentView, };
677
677
  export { getAuditReportGroupViewSelectorView, getAuditRuleGroupViewSelectorView, getUserFromAllUsers, fetchAuditRuleGroupView, fetchAuditReportGroupView, saveReasonForAuditRule, clearAuditReportGroupViewByCompanyId, };
@@ -4,19 +4,41 @@ import { getSortOrder } from '../../../commonPayloadTypes/sortOrderPayload';
4
4
  import { updateTags } from '../../../entity/tag/tagReducer';
5
5
  import { updateTasks } from '../../../entity/task/taskReducer';
6
6
  import { createZeniAPIStatus, isSuccessResponse } from '../../../responsePayload';
7
+ import { date as toZeniDate } from '../../../zeniDayJS';
7
8
  import { fetchCompanyTaskManagerView, updateCompanyTaskManagerViewOnFailure, updateCompanyTaskManagerViewOnSuccess, } from '../companyTaskManagerViewReducer';
8
9
  const DEFAULT_PAGE_SIZE = 100;
9
- export const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => actions$.pipe(filter(fetchCompanyTaskManagerView.match), switchMap((action) => {
10
+ // Mutates the accumulator rather than spreading it: spreading rebuilds the whole
11
+ // map on every entry, which is O(n^2) over a tenant's tag list.
12
+ const toTagNameByID = (state) => Object.entries(state.tagState.tagByID).reduce((result, [tagId, tag]) => {
13
+ const name = tag?.name;
14
+ if (name != null && name !== '') {
15
+ result[tagId] = name;
16
+ }
17
+ return result;
18
+ }, {});
19
+ const hasTagCategory = (filters) => (filters?.categories ?? []).some((category) => category.field === 'tag');
20
+ export const fetchCompanyTaskManagerViewEpic = (actions$, state$, zeniAPI) => actions$.pipe(filter(fetchCompanyTaskManagerView.match), switchMap((action) => {
10
21
  const { from: fromOffset, searchString, sortKey, sortOrder, filters, } = action.payload;
11
22
  const queryValue = {
12
23
  size: DEFAULT_PAGE_SIZE,
13
24
  from: fromOffset,
14
25
  global_search: searchString ?? '',
26
+ // TasksEsSearch defaults this to true, which AND-injects an
27
+ // `assignees = <caller>` filter. Cockpit's task list is a cross-tenant
28
+ // view grouped by company (and offers an Assignee filter), so it must
29
+ // NOT be scoped to the operator — otherwise every category filter
30
+ // AND's down to their own tasks and returns nothing. The metrics panel
31
+ // deliberately passes `true`; this list deliberately passes `false`.
32
+ is_filter_by_logged_in_user: false,
15
33
  sort_by: toSortKeyPayload(sortKey),
16
34
  sort_order: getSortOrder(sortOrder),
17
35
  filter_join: filters?.categoryCombinationOperator === 'AND' ? 'and' : 'or',
18
36
  ...(filters?.categories != null && filters.categories.length > 0
19
- ? { filter_by: toFilterByPayload(filters) }
37
+ ? {
38
+ // Only walk the tag map when a tag filter is actually in play;
39
+ // otherwise every dispatch pays for a map nothing reads.
40
+ filter_by: toFilterByPayload(filters, hasTagCategory(filters) ? toTagNameByID(state$.value) : {}),
41
+ }
20
42
  : {}),
21
43
  task_group_scopes: filters?.taskGroupScopes != null && filters.taskGroupScopes.length > 0
22
44
  ? filters.taskGroupScopes
@@ -63,14 +85,123 @@ const toSortKeyPayload = (sortKey) => {
63
85
  return sortKey;
64
86
  }
65
87
  };
66
- const toFilterByPayload = (filters) => {
88
+ // Cockpit filter-category keys are UI identifiers; the ES index uses its own
89
+ // field names (see TasksEsSearch.get). Anything not listed here already matches
90
+ // the contract (assignees, priority, status, company_id).
91
+ const ES_FIELD_BY_CATEGORY = {
92
+ creationDate: 'create_time',
93
+ dueDate: 'due_date',
94
+ tag: 'tags',
95
+ };
96
+ // ES rejects `is` / `is_not` on date fields — they only accept `between`, whose
97
+ // values are the [start, end] pair the dateRange picker already emits.
98
+ const ES_DATE_FIELDS = new Set(['create_time', 'due_date']);
99
+ // The cockpit date picker hands over ZeniDate objects; once filters have round-
100
+ // tripped through redux they can arrive as ISO or date-only strings instead.
101
+ // Both have to reach ES as instants: `create_time`/`update_time` carry a real
102
+ // timestamp, so a date-only upper bound lands on midnight and drops everything
103
+ // created later that day — a single-day Created filter would return almost
104
+ // nothing, which is the empty state this epic exists to fix.
105
+ // A real check rather than `value as ZeniDate`: the cast would silently lie
106
+ // about a raw Date, a number, or anything else redux hands back, leaving the
107
+ // runtime guard as the only thing standing between us and a crash.
108
+ const isZeniDateLike = (value) => value != null &&
109
+ typeof value.isValid === 'function' &&
110
+ typeof value.format === 'function';
111
+ const CALENDAR_DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
112
+ const toDateBound = (value, edge) => {
113
+ // A bare `YYYY-MM-DD` carries no instant to misread — use it verbatim. This
114
+ // is the only genuinely timezone-proof shape, which is why it is worth a
115
+ // fast path of its own.
116
+ if (typeof value === 'string' && CALENDAR_DATE_ONLY.test(value)) {
117
+ return edge === 'start'
118
+ ? `${value}T00:00:00.000Z`
119
+ : `${value}T23:59:59.999Z`;
120
+ }
121
+ // Everything else came from the picker, and the picker emits LOCAL midnight:
122
+ // `ZeniDatePicker` hands react-datepicker's local-midnight Date to
123
+ // `zeniDate(date.toISOString())`. So the instant encodes "midnight on the day
124
+ // the user clicked, in the user's zone" — and the day they clicked is
125
+ // recovered by reading it locally, never in UTC.
126
+ //
127
+ // Reading it in UTC subtracts the offset for every UTC+ operator: clicking
128
+ // "Mar 4" in Asia/Kolkata stores 2026-03-03T18:30:00Z, which is the 3rd in
129
+ // UTC. A single-day filter then returns the wrong day's tasks rather than
130
+ // none, and US-based testing never sees it.
131
+ const parsed = typeof value === 'string' ? toZeniDate(value) : value;
132
+ if (!isZeniDateLike(parsed) || !parsed.isValid()) {
133
+ // Drop the row rather than send garbage: ES rejects the whole request on
134
+ // one bad bound, taking the other filters down with it.
135
+ return '';
136
+ }
137
+ const ymd = parsed.format('YYYY-MM-DD');
138
+ return edge === 'start' ? `${ymd}T00:00:00.000Z` : `${ymd}T23:59:59.999Z`;
139
+ };
140
+ const toFilterByPayload = (filters, tagNameByID) => {
67
141
  if (filters.categories == null) {
68
142
  return [];
69
143
  }
70
- return filters.categories.map((category) => ({
71
- field: category.field ?? '',
72
- operator: category.matchingOperator === 'equal' ? 'is' : 'is_not',
73
- values: category.values.map((v) => String(v)),
74
- join: category.valuesCombinationOperator === 'ALL' ? 'and' : 'or',
75
- }));
144
+ return filters.categories.flatMap((category) => {
145
+ const categoryField = category.field ?? '';
146
+ const field = ES_FIELD_BY_CATEGORY[categoryField] ?? categoryField;
147
+ // The dropdown is keyed by tagId, but ES matches `tags` on the tag NAME,
148
+ // so resolve through the tag entity this epic itself populates. Unknown ids
149
+ // fall through unchanged rather than being dropped.
150
+ const isDateField = ES_DATE_FIELDS.has(field);
151
+ // `between` is exactly [from, to]. A half-filled picker (one value) makes ES
152
+ // reject the query outright, and a longer array would quietly bind extras to
153
+ // `end` — both land the user back on an unexplained empty page, which is the
154
+ // failure this epic exists to remove. Drop the row instead.
155
+ if (isDateField && category.values.length !== 2) {
156
+ return [];
157
+ }
158
+ const values = category.values.map((value, index) => {
159
+ if (isDateField) {
160
+ // [from, to] — widen the upper bound to the end of its day.
161
+ return toDateBound(value, index === 0 ? 'start' : 'end');
162
+ }
163
+ const raw = String(value);
164
+ if (field !== 'tags') {
165
+ return raw;
166
+ }
167
+ // An id we cannot resolve would reach ES verbatim and match nothing —
168
+ // another silent empty page. Can happen when a filter is hydrated from the
169
+ // URL before `updateTags` has populated `tagByID`, so keep the value
170
+ // (dropping it would widen the result set) but make it visible in logs.
171
+ const tagName = tagNameByID[raw];
172
+ if (tagName == null) {
173
+ console.debug(`[taskManager] unresolved tagId "${raw}" sent to ES verbatim; expect no matches`);
174
+ }
175
+ return tagName ?? raw;
176
+ });
177
+ // `toDateBound` returns '' for a value it cannot parse. Honour that here:
178
+ // emitting a `between` with an empty bound fails the whole ES query, which
179
+ // takes every OTHER filter in the same request down with it — the silent
180
+ // empty page this epic exists to remove, from one unparseable value that a
181
+ // URL-hydrated filter can supply.
182
+ if (isDateField && values.some((value) => value === '')) {
183
+ return [];
184
+ }
185
+ // ES has no date-exclusion operator: `is`/`is_not` are rejected on date
186
+ // fields, and `between` can only select a range, never exclude one. The
187
+ // operator dropdown still offers "is not" for every category, so an excluded
188
+ // date range would otherwise be sent as a plain `between` — returning exactly
189
+ // the rows the user asked to hide. Drop the row instead: a superset is
190
+ // wrong-but-obvious, an inverted result is wrong-and-invisible.
191
+ if (isDateField && category.matchingOperator !== 'equal') {
192
+ return [];
193
+ }
194
+ return [
195
+ {
196
+ field,
197
+ operator: isDateField
198
+ ? 'between'
199
+ : category.matchingOperator === 'equal'
200
+ ? 'is'
201
+ : 'is_not',
202
+ values,
203
+ join: category.valuesCombinationOperator === 'ALL' ? 'and' : 'or',
204
+ },
205
+ ];
206
+ });
76
207
  };
@@ -1,6 +1,7 @@
1
1
  import { createSelector } from '@reduxjs/toolkit';
2
2
  import orderBy from 'lodash/orderBy';
3
3
  import { getSortOrder, } from '../../../commonPayloadTypes/sortOrderPayload';
4
+ import { hasAnyKey, } from '../../../commonStateTypes/common';
4
5
  import { reduceAnyFetchState } from '../../../commonStateTypes/reduceFetchState';
5
6
  import { getTagsByIds } from '../../../entity/tag/tagSelector';
6
7
  import { getTaskById } from '../../../entity/task/taskSelector';
@@ -17,14 +18,18 @@ import { DUE_DATE_GROUP_KEYS, } from './taskList';
17
18
  import { getCategoryValueForTaskList } from './taskListFilterHelpers';
18
19
  const sortTasksList = (tagState, tasksList, sortKey, sortOrder) => {
19
20
  const tasksInOrder = orderBy(tasksList, (task) => {
20
- const tagsByIds = getTagsByIds(tagState, task.tagIds);
21
21
  switch (sortKey) {
22
22
  case 'dueDate':
23
23
  return task.dueDate;
24
24
  case 'creationDate':
25
25
  return task.createTime;
26
26
  case 'tag':
27
- return tagsByIds[0]?.name ?? ''; // only one tag is supported
27
+ // Resolved HERE, not above the switch. Hoisted, it allocated a fresh
28
+ // array per task on every sort key, which made `tagState` a real
29
+ // dependency of the whole pipeline: tags arriving after first paint
30
+ // then rebuilt every group and re-rendered every row, moving that
31
+ // work out from behind the skeleton and into the user's hands.
32
+ return getTagsByIds(tagState, task.tagIds)[0]?.name ?? ''; // only one tag is supported
28
33
  case 'status':
29
34
  return task.status.name;
30
35
  case 'priority':
@@ -69,8 +74,7 @@ const getTasksWithUserDetails = ({ taskListState, taskState, userState, userRole
69
74
  const sortedTaskList = sortTasksList(tagState, filteredTaskList, sortKey, sortOrder);
70
75
  return sortedTaskList;
71
76
  };
72
- const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupViewState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
73
- const { taskGroupsIds } = taskGroupViewState;
77
+ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupsIds, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
74
78
  const taskGroupsWithTasksList = taskGroupsIds
75
79
  .map((taskGroupId) => {
76
80
  const taskGroup = getTaskGroupById(taskGroupState, taskGroupId);
@@ -112,6 +116,7 @@ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupStat
112
116
  if (defaultTaskGroup != null) {
113
117
  sortedTaskGroupsWithTasksList.push(defaultTaskGroup);
114
118
  }
119
+ // Also hides deleted groups, which are empty as a side effect.
115
120
  return sortedTaskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
116
121
  };
117
122
  export const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
@@ -241,7 +246,7 @@ const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, user
241
246
  });
242
247
  return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
243
248
  };
244
- const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupViewState, tagState, userGroupsState, }) => {
249
+ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState, }) => {
245
250
  const { groupByKey } = taskListState.uiState;
246
251
  if (groupByKey === 'groupName') {
247
252
  return getTaskListGroupedByGroupName({
@@ -251,7 +256,7 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
251
256
  userRoleState,
252
257
  addressState,
253
258
  taskGroupState,
254
- taskGroupViewState,
259
+ taskGroupsIds,
255
260
  tagState,
256
261
  userGroupsState,
257
262
  });
@@ -310,24 +315,70 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
310
315
  userGroupsState,
311
316
  });
312
317
  };
313
- export const getAllTasks = createSelector((state) => state.taskListState, (state) => state.taskState, (state) => state.userState, (state) => state.userRoleState, (state) => state.userListViewState, (state) => state.addressState, (state) => state.taskGroupState, (state) => state.taskGroupViewState, (state) => state.tagViewState, (state) => state.tagState, (state) => state.taskGroupTemplateState, (state) => state.taskGroupTemplateViewState, (state) => state.userGroupsState, (state) => state.userGroupListViewState, (_state, isTaskTemplatesEnabled) => isTaskTemplatesEnabled, (taskListState, taskState, userState, userRoleState, userListViewState, addressState, taskGroupState, taskGroupViewState, tagViewState, tagState, taskGroupTemplateState, taskGroupTemplateViewState, userGroupsState, userGroupListViewState, isTaskTemplatesEnabled) => {
318
+ /**
319
+ * Tags are STRUCTURAL only when they name a group or order the rows. Anywhere
320
+ * else they are decoration on a row that has already rendered.
321
+ */
322
+ const tagsAreStructural = (uiState) => uiState.groupByKey === 'tag' || uiState.sortKey === 'tag';
323
+ /** One frozen instance, so the "tags are not structural" input never changes. */
324
+ const EMPTY_TAG_STATE = { tagByID: {} };
325
+ /** Inputs are listed field by field, not as the slice: immer keeps each one
326
+ * referentially stable when `localData` changes, so the memo holds. */
327
+ const getTaskGroupsWithTaskListMemoized = createSelector((state) => state.taskListState.uiState, (state) => state.taskListState.filters, (state) => state.taskListState.taskIdsByGroupsIds, (state) => state.taskListState.taskIdsByAssignees, (state) => state.taskListState.taskIdsByPriority, (state) => state.taskListState.taskIdsByStatus, (state) => state.taskListState.taskIdsByTags, (state) => state.taskListState.taskIdsByDueDate, (state) => state.taskState, (state) => state.userState, (state) => state.userRoleState, (state) => state.addressState, (state) => state.taskGroupState,
328
+ // `taskGroupsIds`, not the whole slice. `TaskGroupViewState` also carries
329
+ // taskGroupCreationStatus / DeleteStatus / UpdateStatus and fetchState, and
330
+ // none of them reach the board — but each transition produces a fresh slice
331
+ // reference, so an inline group rename alone rebuilt the entire grouped list
332
+ // twice (In-Progress, then Completed). That is the same needless rebuild this
333
+ // change removes for the other slices.
334
+ (state) => state.taskGroupViewState.taskGroupsIds,
335
+ // Only when tags are STRUCTURAL — they name a group or order the rows.
336
+ // Otherwise a stable empty slice, so tags landing after first paint cannot
337
+ // invalidate this memo and rebuild a board the user is already using.
338
+ (state) => tagsAreStructural(state.taskListState.uiState)
339
+ ? state.tagState
340
+ : EMPTY_TAG_STATE, (state) => state.userGroupsState, (uiState, filters, taskIdsByGroupsIds, taskIdsByAssignees, taskIdsByPriority, taskIdsByStatus, taskIdsByTags, taskIdsByDueDate, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState) => getTaskGroupsWithTaskList({
341
+ taskListState: {
342
+ uiState,
343
+ filters,
344
+ taskIdsByGroupsIds,
345
+ taskIdsByAssignees,
346
+ taskIdsByPriority,
347
+ taskIdsByStatus,
348
+ taskIdsByTags,
349
+ taskIdsByDueDate,
350
+ },
351
+ taskState,
352
+ userState,
353
+ userRoleState,
354
+ addressState,
355
+ taskGroupState,
356
+ taskGroupsIds,
357
+ tagState,
358
+ userGroupsState,
359
+ }));
360
+ export const getAllTasks = createSelector(
361
+ // `taskState`, `taskGroupState`, `addressState` and `tagState` are gone from
362
+ // here: the grouped list was their only consumer and it is memoised
363
+ // separately now, so a tag edit or an address arriving no longer rebuilds
364
+ // this view.
365
+ (state) => state.taskListState, (state) => state.userState, (state) => state.userRoleState, (state) => state.userListViewState, (state) => state.taskGroupViewState, (state) => state.tagViewState,
366
+ // A BOOLEAN, not the tag slice: reselect compares primitives by value, so
367
+ // this invalidates only when the map goes empty <-> non-empty.
368
+ (state) => hasAnyKey(state.tagState.tagByID), (state) => state.taskGroupTemplateState, (state) => state.taskGroupTemplateViewState, (state) => state.userGroupsState, (state) => state.userGroupListViewState, getTaskGroupsWithTaskListMemoized, (_state, isTaskTemplatesEnabled) => isTaskTemplatesEnabled, (taskListState, userState, userRoleState, userListViewState, taskGroupViewState, tagViewState, hasAnyTag, taskGroupTemplateState, taskGroupTemplateViewState, userGroupsState, userGroupListViewState, taskGroupsWithTasksList, isTaskTemplatesEnabled) => {
314
369
  const { localData } = taskListState;
315
- const taskGroupsWithTasksList = getTaskGroupsWithTaskList({
316
- taskListState,
317
- taskState,
318
- userState,
319
- userRoleState,
320
- addressState,
321
- taskGroupState,
322
- taskGroupViewState,
323
- tagState,
324
- userGroupsState,
325
- });
370
+ // Only the data the list is BUILT from. Tags decorate a row that can
371
+ // already be drawn.
326
372
  const fetchStateVariables = [
327
373
  taskListState,
328
374
  taskGroupViewState,
329
- tagViewState,
330
375
  ];
376
+ // Structural tags are waited on. A failed fetch is bypassed only when tags
377
+ // are already in the store, because then the headers still render.
378
+ if (tagsAreStructural(taskListState.uiState) &&
379
+ !(hasAnyTag && tagViewState.fetchState === 'Error')) {
380
+ fetchStateVariables.push(tagViewState);
381
+ }
331
382
  if (isTaskTemplatesEnabled) {
332
383
  fetchStateVariables.push(taskGroupTemplateViewState);
333
384
  }
package/lib/index.d.ts CHANGED
@@ -629,7 +629,7 @@ import { TaskDetailSelectorView, allTaskPriority, allTaskStatus, getTaskDetail }
629
629
  import { createTaskFromTaskGroupTemplate } from './view/taskManager/taskGroupTemplateView/taskGroupTemplateViewReducer';
630
630
  import { createNewTaskGroup, deleteTaskGroup, fetchAllTaskGroups, updateTaskGroupName } from './view/taskManager/taskGroupView/taskGroupViewReducer';
631
631
  import { ALL_TASK_LIST_TABS, DueDateGroupKey, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, TaskFilterCategory, TaskGroupKey, TaskListFilterCategoryField, TaskListFilters, TaskListLocalData, TaskListTab, TaskListUIState, TaskListViewSortKey, toDueDateGroupKeyType, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict } from './view/taskManager/taskListView/taskList';
632
- import { bulkUpdateTaskList, dragNDropTasks, fetchTaskListPage, initiateTaskListLocalData, removeTaskFromList, updateTaskFilters, updateTaskFromListView, updateTaskListLocalData, updateTaskListSearchText, updateTaskListTab, updateTaskListUIState } from './view/taskManager/taskListView/taskListReducer';
632
+ import { bulkUpdateTaskList, dragNDropTasks, fetchTaskList, fetchTaskListPage, initiateTaskListLocalData, removeTaskFromList, updateTaskFilters, updateTaskFromListView, updateTaskListLocalData, updateTaskListSearchText, updateTaskListTab, updateTaskListUIState } from './view/taskManager/taskListView/taskListReducer';
633
633
  import { TaskGroupWithTasksList, TaskListSelectorView, TaskWithUserDetails, getAllTasks } from './view/taskManager/taskListView/taskListSelector';
634
634
  import { SubtaskSortKey, SubtaskSortOrder, getDueDateValueFromDueDateGroupId, getTaskUpdates, sortSubtasks } from './view/taskManager/taskListView/taskListViewHelpers';
635
635
  import { fetchTasksCard } from './view/tasksCard/tasksCardReducer';
@@ -961,7 +961,7 @@ export { fetchGlobalMerchantRecommendation, createGlobalMerchant, updateCreateGl
961
961
  export { approveVendorGlobalReview, rejectVendorGlobalReview, fetchVendorGlobalReviewView, updateSelectedGlobalMerchant, updateVendorGlobalReviewViewUIState, getVendorGlobalReviewView, getTenantMerchantByMerchantId, toVendorGlobalReviewColumnSortKeyType, VendorGlobalReview, VendorGlobalReviewViewUIState, VendorGlobalReviewViewColumnSortKey, VendorGlobalReviewViewSelectorView, VendorGlobalReviewViewState, VendorGlobalReviewViewLocalData, updateVendorGlobalReviewViewLocalData, GlobalReviewPageCurrentSelectionByColumn, GlobalRecommendationFetchSource, };
962
962
  export { fetchArAging, updateArAgingUIState, fetchArAgingDetail, updateArAgingDetailUIState, ArAgingReport, ArAgingDetail, NestedAgingBalancesByCustomer, getArAgingReport, getArAgingDetailForCustomer, updateArAgingNodeCollapseState, };
963
963
  export { toRecurringBillFrequency, toRecurringBillFrequencyStrict, RecurringBillFrequency, RecurringBillDetail, RecurringBillConfig, RecurringBillStatus, RecurringBillPaymentStatus, };
964
- export { Task, TaskPayload, TaskListSelectorView, TaskWithUserDetails, TaskListViewSortKey, TaskListUIState, TaskDetailSelectorView, EditTaskLocalData, TaskStatusCodeType, PriorityCodeType, getTaskGroupById, TaskStatus, TaskPriority, TaskCodeType, getAllTasks, fetchTaskListPage, getTaskDetail, fetchTaskDetailPage, saveTaskUpdatesToLocalStore, saveTaskDetail, createSubTask, resetSubTaskCreateStatus, fetchSubTasks, CreateSubTaskPayload, archiveTask, CannedResponse, CannedResponsesViewState, fetchCannedResponses, saveCannedResponse, deleteCannedResponse, getCannedResponsesView, updateTaskListSearchText, updateTaskListUIState, allTaskStatus, allTaskPriority, TaskListFilters, updateTaskFilters, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, TaskListFilterCategoryField, deleteTask, discardTaskUpdatesInLocalStore, TaskFilterCategory, TaskType, TaskGroupWithTasksList, TaskListLocalData, bulkUpdateTaskList, createNewTaskGroup, initiateTaskListLocalData, deleteTaskGroup, updateTaskListLocalData, dragNDropTasks, updateTaskGroupName, TaskGroupState, TaskGroupKey, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict, SubtaskSortKey, SubtaskSortOrder, getTaskUpdates, sortSubtasks, fetchAllTaskGroups, initialTaskDetail, getDueDateValueFromDueDateGroupId, toPriorityCodeType, toTaskStatusCodeType, DueDateGroupKey, toDueDateGroupKeyType, updateTaskFromListView, updateTaskListTab, removeTaskFromList, snoozeTask, unsnoozeTask, convertHHMMStrToMinutes, initialTaskDetailLocalData, TaskListTab, ALL_TASK_LIST_TABS, };
964
+ export { Task, TaskPayload, TaskListSelectorView, TaskWithUserDetails, TaskListViewSortKey, TaskListUIState, TaskDetailSelectorView, EditTaskLocalData, TaskStatusCodeType, PriorityCodeType, getTaskGroupById, TaskStatus, TaskPriority, TaskCodeType, getAllTasks, fetchTaskList, fetchTaskListPage, getTaskDetail, fetchTaskDetailPage, saveTaskUpdatesToLocalStore, saveTaskDetail, createSubTask, resetSubTaskCreateStatus, fetchSubTasks, CreateSubTaskPayload, archiveTask, CannedResponse, CannedResponsesViewState, fetchCannedResponses, saveCannedResponse, deleteCannedResponse, getCannedResponsesView, updateTaskListSearchText, updateTaskListUIState, allTaskStatus, allTaskPriority, TaskListFilters, updateTaskFilters, TASK_LIST_FILTER_CATEGORIES, TASK_LIST_GROUP_BY_CATEGORIES, TaskListFilterCategoryField, deleteTask, discardTaskUpdatesInLocalStore, TaskFilterCategory, TaskType, TaskGroupWithTasksList, TaskListLocalData, bulkUpdateTaskList, createNewTaskGroup, initiateTaskListLocalData, deleteTaskGroup, updateTaskListLocalData, dragNDropTasks, updateTaskGroupName, TaskGroupState, TaskGroupKey, toTaskListGroupByKeyType, toTaskListGroupByKeyTypeStrict, SubtaskSortKey, SubtaskSortOrder, getTaskUpdates, sortSubtasks, fetchAllTaskGroups, initialTaskDetail, getDueDateValueFromDueDateGroupId, toPriorityCodeType, toTaskStatusCodeType, DueDateGroupKey, toDueDateGroupKeyType, updateTaskFromListView, updateTaskListTab, removeTaskFromList, snoozeTask, unsnoozeTask, convertHHMMStrToMinutes, initialTaskDetailLocalData, TaskListTab, ALL_TASK_LIST_TABS, };
965
965
  export { Tag, TagState, TagViewState, getAllTags, TagViewSelectorView, fetchTagList, createTag, deleteTag, };
966
966
  export { CardPayment, CardPaymentViewState, SetupIntentData, CardPaymentSelectorView, getAllCardsAndBankPaymentMethods, createCardSetupIntent, confirmCardSetupIntent, addCardPaymentSource, fetchPaymentSources, resetCardPaymentErrorStatuses, clearCardPaymentView, AddCardPaymentSourceType, };
967
967
  export { getAuditReportGroupViewSelectorView, getAuditRuleGroupViewSelectorView, getUserFromAllUsers, AuditReportGroupSelectorView, AuditReportGroupViewSelectorView, AuditRuleGroupViewSelectorView, fetchAuditRuleGroupView, fetchAuditReportGroupView, saveReasonForAuditRule, AuditRuleGroup, AuditRuleGroupReport, AuditReportRule, AuditRuleEntityType, AuditRuleEntityIdType, AuditRuleBypassReason, clearAuditReportGroupViewByCompanyId, };
package/lib/index.js CHANGED
@@ -71,21 +71,21 @@ exports.TIME_SERIES_DURATIONS = exports.anyCardOnHold = exports.getChargeCardByI
71
71
  exports.deleteScheduleAccruedDetail = exports.createNewSchedulesAccrued = exports.updateExpenseAutomationActualMatchingUIState = exports.undoReversalAccruals = exports.searchMatchTransactions = exports.searchMatchAccruals = exports.openMatchNewModal = exports.matchAndReverseAccruals = exports.ignoreActualMatchingSuggestion = exports.fetchExpenseAutomationActualMatchingPage = exports.fetchActualMatchingMatch = exports.fetchExpenseAutomationActualMatching = exports.clearMatchNewModal = exports.closeMatchNewModal = exports.clearExpenseAutomationActualMatchingView = exports.ackCloseMatchAfterUndo = exports.ackCloseMatchAfterIgnore = exports.updateJeScheduleTransactionKeys = exports.updateJeScheduleLocalDataById = exports.updateJeOneTimeAccrualLocalData = exports.removeJeOneTimeAccrualLocalData = exports.updateJeNewScheduleLocalData = exports.updateExpenseAutomationJESchedulesUIState = exports.searchJeTransactionsForNewScheduleSuccess = exports.searchJeTransactionsForNewScheduleFailure = exports.searchJeTransactionsForNewSchedule = exports.saveJeNewScheduleSuccess = exports.saveJeNewScheduleFailure = exports.saveJeNewSchedule = exports.retryExpenseAutomationJESchedule = exports.resetJeNewScheduleLocalData = exports.removeJeScheduleTransactionKey = exports.initializeJeScheduleLocalData = exports.initializeJeNewSchedule = exports.initializeJeAccountSettingsView = exports.ignoreExpenseAutomationJESchedule = exports.fetchExpenseAutomationJESchedulesPage = exports.clearJeSearchTransactionsForNewSchedule = exports.clearExpenseAutomationJESchedulesView = exports.clearExpenseAutomationJEScheduleLocalData = exports.updateApAgingDetailUIState = exports.getApAgingDetailForVendor = exports.fetchApAgingDetail = exports.updateApAgingUIState = exports.getApAgingReport = exports.fetchApAging = exports.aggregatedReportView = exports.fetchAggregatedReport = exports.toTimeSeriesDuration = exports.convertToTimeSeriesSelectionRange = void 0;
72
72
  exports.getQBOUrlForLink = exports.updatedSelectedJELinkRowIndex = exports.updateAccruedJEScheduleAccruedByListKey = exports.updateScheduleListDownloadState = exports.updateScheduleDetailsLocalData = exports.createNewSchedules = exports.deleteScheduleDetail = exports.saveScheduleDetails = exports.fetchScheduleDetailsPage = exports.getAccruedScheduleDetailsView = exports.getScheduleDetailsView = exports.fetchScheduleDetails = exports.updateSelectedJEScheduleKey = exports.updateScheduleListSortState = exports.updateScheduleListScrollState = exports.updateScheduleListSearchText = exports.updateScheduleListSubTab = exports.toScheduleSubTabType = exports.toScheduleListTabsFileTypeStrict = exports.toScheduleTypesTypeStrict = exports.toScheduleTypesType = exports.getFetchStateForScheduleAccountList = exports.updateScheduleListLocalData = exports.fetchSchedulesAccount = exports.fetchDownloadSchedules = exports.fetchAccruedScheduleList = exports.fetchScheduleList = exports.getAccruedScheduleListReport = exports.getScheduleListReport = exports.ALL_SCHEDULES_TYPES = exports.ALL_ONE_TIME_ACCRUAL_REVERT_REASONS = exports.ALL_ONE_TIME_ACCRUAL_IGNORE_REASONS = exports.ALL_JE_SCHEDULE_REVERT_REASONS = exports.ALL_JE_SCHEDULE_IGNORE_REASONS = exports.getJEScheduleTransactionKey = exports.resetAccruedDetailNewScheduleState = exports.resetSelectedJEAccruedScheduleKey = exports.updateSelectedJEAccruedScheduleKey = exports.updateScheduleAccruedDetailsLocalData = exports.updateLinkBillExpenseLocalData = exports.clearSelectedJELinkRowIndex = exports.fetchRecommendedTransactionRowIndex = exports.updatedJELinkInLocalDataAccruedExpenses = exports.updatedJEAccruedLinkWithRecommendedLocalData = exports.updateAmountsInScheduleAccruedDetail = exports.saveScheduleAccruedDetails = exports.resetJEAccruedLinkInLocalData = exports.fetchScheduleAccruedDetailsPage = exports.fetchScheduleAccruedDetails = exports.cancelScheduleAccruedJournalEntry = void 0;
73
73
  exports.getArAgingDetailForCustomer = exports.getArAgingReport = exports.updateArAgingDetailUIState = exports.fetchArAgingDetail = exports.updateArAgingUIState = exports.fetchArAging = exports.updateVendorGlobalReviewViewLocalData = exports.toVendorGlobalReviewColumnSortKeyType = exports.getTenantMerchantByMerchantId = exports.getVendorGlobalReviewView = exports.updateVendorGlobalReviewViewUIState = exports.updateSelectedGlobalMerchant = exports.fetchVendorGlobalReviewView = exports.rejectVendorGlobalReview = exports.approveVendorGlobalReview = exports.getGlobalMerchantView = exports.clearGlobalMerchantView = exports.updateCreateGlobalMerchantLocalData = exports.createGlobalMerchant = exports.fetchGlobalMerchantRecommendation = exports.getVendorDetailSelectorView = exports.saveVendorDetailsView = exports.updateReviewVendorDetailLocalData = exports.clearGlobalMerchantAutoCompleteResults = exports.fetchGlobalMerchantAutoCompleteView = exports.updateVendorFirstReviewSortUiState = exports.updateVendorFirstReviewViewLocalData = exports.saveVendorFirstReviewView = exports.clearRecentlySavedErroredVendorData = exports.updateVendorFirstReviewViewPageToken = exports.resetVendorFirstReviewLocalData = exports.updateVendorFirstReviewViewScrollYOffset = exports.fetchVendorFirstReviewAttachments = exports.fetchVendorFirstReviewView = exports.getVendorFirstReviewAttachmentView = exports.getVendorFirstReviewView = exports.getGlobalMerchantAutoCompleteResults = exports.toVendorFirstReviewViewColumnKeyType = exports.getVendorTabView = exports.updateVendorTabViewTab = exports.fetchVendorTabView = exports.resetMarkAsCompleteStatus = exports.markAsCompleteScheduleDetail = exports.getDefaultSelectedTimeframeForScheduleType = exports.getFetchStateForScheduleListByType = exports.updatedJELinkWithRecommendedLocalData = exports.resetJELinkInLocalData = exports.updateAmountsInScheduleDetail = exports.updatedJELinkInLocalData = exports.getThirdPartyIDFromQBOURL = void 0;
74
- exports.convertHHMMStrToMinutes = exports.unsnoozeTask = exports.snoozeTask = exports.removeTaskFromList = exports.updateTaskListTab = exports.updateTaskFromListView = exports.toDueDateGroupKeyType = exports.toTaskStatusCodeType = exports.toPriorityCodeType = exports.getDueDateValueFromDueDateGroupId = exports.initialTaskDetail = exports.fetchAllTaskGroups = exports.sortSubtasks = exports.getTaskUpdates = exports.toTaskListGroupByKeyTypeStrict = exports.toTaskListGroupByKeyType = exports.updateTaskGroupName = exports.dragNDropTasks = exports.updateTaskListLocalData = exports.deleteTaskGroup = exports.initiateTaskListLocalData = exports.createNewTaskGroup = exports.bulkUpdateTaskList = exports.discardTaskUpdatesInLocalStore = exports.deleteTask = exports.TASK_LIST_GROUP_BY_CATEGORIES = exports.TASK_LIST_FILTER_CATEGORIES = exports.updateTaskFilters = exports.allTaskPriority = exports.allTaskStatus = exports.updateTaskListUIState = exports.updateTaskListSearchText = exports.getCannedResponsesView = exports.deleteCannedResponse = exports.saveCannedResponse = exports.fetchCannedResponses = exports.archiveTask = exports.fetchSubTasks = exports.resetSubTaskCreateStatus = exports.createSubTask = exports.saveTaskDetail = exports.saveTaskUpdatesToLocalStore = exports.fetchTaskDetailPage = exports.getTaskDetail = exports.fetchTaskListPage = exports.getAllTasks = exports.getTaskGroupById = exports.toRecurringBillFrequencyStrict = exports.toRecurringBillFrequency = exports.updateArAgingNodeCollapseState = void 0;
75
- exports.getFeatureNotificationView = exports.notifyMeForFeature = exports.fetchRegisteredInterests = exports.getNotificationsForSelectedSubTab = exports.getExternalNotificationsForSelectedSubTab = exports.getNotificationView = exports.updateNotificationViewUIState = exports.updateNotificationViewSubTab = exports.updateNotificationViewCurrentTabAndSubTab = exports.updateNotificationViewTabState = exports.updateNotificationViewNotificationStatus = exports.updateNotificationViewAllNotificationsStatus = exports.fetchNotificationUnreadCountSuccess = exports.fetchNotificationUnreadCount = exports.fetchNotificationView = exports.toNotificationTabTypeStrict = exports.toNotificationSubTabTypeStrict = exports.updateCommentsNotificationsStatuses = exports.updateCommentsNotifications = exports.toNotificationModeStrict = exports.parseOAuthParams = exports.getZeniOAuthApproveRedirectUrl = exports.getZeniOAuthApproveFetchState = exports.getZeniOAuthApproveError = exports.clearZeniOAuthView = exports.approveOAuthConsentSuccess = exports.approveOAuthConsentFailure = exports.approveOAuthConsent = exports.getAuthenticationView = exports.fetchCollaborationAuthToken = exports.clearAuditReportGroupViewByCompanyId = exports.saveReasonForAuditRule = exports.fetchAuditReportGroupView = exports.fetchAuditRuleGroupView = exports.getUserFromAllUsers = exports.getAuditRuleGroupViewSelectorView = exports.getAuditReportGroupViewSelectorView = exports.clearCardPaymentView = exports.resetCardPaymentErrorStatuses = exports.fetchPaymentSources = exports.addCardPaymentSource = exports.confirmCardSetupIntent = exports.createCardSetupIntent = exports.getAllCardsAndBankPaymentMethods = exports.deleteTag = exports.createTag = exports.fetchTagList = exports.getAllTags = exports.ALL_TASK_LIST_TABS = exports.initialTaskDetailLocalData = void 0;
76
- exports.fetchExpressPayInitialDetails = exports.getIntlWireVerificationView = exports.updateVerificationFormLocalData = exports.submitInternationalVerificationForm = exports.fetchInternationalVerificationForm = exports.createTaskFromTaskGroupTemplate = exports.getCompanyTaskManagerView = exports.fetchTaskManagerMetrics = exports.fetchCompanyTaskManagerView = exports.fetchCockpitContext = exports.toRecurringFrequency = exports.toDayOfWeek = exports.getRecurringEndDateFromCount = exports.getMinAllowedEndDate = exports.SEMI_WEEKLY_REQUIRED_DAYS_COUNT = exports.ALL_WEEK_DAYS = exports.updateReferViewed = exports.getRewardsPlanCard = exports.fetchRewardsPlan = exports.resendReferralInvite = exports.updateReferralListSortUiState = exports.saveReferralFormDataInLocalStore = exports.clearReferrals = exports.sendReferralInvite = exports.fetchReferrals = exports.DEFAULT_REFERRER_AMOUNT = exports.AmountStatusTypes = exports.StatusTypes = exports.toReferralListViewSortKeyType = exports.getInviteFormView = exports.getReferralListView = exports.toNotificationFrequency = exports.toNotificationChannel = exports.toggleEventChannel = exports.setGroupFrequency = exports.setGroupChannelMaster = exports.saveNotificationPreferences = exports.clearNotificationPreferencesLocalOverrides = exports.clearAllNotificationPreferencesView = exports.hasUnsavedNotificationPreferences = exports.getNotificationRegistry = exports.getNotificationPreferencesSaveState = exports.getNotificationLocalOverrides = exports.getEffectiveNotificationPreferences = exports.getNotifications = exports.getLastNotificationTime = exports.pushToastNotification = exports.isFeatureInterestRegistered = exports.getRegisteredInterestsByFeature = exports.getRegisteredInterests = void 0;
77
- exports.fetchRoutineRuns = exports.fetchChatSessionsForUser = exports.fetchChatHistory = exports.deleteSkill = exports.deleteRoutine = exports.deleteChatSession = exports.createSessionAndSubmit = exports.createSession = exports.closeSkillsBrowser = exports.closeRoutinesBrowser = exports.closeRoutineRuns = exports.clearSkillMutation = exports.clearSkillDetail = exports.clearLastContextMessage = exports.clearDeleteChatSessionStatus = exports.clearCurrentSessionId = exports.clearAiCfoSidePanelHostPageContext = exports.applyAiCfoSidePanelHostPageTransition = exports.acceptMasterTOS = exports.getAiAccountantCockpitView = exports.updateAiAccountantUIState = exports.triggerAiAccountantJob = exports.setSelectedTenantIdsForJobTrigger = exports.fetchAiAccountantJobs = exports.fetchAiAccountantCustomers = exports.cancelAiAccountantOnboarding = exports.getAiAccountantJobsByTenantId = exports.getAiAccountantCustomers = exports.updateAiAccountantJobs = exports.updateAiAccountantCustomer = exports.updateAiAccountantCustomers = exports.toAiAccountantJob = exports.toAiAccountantEnrollment = exports.toAiAccountantCustomer = exports.toAiAccountantOperationType = exports.toAiAccountantJobStatus = exports.toAiAccountantEnrollmentStatus = exports.getAllowedOperationsForStatus = exports.getTreasuryFundsMaximumYield = exports.getTreasurySetupViewDetails = exports.updateFundAllocationLocalData = exports.fetchPortfolioAllocation = exports.updatePortfolioAllocation = exports.fetchTreasuryFunds = exports.fetchTreasurySetupView = exports.acceptTreasuryTerms = exports.getExpressPayView = exports.resetExpressPayLocalData = exports.submitExpressPay = exports.updateExpressPayFormLocalData = void 0;
78
- exports.updateSyntheticAiCfoAnswer = exports.appendSyntheticAiCfoAnswer = exports.toAiCfoVisualization = exports.toAiCfoExports = exports.clearSession = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.updateAiCfoAnswerCardPolicyWizardPlan = exports.setSessions = exports.setNewSession = exports.getSuggestedQuestionsForPageContext = exports.getSkillVersions = exports.getSkillVersionBody = exports.getSkillsEnabled = exports.getSkills = exports.getSkillMutation = exports.getSkillDetail = exports.getRoutinesEnabled = exports.getRoutines = exports.getRoutineRuns = exports.getRoutineMutation = exports.getAiCfoView = exports.canCreateRoutine = exports.updateResponseState = exports.updateCurrentInput = exports.updateCotCollapsedState = exports.updateAiCfoViewScrollPosition = exports.submitQuestion = exports.submitFeedback = exports.stopSubmitQuestion = exports.stopSubmit = exports.setSkillVisibility = exports.setSession = exports.setRoutineEnabled = exports.saveSkill = exports.saveRoutine = exports.runRoutine = exports.openSkillsBrowser = exports.openRoutinesBrowser = exports.fetchSuggestedQuestionsSuccess = exports.fetchSuggestedQuestionsFailure = exports.fetchSuggestedQuestions = exports.fetchSkillVersions = exports.fetchSkillVersionBody = exports.fetchSkillsSuccess = exports.fetchSkillsFailure = exports.fetchSkills = exports.fetchSkillDetail = exports.fetchRoutines = void 0;
79
- exports.getCardPolicySuggestedBlockCategories = exports.getCardPolicySuggestedAllowMerchants = exports.getCardPolicySuggestedAllowCategories = exports.getCardPolicyStats = exports.getCardPolicyMccCategoriesFetchState = exports.getCardPolicyMccCategoriesError = exports.getCardPolicyMccCategories = exports.getAllCardPolicyTemplates = exports.updatePolicyRecommendationFromUploadSuccess = exports.updatePolicyRecommendationFromUploadFailure = exports.updatePolicyDocumentExtractionSuccess = exports.updatePolicyDocumentExtractionFailure = exports.updateCreatedCardPolicyTemplate = exports.updateCardPolicyVendorOptionsFailure = exports.updateCardPolicyVendorOptions = exports.updateCardPolicyTemplates = exports.updateCardPolicyStats = exports.updateCardPolicyMccCategoriesFailure = exports.updateCardPolicyMccCategories = exports.removeCardPolicyTemplate = exports.fetchCardPolicyVendorOptions = exports.fetchCardPolicyRecommendationFromUpload = exports.fetchCardPolicyMccCategories = exports.extractPolicyDocument = exports.clearPolicyDocumentExtraction = exports.toMessageType = exports.toMessageSender = exports.ALL_SYNTHETIC_AI_CFO_ANSWER_KINDS = exports.toInteractiveFormTypeStrict = exports.toInteractiveFormType = exports.toAiCfoAnswerResponseTypeStrict = exports.toAiCfoAnswerResponseType = exports.toAiCfoAnswerStateTypeStrict = exports.toAiCfoAnswerStateType = exports.toAiCfoChartTypeStrict = exports.toAiCfoChartType = exports.toAiCfoVisualizationTypeStrict = exports.toAiCfoVisualizationType = exports.ALL_INTERACTIVE_FORM_TYPES = exports.ALL_AI_CFO_ANSWER_RESPONSE_TYPES = exports.ALL_AI_CFO_ANSWER_STATE_TYPES = exports.ALL_AI_CFO_VISUALIZATION_TYPES = exports.ALL_AI_CFO_CHARTS_TYPES = exports.getSyntheticAiCfoAnswerByQuestionAnswerId = exports.getSyntheticAiCfoAnswersForChatSession = exports.getAiCfoSelectorView = exports.getAllQuestionsForChatSession = exports.getQuestionAnswerByIdForChatSession = exports.getAllQuestionAnswersForChatSession = exports.removeSyntheticAiCfoAnswer = void 0;
80
- exports.toMccCategoryLike = exports.CARD_POLICY_LIMIT_ROW_ID_TRANSACTION = exports.CARD_POLICY_LIMIT_ROW_ID_REQUIRE_RECEIPT = exports.getManualCardPolicyFormDraft = exports.getLastCreatedCardPolicyTemplateIds = exports.getLastCreatedCardPolicyTemplateId = exports.getLastCreateCardPolicyTemplateErrors = exports.getLastCreateCardPolicySourceChatSessionId = exports.getCreateCardPolicyTemplateRequestState = exports.getAiCardPolicyFormDraft = exports.updateManualCardPolicyFormDraft = exports.updateCreateCardPolicyTemplateRequestState = exports.updateAiCardPolicyFormDraftFromUploadPlan = exports.updateAiCardPolicyFormDraft = exports.seedManualCardPolicyFormDraft = exports.seedAiCardPolicyFormDraft = exports.createCardPolicyTemplates = exports.clearManualCardPolicyFormDraft = exports.clearCreateCardPolicy = exports.clearAiCardPolicyFormDraft = exports.applyExtractedPolicyToManualCardPolicyDraft = exports.applyExtractedPolicyToAiCardPolicyDraft = exports.toUpdateCardPolicyTemplateRequestBody = exports.toExtractedCardPolicyRules = exports.toCreateCardPolicyTemplatesRequestBody = exports.toCreateCardPolicyTemplateRequestBody = exports.toCardPolicyVendorSearchOption = exports.toCardPolicyTemplateList = exports.toCardPolicyTemplate = exports.toCardPolicyStats = exports.toCardPolicyEditFormDraft = exports.toBulkCreateCardPolicyTemplateError = exports.toCardPolicyTemplateStatus = exports.toCardPolicyTemplateMode = exports.ALL_CARD_POLICY_TEMPLATE_STATUSES = exports.ALL_CARD_POLICY_TEMPLATE_MODES = exports.getUploadedPolicyDocumentFileName = exports.getPolicyRecommendationFromUploadFetchState = exports.getPolicyRecommendationFromUploadError = exports.getPolicyRecommendationFromUploadChatSessionId = exports.getPolicyRecommendationFromUploadAnswerId = exports.getPolicyDocumentExtractionFetchState = exports.getPolicyDocumentExtractionError = exports.getExtractedCardPolicyRules = exports.getCardPolicyVendorSearchString = exports.getCardPolicyVendorSearchOptions = exports.getCardPolicyVendorSearchFetchState = exports.getCardPolicyTemplatesByIds = exports.getCardPolicyTemplateById = exports.getCardPolicySuggestedBlockMerchants = void 0;
81
- exports.fetchAutoTransferRuleHistory = exports.deleteAutoTransferRule = exports.updateAutoTransferRule = exports.createAutoTransferRule = exports.fetchAutoTransferRules = exports.getTreasuryTaxLetters = exports.fetchTreasuryTaxLetterList = exports.getTreasuryStatements = exports.fetchTreasuryStatementList = exports.getTreasuryTransferMoney = exports.clearTreasuryTransferMoney = exports.updateTreasuryTransferMoneyLocalData = exports.executeTreasuryTransferMoney = exports.getTreasuryDetail = exports.updateTreasuryTransactionListUIState = exports.fetchTreasuryTransactionList = exports.fetchTreasuryOverviewDetail = exports.getUpdateCardPolicyFetchState = exports.getCardPolicyFormDraft = exports.getCardPolicyDetailView = exports.getCardPolicyDetailFetchState = exports.updateCardPolicyFormDraft = exports.updateCardPolicyFetchStatus = exports.updateCardPolicyDetailFetchStatus = exports.updateCardPolicy = exports.fetchCardPolicyDetail = exports.getCardPolicyTemplateIds = exports.getCardPolicyListView = exports.getCardPolicyListFetchState = exports.getArchiveCardPolicyFetchState = exports.updateCardPolicyListFetchStatus = exports.updateArchiveCardPolicyFetchStatus = exports.prependCardPolicyTemplateIds = exports.fetchCardPolicyList = exports.archiveCardPolicy = exports.toManualCardPolicyTemplateRequestFromDraft = exports.toBulkCardPolicyTemplateRequestsFromDraft = exports.toCardPolicyTemplateRequestFromDraft = exports.applyAiCardPolicyFormDraftUpdate = exports.deriveAiPolicyReviewRowsFromInputs = exports.buildManualCardPolicyFormDraftSeed = exports.buildUploadReviewRows = exports.buildEmptyLimitRows = exports.buildAiCardPolicyFormDraftSeed = exports.toVendorChipFieldValue = exports.toMccCategoryChipFieldValue = exports.buildVendorChipId = exports.buildMccCategoryChipId = exports.VENDOR_CHIP_ID_PREFIX = exports.MCC_CHIP_ID_PREFIX = void 0;
82
- exports.resetCreateInvoice = exports.fetchCreateInvoiceFormPage = exports.createInvoice = exports.getInvoiceDetail = exports.fetchInvoiceDetailPage = exports.fetchInvoiceDetail = exports.getInvoiceListView = exports.ALL_INVOICING_INVOICE_TAB_IDS = exports.updateInvoiceListFilters = exports.setInvoiceActiveTab = exports.fetchInvoiceListPage = exports.fetchInvoiceList = exports.fetchInvoiceKPIs = exports.fetchInvoiceCounts = exports.getInvoicesByIds = exports.getInvoiceById = exports.updateInvoices = exports.removeInvoice = exports.mapAuditLogEntry = exports.toAuditLogEntityRouteOption = exports.isInvoicingEntityLinkable = exports.buildInvoicingEntityPath = exports.toInvoicingDiscountLifecycleActionOption = exports.toInvoicingDiscountLifecycleAction = exports.toInvoicingCatalogProductLifecycleActionOption = exports.toInvoicingCatalogItemLifecycleActionOption = exports.toInvoicingCatalogProductLifecycleAction = exports.toInvoicingCatalogItemLifecycleAction = exports.toInvoicingSubscriptionLifecycleActionOption = exports.toInvoicingSubscriptionLifecycleAction = exports.toInvoicingDunningAction = exports.INVOICING_DISCOUNT_LIFECYCLE_ACTIONS = exports.INVOICING_CATALOG_PRODUCT_LIFECYCLE_ACTIONS = exports.INVOICING_CATALOG_ITEM_LIFECYCLE_ACTIONS = exports.INVOICING_SUBSCRIPTION_LIFECYCLE_ACTIONS = exports.INVOICING_DUNNING_ACTIONS = exports.toKycProvidedDocumentTypeFromAllowed = exports.toKycProvidedDocumentType = exports.DEFAULT_SESSION_CONFIG = exports.SessionManager = exports.getTransactionActivityLogView = exports.fetchTransactionActivityLog = exports.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = exports.BULK_UPLOAD_AUTOMATCHING_TIMEOUT_MS = exports.getAutoTransferRuleHistory = exports.getAutoTransferRuleById = exports.getAutoTransferRules = exports.clearRuleUpdateLocalData = exports.updateRuleLocalData = exports.fetchAutoTransferReviewDetail = void 0;
83
- exports.entityToInvoicingCustomerFormLocalData = exports.INVOICING_CUSTOMER_BILLING_ADDRESS_TYPE = exports.updateInvoicingCustomerFormDraft = exports.submitInvoicingCustomerFormSuccess = exports.submitInvoicingCustomerFormFailure = exports.submitInvoicingCustomerForm = exports.resetEditInvoicingCustomerDetailView = exports.initializeInvoicingCustomerAddress = exports.getRecordPaymentView = exports.getRecordPaymentInvoiceOptions = exports.getRecordPaymentFormView = exports.getCreateInvoiceFormView = exports.getInvoicingAuditView = exports.fetchInvoicingAuditLog = exports.getInvoicingOverview = exports.buildPeriodOptions = exports.fetchInvoicingOverview = exports.clearInvoicingOverview = exports.initialRecordPaymentFormLocalData = exports.localDataToRecordPaymentPayload = exports.localDataToInvoiceRecordPaymentBody = exports.initializeRecordPaymentDraftFromInvoice = exports.getCreateCreditNoteView = exports.getCreateCreditNoteFormView = exports.initialCreateCreditNoteFormLocalData = exports.localDataToCreateCreditNotePayload = exports.updateCreateCreditNoteFormDraft = exports.submitCreateCreditNote = exports.resetCreateCreditNote = exports.createCreditNoteSuccess = exports.createCreditNoteFailure = exports.getIssueCreditNoteView = exports.initialIssueCreditNoteFormLocalData = exports.localDataToIssueCreditNotePayload = exports.initializeIssueCreditNoteDraftFromInvoice = exports.computeIssueCreditNoteTotal = exports.updateIssueCreditNoteFormDraft = exports.submitIssueCreditNote = exports.resetIssueCreditNote = exports.issueCreditNoteSuccess = exports.issueCreditNoteFailure = exports.initializeIssueCreditNoteDraft = exports.updateRecordPaymentFormDraft = exports.submitRecordPayment = exports.initializeRecordPaymentDraft = exports.resetRecordPayment = exports.initialInvoicingCreateInvoiceFormLocalData = exports.createInvoiceFormLocalDataToRequest = exports.blankInvoicingCreateInvoiceLineItem = exports.updateInvoicingCreateInvoiceFormDraft = void 0;
84
- exports.runInvoicingCatalogProductAction = exports.runInvoicingCatalogPlanAction = exports.fetchInvoicingCatalogItemDetailPage = exports.shouldDefaultAdjustmentCreditNote = exports.isBackdatedInvoiceDate = exports.buildVoidInvoiceSubmitBody = exports.updateInvoicingInvoice = exports.runInvoicingInvoiceAction = exports.getInvoicingCouponFormView = exports.getEditInvoicingCouponDetailViewState = exports.initialInvoicingCouponFormLocalData = exports.entityToInvoicingCouponFormLocalData = exports.updateInvoicingCouponFormDraft = exports.submitInvoicingCouponForm = exports.saveInvoicingCoupon = exports.resetEditInvoicingCouponDetailView = exports.fetchInvoicingCouponDetailPage = exports.getSavedInvoicingCatalogItemKind = exports.getSavedInvoicingCatalogItemId = exports.getInvoicingCatalogItemFormView = exports.getInvoicingApplicableCatalogItemOptions = exports.isTieredCatalogPricingModel = exports.initialInvoicingCatalogItemFormLocalData = exports.invoicingProductToCatalogItemFormSubFamily = exports.entityToInvoicingCatalogItemFormLocalData = exports.blankInvoicingCatalogTier = exports.blankInvoicingCatalogSubFamily = exports.INVOICING_CATALOG_TIER_TYPE_VALUES = exports.INVOICING_CATALOG_PRORATION_VALUES = exports.INVOICING_CATALOG_PRICING_MODEL_VALUES = exports.INVOICING_CATALOG_APPLICABILITY_VALUES = exports.updateInvoicingCatalogItemFormDraft = exports.submitInvoicingCatalogItemForm = exports.resetEditInvoicingCatalogItemDetailView = exports.getInvoicingSubscriptionFormView = exports.getEditInvoicingSubscriptionDetailViewState = exports.toInvoicingSubscriptionQuantity = exports.invoicingSubscriptionTodayIso = exports.initialInvoicingSubscriptionFormLocalData = exports.entityToInvoicingSubscriptionFormLocalData = exports.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE = exports.updateInvoicingSubscriptionFormDraft = exports.submitInvoicingSubscriptionForm = exports.resetEditInvoicingSubscriptionDetailView = exports.initializeInvoicingSubscriptionAddress = exports.fetchInvoicingSubscriptionFormPage = exports.fetchInvoicingSubscriptionEstimate = exports.clearInvoicingSubscriptionEstimate = exports.getInvoicingCustomerFormView = exports.initialInvoicingCustomerFormLocalData = void 0;
85
- exports.setInvoicingSubscriptionActiveTab = exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionCounts = exports.updateInvoicingSubscriptions = exports.removeInvoicingSubscription = exports.resetPromotionalCreditAction = exports.submitAddPromotionalCredits = exports.getInvoicingSetupIntentFetchState = exports.getInvoicingSetupIntent = exports.getInvoicingSentPaymentLinkMagicUrl = exports.getInvoicingSentPaymentLinkEmail = exports.getInvoicingPlaidLinkToken = exports.getInvoicingPaymentMethodSaveState = exports.getInvoicingPaymentLinkSendState = exports.sendInvoicingPaymentLink = exports.saveInvoicingPaymentMethod = exports.resetInvoicingCustomerPaymentMethod = exports.fetchInvoicingPlaidLinkToken = exports.createInvoicingSetupIntent = exports.fetchInvoicingPaymentLinkEmailPreviewPage = exports.fetchInvoicingCustomerDetailPage = exports.fetchInvoicingCustomerDetail = exports.getInvoicingCustomerListView = exports.INVOICING_CUSTOMER_COLUMNS = exports.ALL_INVOICING_CUSTOMER_TAB_IDS = exports.ALL_INVOICING_CUSTOMER_SORT_KEYS = exports.updateInvoicingCustomerFilters = exports.setInvoicingCustomerActiveTab = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomers = exports.removeInvoicingCustomer = exports.INVOICING_LIST_PAGE_SIZE = exports.uploadInvoicingMigrationFiles = exports.startInvoicingMigration = exports.rollbackInvoicingMigration = exports.retryInvoicingMigration = exports.connectInvoicingChargebee = exports.getInvoicingDataImportView = exports.setInvoicingActiveMigrationSessionId = exports.fetchInvoicingMigrationSessions = exports.fetchInvoicingMigrationSession = exports.fetchInvoicingMigrationDiagnostics = exports.fetchInvoicingDataImportStatus = exports.runInvoicingPaymentAction = exports.runInvoicingDunningAction = exports.runInvoicingSubscriptionAction = exports.runInvoicingDiscountAction = void 0;
86
- exports.getInvoicingCouponListItems = exports.getInvoicingCouponListHasMore = exports.getInvoicingCouponListFilters = exports.getInvoicingCouponListFetchState = exports.getInvoicingCouponCounts = exports.INVOICING_COUPON_COLUMNS = exports.ALL_INVOICING_COUPON_TAB_IDS = exports.ALL_INVOICING_COUPON_SORT_KEYS = exports.updateInvoicingCouponFilters = exports.setInvoicingCouponActiveTab = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCoupons = exports.removeInvoicingCoupon = exports.getInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteById = exports.fetchInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteListView = exports.INVOICING_CREDIT_NOTE_COLUMNS = exports.ALL_INVOICING_CREDIT_NOTE_TAB_IDS = exports.ALL_INVOICING_CREDIT_NOTE_SORT_KEYS = exports.updateInvoicingCreditNoteFilters = exports.setInvoicingCreditNoteActiveTab = exports.fetchInvoicingCreditNoteListPage = exports.fetchInvoicingCreditNoteList = exports.fetchInvoicingCreditNoteCounts = exports.updateInvoicingCreditNotes = exports.removeInvoicingCreditNote = exports.getInvoicingTransactionDetail = exports.getInvoicingTransactionById = exports.fetchInvoicingTransactionDetail = exports.getInvoicingTransactionListView = exports.INVOICING_TRANSACTION_COLUMNS = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = exports.updateInvoicingTransactionFilters = exports.setInvoicingTransactionActiveTab = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.updateInvoicingTransactions = exports.removeInvoicingTransaction = exports.getInvoicingSubscriptionById = exports.fetchInvoicingSubscriptionDetailPage = exports.fetchInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionListView = exports.INVOICING_SUBSCRIPTION_COLUMNS = exports.ALL_INVOICING_SUBSCRIPTION_TAB_IDS = exports.ALL_INVOICING_SUBSCRIPTION_SORT_KEYS = exports.updateInvoicingSubscriptionFilters = void 0;
87
- exports.getInvoicingQboSettingsFormView = exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingQboSettingsDraft = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingQboSettings = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = exports.resetSaveInvoicingSettings = exports.resetInvoicingQboSettingsDraft = exports.resetInvoicingBrandingFormDraft = exports.fetchInvoicingSettings = exports.disconnectInvoicingStripe = exports.connectInvoicingStripe = exports.getLowestInvoicingCatalogPricePointAmount = exports.getInvoicingCatalogItemById = exports.fetchInvoicingCatalogItemDetail = exports.getInvoicingCatalogListView = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.fetchInvoicingCatalogProductList = exports.fetchInvoicingCatalogPlanList = exports.fetchInvoicingCatalogListPage = exports.fetchInvoicingCatalogCounts = exports.updateInvoicingCatalogItems = exports.removeInvoicingCatalogItem = exports.mergeInvoicingCatalogPricePoint = exports.getInvoicingDunningEmailPreview = exports.getInvoicingDunningCaseDetail = exports.getInvoicingDunningCaseById = exports.invalidateInvoicingDunningEmailPreview = exports.fetchInvoicingDunningEmailPreviewPage = exports.fetchInvoicingDunningCaseDetailPage = exports.fetchInvoicingDunningCaseDetail = exports.clearInvoicingDunningCaseDetailView = exports.getInvoicingDunningCaseListView = exports.INVOICING_DUNNING_CASE_COLUMNS = exports.ALL_INVOICING_DUNNING_CASE_TAB_IDS = exports.ALL_INVOICING_DUNNING_CASE_SORT_KEYS = exports.updateInvoicingDunningCaseFilters = exports.setInvoicingDunningCaseActiveTab = exports.fetchInvoicingDunningCaseListPage = exports.fetchInvoicingDunningCaseList = exports.fetchInvoicingDunningCaseCounts = exports.updateInvoicingDunningCases = exports.removeInvoicingDunningCase = exports.fetchInvoicingCouponDetail = exports.getInvoicingCouponById = exports.getInvoicingCouponListView = exports.getInvoicingCouponListNextCursor = void 0;
88
- exports.isPendingReviewAccrual = exports.isManuallyReversedAccrual = exports.isAutoReversedAccrual = exports.getExpenseAutomationActualMatchingView = exports.getExpenseAutomationActualMatchingMatchView = exports.parseActualMatchingMatchId = exports.getCloseMatchAfterUndoMatchId = exports.getCloseMatchAfterUndo = exports.getCloseMatchAfterIgnoreMatchId = exports.getActualMatchingMatchModalConfirmStatus = exports.getActualMatchingReversalDate = exports.getActualMatchingAmount = exports.isPendingReviewRow = exports.isRenderableOneTimeAccrual = exports.isOneTimeAccrualRow = exports.isExistingTabRow = exports.isAiAccountantSchedule = exports.isAccruedScheduleRow = exports.getJEScheduleRowType = exports.getExpenseAutomationJEOneTimeAccrualDetailView = exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.toInvoicingQboCustomerMatchingMode = exports.toInvoicingNamedOptionsByKey = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.invoicingAccountsForQboAccountTypes = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingAccountingPickers = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.invoicingQboSettingsLocalDataToPayload = exports.initialInvoicingQboSettingsLocalData = exports.entityToInvoicingQboSettingsLocalData = exports.getInvoicingSettingsView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = void 0;
74
+ exports.unsnoozeTask = exports.snoozeTask = exports.removeTaskFromList = exports.updateTaskListTab = exports.updateTaskFromListView = exports.toDueDateGroupKeyType = exports.toTaskStatusCodeType = exports.toPriorityCodeType = exports.getDueDateValueFromDueDateGroupId = exports.initialTaskDetail = exports.fetchAllTaskGroups = exports.sortSubtasks = exports.getTaskUpdates = exports.toTaskListGroupByKeyTypeStrict = exports.toTaskListGroupByKeyType = exports.updateTaskGroupName = exports.dragNDropTasks = exports.updateTaskListLocalData = exports.deleteTaskGroup = exports.initiateTaskListLocalData = exports.createNewTaskGroup = exports.bulkUpdateTaskList = exports.discardTaskUpdatesInLocalStore = exports.deleteTask = exports.TASK_LIST_GROUP_BY_CATEGORIES = exports.TASK_LIST_FILTER_CATEGORIES = exports.updateTaskFilters = exports.allTaskPriority = exports.allTaskStatus = exports.updateTaskListUIState = exports.updateTaskListSearchText = exports.getCannedResponsesView = exports.deleteCannedResponse = exports.saveCannedResponse = exports.fetchCannedResponses = exports.archiveTask = exports.fetchSubTasks = exports.resetSubTaskCreateStatus = exports.createSubTask = exports.saveTaskDetail = exports.saveTaskUpdatesToLocalStore = exports.fetchTaskDetailPage = exports.getTaskDetail = exports.fetchTaskListPage = exports.fetchTaskList = exports.getAllTasks = exports.getTaskGroupById = exports.toRecurringBillFrequencyStrict = exports.toRecurringBillFrequency = exports.updateArAgingNodeCollapseState = void 0;
75
+ exports.notifyMeForFeature = exports.fetchRegisteredInterests = exports.getNotificationsForSelectedSubTab = exports.getExternalNotificationsForSelectedSubTab = exports.getNotificationView = exports.updateNotificationViewUIState = exports.updateNotificationViewSubTab = exports.updateNotificationViewCurrentTabAndSubTab = exports.updateNotificationViewTabState = exports.updateNotificationViewNotificationStatus = exports.updateNotificationViewAllNotificationsStatus = exports.fetchNotificationUnreadCountSuccess = exports.fetchNotificationUnreadCount = exports.fetchNotificationView = exports.toNotificationTabTypeStrict = exports.toNotificationSubTabTypeStrict = exports.updateCommentsNotificationsStatuses = exports.updateCommentsNotifications = exports.toNotificationModeStrict = exports.parseOAuthParams = exports.getZeniOAuthApproveRedirectUrl = exports.getZeniOAuthApproveFetchState = exports.getZeniOAuthApproveError = exports.clearZeniOAuthView = exports.approveOAuthConsentSuccess = exports.approveOAuthConsentFailure = exports.approveOAuthConsent = exports.getAuthenticationView = exports.fetchCollaborationAuthToken = exports.clearAuditReportGroupViewByCompanyId = exports.saveReasonForAuditRule = exports.fetchAuditReportGroupView = exports.fetchAuditRuleGroupView = exports.getUserFromAllUsers = exports.getAuditRuleGroupViewSelectorView = exports.getAuditReportGroupViewSelectorView = exports.clearCardPaymentView = exports.resetCardPaymentErrorStatuses = exports.fetchPaymentSources = exports.addCardPaymentSource = exports.confirmCardSetupIntent = exports.createCardSetupIntent = exports.getAllCardsAndBankPaymentMethods = exports.deleteTag = exports.createTag = exports.fetchTagList = exports.getAllTags = exports.ALL_TASK_LIST_TABS = exports.initialTaskDetailLocalData = exports.convertHHMMStrToMinutes = void 0;
76
+ exports.getIntlWireVerificationView = exports.updateVerificationFormLocalData = exports.submitInternationalVerificationForm = exports.fetchInternationalVerificationForm = exports.createTaskFromTaskGroupTemplate = exports.getCompanyTaskManagerView = exports.fetchTaskManagerMetrics = exports.fetchCompanyTaskManagerView = exports.fetchCockpitContext = exports.toRecurringFrequency = exports.toDayOfWeek = exports.getRecurringEndDateFromCount = exports.getMinAllowedEndDate = exports.SEMI_WEEKLY_REQUIRED_DAYS_COUNT = exports.ALL_WEEK_DAYS = exports.updateReferViewed = exports.getRewardsPlanCard = exports.fetchRewardsPlan = exports.resendReferralInvite = exports.updateReferralListSortUiState = exports.saveReferralFormDataInLocalStore = exports.clearReferrals = exports.sendReferralInvite = exports.fetchReferrals = exports.DEFAULT_REFERRER_AMOUNT = exports.AmountStatusTypes = exports.StatusTypes = exports.toReferralListViewSortKeyType = exports.getInviteFormView = exports.getReferralListView = exports.toNotificationFrequency = exports.toNotificationChannel = exports.toggleEventChannel = exports.setGroupFrequency = exports.setGroupChannelMaster = exports.saveNotificationPreferences = exports.clearNotificationPreferencesLocalOverrides = exports.clearAllNotificationPreferencesView = exports.hasUnsavedNotificationPreferences = exports.getNotificationRegistry = exports.getNotificationPreferencesSaveState = exports.getNotificationLocalOverrides = exports.getEffectiveNotificationPreferences = exports.getNotifications = exports.getLastNotificationTime = exports.pushToastNotification = exports.isFeatureInterestRegistered = exports.getRegisteredInterestsByFeature = exports.getRegisteredInterests = exports.getFeatureNotificationView = void 0;
77
+ exports.fetchChatSessionsForUser = exports.fetchChatHistory = exports.deleteSkill = exports.deleteRoutine = exports.deleteChatSession = exports.createSessionAndSubmit = exports.createSession = exports.closeSkillsBrowser = exports.closeRoutinesBrowser = exports.closeRoutineRuns = exports.clearSkillMutation = exports.clearSkillDetail = exports.clearLastContextMessage = exports.clearDeleteChatSessionStatus = exports.clearCurrentSessionId = exports.clearAiCfoSidePanelHostPageContext = exports.applyAiCfoSidePanelHostPageTransition = exports.acceptMasterTOS = exports.getAiAccountantCockpitView = exports.updateAiAccountantUIState = exports.triggerAiAccountantJob = exports.setSelectedTenantIdsForJobTrigger = exports.fetchAiAccountantJobs = exports.fetchAiAccountantCustomers = exports.cancelAiAccountantOnboarding = exports.getAiAccountantJobsByTenantId = exports.getAiAccountantCustomers = exports.updateAiAccountantJobs = exports.updateAiAccountantCustomer = exports.updateAiAccountantCustomers = exports.toAiAccountantJob = exports.toAiAccountantEnrollment = exports.toAiAccountantCustomer = exports.toAiAccountantOperationType = exports.toAiAccountantJobStatus = exports.toAiAccountantEnrollmentStatus = exports.getAllowedOperationsForStatus = exports.getTreasuryFundsMaximumYield = exports.getTreasurySetupViewDetails = exports.updateFundAllocationLocalData = exports.fetchPortfolioAllocation = exports.updatePortfolioAllocation = exports.fetchTreasuryFunds = exports.fetchTreasurySetupView = exports.acceptTreasuryTerms = exports.getExpressPayView = exports.resetExpressPayLocalData = exports.submitExpressPay = exports.updateExpressPayFormLocalData = exports.fetchExpressPayInitialDetails = void 0;
78
+ exports.appendSyntheticAiCfoAnswer = exports.toAiCfoVisualization = exports.toAiCfoExports = exports.clearSession = exports.addQuestionPayload = exports.upsertOrAddQuestionAnswerPayload = exports.upsertAnswerPayload = exports.updateAiCfoAnswerCardPolicyWizardPlan = exports.setSessions = exports.setNewSession = exports.getSuggestedQuestionsForPageContext = exports.getSkillVersions = exports.getSkillVersionBody = exports.getSkillsEnabled = exports.getSkills = exports.getSkillMutation = exports.getSkillDetail = exports.getRoutinesEnabled = exports.getRoutines = exports.getRoutineRuns = exports.getRoutineMutation = exports.getAiCfoView = exports.canCreateRoutine = exports.updateResponseState = exports.updateCurrentInput = exports.updateCotCollapsedState = exports.updateAiCfoViewScrollPosition = exports.submitQuestion = exports.submitFeedback = exports.stopSubmitQuestion = exports.stopSubmit = exports.setSkillVisibility = exports.setSession = exports.setRoutineEnabled = exports.saveSkill = exports.saveRoutine = exports.runRoutine = exports.openSkillsBrowser = exports.openRoutinesBrowser = exports.fetchSuggestedQuestionsSuccess = exports.fetchSuggestedQuestionsFailure = exports.fetchSuggestedQuestions = exports.fetchSkillVersions = exports.fetchSkillVersionBody = exports.fetchSkillsSuccess = exports.fetchSkillsFailure = exports.fetchSkills = exports.fetchSkillDetail = exports.fetchRoutines = exports.fetchRoutineRuns = void 0;
79
+ exports.getCardPolicySuggestedAllowMerchants = exports.getCardPolicySuggestedAllowCategories = exports.getCardPolicyStats = exports.getCardPolicyMccCategoriesFetchState = exports.getCardPolicyMccCategoriesError = exports.getCardPolicyMccCategories = exports.getAllCardPolicyTemplates = exports.updatePolicyRecommendationFromUploadSuccess = exports.updatePolicyRecommendationFromUploadFailure = exports.updatePolicyDocumentExtractionSuccess = exports.updatePolicyDocumentExtractionFailure = exports.updateCreatedCardPolicyTemplate = exports.updateCardPolicyVendorOptionsFailure = exports.updateCardPolicyVendorOptions = exports.updateCardPolicyTemplates = exports.updateCardPolicyStats = exports.updateCardPolicyMccCategoriesFailure = exports.updateCardPolicyMccCategories = exports.removeCardPolicyTemplate = exports.fetchCardPolicyVendorOptions = exports.fetchCardPolicyRecommendationFromUpload = exports.fetchCardPolicyMccCategories = exports.extractPolicyDocument = exports.clearPolicyDocumentExtraction = exports.toMessageType = exports.toMessageSender = exports.ALL_SYNTHETIC_AI_CFO_ANSWER_KINDS = exports.toInteractiveFormTypeStrict = exports.toInteractiveFormType = exports.toAiCfoAnswerResponseTypeStrict = exports.toAiCfoAnswerResponseType = exports.toAiCfoAnswerStateTypeStrict = exports.toAiCfoAnswerStateType = exports.toAiCfoChartTypeStrict = exports.toAiCfoChartType = exports.toAiCfoVisualizationTypeStrict = exports.toAiCfoVisualizationType = exports.ALL_INTERACTIVE_FORM_TYPES = exports.ALL_AI_CFO_ANSWER_RESPONSE_TYPES = exports.ALL_AI_CFO_ANSWER_STATE_TYPES = exports.ALL_AI_CFO_VISUALIZATION_TYPES = exports.ALL_AI_CFO_CHARTS_TYPES = exports.getSyntheticAiCfoAnswerByQuestionAnswerId = exports.getSyntheticAiCfoAnswersForChatSession = exports.getAiCfoSelectorView = exports.getAllQuestionsForChatSession = exports.getQuestionAnswerByIdForChatSession = exports.getAllQuestionAnswersForChatSession = exports.removeSyntheticAiCfoAnswer = exports.updateSyntheticAiCfoAnswer = void 0;
80
+ exports.CARD_POLICY_LIMIT_ROW_ID_TRANSACTION = exports.CARD_POLICY_LIMIT_ROW_ID_REQUIRE_RECEIPT = exports.getManualCardPolicyFormDraft = exports.getLastCreatedCardPolicyTemplateIds = exports.getLastCreatedCardPolicyTemplateId = exports.getLastCreateCardPolicyTemplateErrors = exports.getLastCreateCardPolicySourceChatSessionId = exports.getCreateCardPolicyTemplateRequestState = exports.getAiCardPolicyFormDraft = exports.updateManualCardPolicyFormDraft = exports.updateCreateCardPolicyTemplateRequestState = exports.updateAiCardPolicyFormDraftFromUploadPlan = exports.updateAiCardPolicyFormDraft = exports.seedManualCardPolicyFormDraft = exports.seedAiCardPolicyFormDraft = exports.createCardPolicyTemplates = exports.clearManualCardPolicyFormDraft = exports.clearCreateCardPolicy = exports.clearAiCardPolicyFormDraft = exports.applyExtractedPolicyToManualCardPolicyDraft = exports.applyExtractedPolicyToAiCardPolicyDraft = exports.toUpdateCardPolicyTemplateRequestBody = exports.toExtractedCardPolicyRules = exports.toCreateCardPolicyTemplatesRequestBody = exports.toCreateCardPolicyTemplateRequestBody = exports.toCardPolicyVendorSearchOption = exports.toCardPolicyTemplateList = exports.toCardPolicyTemplate = exports.toCardPolicyStats = exports.toCardPolicyEditFormDraft = exports.toBulkCreateCardPolicyTemplateError = exports.toCardPolicyTemplateStatus = exports.toCardPolicyTemplateMode = exports.ALL_CARD_POLICY_TEMPLATE_STATUSES = exports.ALL_CARD_POLICY_TEMPLATE_MODES = exports.getUploadedPolicyDocumentFileName = exports.getPolicyRecommendationFromUploadFetchState = exports.getPolicyRecommendationFromUploadError = exports.getPolicyRecommendationFromUploadChatSessionId = exports.getPolicyRecommendationFromUploadAnswerId = exports.getPolicyDocumentExtractionFetchState = exports.getPolicyDocumentExtractionError = exports.getExtractedCardPolicyRules = exports.getCardPolicyVendorSearchString = exports.getCardPolicyVendorSearchOptions = exports.getCardPolicyVendorSearchFetchState = exports.getCardPolicyTemplatesByIds = exports.getCardPolicyTemplateById = exports.getCardPolicySuggestedBlockMerchants = exports.getCardPolicySuggestedBlockCategories = void 0;
81
+ exports.deleteAutoTransferRule = exports.updateAutoTransferRule = exports.createAutoTransferRule = exports.fetchAutoTransferRules = exports.getTreasuryTaxLetters = exports.fetchTreasuryTaxLetterList = exports.getTreasuryStatements = exports.fetchTreasuryStatementList = exports.getTreasuryTransferMoney = exports.clearTreasuryTransferMoney = exports.updateTreasuryTransferMoneyLocalData = exports.executeTreasuryTransferMoney = exports.getTreasuryDetail = exports.updateTreasuryTransactionListUIState = exports.fetchTreasuryTransactionList = exports.fetchTreasuryOverviewDetail = exports.getUpdateCardPolicyFetchState = exports.getCardPolicyFormDraft = exports.getCardPolicyDetailView = exports.getCardPolicyDetailFetchState = exports.updateCardPolicyFormDraft = exports.updateCardPolicyFetchStatus = exports.updateCardPolicyDetailFetchStatus = exports.updateCardPolicy = exports.fetchCardPolicyDetail = exports.getCardPolicyTemplateIds = exports.getCardPolicyListView = exports.getCardPolicyListFetchState = exports.getArchiveCardPolicyFetchState = exports.updateCardPolicyListFetchStatus = exports.updateArchiveCardPolicyFetchStatus = exports.prependCardPolicyTemplateIds = exports.fetchCardPolicyList = exports.archiveCardPolicy = exports.toManualCardPolicyTemplateRequestFromDraft = exports.toBulkCardPolicyTemplateRequestsFromDraft = exports.toCardPolicyTemplateRequestFromDraft = exports.applyAiCardPolicyFormDraftUpdate = exports.deriveAiPolicyReviewRowsFromInputs = exports.buildManualCardPolicyFormDraftSeed = exports.buildUploadReviewRows = exports.buildEmptyLimitRows = exports.buildAiCardPolicyFormDraftSeed = exports.toVendorChipFieldValue = exports.toMccCategoryChipFieldValue = exports.buildVendorChipId = exports.buildMccCategoryChipId = exports.VENDOR_CHIP_ID_PREFIX = exports.MCC_CHIP_ID_PREFIX = exports.toMccCategoryLike = void 0;
82
+ exports.fetchCreateInvoiceFormPage = exports.createInvoice = exports.getInvoiceDetail = exports.fetchInvoiceDetailPage = exports.fetchInvoiceDetail = exports.getInvoiceListView = exports.ALL_INVOICING_INVOICE_TAB_IDS = exports.updateInvoiceListFilters = exports.setInvoiceActiveTab = exports.fetchInvoiceListPage = exports.fetchInvoiceList = exports.fetchInvoiceKPIs = exports.fetchInvoiceCounts = exports.getInvoicesByIds = exports.getInvoiceById = exports.updateInvoices = exports.removeInvoice = exports.mapAuditLogEntry = exports.toAuditLogEntityRouteOption = exports.isInvoicingEntityLinkable = exports.buildInvoicingEntityPath = exports.toInvoicingDiscountLifecycleActionOption = exports.toInvoicingDiscountLifecycleAction = exports.toInvoicingCatalogProductLifecycleActionOption = exports.toInvoicingCatalogItemLifecycleActionOption = exports.toInvoicingCatalogProductLifecycleAction = exports.toInvoicingCatalogItemLifecycleAction = exports.toInvoicingSubscriptionLifecycleActionOption = exports.toInvoicingSubscriptionLifecycleAction = exports.toInvoicingDunningAction = exports.INVOICING_DISCOUNT_LIFECYCLE_ACTIONS = exports.INVOICING_CATALOG_PRODUCT_LIFECYCLE_ACTIONS = exports.INVOICING_CATALOG_ITEM_LIFECYCLE_ACTIONS = exports.INVOICING_SUBSCRIPTION_LIFECYCLE_ACTIONS = exports.INVOICING_DUNNING_ACTIONS = exports.toKycProvidedDocumentTypeFromAllowed = exports.toKycProvidedDocumentType = exports.DEFAULT_SESSION_CONFIG = exports.SessionManager = exports.getTransactionActivityLogView = exports.fetchTransactionActivityLog = exports.BULK_UPLOAD_BAR_COMPLETE_HOLD_MS = exports.BULK_UPLOAD_AUTOMATCHING_TIMEOUT_MS = exports.getAutoTransferRuleHistory = exports.getAutoTransferRuleById = exports.getAutoTransferRules = exports.clearRuleUpdateLocalData = exports.updateRuleLocalData = exports.fetchAutoTransferReviewDetail = exports.fetchAutoTransferRuleHistory = void 0;
83
+ exports.INVOICING_CUSTOMER_BILLING_ADDRESS_TYPE = exports.updateInvoicingCustomerFormDraft = exports.submitInvoicingCustomerFormSuccess = exports.submitInvoicingCustomerFormFailure = exports.submitInvoicingCustomerForm = exports.resetEditInvoicingCustomerDetailView = exports.initializeInvoicingCustomerAddress = exports.getRecordPaymentView = exports.getRecordPaymentInvoiceOptions = exports.getRecordPaymentFormView = exports.getCreateInvoiceFormView = exports.getInvoicingAuditView = exports.fetchInvoicingAuditLog = exports.getInvoicingOverview = exports.buildPeriodOptions = exports.fetchInvoicingOverview = exports.clearInvoicingOverview = exports.initialRecordPaymentFormLocalData = exports.localDataToRecordPaymentPayload = exports.localDataToInvoiceRecordPaymentBody = exports.initializeRecordPaymentDraftFromInvoice = exports.getCreateCreditNoteView = exports.getCreateCreditNoteFormView = exports.initialCreateCreditNoteFormLocalData = exports.localDataToCreateCreditNotePayload = exports.updateCreateCreditNoteFormDraft = exports.submitCreateCreditNote = exports.resetCreateCreditNote = exports.createCreditNoteSuccess = exports.createCreditNoteFailure = exports.getIssueCreditNoteView = exports.initialIssueCreditNoteFormLocalData = exports.localDataToIssueCreditNotePayload = exports.initializeIssueCreditNoteDraftFromInvoice = exports.computeIssueCreditNoteTotal = exports.updateIssueCreditNoteFormDraft = exports.submitIssueCreditNote = exports.resetIssueCreditNote = exports.issueCreditNoteSuccess = exports.issueCreditNoteFailure = exports.initializeIssueCreditNoteDraft = exports.updateRecordPaymentFormDraft = exports.submitRecordPayment = exports.initializeRecordPaymentDraft = exports.resetRecordPayment = exports.initialInvoicingCreateInvoiceFormLocalData = exports.createInvoiceFormLocalDataToRequest = exports.blankInvoicingCreateInvoiceLineItem = exports.updateInvoicingCreateInvoiceFormDraft = exports.resetCreateInvoice = void 0;
84
+ exports.runInvoicingCatalogPlanAction = exports.fetchInvoicingCatalogItemDetailPage = exports.shouldDefaultAdjustmentCreditNote = exports.isBackdatedInvoiceDate = exports.buildVoidInvoiceSubmitBody = exports.updateInvoicingInvoice = exports.runInvoicingInvoiceAction = exports.getInvoicingCouponFormView = exports.getEditInvoicingCouponDetailViewState = exports.initialInvoicingCouponFormLocalData = exports.entityToInvoicingCouponFormLocalData = exports.updateInvoicingCouponFormDraft = exports.submitInvoicingCouponForm = exports.saveInvoicingCoupon = exports.resetEditInvoicingCouponDetailView = exports.fetchInvoicingCouponDetailPage = exports.getSavedInvoicingCatalogItemKind = exports.getSavedInvoicingCatalogItemId = exports.getInvoicingCatalogItemFormView = exports.getInvoicingApplicableCatalogItemOptions = exports.isTieredCatalogPricingModel = exports.initialInvoicingCatalogItemFormLocalData = exports.invoicingProductToCatalogItemFormSubFamily = exports.entityToInvoicingCatalogItemFormLocalData = exports.blankInvoicingCatalogTier = exports.blankInvoicingCatalogSubFamily = exports.INVOICING_CATALOG_TIER_TYPE_VALUES = exports.INVOICING_CATALOG_PRORATION_VALUES = exports.INVOICING_CATALOG_PRICING_MODEL_VALUES = exports.INVOICING_CATALOG_APPLICABILITY_VALUES = exports.updateInvoicingCatalogItemFormDraft = exports.submitInvoicingCatalogItemForm = exports.resetEditInvoicingCatalogItemDetailView = exports.getInvoicingSubscriptionFormView = exports.getEditInvoicingSubscriptionDetailViewState = exports.toInvoicingSubscriptionQuantity = exports.invoicingSubscriptionTodayIso = exports.initialInvoicingSubscriptionFormLocalData = exports.entityToInvoicingSubscriptionFormLocalData = exports.INVOICING_SUBSCRIPTION_SHIPPING_ADDRESS_TYPE = exports.updateInvoicingSubscriptionFormDraft = exports.submitInvoicingSubscriptionForm = exports.resetEditInvoicingSubscriptionDetailView = exports.initializeInvoicingSubscriptionAddress = exports.fetchInvoicingSubscriptionFormPage = exports.fetchInvoicingSubscriptionEstimate = exports.clearInvoicingSubscriptionEstimate = exports.getInvoicingCustomerFormView = exports.initialInvoicingCustomerFormLocalData = exports.entityToInvoicingCustomerFormLocalData = void 0;
85
+ exports.fetchInvoicingSubscriptionListPage = exports.fetchInvoicingSubscriptionList = exports.fetchInvoicingSubscriptionCounts = exports.updateInvoicingSubscriptions = exports.removeInvoicingSubscription = exports.resetPromotionalCreditAction = exports.submitAddPromotionalCredits = exports.getInvoicingSetupIntentFetchState = exports.getInvoicingSetupIntent = exports.getInvoicingSentPaymentLinkMagicUrl = exports.getInvoicingSentPaymentLinkEmail = exports.getInvoicingPlaidLinkToken = exports.getInvoicingPaymentMethodSaveState = exports.getInvoicingPaymentLinkSendState = exports.sendInvoicingPaymentLink = exports.saveInvoicingPaymentMethod = exports.resetInvoicingCustomerPaymentMethod = exports.fetchInvoicingPlaidLinkToken = exports.createInvoicingSetupIntent = exports.fetchInvoicingPaymentLinkEmailPreviewPage = exports.fetchInvoicingCustomerDetailPage = exports.fetchInvoicingCustomerDetail = exports.getInvoicingCustomerListView = exports.INVOICING_CUSTOMER_COLUMNS = exports.ALL_INVOICING_CUSTOMER_TAB_IDS = exports.ALL_INVOICING_CUSTOMER_SORT_KEYS = exports.updateInvoicingCustomerFilters = exports.setInvoicingCustomerActiveTab = exports.fetchInvoicingCustomerListPage = exports.fetchInvoicingCustomerList = exports.fetchInvoicingCustomerCounts = exports.updateInvoicingCustomers = exports.removeInvoicingCustomer = exports.INVOICING_LIST_PAGE_SIZE = exports.uploadInvoicingMigrationFiles = exports.startInvoicingMigration = exports.rollbackInvoicingMigration = exports.retryInvoicingMigration = exports.connectInvoicingChargebee = exports.getInvoicingDataImportView = exports.setInvoicingActiveMigrationSessionId = exports.fetchInvoicingMigrationSessions = exports.fetchInvoicingMigrationSession = exports.fetchInvoicingMigrationDiagnostics = exports.fetchInvoicingDataImportStatus = exports.runInvoicingPaymentAction = exports.runInvoicingDunningAction = exports.runInvoicingSubscriptionAction = exports.runInvoicingDiscountAction = exports.runInvoicingCatalogProductAction = void 0;
86
+ exports.getInvoicingCouponListHasMore = exports.getInvoicingCouponListFilters = exports.getInvoicingCouponListFetchState = exports.getInvoicingCouponCounts = exports.INVOICING_COUPON_COLUMNS = exports.ALL_INVOICING_COUPON_TAB_IDS = exports.ALL_INVOICING_COUPON_SORT_KEYS = exports.updateInvoicingCouponFilters = exports.setInvoicingCouponActiveTab = exports.fetchInvoicingCouponListPage = exports.fetchInvoicingCouponList = exports.fetchInvoicingCouponCounts = exports.updateInvoicingCoupons = exports.removeInvoicingCoupon = exports.getInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteById = exports.fetchInvoicingCreditNoteDetail = exports.getInvoicingCreditNoteListView = exports.INVOICING_CREDIT_NOTE_COLUMNS = exports.ALL_INVOICING_CREDIT_NOTE_TAB_IDS = exports.ALL_INVOICING_CREDIT_NOTE_SORT_KEYS = exports.updateInvoicingCreditNoteFilters = exports.setInvoicingCreditNoteActiveTab = exports.fetchInvoicingCreditNoteListPage = exports.fetchInvoicingCreditNoteList = exports.fetchInvoicingCreditNoteCounts = exports.updateInvoicingCreditNotes = exports.removeInvoicingCreditNote = exports.getInvoicingTransactionDetail = exports.getInvoicingTransactionById = exports.fetchInvoicingTransactionDetail = exports.getInvoicingTransactionListView = exports.INVOICING_TRANSACTION_COLUMNS = exports.ALL_INVOICING_TRANSACTION_TAB_IDS = exports.ALL_INVOICING_TRANSACTION_SORT_KEYS = exports.updateInvoicingTransactionFilters = exports.setInvoicingTransactionActiveTab = exports.fetchInvoicingTransactionListPage = exports.fetchInvoicingTransactionList = exports.updateInvoicingTransactions = exports.removeInvoicingTransaction = exports.getInvoicingSubscriptionById = exports.fetchInvoicingSubscriptionDetailPage = exports.fetchInvoicingSubscriptionDetail = exports.getInvoicingSubscriptionListView = exports.INVOICING_SUBSCRIPTION_COLUMNS = exports.ALL_INVOICING_SUBSCRIPTION_TAB_IDS = exports.ALL_INVOICING_SUBSCRIPTION_SORT_KEYS = exports.updateInvoicingSubscriptionFilters = exports.setInvoicingSubscriptionActiveTab = void 0;
87
+ exports.getInvoicingBrandingFormView = exports.updateInvoicingSettings = exports.updateInvoicingQboSettingsDraft = exports.updateInvoicingBrandingFormDraft = exports.submitInvoicingQboSettings = exports.submitInvoicingBrandingForm = exports.saveInvoicingSettings = exports.resetSaveInvoicingSettings = exports.resetInvoicingQboSettingsDraft = exports.resetInvoicingBrandingFormDraft = exports.fetchInvoicingSettings = exports.disconnectInvoicingStripe = exports.connectInvoicingStripe = exports.getLowestInvoicingCatalogPricePointAmount = exports.getInvoicingCatalogItemById = exports.fetchInvoicingCatalogItemDetail = exports.getInvoicingCatalogListView = exports.updateInvoicingCatalogProductFilters = exports.updateInvoicingCatalogPlanFilters = exports.fetchInvoicingCatalogProductList = exports.fetchInvoicingCatalogPlanList = exports.fetchInvoicingCatalogListPage = exports.fetchInvoicingCatalogCounts = exports.updateInvoicingCatalogItems = exports.removeInvoicingCatalogItem = exports.mergeInvoicingCatalogPricePoint = exports.getInvoicingDunningEmailPreview = exports.getInvoicingDunningCaseDetail = exports.getInvoicingDunningCaseById = exports.invalidateInvoicingDunningEmailPreview = exports.fetchInvoicingDunningEmailPreviewPage = exports.fetchInvoicingDunningCaseDetailPage = exports.fetchInvoicingDunningCaseDetail = exports.clearInvoicingDunningCaseDetailView = exports.getInvoicingDunningCaseListView = exports.INVOICING_DUNNING_CASE_COLUMNS = exports.ALL_INVOICING_DUNNING_CASE_TAB_IDS = exports.ALL_INVOICING_DUNNING_CASE_SORT_KEYS = exports.updateInvoicingDunningCaseFilters = exports.setInvoicingDunningCaseActiveTab = exports.fetchInvoicingDunningCaseListPage = exports.fetchInvoicingDunningCaseList = exports.fetchInvoicingDunningCaseCounts = exports.updateInvoicingDunningCases = exports.removeInvoicingDunningCase = exports.fetchInvoicingCouponDetail = exports.getInvoicingCouponById = exports.getInvoicingCouponListView = exports.getInvoicingCouponListNextCursor = exports.getInvoicingCouponListItems = void 0;
88
+ exports.isPendingReviewAccrual = exports.isManuallyReversedAccrual = exports.isAutoReversedAccrual = exports.getExpenseAutomationActualMatchingView = exports.getExpenseAutomationActualMatchingMatchView = exports.parseActualMatchingMatchId = exports.getCloseMatchAfterUndoMatchId = exports.getCloseMatchAfterUndo = exports.getCloseMatchAfterIgnoreMatchId = exports.getActualMatchingMatchModalConfirmStatus = exports.getActualMatchingReversalDate = exports.getActualMatchingAmount = exports.isPendingReviewRow = exports.isRenderableOneTimeAccrual = exports.isOneTimeAccrualRow = exports.isExistingTabRow = exports.isAiAccountantSchedule = exports.isAccruedScheduleRow = exports.getJEScheduleRowType = exports.getExpenseAutomationJEOneTimeAccrualDetailView = exports.getInvoicingOnboardingGateView = exports.getInvoicingConfigView = exports.updateInvoicingConfig = exports.resetInvoicingConfigActionStates = exports.fetchInvoicingConfig = exports.enableInvoicing = exports.acceptInvoicingTerms = exports.toInvoicingQboCustomerMatchingMode = exports.toInvoicingNamedOptionsByKey = exports.getInvoicingQboAccountMappingId = exports.INVOICING_QBO_CUSTOMER_MATCHING_MODES = exports.getInvoicingQboView = exports.invoicingAccountsForQboAccountTypes = exports.startInvoicingQboBackfill = exports.retryInvoicingQboSyncTask = exports.fetchInvoicingQboSyncHealth = exports.fetchInvoicingQboConnection = exports.fetchInvoicingAccountingPickers = exports.isStripeConnectedFromSettings = exports.initialInvoicingBrandingFormLocalData = exports.entityToInvoicingBrandingFormLocalData = exports.INVOICING_BUSINESS_ADDRESS_TYPE = exports.invoicingQboSettingsLocalDataToPayload = exports.initialInvoicingQboSettingsLocalData = exports.entityToInvoicingQboSettingsLocalData = exports.getInvoicingSettingsView = exports.getInvoicingSettingsHubView = exports.getInvoicingSettingsFetchState = exports.getInvoicingSettings = exports.getInvoicingQboSettingsFormView = void 0;
89
89
  const allowedValue_1 = require("./commonStateTypes/allowedValue");
90
90
  Object.defineProperty(exports, "isAllowedValueWithCode", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithCode; } });
91
91
  Object.defineProperty(exports, "isAllowedValueWithID", { enumerable: true, get: function () { return allowedValue_1.isAllowedValueWithID; } });
@@ -2181,6 +2181,7 @@ Object.defineProperty(exports, "toTaskListGroupByKeyTypeStrict", { enumerable: t
2181
2181
  const taskListReducer_1 = require("./view/taskManager/taskListView/taskListReducer");
2182
2182
  Object.defineProperty(exports, "bulkUpdateTaskList", { enumerable: true, get: function () { return taskListReducer_1.bulkUpdateTaskList; } });
2183
2183
  Object.defineProperty(exports, "dragNDropTasks", { enumerable: true, get: function () { return taskListReducer_1.dragNDropTasks; } });
2184
+ Object.defineProperty(exports, "fetchTaskList", { enumerable: true, get: function () { return taskListReducer_1.fetchTaskList; } });
2184
2185
  Object.defineProperty(exports, "fetchTaskListPage", { enumerable: true, get: function () { return taskListReducer_1.fetchTaskListPage; } });
2185
2186
  Object.defineProperty(exports, "initiateTaskListLocalData", { enumerable: true, get: function () { return taskListReducer_1.initiateTaskListLocalData; } });
2186
2187
  Object.defineProperty(exports, "removeTaskFromList", { enumerable: true, get: function () { return taskListReducer_1.removeTaskFromList; } });
@@ -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>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<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
- const fetchCompanyTaskManagerViewEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(companyTaskManagerViewReducer_1.fetchCompanyTaskManagerView.match), (0, operators_1.switchMap)((action) => {
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
- ? { filter_by: toFilterByPayload(filters) }
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
- const toFilterByPayload = (filters) => {
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.map((category) => ({
75
- field: category.field ?? '',
76
- operator: category.matchingOperator === 'equal' ? 'is' : 'is_not',
77
- values: category.values.map((v) => String(v)),
78
- join: category.valuesCombinationOperator === 'ALL' ? 'and' : 'or',
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
  };
@@ -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: 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: 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 {};
@@ -7,6 +7,7 @@ exports.getAllTasks = exports.getTaskListGroupedByPriority = exports.getTaskList
7
7
  const toolkit_1 = require("@reduxjs/toolkit");
8
8
  const orderBy_1 = __importDefault(require("lodash/orderBy"));
9
9
  const sortOrderPayload_1 = require("../../../commonPayloadTypes/sortOrderPayload");
10
+ const common_1 = require("../../../commonStateTypes/common");
10
11
  const reduceFetchState_1 = require("../../../commonStateTypes/reduceFetchState");
11
12
  const tagSelector_1 = require("../../../entity/tag/tagSelector");
12
13
  const taskSelector_1 = require("../../../entity/task/taskSelector");
@@ -23,14 +24,18 @@ const taskList_1 = require("./taskList");
23
24
  const taskListFilterHelpers_1 = require("./taskListFilterHelpers");
24
25
  const sortTasksList = (tagState, tasksList, sortKey, sortOrder) => {
25
26
  const tasksInOrder = (0, orderBy_1.default)(tasksList, (task) => {
26
- const tagsByIds = (0, tagSelector_1.getTagsByIds)(tagState, task.tagIds);
27
27
  switch (sortKey) {
28
28
  case 'dueDate':
29
29
  return task.dueDate;
30
30
  case 'creationDate':
31
31
  return task.createTime;
32
32
  case 'tag':
33
- return tagsByIds[0]?.name ?? ''; // only one tag is supported
33
+ // Resolved HERE, not above the switch. Hoisted, it allocated a fresh
34
+ // array per task on every sort key, which made `tagState` a real
35
+ // dependency of the whole pipeline: tags arriving after first paint
36
+ // then rebuilt every group and re-rendered every row, moving that
37
+ // work out from behind the skeleton and into the user's hands.
38
+ return (0, tagSelector_1.getTagsByIds)(tagState, task.tagIds)[0]?.name ?? ''; // only one tag is supported
34
39
  case 'status':
35
40
  return task.status.name;
36
41
  case 'priority':
@@ -75,8 +80,7 @@ const getTasksWithUserDetails = ({ taskListState, taskState, userState, userRole
75
80
  const sortedTaskList = sortTasksList(tagState, filteredTaskList, sortKey, sortOrder);
76
81
  return sortedTaskList;
77
82
  };
78
- const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupViewState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
79
- const { taskGroupsIds } = taskGroupViewState;
83
+ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupsIds, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
80
84
  const taskGroupsWithTasksList = taskGroupsIds
81
85
  .map((taskGroupId) => {
82
86
  const taskGroup = (0, taskGroupSelector_1.getTaskGroupById)(taskGroupState, taskGroupId);
@@ -118,6 +122,7 @@ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupStat
118
122
  if (defaultTaskGroup != null) {
119
123
  sortedTaskGroupsWithTasksList.push(defaultTaskGroup);
120
124
  }
125
+ // Also hides deleted groups, which are empty as a side effect.
121
126
  return sortedTaskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
122
127
  };
123
128
  const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
@@ -249,7 +254,7 @@ const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, user
249
254
  });
250
255
  return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
251
256
  };
252
- const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupViewState, tagState, userGroupsState, }) => {
257
+ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState, }) => {
253
258
  const { groupByKey } = taskListState.uiState;
254
259
  if (groupByKey === 'groupName') {
255
260
  return getTaskListGroupedByGroupName({
@@ -259,7 +264,7 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
259
264
  userRoleState,
260
265
  addressState,
261
266
  taskGroupState,
262
- taskGroupViewState,
267
+ taskGroupsIds,
263
268
  tagState,
264
269
  userGroupsState,
265
270
  });
@@ -318,24 +323,70 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
318
323
  userGroupsState,
319
324
  });
320
325
  };
321
- exports.getAllTasks = (0, toolkit_1.createSelector)((state) => state.taskListState, (state) => state.taskState, (state) => state.userState, (state) => state.userRoleState, (state) => state.userListViewState, (state) => state.addressState, (state) => state.taskGroupState, (state) => state.taskGroupViewState, (state) => state.tagViewState, (state) => state.tagState, (state) => state.taskGroupTemplateState, (state) => state.taskGroupTemplateViewState, (state) => state.userGroupsState, (state) => state.userGroupListViewState, (_state, isTaskTemplatesEnabled) => isTaskTemplatesEnabled, (taskListState, taskState, userState, userRoleState, userListViewState, addressState, taskGroupState, taskGroupViewState, tagViewState, tagState, taskGroupTemplateState, taskGroupTemplateViewState, userGroupsState, userGroupListViewState, isTaskTemplatesEnabled) => {
326
+ /**
327
+ * Tags are STRUCTURAL only when they name a group or order the rows. Anywhere
328
+ * else they are decoration on a row that has already rendered.
329
+ */
330
+ const tagsAreStructural = (uiState) => uiState.groupByKey === 'tag' || uiState.sortKey === 'tag';
331
+ /** One frozen instance, so the "tags are not structural" input never changes. */
332
+ const EMPTY_TAG_STATE = { tagByID: {} };
333
+ /** Inputs are listed field by field, not as the slice: immer keeps each one
334
+ * referentially stable when `localData` changes, so the memo holds. */
335
+ const getTaskGroupsWithTaskListMemoized = (0, toolkit_1.createSelector)((state) => state.taskListState.uiState, (state) => state.taskListState.filters, (state) => state.taskListState.taskIdsByGroupsIds, (state) => state.taskListState.taskIdsByAssignees, (state) => state.taskListState.taskIdsByPriority, (state) => state.taskListState.taskIdsByStatus, (state) => state.taskListState.taskIdsByTags, (state) => state.taskListState.taskIdsByDueDate, (state) => state.taskState, (state) => state.userState, (state) => state.userRoleState, (state) => state.addressState, (state) => state.taskGroupState,
336
+ // `taskGroupsIds`, not the whole slice. `TaskGroupViewState` also carries
337
+ // taskGroupCreationStatus / DeleteStatus / UpdateStatus and fetchState, and
338
+ // none of them reach the board — but each transition produces a fresh slice
339
+ // reference, so an inline group rename alone rebuilt the entire grouped list
340
+ // twice (In-Progress, then Completed). That is the same needless rebuild this
341
+ // change removes for the other slices.
342
+ (state) => state.taskGroupViewState.taskGroupsIds,
343
+ // Only when tags are STRUCTURAL — they name a group or order the rows.
344
+ // Otherwise a stable empty slice, so tags landing after first paint cannot
345
+ // invalidate this memo and rebuild a board the user is already using.
346
+ (state) => tagsAreStructural(state.taskListState.uiState)
347
+ ? state.tagState
348
+ : EMPTY_TAG_STATE, (state) => state.userGroupsState, (uiState, filters, taskIdsByGroupsIds, taskIdsByAssignees, taskIdsByPriority, taskIdsByStatus, taskIdsByTags, taskIdsByDueDate, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState) => getTaskGroupsWithTaskList({
349
+ taskListState: {
350
+ uiState,
351
+ filters,
352
+ taskIdsByGroupsIds,
353
+ taskIdsByAssignees,
354
+ taskIdsByPriority,
355
+ taskIdsByStatus,
356
+ taskIdsByTags,
357
+ taskIdsByDueDate,
358
+ },
359
+ taskState,
360
+ userState,
361
+ userRoleState,
362
+ addressState,
363
+ taskGroupState,
364
+ taskGroupsIds,
365
+ tagState,
366
+ userGroupsState,
367
+ }));
368
+ exports.getAllTasks = (0, toolkit_1.createSelector)(
369
+ // `taskState`, `taskGroupState`, `addressState` and `tagState` are gone from
370
+ // here: the grouped list was their only consumer and it is memoised
371
+ // separately now, so a tag edit or an address arriving no longer rebuilds
372
+ // this view.
373
+ (state) => state.taskListState, (state) => state.userState, (state) => state.userRoleState, (state) => state.userListViewState, (state) => state.taskGroupViewState, (state) => state.tagViewState,
374
+ // A BOOLEAN, not the tag slice: reselect compares primitives by value, so
375
+ // this invalidates only when the map goes empty <-> non-empty.
376
+ (state) => (0, common_1.hasAnyKey)(state.tagState.tagByID), (state) => state.taskGroupTemplateState, (state) => state.taskGroupTemplateViewState, (state) => state.userGroupsState, (state) => state.userGroupListViewState, getTaskGroupsWithTaskListMemoized, (_state, isTaskTemplatesEnabled) => isTaskTemplatesEnabled, (taskListState, userState, userRoleState, userListViewState, taskGroupViewState, tagViewState, hasAnyTag, taskGroupTemplateState, taskGroupTemplateViewState, userGroupsState, userGroupListViewState, taskGroupsWithTasksList, isTaskTemplatesEnabled) => {
322
377
  const { localData } = taskListState;
323
- const taskGroupsWithTasksList = getTaskGroupsWithTaskList({
324
- taskListState,
325
- taskState,
326
- userState,
327
- userRoleState,
328
- addressState,
329
- taskGroupState,
330
- taskGroupViewState,
331
- tagState,
332
- userGroupsState,
333
- });
378
+ // Only the data the list is BUILT from. Tags decorate a row that can
379
+ // already be drawn.
334
380
  const fetchStateVariables = [
335
381
  taskListState,
336
382
  taskGroupViewState,
337
- tagViewState,
338
383
  ];
384
+ // Structural tags are waited on. A failed fetch is bypassed only when tags
385
+ // are already in the store, because then the headers still render.
386
+ if (tagsAreStructural(taskListState.uiState) &&
387
+ !(hasAnyTag && tagViewState.fetchState === 'Error')) {
388
+ fetchStateVariables.push(tagViewState);
389
+ }
339
390
  if (isTaskTemplatesEnabled) {
340
391
  fetchStateVariables.push(taskGroupTemplateViewState);
341
392
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.2.75",
3
+ "version": "5.2.76",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",