@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.
Files changed (213) hide show
  1. package/dist/App.d.ts +4 -0
  2. package/dist/App.js +83 -0
  3. package/dist/AppHostProvider.d.ts +6 -0
  4. package/dist/AppHostProvider.js +4 -0
  5. package/dist/AppHostRoutes.d.ts +1 -0
  6. package/dist/AppHostRoutes.js +7 -0
  7. package/dist/api/image-api.d.ts +8 -0
  8. package/dist/api/image-api.js +45 -0
  9. package/dist/api/mapping-api.d.ts +80 -0
  10. package/dist/api/mapping-api.js +427 -0
  11. package/dist/bookingModule/components/AmenityForm.d.ts +3 -0
  12. package/dist/bookingModule/components/AmenityForm.js +19 -0
  13. package/dist/bookingModule/components/BillingManagement.d.ts +3 -0
  14. package/dist/bookingModule/components/BillingManagement.js +17 -0
  15. package/dist/bookingModule/components/CreateRoomForm.d.ts +3 -0
  16. package/dist/bookingModule/components/CreateRoomForm.js +19 -0
  17. package/dist/bookingModule/components/ExtraRequirementForm.d.ts +3 -0
  18. package/dist/bookingModule/components/ExtraRequirementForm.js +19 -0
  19. package/dist/bookingModule/components/ReservationForm.d.ts +3 -0
  20. package/dist/bookingModule/components/ReservationForm.js +18 -0
  21. package/dist/bookingModule/components/RoomCategoryForm.d.ts +3 -0
  22. package/dist/bookingModule/components/RoomCategoryForm.js +19 -0
  23. package/dist/bookingModule/components/RoomCategoryPriceForm.d.ts +3 -0
  24. package/dist/bookingModule/components/RoomCategoryPriceForm.js +20 -0
  25. package/dist/bookingModule/components/RoomExtraRequirementCapture.d.ts +3 -0
  26. package/dist/bookingModule/components/RoomExtraRequirementCapture.js +18 -0
  27. package/dist/bookingModule/components/RoomFacilityForm.d.ts +3 -0
  28. package/dist/bookingModule/components/RoomFacilityForm.js +19 -0
  29. package/dist/bookingModule/components/RoomReservationAction.d.ts +3 -0
  30. package/dist/bookingModule/components/RoomReservationAction.js +18 -0
  31. package/dist/components/Home/Home.d.ts +3 -0
  32. package/dist/components/Home/Home.js +14 -0
  33. package/dist/components/Loader/Loader.d.ts +2 -0
  34. package/dist/components/Loader/Loader.js +5 -0
  35. package/dist/components/Login/Login.d.ts +7 -0
  36. package/dist/components/Login/Login.js +149 -0
  37. package/dist/components/Login/loginSchema.d.ts +27 -0
  38. package/dist/components/Login/loginSchema.js +41 -0
  39. package/dist/components/Mappings/BranchMapping/Branch.d.ts +5 -0
  40. package/dist/components/Mappings/BranchMapping/Branch.js +135 -0
  41. package/dist/components/Mappings/BranchMapping/BranchTableColumns.d.ts +10 -0
  42. package/dist/components/Mappings/BranchMapping/BranchTableColumns.js +21 -0
  43. package/dist/components/Mappings/BranchMapping/MappingFormBranchUser.d.ts +3 -0
  44. package/dist/components/Mappings/BranchMapping/MappingFormBranchUser.js +150 -0
  45. package/dist/components/Mappings/BranchMapping/MappingTableColumns.d.ts +14 -0
  46. package/dist/components/Mappings/BranchMapping/MappingTableColumns.js +29 -0
  47. package/dist/components/Mappings/BranchMapping/branchSchema.d.ts +37 -0
  48. package/dist/components/Mappings/BranchMapping/branchSchema.js +34 -0
  49. package/dist/components/Mappings/ComponentMapping/ComponentRoleMapping.d.ts +3 -0
  50. package/dist/components/Mappings/ComponentMapping/ComponentRoleMapping.js +98 -0
  51. package/dist/components/Mappings/ComponentMapping/componentRoleColumns.d.ts +3 -0
  52. package/dist/components/Mappings/ComponentMapping/componentRoleColumns.js +29 -0
  53. package/dist/components/Mappings/MappingForm/MappingForm.d.ts +35 -0
  54. package/dist/components/Mappings/MappingForm/MappingForm.js +142 -0
  55. package/dist/components/Mappings/MappingForm/mappingSchema.d.ts +23 -0
  56. package/dist/components/Mappings/MappingForm/mappingSchema.js +32 -0
  57. package/dist/components/Mappings/RoleMapping/MappingFormUserRole.d.ts +5 -0
  58. package/dist/components/Mappings/RoleMapping/MappingFormUserRole.js +194 -0
  59. package/dist/components/Mappings/RoleMapping/UserRoleTableColumns.d.ts +3 -0
  60. package/dist/components/Mappings/RoleMapping/UserRoleTableColumns.js +33 -0
  61. package/dist/components/NavBar/Sidebar.d.ts +4 -0
  62. package/dist/components/NavBar/Sidebar.js +56 -0
  63. package/dist/components/ProfileForm/ProfileForm.d.ts +3 -0
  64. package/dist/components/ProfileForm/ProfileForm.js +190 -0
  65. package/dist/components/ProfileForm/ProfileList.d.ts +3 -0
  66. package/dist/components/ProfileForm/ProfileList.js +33 -0
  67. package/dist/components/ProfileForm/profileColumns.d.ts +3 -0
  68. package/dist/components/ProfileForm/profileColumns.js +67 -0
  69. package/dist/components/ProfileForm/profileSchema.d.ts +52 -0
  70. package/dist/components/ProfileForm/profileSchema.js +50 -0
  71. package/dist/components/SettingsPage/SettingsPage.d.ts +3 -0
  72. package/dist/components/SettingsPage/SettingsPage.js +240 -0
  73. package/dist/components/api/settings-api.d.ts +26 -0
  74. package/dist/components/api/settings-api.js +131 -0
  75. package/dist/components/common/Form/FormActionButtons.d.ts +11 -0
  76. package/dist/components/common/Form/FormActionButtons.js +6 -0
  77. package/dist/components/common/Form/FormLabel.d.ts +8 -0
  78. package/dist/components/common/Form/FormLabel.js +6 -0
  79. package/dist/components/common/ListTable/ListHeader.d.ts +8 -0
  80. package/dist/components/common/ListTable/ListHeader.js +5 -0
  81. package/dist/components/common/ListTable/ListTable.d.ts +17 -0
  82. package/dist/components/common/ListTable/ListTable.js +31 -0
  83. package/dist/components/common/Modal/Modal.d.ts +11 -0
  84. package/dist/components/common/Modal/Modal.js +6 -0
  85. package/dist/config/EnvConfig.d.ts +13 -0
  86. package/dist/config/EnvConfig.js +13 -0
  87. package/dist/config/amplifyConfig.d.ts +1 -0
  88. package/dist/config/amplifyConfig.js +45 -0
  89. package/dist/configureAppHost.d.ts +6 -0
  90. package/dist/configureAppHost.js +5 -0
  91. package/dist/customGraphQL/customMutations.d.ts +3 -0
  92. package/dist/customGraphQL/customMutations.js +53 -0
  93. package/dist/customGraphQL/customQueries.d.ts +7 -0
  94. package/dist/customGraphQL/customQueries.js +104 -0
  95. package/dist/domain/input/input-types.d.ts +47 -0
  96. package/dist/domain/input/input-types.js +1 -0
  97. package/dist/domain/model/BranchDto.d.ts +9 -0
  98. package/dist/domain/model/BranchDto.js +8 -0
  99. package/dist/domain/model/ComponentMappingDto.d.ts +24 -0
  100. package/dist/domain/model/ComponentMappingDto.js +19 -0
  101. package/dist/domain/model/MappingDto.d.ts +30 -0
  102. package/dist/domain/model/MappingDto.js +16 -0
  103. package/dist/domain/model/PrefixDescriptionDto.d.ts +16 -0
  104. package/dist/domain/model/PrefixDescriptionDto.js +13 -0
  105. package/dist/domain/model/ProfileDto.d.ts +21 -0
  106. package/dist/domain/model/ProfileDto.js +20 -0
  107. package/dist/domain/model/RoleMappingDto.d.ts +14 -0
  108. package/dist/domain/model/RoleMappingDto.js +19 -0
  109. package/dist/domain/model/SettingsDto.d.ts +8 -0
  110. package/dist/domain/model/SettingsDto.js +7 -0
  111. package/dist/domain/model/UserMappingDto.d.ts +14 -0
  112. package/dist/domain/model/UserMappingDto.js +28 -0
  113. package/dist/domain/model/imageDto.d.ts +4 -0
  114. package/dist/domain/model/imageDto.js +1 -0
  115. package/dist/domain/type/EntityTypes.d.ts +5 -0
  116. package/dist/domain/type/EntityTypes.js +6 -0
  117. package/dist/domain/type/MappingOptions.d.ts +5 -0
  118. package/dist/domain/type/MappingOptions.js +1 -0
  119. package/dist/domain/type/MappingTypes.d.ts +6 -0
  120. package/dist/domain/type/MappingTypes.js +7 -0
  121. package/dist/domain/type/Nullable.d.ts +13 -0
  122. package/dist/domain/type/Nullable.js +1 -0
  123. package/dist/domain/type/ResettingPeriodOptions.d.ts +2 -0
  124. package/dist/domain/type/ResettingPeriodOptions.js +8 -0
  125. package/dist/domain/type/RolesEnum.d.ts +6 -0
  126. package/dist/domain/type/RolesEnum.js +7 -0
  127. package/dist/domain/type/SelectType.d.ts +16 -0
  128. package/dist/domain/type/SelectType.js +1 -0
  129. package/dist/domain/type/StatusEnum.d.ts +5 -0
  130. package/dist/domain/type/StatusEnum.js +6 -0
  131. package/dist/domain/type/signUpOptions.d.ts +2 -0
  132. package/dist/domain/type/signUpOptions.js +4 -0
  133. package/dist/domain/type/statusOptions.d.ts +2 -0
  134. package/dist/domain/type/statusOptions.js +4 -0
  135. package/dist/graphql/profileQueries.d.ts +4 -0
  136. package/dist/graphql/profileQueries.js +89 -0
  137. package/dist/hoc/withSyzyAuth.d.ts +2 -0
  138. package/dist/hoc/withSyzyAuth.js +87 -0
  139. package/dist/hooks/useCurrentUser.d.ts +3 -0
  140. package/dist/hooks/useCurrentUser.js +6 -0
  141. package/dist/hooks/useDispatch.d.ts +3 -0
  142. package/dist/hooks/useDispatch.js +7 -0
  143. package/dist/hooks/usePermission.d.ts +1 -0
  144. package/dist/hooks/usePermission.js +7 -0
  145. package/dist/index.d.ts +3 -0
  146. package/dist/index.js +3 -15
  147. package/dist/main.d.ts +4 -0
  148. package/dist/main.js +60 -0
  149. package/dist/services/Client.Service.d.ts +12 -0
  150. package/dist/services/Client.Service.js +96 -0
  151. package/dist/services/Storage-service.d.ts +2 -0
  152. package/dist/services/Storage-service.js +26 -0
  153. package/dist/services/navigationMenu.d.ts +1 -0
  154. package/dist/services/navigationMenu.js +9 -0
  155. package/dist/static/constants.d.ts +34 -0
  156. package/dist/static/constants.js +34 -0
  157. package/dist/store/AppAction.d.ts +11 -0
  158. package/dist/store/AppAction.js +5 -0
  159. package/dist/store/AppContext.d.ts +3 -0
  160. package/dist/store/AppContext.js +3 -0
  161. package/dist/store/AppContextType.d.ts +12 -0
  162. package/dist/store/AppContextType.js +6 -0
  163. package/dist/store/AppProvider.d.ts +7 -0
  164. package/dist/store/AppProvider.js +32 -0
  165. package/dist/store/HostedInContainerContext.d.ts +5 -0
  166. package/dist/store/HostedInContainerContext.js +11 -0
  167. package/dist/store/SesssionReducer.d.ts +4 -0
  168. package/dist/store/SesssionReducer.js +16 -0
  169. package/dist/types.d.ts +26 -0
  170. package/dist/types.js +14 -0
  171. package/dist/util/AuthUtils.d.ts +1 -0
  172. package/dist/util/AuthUtils.js +10 -0
  173. package/dist/util/LogEnum.d.ts +6 -0
  174. package/dist/util/LogEnum.js +7 -0
  175. package/dist/util/Logger.d.ts +6 -0
  176. package/dist/util/Logger.js +18 -0
  177. package/dist/util/SyzyDate.d.ts +69 -0
  178. package/dist/util/SyzyDate.js +265 -0
  179. package/dist/util/dateUtils.d.ts +10 -0
  180. package/dist/util/dateUtils.js +24 -0
  181. package/dist/util/hostedinContainer.d.ts +1 -0
  182. package/dist/util/hostedinContainer.js +9 -0
  183. package/dist/util/model-types.d.ts +96 -0
  184. package/dist/util/model-types.js +18 -0
  185. package/dist/util/prefixAndResettingValidation.d.ts +9 -0
  186. package/dist/util/prefixAndResettingValidation.js +54 -0
  187. package/dist/util/transformToData.d.ts +1 -0
  188. package/dist/util/transformToData.js +9 -0
  189. package/package.json +14 -9
  190. package/dist/__federation_shared_@tanstack/react-query-DHuUsaNz.js +0 -2517
  191. package/dist/__federation_shared_react-CikWE6qG.js +0 -7
  192. package/dist/__federation_shared_react-bootstrap-BKlZRvMR.js +0 -7516
  193. package/dist/__federation_shared_react-dom-vrQ70Ay8.js +0 -372
  194. package/dist/__federation_shared_react-router-dom-BKminmS4.js +0 -10448
  195. package/dist/__federation_shared_react-select-B6kehBDI.js +0 -4056
  196. package/dist/__federation_shared_react-toastify-B0S0UGr3.js +0 -412
  197. package/dist/_commonjsHelpers-C6fGbg64.js +0 -6
  198. package/dist/_virtual___federation_fn_import-XZCKozko.js +0 -217
  199. package/dist/favicon.ico +0 -0
  200. package/dist/index-DgtWMtjZ.js +0 -184
  201. package/dist/index-eZknuYwc.js +0 -1219
  202. package/dist/jsx-runtime-D_t4bG-_.js +0 -264
  203. package/dist/manifest.webmanifest +0 -1
  204. package/dist/pwa/Hotel-icon.jpg +0 -0
  205. package/dist/pwa/apple-touch-icon-180x180.png +0 -0
  206. package/dist/pwa/favicon.ico +0 -0
  207. package/dist/pwa/maskable-icon-512x512.png +0 -0
  208. package/dist/pwa/pwa-192x192.png +0 -0
  209. package/dist/pwa/pwa-512x512.png +0 -0
  210. package/dist/pwa/pwa-64x64.png +0 -0
  211. package/dist/registerSW.js +0 -1
  212. package/dist/sw.js +0 -1
  213. 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,5 @@
1
+ import React from "react";
2
+ import type { MappingOptions } from "../../../domain/type/MappingOptions";
3
+ export declare const roles: MappingOptions[];
4
+ declare const MappingFormUserRole: React.FC;
5
+ export default MappingFormUserRole;
@@ -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,3 @@
1
+ import { TableColumn } from "../../common/ListTable/ListTable";
2
+ import { UserRoleMappingDisplay } from "../../../domain/model/MappingDto";
3
+ export declare const UserRoleTableColumns: TableColumn<UserRoleMappingDisplay>[];
@@ -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,4 @@
1
+ import React from "react";
2
+ import './sidebar.css';
3
+ declare const Sidebar: React.FC;
4
+ export default Sidebar;
@@ -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;
@@ -0,0 +1,3 @@
1
+ import '../Mappings/MappingForm/MappingForm.css';
2
+ declare const ProfileForm: () => import("react/jsx-runtime").JSX.Element;
3
+ export default ProfileForm;