@ramesesinc/platform-core 0.1.5 → 0.1.8

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 (91) hide show
  1. package/dist/components/action/LookupPage.js +9 -31
  2. package/dist/components/action/ViewPage.d.ts +2 -0
  3. package/dist/components/action/ViewPage.js +25 -31
  4. package/dist/components/common/UIComponent.js +4 -3
  5. package/dist/components/index.d.ts +1 -1
  6. package/dist/components/index.js +1 -1
  7. package/dist/components/table/DataList.js +2 -2
  8. package/dist/components/view/PopupView.d.ts +13 -0
  9. package/dist/components/view/PopupView.js +25 -20
  10. package/dist/core/DataContext.d.ts +7 -4
  11. package/dist/core/DataContext.js +16 -4
  12. package/dist/core/Page.js +25 -26
  13. package/dist/core/PageCache.js +16 -3
  14. package/dist/core/PageContext.js +90 -18
  15. package/dist/core/PageViewContext.d.ts +13 -1
  16. package/dist/core/PageViewContext.js +89 -5
  17. package/dist/core/PopupContext.d.ts +49 -0
  18. package/dist/core/PopupContext.js +380 -0
  19. package/dist/core/RowContext.js +1 -1
  20. package/dist/core/WindowContext.d.ts +15 -0
  21. package/dist/core/WindowContext.js +28 -0
  22. package/dist/core/index.d.ts +16 -0
  23. package/dist/index.css +25 -7
  24. package/dist/lib/utils/BeanUtils.js +7 -7
  25. package/dist/templates/DataListTemplate.js +7 -2
  26. package/dist/templates/ExplorerTemplate.js +1 -1
  27. package/package.json +5 -5
  28. package/dist/components/action/AlertMessage.tsx +0 -38
  29. package/dist/components/action/Button.tsx +0 -230
  30. package/dist/components/action/CancelEdit.tsx +0 -40
  31. package/dist/components/action/DeleteData.tsx +0 -73
  32. package/dist/components/action/Edit.tsx +0 -40
  33. package/dist/components/action/LookupPage.tsx +0 -113
  34. package/dist/components/action/ProcessRunner.tsx +0 -337
  35. package/dist/components/action/Refresh.tsx +0 -35
  36. package/dist/components/action/SaveData.tsx +0 -74
  37. package/dist/components/action/SelectData.tsx +0 -47
  38. package/dist/components/action/Undo.tsx +0 -50
  39. package/dist/components/action/UpdateContext.tsx +0 -40
  40. package/dist/components/action/UpdateData.tsx +0 -49
  41. package/dist/components/action/ViewBackPage.tsx +0 -46
  42. package/dist/components/action/ViewPage.tsx +0 -141
  43. package/dist/components/common/UIComponent.tsx +0 -86
  44. package/dist/components/common/UIInput.tsx +0 -49
  45. package/dist/components/common/UIMenu.tsx +0 -91
  46. package/dist/components/index.ts +0 -51
  47. package/dist/components/input/CodeEditor.tsx +0 -188
  48. package/dist/components/input/DateField.tsx +0 -274
  49. package/dist/components/input/DayPicker.tsx +0 -5
  50. package/dist/components/input/HtmlCode.tsx +0 -203
  51. package/dist/components/input/JsonCode.tsx +0 -205
  52. package/dist/components/input/MonthPicker.tsx +0 -5
  53. package/dist/components/input/ScriptCode.tsx +0 -195
  54. package/dist/components/input/Select.tsx +0 -78
  55. package/dist/components/input/SqlCode.tsx +0 -162
  56. package/dist/components/input/StringDecision.tsx +0 -64
  57. package/dist/components/input/Text.tsx +0 -57
  58. package/dist/components/input/YearPicker.tsx +0 -81
  59. package/dist/components/list/IconMenu.tsx +0 -115
  60. package/dist/components/list/TabMenu.tsx +0 -127
  61. package/dist/components/list/TreeMenu.tsx +0 -279
  62. package/dist/components/list/TxnTaskList.tsx +0 -198
  63. package/dist/components/output/Label.tsx +0 -50
  64. package/dist/components/table/DataList.tsx +0 -820
  65. package/dist/components/table/DataTable.tsx +0 -572
  66. package/dist/components/table/ListHandler.ts +0 -276
  67. package/dist/components/table/TableContext.tsx +0 -122
  68. package/dist/components/view/ComponentView.tsx +0 -102
  69. package/dist/components/view/FilterView.tsx +0 -21
  70. package/dist/components/view/HtmlForm.tsx +0 -176
  71. package/dist/components/view/HtmlView.tsx +0 -98
  72. package/dist/components/view/IFrameView.tsx +0 -48
  73. package/dist/components/view/Modal.tsx +0 -72
  74. package/dist/components/view/PageView.tsx +0 -131
  75. package/dist/components/view/PopupView.tsx +0 -160
  76. package/dist/components/view/RootView.tsx +0 -109
  77. package/dist/components/view/WizardView.tsx +0 -48
  78. package/dist/lib/layouts/BorderLayout.tsx +0 -31
  79. package/dist/lib/layouts/CardLayout.tsx +0 -73
  80. package/dist/lib/layouts/CenterLayout.tsx +0 -20
  81. package/dist/lib/layouts/GridLayout.tsx +0 -20
  82. package/dist/lib/layouts/HPanel.tsx +0 -31
  83. package/dist/lib/layouts/HorizontalLayout.tsx +0 -29
  84. package/dist/lib/layouts/MainLayout.tsx +0 -16
  85. package/dist/lib/layouts/PageLayout.tsx +0 -29
  86. package/dist/lib/layouts/VPanel.tsx +0 -27
  87. package/dist/lib/layouts/XLayout.tsx +0 -29
  88. package/dist/lib/layouts/YLayout.tsx +0 -29
  89. package/dist/lib/layouts/index.ts +0 -13
  90. /package/dist/components/action/{UpdateContext.d.ts → UpdateState.d.ts} +0 -0
  91. /package/dist/components/action/{UpdateContext.js → UpdateState.js} +0 -0
@@ -1,62 +1,40 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { forwardRef, memo, useImperativeHandle, useRef, useState } from "react";
3
+ import { useRef } from "react";
4
4
  import { usePageContext } from "../../core/PageContext";
5
5
  import { getValue, substituteExpr } from "../../lib/utils/BeanUtils";
6
- import PopupView from "../view/PopupView";
6
+ import { usePopupView } from "../view/PopupView";
7
7
  /* ------------------------------------------------------------------ */
8
8
  /* Component */
9
9
  const LookupPage = (props) => {
10
10
  const { url, name = "", result = null, children, className = "", title, icon, opt = {}, popupClassName = "", iconOnly = false } = props !== null && props !== void 0 ? props : {};
11
11
  const { data = {} } = opt;
12
12
  const pageContext = usePageContext();
13
- const [showPopup, setShowPopup] = useState(false);
14
- const [popupUrl, setPopupUrl] = useState("");
15
- const slotRef = useRef(null);
16
- const onClose = () => {
17
- var _a;
18
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(null);
19
- };
13
+ const popupView = usePopupView();
14
+ const popupRef = useRef(null);
20
15
  /* ---------------------- Events ---------------------- */
21
16
  const handleClick = () => {
22
- var _a;
23
17
  if (!url)
24
18
  return;
25
19
  //combine data if specified and pageContext all data if specified
26
20
  const surl = substituteExpr(url, Object.assign(Object.assign({}, pageContext === null || pageContext === void 0 ? void 0 : pageContext.getAllData()), data));
27
- setPopupUrl(surl);
28
- setShowPopup(true);
29
21
  const handler = {
30
22
  onSelect: (itm) => {
23
+ var _a;
31
24
  let resdata = itm;
32
25
  if (result != null) {
33
26
  resdata = getValue(result, itm);
34
27
  }
35
- alert("item selected " + JSON.stringify(resdata));
28
+ (_a = popupRef.current) === null || _a === void 0 ? void 0 : _a.close();
36
29
  if (name) {
37
30
  pageContext.set(name, resdata);
38
31
  }
39
- onClose();
40
- //pageContext.refresh();
41
32
  },
42
33
  };
43
- //eventHandler={handler}
44
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(_jsx(PopupView, { url: surl, onClose: onClose, eventHandler: handler }));
45
- };
46
- const handleClosePopup = () => {
47
- setShowPopup(false);
34
+ const showPopupRef = popupView.create({ url: surl, eventHandler: handler }).show();
35
+ popupRef.current = showPopupRef;
48
36
  };
49
37
  /* ---------------------- Render ---------------------- */
50
- return (_jsxs(_Fragment, { children: [iconOnly ? (_jsx("span", { onClick: handleClick, className: `cursor-pointer ${className}`, children: icon })) : (_jsxs("button", { onClick: handleClick, className: `px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors ${className}`, children: [icon && _jsx("span", { className: "dl-action-icon", children: icon }), title || "View Page"] })), _jsx(ChildrenSlot, { ref: slotRef })] }));
38
+ return (_jsx(_Fragment, { children: iconOnly ? (_jsx("span", { onClick: handleClick, className: `cursor-pointer ${className}`, children: icon })) : (_jsxs("button", { onClick: handleClick, className: `px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors ${className}`, children: [icon && _jsx("span", { className: "dl-action-icon", children: icon }), title || "View Page"] })) }));
51
39
  };
52
40
  export default LookupPage;
53
- const ChildrenSlot = memo(forwardRef((_, ref) => {
54
- const [content, setContent] = useState(null);
55
- useImperativeHandle(ref, () => ({
56
- update: (content) => {
57
- // console.log("view page children slot", content);
58
- setContent(content);
59
- },
60
- }), []);
61
- return _jsx(_Fragment, { children: content == null ? null : content });
62
- }));
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { AbstractComponent } from "../../types/component";
3
+ import { PopupOptions } from "../../core/PopupContext";
3
4
  interface ViewPageProps extends AbstractComponent {
4
5
  url: string;
5
6
  mode?: "popup" | "window";
@@ -9,6 +10,7 @@ interface ViewPageProps extends AbstractComponent {
9
10
  opt?: Record<string, any>;
10
11
  iconOnly?: boolean;
11
12
  popupClassName?: string;
13
+ popupOptions?: PopupOptions;
12
14
  }
13
15
  declare const ViewPage: (props: ViewPageProps) => import("react/jsx-runtime").JSX.Element;
14
16
  export default ViewPage;
@@ -1,28 +1,28 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { forwardRef, memo, useImperativeHandle, useRef, useState } from "react";
3
+ import { useRef } from "react";
4
4
  import { useDataContext } from "../../core/DataContext";
5
5
  import { usePageContext } from "../../core/PageContext";
6
6
  import { usePageViewContext } from "../../core/PageViewContext";
7
7
  import { substituteExpr } from "../../lib/utils/BeanUtils";
8
8
  import { getUrlPageParams, parseHashUrl } from "../../lib/utils/PageUtils";
9
- import PopupView from "../view/PopupView";
9
+ import { usePopupView } from "../view/PopupView";
10
10
  /* ------------------------------------------------------------------ */
11
11
  /* Component */
12
12
  const ViewPage = (props) => {
13
- const { url, mode, className = "", title, icon, opt = {}, popupClassName = "", iconOnly = false } = props !== null && props !== void 0 ? props : {};
13
+ const { url, mode, className = "", title, icon, iconOnly = false, opt = {}, popupClassName = "", popupOptions = {} } = props !== null && props !== void 0 ? props : {};
14
14
  const { data = {} } = opt;
15
15
  const dataContext = useDataContext();
16
16
  const pageView = usePageViewContext();
17
17
  const pageContext = usePageContext();
18
- const slotRef = useRef(null);
18
+ const popupView = usePopupView();
19
+ const popupShowRef = useRef(null);
19
20
  /* ---------------------- Events ---------------------- */
20
21
  const onClose = () => {
21
22
  var _a;
22
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(null);
23
+ (_a = popupShowRef.current) === null || _a === void 0 ? void 0 : _a.close();
23
24
  };
24
25
  const handleClick = (e) => {
25
- var _a;
26
26
  e.preventDefault();
27
27
  if (!url)
28
28
  return;
@@ -39,21 +39,18 @@ const ViewPage = (props) => {
39
39
  return result !== null && result !== void 0 ? result : {};
40
40
  };
41
41
  const getUrlData = () => {
42
- let result = null;
43
- if (dataContext == null) {
44
- // use data received from props
45
- const fullData = Object.assign(Object.assign({}, pageContext.getAllData()), data);
46
- result = fullData;
47
- }
48
- else {
49
- result = dataContext.getData();
50
- }
51
- return result !== null && result !== void 0 ? result : {};
42
+ const result = Object.assign(Object.assign({}, dataContext.getAllData()), data);
43
+ // console.log("get url data", dataContext, result);
44
+ return result;
52
45
  };
53
46
  const urlParams = getUrlParams();
54
47
  const urlData = getUrlData();
55
48
  const surl = substituteExpr(url, Object.assign(Object.assign({}, urlParams), urlData));
56
- if (mode === "popup") {
49
+ let preferredMode = mode;
50
+ if ((preferredMode == null || preferredMode.trim() === '') && dataContext.getType() === 'row') {
51
+ preferredMode = "window";
52
+ }
53
+ if (preferredMode === "popup") {
57
54
  const handler = {
58
55
  onSave: (itm) => {
59
56
  onClose();
@@ -63,26 +60,23 @@ const ViewPage = (props) => {
63
60
  pageContext.notifyDepends();
64
61
  },
65
62
  };
66
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(_jsx(PopupView, { url: surl, onClose: onClose, eventHandler: handler }));
63
+ const showPopupOptions = Object.assign({}, popupOptions);
64
+ if (popupClassName != null && popupClassName.trim() !== '') {
65
+ showPopupOptions.className = popupClassName;
66
+ }
67
+ const showPopupRef = popupView.create({ url: surl, onClose: onClose, eventHandler: handler }).show(showPopupOptions);
68
+ popupShowRef.current = showPopupRef;
67
69
  }
68
- else if (mode === "window") {
69
- pageView.setPage(surl, { mode });
70
+ else if (preferredMode === "window") {
71
+ popupShowRef.current = null;
72
+ pageView.setPage(surl, { mode: preferredMode });
70
73
  }
71
74
  else {
75
+ popupShowRef.current = null;
72
76
  pageView.pushPage(surl);
73
77
  }
74
78
  };
75
79
  /* ---------------------- Render ---------------------- */
76
- return (_jsxs(_Fragment, { children: [iconOnly ? (_jsx("span", { onClick: handleClick, className: `cursor-pointer ${className}`, children: icon })) : (_jsxs("button", { onClick: handleClick, className: `px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors ${className}`, children: [icon && _jsx("span", { className: "dl-action-icon", children: icon }), title || "View Page"] })), _jsx(ChildrenSlot, { ref: slotRef })] }));
80
+ return (_jsx(_Fragment, { children: iconOnly ? (_jsx("span", { onClick: handleClick, className: `cursor-pointer ${className}`, children: icon })) : (_jsxs("button", { onClick: handleClick, className: `px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors ${className}`, children: [icon && _jsx("span", { className: "dl-action-icon", children: icon }), title || "View Page"] })) }));
77
81
  };
78
82
  export default ViewPage;
79
- const ChildrenSlot = memo(forwardRef((_, ref) => {
80
- const [content, setContent] = useState(null);
81
- useImperativeHandle(ref, () => ({
82
- update: (content) => {
83
- // console.log("view page children slot", content);
84
- setContent(content);
85
- },
86
- }), []);
87
- return _jsx(_Fragment, { children: content == null ? null : content });
88
- }));
@@ -1,15 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { compile } from "expression-eval";
3
2
  import { useEffect, useState } from "react";
4
3
  import { usePageContext } from "../../core/PageContext";
4
+ import { compile } from "expression-eval";
5
5
  const UIComponent = (props) => {
6
6
  var _a;
7
7
  const { name, title, depends, children, visibleWhen, labelPosition = "top", style } = props !== null && props !== void 0 ? props : {};
8
8
  const pageContext = usePageContext();
9
9
  const evaluateVisible = () => {
10
10
  var _a;
11
- if (!visibleWhen)
11
+ if (visibleWhen == null || visibleWhen.trim() === '') {
12
12
  return true;
13
+ }
13
14
  try {
14
15
  const context = (_a = pageContext === null || pageContext === void 0 ? void 0 : pageContext.getAllData()) !== null && _a !== void 0 ? _a : {};
15
16
  const stripped = visibleWhen.replace(/^\s*\{([\s\S]*)\}\s*$/, "$1").trim();
@@ -26,7 +27,7 @@ const UIComponent = (props) => {
26
27
  }
27
28
  catch (e) {
28
29
  console.warn("visibleWhen eval error:", e);
29
- return true;
30
+ return false;
30
31
  }
31
32
  };
32
33
  const [visible, setVisible] = useState(() => evaluateVisible());
@@ -29,7 +29,7 @@ export { default as Refresh } from "./action/Refresh";
29
29
  export { default as SaveData } from "./action/SaveData";
30
30
  export { default as SelectData } from "./action/SelectData";
31
31
  export { default as LookupPage } from "./action/LookupPage";
32
- export { default as UpdateContext } from "./action/UpdateContext";
32
+ export { default as UpdateState } from "./action/UpdateState";
33
33
  export { default as ViewBackPage } from "./action/ViewBackPage";
34
34
  export { default as ViewPage } from "./action/ViewPage";
35
35
  export { default as PageView } from "./view/PageView";
@@ -35,7 +35,7 @@ export { default as Refresh } from "./action/Refresh";
35
35
  export { default as SaveData } from "./action/SaveData";
36
36
  export { default as SelectData } from "./action/SelectData";
37
37
  export { default as LookupPage } from "./action/LookupPage";
38
- export { default as UpdateContext } from "./action/UpdateContext";
38
+ export { default as UpdateState } from "./action/UpdateState";
39
39
  export { default as ViewBackPage } from "./action/ViewBackPage";
40
40
  export { default as ViewPage } from "./action/ViewPage";
41
41
  export { default as PageView } from "./view/PageView";
@@ -297,7 +297,7 @@ const InnerDataList = ({ cols, emptyMessage = "No data available", errorMessage,
297
297
  return (_jsxs("div", { className: `data-list ${className}`, children: [renderToolbar(), renderFilterPanel(), (paginationPosition === "both" || paginationPosition === "top") && renderPagination(), _jsx(DataTable, { data: rows, columns: sortableColumns, loading: isLoading, emptyMessage: emptyMessage, striped: striped, bordered: bordered, hover: hover, dense: dense, rowKey: "id", onRowClick: handleRowClick, selectedRows: selectedRows, onSelectionChange: handleSelectionChange, selectable: selectable, rowClassName: rowClassName }), (paginationPosition === "both" || paginationPosition === "bottom") && rows.length > 0 && renderPagination()] }));
298
298
  };
299
299
  export const DataList = ({ attr }) => {
300
- const { depends, cols, data, rowsPerPage, disableTotalCount, commonActions, rowActions, toolbarActions } = attr, rest = __rest(attr, ["depends", "cols", "data", "rowsPerPage", "disableTotalCount", "commonActions", "rowActions", "toolbarActions"]);
300
+ const { title, depends, cols, data, rowsPerPage, disableTotalCount, commonActions, rowActions, toolbarActions } = attr, rest = __rest(attr, ["title", "depends", "cols", "data", "rowsPerPage", "disableTotalCount", "commonActions", "rowActions", "toolbarActions"]);
301
301
  // All hooks called here — this is a React component so hooks are valid
302
302
  const { tenant, module } = useApp();
303
303
  const pageContext = usePageContext();
@@ -356,7 +356,7 @@ export const DataList = ({ attr }) => {
356
356
  handleRef.current = ref;
357
357
  },
358
358
  };
359
- return (_jsx(TableProvider, { data: data, columns: cols, rowsPerPage: rowsPerPage, disableTotalCount: disableTotalCount, listHandlerFactory: listHandlerFactory, tenant: tenant !== null && tenant !== void 0 ? tenant : "", module: module !== null && module !== void 0 ? module : "", resolvedParams: resolveParams(), children: _jsx(InnerDataList, Object.assign({}, rest, { cols: cols, rowActions: newRowActions, toolbarActions: newToolbarActions, depends: depends, handle: innerHandle })) }));
359
+ return (_jsx(TableProvider, { data: data, columns: cols, rowsPerPage: rowsPerPage, disableTotalCount: disableTotalCount, listHandlerFactory: listHandlerFactory, tenant: tenant !== null && tenant !== void 0 ? tenant : "", module: module !== null && module !== void 0 ? module : "", resolvedParams: resolveParams(), children: _jsx(InnerDataList, Object.assign({}, rest, { toolbarTitle: title, cols: cols, rowActions: newRowActions, toolbarActions: newToolbarActions, depends: depends, handle: innerHandle })) }));
360
360
  };
361
361
  export default DataList;
362
362
  const RefreshButton = ({ show, onClick, size = 18 }) => {
@@ -1,9 +1,22 @@
1
1
  import { EventHandler } from "../../core";
2
+ import { PopupOptions } from "../../core/PopupContext";
2
3
  type PopupViewProps = {
3
4
  url: string;
4
5
  popupClassName?: string;
5
6
  onClose?: () => void;
6
7
  eventHandler?: EventHandler | null;
8
+ title?: string;
7
9
  };
8
10
  declare const PopupView: (props: PopupViewProps) => import("react/jsx-runtime").JSX.Element;
9
11
  export default PopupView;
12
+ export type ShowPopupViewRef = {
13
+ id: string;
14
+ close: () => void;
15
+ };
16
+ export type CreatePopupViewRef = {
17
+ show: (options?: Partial<PopupOptions>) => ShowPopupViewRef;
18
+ };
19
+ export type UsePopupViewResult = {
20
+ create: (props: PopupViewProps) => CreatePopupViewRef;
21
+ };
22
+ export declare const usePopupView: () => UsePopupViewResult;
@@ -1,12 +1,13 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { getError } from "@ramesesinc/client";
3
3
  import clsx from "clsx";
4
4
  import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
5
5
  import { twMerge } from "tailwind-merge";
6
6
  import Page from "../../core/Page";
7
7
  import { PageViewProvider } from "../../core/PageViewContext";
8
+ import { usePopupManager } from "../../core/PopupContext";
8
9
  const PopupView = (props) => {
9
- const { url, popupClassName, onClose = () => { }, eventHandler } = props !== null && props !== void 0 ? props : {};
10
+ const { url, popupClassName, onClose = () => { }, eventHandler, title } = props !== null && props !== void 0 ? props : {};
10
11
  const [paths, setPaths] = useState([]);
11
12
  const providerRef = useRef({});
12
13
  const slotRef = useRef(null);
@@ -28,7 +29,7 @@ const PopupView = (props) => {
28
29
  comp = _jsx("div", { children: e.message });
29
30
  }
30
31
  // update the child slot
31
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(comp, finalPopupClass, onClose);
32
+ (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(comp, finalPopupClass, onClose, title);
32
33
  };
33
34
  useEffect(() => {
34
35
  // console.log("popupview change url", url);
@@ -67,25 +68,29 @@ const ChildrenSlot = memo(forwardRef((_, ref) => {
67
68
  const [content, setContent] = useState(null);
68
69
  const optionsRef = useRef({});
69
70
  useImperativeHandle(ref, () => ({
70
- update: (content, popupClassName, onClose) => {
71
- const options = { popupClassName, onClose };
72
- setContent(wrapContent(content, options));
71
+ update: (content, popupClassName, onClose, title) => {
72
+ const options = { popupClassName, onClose, title };
73
73
  optionsRef.current = options;
74
+ setContent(content);
74
75
  },
75
76
  }), []);
76
- const handleClose = () => {
77
- setContent(null);
78
- const { onClose } = optionsRef.current;
79
- if (onClose != null && typeof onClose === "function") {
80
- onClose();
81
- }
82
- };
83
- const wrapContent = (comp, options) => {
84
- if (comp == null) {
85
- return null;
86
- }
87
- const { popupClassName } = options;
88
- return (_jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: _jsxs("div", { className: popupClassName, children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [_jsx("h2", { className: "text-lg font-semibold", children: "Page Viewer" }), _jsx("button", { onClick: handleClose, className: "w-8 h-8 flex items-center justify-center rounded-md hover:bg-gray-100 transition-colors", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), _jsx("div", { className: "flex-1 overflow-hidden", children: comp })] }) }));
89
- };
90
77
  return _jsx(_Fragment, { children: content == null ? null : content });
91
78
  }));
79
+ export const usePopupView = () => {
80
+ const popupManager = usePopupManager();
81
+ const create = (props) => {
82
+ const { url, onClose, eventHandler, title } = props !== null && props !== void 0 ? props : {};
83
+ const show = (options) => {
84
+ const content = _jsx(PopupView, { url: url, onClose: onClose, eventHandler: eventHandler });
85
+ const popup = popupManager.create(options);
86
+ popup.setContent(content);
87
+ popup.show();
88
+ return {
89
+ id: popup.id,
90
+ close: () => popup.close(),
91
+ };
92
+ };
93
+ return { show };
94
+ };
95
+ return { create };
96
+ };
@@ -1,20 +1,23 @@
1
1
  import { BindingModel } from "@ramesesinc/client";
2
2
  type DependCallback = (value?: any) => void;
3
3
  export type DataBindingValue = {
4
+ getType: () => string;
4
5
  getBinding: () => BindingModel;
5
6
  getData: () => Record<string, any>;
7
+ getAllData: () => Record<string, any>;
6
8
  set: (name: string | null, value: any) => void;
7
9
  get: (name: string | null) => any;
8
10
  dependsTo: (name: string | null, callback: DependCallback) => () => void;
9
11
  notifyDepends: (name?: string | null) => void;
10
12
  };
11
- export declare const useCreateContextValue: (source: Record<string, any>) => DataBindingValue;
12
- declare const DataBindingContext: import("react").Context<DataBindingValue | null>;
13
- export declare const useDataContext: () => DataBindingValue | null;
13
+ export declare const useCreateContextValue: (source: Record<string, any>, type: string) => DataBindingValue;
14
+ declare const DataBindingContext: import("react").Context<DataBindingValue>;
15
+ export declare const useDataContext: () => DataBindingValue;
14
16
  type DataBindingProviderProps = {
17
+ type?: "page" | "row";
15
18
  data?: Record<string, any>;
16
19
  handler?: DataBindingValue;
17
20
  children: React.ReactNode;
18
21
  };
19
- export declare const DataBindingProvider: ({ data, handler, children }: DataBindingProviderProps) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const DataBindingProvider: ({ type, data, handler, children }: DataBindingProviderProps) => import("react/jsx-runtime").JSX.Element;
20
23
  export default DataBindingContext;
@@ -1,20 +1,32 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useBinding } from "@ramesesinc/client";
3
3
  import { createContext, useContext, useMemo } from "react";
4
+ import { usePageContext } from "./PageContext";
4
5
  const createDefaultValue = () => ({
6
+ getType: () => "page",
5
7
  getBinding: () => ({}),
6
8
  getData: () => ({}),
9
+ getAllData: () => ({}),
7
10
  set: () => { },
8
11
  get: () => undefined,
9
12
  dependsTo: () => () => { },
10
13
  notifyDepends: () => { },
11
14
  });
12
- export const useCreateContextValue = (source) => {
15
+ export const useCreateContextValue = (source, type) => {
13
16
  const binding = useBinding(source !== null && source !== void 0 ? source : {});
17
+ const pageContext = usePageContext();
18
+ const preferredType = type == null || type.trim() === "" ? "page" : type.toLowerCase();
19
+ const getAllData = () => {
20
+ var _a, _b, _c;
21
+ return Object.assign(Object.assign({}, ((_b = (_a = pageContext === null || pageContext === void 0 ? void 0 : pageContext.binding) === null || _a === void 0 ? void 0 : _a.getUiData()) !== null && _b !== void 0 ? _b : {})), { pageParams: (_c = pageContext === null || pageContext === void 0 ? void 0 : pageContext.getPageParams()) !== null && _c !== void 0 ? _c : {}, data: binding.getData() });
22
+ };
14
23
  return useMemo(() => ({
24
+ getType: () => preferredType,
15
25
  getBinding: () => binding,
16
26
  getData: () => binding.getData(),
27
+ getAllData,
17
28
  set: (name, value) => {
29
+ console.log("DataContext set 1", binding.set);
18
30
  binding.set(name !== null && name !== void 0 ? name : "", value);
19
31
  },
20
32
  get: (name) => {
@@ -28,13 +40,13 @@ export const useCreateContextValue = (source) => {
28
40
  },
29
41
  }), [binding, source]);
30
42
  };
31
- const DataBindingContext = createContext(null);
43
+ const DataBindingContext = createContext(createDefaultValue());
32
44
  export const useDataContext = () => {
33
45
  const context = useContext(DataBindingContext);
34
46
  return context;
35
47
  };
36
- export const DataBindingProvider = ({ data, handler, children }) => {
37
- const dataWrapper = useCreateContextValue(data !== null && data !== void 0 ? data : {});
48
+ export const DataBindingProvider = ({ type, data, handler, children }) => {
49
+ const dataWrapper = useCreateContextValue(data !== null && data !== void 0 ? data : {}, type !== null && type !== void 0 ? type : "");
38
50
  const value = handler !== null && handler !== void 0 ? handler : dataWrapper;
39
51
  return _jsx(DataBindingContext.Provider, { value: value, children: children });
40
52
  };
package/dist/core/Page.js CHANGED
@@ -9,6 +9,7 @@ import { getUrlPageParams, parseHashUrl } from "../lib/utils/PageUtils";
9
9
  import { useApp } from "./AppContext";
10
10
  import { PageProvider } from "./PageContext";
11
11
  import { usePageViewContext } from "./PageViewContext";
12
+ import { usePopupContext } from "./PopupContext";
12
13
  const Page = (props) => {
13
14
  const { url: finalUrl, fallback = _jsx("div", { children: "Loading page..." }) } = props !== null && props !== void 0 ? props : {};
14
15
  const [uuid] = useState(() => Math.random().toString(36).slice(2));
@@ -17,9 +18,9 @@ const Page = (props) => {
17
18
  const [template, setTemplate] = useState(null);
18
19
  const slotRef = useRef(null); // stable — never changes
19
20
  const pageContext = useRef({});
20
- const mountedRef = useRef(true);
21
21
  const { getPageCache } = useApp();
22
22
  const pageView = usePageViewContext();
23
+ const popupContext = usePopupContext();
23
24
  const originalData = useMemo(() => {
24
25
  const result = {
25
26
  mainPath: "",
@@ -38,9 +39,9 @@ const Page = (props) => {
38
39
  // setValue(url ?? null);
39
40
  // }, [url]);
40
41
  useLayoutEffect(() => {
42
+ // console.log("Page useLayoutEffect", uuid, value);
41
43
  const loadPageCache = async () => {
42
44
  var _a;
43
- // console.log("Page value changed", uuid, value, originalData);
44
45
  const url = value;
45
46
  const findPageCache = async (page) => {
46
47
  const pageCache = await getPageCache(page);
@@ -65,10 +66,10 @@ const Page = (props) => {
65
66
  pageCache = await findPageCache(infoCheck.page);
66
67
  }
67
68
  const { template, pageInfo } = pageCache !== null && pageCache !== void 0 ? pageCache : {};
68
- // console.log("page load template 1.2", url, infoCheck);
69
- const { data } = pageInfo !== null && pageInfo !== void 0 ? pageInfo : {};
69
+ const { data, title } = pageInfo !== null && pageInfo !== void 0 ? pageInfo : {};
70
70
  setCache({
71
- url: url,
71
+ url,
72
+ title,
72
73
  page: pageCache,
73
74
  api: data,
74
75
  params: infoCheck.params,
@@ -78,20 +79,18 @@ const Page = (props) => {
78
79
  };
79
80
  loadPageCache();
80
81
  }, [value]);
81
- useEffect(() => {
82
- // console.log("force update", value, cache);
83
- const loadPage = async () => {
84
- const result = await fetchData(cache === null || cache === void 0 ? void 0 : cache.api);
85
- // console.log("fetchData result", uuid, value, result);
86
- pageContext.current.setData(result !== null && result !== void 0 ? result : {});
87
- };
88
- loadPage();
89
- }, [value, cache]);
82
+ // Push dynamic component into the slot — synchronous, no flash
83
+ useLayoutEffect(() => {
84
+ var _a;
85
+ // console.log("Page template changed", uuid, value, template);
86
+ const { title = null } = cache !== null && cache !== void 0 ? cache : {};
87
+ popupContext === null || popupContext === void 0 ? void 0 : popupContext.setTitle(title);
88
+ (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(template);
89
+ }, [template]);
90
90
  const fetchData = useCallback(async (req) => {
91
- // console.log("page fetchData", uuid, req);
91
+ // console.log("Page fetchData", uuid, value, req);
92
92
  let result = null;
93
93
  if (req === null || req === void 0 ? void 0 : req.api) {
94
- // console.log("url", window.location.href);
95
94
  let params;
96
95
  if (pageView.isStandalone()) {
97
96
  const res = parseHashUrl(value !== null && value !== void 0 ? value : "");
@@ -101,23 +100,23 @@ const Page = (props) => {
101
100
  const res = getUrlPageParams();
102
101
  params = res === null || res === void 0 ? void 0 : res.params;
103
102
  }
104
- // console.log({ page, params });
105
- // const urlParams = pageContext?.getUrlParams();
106
- // console.log("page fetchData exec service 1.1", req.params, params);
107
103
  const resolveParams = replaceValues(req.params, params);
108
- // console.log("page fetchData exec service 1.2", req.api, resolveParams);
104
+ // console.log("Page fetchData params", uuid, value, {params, resolveParams});
109
105
  const resp = await pageContext.current.execService(req.api, resolveParams);
110
106
  const { data } = resp !== null && resp !== void 0 ? resp : {};
111
107
  result = data !== null && data !== void 0 ? data : resp;
112
108
  }
113
109
  return result;
114
- // pageContext.current.setData(result ?? {});
115
110
  }, [value]);
116
- // Push dynamic component into the slot — synchronous, no flash
117
- useLayoutEffect(() => {
118
- var _a;
119
- (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(template);
120
- }, [template]);
111
+ useEffect(() => {
112
+ // console.log("Page cache changed", uuid, value, cache);
113
+ const loadPage = async () => {
114
+ const result = await fetchData(cache === null || cache === void 0 ? void 0 : cache.api);
115
+ // console.log("fetchData result", uuid, value, result);
116
+ pageContext.current.setData(result !== null && result !== void 0 ? result : {});
117
+ };
118
+ loadPage();
119
+ }, [value, cache]);
121
120
  const pageHandle = {
122
121
  init: (ref) => {
123
122
  pageContext.current = ref;
@@ -5,18 +5,31 @@ import React from "react";
5
5
  import { DynamicTemplate } from "./DynamicTemplate";
6
6
  // Simple in-memory cache
7
7
  const cache = {};
8
+ // const getPlatformInfo = async () => {
9
+ // const platform = await localAPI.getPlatform();
10
+ // const { multi_tenant, tenant_name } = platform ?? {};
11
+ // return { multi_tenant, tenant_name };
12
+ // };
8
13
  export const getPage = async (name, fallback) => {
9
- const { getTenant: tenant, getModule: module } = fallback;
14
+ let { getTenant: tenant, getModule: module } = fallback;
10
15
  const key = `${module}/${name}`; // ✅ unique per module
11
16
  if (!cache[key]) {
17
+ if (tenant == null || tenant.trim() === "") {
18
+ // get tenant from platform/info API
19
+ const platform = await localAPI.getPlatform();
20
+ const { multi_tenant, tenant_name } = platform !== null && platform !== void 0 ? platform : {};
21
+ if (String(multi_tenant) === "false") {
22
+ tenant = tenant_name !== null && tenant_name !== void 0 ? tenant_name : "";
23
+ }
24
+ }
12
25
  const pageInfo = await localAPI.useMgmt(tenant, module).get("pages", name);
13
26
  if (!pageInfo) {
14
27
  return { template: _jsxs("div", { className: "text-red-500 p-2 border border-red-500", children: ["Page \"", name, "\" not found."] }), pageInfo: null };
15
28
  }
16
- const { template, attr } = pageInfo !== null && pageInfo !== void 0 ? pageInfo : { template: null, attr: {} };
29
+ const { title, template, attr } = pageInfo !== null && pageInfo !== void 0 ? pageInfo : { template: null, attr: {} };
17
30
  delete pageInfo.template;
18
31
  delete pageInfo.attr;
19
- const tmpl = _jsx(DynamicTemplate, { template: template, attr: attr });
32
+ const tmpl = _jsx(DynamicTemplate, { template: template, attr: Object.assign(Object.assign({}, attr), { title }) });
20
33
  const hasSelectionHandling = template === "ExplorerTemplate";
21
34
  cache[key] = { template: tmpl, pageInfo, hasSelectionHandling };
22
35
  }