@apia/dashboard-controller 4.0.102 → 5.0.1

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 (179) hide show
  1. package/dist/actions/externalFirePanelAction.d.ts +6 -0
  2. package/dist/actions/externalFirePanelAction.d.ts.map +1 -0
  3. package/dist/actions/externalFirePanelAction.js +12 -0
  4. package/dist/actions/externalFirePanelAction.js.map +1 -0
  5. package/dist/actions/firePanelAction.d.ts +6 -0
  6. package/dist/actions/firePanelAction.d.ts.map +1 -0
  7. package/dist/actions/firePanelAction.js +75 -0
  8. package/dist/actions/firePanelAction.js.map +1 -0
  9. package/dist/actions/useActionEventHandlers.d.ts +10 -0
  10. package/dist/actions/useActionEventHandlers.d.ts.map +1 -0
  11. package/dist/actions/useActionEventHandlers.js +67 -0
  12. package/dist/actions/useActionEventHandlers.js.map +1 -0
  13. package/dist/actions/usePanelActions.d.ts +65 -0
  14. package/dist/actions/usePanelActions.d.ts.map +1 -0
  15. package/dist/actions/usePanelActions.js +55 -0
  16. package/dist/actions/usePanelActions.js.map +1 -0
  17. package/dist/actions/usePanelIsLoading.d.ts +4 -0
  18. package/dist/actions/usePanelIsLoading.d.ts.map +1 -0
  19. package/dist/actions/usePanelIsLoading.js +14 -0
  20. package/dist/actions/usePanelIsLoading.js.map +1 -0
  21. package/dist/actions/usePanelNetworkState.d.ts +8 -0
  22. package/dist/actions/usePanelNetworkState.d.ts.map +1 -0
  23. package/dist/actions/usePanelNetworkState.js +21 -0
  24. package/dist/actions/usePanelNetworkState.js.map +1 -0
  25. package/dist/common/usePanelIdentity.d.ts +10 -0
  26. package/dist/common/usePanelIdentity.d.ts.map +1 -0
  27. package/dist/common/usePanelIdentity.js +12 -0
  28. package/dist/common/usePanelIdentity.js.map +1 -0
  29. package/dist/config/parametersStore.d.ts +15 -0
  30. package/dist/config/parametersStore.d.ts.map +1 -0
  31. package/dist/config/parametersStore.js +27 -0
  32. package/dist/config/parametersStore.js.map +1 -0
  33. package/dist/config/saveParameters.d.ts +11 -0
  34. package/dist/config/saveParameters.d.ts.map +1 -0
  35. package/dist/config/saveParameters.js +16 -0
  36. package/dist/config/saveParameters.js.map +1 -0
  37. package/dist/config/usePanelConfig.js +49 -0
  38. package/dist/config/usePanelConfig.js.map +1 -0
  39. package/dist/config/usePanelParametersSelector.d.ts +25 -0
  40. package/dist/config/usePanelParametersSelector.d.ts.map +1 -0
  41. package/dist/config/usePanelParametersSelector.js +17 -0
  42. package/dist/config/usePanelParametersSelector.js.map +1 -0
  43. package/dist/dashboard/ContainerNotFound.js +14 -0
  44. package/dist/dashboard/ContainerNotFound.js.map +1 -0
  45. package/dist/dashboard/DashboardContext.d.ts +6 -0
  46. package/dist/dashboard/DashboardContext.d.ts.map +1 -0
  47. package/dist/dashboard/DashboardContext.js +12 -0
  48. package/dist/dashboard/DashboardContext.js.map +1 -0
  49. package/dist/dashboard/DashboardPanel.d.ts +48 -0
  50. package/dist/dashboard/DashboardPanel.d.ts.map +1 -0
  51. package/dist/dashboard/DashboardPanel.js +264 -0
  52. package/dist/dashboard/DashboardPanel.js.map +1 -0
  53. package/dist/dashboard/DashboardPanelContext.d.ts +6 -0
  54. package/dist/dashboard/DashboardPanelContext.d.ts.map +1 -0
  55. package/dist/dashboard/DashboardPanelContext.js +12 -0
  56. package/dist/dashboard/DashboardPanelContext.js.map +1 -0
  57. package/dist/dashboard/DashboardPanelsBootstraper.d.ts +33 -0
  58. package/dist/dashboard/DashboardPanelsBootstraper.d.ts.map +1 -0
  59. package/dist/dashboard/DashboardPanelsBootstraper.js +135 -0
  60. package/dist/dashboard/DashboardPanelsBootstraper.js.map +1 -0
  61. package/dist/dashboard/DashboardRouter.d.ts +30 -0
  62. package/dist/dashboard/DashboardRouter.d.ts.map +1 -0
  63. package/dist/dashboard/DashboardRouter.js +74 -0
  64. package/dist/dashboard/DashboardRouter.js.map +1 -0
  65. package/dist/dashboard/PanelNotFound.js +17 -0
  66. package/dist/dashboard/PanelNotFound.js.map +1 -0
  67. package/dist/dashboard/dashboard.d.ts +28 -0
  68. package/dist/dashboard/dashboard.d.ts.map +1 -0
  69. package/dist/dashboard/dashboard.js +174 -0
  70. package/dist/dashboard/dashboard.js.map +1 -0
  71. package/dist/eventsController/eventsController.d.ts +11 -0
  72. package/dist/eventsController/eventsController.d.ts.map +1 -0
  73. package/dist/eventsController/eventsController.js +57 -0
  74. package/dist/eventsController/eventsController.js.map +1 -0
  75. package/dist/eventsController/types.d.ts +21 -0
  76. package/dist/eventsController/types.d.ts.map +1 -0
  77. package/dist/eventsController/usePanelFireEvent.d.ts +13 -0
  78. package/dist/eventsController/usePanelFireEvent.d.ts.map +1 -0
  79. package/dist/eventsController/usePanelFireEvent.js +21 -0
  80. package/dist/eventsController/usePanelFireEvent.js.map +1 -0
  81. package/dist/eventsController/usePanelOnEvent.d.ts +12 -0
  82. package/dist/eventsController/usePanelOnEvent.d.ts.map +1 -0
  83. package/dist/eventsController/usePanelOnEvent.js +14 -0
  84. package/dist/eventsController/usePanelOnEvent.js.map +1 -0
  85. package/dist/index.d.ts +31 -467
  86. package/dist/index.js +28 -2290
  87. package/dist/index.js.map +1 -1
  88. package/dist/panelsStore/createPanelStore.d.ts +16 -0
  89. package/dist/panelsStore/createPanelStore.d.ts.map +1 -0
  90. package/dist/panelsStore/createPanelStore.js +58 -0
  91. package/dist/panelsStore/createPanelStore.js.map +1 -0
  92. package/dist/panelsStore/panelsStore.js +59 -0
  93. package/dist/panelsStore/panelsStore.js.map +1 -0
  94. package/dist/panelsStore/usePanelSelector.js +32 -0
  95. package/dist/panelsStore/usePanelSelector.js.map +1 -0
  96. package/dist/panelsUtil/usePanelChangeTitle.d.ts +7 -0
  97. package/dist/panelsUtil/usePanelChangeTitle.d.ts.map +1 -0
  98. package/dist/panelsUtil/usePanelChangeTitle.js +19 -0
  99. package/dist/panelsUtil/usePanelChangeTitle.js.map +1 -0
  100. package/dist/panelsUtil/usePanelTitleAction.d.ts +5 -0
  101. package/dist/panelsUtil/usePanelTitleAction.d.ts.map +1 -0
  102. package/dist/panelsUtil/usePanelTitleAction.js +48 -0
  103. package/dist/panelsUtil/usePanelTitleAction.js.map +1 -0
  104. package/dist/position/usePanelPosition.d.ts +13 -0
  105. package/dist/position/usePanelPosition.d.ts.map +1 -0
  106. package/dist/position/usePanelPosition.js +40 -0
  107. package/dist/position/usePanelPosition.js.map +1 -0
  108. package/dist/splash/events/Dragleave.js +15 -0
  109. package/dist/splash/events/Dragleave.js.map +1 -0
  110. package/dist/splash/events/Dragover.js +120 -0
  111. package/dist/splash/events/Dragover.js.map +1 -0
  112. package/dist/splash/events/Dragstart.js +65 -0
  113. package/dist/splash/events/Dragstart.js.map +1 -0
  114. package/dist/splash/events/Drop.js +66 -0
  115. package/dist/splash/events/Drop.js.map +1 -0
  116. package/dist/splash/panels/DefaultPanelWrapper/CollapseButton.js +31 -0
  117. package/dist/splash/panels/DefaultPanelWrapper/CollapseButton.js.map +1 -0
  118. package/dist/splash/panels/DefaultPanelWrapper/NetworkState.d.ts +8 -0
  119. package/dist/splash/panels/DefaultPanelWrapper/NetworkState.d.ts.map +1 -0
  120. package/dist/splash/panels/DefaultPanelWrapper/NetworkState.js +28 -0
  121. package/dist/splash/panels/DefaultPanelWrapper/NetworkState.js.map +1 -0
  122. package/dist/splash/panels/DefaultPanelWrapper/PanelButtons.d.ts +10 -0
  123. package/dist/splash/panels/DefaultPanelWrapper/PanelButtons.d.ts.map +1 -0
  124. package/dist/splash/panels/DefaultPanelWrapper/PanelButtons.js +32 -0
  125. package/dist/splash/panels/DefaultPanelWrapper/PanelButtons.js.map +1 -0
  126. package/dist/splash/panels/DefaultPanelWrapper/RefreshButton.js +35 -0
  127. package/dist/splash/panels/DefaultPanelWrapper/RefreshButton.js.map +1 -0
  128. package/dist/splash/panels/DefaultPanelWrapper/SettingsButton.js +45 -0
  129. package/dist/splash/panels/DefaultPanelWrapper/SettingsButton.js.map +1 -0
  130. package/dist/splash/panels/DefaultPanelWrapper/index.js +82 -0
  131. package/dist/splash/panels/DefaultPanelWrapper/index.js.map +1 -0
  132. package/dist/splash/panels/EmptyPanelWrapper/index.d.ts +6 -0
  133. package/dist/splash/panels/EmptyPanelWrapper/index.d.ts.map +1 -0
  134. package/dist/splash/panels/EmptyPanelWrapper/index.js +10 -0
  135. package/dist/splash/panels/EmptyPanelWrapper/index.js.map +1 -0
  136. package/dist/splash/panels/LandingPagePanelWrapper.d.ts +6 -0
  137. package/dist/splash/panels/LandingPagePanelWrapper.d.ts.map +1 -0
  138. package/dist/splash/panels/LandingPagePanelWrapper.js +49 -0
  139. package/dist/splash/panels/LandingPagePanelWrapper.js.map +1 -0
  140. package/dist/splash/panels/PanelContext/PanelFooter.d.ts +9 -0
  141. package/dist/splash/panels/PanelContext/PanelFooter.d.ts.map +1 -0
  142. package/dist/splash/panels/PanelContext/PanelFooter.js +72 -0
  143. package/dist/splash/panels/PanelContext/PanelFooter.js.map +1 -0
  144. package/dist/splash/panels/PanelContext/index.d.ts +46 -0
  145. package/dist/splash/panels/PanelContext/index.d.ts.map +1 -0
  146. package/dist/splash/panels/PanelContext/index.js +66 -0
  147. package/dist/splash/panels/PanelContext/index.js.map +1 -0
  148. package/dist/splash/panels/PanelContext/usePanelContextLayout.d.ts +6 -0
  149. package/dist/splash/panels/PanelContext/usePanelContextLayout.d.ts.map +1 -0
  150. package/dist/splash/panels/PanelContext/usePanelContextLayout.js +38 -0
  151. package/dist/splash/panels/PanelContext/usePanelContextLayout.js.map +1 -0
  152. package/dist/splash/panels/PanelContext/usePanelFooter.d.ts +11 -0
  153. package/dist/splash/panels/PanelContext/usePanelFooter.d.ts.map +1 -0
  154. package/dist/splash/panels/PanelContext/usePanelFooter.js +27 -0
  155. package/dist/splash/panels/PanelContext/usePanelFooter.js.map +1 -0
  156. package/dist/splash/panels/PanelContext/useYieldPanelIsReady.d.ts +45 -0
  157. package/dist/splash/panels/PanelContext/useYieldPanelIsReady.d.ts.map +1 -0
  158. package/dist/splash/panels/PanelContext/useYieldPanelIsReady.js +12 -0
  159. package/dist/splash/panels/PanelContext/useYieldPanelIsReady.js.map +1 -0
  160. package/dist/splash/panels/PanelErrorBoundary.js +53 -0
  161. package/dist/splash/panels/PanelErrorBoundary.js.map +1 -0
  162. package/dist/splash/panels/PanelIdentifier.d.ts +16 -0
  163. package/dist/splash/panels/PanelIdentifier.d.ts.map +1 -0
  164. package/dist/splash/panels/PanelIdentifier.js +19 -0
  165. package/dist/splash/panels/PanelIdentifier.js.map +1 -0
  166. package/dist/splash/util/DragAndDrop.js +244 -0
  167. package/dist/splash/util/DragAndDrop.js.map +1 -0
  168. package/dist/splash/util/getColumnAreas.js +19 -0
  169. package/dist/splash/util/getColumnAreas.js.map +1 -0
  170. package/dist/splash/util/isCursorInArea.js +13 -0
  171. package/dist/splash/util/isCursorInArea.js.map +1 -0
  172. package/dist/types.d.ts +30 -0
  173. package/dist/types.d.ts.map +1 -0
  174. package/dist/util.d.ts +8 -0
  175. package/dist/util.d.ts.map +1 -0
  176. package/dist/util.js +55 -0
  177. package/dist/util.js.map +1 -0
  178. package/package.json +8 -9
  179. package/LICENSE.md +0 -6
@@ -0,0 +1,6 @@
1
+ import { TExternalActionDispatcher } from './usePanelActions.js';
2
+
3
+ declare const externalFirePanelAction: TExternalActionDispatcher;
4
+
5
+ export { externalFirePanelAction };
6
+ //# sourceMappingURL=externalFirePanelAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externalFirePanelAction.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { firePanelAction } from './firePanelAction.js';
2
+
3
+ const externalFirePanelAction = (panelId, { action, ...parameters }, options) => {
4
+ const postData = {};
5
+ Object.entries(parameters).forEach(([name, value]) => {
6
+ postData[`p_${name}`] = value;
7
+ });
8
+ firePanelAction(panelId, action, postData, options);
9
+ };
10
+
11
+ export { externalFirePanelAction };
12
+ //# sourceMappingURL=externalFirePanelAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externalFirePanelAction.js","sources":["../../src/actions/externalFirePanelAction.ts"],"sourcesContent":["import { firePanelAction } from './firePanelAction';\r\nimport { TExternalActionDispatcher } from './usePanelActions';\r\n\r\nexport const externalFirePanelAction: TExternalActionDispatcher = (\r\n panelId,\r\n { action, ...parameters },\r\n options,\r\n) => {\r\n const postData: Record<string, unknown> = {};\r\n\r\n Object.entries(parameters).forEach(([name, value]) => {\r\n postData[`p_${name}`] = value;\r\n });\r\n\r\n firePanelAction(panelId, action, postData, options);\r\n};\r\n"],"names":[],"mappings":";;AAGO,MAAM,uBAAA,GAAqD,CAChE,OAAA,EACA,EAAE,QAAQ,GAAG,UAAA,IACb,OAAA,KACG;AACH,EAAA,MAAM,WAAoC,EAAC;AAE3C,EAAA,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,IAAA,EAAM,KAAK,CAAA,KAAM;AACpD,IAAA,QAAA,CAAS,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA,GAAI,KAAA;AAAA,GACzB,CAAA;AAED,EAAA,eAAA,CAAgB,OAAA,EAAS,MAAA,EAAQ,QAAA,EAAU,OAAO,CAAA;AACpD;;;;"}
@@ -0,0 +1,6 @@
1
+ import { TActionResult } from './usePanelActions.js';
2
+
3
+ type TOnSucceed = (hasSucceed: boolean, data: TActionResult) => unknown;
4
+
5
+ export type { TOnSucceed };
6
+ //# sourceMappingURL=firePanelAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firePanelAction.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { ApiaApi, makeApiaUrl } from '@apia/api';
2
+ import { panelActionsEmitter } from './usePanelActions.js';
3
+ import { panelNetworkStateEmitter } from './usePanelNetworkState.js';
4
+ import { ucfirst } from '@apia/util';
5
+ import { setPanelTitleAction, setPanelImageAction, setPanelTitleDescritpion } from '../panelsUtil/usePanelTitleAction.js';
6
+ import { startTransition } from 'react';
7
+ import { changePanelTitle } from '../panelsUtil/usePanelChangeTitle.js';
8
+
9
+ function firePanelAction(panelId, action, parameters, options) {
10
+ const postData = { p_action: action, ...parameters };
11
+ panelActionsEmitter.emit(panelId, `pre${ucfirst(action)}`, null);
12
+ void ApiaApi.post(
13
+ makeApiaUrl({
14
+ action: "panelAction",
15
+ pnlId: panelId
16
+ }),
17
+ { postData, postDataTreatement: "stringify", ...options?.requestConfig }
18
+ ).then((result) => {
19
+ if (result?.status !== 200) {
20
+ console.log("ERROR", panelId);
21
+ panelNetworkStateEmitter.emit("stateChange", {
22
+ panelId,
23
+ isConnected: false
24
+ });
25
+ } else {
26
+ panelNetworkStateEmitter.emit("stateChange", {
27
+ panelId,
28
+ isConnected: true
29
+ });
30
+ }
31
+ try {
32
+ if (result) {
33
+ startTransition(() => {
34
+ if (result?.data?.title) {
35
+ changePanelTitle(
36
+ { panelId },
37
+ result?.data?.title
38
+ );
39
+ }
40
+ if (result?.data?.footer) {
41
+ ({}).changePanelFooter(
42
+ panelId,
43
+ result?.data?.footer
44
+ );
45
+ }
46
+ if (result?.data?.titleAction) {
47
+ setPanelTitleAction(panelId, result?.data?.titleAction);
48
+ }
49
+ setPanelImageAction(panelId, result?.data?.image ?? "");
50
+ if (result?.data?.titleDescription) {
51
+ setPanelTitleDescritpion(
52
+ panelId,
53
+ result?.data?.titleDescription
54
+ );
55
+ }
56
+ options?.onComplete?.(true, result);
57
+ panelActionsEmitter.emit(panelId, action, result);
58
+ });
59
+ } else
60
+ options?.onComplete?.(false, null);
61
+ } catch (e) {
62
+ console.error(e);
63
+ }
64
+ }).catch((e) => {
65
+ console.error(e);
66
+ panelNetworkStateEmitter.emit("stateChange", {
67
+ panelId,
68
+ isConnected: false
69
+ });
70
+ options?.onComplete?.(false, null);
71
+ });
72
+ }
73
+
74
+ export { firePanelAction };
75
+ //# sourceMappingURL=firePanelAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firePanelAction.js","sources":["../../src/actions/firePanelAction.ts"],"sourcesContent":["import { ApiaApi, makeApiaUrl } from '@apia/api';\r\nimport {\r\n TActionDispatcherOptions,\r\n TActionResult,\r\n TFooter,\r\n panelActionsEmitter,\r\n} from './usePanelActions';\r\nimport { panelNetworkStateEmitter } from './usePanelNetworkState';\r\nimport { changePanelTitle } from '../panelsUtil';\r\nimport { ucfirst } from '@apia/util';\r\nimport {\r\n setPanelImageAction,\r\n setPanelTitleAction,\r\n setPanelTitleDescritpion,\r\n} from '../panelsUtil/usePanelTitleAction';\r\nimport { startTransition } from 'react';\r\nimport { TPanelIdentifier } from '../eventsController';\r\n\r\nexport type TOnSucceed = (hasSucceed: boolean, data: TActionResult) => unknown;\r\n\r\n/**\r\n * **MÉTODO DE USO INTERNO**\r\n *\r\n * LLama al server para ejecutar una acción iniciada en el cliente.\r\n *\r\n * La forma de llamar acciones desde un panel es con el hook usePanelActions.\r\n */\r\nexport function firePanelAction(\r\n panelId: string,\r\n action: string,\r\n parameters?: Record<string, unknown>,\r\n options?: TActionDispatcherOptions,\r\n) {\r\n const postData = { p_action: action, ...parameters };\r\n panelActionsEmitter.emit(panelId, `pre${ucfirst(action)}`, null);\r\n void ApiaApi.post(\r\n makeApiaUrl({\r\n action: 'panelAction',\r\n pnlId: panelId,\r\n }),\r\n { postData, postDataTreatement: 'stringify', ...options?.requestConfig },\r\n )\r\n .then((result) => {\r\n if (result?.status !== 200) {\r\n console.log('ERROR', panelId);\r\n panelNetworkStateEmitter.emit('stateChange', {\r\n panelId,\r\n isConnected: false,\r\n });\r\n } else {\r\n panelNetworkStateEmitter.emit('stateChange', {\r\n panelId,\r\n isConnected: true,\r\n });\r\n }\r\n try {\r\n if (result) {\r\n startTransition(() => {\r\n if (result?.data?.title) {\r\n changePanelTitle(\r\n { panelId } as TPanelIdentifier,\r\n (result as TActionResult<{ title: string }>)?.data\r\n ?.title as string,\r\n );\r\n }\r\n if (result?.data?.footer) {\r\n (({}) as any).changePanelFooter(\r\n panelId,\r\n (result as TActionResult<{ footer: TFooter }>)?.data\r\n ?.footer as TFooter,\r\n );\r\n }\r\n if (result?.data?.titleAction) {\r\n setPanelTitleAction(panelId, result?.data?.titleAction as string);\r\n }\r\n\r\n setPanelImageAction(panelId, (result?.data?.image as string) ?? '');\r\n if (result?.data?.titleDescription) {\r\n setPanelTitleDescritpion(\r\n panelId,\r\n result?.data?.titleDescription as string,\r\n );\r\n }\r\n options?.onComplete?.(true, result);\r\n panelActionsEmitter.emit(panelId, action, result);\r\n });\r\n } else options?.onComplete?.(false, null);\r\n } catch (e) {\r\n console.error(e);\r\n }\r\n })\r\n .catch((e) => {\r\n console.error(e);\r\n panelNetworkStateEmitter.emit('stateChange', {\r\n panelId,\r\n isConnected: false,\r\n });\r\n options?.onComplete?.(false, null);\r\n });\r\n}\r\n"],"names":[],"mappings":";;;;;;;;AA2BO,SAAS,eAAA,CACd,OAAA,EACA,MAAA,EACA,UAAA,EACA,OAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAW,EAAE,QAAA,EAAU,MAAA,EAAQ,GAAG,UAAA,EAAW;AACnD,EAAA,mBAAA,CAAoB,KAAK,OAAA,EAAS,CAAA,GAAA,EAAM,QAAQ,MAAM,CAAC,IAAI,IAAI,CAAA;AAC/D,EAAA,KAAK,OAAA,CAAQ,IAAA;AAAA,IACX,WAAA,CAAY;AAAA,MACV,MAAA,EAAQ,aAAA;AAAA,MACR,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,IACD,EAAE,QAAA,EAAU,kBAAA,EAAoB,WAAA,EAAa,GAAG,SAAS,aAAA;AAAc,GACzE,CACG,IAAA,CAAK,CAAC,MAAA,KAAW;AAChB,IAAA,IAAI,MAAA,EAAQ,WAAW,GAAA,EAAK;AAC1B,MAAA,OAAA,CAAQ,GAAA,CAAI,SAAS,OAAO,CAAA;AAC5B,MAAA,wBAAA,CAAyB,KAAK,aAAA,EAAe;AAAA,QAC3C,OAAA;AAAA,QACA,WAAA,EAAa;AAAA,OACd,CAAA;AAAA,KACH,MAAO;AACL,MAAA,wBAAA,CAAyB,KAAK,aAAA,EAAe;AAAA,QAC3C,OAAA;AAAA,QACA,WAAA,EAAa;AAAA,OACd,CAAA;AAAA;AAEH,IAAA,IAAI;AACF,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,eAAA,CAAgB,MAAM;AACpB,UAAA,IAAI,MAAA,EAAQ,MAAM,KAAA,EAAO;AACvB,YAAA,gBAAA;AAAA,cACE,EAAE,OAAA,EAAQ;AAAA,cACT,QAA6C,IAAA,EAC1C;AAAA,aACN;AAAA;AAEF,UAAA,IAAI,MAAA,EAAQ,MAAM,MAAA,EAAQ;AACxB,YAAA,CAAE,EAAC,EAAW,iBAAA;AAAA,cACZ,OAAA;AAAA,cACC,QAA+C,IAAA,EAC5C;AAAA,aACN;AAAA;AAEF,UAAA,IAAI,MAAA,EAAQ,MAAM,WAAA,EAAa;AAC7B,YAAA,mBAAA,CAAoB,OAAA,EAAS,MAAA,EAAQ,IAAA,EAAM,WAAqB,CAAA;AAAA;AAGlE,UAAA,mBAAA,CAAoB,OAAA,EAAU,MAAA,EAAQ,IAAA,EAAM,KAAA,IAAoB,EAAE,CAAA;AAClE,UAAA,IAAI,MAAA,EAAQ,MAAM,gBAAA,EAAkB;AAClC,YAAA,wBAAA;AAAA,cACE,OAAA;AAAA,cACA,QAAQ,IAAA,EAAM;AAAA,aAChB;AAAA;AAEF,UAAA,OAAA,EAAS,UAAA,GAAa,MAAM,MAAM,CAAA;AAClC,UAAA,mBAAA,CAAoB,IAAA,CAAK,OAAA,EAAS,MAAA,EAAQ,MAAM,CAAA;AAAA,SACjD,CAAA;AAAA,OACH;AAAO,QAAA,OAAA,EAAS,UAAA,GAAa,OAAO,IAAI,CAAA;AAAA,aACjC,CAAA,EAAG;AACV,MAAA,OAAA,CAAQ,MAAM,CAAC,CAAA;AAAA;AACjB,GACD,CAAA,CACA,KAAA,CAAM,CAAC,CAAA,KAAM;AACZ,IAAA,OAAA,CAAQ,MAAM,CAAC,CAAA;AACf,IAAA,wBAAA,CAAyB,KAAK,aAAA,EAAe;AAAA,MAC3C,OAAA;AAAA,MACA,WAAA,EAAa;AAAA,KACd,CAAA;AACD,IAAA,OAAA,EAAS,UAAA,GAAa,OAAO,IAAI,CAAA;AAAA,GAClC,CAAA;AACL;;;;"}
@@ -0,0 +1,10 @@
1
+ import { TBasicAction } from '@apia/util';
2
+
3
+ declare const useActionEventHandlers: () => {
4
+ onClick: (ev: React.MouseEvent<HTMLElement, MouseEvent>) => (action: TBasicAction) => void;
5
+ onDoubleClick: (ev: React.MouseEvent<HTMLElement, MouseEvent>) => (action: TBasicAction) => void;
6
+ onKeyDown: (ev: React.KeyboardEvent<HTMLElement>) => (action: TBasicAction) => void;
7
+ };
8
+
9
+ export { useActionEventHandlers };
10
+ //# sourceMappingURL=useActionEventHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActionEventHandlers.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { useCallback } from 'react';
2
+ import { usePanelIdentity } from '../common/usePanelIdentity.js';
3
+ import { handleAction } from '@apia/util';
4
+ import { ApiaApi } from '@apia/api';
5
+ import { firePanelAction } from './firePanelAction.js';
6
+ import { eventsController } from '../eventsController/eventsController.js';
7
+
8
+ const useActionEventHandlers = () => {
9
+ const identifier = usePanelIdentity();
10
+ const handler = useCallback(
11
+ (ev, action) => handleAction(
12
+ {
13
+ callAjaxUrl: ({ url }) => {
14
+ ApiaApi.post(url, { handleLoad: true });
15
+ },
16
+ openTab: ({ url, title }) => {
17
+ window.top?.tabsController.openTabByUrl(title, url);
18
+ },
19
+ fireAction(action2, parameters) {
20
+ firePanelAction(identifier.panelId, action2, parameters, {
21
+ requestConfig: { handleLoad: true }
22
+ });
23
+ },
24
+ fireEvent(eventType, payload) {
25
+ eventsController.fireEvent(identifier, eventType, payload);
26
+ }
27
+ },
28
+ ev,
29
+ action
30
+ ),
31
+ [identifier]
32
+ );
33
+ const onClick = useCallback(
34
+ (ev) => {
35
+ return (action) => {
36
+ if (action.actionSource !== "CLICK")
37
+ return;
38
+ handler(ev, action);
39
+ };
40
+ },
41
+ [handler]
42
+ );
43
+ const onDoubleClick = useCallback(
44
+ (ev) => {
45
+ return (action) => {
46
+ if (action.actionSource !== "DOUBLE_CLICK")
47
+ return;
48
+ handler(ev, action);
49
+ };
50
+ },
51
+ [handler]
52
+ );
53
+ const onKeyDown = useCallback(
54
+ (ev) => {
55
+ return (action) => {
56
+ if (ev.code !== "Enter")
57
+ return;
58
+ handler(ev, action);
59
+ };
60
+ },
61
+ [handler]
62
+ );
63
+ return { onClick, onDoubleClick, onKeyDown };
64
+ };
65
+
66
+ export { useActionEventHandlers };
67
+ //# sourceMappingURL=useActionEventHandlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActionEventHandlers.js","sources":["../../src/actions/useActionEventHandlers.ts"],"sourcesContent":["import { useCallback } from 'react';\r\nimport { usePanelIdentity } from '../common';\r\nimport { handleAction, TBasicAction } from '@apia/util';\r\nimport { ApiaApi } from '@apia/api';\r\nimport { firePanelAction } from './firePanelAction';\r\nimport { eventsController } from '../eventsController';\r\n\r\ninterface ITabsController {\r\n openTabByUrl(title: string, url: string): void;\r\n}\r\n\r\nexport const useActionEventHandlers = () => {\r\n const identifier = usePanelIdentity();\r\n\r\n const handler = useCallback(\r\n (\r\n ev:\r\n | React.MouseEvent<HTMLElement, MouseEvent>\r\n | React.KeyboardEvent<HTMLElement>,\r\n action: TBasicAction,\r\n ) =>\r\n handleAction(\r\n {\r\n callAjaxUrl: ({ url }) => {\r\n ApiaApi.post(url, { handleLoad: true });\r\n },\r\n openTab: ({ url, title }) => {\r\n (\r\n window.top as unknown as { tabsController: ITabsController }\r\n )?.tabsController.openTabByUrl(title, url);\r\n },\r\n fireAction(action, parameters) {\r\n firePanelAction(identifier.panelId, action, parameters, {\r\n requestConfig: { handleLoad: true },\r\n });\r\n },\r\n fireEvent(eventType, payload) {\r\n eventsController.fireEvent(identifier, eventType, payload);\r\n },\r\n },\r\n ev,\r\n action,\r\n ),\r\n [identifier],\r\n );\r\n\r\n const onClick = useCallback(\r\n (ev: React.MouseEvent<HTMLElement, MouseEvent>) => {\r\n return (action: TBasicAction) => {\r\n if (action.actionSource !== 'CLICK') return;\r\n handler(ev, action);\r\n };\r\n },\r\n [handler],\r\n );\r\n\r\n const onDoubleClick = useCallback(\r\n (ev: React.MouseEvent<HTMLElement, MouseEvent>) => {\r\n return (action: TBasicAction) => {\r\n if (action.actionSource !== 'DOUBLE_CLICK') return;\r\n handler(ev, action);\r\n };\r\n },\r\n [handler],\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n (ev: React.KeyboardEvent<HTMLElement>) => {\r\n return (action: TBasicAction) => {\r\n if (ev.code !== 'Enter') return;\r\n handler(ev, action);\r\n };\r\n },\r\n [handler],\r\n );\r\n\r\n return { onClick, onDoubleClick, onKeyDown };\r\n};\r\n"],"names":["action"],"mappings":";;;;;;;AAWO,MAAM,yBAAyB,MAAM;AAC1C,EAAA,MAAM,aAAa,gBAAA,EAAiB;AAEpC,EAAA,MAAM,OAAA,GAAU,WAAA;AAAA,IACd,CACE,IAGA,MAAA,KAEA,YAAA;AAAA,MACE;AAAA,QACE,WAAA,EAAa,CAAC,EAAE,GAAA,EAAI,KAAM;AACxB,UAAA,OAAA,CAAQ,IAAA,CAAK,GAAA,EAAK,EAAE,UAAA,EAAY,MAAM,CAAA;AAAA,SACxC;AAAA,QACA,OAAA,EAAS,CAAC,EAAE,GAAA,EAAK,OAAM,KAAM;AAC3B,UACE,MAAA,CAAO,GAAA,EACN,cAAA,CAAe,YAAA,CAAa,OAAO,GAAG,CAAA;AAAA,SAC3C;AAAA,QACA,UAAA,CAAWA,SAAQ,UAAA,EAAY;AAC7B,UAAA,eAAA,CAAgB,UAAA,CAAW,OAAA,EAASA,OAAAA,EAAQ,UAAA,EAAY;AAAA,YACtD,aAAA,EAAe,EAAE,UAAA,EAAY,IAAA;AAAK,WACnC,CAAA;AAAA,SACH;AAAA,QACA,SAAA,CAAU,WAAW,OAAA,EAAS;AAC5B,UAAA,gBAAA,CAAiB,SAAA,CAAU,UAAA,EAAY,SAAA,EAAW,OAAO,CAAA;AAAA;AAC3D,OACF;AAAA,MACA,EAAA;AAAA,MACA;AAAA,KACF;AAAA,IACF,CAAC,UAAU;AAAA,GACb;AAEA,EAAA,MAAM,OAAA,GAAU,WAAA;AAAA,IACd,CAAC,EAAA,KAAkD;AACjD,MAAA,OAAO,CAAC,MAAA,KAAyB;AAC/B,QAAA,IAAI,OAAO,YAAA,KAAiB,OAAA;AAAS,UAAA;AACrC,QAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,OACpB;AAAA,KACF;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IACpB,CAAC,EAAA,KAAkD;AACjD,MAAA,OAAO,CAAC,MAAA,KAAyB;AAC/B,QAAA,IAAI,OAAO,YAAA,KAAiB,cAAA;AAAgB,UAAA;AAC5C,QAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,OACpB;AAAA,KACF;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,MAAM,SAAA,GAAY,WAAA;AAAA,IAChB,CAAC,EAAA,KAAyC;AACxC,MAAA,OAAO,CAAC,MAAA,KAAyB;AAC/B,QAAA,IAAI,GAAG,IAAA,KAAS,OAAA;AAAS,UAAA;AACzB,QAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA,OACpB;AAAA,KACF;AAAA,IACA,CAAC,OAAO;AAAA,GACV;AAEA,EAAA,OAAO,EAAE,OAAA,EAAS,aAAA,EAAe,SAAA,EAAU;AAC7C;;;;"}
@@ -0,0 +1,65 @@
1
+ import { TApiaApiResult, IApiaApiRequestConfig } from '@apia/api';
2
+ import { TOnSucceed } from './firePanelAction.js';
3
+ import { TBasicAction } from '@apia/util';
4
+
5
+ type TFooter = TBasicAction & {
6
+ force?: boolean;
7
+ };
8
+ type TCommonActionResult = {
9
+ title: string;
10
+ footer: TFooter;
11
+ };
12
+ type TActionResult<T = any> = null | NonNullable<Awaited<TApiaApiResult<T extends Record<string, unknown> ? T & TCommonActionResult : T>>>;
13
+ type TActionDispatcherOptions = {
14
+ onComplete?: TOnSucceed;
15
+ requestConfig?: IApiaApiRequestConfig<object>;
16
+ };
17
+ type TExternalActionDispatcher = (panelId: string, { action, ...parameters }: {
18
+ action: string;
19
+ } & Record<string, unknown>, options?: TActionDispatcherOptions) => void;
20
+ type TActionDispatcher = ({ action, ...parameters }: {
21
+ action: string;
22
+ } & Record<string, unknown>, options?: TActionDispatcherOptions) => Promise<TActionResult>;
23
+ type TActionHandler = (result: TActionResult) => unknown;
24
+ /**
25
+ * El hook usePanelActions es el método principal de comunicación entre el
26
+ * módulo cliente y el módulo server de un panel.
27
+ *
28
+ * Acepta un actionsHandler y devuelve un actionDispatcher.
29
+ *
30
+ * **Existe la acción refresh** que será llamada automáticamente cada vez que
31
+ * se guarde la configuración del panel o se haga click en el botón refrescar
32
+ * del mismo.
33
+ *
34
+ * @param actionsHandler Es un objeto de tipo clave-valor en donde cada clave debe corresponderse con una acción que puede ser ejecutada en el panel. El valor debe ser una función que recibe la respuesta del servidor a la ejecución de la acción.
35
+ *
36
+ * @returns Un método actionDispatcher que permite ejecutar acciones para ser procesadas por la contraparte del panel en el servidor. Al ser llamado acepta un objeto que debe tener como mínimo la propiedad action: string, que indica qué acción será ejecutada. Acepta opcionalmente cualquier cantidad adicional de propiedades en el objeto.
37
+ *
38
+ * @example
39
+ *
40
+ const dispatch = usePanelActions({
41
+ refresh() {
42
+ console.log('Refresh');
43
+ },
44
+ revert(response: TActionResult<TApiaLoadText>) {
45
+ if (response?.data?.text.label !== undefined)
46
+ setLabel(response?.data?.text.label);
47
+ },
48
+ });
49
+
50
+ return <Button
51
+ onClick={() => {
52
+ dispatch({
53
+ action: 'revert',
54
+ text: (document.getElementById('Text') as
55
+ HTMLInputElement).value,
56
+ });
57
+ }}
58
+ >
59
+ Revert
60
+ </Button>
61
+ */
62
+ declare function usePanelActions(actionsHandler?: Record<string, TActionHandler>): TActionDispatcher;
63
+
64
+ export { type TActionDispatcher, type TActionDispatcherOptions, type TActionHandler, type TActionResult, type TCommonActionResult, type TExternalActionDispatcher, type TFooter, usePanelActions };
65
+ //# sourceMappingURL=usePanelActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelActions.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { useMount } from '@apia/util';
2
+ import { usePanelIdentity } from '../common/usePanelIdentity.js';
3
+ import { useDashboardPanel } from '../dashboard/DashboardPanelContext.js';
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField = (obj, key, value) => {
8
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ return value;
10
+ };
11
+ const panelActionsEmitter = new class PanelActionsEmitter {
12
+ constructor() {
13
+ __publicField(this, "listeners", {});
14
+ __publicField(this, "on", (panelId, action, cb) => {
15
+ if (!this.listeners[panelId])
16
+ this.listeners[panelId] = {};
17
+ if (!this.listeners[panelId][action])
18
+ this.listeners[panelId][action] = [];
19
+ this.listeners[panelId][action].push(cb);
20
+ return () => {
21
+ this.listeners[panelId][action] = this.listeners[panelId][action].filter(
22
+ (current) => current !== cb
23
+ );
24
+ };
25
+ });
26
+ __publicField(this, "emit", (panelId, action, data) => {
27
+ this.listeners[panelId]?.[action]?.forEach((current) => {
28
+ window.requestAnimationFrame(() => {
29
+ current({ action, panelId, data });
30
+ });
31
+ });
32
+ });
33
+ }
34
+ }();
35
+ function usePanelActions(actionsHandler) {
36
+ const { panelId } = usePanelIdentity();
37
+ useMount(() => {
38
+ const subscriptions = [];
39
+ Object.entries(actionsHandler ?? {}).forEach(([action, handler]) => {
40
+ subscriptions.push(
41
+ panelActionsEmitter.on(panelId, action, (res) => {
42
+ handler(res.data);
43
+ })
44
+ );
45
+ });
46
+ return () => {
47
+ subscriptions.forEach((unsubscribe) => unsubscribe());
48
+ };
49
+ });
50
+ const panel = useDashboardPanel();
51
+ return panel.fireAction;
52
+ }
53
+
54
+ export { panelActionsEmitter, usePanelActions };
55
+ //# sourceMappingURL=usePanelActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelActions.js","sources":["../../src/actions/usePanelActions.ts"],"sourcesContent":["import { TApiaApiResult, IApiaApiRequestConfig } from '@apia/api';\r\nimport { useMount } from '@apia/util';\r\nimport { usePanelIdentity } from '../common';\r\nimport { TPanelId } from '../types';\r\nimport { TOnSucceed } from './firePanelAction';\r\nimport { TBasicAction } from '@apia/util';\r\nimport { useDashboardPanel } from '../dashboard/DashboardPanelContext';\r\n\r\ntype TActionListener = (result: {\r\n action: string;\r\n data: TActionResult;\r\n panelId: TPanelId;\r\n}) => unknown;\r\n\r\nexport const panelActionsEmitter = new (class PanelActionsEmitter {\r\n listeners: Record<TPanelId, Record<string, TActionListener[]>> = {};\r\n\r\n on = (panelId: TPanelId, action: string, cb: TActionListener) => {\r\n if (!this.listeners[panelId]) this.listeners[panelId] = {};\r\n if (!this.listeners[panelId][action]) this.listeners[panelId][action] = [];\r\n\r\n this.listeners[panelId][action].push(cb);\r\n\r\n return () => {\r\n this.listeners[panelId][action] = this.listeners[panelId][action].filter(\r\n (current) => current !== cb,\r\n );\r\n };\r\n };\r\n\r\n emit = (panelId: TPanelId, action: string, data: TActionResult) => {\r\n this.listeners[panelId]?.[action]?.forEach((current) => {\r\n window.requestAnimationFrame(() => {\r\n current({ action, panelId, data });\r\n });\r\n });\r\n };\r\n})();\r\n\r\nexport type TFooter = TBasicAction & { force?: boolean };\r\n\r\nexport type TCommonActionResult = { title: string; footer: TFooter };\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type TActionResult<T = any> = null | NonNullable<\r\n Awaited<\r\n TApiaApiResult<\r\n T extends Record<string, unknown> ? T & TCommonActionResult : T\r\n >\r\n >\r\n>;\r\n\r\nexport type TActionDispatcherOptions = {\r\n onComplete?: TOnSucceed;\r\n requestConfig?: IApiaApiRequestConfig<object>;\r\n};\r\n\r\nexport type TExternalActionDispatcher = (\r\n panelId: string,\r\n { action, ...parameters }: { action: string } & Record<string, unknown>,\r\n options?: TActionDispatcherOptions,\r\n) => void;\r\n\r\nexport type TActionDispatcher = (\r\n { action, ...parameters }: { action: string } & Record<string, unknown>,\r\n options?: TActionDispatcherOptions,\r\n) => Promise<TActionResult>;\r\n\r\nexport type TActionHandler = (result: TActionResult) => unknown;\r\n\r\n/**\r\n * El hook usePanelActions es el método principal de comunicación entre el\r\n * módulo cliente y el módulo server de un panel.\r\n *\r\n * Acepta un actionsHandler y devuelve un actionDispatcher.\r\n *\r\n * **Existe la acción refresh** que será llamada automáticamente cada vez que\r\n * se guarde la configuración del panel o se haga click en el botón refrescar\r\n * del mismo.\r\n *\r\n * @param actionsHandler Es un objeto de tipo clave-valor en donde cada clave debe corresponderse con una acción que puede ser ejecutada en el panel. El valor debe ser una función que recibe la respuesta del servidor a la ejecución de la acción.\r\n *\r\n * @returns Un método actionDispatcher que permite ejecutar acciones para ser procesadas por la contraparte del panel en el servidor. Al ser llamado acepta un objeto que debe tener como mínimo la propiedad action: string, que indica qué acción será ejecutada. Acepta opcionalmente cualquier cantidad adicional de propiedades en el objeto.\r\n *\r\n * @example\r\n *\r\n const dispatch = usePanelActions({\r\n refresh() {\r\n console.log('Refresh');\r\n },\r\n revert(response: TActionResult<TApiaLoadText>) {\r\n if (response?.data?.text.label !== undefined)\r\n setLabel(response?.data?.text.label);\r\n },\r\n });\r\n\r\n return <Button\r\n onClick={() => {\r\n dispatch({\r\n action: 'revert',\r\n text: (document.getElementById('Text') as\r\n HTMLInputElement).value,\r\n });\r\n }}\r\n >\r\n Revert\r\n </Button>\r\n */\r\nexport function usePanelActions(\r\n actionsHandler?: Record<string, TActionHandler>,\r\n) {\r\n const { panelId } = usePanelIdentity();\r\n\r\n useMount(() => {\r\n const subscriptions: (() => unknown)[] = [];\r\n\r\n Object.entries(actionsHandler ?? {}).forEach(([action, handler]) => {\r\n subscriptions.push(\r\n panelActionsEmitter.on(panelId, action, (res) => {\r\n handler(res.data);\r\n }),\r\n );\r\n });\r\n\r\n return () => {\r\n subscriptions.forEach((unsubscribe) => unsubscribe());\r\n };\r\n });\r\n\r\n const panel = useDashboardPanel();\r\n\r\n return panel.fireAction as TActionDispatcher;\r\n}\r\n"],"names":[],"mappings":";;;;;;;;;;AAcO,MAAM,mBAAA,GAAsB,IAAK,MAAM,mBAAA,CAAoB;AAAA,EAA1B,WAAA,GAAA;AACtC,IAAA,aAAA,CAAA,IAAA,EAAA,WAAA,EAAiE,EAAC,CAAA;AAElE,IAAA,aAAA,CAAA,IAAA,EAAA,IAAA,EAAK,CAAC,OAAA,EAAmB,MAAA,EAAgB,EAAA,KAAwB;AAC/D,MAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA;AAAG,QAAA,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,GAAI,EAAC;AACzD,MAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,OAAO,EAAE,MAAM,CAAA;AAAG,QAAA,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,CAAE,MAAM,IAAI,EAAC;AAEzE,MAAA,IAAA,CAAK,UAAU,OAAO,CAAA,CAAE,MAAM,CAAA,CAAE,KAAK,EAAE,CAAA;AAEvC,MAAA,OAAO,MAAM;AACX,QAAA,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,CAAE,MAAM,CAAA,GAAI,KAAK,SAAA,CAAU,OAAO,CAAA,CAAE,MAAM,CAAA,CAAE,MAAA;AAAA,UAChE,CAAC,YAAY,OAAA,KAAY;AAAA,SAC3B;AAAA,OACF;AAAA,KACF,CAAA;AAEA,IAAA,aAAA,CAAA,IAAA,EAAA,MAAA,EAAO,CAAC,OAAA,EAAmB,MAAA,EAAgB,IAAA,KAAwB;AACjE,MAAA,IAAA,CAAK,UAAU,OAAO,CAAA,GAAI,MAAM,CAAA,EAAG,OAAA,CAAQ,CAAC,OAAA,KAAY;AACtD,QAAA,MAAA,CAAO,sBAAsB,MAAM;AACjC,UAAA,OAAA,CAAQ,EAAE,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA;AAAA,SAClC,CAAA;AAAA,OACF,CAAA;AAAA,KACH,CAAA;AAAA;AACF,CAAA;AAuEO,SAAS,gBACd,cAAA,EACA;AACA,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,gBAAA,EAAiB;AAErC,EAAA,QAAA,CAAS,MAAM;AACb,IAAA,MAAM,gBAAmC,EAAC;AAE1C,IAAA,MAAA,CAAO,OAAA,CAAQ,cAAA,IAAkB,EAAE,CAAA,CAAE,QAAQ,CAAC,CAAC,MAAA,EAAQ,OAAO,CAAA,KAAM;AAClE,MAAA,aAAA,CAAc,IAAA;AAAA,QACZ,mBAAA,CAAoB,EAAA,CAAG,OAAA,EAAS,MAAA,EAAQ,CAAC,GAAA,KAAQ;AAC/C,UAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAAA,SACjB;AAAA,OACH;AAAA,KACD,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,aAAA,CAAc,OAAA,CAAQ,CAAC,WAAA,KAAgB,WAAA,EAAa,CAAA;AAAA,KACtD;AAAA,GACD,CAAA;AAED,EAAA,MAAM,QAAQ,iBAAA,EAAkB;AAEhC,EAAA,OAAO,KAAA,CAAM,UAAA;AACf;;;;"}
@@ -0,0 +1,4 @@
1
+ declare function usePanelIsLoading(): boolean;
2
+
3
+ export { usePanelIsLoading };
4
+ //# sourceMappingURL=usePanelIsLoading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelIsLoading.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { useState } from 'react';
2
+ import { usePanelActions } from './usePanelActions.js';
3
+
4
+ function usePanelIsLoading() {
5
+ const [isLoading, setIsLoading] = useState(false);
6
+ usePanelActions({
7
+ preRefresh: () => setIsLoading(true),
8
+ refresh: () => setIsLoading(false)
9
+ });
10
+ return isLoading;
11
+ }
12
+
13
+ export { usePanelIsLoading };
14
+ //# sourceMappingURL=usePanelIsLoading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelIsLoading.js","sources":["../../src/actions/usePanelIsLoading.ts"],"sourcesContent":["import { useState } from 'react';\r\nimport { usePanelActions } from './usePanelActions';\r\n\r\nexport function usePanelIsLoading() {\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n usePanelActions({\r\n preRefresh: () => setIsLoading(true),\r\n refresh: () => setIsLoading(false),\r\n });\r\n\r\n return isLoading;\r\n}\r\n"],"names":[],"mappings":";;;AAGO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAA,eAAA,CAAgB;AAAA,IACd,UAAA,EAAY,MAAM,YAAA,CAAa,IAAI,CAAA;AAAA,IACnC,OAAA,EAAS,MAAM,YAAA,CAAa,KAAK;AAAA,GAClC,CAAA;AAED,EAAA,OAAO,SAAA;AACT;;;;"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Permite saber en todo momento si el panel actual tuvo un error en su
3
+ * conexión de red
4
+ */
5
+ declare const usePanelNetworkState: () => boolean;
6
+
7
+ export { usePanelNetworkState };
8
+ //# sourceMappingURL=usePanelNetworkState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelNetworkState.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { EventEmitter } from '@apia/util';
3
+ import { usePanelIdentity } from '../common/usePanelIdentity.js';
4
+
5
+ class PanelNetworkStateEmitter extends EventEmitter {
6
+ }
7
+ const panelNetworkStateEmitter = new PanelNetworkStateEmitter();
8
+ const usePanelNetworkState = () => {
9
+ const [isConnected, setIsConnected] = useState(true);
10
+ const { panelId } = usePanelIdentity();
11
+ useEffect(() => {
12
+ return panelNetworkStateEmitter.on("stateChange", (ev) => {
13
+ if (ev.panelId === panelId && ev.isConnected !== isConnected)
14
+ setIsConnected(ev.isConnected);
15
+ });
16
+ }, [isConnected, panelId]);
17
+ return isConnected;
18
+ };
19
+
20
+ export { panelNetworkStateEmitter, usePanelNetworkState };
21
+ //# sourceMappingURL=usePanelNetworkState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelNetworkState.js","sources":["../../src/actions/usePanelNetworkState.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\r\nimport { EventEmitter, TId } from '@apia/util';\r\nimport { usePanelIdentity } from '../common';\r\n\r\nclass PanelNetworkStateEmitter extends EventEmitter<{\r\n stateChange: {\r\n panelId: TId;\r\n isConnected: boolean;\r\n };\r\n}> {}\r\n\r\nexport const panelNetworkStateEmitter = new PanelNetworkStateEmitter();\r\n\r\n/**\r\n * Permite saber en todo momento si el panel actual tuvo un error en su\r\n * conexión de red\r\n */\r\nexport const usePanelNetworkState = () => {\r\n const [isConnected, setIsConnected] = useState(true);\r\n\r\n const { panelId } = usePanelIdentity();\r\n\r\n useEffect(() => {\r\n return panelNetworkStateEmitter.on('stateChange', (ev) => {\r\n if (ev.panelId === panelId && ev.isConnected !== isConnected)\r\n setIsConnected(ev.isConnected);\r\n });\r\n }, [isConnected, panelId]);\r\n\r\n return isConnected;\r\n};\r\n"],"names":[],"mappings":";;;;AAIA,MAAM,iCAAiC,YAAA,CAKpC;AAAC;AAEG,MAAM,wBAAA,GAA2B,IAAI,wBAAA;AAMrC,MAAM,uBAAuB,MAAM;AACxC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,IAAI,CAAA;AAEnD,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,gBAAA,EAAiB;AAErC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,wBAAA,CAAyB,EAAA,CAAG,aAAA,EAAe,CAAC,EAAA,KAAO;AACxD,MAAA,IAAI,EAAA,CAAG,OAAA,KAAY,OAAA,IAAW,EAAA,CAAG,WAAA,KAAgB,WAAA;AAC/C,QAAA,cAAA,CAAe,GAAG,WAAW,CAAA;AAAA,KAChC,CAAA;AAAA,GACH,EAAG,CAAC,WAAA,EAAa,OAAO,CAAC,CAAA;AAEzB,EAAA,OAAO,WAAA;AACT;;;;"}
@@ -0,0 +1,10 @@
1
+ import { TPanelIdentifier } from '../eventsController/types.js';
2
+ import '../dashboard/DashboardPanelsBootstraper.js';
3
+
4
+ /**
5
+ * Permite acceder a la identidad del panel actual.
6
+ */
7
+ declare function usePanelIdentity(): TPanelIdentifier;
8
+
9
+ export { usePanelIdentity };
10
+ //# sourceMappingURL=usePanelIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelIdentity.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { useContext } from 'react';
2
+ import { PanelIdentifierContext } from '../splash/panels/PanelIdentifier.js';
3
+
4
+ function usePanelIdentity() {
5
+ const context = useContext(PanelIdentifierContext);
6
+ if (!context)
7
+ throw new Error("Trying to access an unexistent PanelIdentifierContext");
8
+ return context;
9
+ }
10
+
11
+ export { usePanelIdentity };
12
+ //# sourceMappingURL=usePanelIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelIdentity.js","sources":["../../src/common/usePanelIdentity.ts"],"sourcesContent":["import { useContext } from 'react';\r\nimport { PanelIdentifierContext } from '../splash/panels/PanelIdentifier';\r\n\r\n/**\r\n * Permite acceder a la identidad del panel actual.\r\n */\r\nexport function usePanelIdentity() {\r\n const context = useContext(PanelIdentifierContext);\r\n\r\n if (!context)\r\n throw new Error('Trying to access an unexistent PanelIdentifierContext');\r\n\r\n return context;\r\n}\r\n"],"names":[],"mappings":";;;AAMO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,OAAA,GAAU,WAAW,sBAAsB,CAAA;AAEjD,EAAA,IAAI,CAAC,OAAA;AACH,IAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAEzE,EAAA,OAAO,OAAA;AACT;;;;"}
@@ -0,0 +1,15 @@
1
+ type TPanelParameter = string | number | boolean;
2
+ type TParamsStore = Record<string, TPanelParameter>;
3
+ type TPortableAction = {
4
+ type: string;
5
+ payload?: unknown;
6
+ };
7
+ type TPortableStore = {
8
+ dispatch: (action: TPortableAction) => unknown;
9
+ getState: () => unknown;
10
+ subscribe: (listener: () => void) => () => void;
11
+ };
12
+ declare const parametersStore: TPortableStore;
13
+
14
+ export { type TPanelParameter, type TParamsStore, parametersStore };
15
+ //# sourceMappingURL=parametersStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parametersStore.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { injectReducers, createSlice } from '@apia/store';
2
+
3
+ const paramsSlice = createSlice({
4
+ initialState: {},
5
+ name: "panelParameters",
6
+ reducers: {
7
+ udpate(state, {
8
+ payload
9
+ }) {
10
+ if (!state[payload.panelId])
11
+ state[payload.panelId] = {};
12
+ state[payload.panelId] = {
13
+ ...state[payload.panelId],
14
+ ...payload.parameters
15
+ };
16
+ }
17
+ }
18
+ });
19
+ const { store, useSelector } = injectReducers({
20
+ panelParameters: paramsSlice.reducer
21
+ });
22
+ const parametersStore = store;
23
+ const useParametersSelector = useSelector;
24
+ const parametersActions = paramsSlice.actions;
25
+
26
+ export { parametersActions, parametersStore, useParametersSelector };
27
+ //# sourceMappingURL=parametersStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parametersStore.js","sources":["../../src/config/parametersStore.ts"],"sourcesContent":["import { createSlice, injectReducers, PayloadAction } from '@apia/store';\r\nimport { TPanelId } from '../types';\r\n\r\nexport type TPanelParameter = string | number | boolean;\r\nexport type TParamsStore = Record<string, TPanelParameter>;\r\nexport type TParamsSlice = Record<string, TParamsStore>;\r\n\r\nconst paramsSlice = createSlice({\r\n initialState: {} as TParamsSlice,\r\n name: 'panelParameters',\r\n reducers: {\r\n udpate(\r\n state,\r\n {\r\n payload,\r\n }: PayloadAction<{\r\n panelId: TPanelId;\r\n parameters: TParamsStore;\r\n }>,\r\n ) {\r\n if (!state[payload.panelId]) state[payload.panelId] = {};\r\n\r\n state[payload.panelId] = {\r\n ...state[payload.panelId],\r\n ...payload.parameters,\r\n };\r\n },\r\n },\r\n});\r\n\r\ntype TTypedUseSelectorHook<TState> = <TSelected>(\r\n selector: (state: TState) => TSelected,\r\n equalityFn?: (a: TSelected, b: TSelected) => boolean,\r\n) => TSelected;\r\ntype TPortableAction = {\r\n type: string;\r\n payload?: unknown;\r\n};\r\ntype TPortableStore = {\r\n dispatch: (action: TPortableAction) => unknown;\r\n getState: () => unknown;\r\n subscribe: (listener: () => void) => () => void;\r\n};\r\ntype TPortableActionCreator = (...args: any[]) => TPortableAction;\r\ntype TParametersActions = Record<string, TPortableActionCreator>;\r\n\r\nconst { store, useSelector } = injectReducers({\r\n panelParameters: paramsSlice.reducer,\r\n});\r\n\r\nexport const parametersStore: TPortableStore = store;\r\nexport const useParametersSelector: TTypedUseSelectorHook<{\r\n panelParameters: TParamsSlice;\r\n}> = useSelector;\r\nexport const parametersActions: TParametersActions = paramsSlice.actions;\r\n"],"names":[],"mappings":";;AAOA,MAAM,cAAc,WAAA,CAAY;AAAA,EAC9B,cAAc,EAAC;AAAA,EACf,IAAA,EAAM,iBAAA;AAAA,EACN,QAAA,EAAU;AAAA,IACR,OACE,KAAA,EACA;AAAA,MACE;AAAA,KACF,EAIA;AACA,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAAG,QAAA,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,GAAI,EAAC;AAEvD,MAAA,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,GAAI;AAAA,QACvB,GAAG,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAAA,QACxB,GAAG,OAAA,CAAQ;AAAA,OACb;AAAA;AACF;AAEJ,CAAC,CAAA;AAkBD,MAAM,EAAE,KAAA,EAAO,WAAA,EAAY,GAAI,cAAA,CAAe;AAAA,EAC5C,iBAAiB,WAAA,CAAY;AAC/B,CAAC,CAAA;AAEM,MAAM,eAAA,GAAkC;AACxC,MAAM,qBAAA,GAER;AACE,MAAM,oBAAwC,WAAA,CAAY;;;;"}
@@ -0,0 +1,11 @@
1
+ import { TPanelId } from '../types.js';
2
+ import { TParamsStore } from './parametersStore.js';
3
+
4
+ /**
5
+ * Actualiza los parámetros de un panel a nivel de cliente. Este método se
6
+ * expone con el único fin de ser llamado por la acción saveParams del api.
7
+ */
8
+ declare function saveParameters(panelId: TPanelId, parameters: TParamsStore, refresh?: boolean): void;
9
+
10
+ export { saveParameters };
11
+ //# sourceMappingURL=saveParameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saveParameters.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { firePanelAction } from '../actions/firePanelAction.js';
2
+ import { panelActionsEmitter } from '../actions/usePanelActions.js';
3
+ import { parametersStore, parametersActions } from './parametersStore.js';
4
+
5
+ function saveParameters(panelId, parameters, refresh = true) {
6
+ parametersStore.dispatch(parametersActions.udpate({ panelId, parameters }));
7
+ if (refresh) {
8
+ panelActionsEmitter.emit(panelId, "configurationApply", {
9
+ data: parameters
10
+ });
11
+ firePanelAction(panelId, "refresh");
12
+ }
13
+ }
14
+
15
+ export { saveParameters };
16
+ //# sourceMappingURL=saveParameters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saveParameters.js","sources":["../../src/config/saveParameters.ts"],"sourcesContent":["import { firePanelAction } from '../actions/firePanelAction';\r\nimport { TActionResult, panelActionsEmitter } from '../actions/usePanelActions';\r\nimport { TPanelId } from '../types';\r\nimport {\r\n TParamsStore,\r\n parametersActions,\r\n parametersStore,\r\n} from './parametersStore';\r\n\r\n/**\r\n * Actualiza los parámetros de un panel a nivel de cliente. Este método se\r\n * expone con el único fin de ser llamado por la acción saveParams del api.\r\n */\r\nexport function saveParameters(\r\n panelId: TPanelId,\r\n parameters: TParamsStore,\r\n refresh = true,\r\n) {\r\n parametersStore.dispatch(parametersActions.udpate({ panelId, parameters }));\r\n if (refresh) {\r\n panelActionsEmitter.emit(panelId, 'configurationApply', {\r\n data: parameters,\r\n } as TActionResult);\r\n firePanelAction(panelId, 'refresh');\r\n }\r\n}\r\n"],"names":[],"mappings":";;;;AAaO,SAAS,cAAA,CACd,OAAA,EACA,UAAA,EACA,OAAA,GAAU,IAAA,EACV;AACA,EAAA,eAAA,CAAgB,SAAS,iBAAA,CAAkB,MAAA,CAAO,EAAE,OAAA,EAAS,UAAA,EAAY,CAAC,CAAA;AAC1E,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,mBAAA,CAAoB,IAAA,CAAK,SAAS,oBAAA,EAAsB;AAAA,MACtD,IAAA,EAAM;AAAA,KACU,CAAA;AAClB,IAAA,eAAA,CAAgB,SAAS,SAAS,CAAA;AAAA;AAEtC;;;;"}
@@ -0,0 +1,49 @@
1
+ import { ApiaApi, makeApiaUrl } from '@apia/api';
2
+ import { EventEmitter } from '@apia/util';
3
+ import { usePanelIdentity } from '../common/usePanelIdentity.js';
4
+
5
+ class ConfigEmitter extends EventEmitter {
6
+ }
7
+ new ConfigEmitter();
8
+ function usePanelConfig() {
9
+ const { panelId } = usePanelIdentity();
10
+ return function config() {
11
+ void ApiaApi.post(
12
+ makeApiaUrl({
13
+ action: "panelEdit",
14
+ pnlId: panelId
15
+ }),
16
+ {
17
+ handleLoad: true,
18
+ modalConfiguration: {
19
+ async onFieldChange(element, handler) {
20
+ if (element.onChange === "refresh") {
21
+ await ApiaApi.post(
22
+ makeApiaUrl({
23
+ action: "panelEditConfirm",
24
+ pnlId: panelId
25
+ }),
26
+ {
27
+ postData: { [`${element.name}`]: element.value },
28
+ postDataTreatement: "stringify"
29
+ }
30
+ );
31
+ const newForm = await ApiaApi.post(
32
+ makeApiaUrl({
33
+ action: "panelEdit",
34
+ pnlId: panelId
35
+ })
36
+ );
37
+ if (newForm?.data) {
38
+ handler.assignForm(newForm.data);
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ );
45
+ };
46
+ }
47
+
48
+ export { usePanelConfig };
49
+ //# sourceMappingURL=usePanelConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePanelConfig.js","sources":["../../src/config/usePanelConfig.tsx"],"sourcesContent":["import { ApiaApi, makeApiaUrl } from '@apia/api';\r\nimport { EventEmitter, TApiaLoad } from '@apia/util';\r\nimport { usePanelIdentity } from '../common';\r\nimport { TPanelId } from '../types';\r\n\r\nclass ConfigEmitter extends EventEmitter<{\r\n refresh: { panelId: TPanelId };\r\n}> {}\r\n\r\nexport const configEmitter = new ConfigEmitter();\r\n\r\n/**\r\n * Esta función devuelve una función que al ser llamada abre el modal de\r\n * configuración del panel actual. Este modal permite al usuario modificar\r\n * parámetros y una vez confirmado, el resultado de la operación deberá ser\r\n * tomado por una función aún inexistente.\r\n *\r\n * Esta función se deberá encargar de almacenar los parámetros recibidos desde\r\n * el server para el panel actual, así como hacerle llegar al panel\r\n * correspondiente los datos emitidos por su contraparte en el servidor, a fin\r\n * de que actualice su vista.\r\n *\r\n * Admite un callback que será llamado cada vez que se confirme el modal de\r\n * configuración. Este callback se expone a fin de permitir la ejecución de\r\n * acciones previas al refresh que es lanzado en forma automática cuando\r\n */\r\nexport function usePanelConfig() {\r\n const { panelId } = usePanelIdentity();\r\n\r\n return function config() {\r\n void ApiaApi.post(\r\n makeApiaUrl({\r\n action: 'panelEdit',\r\n pnlId: panelId,\r\n }),\r\n {\r\n handleLoad: true,\r\n modalConfiguration: {\r\n async onFieldChange(element, handler) {\r\n if (element.onChange === 'refresh') {\r\n await ApiaApi.post<TApiaLoad>(\r\n makeApiaUrl({\r\n action: 'panelEditConfirm',\r\n pnlId: panelId,\r\n }),\r\n {\r\n postData: { [`${element.name}`]: element.value },\r\n postDataTreatement: 'stringify',\r\n },\r\n );\r\n\r\n const newForm = await ApiaApi.post<TApiaLoad>(\r\n makeApiaUrl({\r\n action: 'panelEdit',\r\n pnlId: panelId,\r\n }),\r\n );\r\n\r\n if (newForm?.data) {\r\n handler.assignForm(newForm.data);\r\n }\r\n }\r\n },\r\n },\r\n },\r\n );\r\n };\r\n}\r\n"],"names":[],"mappings":";;;;AAKA,MAAM,sBAAsB,YAAA,CAEzB;AAAC;AAEyB,IAAI,aAAA;AAiB1B,SAAS,cAAA,GAAiB;AAC/B,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,gBAAA,EAAiB;AAErC,EAAA,OAAO,SAAS,MAAA,GAAS;AACvB,IAAA,KAAK,OAAA,CAAQ,IAAA;AAAA,MACX,WAAA,CAAY;AAAA,QACV,MAAA,EAAQ,WAAA;AAAA,QACR,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,MACD;AAAA,QACE,UAAA,EAAY,IAAA;AAAA,QACZ,kBAAA,EAAoB;AAAA,UAClB,MAAM,aAAA,CAAc,OAAA,EAAS,OAAA,EAAS;AACpC,YAAA,IAAI,OAAA,CAAQ,aAAa,SAAA,EAAW;AAClC,cAAA,MAAM,OAAA,CAAQ,IAAA;AAAA,gBACZ,WAAA,CAAY;AAAA,kBACV,MAAA,EAAQ,kBAAA;AAAA,kBACR,KAAA,EAAO;AAAA,iBACR,CAAA;AAAA,gBACD;AAAA,kBACE,QAAA,EAAU,EAAE,CAAC,CAAA,EAAG,QAAQ,IAAI,CAAA,CAAE,GAAG,OAAA,CAAQ,KAAA,EAAM;AAAA,kBAC/C,kBAAA,EAAoB;AAAA;AACtB,eACF;AAEA,cAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,IAAA;AAAA,gBAC5B,WAAA,CAAY;AAAA,kBACV,MAAA,EAAQ,WAAA;AAAA,kBACR,KAAA,EAAO;AAAA,iBACR;AAAA,eACH;AAEA,cAAA,IAAI,SAAS,IAAA,EAAM;AACjB,gBAAA,OAAA,CAAQ,UAAA,CAAW,QAAQ,IAAI,CAAA;AAAA;AACjC;AACF;AACF;AACF;AACF,KACF;AAAA,GACF;AACF;;;;"}