-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathworkflowSlice.ts
More file actions
161 lines (146 loc) · 4.02 KB
/
workflowSlice.ts
File metadata and controls
161 lines (146 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import camelcaseKeys from "camelcase-keys";
import { PayloadAction, SerializedError, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
import { createAppAsyncThunk } from "../createAsyncThunkWithTypes";
/**
* This file contains redux reducer for actions affecting the state of workflows
*/
export type FieldSetField = {
name: string
value: unknown,
type: string,
checked: boolean,
fieldset?: FieldSetField[]
defaultValue?: unknown
max?: number // number field
min?: number // number field
options?: { value: string, label: string }[]
[key: string]: unknown
}
type ConfigurationPanelField = {
// We could potentially specify 'fieldset' more, but I cannot find a definition
// for which key value pairs are allowed
fieldset?: FieldSetField[] // Values can be anything
legend?: string,
description?: string,
}
export type Workflow = {
configurationPanel: string, // XML
configurationPanelJson: string | ConfigurationPanelField[], // 'string' will always be the empty string
description: string,
displayOrder: number,
id: string,
tags: string[],
title: string,
}
type WorkflowState = {
status: "uninitialized" | "loading" | "succeeded" | "failed",
error: SerializedError | null,
defaultWorkflowId: string,
workflows: Workflow[],
};
// Initial state of workflows in redux store
const initialState: WorkflowState = {
status: "uninitialized",
error: null,
defaultWorkflowId: "",
workflows: [],
};
// fetch workflow definitions from server
export const fetchWorkflowDef = createAppAsyncThunk("workflow/fetchWorkflowDef", async (
type: "tasks" | "delete-event" | "event-details" | "new-event-upload" | "new-event-schedule" | "default",
) => {
type NewProcessing = {
default_workflow_id: string,
workflows: Workflow[],
}
let urlParams;
switch (type) {
case "tasks": {
urlParams = {
tags: "archive",
};
break;
}
case "delete-event": {
urlParams = {
tags: "delete",
};
break;
}
case "event-details":
urlParams = {
tags: "schedule",
};
break;
case "new-event-upload":
urlParams = {
tags: "upload",
};
break;
case "new-event-schedule":
urlParams = {
tags: "schedule",
};
break;
default: {
urlParams = {
tags: "upload,schedule",
};
}
}
// Just make the async request here, and return the response.
// This will automatically dispatch a `pending` action first,
// and then `fulfilled` or `rejected` actions based on the promise.
const res = await axios.get<NewProcessing>("/admin-ng/event/new/processing?", { params: urlParams });
let workflows = camelcaseKeys(res.data.workflows);
workflows = workflows.map((workflow: Workflow) => {
if (workflow.configurationPanelJson.length > 0) {
return {
...workflow,
// TODO: Handle JSON parsing errors
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
configurationPanelJson: JSON.parse(
workflow.configurationPanelJson as string,
),
};
} else {
return workflow;
}
});
const workflowDef = {
defaultWorkflowId: res.data.default_workflow_id,
workflows: workflows,
};
return workflowDef;
});
const workflowSlice = createSlice({
name: "workflow",
initialState,
reducers: {},
// These are used for thunks
extraReducers: builder => {
builder
.addCase(fetchWorkflowDef.pending, state => {
state.status = "loading";
})
// Pass the generated action creators to `.addCase()`
.addCase(fetchWorkflowDef.fulfilled, (state, action: PayloadAction<{
defaultWorkflowId: WorkflowState["defaultWorkflowId"],
workflows: WorkflowState["workflows"],
}>) => {
// Same "mutating" update syntax thanks to Immer
state.status = "succeeded";
const acls = action.payload;
state.defaultWorkflowId = acls.defaultWorkflowId;
state.workflows = acls.workflows;
})
.addCase(fetchWorkflowDef.rejected, (state, action) => {
state.status = "failed";
state.error = action.error;
});
},
});
// export const {} = workflowSlice.actions;
// Export the slice reducer as the default export
export default workflowSlice.reducer;