@webiny/app-security-access-management 6.3.0 → 6.4.0-beta.0
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/Extension.js +74 -73
- package/Extension.js.map +1 -1
- package/SecurityPermissions.js +49 -41
- package/SecurityPermissions.js.map +1 -1
- package/constants.js +6 -5
- package/constants.js.map +1 -1
- package/domain/permissionsSchema.js +30 -19
- package/domain/permissionsSchema.js.map +1 -1
- package/features/permissions/abstractions.js +2 -1
- package/features/permissions/abstractions.js.map +1 -1
- package/features/permissions/feature.js +2 -1
- package/features/permissions/feature.js.map +1 -1
- package/index.js +0 -2
- package/package.json +9 -11
- package/routes.js +32 -37
- package/routes.js.map +1 -1
- package/types.js +0 -3
- package/ui/views/ApiKeys/ApiKeyForm.js +203 -220
- package/ui/views/ApiKeys/ApiKeyForm.js.map +1 -1
- package/ui/views/ApiKeys/ApiKeys.js +11 -12
- package/ui/views/ApiKeys/ApiKeys.js.map +1 -1
- package/ui/views/ApiKeys/ApiKeysDataList.js +129 -143
- package/ui/views/ApiKeys/ApiKeysDataList.js.map +1 -1
- package/ui/views/ApiKeys/graphql.js +7 -6
- package/ui/views/ApiKeys/graphql.js.map +1 -1
- package/ui/views/ApiKeys/index.js +0 -2
- package/ui/views/ApiKeys/utils.js +12 -6
- package/ui/views/ApiKeys/utils.js.map +1 -1
- package/ui/views/Roles/Roles.js +11 -12
- package/ui/views/Roles/Roles.js.map +1 -1
- package/ui/views/Roles/RolesDataList.js +130 -144
- package/ui/views/Roles/RolesDataList.js.map +1 -1
- package/ui/views/Roles/RolesForm.js +198 -223
- package/ui/views/Roles/RolesForm.js.map +1 -1
- package/ui/views/Roles/graphql.js +7 -6
- package/ui/views/Roles/graphql.js.map +1 -1
- package/ui/views/Roles/index.js +0 -2
- package/ui/views/Teams/Teams.js +11 -12
- package/ui/views/Teams/Teams.js.map +1 -1
- package/ui/views/Teams/TeamsDataList.js +130 -146
- package/ui/views/Teams/TeamsDataList.js.map +1 -1
- package/ui/views/Teams/TeamsForm.js +174 -182
- package/ui/views/Teams/TeamsForm.js.map +1 -1
- package/ui/views/Teams/graphql.js +7 -6
- package/ui/views/Teams/graphql.js.map +1 -1
- package/ui/views/Teams/index.js +0 -2
- package/ui/views/utils.js +9 -7
- package/ui/views/utils.js.map +1 -1
- package/index.js.map +0 -1
- package/types.js.map +0 -1
- package/ui/views/ApiKeys/index.js.map +0 -1
- package/ui/views/Roles/index.js.map +0 -1
- package/ui/views/Teams/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"ui/views/Teams/Teams.js","sources":["../../../../src/ui/views/Teams/Teams.tsx"],"sourcesContent":["import React from \"react\";\nimport { TeamsDataList } from \"./TeamsDataList.js\";\nimport { TeamsForm } from \"./TeamsForm.js\";\nimport { SplitView, LeftPanel, RightPanel, useRoute } from \"@webiny/app-admin\";\nimport { Routes } from \"~/routes.js\";\n\nexport const Teams = () => {\n const { route } = useRoute(Routes.Roles.List);\n\n return (\n <SplitView>\n <LeftPanel>\n <TeamsDataList activeId={route.params.id} />\n </LeftPanel>\n <RightPanel>\n <TeamsForm newEntry={route.params.new === true} id={route.params.id} />\n </RightPanel>\n </SplitView>\n );\n};\n"],"names":["Teams","route","useRoute","Routes","SplitView","LeftPanel","TeamsDataList","RightPanel","TeamsForm"],"mappings":";;;;;AAMO,MAAMA,QAAQ;IACjB,MAAM,EAAEC,KAAK,EAAE,GAAGC,SAASC,OAAO,KAAK,CAAC,IAAI;IAE5C,OAAO,WAAP,GACI,oBAACC,WAASA,MAAAA,WAAAA,GACN,oBAACC,WAASA,MAAAA,WAAAA,GACN,oBAACC,eAAaA;QAAC,UAAUL,MAAM,MAAM,CAAC,EAAE;uBAE5C,oBAACM,YAAUA,MAAAA,WAAAA,GACP,oBAACC,WAASA;QAAC,UAAUP,AAAqB,SAArBA,MAAM,MAAM,CAAC,GAAG;QAAW,IAAIA,MAAM,MAAM,CAAC,EAAE;;AAInF"}
|
|
@@ -1,157 +1,141 @@
|
|
|
1
|
-
import
|
|
1
|
+
import react, { useCallback, useMemo, useState } from "react";
|
|
2
2
|
import orderBy from "lodash/orderBy.js";
|
|
3
|
-
import { Button, Grid, Select, Tooltip } from "@webiny/admin-ui";
|
|
4
|
-
import { ReactComponent
|
|
3
|
+
import { Button, DataList, DataListModal, DeleteIcon, Grid, List, Select, Tooltip } from "@webiny/admin-ui";
|
|
4
|
+
import { ReactComponent } from "@webiny/icons/add.svg";
|
|
5
5
|
import { i18n } from "@webiny/app/i18n/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { useQuery, useMutation } from "@apollo/react-hooks";
|
|
10
|
-
import { LIST_TEAMS, DELETE_TEAM } from "./graphql.js";
|
|
6
|
+
import { SearchUI, useConfirmationDialog, useRouter, useSnackbar } from "@webiny/app-admin";
|
|
7
|
+
import { useMutation, useQuery } from "@apollo/react-hooks";
|
|
8
|
+
import { DELETE_TEAM, LIST_TEAMS } from "./graphql.js";
|
|
11
9
|
import { deserializeSorters } from "../utils.js";
|
|
12
10
|
import { Routes } from "../../../routes.js";
|
|
13
11
|
const t = i18n.ns("app-security/admin/teams/data-list");
|
|
14
|
-
const SORTERS = [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const [filter, setFilter] = useState("");
|
|
31
|
-
const [sort, setSort] = useState(SORTERS[0].sorter);
|
|
32
|
-
const {
|
|
33
|
-
goToRoute
|
|
34
|
-
} = useRouter();
|
|
35
|
-
const {
|
|
36
|
-
showSnackbar
|
|
37
|
-
} = useSnackbar();
|
|
38
|
-
const {
|
|
39
|
-
showConfirmation
|
|
40
|
-
} = useConfirmationDialog({
|
|
41
|
-
dataTestId: "default-data-list.delete-dialog"
|
|
42
|
-
});
|
|
43
|
-
const {
|
|
44
|
-
data: listResponse,
|
|
45
|
-
loading: listLoading
|
|
46
|
-
} = useQuery(LIST_TEAMS);
|
|
47
|
-
const [deleteIt, {
|
|
48
|
-
loading: deleteLoading
|
|
49
|
-
}] = useMutation(DELETE_TEAM, {
|
|
50
|
-
refetchQueries: [{
|
|
51
|
-
query: LIST_TEAMS
|
|
52
|
-
}]
|
|
53
|
-
});
|
|
54
|
-
const data = listLoading && !listResponse ? [] : listResponse?.security.teams.data || [];
|
|
55
|
-
const filterTeam = useCallback(({
|
|
56
|
-
name,
|
|
57
|
-
slug,
|
|
58
|
-
description
|
|
59
|
-
}) => {
|
|
60
|
-
return name.toLowerCase().includes(filter) || slug.toLowerCase().includes(filter) || description && description.toLowerCase().includes(filter);
|
|
61
|
-
}, [filter]);
|
|
62
|
-
const sortTeams = useCallback(teams => {
|
|
63
|
-
if (!sort) {
|
|
64
|
-
return teams;
|
|
12
|
+
const SORTERS = [
|
|
13
|
+
{
|
|
14
|
+
label: t`Newest to oldest`,
|
|
15
|
+
sorter: "createdOn_DESC"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: t`Oldest to newest`,
|
|
19
|
+
sorter: "createdOn_ASC"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: t`Name A-Z`,
|
|
23
|
+
sorter: "name_ASC"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: t`Name Z-A`,
|
|
27
|
+
sorter: "name_DESC"
|
|
65
28
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
variables: item
|
|
75
|
-
});
|
|
76
|
-
const {
|
|
77
|
-
error
|
|
78
|
-
} = data.security.deleteTeam;
|
|
79
|
-
if (error) {
|
|
80
|
-
return showSnackbar(error.message);
|
|
81
|
-
}
|
|
82
|
-
showSnackbar(t`Team "{slug}" deleted.`({
|
|
83
|
-
slug: item.slug
|
|
84
|
-
}));
|
|
85
|
-
if (activeId === item.id) {
|
|
86
|
-
goToRoute(Routes.Teams.List);
|
|
87
|
-
}
|
|
29
|
+
];
|
|
30
|
+
const TeamsDataList = ({ activeId })=>{
|
|
31
|
+
const [filter, setFilter] = useState("");
|
|
32
|
+
const [sort, setSort] = useState(SORTERS[0].sorter);
|
|
33
|
+
const { goToRoute } = useRouter();
|
|
34
|
+
const { showSnackbar } = useSnackbar();
|
|
35
|
+
const { showConfirmation } = useConfirmationDialog({
|
|
36
|
+
dataTestId: "default-data-list.delete-dialog"
|
|
88
37
|
});
|
|
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
|
-
|
|
38
|
+
const { data: listResponse, loading: listLoading } = useQuery(LIST_TEAMS);
|
|
39
|
+
const [deleteIt, { loading: deleteLoading }] = useMutation(DELETE_TEAM, {
|
|
40
|
+
refetchQueries: [
|
|
41
|
+
{
|
|
42
|
+
query: LIST_TEAMS
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
const data = listLoading && !listResponse ? [] : listResponse?.security.teams.data || [];
|
|
47
|
+
const filterTeam = useCallback(({ name, slug, description })=>name.toLowerCase().includes(filter) || slug.toLowerCase().includes(filter) || description && description.toLowerCase().includes(filter), [
|
|
48
|
+
filter
|
|
49
|
+
]);
|
|
50
|
+
const sortTeams = useCallback((teams)=>{
|
|
51
|
+
if (!sort) return teams;
|
|
52
|
+
const [key, sortBy] = deserializeSorters(sort);
|
|
53
|
+
return orderBy(teams, [
|
|
54
|
+
key
|
|
55
|
+
], [
|
|
56
|
+
sortBy
|
|
57
|
+
]);
|
|
58
|
+
}, [
|
|
59
|
+
sort
|
|
60
|
+
]);
|
|
61
|
+
const deleteItem = useCallback((item)=>{
|
|
62
|
+
showConfirmation(async ()=>{
|
|
63
|
+
const { data } = await deleteIt({
|
|
64
|
+
variables: item
|
|
65
|
+
});
|
|
66
|
+
const { error } = data.security.deleteTeam;
|
|
67
|
+
if (error) return showSnackbar(error.message);
|
|
68
|
+
showSnackbar(t`Team "{slug}" deleted.`({
|
|
69
|
+
slug: item.slug
|
|
70
|
+
}));
|
|
71
|
+
if (activeId === item.id) goToRoute(Routes.Teams.List);
|
|
119
72
|
});
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"data
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
73
|
+
}, [
|
|
74
|
+
activeId
|
|
75
|
+
]);
|
|
76
|
+
const teamsDataListModalOverlay = useMemo(()=>/*#__PURE__*/ react.createElement(DataListModal.Content, null, /*#__PURE__*/ react.createElement(Grid, null, /*#__PURE__*/ react.createElement(Grid.Column, {
|
|
77
|
+
span: 12
|
|
78
|
+
}, /*#__PURE__*/ react.createElement(Select, {
|
|
79
|
+
value: sort,
|
|
80
|
+
onChange: setSort,
|
|
81
|
+
label: t`Sort by`,
|
|
82
|
+
options: SORTERS.map(({ label, sorter: value })=>({
|
|
83
|
+
label,
|
|
84
|
+
value
|
|
85
|
+
}))
|
|
86
|
+
})))), [
|
|
87
|
+
sort
|
|
88
|
+
]);
|
|
89
|
+
const filteredData = "" === filter ? data : data.filter(filterTeam);
|
|
90
|
+
const teamList = sortTeams(filteredData);
|
|
91
|
+
return /*#__PURE__*/ react.createElement(DataList, {
|
|
92
|
+
title: t`Teams`,
|
|
93
|
+
actions: /*#__PURE__*/ react.createElement(Button, {
|
|
94
|
+
text: t`New`,
|
|
95
|
+
icon: /*#__PURE__*/ react.createElement(ReactComponent, null),
|
|
96
|
+
size: "sm",
|
|
97
|
+
className: "ml-xs",
|
|
98
|
+
"data-testid": "new-record-button",
|
|
99
|
+
onClick: ()=>{
|
|
100
|
+
goToRoute(Routes.Teams.List, {
|
|
101
|
+
new: true
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
data: teamList,
|
|
106
|
+
loading: listLoading || deleteLoading,
|
|
107
|
+
search: /*#__PURE__*/ react.createElement(SearchUI, {
|
|
108
|
+
value: filter,
|
|
109
|
+
onChange: setFilter,
|
|
110
|
+
inputPlaceholder: t`Search teams...`
|
|
111
|
+
}),
|
|
112
|
+
modalOverlay: teamsDataListModalOverlay,
|
|
113
|
+
modalOverlayAction: /*#__PURE__*/ react.createElement(DataListModal.Trigger, {
|
|
114
|
+
"data-testid": "default-data-list.filter"
|
|
115
|
+
})
|
|
116
|
+
}, ({ data })=>/*#__PURE__*/ react.createElement(List, {
|
|
117
|
+
"data-testid": "default-data-list"
|
|
118
|
+
}, data.map((item)=>/*#__PURE__*/ react.createElement(List.Item, {
|
|
119
|
+
key: item.id,
|
|
120
|
+
selected: item.id === activeId,
|
|
121
|
+
title: item.name,
|
|
122
|
+
description: item.description ?? "(no description)",
|
|
123
|
+
onClick: ()=>{
|
|
124
|
+
goToRoute(Routes.Teams.List, {
|
|
125
|
+
id: item.id
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
actions: item.system || item.plugin ? /*#__PURE__*/ react.createElement(Tooltip, {
|
|
129
|
+
content: /*#__PURE__*/ react.createElement("span", null, item.system ? t`Cannot delete system teams.` : t`Cannot delete teams created via extensions.`),
|
|
130
|
+
trigger: /*#__PURE__*/ react.createElement(DeleteIcon, {
|
|
131
|
+
disabled: true
|
|
132
|
+
})
|
|
133
|
+
}) : /*#__PURE__*/ react.createElement(DeleteIcon, {
|
|
134
|
+
onClick: ()=>deleteItem(item),
|
|
135
|
+
"data-testid": "default-data-list.delete"
|
|
136
|
+
})
|
|
137
|
+
}))));
|
|
155
138
|
};
|
|
139
|
+
export { TeamsDataList };
|
|
156
140
|
|
|
157
141
|
//# sourceMappingURL=TeamsDataList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useMemo","useState","orderBy","Button","Grid","Select","Tooltip","ReactComponent","AddIcon","i18n","DataList","ScrollList","ListItem","ListItemText","ListItemTextSecondary","ListItemMeta","DataListModalOverlayAction","DataListModalOverlay","ListItemTextPrimary","ListActions","DeleteIcon","useRouter","useSnackbar","useConfirmationDialog","SearchUI","useQuery","useMutation","LIST_TEAMS","DELETE_TEAM","deserializeSorters","Routes","t","ns","SORTERS","label","sorter","TeamsDataList","activeId","filter","setFilter","sort","setSort","goToRoute","showSnackbar","showConfirmation","dataTestId","data","listResponse","loading","listLoading","deleteIt","deleteLoading","refetchQueries","query","security","teams","filterTeam","name","slug","description","toLowerCase","includes","sortTeams","key","sortBy","deleteItem","item","variables","error","deleteTeam","message","id","Teams","List","teamsDataListModalOverlay","createElement","Column","span","value","onChange","options","map","filteredData","teamList","title","actions","text","icon","size","className","onClick","new","search","inputPlaceholder","modalOverlay","modalOverlayAction","selected","system","plugin","content","trigger","disabled"],"sources":["TeamsDataList.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from \"react\";\nimport orderBy from \"lodash/orderBy.js\";\nimport { Button, Grid, Select, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport {\n DataList,\n ScrollList,\n ListItem,\n ListItemText,\n ListItemTextSecondary,\n ListItemMeta,\n DataListModalOverlayAction,\n DataListModalOverlay,\n ListItemTextPrimary,\n ListActions\n} from \"@webiny/ui/List/index.js\";\nimport { DeleteIcon } from \"@webiny/ui/List/DataList/icons/index.js\";\nimport { useRouter, useSnackbar, useConfirmationDialog, SearchUI } from \"@webiny/app-admin\";\nimport { useQuery, useMutation } from \"@apollo/react-hooks\";\nimport type { ListTeamsResponse } from \"./graphql.js\";\nimport { LIST_TEAMS, DELETE_TEAM } from \"./graphql.js\";\nimport { deserializeSorters } from \"../utils.js\";\nimport type { Team } from \"~/types.js\";\nimport { Routes } from \"~/routes.js\";\n\nconst t = i18n.ns(\"app-security/admin/teams/data-list\");\n\nconst SORTERS = [\n {\n label: t`Newest to oldest`,\n sorter: \"createdOn_DESC\"\n },\n {\n label: t`Oldest to newest`,\n sorter: \"createdOn_ASC\"\n },\n {\n label: t`Name A-Z`,\n sorter: \"name_ASC\"\n },\n {\n label: t`Name Z-A`,\n sorter: \"name_DESC\"\n }\n];\n\nexport interface TeamsDataListProps {\n activeId: string | undefined;\n}\n\nexport const TeamsDataList = ({ activeId }: TeamsDataListProps) => {\n const [filter, setFilter] = useState(\"\");\n const [sort, setSort] = useState(SORTERS[0].sorter);\n const { goToRoute } = useRouter();\n const { showSnackbar } = useSnackbar();\n const { showConfirmation } = useConfirmationDialog({\n dataTestId: \"default-data-list.delete-dialog\"\n });\n\n const { data: listResponse, loading: listLoading } = useQuery<ListTeamsResponse>(LIST_TEAMS);\n\n const [deleteIt, { loading: deleteLoading }] = useMutation(DELETE_TEAM, {\n refetchQueries: [{ query: LIST_TEAMS }]\n });\n\n const data = listLoading && !listResponse ? [] : listResponse?.security.teams.data || [];\n\n const filterTeam = useCallback(\n ({ name, slug, description }: Team) => {\n return (\n name.toLowerCase().includes(filter) ||\n slug.toLowerCase().includes(filter) ||\n (description && description.toLowerCase().includes(filter))\n );\n },\n [filter]\n );\n\n const sortTeams = useCallback(\n (teams: Team[]) => {\n if (!sort) {\n return teams;\n }\n const [key, sortBy] = deserializeSorters(sort);\n return orderBy(teams, [key], [sortBy]);\n },\n [sort]\n );\n\n const deleteItem = useCallback(\n (item: Team) => {\n showConfirmation(async () => {\n const { data } = await deleteIt({\n variables: item\n });\n\n const { error } = data.security.deleteTeam;\n if (error) {\n return showSnackbar(error.message);\n }\n\n showSnackbar(t`Team \"{slug}\" deleted.`({ slug: item.slug }));\n\n if (activeId === item.id) {\n goToRoute(Routes.Teams.List);\n }\n });\n },\n [activeId]\n );\n\n const teamsDataListModalOverlay = useMemo(\n () => (\n <DataListModalOverlay>\n <Grid>\n <Grid.Column span={12}>\n <Select\n value={sort}\n onChange={setSort}\n label={t`Sort by`}\n options={SORTERS.map(({ label, sorter: value }) => {\n return {\n label,\n value\n };\n })}\n />\n </Grid.Column>\n </Grid>\n </DataListModalOverlay>\n ),\n [sort]\n );\n\n const filteredData = filter === \"\" ? data : data.filter(filterTeam);\n const teamList = sortTeams(filteredData);\n\n return (\n <DataList\n title={t`Teams`}\n actions={\n <Button\n text={t`New`}\n icon={<AddIcon />}\n size={\"sm\"}\n className={\"ml-xs\"}\n data-testid=\"new-record-button\"\n onClick={() => {\n goToRoute(Routes.Teams.List, { new: true });\n }}\n />\n }\n data={teamList}\n loading={listLoading || deleteLoading}\n search={\n <SearchUI\n value={filter}\n onChange={setFilter}\n inputPlaceholder={t`Search teams...`}\n />\n }\n modalOverlay={teamsDataListModalOverlay}\n modalOverlayAction={\n <DataListModalOverlayAction data-testid={\"default-data-list.filter\"} />\n }\n >\n {({ data }: { data: Team[] }) => (\n <ScrollList data-testid=\"default-data-list\">\n {data.map(item => (\n <ListItem key={item.id} selected={item.id === activeId}>\n <ListItemText\n onClick={() => {\n goToRoute(Routes.Teams.List, { id: item.id });\n }}\n >\n <ListItemTextPrimary>{item.name}</ListItemTextPrimary>\n <ListItemTextSecondary>\n {item.description ?? \"(no description)\"}\n </ListItemTextSecondary>\n </ListItemText>\n\n <ListItemMeta>\n <ListActions>\n {item.system || item.plugin ? (\n <Tooltip\n content={\n <span>\n {item.system\n ? t`Cannot delete system teams.`\n : t`Cannot delete teams created via extensions.`}\n </span>\n }\n trigger={<DeleteIcon disabled />}\n />\n ) : (\n <DeleteIcon\n onClick={() => deleteItem(item)}\n data-testid={\"default-data-list.delete\"}\n />\n )}\n </ListActions>\n </ListItemMeta>\n </ListItem>\n ))}\n </ScrollList>\n )}\n </DataList>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,WAAW,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AAC7D,OAAOC,OAAO,MAAM,mBAAmB;AACvC,SAASC,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAEC,OAAO,QAAQ,kBAAkB;AAChE,SAASC,cAAc,IAAIC,OAAO,QAAQ,uBAAuB;AACjE,SAASC,IAAI,QAAQ,2BAA2B;AAChD,SACIC,QAAQ,EACRC,UAAU,EACVC,QAAQ,EACRC,YAAY,EACZC,qBAAqB,EACrBC,YAAY,EACZC,0BAA0B,EAC1BC,oBAAoB,EACpBC,mBAAmB,EACnBC,WAAW,QACR,0BAA0B;AACjC,SAASC,UAAU,QAAQ,yCAAyC;AACpE,SAASC,SAAS,EAAEC,WAAW,EAAEC,qBAAqB,EAAEC,QAAQ,QAAQ,mBAAmB;AAC3F,SAASC,QAAQ,EAAEC,WAAW,QAAQ,qBAAqB;AAE3D,SAASC,UAAU,EAAEC,WAAW;AAChC,SAASC,kBAAkB;AAE3B,SAASC,MAAM;AAEf,MAAMC,CAAC,GAAGtB,IAAI,CAACuB,EAAE,CAAC,oCAAoC,CAAC;AAEvD,MAAMC,OAAO,GAAG,CACZ;EACIC,KAAK,EAAEH,CAAC,kBAAkB;EAC1BI,MAAM,EAAE;AACZ,CAAC,EACD;EACID,KAAK,EAAEH,CAAC,kBAAkB;EAC1BI,MAAM,EAAE;AACZ,CAAC,EACD;EACID,KAAK,EAAEH,CAAC,UAAU;EAClBI,MAAM,EAAE;AACZ,CAAC,EACD;EACID,KAAK,EAAEH,CAAC,UAAU;EAClBI,MAAM,EAAE;AACZ,CAAC,CACJ;AAMD,OAAO,MAAMC,aAAa,GAAGA,CAAC;EAAEC;AAA6B,CAAC,KAAK;EAC/D,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGtC,QAAQ,CAAC,EAAE,CAAC;EACxC,MAAM,CAACuC,IAAI,EAAEC,OAAO,CAAC,GAAGxC,QAAQ,CAACgC,OAAO,CAAC,CAAC,CAAC,CAACE,MAAM,CAAC;EACnD,MAAM;IAAEO;EAAU,CAAC,GAAGrB,SAAS,CAAC,CAAC;EACjC,MAAM;IAAEsB;EAAa,CAAC,GAAGrB,WAAW,CAAC,CAAC;EACtC,MAAM;IAAEsB;EAAiB,CAAC,GAAGrB,qBAAqB,CAAC;IAC/CsB,UAAU,EAAE;EAChB,CAAC,CAAC;EAEF,MAAM;IAAEC,IAAI,EAAEC,YAAY;IAAEC,OAAO,EAAEC;EAAY,CAAC,GAAGxB,QAAQ,CAAoBE,UAAU,CAAC;EAE5F,MAAM,CAACuB,QAAQ,EAAE;IAAEF,OAAO,EAAEG;EAAc,CAAC,CAAC,GAAGzB,WAAW,CAACE,WAAW,EAAE;IACpEwB,cAAc,EAAE,CAAC;MAAEC,KAAK,EAAE1B;IAAW,CAAC;EAC1C,CAAC,CAAC;EAEF,MAAMmB,IAAI,GAAGG,WAAW,IAAI,CAACF,YAAY,GAAG,EAAE,GAAGA,YAAY,EAAEO,QAAQ,CAACC,KAAK,CAACT,IAAI,IAAI,EAAE;EAExF,MAAMU,UAAU,GAAGzD,WAAW,CAC1B,CAAC;IAAE0D,IAAI;IAAEC,IAAI;IAAEC;EAAkB,CAAC,KAAK;IACnC,OACIF,IAAI,CAACG,WAAW,CAAC,CAAC,CAACC,QAAQ,CAACvB,MAAM,CAAC,IACnCoB,IAAI,CAACE,WAAW,CAAC,CAAC,CAACC,QAAQ,CAACvB,MAAM,CAAC,IAClCqB,WAAW,IAAIA,WAAW,CAACC,WAAW,CAAC,CAAC,CAACC,QAAQ,CAACvB,MAAM,CAAE;EAEnE,CAAC,EACD,CAACA,MAAM,CACX,CAAC;EAED,MAAMwB,SAAS,GAAG/D,WAAW,CACxBwD,KAAa,IAAK;IACf,IAAI,CAACf,IAAI,EAAE;MACP,OAAOe,KAAK;IAChB;IACA,MAAM,CAACQ,GAAG,EAAEC,MAAM,CAAC,GAAGnC,kBAAkB,CAACW,IAAI,CAAC;IAC9C,OAAOtC,OAAO,CAACqD,KAAK,EAAE,CAACQ,GAAG,CAAC,EAAE,CAACC,MAAM,CAAC,CAAC;EAC1C,CAAC,EACD,CAACxB,IAAI,CACT,CAAC;EAED,MAAMyB,UAAU,GAAGlE,WAAW,CACzBmE,IAAU,IAAK;IACZtB,gBAAgB,CAAC,YAAY;MACzB,MAAM;QAAEE;MAAK,CAAC,GAAG,MAAMI,QAAQ,CAAC;QAC5BiB,SAAS,EAAED;MACf,CAAC,CAAC;MAEF,MAAM;QAAEE;MAAM,CAAC,GAAGtB,IAAI,CAACQ,QAAQ,CAACe,UAAU;MAC1C,IAAID,KAAK,EAAE;QACP,OAAOzB,YAAY,CAACyB,KAAK,CAACE,OAAO,CAAC;MACtC;MAEA3B,YAAY,CAACZ,CAAC,wBAAwB,CAAC;QAAE2B,IAAI,EAAEQ,IAAI,CAACR;MAAK,CAAC,CAAC,CAAC;MAE5D,IAAIrB,QAAQ,KAAK6B,IAAI,CAACK,EAAE,EAAE;QACtB7B,SAAS,CAACZ,MAAM,CAAC0C,KAAK,CAACC,IAAI,CAAC;MAChC;IACJ,CAAC,CAAC;EACN,CAAC,EACD,CAACpC,QAAQ,CACb,CAAC;EAED,MAAMqC,yBAAyB,GAAG1E,OAAO,CACrC,mBACIF,KAAA,CAAA6E,aAAA,CAAC1D,oBAAoB,qBACjBnB,KAAA,CAAA6E,aAAA,CAACvE,IAAI,qBACDN,KAAA,CAAA6E,aAAA,CAACvE,IAAI,CAACwE,MAAM;IAACC,IAAI,EAAE;EAAG,gBAClB/E,KAAA,CAAA6E,aAAA,CAACtE,MAAM;IACHyE,KAAK,EAAEtC,IAAK;IACZuC,QAAQ,EAAEtC,OAAQ;IAClBP,KAAK,EAAEH,CAAC,SAAU;IAClBiD,OAAO,EAAE/C,OAAO,CAACgD,GAAG,CAAC,CAAC;MAAE/C,KAAK;MAAEC,MAAM,EAAE2C;IAAM,CAAC,KAAK;MAC/C,OAAO;QACH5C,KAAK;QACL4C;MACJ,CAAC;IACL,CAAC;EAAE,CACN,CACQ,CACX,CACY,CACzB,EACD,CAACtC,IAAI,CACT,CAAC;EAED,MAAM0C,YAAY,GAAG5C,MAAM,KAAK,EAAE,GAAGQ,IAAI,GAAGA,IAAI,CAACR,MAAM,CAACkB,UAAU,CAAC;EACnE,MAAM2B,QAAQ,GAAGrB,SAAS,CAACoB,YAAY,CAAC;EAExC,oBACIpF,KAAA,CAAA6E,aAAA,CAACjE,QAAQ;IACL0E,KAAK,EAAErD,CAAC,OAAQ;IAChBsD,OAAO,eACHvF,KAAA,CAAA6E,aAAA,CAACxE,MAAM;MACHmF,IAAI,EAAEvD,CAAC,KAAM;MACbwD,IAAI,eAAEzF,KAAA,CAAA6E,aAAA,CAACnE,OAAO,MAAE,CAAE;MAClBgF,IAAI,EAAE,IAAK;MACXC,SAAS,EAAE,OAAQ;MACnB,eAAY,mBAAmB;MAC/BC,OAAO,EAAEA,CAAA,KAAM;QACXhD,SAAS,CAACZ,MAAM,CAAC0C,KAAK,CAACC,IAAI,EAAE;UAAEkB,GAAG,EAAE;QAAK,CAAC,CAAC;MAC/C;IAAE,CACL,CACJ;IACD7C,IAAI,EAAEqC,QAAS;IACfnC,OAAO,EAAEC,WAAW,IAAIE,aAAc;IACtCyC,MAAM,eACF9F,KAAA,CAAA6E,aAAA,CAACnD,QAAQ;MACLsD,KAAK,EAAExC,MAAO;MACdyC,QAAQ,EAAExC,SAAU;MACpBsD,gBAAgB,EAAE9D,CAAC;IAAkB,CACxC,CACJ;IACD+D,YAAY,EAAEpB,yBAA0B;IACxCqB,kBAAkB,eACdjG,KAAA,CAAA6E,aAAA,CAAC3D,0BAA0B;MAAC,eAAa;IAA2B,CAAE;EACzE,GAEA,CAAC;IAAE8B;EAAuB,CAAC,kBACxBhD,KAAA,CAAA6E,aAAA,CAAChE,UAAU;IAAC,eAAY;EAAmB,GACtCmC,IAAI,CAACmC,GAAG,CAACf,IAAI,iBACVpE,KAAA,CAAA6E,aAAA,CAAC/D,QAAQ;IAACmD,GAAG,EAAEG,IAAI,CAACK,EAAG;IAACyB,QAAQ,EAAE9B,IAAI,CAACK,EAAE,KAAKlC;EAAS,gBACnDvC,KAAA,CAAA6E,aAAA,CAAC9D,YAAY;IACT6E,OAAO,EAAEA,CAAA,KAAM;MACXhD,SAAS,CAACZ,MAAM,CAAC0C,KAAK,CAACC,IAAI,EAAE;QAAEF,EAAE,EAAEL,IAAI,CAACK;MAAG,CAAC,CAAC;IACjD;EAAE,gBAEFzE,KAAA,CAAA6E,aAAA,CAACzD,mBAAmB,QAAEgD,IAAI,CAACT,IAA0B,CAAC,eACtD3D,KAAA,CAAA6E,aAAA,CAAC7D,qBAAqB,QACjBoD,IAAI,CAACP,WAAW,IAAI,kBACF,CACb,CAAC,eAEf7D,KAAA,CAAA6E,aAAA,CAAC5D,YAAY,qBACTjB,KAAA,CAAA6E,aAAA,CAACxD,WAAW,QACP+C,IAAI,CAAC+B,MAAM,IAAI/B,IAAI,CAACgC,MAAM,gBACvBpG,KAAA,CAAA6E,aAAA,CAACrE,OAAO;IACJ6F,OAAO,eACHrG,KAAA,CAAA6E,aAAA,eACKT,IAAI,CAAC+B,MAAM,GACNlE,CAAC,6BAA6B,GAC9BA,CAAC,6CACL,CACT;IACDqE,OAAO,eAAEtG,KAAA,CAAA6E,aAAA,CAACvD,UAAU;MAACiF,QAAQ;IAAA,CAAE;EAAE,CACpC,CAAC,gBAEFvG,KAAA,CAAA6E,aAAA,CAACvD,UAAU;IACPsE,OAAO,EAAEA,CAAA,KAAMzB,UAAU,CAACC,IAAI,CAAE;IAChC,eAAa;EAA2B,CAC3C,CAEI,CACH,CACR,CACb,CACO,CAEV,CAAC;AAEnB,CAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"ui/views/Teams/TeamsDataList.js","sources":["../../../../src/ui/views/Teams/TeamsDataList.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from \"react\";\nimport orderBy from \"lodash/orderBy.js\";\nimport { Button, Grid, Select, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { List, DataList, DataListModal, DeleteIcon } from \"@webiny/admin-ui\";\n\nimport { useRouter, useSnackbar, useConfirmationDialog, SearchUI } from \"@webiny/app-admin\";\nimport { useQuery, useMutation } from \"@apollo/react-hooks\";\nimport type { ListTeamsResponse } from \"./graphql.js\";\nimport { LIST_TEAMS, DELETE_TEAM } from \"./graphql.js\";\nimport { deserializeSorters } from \"../utils.js\";\nimport type { Team } from \"~/types.js\";\nimport { Routes } from \"~/routes.js\";\n\nconst t = i18n.ns(\"app-security/admin/teams/data-list\");\n\nconst SORTERS = [\n {\n label: t`Newest to oldest`,\n sorter: \"createdOn_DESC\"\n },\n {\n label: t`Oldest to newest`,\n sorter: \"createdOn_ASC\"\n },\n {\n label: t`Name A-Z`,\n sorter: \"name_ASC\"\n },\n {\n label: t`Name Z-A`,\n sorter: \"name_DESC\"\n }\n];\n\nexport interface TeamsDataListProps {\n activeId: string | undefined;\n}\n\nexport const TeamsDataList = ({ activeId }: TeamsDataListProps) => {\n const [filter, setFilter] = useState(\"\");\n const [sort, setSort] = useState(SORTERS[0].sorter);\n const { goToRoute } = useRouter();\n const { showSnackbar } = useSnackbar();\n const { showConfirmation } = useConfirmationDialog({\n dataTestId: \"default-data-list.delete-dialog\"\n });\n\n const { data: listResponse, loading: listLoading } = useQuery<ListTeamsResponse>(LIST_TEAMS);\n\n const [deleteIt, { loading: deleteLoading }] = useMutation(DELETE_TEAM, {\n refetchQueries: [{ query: LIST_TEAMS }]\n });\n\n const data = listLoading && !listResponse ? [] : listResponse?.security.teams.data || [];\n\n const filterTeam = useCallback(\n ({ name, slug, description }: Team) => {\n return (\n name.toLowerCase().includes(filter) ||\n slug.toLowerCase().includes(filter) ||\n (description && description.toLowerCase().includes(filter))\n );\n },\n [filter]\n );\n\n const sortTeams = useCallback(\n (teams: Team[]) => {\n if (!sort) {\n return teams;\n }\n const [key, sortBy] = deserializeSorters(sort);\n return orderBy(teams, [key], [sortBy]);\n },\n [sort]\n );\n\n const deleteItem = useCallback(\n (item: Team) => {\n showConfirmation(async () => {\n const { data } = await deleteIt({\n variables: item\n });\n\n const { error } = data.security.deleteTeam;\n if (error) {\n return showSnackbar(error.message);\n }\n\n showSnackbar(t`Team \"{slug}\" deleted.`({ slug: item.slug }));\n\n if (activeId === item.id) {\n goToRoute(Routes.Teams.List);\n }\n });\n },\n [activeId]\n );\n\n const teamsDataListModalOverlay = useMemo(\n () => (\n <DataListModal.Content>\n <Grid>\n <Grid.Column span={12}>\n <Select\n value={sort}\n onChange={setSort}\n label={t`Sort by`}\n options={SORTERS.map(({ label, sorter: value }) => {\n return {\n label,\n value\n };\n })}\n />\n </Grid.Column>\n </Grid>\n </DataListModal.Content>\n ),\n [sort]\n );\n\n const filteredData = filter === \"\" ? data : data.filter(filterTeam);\n const teamList = sortTeams(filteredData);\n\n return (\n <DataList\n title={t`Teams`}\n actions={\n <Button\n text={t`New`}\n icon={<AddIcon />}\n size={\"sm\"}\n className={\"ml-xs\"}\n data-testid=\"new-record-button\"\n onClick={() => {\n goToRoute(Routes.Teams.List, { new: true });\n }}\n />\n }\n data={teamList}\n loading={listLoading || deleteLoading}\n search={\n <SearchUI\n value={filter}\n onChange={setFilter}\n inputPlaceholder={t`Search teams...`}\n />\n }\n modalOverlay={teamsDataListModalOverlay}\n modalOverlayAction={<DataListModal.Trigger data-testid={\"default-data-list.filter\"} />}\n >\n {({ data }: { data: Team[] }) => (\n <List data-testid=\"default-data-list\">\n {data.map(item => (\n <List.Item\n key={item.id}\n selected={item.id === activeId}\n title={item.name}\n description={item.description ?? \"(no description)\"}\n onClick={() => {\n goToRoute(Routes.Teams.List, { id: item.id });\n }}\n actions={\n item.system || item.plugin ? (\n <Tooltip\n content={\n <span>\n {item.system\n ? t`Cannot delete system teams.`\n : t`Cannot delete teams created via extensions.`}\n </span>\n }\n trigger={<DeleteIcon disabled />}\n />\n ) : (\n <DeleteIcon\n onClick={() => deleteItem(item)}\n data-testid={\"default-data-list.delete\"}\n />\n )\n }\n />\n ))}\n </List>\n )}\n </DataList>\n );\n};\n"],"names":["t","i18n","SORTERS","TeamsDataList","activeId","filter","setFilter","useState","sort","setSort","goToRoute","useRouter","showSnackbar","useSnackbar","showConfirmation","useConfirmationDialog","listResponse","listLoading","useQuery","LIST_TEAMS","deleteIt","deleteLoading","useMutation","DELETE_TEAM","data","filterTeam","useCallback","name","slug","description","sortTeams","teams","key","sortBy","deserializeSorters","orderBy","deleteItem","item","error","Routes","teamsDataListModalOverlay","useMemo","DataListModal","Grid","Select","label","value","filteredData","teamList","DataList","Button","AddIcon","SearchUI","List","Tooltip","DeleteIcon"],"mappings":"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"}
|