@ramesesinc/platform-core 0.1.6 → 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 (87) 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/table/DataList.js +2 -2
  6. package/dist/components/view/PopupView.d.ts +13 -0
  7. package/dist/components/view/PopupView.js +25 -20
  8. package/dist/core/DataContext.d.ts +7 -4
  9. package/dist/core/DataContext.js +16 -4
  10. package/dist/core/Page.js +25 -26
  11. package/dist/core/PageCache.js +7 -7
  12. package/dist/core/PageContext.js +17 -7
  13. package/dist/core/PageViewContext.d.ts +13 -1
  14. package/dist/core/PageViewContext.js +75 -2
  15. package/dist/core/PopupContext.d.ts +49 -0
  16. package/dist/core/PopupContext.js +380 -0
  17. package/dist/core/RowContext.js +1 -1
  18. package/dist/core/WindowContext.d.ts +15 -0
  19. package/dist/core/WindowContext.js +28 -0
  20. package/dist/core/index.d.ts +16 -0
  21. package/dist/index.css +25 -7
  22. package/dist/lib/utils/BeanUtils.js +7 -7
  23. package/dist/templates/DataListTemplate.js +7 -2
  24. package/dist/templates/ExplorerTemplate.js +1 -1
  25. package/package.json +5 -5
  26. package/dist/components/action/AlertMessage.tsx +0 -38
  27. package/dist/components/action/Button.tsx +0 -230
  28. package/dist/components/action/CancelEdit.tsx +0 -40
  29. package/dist/components/action/DeleteData.tsx +0 -73
  30. package/dist/components/action/Edit.tsx +0 -40
  31. package/dist/components/action/LookupPage.tsx +0 -113
  32. package/dist/components/action/ProcessRunner.tsx +0 -337
  33. package/dist/components/action/Refresh.tsx +0 -35
  34. package/dist/components/action/SaveData.tsx +0 -74
  35. package/dist/components/action/SelectData.tsx +0 -47
  36. package/dist/components/action/Undo.tsx +0 -50
  37. package/dist/components/action/UpdateData.tsx +0 -49
  38. package/dist/components/action/UpdateState.tsx +0 -40
  39. package/dist/components/action/ViewBackPage.tsx +0 -46
  40. package/dist/components/action/ViewPage.tsx +0 -141
  41. package/dist/components/common/UIComponent.tsx +0 -86
  42. package/dist/components/common/UIInput.tsx +0 -49
  43. package/dist/components/common/UIMenu.tsx +0 -91
  44. package/dist/components/index.ts +0 -51
  45. package/dist/components/input/CodeEditor.tsx +0 -188
  46. package/dist/components/input/DateField.tsx +0 -274
  47. package/dist/components/input/DayPicker.tsx +0 -5
  48. package/dist/components/input/HtmlCode.tsx +0 -203
  49. package/dist/components/input/JsonCode.tsx +0 -205
  50. package/dist/components/input/MonthPicker.tsx +0 -5
  51. package/dist/components/input/ScriptCode.tsx +0 -195
  52. package/dist/components/input/Select.tsx +0 -78
  53. package/dist/components/input/SqlCode.tsx +0 -162
  54. package/dist/components/input/StringDecision.tsx +0 -64
  55. package/dist/components/input/Text.tsx +0 -57
  56. package/dist/components/input/YearPicker.tsx +0 -81
  57. package/dist/components/list/IconMenu.tsx +0 -115
  58. package/dist/components/list/TabMenu.tsx +0 -127
  59. package/dist/components/list/TreeMenu.tsx +0 -279
  60. package/dist/components/list/TxnTaskList.tsx +0 -198
  61. package/dist/components/output/Label.tsx +0 -50
  62. package/dist/components/table/DataList.tsx +0 -820
  63. package/dist/components/table/DataTable.tsx +0 -572
  64. package/dist/components/table/ListHandler.ts +0 -276
  65. package/dist/components/table/TableContext.tsx +0 -122
  66. package/dist/components/view/ComponentView.tsx +0 -102
  67. package/dist/components/view/FilterView.tsx +0 -21
  68. package/dist/components/view/HtmlForm.tsx +0 -176
  69. package/dist/components/view/HtmlView.tsx +0 -98
  70. package/dist/components/view/IFrameView.tsx +0 -48
  71. package/dist/components/view/Modal.tsx +0 -72
  72. package/dist/components/view/PageView.tsx +0 -131
  73. package/dist/components/view/PopupView.tsx +0 -160
  74. package/dist/components/view/RootView.tsx +0 -109
  75. package/dist/components/view/WizardView.tsx +0 -48
  76. package/dist/lib/layouts/BorderLayout.tsx +0 -31
  77. package/dist/lib/layouts/CardLayout.tsx +0 -73
  78. package/dist/lib/layouts/CenterLayout.tsx +0 -20
  79. package/dist/lib/layouts/GridLayout.tsx +0 -20
  80. package/dist/lib/layouts/HPanel.tsx +0 -31
  81. package/dist/lib/layouts/HorizontalLayout.tsx +0 -29
  82. package/dist/lib/layouts/MainLayout.tsx +0 -16
  83. package/dist/lib/layouts/PageLayout.tsx +0 -29
  84. package/dist/lib/layouts/VPanel.tsx +0 -27
  85. package/dist/lib/layouts/XLayout.tsx +0 -29
  86. package/dist/lib/layouts/YLayout.tsx +0 -29
  87. package/dist/lib/layouts/index.ts +0 -13
@@ -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());
@@ -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,11 +5,11 @@ 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 !== null && platform !== void 0 ? platform : {};
11
- return { multi_tenant, tenant_name };
12
- };
8
+ // const getPlatformInfo = async () => {
9
+ // const platform = await localAPI.getPlatform();
10
+ // const { multi_tenant, tenant_name } = platform ?? {};
11
+ // return { multi_tenant, tenant_name };
12
+ // };
13
13
  export const getPage = async (name, fallback) => {
14
14
  let { getTenant: tenant, getModule: module } = fallback;
15
15
  const key = `${module}/${name}`; // ✅ unique per module
@@ -26,10 +26,10 @@ export const getPage = async (name, fallback) => {
26
26
  if (!pageInfo) {
27
27
  return { template: _jsxs("div", { className: "text-red-500 p-2 border border-red-500", children: ["Page \"", name, "\" not found."] }), pageInfo: null };
28
28
  }
29
- 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: {} };
30
30
  delete pageInfo.template;
31
31
  delete pageInfo.attr;
32
- const tmpl = _jsx(DynamicTemplate, { template: template, attr: attr });
32
+ const tmpl = _jsx(DynamicTemplate, { template: template, attr: Object.assign(Object.assign({}, attr), { title }) });
33
33
  const hasSelectionHandling = template === "ExplorerTemplate";
34
34
  cache[key] = { template: tmpl, pageInfo, hasSelectionHandling };
35
35
  }
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useBinding } from "@ramesesinc/client";
4
4
  import { localAPI } from "@ramesesinc/lib/local-api";
5
- import { createContext, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
5
+ import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
6
6
  import { parseHashUrl } from "../lib/utils/PageUtils";
7
7
  import { useApp } from "./AppContext";
8
8
  import { DataBindingProvider } from "./DataContext";
@@ -39,8 +39,8 @@ export const PageProvider = ({ handle, children }) => {
39
39
  const pageView = usePageViewContext();
40
40
  const binding = useBinding();
41
41
  // setup the selectedPath from the handle
42
- // useMemo(() => {
43
- useLayoutEffect(() => {
42
+ useMemo(() => {
43
+ // useLayoutEffect(() => {
44
44
  const path = handle === null || handle === void 0 ? void 0 : handle.getSelectedPath();
45
45
  if (binding && typeof binding.set === "function") {
46
46
  binding.set("selectedPage", path);
@@ -51,8 +51,8 @@ export const PageProvider = ({ handle, children }) => {
51
51
  // return path;
52
52
  }, [handle, binding]);
53
53
  // for DEV purposes only
54
- // useMemo(() => {
55
- useLayoutEffect(() => {
54
+ useMemo(() => {
55
+ // useLayoutEffect(() => {
56
56
  const dependHandler = () => {
57
57
  // console.log("selectedPage changed => ", binding.get("selectedPage"));
58
58
  };
@@ -165,6 +165,15 @@ export const PageProvider = ({ handle, children }) => {
165
165
  return {};
166
166
  }
167
167
  }
168
+ if (name === "pageView" || String(name).startsWith("pageView.")) {
169
+ if (name === "pageView") {
170
+ return pageView.getInfo();
171
+ }
172
+ if (binding && typeof binding.getByPath === "function") {
173
+ return binding.getByPath({ pageView: pageView.getInfo() }, name);
174
+ }
175
+ return null;
176
+ }
168
177
  if (binding && typeof binding.get === "function") {
169
178
  const val = binding.get(name);
170
179
  // console.log("page context get", name, val, binding.getData());
@@ -232,7 +241,8 @@ export const PageProvider = ({ handle, children }) => {
232
241
  getMgmt,
233
242
  postMgmt,
234
243
  getAllData: () => {
235
- const allData = Object.assign(Object.assign({}, (binding && typeof binding.getUiData === "function" ? binding.getUiData() : {})), { data: binding && typeof binding.getData === "function" ? binding.getData() : {}, pageParams: getPageParams() });
244
+ var _a;
245
+ const allData = Object.assign(Object.assign({}, (binding && typeof binding.getUiData === "function" ? binding.getUiData() : {})), { data: binding && typeof binding.getData === "function" ? binding.getData() : {}, pageParams: (_a = getPageParams()) !== null && _a !== void 0 ? _a : {} });
236
246
  return allData;
237
247
  },
238
248
  setPageParams,
@@ -254,7 +264,7 @@ export const PageProvider = ({ handle, children }) => {
254
264
  };
255
265
  }, []);
256
266
  const contextValue = values;
257
- const dataBindingValue = Object.assign(Object.assign({}, contextValue), { getBinding: () => binding });
267
+ const dataBindingValue = Object.assign(Object.assign({}, contextValue), { getBinding: () => binding, getType: () => "page" });
258
268
  useLayoutEffect(() => {
259
269
  if (handle == null)
260
270
  return;