@zeniai/client-epic-state 5.3.12-beta0DI → 5.3.12
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/entity/task/taskPayload.d.ts +0 -1
- package/lib/entity/task/taskPayload.js +0 -1
- package/lib/entity/task/taskReducer.d.ts +1 -4
- package/lib/entity/task/taskReducer.js +2 -19
- package/lib/entity/task/taskState.d.ts +0 -3
- package/lib/epic.d.ts +1 -4
- package/lib/epic.js +0 -9
- package/lib/esm/entity/task/taskPayload.js +0 -1
- package/lib/esm/entity/task/taskReducer.js +1 -18
- package/lib/esm/epic.js +0 -9
- package/lib/esm/index.js +1 -4
- package/lib/esm/reducer.js +0 -6
- package/lib/esm/view/taskManager/taskDetailView/taskDetailSelector.js +0 -3
- package/lib/esm/view/taskManager/taskListView/taskList.js +0 -6
- package/lib/esm/view/taskManager/taskListView/taskListFilterHelpers.js +0 -7
- package/lib/esm/view/taskManager/taskListView/taskListSelector.js +11 -27
- package/lib/esm/view/taskManager/taskListView/taskListViewHelpers.js +0 -37
- package/lib/index.d.ts +1 -5
- package/lib/index.js +16 -31
- package/lib/reducer.d.ts +0 -2
- package/lib/reducer.js +0 -6
- package/lib/rootStateTypes.d.ts +0 -4
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.d.ts +0 -4
- package/lib/view/taskManager/taskDetailView/taskDetailSelector.js +0 -3
- package/lib/view/taskManager/taskListView/taskList.d.ts +1 -1
- package/lib/view/taskManager/taskListView/taskList.js +0 -6
- package/lib/view/taskManager/taskListView/taskListFilterHelpers.d.ts +0 -4
- package/lib/view/taskManager/taskListView/taskListFilterHelpers.js +1 -9
- package/lib/view/taskManager/taskListView/taskListSelector.d.ts +3 -6
- package/lib/view/taskManager/taskListView/taskListSelector.js +10 -26
- package/lib/view/taskManager/taskListView/taskListViewHelpers.d.ts +1 -1
- package/lib/view/taskManager/taskListView/taskListViewHelpers.js +0 -37
- package/package.json +1 -1
- package/lib/entity/timeEntry/timeEntryPayload.d.ts +0 -26
- package/lib/entity/timeEntry/timeEntryPayload.js +0 -2
- package/lib/entity/timeEntry/timeEntryReducer.d.ts +0 -8
- package/lib/entity/timeEntry/timeEntryReducer.js +0 -76
- package/lib/entity/timeEntry/timeEntrySelector.d.ts +0 -10
- package/lib/entity/timeEntry/timeEntrySelector.js +0 -32
- package/lib/entity/timeEntry/timeEntryState.d.ts +0 -43
- package/lib/entity/timeEntry/timeEntryState.js +0 -13
- package/lib/esm/entity/timeEntry/timeEntryPayload.js +0 -1
- package/lib/esm/entity/timeEntry/timeEntryReducer.js +0 -70
- package/lib/esm/entity/timeEntry/timeEntrySelector.js +0 -23
- package/lib/esm/entity/timeEntry/timeEntryState.js +0 -8
- package/lib/esm/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.js +0 -24
- package/lib/esm/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.js +0 -73
- package/lib/esm/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.js +0 -77
- package/lib/esm/view/taskManager/timeEntryView/timeEntryViewPayload.js +0 -1
- package/lib/esm/view/taskManager/timeEntryView/timeEntryViewReducer.js +0 -160
- package/lib/esm/view/taskManager/timeEntryView/timeEntryViewSelector.js +0 -41
- package/lib/esm/view/taskManager/timeEntryView/timeEntryViewState.js +0 -1
- package/lib/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.d.ts +0 -18
- package/lib/view/taskManager/timeEntryView/epic/fetchTaskCategoriesEpic.js +0 -28
- package/lib/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.d.ts +0 -23
- package/lib/view/taskManager/timeEntryView/epic/fetchTimeEntriesEpic.js +0 -78
- package/lib/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.d.ts +0 -23
- package/lib/view/taskManager/timeEntryView/epic/writeTimeEntryEpic.js +0 -83
- package/lib/view/taskManager/timeEntryView/timeEntryViewPayload.d.ts +0 -27
- package/lib/view/taskManager/timeEntryView/timeEntryViewPayload.js +0 -2
- package/lib/view/taskManager/timeEntryView/timeEntryViewReducer.d.ts +0 -48
- package/lib/view/taskManager/timeEntryView/timeEntryViewReducer.js +0 -164
- package/lib/view/taskManager/timeEntryView/timeEntryViewSelector.d.ts +0 -24
- package/lib/view/taskManager/timeEntryView/timeEntryViewSelector.js +0 -46
- package/lib/view/taskManager/timeEntryView/timeEntryViewState.d.ts +0 -21
- package/lib/view/taskManager/timeEntryView/timeEntryViewState.js +0 -5
package/lib/rootStateTypes.d.ts
CHANGED
|
@@ -69,7 +69,6 @@ import { TaskGroupState } from './entity/taskGroup/taskGroupState';
|
|
|
69
69
|
import { TaskGroupTemplateState } from './entity/taskGroupTemplate/taskGroupTemplateState';
|
|
70
70
|
import { TaskSummaryState } from './entity/taskSummary/taskSummaryState';
|
|
71
71
|
import { TenantState } from './entity/tenant/tenantState';
|
|
72
|
-
import { TimeEntryState } from './entity/timeEntry/timeEntryState';
|
|
73
72
|
import { ToastNotificationState } from './entity/toastNotification/toastNotificationState';
|
|
74
73
|
import { TransactionState } from './entity/transaction/transactionState';
|
|
75
74
|
import { TransactionActivityLogState } from './entity/transactionActivityLog/transactionActivityLogState';
|
|
@@ -254,7 +253,6 @@ import { TaskDetailViewState } from './view/taskManager/taskDetailView/taskDetai
|
|
|
254
253
|
import { TaskGroupTemplateViewState } from './view/taskManager/taskGroupTemplateView/taskGroupTemplateViewState';
|
|
255
254
|
import { TaskGroupViewState } from './view/taskManager/taskGroupView/taskGroupViewState';
|
|
256
255
|
import { TaskListState } from './view/taskManager/taskListView/taskList';
|
|
257
|
-
import { TimeEntryViewState } from './view/taskManager/timeEntryView/timeEntryViewState';
|
|
258
256
|
import { TasksCardState } from './view/tasksCard/tasksCardState';
|
|
259
257
|
import { TopExState } from './view/topEx/topExState';
|
|
260
258
|
import { TransactionActivityLogViewState } from './view/transactionActivityLogView/transactionActivityLogViewState';
|
|
@@ -347,7 +345,6 @@ export type EntitiesState = {
|
|
|
347
345
|
taskState: TaskState;
|
|
348
346
|
taskSummaryState: TaskSummaryState;
|
|
349
347
|
tenantState: TenantState;
|
|
350
|
-
timeEntryState: TimeEntryState;
|
|
351
348
|
toastNotificationState: ToastNotificationState;
|
|
352
349
|
transactionActivityLogState: TransactionActivityLogState;
|
|
353
350
|
transactionState: TransactionState;
|
|
@@ -526,7 +523,6 @@ export type ViewsState = {
|
|
|
526
523
|
taskGroupViewState: TaskGroupViewState;
|
|
527
524
|
taskListState: TaskListState;
|
|
528
525
|
tasksCardState: TasksCardState;
|
|
529
|
-
timeEntryViewState: TimeEntryViewState;
|
|
530
526
|
topExState: TopExState;
|
|
531
527
|
transactionActivityLogViewState: TransactionActivityLogViewState;
|
|
532
528
|
transactionDetailState: TransactionDetailState;
|
|
@@ -25,10 +25,6 @@ export interface TaskDetailSelectorView extends SelectorView {
|
|
|
25
25
|
isDeleted?: boolean;
|
|
26
26
|
recurringSourceTaskId?: ID;
|
|
27
27
|
snoozedUntil?: ZeniDate | null;
|
|
28
|
-
/** Drives the Category control in the For Internal Use block. Read from
|
|
29
|
-
* the task entity rather than mirrored into local form data: it is not
|
|
30
|
-
* editable inline, and a mirror would need its own discard path. */
|
|
31
|
-
taskCategoryId?: ID;
|
|
32
28
|
taskGroupId?: ID;
|
|
33
29
|
}
|
|
34
30
|
export declare const getTaskDetail: (state: RootState, taskId?: ID) => TaskDetailSelectorView;
|
|
@@ -32,7 +32,6 @@ const getTaskDetail = (state, taskId) => {
|
|
|
32
32
|
let isDeleted = undefined;
|
|
33
33
|
let depth = undefined;
|
|
34
34
|
let recurringSourceTaskId = undefined;
|
|
35
|
-
let taskCategoryId = undefined;
|
|
36
35
|
let snoozedUntil = undefined;
|
|
37
36
|
let taskGroupId = undefined;
|
|
38
37
|
let subtasks = [];
|
|
@@ -46,7 +45,6 @@ const getTaskDetail = (state, taskId) => {
|
|
|
46
45
|
if (taskEntity != null) {
|
|
47
46
|
createdByUser = (0, userAndRole_1.getUserAndUserRole)(userState, userRoleState, addressState, taskEntity.createdBy);
|
|
48
47
|
depth = taskEntity.depth;
|
|
49
|
-
taskCategoryId = taskEntity.taskCategoryId;
|
|
50
48
|
isArchived = taskEntity.isArchived;
|
|
51
49
|
isDeleted = taskEntity.isDeleted;
|
|
52
50
|
recurringSourceTaskId = taskEntity.recurringSourceTaskId;
|
|
@@ -111,7 +109,6 @@ const getTaskDetail = (state, taskId) => {
|
|
|
111
109
|
version: 0,
|
|
112
110
|
createdByUser,
|
|
113
111
|
depth,
|
|
114
|
-
taskCategoryId,
|
|
115
112
|
isArchived,
|
|
116
113
|
isDeleted,
|
|
117
114
|
recurringSourceTaskId,
|
|
@@ -48,7 +48,7 @@ export interface TaskFilterCategory {
|
|
|
48
48
|
values: (string | ZeniDate)[];
|
|
49
49
|
valuesCombinationOperator: 'ANY';
|
|
50
50
|
}
|
|
51
|
-
export type TaskListFilterCategoryField = 'status' | 'dueDate' | 'assignee' | '
|
|
51
|
+
export type TaskListFilterCategoryField = 'status' | 'dueDate' | 'assignee' | 'creationDate' | 'priority' | 'tag';
|
|
52
52
|
export declare const TASK_LIST_GROUP_BY_KEYS: readonly ["groupName", "status", "dueDate", "assignee", "priority", "tag"];
|
|
53
53
|
export declare const toTaskListGroupByKeyType: (v: string) => "status" | "dueDate" | "priority" | "assignee" | "tag" | "groupName";
|
|
54
54
|
export declare const toTaskListGroupByKeyTypeStrict: (v: string) => "status" | "dueDate" | "priority" | "assignee" | "tag" | "groupName" | undefined;
|
|
@@ -53,13 +53,7 @@ exports.TASK_LIST_FILTER_CATEGORIES = [
|
|
|
53
53
|
type: 'user',
|
|
54
54
|
multiple: true,
|
|
55
55
|
},
|
|
56
|
-
{
|
|
57
|
-
value: 'createdBy',
|
|
58
|
-
type: 'user',
|
|
59
|
-
multiple: true,
|
|
60
|
-
},
|
|
61
56
|
{ value: 'creationDate', type: 'dateRange', multiple: true },
|
|
62
|
-
{ value: 'billing', type: 'dropdown', multiple: true },
|
|
63
57
|
];
|
|
64
58
|
exports.TASK_LIST_GROUP_BY_CATEGORIES = [
|
|
65
59
|
{ value: 'status' },
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import { ID } from '../../../commonStateTypes/common';
|
|
2
1
|
import { Task } from '../../../entity/task/taskState';
|
|
3
|
-
import { TaskCategory } from '../../../entity/timeEntry/timeEntryState';
|
|
4
2
|
import { FilterCategoryValueType } from '../../spendManagement/spendManagementFilterHelpers';
|
|
5
|
-
/** Billing lives on the task's category, not the task, so it needs the catalog. */
|
|
6
|
-
export declare const buildCategoryValueGetter: (taskCategoriesById: Record<ID, TaskCategory>) => (key: string, task: Task) => FilterCategoryValueType | (string | undefined)[] | undefined;
|
|
7
3
|
export declare const getCategoryValueForTaskList: (key: string, task: Task) => FilterCategoryValueType | (string | undefined)[] | undefined;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCategoryValueForTaskList =
|
|
4
|
-
/** Billing lives on the task's category, not the task, so it needs the catalog. */
|
|
5
|
-
const buildCategoryValueGetter = (taskCategoriesById) => (key, task) => key === 'billing'
|
|
6
|
-
? (taskCategoriesById[task.taskCategoryId ?? '']?.billingType ??
|
|
7
|
-
'non_billable')
|
|
8
|
-
: (0, exports.getCategoryValueForTaskList)(key, task);
|
|
9
|
-
exports.buildCategoryValueGetter = buildCategoryValueGetter;
|
|
3
|
+
exports.getCategoryValueForTaskList = void 0;
|
|
10
4
|
const getCategoryValueForTaskList = (key, task) => {
|
|
11
5
|
switch (key) {
|
|
12
6
|
case 'dueDate':
|
|
@@ -21,8 +15,6 @@ const getCategoryValueForTaskList = (key, task) => {
|
|
|
21
15
|
return task.createTime;
|
|
22
16
|
case 'assignee':
|
|
23
17
|
return task.assignees;
|
|
24
|
-
case 'createdBy':
|
|
25
|
-
return task.createdBy;
|
|
26
18
|
default:
|
|
27
19
|
return undefined;
|
|
28
20
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { FetchStateAndError
|
|
1
|
+
import { FetchStateAndError } from '../../../commonStateTypes/common';
|
|
2
2
|
import { SelectorView } from '../../../commonStateTypes/viewAndReport/viewAndReport';
|
|
3
3
|
import { AddressState } from '../../../entity/address/addressState';
|
|
4
4
|
import { TagState } from '../../../entity/tag/tagState';
|
|
5
5
|
import { Task, TaskState } from '../../../entity/task/taskState';
|
|
6
6
|
import { TaskGroupTemplate } from '../../../entity/taskGroupTemplate/taskGroupTemplateState';
|
|
7
|
-
import { TaskCategory } from '../../../entity/timeEntry/timeEntryState';
|
|
8
7
|
import { UserState } from '../../../entity/user/userState';
|
|
9
8
|
import { UserGroupsState } from '../../../entity/userGroups/userGroupsState';
|
|
10
9
|
import { UserRoleState } from '../../../entity/userRole/userRoleState';
|
|
@@ -49,10 +48,9 @@ export interface TaskListSelectorView extends SelectorView {
|
|
|
49
48
|
* slice. `TaskListState` still satisfies this, so callers are unaffected.
|
|
50
49
|
*/
|
|
51
50
|
type TaskListGroupingInputs = Pick<TaskListState, 'filters' | 'taskIdsByAssignees' | 'taskIdsByDueDate' | 'taskIdsByGroupsIds' | 'taskIdsByPriority' | 'taskIdsByStatus' | 'taskIdsByTags' | 'uiState'>;
|
|
52
|
-
export declare const getTaskListGroupedByAssignees: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
51
|
+
export declare const getTaskListGroupedByAssignees: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }: {
|
|
53
52
|
addressState: AddressState;
|
|
54
53
|
tagState: TagState;
|
|
55
|
-
taskCategoriesById: Record<ID, TaskCategory>;
|
|
56
54
|
taskListState: TaskListGroupingInputs;
|
|
57
55
|
taskState: TaskState;
|
|
58
56
|
userGroupsState: UserGroupsState;
|
|
@@ -64,10 +62,9 @@ export declare const getTaskListGroupedByAssignees: ({ taskListState, taskState,
|
|
|
64
62
|
isDefault: boolean;
|
|
65
63
|
tasks: TaskWithUserDetails[];
|
|
66
64
|
}[];
|
|
67
|
-
export declare const getTaskListGroupedByPriority: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
65
|
+
export declare const getTaskListGroupedByPriority: ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }: {
|
|
68
66
|
addressState: AddressState;
|
|
69
67
|
tagState: TagState;
|
|
70
|
-
taskCategoriesById: Record<ID, TaskCategory>;
|
|
71
68
|
taskListState: TaskListGroupingInputs;
|
|
72
69
|
taskState: TaskState;
|
|
73
70
|
userGroupsState: UserGroupsState;
|
|
@@ -53,7 +53,7 @@ const sortTasksList = (tagState, tasksList, sortKey, sortOrder) => {
|
|
|
53
53
|
}, sortOrder);
|
|
54
54
|
return tasksInOrder;
|
|
55
55
|
};
|
|
56
|
-
const getTasksWithUserDetails = ({ taskListState, taskState, userState, userRoleState, addressState, taskIds, tagState, userGroupsState,
|
|
56
|
+
const getTasksWithUserDetails = ({ taskListState, taskState, userState, userRoleState, addressState, taskIds, tagState, userGroupsState, }) => {
|
|
57
57
|
const { sortKey, searchText } = taskListState.uiState;
|
|
58
58
|
const sortOrder = (0, sortOrderPayload_1.getSortOrder)(taskListState.uiState.sortOrder);
|
|
59
59
|
const tasks = taskIds
|
|
@@ -76,11 +76,11 @@ const getTasksWithUserDetails = ({ taskListState, taskState, userState, userRole
|
|
|
76
76
|
return undefined;
|
|
77
77
|
})
|
|
78
78
|
.filter((value) => value?.name.toLowerCase().includes(searchText.toLowerCase()) === true);
|
|
79
|
-
const filteredTaskList = (0, spendManagementFilterHelpers_1.applyAdvancedFiltersOnList)(
|
|
79
|
+
const filteredTaskList = (0, spendManagementFilterHelpers_1.applyAdvancedFiltersOnList)(taskListFilterHelpers_1.getCategoryValueForTaskList, tasks, taskListState.filters);
|
|
80
80
|
const sortedTaskList = sortTasksList(tagState, filteredTaskList, sortKey, sortOrder);
|
|
81
81
|
return sortedTaskList;
|
|
82
82
|
};
|
|
83
|
-
const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupsIds, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
83
|
+
const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupState, taskGroupsIds, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
84
84
|
const taskGroupsWithTasksList = taskGroupsIds
|
|
85
85
|
.map((taskGroupId) => {
|
|
86
86
|
const taskGroup = (0, taskGroupSelector_1.getTaskGroupById)(taskGroupState, taskGroupId);
|
|
@@ -94,7 +94,6 @@ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupStat
|
|
|
94
94
|
taskIds,
|
|
95
95
|
tagState,
|
|
96
96
|
userGroupsState,
|
|
97
|
-
taskCategoriesById,
|
|
98
97
|
});
|
|
99
98
|
if (taskGroup != null) {
|
|
100
99
|
return {
|
|
@@ -126,7 +125,7 @@ const getTaskListGroupedByGroupName = ({ taskListState, taskState, taskGroupStat
|
|
|
126
125
|
// Also hides deleted groups, which are empty as a side effect.
|
|
127
126
|
return sortedTaskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
128
127
|
};
|
|
129
|
-
const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
128
|
+
const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
130
129
|
const assigneeGroups = Object.keys(taskListState.taskIdsByAssignees);
|
|
131
130
|
const taskGroupsWithTasksList = assigneeGroups.map((groupKey) => {
|
|
132
131
|
const taskIds = taskListState.taskIdsByAssignees[groupKey];
|
|
@@ -139,7 +138,6 @@ const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, us
|
|
|
139
138
|
taskIds,
|
|
140
139
|
tagState,
|
|
141
140
|
userGroupsState,
|
|
142
|
-
taskCategoriesById,
|
|
143
141
|
});
|
|
144
142
|
const assigneeIds = groupKey.split(',');
|
|
145
143
|
const groupName = (0, userSelector_1.getUsersByUserIds)(userState, assigneeIds)
|
|
@@ -158,7 +156,7 @@ const getTaskListGroupedByAssignees = ({ taskListState, taskState, userState, us
|
|
|
158
156
|
return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
159
157
|
};
|
|
160
158
|
exports.getTaskListGroupedByAssignees = getTaskListGroupedByAssignees;
|
|
161
|
-
const getTaskListGroupedByPriority = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
159
|
+
const getTaskListGroupedByPriority = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
162
160
|
const taskGroupsWithTasksList = taskState_1.ALL_PRIORITY_CODE.map((groupKey) => {
|
|
163
161
|
const taskIds = taskListState.taskIdsByPriority[groupKey] ?? [];
|
|
164
162
|
const tasksWithUserDetails = getTasksWithUserDetails({
|
|
@@ -170,7 +168,6 @@ const getTaskListGroupedByPriority = ({ taskListState, taskState, userState, use
|
|
|
170
168
|
taskIds,
|
|
171
169
|
tagState,
|
|
172
170
|
userGroupsState,
|
|
173
|
-
taskCategoriesById,
|
|
174
171
|
});
|
|
175
172
|
return {
|
|
176
173
|
groupName: taskDetailSelector_1.allTaskPriority.find((priority) => priority.code === groupKey)?.name ??
|
|
@@ -183,7 +180,7 @@ const getTaskListGroupedByPriority = ({ taskListState, taskState, userState, use
|
|
|
183
180
|
return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
184
181
|
};
|
|
185
182
|
exports.getTaskListGroupedByPriority = getTaskListGroupedByPriority;
|
|
186
|
-
const getTaskListGroupedByStatus = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
183
|
+
const getTaskListGroupedByStatus = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
187
184
|
const taskGroupsWithTasksList = taskState_1.ALL_TASK_STATUS_CODE.map((groupKey) => {
|
|
188
185
|
const taskIds = taskListState.taskIdsByStatus[groupKey] ?? [];
|
|
189
186
|
const tasksWithUserDetails = getTasksWithUserDetails({
|
|
@@ -195,7 +192,6 @@ const getTaskListGroupedByStatus = ({ taskListState, taskState, userState, userR
|
|
|
195
192
|
taskIds,
|
|
196
193
|
tagState,
|
|
197
194
|
userGroupsState,
|
|
198
|
-
taskCategoriesById,
|
|
199
195
|
});
|
|
200
196
|
return {
|
|
201
197
|
groupName: taskDetailSelector_1.allTaskStatus.find((taskStatus) => taskStatus.code === groupKey)
|
|
@@ -207,7 +203,7 @@ const getTaskListGroupedByStatus = ({ taskListState, taskState, userState, userR
|
|
|
207
203
|
});
|
|
208
204
|
return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
209
205
|
};
|
|
210
|
-
const getTaskListGroupedByTags = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
206
|
+
const getTaskListGroupedByTags = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
211
207
|
const tagGroups = Object.keys(taskListState.taskIdsByTags);
|
|
212
208
|
const taskGroupsWithTasksList = tagGroups.map((groupKey) => {
|
|
213
209
|
const taskIds = taskListState.taskIdsByTags[groupKey];
|
|
@@ -220,7 +216,6 @@ const getTaskListGroupedByTags = ({ taskListState, taskState, userState, userRol
|
|
|
220
216
|
taskIds,
|
|
221
217
|
tagState,
|
|
222
218
|
userGroupsState,
|
|
223
|
-
taskCategoriesById,
|
|
224
219
|
});
|
|
225
220
|
const tagIds = groupKey.split(',');
|
|
226
221
|
const groupName = (0, tagSelector_1.getTagsByIds)(tagState, tagIds)
|
|
@@ -237,7 +232,7 @@ const getTaskListGroupedByTags = ({ taskListState, taskState, userState, userRol
|
|
|
237
232
|
});
|
|
238
233
|
return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
239
234
|
};
|
|
240
|
-
const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState,
|
|
235
|
+
const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, userRoleState, addressState, tagState, userGroupsState, }) => {
|
|
241
236
|
const taskGroupsWithTasksList = taskList_1.DUE_DATE_GROUP_KEYS.map((groupKey) => {
|
|
242
237
|
const taskIds = taskListState.taskIdsByDueDate[groupKey];
|
|
243
238
|
const tasksWithUserDetails = getTasksWithUserDetails({
|
|
@@ -249,7 +244,6 @@ const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, user
|
|
|
249
244
|
taskIds,
|
|
250
245
|
tagState,
|
|
251
246
|
userGroupsState,
|
|
252
|
-
taskCategoriesById,
|
|
253
247
|
});
|
|
254
248
|
return {
|
|
255
249
|
groupName: groupKey,
|
|
@@ -260,7 +254,7 @@ const getTaskListGroupedByDueDate = ({ taskListState, taskState, userState, user
|
|
|
260
254
|
});
|
|
261
255
|
return taskGroupsWithTasksList.filter((group) => group.tasks.length > 0);
|
|
262
256
|
};
|
|
263
|
-
const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState,
|
|
257
|
+
const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState, }) => {
|
|
264
258
|
const { groupByKey } = taskListState.uiState;
|
|
265
259
|
if (groupByKey === 'groupName') {
|
|
266
260
|
return getTaskListGroupedByGroupName({
|
|
@@ -273,7 +267,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
273
267
|
taskGroupsIds,
|
|
274
268
|
tagState,
|
|
275
269
|
userGroupsState,
|
|
276
|
-
taskCategoriesById,
|
|
277
270
|
});
|
|
278
271
|
}
|
|
279
272
|
if (groupByKey === 'assignee') {
|
|
@@ -285,7 +278,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
285
278
|
addressState,
|
|
286
279
|
tagState,
|
|
287
280
|
userGroupsState,
|
|
288
|
-
taskCategoriesById,
|
|
289
281
|
});
|
|
290
282
|
}
|
|
291
283
|
if (groupByKey === 'priority') {
|
|
@@ -297,7 +289,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
297
289
|
addressState,
|
|
298
290
|
tagState,
|
|
299
291
|
userGroupsState,
|
|
300
|
-
taskCategoriesById,
|
|
301
292
|
});
|
|
302
293
|
}
|
|
303
294
|
if (groupByKey === 'status') {
|
|
@@ -309,7 +300,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
309
300
|
addressState,
|
|
310
301
|
tagState,
|
|
311
302
|
userGroupsState,
|
|
312
|
-
taskCategoriesById,
|
|
313
303
|
});
|
|
314
304
|
}
|
|
315
305
|
if (groupByKey === 'tag') {
|
|
@@ -321,7 +311,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
321
311
|
addressState,
|
|
322
312
|
tagState,
|
|
323
313
|
userGroupsState,
|
|
324
|
-
taskCategoriesById,
|
|
325
314
|
});
|
|
326
315
|
}
|
|
327
316
|
return getTaskListGroupedByDueDate({
|
|
@@ -332,7 +321,6 @@ const getTaskGroupsWithTaskList = ({ taskListState, taskState, userState, userRo
|
|
|
332
321
|
addressState,
|
|
333
322
|
tagState,
|
|
334
323
|
userGroupsState,
|
|
335
|
-
taskCategoriesById,
|
|
336
324
|
});
|
|
337
325
|
};
|
|
338
326
|
/**
|
|
@@ -357,10 +345,7 @@ const getTaskGroupsWithTaskListMemoized = (0, toolkit_1.createSelector)((state)
|
|
|
357
345
|
// invalidate this memo and rebuild a board the user is already using.
|
|
358
346
|
(state) => tagsAreStructural(state.taskListState.uiState)
|
|
359
347
|
? state.tagState
|
|
360
|
-
: EMPTY_TAG_STATE, (state) => state.userGroupsState,
|
|
361
|
-
// Only the catalog, not the whole timeEntry slice: billing is read off
|
|
362
|
-
// the task's category, and a timer tick must not rebuild the board.
|
|
363
|
-
(state) => state.timeEntryState.taskCategoriesById, (uiState, filters, taskIdsByGroupsIds, taskIdsByAssignees, taskIdsByPriority, taskIdsByStatus, taskIdsByTags, taskIdsByDueDate, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState, taskCategoriesById) => getTaskGroupsWithTaskList({
|
|
348
|
+
: EMPTY_TAG_STATE, (state) => state.userGroupsState, (uiState, filters, taskIdsByGroupsIds, taskIdsByAssignees, taskIdsByPriority, taskIdsByStatus, taskIdsByTags, taskIdsByDueDate, taskState, userState, userRoleState, addressState, taskGroupState, taskGroupsIds, tagState, userGroupsState) => getTaskGroupsWithTaskList({
|
|
364
349
|
taskListState: {
|
|
365
350
|
uiState,
|
|
366
351
|
filters,
|
|
@@ -379,7 +364,6 @@ const getTaskGroupsWithTaskListMemoized = (0, toolkit_1.createSelector)((state)
|
|
|
379
364
|
taskGroupsIds,
|
|
380
365
|
tagState,
|
|
381
366
|
userGroupsState,
|
|
382
|
-
taskCategoriesById,
|
|
383
367
|
}));
|
|
384
368
|
exports.getAllTasks = (0, toolkit_1.createSelector)(
|
|
385
369
|
// `taskState`, `taskGroupState`, `addressState` and `tagState` are gone from
|
|
@@ -3,7 +3,7 @@ import { Task } from '../../../entity/task/taskState';
|
|
|
3
3
|
import { User } from '../../../entity/user/userState';
|
|
4
4
|
import { ZeniDate } from '../../../zeniDayJS';
|
|
5
5
|
import { TaskGroupKey } from './taskList';
|
|
6
|
-
export type SubtaskSortKey = 'name' | 'status' | 'assignee' | 'tag'
|
|
6
|
+
export type SubtaskSortKey = 'name' | 'status' | 'assignee' | 'tag';
|
|
7
7
|
export type SubtaskSortOrder = 'asc' | 'desc';
|
|
8
8
|
export declare const getDueDateValueFromDueDateGroupId: (groupId: string) => ZeniDate;
|
|
9
9
|
export declare const getTaskUpdates: (groupByKey: TaskGroupKey, groupId: string) => Partial<Task>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.sortSubtasks = exports.getTaskUpdates = exports.getDueDateValueFromDueDateGroupId = void 0;
|
|
4
|
-
const formatMinutesToFromHHMM_1 = require("../../../commonStateTypes/fiscalYearHelpers/formatMinutesToFromHHMM");
|
|
5
4
|
const zeniDayJS_1 = require("../../../zeniDayJS");
|
|
6
5
|
const taskDetailSelector_1 = require("../taskDetailView/taskDetailSelector");
|
|
7
6
|
const taskList_1 = require("./taskList");
|
|
@@ -69,11 +68,6 @@ const sortSubtasks = (subtasks, sortKey, sortOrder, userList, tagList) => {
|
|
|
69
68
|
return acc;
|
|
70
69
|
}, {});
|
|
71
70
|
const unknownStatusRank = taskDetailSelector_1.allTaskStatus.length;
|
|
72
|
-
const priorityOrder = taskDetailSelector_1.allTaskPriority.reduce((acc, priority, index) => {
|
|
73
|
-
acc[priority.code] = index;
|
|
74
|
-
return acc;
|
|
75
|
-
}, {});
|
|
76
|
-
const unknownPriorityRank = taskDetailSelector_1.allTaskPriority.length;
|
|
77
71
|
const cmpStr = (a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' });
|
|
78
72
|
const keyFn = (task) => {
|
|
79
73
|
if (sortKey === 'name') {
|
|
@@ -100,37 +94,6 @@ const sortSubtasks = (subtasks, sortKey, sortOrder, userList, tagList) => {
|
|
|
100
94
|
const tag = tagList.find((candidate) => candidate.tagId === firstTagId);
|
|
101
95
|
return tag?.name ?? '';
|
|
102
96
|
}
|
|
103
|
-
if (sortKey === 'priority') {
|
|
104
|
-
// Rank by the canonical order, not the code string: alphabetical would
|
|
105
|
-
// sort "high" before "urgent" and read as wrong to anyone scanning it.
|
|
106
|
-
return priorityOrder[task.priority?.code] ?? unknownPriorityRank;
|
|
107
|
-
}
|
|
108
|
-
if (sortKey === 'dueDate') {
|
|
109
|
-
// A task with no date is not "earliest", so undated rows belong at the
|
|
110
|
-
// bottom in BOTH directions. The comparator negates for 'desc', so one
|
|
111
|
-
// fixed sentinel would flip them to the top — the sentinel has to flip
|
|
112
|
-
// with the order to survive that negation.
|
|
113
|
-
// `dueDate` is already a ZeniDate (dayjs), so valueOf() is the epoch.
|
|
114
|
-
// An unparseable date yields NaN, and a NaN comparator leaves the array
|
|
115
|
-
// untouched -- the same silent failure the timeSpent branch guards.
|
|
116
|
-
// Treat it as undated rather than as a date.
|
|
117
|
-
const due = task.dueDate;
|
|
118
|
-
const epoch = due?.valueOf();
|
|
119
|
-
if (epoch == null || Number.isNaN(epoch)) {
|
|
120
|
-
return sortOrder === 'asc'
|
|
121
|
-
? Number.MAX_SAFE_INTEGER
|
|
122
|
-
: Number.MIN_SAFE_INTEGER;
|
|
123
|
-
}
|
|
124
|
-
return epoch;
|
|
125
|
-
}
|
|
126
|
-
if (sortKey === 'timeSpent') {
|
|
127
|
-
// `timeSpent` is an "HHMM" STRING (no colon). Comparing it as text puts
|
|
128
|
-
// "1000" before "0900" only by luck of padding, and any malformed value
|
|
129
|
-
// makes the converter return NaN -- which a comparator turns into "no
|
|
130
|
-
// sort at all", silently. Coerce that to 0.
|
|
131
|
-
const minutes = (0, formatMinutesToFromHHMM_1.convertHHMMStrToMinutes)(task.timeSpent ?? '');
|
|
132
|
-
return Number.isFinite(minutes) ? minutes : 0;
|
|
133
|
-
}
|
|
134
97
|
return '';
|
|
135
98
|
};
|
|
136
99
|
const copy = [...subtasks];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeniai/client-epic-state",
|
|
3
|
-
"version": "5.3.12
|
|
3
|
+
"version": "5.3.12",
|
|
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",
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../commonStateTypes/common';
|
|
2
|
-
/** Exactly what `task-manager` returns. snake_case, API-nullable. */
|
|
3
|
-
export interface TimeEntryPayload {
|
|
4
|
-
create_time: string;
|
|
5
|
-
entry_date: string;
|
|
6
|
-
minutes: number;
|
|
7
|
-
source: string;
|
|
8
|
-
task_id: ID;
|
|
9
|
-
time_entry_id: ID;
|
|
10
|
-
update_time: string;
|
|
11
|
-
user_id: ID;
|
|
12
|
-
/** Derived from the category server-side (D15/D22) and READ-ONLY. Null when
|
|
13
|
-
* the task has no category, or the category is not yet classified. */
|
|
14
|
-
billing_type?: string | null;
|
|
15
|
-
created_by?: ID | null;
|
|
16
|
-
department?: string | null;
|
|
17
|
-
task_category_id?: ID | null;
|
|
18
|
-
}
|
|
19
|
-
export interface TaskCategoryPayload {
|
|
20
|
-
is_active: boolean;
|
|
21
|
-
name: string;
|
|
22
|
-
task_category_id: ID;
|
|
23
|
-
billing_type?: string | null;
|
|
24
|
-
service?: string | null;
|
|
25
|
-
vertical?: string | null;
|
|
26
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { TaskCategoryPayload, TimeEntryPayload } from './timeEntryPayload';
|
|
2
|
-
import { TaskCategory, TimeEntry, TimeEntryState } from './timeEntryState';
|
|
3
|
-
export declare const initialState: TimeEntryState;
|
|
4
|
-
export declare const updateTimeEntries: import("@reduxjs/toolkit").ActionCreatorWithPayload<TimeEntryPayload[], "timeEntry/updateTimeEntries">, removeTimeEntry: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "timeEntry/removeTimeEntry">, updateTaskCategories: import("@reduxjs/toolkit").ActionCreatorWithPayload<TaskCategoryPayload[], "timeEntry/updateTaskCategories">;
|
|
5
|
-
declare const _default: import("redux").Reducer<TimeEntryState>;
|
|
6
|
-
export default _default;
|
|
7
|
-
export declare function mapTimeEntryPayloadToTimeEntry(payload: TimeEntryPayload): TimeEntry;
|
|
8
|
-
export declare function mapTaskCategoryPayloadToTaskCategory(payload: TaskCategoryPayload): TaskCategory;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.updateTaskCategories = exports.removeTimeEntry = exports.updateTimeEntries = exports.initialState = void 0;
|
|
5
|
-
exports.mapTimeEntryPayloadToTimeEntry = mapTimeEntryPayloadToTimeEntry;
|
|
6
|
-
exports.mapTaskCategoryPayloadToTaskCategory = mapTaskCategoryPayloadToTaskCategory;
|
|
7
|
-
const toolkit_1 = require("@reduxjs/toolkit");
|
|
8
|
-
const rootActions_1 = require("../../rootActions");
|
|
9
|
-
const zeniDayJS_1 = require("../../zeniDayJS");
|
|
10
|
-
const timeEntryState_1 = require("./timeEntryState");
|
|
11
|
-
exports.initialState = {
|
|
12
|
-
timeEntriesById: {},
|
|
13
|
-
taskCategoriesById: {},
|
|
14
|
-
};
|
|
15
|
-
const timeEntry = (0, toolkit_1.createSlice)({
|
|
16
|
-
name: 'timeEntry',
|
|
17
|
-
initialState: exports.initialState,
|
|
18
|
-
reducers: {
|
|
19
|
-
updateTimeEntries(draft, action) {
|
|
20
|
-
action.payload.forEach((payload) => {
|
|
21
|
-
const latest = mapTimeEntryPayloadToTimeEntry(payload);
|
|
22
|
-
const inStore = draft.timeEntriesById[latest.timeEntryId];
|
|
23
|
-
// Last-write-wins by updateTime, same as `address`. A weekly fetch and
|
|
24
|
-
// a single-entry edit can land in either order.
|
|
25
|
-
if (inStore == null || latest.updateTime.isAfter(inStore.updateTime)) {
|
|
26
|
-
draft.timeEntriesById[latest.timeEntryId] = latest;
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
},
|
|
30
|
-
/** A soft delete comes back as a normal entry; the server has already
|
|
31
|
-
* dropped it from the totals, so the client drops it from the store
|
|
32
|
-
* rather than keeping a row it must then remember to filter. */
|
|
33
|
-
removeTimeEntry(draft, action) {
|
|
34
|
-
delete draft.timeEntriesById[action.payload];
|
|
35
|
-
},
|
|
36
|
-
updateTaskCategories(draft, action) {
|
|
37
|
-
action.payload.forEach((payload) => {
|
|
38
|
-
const category = mapTaskCategoryPayloadToTaskCategory(payload);
|
|
39
|
-
draft.taskCategoriesById[category.taskCategoryId] = category;
|
|
40
|
-
});
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
extraReducers: (builder) => {
|
|
44
|
-
builder.addCase(rootActions_1.clearAll, (draft) => {
|
|
45
|
-
Object.assign(draft, exports.initialState);
|
|
46
|
-
});
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
_a = timeEntry.actions, exports.updateTimeEntries = _a.updateTimeEntries, exports.removeTimeEntry = _a.removeTimeEntry, exports.updateTaskCategories = _a.updateTaskCategories;
|
|
50
|
-
exports.default = timeEntry.reducer;
|
|
51
|
-
function mapTimeEntryPayloadToTimeEntry(payload) {
|
|
52
|
-
return {
|
|
53
|
-
timeEntryId: payload.time_entry_id,
|
|
54
|
-
taskId: payload.task_id,
|
|
55
|
-
userId: payload.user_id,
|
|
56
|
-
minutes: payload.minutes,
|
|
57
|
-
entryDate: (0, zeniDayJS_1.date)(payload.entry_date),
|
|
58
|
-
source: (0, timeEntryState_1.toTimeEntrySource)(payload.source),
|
|
59
|
-
createTime: (0, zeniDayJS_1.date)(payload.create_time),
|
|
60
|
-
updateTime: (0, zeniDayJS_1.date)(payload.update_time),
|
|
61
|
-
billingType: (0, timeEntryState_1.toBillingType)(payload.billing_type),
|
|
62
|
-
createdBy: payload.created_by ?? undefined,
|
|
63
|
-
department: payload.department ?? undefined,
|
|
64
|
-
taskCategoryId: payload.task_category_id ?? undefined,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
function mapTaskCategoryPayloadToTaskCategory(payload) {
|
|
68
|
-
return {
|
|
69
|
-
taskCategoryId: payload.task_category_id,
|
|
70
|
-
name: payload.name,
|
|
71
|
-
isActive: payload.is_active,
|
|
72
|
-
billingType: (0, timeEntryState_1.toBillingType)(payload.billing_type),
|
|
73
|
-
service: payload.service ?? undefined,
|
|
74
|
-
vertical: payload.vertical ?? undefined,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../commonStateTypes/common';
|
|
2
|
-
import { TaskCategory, TimeEntry, TimeEntryState } from './timeEntryState';
|
|
3
|
-
export declare function getTimeEntryById(timeEntryState: TimeEntryState, timeEntryId: ID): TimeEntry | undefined;
|
|
4
|
-
export declare function getTimeEntriesByIds(timeEntryState: TimeEntryState, timeEntryIds: ID[]): TimeEntry[];
|
|
5
|
-
export declare function getTaskCategoryById(timeEntryState: TimeEntryState, taskCategoryId: ID): TaskCategory | undefined;
|
|
6
|
-
/**
|
|
7
|
-
* The catalog, ordered service → vertical → name, matching the order the
|
|
8
|
-
* server sends so the dropdown reads the same on both sides.
|
|
9
|
-
*/
|
|
10
|
-
export declare function getTaskCategories(timeEntryState: TimeEntryState, includeInactive?: boolean): TaskCategory[];
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getTimeEntryById = getTimeEntryById;
|
|
7
|
-
exports.getTimeEntriesByIds = getTimeEntriesByIds;
|
|
8
|
-
exports.getTaskCategoryById = getTaskCategoryById;
|
|
9
|
-
exports.getTaskCategories = getTaskCategories;
|
|
10
|
-
const get_1 = __importDefault(require("lodash/get"));
|
|
11
|
-
function getTimeEntryById(timeEntryState, timeEntryId) {
|
|
12
|
-
return (0, get_1.default)(timeEntryState.timeEntriesById, timeEntryId, undefined);
|
|
13
|
-
}
|
|
14
|
-
function getTimeEntriesByIds(timeEntryState, timeEntryIds) {
|
|
15
|
-
return timeEntryIds
|
|
16
|
-
.map((timeEntryId) => getTimeEntryById(timeEntryState, timeEntryId))
|
|
17
|
-
.filter((entry) => entry != null);
|
|
18
|
-
}
|
|
19
|
-
function getTaskCategoryById(timeEntryState, taskCategoryId) {
|
|
20
|
-
return (0, get_1.default)(timeEntryState.taskCategoriesById, taskCategoryId, undefined);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* The catalog, ordered service → vertical → name, matching the order the
|
|
24
|
-
* server sends so the dropdown reads the same on both sides.
|
|
25
|
-
*/
|
|
26
|
-
function getTaskCategories(timeEntryState, includeInactive = false) {
|
|
27
|
-
return Object.values(timeEntryState.taskCategoriesById)
|
|
28
|
-
.filter((category) => includeInactive || category.isActive)
|
|
29
|
-
.sort((left, right) => (left.service ?? '').localeCompare(right.service ?? '') ||
|
|
30
|
-
(left.vertical ?? '').localeCompare(right.vertical ?? '') ||
|
|
31
|
-
left.name.localeCompare(right.name));
|
|
32
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ID } from '../../commonStateTypes/common';
|
|
2
|
-
import { ZeniDate } from '../../zeniDayJS';
|
|
3
|
-
export declare const ALL_TIME_ENTRY_SOURCES: readonly ["timer", "manual", "migration"];
|
|
4
|
-
export type TimeEntrySource = (typeof ALL_TIME_ENTRY_SOURCES)[number];
|
|
5
|
-
export declare const ALL_BILLING_TYPES: readonly ["billable", "non_billable"];
|
|
6
|
-
export type BillingType = (typeof ALL_BILLING_TYPES)[number];
|
|
7
|
-
/** Unknown values become `undefined` rather than being cast through.
|
|
8
|
-
* A server that gains a source we do not know about must not land an
|
|
9
|
-
* unmatched string in a union the UI switches on. */
|
|
10
|
-
export declare const toTimeEntrySource: (raw: string | null | undefined) => "manual" | "timer" | "migration" | undefined;
|
|
11
|
-
export declare const toBillingType: (raw: string | null | undefined) => "billable" | "non_billable" | undefined;
|
|
12
|
-
export interface TimeEntry {
|
|
13
|
-
createTime: ZeniDate;
|
|
14
|
-
/** The day the work happened, not the day the row was written. The grain is
|
|
15
|
-
* a DAY: one row per user per task per day. */
|
|
16
|
-
entryDate: ZeniDate;
|
|
17
|
-
minutes: number;
|
|
18
|
-
taskId: ID;
|
|
19
|
-
timeEntryId: ID;
|
|
20
|
-
updateTime: ZeniDate;
|
|
21
|
-
userId: ID;
|
|
22
|
-
/** Snapshotted at write time, never refreshed — reclassifying a category
|
|
23
|
-
* must not rewrite an approved week. Read-only to the client. */
|
|
24
|
-
billingType?: BillingType;
|
|
25
|
-
createdBy?: ID;
|
|
26
|
-
department?: string;
|
|
27
|
-
source?: TimeEntrySource;
|
|
28
|
-
taskCategoryId?: ID;
|
|
29
|
-
}
|
|
30
|
-
export interface TaskCategory {
|
|
31
|
-
isActive: boolean;
|
|
32
|
-
name: string;
|
|
33
|
-
taskCategoryId: ID;
|
|
34
|
-
billingType?: BillingType;
|
|
35
|
-
service?: string;
|
|
36
|
-
vertical?: string;
|
|
37
|
-
}
|
|
38
|
-
export interface TimeEntryState {
|
|
39
|
-
taskCategoriesById: Record<ID, TaskCategory>;
|
|
40
|
-
/** Keyed by id, like every other entity slice. The per-task and per-user
|
|
41
|
-
* groupings live in the VIEW slice, because they are queries over this. */
|
|
42
|
-
timeEntriesById: Record<ID, TimeEntry>;
|
|
43
|
-
}
|