-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathinternalActions.ts
More file actions
169 lines (152 loc) · 5.5 KB
/
Copy pathinternalActions.ts
File metadata and controls
169 lines (152 loc) · 5.5 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
162
163
164
165
166
167
168
169
import { Context } from 'app/overmind';
import { DashboardSandboxFragment } from './types';
/**
* Change sandbox frozen in state and returns the sandboxes that have changed in their old state
*/
export const changeSandboxesInState = (
{ state: { dashboard } }: Context,
{
sandboxIds,
sandboxMutation,
}: {
sandboxIds: string[];
/**
* The mutation that happens on the sandbox, make sure to return a *new* sandbox here, to make sure
* that we can still rollback easily in the future.
*/
sandboxMutation: <T extends DashboardSandboxFragment>(
sandbox: T
) => T;
}
) => {
const changedSandboxes: Set<ReturnType<typeof sandboxMutation>> = new Set();
const doMutateSandbox = <T extends DashboardSandboxFragment>(
sandbox: T
): T => {
changedSandboxes.add(sandbox);
return sandboxMutation(sandbox);
};
type SandboxTypes = keyof typeof dashboard.sandboxes;
Object.keys(dashboard.sandboxes)
.filter(t => dashboard.sandboxes[t])
.forEach((type: SandboxTypes) => {
// For typescript, we've filtered out all pages that have `null` as value, but we need to let TS
// know that's the case here
const sandboxStructure = dashboard.sandboxes as {
[key in SandboxTypes]: NonNullable<typeof dashboard.sandboxes[key]>;
};
if (type === 'RECENT_BRANCHES') {
return;
}
if (type === 'REPOS') {
Object.keys(sandboxStructure.REPOS).forEach(repoName => {
const repoSandboxes = sandboxStructure.REPOS[repoName];
if (!repoSandboxes.sandboxes) {
return;
}
repoSandboxes.sandboxes = repoSandboxes.sandboxes.map(sandbox => {
if (sandboxIds.includes(sandbox.id)) {
return doMutateSandbox(sandbox);
}
return sandbox;
});
});
} else if (type === 'TEMPLATES' || type === 'TEMPLATE_HOME') {
dashboard.sandboxes[type] = sandboxStructure[type].map(template => {
if (template.sandbox && sandboxIds.includes(template.sandbox.id)) {
return {
...template,
sandbox: doMutateSandbox(template.sandbox),
};
}
return template;
});
} else if (type === 'ALL') {
// These are all folders
const folders = sandboxStructure.ALL;
const folderNames = Object.keys(folders);
folderNames.forEach(folderName => {
folders[folderName] = folders[folderName].map(sandbox => {
if (sandboxIds.includes(sandbox.id)) {
return doMutateSandbox(sandbox);
}
return sandbox;
});
});
} else {
// If it's not a folder
dashboard.sandboxes[type] = sandboxStructure[type].map(sandbox => {
if (sandboxIds.includes(sandbox.id)) {
return doMutateSandbox(sandbox);
}
return sandbox;
});
}
});
return { changedSandboxes };
};
export const deleteSandboxesFromState = (
{ state: { dashboard } }: Context,
{
ids,
}: {
ids: string[];
}
) => {
const sandboxFilter = <T extends DashboardSandboxFragment>(
sandbox: T
): boolean => !ids.includes(sandbox.id);
type SandboxTypes = keyof typeof dashboard.sandboxes;
Object.keys(dashboard.sandboxes)
.filter(t => dashboard.sandboxes[t])
.forEach((type: SandboxTypes) => {
// For typescript, we've filtered out all pages that have `null` as value, but we need to let TS
// know that's the case here
const sandboxStructure = dashboard.sandboxes as {
[key in SandboxTypes]: NonNullable<typeof dashboard.sandboxes[key]>;
};
if (type === 'ALL') {
const folderNames = Object.keys(sandboxStructure[type]);
folderNames.forEach(folderName => {
if (!sandboxStructure.ALL[folderName]) {
return;
}
const newSandboxes = sandboxStructure.ALL[folderName].filter(
sandboxFilter
);
if (newSandboxes.length !== sandboxStructure.ALL[folderName].length) {
sandboxStructure.ALL[folderName] = newSandboxes;
}
});
} else if (type === 'TEMPLATES' || type === 'TEMPLATE_HOME') {
const newTemplates = sandboxStructure[type].filter(
t => t.sandbox && !ids.includes(t.sandbox.id)
);
if (newTemplates.length !== sandboxStructure[type].length) {
dashboard.sandboxes[type] = newTemplates;
}
} else if (type === 'REPOS') {
const repos = Object.keys(sandboxStructure.REPOS);
repos.forEach(repo => {
const repoSandbox = sandboxStructure.REPOS[repo];
const newSandboxes = repoSandbox.sandboxes.filter(sandboxFilter);
if (newSandboxes.length !== repoSandbox.sandboxes.length) {
repoSandbox.sandboxes = newSandboxes;
}
});
} else if (type === 'DELETED') {
const newSandboxes = sandboxStructure[type].filter(
sandbox => !ids.includes(sandbox.id)
);
if (newSandboxes.length !== sandboxStructure[type].length) {
dashboard.sandboxes[type] = newSandboxes;
}
} else if (type !== 'RECENT_BRANCHES') {
const newSandboxes = sandboxStructure[type].filter(sandboxFilter);
if (newSandboxes.length !== sandboxStructure[type].length) {
// TypeScript can't narrow the union type based on the key, so we need to assert
(dashboard.sandboxes as any)[type] = newSandboxes;
}
}
});
};