Skip to content

Commit 312d9c6

Browse files
committed
WIP for #360
1 parent d074b63 commit 312d9c6

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

client/src/pages/Manage.jsx

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import React, {useCallback, useEffect, useRef, useState} from "react";
2+
import "./Manage.scss";
3+
import I18n from "../locale/I18n";
4+
import "../components/Entities.scss";
5+
import {Entities} from "../components/Entities";
6+
import {autoCompleteEntities} from "../api";
7+
import {isEmpty} from "../utils/Utils";
8+
import {useDebouncedCallback} from "use-debounce";
9+
import {providerName, providerOrganizationName} from "../utils/Manage.js";
10+
import SelectField from "../components/SelectField.jsx";
11+
import {useNavigate} from "react-router";
12+
13+
const entityTypes = ["oidc10_rp", "saml20_sp"]
14+
.map(type => ({label: I18n.t(`manage.${type}`), value: type}))
15+
16+
export const Manage = () => {
17+
18+
const [entityType, setEntityType] = useState(entityTypes[0]);
19+
const [totalElements, setTotalElements] = useState(0);
20+
const [entities, setEntities] = useState([]);
21+
const currentQueryRef = useRef("");
22+
const navigate = useNavigate();
23+
24+
const search = query => {
25+
currentQueryRef.current = query;
26+
if (!isEmpty(query) && query.trim().length > 2) {
27+
delayedAutocomplete(query);
28+
}
29+
};
30+
31+
const showEntityDetails = entity => {
32+
navigate(`/manage/details/${entity["type"]}/${entity["_id"]}`);
33+
}
34+
35+
const delayedAutocomplete = useDebouncedCallback(useCallback(query => {
36+
autoCompleteEntities(query, entityType.value).then(res => {
37+
setEntities(res);
38+
setTotalElements(res.length);
39+
});
40+
}, [entityType]), 375);
41+
42+
useEffect(() => {
43+
if (!isEmpty(currentQueryRef.current) && currentQueryRef.current.trim().length > 2) {
44+
delayedAutocomplete(currentQueryRef.current);
45+
}
46+
}, [entityType, delayedAutocomplete]);
47+
48+
const filters = () => {
49+
return (
50+
<SelectField
51+
value={entityType}
52+
options={entityTypes}
53+
searchable={false}
54+
onChange={option => setEntityType(option)}
55+
clearable={false}
56+
/>
57+
)
58+
}
59+
60+
const columns = [
61+
{
62+
key: "name",
63+
header: I18n.t("manage.name"),
64+
mapper: entity => providerName(I18n.locale, entity)
65+
},
66+
{
67+
key: "organization",
68+
header: I18n.t("manage.organization"),
69+
mapper: entity => providerOrganizationName(I18n.locale, entity)
70+
},
71+
{
72+
key: "type",
73+
header: I18n.t("manage.type"),
74+
mapper: entity => I18n.t(`manage.${entity.type}`)
75+
},
76+
];
77+
78+
return (
79+
<div className="mod-entities">
80+
<Entities entities={entities}
81+
modelName="manage"
82+
defaultSort="name"
83+
columns={columns}
84+
showNew={false}
85+
filters={filters()}
86+
inputFocus={true}
87+
hideTitle={true}
88+
rowLinkMapper={(e, entity) => showEntityDetails(entity)}
89+
customSearch={search}
90+
totalElements={totalElements}
91+
/>
92+
</div>
93+
);
94+
95+
}

client/src/pages/Manage.scss

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.mod-manage {
2+
position: relative;
3+
max-width: 100%;
4+
5+
.mod-spinner-loading {
6+
position: absolute;
7+
top: -90px;
8+
right: 50%;
9+
}
10+
11+
.mod-entities .entities-search {
12+
width: auto;
13+
}
14+
15+
table.users {
16+
17+
thead {
18+
th {
19+
&.name {
20+
width: 35%;
21+
}
22+
23+
&.schac_home_organisation {
24+
width: 20%;
25+
}
26+
27+
&.createdAt {
28+
width: 20%;
29+
}
30+
31+
&.lastActivity {
32+
width: 20%;
33+
}
34+
}
35+
}
36+
37+
tbody {
38+
td.authority {
39+
text-align: center;
40+
}
41+
42+
}
43+
44+
}
45+
46+
}

0 commit comments

Comments
 (0)