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, page: 1,
pagedData: Paginated<CustomField>, pageSize: 10,
sortColumn: Column<CustomField>, count: 0,
filters: Map<string, string>; totalPages: 1,
} data: [],
};
class CustomFields extends Component<any, any, CustomFieldsState> { const initialSortColumn: Column<CustomField> = {
state = { key: "name",
loaded: false, label: "Name",
pagedData: { order: "asc",
page: 1, };
pageSize: 10,
count: 0,
totalPages: 1,
data: []
},
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
componentDidMount = async () => { const CustomFields: React.FC = () => {
const { page, pageSize } = this.state.pagedData; 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>(),
);
await this.changePage(page, pageSize); useEffect(() => {
} const loadInitial = async () => {
const pagedDataResult = await customFieldsService.getFields(
changePage = async (page: number, pageSize: number) => { initialPagedData.page,
const { sortColumn, filters } = this.state; initialPagedData.pageSize,
initialSortColumn.key,
const pagedData = await customFieldsService.getFields(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); initialSortColumn.order === "asc",
if (pagedData) { new Map<string, string>(),
this.setState({ loaded: true, pagedData }); );
} if (pagedDataResult) {
else { setLoaded(true);
this.setState({ loaded: false }); setPagedData(pagedDataResult);
} } else {
} setLoaded(false);
}
onSort = async (sortColumn: Column<CustomField>) => {
const { page, pageSize } = this.state.pagedData;
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,
return ( pageSize,
<Loading loaded={loaded}> sortColumn.key,
<Permission privilegeKey="AddField"> sortColumn.order === "asc",
<div> filters,
<Button buttonType={ButtonType.primary} to="add">Add</Button> );
</div> if (pagedDataResult) {
</Permission> setLoaded(true);
<hr /> setPagedData(pagedDataResult);
<CustomFieldsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete} /> } else {
</Loading> 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 (
<Loading loaded={loaded}>
<Permission privilegeKey="AddField">
<div>
<Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div>
</Permission>
<hr />
<CustomFieldsTable
data={pagedData}
sortColumn={translatedSortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</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>, pageSize: 10,
sortColumn : Column<GetDomain>, count: 0,
filters: Map<string, string>; totalPages: 1,
} data: [],
};
class Domains extends Component< any, any, DomainsState> { const Domains: React.FC = () => {
state = { const { t } = useTranslation();
loaded : false, const [loaded, setLoaded] = useState(false);
pagedData : { page: 1, const [pagedData, setPagedData] =
pageSize : 10, useState<Paginated<GetDomain>>(initialPagedData);
count: 0, const [sortColumn, setSortColumn] = useState<Column<GetDomain>>({
totalPages: 1, key: "name",
data: [] }, label: t("Name"),
sortColumn: { key: "name", label: "Name", order: "asc" }, order: "asc",
filters: new Map<string, string>() });
} const [filters, setFilters] = useState<Map<string, string>>(
() => new Map<string, string>(),
);
componentDidMount = async () => { useEffect(() => {
const { page, pageSize } = this.state.pagedData; const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
await this.changePage(page, pageSize);
}
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
const pagedData = await domainsService.getDomains(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters);
if (pagedData) {
this.setState({ loaded: true, pagedData });
}
else {
this.setState({ loaded: false });
}
}
onSort = async(sortColumn : Column<GetDomain>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const pagedData = await domainsService.getDomains(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 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) => { void loadInitial();
const response = await domainsService.deleteDomain( keyValue?.id, keyValue?.guid); }, []);
if (response) {
this.componentDidMount();
}
}
render(): JSX.Element { const changePage = async (page: number, pageSize: number) => {
const { loaded, pagedData, sortColumn } = this.state; const pagedDataResult = await domainsService.getDomains(
page,
return ( pageSize,
<Loading loaded={loaded}> sortColumn.key,
<Permission privilegeKey="AddDomain"> sortColumn.order === "asc",
<div> filters,
<Button buttonType={ButtonType.primary} to="add">Add</Button> );
</div> if (pagedDataResult) {
</Permission> setLoaded(true);
<hr/> setPagedData(pagedDataResult);
<DomainsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> } else {
</Loading> setLoaded(false);
);
} }
};
const onSort = async (nextSortColumn: Column<GetDomain>) => {
const { page, pageSize } = pagedData;
const pagedDataResult = await domainsService.getDomains(
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 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 (
<Loading loaded={loaded}>
<Permission privilegeKey="AddDomain">
<div>
<Button buttonType={ButtonType.primary} to="add">
{t("Add")}
</Button>
</div>
</Permission>
<hr />
<DomainsTable
data={pagedData}
sortColumn={translatedSortColumn}
onChangePage={changePage}
onSort={onSort}
onSearch={onSearch}
onDelete={onDelete}
/>
</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";
@ -7,54 +8,47 @@ import MailTemplatesTab from "./components/MailTemplatesTab";
import SecurityRolesTab from "./components/SecurityRolesTab"; import SecurityRolesTab from "./components/SecurityRolesTab";
interface DomainsDetailsProps { 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}/> if (canViewMailTemplates) {
</Tab> ); tabs.push(
<Tab key={2} label={t("MailTemplates")}>
if (isEditMode) { <MailTemplatesTab />
if (canViewMailTemplates) { </Tab>,
tabs.push(<Tab key={2} label="Mail Templates"> );
<MailTemplatesTab />
</Tab>
);
}
if (canViewSecurityRoles) {
tabs.push(<Tab key={3} label="Security Roles">
<SecurityRolesTab />
</Tab>
);
}
}
return (
<div>
<h1>{mode} Domain</h1>
<HorizontalTabs>
{tabs}
</HorizontalTabs>
</div>
);
} }
} if (canViewSecurityRoles) {
tabs.push(
<Tab key={3} label={t("SecurityRoles")}>
<SecurityRolesTab />
</Tab>,
);
}
}
return (
<div>
<h1>{heading}</h1>
<HorizontalTabs>{tabs}</HorizontalTabs>
</div>
);
};
export default DomainsDetails; export default DomainsDetails;

View File

@ -1,82 +1,80 @@
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";
import Loading from "../../../../components/common/Loading"; import Loading from "../../../../components/common/Loading";
interface MailType{ interface MailType {
mailType : string; mailType: string;
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[]>([]);
class MailTemplatesTabNoRouter extends React.Component<MailTemplatesTabProps, MailTemplatesTabState> { useEffect(() => {
state : MailTemplatesTabState = { const loadTypes = async () => {
loaded : false, const response = await mailTemplatesService.getTypes(0, 10, "", true);
currentMailType : "", if (response) {
types: [] const nextTypes = response.data as MailType[];
} setTypes(nextTypes);
async componentDidMount() { if (nextTypes.length > 0) {
const types = await mailTemplatesService.getTypes(0,10,"",true); setLoaded(true);
if (types) { setCurrentMailType(nextTypes[0].mailType);
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);
return (
<Loading loaded={loaded}>
<div className="two-column-grid-1-3">
<div>
<ul className="mail-types">
{ types.map( (x) => {
return <li key={x.mailType} value={x.mailType} onClick={this.onClick}>{x.description}</li>
})}
</ul>
</div>
<div>
<HOCEmailTemplateEditor domainId={domainId} currentMailType={currentMailType} />
</div>
</div>
</Loading>
);
} }
} };
const { domainId } = router.params;
return (
<Loading loaded={loaded}>
<div className="two-column-grid-1-3">
<div>
<ul className="mail-types">
{types.map((x) => {
return (
<li key={x.mailType} value={x.mailType} onClick={onClick}>
{x.description}
</li>
);
})}
</ul>
</div>
<div>
<HOCEmailTemplateEditor
domainId={domainId}
currentMailType={currentMailType}
/>
</div>
</div>
</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 {
role: any | undefined;
} }
interface RoleAccessEditorProps extends RouterProps{ const RoleAccessEditorNoRouter: React.FC<RoleAccessEditorProps> = ({
role : any | undefined role,
} router,
}) => {
const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [accessList, setAccessList] =
useState<Paginated<GetSecurityAccess>>(initialAccessList);
const [accessRightsForRole, setAccessRightsForRole] =
useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
const [pagedData, setPagedData] =
useState<Paginated<GetRoleSecurityAccess>>(initialPagedData);
const [sortColumn] = useState<Column<GetRoleSecurityAccess>>({
key: "name",
label: t("Name"),
order: "asc",
});
class RoleAccessEditorNoRouter extends React.Component<RoleAccessEditorProps, RoleAccessEditorState> { const isItemSelected = (
state : RoleAccessEditorState = { securityAccess: string,
loaded : false, roleAccessList: unknown[] | undefined,
accessList : { page: 1, ): boolean => {
pageSize : 10, if (roleAccessList === undefined) return false;
count: 0,
totalPages: 1, const filtered = roleAccessList.filter(
data: [] }, (x) => (x as any).securityAccess === securityAccess,
accessRightsForRole : { page: 1, );
pageSize : 10, return filtered.length > 0;
count: 0, };
totalPages: 1,
data: [] }, const compileAccessRightsPagedData = (
pagedData : { page: 1, masterList: GetSecurityAccess[] | undefined,
pageSize : 10, roleAccessList: unknown[] | undefined,
count: 0, ): Paginated<GetRoleSecurityAccess> => {
totalPages: 1, if (masterList === undefined) {
data: [] }, return initialPagedData;
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
} }
componentDidMount = async () => { if (roleAccessList === undefined) {
await this.updatePage(); return {
page: 1,
pageSize: 10,
count: 0,
totalPages: 1,
data: masterList as GetRoleSecurityAccess[],
};
} }
async componentDidUpdate(prevProps: Readonly<RoleAccessEditorProps>, prevState: Readonly<RoleAccessEditorState>, snapshot?: any) { const accessRightsForRoleData = masterList.map((value) => {
if (prevProps.role?.id !== this.props.role?.id) { const item: any = value;
await this.updatePage(); item.selected = isItemSelected(item.securityAccess, roleAccessList);
} return item;
});
return {
page: 1,
pageSize: 10,
count: 0,
totalPages: 1,
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 {
setLoaded(false);
}
};
const updatePage = async (nextAccessList?: Paginated<GetSecurityAccess>) => {
if (nextAccessList && nextAccessList.count === 0) {
const list = await roleService.getAccessList(0, 10, "name", true);
setAccessList(list);
await changePage(list);
} else {
await changePage(nextAccessList);
}
};
useEffect(() => {
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);
let response = undefined;
if (additions.length > 0) {
response = await roleService.addRoleAccess(roleGeneralIdRef, additions);
} }
updatePage = async() => if (deletions.length > 0) {
{ response = await roleService.deleteRoleAccess(
const { page, pageSize } = this.state.pagedData; roleGeneralIdRef,
deletions,
await this.changePage(page, pageSize); );
} }
changePage = async(page: number, pageSize : number) => { if (response) {
let { accessList } = this.state; toast.info(t("RoleAccessUpdated"));
const { role } = this.props; await updatePage(accessList);
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 => { const isAdministrator = role?.isAdministrator || role?.isSuperUser;
if (roleAccess === undefined)
return false;
const filtered = roleAccess?.filter( (x) => (x as any).securityAccess === securityAccess); return (
<Loading loaded={loaded}>
return filtered!.length > 0; <RollAccessTable
} role={role?.id}
isAdministrator={isAdministrator}
complieAccessRightsPagedData = (masterList: GetSecurityAccess[] | undefined, roleAccess: unknown[] | undefined) : Paginated<GetRoleSecurityAccess> => { data={pagedData}
if ( masterList === undefined ) { onSave={handleSave}
return { page: 1, />
pageSize : 10, </Loading>
count: 0, );
totalPages: 1, };
data: [] }
}
if (roleAccess === undefined) {
return { page: 1,
pageSize : 10,
count: 0,
totalPages: 1,
data: (masterList as GetRoleSecurityAccess[]) }
}
const accessrightsForRole : Paginated<GetRoleSecurityAccess> = { page: 1,
pageSize : 10,
count: 0,
totalPages: 1,
data: []
}
accessrightsForRole.data = masterList.map( value => {
let item : any = value
item.selected = this.IsItemSelected(item.securityAccess, roleAccess);
return item
})
return accessrightsForRole;
}
handleSave = async ( additions : string[], deletions : string[] ) => {
const { role } = this.props;
const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
let response = undefined;
if (additions.length > 0)
{
response = await roleService.addRoleAccess( roleGeneralIdRef, additions);
}
if (deletions.length > 0)
{
response = await roleService.deleteRoleAccess( roleGeneralIdRef, deletions);
}
if (response) {
toast.info("Role access updated successfully.")
await this.updatePage();
}
}
render() {
const { loaded, pagedData } = this.state;
const { role } = this.props;
const isAdministrator = role.isAdministrator || role.isSuperUser;
return (
<Loading loaded={loaded}>
<RollAccessTable role={role.id} isAdministrator={isAdministrator} data={pagedData} onSave={this.handleSave}/>
</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,132 +10,160 @@ 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 {
selectedRole?: GetRoleResponse;
onSelectRole?: (keyValue: any) => void;
onUnselectRole?: () => void;
} }
interface RolesEditorProps extends RouterProps{ const RolesEditorTabNoRouter: React.FC<RolesEditorProps> = ({
selectedRole? : GetRoleResponse; selectedRole,
onSelectRole?: (keyValue: any) => void; onSelectRole,
onUnselectRole?: () => void; onUnselectRole,
} router,
}) => {
const { t } = useTranslation();
const [loaded, setLoaded] = useState(false);
const [pagedData, setPagedData] =
useState<Paginated<GetRoleResponse>>(initialPagedData);
const [sortColumn, setSortColumn] = useState<Column<GetRoleResponse>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
() => new Map<string, string>(),
);
class RolesEditorTabNoRouter extends React.Component<RolesEditorProps, RolesEditorState> { const { domainId } = router.params;
state : RolesEditorState = { const domainGeneralIdRef = MakeGeneralIdRef(domainId);
loaded : false,
pagedData : { page: 1,
pageSize : 10,
count: 0,
totalPages: 1,
data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" },
filters: new Map<string, string>()
}
componentDidMount = async () => { useEffect(() => {
const { page, pageSize } = this.state.pagedData; const loadInitial = async () => {
await changePage(initialPagedData.page, initialPagedData.pageSize);
await this.changePage(page, pageSize);
}
changePage = async(page: number, pageSize : number) =>{
const { sortColumn, filters } = this.state;
const { domainId } = this.props.router.params;
const domainGeneralIdRef = MakeGeneralIdRef( domainId);
const pagedData = await roleService.getRoles(page, pageSize, sortColumn.key, sortColumn.order === "asc", domainGeneralIdRef, filters);
if (pagedData) {
this.setState({ loaded: true, pagedData });
}
else {
this.setState({ loaded: false });
}
}
onSort = async(sortColumn : Column<GetRoleResponse>) => {
const {page, pageSize } = this.state.pagedData;
const { filters } = this.state;
const { domainId } = this.props.router.params;
const domainGeneralIdRef = MakeGeneralIdRef( domainId);
const pagedData = await roleService.getRoles(page, pageSize, sortColumn.key, sortColumn.order === "asc", domainGeneralIdRef, 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;
const { domainId } = this.props.router.params;
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) => { void loadInitial();
return keyValue.canDelete; }, [domainId]);
const changePage = async (page: number, pageSize: number) => {
const pagedDataResult = await roleService.getRoles(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
domainGeneralIdRef,
filters,
);
if (pagedDataResult) {
setLoaded(true);
setPagedData(pagedDataResult);
} else {
setLoaded(false);
} }
};
canDelete = ( keyValue : any) => { const onSort = async (nextSortColumn: Column<GetRoleResponse>) => {
return keyValue.canDelete; const { page, pageSize } = pagedData;
const pagedDataResult = await roleService.getRoles(
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 response = await roleService.deleteRole( keyValue!.id, keyValue!.guid); const { page, pageSize } = pagedData;
if (response) { const nextFilters = new Map(filters);
this.componentDidMount(); 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);
} }
};
onSelectRow = ( id : GetRoleResponse ) => const canEdit = (keyValue: any) => {
{ return keyValue.canDelete;
const { onSelectRole } = this.props; };
if (onSelectRole !== undefined){ const canDelete = (keyValue: any) => {
onSelectRole(id); return keyValue.canDelete;
} };
const onDelete = async (keyValue?: GetRoleResponse) => {
const response = await roleService.deleteRole(keyValue!.id, keyValue!.guid);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
} }
};
onUnselectRole = () => { const onSelectRow = (id: GetRoleResponse) => {
const { onUnselectRole } = this.props; if (onSelectRole !== undefined) {
onSelectRole(id);
if (onUnselectRole !== undefined) {
onUnselectRole();
}
} }
};
render() { const translatedSortColumn = { ...sortColumn, label: t("Name") };
const { loaded, pagedData, sortColumn } = this.state;
const { selectedRole, onUnselectRole } = this.props; return (
<Loading loaded={loaded}>
return ( <Permission privilegeKey="AddRole">
<Loading loaded={loaded}> <Button
<Permission privilegeKey="AddRole"> id="btnAddRoleToDomain"
<Button id="btnAddRoleToDomain" buttonType={ButtonType.primary} to="addRole">Add</Button> buttonType={ButtonType.primary}
</Permission> to="addRole"
<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}/> {t("Add")}
</Loading> </Button>
); </Permission>
} <hr />
} <RolesTable
data={pagedData}
sortColumn={translatedSortColumn}
selectedRow={selectedRole}
onChangePage={changePage}
onUnselectRow={onUnselectRole}
onSort={onSort}
onSearch={onSearch}
onSelectRow={onSelectRow}
canEdit={canEdit}
canDelete={canDelete}
onDelete={onDelete}
/>
</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" }
];
raiseSort = (sortColumn : Column<GetRoleResponse>) => { const columns: Column<GetRoleResponse>[] = [
this.setState({sortColumn}); { key: "name", label: t("Name"), order: "asc" },
if ( this.props.onSort !== undefined) ];
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const raiseSort = (sortColumn: Column<GetRoleResponse>) => {
return { if (props.onSort !== undefined) props.onSort(sortColumn);
entityName : "e_suite.Database.Core.Tables.Domain.Role", };
primaryKey : "{\"Id\":"+item.id+"}"
}
}
render() { const handleAuditParams = (item: any) => {
const { data, sortColumn, selectedRow, onChangePage, onSearch, onSelectRow, canEdit, canDelete, onDelete, onUnselectRow } = this.props; return {
const editPath = authentication.hasAccess("EditRole") ? "editRole/{0}" : undefined; entityName: "e_suite.Database.Core.Tables.Domain.Role",
const doDelete = authentication.hasAccess("DeleteRole") ? onDelete : undefined; primaryKey: '{"Id":' + item.id + "}",
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.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}/>; const {
} data,
} sortColumn,
selectedRow,
export default RolesTable; 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={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;

View File

@ -1,150 +1,150 @@
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";
interface RollAccessTableProps extends PublishedTableProps<GetSecurityAccess>{ interface RollAccessTableProps extends PublishedTableProps<GetSecurityAccess> {
role : any; role: any;
isAdministrator : boolean; isAdministrator: boolean;
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[]>([]);
class RollAccessTable extends React.Component<RollAccessTableProps, RollAccessTableState> { useEffect(() => {
setDeltaAdditions([]);
setDeltaDeletions([]);
}, [role]);
state : RollAccessTableState = { const itemIsSelected = (item: any): boolean => {
deltaAdditions : [], if (isAdministrator) return true;
deltaDeletions : []
};
ResetState = () => { let selected = item.selected;
this.setState( {
deltaAdditions : [], if (selected === true) {
deltaDeletions : [] selected = !(
} ); deltaDeletions.filter((x) => x === item.securityAccess).length > 0
);
} else {
selected =
deltaAdditions.filter((x) => x === item.securityAccess).length > 0;
} }
componentDidMount = async () => { return selected;
this.ResetState(); };
}
componentDidUpdate(prevProps: Readonly<RollAccessTableProps>, prevState: Readonly<RollAccessTableState>, snapshot?: any): void { const checkboxChange = (e: any) => {
if (prevProps.role !== this.props.role) { const accessKey = e.target.id;
this.ResetState(); const newSelectedState = e.target.checked;
const filteredData = data.data?.filter(
(x: any) => x.securityAccess === accessKey,
);
if (filteredData?.length === 1) {
const item: any = filteredData[0];
const oldSelectedState = item.selected;
if (oldSelectedState === true) {
if (newSelectedState === true) {
setDeltaDeletions(deltaDeletions.filter((x) => x !== accessKey));
} else {
setDeltaDeletions([...deltaDeletions, accessKey]);
} }
} } else {
if (newSelectedState === true) {
checkboxChange = (e : any) => { setDeltaAdditions([...deltaAdditions, accessKey]);
const accessKey = e.target.id; } else {
const newSelectedState = e.target.checked; setDeltaAdditions(deltaAdditions.filter((x) => x !== accessKey));
let { deltaAdditions, deltaDeletions } = this.state;
const { data } = this.props;
const filteredData = data.data?.filter( (x: any) => x.securityAccess === accessKey );
if (filteredData?.length === 1)
{
const item : any = filteredData[0];
const oldSelectedState = item.selected;
if (oldSelectedState===true) {
if (newSelectedState===true){
deltaDeletions = deltaDeletions.filter( x => x !== accessKey);
}
else {
deltaDeletions.push(accessKey);
}
}
else {
if (newSelectedState===true){
deltaAdditions.push(accessKey);
}
else {
deltaAdditions = deltaAdditions.filter( x => x !== accessKey);
}
}
} }
}
this.setState( { deltaAdditions, deltaDeletions })
} }
};
itemIsSelected = (item : any) => { const columns: Column<GetSecurityAccess>[] = [
const { deltaAdditions, deltaDeletions } = this.state; {
const { isAdministrator } = this.props; key: "selected",
if (isAdministrator) label: t("Allowed"),
return true; order: "asc",
content: (item: any) => {
return (
<>
<input
id={item.securityAccess}
type="checkbox"
checked={itemIsSelected(item)}
onChange={checkboxChange}
/>
</>
);
},
},
{ key: "name", label: t("Name"), order: "asc" },
{ key: "groupName", label: t("Group"), order: "asc" },
{ key: "description", label: t("Description"), order: "asc" },
];
let selected = item.selected; const raiseSort = (sortColumn: Column<GetSecurityAccess>) => {
if (onSort !== undefined) onSort(sortColumn);
};
if (selected === true) { const handleClickCancel = () => {
selected = !(deltaDeletions.filter( x => x === item.securityAccess).length > 0); setDeltaAdditions([]);
} setDeltaDeletions([]);
else { };
selected = (deltaAdditions.filter( x => x === item.securityAccess).length > 0);
}
return selected; const handleClickSave = () => {
} onSave(deltaAdditions, deltaDeletions);
setDeltaAdditions([]);
setDeltaDeletions([]);
};
columns : Column<GetSecurityAccess>[] = [ const canEditRoleAccess = authentication.hasAccess("EditRoleAccess");
{ key: "selected", label: "Allowed", order: "asc", content:(item : any) => { const canChangeRoleAccess = isAdministrator || canEditRoleAccess;
return <><input id={item.securityAccess} type="checkbox" checked={this.itemIsSelected(item)} onChange={this.checkboxChange}/></> } }, //todo refactor this to use the normal forms code? const hasChanges = !(deltaAdditions.length + deltaDeletions.length === 0);
{ key: "name", label: "Name", order: "asc" },
{ key: "groupName", label: "Group", order: "asc" },
{ key: "description", label: "Description", order: "asc" }
];
raiseSort = (sortColumn : Column<GetSecurityAccess>) => { return (
if ( this.props.onSort !== undefined) <>
this.props.onSort(sortColumn); <Table
} data={data}
keyName="securityAccess"
columns={columns}
onSort={raiseSort}
/>
{canChangeRoleAccess && (
<>
<Button
disabled={!hasChanges}
buttonType={ButtonType.secondary}
onClick={handleClickCancel}
>
{t("Cancel")}
</Button>
<Button
disabled={!hasChanges}
buttonType={ButtonType.primary}
onClick={handleClickSave}
>
{t("Save")}
</Button>
</>
)}
</>
);
};
handleAuditParams = (item: any) => { export default RollAccessTable;
return {
entityName : "e_suite.Database.Core.Tables.Domain.UserRole",
primaryKey : "{\"Id\":"+item.id+"}"
}
}
HandleClickCancel = () => {
this.setState( { deltaAdditions : [], deltaDeletions : [] })
}
HandleClickSave = () => {
const { onSave } = this.props;
const { deltaAdditions, deltaDeletions } = this.state;
onSave(deltaAdditions, deltaDeletions);
this.setState( { deltaAdditions : [], deltaDeletions : [] })
}
render() {
const { deltaAdditions, deltaDeletions } = this.state;
const { data, isAdministrator } = this.props;
const canEditRoleAccess = authentication.hasAccess("EditRoleAccess");
const canChangeRoleAccess = isAdministrator || canEditRoleAccess;
const hasChanges = !(deltaAdditions.length + deltaDeletions.length === 0);
return <>
<Table data={ data } keyName="securityAccess" columns={this.columns} />
{canChangeRoleAccess && <>
<Button disabled={!hasChanges} buttonType={ButtonType.secondary} onClick={this.HandleClickCancel}>
Cancel
</Button>
<Button disabled={!hasChanges} buttonType={ButtonType.primary} onClick={this.HandleClickSave}>
Save
</Button>
</>}
</>;
}
}
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,
);
class SecurityRolesTabNoRouter extends React.Component<SecurityRolesTabProps, SecurityRolesTabState> { const onSelectRow = (id: any) => {
state : SecurityRolesTabState = { setSelectedRole(id);
selectedRole: undefined };
}
async componentDidMount() {
}
onSelectRow = ( id : any ) => const onUnselectRow = () => {
{ setSelectedRole(undefined);
this.setState({selectedRole:id}); };
}
onUnselectRow =() => { const canViewRoleAccess = authentication.hasAccess("ViewRoleAccess");
this.setState({ selectedRole: undefined }); const canViewRoleUsers = authentication.hasAccess("ViewRoleUsers");
}
render() { const tabs: JSX.Element[] = [];
const { selectedRole } = this.state;
const canViewRoleAccess = authentication.hasAccess("ViewRoleAccess")
const canViewRoleUsers = authentication.hasAccess("ViewRoleUsers")
let tabs : JSX.Element[] = []; if (canViewRoleAccess) {
tabs.push(
<Tab key={1} label={t("RoleAccess")}>
<RoleAccessEditor role={selectedRole} />
</Tab>,
);
}
if (canViewRoleUsers) {
tabs.push(
<Tab key={2} label={t("Users")}>
<UserRoleEditor role={selectedRole} />
</Tab>,
);
}
if (canViewRoleAccess) { return (
tabs.push(<Tab key={1} label="Role Access"> <div className="two-column-grid-1-1">
<RoleAccessEditor role={selectedRole} /> <div>
</Tab>); <RolesEditor
} selectedRole={selectedRole}
if (canViewRoleUsers) { onSelectRole={onSelectRow}
tabs.push(<Tab key={2} label="Users"> onUnselectRole={onUnselectRow}
<UserRoleEditor role={selectedRole} /> />
</Tab>); </div>
} <div>
{selectedRole !== undefined &&
return ( (canViewRoleAccess || canViewRoleUsers) && (
<div className="two-column-grid-1-1"> <HorizontalTabs>{tabs}</HorizontalTabs>
<div> )}
<RolesEditor selectedRole={selectedRole} onSelectRole={this.onSelectRow} onUnselectRole={this.onUnselectRow} /> </div>
</div> </div>
<div> );
{((selectedRole !== undefined) && (canViewRoleAccess || canViewRoleUsers)) && <HorizontalTabs> };
{tabs}
</HorizontalTabs>
}
</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>, pageSize: 10,
sortColumn : Column<RoleUser>, count: 0,
filters: Map<string, string>; totalPages: 1,
data: [],
};
interface UserRoleEditorProps extends RouterProps {
role: any | undefined;
} }
interface UserRoleEditorProps extends RouterProps{ const UserRoleEditorNoRouter: React.FC<UserRoleEditorProps> = ({
role : any | undefined 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>(),
);
class UserRoleEditorNoRouter extends React.Component<UserRoleEditorProps, UserRoleEditorState> { const roleGeneralIdRef = MakeGeneralIdRef(role?.id, role?.guid);
state : UserRoleEditorState = {
loaded : false, const getRoleUsers = async (
pagedData : { page: 1, page: number,
pageSize : 10, pageSize: number,
count: 0, nextSortColumn: Column<RoleUser>,
totalPages: 1, nextFilters: Map<string, string>,
data: [] }, ) => {
sortColumn: { key: "name", label: "Name", order: "asc" }, const pagedDataResult = await roleService.getRoleUsers(
filters: new Map<string, string>() page,
pageSize,
nextSortColumn.key,
nextSortColumn.order === "asc",
roleGeneralIdRef,
nextFilters,
);
if (pagedDataResult) {
setLoaded(true);
setFilters(nextFilters);
setPagedData(pagedDataResult);
setSortColumn(nextSortColumn);
} else {
setLoaded(false);
} }
};
componentDidMount = async () => { useEffect(() => {
const { page, pageSize } = this.state.pagedData; const loadInitial = async () => {
await getRoleUsers(
await this.changePage(page, pageSize); initialPagedData.page,
} initialPagedData.pageSize,
sortColumn,
async componentDidUpdate(prevProps: Readonly<UserRoleEditorProps>, prevState: Readonly<UserRoleEditorState>, snapshot?: any) { new Map<string, string>(),
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>) => { void loadInitial();
}, [role?.id]);
const { role } = this.props; const changePage = async (page: number, pageSize: number) => {
const roleGeneralIdRef = MakeGeneralIdRef( role?.id, role?.guid); await getRoleUsers(page, pageSize, sortColumn, filters);
const pagedData = await roleService.getRoleUsers(page, pageSize, sortColumn.key, sortColumn.order === "asc", roleGeneralIdRef, filters); };
if (pagedData) {
this.setState({ loaded: true, filters, pagedData, sortColumn }); const onSort = async (nextSortColumn: Column<RoleUser>) => {
} const { page, pageSize } = pagedData;
else { await getRoleUsers(page, pageSize, nextSortColumn, filters);
this.setState({ loaded: false }); };
}
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 response = await roleService.deleteRoleUser(userId, roleGeneralIdRef);
if (response) {
await changePage(pagedData.page, pagedData.pageSize);
} }
};
onDelete = async ( user? : RoleUser) => { const addLink = "editRole/" + role?.id + "/addUserToRole";
const { role } = this.props;
const roleId = MakeGeneralIdRef(role?.id, role?.guid); return (
const userId = MakeGeneralIdRef(user?.id, user?.guid); <Loading loaded={loaded}>
<Permission privilegeKey="AddRoleUser">
const response = await roleService.deleteRoleUser(userId, roleId); <div>
if (response) { <Button
this.componentDidMount(); id="btnAddUserToRole"
} buttonType={ButtonType.primary}
} to={addLink}
>
render() { {t("Add")}
const {loaded, pagedData, sortColumn } = this.state; </Button>
</div>
const { role } = this.props; </Permission>
<hr />
const addLink = "editRole/" + role.id + "/addUserToRole"; <UserRolesTable
data={pagedData}
return ( sortColumn={sortColumn}
<Loading loaded={loaded}> onChangePage={changePage}
<Permission privilegeKey="AddRoleUser"> onSort={onSort}
<div> onSearch={onSearch}
<Button id="btnAddUserToRole" buttonType={ButtonType.primary} to={addLink}>Add</Button> onDelete={onDelete}
</div> />
</Permission> </Loading>
<hr/> );
<UserRolesTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/> };
</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" }
];
raiseSort = (sortColumn : Column<RoleUser>) => { const columns: Column<RoleUser>[] = [
this.setState({sortColumn}); { key: "displayName", label: t("Name"), order: "asc" },
if ( this.props.onSort !== undefined) ];
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const raiseSort = (sortColumn: Column<RoleUser>) => {
return { if (props.onSort !== undefined) props.onSort(sortColumn);
entityName : "e_suite.Database.Core.Tables.Domain.UserRole", };
primaryKey : "{\"Id\":"+item.id+"}"
}
}
render() { const handleAuditParams = (item: any) => {
const { data, sortColumn, selectedRow, onChangePage, onSearch, onSelectRow, onDelete } = this.props; return {
const doDelete = authentication.hasAccess("DeleteRoleUser") ? onDelete : undefined; entityName: "e_suite.Database.Core.Tables.Domain.UserRole",
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; primaryKey: '{"Id":' + item.id + "}",
};
};
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}/>; const {
} data,
} sortColumn,
selectedRow,
export default UserRolesTable; 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={columns}
sortColumn={sortColumn}
selectedRow={selectedRow}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onSelectRow={onSelectRow}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
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" }
];
raiseSort = (sortColumn : Column<GetDomain>) => { const columns: Column<GetDomain>[] = [
this.setState({sortColumn}); { key: "name", label: t("Name"), order: "asc" },
if ( this.props.onSort !== undefined) ];
this.props.onSort(sortColumn);
}
handleAuditParams = (item: any) => { const raiseSort = (sortColumn: Column<GetDomain>) => {
return { if (props.onSort !== undefined) props.onSort(sortColumn);
entityName : "e_suite.Database.Core.Tables.Domain.Domain", };
primaryKey : "{\"Id\":"+item.id+"}"
}
}
render() { const handleAuditParams = (item: any) => {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; return {
const editPath = authentication.hasAccess("EditDomain") ? "edit/{0}" : undefined; entityName: "e_suite.Database.Core.Tables.Domain.Domain",
const doDelete = authentication.hasAccess("DeleteDomain") ? onDelete : undefined; primaryKey: '{"Id":' + item.id + "}",
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 { data, sortColumn, onChangePage, onSearch, onDelete } = props;
} const editPath = authentication.hasAccess("EditDomain")
} ? "edit/{0}"
: undefined;
export default DomainsTable; const doDelete = authentication.hasAccess("DeleteDomain")
? 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 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" }, const [sortColumn, setSortColumn] = useState<Column<GetFormResponse>>({
filters: new Map<string, string>() key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
const changePage = async (page: number, pageSize: number) => {
const data = await formsService.getForms(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
} else {
setLoaded(false);
} }
};
componentDidMount = async () => { const onSort = async (newSortColumn: Column<GetFormResponse>) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const data = await formsService.getForms(
await this.changePage(page, pageSize); page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
} }
};
changePage = async(page: number, pageSize : number) =>{ const onSearch = async (name: string, value: string) => {
const { sortColumn, filters } = this.state; const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
const pagedData = await formsService.getForms(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); newFilters.set(name, value);
if (pagedData) {
this.setState({ loaded: true, pagedData }); const data = await formsService.getForms(
} page,
else { pageSize,
this.setState({ loaded: false }); sortColumn.key,
} sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
} }
};
onSort = async(sortColumn : Column<GetFormResponse>) => { const onDelete = async (item?: GetFormResponse) => {
const {page, pageSize } = this.state.pagedData; const response = await formsService.deleteForm(item?.id, item?.guid);
const { filters } = this.state; if (response) {
const pagedData = await formsService.getForms(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); await changePage(pagedData.page, pagedData.pageSize);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn });
}
else {
this.setState({ loaded: false });
}
} }
};
onSearch = async ( name: string, value: string) => { useEffect(() => {
const {page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const {sortColumn, filters } = this.state; changePage(page, pageSize);
filters.set(name, value); }, [pagedData]);
const pagedData = await formsService.getForms(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); return (
if (pagedData) { <Loading loaded={loaded}>
this.setState({ loaded: true, filters, pagedData }); <Permission privilegeKey="AddFormTemplate">
} <div>
else { <Button buttonType={ButtonType.primary} to="add">
this.setState({ loaded: false }); {t("Add")}
} </Button>
}; </div>
</Permission>
onDelete = async ( item? : GetFormResponse) => { <hr />
const response = await formsService.deleteForm( item?.id, item?.guid); <FormsTable
if (response) { data={pagedData}
this.componentDidMount(); sortColumn={sortColumn}
} onChangePage={changePage}
} onSort={onSort}
onSearch={onSearch}
render(): JSX.Element { onDelete={onDelete}
const { loaded, pagedData, sortColumn } = this.state; />
</Loading>
return ( );
<Loading loaded={loaded}> };
<Permission privilegeKey="AddFormTemplate">
<div>
<Button buttonType={ButtonType.primary} to="add">Add</Button>
</div>
</Permission>
<hr/>
<FormsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/>
</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],
);
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.Forms.FormTemplate",
primaryKey: `{"Id":${item.id}}`,
};
};
const raiseSort = (sortCol: Column<GetFormResponse>) => {
if (onSort !== undefined) {
onSort(sortCol);
} }
};
handleAuditParams = (item: any) => { const editPath = authentication.hasAccess("EditFormTemplate")
return { ? "edit/{0}"
entityName : "e_suite.Database.Core.Tables.Forms.FormTemplate", : undefined;
primaryKey : "{\"Id\":"+item.id+"}" const doDelete = authentication.hasAccess("DeleteFormTemplate")
} ? onDelete
} : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
render() { return (
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; <Table
const editPath = authentication.hasAccess("EditFormTemplate") ? "edit/{0}" : undefined; data={data}
const doDelete = authentication.hasAccess("DeleteFormTemplate") ? onDelete : undefined; keyName="id"
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; columns={columns}
sortColumn={sortColumn}
editPath={editPath}
onSort={raiseSort}
onChangePage={onChangePage}
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
return <Table data={data} keyName="id" columns={this.columns} sortColumn={sortColumn} editPath={editPath} onSort={this.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);
}; let parentItem: GeneralIdRef = SystemGlossaries;
componentDidUpdate(prevProps: Readonly<any>, prevState: Readonly<any>, snapshot?: GlossariesState | undefined): void { if (glossaryId !== undefined) {
if (!equal(this.props?.router?.params?.glossaryId, prevProps?.router?.params?.glossaryId)){ parentItem = MakeGeneralIdRef(glossaryId);
this.setState({ loaded: false });
this.loadData();
}
} }
loadData = async () => { const result = await glossariesService.getGlossaryItem(parentItem);
let parentItem: GeneralIdRef = SystemGlossaries; if (result) {
let nextParentAddress = "/glossaries";
if (
result.parent?.guid?.toLowerCase() !==
SystemGlossaries.guid?.toLowerCase()
) {
nextParentAddress += "/" + result.parent?.id;
}
const { glossaryId } = this.props.router.params; setData(result);
setParentAddress(nextParentAddress);
if (glossaryId !== undefined) setLoaded(true);
parentItem = MakeGeneralIdRef(glossaryId); } else {
setLoaded(false);
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 response = await glossariesService.deleteGlossaryItem(keyValue.id);
if (response) {
this.componentDidMount();
}
};
render(): JSX.Element {
const { loaded, data, parentAddress } = this.state;
const id = data?.id;
let table = <></>;
let upButton = <></>;
let editButton = <></>;
table = (
<div>
Items
<GlossariesTable params={this.props.params} data={data} onDelete={this.onDelete} />
</div>
);
if (data?.parent)
{
if (data.parent?.id !== BigInt(0) ) {
upButton = (
<Button buttonType={ButtonType.primary} to={parentAddress}>Up</Button>
);
}
if (data.parent?.id !== BigInt(0) ) {
editButton = (
<Button buttonType={ButtonType.primary} to={concatinate( ["/glossaries/edit", id], "/")}>Edit</Button>
);
}
}
const addPath = concatinate( ["/glossaries/add", id], "/");
let pathBlock = this.createPathBlock();
return (
<Loading loaded={loaded}>
<div>
<Permission privilegeKey="ViewGlossary">
{upButton}
</Permission>
<Permission privilegeKey="AddGlossary">
<Button buttonType={ButtonType.primary} to={addPath}>Add</Button>
</Permission>
<Permission privilegeKey="EditGlossary">
{editButton}
</Permission>
</div>
<hr />
{pathBlock}
{table}
</Loading>
);
} }
}, [glossaryId]);
createPathBlock = () : JSX.Element | undefined =>
{
const { data } = this.state;
let item : Glossary | undefined = data; useEffect(() => {
const empty = <></>; loadData();
let pathBlock : JSX.Element = empty; }, [loadData]);
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}</>; const onDelete = async (keyValue: any) => {
const response = await glossariesService.deleteGlossaryItem(keyValue.id);
item = item?.parent; if (response) {
} loadData();
if (pathBlock === undefined)
{
pathBlock = <></>;
}
pathBlock = <><Link to="/glossaries">Glossaries</Link>/{pathBlock}</>
return pathBlock;
} }
} };
const createPathBlock = (): JSX.Element | undefined => {
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 addPath = concatinate(["/glossaries/add", id], "/");
const table = (
<div>
{t("Items")}
<GlossariesTable params={props.params} data={data} onDelete={onDelete} />
</div>
);
let upButton = <></>;
let editButton = <></>;
if (data?.parent) {
if (data.parent.id !== BigInt(0)) {
upButton = (
<Button buttonType={ButtonType.primary} to={parentAddress}>
{t("Up")}
</Button>
);
editButton = (
<Button
buttonType={ButtonType.primary}
to={concatinate(["/glossaries/edit", id], "/")}
>
{t("Edit")}
</Button>
);
}
}
const pathBlock = createPathBlock();
return (
<Loading loaded={loaded}>
<div>
<Permission privilegeKey="ViewGlossary">{upButton}</Permission>
<Permission privilegeKey="AddGlossary">
<Button buttonType={ButtonType.primary} to={addPath}>
{t("Add")}
</Button>
</Permission>
<Permission privilegeKey="EditGlossary">{editButton}</Permission>
</div>
<hr />
{pathBlock}
{table}
</Loading>
);
};
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 !== "") result += seperator;
if ( result !== "") result += arg;
result += seperator;
result += arg;
}
} }
}
return result; return result;
} }

View File

@ -1,127 +1,140 @@
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;
} }
interface CustomColumn extends Column<customField>{ interface CustomColumn extends Column<customField> {
isCustom : boolean; isCustom: boolean;
} }
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 ?? "";
return 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 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 = {
id: x.id,
name: x.name,
};
columns : CustomColumn[] = [ for (const column of columnsList) {
{ key: "name", label: "Name", order: "asc", link:"/glossaries/{0}", isCustom: false } if (column.isCustom) {
]; dataItem[column.key] = findValueById(x, column.key);
PaginatedData = () => {
const { data } = this.props;
const { columnsList } = this.state;
const pagedData = data!.children.map( (x) => {
let dataItem : customField = {
id: x.id,
name : x.name }
for( const column of columnsList) {
if (column.isCustom){
dataItem[column.key] = this.findValueById(x, column.key);
}
}
return dataItem;
} )
let paginated : Paginated<customField> = {
count : 1,
page: 1,
pageSize: 1,
totalPages: 1,
data : pagedData
} }
}
return paginated;
return dataItem;
});
return {
count: 1,
page: 1,
pageSize: 1,
totalPages: 1,
data: pagedData,
};
}, [data, columnsList]);
useEffect(() => {
const newColumnsList = [...baseColumns];
if (data?.childCustomFieldDefinition) {
for (const customfield of data.childCustomFieldDefinition) {
newColumnsList.push({
key: String(customfield.id),
label: customfield.name,
order: "asc",
isCustom: true,
});
}
} }
componentDidMount = () => { setColumnsList(newColumnsList);
this.CompileColumns(); }, [baseColumns, data]);
}
componentDidUpdate(prevProps: Readonly<GlossariesTableProps>, prevState: Readonly<{}>, snapshot?: any): void { const handleAuditParams = (item: any) => {
if(!equal(this.props.data, prevProps.data)) return {
this.CompileColumns(); entityName: "e_suite.Database.Core.Tables.Glossaries.Glossary",
} primaryKey: `{"Id":${item.id}}`,
};
};
CompileColumns = () => { const editPath = authentication.hasAccess("EditGlossary")
const { data } = this.props; ? "/glossaries/edit/{0}"
: undefined;
const doDelete = authentication.hasAccess("DeleteGlossary")
? onDelete
: undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
let columnsList = [...this.columns]; return (
<Table
data={paginatedData}
keyName="id"
columns={columnsList}
editPath={editPath}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
};
if (data?.childCustomFieldDefinition) export default GlossariesTable;
{
for( const customfield of data?.childCustomFieldDefinition)
{
columnsList.push({
key: String(customfield.id),
label: customfield.name,
order: "asc",
isCustom: true
})
}
}
this.setState({columnsList});
}
handleAuditParams = (item: any) => {
return {
entityName : "e_suite.Database.Core.Tables.Glossaries.Glossary",
primaryKey : "{\"Id\":"+item.id+"}"
}
}
render() {
const { onDelete } = this.props;
const { columnsList } = this.state;
const editPath = authentication.hasAccess("EditGlossary") ? "/glossaries/edit/{0}" : undefined;
const doDelete = authentication.hasAccess("DeleteGlossary") ? onDelete : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined;
const paginated = this.PaginatedData();
return <Table data={paginated} keyName="id" columns={columnsList} editPath={editPath} onDelete={doDelete} onAuditParams={showAudit}/>;
}
}
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,
} pageSize: 10,
count: 0,
totalPages: 1,
data: [],
});
const [sortColumn, setSortColumn] = useState<Column<ReadOrganisation>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
class Organisations extends Component<any, any, OrganisationsState> { const changePage = async (page: number, pageSize: number) => {
state = { const data = await organisationsService.getOrganisations(
loaded : false, page,
pagedData : { page: 1, pageSize,
pageSize : 10, sortColumn.key,
count: 0, sortColumn.order === "asc",
totalPages: 1, filters,
data: [] );
}, if (data) {
sortColumn: { key: "name", label: "Name", order: "asc" }, setLoaded(true);
filters: new Map<string, string>() setPagedData(data);
} else {
setLoaded(false);
} }
};
componentDidMount = async () => { const onSort = async (newSortColumn: Column<ReadOrganisation>) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const data = await organisationsService.getOrganisations(
page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
await this.changePage(page, pageSize); if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
} }
};
changePage = async (page: number, pageSize: number) => { const onSearch = async (name: string, value: string) => {
const { sortColumn, filters } = this.state; const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
const pagedData = await organisationsService.getOrganisations(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); newFilters.set(name, value);
if (pagedData) {
this.setState({ loaded: true, pagedData }); const data = await organisationsService.getOrganisations(
} page,
else { pageSize,
this.setState({ loaded: false }); sortColumn.key,
} sortColumn.order === "asc",
newFilters,
);
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
} }
};
onSort = async (sortColumn: Column<ReadOrganisation>) => { const onDelete = async (item?: ReadOrganisation) => {
const { page, pageSize } = this.state.pagedData; const response = await organisationsService.deleteOrganisation(
const { filters } = this.state; item?.id,
const pagedData = await organisationsService.getOrganisations(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); item?.guid,
);
if (pagedData) { if (response) {
this.setState({loaded: true, pagedData, sortColumn}); await changePage(pagedData.page, pagedData.pageSize);
}
else {
this.setState({ loaded: false });
}
} }
};
onSearch = async (name: string, value: string) => { useEffect(() => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const { sortColumn, filters } = this.state; changePage(page, pageSize);
filters.set(name, value); });
const pagedData = await organisationsService.getOrganisations(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); return (
if (pagedData) { <Loading loaded={loaded}>
this.setState( { loaded: true, filters, pagedData }); <Permission privilegeKey="AddOrganisation">
} <Button buttonType={ButtonType.primary} to="add">
else { {t("Add")}
this.setState({ loaded: false }); </Button>
} </Permission>
}; <hr />
<OrganisationsTable
onDelete = async (item?: ReadOrganisation) => { data={pagedData}
const response = await organisationsService.deleteOrganisation(item?.id, item?.guid); sortColumn={sortColumn}
if (response) { onChangePage={changePage}
this.componentDidMount(); onSort={onSort}
} onSearch={onSearch}
} onDelete={onDelete}
/>
render(): JSX.Element { </Loading>
const { loaded, pagedData, sortColumn } = this.state; );
return (
<Loading loaded={loaded}>
<Permission privilegeKey="AddOrganisation">
<Button buttonType={ButtonType.primary} to="add">Add</Button>
</Permission>
<hr/>
<OrganisationsTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/>
</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); };
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.Printer.Organisation",
primaryKey: `{"Id":${item.id}}`,
}; };
};
handleAuditParams = (item: any) => { const editPath = authentication.hasAccess("EditOrganisation")
return { ? "{0}"
entityName: "e_suite.Database.Core.Tables.Printer.Organisation", : undefined;
primaryKey: '{"Id":' + item.id + "}", const doDelete = authentication.hasAccess("DeleteOrganisation")
}; ? onDelete
}; : undefined;
const showAudit = authentication.hasAccess("ViewAuditLog")
? handleAuditParams
: undefined;
render() { return (
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; <Table
const editPath = authentication.hasAccess("EditOrganisation") ? "{0}" : undefined; data={data}
const doDelete = authentication.hasAccess("DeleteOrganisation") ? onDelete : undefined; keyName="id"
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; columns={columns}
sortColumn={sortColumn}
return ( editPath={editPath}
<Table onSort={raiseSort}
data={data} onChangePage={onChangePage}
keyName="id" onSearch={onSearch}
columns={this.columns} onDelete={doDelete}
sortColumn={sortColumn} onAuditParams={showAudit}
editPath={editPath} />
onSort={this.raiseSort} );
onChangePage={onChangePage} };
onSearch={onSearch}
onDelete={doDelete}
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>) => {
return { if (onSort !== undefined) onSort(sortCol);
entityName : "e_suite.Database.Core.Tables.Sequences.Sequence", };
primaryKey : "{\"Id\":"+item.id+"}"
}
}
render() { const handleAuditParams = (item: any) => {
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; return {
const editPath = authentication.hasAccess("EditSequence") ? "edit/{0}" : undefined; entityName: "e_suite.Database.Core.Tables.Sequences.Sequence",
const doDelete = authentication.hasAccess("DeleteSequence") ? onDelete : undefined; primaryKey: `{"Id":${item.id}}`,
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("EditSequence")
} ? "edit/{0}"
} : undefined;
const doDelete = authentication.hasAccess("DeleteSequence")
export default SequenceTable; ? 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 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>; page: 1,
} pageSize: 10,
count: 0,
totalPages: 1,
data: [],
});
const [sortColumn, setSortColumn] = useState<Column<ReadSequence>>({
key: "name",
label: t("Name"),
order: "asc",
});
const [filters, setFilters] = useState<Map<string, string>>(
new Map<string, string>(),
);
class Sequence extends Component<any, any, sequenceState> { const changePage = async (page: number, pageSize: number) => {
state = { const data = await sequenceService.getSequences(
loaded: false, page,
pagedData: { pageSize,
page: 1, sortColumn.key,
pageSize: 10, sortColumn.order === "asc",
count: 0, filters,
totalPages: 1, );
data: [] if (data) {
}, setLoaded(true);
sortColumn: { key: "name", label: "Name", order: "asc" }, setPagedData(data);
filters: new Map<string, string>() } else {
setLoaded(false);
} }
};
componentDidMount = async () => { const onSort = async (newSortColumn: Column<ReadSequence>) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const data = await sequenceService.getSequences(
await this.changePage(page, pageSize); page,
pageSize,
newSortColumn.key,
newSortColumn.order === "asc",
filters,
);
if (data) {
setLoaded(true);
setPagedData(data);
setSortColumn(newSortColumn);
} else {
setLoaded(false);
} }
};
changePage = async (page: number, pageSize: number) => { const onSearch = async (name: string, value: string) => {
const { sortColumn, filters } = this.state; const { page, pageSize } = pagedData;
const newFilters = new Map(filters);
newFilters.set(name, value);
const pagedData = await sequenceService.getSequences(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const data = await sequenceService.getSequences(
if (pagedData) { page,
this.setState({ loaded: true, pagedData }); pageSize,
} sortColumn.key,
else { sortColumn.order === "asc",
this.setState({ loaded: false }); newFilters,
} );
if (data) {
setLoaded(true);
setFilters(newFilters);
setPagedData(data);
} else {
setLoaded(false);
} }
};
onSort = async (sortColumn: Column<ReadSequence>) => { const onDelete = async (item?: ReadSequence) => {
const { page, pageSize } = this.state.pagedData; const response = await sequenceService.deleteSequence(item?.id, item?.guid);
const { filters } = this.state; if (response) {
const pagedData = await sequenceService.getSequences(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); await changePage(pagedData.page, pagedData.pageSize);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn });
}
else {
this.setState({ loaded: false });
}
} }
};
onSearch = async (name: string, value: string) => { useEffect(() => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = pagedData;
const { sortColumn, filters } = this.state; changePage(page, pageSize);
filters.set(name, value); }, []);
const pagedData = await sequenceService.getSequences(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); return (
if (pagedData) { <Loading loaded={loaded}>
this.setState({ loaded: true, filters, pagedData }); <Permission privilegeKey="AddSequence">
} <div>
else { <Button buttonType={ButtonType.primary} to="add">
this.setState({ loaded: false }); {t("Add")}
} </Button>
}; </div>
</Permission>
onDelete = async (item?: ReadSequence) => { <hr />
const response = await sequenceService.deleteSequence(item?.id, item?.guid); <SequenceTable
if (response) { data={pagedData}
this.componentDidMount(); sortColumn={sortColumn}
} onChangePage={changePage}
} onSort={onSort}
onSearch={onSearch}
render(): JSX.Element { onDelete={onDelete}
const { loaded, pagedData, sortColumn } = this.state; />
</Loading>
return ( );
<Loading loaded={loaded}>
<Permission privilegeKey="AddSequence">
<div>
<Button buttonType={ButtonType.primary} to="add">Add</Button>
</div>
</Permission>
<hr />
<SequenceTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete} />
</Loading>
);
}
}; };
export default Sequence; export default Sequence;

View File

@ -1,107 +1,127 @@
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, sortColumn: { key: "name", label: "Name", order: "asc" },
count: 0, filters: new Map<string, string>(),
totalPages: 1, };
data: [] },
sortColumn: { key: "name", label: "Name", order: "asc" }, componentDidMount = async () => {
filters: new Map<string, string>() const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize);
};
changePage = async (page: number, pageSize: number) => {
const { sortColumn, filters } = this.state;
const { organisationId } = this.props.router.params;
filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, pagedData, filters });
} else {
this.setState({ loaded: false });
} }
};
componentDidMount = async () => { onSort = async (sortColumn: Column<ReadSite>) => {
const { page, pageSize } = this.state.pagedData; const { page, pageSize } = this.state.pagedData;
await this.changePage(page, pageSize); const { filters } = this.state;
const { organisationId } = this.props.router.params;
filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(
page,
pageSize,
sortColumn.key,
sortColumn.order === "asc",
filters,
);
if (pagedData) {
this.setState({ loaded: true, pagedData, sortColumn });
} else {
this.setState({ loaded: false });
} }
};
changePage = async(page: number, pageSize : number) =>{ onSearch = async (name: string, value: string) => {
const { sortColumn, filters } = this.state; const { page, pageSize } = this.state.pagedData;
const { organisationId } = this.props.router.params; const { sortColumn, filters } = this.state;
filters.set(name, value);
filters.set("organisationId", organisationId); const { organisationId } = this.props.router.params;
filters.set("organisationId", organisationId);
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); const pagedData = await siteService.getSites(
if (pagedData) { page,
this.setState({ loaded: true, pagedData, filters }); pageSize,
} sortColumn.key,
else { sortColumn.order === "asc",
this.setState({ loaded: false }); filters,
} );
if (pagedData) {
this.setState({ loaded: true, filters, pagedData });
} else {
this.setState({ loaded: false });
} }
};
onSort = async(sortColumn : Column<ReadSite>) => { onDelete = async (item?: ReadSite) => {
const {page, pageSize } = this.state.pagedData; await siteService.deleteSite(item?.id, item?.guid);
const { filters } = this.state;
const { organisationId } = this.props.router.params; this.componentDidMount();
filters.set("organisationId", organisationId); };
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); render(): JSX.Element {
if (pagedData) { const { loaded, pagedData, sortColumn } = this.state;
this.setState({ loaded: true, pagedData, sortColumn });
}
else {
this.setState({ loaded: false });
}
}
onSearch = async ( name: string, value: string) => { return (
const {page, pageSize } = this.state.pagedData; <Loading loaded={loaded}>
const {sortColumn, filters } = this.state; <Permission privilegeKey="AddSite">
filters.set(name, value); <div>
<Button buttonType={ButtonType.primary} to="add">
const { organisationId } = this.props.router.params; Add
filters.set("organisationId", organisationId); </Button>
</div>
const pagedData = await siteService.getSites(page, pageSize, sortColumn.key, sortColumn.order === "asc", filters); </Permission>
if (pagedData) { <hr />
this.setState({ loaded: true, filters, pagedData }); <SitesTable
} data={pagedData}
else { sortColumn={sortColumn}
this.setState({ loaded: false }); onChangePage={this.changePage}
} onSort={this.onSort}
}; onSearch={this.onSearch}
onDelete={this.onDelete}
onDelete = async ( item? : ReadSite) => { />
await siteService.deleteSite( item?.id, item?.guid); </Loading>
);
this.componentDidMount(); }
} }
render(): JSX.Element {
const { loaded, pagedData, sortColumn } = this.state;
return (
<Loading loaded={loaded}>
<Permission privilegeKey="AddSite">
<div>
<Button buttonType={ButtonType.primary} to="add">Add</Button>
</div>
</Permission>
<hr/>
<SitesTable data={pagedData} sortColumn={sortColumn} onChangePage={this.changePage} onSort={this.onSort} onSearch={this.onSearch} onDelete={this.onDelete}/>
</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", {
label: "Name", key: "name",
order: "asc", label: t("Name"),
content: (item) => { order: "asc",
return ( content: (item) => (
<> <Button
<Button buttonType={ButtonType.link} to={"/specifications/" + item.organisationId.id + "/" + item.id}> buttonType={ButtonType.link}
{item.name} to={`/specifications/${item.organisationId.id}/${item.id}`}
</Button> >
</> {item.name}
); </Button>
}, ),
}, },
{ key: "address", label: "Address", order: "asc" }, { key: "address", label: t("Address"), order: "asc" },
{ key: "status", label: "Status", order: "asc" }, { key: "status", label: t("Status"), order: "asc" },
]; ],
[t, canViewSpecification],
);
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); };
const handleAuditParams = (item: any) => {
return {
entityName: "e_suite.Database.Core.Tables.Printer.Site",
primaryKey: `{"Id":${item.id}}`,
}; };
};
handleAuditParams = (item: any) => { const editPath = authentication.hasAccess("EditSite") ? "{0}" : undefined;
return { const doDelete = authentication.hasAccess("DeleteSite")
entityName: "e_suite.Database.Core.Tables.Printer.Site", ? onDelete
primaryKey: '{"Id":' + item.id + "}", : undefined;
}; const showAudit = authentication.hasAccess("ViewAuditLog")
}; ? handleAuditParams
: undefined;
render() { return (
const { data, sortColumn, onChangePage, onSearch, onDelete } = this.props; <Table
const editPath = authentication.hasAccess("EditSite") ? "{0}" : undefined; data={data}
const doDelete = authentication.hasAccess("DeleteSite") ? onDelete : undefined; keyName="id"
const showAudit = authentication.hasAccess("ViewAuditLog") ? this.handleAuditParams : undefined; columns={columns}
sortColumn={sortColumn}
return ( editPath={editPath}
<Table onSort={raiseSort}
data={data} onChangePage={onChangePage}
keyName="id" onSearch={onSearch}
columns={this.columns} onDelete={doDelete}
sortColumn={sortColumn} onAuditParams={showAudit}
editPath={editPath} />
onSort={this.raiseSort} );
onChangePage={onChangePage} };
onSearch={onSearch}
onDelete={doDelete}
onAuditParams={showAudit}
/>
);
}
}
export default SitesTable; export default SitesTable;