Next round of refactoring done

This commit is contained in:
Colin Dawson 2026-01-30 23:34:29 +00:00
parent 8c0c6a167c
commit 9c7959cec8
23 changed files with 2040 additions and 1603 deletions

View File

@ -1,14 +1,19 @@
{ {
"Activate": "Activate", "Activate": "Activate",
"Add": "Add",
"AddDomain": "Add Domain",
"Address": "Address",
"Admin": "Admin", "Admin": "Admin",
"AnEmailWithPasswordResetLinkHasBeenSent": "An email with a password reset link has been sent.", "AnEmailWithPasswordResetLinkHasBeenSent": "An email with a password reset link has been sent.",
"AnErrorOccurred": "An error occurred", "AnErrorOccurred": "An error occurred",
"Application": "Application", "Application": "Application",
"Applications": "Applications", "Applications": "Applications",
"Allowed": "Allowed",
"AuditLog": "Audit Logs", "AuditLog": "Audit Logs",
"AuditLogs": "Audit Logs", "AuditLogs": "Audit Logs",
"BlockedIPAddresses": "Blocked IP addresses", "BlockedIPAddresses": "Blocked IP addresses",
"BlockedIPs": "Blocked IPs", "BlockedIPs": "Blocked IPs",
"Cancel": "Cancel",
"Changes": "Changes", "Changes": "Changes",
"ClientDomainManager": "Client Domain Manager", "ClientDomainManager": "Client Domain Manager",
"ClientDomains": "Client Domains", "ClientDomains": "Client Domains",
@ -18,6 +23,8 @@
"CustomFields": "Custom Fields", "CustomFields": "Custom Fields",
"DisableAuthenticator": "Disable Authenticator", "DisableAuthenticator": "Disable Authenticator",
"DisplayName": "Display Name", "DisplayName": "Display Name",
"Edit": "Edit",
"EditDomain": "Edit Domain",
"e-print": "e-print", "e-print": "e-print",
"e-suite": "e-suite", "e-suite": "e-suite",
"e-suiteLogo": "e-suite logo", "e-suiteLogo": "e-suite logo",
@ -29,14 +36,18 @@
"FieldType": "Field Type", "FieldType": "Field Type",
"Forms": "Forms", "Forms": "Forms",
"FormTemplateManager": "Form Template Manager", "FormTemplateManager": "Form Template Manager",
"General": "General",
"Glossaries": "Glossaries", "Glossaries": "Glossaries",
"GlossaryManager": "Glossary Manager", "GlossaryManager": "Glossary Manager",
"Group": "Group",
"Home": "Home", "Home": "Home",
"Id": "Id", "Id": "Id",
"IPAddress": "IP Address", "IPAddress": "IP Address",
"IPAddressUnblocked": "IP Address '{{ip}}' unblocked.", "IPAddressUnblocked": "IP Address '{{ip}}' unblocked.",
"Items": "Items",
"Loading": "Loading", "Loading": "Loading",
"LoggingOut": "Logging out", "LoggingOut": "Logging out",
"MailTemplates": "Mail Templates",
"Message": "Message", "Message": "Message",
"Name": "Name", "Name": "Name",
"NewPassword": "New Password", "NewPassword": "New Password",
@ -51,6 +62,9 @@
"PasswordsMustMatch": "You need to confirm by typing exactly the same as the new password", "PasswordsMustMatch": "You need to confirm by typing exactly the same as the new password",
"PressAgainToUnblock": "Press again to unblock", "PressAgainToUnblock": "Press again to unblock",
"ResetPassword": "Reset Password", "ResetPassword": "Reset Password",
"RoleAccess": "Role Access",
"RoleAccessUpdated": "Role access updated successfully.",
"SecurityRoles": "Security Roles",
"Save": "Save", "Save": "Save",
"Sequence": "Sequence", "Sequence": "Sequence",
"SequenceManager": "Sequence Manager", "SequenceManager": "Sequence Manager",
@ -60,14 +74,17 @@
"SpecificationManager": "Specification Manager", "SpecificationManager": "Specification Manager",
"SsoManager": "Sso Manager", "SsoManager": "Sso Manager",
"StackTrace": "Stack Trace", "StackTrace": "Stack Trace",
"Status": "Status",
"Support": "Support", "Support": "Support",
"SupportingData": "Supporting Data", "SupportingData": "Supporting Data",
"Timing": "Timing", "Timing": "Timing",
"Type": "Type", "Type": "Type",
"Up": "Up",
"UnblockedInMinutes": "Unblocked In (Minutes)", "UnblockedInMinutes": "Unblocked In (Minutes)",
"UserManager": "User Manager", "UserManager": "User Manager",
"UserName": "User Name", "UserName": "User Name",
"UsernameIsRequired": "Username is required", "UsernameIsRequired": "Username is required",
"Version": "Version",
"UsernameMustBeValidEmail": "Username must be a valid email", "UsernameMustBeValidEmail": "Username must be a valid email",
"Users": "Users" "Users": "Users"
} }

View File

@ -1,99 +1,150 @@
import React, { Component } from 'react'; import React, { useEffect, useMemo, useState } from "react";
import Column from '../../../components/common/columns'; import { useTranslation } from "react-i18next";
import { Paginated } from '../../../services/Paginated'; import Column from "../../../components/common/columns";
import CustomFieldsTable from './components/CustomFieldsTable'; import { Paginated } from "../../../services/Paginated";
import customFieldsService, { CustomField } from './services/customFieldsService'; import CustomFieldsTable from "./components/CustomFieldsTable";
import Button, { ButtonType } from '../../../components/common/Button'; import customFieldsService, {
import Loading from '../../../components/common/Loading'; CustomField,
import Permission from '../../../components/common/Permission'; } from "./services/customFieldsService";
import Button, { ButtonType } from "../../../components/common/Button";
import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface CustomFieldsState { const initialPagedData: Paginated<CustomField> = {
loaded: boolean,
pagedData: Paginated<CustomField>,
sortColumn: Column<CustomField>,
filters: Map<string, string>;
}
class CustomFields extends Component<any, any, CustomFieldsState> {
state = {
loaded: false,
pagedData: {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] data: [],
}, };
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
componentDidMount = async () => { const initialSortColumn: Column<CustomField> = {
const { page, pageSize } = this.state.pagedData; key: "name",
label: "Name",
order: "asc",
};
await this.changePage(page, pageSize); const CustomFields: React.FC = () => {
} const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] =
useState<Paginated<CustomField>>(initialPagedData);
const [sortColumn, setSortColumn] =
useState<Column<CustomField>>(initialSortColumn);
const [filters, setFilters] = useState<Map<string, string>>(
() => new Map<string, string>(),
);
changePage = async (page: number, pageSize: number) => { useEffect(() => {
const { sortColumn, filters } = this.state; const loadInitial = async () => {
const pagedDataResult = await customFieldsService.getFields(
const pagedData = await customFieldsService.getFields(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); initialPagedData.page,
if (pagedData) { initialPagedData.pageSize,
this.setState({ loaded: true, pagedData }); initialSortColumn.key,
} initialSortColumn.order === "asc",
else { new Map<string, string>(),
this.setState({ loaded: false }); );
} if (pagedDataResult) {
} setLoaded(true);
setPagedData(pagedDataResult);
onSort = async (sortColumn: Column<CustomField>) => { } else {
const { page, pageSize } = this.state.pagedData; setLoaded(false);
const { filters } = this.state;
const pagedData = await customFieldsService.getFields(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 customFieldsService.getFields(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
onDelete = async (item?: CustomField) => { void loadInitial();
const response = await customFieldsService.deleteField(item?.id, item?.guid); }, []);
if (response) {
this.componentDidMount();
}
}
render(): JSX.Element { const changePage = async (page: number, pageSize: number) => {
const { loaded, pagedData, sortColumn } = this.state; const pagedDataResult = await customFieldsService.getFields(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedDataResult) {
setLoaded(true);
setPagedData(pagedDataResult);
} else {
setLoaded(false);
}
};
const onSort = async (nextSortColumn: Column<CustomField>) => {
const { page, pageSize } = pagedData;
const pagedDataResult = await customFieldsService.getFields(
page,
pageSize,
nextSortColumn.key,
nextSortColumn.order === "asc",
filters,
);
if (pagedDataResult) {
setLoaded(true);
setPagedData(pagedDataResult);
setSortColumn(nextSortColumn);
} else {
setLoaded(false);
}
};
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const nextFilters = new Map(filters);
nextFilters.set(name, value);
const pagedDataResult = await customFieldsService.getFields(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
nextFilters,
);
if (pagedDataResult) {
setLoaded(true);
setFilters(nextFilters);
setPagedData(pagedDataResult);
} else {
setLoaded(false);
}
};
const onDelete = async (item?: CustomField) => {
const response = await customFieldsService.deleteField(
item?.id,
item?.guid,
);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
}
};
const translatedSortColumn = useMemo(
() => ({ ...sortColumn, label: t("Name") }),
[sortColumn, t],
);
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddField"> <Permission privilegeKey="AddField">
<div> <div>
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<CustomFieldsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete} /> <CustomFieldsTable
data={pagedData}
sortColumn={translatedSortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
}
}; };
export default CustomFields; export default CustomFields;

View File

@ -1,97 +1,130 @@
import React, { Component } from 'react'; import React, { useEffect, useState } from "react";
import Column from '../../../components/common/columns'; import { useTranslation } from "react-i18next";
import { Paginated } from '../../../services/Paginated'; import Column from "../../../components/common/columns";
import DomainsTable from './components/domainsTable'; import { Paginated } from "../../../services/Paginated";
import domainsService, { GetDomain } from './serrvices/domainsService'; import DomainsTable from "./components/domainsTable";
import Button, { ButtonType } from '../../../components/common/Button'; import domainsService, { GetDomain } from "./serrvices/domainsService";
import Loading from '../../../components/common/Loading'; import Button, { ButtonType } from "../../../components/common/Button";
import Permission from '../../../components/common/Permission'; import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface DomainsState{ const initialPagedData: Paginated<GetDomain> = {
loaded: boolean; page: 1,
pagedData : Paginated<GetDomain>,
sortColumn : Column<GetDomain>,
filters: Map<string, string>;
}
class Domains extends Component< any, any, DomainsState> {
state = {
loaded : false,
pagedData : { page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] }, data: [],
sortColumn: { key: "name", label: "Name", order: "asc" }, };
filters: new Map<string, string>()
}
componentDidMount = async () => { const Domains: React.FC = () => {
const { page, pageSize } = this.state.pagedData; const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] =
useState<Paginated<GetDomain>>(initialPagedData);
const [sortColumn, setSortColumn] = useState<Column<GetDomain>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
() => new Map<string, string>(),
);
await this.changePage(page, pageSize); useEffect(() => {
} const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
};
changePage = async(page: number, pageSize : number) =>{ void loadInitial();
const { sortColumn, filters } = this.state; }, []);
const pagedData = await domainsService.getDomains(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const changePage = async (page: number, pageSize: number) => {
if (pagedData) { const pagedDataResult = await domainsService.getDomains(
this.setState({ loaded: true, pagedData }); page,
} pageSize,
else { sortColumn.key,
this.setState({ loaded: false }); sortColumn.order === "asc",
} filters,
} );
if (pagedDataResult) {
onSort = async(sortColumn : Column<GetDomain>) => { setLoaded(true);
const {page, pageSize } = this.state.pagedData; setPagedData(pagedDataResult);
const { filters } = this.state; } else {
const pagedData = await domainsService.getDomains(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); setLoaded(false);
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 domainsService.getDomains(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
onDelete = async ( keyValue? : GetDomain) => { const onSort = async (nextSortColumn: Column<GetDomain>) => {
const response = await domainsService.deleteDomain( keyValue?.id, keyValue?.guid); const { page, pageSize } = pagedData;
if (response) { const pagedDataResult = await domainsService.getDomains(
this.componentDidMount(); page,
} pageSize,
nextSortColumn.key,
nextSortColumn.order === "asc",
filters,
);
if (pagedDataResult) {
setLoaded(true);
setPagedData(pagedDataResult);
setSortColumn(nextSortColumn);
} else {
setLoaded(false);
} }
};
render(): JSX.Element { const onSearch = async (name: string, value: string) => {
const { loaded, pagedData, sortColumn } = this.state; const { page, pageSize } = pagedData;
const nextFilters = new Map(filters);
nextFilters.set(name, value);
const pagedDataResult = await domainsService.getDomains(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
nextFilters,
);
if (pagedDataResult) {
setLoaded(true);
setFilters(nextFilters);
setPagedData(pagedDataResult);
} else {
setLoaded(false);
}
};
const onDelete = async (keyValue?: GetDomain) => {
const response = await domainsService.deleteDomain(
keyValue?.id,
keyValue?.guid,
);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
}
};
const translatedSortColumn = { ...sortColumn, label: t("Name") };
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddDomain"> <Permission privilegeKey="AddDomain">
<div> <div>
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<DomainsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> <DomainsTable
data={pagedData}
sortColumn={translatedSortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
}
}; };
export default Domains; export default Domains;

View File

@ -1,4 +1,5 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next";
import HorizontalTabs from "../../../components/common/HorizionalTabs"; import HorizontalTabs from "../../../components/common/HorizionalTabs";
import Tab from "../../../components/common/Tab"; import Tab from "../../../components/common/Tab";
import authentication from "../../frame/services/authenticationService"; import authentication from "../../frame/services/authenticationService";
@ -10,51 +11,44 @@ interface DomainsDetailsProps {
editMode: boolean; editMode: boolean;
} }
class DomainsDetails extends React.Component<DomainsDetailsProps> { const DomainsDetails: React.FC<DomainsDetailsProps> = ({ editMode }) => {
isEditMode = () => { const { t } = useTranslation();
const { editMode } = this.props;
return editMode;
};
render() { const canViewMailTemplates = authentication.hasAccess("ViewDomain");
const isEditMode = this.isEditMode(); const canViewSecurityRoles = authentication.hasAccess("ViewRole");
const canViewMailTemplates = authentication.hasAccess("ViewDomain")
const canViewSecurityRoles = authentication.hasAccess("ViewRole")
let mode = "Add"; const heading = editMode ? t("EditDomain") : t("AddDomain");
if (isEditMode) mode = "Edit";
const tabs: JSX.Element[] = [];
let tabs : JSX.Element[] = []; tabs.push(
<Tab key={1} label={t("General")}>
<GeneralTab isEditMode={editMode} />
</Tab>,
);
tabs.push( <Tab key={1} label="General"> if (editMode) {
<GeneralTab isEditMode={isEditMode}/>
</Tab> );
if (isEditMode) {
if (canViewMailTemplates) { if (canViewMailTemplates) {
tabs.push(<Tab key={2} label="Mail Templates"> tabs.push(
<Tab key={2} label={t("MailTemplates")}>
<MailTemplatesTab /> <MailTemplatesTab />
</Tab> </Tab>,
); );
} }
if (canViewSecurityRoles) { if (canViewSecurityRoles) {
tabs.push(<Tab key={3} label="Security Roles"> tabs.push(
<Tab key={3} label={t("SecurityRoles")}>
<SecurityRolesTab /> <SecurityRolesTab />
</Tab> </Tab>,
); );
} }
} }
return ( return (
<div> <div>
<h1>{mode} Domain</h1> <h1>{heading}</h1>
<HorizontalTabs> <HorizontalTabs>{tabs}</HorizontalTabs>
{tabs}
</HorizontalTabs>
</div> </div>
); );
} };
}
export default DomainsDetails; export default DomainsDetails;

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect, useState } from "react";
import withRouter, { RouterProps } from "../../../../utils/withRouter"; import withRouter, { RouterProps } from "../../../../utils/withRouter";
import mailTemplatesService from "../serrvices/mailTemplatesService"; import mailTemplatesService from "../serrvices/mailTemplatesService";
import HOCEmailTemplateEditor from "./EmailTemplateEditor"; import HOCEmailTemplateEditor from "./EmailTemplateEditor";
@ -9,55 +9,47 @@ interface MailType{
description: string; description: string;
} }
interface MailTemplatesTabState{ interface MailTemplatesTabProps extends RouterProps {}
loaded : boolean;
currentMailType : string;
types : MailType[]
}
interface MailTemplatesTabProps extends RouterProps{ const MailTemplatesTabNoRouter: React.FC<MailTemplatesTabProps> = ({
router,
}) => {
const [loaded, setLoaded] = useState(false);
const [currentMailType, setCurrentMailType] = useState("");
const [types, setTypes] = useState<MailType[]>([]);
} useEffect(() => {
const loadTypes = async () => {
const response = await mailTemplatesService.getTypes(0, 10, "", true);
if (response) {
const nextTypes = response.data as MailType[];
setTypes(nextTypes);
class MailTemplatesTabNoRouter extends React.Component<MailTemplatesTabProps, MailTemplatesTabState> { if (nextTypes.length > 0) {
state : MailTemplatesTabState = { setLoaded(true);
loaded : false, setCurrentMailType(nextTypes[0].mailType);
currentMailType : "",
types: []
}
async componentDidMount() {
const types = await mailTemplatesService.getTypes(0,10,"",true);
if (types) {
this.setState({ types: types.data as MailType[] });
if ((types.data as MailType[])?.length > 0) {
this.SelectTemplate((types.data as MailType[])[0].mailType);
} }
} }
}
onClick = (e: React.MouseEvent<HTMLElement>) => {
const { target } = e;
const value = (target as HTMLElement).getAttribute("value");
this.SelectTemplate(value!);
}; };
SelectTemplate = ( emailType : string) => { void loadTypes();
const { currentMailType } = this.state; }, []);
if (currentMailType !== emailType) const selectTemplate = (emailType: string) => {
{ if (currentMailType !== emailType) {
console.log("Selecting", emailType); setLoaded(true);
this.setState({ loaded: true, currentMailType : emailType}); setCurrentMailType(emailType);
}
} }
};
render() { const onClick = (e: React.MouseEvent<HTMLElement>) => {
const { domainId } = this.props.router.params; const value = (e.target as HTMLElement).getAttribute("value");
const { loaded, types, currentMailType } = this.state; if (value) {
selectTemplate(value);
}
};
const { domainId } = router.params;
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
@ -65,18 +57,24 @@ class MailTemplatesTabNoRouter extends React.Component<MailTemplatesTabProps, Ma
<div> <div>
<ul className="mail-types"> <ul className="mail-types">
{types.map((x) => { {types.map((x) => {
return <li key={x.mailType} value={x.mailType} onClick={this.onClick}>{x.description}</li> return (
<li key={x.mailType} value={x.mailType} onClick={onClick}>
{x.description}
</li>
);
})} })}
</ul> </ul>
</div> </div>
<div> <div>
<HOCEmailTemplateEditor domainId={domainId} currentMailType={currentMailType} /> <HOCEmailTemplateEditor
domainId={domainId}
currentMailType={currentMailType}
/>
</div> </div>
</div> </div>
</Loading> </Loading>
); );
} };
}
const MailTemplatesTab = withRouter(MailTemplatesTabNoRouter); const MailTemplatesTab = withRouter(MailTemplatesTabNoRouter);

View File

@ -1,166 +1,186 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated"; import { Paginated } from "../../../../services/Paginated";
import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef"; import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
import withRouter, { RouterProps } from "../../../../utils/withRouter"; import withRouter, { RouterProps } from "../../../../utils/withRouter";
import roleService, { GetRoleSecurityAccess, GetSecurityAccess } from "../serrvices/rolesService"; import roleService, {
GetRoleSecurityAccess,
GetSecurityAccess,
} from "../serrvices/rolesService";
import RollAccessTable from "./RollAccessTable"; import RollAccessTable from "./RollAccessTable";
import Loading from "../../../../components/common/Loading"; import Loading from "../../../../components/common/Loading";
interface RoleAccessEditorState{ const initialPagedData: Paginated<GetRoleSecurityAccess> = {
loaded: boolean, page: 1,
accessList : Paginated<GetSecurityAccess>, pageSize: 10,
accessRightsForRole : Paginated<GetRoleSecurityAccess>, count: 0,
pagedData : Paginated<GetRoleSecurityAccess>, totalPages: 1,
sortColumn : Column<GetRoleSecurityAccess>, data: [],
filters: Map<string, string>; };
}
const initialAccessList: Paginated<GetSecurityAccess> = {
page: 1,
pageSize: 10,
count: 0,
totalPages: 1,
data: [],
};
interface RoleAccessEditorProps extends RouterProps { interface RoleAccessEditorProps extends RouterProps {
role : any | undefined role: any | undefined;
} }
class RoleAccessEditorNoRouter extends React.Component<RoleAccessEditorProps, RoleAccessEditorState> { const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
state : RoleAccessEditorState = { role,
loaded : false, router,
accessList : { page: 1, }) => {
pageSize : 10, const { t } = useTranslation();
count: 0, const [loaded, setLoaded] = useState(false);
totalPages: 1, const [accessList, setAccessList] =
data: [] }, useState<Paginated<GetSecurityAccess>>(initialAccessList);
accessRightsForRole : { page: 1, const [accessRightsForRole, setAccessRightsForRole] =
pageSize : 10, useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
count: 0, const [pagedData, setPagedData] =
totalPages: 1, useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
data: [] }, const [sortColumn] = useState<Column<GetRoleSecurityAccess>>({
pagedData : { page: 1, key: "name",
pageSize : 10, label: t("Name"),
count: 0, order: "asc",
totalPages: 1, });
data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
componentDidMount = async () => { const isItemSelected = (
await this.updatePage(); securityAccess: string,
} roleAccessList: unknown[] | undefined,
): boolean => {
if (roleAccessList === undefined) return false;
async componentDidUpdate(prevProps: Readonly<RoleAccessEditorProps>, prevState: Readonly<RoleAccessEditorState>, snapshot?: any) { const filtered = roleAccessList.filter(
if (prevProps.role?.id !== this.props.role?.id) { (x) => (x as any).securityAccess === securityAccess,
await this.updatePage(); );
} return filtered.length > 0;
} };
updatePage = async() => const compileAccessRightsPagedData = (
{ masterList: GetSecurityAccess[] | undefined,
const { page, pageSize } = this.state.pagedData; roleAccessList: unknown[] | undefined,
): Paginated<GetRoleSecurityAccess> => {
await this.changePage(page, pageSize);
}
changePage = async(page: number, pageSize : number) => {
let { accessList } = this.state;
const { role } = this.props;
if (accessList?.count === 0)
{
accessList = await roleService.getAccessList(0, 10, "name", true );
this.setState({ accessList });
}
const roleAccessfilters = new Map<string, string>();
roleAccessfilters.set( "roleId", String(role?.id));
const accessRightsForRole = await roleService.getRoleAccess(0,10,"name",true, roleAccessfilters);
if (accessRightsForRole) {
const pagedData = this.complieAccessRightsPagedData(accessList?.data, accessRightsForRole?.data);
if (pagedData) {
this.setState({ loaded: true, accessRightsForRole, pagedData });
}
}
else {
this.setState({ loaded: false });
}
}
IsItemSelected = (securityAccess: string, roleAccess: unknown[] | undefined) : boolean => {
if (roleAccess === undefined)
return false;
const filtered = roleAccess?.filter( (x) => (x as any).securityAccess === securityAccess);
return filtered!.length > 0;
}
complieAccessRightsPagedData = (masterList: GetSecurityAccess[] | undefined, roleAccess: unknown[] | undefined) : Paginated<GetRoleSecurityAccess> => {
if (masterList === undefined) { if (masterList === undefined) {
return { page: 1, return initialPagedData;
}
if (roleAccessList === undefined) {
return {
page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] } data: masterList as GetRoleSecurityAccess[],
};
} }
if (roleAccess === undefined) { const accessRightsForRoleData = masterList.map((value) => {
return { page: 1, const item: any = value;
item.selected = isItemSelected(item.securityAccess, roleAccessList);
return item;
});
return {
page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: (masterList as GetRoleSecurityAccess[]) } data: accessRightsForRoleData,
};
};
const changePage = async (nextAccessList?: Paginated<GetSecurityAccess>) => {
const list = nextAccessList || accessList;
const roleAccessFilters = new Map<string, string>();
roleAccessFilters.set("roleId", String(role?.id));
const accessRightsResponse = await roleService.getRoleAccess(
0,
10,
"name",
true,
roleAccessFilters,
);
if (accessRightsResponse) {
const nextPagedData = compileAccessRightsPagedData(
list?.data,
accessRightsResponse?.data,
);
if (nextPagedData) {
setLoaded(true);
setAccessRightsForRole(accessRightsResponse);
setPagedData(nextPagedData);
} }
} else {
const accessrightsForRole : Paginated<GetRoleSecurityAccess> = { page: 1, setLoaded(false);
pageSize : 10,
count: 0,
totalPages: 1,
data: []
} }
};
accessrightsForRole.data = masterList.map( value => { const updatePage = async (nextAccessList?: Paginated<GetSecurityAccess>) => {
let item : any = value if (nextAccessList && nextAccessList.count === 0) {
item.selected = this.IsItemSelected(item.securityAccess, roleAccess); const list = await roleService.getAccessList(0, 10, "name", true);
return item setAccessList(list);
}) await changePage(list);
} else {
return accessrightsForRole; await changePage(nextAccessList);
} }
};
handleSave = async ( additions : string[], deletions : string[] ) => { useEffect(() => {
const { role } = this.props; const loadInitial = async () => {
let list = accessList;
if (list.count === 0) {
list = await roleService.getAccessList(0, 10, "name", true);
setAccessList(list);
}
await updatePage(list);
};
void loadInitial();
}, [role?.id]);
const handleSave = async (additions: string[], deletions: string[]) => {
const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid); const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
let response = undefined; let response = undefined;
if (additions.length > 0)
{ if (additions.length > 0) {
response = await roleService.addRoleAccess(roleGeneralIdRef, additions); response = await roleService.addRoleAccess(roleGeneralIdRef, additions);
} }
if (deletions.length > 0) if (deletions.length > 0) {
{ response = await roleService.deleteRoleAccess(
response = await roleService.deleteRoleAccess( roleGeneralIdRef, deletions); roleGeneralIdRef,
deletions,
);
} }
if (response) { if (response) {
toast.info("Role access updated successfully.") toast.info(t("RoleAccessUpdated"));
await this.updatePage(); await updatePage(accessList);
}
} }
};
render() { const isAdministrator = role?.isAdministrator || role?.isSuperUser;
const { loaded, pagedData } = this.state;
const { role } = this.props;
const isAdministrator = role.isAdministrator || role.isSuperUser;
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<RollAccessTable role={role.id} isAdministrator={isAdministrator} data={pagedData} onSave={this.handleSave}/> <RollAccessTable
role={role?.id}
isAdministrator={isAdministrator}
data={pagedData}
onSave={handleSave}
/>
</Loading> </Loading>
); );
} };
}
const RoleAccessEditor = withRouter(RoleAccessEditorNoRouter); const RoleAccessEditor = withRouter(RoleAccessEditorNoRouter);
export default RoleAccessEditor; export default RoleAccessEditor;

View File

@ -1,4 +1,5 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated"; import { Paginated } from "../../../../services/Paginated";
import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef"; import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
@ -9,12 +10,13 @@ import Button, { ButtonType } from "../../../../components/common/Button";
import Loading from "../../../../components/common/Loading"; import Loading from "../../../../components/common/Loading";
import Permission from "../../../../components/common/Permission"; import Permission from "../../../../components/common/Permission";
interface RolesEditorState{ const initialPagedData: Paginated<GetRoleResponse> = {
loaded : boolean, page: 1,
pagedData : Paginated<GetRoleResponse>, pageSize: 10,
sortColumn : Column<GetRoleResponse>, count: 0,
filters: Map<string, string>; totalPages: 1,
} data: [],
};
interface RolesEditorProps extends RouterProps { interface RolesEditorProps extends RouterProps {
selectedRole?: GetRoleResponse; selectedRole?: GetRoleResponse;
@ -22,119 +24,146 @@ interface RolesEditorProps extends RouterProps{
onUnselectRole?: () => void; onUnselectRole?: () => void;
} }
class RolesEditorTabNoRouter extends React.Component<RolesEditorProps, RolesEditorState> { const RolesEditorTabNoRouter: React.FC<RolesEditorProps> = ({
state : RolesEditorState = { selectedRole,
loaded : false, onSelectRole,
pagedData : { page: 1, onUnselectRole,
pageSize : 10, router,
count: 0, }) => {
totalPages: 1, const { t } = useTranslation();
data: [] }, const [loaded, setLoaded] = useState(false);
sortColumn: { key: "name", label: "Name", order: "asc" }, const [pagedData, setPagedData] =
filters: new Map<string, string>() useState<Paginated<GetRoleResponse>>(initialPagedData);
} const [sortColumn, setSortColumn] = useState<Column<GetRoleResponse>>({
key: "name",
componentDidMount = async () => { label: t("Name"),
const { page, pageSize } = this.state.pagedData; order: "asc",
});
await this.changePage(page, pageSize); const [filters, setFilters] = useState<Map<string, string>>(
} () => new Map<string, string>(),
);
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
const { domainId } = this.props.router.params;
const { domainId } = router.params;
const domainGeneralIdRef = MakeGeneralIdRef(domainId); const domainGeneralIdRef = MakeGeneralIdRef(domainId);
const pagedData = await roleService.getRoles(page, pageSize, sortColumn.key, sortColumn.order === "asc", domainGeneralIdRef, filters); useEffect(() => {
if (pagedData) { const loadInitial = async () => {
this.setState({ loaded: true, pagedData }); await changePage(initialPagedData.page, initialPagedData.pageSize);
} };
else {
this.setState({ loaded: false });
}
}
onSort = async(sortColumn : Column<GetRoleResponse>) => { void loadInitial();
const {page, pageSize } = this.state.pagedData; }, [domainId]);
const { filters } = this.state;
const { domainId } = this.props.router.params;
const domainGeneralIdRef = MakeGeneralIdRef( domainId); const changePage = async (page: number, pageSize: number) => {
const pagedData = await roleService.getRoles(page, pageSize, sortColumn.key, sortColumn.order === "asc", domainGeneralIdRef, filters); const pagedDataResult = await roleService.getRoles(
if (pagedData) { page,
this.setState({ loaded: true, pagedData, sortColumn }); pageSize,
} sortColumn.key,
else { sortColumn.order === "asc",
this.setState({ loaded: false }); domainGeneralIdRef,
} filters,
} );
if (pagedDataResult) {
onSearch = async ( name: string, value: string) => { setLoaded(true);
const {page, pageSize } = this.state.pagedData; setPagedData(pagedDataResult);
const {sortColumn, filters } = this.state; } else {
const { domainId } = this.props.router.params; setLoaded(false);
const domainGeneralIdRef = MakeGeneralIdRef( domainId);
filters.set(name, value);
const pagedData = await roleService.getRoles(page, pageSize, sortColumn.key, sortColumn.order === "asc", domainGeneralIdRef, filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
canEdit = ( keyValue : any) => { const onSort = async (nextSortColumn: Column<GetRoleResponse>) => {
return keyValue.canDelete; const { page, pageSize } = pagedData;
}
canDelete = ( keyValue : any) => { const pagedDataResult = await roleService.getRoles(
return keyValue.canDelete; page,
pageSize,
nextSortColumn.key,
nextSortColumn.order === "asc",
domainGeneralIdRef,
filters,
);
if (pagedDataResult) {
setLoaded(true);
setPagedData(pagedDataResult);
setSortColumn(nextSortColumn);
} else {
setLoaded(false);
} }
};
onDelete = async ( keyValue? : GetRoleResponse) => { const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const nextFilters = new Map(filters);
nextFilters.set(name, value);
const pagedDataResult = await roleService.getRoles(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
domainGeneralIdRef,
nextFilters,
);
if (pagedDataResult) {
setLoaded(true);
setFilters(nextFilters);
setPagedData(pagedDataResult);
} else {
setLoaded(false);
}
};
const canEdit = (keyValue: any) => {
return keyValue.canDelete;
};
const canDelete = (keyValue: any) => {
return keyValue.canDelete;
};
const onDelete = async (keyValue?: GetRoleResponse) => {
const response = await roleService.deleteRole(keyValue!.id, keyValue!.guid); const response = await roleService.deleteRole(keyValue!.id, keyValue!.guid);
if (response) { if (response) {
this.componentDidMount(); await changePage(pagedData.page, pagedData.pageSize);
}
} }
};
onSelectRow = ( id : GetRoleResponse ) => const onSelectRow = (id: GetRoleResponse) => {
{
const { onSelectRole } = this.props;
if (onSelectRole !== undefined) { if (onSelectRole !== undefined) {
onSelectRole(id); onSelectRole(id);
} }
} };
onUnselectRole = () => { const translatedSortColumn = { ...sortColumn, label: t("Name") };
const { onUnselectRole } = this.props;
if (onUnselectRole !== undefined) {
onUnselectRole();
}
}
render() {
const { loaded, pagedData, sortColumn } = this.state;
const { selectedRole, onUnselectRole } = this.props;
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddRole"> <Permission privilegeKey="AddRole">
<Button id="btnAddRoleToDomain" buttonType={ButtonType.primary} to="addRole">Add</Button> <Button
id="btnAddRoleToDomain"
buttonType={ButtonType.primary}
to="addRole"
>
{t("Add")}
</Button>
</Permission> </Permission>
<hr /> <hr />
<RolesTable data={pagedData} sortColumn={sortColumn} selectedRow={selectedRole} onChangePage={this.changePage} onUnselectRow={onUnselectRole} onSort={this.onSort} onSearch={this.onSearch} onSelectRow={this.onSelectRow} canEdit={this.canEdit}canDelete={this.canDelete} onDelete={this.onDelete}/> <RolesTable
data={pagedData}
sortColumn={translatedSortColumn}
selectedRow={selectedRole}
onChangePage={changePage}
onUnselectRow={onUnselectRole}
onSort={onSort}
onSearch={onSearch}
onSelectRow={onSelectRow}
canEdit={canEdit}
canDelete={canDelete}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
} };
}
const RolesEditor = withRouter(RolesEditorTabNoRouter); const RolesEditor = withRouter(RolesEditorTabNoRouter);

View File

@ -1,35 +1,71 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { GetRoleResponse } from "../serrvices/rolesService"; import { GetRoleResponse } from "../serrvices/rolesService";
class RolesTable extends React.Component<PublishedTableProps<GetRoleResponse>> { const RolesTable: React.FC<PublishedTableProps<GetRoleResponse>> = (props) => {
columns : Column<GetRoleResponse>[] = [ const { t } = useTranslation();
{ key: "name", label: "Name", order: "asc" }
const columns: Column<GetRoleResponse>[] = [
{ key: "name", label: t("Name"), order: "asc" },
]; ];
raiseSort = (sortColumn : Column<GetRoleResponse>) => { const raiseSort = (sortColumn: Column<GetRoleResponse>) => {
this.setState({sortColumn}); if (props.onSort !== undefined) props.onSort(sortColumn);
if ( this.props.onSort !== undefined) };
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Domain.Role", entityName: "e_suite.Database.Core.Tables.Domain.Role",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: '{"Id":' + item.id + "}",
} };
} };
render() { const {
const { data, sortColumn, selectedRow, onChangePage, onSearch, onSelectRow, canEdit, canDelete, onDelete, onUnselectRow } = this.props; data,
const editPath = authentication.hasAccess("EditRole") ? "editRole/{0}" : undefined; sortColumn,
const doDelete = authentication.hasAccess("DeleteRole") ? onDelete : undefined; selectedRow,
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; onChangePage,
onSearch,
onSelectRow,
canEdit,
canDelete,
onDelete,
onUnselectRow,
} = props;
const editPath = authentication.hasAccess("EditRole")
? "editRole/{0}"
: undefined;
const doDelete = authentication.hasAccess("DeleteRole")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} editPath={editPath} selectedRow={selectedRow} onSort={this.raiseSort} onChangePage={onChangePage} onSearch={onSearch} onSelectRow={onSelectRow} onUnselectRow={onUnselectRow} canEdit={canEdit} canDelete={canDelete} onDelete={doDelete} onAuditParams={showAudit}/>; return (
} <Table
} data={data}
keyName="id"
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
selectedRow={selectedRow}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onSelectRow={onSelectRow}
onUnselectRow={onUnselectRow}
canEdit={canEdit}
canDelete={canDelete}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default RolesTable; export default RolesTable;

View File

@ -1,6 +1,9 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import Table, { PublishedTableProps } from "../../../../components/common/Table"; import Table, {
PublishedTableProps,
} from "../../../../components/common/Table";
import Button, { ButtonType } from "../../../../components/common/Button"; import Button, { ButtonType } from "../../../../components/common/Button";
import { GetSecurityAccess } from "../serrvices/rolesService"; import { GetSecurityAccess } from "../serrvices/rolesService";
import authentication from "../../../frame/services/authenticationService"; import authentication from "../../../frame/services/authenticationService";
@ -11,140 +14,137 @@ interface RollAccessTableProps extends PublishedTableProps<GetSecurityAccess>{
onSave: (additions: string[], deletions: string[]) => void; onSave: (additions: string[], deletions: string[]) => void;
} }
interface RollAccessTableState{ const RollAccessTable: React.FC<RollAccessTableProps> = ({
deltaAdditions : string[]; role,
deltaDeletions : string[]; isAdministrator,
onSave,
onSort,
data,
}) => {
const { t } = useTranslation();
const [deltaAdditions, setDeltaAdditions] = useState<string[]>([]);
const [deltaDeletions, setDeltaDeletions] = useState<string[]>([]);
useEffect(() => {
setDeltaAdditions([]);
setDeltaDeletions([]);
}, [role]);
const itemIsSelected = (item: any): boolean => {
if (isAdministrator) return true;
let selected = item.selected;
if (selected === true) {
selected = !(
deltaDeletions.filter((x) => x === item.securityAccess).length > 0
);
} else {
selected =
deltaAdditions.filter((x) => x === item.securityAccess).length > 0;
} }
class RollAccessTable extends React.Component<RollAccessTableProps, RollAccessTableState> { return selected;
state : RollAccessTableState = {
deltaAdditions : [],
deltaDeletions : []
}; };
ResetState = () => { const checkboxChange = (e: any) => {
this.setState( {
deltaAdditions : [],
deltaDeletions : []
} );
}
componentDidMount = async () => {
this.ResetState();
}
componentDidUpdate(prevProps: Readonly<RollAccessTableProps>, prevState: Readonly<RollAccessTableState>, snapshot?: any): void {
if (prevProps.role !== this.props.role) {
this.ResetState();
}
}
checkboxChange = (e : any) => {
const accessKey = e.target.id; const accessKey = e.target.id;
const newSelectedState = e.target.checked; const newSelectedState = e.target.checked;
let { deltaAdditions, deltaDeletions } = this.state;
const { data } = this.props; const filteredData = data.data?.filter(
const filteredData = data.data?.filter( (x: any) => x.securityAccess === accessKey ); (x: any) => x.securityAccess === accessKey,
);
if (filteredData?.length === 1) if (filteredData?.length === 1) {
{
const item: any = filteredData[0]; const item: any = filteredData[0];
const oldSelectedState = item.selected; const oldSelectedState = item.selected;
if (oldSelectedState === true) { if (oldSelectedState === true) {
if (newSelectedState === true) { if (newSelectedState === true) {
deltaDeletions = deltaDeletions.filter( x => x !== accessKey); setDeltaDeletions(deltaDeletions.filter((x) => x !== accessKey));
} else {
setDeltaDeletions([...deltaDeletions, accessKey]);
} }
else { } else {
deltaDeletions.push(accessKey);
}
}
else {
if (newSelectedState === true) { if (newSelectedState === true) {
deltaAdditions.push(accessKey); setDeltaAdditions([...deltaAdditions, accessKey]);
} } else {
else { setDeltaAdditions(deltaAdditions.filter((x) => x !== accessKey));
deltaAdditions = deltaAdditions.filter( x => x !== accessKey);
} }
} }
} }
};
this.setState( { deltaAdditions, deltaDeletions }) const columns: Column<GetSecurityAccess>[] = [
} {
key: "selected",
itemIsSelected = (item : any) => { label: t("Allowed"),
const { deltaAdditions, deltaDeletions } = this.state; order: "asc",
const { isAdministrator } = this.props; content: (item: any) => {
if (isAdministrator) return (
return true; <>
<input
let selected = item.selected; id={item.securityAccess}
type="checkbox"
if (selected === true) { checked={itemIsSelected(item)}
selected = !(deltaDeletions.filter( x => x === item.securityAccess).length > 0); onChange={checkboxChange}
} />
else { </>
selected = (deltaAdditions.filter( x => x === item.securityAccess).length > 0); );
} },
},
return selected; { key: "name", label: t("Name"), order: "asc" },
} { key: "groupName", label: t("Group"), order: "asc" },
{ key: "description", label: t("Description"), order: "asc" },
columns : Column<GetSecurityAccess>[] = [
{ key: "selected", label: "Allowed", order: "asc", content:(item : any) => {
return <><input id={item.securityAccess} type="checkbox" checked={this.itemIsSelected(item)} onChange={this.checkboxChange}/></> } }, //todo refactor this to use the normal forms code?
{ key: "name", label: "Name", order: "asc" },
{ key: "groupName", label: "Group", order: "asc" },
{ key: "description", label: "Description", order: "asc" }
]; ];
raiseSort = (sortColumn : Column<GetSecurityAccess>) => { const raiseSort = (sortColumn: Column<GetSecurityAccess>) => {
if ( this.props.onSort !== undefined) if (onSort !== undefined) onSort(sortColumn);
this.props.onSort(sortColumn); };
}
handleAuditParams = (item: any) => { const handleClickCancel = () => {
return { setDeltaAdditions([]);
entityName : "e_suite.Database.Core.Tables.Domain.UserRole", setDeltaDeletions([]);
primaryKey : "{\"Id\":"+item.id+"}" };
}
}
HandleClickCancel = () => {
this.setState( { deltaAdditions : [], deltaDeletions : [] })
}
HandleClickSave = () => {
const { onSave } = this.props;
const { deltaAdditions, deltaDeletions } = this.state;
const handleClickSave = () => {
onSave(deltaAdditions, deltaDeletions); onSave(deltaAdditions, deltaDeletions);
setDeltaAdditions([]);
setDeltaDeletions([]);
};
this.setState( { deltaAdditions : [], deltaDeletions : [] })
}
render() {
const { deltaAdditions, deltaDeletions } = this.state;
const { data, isAdministrator } = this.props;
const canEditRoleAccess = authentication.hasAccess("EditRoleAccess"); const canEditRoleAccess = authentication.hasAccess("EditRoleAccess");
const canChangeRoleAccess = isAdministrator || canEditRoleAccess; const canChangeRoleAccess = isAdministrator || canEditRoleAccess;
const hasChanges = !(deltaAdditions.length + deltaDeletions.length === 0); const hasChanges = !(deltaAdditions.length + deltaDeletions.length === 0);
return <> return (
<Table data={ data } keyName="securityAccess" columns={this.columns} /> <>
{canChangeRoleAccess && <> <Table
<Button disabled={!hasChanges} buttonType={ButtonType.secondary} onClick={this.HandleClickCancel}> data={data}
Cancel keyName="securityAccess"
columns={columns}
onSort={raiseSort}
/>
{canChangeRoleAccess && (
<>
<Button
disabled={!hasChanges}
buttonType={ButtonType.secondary}
onClick={handleClickCancel}
>
{t("Cancel")}
</Button> </Button>
<Button disabled={!hasChanges} buttonType={ButtonType.primary} onClick={this.HandleClickSave}> <Button
Save disabled={!hasChanges}
buttonType={ButtonType.primary}
onClick={handleClickSave}
>
{t("Save")}
</Button> </Button>
</>} </>
</>; )}
} </>
} );
};
export default RollAccessTable; export default RollAccessTable;

View File

@ -1,4 +1,5 @@
import React from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import HorizontalTabs from "../../../../components/common/HorizionalTabs"; import HorizontalTabs from "../../../../components/common/HorizionalTabs";
import Tab from "../../../../components/common/Tab"; import Tab from "../../../../components/common/Tab";
import withRouter, { RouterProps } from "../../../../utils/withRouter"; import withRouter, { RouterProps } from "../../../../utils/withRouter";
@ -8,65 +9,60 @@ import UserRoleEditor from "./UserRoleEditor";
import { GetRoleResponse } from "../serrvices/rolesService"; import { GetRoleResponse } from "../serrvices/rolesService";
import authentication from "../../../frame/services/authenticationService"; import authentication from "../../../frame/services/authenticationService";
interface SecurityRolesTabState{ interface SecurityRolesTabProps extends RouterProps {}
selectedRole? : GetRoleResponse
}
interface SecurityRolesTabProps extends RouterProps{ const SecurityRolesTabNoRouter: React.FC<SecurityRolesTabProps> = () => {
const { t } = useTranslation();
const [selectedRole, setSelectedRole] = useState<GetRoleResponse | undefined>(
undefined,
);
} const onSelectRow = (id: any) => {
setSelectedRole(id);
};
class SecurityRolesTabNoRouter extends React.Component<SecurityRolesTabProps, SecurityRolesTabState> { const onUnselectRow = () => {
state : SecurityRolesTabState = { setSelectedRole(undefined);
selectedRole: undefined };
}
async componentDidMount() { const canViewRoleAccess = authentication.hasAccess("ViewRoleAccess");
} const canViewRoleUsers = authentication.hasAccess("ViewRoleUsers");
onSelectRow = ( id : any ) => const tabs: JSX.Element[] = [];
{
this.setState({selectedRole:id});
}
onUnselectRow =() => {
this.setState({ selectedRole: undefined });
}
render() {
const { selectedRole } = this.state;
const canViewRoleAccess = authentication.hasAccess("ViewRoleAccess")
const canViewRoleUsers = authentication.hasAccess("ViewRoleUsers")
let tabs : JSX.Element[] = [];
if (canViewRoleAccess) { if (canViewRoleAccess) {
tabs.push(<Tab key={1} label="Role Access"> tabs.push(
<Tab key={1} label={t("RoleAccess")}>
<RoleAccessEditor role={selectedRole} /> <RoleAccessEditor role={selectedRole} />
</Tab>); </Tab>,
);
} }
if (canViewRoleUsers) { if (canViewRoleUsers) {
tabs.push(<Tab key={2} label="Users"> tabs.push(
<Tab key={2} label={t("Users")}>
<UserRoleEditor role={selectedRole} /> <UserRoleEditor role={selectedRole} />
</Tab>); </Tab>,
);
} }
return ( return (
<div className="two-column-grid-1-1"> <div className="two-column-grid-1-1">
<div> <div>
<RolesEditor selectedRole={selectedRole} onSelectRole={this.onSelectRow} onUnselectRole={this.onUnselectRow} /> <RolesEditor
selectedRole={selectedRole}
onSelectRole={onSelectRow}
onUnselectRole={onUnselectRow}
/>
</div> </div>
<div> <div>
{((selectedRole !== undefined) && (canViewRoleAccess || canViewRoleUsers)) && <HorizontalTabs> {selectedRole !== undefined &&
{tabs} (canViewRoleAccess || canViewRoleUsers) && (
</HorizontalTabs> <HorizontalTabs>{tabs}</HorizontalTabs>
} )}
</div> </div>
</div> </div>
); );
} };
}
const SecurityRolesTab = withRouter(SecurityRolesTabNoRouter); const SecurityRolesTab = withRouter(SecurityRolesTabNoRouter);

View File

@ -1,4 +1,5 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import { Paginated } from "../../../../services/Paginated"; import { Paginated } from "../../../../services/Paginated";
import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef"; import { MakeGeneralIdRef } from "../../../../utils/GeneralIdRef";
@ -9,107 +10,127 @@ import Button, { ButtonType } from "../../../../components/common/Button";
import Loading from "../../../../components/common/Loading"; import Loading from "../../../../components/common/Loading";
import Permission from "../../../../components/common/Permission"; import Permission from "../../../../components/common/Permission";
interface UserRoleEditorState{ const initialPagedData: Paginated<RoleUser> = {
loaded: boolean, page: 1,
pagedData : Paginated<RoleUser>,
sortColumn : Column<RoleUser>,
filters: Map<string, string>;
}
interface UserRoleEditorProps extends RouterProps{
role : any | undefined
}
class UserRoleEditorNoRouter extends React.Component<UserRoleEditorProps, UserRoleEditorState> {
state : UserRoleEditorState = {
loaded : false,
pagedData : { page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] }, data: [],
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
componentDidMount = async () => {
const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize);
}
async componentDidUpdate(prevProps: Readonly<UserRoleEditorProps>, prevState: Readonly<UserRoleEditorState>, snapshot?: any) {
if (prevProps.role?.id !== this.props.role?.id) {
this.componentDidMount();
}
}
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
await this.getRoleUsers(page, pageSize, sortColumn, filters);
}
onSort = async(sortColumn : Column<RoleUser>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
await this.getRoleUsers(page, pageSize, sortColumn, filters);
}
onSearch = async ( name: string, value: string) => {
const {page, pageSize } = this.state.pagedData;
const {sortColumn, filters } = this.state;
filters.set(name, value);
await this.getRoleUsers(page, pageSize, sortColumn, filters);
}; };
getRoleUsers = async ( page : number, pageSize : number, sortColumn : Column<RoleUser>, filters : Map<string, string>) => { interface UserRoleEditorProps extends RouterProps {
role: any | undefined;
}
const UserRoleEditorNoRouter: React.FC<UserRoleEditorProps> = ({
role,
router,
}) => {
const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] =
useState<Paginated<RoleUser>>(initialPagedData);
const [sortColumn, setSortColumn] = useState<Column<RoleUser>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
() => new Map<string, string>(),
);
const { role } = this.props;
const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid); const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
const pagedData = await roleService.getRoleUsers(page, pageSize, sortColumn.key, sortColumn.order === "asc", roleGeneralIdRef, filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData, sortColumn });
}
else {
this.setState({ loaded: false });
}
}
onDelete = async ( user? : RoleUser) => { const getRoleUsers = async (
const { role } = this.props; page: number,
pageSize: number,
nextSortColumn: Column<RoleUser>,
nextFilters: Map<string, string>,
) => {
const pagedDataResult = await roleService.getRoleUsers(
page,
pageSize,
nextSortColumn.key,
nextSortColumn.order === "asc",
roleGeneralIdRef,
nextFilters,
);
if (pagedDataResult) {
setLoaded(true);
setFilters(nextFilters);
setPagedData(pagedDataResult);
setSortColumn(nextSortColumn);
} else {
setLoaded(false);
}
};
const roleId = MakeGeneralIdRef(role?.id, role?.guid); useEffect(() => {
const loadInitial = async () => {
await getRoleUsers(
initialPagedData.page,
initialPagedData.pageSize,
sortColumn,
new Map<string, string>(),
);
};
void loadInitial();
}, [role?.id]);
const changePage = async (page: number, pageSize: number) => {
await getRoleUsers(page, pageSize, sortColumn, filters);
};
const onSort = async (nextSortColumn: Column<RoleUser>) => {
const { page, pageSize } = pagedData;
await getRoleUsers(page, pageSize, nextSortColumn, filters);
};
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const nextFilters = new Map(filters);
nextFilters.set(name, value);
await getRoleUsers(page, pageSize, sortColumn, nextFilters);
};
const onDelete = async (user?: RoleUser) => {
const userId = MakeGeneralIdRef(user?.id, user?.guid); const userId = MakeGeneralIdRef(user?.id, user?.guid);
const response = await roleService.deleteRoleUser(userId, roleId); const response = await roleService.deleteRoleUser(userId, roleGeneralIdRef);
if (response) { if (response) {
this.componentDidMount(); await changePage(pagedData.page, pagedData.pageSize);
}
} }
};
render() { const addLink = "editRole/" + role?.id + "/addUserToRole";
const {loaded, pagedData, sortColumn } = this.state;
const { role } = this.props;
const addLink = "editRole/" + role.id + "/addUserToRole";
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddRoleUser"> <Permission privilegeKey="AddRoleUser">
<div> <div>
<Button id="btnAddUserToRole" buttonType={ButtonType.primary} to={addLink}>Add</Button> <Button
id="btnAddUserToRole"
buttonType={ButtonType.primary}
to={addLink}
>
{t("Add")}
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<UserRolesTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> <UserRolesTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
} };
}
const UserRoleEditor = withRouter(UserRoleEditorNoRouter); const UserRoleEditor = withRouter(UserRoleEditorNoRouter);

View File

@ -1,34 +1,61 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { RoleUser } from "../serrvices/rolesService"; import { RoleUser } from "../serrvices/rolesService";
class UserRolesTable extends React.Component<PublishedTableProps<RoleUser>> { const UserRolesTable: React.FC<PublishedTableProps<RoleUser>> = (props) => {
columns : Column<RoleUser>[] = [ const { t } = useTranslation();
{ key: "displayName", label: "Name", order: "asc" }
const columns: Column<RoleUser>[] = [
{ key: "displayName", label: t("Name"), order: "asc" },
]; ];
raiseSort = (sortColumn : Column<RoleUser>) => { const raiseSort = (sortColumn: Column<RoleUser>) => {
this.setState({sortColumn}); if (props.onSort !== undefined) props.onSort(sortColumn);
if ( this.props.onSort !== undefined) };
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Domain.UserRole", entityName: "e_suite.Database.Core.Tables.Domain.UserRole",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: '{"Id":' + item.id + "}",
} };
} };
render() { const {
const { data, sortColumn, selectedRow, onChangePage, onSearch, onSelectRow, onDelete } = this.props; data,
const doDelete = authentication.hasAccess("DeleteRoleUser") ? onDelete : undefined; sortColumn,
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; selectedRow,
onChangePage,
onSearch,
onSelectRow,
onDelete,
} = props;
const doDelete = authentication.hasAccess("DeleteRoleUser")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} selectedRow={selectedRow} onSort={this.raiseSort} onChangePage={onChangePage} onSearch={onSearch} onSelectRow={onSelectRow} onDelete={doDelete} onAuditParams={showAudit}/>; return (
} <Table
} data={data}
keyName="id"
columns={columns}
sortColumn={sortColumn}
selectedRow={selectedRow}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onSelectRow={onSelectRow}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default UserRolesTable; export default UserRolesTable;

View File

@ -1,35 +1,55 @@
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { GetDomain } from "../serrvices/domainsService"; import { GetDomain } from "../serrvices/domainsService";
class DomainsTable extends React.Component<PublishedTableProps<GetDomain>> { const DomainsTable: React.FC<PublishedTableProps<GetDomain>> = (props) => {
columns : Column<GetDomain>[] = [ const { t } = useTranslation();
{ key: "name", label: "Name", order: "asc" }
const columns: Column<GetDomain>[] = [
{ key: "name", label: t("Name"), order: "asc" },
]; ];
raiseSort = (sortColumn : Column<GetDomain>) => { const raiseSort = (sortColumn: Column<GetDomain>) => {
this.setState({sortColumn}); if (props.onSort !== undefined) props.onSort(sortColumn);
if ( this.props.onSort !== undefined) };
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Domain.Domain", entityName: "e_suite.Database.Core.Tables.Domain.Domain",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: '{"Id":' + item.id + "}",
} };
} };
render() { const { data, sortColumn, onChangePage, onSearch, onDelete } = props;
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; const editPath = authentication.hasAccess("EditDomain")
const editPath = authentication.hasAccess("EditDomain") ? "edit/{0}" : undefined; ? "edit/{0}"
const doDelete = authentication.hasAccess("DeleteDomain") ? onDelete : undefined; : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; const doDelete = authentication.hasAccess("DeleteDomain")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} editPath={editPath} onSort={this.raiseSort} onChangePage={onChangePage} onSearch={onSearch} onDelete={doDelete} onAuditParams={showAudit}/>; return (
} <Table
} data={data}
keyName="id"
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default DomainsTable; export default DomainsTable;

View File

@ -1,97 +1,120 @@
import { Component } from 'react'; import { useState, useEffect } from "react";
import Button, { ButtonType } from '../../../components/common/Button'; import { useTranslation } from "react-i18next";
import Column from '../../../components/common/columns'; import Button, { ButtonType } from "../../../components/common/Button";
import Permission from '../../../components/common/Permission'; import Column from "../../../components/common/columns";
import { Paginated } from '../../../services/Paginated'; import Permission from "../../../components/common/Permission";
import FormsTable from './components/formsTable'; import { Paginated } from "../../../services/Paginated";
import formsService, { GetFormResponse } from './services/formsService'; import FormsTable from "./components/formsTable";
import Loading from '../../../components/common/Loading'; import formsService, { GetFormResponse } from "./services/formsService";
import Loading from "../../../components/common/Loading";
interface FormsState{ const Forms: React.FC = () => {
loaded: boolean; const { t } = useTranslation();
pagedData : Paginated<GetFormResponse>,
sortColumn : Column<GetFormResponse>,
filters: Map<string, string>;
}
class Forms extends Component< any, any, FormsState> { const [loaded, setLoaded] = useState(false);
state = { const [pagedData, setPagedData] = useState<Paginated<GetFormResponse>>({
loaded: false, page: 1,
pagedData : { page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] }, data: [],
sortColumn: { key: "name", label: "Name", order: "asc" }, });
filters: new Map<string, string>() const [sortColumn, setSortColumn] = useState<Column<GetFormResponse>>({
} key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
componentDidMount = async () => { const changePage = async (page: number, pageSize: number) => {
const { page, pageSize } = this.state.pagedData; const data = await formsService.getForms(
page,
await this.changePage(page, pageSize); pageSize,
} sortColumn.key,
sortColumn.order === "asc",
changePage = async(page: number, pageSize : number) =>{ filters,
const { sortColumn, filters } = this.state; );
if (data) {
const pagedData = await formsService.getForms(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); setLoaded(true);
if (pagedData) { setPagedData(data);
this.setState({ loaded: true, pagedData }); } else {
} setLoaded(false);
else {
this.setState({ loaded: false });
}
}
onSort = async(sortColumn : Column<GetFormResponse>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await formsService.getForms(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 formsService.getForms(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
onDelete = async ( item? : GetFormResponse) => { const onSort = async (newSortColumn: Column<GetFormResponse>) => {
const { page, pageSize } = pagedData;
const data = await formsService.getForms(
page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
}
};
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
const data = await formsService.getForms(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
}
};
const onDelete = async (item?: GetFormResponse) => {
const response = await formsService.deleteForm(item?.id, item?.guid); const response = await formsService.deleteForm(item?.id, item?.guid);
if (response) { if (response) {
this.componentDidMount(); await changePage(pagedData.page, pagedData.pageSize);
}
} }
};
render(): JSX.Element { useEffect(() => {
const { loaded, pagedData, sortColumn } = this.state; const { page, pageSize } = pagedData;
changePage(page, pageSize);
}, [pagedData]);
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddFormTemplate"> <Permission privilegeKey="AddFormTemplate">
<div> <div>
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<FormsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> <FormsTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
} };
}
export default Forms; export default Forms;

View File

@ -1,36 +1,67 @@
import React from "react"; import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { GetFormResponse } from "../services/formsService"; import { GetFormResponse } from "../services/formsService";
class FormsTable extends React.Component<PublishedTableProps<GetFormResponse>> { const FormsTable: React.FC<PublishedTableProps<GetFormResponse>> = ({
columns : Column<GetFormResponse>[] = [ data,
{ key: "name", label: "Name", order: "asc" }, sortColumn,
{ key: "version", label: "Version", order: "asc" } onChangePage,
]; onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
raiseSort = (sortColumn : Column<GetFormResponse>) => { const columns: Column<GetFormResponse>[] = useMemo(
this.setState({sortColumn}); () => [
if ( this.props.onSort !== undefined) { key: "name", label: t("Name"), order: "asc" },
this.props.onSort(sortColumn); { key: "version", label: t("Version"), order: "asc" },
} ],
[t],
);
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Forms.FormTemplate", entityName: "e_suite.Database.Core.Tables.Forms.FormTemplate",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: `{"Id":${item.id}}`,
} };
} };
render() { const raiseSort = (sortCol: Column<GetFormResponse>) => {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; if (onSort !== undefined) {
const editPath = authentication.hasAccess("EditFormTemplate") ? "edit/{0}" : undefined; onSort(sortCol);
const doDelete = authentication.hasAccess("DeleteFormTemplate") ? onDelete : undefined; }
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; };
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} editPath={editPath} onSort={this.raiseSort} onChangePage={onChangePage} onSearch={onSearch} onDelete={doDelete} onAuditParams={showAudit}/>; const editPath = authentication.hasAccess("EditFormTemplate")
} ? "edit/{0}"
} : undefined;
const doDelete = authentication.hasAccess("DeleteFormTemplate")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return (
<Table
data={data}
keyName="id"
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default FormsTable; export default FormsTable;

View File

@ -1,168 +1,164 @@
import React, { Component } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { MakeGeneralIdRef } from "../../../utils/GeneralIdRef"; import { MakeGeneralIdRef } from "../../../utils/GeneralIdRef";
import withRouter from "../../../utils/withRouter"; import withRouter from "../../../utils/withRouter";
import GlossariesTable from "./components/GlossariesTable"; import GlossariesTable from "./components/GlossariesTable";
import glossariesService, { Glossary, SystemGlossaries } from "./services/glossaryService"; import glossariesService, {
Glossary,
SystemGlossaries,
} from "./services/glossaryService";
import { GeneralIdRef } from "./../../../utils/GeneralIdRef"; import { GeneralIdRef } from "./../../../utils/GeneralIdRef";
import equal from "fast-deep-equal";
import Button, { ButtonType } from "../../../components/common/Button"; import Button, { ButtonType } from "../../../components/common/Button";
import Loading from "../../../components/common/Loading"; import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission"; import Permission from "../../../components/common/Permission";
interface GlossariesState { const Glossaries: React.FC<any> = (props) => {
loaded: boolean; const { t } = useTranslation();
data: Glossary | undefined; const glossaryId = props?.router?.params?.glossaryId;
// sortColumn : Column,
// filters: Map<string, string>;
parentAddress: string;
}
class Glossaries extends Component<any, any, GlossariesState> { const [loaded, setLoaded] = useState(false);
state: GlossariesState = { const [data, setData] = useState<Glossary | undefined>(undefined);
loaded: false, const [parentAddress, setParentAddress] = useState("");
data: undefined,
// sortColumn: { key: "name", label: "Name", order: "asc" },
// filters: new Map<string, string>()
parentAddress: "",
};
componentDidMount = () => { const loadData = useCallback(async () => {
this.loadData(); setLoaded(false);
};
componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<any>, snapshot?: GlossariesState | undefined): void {
if (!equal(this.props?.router?.params?.glossaryId, prevProps?.router?.params?.glossaryId)){
this.setState({ loaded: false });
this.loadData();
}
}
loadData = async () => {
let parentItem: GeneralIdRef = SystemGlossaries; let parentItem: GeneralIdRef = SystemGlossaries;
const { glossaryId } = this.props.router.params; if (glossaryId !== undefined) {
if (glossaryId !== undefined)
parentItem = MakeGeneralIdRef(glossaryId); parentItem = MakeGeneralIdRef(glossaryId);
const data = await glossariesService.getGlossaryItem(parentItem);
if (data) {
let parentAddress = "/glossaries";
if (data.parent?.guid?.toLowerCase() !== SystemGlossaries.guid?.toLowerCase())
parentAddress += "/" + data.parent?.id;
this.setState({ loaded: true, data, parentAddress });
} }
else {
this.setState({ loaded: false });
}
};
onDelete = async (keyValue: any) => { const result = await glossariesService.getGlossaryItem(parentItem);
if (result) {
let nextParentAddress = "/glossaries";
if (
result.parent?.guid?.toLowerCase() !==
SystemGlossaries.guid?.toLowerCase()
) {
nextParentAddress += "/" + result.parent?.id;
}
setData(result);
setParentAddress(nextParentAddress);
setLoaded(true);
} else {
setLoaded(false);
}
}, [glossaryId]);
useEffect(() => {
loadData();
}, [loadData]);
const onDelete = async (keyValue: any) => {
const response = await glossariesService.deleteGlossaryItem(keyValue.id); const response = await glossariesService.deleteGlossaryItem(keyValue.id);
if (response) { if (response) {
this.componentDidMount(); loadData();
} }
}; };
render(): JSX.Element { const createPathBlock = (): JSX.Element | undefined => {
const { loaded, data, parentAddress } = this.state; let item: Glossary | undefined = data;
const empty = <></>;
let pathBlock: JSX.Element = empty;
while (
item !== undefined &&
item.guid.toLowerCase() !== SystemGlossaries.guid &&
item.id !== BigInt(0)
) {
const divider = pathBlock === empty ? <></> : <>/</>;
pathBlock = (
<>
<Link to={concatinate(["/glossaries", item.id], "/")}>
{item.name}
</Link>
{divider}
{pathBlock}
</>
);
item = item.parent;
}
if (pathBlock === undefined) {
pathBlock = <></>;
}
pathBlock = (
<>
<Link to="/glossaries">{t("Glossaries")}</Link>/{pathBlock}
</>
);
return pathBlock;
};
const id = data?.id; const id = data?.id;
const addPath = concatinate(["/glossaries/add", id], "/");
let table = <></>; const table = (
let upButton = <></>;
let editButton = <></>;
table = (
<div> <div>
Items {t("Items")}
<GlossariesTable params={this.props.params} data={data} onDelete={this.onDelete} /> <GlossariesTable params={props.params} data={data} onDelete={onDelete} />
</div> </div>
); );
if (data?.parent) let upButton = <></>;
{ let editButton = <></>;
if (data.parent?.id !== BigInt(0) ) {
if (data?.parent) {
if (data.parent.id !== BigInt(0)) {
upButton = ( upButton = (
<Button buttonType={ButtonType.primary} to={parentAddress}>Up</Button> <Button buttonType={ButtonType.primary} to={parentAddress}>
{t("Up")}
</Button>
); );
}
if (data.parent?.id !== BigInt(0) ) {
editButton = ( editButton = (
<Button buttonType={ButtonType.primary} to={concatinate( ["/glossaries/edit", id], "/")}>Edit</Button> <Button
buttonType={ButtonType.primary}
to={concatinate(["/glossaries/edit", id], "/")}
>
{t("Edit")}
</Button>
); );
} }
} }
const addPath = concatinate( ["/glossaries/add", id], "/"); const pathBlock = createPathBlock();
let pathBlock = this.createPathBlock();
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<div> <div>
<Permission privilegeKey="ViewGlossary"> <Permission privilegeKey="ViewGlossary">{upButton}</Permission>
{upButton}
</Permission>
<Permission privilegeKey="AddGlossary"> <Permission privilegeKey="AddGlossary">
<Button buttonType={ButtonType.primary} to={addPath}>Add</Button> <Button buttonType={ButtonType.primary} to={addPath}>
</Permission> {t("Add")}
<Permission privilegeKey="EditGlossary"> </Button>
{editButton}
</Permission> </Permission>
<Permission privilegeKey="EditGlossary">{editButton}</Permission>
</div> </div>
<hr /> <hr />
{pathBlock} {pathBlock}
{table} {table}
</Loading> </Loading>
); );
} };
createPathBlock = () : JSX.Element | undefined =>
{
const { data } = this.state;
let item : Glossary | undefined = data;
const empty = <></>;
let pathBlock : JSX.Element = empty;
while (item !== undefined && (item?.guid.toLowerCase() !== SystemGlossaries.guid && item.id !== BigInt(0)) ){
let divider = pathBlock === empty ? <></> : <>/</>;
pathBlock = <><Link to={concatinate( ["/glossaries", item?.id], "/")} >{item?.name}</Link>{divider}{pathBlock}</>;
item = item?.parent;
}
if (pathBlock === undefined)
{
pathBlock = <></>;
}
pathBlock = <><Link to="/glossaries">Glossaries</Link>/{pathBlock}</>
return pathBlock;
}
}
const HOCGlossaries = withRouter(Glossaries); const HOCGlossaries = withRouter(Glossaries);
export default HOCGlossaries; export default HOCGlossaries;
function concatinate(args: (unknown | undefined)[], seperator: string): string { function concatinate(args: (unknown | undefined)[], seperator: string): string {
let result = "" let result = "";
for( const arg of args) for (const arg of args) {
{
if (arg !== undefined) { if (arg !== undefined) {
if ( result !== "") if (result !== "") result += seperator;
result += seperator;
result += arg; result += arg;
} }
} }
return result; return result;
} }

View File

@ -1,17 +1,16 @@
import React from "react"; import React, { useState, useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import Table from "../../../../components/common/Table"; import Table from "../../../../components/common/Table";
import { Paginated } from "../../../../services/Paginated";
import { Glossary } from "../services/glossaryService"; import { Glossary } from "../services/glossaryService";
import equal from 'fast-deep-equal';
import authentication from "../../../frame/services/authenticationService"; import authentication from "../../../frame/services/authenticationService";
export interface GlossaryParams { export interface GlossaryParams {
id : number id: number;
} }
interface GlossariesTableProps { interface GlossariesTableProps {
data? : Glossary, data?: Glossary;
onDelete?: (keyValue: any) => void; onDelete?: (keyValue: any) => void;
params: GlossaryParams; params: GlossaryParams;
} }
@ -21,107 +20,121 @@ interface CustomColumn extends Column<customField>{
} }
interface customField { interface customField {
[key: string]: any [key: string]: any;
} }
class GlossariesTable extends React.Component<GlossariesTableProps> { const GlossariesTable: React.FC<GlossariesTableProps> = ({
findValueById = (data: Glossary, key: string) => { data,
if (data.customFieldValues){ onDelete,
for( const value of data.customFieldValues ){ }) => {
if (String(value.id.id) === key) const { t } = useTranslation();
{
const displayValue : string = value.values[0].displayValue ?? "";
const [columnsList, setColumnsList] = useState<CustomColumn[]>([]);
const baseColumns: CustomColumn[] = useMemo(
() => [
{
key: "name",
label: t("Name"),
order: "asc",
link: "/glossaries/{0}",
isCustom: false,
},
],
[t],
);
const findValueById = (glossaryData: Glossary, key: string) => {
if (glossaryData.customFieldValues) {
for (const value of glossaryData.customFieldValues) {
if (String(value.id.id) === key) {
const displayValue: string = value.values[0].displayValue ?? "";
return displayValue; return displayValue;
} }
} }
} }
return undefined; return undefined;
};
const paginatedData = useMemo(() => {
if (!data) {
return {
count: 0,
page: 1,
pageSize: 1,
totalPages: 0,
data: [],
};
} }
state = { columnsList: ([] as CustomColumn[]) } const pagedData = data.children.map((x) => {
const dataItem: customField = {
columns : CustomColumn[] = [
{ key: "name", label: "Name", order: "asc", link:"/glossaries/{0}", isCustom: false }
];
PaginatedData = () => {
const { data } = this.props;
const { columnsList } = this.state;
const pagedData = data!.children.map( (x) => {
let dataItem : customField = {
id: x.id, id: x.id,
name : x.name } name: x.name,
};
for (const column of columnsList) { for (const column of columnsList) {
if (column.isCustom) { if (column.isCustom) {
dataItem[column.key] = this.findValueById(x, column.key); dataItem[column.key] = findValueById(x, column.key);
} }
} }
return dataItem; return dataItem;
} ) });
let paginated : Paginated<customField> = { return {
count: 1, count: 1,
page: 1, page: 1,
pageSize: 1, pageSize: 1,
totalPages: 1, totalPages: 1,
data : pagedData data: pagedData,
} };
}, [data, columnsList]);
return paginated; useEffect(() => {
} const newColumnsList = [...baseColumns];
componentDidMount = () => { if (data?.childCustomFieldDefinition) {
this.CompileColumns(); for (const customfield of data.childCustomFieldDefinition) {
} newColumnsList.push({
componentDidUpdate(prevProps: Readonly<GlossariesTableProps>, prevState: Readonly<{}>, snapshot?: any): void {
if(!equal(this.props.data, prevProps.data))
this.CompileColumns();
}
CompileColumns = () => {
const { data } = this.props;
let columnsList = [...this.columns];
if (data?.childCustomFieldDefinition)
{
for( const customfield of data?.childCustomFieldDefinition)
{
columnsList.push({
key: String(customfield.id), key: String(customfield.id),
label: customfield.name, label: customfield.name,
order: "asc", order: "asc",
isCustom: true isCustom: true,
}) });
} }
} }
this.setState({columnsList}); setColumnsList(newColumnsList);
} }, [baseColumns, data]);
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Glossaries.Glossary", entityName: "e_suite.Database.Core.Tables.Glossaries.Glossary",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: `{"Id":${item.id}}`,
} };
} };
render() { const editPath = authentication.hasAccess("EditGlossary")
const { onDelete } = this.props; ? "/glossaries/edit/{0}"
const { columnsList } = this.state; : undefined;
const editPath = authentication.hasAccess("EditGlossary") ? "/glossaries/edit/{0}" : undefined; const doDelete = authentication.hasAccess("DeleteGlossary")
const doDelete = authentication.hasAccess("DeleteGlossary") ? onDelete : undefined; ? onDelete
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
const paginated = this.PaginatedData(); return (
return <Table data={paginated} keyName="id" columns={columnsList} editPath={editPath} onDelete={doDelete} onAuditParams={showAudit}/>; <Table
} data={paginatedData}
} keyName="id"
columns={columnsList}
editPath={editPath}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default GlossariesTable; export default GlossariesTable;

View File

@ -1,97 +1,123 @@
import { Component } from 'react'; import { useEffect, useState } from "react";
import Button, { ButtonType } from '../../../components/common/Button'; import { useTranslation } from "react-i18next";
import Column from '../../../components/common/columns'; import Button, { ButtonType } from "../../../components/common/Button";
import Permission from '../../../components/common/Permission'; import Column from "../../../components/common/columns";
import { Paginated } from '../../../services/Paginated'; import Permission from "../../../components/common/Permission";
import OrganisationsTable from './components/OrganisationsTable'; import { Paginated } from "../../../services/Paginated";
import organisationsService, { ReadOrganisation } from './services/organisationsService'; import OrganisationsTable from "./components/OrganisationsTable";
import Loading from '../../../components/common/Loading'; import organisationsService, {
ReadOrganisation,
} from "./services/organisationsService";
import Loading from "../../../components/common/Loading";
interface OrganisationsState{ const Organisations: React.FC = () => {
loaded: boolean, const { t } = useTranslation();
pagedData : Paginated<ReadOrganisation>, const [loaded, setLoaded] = useState(false);
sortColumn : Column<ReadOrganisation>, const [pagedData, setPagedData] = useState<Paginated<ReadOrganisation>>({
filters: Map<string, string>; page: 1,
}
class Organisations extends Component<any, any, OrganisationsState> {
state = {
loaded : false,
pagedData : { page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] data: [],
}, });
sortColumn: { key: "name", label: "Name", order: "asc" }, const [sortColumn, setSortColumn] = useState<Column<ReadOrganisation>>({
filters: new Map<string, string>() key: "name",
} label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
componentDidMount = async () => { const changePage = async (page: number, pageSize: number) => {
const { page, pageSize } = this.state.pagedData; const data = await organisationsService.getOrganisations(
page,
await this.changePage(page, pageSize); pageSize,
} sortColumn.key,
sortColumn.order === "asc",
changePage = async (page: number, pageSize: number) => { filters,
const { sortColumn, filters } = this.state; );
if (data) {
const pagedData = await organisationsService.getOrganisations(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); setLoaded(true);
if (pagedData) { setPagedData(data);
this.setState({ loaded: true, pagedData }); } else {
} setLoaded(false);
else {
this.setState({ loaded: false });
}
}
onSort = async (sortColumn: Column<ReadOrganisation>) => {
const { page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await organisationsService.getOrganisations(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 organisationsService.getOrganisations(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState( { loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
onDelete = async (item?: ReadOrganisation) => { const onSort = async (newSortColumn: Column<ReadOrganisation>) => {
const response = await organisationsService.deleteOrganisation(item?.id, item?.guid); const { page, pageSize } = pagedData;
if (response) { const data = await organisationsService.getOrganisations(
this.componentDidMount(); page,
} pageSize,
} newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
render(): JSX.Element { if (data) {
const { loaded, pagedData, sortColumn } = this.state; setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
}
};
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
const data = await organisationsService.getOrganisations(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
}
};
const onDelete = async (item?: ReadOrganisation) => {
const response = await organisationsService.deleteOrganisation(
item?.id,
item?.guid,
);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
}
};
useEffect(() => {
const { page, pageSize } = pagedData;
changePage(page, pageSize);
});
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddOrganisation"> <Permission privilegeKey="AddOrganisation">
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</Permission> </Permission>
<hr /> <hr />
<OrganisationsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> <OrganisationsTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
}
}; };
export default Organisations; export default Organisations;

View File

@ -1,51 +1,77 @@
import React from "react"; import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { ReadOrganisation } from "../services/organisationsService"; import { ReadOrganisation } from "../services/organisationsService";
class OrganisationsTable extends React.Component<PublishedTableProps<ReadOrganisation>> { const OrganisationsTable: React.FC<PublishedTableProps<ReadOrganisation>> = ({
canViewSite = authentication.hasAccess("ViewSite"); data,
sortColumn,
onChangePage,
onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
const canViewSite = authentication.hasAccess("ViewSite");
columns: Column<ReadOrganisation>[] = [ const columns: Column<ReadOrganisation>[] = useMemo(
{ key: "name", label: "Name", order: "asc", link: this.canViewSite ? "/site/{0}" : undefined }, () => [
{ key: "address", label: "Address", order: "asc" }, {
{ key: "status", label: "Status", order: "asc", searchable: false }, key: "name",
]; label: t("Name"),
order: "asc",
link: canViewSite ? "/site/{0}" : undefined,
},
{ key: "address", label: t("Address"), order: "asc" },
{
key: "status",
label: t("Status"),
order: "asc",
searchable: false,
},
],
[t, canViewSite],
);
raiseSort = (sortColumn: Column<ReadOrganisation>) => { const raiseSort = (sortCol: Column<ReadOrganisation>) => {
this.setState({ sortColumn }); if (onSort !== undefined) onSort(sortCol);
if (this.props.onSort !== undefined) this.props.onSort(sortColumn);
}; };
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Printer.Organisation", entityName: "e_suite.Database.Core.Tables.Printer.Organisation",
primaryKey: '{"Id":' + item.id + "}", primaryKey: `{"Id":${item.id}}`,
}; };
}; };
render() { const editPath = authentication.hasAccess("EditOrganisation")
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; ? "{0}"
const editPath = authentication.hasAccess("EditOrganisation") ? "{0}" : undefined; : undefined;
const doDelete = authentication.hasAccess("DeleteOrganisation") ? onDelete : undefined; const doDelete = authentication.hasAccess("DeleteOrganisation")
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; ? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return ( return (
<Table <Table
data={data} data={data}
keyName="id" keyName="id"
columns={this.columns} columns={columns}
sortColumn={sortColumn} sortColumn={sortColumn}
editPath={editPath} editPath={editPath}
onSort={this.raiseSort} onSort={raiseSort}
onChangePage={onChangePage} onChangePage={onChangePage}
onSearch={onSearch} onSearch={onSearch}
onDelete={doDelete} onDelete={doDelete}
onAuditParams={showAudit} onAuditParams={showAudit}
/> />
); );
} };
}
export default OrganisationsTable; export default OrganisationsTable;

View File

@ -1,35 +1,62 @@
import React from "react"; import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; 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 authentication from "../../../frame/services/authenticationService";
import { ReadSequence } from "../services/sequenceService"; import { ReadSequence } from "../services/sequenceService";
class SequenceTable extends React.Component<PublishedTableProps<ReadSequence>> { const SequenceTable: React.FC<PublishedTableProps<ReadSequence>> = ({
columns : Column<ReadSequence>[] = [ data,
{ key: "name", label: "Name", order: "asc" } sortColumn,
]; onChangePage,
onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
raiseSort = (sortColumn : Column<ReadSequence>) => { const columns: Column<ReadSequence>[] = useMemo(
this.setState({sortColumn}); () => [{ key: "name", label: t("Name"), order: "asc" }],
if ( this.props.onSort !== undefined) [t],
this.props.onSort(sortColumn); );
}
handleAuditParams = (item: any) => { const raiseSort = (sortCol: Column<ReadSequence>) => {
if (onSort !== undefined) onSort(sortCol);
};
const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Sequences.Sequence", entityName: "e_suite.Database.Core.Tables.Sequences.Sequence",
primaryKey : "{\"Id\":"+item.id+"}" primaryKey: `{"Id":${item.id}}`,
} };
} };
render() { const editPath = authentication.hasAccess("EditSequence")
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; ? "edit/{0}"
const editPath = authentication.hasAccess("EditSequence") ? "edit/{0}" : undefined; : undefined;
const doDelete = authentication.hasAccess("DeleteSequence") ? onDelete : undefined; const doDelete = authentication.hasAccess("DeleteSequence")
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; ? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} editPath={editPath} onSort={this.raiseSort} onChangePage={onChangePage} onSearch={onSearch} onDelete={doDelete} onAuditParams={showAudit }/>; return (
} <Table
} data={data}
keyName="id"
columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
export default SequenceTable; export default SequenceTable;

View File

@ -1,99 +1,119 @@
import React, { Component } from 'react'; import React, { useEffect, useState } from "react";
import sequenceService, { ReadSequence } from './services/sequenceService'; import { useTranslation } from "react-i18next";
import SequenceTable from './components/squenceTable'; import sequenceService, { ReadSequence } from "./services/sequenceService";
import Column from '../../../components/common/columns'; import SequenceTable from "./components/squenceTable";
import { Paginated } from '../../../services/Paginated'; import Column from "../../../components/common/columns";
import Button, { ButtonType } from '../../../components/common/Button'; import { Paginated } from "../../../services/Paginated";
import Loading from '../../../components/common/Loading'; import Button, { ButtonType } from "../../../components/common/Button";
import Permission from '../../../components/common/Permission'; import Loading from "../../../components/common/Loading";
import Permission from "../../../components/common/Permission";
interface sequenceState { const Sequence: React.FC = () => {
loaded: boolean, const { t } = useTranslation();
pagedData: Paginated<ReadSequence>, const [loaded, setLoaded] = useState(false);
sortColumn: Column<ReadSequence>, const [pagedData, setPagedData] = useState<Paginated<ReadSequence>>({
filters: Map<string, string>;
}
class Sequence extends Component<any, any, sequenceState> {
state = {
loaded: false,
pagedData: {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
count: 0, count: 0,
totalPages: 1, totalPages: 1,
data: [] data: [],
}, });
sortColumn: { key: "name", label: "Name", order: "asc" }, const [sortColumn, setSortColumn] = useState<Column<ReadSequence>>({
filters: new Map<string, string>() key: "name",
} label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
componentDidMount = async () => { const changePage = async (page: number, pageSize: number) => {
const { page, pageSize } = this.state.pagedData; const data = await sequenceService.getSequences(
page,
await this.changePage(page, pageSize); pageSize,
} sortColumn.key,
sortColumn.order === "asc",
changePage = async (page: number, pageSize: number) => { filters,
const { sortColumn, filters } = this.state; );
if (data) {
const pagedData = await sequenceService.getSequences(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); setLoaded(true);
if (pagedData) { setPagedData(data);
this.setState({ loaded: true, pagedData }); } else {
} setLoaded(false);
else {
this.setState({ loaded: false });
}
}
onSort = async (sortColumn: Column<ReadSequence>) => {
const { page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await sequenceService.getSequences(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 sequenceService.getSequences(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
}
else {
this.setState({ loaded: false });
} }
}; };
onDelete = async (item?: ReadSequence) => { const onSort = async (newSortColumn: Column<ReadSequence>) => {
const { page, pageSize } = pagedData;
const data = await sequenceService.getSequences(
page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
}
};
const onSearch = async (name: string, value: string) => {
const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
const data = await sequenceService.getSequences(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
}
};
const onDelete = async (item?: ReadSequence) => {
const response = await sequenceService.deleteSequence(item?.id, item?.guid); const response = await sequenceService.deleteSequence(item?.id, item?.guid);
if (response) { if (response) {
this.componentDidMount(); await changePage(pagedData.page, pagedData.pageSize);
}
} }
};
render(): JSX.Element { useEffect(() => {
const { loaded, pagedData, sortColumn } = this.state; const { page, pageSize } = pagedData;
changePage(page, pageSize);
}, []);
return ( return (
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddSequence"> <Permission privilegeKey="AddSequence">
<div> <div>
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<SequenceTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete} /> <SequenceTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</Loading> </Loading>
); );
}
}; };
export default Sequence; export default Sequence;

View File

@ -1,36 +1,32 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import Column from '../../../components/common/columns'; import Column from "../../../components/common/columns";
import { Paginated } from '../../../services/Paginated'; import { Paginated } from "../../../services/Paginated";
import Button, { ButtonType } from '../../../components/common/Button'; import Button, { ButtonType } from "../../../components/common/Button";
import withRouter from '../../../utils/withRouter'; import withRouter from "../../../utils/withRouter";
import siteService, { ReadSite } from './services/sitessService'; import siteService, { ReadSite } from "./services/sitessService";
import SitesTable from './components/SitesTable'; import SitesTable from "./components/SitesTable";
import Loading from '../../../components/common/Loading'; import Loading from "../../../components/common/Loading";
import Permission from '../../../components/common/Permission'; import Permission from "../../../components/common/Permission";
interface SitesState { interface SitesState {
loaded: boolean; loaded: boolean;
pagedData : Paginated<ReadSite>, pagedData: Paginated<ReadSite>;
sortColumn : Column<ReadSite>, sortColumn: Column<ReadSite>;
filters: Map<string, string>; filters: Map<string, string>;
} }
class LocSites extends Component<any, any, SitesState> { class LocSites extends Component<any, any, SitesState> {
state = { state = {
loaded: false, loaded: false,
pagedData : { page: 1, pagedData: { page: 1, pageSize: 10, count: 0, totalPages: 1, data: [] },
pageSize : 10,
count: 0,
totalPages: 1,
data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" }, sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>() filters: new Map<string, string>(),
} };
componentDidMount = async () => { componentDidMount = async () => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize); await this.changePage(page, pageSize);
} };
changePage = async (page: number, pageSize: number) => { changePage = async (page: number, pageSize: number) => {
const { sortColumn, filters } = this.state; const { sortColumn, filters } = this.state;
@ -38,14 +34,19 @@ class LocSites extends Component< any, any, SitesState> {
filters.set("organisationId", organisationId); filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const pagedData = await siteService.getSites(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) { if (pagedData) {
this.setState({ loaded: true, pagedData, filters }); this.setState({ loaded: true, pagedData, filters });
} } else {
else {
this.setState({ loaded: false }); this.setState({ loaded: false });
} }
} };
onSort = async (sortColumn: Column<ReadSite>) => { onSort = async (sortColumn: Column<ReadSite>) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = this.state.pagedData;
@ -54,14 +55,19 @@ class LocSites extends Component< any, any, SitesState> {
const { organisationId } = this.props.router.params; const { organisationId } = this.props.router.params;
filters.set("organisationId", organisationId); filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const pagedData = await siteService.getSites(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) { if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn }); this.setState({ loaded: true, pagedData, sortColumn });
} } else {
else {
this.setState({ loaded: false }); this.setState({ loaded: false });
} }
} };
onSearch = async (name: string, value: string) => { onSearch = async (name: string, value: string) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = this.state.pagedData;
@ -71,11 +77,16 @@ class LocSites extends Component< any, any, SitesState> {
const { organisationId } = this.props.router.params; const { organisationId } = this.props.router.params;
filters.set("organisationId", organisationId); filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const pagedData = await siteService.getSites(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) { if (pagedData) {
this.setState({ loaded: true, filters, pagedData }); this.setState({ loaded: true, filters, pagedData });
} } else {
else {
this.setState({ loaded: false }); this.setState({ loaded: false });
} }
}; };
@ -84,7 +95,7 @@ class LocSites extends Component< any, any, SitesState> {
await siteService.deleteSite(item?.id, item?.guid); await siteService.deleteSite(item?.id, item?.guid);
this.componentDidMount(); this.componentDidMount();
} };
render(): JSX.Element { render(): JSX.Element {
const { loaded, pagedData, sortColumn } = this.state; const { loaded, pagedData, sortColumn } = this.state;
@ -93,15 +104,24 @@ class LocSites extends Component< any, any, SitesState> {
<Loading loaded={loaded}> <Loading loaded={loaded}>
<Permission privilegeKey="AddSite"> <Permission privilegeKey="AddSite">
<div> <div>
<Button buttonType={ButtonType.primary} to="add">Add</Button> <Button buttonType={ButtonType.primary} to="add">
Add
</Button>
</div> </div>
</Permission> </Permission>
<hr /> <hr />
<SitesTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> <SitesTable
data={pagedData}
sortColumn={sortColumn}
onChangePage={this.changePage}
onSort={this.onSort}
onSearch={this.onSearch}
onDelete={this.onDelete}
/>
</Loading> </Loading>
); );
} }
}; }
const Sites = withRouter(LocSites); const Sites = withRouter(LocSites);

View File

@ -1,65 +1,78 @@
import React from "react"; import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import Column from "../../../../components/common/columns"; import Column from "../../../../components/common/columns";
import Table, { PublishedTableProps } from "../../../../components/common/Table"; import Table, {
PublishedTableProps,
} from "../../../../components/common/Table";
import { ReadSite } from "../services/sitessService"; import { ReadSite } from "../services/sitessService";
import Button, { ButtonType } from "../../../../components/common/Button"; import Button, { ButtonType } from "../../../../components/common/Button";
import authentication from "../../../frame/services/authenticationService"; import authentication from "../../../frame/services/authenticationService";
class SitesTable extends React.Component<PublishedTableProps<ReadSite>> { const SitesTable: React.FC<PublishedTableProps<ReadSite>> = ({
canViewSpecification = authentication.hasAccess("ViewSpecification"); data,
sortColumn,
onChangePage,
onSearch,
onDelete,
onSort,
}) => {
const { t } = useTranslation();
const canViewSpecification = authentication.hasAccess("ViewSpecification");
columns: Column<ReadSite>[] = [ const columns: Column<ReadSite>[] = useMemo(
() => [
{ {
key: "name", key: "name",
label: "Name", label: t("Name"),
order: "asc", order: "asc",
content: (item) => { content: (item) => (
return ( <Button
<> buttonType={ButtonType.link}
<Button buttonType={ButtonType.link} to={"/specifications/" + item.organisationId.id + "/" + item.id}> to={`/specifications/${item.organisationId.id}/${item.id}`}
>
{item.name} {item.name}
</Button> </Button>
</> ),
},
{ key: "address", label: t("Address"), order: "asc" },
{ key: "status", label: t("Status"), order: "asc" },
],
[t, canViewSpecification],
); );
},
},
{ key: "address", label: "Address", order: "asc" },
{ key: "status", label: "Status", order: "asc" },
];
raiseSort = (sortColumn: Column<ReadSite>) => { const raiseSort = (sortCol: Column<ReadSite>) => {
this.setState({ sortColumn }); if (onSort !== undefined) onSort(sortCol);
if (this.props.onSort !== undefined) this.props.onSort(sortColumn);
}; };
handleAuditParams = (item: any) => { const handleAuditParams = (item: any) => {
return { return {
entityName: "e_suite.Database.Core.Tables.Printer.Site", entityName: "e_suite.Database.Core.Tables.Printer.Site",
primaryKey: '{"Id":' + item.id + "}", primaryKey: `{"Id":${item.id}}`,
}; };
}; };
render() {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props;
const editPath = authentication.hasAccess("EditSite") ? "{0}" : undefined; const editPath = authentication.hasAccess("EditSite") ? "{0}" : undefined;
const doDelete = authentication.hasAccess("DeleteSite") ? onDelete : undefined; const doDelete = authentication.hasAccess("DeleteSite")
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; ? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
return ( return (
<Table <Table
data={data} data={data}
keyName="id" keyName="id"
columns={this.columns} columns={columns}
sortColumn={sortColumn} sortColumn={sortColumn}
editPath={editPath} editPath={editPath}
onSort={this.raiseSort} onSort={raiseSort}
onChangePage={onChangePage} onChangePage={onChangePage}
onSearch={onSearch} onSearch={onSearch}
onDelete={doDelete} onDelete={doDelete}
onAuditParams={showAudit} onAuditParams={showAudit}
/> />
); );
} };
}
export default SitesTable; export default SitesTable;