@zeniai/client-epic-state 5.3.12-beta0DI → 5.3.13

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 (93) hide show
  1. package/lib/commonStateTypes/animations.d.ts +1 -1
  2. package/lib/commonStateTypes/animations.js +1 -0
  3. package/lib/entity/task/taskPayload.d.ts +0 -1
  4. package/lib/entity/task/taskPayload.js +0 -1
  5. package/lib/entity/task/taskReducer.d.ts +1 -4
  6. package/lib/entity/task/taskReducer.js +2 -19
  7. package/lib/entity/task/taskState.d.ts +0 -3
  8. package/lib/epic.d.ts +2 -4
  9. package/lib/epic.js +2 -9
  10. package/lib/esm/commonStateTypes/animations.js +1 -0
  11. package/lib/esm/entity/task/taskPayload.js +0 -1
  12. package/lib/esm/entity/task/taskReducer.js +1 -18
  13. package/lib/esm/epic.js +2 -9
  14. package/lib/esm/index.js +5 -8
  15. package/lib/esm/reducer.js +0 -6
  16. package/lib/esm/view/aiCfoView/aiCfoViewReducer.js +65 -3
  17. package/lib/esm/view/aiCfoView/aiCfoViewSelector.js +25 -0
  18. package/lib/esm/view/aiCfoView/epics/transcribeAudioEpic.js +60 -0
  19. package/lib/esm/view/expenseAutomationView/types/transactionGroup.js +10 -5
  20. package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +0 -3
  21. package/lib/esm/view/taskManager/taskListView/taskList.js +0 -6
  22. package/lib/esm/view/taskManager/taskListView/taskListFilterHelpers.js +0 -7
  23. package/lib/esm/view/taskManager/taskListView/taskListSelector.js +11 -27
  24. package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +0 -37
  25. package/lib/esm/view/transactionDetail/createTransaction/createTransactionPayload.js +19 -3
  26. package/lib/esm/view/transactionDetail/createTransaction/createTransactionState.js +2 -0
  27. package/lib/index.d.ts +6 -10
  28. package/lib/index.js +28 -37
  29. package/lib/reducer.d.ts +0 -2
  30. package/lib/reducer.js +0 -6
  31. package/lib/rootStateTypes.d.ts +0 -4
  32. package/lib/view/aiCfoView/aiCfoViewPayload.d.ts +20 -0
  33. package/lib/view/aiCfoView/aiCfoViewReducer.d.ts +2 -2
  34. package/lib/view/aiCfoView/aiCfoViewReducer.js +66 -4
  35. package/lib/view/aiCfoView/aiCfoViewSelector.d.ts +8 -1
  36. package/lib/view/aiCfoView/aiCfoViewSelector.js +27 -0
  37. package/lib/view/aiCfoView/aiCfoViewState.d.ts +9 -0
  38. package/lib/view/aiCfoView/epics/transcribeAudioEpic.d.ts +19 -0
  39. package/lib/view/aiCfoView/epics/transcribeAudioEpic.js +64 -0
  40. package/lib/view/expenseAutomationView/payload/transactionCategorizationPayload.d.ts +2 -2
  41. package/lib/view/expenseAutomationView/reducers/transactionsViewReducer.d.ts +2 -2
  42. package/lib/view/expenseAutomationView/types/transactionGroup.d.ts +6 -6
  43. package/lib/view/expenseAutomationView/types/transactionGroup.js +10 -5
  44. package/lib/view/expenseAutomationView/types/transactionsViewState.d.ts +2 -2
  45. package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +0 -4
  46. package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +0 -3
  47. package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
  48. package/lib/view/taskManager/taskListView/taskList.js +0 -6
  49. package/lib/view/taskManager/taskListView/taskListFilterHelpers.d.ts +0 -4
  50. package/lib/view/taskManager/taskListView/taskListFilterHelpers.js +1 -9
  51. package/lib/view/taskManager/taskListView/taskListSelector.d.ts +3 -6
  52. package/lib/view/taskManager/taskListView/taskListSelector.js +10 -26
  53. package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +1 -1
  54. package/lib/view/taskManager/taskListView/taskListViewHelpers.js +0 -37
  55. package/lib/view/transactionDetail/createTransaction/createTransactionPayload.d.ts +6 -3
  56. package/lib/view/transactionDetail/createTransaction/createTransactionPayload.js +19 -3
  57. package/lib/view/transactionDetail/createTransaction/createTransactionState.d.ts +7 -2
  58. package/lib/view/transactionDetail/createTransaction/createTransactionState.js +2 -0
  59. package/lib/view/transactionDetail/transactionDetailReducer.d.ts +20 -20
  60. package/package.json +1 -1
  61. package/lib/entity/timeEntry/timeEntryPayload.d.ts +0 -26
  62. package/lib/entity/timeEntry/timeEntryPayload.js +0 -2
  63. package/lib/entity/timeEntry/timeEntryReducer.d.ts +0 -8
  64. package/lib/entity/timeEntry/timeEntryReducer.js +0 -76
  65. package/lib/entity/timeEntry/timeEntrySelector.d.ts +0 -10
  66. package/lib/entity/timeEntry/timeEntrySelector.js +0 -32
  67. package/lib/entity/timeEntry/timeEntryState.d.ts +0 -43
  68. package/lib/entity/timeEntry/timeEntryState.js +0 -13
  69. package/lib/esm/entity/timeEntry/timeEntryPayload.js +0 -1
  70. package/lib/esm/entity/timeEntry/timeEntryReducer.js +0 -70
  71. package/lib/esm/entity/timeEntry/timeEntrySelector.js +0 -23
  72. package/lib/esm/entity/timeEntry/timeEntryState.js +0 -8
  73. package/lib/esm/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.js +0 -24
  74. package/lib/esm/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.js +0 -73
  75. package/lib/esm/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.js +0 -77
  76. package/lib/esm/view/taskManager/timeEntryView/timeEntryViewPayload.js +0 -1
  77. package/lib/esm/view/taskManager/timeEntryView/timeEntryViewReducer.js +0 -160
  78. package/lib/esm/view/taskManager/timeEntryView/timeEntryViewSelector.js +0 -41
  79. package/lib/esm/view/taskManager/timeEntryView/timeEntryViewState.js +0 -1
  80. package/lib/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.d.ts +0 -18
  81. package/lib/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.js +0 -28
  82. package/lib/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.d.ts +0 -23
  83. package/lib/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.js +0 -78
  84. package/lib/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.d.ts +0 -23
  85. package/lib/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.js +0 -83
  86. package/lib/view/taskManager/timeEntryView/timeEntryViewPayload.d.ts +0 -27
  87. package/lib/view/taskManager/timeEntryView/timeEntryViewPayload.js +0 -2
  88. package/lib/view/taskManager/timeEntryView/timeEntryViewReducer.d.ts +0 -48
  89. package/lib/view/taskManager/timeEntryView/timeEntryViewReducer.js +0 -164
  90. package/lib/view/taskManager/timeEntryView/timeEntryViewSelector.d.ts +0 -24
  91. package/lib/view/taskManager/timeEntryView/timeEntryViewSelector.js +0 -46
  92. package/lib/view/taskManager/timeEntryView/timeEntryViewState.d.ts +0 -21
  93. package/lib/view/taskManager/timeEntryView/timeEntryViewState.js +0 -5
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchTimeEntriesForRangeEpic = exports.fetchTimeEntriesForTaskEpic = void 0;
4
- const rxjs_1 = require("rxjs");
5
- const operators_1 = require("rxjs/operators");
6
- const timeEntryReducer_1 = require("../../../../entity/timeEntry/timeEntryReducer");
7
- const responsePayload_1 = require("../../../../responsePayload");
8
- const timeEntryViewReducer_1 = require("../timeEntryViewReducer");
9
- const timeEntryViewState_1 = require("../timeEntryViewState");
10
- /**
11
- * Every entry on one task, all users — the task detail breakdown.
12
- *
13
- * `mergeMap`, not `switchMap`: a detail page and an expanded board row can
14
- * ask for two different tasks at once, and cancelling the first would leave
15
- * its breakdown stuck In-Progress forever.
16
- */
17
- const fetchTimeEntriesForTaskEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(timeEntryViewReducer_1.fetchTimeEntriesForTask.match), (0, operators_1.mergeMap)((action) => {
18
- const { taskId, cacheOverride } = action.payload;
19
- const cached = state$.value.timeEntryViewState.timeEntryIdsByTaskId[taskId];
20
- const status = state$.value.timeEntryViewState.fetchStateByTaskId[taskId];
21
- // The reducer has already flipped this request to In-Progress, so the
22
- // guard reads the COMPLETED cache, never the fetch state -- a fetch
23
- // state is not an in-flight signal.
24
- if (cacheOverride !== true &&
25
- cached != null &&
26
- status?.fetchState === 'In-Progress') {
27
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.fetchTimeEntriesForTaskSuccess)({ taskId, timeEntryIds: cached }));
28
- }
29
- return zeniAPI
30
- .getJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks/${taskId}/time-entries`)
31
- .pipe((0, operators_1.mergeMap)((response) => {
32
- if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
33
- const entries = response.data.time_entries ?? [];
34
- return (0, rxjs_1.of)((0, timeEntryReducer_1.updateTimeEntries)(entries), (0, timeEntryViewReducer_1.fetchTimeEntriesForTaskSuccess)({
35
- taskId,
36
- timeEntryIds: entries.map((entry) => entry.time_entry_id),
37
- }));
38
- }
39
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.fetchTimeEntriesForTaskFailure)({ taskId, status: response.status }));
40
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, timeEntryViewReducer_1.fetchTimeEntriesForTaskFailure)({
41
- taskId,
42
- status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch time entries for task errored out' +
43
- JSON.stringify(error)),
44
- }))));
45
- }));
46
- exports.fetchTimeEntriesForTaskEpic = fetchTimeEntriesForTaskEpic;
47
- /**
48
- * One user's entries in an inclusive date range — the weekly timesheet.
49
- *
50
- * Needs the `is_deleted + user_id + entry_date` composite index (api #593).
51
- * Without it the server returns 500, not an empty list, so the failure is
52
- * surfaced rather than rendered as a blank week.
53
- */
54
- const fetchTimeEntriesForRangeEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(timeEntryViewReducer_1.fetchTimeEntriesForRange.match), (0, operators_1.mergeMap)((action) => {
55
- const { userId, startDate, endDate } = action.payload;
56
- const rangeKey = (0, timeEntryViewState_1.toTimeEntryRangeKey)(userId, startDate, endDate);
57
- const query = `user_id=${encodeURIComponent(userId)}&start_date=${encodeURIComponent(startDate)}&end_date=${encodeURIComponent(endDate)}`;
58
- return zeniAPI
59
- .getJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/time-entries?${query}`)
60
- .pipe((0, operators_1.mergeMap)((response) => {
61
- if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
62
- const entries = response.data.time_entries ?? [];
63
- return (0, rxjs_1.of)((0, timeEntryReducer_1.updateTimeEntries)(entries), (0, timeEntryViewReducer_1.fetchTimeEntriesForRangeSuccess)({
64
- rangeKey,
65
- timeEntryIds: entries.map((entry) => entry.time_entry_id),
66
- }));
67
- }
68
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.fetchTimeEntriesForRangeFailure)({
69
- rangeKey,
70
- status: response.status,
71
- }));
72
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, timeEntryViewReducer_1.fetchTimeEntriesForRangeFailure)({
73
- rangeKey,
74
- status: (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', 'Fetch time entries for range errored out' +
75
- JSON.stringify(error)),
76
- }))));
77
- }));
78
- exports.fetchTimeEntriesForRangeEpic = fetchTimeEntriesForRangeEpic;
@@ -1,23 +0,0 @@
1
- import { ActionsObservable, StateObservable } from 'redux-observable';
2
- import { Observable } from 'rxjs';
3
- import { updateTaskTimeSpentMinutes } from '../../../../entity/task/taskReducer';
4
- import { removeTimeEntry, updateTimeEntries } from '../../../../entity/timeEntry/timeEntryReducer';
5
- import { RootState } from '../../../../rootStateTypes';
6
- import { ZeniAPI } from '../../../../zeniAPI';
7
- import { deleteTimeEntry, logTime, logTimeFailure, logTimeSuccess, timeEntryWriteFailure, timeEntryWriteSuccess, updateTimeEntryMinutes } from '../timeEntryViewReducer';
8
- export type ActionType = ReturnType<typeof logTime> | ReturnType<typeof logTimeSuccess> | ReturnType<typeof logTimeFailure> | ReturnType<typeof updateTimeEntryMinutes> | ReturnType<typeof deleteTimeEntry> | ReturnType<typeof timeEntryWriteSuccess> | ReturnType<typeof timeEntryWriteFailure> | ReturnType<typeof updateTimeEntries> | ReturnType<typeof removeTimeEntry> | ReturnType<typeof updateTaskTimeSpentMinutes>;
9
- /**
10
- * Log time against a task.
11
- *
12
- * `mergeMap`, not `switchMap`: two rows on the board can be edited in quick
13
- * succession and cancelling the first would silently drop that entry.
14
- */
15
- export declare const logTimeEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
16
- /** Correct an entry's minutes. Owner, or a Zeni user as the admin path. */
17
- export declare const updateTimeEntryEpic: (actions$: ActionsObservable<ActionType>, _state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
18
- /**
19
- * Soft delete. The row stays in Datastore for the audit trail but leaves the
20
- * totals, so the client drops it from the store rather than keeping something
21
- * every reader would then have to remember to filter.
22
- */
23
- export declare const deleteTimeEntryEpic: (actions$: ActionsObservable<ActionType>, state$: StateObservable<RootState>, zeniAPI: ZeniAPI) => Observable<ActionType>;
@@ -1,83 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteTimeEntryEpic = exports.updateTimeEntryEpic = exports.logTimeEpic = void 0;
4
- const rxjs_1 = require("rxjs");
5
- const operators_1 = require("rxjs/operators");
6
- const taskReducer_1 = require("../../../../entity/task/taskReducer");
7
- const timeEntryReducer_1 = require("../../../../entity/timeEntry/timeEntryReducer");
8
- const timeEntrySelector_1 = require("../../../../entity/timeEntry/timeEntrySelector");
9
- const responsePayload_1 = require("../../../../responsePayload");
10
- const timeEntryViewReducer_1 = require("../timeEntryViewReducer");
11
- const unexpected = (what, error) => (0, responsePayload_1.createZeniAPIStatus)('Unexpected Error', `${what} errored out${JSON.stringify(error)}`);
12
- /**
13
- * Log time against a task.
14
- *
15
- * `mergeMap`, not `switchMap`: two rows on the board can be edited in quick
16
- * succession and cancelling the first would silently drop that entry.
17
- */
18
- const logTimeEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(timeEntryViewReducer_1.logTime.match), (0, operators_1.mergeMap)((action) => {
19
- const { taskId, minutes, entryDate, source, identifier } = action.payload;
20
- return zeniAPI
21
- .postAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/tasks/${taskId}/time-entries`, {
22
- minutes,
23
- entry_date: entryDate,
24
- source,
25
- // Sent only when the caller has one. The server treats it as the
26
- // entity key, which is what makes a retried timer stop idempotent.
27
- ...(identifier != null ? { identifier } : {}),
28
- })
29
- .pipe((0, operators_1.mergeMap)((response) => {
30
- if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
31
- const { time_entry, task_time_spent_minutes } = response.data;
32
- return (0, rxjs_1.of)((0, timeEntryReducer_1.updateTimeEntries)([time_entry]),
33
- // The board reads `Task.time_spent` per row, so it has to be
34
- // told the new total; otherwise the row keeps the old number
35
- // until something refetches the whole list.
36
- (0, taskReducer_1.updateTaskTimeSpentMinutes)({
37
- taskId,
38
- minutes: task_time_spent_minutes ?? 0,
39
- }), (0, timeEntryViewReducer_1.logTimeSuccess)({ taskId, timeEntryId: time_entry.time_entry_id }));
40
- }
41
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.logTimeFailure)({ taskId, status: response.status }));
42
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, timeEntryViewReducer_1.logTimeFailure)({ taskId, status: unexpected('Log time', error) }))));
43
- }));
44
- exports.logTimeEpic = logTimeEpic;
45
- /** Correct an entry's minutes. Owner, or a Zeni user as the admin path. */
46
- const updateTimeEntryEpic = (actions$, _state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(timeEntryViewReducer_1.updateTimeEntryMinutes.match), (0, operators_1.mergeMap)((action) => {
47
- const { timeEntryId, minutes } = action.payload;
48
- return zeniAPI
49
- .putAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/time-entries/${timeEntryId}`, { minutes })
50
- .pipe((0, operators_1.mergeMap)((response) => {
51
- if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
52
- return (0, rxjs_1.of)((0, timeEntryReducer_1.updateTimeEntries)([response.data.time_entry]), (0, timeEntryViewReducer_1.timeEntryWriteSuccess)({ timeEntryId }));
53
- }
54
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.timeEntryWriteFailure)({ timeEntryId, status: response.status }));
55
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, timeEntryViewReducer_1.timeEntryWriteFailure)({
56
- timeEntryId,
57
- status: unexpected('Update time entry', error),
58
- }))));
59
- }));
60
- exports.updateTimeEntryEpic = updateTimeEntryEpic;
61
- /**
62
- * Soft delete. The row stays in Datastore for the audit trail but leaves the
63
- * totals, so the client drops it from the store rather than keeping something
64
- * every reader would then have to remember to filter.
65
- */
66
- const deleteTimeEntryEpic = (actions$, state$, zeniAPI) => actions$.pipe((0, operators_1.filter)(timeEntryViewReducer_1.deleteTimeEntry.match), (0, operators_1.mergeMap)((action) => {
67
- const timeEntryId = action.payload;
68
- // Read the task id BEFORE the delete: the entry is about to leave the
69
- // store, and the view slice needs to know which task's id list to prune.
70
- const taskId = (0, timeEntrySelector_1.getTimeEntryById)(state$.value.timeEntryState, timeEntryId)?.taskId;
71
- return zeniAPI
72
- .deleteAndGetJSON(`${zeniAPI.apiEndPoints.taskMicroServiceBaseUrl}/1.0/task-manager/time-entries/${timeEntryId}`)
73
- .pipe((0, operators_1.mergeMap)((response) => {
74
- if ((0, responsePayload_1.isSuccessResponse)(response)) {
75
- return (0, rxjs_1.of)((0, timeEntryReducer_1.removeTimeEntry)(timeEntryId), (0, timeEntryViewReducer_1.timeEntryWriteSuccess)({ timeEntryId, removedFromTaskId: taskId }));
76
- }
77
- return (0, rxjs_1.of)((0, timeEntryViewReducer_1.timeEntryWriteFailure)({ timeEntryId, status: response.status }));
78
- }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, timeEntryViewReducer_1.timeEntryWriteFailure)({
79
- timeEntryId,
80
- status: unexpected('Delete time entry', error),
81
- }))));
82
- }));
83
- exports.deleteTimeEntryEpic = deleteTimeEntryEpic;
@@ -1,27 +0,0 @@
1
- import { ID } from '../../../commonStateTypes/common';
2
- import { TaskCategoryPayload, TimeEntryPayload } from '../../../entity/timeEntry/timeEntryPayload';
3
- import { ZeniAPIResponse } from '../../../responsePayload';
4
- export interface TimeEntriesPayload {
5
- time_entries: TimeEntryPayload[];
6
- total_minutes: number;
7
- }
8
- export interface TimeEntryRangePayload extends TimeEntriesPayload {
9
- end_date: string;
10
- start_date: string;
11
- user_id: ID;
12
- }
13
- export interface TimeEntryWritePayload {
14
- /** The ids whose `time_spent` the server recomputed. The client refreshes
15
- * exactly these board rows instead of the whole list. */
16
- recomputed_task_ids: ID[];
17
- time_entry: TimeEntryPayload;
18
- task_time_spent_minutes?: number;
19
- }
20
- export interface TaskCategoriesPayload {
21
- count: number;
22
- task_categories: TaskCategoryPayload[];
23
- }
24
- export type TimeEntriesResponse = ZeniAPIResponse<TimeEntriesPayload>;
25
- export type TimeEntryRangeResponse = ZeniAPIResponse<TimeEntryRangePayload>;
26
- export type TimeEntryWriteResponse = ZeniAPIResponse<TimeEntryWritePayload>;
27
- export type TaskCategoriesResponse = ZeniAPIResponse<TaskCategoriesPayload>;
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,48 +0,0 @@
1
- import { ID } from '../../../commonStateTypes/common';
2
- import { ZeniAPIStatus } from '../../../responsePayload';
3
- import { TimeEntryRangeKey, TimeEntryViewState } from './timeEntryViewState';
4
- export declare const initialState: TimeEntryViewState;
5
- export declare const fetchTimeEntriesForTask: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId: string, cacheOverride?: any], {
6
- taskId: string;
7
- cacheOverride: any;
8
- }, "timeEntryView/fetchTimeEntriesForTask", never, never>, fetchTimeEntriesForTaskSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
9
- taskId: ID;
10
- timeEntryIds: ID[];
11
- }, "timeEntryView/fetchTimeEntriesForTaskSuccess">, fetchTimeEntriesForTaskFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
12
- status: ZeniAPIStatus;
13
- taskId: ID;
14
- }, "timeEntryView/fetchTimeEntriesForTaskFailure">, fetchTimeEntriesForRange: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, startDate: string, endDate: string, cacheOverride?: any], {
15
- userId: string;
16
- startDate: string;
17
- endDate: string;
18
- cacheOverride: any;
19
- }, "timeEntryView/fetchTimeEntriesForRange", never, never>, fetchTimeEntriesForRangeSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
20
- rangeKey: TimeEntryRangeKey;
21
- timeEntryIds: ID[];
22
- }, "timeEntryView/fetchTimeEntriesForRangeSuccess">, fetchTimeEntriesForRangeFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
23
- rangeKey: TimeEntryRangeKey;
24
- status: ZeniAPIStatus;
25
- }, "timeEntryView/fetchTimeEntriesForRangeFailure">, logTime: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[taskId: string, minutes: number, entryDate: string, source?: "manual" | "timer" | undefined, identifier?: string | undefined], {
26
- taskId: string;
27
- minutes: number;
28
- entryDate: string;
29
- source: "manual" | "timer";
30
- identifier: string | undefined;
31
- }, "timeEntryView/logTime", never, never>, logTimeSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
32
- taskId: ID;
33
- timeEntryId: ID;
34
- }, "timeEntryView/logTimeSuccess">, logTimeFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
35
- status: ZeniAPIStatus;
36
- taskId: ID;
37
- }, "timeEntryView/logTimeFailure">, updateTimeEntryMinutes: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[timeEntryId: string, minutes: number], {
38
- timeEntryId: string;
39
- minutes: number;
40
- }, "timeEntryView/updateTimeEntryMinutes", never, never>, deleteTimeEntry: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "timeEntryView/deleteTimeEntry">, timeEntryWriteSuccess: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
41
- timeEntryId: ID;
42
- removedFromTaskId?: ID;
43
- }, "timeEntryView/timeEntryWriteSuccess">, timeEntryWriteFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
44
- status: ZeniAPIStatus;
45
- timeEntryId: ID;
46
- }, "timeEntryView/timeEntryWriteFailure">, fetchTaskCategories: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"timeEntryView/fetchTaskCategories">, fetchTaskCategoriesSuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"timeEntryView/fetchTaskCategoriesSuccess">, fetchTaskCategoriesFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "timeEntryView/fetchTaskCategoriesFailure">;
47
- declare const _default: import("redux").Reducer<TimeEntryViewState>;
48
- export default _default;
@@ -1,164 +0,0 @@
1
- "use strict";
2
- var _a;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.fetchTaskCategoriesFailure = exports.fetchTaskCategoriesSuccess = exports.fetchTaskCategories = exports.timeEntryWriteFailure = exports.timeEntryWriteSuccess = exports.deleteTimeEntry = exports.updateTimeEntryMinutes = exports.logTimeFailure = exports.logTimeSuccess = exports.logTime = exports.fetchTimeEntriesForRangeFailure = exports.fetchTimeEntriesForRangeSuccess = exports.fetchTimeEntriesForRange = exports.fetchTimeEntriesForTaskFailure = exports.fetchTimeEntriesForTaskSuccess = exports.fetchTimeEntriesForTask = exports.initialState = void 0;
5
- const toolkit_1 = require("@reduxjs/toolkit");
6
- const rootActions_1 = require("../../../rootActions");
7
- const NOT_STARTED = { fetchState: 'Not-Started', error: undefined };
8
- exports.initialState = {
9
- timeEntryIdsByTaskId: {},
10
- fetchStateByTaskId: {},
11
- timeEntryIdsByRangeKey: {},
12
- fetchStateByRangeKey: {},
13
- saveStateByTaskId: {},
14
- saveStateByTimeEntryId: {},
15
- taskCategoryFetchState: NOT_STARTED,
16
- };
17
- const timeEntryView = (0, toolkit_1.createSlice)({
18
- name: 'timeEntryView',
19
- initialState: exports.initialState,
20
- reducers: {
21
- fetchTimeEntriesForTask: {
22
- prepare(taskId, cacheOverride = false) {
23
- return { payload: { taskId, cacheOverride } };
24
- },
25
- reducer(draft, action) {
26
- draft.fetchStateByTaskId[action.payload.taskId] = {
27
- fetchState: 'In-Progress',
28
- error: undefined,
29
- };
30
- },
31
- },
32
- fetchTimeEntriesForTaskSuccess(draft, action) {
33
- const { taskId, timeEntryIds } = action.payload;
34
- // Replaced, not merged: the server is authoritative about which entries
35
- // a task has, and a merge would resurrect one that was just deleted.
36
- draft.timeEntryIdsByTaskId[taskId] = timeEntryIds;
37
- draft.fetchStateByTaskId[taskId] = {
38
- fetchState: 'Completed',
39
- error: undefined,
40
- };
41
- },
42
- fetchTimeEntriesForTaskFailure(draft, action) {
43
- draft.fetchStateByTaskId[action.payload.taskId] = {
44
- fetchState: 'Error',
45
- error: action.payload.status,
46
- };
47
- },
48
- fetchTimeEntriesForRange: {
49
- prepare(userId, startDate, endDate, cacheOverride = false) {
50
- return { payload: { userId, startDate, endDate, cacheOverride } };
51
- },
52
- reducer(draft, action) {
53
- const { userId, startDate, endDate } = action.payload;
54
- draft.fetchStateByRangeKey[`${userId}_${startDate}_${endDate}`] = {
55
- fetchState: 'In-Progress',
56
- error: undefined,
57
- };
58
- },
59
- },
60
- fetchTimeEntriesForRangeSuccess(draft, action) {
61
- const { rangeKey, timeEntryIds } = action.payload;
62
- draft.timeEntryIdsByRangeKey[rangeKey] = timeEntryIds;
63
- draft.fetchStateByRangeKey[rangeKey] = {
64
- fetchState: 'Completed',
65
- error: undefined,
66
- };
67
- },
68
- fetchTimeEntriesForRangeFailure(draft, action) {
69
- draft.fetchStateByRangeKey[action.payload.rangeKey] = {
70
- fetchState: 'Error',
71
- error: action.payload.status,
72
- };
73
- },
74
- logTime: {
75
- prepare(taskId, minutes, entryDate, source = 'manual', identifier) {
76
- return { payload: { taskId, minutes, entryDate, source, identifier } };
77
- },
78
- reducer(draft, action) {
79
- draft.saveStateByTaskId[action.payload.taskId] = {
80
- fetchState: 'In-Progress',
81
- error: undefined,
82
- };
83
- },
84
- },
85
- logTimeSuccess(draft, action) {
86
- const { taskId, timeEntryId } = action.payload;
87
- draft.saveStateByTaskId[taskId] = {
88
- fetchState: 'Completed',
89
- error: undefined,
90
- };
91
- const existing = draft.timeEntryIdsByTaskId[taskId] ?? [];
92
- // Guarded against a duplicate id: a retried write with the same
93
- // deterministic identifier returns the SAME entry, and pushing it twice
94
- // would double it in the breakdown even though the server has one row.
95
- if (!existing.includes(timeEntryId)) {
96
- draft.timeEntryIdsByTaskId[taskId] = [...existing, timeEntryId];
97
- }
98
- },
99
- logTimeFailure(draft, action) {
100
- draft.saveStateByTaskId[action.payload.taskId] = {
101
- fetchState: 'Error',
102
- error: action.payload.status,
103
- };
104
- },
105
- updateTimeEntryMinutes: {
106
- prepare(timeEntryId, minutes) {
107
- return { payload: { timeEntryId, minutes } };
108
- },
109
- reducer(draft, action) {
110
- draft.saveStateByTimeEntryId[action.payload.timeEntryId] = {
111
- fetchState: 'In-Progress',
112
- error: undefined,
113
- };
114
- },
115
- },
116
- deleteTimeEntry(draft, action) {
117
- draft.saveStateByTimeEntryId[action.payload] = {
118
- fetchState: 'In-Progress',
119
- error: undefined,
120
- };
121
- },
122
- timeEntryWriteSuccess(draft, action) {
123
- const { timeEntryId, removedFromTaskId } = action.payload;
124
- draft.saveStateByTimeEntryId[timeEntryId] = {
125
- fetchState: 'Completed',
126
- error: undefined,
127
- };
128
- if (removedFromTaskId != null) {
129
- draft.timeEntryIdsByTaskId[removedFromTaskId] = (draft.timeEntryIdsByTaskId[removedFromTaskId] ?? []).filter((candidate) => candidate !== timeEntryId);
130
- }
131
- },
132
- timeEntryWriteFailure(draft, action) {
133
- draft.saveStateByTimeEntryId[action.payload.timeEntryId] = {
134
- fetchState: 'Error',
135
- error: action.payload.status,
136
- };
137
- },
138
- fetchTaskCategories(draft) {
139
- draft.taskCategoryFetchState = {
140
- fetchState: 'In-Progress',
141
- error: undefined,
142
- };
143
- },
144
- fetchTaskCategoriesSuccess(draft) {
145
- draft.taskCategoryFetchState = {
146
- fetchState: 'Completed',
147
- error: undefined,
148
- };
149
- },
150
- fetchTaskCategoriesFailure(draft, action) {
151
- draft.taskCategoryFetchState = {
152
- fetchState: 'Error',
153
- error: action.payload,
154
- };
155
- },
156
- },
157
- extraReducers: (builder) => {
158
- builder.addCase(rootActions_1.clearAll, (draft) => {
159
- Object.assign(draft, exports.initialState);
160
- });
161
- },
162
- });
163
- _a = timeEntryView.actions, exports.fetchTimeEntriesForTask = _a.fetchTimeEntriesForTask, exports.fetchTimeEntriesForTaskSuccess = _a.fetchTimeEntriesForTaskSuccess, exports.fetchTimeEntriesForTaskFailure = _a.fetchTimeEntriesForTaskFailure, exports.fetchTimeEntriesForRange = _a.fetchTimeEntriesForRange, exports.fetchTimeEntriesForRangeSuccess = _a.fetchTimeEntriesForRangeSuccess, exports.fetchTimeEntriesForRangeFailure = _a.fetchTimeEntriesForRangeFailure, exports.logTime = _a.logTime, exports.logTimeSuccess = _a.logTimeSuccess, exports.logTimeFailure = _a.logTimeFailure, exports.updateTimeEntryMinutes = _a.updateTimeEntryMinutes, exports.deleteTimeEntry = _a.deleteTimeEntry, exports.timeEntryWriteSuccess = _a.timeEntryWriteSuccess, exports.timeEntryWriteFailure = _a.timeEntryWriteFailure, exports.fetchTaskCategories = _a.fetchTaskCategories, exports.fetchTaskCategoriesSuccess = _a.fetchTaskCategoriesSuccess, exports.fetchTaskCategoriesFailure = _a.fetchTaskCategoriesFailure;
164
- exports.default = timeEntryView.reducer;
@@ -1,24 +0,0 @@
1
- import { FetchState, ID } from '../../../commonStateTypes/common';
2
- import { TimeEntry } from '../../../entity/timeEntry/timeEntryState';
3
- import { ZeniAPIStatus } from '../../../responsePayload';
4
- import { RootState } from '../../../rootStateTypes';
5
- import { TimeEntryRangeKey } from './timeEntryViewState';
6
- export interface TimeEntryListView {
7
- fetchState: FetchState;
8
- timeEntries: TimeEntry[];
9
- totalMinutes: number;
10
- error?: ZeniAPIStatus;
11
- }
12
- /** Every entry on one task, all users — the task detail breakdown. */
13
- export declare function getTimeEntriesForTask(state: RootState, taskId: ID): TimeEntryListView;
14
- export interface TimesheetWeekView extends TimeEntryListView {
15
- /** Minutes per `YYYY-MM-DD`. The weekly grid is a column per day, so the
16
- * grouping belongs here rather than in every consumer. */
17
- minutesByDate: Record<string, number>;
18
- rangeKey: TimeEntryRangeKey;
19
- }
20
- /** One user's week — the timesheet grid. */
21
- export declare function getTimeEntriesForRange(state: RootState, userId: ID, startDate: string, endDate: string): TimesheetWeekView;
22
- /** Save state for the row the user is editing, so two rows saving at once do
23
- * not share one spinner. */
24
- export declare function getTimeEntrySaveState(state: RootState, taskId: ID): FetchState;
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTimeEntriesForTask = getTimeEntriesForTask;
4
- exports.getTimeEntriesForRange = getTimeEntriesForRange;
5
- exports.getTimeEntrySaveState = getTimeEntrySaveState;
6
- const timeEntrySelector_1 = require("../../../entity/timeEntry/timeEntrySelector");
7
- const timeEntryViewState_1 = require("./timeEntryViewState");
8
- const byEntryDateThenCreate = (left, right) => left.entryDate.valueOf() - right.entryDate.valueOf() ||
9
- left.createTime.valueOf() - right.createTime.valueOf();
10
- const sumMinutes = (entries) => entries.reduce((total, entry) => total + (entry.minutes || 0), 0);
11
- /** Every entry on one task, all users — the task detail breakdown. */
12
- function getTimeEntriesForTask(state, taskId) {
13
- const { timeEntryIdsByTaskId, fetchStateByTaskId } = state.timeEntryViewState;
14
- const timeEntries = (0, timeEntrySelector_1.getTimeEntriesByIds)(state.timeEntryState, timeEntryIdsByTaskId[taskId] ?? []).sort(byEntryDateThenCreate);
15
- return {
16
- timeEntries,
17
- totalMinutes: sumMinutes(timeEntries),
18
- fetchState: fetchStateByTaskId[taskId]?.fetchState ?? 'Not-Started',
19
- error: fetchStateByTaskId[taskId]?.error,
20
- };
21
- }
22
- /** One user's week — the timesheet grid. */
23
- function getTimeEntriesForRange(state, userId, startDate, endDate) {
24
- const rangeKey = (0, timeEntryViewState_1.toTimeEntryRangeKey)(userId, startDate, endDate);
25
- const { timeEntryIdsByRangeKey, fetchStateByRangeKey } = state.timeEntryViewState;
26
- const timeEntries = (0, timeEntrySelector_1.getTimeEntriesByIds)(state.timeEntryState, timeEntryIdsByRangeKey[rangeKey] ?? []).sort(byEntryDateThenCreate);
27
- const minutesByDate = {};
28
- timeEntries.forEach((entry) => {
29
- const key = entry.entryDate.format('YYYY-MM-DD');
30
- minutesByDate[key] = (minutesByDate[key] ?? 0) + (entry.minutes || 0);
31
- });
32
- return {
33
- rangeKey,
34
- timeEntries,
35
- minutesByDate,
36
- totalMinutes: sumMinutes(timeEntries),
37
- fetchState: fetchStateByRangeKey[rangeKey]?.fetchState ?? 'Not-Started',
38
- error: fetchStateByRangeKey[rangeKey]?.error,
39
- };
40
- }
41
- /** Save state for the row the user is editing, so two rows saving at once do
42
- * not share one spinner. */
43
- function getTimeEntrySaveState(state, taskId) {
44
- return (state.timeEntryViewState.saveStateByTaskId[taskId]?.fetchState ??
45
- 'Not-Started');
46
- }
@@ -1,21 +0,0 @@
1
- import { FetchStateAndError, ID } from '../../../commonStateTypes/common';
2
- /** Mon-Fri is quoted to people inclusively, so the key is both ends. */
3
- export type TimeEntryRangeKey = `${string}_${string}_${string}`;
4
- export declare const toTimeEntryRangeKey: (userId: ID, startDate: string, endDate: string) => TimeEntryRangeKey;
5
- export interface TimeEntryViewState {
6
- fetchStateByRangeKey: Record<TimeEntryRangeKey, FetchStateAndError>;
7
- fetchStateByTaskId: Record<ID, FetchStateAndError>;
8
- /** Per task, because two rows can be saving at once on the board and a
9
- * single flag would make one row's spinner answer for the other. */
10
- saveStateByTaskId: Record<ID, FetchStateAndError>;
11
- /** Per entry, for edits and deletes addressed by entry id. */
12
- saveStateByTimeEntryId: Record<ID, FetchStateAndError>;
13
- taskCategoryFetchState: FetchStateAndError;
14
- /** Ids per (user, start, end). Keyed by the window rather than by user so
15
- * two weeks open at once do not overwrite each other. */
16
- timeEntryIdsByRangeKey: Record<TimeEntryRangeKey, ID[]>;
17
- /** Ids per task, so the detail breakdown does not scan every entry in the
18
- * store. Replaced wholesale on fetch — the server is authoritative about
19
- * which entries a task has. */
20
- timeEntryIdsByTaskId: Record<ID, ID[]>;
21
- }
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toTimeEntryRangeKey = void 0;
4
- const toTimeEntryRangeKey = (userId, startDate, endDate) => `${userId}_${startDate}_${endDate}`;
5
- exports.toTimeEntryRangeKey = toTimeEntryRangeKey;