@zeniai/client-epic-state 5.2.75 → 5.2.76-betaNB1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/lib/commonStateTypes/common.d.ts +3 -0
  2. package/lib/commonStateTypes/common.js +10 -1
  3. package/lib/entity/reconciliationReport/reconciliationReportPayload.d.ts +124 -0
  4. package/lib/entity/reconciliationReport/reconciliationReportPayload.js +2 -0
  5. package/lib/entity/reconciliationReport/reconciliationReportReducer.d.ts +7 -0
  6. package/lib/entity/reconciliationReport/reconciliationReportReducer.js +173 -0
  7. package/lib/entity/reconciliationReport/reconciliationReportSelector.d.ts +3 -0
  8. package/lib/entity/reconciliationReport/reconciliationReportSelector.js +10 -0
  9. package/lib/entity/reconciliationReport/reconciliationReportState.d.ts +133 -0
  10. package/lib/entity/reconciliationReport/reconciliationReportState.js +15 -0
  11. package/lib/epic.d.ts +2 -1
  12. package/lib/epic.js +2 -0
  13. package/lib/esm/commonStateTypes/common.js +8 -0
  14. package/lib/esm/entity/reconciliationReport/reconciliationReportPayload.js +1 -0
  15. package/lib/esm/entity/reconciliationReport/reconciliationReportReducer.js +168 -0
  16. package/lib/esm/entity/reconciliationReport/reconciliationReportSelector.js +4 -0
  17. package/lib/esm/entity/reconciliationReport/reconciliationReportState.js +10 -0
  18. package/lib/esm/epic.js +2 -0
  19. package/lib/esm/index.js +5 -2
  20. package/lib/esm/reducer.js +7 -1
  21. package/lib/esm/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +140 -9
  22. package/lib/esm/view/reconciliationReportView/epic/fetchReconciliationReportEpic.js +29 -0
  23. package/lib/esm/view/reconciliationReportView/reconciliationReportViewPayload.js +1 -0
  24. package/lib/esm/view/reconciliationReportView/reconciliationReportViewReducer.js +44 -0
  25. package/lib/esm/view/reconciliationReportView/reconciliationReportViewSelector.js +10 -0
  26. package/lib/esm/view/reconciliationReportView/reconciliationReportViewState.js +1 -0
  27. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +70 -19
  28. package/lib/index.d.ts +6 -2
  29. package/lib/index.js +40 -34
  30. package/lib/reducer.d.ts +2 -0
  31. package/lib/reducer.js +7 -1
  32. package/lib/rootStateTypes.d.ts +5 -1
  33. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.d.ts +1 -1
  34. package/lib/view/companyTaskManagerView/epics/fetchCompanyTaskManagerViewEpic.js +140 -9
  35. package/lib/view/reconciliationReportView/epic/fetchReconciliationReportEpic.d.ts +19 -0
  36. package/lib/view/reconciliationReportView/epic/fetchReconciliationReportEpic.js +33 -0
  37. package/lib/view/reconciliationReportView/reconciliationReportViewPayload.d.ts +3 -0
  38. package/lib/view/reconciliationReportView/reconciliationReportViewPayload.js +2 -0
  39. package/lib/view/reconciliationReportView/reconciliationReportViewReducer.d.ts +13 -0
  40. package/lib/view/reconciliationReportView/reconciliationReportViewReducer.js +48 -0
  41. package/lib/view/reconciliationReportView/reconciliationReportViewSelector.d.ts +9 -0
  42. package/lib/view/reconciliationReportView/reconciliationReportViewSelector.js +13 -0
  43. package/lib/view/reconciliationReportView/reconciliationReportViewState.d.ts +4 -0
  44. package/lib/view/reconciliationReportView/reconciliationReportViewState.js +2 -0
  45. package/lib/view/taskManager/taskListView/taskListSelector.d.ts +13 -2
  46. package/lib/view/taskManager/taskListView/taskListSelector.js +70 -19
  47. package/package.json +1 -1
@@ -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-betaNB1",
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",