@syzy/apphost 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +4 -0
- package/dist/App.js +83 -0
- package/dist/AppHostProvider.d.ts +6 -0
- package/dist/AppHostProvider.js +4 -0
- package/dist/AppHostRoutes.d.ts +1 -0
- package/dist/AppHostRoutes.js +7 -0
- package/dist/api/image-api.d.ts +8 -0
- package/dist/api/image-api.js +45 -0
- package/dist/api/mapping-api.d.ts +80 -0
- package/dist/api/mapping-api.js +427 -0
- package/dist/bookingModule/components/AmenityForm.d.ts +3 -0
- package/dist/bookingModule/components/AmenityForm.js +19 -0
- package/dist/bookingModule/components/BillingManagement.d.ts +3 -0
- package/dist/bookingModule/components/BillingManagement.js +17 -0
- package/dist/bookingModule/components/CreateRoomForm.d.ts +3 -0
- package/dist/bookingModule/components/CreateRoomForm.js +19 -0
- package/dist/bookingModule/components/ExtraRequirementForm.d.ts +3 -0
- package/dist/bookingModule/components/ExtraRequirementForm.js +19 -0
- package/dist/bookingModule/components/ReservationForm.d.ts +3 -0
- package/dist/bookingModule/components/ReservationForm.js +18 -0
- package/dist/bookingModule/components/RoomCategoryForm.d.ts +3 -0
- package/dist/bookingModule/components/RoomCategoryForm.js +19 -0
- package/dist/bookingModule/components/RoomCategoryPriceForm.d.ts +3 -0
- package/dist/bookingModule/components/RoomCategoryPriceForm.js +20 -0
- package/dist/bookingModule/components/RoomExtraRequirementCapture.d.ts +3 -0
- package/dist/bookingModule/components/RoomExtraRequirementCapture.js +18 -0
- package/dist/bookingModule/components/RoomFacilityForm.d.ts +3 -0
- package/dist/bookingModule/components/RoomFacilityForm.js +19 -0
- package/dist/bookingModule/components/RoomReservationAction.d.ts +3 -0
- package/dist/bookingModule/components/RoomReservationAction.js +18 -0
- package/dist/components/Home/Home.d.ts +3 -0
- package/dist/components/Home/Home.js +14 -0
- package/dist/components/Loader/Loader.d.ts +2 -0
- package/dist/components/Loader/Loader.js +5 -0
- package/dist/components/Login/Login.d.ts +7 -0
- package/dist/components/Login/Login.js +149 -0
- package/dist/components/Login/loginSchema.d.ts +27 -0
- package/dist/components/Login/loginSchema.js +41 -0
- package/dist/components/Mappings/BranchMapping/Branch.d.ts +5 -0
- package/dist/components/Mappings/BranchMapping/Branch.js +135 -0
- package/dist/components/Mappings/BranchMapping/BranchTableColumns.d.ts +10 -0
- package/dist/components/Mappings/BranchMapping/BranchTableColumns.js +21 -0
- package/dist/components/Mappings/BranchMapping/MappingFormBranchUser.d.ts +3 -0
- package/dist/components/Mappings/BranchMapping/MappingFormBranchUser.js +150 -0
- package/dist/components/Mappings/BranchMapping/MappingTableColumns.d.ts +14 -0
- package/dist/components/Mappings/BranchMapping/MappingTableColumns.js +29 -0
- package/dist/components/Mappings/BranchMapping/branchSchema.d.ts +37 -0
- package/dist/components/Mappings/BranchMapping/branchSchema.js +34 -0
- package/dist/components/Mappings/ComponentMapping/ComponentRoleMapping.d.ts +3 -0
- package/dist/components/Mappings/ComponentMapping/ComponentRoleMapping.js +98 -0
- package/dist/components/Mappings/ComponentMapping/componentRoleColumns.d.ts +3 -0
- package/dist/components/Mappings/ComponentMapping/componentRoleColumns.js +29 -0
- package/dist/components/Mappings/MappingForm/MappingForm.d.ts +35 -0
- package/dist/components/Mappings/MappingForm/MappingForm.js +142 -0
- package/dist/components/Mappings/MappingForm/mappingSchema.d.ts +23 -0
- package/dist/components/Mappings/MappingForm/mappingSchema.js +32 -0
- package/dist/components/Mappings/RoleMapping/MappingFormUserRole.d.ts +5 -0
- package/dist/components/Mappings/RoleMapping/MappingFormUserRole.js +194 -0
- package/dist/components/Mappings/RoleMapping/UserRoleTableColumns.d.ts +3 -0
- package/dist/components/Mappings/RoleMapping/UserRoleTableColumns.js +33 -0
- package/dist/components/NavBar/Sidebar.d.ts +4 -0
- package/dist/components/NavBar/Sidebar.js +56 -0
- package/dist/components/ProfileForm/ProfileForm.d.ts +3 -0
- package/dist/components/ProfileForm/ProfileForm.js +190 -0
- package/dist/components/ProfileForm/ProfileList.d.ts +3 -0
- package/dist/components/ProfileForm/ProfileList.js +33 -0
- package/dist/components/ProfileForm/profileColumns.d.ts +3 -0
- package/dist/components/ProfileForm/profileColumns.js +67 -0
- package/dist/components/ProfileForm/profileSchema.d.ts +52 -0
- package/dist/components/ProfileForm/profileSchema.js +50 -0
- package/dist/components/SettingsPage/SettingsPage.d.ts +3 -0
- package/dist/components/SettingsPage/SettingsPage.js +240 -0
- package/dist/components/api/settings-api.d.ts +26 -0
- package/dist/components/api/settings-api.js +131 -0
- package/dist/components/common/Form/FormActionButtons.d.ts +11 -0
- package/dist/components/common/Form/FormActionButtons.js +6 -0
- package/dist/components/common/Form/FormLabel.d.ts +8 -0
- package/dist/components/common/Form/FormLabel.js +6 -0
- package/dist/components/common/ListTable/ListHeader.d.ts +8 -0
- package/dist/components/common/ListTable/ListHeader.js +5 -0
- package/dist/components/common/ListTable/ListTable.d.ts +17 -0
- package/dist/components/common/ListTable/ListTable.js +31 -0
- package/dist/components/common/Modal/Modal.d.ts +11 -0
- package/dist/components/common/Modal/Modal.js +6 -0
- package/dist/config/EnvConfig.d.ts +13 -0
- package/dist/config/EnvConfig.js +13 -0
- package/dist/config/amplifyConfig.d.ts +1 -0
- package/dist/config/amplifyConfig.js +45 -0
- package/dist/configureAppHost.d.ts +6 -0
- package/dist/configureAppHost.js +5 -0
- package/dist/customGraphQL/customMutations.d.ts +3 -0
- package/dist/customGraphQL/customMutations.js +53 -0
- package/dist/customGraphQL/customQueries.d.ts +7 -0
- package/dist/customGraphQL/customQueries.js +104 -0
- package/dist/domain/input/input-types.d.ts +47 -0
- package/dist/domain/input/input-types.js +1 -0
- package/dist/domain/model/BranchDto.d.ts +9 -0
- package/dist/domain/model/BranchDto.js +8 -0
- package/dist/domain/model/ComponentMappingDto.d.ts +24 -0
- package/dist/domain/model/ComponentMappingDto.js +19 -0
- package/dist/domain/model/MappingDto.d.ts +30 -0
- package/dist/domain/model/MappingDto.js +16 -0
- package/dist/domain/model/PrefixDescriptionDto.d.ts +16 -0
- package/dist/domain/model/PrefixDescriptionDto.js +13 -0
- package/dist/domain/model/ProfileDto.d.ts +21 -0
- package/dist/domain/model/ProfileDto.js +20 -0
- package/dist/domain/model/RoleMappingDto.d.ts +14 -0
- package/dist/domain/model/RoleMappingDto.js +19 -0
- package/dist/domain/model/SettingsDto.d.ts +8 -0
- package/dist/domain/model/SettingsDto.js +7 -0
- package/dist/domain/model/UserMappingDto.d.ts +14 -0
- package/dist/domain/model/UserMappingDto.js +28 -0
- package/dist/domain/model/imageDto.d.ts +4 -0
- package/dist/domain/model/imageDto.js +1 -0
- package/dist/domain/type/EntityTypes.d.ts +5 -0
- package/dist/domain/type/EntityTypes.js +6 -0
- package/dist/domain/type/MappingOptions.d.ts +5 -0
- package/dist/domain/type/MappingOptions.js +1 -0
- package/dist/domain/type/MappingTypes.d.ts +6 -0
- package/dist/domain/type/MappingTypes.js +7 -0
- package/dist/domain/type/Nullable.d.ts +13 -0
- package/dist/domain/type/Nullable.js +1 -0
- package/dist/domain/type/ResettingPeriodOptions.d.ts +2 -0
- package/dist/domain/type/ResettingPeriodOptions.js +8 -0
- package/dist/domain/type/RolesEnum.d.ts +6 -0
- package/dist/domain/type/RolesEnum.js +7 -0
- package/dist/domain/type/SelectType.d.ts +16 -0
- package/dist/domain/type/SelectType.js +1 -0
- package/dist/domain/type/StatusEnum.d.ts +5 -0
- package/dist/domain/type/StatusEnum.js +6 -0
- package/dist/domain/type/signUpOptions.d.ts +2 -0
- package/dist/domain/type/signUpOptions.js +4 -0
- package/dist/domain/type/statusOptions.d.ts +2 -0
- package/dist/domain/type/statusOptions.js +4 -0
- package/dist/graphql/profileQueries.d.ts +4 -0
- package/dist/graphql/profileQueries.js +89 -0
- package/dist/hoc/withSyzyAuth.d.ts +2 -0
- package/dist/hoc/withSyzyAuth.js +87 -0
- package/dist/hooks/useCurrentUser.d.ts +3 -0
- package/dist/hooks/useCurrentUser.js +6 -0
- package/dist/hooks/useDispatch.d.ts +3 -0
- package/dist/hooks/useDispatch.js +7 -0
- package/dist/hooks/usePermission.d.ts +1 -0
- package/dist/hooks/usePermission.js +7 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -15
- package/dist/main.d.ts +4 -0
- package/dist/main.js +60 -0
- package/dist/services/Client.Service.d.ts +12 -0
- package/dist/services/Client.Service.js +96 -0
- package/dist/services/Storage-service.d.ts +2 -0
- package/dist/services/Storage-service.js +26 -0
- package/dist/services/navigationMenu.d.ts +1 -0
- package/dist/services/navigationMenu.js +9 -0
- package/dist/static/constants.d.ts +34 -0
- package/dist/static/constants.js +34 -0
- package/dist/store/AppAction.d.ts +11 -0
- package/dist/store/AppAction.js +5 -0
- package/dist/store/AppContext.d.ts +3 -0
- package/dist/store/AppContext.js +3 -0
- package/dist/store/AppContextType.d.ts +12 -0
- package/dist/store/AppContextType.js +6 -0
- package/dist/store/AppProvider.d.ts +7 -0
- package/dist/store/AppProvider.js +32 -0
- package/dist/store/HostedInContainerContext.d.ts +5 -0
- package/dist/store/HostedInContainerContext.js +11 -0
- package/dist/store/SesssionReducer.d.ts +4 -0
- package/dist/store/SesssionReducer.js +16 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.js +14 -0
- package/dist/util/AuthUtils.d.ts +1 -0
- package/dist/util/AuthUtils.js +10 -0
- package/dist/util/LogEnum.d.ts +6 -0
- package/dist/util/LogEnum.js +7 -0
- package/dist/util/Logger.d.ts +6 -0
- package/dist/util/Logger.js +18 -0
- package/dist/util/SyzyDate.d.ts +69 -0
- package/dist/util/SyzyDate.js +265 -0
- package/dist/util/dateUtils.d.ts +10 -0
- package/dist/util/dateUtils.js +24 -0
- package/dist/util/hostedinContainer.d.ts +1 -0
- package/dist/util/hostedinContainer.js +9 -0
- package/dist/util/model-types.d.ts +96 -0
- package/dist/util/model-types.js +18 -0
- package/dist/util/prefixAndResettingValidation.d.ts +9 -0
- package/dist/util/prefixAndResettingValidation.js +54 -0
- package/dist/util/transformToData.d.ts +1 -0
- package/dist/util/transformToData.js +9 -0
- package/package.json +14 -9
- package/dist/__federation_shared_@tanstack/react-query-DHuUsaNz.js +0 -2517
- package/dist/__federation_shared_react-CikWE6qG.js +0 -7
- package/dist/__federation_shared_react-bootstrap-BKlZRvMR.js +0 -7516
- package/dist/__federation_shared_react-dom-vrQ70Ay8.js +0 -372
- package/dist/__federation_shared_react-router-dom-BKminmS4.js +0 -10448
- package/dist/__federation_shared_react-select-B6kehBDI.js +0 -4056
- package/dist/__federation_shared_react-toastify-B0S0UGr3.js +0 -412
- package/dist/_commonjsHelpers-C6fGbg64.js +0 -6
- package/dist/_virtual___federation_fn_import-XZCKozko.js +0 -217
- package/dist/favicon.ico +0 -0
- package/dist/index-DgtWMtjZ.js +0 -184
- package/dist/index-eZknuYwc.js +0 -1219
- package/dist/jsx-runtime-D_t4bG-_.js +0 -264
- package/dist/manifest.webmanifest +0 -1
- package/dist/pwa/Hotel-icon.jpg +0 -0
- package/dist/pwa/apple-touch-icon-180x180.png +0 -0
- package/dist/pwa/favicon.ico +0 -0
- package/dist/pwa/maskable-icon-512x512.png +0 -0
- package/dist/pwa/pwa-192x192.png +0 -0
- package/dist/pwa/pwa-512x512.png +0 -0
- package/dist/pwa/pwa-64x64.png +0 -0
- package/dist/registerSW.js +0 -1
- package/dist/sw.js +0 -1
- package/dist/workbox-1ef09536.js +0 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Form, Col } from "react-bootstrap";
|
|
4
|
+
import Select from "react-select";
|
|
5
|
+
import { useForm } from "react-hook-form";
|
|
6
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
7
|
+
import './MappingForm.css';
|
|
8
|
+
import { statusOptions } from "../../../domain/type/statusOptions";
|
|
9
|
+
import { Status } from "../../../domain/type/StatusEnum";
|
|
10
|
+
import '../../../styles/button.css';
|
|
11
|
+
import { mappingFormSchema } from "./mappingSchema";
|
|
12
|
+
import FormActionButtons from "../../common/Form/FormActionButtons";
|
|
13
|
+
import FormLabel from "../../common/Form/FormLabel";
|
|
14
|
+
const MappingForm = ({ branchOptions = [], sourceLabel, targetLabel, sourceOptions, targetOptions, onSubmit, mode = "default", hideBranch = false, hideTarget = false, onSourceChange, selectedUserBranch, initialMapping, userHasNoBranch }) => {
|
|
15
|
+
const showBranchUserOnly = mode === "branch-user";
|
|
16
|
+
const { handleSubmit, setValue, formState: { errors } } = useForm({
|
|
17
|
+
resolver: zodResolver(mappingFormSchema),
|
|
18
|
+
defaultValues: {
|
|
19
|
+
branchSelections: [],
|
|
20
|
+
sourceSelections: [],
|
|
21
|
+
targetSelections: [],
|
|
22
|
+
status: Status.Active,
|
|
23
|
+
hideBranch,
|
|
24
|
+
hideTarget
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const [selectedBranches, setSelectedBranches] = useState([]);
|
|
28
|
+
const [selectedSources, setSelectedSources] = useState([]);
|
|
29
|
+
const [selectedTargets, setSelectedTargets] = useState([]);
|
|
30
|
+
const [status, setStatus] = useState(Status.Active);
|
|
31
|
+
const toSelectOption = (opt, type) => {
|
|
32
|
+
if (type === "source" && sourceLabel === "User") {
|
|
33
|
+
return {
|
|
34
|
+
value: opt.id,
|
|
35
|
+
label: `${opt.name} (${opt.id})`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
value: opt.id,
|
|
40
|
+
label: opt.name,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/** Prefill form if editing */
|
|
44
|
+
const hasInitialized = useRef(false);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!initialMapping || hasInitialized.current)
|
|
47
|
+
return;
|
|
48
|
+
if (sourceOptions.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
hasInitialized.current = true;
|
|
51
|
+
// Branch
|
|
52
|
+
if (!hideBranch && initialMapping.branchId) {
|
|
53
|
+
const branchOpt = branchOptions.find(b => b.id === initialMapping.branchId);
|
|
54
|
+
if (branchOpt) {
|
|
55
|
+
setSelectedBranches([branchOpt]);
|
|
56
|
+
setValue("branchSelections", [branchOpt], { shouldDirty: false });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Source (User)
|
|
60
|
+
const srcOpt = sourceOptions.find(s => s.id === initialMapping.sourceId);
|
|
61
|
+
if (srcOpt) {
|
|
62
|
+
setSelectedSources([srcOpt]);
|
|
63
|
+
setValue("sourceSelections", [srcOpt], { shouldDirty: false });
|
|
64
|
+
}
|
|
65
|
+
// Target (Role)
|
|
66
|
+
if (initialMapping.targetId) {
|
|
67
|
+
const tgtOpt = targetOptions.find(t => t.id === initialMapping.targetId);
|
|
68
|
+
if (tgtOpt) {
|
|
69
|
+
setSelectedTargets([tgtOpt]);
|
|
70
|
+
setValue("targetSelections", [tgtOpt], { shouldDirty: false });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Status
|
|
74
|
+
setStatus(initialMapping.status);
|
|
75
|
+
setValue("status", initialMapping.status, { shouldDirty: false });
|
|
76
|
+
}, [initialMapping, sourceOptions]);
|
|
77
|
+
/** Clear form */
|
|
78
|
+
const handleClear = () => {
|
|
79
|
+
setSelectedBranches([]);
|
|
80
|
+
setSelectedSources([]);
|
|
81
|
+
setSelectedTargets([]);
|
|
82
|
+
setStatus(Status.Active);
|
|
83
|
+
setValue("branchSelections", []);
|
|
84
|
+
setValue("sourceSelections", []);
|
|
85
|
+
setValue("targetSelections", []);
|
|
86
|
+
setValue("status", Status.Active);
|
|
87
|
+
};
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
setValue("hideBranch", hideBranch, { shouldValidate: true });
|
|
90
|
+
setValue("hideTarget", hideTarget, { shouldValidate: true });
|
|
91
|
+
}, [hideBranch, hideTarget]);
|
|
92
|
+
/** Submit handler */
|
|
93
|
+
const handleZodSubmit = (formData) => {
|
|
94
|
+
let mappings = [];
|
|
95
|
+
if (hideBranch) {
|
|
96
|
+
const branchId = branchOptions?.[0]?.id || "DEFAULT_BRANCH";
|
|
97
|
+
mappings = formData.sourceSelections.flatMap(src => formData.targetSelections.map(tgt => ({
|
|
98
|
+
branchId,
|
|
99
|
+
sourceId: src.id,
|
|
100
|
+
targetId: tgt.id,
|
|
101
|
+
status: formData.status
|
|
102
|
+
})));
|
|
103
|
+
}
|
|
104
|
+
else if (showBranchUserOnly) {
|
|
105
|
+
mappings = formData.branchSelections.flatMap(branch => formData.sourceSelections.map(src => ({
|
|
106
|
+
branchId: branch.id,
|
|
107
|
+
sourceId: src.id,
|
|
108
|
+
targetId: "",
|
|
109
|
+
status: formData.status
|
|
110
|
+
})));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
mappings = formData.branchSelections.flatMap(branch => formData.sourceSelections.flatMap(src => formData.targetSelections.map(tgt => ({
|
|
114
|
+
branchId: branch.id,
|
|
115
|
+
sourceId: src.id,
|
|
116
|
+
targetId: tgt.id,
|
|
117
|
+
status: formData.status
|
|
118
|
+
}))));
|
|
119
|
+
}
|
|
120
|
+
onSubmit(mappings);
|
|
121
|
+
handleClear();
|
|
122
|
+
};
|
|
123
|
+
return (_jsxs(Form, { onSubmit: handleSubmit(handleZodSubmit), className: "mapping-form", children: [!hideBranch && (_jsxs(Col, { children: [_jsx(FormLabel, { label: "Branch", required: true }), _jsx(Select, { isMulti: true, options: branchOptions.map(opt => toSelectOption(opt, "branch")), value: selectedBranches.map(opt => toSelectOption(opt, "branch")), closeMenuOnSelect: false, onChange: (selected) => {
|
|
124
|
+
const formatted = selected?.map(s => ({ id: s.value, name: s.label })) || [];
|
|
125
|
+
setSelectedBranches(formatted);
|
|
126
|
+
setValue("branchSelections", formatted, { shouldValidate: true, shouldDirty: true, });
|
|
127
|
+
} }), errors.branchSelections && _jsx(Form.Text, { className: "text-danger", children: errors.branchSelections.message })] })), !hideTarget && (_jsxs(Col, { children: [_jsx(FormLabel, { label: targetLabel, required: true }), _jsx(Select, { isMulti: true, options: targetOptions.map(opt => toSelectOption(opt, "target")), value: selectedTargets.map(opt => toSelectOption(opt, "target")), closeMenuOnSelect: false, onChange: (selected) => {
|
|
128
|
+
const formatted = selected?.map(s => ({ id: s.value, name: s.label })) || [];
|
|
129
|
+
setSelectedTargets(formatted);
|
|
130
|
+
setValue("targetSelections", formatted, { shouldValidate: true, shouldDirty: true, });
|
|
131
|
+
} }), errors.targetSelections && (_jsx(Form.Text, { className: "text-danger", children: errors.targetSelections.message }))] })), _jsxs(Col, { children: [_jsx(FormLabel, { label: sourceLabel, required: true }), _jsx(Select, { isMulti: true, options: sourceOptions.map(opt => toSelectOption(opt, "source")), value: selectedSources.map(opt => toSelectOption(opt, "source")), closeMenuOnSelect: false, onChange: (selected) => {
|
|
132
|
+
const formatted = selected?.map(s => ({ id: s.value, name: sourceOptions.find(opt => opt.id === s.value)?.name || "" })) || [];
|
|
133
|
+
setSelectedSources(formatted);
|
|
134
|
+
setValue("sourceSelections", formatted, { shouldValidate: true, shouldDirty: true, });
|
|
135
|
+
onSourceChange?.(formatted);
|
|
136
|
+
} }), errors.sourceSelections && _jsx(Form.Text, { className: "text-danger", children: errors.sourceSelections.message }), selectedUserBranch && selectedUserBranch.length > 0 && (_jsxs("div", { className: "mt-1 text-primary fw-bold", children: ["Branch: ", selectedUserBranch.join(", ")] })), userHasNoBranch && (_jsx("div", { className: "mt-2 text-danger fw-semibold", children: "\u26A0\uFE0F Selected user is not assigned to any branch. Please assign a branch before mapping roles." }))] }), _jsxs(Col, { children: [_jsx(FormLabel, { label: "Status" }), _jsx(Select, { isClearable: false, options: statusOptions, closeMenuOnSelect: false, value: statusOptions.find(s => s.value.toUpperCase() === status.toUpperCase()), onChange: (selected) => {
|
|
137
|
+
const newStatus = selected?.value || Status.Active;
|
|
138
|
+
setStatus(newStatus);
|
|
139
|
+
setValue("status", newStatus);
|
|
140
|
+
} })] }), _jsx(FormActionButtons, { isEditMode: !!initialMapping, onClear: handleClear, disableSubmit: userHasNoBranch })] }));
|
|
141
|
+
};
|
|
142
|
+
export default MappingForm;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const mappingOptionSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
}, z.core.$strip>;
|
|
6
|
+
export declare const mappingFormSchema: z.ZodObject<{
|
|
7
|
+
branchSelections: z.ZodArray<z.ZodObject<{
|
|
8
|
+
id: z.ZodString;
|
|
9
|
+
name: z.ZodString;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
sourceSelections: z.ZodArray<z.ZodObject<{
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
name: z.ZodString;
|
|
14
|
+
}, z.core.$strip>>;
|
|
15
|
+
targetSelections: z.ZodArray<z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
}, z.core.$strip>>;
|
|
19
|
+
status: z.ZodString;
|
|
20
|
+
hideBranch: z.ZodBoolean;
|
|
21
|
+
hideTarget: z.ZodBoolean;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
export type MappingFormInputs = z.infer<typeof mappingFormSchema>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const mappingOptionSchema = z.object({
|
|
3
|
+
id: z.string().min(1, "Invalid option id"),
|
|
4
|
+
name: z.string().min(1, "Invalid option name"),
|
|
5
|
+
});
|
|
6
|
+
export const mappingFormSchema = z.object({
|
|
7
|
+
branchSelections: z.array(mappingOptionSchema),
|
|
8
|
+
sourceSelections: z.array(mappingOptionSchema)
|
|
9
|
+
.min(1, "Please select at least one source"),
|
|
10
|
+
targetSelections: z.array(mappingOptionSchema),
|
|
11
|
+
status: z.string().min(1, "Status is required"),
|
|
12
|
+
hideBranch: z.boolean(), // REQUIRED
|
|
13
|
+
hideTarget: z.boolean(), // REQUIRED
|
|
14
|
+
})
|
|
15
|
+
.refine((data) => {
|
|
16
|
+
if (!data.hideBranch && data.branchSelections.length === 0) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}, {
|
|
21
|
+
message: "Please select at least one branch",
|
|
22
|
+
path: ["branchSelections"]
|
|
23
|
+
})
|
|
24
|
+
.refine((data) => {
|
|
25
|
+
if (!data.hideTarget && data.targetSelections.length === 0) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}, {
|
|
30
|
+
message: "Please select at least one target",
|
|
31
|
+
path: ["targetSelections"]
|
|
32
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import MappingForm from "../MappingForm/MappingForm";
|
|
4
|
+
import FormModal from "../../common/Modal/Modal";
|
|
5
|
+
import ListTable from "../../common/ListTable/ListTable";
|
|
6
|
+
import { toast } from "react-toastify";
|
|
7
|
+
import { Status } from "../../../domain/type/StatusEnum";
|
|
8
|
+
import { getBranchIdByUserId, useCreateMappingMutation, useListProfiles, useUpdateMappingMutation, fetchUserRoleMappings, getBranchNameById, } from "../../../api/mapping-api";
|
|
9
|
+
import { SyzyDate } from "../../../util/SyzyDate";
|
|
10
|
+
import { EntityTypes } from "../../../domain/type/EntityTypes";
|
|
11
|
+
import { DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS } from "../../../util/dateUtils";
|
|
12
|
+
import { logger } from "../../../util/Logger";
|
|
13
|
+
import { UserRoleTableColumns } from "./UserRoleTableColumns";
|
|
14
|
+
import ListHeader from "../../common/ListTable/ListHeader";
|
|
15
|
+
import { ToastContainer } from "react-toastify";
|
|
16
|
+
/* ---------------- Roles ---------------- */
|
|
17
|
+
export const roles = [
|
|
18
|
+
{ id: "Role#01", name: "SUPERADMIN" },
|
|
19
|
+
{ id: "Role#02", name: "SUPPORTADMIN" },
|
|
20
|
+
{ id: "Role#03", name: "ADMIN" },
|
|
21
|
+
{ id: "Role#04", name: "EMPLOYEE" },
|
|
22
|
+
];
|
|
23
|
+
const MappingFormUserRole = () => {
|
|
24
|
+
const [showModal, setShowModal] = useState(false);
|
|
25
|
+
const [editingRow, setEditingRow] = useState();
|
|
26
|
+
const [users, setUsers] = useState([]);
|
|
27
|
+
const [mappings, setMappings] = useState([]);
|
|
28
|
+
const [loading, setLoading] = useState(true);
|
|
29
|
+
const [selectedUserBranch, setSelectedUserBranch] = useState([]);
|
|
30
|
+
const [isUserSelected, setIsUserSelected] = useState(false);
|
|
31
|
+
const currentISODate = new SyzyDate().toDateFormatString(DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS);
|
|
32
|
+
const { data: profiles, isLoading } = useListProfiles();
|
|
33
|
+
const createMappingMutation = useCreateMappingMutation();
|
|
34
|
+
const updateMappingMutation = useUpdateMappingMutation();
|
|
35
|
+
const tableLoading = isLoading || createMappingMutation.isPending || updateMappingMutation.isPending;
|
|
36
|
+
const userHasNoBranch = isUserSelected && selectedUserBranch.length === 0 && !editingRow;
|
|
37
|
+
const handleUserChange = async (selectedUsers) => {
|
|
38
|
+
if (selectedUsers.length === 1) {
|
|
39
|
+
setIsUserSelected(true);
|
|
40
|
+
const userId = selectedUsers[0].id;
|
|
41
|
+
const branchPk = await getBranchIdByUserId(userId);
|
|
42
|
+
if (branchPk.length === 0) {
|
|
43
|
+
setSelectedUserBranch([]);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const branchName = await Promise.all(branchPk.map(async (id) => await getBranchNameById(id)));
|
|
47
|
+
setSelectedUserBranch(branchName);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
setIsUserSelected(false);
|
|
51
|
+
setSelectedUserBranch([]);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/* ---------------- Load Users ---------------- */
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (profiles) {
|
|
57
|
+
setUsers(profiles.map((p) => ({ id: p.sk, name: p.name })));
|
|
58
|
+
}
|
|
59
|
+
}, [profiles]);
|
|
60
|
+
/* ---------------- Load User-Role Mappings ---------------- */
|
|
61
|
+
const loadMappings = async () => {
|
|
62
|
+
try {
|
|
63
|
+
const result = await fetchUserRoleMappings();
|
|
64
|
+
const enriched = await Promise.all(result.map(async (m) => {
|
|
65
|
+
// Extract branchId from pk
|
|
66
|
+
const match = m.pk.match(/^BRANCH#([^#]+)#USER#/);
|
|
67
|
+
const branchId = match ? match[1] : "";
|
|
68
|
+
const branchName = branchId ? await getBranchNameById(branchId) : "";
|
|
69
|
+
return {
|
|
70
|
+
...m,
|
|
71
|
+
branchId,
|
|
72
|
+
branchName,
|
|
73
|
+
};
|
|
74
|
+
}));
|
|
75
|
+
setMappings(enriched);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
toast.error("Failed to load user-role mappings");
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
setLoading(false);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
loadMappings();
|
|
86
|
+
}, []);
|
|
87
|
+
/* ---------------- Add / Edit ---------------- */
|
|
88
|
+
const handleAdd = () => {
|
|
89
|
+
setEditingRow(undefined);
|
|
90
|
+
setShowModal(true);
|
|
91
|
+
setSelectedUserBranch([]);
|
|
92
|
+
setIsUserSelected(false);
|
|
93
|
+
};
|
|
94
|
+
const handleEdit = (row) => {
|
|
95
|
+
setEditingRow(row);
|
|
96
|
+
setSelectedUserBranch([row.branchName]);
|
|
97
|
+
setIsUserSelected(true);
|
|
98
|
+
setShowModal(true);
|
|
99
|
+
};
|
|
100
|
+
/* ---------------- Submit ---------------- */
|
|
101
|
+
const handleSubmit = async (data) => {
|
|
102
|
+
try {
|
|
103
|
+
for (const map of data) {
|
|
104
|
+
const user = users.find(u => u.id === map.sourceId);
|
|
105
|
+
const role = roles.find(r => r.id === map.targetId);
|
|
106
|
+
if (!user || !role)
|
|
107
|
+
continue;
|
|
108
|
+
if (editingRow) {
|
|
109
|
+
const isRoleChanged = editingRow.roleId !== role.id;
|
|
110
|
+
const isUserChanged = editingRow.userId !== user.id;
|
|
111
|
+
if (isRoleChanged || isUserChanged) {
|
|
112
|
+
const buildInactivePayload = (row, disabledDt) => ({
|
|
113
|
+
pk: editingRow.pk,
|
|
114
|
+
sk: row.roleId,
|
|
115
|
+
entity: EntityTypes.ROLE,
|
|
116
|
+
userId: row.userId,
|
|
117
|
+
branchName: editingRow.branchName,
|
|
118
|
+
userName: row.userName,
|
|
119
|
+
roleId: row.roleId,
|
|
120
|
+
roleName: row.roleName,
|
|
121
|
+
componentId: "null",
|
|
122
|
+
componentTitle: "null",
|
|
123
|
+
status: Status.Inactive,
|
|
124
|
+
createdDt: row.createdDt,
|
|
125
|
+
createdBy: `${user.id}#${user.name}`,
|
|
126
|
+
disabledDt,
|
|
127
|
+
});
|
|
128
|
+
// 1️⃣ Deactivate OLD role for THIS branch only
|
|
129
|
+
await updateMappingMutation.mutateAsync(buildInactivePayload(editingRow, currentISODate));
|
|
130
|
+
// 2️⃣ Create NEW role for SAME branch only
|
|
131
|
+
const newPayload = {
|
|
132
|
+
pk: editingRow.pk,
|
|
133
|
+
sk: role.id,
|
|
134
|
+
entity: EntityTypes.ROLE,
|
|
135
|
+
userId: user.id,
|
|
136
|
+
branchName: editingRow.branchName,
|
|
137
|
+
userName: user.name,
|
|
138
|
+
roleId: role.id,
|
|
139
|
+
roleName: role.name,
|
|
140
|
+
componentId: "null",
|
|
141
|
+
componentTitle: "null",
|
|
142
|
+
status: Status.Active,
|
|
143
|
+
createdDt: currentISODate,
|
|
144
|
+
createdBy: `${user.id}#${user.name}`,
|
|
145
|
+
disabledDt: "",
|
|
146
|
+
};
|
|
147
|
+
await createMappingMutation.mutateAsync(newPayload);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const branchIds = await getBranchIdByUserId(user.id);
|
|
152
|
+
for (const branchId of branchIds) {
|
|
153
|
+
const branchName = await getBranchNameById(branchId);
|
|
154
|
+
const payload = {
|
|
155
|
+
pk: `${branchId}#USER#${user.id}`,
|
|
156
|
+
sk: role.id,
|
|
157
|
+
entity: EntityTypes.ROLE,
|
|
158
|
+
userId: user.id,
|
|
159
|
+
branchName,
|
|
160
|
+
userName: user.name,
|
|
161
|
+
roleId: role.id,
|
|
162
|
+
roleName: role.name,
|
|
163
|
+
componentId: "null",
|
|
164
|
+
componentTitle: "null",
|
|
165
|
+
status: map.status,
|
|
166
|
+
createdDt: currentISODate,
|
|
167
|
+
createdBy: `${user.id}#${user.name}`,
|
|
168
|
+
disabledDt: "",
|
|
169
|
+
};
|
|
170
|
+
await createMappingMutation.mutateAsync(payload);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
toast.success("User-Role mapping saved successfully");
|
|
175
|
+
setShowModal(false);
|
|
176
|
+
loadMappings();
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
logger.error(err);
|
|
180
|
+
toast.error("User-Role mapping failed");
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
/* ---------------- Render ---------------- */
|
|
184
|
+
return (_jsxs(_Fragment, { children: [_jsx(ToastContainer, {}), _jsxs("div", { className: "container", children: [_jsx(ListHeader, { title: "User & Role Mappings List", buttonLabel: "Add Mapping", onButtonClick: handleAdd }), loading ? null : (_jsx(ListTable, { columns: UserRoleTableColumns, data: mappings, emptyMessage: "No user-role mappings found", onEdit: handleEdit, loading: tableLoading })), _jsx(FormModal, { show: showModal, title: editingRow ? "Edit User-Role Mapping" : "Assign Role to User", onClose: () => setShowModal(false), size: "lg", children: _jsx(MappingForm, { mode: "default", hideBranch: true, hideTarget: false, sourceLabel: "User", targetLabel: "Role", sourceOptions: users, targetOptions: roles, onSubmit: handleSubmit, onSourceChange: handleUserChange, selectedUserBranch: selectedUserBranch ?? "", userHasNoBranch: userHasNoBranch, initialMapping: editingRow
|
|
185
|
+
? {
|
|
186
|
+
sourceId: editingRow.userId,
|
|
187
|
+
sourceName: editingRow.userName,
|
|
188
|
+
branchName: editingRow.branchName,
|
|
189
|
+
targetId: editingRow.roleId,
|
|
190
|
+
status: editingRow.status,
|
|
191
|
+
}
|
|
192
|
+
: undefined }) })] })] }));
|
|
193
|
+
};
|
|
194
|
+
export default MappingFormUserRole;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Status } from "../../../domain/type/StatusEnum";
|
|
3
|
+
export const UserRoleTableColumns = [
|
|
4
|
+
{
|
|
5
|
+
header: "ID",
|
|
6
|
+
accessor: "userId",
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
header: "User",
|
|
10
|
+
accessor: "userName",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
header: "Branch",
|
|
14
|
+
accessor: (row) => row.branchName || "-",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
header: "Role",
|
|
18
|
+
accessor: "roleName",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
header: "Created",
|
|
22
|
+
accessor: (row) => row.createdDt ? new Date(row.createdDt).toLocaleString() : "-",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
header: "Disabled",
|
|
26
|
+
accessor: (row) => row.disabledDt ? new Date(row.disabledDt).toLocaleString() : "-",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
header: "Status",
|
|
30
|
+
accessor: (row) => (_jsx("span", { className: `status-message ${row.status === Status.Active ? "text-success" : "text-danger"}`, children: row.status })),
|
|
31
|
+
align: "center",
|
|
32
|
+
},
|
|
33
|
+
];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
|
+
import { NavLink, useNavigate } from "react-router-dom";
|
|
4
|
+
import { getSidebarMenu } from "../../services/navigationMenu";
|
|
5
|
+
import { Link } from "react-router-dom";
|
|
6
|
+
import './sidebar.css';
|
|
7
|
+
import { useDispatch } from "../../hooks/useDispatch";
|
|
8
|
+
import { signOut } from "aws-amplify/auth";
|
|
9
|
+
import { AppActionEnum } from "../../store/AppAction";
|
|
10
|
+
import { RiLogoutBoxLine } from "react-icons/ri";
|
|
11
|
+
import { FaArrowRight } from "react-icons/fa";
|
|
12
|
+
import { FaArrowLeft } from "react-icons/fa";
|
|
13
|
+
import { FaChevronDown, FaChevronUp } from "react-icons/fa";
|
|
14
|
+
import * as FA from "react-icons/fa";
|
|
15
|
+
import * as FA6 from "react-icons/fa6";
|
|
16
|
+
import * as IO from "react-icons/io5";
|
|
17
|
+
import * as IO4 from "react-icons/io";
|
|
18
|
+
import * as RI from "react-icons/ri";
|
|
19
|
+
const iconPacks = { FA, FA6, IO, IO4, RI };
|
|
20
|
+
const Sidebar = () => {
|
|
21
|
+
const navigate = useNavigate();
|
|
22
|
+
const { dispatch } = useDispatch();
|
|
23
|
+
const [menus, setMenus] = useState([]);
|
|
24
|
+
const [activeMenu, setActiveMenu] = useState(null);
|
|
25
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
26
|
+
const handleToggle = () => {
|
|
27
|
+
setIsExpanded(prevState => !prevState);
|
|
28
|
+
};
|
|
29
|
+
const handleMenuClick = (menu) => {
|
|
30
|
+
setActiveMenu(prevMenu => (prevMenu === menu ? null : menu));
|
|
31
|
+
};
|
|
32
|
+
const signOutFn = async () => {
|
|
33
|
+
await signOut({ global: true });
|
|
34
|
+
dispatch({ type: AppActionEnum.SignOut });
|
|
35
|
+
navigate("/");
|
|
36
|
+
};
|
|
37
|
+
const getIcon = (iconName, pack = "FA") => {
|
|
38
|
+
const library = iconPacks[pack] || FA;
|
|
39
|
+
return library[iconName] ? React.createElement(library[iconName]) : null;
|
|
40
|
+
};
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const fetchMenu = async () => {
|
|
43
|
+
const data = await getSidebarMenu();
|
|
44
|
+
setMenus(data);
|
|
45
|
+
};
|
|
46
|
+
fetchMenu();
|
|
47
|
+
}, []);
|
|
48
|
+
return (_jsx(_Fragment, { children: _jsx("div", { className: "wrapper", children: _jsxs("aside", { id: "sidebar", className: isExpanded ? '' : 'expand', children: [_jsxs("div", { children: [_jsx("button", { type: "button", className: "toggle-btn", onClick: handleToggle, children: isExpanded ? _jsx(FaArrowRight, { className: 'icon' }) : _jsx(FaArrowLeft, { className: 'icon' }) }), _jsx("div", { className: "sidebar-logo", children: _jsxs("div", { children: [_jsx(Link, { to: '/', children: "HMS" }), _jsx("br", {}), _jsx("span", { children: "Salem" })] }) })] }), _jsxs("ul", { className: "sidebar-nav", children: [menus.map((menu, index) => (_jsx("li", { className: "sidebar-item", children: menu.children && menu.children.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Link, { to: menu.children[0].path, className: `d-flex justify-content-between sidebar-link has-dropdown ${menu.children.some((child) => location.pathname.startsWith(child.path))
|
|
49
|
+
? "active" : ""}`, onClick: (e) => {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
handleMenuClick(menu.title);
|
|
52
|
+
}, "aria-controls": `menu-${index}`, children: [_jsxs("div", { children: [_jsx("span", { className: "icon", children: getIcon(menu.icon, menu.iconPack) }), _jsx("span", { className: "label", children: menu.title })] }), _jsx("span", { className: "arrow-icon d-flex justify-content-center align-items-center", children: activeMenu === menu.title ? _jsx(FaChevronUp, {}) : _jsx(FaChevronDown, {}) })] }), _jsx("ul", { id: `menu-${index}`, className: `sidebar-dropdown list-unstyled ${activeMenu === menu.title ? "show" : "collapse"}`, children: menu.children.map((child, cIndex) => (_jsx("li", { className: "sidebar-item", children: _jsx(Link, { to: child.path, className: `sidebar-link ${location.pathname === child.path ? "active-child" : ""}`, children: _jsx("span", { className: "label test", children: child.title }) }) }, cIndex))) })] })) : (
|
|
53
|
+
// Normal single-level item
|
|
54
|
+
_jsxs(NavLink, { to: menu.path, className: ({ isActive }) => `sidebar-link d-flex align-items-center ${isActive ? "active-link" : ""}`, children: [_jsx("div", { className: "icon", children: getIcon(menu.icon, menu.iconPack) }), _jsx("div", { className: "label", children: menu.title })] })) }, index))), _jsx("li", { className: "sidebar-item", children: _jsxs(Link, { to: '/', className: "sidebar-link", onClick: signOutFn, children: [_jsx(RiLogoutBoxLine, { className: 'log-icon' }), _jsx("span", { className: "label", children: "Logout" })] }) })] })] }) }) }));
|
|
55
|
+
};
|
|
56
|
+
export default Sidebar;
|