@acoustte-digital-services/digitalstore-controls-dev 0.8.1-dev.20260616104505 → 0.8.1-dev.20260620042502

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/index.js CHANGED
@@ -5566,6 +5566,73 @@ var ImageGalleryNode_default = ImageGalleryNode;
5566
5566
 
5567
5567
  // src/components/pageRenderingEngine/nodes/DivContainer.tsx
5568
5568
  var import_link2 = __toESM(require("next/link"));
5569
+
5570
+ // src/utilities/RoleUtility.tsx
5571
+ var decodeJWT = (token) => {
5572
+ if (!token) return null;
5573
+ try {
5574
+ const cleanToken = token.replace(/^Bearer\s+/i, "");
5575
+ const parts = cleanToken.split(".");
5576
+ if (parts.length !== 3) {
5577
+ console.warn("Invalid JWT token format");
5578
+ return null;
5579
+ }
5580
+ const payload = parts[1];
5581
+ const decoded = JSON.parse(atob(payload));
5582
+ return decoded;
5583
+ } catch (error) {
5584
+ console.warn("Failed to decode JWT token:", error);
5585
+ return null;
5586
+ }
5587
+ };
5588
+ var extractRolesFromToken = (decodedPayload) => {
5589
+ if (!decodedPayload) return [];
5590
+ const roles = [];
5591
+ if (decodedPayload.role && typeof decodedPayload.role === "string") {
5592
+ roles.push(decodedPayload.role);
5593
+ }
5594
+ if (decodedPayload.roles && Array.isArray(decodedPayload.roles)) {
5595
+ roles.push(...decodedPayload.roles);
5596
+ }
5597
+ if (decodedPayload.realm_access?.roles && Array.isArray(decodedPayload.realm_access.roles)) {
5598
+ roles.push(...decodedPayload.realm_access.roles);
5599
+ }
5600
+ if (decodedPayload.resource_access && typeof decodedPayload.resource_access === "object") {
5601
+ Object.values(decodedPayload.resource_access).forEach((resource) => {
5602
+ if (resource?.roles && Array.isArray(resource.roles)) {
5603
+ roles.push(...resource.roles);
5604
+ }
5605
+ });
5606
+ }
5607
+ return [...new Set(roles)];
5608
+ };
5609
+ var getUserRoles = (oAuthToken) => {
5610
+ const decodedPayload = decodeJWT(oAuthToken);
5611
+ return extractRolesFromToken(decodedPayload);
5612
+ };
5613
+ var hasRole = (userRoles, requiredRole) => {
5614
+ if (!requiredRole || !userRoles) return false;
5615
+ return userRoles.some(
5616
+ (role) => role.toLowerCase() === requiredRole.toLowerCase()
5617
+ );
5618
+ };
5619
+ var shouldRenderByRole = (roleCode, userRoles) => {
5620
+ if (!roleCode || roleCode.trim() === "") {
5621
+ return true;
5622
+ }
5623
+ const trimmedRoleCode = roleCode.trim();
5624
+ if (trimmedRoleCode.startsWith("!")) {
5625
+ const requiredRole = trimmedRoleCode.substring(1);
5626
+ return !hasRole(userRoles, requiredRole);
5627
+ }
5628
+ return hasRole(userRoles, trimmedRoleCode);
5629
+ };
5630
+ var validateRoleVisibility = (roleCode, oAuthToken) => {
5631
+ const userRoles = getUserRoles(oAuthToken);
5632
+ return shouldRenderByRole(roleCode, userRoles);
5633
+ };
5634
+
5635
+ // src/components/pageRenderingEngine/nodes/DivContainer.tsx
5569
5636
  var import_jsx_runtime70 = require("react/jsx-runtime");
5570
5637
  function toCamelCase(str) {
5571
5638
  return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
@@ -5792,7 +5859,16 @@ var DivContainer = async (props) => {
5792
5859
  }
5793
5860
  return isNegated ? fieldValue === true : fieldValue === false;
5794
5861
  };
5795
- const isHidden = shouldHideContainer();
5862
+ const shouldHideByRole = () => {
5863
+ if (!props.node.roleCode) return false;
5864
+ const roleCode = props.node.roleCode;
5865
+ const oAuthToken = props.session?.oAuthToken;
5866
+ if (!roleCode || roleCode.trim() === "") {
5867
+ return false;
5868
+ }
5869
+ return !validateRoleVisibility(roleCode, oAuthToken);
5870
+ };
5871
+ const isHidden = shouldHideContainer() || shouldHideByRole();
5796
5872
  let odataString = void 0;
5797
5873
  let endpoint = void 0;
5798
5874
  let result = null;
@@ -6002,10 +6078,21 @@ var PageBodyRenderer = (props) => {
6002
6078
  if (pageBodyTree && pageBodyTree.root) {
6003
6079
  rootNode = pageBodyTree.root;
6004
6080
  }
6081
+ const shouldRenderNode = (node) => {
6082
+ {
6083
+ }
6084
+ if (node.type === "div-container" && node.roleCode) {
6085
+ return validateRoleVisibility(node.roleCode, props.session?.oAuthToken);
6086
+ }
6087
+ return true;
6088
+ };
6005
6089
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react51.default.Fragment, { children: rootNode && rootNode?.children?.map((node, index) => {
6006
6090
  {
6007
6091
  }
6008
6092
  const SelectedNode = NodeTypes[node.type];
6093
+ if (!shouldRenderNode(node)) {
6094
+ return null;
6095
+ }
6009
6096
  return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react51.default.Fragment, { children: SelectedNode && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react51.default.Fragment, { children: node.type == "layout-container" ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react51.default.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
6010
6097
  SelectedNode,
6011
6098
  {
@@ -6504,7 +6591,9 @@ var DataList = (props) => {
6504
6591
  controlType: InputControlType_default.lineTextInput,
6505
6592
  value: searchTerm,
6506
6593
  callback: (e) => setSearchTerm(e.value),
6507
- attributes: { placeholder: "Search..." }
6594
+ attributes: {
6595
+ placeholder: `Search by ${props.columns.filter((col) => col.isSearchable).map((col) => col.label).join(", ")}`
6596
+ }
6508
6597
  }
6509
6598
  ),
6510
6599
  props.filters && props.filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
@@ -6666,7 +6755,9 @@ var DataList = (props) => {
6666
6755
  controlType: InputControlType_default.lineTextInput,
6667
6756
  value: searchTerm,
6668
6757
  callback: (e) => setSearchTerm(e.value),
6669
- attributes: { placeholder: "Search..." }
6758
+ attributes: {
6759
+ placeholder: `Search by ${props.columns.filter((col) => col.isSearchable).map((col) => col.label).join(", ")}`
6760
+ }
6670
6761
  }
6671
6762
  ),
6672
6763
  props.filters && props.filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
package/dist/index.mjs CHANGED
@@ -3960,6 +3960,73 @@ var ImageGalleryNode_default = ImageGalleryNode;
3960
3960
 
3961
3961
  // src/components/pageRenderingEngine/nodes/DivContainer.tsx
3962
3962
  import Link2 from "next/link";
3963
+
3964
+ // src/utilities/RoleUtility.tsx
3965
+ var decodeJWT = (token) => {
3966
+ if (!token) return null;
3967
+ try {
3968
+ const cleanToken = token.replace(/^Bearer\s+/i, "");
3969
+ const parts = cleanToken.split(".");
3970
+ if (parts.length !== 3) {
3971
+ console.warn("Invalid JWT token format");
3972
+ return null;
3973
+ }
3974
+ const payload = parts[1];
3975
+ const decoded = JSON.parse(atob(payload));
3976
+ return decoded;
3977
+ } catch (error) {
3978
+ console.warn("Failed to decode JWT token:", error);
3979
+ return null;
3980
+ }
3981
+ };
3982
+ var extractRolesFromToken = (decodedPayload) => {
3983
+ if (!decodedPayload) return [];
3984
+ const roles = [];
3985
+ if (decodedPayload.role && typeof decodedPayload.role === "string") {
3986
+ roles.push(decodedPayload.role);
3987
+ }
3988
+ if (decodedPayload.roles && Array.isArray(decodedPayload.roles)) {
3989
+ roles.push(...decodedPayload.roles);
3990
+ }
3991
+ if (decodedPayload.realm_access?.roles && Array.isArray(decodedPayload.realm_access.roles)) {
3992
+ roles.push(...decodedPayload.realm_access.roles);
3993
+ }
3994
+ if (decodedPayload.resource_access && typeof decodedPayload.resource_access === "object") {
3995
+ Object.values(decodedPayload.resource_access).forEach((resource) => {
3996
+ if (resource?.roles && Array.isArray(resource.roles)) {
3997
+ roles.push(...resource.roles);
3998
+ }
3999
+ });
4000
+ }
4001
+ return [...new Set(roles)];
4002
+ };
4003
+ var getUserRoles = (oAuthToken) => {
4004
+ const decodedPayload = decodeJWT(oAuthToken);
4005
+ return extractRolesFromToken(decodedPayload);
4006
+ };
4007
+ var hasRole = (userRoles, requiredRole) => {
4008
+ if (!requiredRole || !userRoles) return false;
4009
+ return userRoles.some(
4010
+ (role) => role.toLowerCase() === requiredRole.toLowerCase()
4011
+ );
4012
+ };
4013
+ var shouldRenderByRole = (roleCode, userRoles) => {
4014
+ if (!roleCode || roleCode.trim() === "") {
4015
+ return true;
4016
+ }
4017
+ const trimmedRoleCode = roleCode.trim();
4018
+ if (trimmedRoleCode.startsWith("!")) {
4019
+ const requiredRole = trimmedRoleCode.substring(1);
4020
+ return !hasRole(userRoles, requiredRole);
4021
+ }
4022
+ return hasRole(userRoles, trimmedRoleCode);
4023
+ };
4024
+ var validateRoleVisibility = (roleCode, oAuthToken) => {
4025
+ const userRoles = getUserRoles(oAuthToken);
4026
+ return shouldRenderByRole(roleCode, userRoles);
4027
+ };
4028
+
4029
+ // src/components/pageRenderingEngine/nodes/DivContainer.tsx
3963
4030
  import { jsx as jsx59, jsxs as jsxs32 } from "react/jsx-runtime";
3964
4031
  function toCamelCase(str) {
3965
4032
  return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
@@ -4186,7 +4253,16 @@ var DivContainer = async (props) => {
4186
4253
  }
4187
4254
  return isNegated ? fieldValue === true : fieldValue === false;
4188
4255
  };
4189
- const isHidden = shouldHideContainer();
4256
+ const shouldHideByRole = () => {
4257
+ if (!props.node.roleCode) return false;
4258
+ const roleCode = props.node.roleCode;
4259
+ const oAuthToken = props.session?.oAuthToken;
4260
+ if (!roleCode || roleCode.trim() === "") {
4261
+ return false;
4262
+ }
4263
+ return !validateRoleVisibility(roleCode, oAuthToken);
4264
+ };
4265
+ const isHidden = shouldHideContainer() || shouldHideByRole();
4190
4266
  let odataString = void 0;
4191
4267
  let endpoint = void 0;
4192
4268
  let result = null;
@@ -4396,10 +4472,21 @@ var PageBodyRenderer = (props) => {
4396
4472
  if (pageBodyTree && pageBodyTree.root) {
4397
4473
  rootNode = pageBodyTree.root;
4398
4474
  }
4475
+ const shouldRenderNode = (node) => {
4476
+ {
4477
+ }
4478
+ if (node.type === "div-container" && node.roleCode) {
4479
+ return validateRoleVisibility(node.roleCode, props.session?.oAuthToken);
4480
+ }
4481
+ return true;
4482
+ };
4399
4483
  return /* @__PURE__ */ jsx60(React42.Fragment, { children: rootNode && rootNode?.children?.map((node, index) => {
4400
4484
  {
4401
4485
  }
4402
4486
  const SelectedNode = NodeTypes[node.type];
4487
+ if (!shouldRenderNode(node)) {
4488
+ return null;
4489
+ }
4403
4490
  return /* @__PURE__ */ jsx60(React42.Fragment, { children: SelectedNode && /* @__PURE__ */ jsx60(React42.Fragment, { children: node.type == "layout-container" ? /* @__PURE__ */ jsx60(React42.Fragment, { children: /* @__PURE__ */ jsx60(
4404
4491
  SelectedNode,
4405
4492
  {
@@ -4892,7 +4979,9 @@ var DataList = (props) => {
4892
4979
  controlType: InputControlType_default.lineTextInput,
4893
4980
  value: searchTerm,
4894
4981
  callback: (e) => setSearchTerm(e.value),
4895
- attributes: { placeholder: "Search..." }
4982
+ attributes: {
4983
+ placeholder: `Search by ${props.columns.filter((col) => col.isSearchable).map((col) => col.label).join(", ")}`
4984
+ }
4896
4985
  }
4897
4986
  ),
4898
4987
  props.filters && props.filters.map((filter) => /* @__PURE__ */ jsx65(
@@ -5054,7 +5143,9 @@ var DataList = (props) => {
5054
5143
  controlType: InputControlType_default.lineTextInput,
5055
5144
  value: searchTerm,
5056
5145
  callback: (e) => setSearchTerm(e.value),
5057
- attributes: { placeholder: "Search..." }
5146
+ attributes: {
5147
+ placeholder: `Search by ${props.columns.filter((col) => col.isSearchable).map((col) => col.label).join(", ")}`
5148
+ }
5058
5149
  }
5059
5150
  ),
5060
5151
  props.filters && props.filters.map((filter) => /* @__PURE__ */ jsx65(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acoustte-digital-services/digitalstore-controls-dev",
3
- "version": "0.8.1-dev.20260616104505",
3
+ "version": "0.8.1-dev.20260620042502",
4
4
  "description": "Reusable React components",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -22,7 +22,7 @@
22
22
  }
23
23
  },
24
24
  "devDependencies": {
25
- "@types/node": "^25.9.3",
25
+ "@types/node": "^26.0.0",
26
26
  "@types/react": "^19",
27
27
  "@types/react-dom": "^19",
28
28
  "tsup": "^8.5.1",