@zeniai/client-epic-state 5.2.97 → 5.2.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/view/taskManager/taskDetailView/epics/fetchTaskDetailEpic.js +11 -0
- package/lib/esm/view/taskManager/taskDetailView/epics/fetchTaskHistoryEpic.js +9 -1
- package/lib/esm/view/taskManager/taskDetailView/taskDetailLocalData.js +6 -0
- package/lib/esm/view/taskManager/taskDetailView/taskDetailReducer.js +51 -11
- package/lib/esm/view/taskManager/taskGroupView/taskGroupViewReducer.js +18 -1
- package/lib/view/taskManager/taskDetailView/epics/fetchTaskDetailEpic.js +11 -0
- package/lib/view/taskManager/taskDetailView/epics/fetchTaskHistoryEpic.js +8 -0
- package/lib/view/taskManager/taskDetailView/taskDetailLocalData.js +6 -0
- package/lib/view/taskManager/taskDetailView/taskDetailReducer.js +51 -11
- package/lib/view/taskManager/taskGroupView/taskGroupViewReducer.js +18 -1
- package/package.json +1 -1
|
@@ -22,6 +22,17 @@ export const fetchTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe(
|
|
|
22
22
|
if (cacheOverride === true) {
|
|
23
23
|
taskActions.push(removeTaskDetail(taskId));
|
|
24
24
|
}
|
|
25
|
+
// The task is already loaded and the caller did not ask for a refresh, so
|
|
26
|
+
// serve it from the store. The `fetchState !== 'In-Progress'` check below
|
|
27
|
+
// only suppresses a duplicate request while one is in flight; it is not a
|
|
28
|
+
// cache check, because a loaded task sits at 'Completed' and so passes it.
|
|
29
|
+
// Without this, re-opening the same task refetches it every time.
|
|
30
|
+
if (cacheOverride === false && isLoadedTaskDetail(taskDetail)) {
|
|
31
|
+
// Rebuild the editable copy from the cached task entity rather than
|
|
32
|
+
// emitting nothing: leaving the page discards the local data, so a
|
|
33
|
+
// silent cache hit would render an empty form.
|
|
34
|
+
return of(initializeTaskToLocalStore(taskId));
|
|
35
|
+
}
|
|
25
36
|
if (cacheOverride === true ||
|
|
26
37
|
taskDetail == null ||
|
|
27
38
|
taskDetail.fetchTaskStatus.fetchState !== 'In-Progress') {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import recordGet from 'lodash/get';
|
|
2
|
-
import { concat, from, of } from 'rxjs';
|
|
2
|
+
import { EMPTY, concat, from, of } from 'rxjs';
|
|
3
3
|
import { catchError, filter, mergeMap } from 'rxjs/operators';
|
|
4
4
|
import { createZeniAPIStatus, isSuccessResponse, } from '../../../../responsePayload';
|
|
5
5
|
import { fetchTaskHistory, updateTaskHistory, updateTaskHistoryFetchStatus, } from '../taskDetailReducer';
|
|
@@ -8,6 +8,14 @@ export const fetchTaskHistoryEpic = (actions$, state$, zeniAPI) => actions$.pipe
|
|
|
8
8
|
const historyActions = [];
|
|
9
9
|
const state = state$.value;
|
|
10
10
|
const taskHistoryDetail = recordGet(state.taskDetailState.taskHistoryById, taskId, undefined);
|
|
11
|
+
// Already fetched and no refresh asked for: keep what we have. As in
|
|
12
|
+
// fetchTaskDetailEpic, the 'In-Progress' check below is an in-flight
|
|
13
|
+
// guard, not a cache check.
|
|
14
|
+
if (cacheOverride === false &&
|
|
15
|
+
taskHistoryDetail != null &&
|
|
16
|
+
taskHistoryDetail.fetchState === 'Completed') {
|
|
17
|
+
return EMPTY;
|
|
18
|
+
}
|
|
11
19
|
if (cacheOverride === true ||
|
|
12
20
|
taskHistoryDetail == null ||
|
|
13
21
|
taskHistoryDetail.fetchState !== 'In-Progress') {
|
|
@@ -17,6 +17,12 @@ export const buildTaskDetailLocalData = (task) => ({
|
|
|
17
17
|
recurringEndDate: task.recurringEndDate,
|
|
18
18
|
},
|
|
19
19
|
savedRecurringEndDate: task.recurringEndDate,
|
|
20
|
+
// Explicitly cleared, not omitted. `saveTaskUpdatesToLocalStore` SHALLOW
|
|
21
|
+
// MERGES this over the existing local data, so a key left out here keeps
|
|
22
|
+
// whatever was there before. The task entity carries no recurrence count —
|
|
23
|
+
// this is a form-local value — so a rebuild from the entity must reset it,
|
|
24
|
+
// or an abandoned recurrence edit survives leaving and re-opening the task.
|
|
25
|
+
savedRecurringTasksCount: undefined,
|
|
20
26
|
recurringStartDate: task.recurringStartDate,
|
|
21
27
|
timeSpent: task.timeSpent,
|
|
22
28
|
isPrivate: task.isPrivate,
|
|
@@ -4,7 +4,6 @@ import { clearAll } from '../../../rootActions';
|
|
|
4
4
|
import { initialCommonHistory } from '../../spendManagement/commonHistoryView/commonHistory';
|
|
5
5
|
import { toHistoricEvent, } from '../../spendManagement/commonHistoryView/commonHistoryPayload';
|
|
6
6
|
import { initialTaskDetail, } from './taskDetail';
|
|
7
|
-
import { isLoadedTaskDetail } from './taskDetailLocalData';
|
|
8
7
|
export const initialState = {
|
|
9
8
|
newTaskState: initialTaskDetail,
|
|
10
9
|
editTaskStateById: {},
|
|
@@ -21,12 +20,17 @@ const taskDetailView = createSlice({
|
|
|
21
20
|
reducers: {
|
|
22
21
|
fetchTaskDetailPage: {
|
|
23
22
|
reducer(draft, action) {
|
|
24
|
-
const { taskId } = action.payload;
|
|
23
|
+
const { cacheOverride, taskId } = action.payload;
|
|
25
24
|
if (taskId != null) {
|
|
26
25
|
const detail = recordGet(draft.editTaskStateById, taskId, undefined);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// An already-loaded task is served from the store on BOTH paths:
|
|
27
|
+
// cacheOverride=true refreshes it in place, cacheOverride=false
|
|
28
|
+
// re-opens it. Resetting the record to `initialTaskDetail` would put
|
|
29
|
+
// `fetchTaskStatus` back to 'Not-Started' and throw the cached task
|
|
30
|
+
// away, so the detail epic's cache check could never hit and every
|
|
31
|
+
// open refetched behind a skeleton.
|
|
32
|
+
if (detail?.fetchTaskStatus.fetchState !== 'Completed' &&
|
|
33
|
+
(cacheOverride === true ||
|
|
30
34
|
detail == null ||
|
|
31
35
|
detail.fetchTaskStatus.fetchState !== 'In-Progress')) {
|
|
32
36
|
draft.editTaskStateById[taskId] = {
|
|
@@ -119,7 +123,29 @@ const taskDetailView = createSlice({
|
|
|
119
123
|
discardTaskUpdatesInLocalStore(draft, action) {
|
|
120
124
|
if (action.payload.taskId != null) {
|
|
121
125
|
const key = action.payload.taskId;
|
|
122
|
-
draft.editTaskStateById[key]
|
|
126
|
+
const existing = draft.editTaskStateById[key];
|
|
127
|
+
// Reset the MUTATION statuses. Nothing else.
|
|
128
|
+
//
|
|
129
|
+
// Replacing the whole record reset `fetchTaskStatus` to 'Not-Started',
|
|
130
|
+
// which threw the cached task away, so re-opening always refetched.
|
|
131
|
+
// But blanking `taskDetailLocalData` while keeping 'Completed' is just
|
|
132
|
+
// as wrong the other way: the page skeletons only on 'Not-Started' /
|
|
133
|
+
// 'In-Progress', so the detail page renders one more frame on its way
|
|
134
|
+
// out — now as an EMPTY form, which reads as "a new task" for an
|
|
135
|
+
// instant before the board appears. The skeleton used to cover that.
|
|
136
|
+
//
|
|
137
|
+
// The edits do not need clearing here: every open dispatches
|
|
138
|
+
// `initializeTaskToLocalStore`, and its epic overwrites the local data
|
|
139
|
+
// wholesale from the task entity. That is what actually discards them.
|
|
140
|
+
draft.editTaskStateById[key] =
|
|
141
|
+
existing == null
|
|
142
|
+
? initialTaskDetail
|
|
143
|
+
: {
|
|
144
|
+
...initialTaskDetail,
|
|
145
|
+
taskId: existing.taskId,
|
|
146
|
+
fetchTaskStatus: existing.fetchTaskStatus,
|
|
147
|
+
taskDetailLocalData: existing.taskDetailLocalData,
|
|
148
|
+
};
|
|
123
149
|
}
|
|
124
150
|
else {
|
|
125
151
|
draft.newTaskState = initialTaskDetail;
|
|
@@ -293,11 +319,21 @@ const taskDetailView = createSlice({
|
|
|
293
319
|
},
|
|
294
320
|
fetchTaskHistory: {
|
|
295
321
|
reducer(draft, action) {
|
|
296
|
-
|
|
322
|
+
// `cacheOverride` is deliberately unused: a refresh of loaded history
|
|
323
|
+
// is silent either way now, and the epic decides whether to refetch.
|
|
324
|
+
const { taskId } = action.payload;
|
|
297
325
|
const detail = recordGet(draft.taskHistoryById, taskId, undefined);
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
326
|
+
// Same as `fetchTaskDetailPage`: re-opening a task must not wipe the
|
|
327
|
+
// history it already has, or the history epic's cache check can never
|
|
328
|
+
// hit and every open refetches it.
|
|
329
|
+
//
|
|
330
|
+
// Only a record that does not exist yet is seeded. Keying this on
|
|
331
|
+
// `fetchState === 'Completed'` left a gap: a silent refresh moves the
|
|
332
|
+
// record to 'In-Progress' with its events intact, and a second refresh
|
|
333
|
+
// landing on top of that no longer saw 'Completed', so it rebuilt from
|
|
334
|
+
// `initialCommonHistory` and emptied `historicEvents` — the very flash
|
|
335
|
+
// this is here to prevent.
|
|
336
|
+
if (detail == null) {
|
|
301
337
|
draft.taskHistoryById[taskId] = {
|
|
302
338
|
...initialCommonHistory,
|
|
303
339
|
};
|
|
@@ -321,8 +357,12 @@ const taskDetailView = createSlice({
|
|
|
321
357
|
},
|
|
322
358
|
updateTaskHistoryFetchStatus(draft, action) {
|
|
323
359
|
const { taskId, fetchState, error } = action.payload;
|
|
360
|
+
// Keep the events that are already there. Spreading `initialCommonHistory`
|
|
361
|
+
// emptied the list on every status change, which the loading skeleton used
|
|
362
|
+
// to hide; now that a re-open serves from cache and shows no skeleton, a
|
|
363
|
+
// silent refresh would flash the history list empty and refill it.
|
|
324
364
|
draft.taskHistoryById[taskId] = {
|
|
325
|
-
...initialCommonHistory,
|
|
365
|
+
...(draft.taskHistoryById[taskId] ?? initialCommonHistory),
|
|
326
366
|
fetchState,
|
|
327
367
|
error,
|
|
328
368
|
};
|
|
@@ -25,7 +25,24 @@ const taskGroupView = createSlice({
|
|
|
25
25
|
initialState,
|
|
26
26
|
reducers: {
|
|
27
27
|
fetchAllTaskGroups(draft) {
|
|
28
|
-
|
|
28
|
+
// Groups already in the store: refetch in the background and stay
|
|
29
|
+
// 'Completed'. This mirrors `fetchTaskList`, which has always done it.
|
|
30
|
+
//
|
|
31
|
+
// The board's fetch state is `reduceAnyFetchState([taskListState,
|
|
32
|
+
// taskGroupViewState, ...])`, so flipping this one slice to
|
|
33
|
+
// 'In-Progress' skeletons the WHOLE board — every tab — even with the
|
|
34
|
+
// task list fully cached. The Pusher snapshot-on-connect catch-up
|
|
35
|
+
// refetches groups on every re-subscribe, which is why returning from a
|
|
36
|
+
// task made the board look like it was reloading when no task request
|
|
37
|
+
// was in flight at all.
|
|
38
|
+
//
|
|
39
|
+
// Keyed on "has a fetch ever completed", NOT on `taskGroupsIds.length`:
|
|
40
|
+
// a tenant that uses no groups has a legitimately empty list, and
|
|
41
|
+
// counting ids makes that indistinguishable from a cold load — so every
|
|
42
|
+
// catch-up would skeleton the board for exactly the orgs this is meant
|
|
43
|
+
// to help.
|
|
44
|
+
draft.fetchState =
|
|
45
|
+
draft.fetchState === 'Completed' ? 'Completed' : 'In-Progress';
|
|
29
46
|
draft.error = undefined;
|
|
30
47
|
},
|
|
31
48
|
updateTaskGroupsOnSuccess(draft, action) {
|
|
@@ -28,6 +28,17 @@ const fetchTaskDetailEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, ope
|
|
|
28
28
|
if (cacheOverride === true) {
|
|
29
29
|
taskActions.push((0, taskDetailReducer_1.removeTaskDetail)(taskId));
|
|
30
30
|
}
|
|
31
|
+
// The task is already loaded and the caller did not ask for a refresh, so
|
|
32
|
+
// serve it from the store. The `fetchState !== 'In-Progress'` check below
|
|
33
|
+
// only suppresses a duplicate request while one is in flight; it is not a
|
|
34
|
+
// cache check, because a loaded task sits at 'Completed' and so passes it.
|
|
35
|
+
// Without this, re-opening the same task refetches it every time.
|
|
36
|
+
if (cacheOverride === false && (0, taskDetailLocalData_1.isLoadedTaskDetail)(taskDetail)) {
|
|
37
|
+
// Rebuild the editable copy from the cached task entity rather than
|
|
38
|
+
// emitting nothing: leaving the page discards the local data, so a
|
|
39
|
+
// silent cache hit would render an empty form.
|
|
40
|
+
return (0, rxjs_1.of)((0, taskDetailReducer_1.initializeTaskToLocalStore)(taskId));
|
|
41
|
+
}
|
|
31
42
|
if (cacheOverride === true ||
|
|
32
43
|
taskDetail == null ||
|
|
33
44
|
taskDetail.fetchTaskStatus.fetchState !== 'In-Progress') {
|
|
@@ -14,6 +14,14 @@ const fetchTaskHistoryEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, op
|
|
|
14
14
|
const historyActions = [];
|
|
15
15
|
const state = state$.value;
|
|
16
16
|
const taskHistoryDetail = (0, get_1.default)(state.taskDetailState.taskHistoryById, taskId, undefined);
|
|
17
|
+
// Already fetched and no refresh asked for: keep what we have. As in
|
|
18
|
+
// fetchTaskDetailEpic, the 'In-Progress' check below is an in-flight
|
|
19
|
+
// guard, not a cache check.
|
|
20
|
+
if (cacheOverride === false &&
|
|
21
|
+
taskHistoryDetail != null &&
|
|
22
|
+
taskHistoryDetail.fetchState === 'Completed') {
|
|
23
|
+
return rxjs_1.EMPTY;
|
|
24
|
+
}
|
|
17
25
|
if (cacheOverride === true ||
|
|
18
26
|
taskHistoryDetail == null ||
|
|
19
27
|
taskHistoryDetail.fetchState !== 'In-Progress') {
|
|
@@ -23,6 +23,12 @@ const buildTaskDetailLocalData = (task) => ({
|
|
|
23
23
|
recurringEndDate: task.recurringEndDate,
|
|
24
24
|
},
|
|
25
25
|
savedRecurringEndDate: task.recurringEndDate,
|
|
26
|
+
// Explicitly cleared, not omitted. `saveTaskUpdatesToLocalStore` SHALLOW
|
|
27
|
+
// MERGES this over the existing local data, so a key left out here keeps
|
|
28
|
+
// whatever was there before. The task entity carries no recurrence count —
|
|
29
|
+
// this is a form-local value — so a rebuild from the entity must reset it,
|
|
30
|
+
// or an abandoned recurrence edit survives leaving and re-opening the task.
|
|
31
|
+
savedRecurringTasksCount: undefined,
|
|
26
32
|
recurringStartDate: task.recurringStartDate,
|
|
27
33
|
timeSpent: task.timeSpent,
|
|
28
34
|
isPrivate: task.isPrivate,
|
|
@@ -11,7 +11,6 @@ const rootActions_1 = require("../../../rootActions");
|
|
|
11
11
|
const commonHistory_1 = require("../../spendManagement/commonHistoryView/commonHistory");
|
|
12
12
|
const commonHistoryPayload_1 = require("../../spendManagement/commonHistoryView/commonHistoryPayload");
|
|
13
13
|
const taskDetail_1 = require("./taskDetail");
|
|
14
|
-
const taskDetailLocalData_1 = require("./taskDetailLocalData");
|
|
15
14
|
exports.initialState = {
|
|
16
15
|
newTaskState: taskDetail_1.initialTaskDetail,
|
|
17
16
|
editTaskStateById: {},
|
|
@@ -28,12 +27,17 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
28
27
|
reducers: {
|
|
29
28
|
fetchTaskDetailPage: {
|
|
30
29
|
reducer(draft, action) {
|
|
31
|
-
const { taskId } = action.payload;
|
|
30
|
+
const { cacheOverride, taskId } = action.payload;
|
|
32
31
|
if (taskId != null) {
|
|
33
32
|
const detail = (0, get_1.default)(draft.editTaskStateById, taskId, undefined);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
// An already-loaded task is served from the store on BOTH paths:
|
|
34
|
+
// cacheOverride=true refreshes it in place, cacheOverride=false
|
|
35
|
+
// re-opens it. Resetting the record to `initialTaskDetail` would put
|
|
36
|
+
// `fetchTaskStatus` back to 'Not-Started' and throw the cached task
|
|
37
|
+
// away, so the detail epic's cache check could never hit and every
|
|
38
|
+
// open refetched behind a skeleton.
|
|
39
|
+
if (detail?.fetchTaskStatus.fetchState !== 'Completed' &&
|
|
40
|
+
(cacheOverride === true ||
|
|
37
41
|
detail == null ||
|
|
38
42
|
detail.fetchTaskStatus.fetchState !== 'In-Progress')) {
|
|
39
43
|
draft.editTaskStateById[taskId] = {
|
|
@@ -126,7 +130,29 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
126
130
|
discardTaskUpdatesInLocalStore(draft, action) {
|
|
127
131
|
if (action.payload.taskId != null) {
|
|
128
132
|
const key = action.payload.taskId;
|
|
129
|
-
draft.editTaskStateById[key]
|
|
133
|
+
const existing = draft.editTaskStateById[key];
|
|
134
|
+
// Reset the MUTATION statuses. Nothing else.
|
|
135
|
+
//
|
|
136
|
+
// Replacing the whole record reset `fetchTaskStatus` to 'Not-Started',
|
|
137
|
+
// which threw the cached task away, so re-opening always refetched.
|
|
138
|
+
// But blanking `taskDetailLocalData` while keeping 'Completed' is just
|
|
139
|
+
// as wrong the other way: the page skeletons only on 'Not-Started' /
|
|
140
|
+
// 'In-Progress', so the detail page renders one more frame on its way
|
|
141
|
+
// out — now as an EMPTY form, which reads as "a new task" for an
|
|
142
|
+
// instant before the board appears. The skeleton used to cover that.
|
|
143
|
+
//
|
|
144
|
+
// The edits do not need clearing here: every open dispatches
|
|
145
|
+
// `initializeTaskToLocalStore`, and its epic overwrites the local data
|
|
146
|
+
// wholesale from the task entity. That is what actually discards them.
|
|
147
|
+
draft.editTaskStateById[key] =
|
|
148
|
+
existing == null
|
|
149
|
+
? taskDetail_1.initialTaskDetail
|
|
150
|
+
: {
|
|
151
|
+
...taskDetail_1.initialTaskDetail,
|
|
152
|
+
taskId: existing.taskId,
|
|
153
|
+
fetchTaskStatus: existing.fetchTaskStatus,
|
|
154
|
+
taskDetailLocalData: existing.taskDetailLocalData,
|
|
155
|
+
};
|
|
130
156
|
}
|
|
131
157
|
else {
|
|
132
158
|
draft.newTaskState = taskDetail_1.initialTaskDetail;
|
|
@@ -300,11 +326,21 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
300
326
|
},
|
|
301
327
|
fetchTaskHistory: {
|
|
302
328
|
reducer(draft, action) {
|
|
303
|
-
|
|
329
|
+
// `cacheOverride` is deliberately unused: a refresh of loaded history
|
|
330
|
+
// is silent either way now, and the epic decides whether to refetch.
|
|
331
|
+
const { taskId } = action.payload;
|
|
304
332
|
const detail = (0, get_1.default)(draft.taskHistoryById, taskId, undefined);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
333
|
+
// Same as `fetchTaskDetailPage`: re-opening a task must not wipe the
|
|
334
|
+
// history it already has, or the history epic's cache check can never
|
|
335
|
+
// hit and every open refetches it.
|
|
336
|
+
//
|
|
337
|
+
// Only a record that does not exist yet is seeded. Keying this on
|
|
338
|
+
// `fetchState === 'Completed'` left a gap: a silent refresh moves the
|
|
339
|
+
// record to 'In-Progress' with its events intact, and a second refresh
|
|
340
|
+
// landing on top of that no longer saw 'Completed', so it rebuilt from
|
|
341
|
+
// `initialCommonHistory` and emptied `historicEvents` — the very flash
|
|
342
|
+
// this is here to prevent.
|
|
343
|
+
if (detail == null) {
|
|
308
344
|
draft.taskHistoryById[taskId] = {
|
|
309
345
|
...commonHistory_1.initialCommonHistory,
|
|
310
346
|
};
|
|
@@ -328,8 +364,12 @@ const taskDetailView = (0, toolkit_1.createSlice)({
|
|
|
328
364
|
},
|
|
329
365
|
updateTaskHistoryFetchStatus(draft, action) {
|
|
330
366
|
const { taskId, fetchState, error } = action.payload;
|
|
367
|
+
// Keep the events that are already there. Spreading `initialCommonHistory`
|
|
368
|
+
// emptied the list on every status change, which the loading skeleton used
|
|
369
|
+
// to hide; now that a re-open serves from cache and shows no skeleton, a
|
|
370
|
+
// silent refresh would flash the history list empty and refill it.
|
|
331
371
|
draft.taskHistoryById[taskId] = {
|
|
332
|
-
...commonHistory_1.initialCommonHistory,
|
|
372
|
+
...(draft.taskHistoryById[taskId] ?? commonHistory_1.initialCommonHistory),
|
|
333
373
|
fetchState,
|
|
334
374
|
error,
|
|
335
375
|
};
|
|
@@ -29,7 +29,24 @@ const taskGroupView = (0, toolkit_1.createSlice)({
|
|
|
29
29
|
initialState: exports.initialState,
|
|
30
30
|
reducers: {
|
|
31
31
|
fetchAllTaskGroups(draft) {
|
|
32
|
-
|
|
32
|
+
// Groups already in the store: refetch in the background and stay
|
|
33
|
+
// 'Completed'. This mirrors `fetchTaskList`, which has always done it.
|
|
34
|
+
//
|
|
35
|
+
// The board's fetch state is `reduceAnyFetchState([taskListState,
|
|
36
|
+
// taskGroupViewState, ...])`, so flipping this one slice to
|
|
37
|
+
// 'In-Progress' skeletons the WHOLE board — every tab — even with the
|
|
38
|
+
// task list fully cached. The Pusher snapshot-on-connect catch-up
|
|
39
|
+
// refetches groups on every re-subscribe, which is why returning from a
|
|
40
|
+
// task made the board look like it was reloading when no task request
|
|
41
|
+
// was in flight at all.
|
|
42
|
+
//
|
|
43
|
+
// Keyed on "has a fetch ever completed", NOT on `taskGroupsIds.length`:
|
|
44
|
+
// a tenant that uses no groups has a legitimately empty list, and
|
|
45
|
+
// counting ids makes that indistinguishable from a cold load — so every
|
|
46
|
+
// catch-up would skeleton the board for exactly the orgs this is meant
|
|
47
|
+
// to help.
|
|
48
|
+
draft.fetchState =
|
|
49
|
+
draft.fetchState === 'Completed' ? 'Completed' : 'In-Progress';
|
|
33
50
|
draft.error = undefined;
|
|
34
51
|
},
|
|
35
52
|
updateTaskGroupsOnSuccess(draft, action) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.99",
|
|
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",
|