@ramesesinc/platform-core 0.1.0

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 (285) hide show
  1. package/dist/components/action/AlertMessage.d.ts +8 -0
  2. package/dist/components/action/AlertMessage.js +19 -0
  3. package/dist/components/action/AlertMessage.tsx +38 -0
  4. package/dist/components/action/Button.d.ts +21 -0
  5. package/dist/components/action/Button.js +139 -0
  6. package/dist/components/action/Button.tsx +230 -0
  7. package/dist/components/action/CancelEdit.d.ts +9 -0
  8. package/dist/components/action/CancelEdit.js +21 -0
  9. package/dist/components/action/CancelEdit.tsx +40 -0
  10. package/dist/components/action/DeleteData.d.ts +13 -0
  11. package/dist/components/action/DeleteData.js +43 -0
  12. package/dist/components/action/DeleteData.tsx +73 -0
  13. package/dist/components/action/Edit.d.ts +9 -0
  14. package/dist/components/action/Edit.js +21 -0
  15. package/dist/components/action/Edit.tsx +40 -0
  16. package/dist/components/action/LookupPage.d.ts +16 -0
  17. package/dist/components/action/LookupPage.js +62 -0
  18. package/dist/components/action/LookupPage.tsx +113 -0
  19. package/dist/components/action/ProcessRunner.d.ts +62 -0
  20. package/dist/components/action/ProcessRunner.js +156 -0
  21. package/dist/components/action/ProcessRunner.tsx +337 -0
  22. package/dist/components/action/Refresh.d.ts +7 -0
  23. package/dist/components/action/Refresh.js +17 -0
  24. package/dist/components/action/Refresh.tsx +35 -0
  25. package/dist/components/action/SaveData.d.ts +10 -0
  26. package/dist/components/action/SaveData.js +54 -0
  27. package/dist/components/action/SaveData.tsx +74 -0
  28. package/dist/components/action/SelectData.d.ts +8 -0
  29. package/dist/components/action/SelectData.js +29 -0
  30. package/dist/components/action/SelectData.tsx +47 -0
  31. package/dist/components/action/Undo.d.ts +9 -0
  32. package/dist/components/action/Undo.js +31 -0
  33. package/dist/components/action/Undo.tsx +50 -0
  34. package/dist/components/action/UpdateContext.d.ts +9 -0
  35. package/dist/components/action/UpdateContext.js +21 -0
  36. package/dist/components/action/UpdateContext.tsx +40 -0
  37. package/dist/components/action/UpdateData.d.ts +9 -0
  38. package/dist/components/action/UpdateData.js +33 -0
  39. package/dist/components/action/UpdateData.tsx +49 -0
  40. package/dist/components/action/ViewBackPage.d.ts +9 -0
  41. package/dist/components/action/ViewBackPage.js +19 -0
  42. package/dist/components/action/ViewBackPage.tsx +46 -0
  43. package/dist/components/action/ViewPage.d.ts +14 -0
  44. package/dist/components/action/ViewPage.js +88 -0
  45. package/dist/components/action/ViewPage.tsx +141 -0
  46. package/dist/components/common/UIComponent.d.ts +11 -0
  47. package/dist/components/common/UIComponent.js +52 -0
  48. package/dist/components/common/UIComponent.tsx +84 -0
  49. package/dist/components/common/UIInput.d.ts +12 -0
  50. package/dist/components/common/UIInput.js +37 -0
  51. package/dist/components/common/UIInput.tsx +49 -0
  52. package/dist/components/common/UIMenu.d.ts +23 -0
  53. package/dist/components/common/UIMenu.js +61 -0
  54. package/dist/components/common/UIMenu.tsx +91 -0
  55. package/dist/components/index.d.ts +37 -0
  56. package/dist/components/index.js +44 -0
  57. package/dist/components/index.ts +51 -0
  58. package/dist/components/input/CodeEditor.d.ts +12 -0
  59. package/dist/components/input/CodeEditor.js +132 -0
  60. package/dist/components/input/CodeEditor.tsx +188 -0
  61. package/dist/components/input/DateField.d.ts +9 -0
  62. package/dist/components/input/DateField.js +140 -0
  63. package/dist/components/input/DateField.tsx +274 -0
  64. package/dist/components/input/DayPicker.d.ts +2 -0
  65. package/dist/components/input/DayPicker.js +5 -0
  66. package/dist/components/input/DayPicker.tsx +5 -0
  67. package/dist/components/input/HtmlCode.d.ts +8 -0
  68. package/dist/components/input/HtmlCode.js +157 -0
  69. package/dist/components/input/HtmlCode.tsx +203 -0
  70. package/dist/components/input/JsonCode.d.ts +9 -0
  71. package/dist/components/input/JsonCode.js +159 -0
  72. package/dist/components/input/JsonCode.tsx +205 -0
  73. package/dist/components/input/MonthPicker.d.ts +2 -0
  74. package/dist/components/input/MonthPicker.js +5 -0
  75. package/dist/components/input/MonthPicker.tsx +5 -0
  76. package/dist/components/input/ScriptCode.d.ts +8 -0
  77. package/dist/components/input/ScriptCode.js +153 -0
  78. package/dist/components/input/ScriptCode.tsx +195 -0
  79. package/dist/components/input/Select.d.ts +14 -0
  80. package/dist/components/input/Select.js +40 -0
  81. package/dist/components/input/Select.tsx +78 -0
  82. package/dist/components/input/SqlCode.d.ts +8 -0
  83. package/dist/components/input/SqlCode.js +121 -0
  84. package/dist/components/input/SqlCode.tsx +162 -0
  85. package/dist/components/input/StringDecision.d.ts +2 -0
  86. package/dist/components/input/StringDecision.js +34 -0
  87. package/dist/components/input/StringDecision.tsx +64 -0
  88. package/dist/components/input/Text.d.ts +7 -0
  89. package/dist/components/input/Text.js +39 -0
  90. package/dist/components/input/Text.tsx +57 -0
  91. package/dist/components/input/YearPicker.d.ts +8 -0
  92. package/dist/components/input/YearPicker.js +44 -0
  93. package/dist/components/input/YearPicker.tsx +81 -0
  94. package/dist/components/list/IconMenu.d.ts +14 -0
  95. package/dist/components/list/IconMenu.js +72 -0
  96. package/dist/components/list/IconMenu.tsx +115 -0
  97. package/dist/components/list/TabMenu.d.ts +10 -0
  98. package/dist/components/list/TabMenu.js +72 -0
  99. package/dist/components/list/TabMenu.tsx +127 -0
  100. package/dist/components/list/TreeMenu.d.ts +14 -0
  101. package/dist/components/list/TreeMenu.js +207 -0
  102. package/dist/components/list/TreeMenu.tsx +279 -0
  103. package/dist/components/list/TxnTaskList.d.ts +2 -0
  104. package/dist/components/list/TxnTaskList.js +77 -0
  105. package/dist/components/list/TxnTaskList.tsx +198 -0
  106. package/dist/components/output/Label.d.ts +8 -0
  107. package/dist/components/output/Label.js +33 -0
  108. package/dist/components/output/Label.tsx +51 -0
  109. package/dist/components/table/DataList.d.ts +88 -0
  110. package/dist/components/table/DataList.js +361 -0
  111. package/dist/components/table/DataList.tsx +782 -0
  112. package/dist/components/table/DataTable.d.ts +46 -0
  113. package/dist/components/table/DataTable.js +253 -0
  114. package/dist/components/table/DataTable.tsx +572 -0
  115. package/dist/components/table/ListHandler.d.ts +42 -0
  116. package/dist/components/table/ListHandler.js +197 -0
  117. package/dist/components/table/ListHandler.ts +276 -0
  118. package/dist/components/table/TableContext.d.ts +33 -0
  119. package/dist/components/table/TableContext.js +57 -0
  120. package/dist/components/table/TableContext.tsx +122 -0
  121. package/dist/components/view/ComponentView.d.ts +8 -0
  122. package/dist/components/view/ComponentView.js +78 -0
  123. package/dist/components/view/ComponentView.tsx +102 -0
  124. package/dist/components/view/FilterView.d.ts +2 -0
  125. package/dist/components/view/FilterView.js +14 -0
  126. package/dist/components/view/FilterView.tsx +21 -0
  127. package/dist/components/view/HtmlForm.d.ts +7 -0
  128. package/dist/components/view/HtmlForm.js +145 -0
  129. package/dist/components/view/HtmlForm.tsx +186 -0
  130. package/dist/components/view/HtmlView.d.ts +9 -0
  131. package/dist/components/view/HtmlView.js +85 -0
  132. package/dist/components/view/HtmlView.tsx +114 -0
  133. package/dist/components/view/IFrameView.d.ts +2 -0
  134. package/dist/components/view/IFrameView.js +34 -0
  135. package/dist/components/view/IFrameView.tsx +48 -0
  136. package/dist/components/view/Modal.d.ts +14 -0
  137. package/dist/components/view/Modal.js +28 -0
  138. package/dist/components/view/Modal.tsx +72 -0
  139. package/dist/components/view/PageView.d.ts +9 -0
  140. package/dist/components/view/PageView.js +90 -0
  141. package/dist/components/view/PageView.tsx +131 -0
  142. package/dist/components/view/PopupView.d.ts +9 -0
  143. package/dist/components/view/PopupView.js +91 -0
  144. package/dist/components/view/PopupView.tsx +160 -0
  145. package/dist/components/view/RootView.d.ts +8 -0
  146. package/dist/components/view/RootView.js +75 -0
  147. package/dist/components/view/RootView.tsx +109 -0
  148. package/dist/components/view/WizardView.d.ts +6 -0
  149. package/dist/components/view/WizardView.js +34 -0
  150. package/dist/components/view/WizardView.tsx +48 -0
  151. package/dist/core/AppContext.d.ts +25 -0
  152. package/dist/core/AppContext.js +159 -0
  153. package/dist/core/AuthContext.d.ts +13 -0
  154. package/dist/core/AuthContext.js +80 -0
  155. package/dist/core/ComponentCache.d.ts +15 -0
  156. package/dist/core/ComponentCache.js +25 -0
  157. package/dist/core/DataContext.d.ts +20 -0
  158. package/dist/core/DataContext.js +41 -0
  159. package/dist/core/DynamicComponent.d.ts +12 -0
  160. package/dist/core/DynamicComponent.js +30 -0
  161. package/dist/core/DynamicIcon.d.ts +6 -0
  162. package/dist/core/DynamicIcon.js +48 -0
  163. package/dist/core/DynamicTemplate.d.ts +4 -0
  164. package/dist/core/DynamicTemplate.js +17 -0
  165. package/dist/core/ErrorMessage.d.ts +5 -0
  166. package/dist/core/ErrorMessage.js +7 -0
  167. package/dist/core/EventHandler.d.ts +3 -0
  168. package/dist/core/EventHandler.js +1 -0
  169. package/dist/core/HtmlCache.d.ts +6 -0
  170. package/dist/core/HtmlCache.js +17 -0
  171. package/dist/core/Page.d.ts +6 -0
  172. package/dist/core/Page.js +141 -0
  173. package/dist/core/PageCache.d.ts +15 -0
  174. package/dist/core/PageCache.js +26 -0
  175. package/dist/core/PageContext.d.ts +49 -0
  176. package/dist/core/PageContext.js +207 -0
  177. package/dist/core/PageRegistry.d.ts +7 -0
  178. package/dist/core/PageRegistry.js +11 -0
  179. package/dist/core/PageViewContext.d.ts +45 -0
  180. package/dist/core/PageViewContext.js +277 -0
  181. package/dist/core/Panel.d.ts +16 -0
  182. package/dist/core/Panel.js +39 -0
  183. package/dist/core/RowContext.d.ts +11 -0
  184. package/dist/core/RowContext.js +16 -0
  185. package/dist/core/StepHandler.d.ts +9 -0
  186. package/dist/core/StepHandler.js +39 -0
  187. package/dist/core/UIDependHandler.d.ts +6 -0
  188. package/dist/core/UIDependHandler.js +31 -0
  189. package/dist/core/auth/index.d.ts +18 -0
  190. package/dist/core/auth/index.js +187 -0
  191. package/dist/core/auth/session.d.ts +4 -0
  192. package/dist/core/auth/session.js +45 -0
  193. package/dist/core/index.d.ts +3 -0
  194. package/dist/core/index.js +1 -0
  195. package/dist/core/page-helper.d.ts +27 -0
  196. package/dist/core/page-helper.js +47 -0
  197. package/dist/hooks/useUrlParams.d.ts +11 -0
  198. package/dist/hooks/useUrlParams.js +164 -0
  199. package/dist/index.d.ts +65 -0
  200. package/dist/index.js +69 -0
  201. package/dist/layouts/BorderLayout.d.ts +14 -0
  202. package/dist/layouts/BorderLayout.js +8 -0
  203. package/dist/layouts/CardLayout.d.ts +27 -0
  204. package/dist/layouts/CardLayout.js +36 -0
  205. package/dist/layouts/CenterLayout.d.ts +8 -0
  206. package/dist/layouts/CenterLayout.js +6 -0
  207. package/dist/layouts/GridLayout.d.ts +9 -0
  208. package/dist/layouts/GridLayout.js +5 -0
  209. package/dist/layouts/HPanel.d.ts +11 -0
  210. package/dist/layouts/HPanel.js +8 -0
  211. package/dist/layouts/HorizontalLayout.d.ts +11 -0
  212. package/dist/layouts/HorizontalLayout.js +6 -0
  213. package/dist/layouts/MainLayout.d.ts +6 -0
  214. package/dist/layouts/MainLayout.js +5 -0
  215. package/dist/layouts/PageLayout.d.ts +11 -0
  216. package/dist/layouts/PageLayout.js +6 -0
  217. package/dist/layouts/VPanel.d.ts +9 -0
  218. package/dist/layouts/VPanel.js +7 -0
  219. package/dist/layouts/XLayout.d.ts +10 -0
  220. package/dist/layouts/XLayout.js +10 -0
  221. package/dist/layouts/YLayout.d.ts +10 -0
  222. package/dist/layouts/YLayout.js +10 -0
  223. package/dist/lib/PlatformRoute.d.ts +5 -0
  224. package/dist/lib/PlatformRoute.js +288 -0
  225. package/dist/lib/WebPlatform.d.ts +13 -0
  226. package/dist/lib/WebPlatform.js +124 -0
  227. package/dist/lib/components/ActivityBar.d.ts +13 -0
  228. package/dist/lib/components/ActivityBar.js +39 -0
  229. package/dist/lib/components/CopyButton.d.ts +8 -0
  230. package/dist/lib/components/CopyButton.js +50 -0
  231. package/dist/lib/components/Header.d.ts +2 -0
  232. package/dist/lib/components/Header.js +74 -0
  233. package/dist/lib/components/QuickActionMenu.d.ts +18 -0
  234. package/dist/lib/components/QuickActionMenu.js +50 -0
  235. package/dist/lib/components/UserButton.d.ts +11 -0
  236. package/dist/lib/components/UserButton.js +66 -0
  237. package/dist/lib/layouts/BorderLayout.tsx +31 -0
  238. package/dist/lib/layouts/CardLayout.tsx +73 -0
  239. package/dist/lib/layouts/CenterLayout.tsx +20 -0
  240. package/dist/lib/layouts/GridLayout.tsx +20 -0
  241. package/dist/lib/layouts/HPanel.tsx +31 -0
  242. package/dist/lib/layouts/HorizontalLayout.tsx +29 -0
  243. package/dist/lib/layouts/MainLayout.tsx +16 -0
  244. package/dist/lib/layouts/PageLayout.tsx +29 -0
  245. package/dist/lib/layouts/VPanel.tsx +27 -0
  246. package/dist/lib/layouts/XLayout.tsx +29 -0
  247. package/dist/lib/layouts/YLayout.tsx +29 -0
  248. package/dist/lib/utils/BeanUtils.d.ts +3 -0
  249. package/dist/lib/utils/BeanUtils.js +75 -0
  250. package/dist/lib/utils/ComponentLoader.d.ts +13 -0
  251. package/dist/lib/utils/ComponentLoader.js +26 -0
  252. package/dist/lib/utils/ExprUtil.d.ts +7 -0
  253. package/dist/lib/utils/ExprUtil.js +44 -0
  254. package/dist/lib/utils/PageUtils.d.ts +6 -0
  255. package/dist/lib/utils/PageUtils.js +121 -0
  256. package/dist/lib/utils/ResourceLoader.d.ts +11 -0
  257. package/dist/lib/utils/ResourceLoader.js +37 -0
  258. package/dist/lib/utils/SectionProvider.d.ts +5 -0
  259. package/dist/lib/utils/SectionProvider.js +39 -0
  260. package/dist/lib/utils/initResourceLoader.d.ts +0 -0
  261. package/dist/lib/utils/initResourceLoader.js +95 -0
  262. package/dist/styles/index.css +38 -0
  263. package/dist/templates/BasicTemplate.d.ts +2 -0
  264. package/dist/templates/BasicTemplate.js +14 -0
  265. package/dist/templates/CrudFormTemplate.d.ts +2 -0
  266. package/dist/templates/CrudFormTemplate.js +38 -0
  267. package/dist/templates/DataListTemplate.d.ts +2 -0
  268. package/dist/templates/DataListTemplate.js +13 -0
  269. package/dist/templates/ExplorerTemplate.d.ts +10 -0
  270. package/dist/templates/ExplorerTemplate.js +17 -0
  271. package/dist/templates/TxnFormTemplate.d.ts +2 -0
  272. package/dist/templates/TxnFormTemplate.js +66 -0
  273. package/dist/templates/WizardTemplate.d.ts +9 -0
  274. package/dist/templates/WizardTemplate.js +37 -0
  275. package/dist/templates/index.d.ts +5 -0
  276. package/dist/templates/index.js +5 -0
  277. package/dist/types/action.d.ts +8 -0
  278. package/dist/types/action.js +1 -0
  279. package/dist/types/component.d.ts +18 -0
  280. package/dist/types/component.js +1 -0
  281. package/dist/types/list.d.ts +14 -0
  282. package/dist/types/list.js +1 -0
  283. package/dist/types/template.d.ts +6 -0
  284. package/dist/types/template.js +1 -0
  285. package/package.json +56 -0
@@ -0,0 +1,81 @@
1
+ import { useEffect, useRef, useState } from "react";
2
+ import UIComponent from "../common/UIComponent";
3
+ import useUIInput, { UIInputProps } from "../common/UIInput";
4
+
5
+ type YearPickerProps = UIInputProps & {
6
+ min?: number;
7
+ max?: number;
8
+ immediate?: boolean;
9
+ };
10
+
11
+ const YearPicker = (props: YearPickerProps) => {
12
+ const { min = 1900, max, immediate = true } = props ?? {};
13
+ const valueRef = useRef<string>("");
14
+ const [focused, setFocused] = useState(false);
15
+
16
+ // Set default max to current year if not provided
17
+ const currentYear = new Date().getFullYear();
18
+ const maxYear = max || currentYear;
19
+
20
+ // Generate array of years (descending order)
21
+ const years = Array.from({ length: maxYear - min + 1 }, (_, i) => maxYear - i);
22
+
23
+ const onRefresh = () => {
24
+ setInputValue(getValue());
25
+ };
26
+
27
+ const { initialValue, getValue, setValue } = useUIInput({ ...props, onRefresh });
28
+ valueRef.current = initialValue ?? "";
29
+ const [inputValue, setInputValue] = useState(valueRef.current);
30
+
31
+ const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
32
+ const year = e.target.value;
33
+
34
+ if (year !== inputValue) {
35
+ valueRef.current = year;
36
+ setInputValue(valueRef.current);
37
+ }
38
+
39
+ if (immediate) {
40
+ setValue(year);
41
+ }
42
+ };
43
+
44
+ const handleFocus = () => {
45
+ setFocused(true);
46
+ };
47
+
48
+ const handleBlur = () => {
49
+ if (!immediate) {
50
+ setValue(inputValue);
51
+ }
52
+ setFocused(false);
53
+ };
54
+
55
+ useEffect(() => {
56
+ // console.log("inputValue", inputValue);
57
+ }, [inputValue]);
58
+
59
+ return (
60
+ <UIComponent {...(props ?? {})}>
61
+ <div className="flex flex-col gap-1">
62
+ <select
63
+ value={inputValue}
64
+ onChange={handleChange}
65
+ onFocus={handleFocus}
66
+ onBlur={handleBlur}
67
+ className="px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed"
68
+ >
69
+ <option value="">Select year</option>
70
+ {years.map((year) => (
71
+ <option key={year} value={year}>
72
+ {year}
73
+ </option>
74
+ ))}
75
+ </select>
76
+ </div>
77
+ </UIComponent>
78
+ );
79
+ };
80
+
81
+ export default YearPicker;
@@ -0,0 +1,14 @@
1
+ import { AbstractComponent } from "../../types/component";
2
+ import { MenuGroup } from "../common/UIMenu";
3
+ interface IconMenuProps extends AbstractComponent {
4
+ name?: string;
5
+ items?: MenuGroup[];
6
+ data?: Record<string, any>;
7
+ menugroup?: string;
8
+ depends?: string;
9
+ columns?: number;
10
+ size?: "sm" | "md" | "lg";
11
+ style?: string;
12
+ }
13
+ declare const IconMenu: (props: IconMenuProps) => import("react/jsx-runtime").JSX.Element;
14
+ export default IconMenu;
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import clsx from "clsx";
4
+ import { useState } from "react";
5
+ import { twMerge } from "tailwind-merge";
6
+ import DynamicIcon from "../../core/DynamicIcon";
7
+ import { usePageContext } from "../../core/PageContext";
8
+ import { usePageViewContext } from "../../core/PageViewContext";
9
+ import useUIMenu from "../common/UIMenu";
10
+ /* ------------------------------------------------------------------ */
11
+ /* Size config */
12
+ const sizeConfig = {
13
+ sm: { tile: "w-20 h-20", icon: 24, label: "text-xs", gap: "gap-2" },
14
+ md: { tile: "w-28 h-28", icon: 32, label: "text-sm", gap: "gap-3" },
15
+ lg: { tile: "w-36 h-36", icon: 40, label: "text-base", gap: "gap-4" },
16
+ };
17
+ /* ------------------------------------------------------------------ */
18
+ /* Component */
19
+ const IconMenu = (props) => {
20
+ var _a;
21
+ const { name, menugroup, depends, items: itemsProp, data, columns = 5, size = "md", style = "" } = props !== null && props !== void 0 ? props : {};
22
+ const pageContext = usePageContext();
23
+ const pageView = usePageViewContext();
24
+ const contextKey = (_a = name !== null && name !== void 0 ? name : depends) !== null && _a !== void 0 ? _a : "";
25
+ const [activeItem, setActiveItem] = useState(null);
26
+ const defaultPopupClass = `bg-white rounded-lg shadow-xl w-[90%] h-[90%] flex flex-col`;
27
+ const finalPopupClass = twMerge(clsx(defaultPopupClass, style));
28
+ // useUIMenu always returns MenuGroup[]
29
+ const { items } = useUIMenu({ menugroup, items: itemsProp, data });
30
+ const cfg = sizeConfig[size];
31
+ /* ---------------------- Events ---------------------- */
32
+ const handleItemClick = (item) => {
33
+ if (!item.page || item.page === activeItem)
34
+ return;
35
+ if (item.mode == "window") {
36
+ const oldHref = window.location.href;
37
+ const nidx = oldHref.lastIndexOf("/");
38
+ if (nidx > 0) {
39
+ const newUrl = oldHref.substring(0, nidx) + "/" + item.page;
40
+ window.location.href = newUrl;
41
+ }
42
+ }
43
+ else {
44
+ setActiveItem(item.page);
45
+ if (contextKey && contextKey !== "selectedPage") {
46
+ pageContext === null || pageContext === void 0 ? void 0 : pageContext.set(contextKey, item.page);
47
+ }
48
+ else {
49
+ pageView === null || pageView === void 0 ? void 0 : pageView.setPage(item.page);
50
+ }
51
+ }
52
+ };
53
+ /* ---------------------- Shared button ---------------------- */
54
+ const renderButton = (item, index) => (_jsxs("button", { onClick: () => handleItemClick(item), className: `
55
+ ${cfg.tile}
56
+ flex flex-col items-center justify-center gap-2
57
+ rounded-2xl select-none cursor-pointer
58
+ transition-all duration-200 ease-out
59
+ focus:outline-none
60
+ text-gray-600 hover:bg-gray-100 hover:text-gray-900
61
+ `, children: [_jsx(DynamicIcon, { icon: item.icon, size: cfg.icon }), _jsx("span", { className: `${cfg.label} font-semibold leading-tight text-center px-1 truncate w-full`, children: item.title })] }, index));
62
+ /* ---------------------- Render ---------------------- */
63
+ return (_jsx("div", { className: "flex flex-col gap-6 p-4", children: items.map((group, groupIndex) => {
64
+ // Flat item — no group structure
65
+ if (!Array.isArray(group.items)) {
66
+ return renderButton(group, groupIndex);
67
+ }
68
+ // Grouped with category title
69
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [group.title && _jsx("span", { className: "text-xs font-semibold text-gray-400 uppercase tracking-widest px-1", children: group.title }), _jsx("div", { className: `grid ${cfg.gap} justify-items-center`, style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }, children: group.items.map((item, index) => renderButton(item, index)) })] }, groupIndex));
70
+ }) }));
71
+ };
72
+ export default IconMenu;
@@ -0,0 +1,115 @@
1
+ "use client";
2
+
3
+ import clsx from "clsx";
4
+ import { useState } from "react";
5
+ import { twMerge } from "tailwind-merge";
6
+ import DynamicIcon from "../../core/DynamicIcon";
7
+ import { usePageContext } from "../../core/PageContext";
8
+ import { usePageViewContext } from "../../core/PageViewContext";
9
+ import { AbstractComponent } from "../../types/component";
10
+ import useUIMenu, { MenuGroup, MenuItem } from "../common/UIMenu";
11
+
12
+ /* ------------------------------------------------------------------ */
13
+ /* Types */
14
+
15
+ interface IconMenuProps extends AbstractComponent {
16
+ name?: string;
17
+ items?: MenuGroup[];
18
+ data?: Record<string, any>;
19
+ menugroup?: string;
20
+ depends?: string;
21
+ columns?: number;
22
+ size?: "sm" | "md" | "lg";
23
+ style?: string;
24
+ }
25
+
26
+ /* ------------------------------------------------------------------ */
27
+ /* Size config */
28
+
29
+ const sizeConfig = {
30
+ sm: { tile: "w-20 h-20", icon: 24, label: "text-xs", gap: "gap-2" },
31
+ md: { tile: "w-28 h-28", icon: 32, label: "text-sm", gap: "gap-3" },
32
+ lg: { tile: "w-36 h-36", icon: 40, label: "text-base", gap: "gap-4" },
33
+ };
34
+
35
+ /* ------------------------------------------------------------------ */
36
+ /* Component */
37
+
38
+ const IconMenu = (props: IconMenuProps) => {
39
+ const { name, menugroup, depends, items: itemsProp, data, columns = 5, size = "md", style = "" } = props ?? {};
40
+ const pageContext = usePageContext();
41
+ const pageView = usePageViewContext();
42
+ const contextKey = name ?? depends ?? "";
43
+ const [activeItem, setActiveItem] = useState<string | null>(null);
44
+
45
+ const defaultPopupClass = `bg-white rounded-lg shadow-xl w-[90%] h-[90%] flex flex-col`;
46
+ const finalPopupClass = twMerge(clsx(defaultPopupClass, style));
47
+
48
+ // useUIMenu always returns MenuGroup[]
49
+ const { items } = useUIMenu({ menugroup, items: itemsProp, data });
50
+
51
+ const cfg = sizeConfig[size];
52
+
53
+ /* ---------------------- Events ---------------------- */
54
+ const handleItemClick = (item: MenuItem) => {
55
+ if (!item.page || item.page === activeItem) return;
56
+ if (item.mode == "window") {
57
+ const oldHref = window.location.href;
58
+ const nidx = oldHref.lastIndexOf("/");
59
+ if (nidx > 0) {
60
+ const newUrl = oldHref.substring(0, nidx) + "/" + item.page;
61
+ window.location.href = newUrl;
62
+ }
63
+ } else {
64
+ setActiveItem(item.page);
65
+ if (contextKey && contextKey !== "selectedPage") {
66
+ pageContext?.set(contextKey, item.page);
67
+ } else {
68
+ pageView?.setPage(item.page);
69
+ }
70
+ }
71
+ };
72
+
73
+ /* ---------------------- Shared button ---------------------- */
74
+ const renderButton = (item: MenuItem, index: number) => (
75
+ <button
76
+ key={index}
77
+ onClick={() => handleItemClick(item)}
78
+ className={`
79
+ ${cfg.tile}
80
+ flex flex-col items-center justify-center gap-2
81
+ rounded-2xl select-none cursor-pointer
82
+ transition-all duration-200 ease-out
83
+ focus:outline-none
84
+ text-gray-600 hover:bg-gray-100 hover:text-gray-900
85
+ `}
86
+ >
87
+ <DynamicIcon icon={item.icon} size={cfg.icon} />
88
+ <span className={`${cfg.label} font-semibold leading-tight text-center px-1 truncate w-full`}>{item.title}</span>
89
+ </button>
90
+ );
91
+
92
+ /* ---------------------- Render ---------------------- */
93
+ return (
94
+ <div className="flex flex-col gap-6 p-4">
95
+ {(items as MenuGroup[]).map((group, groupIndex) => {
96
+ // Flat item — no group structure
97
+ if (!Array.isArray(group.items)) {
98
+ return renderButton(group as unknown as MenuItem, groupIndex);
99
+ }
100
+
101
+ // Grouped with category title
102
+ return (
103
+ <div key={groupIndex} className="flex flex-col gap-2">
104
+ {group.title && <span className="text-xs font-semibold text-gray-400 uppercase tracking-widest px-1">{group.title}</span>}
105
+ <div className={`grid ${cfg.gap} justify-items-center`} style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}>
106
+ {group.items.map((item, index) => renderButton(item, index))}
107
+ </div>
108
+ </div>
109
+ );
110
+ })}
111
+ </div>
112
+ );
113
+ };
114
+
115
+ export default IconMenu;
@@ -0,0 +1,10 @@
1
+ type TabMenuProps = {
2
+ name?: string;
3
+ depends?: string;
4
+ items?: Record<string, any>[];
5
+ data?: Record<string, any>;
6
+ menugroup?: string;
7
+ orientation?: "horizontal" | "vertical";
8
+ };
9
+ declare const TabMenu: (props: TabMenuProps) => import("react/jsx-runtime").JSX.Element;
10
+ export default TabMenu;
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createElement as _createElement } from "react";
3
+ import { useEffect, useState } from "react";
4
+ import { usePageContext } from "../../core/PageContext";
5
+ import { usePageViewContext } from "../../core/PageViewContext";
6
+ import useDependHandler from "../../core/UIDependHandler";
7
+ import HPanel from "../../layouts/HPanel";
8
+ import VPanel from "../../layouts/VPanel";
9
+ const TabMenu = (props) => {
10
+ var _a;
11
+ const { name, depends, items = [], data, menugroup, orientation = "horizontal" } = props !== null && props !== void 0 ? props : {};
12
+ const [selectedIndex, setSelectedIndex] = useState(-1);
13
+ const [refreshKey, setRefreshKey] = useState(0);
14
+ const pageContext = usePageContext();
15
+ const pageView = usePageViewContext();
16
+ const contextKey = (_a = name !== null && name !== void 0 ? name : depends) !== null && _a !== void 0 ? _a : "";
17
+ const resolvedItems = items.map((item, index) => {
18
+ var _a;
19
+ return (Object.assign(Object.assign({}, item), { key: (_a = item.id) !== null && _a !== void 0 ? _a : Math.random().toString(36).substring(2, 15), index }));
20
+ });
21
+ const onRefresh = () => setRefreshKey((k) => k + 1);
22
+ useDependHandler({ name: depends, onRefresh });
23
+ const handleClick = (item) => {
24
+ setSelectedIndex(item.index);
25
+ if (item.page != null && item.page.trim() !== "") {
26
+ pageView.setPage(item.page);
27
+ }
28
+ else if (contextKey != null && contextKey.trim() !== "") {
29
+ const selItem = Object.assign({}, item);
30
+ delete selItem.id;
31
+ delete selItem.title;
32
+ delete selItem.index;
33
+ delete selItem.key;
34
+ delete selItem.selected;
35
+ delete selItem.onClick;
36
+ pageContext.set(contextKey, selItem); // ← sets "selectedTask" = "new_application_list"
37
+ }
38
+ };
39
+ useEffect(() => {
40
+ if (resolvedItems != null && resolvedItems.length > 0 && selectedIndex === -1) {
41
+ handleClick(resolvedItems[0]);
42
+ }
43
+ }, [resolvedItems]);
44
+ const render = () => {
45
+ if (resolvedItems.length === 0)
46
+ return null;
47
+ const elems = resolvedItems.map((it) => {
48
+ const item = it;
49
+ item.selected = item.index === selectedIndex;
50
+ return _createElement(TabMenuItem, Object.assign({}, item, { key: item.key, onClick: handleClick }));
51
+ });
52
+ if (orientation === "vertical") {
53
+ return (_jsx("div", { className: "border-r border-gray-200", children: _jsx(VPanel, { gap: 25, children: elems }) }));
54
+ }
55
+ return (_jsx("div", { className: "w-full", children: _jsx(HPanel, { gap: 25, children: elems }) }));
56
+ };
57
+ return _jsx("div", { children: render() });
58
+ };
59
+ export default TabMenu;
60
+ /* ------------------------------------------------------------------ */
61
+ /* TabMenuItem */
62
+ const TabMenuItem = (props) => {
63
+ const { title, onClick } = props !== null && props !== void 0 ? props : {};
64
+ const handleClick = () => onClick(props);
65
+ const render = () => {
66
+ if (props.selected) {
67
+ return (_jsxs("div", { onClick: handleClick, className: "relative px-4 py-3 cursor-pointer text-sm transition-all duration-200 text-gray-900 font-semibold", children: [title, _jsx("span", { className: "absolute bottom-0 left-0 w-full h-[2px] rounded-full bg-gray-900" })] }));
68
+ }
69
+ return (_jsx("div", { onClick: handleClick, className: "relative px-4 py-3 cursor-pointer text-sm transition-all duration-200 text-gray-500 font-normal hover:text-gray-600", children: title }));
70
+ };
71
+ return _jsx("div", { onClick: handleClick, children: render() });
72
+ };
@@ -0,0 +1,127 @@
1
+ import { useEffect, useState } from "react";
2
+ import { usePageContext } from "../../core/PageContext";
3
+ import { usePageViewContext } from "../../core/PageViewContext";
4
+ import useDependHandler from "../../core/UIDependHandler";
5
+ import HPanel from "../../layouts/HPanel";
6
+ import VPanel from "../../layouts/VPanel";
7
+
8
+ type TabMenuProps = {
9
+ name?: string;
10
+ depends?: string;
11
+ items?: Record<string, any>[];
12
+ data?: Record<string, any>;
13
+ menugroup?: string;
14
+ orientation?: "horizontal" | "vertical";
15
+ };
16
+
17
+ type TabMenuItemProps = {
18
+ id: string;
19
+ title: string;
20
+ key: string;
21
+ component?: string;
22
+ attr?: Record<string, any>;
23
+ index: number;
24
+ selected?: boolean;
25
+ onClick: (item: Record<string, any>) => void;
26
+ [key: string]: any;
27
+ };
28
+
29
+ const TabMenu = (props: TabMenuProps) => {
30
+ const { name, depends, items = [], data, menugroup, orientation = "horizontal" } = props ?? {};
31
+ const [selectedIndex, setSelectedIndex] = useState(-1);
32
+ const [refreshKey, setRefreshKey] = useState(0);
33
+ const pageContext = usePageContext();
34
+ const pageView = usePageViewContext();
35
+ const contextKey = name ?? depends ?? "";
36
+
37
+ const resolvedItems = items.map((item: any, index: number) => ({
38
+ ...item,
39
+ key: item.id ?? Math.random().toString(36).substring(2, 15),
40
+ index,
41
+ }));
42
+
43
+ const onRefresh = () => setRefreshKey((k) => k + 1);
44
+ useDependHandler({ name: depends, onRefresh });
45
+
46
+ const handleClick = (item: Record<string, any>) => {
47
+ setSelectedIndex(item.index);
48
+
49
+ if (item.page != null && item.page.trim() !== "") {
50
+ pageView.setPage(item.page);
51
+ } else if (contextKey != null && contextKey.trim() !== "") {
52
+ const selItem = { ...item };
53
+ delete selItem.id;
54
+ delete selItem.title;
55
+ delete selItem.index;
56
+ delete selItem.key;
57
+ delete selItem.selected;
58
+ delete selItem.onClick;
59
+ pageContext.set(contextKey, selItem); // ← sets "selectedTask" = "new_application_list"
60
+ }
61
+ };
62
+
63
+ useEffect(() => {
64
+ if (resolvedItems != null && resolvedItems.length > 0 && selectedIndex === -1) {
65
+ handleClick(resolvedItems[0]);
66
+ }
67
+ }, [resolvedItems]);
68
+
69
+ const render = () => {
70
+ if (resolvedItems.length === 0) return null;
71
+
72
+ const elems = resolvedItems.map((it) => {
73
+ const item = it as unknown as TabMenuItemProps;
74
+ item.selected = item.index === selectedIndex;
75
+ return <TabMenuItem {...item} key={item.key} onClick={handleClick} />;
76
+ });
77
+
78
+ if (orientation === "vertical") {
79
+ return (
80
+ <div className="border-r border-gray-200">
81
+ <VPanel gap={25}>{elems}</VPanel>
82
+ </div>
83
+ );
84
+ }
85
+
86
+ return (
87
+ <div className="w-full">
88
+ <HPanel gap={25}>{elems}</HPanel>
89
+ </div>
90
+ );
91
+ };
92
+
93
+ return <div>{render()}</div>;
94
+ };
95
+
96
+ export default TabMenu;
97
+
98
+ /* ------------------------------------------------------------------ */
99
+ /* TabMenuItem */
100
+
101
+ const TabMenuItem = (props: TabMenuItemProps) => {
102
+ const { title, onClick } = props ?? {};
103
+
104
+ const handleClick = () => onClick(props);
105
+
106
+ const render = () => {
107
+ if (props.selected) {
108
+ return (
109
+ <div onClick={handleClick} className="relative px-4 py-3 cursor-pointer text-sm transition-all duration-200 text-gray-900 font-semibold">
110
+ {title}
111
+ <span className="absolute bottom-0 left-0 w-full h-[2px] rounded-full bg-gray-900" />
112
+ </div>
113
+ );
114
+ }
115
+
116
+ return (
117
+ <div
118
+ onClick={handleClick}
119
+ className="relative px-4 py-3 cursor-pointer text-sm transition-all duration-200 text-gray-500 font-normal hover:text-gray-600"
120
+ >
121
+ {title}
122
+ </div>
123
+ );
124
+ };
125
+
126
+ return <div onClick={handleClick}>{render()}</div>;
127
+ };
@@ -0,0 +1,14 @@
1
+ import { AbstractComponent } from "../../types/component";
2
+ import { MenuGroup, MenuItem } from "../common/UIMenu";
3
+ type TreeMenuGroup = MenuGroup & {
4
+ isDropdown?: boolean;
5
+ };
6
+ interface TreeMenuProps extends AbstractComponent {
7
+ name?: string;
8
+ items?: TreeMenuGroup[] | MenuItem[];
9
+ data?: Record<string, any>;
10
+ menugroup?: string;
11
+ depends?: string;
12
+ }
13
+ declare const TreeMenu: (props: TreeMenuProps) => import("react/jsx-runtime").JSX.Element;
14
+ export default TreeMenu;