@vuu-ui/vuu-data-react 0.13.8 → 0.13.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 (85) hide show
  1. package/cjs/data-editing/EditForm.css.js +6 -0
  2. package/cjs/data-editing/EditForm.css.js.map +1 -0
  3. package/cjs/data-editing/EditForm.js +90 -0
  4. package/cjs/data-editing/EditForm.js.map +1 -0
  5. package/cjs/data-editing/UnsavedChangesReport.css.js +6 -0
  6. package/cjs/data-editing/UnsavedChangesReport.css.js.map +1 -0
  7. package/cjs/data-editing/UnsavedChangesReport.js +29 -0
  8. package/cjs/data-editing/UnsavedChangesReport.js.map +1 -0
  9. package/cjs/data-editing/edit-rule-validation-checker.js +41 -0
  10. package/cjs/data-editing/edit-rule-validation-checker.js.map +1 -0
  11. package/cjs/data-editing/edit-validation-rules.js +52 -0
  12. package/cjs/data-editing/edit-validation-rules.js.map +1 -0
  13. package/cjs/data-editing/form-edit-state.js +26 -0
  14. package/cjs/data-editing/form-edit-state.js.map +1 -0
  15. package/cjs/data-editing/get-data-item-edit-control.js +56 -0
  16. package/cjs/data-editing/get-data-item-edit-control.js.map +1 -0
  17. package/cjs/data-editing/useEditForm.js +249 -0
  18. package/cjs/data-editing/useEditForm.js.map +1 -0
  19. package/cjs/datasource-provider/RestDataSourceProvider.js +78 -0
  20. package/cjs/datasource-provider/RestDataSourceProvider.js.map +1 -0
  21. package/cjs/datasource-provider/VuuDataSourceProvider.js +34 -0
  22. package/cjs/datasource-provider/VuuDataSourceProvider.js.map +1 -0
  23. package/cjs/datasource-provider/useAutoLoginToVuuServer.js +54 -0
  24. package/cjs/datasource-provider/useAutoLoginToVuuServer.js.map +1 -0
  25. package/cjs/hooks/useLookupValues.js +100 -0
  26. package/cjs/hooks/useLookupValues.js.map +1 -0
  27. package/cjs/hooks/useSessionDataSource.js +72 -0
  28. package/cjs/hooks/useSessionDataSource.js.map +1 -0
  29. package/cjs/hooks/useTypeaheadSuggestions.js +41 -0
  30. package/cjs/hooks/useTypeaheadSuggestions.js.map +1 -0
  31. package/cjs/hooks/useVisualLinks.js +83 -0
  32. package/cjs/hooks/useVisualLinks.js.map +1 -0
  33. package/cjs/hooks/useVuuMenuActions.js +362 -0
  34. package/cjs/hooks/useVuuMenuActions.js.map +1 -0
  35. package/cjs/hooks/useVuuTables.js +38 -0
  36. package/cjs/hooks/useVuuTables.js.map +1 -0
  37. package/cjs/index.js +40 -1556
  38. package/cjs/index.js.map +1 -1
  39. package/cjs/session-editing-form/SessionEditingForm.css.js +6 -0
  40. package/cjs/session-editing-form/SessionEditingForm.css.js.map +1 -0
  41. package/cjs/session-editing-form/SessionEditingForm.js +269 -0
  42. package/cjs/session-editing-form/SessionEditingForm.js.map +1 -0
  43. package/esm/data-editing/EditForm.css.js +4 -0
  44. package/esm/data-editing/EditForm.css.js.map +1 -0
  45. package/esm/data-editing/EditForm.js +88 -0
  46. package/esm/data-editing/EditForm.js.map +1 -0
  47. package/esm/data-editing/UnsavedChangesReport.css.js +4 -0
  48. package/esm/data-editing/UnsavedChangesReport.css.js.map +1 -0
  49. package/esm/data-editing/UnsavedChangesReport.js +27 -0
  50. package/esm/data-editing/UnsavedChangesReport.js.map +1 -0
  51. package/esm/data-editing/edit-rule-validation-checker.js +37 -0
  52. package/esm/data-editing/edit-rule-validation-checker.js.map +1 -0
  53. package/esm/data-editing/edit-validation-rules.js +50 -0
  54. package/esm/data-editing/edit-validation-rules.js.map +1 -0
  55. package/esm/data-editing/form-edit-state.js +23 -0
  56. package/esm/data-editing/form-edit-state.js.map +1 -0
  57. package/esm/data-editing/get-data-item-edit-control.js +54 -0
  58. package/esm/data-editing/get-data-item-edit-control.js.map +1 -0
  59. package/esm/data-editing/useEditForm.js +247 -0
  60. package/esm/data-editing/useEditForm.js.map +1 -0
  61. package/esm/datasource-provider/RestDataSourceProvider.js +75 -0
  62. package/esm/datasource-provider/RestDataSourceProvider.js.map +1 -0
  63. package/esm/datasource-provider/VuuDataSourceProvider.js +32 -0
  64. package/esm/datasource-provider/VuuDataSourceProvider.js.map +1 -0
  65. package/esm/datasource-provider/useAutoLoginToVuuServer.js +52 -0
  66. package/esm/datasource-provider/useAutoLoginToVuuServer.js.map +1 -0
  67. package/esm/hooks/useLookupValues.js +98 -0
  68. package/esm/hooks/useLookupValues.js.map +1 -0
  69. package/esm/hooks/useSessionDataSource.js +70 -0
  70. package/esm/hooks/useSessionDataSource.js.map +1 -0
  71. package/esm/hooks/useTypeaheadSuggestions.js +38 -0
  72. package/esm/hooks/useTypeaheadSuggestions.js.map +1 -0
  73. package/esm/hooks/useVisualLinks.js +81 -0
  74. package/esm/hooks/useVisualLinks.js.map +1 -0
  75. package/esm/hooks/useVuuMenuActions.js +358 -0
  76. package/esm/hooks/useVuuMenuActions.js.map +1 -0
  77. package/esm/hooks/useVuuTables.js +36 -0
  78. package/esm/hooks/useVuuTables.js.map +1 -0
  79. package/esm/index.js +15 -1535
  80. package/esm/index.js.map +1 -1
  81. package/esm/session-editing-form/SessionEditingForm.css.js +4 -0
  82. package/esm/session-editing-form/SessionEditingForm.css.js.map +1 -0
  83. package/esm/session-editing-form/SessionEditingForm.js +267 -0
  84. package/esm/session-editing-form/SessionEditingForm.js.map +1 -0
  85. package/package.json +14 -14
@@ -0,0 +1,75 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { RestDataSource } from '@vuu-ui/vuu-data-remote';
3
+ import { isObject, DataProvider } from '@vuu-ui/vuu-utils';
4
+
5
+ const serverAPI = (schemas) => ({
6
+ getTableList: async () => {
7
+ if (schemas) {
8
+ return {
9
+ tables: Object.keys(schemas).map((key) => {
10
+ const [module, table] = key.split(":");
11
+ return { module, table };
12
+ })
13
+ };
14
+ } else {
15
+ console.log(`Rest data source does not yet support table list`);
16
+ return { tables: [] };
17
+ }
18
+ },
19
+ getTableSchema: async ({ module, table }) => {
20
+ const schema = schemas?.[`${module}:${table}`];
21
+ if (schema) {
22
+ return schema;
23
+ } else {
24
+ throw Error(
25
+ `Rest data source does not yet support table schema (${table})`
26
+ );
27
+ }
28
+ },
29
+ rpcCall: async (message) => Promise.reject(
30
+ Error(`Rest data source does not yet support RPC (${message.type})`)
31
+ )
32
+ });
33
+ const getServerAPI = (schemas) => async () => serverAPI(schemas);
34
+ const isRestDataSourceExtension = (o) => {
35
+ return isObject(o) && "createHttpHeaders" in o && typeof o["createHttpHeaders"] === "function";
36
+ };
37
+ const getRestDataSourceClass = ({
38
+ createHttpHeaders
39
+ }) => {
40
+ if (createHttpHeaders) {
41
+ return class ExtendedClass extends RestDataSource {
42
+ constructor(props) {
43
+ super(props);
44
+ }
45
+ get httpHeaders() {
46
+ return createHttpHeaders();
47
+ }
48
+ };
49
+ } else {
50
+ return RestDataSource;
51
+ }
52
+ };
53
+ const RestDataSourceProvider = ({
54
+ children,
55
+ createHttpHeaders,
56
+ tableSchemas,
57
+ url
58
+ }) => {
59
+ RestDataSource.api = url;
60
+ const restDataSourceClass = getRestDataSourceClass({ createHttpHeaders });
61
+ return /* @__PURE__ */ jsx(
62
+ DataProvider,
63
+ {
64
+ VuuDataSource: restDataSourceClass,
65
+ dataSourceExtensions: { createHttpHeaders },
66
+ getServerAPI: getServerAPI(tableSchemas),
67
+ isLocalData: false,
68
+ tableSchemas,
69
+ children
70
+ }
71
+ );
72
+ };
73
+
74
+ export { RestDataSourceProvider, isRestDataSourceExtension };
75
+ //# sourceMappingURL=RestDataSourceProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestDataSourceProvider.js","sources":["../../src/datasource-provider/RestDataSourceProvider.tsx"],"sourcesContent":["import { RestDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport {\n DataSourceConstructorProps,\n ServerAPI,\n TableSchema,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuCreateVisualLink,\n VuuRemoveVisualLink,\n VuuRpcMenuRequest,\n VuuRpcServiceRequest,\n VuuRpcViewportRequest,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { DataProvider, isObject } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode } from \"react\";\n\nconst serverAPI = (\n schemas?: Record<string, TableSchema>,\n): Pick<ServerAPI, \"getTableList\" | \"getTableSchema\" | \"rpcCall\"> => ({\n getTableList: async () => {\n if (schemas) {\n return {\n tables: Object.keys(schemas).map((key) => {\n const [module, table] = key.split(\":\");\n return { module, table };\n }),\n };\n } else {\n console.log(`Rest data source does not yet support table list`);\n return { tables: [] };\n }\n },\n getTableSchema: async ({ module, table }: VuuTable) => {\n const schema = schemas?.[`${module}:${table}`];\n if (schema) {\n return schema;\n } else {\n throw Error(\n `Rest data source does not yet support table schema (${table})`,\n );\n }\n },\n rpcCall: async (\n message:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) =>\n Promise.reject(\n Error(`Rest data source does not yet support RPC (${message.type})`),\n ),\n});\n\nconst getServerAPI = (schemas?: Record<string, TableSchema>) => async () =>\n serverAPI(schemas);\n\nexport type RestDataSourceExtension = {\n createHttpHeaders?: () => Headers;\n};\n\nexport const isRestDataSourceExtension = (\n o?: unknown,\n): o is RestDataSourceExtension => {\n return (\n isObject(o) &&\n \"createHttpHeaders\" in o &&\n typeof o[\"createHttpHeaders\"] === \"function\"\n );\n};\n\nconst getRestDataSourceClass = ({\n createHttpHeaders,\n}: RestDataSourceExtension) => {\n if (createHttpHeaders) {\n return class ExtendedClass extends RestDataSource {\n constructor(props: DataSourceConstructorProps) {\n super(props);\n }\n get httpHeaders(): Headers | undefined {\n return createHttpHeaders();\n }\n };\n } else {\n return RestDataSource;\n }\n};\n\nexport const RestDataSourceProvider = ({\n children,\n createHttpHeaders,\n tableSchemas,\n url,\n}: {\n children: ReactNode;\n tableSchemas?: Record<string, TableSchema>;\n url: string;\n} & RestDataSourceExtension) => {\n RestDataSource.api = url;\n\n const restDataSourceClass = getRestDataSourceClass({ createHttpHeaders });\n\n return (\n <DataProvider\n VuuDataSource={restDataSourceClass}\n dataSourceExtensions={{ createHttpHeaders }}\n getServerAPI={getServerAPI(tableSchemas)}\n isLocalData={false}\n tableSchemas={tableSchemas}\n >\n {children}\n </DataProvider>\n );\n};\n"],"names":[],"mappings":";;;;AAiBA,MAAM,SAAA,GAAY,CAChB,OACoE,MAAA;AAAA,EACpE,cAAc,YAAY;AACxB,IAAA,IAAI,OAAS,EAAA;AACX,MAAO,OAAA;AAAA,QACL,QAAQ,MAAO,CAAA,IAAA,CAAK,OAAO,CAAE,CAAA,GAAA,CAAI,CAAC,GAAQ,KAAA;AACxC,UAAA,MAAM,CAAC,MAAQ,EAAA,KAAK,CAAI,GAAA,GAAA,CAAI,MAAM,GAAG,CAAA;AACrC,UAAO,OAAA,EAAE,QAAQ,KAAM,EAAA;AAAA,SACxB;AAAA,OACH;AAAA,KACK,MAAA;AACL,MAAA,OAAA,CAAQ,IAAI,CAAkD,gDAAA,CAAA,CAAA;AAC9D,MAAO,OAAA,EAAE,MAAQ,EAAA,EAAG,EAAA;AAAA;AACtB,GACF;AAAA,EACA,cAAgB,EAAA,OAAO,EAAE,MAAA,EAAQ,OAAsB,KAAA;AACrD,IAAA,MAAM,SAAS,OAAU,GAAA,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,KAAK,CAAE,CAAA,CAAA;AAC7C,IAAA,IAAI,MAAQ,EAAA;AACV,MAAO,OAAA,MAAA;AAAA,KACF,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,uDAAuD,KAAK,CAAA,CAAA;AAAA,OAC9D;AAAA;AACF,GACF;AAAA,EACA,OAAA,EAAS,OACP,OAAA,KAOA,OAAQ,CAAA,MAAA;AAAA,IACN,KAAM,CAAA,CAAA,2CAAA,EAA8C,OAAQ,CAAA,IAAI,CAAG,CAAA,CAAA;AAAA;AAEzE,CAAA,CAAA;AAEA,MAAM,YAAe,GAAA,CAAC,OAA0C,KAAA,YAC9D,UAAU,OAAO,CAAA;AAMN,MAAA,yBAAA,GAA4B,CACvC,CACiC,KAAA;AACjC,EACE,OAAA,QAAA,CAAS,CAAC,CACV,IAAA,mBAAA,IAAuB,KACvB,OAAO,CAAA,CAAE,mBAAmB,CAAM,KAAA,UAAA;AAEtC;AAEA,MAAM,yBAAyB,CAAC;AAAA,EAC9B;AACF,CAA+B,KAAA;AAC7B,EAAA,IAAI,iBAAmB,EAAA;AACrB,IAAO,OAAA,MAAM,sBAAsB,cAAe,CAAA;AAAA,MAChD,YAAY,KAAmC,EAAA;AAC7C,QAAA,KAAA,CAAM,KAAK,CAAA;AAAA;AACb,MACA,IAAI,WAAmC,GAAA;AACrC,QAAA,OAAO,iBAAkB,EAAA;AAAA;AAC3B,KACF;AAAA,GACK,MAAA;AACL,IAAO,OAAA,cAAA;AAAA;AAEX,CAAA;AAEO,MAAM,yBAAyB,CAAC;AAAA,EACrC,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAIgC,KAAA;AAC9B,EAAA,cAAA,CAAe,GAAM,GAAA,GAAA;AAErB,EAAA,MAAM,mBAAsB,GAAA,sBAAA,CAAuB,EAAE,iBAAA,EAAmB,CAAA;AAExE,EACE,uBAAA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,aAAe,EAAA,mBAAA;AAAA,MACf,oBAAA,EAAsB,EAAE,iBAAkB,EAAA;AAAA,MAC1C,YAAA,EAAc,aAAa,YAAY,CAAA;AAAA,MACvC,WAAa,EAAA,KAAA;AAAA,MACb,YAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ;;;;"}
@@ -0,0 +1,32 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { VuuDataSource, ConnectionManager } from '@vuu-ui/vuu-data-remote';
3
+ import { DataProvider } from '@vuu-ui/vuu-utils';
4
+ import { useAutoLoginToVuuServer } from './useAutoLoginToVuuServer.js';
5
+
6
+ const getServerAPI = () => ConnectionManager.serverAPI;
7
+ const VuuDataSourceProvider = ({
8
+ authenticate,
9
+ autoConnect = false,
10
+ autoLogin = false,
11
+ children,
12
+ websocketUrl
13
+ }) => {
14
+ useAutoLoginToVuuServer({
15
+ authenticate,
16
+ autoConnect,
17
+ autoLogin,
18
+ websocketUrl
19
+ });
20
+ return /* @__PURE__ */ jsx(
21
+ DataProvider,
22
+ {
23
+ VuuDataSource,
24
+ getServerAPI,
25
+ isLocalData: false,
26
+ children
27
+ }
28
+ );
29
+ };
30
+
31
+ export { VuuDataSourceProvider };
32
+ //# sourceMappingURL=VuuDataSourceProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VuuDataSourceProvider.js","sources":["../../src/datasource-provider/VuuDataSourceProvider.tsx"],"sourcesContent":["import { ConnectionManager, VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataProvider } from \"@vuu-ui/vuu-utils\";\nimport { ReactNode } from \"react\";\nimport { useAutoLoginToVuuServer } from \"./useAutoLoginToVuuServer\";\n\nconst getServerAPI = () => ConnectionManager.serverAPI;\n\nexport const VuuDataSourceProvider = ({\n authenticate,\n autoConnect = false,\n autoLogin = false,\n children,\n websocketUrl,\n}: {\n authenticate?: boolean;\n autoConnect?: boolean;\n autoLogin?: boolean;\n children: ReactNode;\n websocketUrl?: string;\n}) => {\n useAutoLoginToVuuServer({\n authenticate,\n autoConnect,\n autoLogin,\n websocketUrl,\n });\n return (\n <DataProvider\n VuuDataSource={VuuDataSource}\n getServerAPI={getServerAPI}\n isLocalData={false}\n >\n {children}\n </DataProvider>\n );\n};\n"],"names":[],"mappings":";;;;;AAKA,MAAM,YAAA,GAAe,MAAM,iBAAkB,CAAA,SAAA;AAEtC,MAAM,wBAAwB,CAAC;AAAA,EACpC,YAAA;AAAA,EACA,WAAc,GAAA,KAAA;AAAA,EACd,SAAY,GAAA,KAAA;AAAA,EACZ,QAAA;AAAA,EACA;AACF,CAMM,KAAA;AACJ,EAAwB,uBAAA,CAAA;AAAA,IACtB,YAAA;AAAA,IACA,WAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EACE,uBAAA,GAAA;AAAA,IAAC,YAAA;AAAA,IAAA;AAAA,MACC,aAAA;AAAA,MACA,YAAA;AAAA,MACA,WAAa,EAAA,KAAA;AAAA,MAEZ;AAAA;AAAA,GACH;AAEJ;;;;"}
@@ -0,0 +1,52 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { ConnectionManager, authenticate } from '@vuu-ui/vuu-data-remote';
3
+ import { useState, useEffect } from 'react';
4
+
5
+ const useAutoLoginToVuuServer = ({
6
+ authenticate: authenticate$1 = true,
7
+ autoConnect = true,
8
+ // autoLogin = true,
9
+ secure = true,
10
+ websocketUrl
11
+ } = {}) => {
12
+ const [errorMessage, setErrorMessage] = useState("");
13
+ useEffect(() => {
14
+ const connect = async () => {
15
+ try {
16
+ let token = "no-token";
17
+ if (authenticate$1) {
18
+ token = await authenticate(
19
+ "steve",
20
+ "xyz",
21
+ "/api/authn"
22
+ );
23
+ }
24
+ const url = websocketUrl ?? `${secure ? "wss" : "ws"}://localhost/8090/websocket`;
25
+ ConnectionManager.connect({
26
+ url,
27
+ token,
28
+ username: "steve"
29
+ });
30
+ } catch (e) {
31
+ if (e instanceof Error) {
32
+ console.error(e.message);
33
+ setErrorMessage(e.message);
34
+ }
35
+ }
36
+ };
37
+ if (autoConnect) {
38
+ connect();
39
+ }
40
+ return () => {
41
+ if (autoConnect) {
42
+ ConnectionManager.disconnect();
43
+ }
44
+ };
45
+ }, [authenticate$1, autoConnect, secure, websocketUrl]);
46
+ if (errorMessage) {
47
+ return /* @__PURE__ */ jsx("p", { children: "Unable to authenticate against Vuu Server A Vuu Server instance must be running to show this example." });
48
+ }
49
+ };
50
+
51
+ export { useAutoLoginToVuuServer };
52
+ //# sourceMappingURL=useAutoLoginToVuuServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAutoLoginToVuuServer.js","sources":["../../src/datasource-provider/useAutoLoginToVuuServer.tsx"],"sourcesContent":["import {\n authenticate as vuuAuthenticate,\n ConnectionManager,\n} from \"@vuu-ui/vuu-data-remote\";\nimport { useEffect, useState } from \"react\";\n\nexport const useAutoLoginToVuuServer = ({\n authenticate = true,\n autoConnect = true,\n // autoLogin = true,\n secure = true,\n websocketUrl,\n}: {\n authenticate?: boolean;\n autoConnect?: boolean;\n autoLogin?: boolean;\n secure?: boolean;\n websocketUrl?: string;\n} = {}) => {\n const [errorMessage, setErrorMessage] = useState(\"\");\n useEffect(() => {\n const connect = async () => {\n try {\n let token = \"no-token\";\n if (authenticate) {\n token = (await vuuAuthenticate(\n \"steve\",\n \"xyz\",\n \"/api/authn\",\n )) as string;\n }\n\n const url =\n websocketUrl ?? `${secure ? \"wss\" : \"ws\"}://localhost/8090/websocket`;\n\n ConnectionManager.connect({\n url,\n token,\n username: \"steve\",\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n console.error(e.message);\n setErrorMessage(e.message);\n }\n }\n };\n if (autoConnect) {\n connect();\n }\n\n return () => {\n if (autoConnect) {\n ConnectionManager.disconnect();\n }\n };\n }, [authenticate, autoConnect, secure, websocketUrl]);\n\n if (errorMessage) {\n return (\n <p>\n Unable to authenticate against Vuu Server A Vuu Server instance must be\n running to show this example.\n </p>\n );\n }\n};\n"],"names":["authenticate","vuuAuthenticate"],"mappings":";;;;AAMO,MAAM,0BAA0B,CAAC;AAAA,gBACtCA,cAAe,GAAA,IAAA;AAAA,EACf,WAAc,GAAA,IAAA;AAAA;AAAA,EAEd,MAAS,GAAA,IAAA;AAAA,EACT;AACF,CAAA,GAMI,EAAO,KAAA;AACT,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,EAAE,CAAA;AACnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,YAAY;AAC1B,MAAI,IAAA;AACF,QAAA,IAAI,KAAQ,GAAA,UAAA;AACZ,QAAA,IAAIA,cAAc,EAAA;AAChB,UAAA,KAAA,GAAS,MAAMC,YAAA;AAAA,YACb,OAAA;AAAA,YACA,KAAA;AAAA,YACA;AAAA,WACF;AAAA;AAGF,QAAA,MAAM,GACJ,GAAA,YAAA,IAAgB,CAAG,EAAA,MAAA,GAAS,QAAQ,IAAI,CAAA,2BAAA,CAAA;AAE1C,QAAA,iBAAA,CAAkB,OAAQ,CAAA;AAAA,UACxB,GAAA;AAAA,UACA,KAAA;AAAA,UACA,QAAU,EAAA;AAAA,SACX,CAAA;AAAA,eACM,CAAY,EAAA;AACnB,QAAA,IAAI,aAAa,KAAO,EAAA;AACtB,UAAQ,OAAA,CAAA,KAAA,CAAM,EAAE,OAAO,CAAA;AACvB,UAAA,eAAA,CAAgB,EAAE,OAAO,CAAA;AAAA;AAC3B;AACF,KACF;AACA,IAAA,IAAI,WAAa,EAAA;AACf,MAAQ,OAAA,EAAA;AAAA;AAGV,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,WAAa,EAAA;AACf,QAAA,iBAAA,CAAkB,UAAW,EAAA;AAAA;AAC/B,KACF;AAAA,KACC,CAACD,cAAA,EAAc,WAAa,EAAA,MAAA,EAAQ,YAAY,CAAC,CAAA;AAEpD,EAAA,IAAI,YAAc,EAAA;AAChB,IACE,uBAAA,GAAA,CAAC,OAAE,QAGH,EAAA,uGAAA,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -0,0 +1,98 @@
1
+ import { VuuDataSource } from '@vuu-ui/vuu-data-remote';
2
+ import { useShellContext, isTypeDescriptor, isValueListRenderer, getSelectedOption, buildColumnMap, Range, isLookupRenderer } from '@vuu-ui/vuu-utils';
3
+ import { useMemo, useState } from 'react';
4
+
5
+ const NO_VALUES = [];
6
+ const toListOption = (value) => ({
7
+ label: value,
8
+ value
9
+ });
10
+ const lookupValueMap = /* @__PURE__ */ new Map();
11
+ const loadLookupValues = ({
12
+ labelColumn,
13
+ table,
14
+ valueColumn
15
+ }) => {
16
+ const tableKey = `${table.module}:${table.table}`;
17
+ const lookupValues = lookupValueMap.get(tableKey);
18
+ if (lookupValues) {
19
+ return lookupValues;
20
+ } else {
21
+ const promise = new Promise((resolve) => {
22
+ const columns = [valueColumn, labelColumn];
23
+ const columnMap = buildColumnMap(columns);
24
+ const dataSource = new VuuDataSource({
25
+ bufferSize: 0,
26
+ table
27
+ });
28
+ dataSource.subscribe(
29
+ {
30
+ columns,
31
+ range: Range(0, 100)
32
+ },
33
+ (message) => {
34
+ if (message.type === "viewport-update") {
35
+ if (message.rows) {
36
+ const listOptions = message.rows.map((row) => ({
37
+ value: row[columnMap[valueColumn]],
38
+ label: row[columnMap[labelColumn]]
39
+ }));
40
+ resolve(listOptions);
41
+ dataSource.unsubscribe();
42
+ }
43
+ }
44
+ }
45
+ );
46
+ });
47
+ lookupValueMap.set(tableKey, promise);
48
+ return promise;
49
+ }
50
+ };
51
+ const getLookupDetails = ({ name, type }) => {
52
+ if (isTypeDescriptor(type) && isLookupRenderer(type.renderer)) {
53
+ return type.renderer.lookup;
54
+ } else {
55
+ throw Error(
56
+ `useLookupValues column ${name} is not configured to use lookup values`
57
+ );
58
+ }
59
+ };
60
+ const useLookupValues = (column, initialValueProp) => {
61
+ const { type: columnType } = column;
62
+ const { getLookupValues } = useShellContext();
63
+ const initialState = useMemo(() => {
64
+ if (isTypeDescriptor(columnType) && isValueListRenderer(columnType?.renderer)) {
65
+ const values2 = columnType.renderer.values.map(toListOption);
66
+ return {
67
+ initialValue: getSelectedOption(values2, initialValueProp) ?? null,
68
+ values: values2
69
+ };
70
+ } else {
71
+ const lookupDetails = getLookupDetails(column);
72
+ const values2 = getLookupValues?.(lookupDetails.table) ?? NO_VALUES;
73
+ return {
74
+ initialValue: getSelectedOption(values2, initialValueProp) ?? null,
75
+ values: values2
76
+ };
77
+ }
78
+ }, [column, columnType, getLookupValues, initialValueProp]);
79
+ const [{ initialValue, values }, setLookupState] = useState(initialState);
80
+ useMemo(() => {
81
+ if (values === NO_VALUES) {
82
+ const lookupDetails = getLookupDetails(column);
83
+ loadLookupValues(lookupDetails).then(
84
+ (values2) => setLookupState({
85
+ initialValue: getSelectedOption(values2, initialValueProp) ?? null,
86
+ values: values2
87
+ })
88
+ );
89
+ }
90
+ }, [values, column, initialValueProp]);
91
+ return {
92
+ initialValue,
93
+ values
94
+ };
95
+ };
96
+
97
+ export { useLookupValues };
98
+ //# sourceMappingURL=useLookupValues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLookupValues.js","sources":["../../src/hooks/useLookupValues.ts"],"sourcesContent":["import {\n ColumnDescriptor,\n ListOption,\n LookupTableDetails,\n} from \"@vuu-ui/vuu-table-types\";\nimport { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport {\n buildColumnMap,\n getSelectedOption,\n isLookupRenderer,\n isTypeDescriptor,\n isValueListRenderer,\n Range,\n useShellContext,\n} from \"@vuu-ui/vuu-utils\";\nimport { useMemo, useState } from \"react\";\n\nconst NO_VALUES: ListOption[] = [];\n\nconst toListOption = (value: string): ListOption => ({\n label: value,\n value,\n});\n\nconst lookupValueMap = new Map<string, Promise<ListOption[]>>();\n\nconst loadLookupValues = ({\n labelColumn,\n table,\n valueColumn,\n}: LookupTableDetails): Promise<ListOption[]> => {\n const tableKey = `${table.module}:${table.table}`;\n const lookupValues = lookupValueMap.get(tableKey);\n if (lookupValues) {\n return lookupValues;\n } else {\n const promise: Promise<ListOption[]> = new Promise((resolve) => {\n const columns = [valueColumn, labelColumn];\n const columnMap = buildColumnMap(columns);\n const dataSource = new VuuDataSource({\n bufferSize: 0,\n table,\n });\n dataSource.subscribe(\n {\n columns,\n range: Range(0, 100),\n },\n (message) => {\n if (message.type === \"viewport-update\") {\n //TODO check we have full dataset\n if (message.rows) {\n const listOptions = message.rows.map<ListOption>((row) => ({\n value: row[columnMap[valueColumn]] as string | number,\n label: row[columnMap[labelColumn]] as string,\n }));\n resolve(listOptions);\n dataSource.unsubscribe();\n }\n }\n },\n );\n });\n lookupValueMap.set(tableKey, promise);\n return promise;\n }\n};\n\ntype LookupState = {\n initialValue: ListOption | null;\n values: ListOption[];\n};\n\nconst getLookupDetails = ({ name, type }: ColumnDescriptor) => {\n if (isTypeDescriptor(type) && isLookupRenderer(type.renderer)) {\n return type.renderer.lookup;\n } else {\n throw Error(\n `useLookupValues column ${name} is not configured to use lookup values`,\n );\n }\n};\n\nexport const useLookupValues = (\n column: ColumnDescriptor,\n initialValueProp: number | string,\n) => {\n const { type: columnType } = column;\n const { getLookupValues } = useShellContext();\n\n const initialState = useMemo<LookupState>(() => {\n if (\n isTypeDescriptor(columnType) &&\n isValueListRenderer(columnType?.renderer)\n ) {\n const values = columnType.renderer.values.map(toListOption);\n return {\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n };\n } else {\n const lookupDetails = getLookupDetails(column);\n const values = getLookupValues?.(lookupDetails.table) ?? NO_VALUES;\n\n return {\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n };\n }\n }, [column, columnType, getLookupValues, initialValueProp]);\n\n const [{ initialValue, values }, setLookupState] =\n useState<LookupState>(initialState);\n\n useMemo(() => {\n if (values === NO_VALUES) {\n const lookupDetails = getLookupDetails(column);\n loadLookupValues(lookupDetails).then((values) =>\n setLookupState({\n initialValue: getSelectedOption(values, initialValueProp) ?? null,\n values,\n }),\n );\n }\n }, [values, column, initialValueProp]);\n\n return {\n initialValue,\n values,\n };\n};\n"],"names":["values"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { useViewContext } from '@vuu-ui/vuu-layout';
2
+ import { useData, isConfigChanged } from '@vuu-ui/vuu-utils';
3
+ import { useMemo, useRef, useCallback } from 'react';
4
+
5
+ const NO_CONFIG = {};
6
+ const useSessionDataSource = ({
7
+ dataSourceSessionKey = "data-source",
8
+ tableSchema
9
+ }) => {
10
+ const { id, load, save, loadSession, saveSession, title } = useViewContext();
11
+ const { VuuDataSource } = useData();
12
+ const { "datasource-config": dataSourceConfigFromState } = useMemo(() => load?.() ?? NO_CONFIG, [load]);
13
+ const dataSourceConfigRef = useRef(
14
+ dataSourceConfigFromState
15
+ );
16
+ const handleDataSourceConfigChange = useCallback(
17
+ (config, _range, confirmed) => {
18
+ if (confirmed !== false) {
19
+ const { noChanges } = isConfigChanged(
20
+ dataSourceConfigRef.current,
21
+ config
22
+ );
23
+ if (noChanges === false) {
24
+ dataSourceConfigRef.current = config;
25
+ save?.(config, "datasource-config");
26
+ }
27
+ }
28
+ },
29
+ [save]
30
+ );
31
+ const dataSource = useMemo(() => {
32
+ let ds = loadSession?.(dataSourceSessionKey);
33
+ if (ds) {
34
+ if (dataSourceConfigFromState) {
35
+ ds.applyConfig(dataSourceConfigFromState, true);
36
+ }
37
+ if (ds.range.from > 0) {
38
+ ds.range = ds.range.reset;
39
+ }
40
+ return ds;
41
+ }
42
+ const columns = dataSourceConfigFromState?.columns ?? tableSchema.columns.map((col) => col.name);
43
+ ds = new VuuDataSource({
44
+ // bufferSize: 0,
45
+ viewport: id,
46
+ table: tableSchema.table,
47
+ ...dataSourceConfigRef.current,
48
+ columns,
49
+ title
50
+ });
51
+ ds.on("config", handleDataSourceConfigChange);
52
+ saveSession?.(ds, "data-source");
53
+ return ds;
54
+ }, [
55
+ VuuDataSource,
56
+ dataSourceConfigFromState,
57
+ dataSourceSessionKey,
58
+ handleDataSourceConfigChange,
59
+ id,
60
+ loadSession,
61
+ saveSession,
62
+ tableSchema.columns,
63
+ tableSchema.table,
64
+ title
65
+ ]);
66
+ return dataSource;
67
+ };
68
+
69
+ export { useSessionDataSource };
70
+ //# sourceMappingURL=useSessionDataSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSessionDataSource.js","sources":["../../src/hooks/useSessionDataSource.ts"],"sourcesContent":["import type {\n DataSource,\n DataSourceConfig,\n DataSourceConfigChangeHandler,\n TableSchema,\n} from \"@vuu-ui/vuu-data-types\";\nimport { useViewContext } from \"@vuu-ui/vuu-layout\";\nimport type { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { isConfigChanged, useData } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\ntype SessionState = {\n \"datasource-config\"?: DataSourceConfig;\n};\n\nconst NO_CONFIG: SessionState = {};\n\nexport const useSessionDataSource = ({\n dataSourceSessionKey = \"data-source\",\n tableSchema,\n}: {\n dataSourceSessionKey?: string;\n tableSchema: TableSchema;\n}) => {\n const { id, load, save, loadSession, saveSession, title } = useViewContext();\n const { VuuDataSource } = useData();\n\n const { \"datasource-config\": dataSourceConfigFromState } =\n useMemo<SessionState>(() => load?.() ?? NO_CONFIG, [load]);\n\n const dataSourceConfigRef = useRef<DataSourceConfig | undefined>(\n dataSourceConfigFromState,\n );\n\n const handleDataSourceConfigChange =\n useCallback<DataSourceConfigChangeHandler>(\n (\n config: DataSourceConfig | undefined,\n _range: VuuRange,\n confirmed?: boolean,\n ) => {\n if (confirmed !== false) {\n const { noChanges } = isConfigChanged(\n dataSourceConfigRef.current,\n config,\n );\n if (noChanges === false) {\n dataSourceConfigRef.current = config;\n save?.(config, \"datasource-config\");\n }\n }\n },\n [save],\n );\n\n const dataSource: DataSource = useMemo(() => {\n let ds = loadSession?.(dataSourceSessionKey) as DataSource;\n if (ds) {\n if (dataSourceConfigFromState) {\n // this won't do anything if dataSource config already matches this\n // This is only really used when injecting a dataSource into session\n // state in Showcase examples\n // DO we definitely need this ? If not apply config can be provate\n ds.applyConfig(dataSourceConfigFromState, true);\n }\n\n if (ds.range.from > 0) {\n // UI does not currently restore scroll position, so always reset to top of dataset\n ds.range = ds.range.reset;\n }\n\n return ds;\n }\n\n const columns =\n dataSourceConfigFromState?.columns ??\n tableSchema.columns.map((col) => col.name);\n\n ds = new VuuDataSource({\n // bufferSize: 0,\n viewport: id,\n table: tableSchema.table,\n ...dataSourceConfigRef.current,\n columns,\n title,\n });\n ds.on(\"config\", handleDataSourceConfigChange);\n saveSession?.(ds, \"data-source\");\n return ds;\n }, [\n VuuDataSource,\n dataSourceConfigFromState,\n dataSourceSessionKey,\n handleDataSourceConfigChange,\n id,\n loadSession,\n saveSession,\n tableSchema.columns,\n tableSchema.table,\n title,\n ]);\n\n return dataSource;\n};\n"],"names":[],"mappings":";;;;AAeA,MAAM,YAA0B,EAAC;AAE1B,MAAM,uBAAuB,CAAC;AAAA,EACnC,oBAAuB,GAAA,aAAA;AAAA,EACvB;AACF,CAGM,KAAA;AACJ,EAAM,MAAA,EAAE,IAAI,IAAM,EAAA,IAAA,EAAM,aAAa,WAAa,EAAA,KAAA,KAAU,cAAe,EAAA;AAC3E,EAAM,MAAA,EAAE,aAAc,EAAA,GAAI,OAAQ,EAAA;AAElC,EAAM,MAAA,EAAE,mBAAqB,EAAA,yBAAA,EAC3B,GAAA,OAAA,CAAsB,MAAM,IAAA,IAAY,IAAA,SAAA,EAAW,CAAC,IAAI,CAAC,CAAA;AAE3D,EAAA,MAAM,mBAAsB,GAAA,MAAA;AAAA,IAC1B;AAAA,GACF;AAEA,EAAA,MAAM,4BACJ,GAAA,WAAA;AAAA,IACE,CACE,MACA,EAAA,MAAA,EACA,SACG,KAAA;AACH,MAAA,IAAI,cAAc,KAAO,EAAA;AACvB,QAAM,MAAA,EAAE,WAAc,GAAA,eAAA;AAAA,UACpB,mBAAoB,CAAA,OAAA;AAAA,UACpB;AAAA,SACF;AACA,QAAA,IAAI,cAAc,KAAO,EAAA;AACvB,UAAA,mBAAA,CAAoB,OAAU,GAAA,MAAA;AAC9B,UAAA,IAAA,GAAO,QAAQ,mBAAmB,CAAA;AAAA;AACpC;AACF,KACF;AAAA,IACA,CAAC,IAAI;AAAA,GACP;AAEF,EAAM,MAAA,UAAA,GAAyB,QAAQ,MAAM;AAC3C,IAAI,IAAA,EAAA,GAAK,cAAc,oBAAoB,CAAA;AAC3C,IAAA,IAAI,EAAI,EAAA;AACN,MAAA,IAAI,yBAA2B,EAAA;AAK7B,QAAG,EAAA,CAAA,WAAA,CAAY,2BAA2B,IAAI,CAAA;AAAA;AAGhD,MAAI,IAAA,EAAA,CAAG,KAAM,CAAA,IAAA,GAAO,CAAG,EAAA;AAErB,QAAG,EAAA,CAAA,KAAA,GAAQ,GAAG,KAAM,CAAA,KAAA;AAAA;AAGtB,MAAO,OAAA,EAAA;AAAA;AAGT,IAAM,MAAA,OAAA,GACJ,2BAA2B,OAC3B,IAAA,WAAA,CAAY,QAAQ,GAAI,CAAA,CAAC,GAAQ,KAAA,GAAA,CAAI,IAAI,CAAA;AAE3C,IAAA,EAAA,GAAK,IAAI,aAAc,CAAA;AAAA;AAAA,MAErB,QAAU,EAAA,EAAA;AAAA,MACV,OAAO,WAAY,CAAA,KAAA;AAAA,MACnB,GAAG,mBAAoB,CAAA,OAAA;AAAA,MACvB,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAG,EAAA,CAAA,EAAA,CAAG,UAAU,4BAA4B,CAAA;AAC5C,IAAA,WAAA,GAAc,IAAI,aAAa,CAAA;AAC/B,IAAO,OAAA,EAAA;AAAA,GACN,EAAA;AAAA,IACD,aAAA;AAAA,IACA,yBAAA;AAAA,IACA,oBAAA;AAAA,IACA,4BAAA;AAAA,IACA,EAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAY,CAAA,OAAA;AAAA,IACZ,WAAY,CAAA,KAAA;AAAA,IACZ;AAAA,GACD,CAAA;AAED,EAAO,OAAA,UAAA;AACT;;;;"}
@@ -0,0 +1,38 @@
1
+ import { useData } from '@vuu-ui/vuu-utils';
2
+ import { useCallback } from 'react';
3
+
4
+ const getTypeaheadParams = (table, column, text = "", selectedValues = []) => {
5
+ if (text !== "" && !selectedValues.includes(text.toLowerCase())) {
6
+ return [table, column, text];
7
+ }
8
+ return [table, column];
9
+ };
10
+ const useTypeaheadSuggestions = () => {
11
+ const { getServerAPI } = useData();
12
+ return useCallback(
13
+ async (params) => {
14
+ const rpcMessage = params.length === 2 ? {
15
+ type: "RPC_CALL",
16
+ service: "TypeAheadRpcHandler",
17
+ method: "getUniqueFieldValues",
18
+ params
19
+ } : {
20
+ type: "RPC_CALL",
21
+ service: "TypeAheadRpcHandler",
22
+ method: "getUniqueFieldValuesStartingWith",
23
+ params
24
+ };
25
+ try {
26
+ const serverAPI = await getServerAPI();
27
+ const response = await serverAPI.rpcCall(rpcMessage);
28
+ return response;
29
+ } catch (err) {
30
+ return false;
31
+ }
32
+ },
33
+ [getServerAPI]
34
+ );
35
+ };
36
+
37
+ export { getTypeaheadParams, useTypeaheadSuggestions };
38
+ //# sourceMappingURL=useTypeaheadSuggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTypeaheadSuggestions.js","sources":["../../src/hooks/useTypeaheadSuggestions.ts"],"sourcesContent":["import { SuggestionFetcher, TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuRpcServiceRequest,\n TypeaheadParams,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { useData } from \"@vuu-ui/vuu-utils\";\nimport { useCallback } from \"react\";\n\nexport const getTypeaheadParams = (\n table: TableSchemaTable,\n column: string,\n text = \"\",\n selectedValues: string[] = [],\n): TypeaheadParams => {\n if (text !== \"\" && !selectedValues.includes(text.toLowerCase())) {\n return [table, column, text];\n }\n return [table, column];\n};\n\nexport const useTypeaheadSuggestions = () => {\n const { getServerAPI } = useData();\n return useCallback<SuggestionFetcher>(\n async (params: TypeaheadParams) => {\n const rpcMessage: VuuRpcServiceRequest =\n params.length === 2\n ? {\n type: \"RPC_CALL\",\n service: \"TypeAheadRpcHandler\",\n method: \"getUniqueFieldValues\",\n params,\n }\n : {\n type: \"RPC_CALL\",\n service: \"TypeAheadRpcHandler\",\n method: \"getUniqueFieldValuesStartingWith\",\n params,\n };\n\n try {\n const serverAPI = await getServerAPI();\n // We don't just return serverAPI.rpcCall . In the case of an\n // error we will be returning the rejected promise, bypassing\n // the catch block below.\n const response = await serverAPI.rpcCall<string[]>(rpcMessage);\n return response;\n } catch (err) {\n return false;\n }\n },\n [getServerAPI],\n );\n};\n"],"names":[],"mappings":";;;AAQa,MAAA,kBAAA,GAAqB,CAChC,KACA,EAAA,MAAA,EACA,OAAO,EACP,EAAA,cAAA,GAA2B,EACP,KAAA;AACpB,EAAI,IAAA,IAAA,KAAS,MAAM,CAAC,cAAA,CAAe,SAAS,IAAK,CAAA,WAAA,EAAa,CAAG,EAAA;AAC/D,IAAO,OAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,IAAI,CAAA;AAAA;AAE7B,EAAO,OAAA,CAAC,OAAO,MAAM,CAAA;AACvB;AAEO,MAAM,0BAA0B,MAAM;AAC3C,EAAM,MAAA,EAAE,YAAa,EAAA,GAAI,OAAQ,EAAA;AACjC,EAAO,OAAA,WAAA;AAAA,IACL,OAAO,MAA4B,KAAA;AACjC,MAAM,MAAA,UAAA,GACJ,MAAO,CAAA,MAAA,KAAW,CACd,GAAA;AAAA,QACE,IAAM,EAAA,UAAA;AAAA,QACN,OAAS,EAAA,qBAAA;AAAA,QACT,MAAQ,EAAA,sBAAA;AAAA,QACR;AAAA,OAEF,GAAA;AAAA,QACE,IAAM,EAAA,UAAA;AAAA,QACN,OAAS,EAAA,qBAAA;AAAA,QACT,MAAQ,EAAA,kCAAA;AAAA,QACR;AAAA,OACF;AAEN,MAAI,IAAA;AACF,QAAM,MAAA,SAAA,GAAY,MAAM,YAAa,EAAA;AAIrC,QAAA,MAAM,QAAW,GAAA,MAAM,SAAU,CAAA,OAAA,CAAkB,UAAU,CAAA;AAC7D,QAAO,OAAA,QAAA;AAAA,eACA,GAAK,EAAA;AACZ,QAAO,OAAA,KAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,YAAY;AAAA,GACf;AACF;;;;"}
@@ -0,0 +1,81 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useViewContext } from '@vuu-ui/vuu-layout';
3
+ import { IconButton } from '@vuu-ui/vuu-ui-controls';
4
+ import { useCallback, useEffect } from 'react';
5
+
6
+ const useVisualLinks = (dataSource) => {
7
+ const { dispatch } = useViewContext();
8
+ const clearVisualLinkTarget = useCallback(() => {
9
+ if (dataSource.visualLink) {
10
+ dispatch?.({
11
+ type: "broadcast-message",
12
+ message: {
13
+ targetId: dataSource.visualLink.parentClientVpId,
14
+ type: "highlight-off"
15
+ }
16
+ });
17
+ }
18
+ }, [dataSource, dispatch]);
19
+ const removeVisualLink = useCallback(() => {
20
+ if (dataSource.visualLink) {
21
+ dispatch?.({
22
+ type: "broadcast-message",
23
+ message: {
24
+ targetId: dataSource.visualLink.parentClientVpId,
25
+ type: "highlight-off"
26
+ }
27
+ });
28
+ dataSource.visualLink = void 0;
29
+ }
30
+ }, [dataSource, dispatch]);
31
+ const handleLinkRemoved = useCallback(() => {
32
+ dispatch?.({
33
+ type: "remove-toolbar-contribution",
34
+ location: "post-title"
35
+ });
36
+ }, [dispatch]);
37
+ const highlightVisualLinkTarget = useCallback(() => {
38
+ if (dataSource.visualLink) {
39
+ dispatch?.({
40
+ type: "broadcast-message",
41
+ message: {
42
+ targetId: dataSource.visualLink.parentClientVpId,
43
+ type: "highlight-on"
44
+ }
45
+ });
46
+ }
47
+ }, [dataSource, dispatch]);
48
+ const handleLinkCreated = useCallback(() => {
49
+ dispatch?.({
50
+ type: "add-toolbar-contribution",
51
+ location: "post-title",
52
+ content: /* @__PURE__ */ jsx(
53
+ IconButton,
54
+ {
55
+ "aria-label": "remove-link",
56
+ icon: "link",
57
+ onClick: removeVisualLink,
58
+ onMouseEnter: highlightVisualLinkTarget,
59
+ onMouseLeave: clearVisualLinkTarget,
60
+ variant: "secondary"
61
+ }
62
+ )
63
+ });
64
+ }, [
65
+ dispatch,
66
+ removeVisualLink,
67
+ highlightVisualLinkTarget,
68
+ clearVisualLinkTarget
69
+ ]);
70
+ useEffect(() => {
71
+ dataSource.on("visual-link-created", handleLinkCreated);
72
+ dataSource.on("visual-link-removed", handleLinkRemoved);
73
+ return () => {
74
+ dataSource.removeListener("visual-link-created", handleLinkCreated);
75
+ dataSource.removeListener("visual-link-removed", handleLinkRemoved);
76
+ };
77
+ }, [dataSource, handleLinkCreated, handleLinkRemoved]);
78
+ };
79
+
80
+ export { useVisualLinks };
81
+ //# sourceMappingURL=useVisualLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVisualLinks.js","sources":["../../src/hooks/useVisualLinks.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { useViewContext } from \"@vuu-ui/vuu-layout\";\nimport { IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { useCallback, useEffect } from \"react\";\n\nexport const useVisualLinks = (dataSource: DataSource) => {\n const { dispatch } = useViewContext();\n\n const clearVisualLinkTarget = useCallback(() => {\n if (dataSource.visualLink) {\n dispatch?.({\n type: \"broadcast-message\",\n message: {\n targetId: dataSource.visualLink.parentClientVpId,\n type: \"highlight-off\",\n },\n });\n }\n }, [dataSource, dispatch]);\n\n const removeVisualLink = useCallback(() => {\n if (dataSource.visualLink) {\n dispatch?.({\n type: \"broadcast-message\",\n message: {\n targetId: dataSource.visualLink.parentClientVpId,\n type: \"highlight-off\",\n },\n });\n\n dataSource.visualLink = undefined;\n }\n }, [dataSource, dispatch]);\n\n const handleLinkRemoved = useCallback(() => {\n dispatch?.({\n type: \"remove-toolbar-contribution\",\n location: \"post-title\",\n });\n }, [dispatch]);\n\n const highlightVisualLinkTarget = useCallback(() => {\n if (dataSource.visualLink) {\n dispatch?.({\n type: \"broadcast-message\",\n message: {\n targetId: dataSource.visualLink.parentClientVpId,\n type: \"highlight-on\",\n },\n });\n }\n }, [dataSource, dispatch]);\n\n const handleLinkCreated = useCallback(() => {\n dispatch?.({\n type: \"add-toolbar-contribution\",\n location: \"post-title\",\n content: (\n <IconButton\n aria-label=\"remove-link\"\n icon=\"link\"\n onClick={removeVisualLink}\n onMouseEnter={highlightVisualLinkTarget}\n onMouseLeave={clearVisualLinkTarget}\n variant=\"secondary\"\n />\n ),\n });\n }, [\n dispatch,\n removeVisualLink,\n highlightVisualLinkTarget,\n clearVisualLinkTarget,\n ]);\n\n useEffect(() => {\n dataSource.on(\"visual-link-created\", handleLinkCreated);\n dataSource.on(\"visual-link-removed\", handleLinkRemoved);\n return () => {\n dataSource.removeListener(\"visual-link-created\", handleLinkCreated);\n dataSource.removeListener(\"visual-link-removed\", handleLinkRemoved);\n };\n }, [dataSource, handleLinkCreated, handleLinkRemoved]);\n};\n"],"names":[],"mappings":";;;;;AAKa,MAAA,cAAA,GAAiB,CAAC,UAA2B,KAAA;AACxD,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,cAAe,EAAA;AAEpC,EAAM,MAAA,qBAAA,GAAwB,YAAY,MAAM;AAC9C,IAAA,IAAI,WAAW,UAAY,EAAA;AACzB,MAAW,QAAA,GAAA;AAAA,QACT,IAAM,EAAA,mBAAA;AAAA,QACN,OAAS,EAAA;AAAA,UACP,QAAA,EAAU,WAAW,UAAW,CAAA,gBAAA;AAAA,UAChC,IAAM,EAAA;AAAA;AACR,OACD,CAAA;AAAA;AACH,GACC,EAAA,CAAC,UAAY,EAAA,QAAQ,CAAC,CAAA;AAEzB,EAAM,MAAA,gBAAA,GAAmB,YAAY,MAAM;AACzC,IAAA,IAAI,WAAW,UAAY,EAAA;AACzB,MAAW,QAAA,GAAA;AAAA,QACT,IAAM,EAAA,mBAAA;AAAA,QACN,OAAS,EAAA;AAAA,UACP,QAAA,EAAU,WAAW,UAAW,CAAA,gBAAA;AAAA,UAChC,IAAM,EAAA;AAAA;AACR,OACD,CAAA;AAED,MAAA,UAAA,CAAW,UAAa,GAAA,KAAA,CAAA;AAAA;AAC1B,GACC,EAAA,CAAC,UAAY,EAAA,QAAQ,CAAC,CAAA;AAEzB,EAAM,MAAA,iBAAA,GAAoB,YAAY,MAAM;AAC1C,IAAW,QAAA,GAAA;AAAA,MACT,IAAM,EAAA,6BAAA;AAAA,MACN,QAAU,EAAA;AAAA,KACX,CAAA;AAAA,GACH,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAM,MAAA,yBAAA,GAA4B,YAAY,MAAM;AAClD,IAAA,IAAI,WAAW,UAAY,EAAA;AACzB,MAAW,QAAA,GAAA;AAAA,QACT,IAAM,EAAA,mBAAA;AAAA,QACN,OAAS,EAAA;AAAA,UACP,QAAA,EAAU,WAAW,UAAW,CAAA,gBAAA;AAAA,UAChC,IAAM,EAAA;AAAA;AACR,OACD,CAAA;AAAA;AACH,GACC,EAAA,CAAC,UAAY,EAAA,QAAQ,CAAC,CAAA;AAEzB,EAAM,MAAA,iBAAA,GAAoB,YAAY,MAAM;AAC1C,IAAW,QAAA,GAAA;AAAA,MACT,IAAM,EAAA,0BAAA;AAAA,MACN,QAAU,EAAA,YAAA;AAAA,MACV,OACE,kBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,YAAW,EAAA,aAAA;AAAA,UACX,IAAK,EAAA,MAAA;AAAA,UACL,OAAS,EAAA,gBAAA;AAAA,UACT,YAAc,EAAA,yBAAA;AAAA,UACd,YAAc,EAAA,qBAAA;AAAA,UACd,OAAQ,EAAA;AAAA;AAAA;AACV,KAEH,CAAA;AAAA,GACA,EAAA;AAAA,IACD,QAAA;AAAA,IACA,gBAAA;AAAA,IACA,yBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAW,UAAA,CAAA,EAAA,CAAG,uBAAuB,iBAAiB,CAAA;AACtD,IAAW,UAAA,CAAA,EAAA,CAAG,uBAAuB,iBAAiB,CAAA;AACtD,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,uBAAuB,iBAAiB,CAAA;AAClE,MAAW,UAAA,CAAA,cAAA,CAAe,uBAAuB,iBAAiB,CAAA;AAAA,KACpE;AAAA,GACC,EAAA,CAAC,UAAY,EAAA,iBAAA,EAAmB,iBAAiB,CAAC,CAAA;AACvD;;;;"}