@zeniai/client-epic-state 4.20.0-beta0ND → 4.20.0-beta0RR

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.
Files changed (24) hide show
  1. package/lib/entity/task/taskPayload.d.ts +1 -0
  2. package/lib/entity/task/taskPayload.js +1 -0
  3. package/lib/entity/task/taskState.d.ts +1 -0
  4. package/lib/esm/entity/task/taskPayload.js +1 -0
  5. package/lib/esm/view/companyView/types/cockpitTypes.js +1 -0
  6. package/lib/esm/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +8 -3
  7. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +59 -140
  8. package/lib/esm/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
  9. package/lib/esm/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +1 -0
  10. package/lib/esm/view/taskManager/taskListView/taskList.js +1 -0
  11. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +6 -2
  12. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  13. package/lib/view/companyTaskManagerView/companyTaskManagerViewReducer.d.ts +2 -2
  14. package/lib/view/companyView/types/cockpitTypes.d.ts +1 -1
  15. package/lib/view/companyView/types/cockpitTypes.js +1 -0
  16. package/lib/view/profitAndLossClassesView/profitAndLossClassesByClassHorizontalSelector.js +8 -3
  17. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +59 -140
  18. package/lib/view/taskManager/taskDetailView/epics/initializeTaskToLocalStoreEpic.js +1 -0
  19. package/lib/view/taskManager/taskDetailView/epics/saveTaskDetailEpic.js +1 -0
  20. package/lib/view/taskManager/taskDetailView/taskDetail.d.ts +1 -0
  21. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  22. package/lib/view/taskManager/taskListView/taskList.js +1 -0
  23. package/lib/view/taskManager/taskListView/taskListSelector.js +6 -2
  24. package/package.json +1 -1
@@ -9,6 +9,7 @@ export interface TaskPayload {
9
9
  file_ids: string[];
10
10
  is_archived: boolean;
11
11
  is_deleted: boolean;
12
+ is_private: boolean;
12
13
  name: string;
13
14
  priority: AllowedValueWithCodePayload;
14
15
  recurring_end_date: string | null;
@@ -13,6 +13,7 @@ const mapTaskPayloadToTask = (payload) => ({
13
13
  fileIds: payload.file_ids,
14
14
  isArchived: payload.is_archived,
15
15
  isDeleted: payload.is_deleted,
16
+ isPrivate: payload.is_private,
16
17
  name: payload.name,
17
18
  syncToken: payload.sync_token ?? '',
18
19
  priority: {
@@ -11,6 +11,7 @@ export interface Task {
11
11
  id: ID;
12
12
  isArchived: boolean;
13
13
  isDeleted: boolean;
14
+ isPrivate: boolean;
14
15
  name: string;
15
16
  priority: TaskPriority;
16
17
  status: TaskStatus;
@@ -10,6 +10,7 @@ export const mapTaskPayloadToTask = (payload) => ({
10
10
  fileIds: payload.file_ids,
11
11
  isArchived: payload.is_archived,
12
12
  isDeleted: payload.is_deleted,
13
+ isPrivate: payload.is_private,
13
14
  name: payload.name,
14
15
  syncToken: payload.sync_token ?? '',
15
16
  priority: {
@@ -68,6 +68,7 @@ const ALL_TASK_MANAGER_SORT_KEYS = [
68
68
  'dueDate',
69
69
  'assignee',
70
70
  'tags',
71
+ 'visibility',
71
72
  'createdBy',
72
73
  ];
73
74
  export const toPortfolioSortKeyType = (v) => stringToUnion(v, ALL_PORTFOLIO_SORT_KEYS);
@@ -49,11 +49,16 @@ export const getProfitAndLossClassesHorizontalView = (filter, accountState, clas
49
49
  const calculatedSections = {};
50
50
  let reportCurrency = defaultCustomerCurrency;
51
51
  if (fetchState.fetchState === 'Completed' && selectedPeriod != null) {
52
+ // Get section reports using existing selector infrastructure
53
+ const sectionReports = {};
54
+ HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
55
+ sectionReports[sectionId] = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
56
+ });
52
57
  reportCurrency =
53
58
  profitAndLossClassesViewState.currency ?? defaultCustomerCurrency;
54
- // Fetch each section and pivot class→account to account→class in one pass
59
+ // Pivot each section from class→account to account→class
55
60
  HORIZONTAL_PANDL_SECTION_IDS.forEach((sectionId) => {
56
- const sectionReport = getSectionClassesViewReport(accountState, classState, sectionsState, { reportId, sectionId }, filter);
61
+ const sectionReport = sectionReports[sectionId];
57
62
  if (sectionReport != null) {
58
63
  sections[sectionId] = pivotSectionToHorizontal(sectionReport, classColumns, SECTION_TITLES[sectionId] ?? sectionId, reportCurrency);
59
64
  }
@@ -256,7 +261,7 @@ function sumBalancesInSlice(balances) {
256
261
  if (balances.length === 0) {
257
262
  return 0;
258
263
  }
259
- const summed = getSummationFreeRangeTotalBalance(balances);
264
+ const summed = getSummationFreeRangeTotalBalance([...balances]);
260
265
  return summed?.balance.amount ?? 0;
261
266
  }
262
267
  /**
@@ -25,31 +25,30 @@ function enrichHorizontalSection(report, section) {
25
25
  return total?.balance.amount ?? 0;
26
26
  });
27
27
  section.sectionHeaderBalancesSlice = buildHorizontalClassColumnBalancesSlice(report, classAmounts, section.sectionTotal.amount);
28
- const parentIndices = computeHorizontalAccountParentIndices(section.accounts);
29
- const childrenRowIndicesByParent = buildHorizontalAccountChildIndicesByParent(parentIndices);
28
+ const childrenRowIndicesByParent = buildHorizontalAccountChildIndicesByParent(section.accounts);
30
29
  const childrenRecord = {};
31
30
  childrenRowIndicesByParent.forEach((childIndices, parentIndex) => {
32
31
  childrenRecord[parentIndex] = childIndices;
33
32
  });
34
33
  section.treeLayout = {
35
34
  rootAccountRowIndices: section.accounts
36
- .map((_, i) => (parentIndices[i] === -1 ? i : -1))
35
+ .map((_, i) => findHorizontalAccountParentIndex(section.accounts, i) === -1 ? i : -1)
37
36
  .filter((i) => i >= 0),
38
37
  childrenRowIndicesByParent: childrenRecord,
39
38
  };
40
- const siblingsPerRow = buildSiblingIndicesPerRow(section.accounts, parentIndices);
41
- const hasChildFlags = computeHorizontalHasChildFlags(parentIndices);
42
39
  for (let i = 0; i < section.accounts.length; i++) {
43
40
  const row = section.accounts[i];
44
- // Same column order as `report.classColumns` (see `pivotSectionToHorizontal`).
45
- const classRowAmounts = row.classBalances.map((b) => b.balance.amount);
41
+ const classRowAmounts = report.classColumns.map((col) => {
42
+ const cb = row.classBalances.find((b) => b.classId === col.classId);
43
+ return cb?.balance.amount ?? 0;
44
+ });
46
45
  row.accountReportData = {
47
46
  accountId: row.accountId,
48
47
  accountName: row.accountName,
49
48
  accountType: row.accountType,
50
49
  depth: row.depth,
51
50
  balancesInTimeframe: buildHorizontalClassColumnBalancesSlice(report, classRowAmounts, row.rowTotal.amount),
52
- horizontalTreeView: buildHorizontalTreeViewFromPrecomputed(section.accounts, i, parentIndices, siblingsPerRow, hasChildFlags),
51
+ horizontalTreeView: buildHorizontalTreeView(section.accounts, i),
53
52
  };
54
53
  }
55
54
  }
@@ -121,157 +120,64 @@ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmou
121
120
  },
122
121
  };
123
122
  }
124
- /**
125
- * Parent index per DFS row — O(n). Matches the scan in the former
126
- * `findHorizontalAccountParentIndex` (depth &lt;= 2 rows have no parent).
127
- */
128
- function computeHorizontalAccountParentIndices(rows) {
129
- const accountRowCount = rows.length;
130
- const parentIndex = new Array(accountRowCount).fill(-1);
131
- const stack = [];
132
- for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
133
- const accountRow = rows[rowIndex];
134
- if (accountRow == null) {
135
- continue;
136
- }
137
- const d = accountRow.depth;
138
- while (stack.length > 0) {
139
- const topIdx = stack[stack.length - 1];
140
- if (topIdx == null) {
141
- break;
142
- }
143
- const topRow = rows[topIdx];
144
- if (topRow == null) {
145
- stack.pop();
146
- continue;
147
- }
148
- if (topRow.depth < d) {
149
- break;
150
- }
151
- stack.pop();
152
- }
153
- if (d <= 2) {
154
- parentIndex[rowIndex] = -1;
155
- }
156
- else if (stack.length === 0) {
157
- parentIndex[rowIndex] = -1;
158
- }
159
- else {
160
- const peek = stack[stack.length - 1];
161
- if (peek == null) {
162
- parentIndex[rowIndex] = -1;
163
- }
164
- else {
165
- const parentRow = rows[peek];
166
- parentIndex[rowIndex] =
167
- parentRow != null && parentRow.depth === d - 1 ? peek : -1;
123
+ function findHorizontalAccountParentIndex(dfsOrderedAccountRows, childRowIndex) {
124
+ const childDepth = dfsOrderedAccountRows[childRowIndex].depth;
125
+ if (childDepth <= 2) {
126
+ return -1;
127
+ }
128
+ for (let earlierRowIndex = childRowIndex - 1; earlierRowIndex >= 0; earlierRowIndex--) {
129
+ const earlierDepth = dfsOrderedAccountRows[earlierRowIndex].depth;
130
+ if (earlierDepth < childDepth) {
131
+ if (earlierDepth === childDepth - 1) {
132
+ return earlierRowIndex;
168
133
  }
134
+ return -1;
169
135
  }
170
- stack.push(rowIndex);
171
136
  }
172
- return parentIndex;
137
+ return -1;
173
138
  }
174
- /** Sibling row indices (same parent + depth), in traversal order — O(n). */
175
- function buildSiblingIndicesPerRow(rows, parentIndices) {
176
- const accountRowCount = rows.length;
177
- const keyToIndices = new Map();
178
- for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
179
- const parentRowIndex = parentIndices[rowIndex];
180
- const accountRow = rows[rowIndex];
181
- if (parentRowIndex == null || accountRow == null) {
182
- continue;
183
- }
184
- const key = `${parentRowIndex}:${accountRow.depth}`;
185
- let g = keyToIndices.get(key);
186
- if (g == null) {
187
- g = [];
188
- keyToIndices.set(key, g);
139
+ function getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex) {
140
+ const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
141
+ const rowDepth = dfsOrderedAccountRows[rowIndex].depth;
142
+ const siblings = [];
143
+ for (let i = 0; i < dfsOrderedAccountRows.length; i++) {
144
+ if (dfsOrderedAccountRows[i].depth === rowDepth &&
145
+ findHorizontalAccountParentIndex(dfsOrderedAccountRows, i) ===
146
+ parentRowIndex) {
147
+ siblings.push(i);
189
148
  }
190
- g.push(rowIndex);
191
149
  }
192
- const siblingsPerRow = new Array(accountRowCount);
193
- for (let rowIndex = 0; rowIndex < accountRowCount; rowIndex++) {
194
- const parentRowIndex = parentIndices[rowIndex];
195
- const accountRow = rows[rowIndex];
196
- if (parentRowIndex == null || accountRow == null) {
197
- siblingsPerRow[rowIndex] = [rowIndex];
198
- continue;
199
- }
200
- const key = `${parentRowIndex}:${accountRow.depth}`;
201
- const group = keyToIndices.get(key);
202
- siblingsPerRow[rowIndex] = group != null ? group : [rowIndex];
203
- }
204
- return siblingsPerRow;
150
+ return siblings;
205
151
  }
206
- function computeHorizontalHasChildFlags(parentIndices) {
207
- const rowCount = parentIndices.length;
208
- const flags = new Array(rowCount).fill(false);
209
- for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
210
- const parentRowIndex = parentIndices[rowIndex];
211
- if (parentRowIndex != null &&
212
- parentRowIndex >= 0 &&
213
- parentRowIndex < rowCount) {
214
- flags[parentRowIndex] = true;
215
- }
216
- }
217
- return flags;
152
+ function horizontalAccountHasChildRows(dfsOrderedAccountRows, parentRowIndex) {
153
+ return dfsOrderedAccountRows.some((_, rowIndex) => findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex) ===
154
+ parentRowIndex);
218
155
  }
219
- function buildHorizontalSubAccountAncestorMetadataFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags) {
220
- const chain = [];
156
+ function buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex) {
157
+ const ancestorRowIndicesRootToLeaf = [];
221
158
  let walkRowIndex = currentRowIndex;
222
159
  while (walkRowIndex >= 0) {
223
- chain.unshift(walkRowIndex);
224
- const parentRowIndex = parentIndices[walkRowIndex];
225
- if (parentRowIndex == null) {
226
- break;
227
- }
228
- walkRowIndex = parentRowIndex;
160
+ ancestorRowIndicesRootToLeaf.unshift(walkRowIndex);
161
+ walkRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, walkRowIndex);
229
162
  }
230
- return chain.map((rowIndex) => {
231
- const accountRow = dfsOrderedAccountRows[rowIndex];
232
- const siblingIndices = siblingsPerRow[rowIndex];
233
- const hasChild = hasChildFlags[rowIndex];
234
- if (accountRow == null || siblingIndices == null) {
235
- return {
236
- depth: 0,
237
- hasSibling: false,
238
- hasChildren: hasChild === true,
239
- isLastNode: true,
240
- name: '',
241
- };
242
- }
163
+ return ancestorRowIndicesRootToLeaf.map((rowIndex) => {
164
+ const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, rowIndex);
243
165
  return {
244
- depth: accountRow.depth - 2,
166
+ depth: dfsOrderedAccountRows[rowIndex].depth - 2,
245
167
  hasSibling: siblingIndices.length > 1,
246
- hasChildren: hasChild === true,
168
+ hasChildren: horizontalAccountHasChildRows(dfsOrderedAccountRows, rowIndex),
247
169
  isLastNode: rowIndex === siblingIndices[siblingIndices.length - 1],
248
- name: accountRow.accountName,
170
+ name: dfsOrderedAccountRows[rowIndex].accountName,
249
171
  };
250
172
  });
251
173
  }
252
- function buildHorizontalTreeViewFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags) {
253
- const siblingIndices = siblingsPerRow[currentRowIndex];
254
- const accountRow = dfsOrderedAccountRows[currentRowIndex];
255
- const hasChildrenFlag = hasChildFlags[currentRowIndex];
256
- const treeDepth = accountRow != null ? Math.max(0, accountRow.depth - 2) : 0;
257
- const hasChildren = hasChildrenFlag === true;
258
- const sibs = siblingIndices ?? [currentRowIndex];
259
- return {
260
- subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadataFromPrecomputed(dfsOrderedAccountRows, currentRowIndex, parentIndices, siblingsPerRow, hasChildFlags),
261
- treeDepth,
262
- hasChildren,
263
- hasSiblings: sibs.length > 1,
264
- isLeaf: !hasChildren,
265
- isLastNode: currentRowIndex === sibs[sibs.length - 1],
266
- };
267
- }
268
- function buildHorizontalAccountChildIndicesByParent(parentIndices) {
174
+ function buildHorizontalAccountChildIndicesByParent(dfsOrderedAccountRows) {
269
175
  const childIndicesByParentRowIndex = new Map();
270
- for (let rowIndex = 0; rowIndex < parentIndices.length; rowIndex++) {
271
- const parentRowIndex = parentIndices[rowIndex];
272
- if (parentRowIndex != null && parentRowIndex >= 0) {
176
+ for (let rowIndex = 0; rowIndex < dfsOrderedAccountRows.length; rowIndex++) {
177
+ const parentRowIndex = findHorizontalAccountParentIndex(dfsOrderedAccountRows, rowIndex);
178
+ if (parentRowIndex >= 0) {
273
179
  let childRowIndices = childIndicesByParentRowIndex.get(parentRowIndex);
274
- if (childRowIndices == null) {
180
+ if (childRowIndices === undefined) {
275
181
  childRowIndices = [];
276
182
  childIndicesByParentRowIndex.set(parentRowIndex, childRowIndices);
277
183
  }
@@ -280,3 +186,16 @@ function buildHorizontalAccountChildIndicesByParent(parentIndices) {
280
186
  }
281
187
  return childIndicesByParentRowIndex;
282
188
  }
189
+ function buildHorizontalTreeView(dfsOrderedAccountRows, currentRowIndex) {
190
+ const treeDepth = Math.max(0, dfsOrderedAccountRows[currentRowIndex].depth - 2);
191
+ const siblingIndices = getHorizontalAccountSiblingIndices(dfsOrderedAccountRows, currentRowIndex);
192
+ const hasChildren = horizontalAccountHasChildRows(dfsOrderedAccountRows, currentRowIndex);
193
+ return {
194
+ subAccountAncestorMetadata: buildHorizontalSubAccountAncestorMetadata(dfsOrderedAccountRows, currentRowIndex),
195
+ treeDepth,
196
+ hasChildren,
197
+ hasSiblings: siblingIndices.length > 1,
198
+ isLeaf: !hasChildren,
199
+ isLastNode: currentRowIndex === siblingIndices[siblingIndices.length - 1],
200
+ };
201
+ }
@@ -25,6 +25,7 @@ export const initializeTaskToLocalStoreEpic = (actions$, state$) => actions$.pip
25
25
  savedRecurringEndDate: task.recurringEndDate,
26
26
  recurringStartDate: task.recurringStartDate,
27
27
  timeSpent: task.timeSpent,
28
+ isPrivate: task.isPrivate,
28
29
  };
29
30
  const actions = [
30
31
  saveTaskUpdatesToLocalStore({ taskDetailLocalData, taskId }),
@@ -94,5 +94,6 @@ const prepareTaskPayload = (state, taskId, taskGroupId) => {
94
94
  sync_token: syncToken,
95
95
  task_group_ids: taskGroupId != null ? [taskGroupId] : [],
96
96
  time_spent: convertHHMMStrToMinutes(localData.timeSpent),
97
+ is_private: localData.isPrivate ?? false,
97
98
  };
98
99
  };
@@ -26,6 +26,7 @@ const ALL_TASK_LIST_SORT_KEYS = [
26
26
  'status',
27
27
  'priority',
28
28
  'timeSpent',
29
+ 'visibility',
29
30
  ];
30
31
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
32
  const toTaskListSortKeyType = (v) => stringToUnion(v, ALL_TASK_LIST_SORT_KEYS);
@@ -17,8 +17,12 @@ import { allTaskPriority, allTaskStatus, } from '../taskDetailView/taskDetailSel
17
17
  import { DUE_DATE_GROUP_KEYS, } from './taskList';
18
18
  import { initialState } from './taskListReducer';
19
19
  const isDefaultFilters = (taskListState) => {
20
- return (isEqual(taskListState.filters, initialState.filters) &&
21
- initialState.uiState.searchText === taskListState.uiState.searchText);
20
+ if (taskListState.uiState.searchText !== initialState.uiState.searchText) {
21
+ return false;
22
+ }
23
+ const hasNoActiveFilters = taskListState.filters.categories == null ||
24
+ taskListState.filters.categories.length === 0;
25
+ return (hasNoActiveFilters || isEqual(taskListState.filters, initialState.filters));
22
26
  };
23
27
  const sortTasksList = (tagState, tasksList, sortKey, sortOrder) => {
24
28
  const tasksInOrder = orderBy(tasksList, (task) => {