@ramesesinc/platform-core 0.1.9 → 0.1.10

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 (58) hide show
  1. package/dist/components/action/LookupPage.d.ts +2 -1
  2. package/dist/components/action/LookupPage.js +4 -3
  3. package/dist/components/action/Play.d.ts +6 -0
  4. package/dist/components/action/Play.js +40 -0
  5. package/dist/components/action/ProgressBar.d.ts +8 -0
  6. package/dist/components/action/ProgressBar.js +146 -0
  7. package/dist/components/action/ViewPage.d.ts +2 -1
  8. package/dist/components/action/ViewPage.js +19 -9
  9. package/dist/components/common/UIMenu.js +4 -3
  10. package/dist/components/index.d.ts +4 -1
  11. package/dist/components/index.js +4 -1
  12. package/dist/components/input/Combo.d.ts +21 -0
  13. package/dist/components/input/Combo.js +137 -0
  14. package/dist/components/input/DateField.js +7 -14
  15. package/dist/components/input/Text.d.ts +5 -0
  16. package/dist/components/input/Text.js +42 -7
  17. package/dist/components/list/EditableMenu.d.ts +2 -0
  18. package/dist/components/list/EditableMenu.js +128 -0
  19. package/dist/components/list/TabMenu.js +2 -2
  20. package/dist/components/list/TreeMenu.js +17 -12
  21. package/dist/components/table/DataList.d.ts +1 -1
  22. package/dist/components/table/DataList.js +49 -24
  23. package/dist/components/table/DataTable.d.ts +2 -0
  24. package/dist/components/table/DataTable.js +31 -22
  25. package/dist/components/view/FilterView.js +1 -1
  26. package/dist/components/view/HtmlForm.js +12 -9
  27. package/dist/components/view/PageView.js +36 -9
  28. package/dist/components/view/RootView.js +16 -16
  29. package/dist/core/AuthContext.js +1 -1
  30. package/dist/core/Page.js +2 -4
  31. package/dist/core/PageCache.d.ts +0 -2
  32. package/dist/core/PageCache.js +3 -8
  33. package/dist/core/PageContext.js +12 -0
  34. package/dist/core/PageViewContext.d.ts +8 -2
  35. package/dist/core/PageViewContext.js +129 -75
  36. package/dist/core/Panel.js +31 -9
  37. package/dist/index.css +79 -0
  38. package/dist/layouts/CardLayout.d.ts +2 -2
  39. package/dist/layouts/CardLayout.js +3 -4
  40. package/dist/layouts/HPanel.d.ts +2 -2
  41. package/dist/layouts/HPanel.js +1 -2
  42. package/dist/layouts/VPanel.d.ts +2 -2
  43. package/dist/layouts/VPanel.js +1 -2
  44. package/dist/layouts/index.d.ts +2 -3
  45. package/dist/layouts/index.js +2 -3
  46. package/dist/lib/utils/ExprUtil.js +18 -29
  47. package/dist/lib/utils/ResourceLoader.js +19 -7
  48. package/dist/lib/utils/SectionProvider.js +1 -1
  49. package/dist/lib/utils/initResourceLoader.d.ts +2 -0
  50. package/dist/lib/utils/initResourceLoader.js +64 -95
  51. package/dist/lib/utils/nunjucks.d.ts +2 -0
  52. package/dist/lib/utils/nunjucks.js +8 -0
  53. package/dist/templates/CrudFormTemplate.js +2 -3
  54. package/dist/templates/DataListTemplate.js +1 -1
  55. package/dist/templates/WizardTemplate.js +3 -1
  56. package/package.json +1 -1
  57. package/dist/components/input/Select.d.ts +0 -14
  58. package/dist/components/input/Select.js +0 -40
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { localAPI } from "@ramesesinc/lib/local-api";
3
- import React, { useEffect, useMemo, useState } from "react";
4
- import { useApp } from "../../core/AppContext";
5
2
  import { DynamicComponent } from "../../core/DynamicComponent";
3
+ import { useApp } from "../../core/AppContext";
6
4
  import useDependHandler from "../../core/UIDependHandler";
5
+ import { localAPI } from "@ramesesinc/lib/local-api";
6
+ import { useEffect, useMemo, useState } from "react";
7
7
  import UIComponent from "../common/UIComponent";
8
+ import React from "react";
8
9
  // ─────────────────────────────────────────────────────────────────────────────
9
10
  // Attr Parser
10
11
  // Handles both strict JSON {"key":"value"} and JS object literals {key: "value"}
@@ -18,9 +19,7 @@ function parseAttr(attrStr) {
18
19
  catch (_a) {
19
20
  try {
20
21
  // eslint-disable-next-line no-new-func
21
- // return new Function(`"use strict"; return (${attrStr})`)();
22
- const normalized = attrStr.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)(\s*:)/g, '$1"$2"$3').replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, '"$1"');
23
- return JSON.parse(normalized);
22
+ return new Function(`"use strict"; return (${attrStr})`)();
24
23
  }
25
24
  catch (_b) {
26
25
  console.warn("HtmlForm: could not parse attr →", attrStr);
@@ -60,7 +59,9 @@ function domAttrsToProps(el) {
60
59
  if (["component", "attr"].includes(attr.name))
61
60
  continue;
62
61
  const reactName = (_a = ATTR_MAP[attr.name]) !== null && _a !== void 0 ? _a : attr.name;
63
- props[reactName] = attr.name === "style" ? styleStringToObject(attr.value) : attr.value;
62
+ props[reactName] = attr.name === "style"
63
+ ? styleStringToObject(attr.value)
64
+ : attr.value;
64
65
  }
65
66
  return props;
66
67
  }
@@ -94,14 +95,16 @@ function walkNode(node, parentTag) {
94
95
  if (tag === "span" && componentName) {
95
96
  const attr = parseAttr(el.getAttribute("attr"));
96
97
  const config = { component: componentName, attr };
97
- return _jsx(DynamicComponent, { config: config }, nextKey());
98
+ return (_jsx(DynamicComponent, { config: config }, nextKey()));
98
99
  }
99
100
  // ── Regular element → recurse ──────────────────────────────────────────
100
101
  const props = Object.assign(Object.assign({}, domAttrsToProps(el)), { key: nextKey() });
101
102
  const children = Array.from(el.childNodes)
102
103
  .map((child) => walkNode(child, tag)) // pass current tag as parentTag
103
104
  .filter((n) => n !== null && n !== undefined);
104
- return children.length > 0 ? React.createElement(tag, props, ...children) : React.createElement(tag, props);
105
+ return children.length > 0
106
+ ? React.createElement(tag, props, ...children)
107
+ : React.createElement(tag, props);
105
108
  }
106
109
  return null;
107
110
  }
@@ -1,12 +1,11 @@
1
1
  "use client";
2
2
  import { createElement as _createElement } from "react";
3
3
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
4
- import { forwardRef, memo, useEffect, useImperativeHandle, useRef, useState } from "react";
4
+ import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
5
5
  import Page from "../../core/Page";
6
6
  import { usePageContext } from "../../core/PageContext";
7
7
  import { PageViewProvider, usePageViewContext } from "../../core/PageViewContext";
8
8
  import useDependHandler from "../../core/UIDependHandler";
9
- import { useUrlParams } from "../../hooks/useUrlParams";
10
9
  import UIComponent from "../common/UIComponent";
11
10
  const StableShell = memo((props) => {
12
11
  const { uiProps, slotRef, handle, paths } = props !== null && props !== void 0 ? props : {};
@@ -16,15 +15,16 @@ const PageView = memo((props) => {
16
15
  const { name = "selectedPage", depends, url } = props !== null && props !== void 0 ? props : {};
17
16
  const [forceUpdate, setForceUpdate] = useState({});
18
17
  const providerRef = useRef({});
19
- const { setAnchorPath } = useUrlParams();
20
18
  const slotRef = useRef(null);
21
19
  const pageContext = usePageContext();
22
- const [ownPaths, setOwnPaths] = useState([]);
23
20
  const isEmpty = (value) => value == null || value.trim() === "";
24
21
  const pageView = usePageViewContext();
22
+ const [ownPaths, setOwnPaths] = useState([]);
23
+ const pathsRef = useRef([]);
25
24
  let preferredName = isEmpty(name) ? depends : name;
26
25
  let preferredDepends = isEmpty(depends) ? preferredName : depends;
27
- const newProps = Object.assign(Object.assign({}, props), { name: preferredName, depends: preferredDepends });
26
+ // const newProps = { ...props, name: preferredName, depends: preferredDepends };
27
+ const newProps = useMemo(() => (Object.assign(Object.assign({}, props), { name: preferredName, depends: preferredDepends })), [props, preferredName, preferredDepends]);
28
28
  const propsRef = useRef(newProps);
29
29
  useEffect(() => {
30
30
  propsRef.current = newProps;
@@ -40,6 +40,32 @@ const PageView = memo((props) => {
40
40
  useEffect(() => {
41
41
  getUrlRef.current = getUrl;
42
42
  });
43
+ useEffect(() => {
44
+ var _a;
45
+ let paths = [];
46
+ let firstPath = null;
47
+ if (url == null) {
48
+ const value = pageContext.get(preferredName !== null && preferredName !== void 0 ? preferredName : "");
49
+ if (value == null) {
50
+ // only use subPaths if this pageView is directly under root
51
+ if (pageView.isRootView()) {
52
+ paths = (_a = pageView.getSubPaths()) !== null && _a !== void 0 ? _a : [];
53
+ }
54
+ }
55
+ else {
56
+ paths = String(value).split("#");
57
+ }
58
+ }
59
+ else {
60
+ paths = String(url).split("#");
61
+ }
62
+ [firstPath] = paths;
63
+ if (firstPath == null || firstPath.trim() === "")
64
+ return;
65
+ pathsRef.current = paths;
66
+ setOwnPaths([firstPath]); // ← track own paths
67
+ pageViewHandleRef.current.renderPage(firstPath);
68
+ }, []);
43
69
  // Stable handle — never recreated
44
70
  const pageViewHandleRef = useRef({
45
71
  displayName: "PageView#pageViewHandle",
@@ -62,8 +88,8 @@ const PageView = memo((props) => {
62
88
  return pageView == null ? true : pageView.isStandalone();
63
89
  },
64
90
  });
65
- const onRefresh = (val) => {
66
- setForceUpdate({ val }); // ← carry the value
91
+ const onRefresh = () => {
92
+ setForceUpdate({});
67
93
  };
68
94
  useDependHandler({ name: newProps.depends, onRefresh });
69
95
  useEffect(() => {
@@ -71,10 +97,11 @@ const PageView = memo((props) => {
71
97
  if (prov == null || typeof prov.setPage !== "function")
72
98
  return;
73
99
  const url = getUrlRef.current();
74
- // console.log("pageView forceUpdate", url, providerRef.current);
75
100
  providerRef.current.setPage(url);
76
101
  }, [forceUpdate]);
77
- return _jsx(StableShell, { uiProps: newProps, handle: pageViewHandleRef.current, slotRef: slotRef, paths: ownPaths });
102
+ return (_jsx(StableShell, { uiProps: newProps, handle: pageViewHandleRef.current, slotRef: slotRef,
103
+ // paths={pathsRef.current}
104
+ paths: ownPaths }));
78
105
  });
79
106
  const PageSlot = memo(forwardRef((_, ref) => {
80
107
  const [content, setContent] = useState(null);
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { getError } from "@ramesesinc/client";
3
3
  import { forwardRef, memo, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
4
4
  import Page from "../../core/Page";
@@ -16,6 +16,7 @@ const RootView = (props) => {
16
16
  try {
17
17
  // console.log("RootView loadPage", path); // main#tasklist
18
18
  const pageUUID = "page-" + Math.random().toString(36).slice(2);
19
+ const newUrl = url.split("#");
19
20
  comp = _jsx(Page, { url: path }, pageUUID);
20
21
  }
21
22
  catch (error) {
@@ -29,24 +30,24 @@ const RootView = (props) => {
29
30
  (_a = slotRef.current) === null || _a === void 0 ? void 0 : _a.update(comp);
30
31
  };
31
32
  useLayoutEffect(() => {
32
- const paths = (url == null || url.trim() === "" ? "" : url).split("#");
33
- // console.log("RootView useLayoutEffect ", url, paths);
34
- const [firstPath] = paths;
35
- mainPath.current = firstPath;
36
- setPaths(paths);
33
+ const splitPaths = (url == null || url.trim() === "" ? "" : url).split("#");
34
+ const [mainPage] = splitPaths;
35
+ mainPath.current = mainPage;
36
+ setPaths(splitPaths);
37
37
  }, [url]);
38
+ // fires when paths changes — handles both initial load and url change
38
39
  useEffect(() => {
39
- // this routine is for the initial loading
40
- // pass the original url
41
- loadPage(url);
42
- setReInitPage(false);
40
+ if (paths.length === 0)
41
+ return;
42
+ loadPage(paths[0]);
43
43
  }, [paths]);
44
+ // fires when mode=window navigation happens
45
+ // setPaths first, then loadPage is triggered by paths useEffect
44
46
  useEffect(() => {
45
- if (reInitPage) {
46
- // let the initial loading take effect
47
+ if (newRootPath == null)
47
48
  return;
48
- }
49
- loadPage(newRootPath);
49
+ setPaths([newRootPath]); // ← paths updates first
50
+ // loadPage will be called by paths useEffect after setPaths takes effect
50
51
  }, [newRootPath]);
51
52
  const pageViewHandle = {
52
53
  displayName: "RootView#pageViewHandle",
@@ -54,7 +55,6 @@ const RootView = (props) => {
54
55
  providerRef.current = ref;
55
56
  },
56
57
  renderPage: (page) => {
57
- // console.log("RootView renderPage", page);
58
58
  setNewRootPath(page);
59
59
  },
60
60
  isStandalone: () => standalone,
@@ -71,5 +71,5 @@ const ChildrenSlot = memo(forwardRef((_, ref) => {
71
71
  setContent(content);
72
72
  },
73
73
  }), []);
74
- return _jsx(_Fragment, { children: content == null ? null : content });
74
+ return _jsx("div", { className: "px-2", children: content == null ? null : content });
75
75
  }));
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // lib/context/AuthContext.tsx
3
3
  import { createContext, useContext, useEffect, useState } from "react";
4
- import * as auth from "../core/auth";
5
4
  import { useApp } from "./AppContext";
5
+ import * as auth from "./auth";
6
6
  export const useAuth = () => {
7
7
  const ctx = useContext(AuthContext);
8
8
  if (!ctx)
package/dist/core/Page.js CHANGED
@@ -101,10 +101,8 @@ const Page = (props) => {
101
101
  params = res === null || res === void 0 ? void 0 : res.params;
102
102
  }
103
103
  const resolveParams = replaceValues(req.params, params);
104
- // console.log("Page fetchData params", uuid, value, {params, resolveParams});
105
- const resp = await pageContext.current.execService(req.api, resolveParams);
106
- const { data } = resp !== null && resp !== void 0 ? resp : {};
107
- result = data !== null && data !== void 0 ? data : resp;
104
+ // console.log("page fetchData exec service 1.2", req.api, resolveParams);
105
+ result = await pageContext.current.execService(req.api, resolveParams);
108
106
  }
109
107
  return result;
110
108
  }, [value]);
@@ -6,10 +6,8 @@ interface CacheFallback {
6
6
  export declare const getPage: (name: string, fallback: CacheFallback) => Promise<{
7
7
  template: import("react/jsx-runtime").JSX.Element;
8
8
  pageInfo: null;
9
- hasSelectionHandling?: undefined;
10
9
  } | {
11
10
  template: React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
12
11
  pageInfo: any;
13
- hasSelectionHandling: any;
14
12
  }>;
15
13
  export {};
@@ -5,11 +5,6 @@ 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
- // };
13
8
  export const getPage = async (name, fallback) => {
14
9
  let { getTenant: tenant, getModule: module } = fallback;
15
10
  const key = `${module}/${name}`; // ✅ unique per module
@@ -30,10 +25,10 @@ export const getPage = async (name, fallback) => {
30
25
  delete pageInfo.template;
31
26
  delete pageInfo.attr;
32
27
  const tmpl = _jsx(DynamicTemplate, { template: template, attr: Object.assign(Object.assign({}, attr), { title }) });
33
- const hasSelectionHandling = template === "ExplorerTemplate";
34
- cache[key] = { template: tmpl, pageInfo, hasSelectionHandling };
28
+ // const hasSelectionHandling = template === "ExplorerTemplate";
29
+ cache[key] = { template: tmpl, pageInfo /*, hasSelectionHandling*/ };
35
30
  }
36
31
  const pageCache = cache[key];
37
32
  const newTemplate = React.cloneElement(pageCache.template);
38
- return { template: newTemplate, pageInfo: pageCache.pageInfo, hasSelectionHandling: pageCache.hasSelectionHandling };
33
+ return { template: newTemplate, pageInfo: pageCache.pageInfo /*, hasSelectionHandling: pageCache.hasSelectionHandling*/ };
39
34
  };
@@ -38,6 +38,18 @@ export const PageProvider = ({ handle, children }) => {
38
38
  const parentContext = useContext(PageContext);
39
39
  const pageView = usePageViewContext();
40
40
  const binding = useBinding();
41
+ useLayoutEffect(() => {
42
+ var _a;
43
+ if (handle == null)
44
+ return;
45
+ handle.init(contextValue);
46
+ // load params from pageChain into binding
47
+ const chainInfo = pageView.getPageChainInfo();
48
+ const viewParams = (_a = chainInfo === null || chainInfo === void 0 ? void 0 : chainInfo.params) !== null && _a !== void 0 ? _a : {};
49
+ Object.keys(viewParams).forEach((k) => {
50
+ set(k, viewParams[k]);
51
+ });
52
+ }, []);
41
53
  // setup the selectedPath from the handle
42
54
  useMemo(() => {
43
55
  // useLayoutEffect(() => {
@@ -22,7 +22,6 @@ export type PageViewContextValue = {
22
22
  getTitle: () => string | null;
23
23
  setTitle: (title: string | null) => void;
24
24
  setPage: (page: string | null, options?: PageOptions) => void;
25
- setSelectedPage: (page: string | null) => void;
26
25
  getSelectedPage: () => string | null;
27
26
  pushPage: (page: string) => void;
28
27
  popPage: () => void;
@@ -32,6 +31,12 @@ export type PageViewContextValue = {
32
31
  setSelectionHandling: (hasHandling: boolean) => void;
33
32
  getOriginalLocationInfo: () => PageChainInfo | null;
34
33
  getEventHandler: () => EventHandler | null;
34
+ isRootView: () => boolean;
35
+ getUrl: () => string;
36
+ getPage: () => string;
37
+ getParams: () => Record<string, string>;
38
+ getSubPaths: () => string[];
39
+ getPageChainInfo: () => PageChainInfo;
35
40
  };
36
41
  export type PageViewHandle = {
37
42
  init: (ref: PageViewContextValue) => void;
@@ -39,11 +44,12 @@ export type PageViewHandle = {
39
44
  isStandalone: () => boolean;
40
45
  };
41
46
  export type PageSelectionHandler = {};
42
- type PageChainInfo = {
47
+ export type PageChainInfo = {
43
48
  path: string;
44
49
  base: string;
45
50
  page: string;
46
51
  options: PageOptions;
52
+ params: Record<string, any>;
47
53
  };
48
54
  type PageViewProviderProps = {
49
55
  paths: string[];