-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathgetModeratedItems.ts
More file actions
109 lines (92 loc) · 3.21 KB
/
Copy pathgetModeratedItems.ts
File metadata and controls
109 lines (92 loc) · 3.21 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
import {
FolderNode,
ProjectNode,
SpaceNode,
TreeView,
} from 'api/admin_publications/types';
import { IUserData } from 'api/users/types';
/**
* Derives the spaces, folders and projects a user moderates from the
* admin_publications tree view, based on the user's roles, grouped by type.
* Reusable wherever the tree view needs to be scoped to what a given user can
* manage (e.g. the users table, adding items to a space).
*/
export const getModeratedItems = (user: IUserData, treeView: TreeView) => {
const folderIds = user.attributes.roles
?.filter(
(
role
): role is Extract<typeof role, { type: 'project_folder_moderator' }> =>
role.type === 'project_folder_moderator'
)
.map((role) => role.project_folder_id);
const projectIds = user.attributes.roles
?.filter(
(role): role is Extract<typeof role, { type: 'project_moderator' }> =>
role.type === 'project_moderator'
)
.map((role) => role.project_id);
const spaceIds = user.attributes.roles
?.filter(
(role): role is Extract<typeof role, { type: 'space_moderator' }> =>
role.type === 'space_moderator'
)
.map((role) => role.space_id);
const foldersSet = new Set(folderIds);
const projectsSet = new Set(projectIds);
const spacesSet = new Set(spaceIds);
const { nodes } = treeView.data.attributes;
// Collect all spaces, folders, and projects
const spaces = nodes.filter(
(node): node is SpaceNode => node.type === 'space'
);
const rootFolders = nodes.filter(
(node): node is FolderNode => node.type === 'folder'
);
// Get folders from spaces
const foldersInSpaces = spaces.flatMap((space) =>
space.children.filter(
(child): child is FolderNode => child.type === 'folder'
)
);
const allFolders = [...rootFolders, ...foldersInSpaces];
// Find spaces user moderates
const spacesUserModerates = spaces.filter((node) => spacesSet.has(node.id));
// Find folders user moderates
const foldersUserModerates = allFolders.filter((node) =>
foldersSet.has(node.id)
);
// Find projects user moderates
// 1. Root-level projects
const rootProjectsUserModerates = nodes.filter(
(node): node is ProjectNode =>
node.type === 'project' && projectsSet.has(node.id)
);
// 2. Projects inside root-level folders
const projectsInRootFoldersUserModerates = rootFolders
.flatMap((folder) => folder.children)
.filter((child) => projectsSet.has(child.id));
// 3. Projects inside spaces (not in folders)
const projectsInSpacesUserModerates = spaces
.flatMap((space) =>
space.children.filter(
(child): child is ProjectNode => child.type === 'project'
)
)
.filter((project) => projectsSet.has(project.id));
// 4. Projects inside folders that are in spaces
const projectsInSpaceFoldersUserModerates = foldersInSpaces
.flatMap((folder) => folder.children)
.filter((child) => projectsSet.has(child.id));
const projectsUserModerates = [
...rootProjectsUserModerates,
...projectsInRootFoldersUserModerates,
...projectsInSpacesUserModerates,
...projectsInSpaceFoldersUserModerates,
];
return {
projectsUserModerates,
foldersUserModerates,
spacesUserModerates,
};
};