Next round of refactoring done

This commit is contained in:
Colin Dawson 2026-01-30 23:54:14 +00:00
parent 9c7959cec8
commit 81a01fe9f3
15 changed files with 769 additions and 612 deletions

View File

@ -2,6 +2,7 @@
"Activate": "Activate",
"Add": "Add",
"AddDomain": "Add Domain",
"AddUser": "Add User",
"Address": "Address",
"Admin": "Admin",
"AnEmailWithPasswordResetLinkHasBeenSent": "An email with a password reset link has been sent.",
@ -15,16 +16,22 @@
"BlockedIPs": "Blocked IPs",
"Cancel": "Cancel",
"Changes": "Changes",
"Confirm": "Confirm",
"ConfirmEmailResent": "Confirm e-mail resent",
"ClientDomainManager": "Client Domain Manager",
"ClientDomains": "Client Domains",
"Comment": "Comment",
"ConfirmPassword": "Confirm Password",
"CustomFieldManager": "Custom Field Manager",
"CustomFields": "Custom Fields",
"Created": "Created",
"DisableAuthenticator": "Disable Authenticator",
"DisplayName": "Display Name",
"Domain": "Domain",
"Email": "Email",
"Edit": "Edit",
"EditDomain": "Edit Domain",
"EditUser": "Edit User",
"e-print": "e-print",
"e-suite": "e-suite",
"e-suiteLogo": "e-suite logo",
@ -45,6 +52,7 @@
"IPAddress": "IP Address",
"IPAddressUnblocked": "IP Address '{{ip}}' unblocked.",
"Items": "Items",
"LastUpdated": "Last Updated",
"Loading": "Loading",
"LoggingOut": "Logging out",
"MailTemplates": "Mail Templates",
@ -62,6 +70,7 @@
"PasswordsMustMatch": "You need to confirm by typing exactly the same as the new password",
"PressAgainToUnblock": "Press again to unblock",
"ResetPassword": "Reset Password",
"ResendConfirm": "Resend Confirm",
"RoleAccess": "Role Access",
"RoleAccessUpdated": "Role access updated successfully.",
"SecurityRoles": "Security Roles",

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../components/common/columns";
import { Paginated } from "../../../services/Paginated";
@ -30,15 +30,8 @@ const Domains: React.FC = () => {
() => new Map<string, string>(),
);
useEffect(() => {
const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
};
void loadInitial();
}, []);
const changePage = async (page: number, pageSize: number) => {
const changePage = useCallback(
async (page: number, pageSize: number) => {
const pagedDataResult = await domainsService.getDomains(
page,
pageSize,
@ -52,8 +45,18 @@ const Domains: React.FC = () => {
} else {
setLoaded(false);
}
},
[filters, sortColumn.key, sortColumn.order],
);
useEffect(() => {
const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
};
void loadInitial();
}, [changePage]);
const onSort = async (nextSortColumn: Column<GetDomain>) => {
const { page, pageSize } = pagedData;
const pagedDataResult = await domainsService.getDomains(

View File

@ -1,7 +1,6 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify";
import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated";
import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
import withRouter, { RouterProps } from "../../../../utils/withRouter";
@ -40,17 +39,15 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
const [loaded, setLoaded] = useState(false);
const [accessList, setAccessList] =
useState<Paginated<GetSecurityAccess>>(initialAccessList);
const [accessRightsForRole, setAccessRightsForRole] =
useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
const [pagedData, setPagedData] =
useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
const [sortColumn] = useState<Column<GetRoleSecurityAccess>>({
key: "name",
label: t("Name"),
order: "asc",
});
const roleGeneralIdRef = useMemo(
() => MakeGeneralIdRef(role?.id, role?.guid),
[role?.id, role?.guid],
);
const isItemSelected = (
const isItemSelected = useCallback(
(
securityAccess: string,
roleAccessList: unknown[] | undefined,
): boolean => {
@ -60,9 +57,12 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
(x) => (x as any).securityAccess === securityAccess,
);
return filtered.length > 0;
};
},
[],
);
const compileAccessRightsPagedData = (
const compileAccessRightsPagedData = useCallback(
(
masterList: GetSecurityAccess[] | undefined,
roleAccessList: unknown[] | undefined,
): Paginated<GetRoleSecurityAccess> => {
@ -93,9 +93,12 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
totalPages: 1,
data: accessRightsForRoleData,
};
};
},
[isItemSelected],
);
const changePage = async (nextAccessList?: Paginated<GetSecurityAccess>) => {
const changePage = useCallback(
async (nextAccessList?: Paginated<GetSecurityAccess>) => {
const list = nextAccessList || accessList;
const roleAccessFilters = new Map<string, string>();
@ -115,15 +118,17 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
);
if (nextPagedData) {
setLoaded(true);
setAccessRightsForRole(accessRightsResponse);
setPagedData(nextPagedData);
}
} else {
setLoaded(false);
}
};
},
[accessList, compileAccessRightsPagedData, role?.id],
);
const updatePage = async (nextAccessList?: Paginated<GetSecurityAccess>) => {
const updatePage = useCallback(
async (nextAccessList?: Paginated<GetSecurityAccess>) => {
if (nextAccessList && nextAccessList.count === 0) {
const list = await roleService.getAccessList(0, 10, "name", true);
setAccessList(list);
@ -131,7 +136,9 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
} else {
await changePage(nextAccessList);
}
};
},
[changePage],
);
useEffect(() => {
const loadInitial = async () => {
@ -144,10 +151,9 @@ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
};
void loadInitial();
}, [role?.id]);
}, [accessList, updatePage, role?.id]);
const handleSave = async (additions: string[], deletions: string[]) => {
const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
let response = undefined;
if (additions.length > 0) {

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated";
@ -44,17 +44,13 @@ const RolesEditorTabNoRouter: React.FC<RolesEditorProps> = ({
);
const { domainId } = router.params;
const domainGeneralIdRef = MakeGeneralIdRef(domainId);
const domainGeneralIdRef = useMemo(
() => MakeGeneralIdRef(domainId),
[domainId],
);
useEffect(() => {
const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
};
void loadInitial();
}, [domainId]);
const changePage = async (page: number, pageSize: number) => {
const changePage = useCallback(
async (page: number, pageSize: number) => {
const pagedDataResult = await roleService.getRoles(
page,
pageSize,
@ -69,8 +65,18 @@ const RolesEditorTabNoRouter: React.FC<RolesEditorProps> = ({
} else {
setLoaded(false);
}
},
[domainGeneralIdRef, filters, sortColumn.key, sortColumn.order],
);
useEffect(() => {
const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
};
void loadInitial();
}, [changePage, domainId]);
const onSort = async (nextSortColumn: Column<GetRoleResponse>) => {
const { page, pageSize } = pagedData;

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated";
@ -39,9 +39,13 @@ const UserRoleEditorNoRouter: React.FC<UserRoleEditorProps> = ({
() => new Map<string, string>(),
);
const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
const roleGeneralIdRef = useMemo(
() => MakeGeneralIdRef(role?.id, role?.guid),
[role?.id, role?.guid],
);
const getRoleUsers = async (
const getRoleUsers = useCallback(
async (
page: number,
pageSize: number,
nextSortColumn: Column<RoleUser>,
@ -63,7 +67,9 @@ const UserRoleEditorNoRouter: React.FC<UserRoleEditorProps> = ({
} else {
setLoaded(false);
}
};
},
[roleGeneralIdRef],
);
useEffect(() => {
const loadInitial = async () => {
@ -76,7 +82,7 @@ const UserRoleEditorNoRouter: React.FC<UserRoleEditorProps> = ({
};
void loadInitial();
}, [role?.id]);
}, [getRoleUsers, role?.id, sortColumn]);
const changePage = async (page: number, pageSize: number) => {
await getRoleUsers(page, pageSize, sortColumn, filters);

View File

@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Button, { ButtonType } from "../../../components/common/Button";
import Column from "../../../components/common/columns";
@ -28,7 +28,8 @@ const Forms: React.FC = () => {
new Map<string, string>(),
);
const changePage = async (page: number, pageSize: number) => {
const changePage = useCallback(
async (page: number, pageSize: number) => {
const data = await formsService.getForms(
page,
pageSize,
@ -42,7 +43,9 @@ const Forms: React.FC = () => {
} else {
setLoaded(false);
}
};
},
[filters, sortColumn.key, sortColumn.order],
);
const onSort = async (newSortColumn: Column<GetFormResponse>) => {
const { page, pageSize } = pagedData;
@ -91,9 +94,8 @@ const Forms: React.FC = () => {
};
useEffect(() => {
const { page, pageSize } = pagedData;
changePage(page, pageSize);
}, [pagedData]);
changePage(pagedData.page, pagedData.pageSize);
}, [changePage, pagedData.page, pagedData.pageSize]);
return (
<Loading loaded={loaded}>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import sequenceService, { ReadSequence } from "./services/sequenceService";
import SequenceTable from "./components/squenceTable";
@ -27,7 +27,8 @@ const Sequence: React.FC = () => {
new Map<string, string>(),
);
const changePage = async (page: number, pageSize: number) => {
const changePage = useCallback(
async (page: number, pageSize: number) => {
const data = await sequenceService.getSequences(
page,
pageSize,
@ -41,7 +42,9 @@ const Sequence: React.FC = () => {
} else {
setLoaded(false);
}
};
},
[filters, sortColumn.key, sortColumn.order],
);
const onSort = async (newSortColumn: Column<ReadSequence>) => {
const { page, pageSize } = pagedData;
@ -90,9 +93,8 @@ const Sequence: React.FC = () => {
};
useEffect(() => {
const { page, pageSize } = pagedData;
changePage(page, pageSize);
}, []);
changePage(pagedData.page, pagedData.pageSize);
}, [changePage, pagedData.page, pagedData.pageSize]);
return (
<Loading loaded={loaded}>

View File

@ -17,7 +17,6 @@ const SitesTable: React.FC<PublishedTableProps<ReadSite>> = ({
onSort,
}) => {
const { t } = useTranslation();
const canViewSpecification = authentication.hasAccess("ViewSpecification");
const columns: Column<ReadSite>[] = useMemo(
() => [
@ -37,7 +36,7 @@ const SitesTable: React.FC<PublishedTableProps<ReadSite>> = ({
{ key: "address", label: t("Address"), order: "asc" },
{ key: "status", label: t("Status"), order: "asc" },
],
[t, canViewSpecification],
[t],
);
const raiseSort = (sortCol: Column<ReadSite>) => {

View File

@ -1,51 +1,53 @@
import React, { Component } from 'react';
import Column from '../../../components/common/columns';
import { Paginated } from '../../../services/Paginated';
import Button, { ButtonType } from '../../../components/common/Button';
import withRouter from '../../../utils/withRouter';
import specificationService, { ReadSpecification } from './services/specificationService';
import SpecificationsTable from './components/SpecificationsTable';
import Loading from '../../../components/common/Loading';
import Permission from '../../../components/common/Permission';
import React, { Component } from "react";
import Column from "../../../components/common/columns";
import { Paginated } from "../../../services/Paginated";
import Button, { ButtonType } from "../../../components/common/Button";
import withRouter from "../../../utils/withRouter";
import specificationService, {
ReadSpecification,
} from "./services/specificationService";
import SpecificationsTable from "./components/SpecificationsTable";
import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface SpecificationsState{
interface SpecificationsState {
loaded: boolean;
pagedData : Paginated<ReadSpecification>,
sortColumn : Column<ReadSpecification>,
pagedData: Paginated<ReadSpecification>;
sortColumn: Column<ReadSpecification>;
filters: Map<string, string>;
}
class LocSpecifications extends Component<any, any, SpecificationsState> {
state = {
loaded : false,
pagedData : { page: 1,
pageSize : 10,
count: 0,
totalPages: 1,
data: []
},
loaded: false,
pagedData: { page: 1, pageSize: 10, count: 0, totalPages: 1, data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
filters: new Map<string, string>(),
};
componentDidMount = async () => {
const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize);
}
};
changePage = async (page: number, pageSize: number) => {
const { sortColumn, filters } = this.state;
const { siteId } = this.props.router.params;
filters.set("site.id", siteId);
const pagedData = await specificationService.GetSSpecifications(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
const pagedData = await specificationService.GetSSpecifications(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, pagedData, filters });
}
else {
} else {
this.setState({ loaded: false });
}
}
};
onSort = async (sortColumn: Column<ReadSpecification>) => {
const { page, pageSize } = this.state.pagedData;
@ -54,14 +56,19 @@ class LocSpecifications extends Component<any, any, SpecificationsState> {
const { siteId } = this.props.router.params;
filters.set("site.id", siteId);
const pagedData = await specificationService.GetSSpecifications(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
const pagedData = await specificationService.GetSSpecifications(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn });
}
else {
} else {
this.setState({ loaded: false });
}
}
};
onSearch = async (name: string, value: string) => {
const { page, pageSize } = this.state.pagedData;
@ -71,21 +78,29 @@ class LocSpecifications extends Component<any, any, SpecificationsState> {
const { siteId } = this.props.router.params;
filters.set("site.id", siteId);
const pagedData = await specificationService.GetSSpecifications(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
const pagedData = await specificationService.GetSSpecifications(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
} else {
this.setState({ loaded: false });
}
};
onDelete = async (item?: ReadSpecification) => {
const response = await specificationService.DeleteSpecification(item?.id, item?.guid);
const response = await specificationService.DeleteSpecification(
item?.id,
item?.guid,
);
if (response) {
this.componentDidMount();
}
}
};
render(): JSX.Element {
const { loaded, pagedData, sortColumn } = this.state;
@ -93,14 +108,23 @@ class LocSpecifications extends Component<any, any, SpecificationsState> {
return (
<Loading loaded={loaded}>
<Permission privilegeKey="AddSpecification">
<Button buttonType={ButtonType.primary} to="add">Add</Button>
<Button buttonType={ButtonType.primary} to="add">
Add
</Button>
</Permission>
<hr/>
<SpecificationsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/>
<hr />
<SpecificationsTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={this.changePage}
onSort={this.onSort}
onSearch={this.onSearch}
onDelete={this.onDelete}
/>
</Loading>
);
}
};
}
const Specifications = withRouter(LocSpecifications);

View File

@ -1,45 +1,62 @@
import React from "react";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import Table, { PublishedTableProps } from "../../../../components/common/Table";
import Table, {
PublishedTableProps,
} from "../../../../components/common/Table";
import authentication from "../../../frame/services/authenticationService";
import { ReadSpecification } from "../services/specificationService";
class SpecificationsTable extends React.Component<PublishedTableProps<ReadSpecification>> {
columns: Column<ReadSpecification>[] = [{ key: "name", label: "Name", order: "asc" }];
const SpecificationsTable: React.FC<PublishedTableProps<ReadSpecification>> = ({
data,
sortColumn,
onChangePage,
onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
raiseSort = (sortColumn: Column<ReadSpecification>) => {
this.setState({ sortColumn });
if (this.props.onSort !== undefined) this.props.onSort(sortColumn);
const columns: Column<ReadSpecification>[] = useMemo(
() => [{ key: "name", label: t("Name"), order: "asc" }],
[t],
);
const raiseSort = (sortCol: Column<ReadSpecification>) => {
if (onSort !== undefined) onSort(sortCol);
};
handleAuditParams = (item: any) => {
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.Printer.Specification",
primaryKey: '{"Id":' + item.id + "}",
primaryKey: `{"Id":${item.id}}`,
};
};
render() {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props;
const editPath = authentication.hasAccess("EditSpecification") ? "{0}" : undefined;
const doDelete = authentication.hasAccess("DeleteSpecification") ? onDelete : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined;
const editPath = authentication.hasAccess("EditSpecification")
? "{0}"
: undefined;
const doDelete = authentication.hasAccess("DeleteSpecification")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return (
<Table
data={data}
keyName="id"
columns={this.columns}
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={this.raiseSort}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
}
}
};
export default SpecificationsTable;

View File

@ -1,45 +1,62 @@
import React from "react";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import Table, { PublishedTableProps } from "../../../../components/common/Table";
import Table, {
PublishedTableProps,
} from "../../../../components/common/Table";
import authentication from "../../../frame/services/authenticationService";
import { GetSsoProvider } from "../services/ssoManagerService";
class SsoManagerTable extends React.Component<PublishedTableProps<GetSsoProvider>> {
columns: Column<GetSsoProvider>[] = [{ key: "name", label: "Name", order: "asc" }];
const SsoManagerTable: React.FC<PublishedTableProps<GetSsoProvider>> = ({
data,
sortColumn,
onChangePage,
onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
raiseSort = (sortColumn: Column<GetSsoProvider>) => {
this.setState({ sortColumn });
if (this.props.onSort !== undefined) this.props.onSort(sortColumn);
const columns: Column<GetSsoProvider>[] = useMemo(
() => [{ key: "name", label: t("Name"), order: "asc" }],
[t],
);
const raiseSort = (sortCol: Column<GetSsoProvider>) => {
if (onSort !== undefined) onSort(sortCol);
};
handleAuditParams = (item: any) => {
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.UserManager.SsoProvider",
primaryKey: '{"Id":' + item.id + "}",
primaryKey: `{"Id":${item.id}}`,
};
};
render() {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props;
const editPath = authentication.hasAccess("EditSsoProvider") ? "edit/{0}" : undefined;
const doDelete = authentication.hasAccess("DeleteSsoProvider") ? onDelete : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined;
const editPath = authentication.hasAccess("EditSsoProvider")
? "edit/{0}"
: undefined;
const doDelete = authentication.hasAccess("DeleteSsoProvider")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return (
<Table
data={data}
keyName="id"
columns={this.columns}
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={this.raiseSort}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
}
}
};
export default SsoManagerTable;

View File

@ -1,97 +1,126 @@
import React, { Component } from 'react';
import Column from '../../../components/common/columns';
import { Paginated } from '../../../services/Paginated';
import SsoManagerTable from './components/ssoManagerTable';
import ssoManagerService, { GetSsoProvider } from './services/ssoManagerService';
import Button, { ButtonType } from '../../../components/common/Button';
import Loading from '../../../components/common/Loading';
import Permission from '../../../components/common/Permission';
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../components/common/columns";
import { Paginated } from "../../../services/Paginated";
import SsoManagerTable from "./components/ssoManagerTable";
import ssoManagerService, {
GetSsoProvider,
} from "./services/ssoManagerService";
import Button, { ButtonType } from "../../../components/common/Button";
import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface SsoManagerState{
loaded: boolean;
pagedData : Paginated<GetSsoProvider>,
sortColumn : Column<GetSsoProvider>,
filters: Map<string, string>;
}
class SsoManager extends Component< any, any, SsoManagerState> {
state = {
loaded : false,
pagedData : { page: 1,
pageSize : 10,
const SsoManager: React.FC = () => {
const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] = useState<Paginated<GetSsoProvider>>({
page: 1,
pageSize: 10,
count: 0,
totalPages: 1,
data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
data: [],
});
const [sortColumn, setSortColumn] = useState<Column<GetSsoProvider>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
componentDidMount = async () => {
const { page, pageSize } = this.state.pagedData;
const changePage = useCallback(
async (page: number, pageSize: number) => {
const data = await ssoManagerService.getSsoProviders(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
} else {
setLoaded(false);
}
},
[filters, sortColumn.key, sortColumn.order],
);
await this.changePage(page, pageSize);
}
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
const pagedData = await ssoManagerService.getSsoProviders(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, pagedData });
}
else {
this.setState({ loaded: false });
}
}
onSort = async(sortColumn : Column<GetSsoProvider>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await ssoManagerService.getSsoProviders(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn });
}
else {
this.setState({ loaded: false });
}
}
onSearch = async ( name: string, value: string) => {
const {page, pageSize } = this.state.pagedData;
const {sortColumn, filters } = this.state;
filters.set(name, value);
const pagedData = await ssoManagerService.getSsoProviders(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
const onSort = async (newSortColumn: Column<GetSsoProvider>) => {
const { page, pageSize } = pagedData;
const data = await ssoManagerService.getSsoProviders(
page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
}
};
onDelete = async ( keyValue? : GetSsoProvider) => {
const response = await ssoManagerService.deleteSsoProvider( keyValue?.id, keyValue?.guid);
if (response) {
this.componentDidMount();
}
}
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
render(): JSX.Element {
const { loaded, pagedData, sortColumn } = this.state;
const data = await ssoManagerService.getSsoProviders(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
}
};
const onDelete = async (keyValue?: GetSsoProvider) => {
const response = await ssoManagerService.deleteSsoProvider(
keyValue?.id,
keyValue?.guid,
);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
}
};
useEffect(() => {
changePage(pagedData.page, pagedData.pageSize);
}, [changePage, pagedData.page, pagedData.pageSize]);
return (
<Loading loaded={loaded}>
<Permission privilegeKey="AddSsoProvider">
<div>
<Button buttonType={ButtonType.primary} to="add">Add</Button>
<Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div>
</Permission>
<hr/>
<SsoManagerTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/>
<hr />
<SsoManagerTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading>
);
}
};
export default SsoManager;

View File

@ -1,40 +1,30 @@
import React from "react";
import { useTranslation } from "react-i18next";
import HorizontalTabs from "../../../components/common/HorizionalTabs";
import Tab from "../../../components/common/Tab";
import GeneralTab from "./components/GeneralTab";
interface UserDetailsProps {
editMode : boolean;
editMode: boolean;
}
class UserDetails extends React.Component<UserDetailsProps> {
isEditMode = () => {
const { editMode } = this.props;
return editMode;
};
const UserDetails: React.FC<UserDetailsProps> = ({ editMode }) => {
const { t } = useTranslation();
render() {
const isEditMode = this.isEditMode();
const heading = editMode ? t("EditUser") : t("AddUser");
let mode = "Add";
if (isEditMode) mode = "Edit";
let tabs : JSX.Element[] = [];
tabs.push( <Tab key={1} label="General">
<GeneralTab isEditMode={isEditMode}/>
</Tab> );
const tabs: JSX.Element[] = [
<Tab key={1} label={t("General")}>
<GeneralTab isEditMode={editMode} />
</Tab>,
];
return (
<div>
<h1>{mode} User</h1>
<HorizontalTabs>
{tabs}
</HorizontalTabs>
<h1>{heading}</h1>
<HorizontalTabs>{tabs}</HorizontalTabs>
</div>
);
}
}
};
export default UserDetails;

View File

@ -1,6 +1,9 @@
import React from "react";
import React, { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns";
import Table, { PublishedTableProps } from "../../../../components/common/Table";
import Table, {
PublishedTableProps,
} from "../../../../components/common/Table";
import { GetUser } from "../services/usersService";
import Button, { ButtonType } from "../../../../components/common/Button";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@ -11,80 +14,96 @@ export interface UsersTableProps extends PublishedTableProps<GetUser> {
resendConfirmEmail?: (user: GetUser) => void;
}
class UsersTable extends React.Component<UsersTableProps> {
canResendConfirmMail = authentication.hasAccess("ResendConfirmMail");
const UsersTable: React.FC<UsersTableProps> = ({
data,
sortColumn,
onChangePage,
onSearch,
onDelete,
onSort,
resendConfirmEmail,
}) => {
const { t } = useTranslation();
const canResendConfirmMail = authentication.hasAccess("ResendConfirmMail");
columns: Column<GetUser>[] = [
{ key: "displayName", label: "Name", order: "asc" },
{ key: "email", label: "Email", order: "asc" },
{ key: "domainName", label: "Domain", order: "asc" },
{ key: "created", label: "Created", order: "asc" },
{ key: "lastUpdated", label: "Last Updated", order: "asc" },
const resendConfirmEmailHandler = useCallback(
(keyValue: GetUser) => {
if (resendConfirmEmail != null) resendConfirmEmail(keyValue);
},
[resendConfirmEmail],
);
const columns: Column<GetUser>[] = useMemo(
() => [
{ key: "displayName", label: t("Name"), order: "asc" },
{ key: "email", label: t("Email"), order: "asc" },
{ key: "domainName", label: t("Domain"), order: "asc" },
{ key: "created", label: t("Created"), order: "asc" },
{ key: "lastUpdated", label: t("LastUpdated"), order: "asc" },
{
key: "emailConfirmed",
label: "Resend Confirm",
label: t("ResendConfirm"),
order: "asc",
searchable: false,
content: (item) => {
if (!item!.emailConfirmed && this.canResendConfirmMail) {
if (!item.emailConfirmed && canResendConfirmMail) {
return (
<>
<Button buttonType={ButtonType.secondary} onClick={() => this.resendConfirmEmail(item)}>
<FontAwesomeIcon icon={faEnvelope} /> Confirm
<Button
buttonType={ButtonType.secondary}
onClick={() => resendConfirmEmailHandler(item)}
>
<FontAwesomeIcon icon={faEnvelope} /> {t("Confirm")}
</Button>
</>
);
}
return <></>;
},
},
];
],
[t, canResendConfirmMail, resendConfirmEmailHandler],
);
resendConfirmEmail = (keyValue: GetUser) => {
const { resendConfirmEmail } = this.props;
if (resendConfirmEmail != null) resendConfirmEmail(keyValue!);
const raiseSort = (sortCol: Column<GetUser>) => {
if (onSort !== undefined) onSort(sortCol);
};
raiseSort = (sortColumn: Column<GetUser>) => {
this.setState({ sortColumn });
if (this.props.onSort !== undefined) this.props.onSort(sortColumn);
};
handleAuditParams = (item: any) => {
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.UserManager.User",
primaryKey: '{"Id":' + item.id + "}",
primaryKey: `{"Id":${item.id}}`,
};
};
canDelete = (item: GetUser) => {
const canDelete = (item: GetUser) => {
const user = authentication.getCurrentUser();
return item.id != user!.primarysid;
return item.id !== user!.primarysid;
};
render() {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props;
const editPath = authentication.hasAccess("EditUser") ? "edit/{0}" : undefined;
const doDelete = authentication.hasAccess("DeleteUser") ? onDelete : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined;
const editPath = authentication.hasAccess("EditUser")
? "edit/{0}"
: undefined;
const doDelete = authentication.hasAccess("DeleteUser")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return (
<Table
data={data}
keyName="id"
columns={this.columns}
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={this.raiseSort}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
canDelete={this.canDelete}
canDelete={canDelete}
/>
);
}
}
};
export default UsersTable;

View File

@ -1,103 +1,131 @@
import React, { Component } from 'react';
import Column from '../../../components/common/columns';
import { Paginated } from '../../../services/Paginated';
import UsersTable from './components/usersTable';
import userService, { GetUser } from './services/usersService';
import Button, { ButtonType } from '../../../components/common/Button';
import { toast } from 'react-toastify';
import Loading from '../../../components/common/Loading';
import Permission from '../../../components/common/Permission';
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../components/common/columns";
import { Paginated } from "../../../services/Paginated";
import UsersTable from "./components/usersTable";
import userService, { GetUser } from "./services/usersService";
import Button, { ButtonType } from "../../../components/common/Button";
import { toast } from "react-toastify";
import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface UsersState{
loaded: boolean,
pagedData : Paginated<GetUser>,
sortColumn : Column<GetUser>,
filters: Map<string, string>;
}
class Users extends Component< any, any, UsersState> {
state = {
loaded: false,
pagedData : { page: 1,
pageSize : 10,
const Users: React.FC = () => {
const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] = useState<Paginated<GetUser>>({
page: 1,
pageSize: 10,
count: 0,
totalPages: 1,
data: [] },
sortColumn: { key: "displayName", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
data: [],
});
const [sortColumn, setSortColumn] = useState<Column<GetUser>>({
key: "displayName",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
componentDidMount = async () => {
const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize);
}
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
const pagedData = await userService.getUsers(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if(pagedData) {
this.setState({ loaded: true, pagedData });
const changePage = useCallback(
async (page: number, pageSize: number) => {
const data = await userService.getUsers(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
} else {
this.setState({ loaded: false });
}
setLoaded(false);
}
},
[filters, sortColumn.key, sortColumn.order],
);
onSort = async(sortColumn : Column<GetUser>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await userService.getUsers(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
const onSort = async (newSortColumn: Column<GetUser>) => {
const { page, pageSize } = pagedData;
const data = await userService.getUsers(
page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn});
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
this.setState({ loaded: false });
}
}
onSearch = async ( name: string, value: string) => {
const {page, pageSize } = this.state.pagedData;
const {sortColumn, filters } = this.state;
filters.set(name, value);
const pagedData = await userService.getUsers(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState( { loaded: true, filters, pagedData });
} else {
this.setState({ loaded: false });
setLoaded(false);
}
};
onDelete = async ( item? : GetUser) => {
const response = await userService.deleteUser( item?.id, item?.guid);
if (response) {
this.componentDidMount();
}
}
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
const data = await userService.getUsers(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
newFilters,
);
resentConfirmEmail = async (user: GetUser) => {
const response = await userService.resendConfirmEmail( user.id, user.guid);
if (response) {
toast.info("Confirm e-mail resent");
}
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
}
};
render(): JSX.Element {
const { loaded, pagedData, sortColumn } = this.state;
const onDelete = async (item?: GetUser) => {
const response = await userService.deleteUser(item?.id, item?.guid);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
}
};
const resentConfirmEmail = async (user: GetUser) => {
const response = await userService.resendConfirmEmail(user.id, user.guid);
if (response) {
toast.info(t("ConfirmEmailResent"));
}
};
useEffect(() => {
changePage(pagedData.page, pagedData.pageSize);
}, [changePage, pagedData.page, pagedData.pageSize]);
return (
<Loading loaded={loaded}>
<Permission privilegeKey="AddUser">
<div>
<Button buttonType={ButtonType.primary} to="add">Add</Button>
<Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div>
</Permission>
<hr/>
<UsersTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete} resendConfirmEmail={this.resentConfirmEmail}/>
<hr />
<UsersTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
resendConfirmEmail={resentConfirmEmail}
/>
</Loading>
);
}
};
export default Users;