@vuu-ui/vuu-shell 0.8.73 → 0.8.74

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.
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
5
+ var React = require('react');
6
+
7
+ const DataSourceContext = React.createContext({
8
+ isLocalData: false,
9
+ getServerAPI: vuuDataRemote.getServerAPI,
10
+ VuuDataSource: vuuDataRemote.VuuDataSource
11
+ });
12
+ const DataSourceProvider = ({
13
+ children,
14
+ getServerAPI: getServerAPI2,
15
+ isLocalData = true,
16
+ VuuDataSource: VuuDataSource2,
17
+ vuuModuleName
18
+ }) => {
19
+ return /* @__PURE__ */ jsxRuntime.jsx(
20
+ DataSourceContext.Provider,
21
+ {
22
+ value: { isLocalData, vuuModuleName, VuuDataSource: VuuDataSource2, getServerAPI: getServerAPI2 },
23
+ children
24
+ }
25
+ );
26
+ };
27
+ const useDataSource = () => React.useContext(DataSourceContext);
28
+
29
+ exports.DataSourceProvider = DataSourceProvider;
30
+ exports.useDataSource = useDataSource;
31
+ //# sourceMappingURL=DataSourceProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataSourceProvider.js","sources":["../../src/datasource-provider/DataSourceProvider.tsx"],"sourcesContent":["import {\n getServerAPI,\n ServerAPI,\n VuuDataSource,\n} from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, DataSourceConstructorProps } from \"@vuu-ui/vuu-data-types\";\nimport { createContext, ReactNode, useContext } from \"react\";\n\nexport type DataSourceConstructor = {\n new (props: DataSourceConstructorProps): DataSource;\n};\n\nexport interface DataSourceContextProps {\n isLocalData: boolean;\n VuuDataSource: DataSourceConstructor;\n vuuModuleName?: string;\n getServerAPI: () => Promise<\n Pick<ServerAPI, \"getTableList\" | \"getTableSchema\">\n >;\n}\n\nconst DataSourceContext = createContext<DataSourceContextProps>({\n isLocalData: false,\n getServerAPI,\n VuuDataSource,\n});\n\n/**\n * If a client is adding a DataSOurceProvider, it will ususlly be\n * to install local test data, so we default isLocalData to true\n */\nexport const DataSourceProvider = ({\n children,\n getServerAPI,\n isLocalData = true,\n VuuDataSource,\n vuuModuleName,\n}: Omit<DataSourceContextProps, \"isLocalData\"> & {\n children: ReactNode;\n isLocalData?: boolean;\n}) => {\n return (\n <DataSourceContext.Provider\n value={{ isLocalData, vuuModuleName, VuuDataSource, getServerAPI }}\n >\n {children}\n </DataSourceContext.Provider>\n );\n};\n\nexport const useDataSource = () => useContext(DataSourceContext);\n"],"names":["createContext","getServerAPI","VuuDataSource","jsx","useContext"],"mappings":";;;;;;AAqBA,MAAM,oBAAoBA,mBAAsC,CAAA;AAAA,EAC9D,WAAa,EAAA,KAAA;AAAA,gBACbC,0BAAA;AAAA,iBACAC,2BAAA;AACF,CAAC,CAAA,CAAA;AAMM,MAAM,qBAAqB,CAAC;AAAA,EACjC,QAAA;AAAA,EACA,YAAAD,EAAAA,aAAAA;AAAA,EACA,WAAc,GAAA,IAAA;AAAA,EACd,aAAAC,EAAAA,cAAAA;AAAA,EACA,aAAA;AACF,CAGM,KAAA;AACJ,EACE,uBAAAC,cAAA;AAAA,IAAC,iBAAkB,CAAA,QAAA;AAAA,IAAlB;AAAA,MACC,OAAO,EAAE,WAAA,EAAa,eAAe,aAAAD,EAAAA,cAAAA,EAAe,cAAAD,aAAa,EAAA;AAAA,MAEhE,QAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,EAAA;AAEa,MAAA,aAAA,GAAgB,MAAMG,gBAAA,CAAW,iBAAiB;;;;;"}
package/cjs/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  var AppHeader = require('./app-header/AppHeader.js');
4
4
  var ConnectionStatusIndicator = require('./connection-status/ConnectionStatusIndicator.js');
5
+ var DataSourceProvider = require('./datasource-provider/DataSourceProvider.js');
5
6
  var Feature = require('./feature/Feature.js');
6
7
  var defaultApplicationJson = require('./layout-management/defaultApplicationJson.js');
7
8
  var SaveLayoutPanel = require('./layout-management/SaveLayoutPanel.js');
@@ -30,6 +31,8 @@ var ApplicationProvider = require('./application-provider/ApplicationProvider.js
30
31
 
31
32
  exports.AppHeader = AppHeader.AppHeader;
32
33
  exports.ConnectionStatusIndicator = ConnectionStatusIndicator.ConnectionStatusIndicator;
34
+ exports.DataSourceProvider = DataSourceProvider.DataSourceProvider;
35
+ exports.useDataSource = DataSourceProvider.useDataSource;
33
36
  exports.Feature = Feature.Feature;
34
37
  exports.defaultApplicationJson = defaultApplicationJson.defaultApplicationJson;
35
38
  exports.defaultLayoutJson = defaultApplicationJson.defaultLayoutJson;
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -159,8 +159,8 @@ class LocalPersistenceManager {
159
159
  const applicationJSON = vuuUtils.getLocalEntity(__privateGet(this, _urlKey));
160
160
  if (applicationJSON) {
161
161
  __privateSet(this, _applicationJSON, applicationJSON);
162
- resolve(applicationJSON);
163
162
  }
163
+ resolve(applicationJSON);
164
164
  });
165
165
  }
166
166
  saveApplicationJSON(applicationJSON) {
@@ -1 +1 @@
1
- {"version":3,"file":"LocalPersistenceManager.js","sources":["../../src/persistence-manager/LocalPersistenceManager.ts"],"sourcesContent":["import {\n ApplicationJSON,\n LayoutJSON,\n Settings,\n formatDate,\n getLocalEntity,\n getUniqueId,\n saveLocalEntity,\n} from \"@vuu-ui/vuu-utils\";\n\nimport {\n Layout,\n LayoutMetadata,\n LayoutMetadataDto,\n WithId,\n} from \"../layout-management\";\nimport { getAuthDetailsFromCookies } from \"../login\";\nimport { IPersistenceManager } from \"./PersistenceManager\";\nconst baseMetadataSaveLocation = \"layouts/metadata\";\nconst baseLayoutsSaveLocation = \"layouts/layouts\";\n\nexport class LocalPersistenceManager implements IPersistenceManager {\n #username: string = getAuthDetailsFromCookies()[0];\n metadataSaveLocation = `${baseMetadataSaveLocation}/${this.#username}`;\n layoutsSaveLocation = `${baseLayoutsSaveLocation}/${this.#username}`;\n #urlKey = `api/vui/${this.#username}`;\n #applicationJSON: ApplicationJSON | undefined;\n\n constructor(urlKey?: string) {\n if (urlKey) {\n this.#urlKey = urlKey;\n }\n }\n\n createLayout(\n metadata: LayoutMetadataDto,\n layout: LayoutJSON\n ): Promise<LayoutMetadata> {\n return new Promise((resolve) => {\n Promise.all([this.loadLayouts(), this.loadMetadata()]).then(\n ([existingLayouts, existingMetadata]) => {\n const id = getUniqueId();\n const newMetadata: LayoutMetadata = {\n ...metadata,\n id,\n created: formatDate({ date: \"dd.mm.yyyy\" })(new Date()),\n };\n\n this.saveLayoutsWithMetadata(\n [...existingLayouts, { id, json: layout }],\n [...existingMetadata, newMetadata]\n );\n resolve(newMetadata);\n }\n );\n });\n }\n\n updateLayout(\n id: string,\n newMetadata: LayoutMetadataDto,\n newLayout: LayoutJSON\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const updatedLayouts = existingLayouts.map((layout) =>\n layout.id === id ? { ...layout, json: newLayout } : layout\n );\n const updatedMetadata = existingMetadata.map((metadata) =>\n metadata.id === id ? { ...metadata, ...newMetadata } : metadata\n );\n this.saveLayoutsWithMetadata(updatedLayouts, updatedMetadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n deleteLayout(id: string): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const layouts = existingLayouts.filter((layout) => layout.id !== id);\n const metadata = existingMetadata.filter(\n (metadata) => metadata.id !== id\n );\n this.saveLayoutsWithMetadata(layouts, metadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n loadLayout(id: string): Promise<LayoutJSON> {\n return new Promise((resolve, reject) => {\n this.validateId(id, \"layout\")\n .then(() => this.loadLayouts())\n .then((existingLayouts) => {\n const foundLayout = existingLayouts.find(\n (layout) => layout.id === id\n );\n if (foundLayout) {\n resolve(foundLayout.json);\n } else {\n reject(new Error(`no layout found matching id ${id}`));\n }\n })\n .catch((e) => reject(e));\n });\n }\n\n loadMetadata(): Promise<LayoutMetadata[]> {\n return new Promise((resolve) => {\n const metadata = getLocalEntity<LayoutMetadata[]>(\n this.metadataSaveLocation\n );\n resolve(metadata || []);\n });\n }\n\n async loadApplicationJSON(): Promise<ApplicationJSON | undefined> {\n return (\n this.#applicationJSON ||\n new Promise((resolve) => {\n const applicationJSON = getLocalEntity<ApplicationJSON>(this.#urlKey);\n if (applicationJSON) {\n this.#applicationJSON = applicationJSON;\n resolve(applicationJSON);\n }\n })\n );\n }\n\n saveApplicationJSON(applicationJSON: ApplicationJSON): Promise<void> {\n return new Promise((resolve, reject) => {\n const savedLayout = saveLocalEntity<ApplicationJSON>(\n this.#urlKey,\n applicationJSON\n );\n if (savedLayout) {\n this.#applicationJSON = applicationJSON;\n resolve();\n } else {\n reject(new Error(\"Application Json failed to save\"));\n }\n });\n }\n\n loadLayouts = (): Promise<Layout[]> => {\n return new Promise((resolve) => {\n const layouts = getLocalEntity<Layout[]>(this.layoutsSaveLocation);\n resolve(layouts || []);\n });\n };\n\n saveLayoutsWithMetadata = (\n layouts: Layout[],\n metadata: LayoutMetadata[]\n ): void => {\n saveLocalEntity<Layout[]>(this.layoutsSaveLocation, layouts);\n saveLocalEntity<LayoutMetadata[]>(this.metadataSaveLocation, metadata);\n };\n\n // Ensures that there is exactly one Layout entry and exactly one Metadata\n // entry in local storage corresponding to the provided ID.\n validateIds = async (id: string): Promise<void> => {\n return Promise.all([\n this.validateId(id, \"metadata\").catch((error) => error.message),\n this.validateId(id, \"layout\").catch((error) => error.message),\n ]).then((errorMessages: string[]) => {\n // filter() is used to remove any blank messages before joining.\n // Avoids orphaned delimiters in combined messages, e.g. \"; \" or \"; error 2\"\n const combinedMessage = errorMessages\n .filter((msg) => msg !== undefined)\n .join(\"; \");\n if (combinedMessage) {\n throw new Error(combinedMessage);\n }\n });\n };\n\n // Ensures that there is exactly one element (Layout or Metadata) in local\n // storage corresponding to the provided ID.\n validateId = (id: string, dataType: \"metadata\" | \"layout\"): Promise<void> => {\n return new Promise((resolve, reject) => {\n const loadFunc =\n dataType === \"metadata\"\n ? () => this.loadMetadata()\n : () => this.loadLayouts();\n\n loadFunc().then((array: WithId[]) => {\n const count = array.filter((element) => element.id === id).length;\n switch (count) {\n case 1: {\n resolve();\n break;\n }\n case 0: {\n reject(new Error(`No ${dataType} with ID ${id}`));\n break;\n }\n default:\n reject(new Error(`Non-unique ${dataType} with ID ${id}`));\n }\n });\n });\n };\n\n async getUserSettings() {\n if (this.#applicationJSON) {\n return this.#applicationJSON.userSettings ?? {};\n }\n\n try {\n const applicationJSON = await this.loadApplicationJSON();\n return applicationJSON?.userSettings ?? {};\n } catch (e) {\n return {};\n }\n }\n\n saveUserSettings(userSettings: Settings) {\n if (this.#applicationJSON) {\n this.saveApplicationJSON({\n ...this.#applicationJSON,\n userSettings,\n });\n }\n }\n}\n"],"names":["getAuthDetailsFromCookies","getLocalEntity","saveLocalEntity","getUniqueId","formatDate","metadata"],"mappings":"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"}
1
+ {"version":3,"file":"LocalPersistenceManager.js","sources":["../../src/persistence-manager/LocalPersistenceManager.ts"],"sourcesContent":["import {\n ApplicationJSON,\n LayoutJSON,\n Settings,\n formatDate,\n getLocalEntity,\n getUniqueId,\n saveLocalEntity,\n} from \"@vuu-ui/vuu-utils\";\n\nimport {\n Layout,\n LayoutMetadata,\n LayoutMetadataDto,\n WithId,\n} from \"../layout-management\";\nimport { getAuthDetailsFromCookies } from \"../login\";\nimport { IPersistenceManager } from \"./PersistenceManager\";\nconst baseMetadataSaveLocation = \"layouts/metadata\";\nconst baseLayoutsSaveLocation = \"layouts/layouts\";\n\nexport class LocalPersistenceManager implements IPersistenceManager {\n #username: string = getAuthDetailsFromCookies()[0];\n metadataSaveLocation = `${baseMetadataSaveLocation}/${this.#username}`;\n layoutsSaveLocation = `${baseLayoutsSaveLocation}/${this.#username}`;\n #urlKey = `api/vui/${this.#username}`;\n #applicationJSON: ApplicationJSON | undefined;\n\n constructor(urlKey?: string) {\n if (urlKey) {\n this.#urlKey = urlKey;\n }\n }\n\n createLayout(\n metadata: LayoutMetadataDto,\n layout: LayoutJSON\n ): Promise<LayoutMetadata> {\n return new Promise((resolve) => {\n Promise.all([this.loadLayouts(), this.loadMetadata()]).then(\n ([existingLayouts, existingMetadata]) => {\n const id = getUniqueId();\n const newMetadata: LayoutMetadata = {\n ...metadata,\n id,\n created: formatDate({ date: \"dd.mm.yyyy\" })(new Date()),\n };\n\n this.saveLayoutsWithMetadata(\n [...existingLayouts, { id, json: layout }],\n [...existingMetadata, newMetadata]\n );\n resolve(newMetadata);\n }\n );\n });\n }\n\n updateLayout(\n id: string,\n newMetadata: LayoutMetadataDto,\n newLayout: LayoutJSON\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const updatedLayouts = existingLayouts.map((layout) =>\n layout.id === id ? { ...layout, json: newLayout } : layout\n );\n const updatedMetadata = existingMetadata.map((metadata) =>\n metadata.id === id ? { ...metadata, ...newMetadata } : metadata\n );\n this.saveLayoutsWithMetadata(updatedLayouts, updatedMetadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n deleteLayout(id: string): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const layouts = existingLayouts.filter((layout) => layout.id !== id);\n const metadata = existingMetadata.filter(\n (metadata) => metadata.id !== id\n );\n this.saveLayoutsWithMetadata(layouts, metadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n loadLayout(id: string): Promise<LayoutJSON> {\n return new Promise((resolve, reject) => {\n this.validateId(id, \"layout\")\n .then(() => this.loadLayouts())\n .then((existingLayouts) => {\n const foundLayout = existingLayouts.find(\n (layout) => layout.id === id\n );\n if (foundLayout) {\n resolve(foundLayout.json);\n } else {\n reject(new Error(`no layout found matching id ${id}`));\n }\n })\n .catch((e) => reject(e));\n });\n }\n\n loadMetadata(): Promise<LayoutMetadata[]> {\n return new Promise((resolve) => {\n const metadata = getLocalEntity<LayoutMetadata[]>(\n this.metadataSaveLocation\n );\n resolve(metadata || []);\n });\n }\n\n async loadApplicationJSON(): Promise<ApplicationJSON | undefined> {\n return (\n this.#applicationJSON ||\n new Promise((resolve) => {\n const applicationJSON = getLocalEntity<ApplicationJSON>(this.#urlKey);\n if (applicationJSON) {\n this.#applicationJSON = applicationJSON;\n }\n resolve(applicationJSON);\n })\n );\n }\n\n saveApplicationJSON(applicationJSON: ApplicationJSON): Promise<void> {\n return new Promise((resolve, reject) => {\n const savedLayout = saveLocalEntity<ApplicationJSON>(\n this.#urlKey,\n applicationJSON\n );\n if (savedLayout) {\n this.#applicationJSON = applicationJSON;\n resolve();\n } else {\n reject(new Error(\"Application Json failed to save\"));\n }\n });\n }\n\n loadLayouts = (): Promise<Layout[]> => {\n return new Promise((resolve) => {\n const layouts = getLocalEntity<Layout[]>(this.layoutsSaveLocation);\n resolve(layouts || []);\n });\n };\n\n saveLayoutsWithMetadata = (\n layouts: Layout[],\n metadata: LayoutMetadata[]\n ): void => {\n saveLocalEntity<Layout[]>(this.layoutsSaveLocation, layouts);\n saveLocalEntity<LayoutMetadata[]>(this.metadataSaveLocation, metadata);\n };\n\n // Ensures that there is exactly one Layout entry and exactly one Metadata\n // entry in local storage corresponding to the provided ID.\n validateIds = async (id: string): Promise<void> => {\n return Promise.all([\n this.validateId(id, \"metadata\").catch((error) => error.message),\n this.validateId(id, \"layout\").catch((error) => error.message),\n ]).then((errorMessages: string[]) => {\n // filter() is used to remove any blank messages before joining.\n // Avoids orphaned delimiters in combined messages, e.g. \"; \" or \"; error 2\"\n const combinedMessage = errorMessages\n .filter((msg) => msg !== undefined)\n .join(\"; \");\n if (combinedMessage) {\n throw new Error(combinedMessage);\n }\n });\n };\n\n // Ensures that there is exactly one element (Layout or Metadata) in local\n // storage corresponding to the provided ID.\n validateId = (id: string, dataType: \"metadata\" | \"layout\"): Promise<void> => {\n return new Promise((resolve, reject) => {\n const loadFunc =\n dataType === \"metadata\"\n ? () => this.loadMetadata()\n : () => this.loadLayouts();\n\n loadFunc().then((array: WithId[]) => {\n const count = array.filter((element) => element.id === id).length;\n switch (count) {\n case 1: {\n resolve();\n break;\n }\n case 0: {\n reject(new Error(`No ${dataType} with ID ${id}`));\n break;\n }\n default:\n reject(new Error(`Non-unique ${dataType} with ID ${id}`));\n }\n });\n });\n };\n\n async getUserSettings() {\n if (this.#applicationJSON) {\n return this.#applicationJSON.userSettings ?? {};\n }\n\n try {\n const applicationJSON = await this.loadApplicationJSON();\n return applicationJSON?.userSettings ?? {};\n } catch (e) {\n return {};\n }\n }\n\n saveUserSettings(userSettings: Settings) {\n if (this.#applicationJSON) {\n this.saveApplicationJSON({\n ...this.#applicationJSON,\n userSettings,\n });\n }\n }\n}\n"],"names":["getAuthDetailsFromCookies","getLocalEntity","saveLocalEntity","getUniqueId","formatDate","metadata"],"mappings":"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"}
@@ -162,7 +162,7 @@ const SessionEditingForm = ({
162
162
  value: typedValue,
163
163
  type: "VP_EDIT_CELL_RPC"
164
164
  }).then((response) => {
165
- if (response?.type === "VP_EDIT_RPC_REJECT") {
165
+ if (vuuUtils.isErrorResponse(response)) {
166
166
  console.log(`edit rejected ${response.error}`);
167
167
  setFieldStatusValues((map) => ({
168
168
  ...map,
@@ -1 +1 @@
1
- {"version":3,"file":"SessionEditingForm.js","sources":["../../src/session-editing-form/SessionEditingForm.tsx"],"sourcesContent":["import { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n hasAction,\n isErrorResponse,\n isValidNumber,\n queryClosest,\n shallowEquals,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldHelperText,\n FormFieldLabel,\n Input,\n useIdMemo,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n ChangeEvent,\n ChangeEventHandler,\n FocusEvent,\n FocusEventHandler,\n HTMLAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport sessionEditingFormCss from \"./SessionEditingForm.css\";\n\nexport type FormFieldDescriptor = {\n isKeyField?: boolean;\n label?: string;\n name: string;\n type: VuuColumnDataType;\n description: string;\n readonly?: boolean;\n required?: boolean;\n};\n\nexport type FormConfig = {\n title: string;\n key: string;\n fields: FormFieldDescriptor[];\n};\n\nexport interface SessionEditingFormProps\n extends HTMLAttributes<HTMLDivElement> {\n config: FormConfig;\n onClose?: () => void;\n dataSource?: DataSource;\n schema?: TableSchema;\n}\n\nconst classBase = \"vuuSessionEditingForm\";\n\nconst getField = (\n fields: FormFieldDescriptor[],\n name: string\n): FormFieldDescriptor => {\n const field = fields.find((f) => f.name === name);\n if (field) {\n return field;\n } else {\n throw Error(`SessionEditingForm, no field '${name}' found`);\n }\n};\n\nconst getFieldNameAndValue = ({\n target,\n}: ChangeEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>): [\n string,\n string\n] => {\n const formField = queryClosest(target, \".saltFormField\");\n if (formField) {\n const {\n dataset: { field },\n } = formField;\n if (field === undefined) {\n throw Error(\"SessionEditingForm, form field has no field data attribute\");\n }\n return [field, target.value];\n } else {\n throw Error(\"Form control is not enclosed in FormField\");\n }\n};\n\nconst Status = {\n uninitialised: 0,\n unchanged: 1,\n changed: 2,\n invalid: 3,\n};\n\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined?: false\n): VuuRowDataItemType | undefined;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined: true\n): VuuRowDataItemType;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined = false\n): VuuRowDataItemType | undefined {\n switch (type) {\n case \"int\":\n case \"long\": {\n const typedValue = parseInt(value, 10);\n if (isValidNumber(typedValue)) {\n return typedValue;\n } else if (throwIfUndefined) {\n throw Error(\"SessionEditingForm getTypedValue\");\n } else {\n return undefined;\n }\n }\n\n case \"double\": {\n const typedValue = parseFloat(value);\n if (isValidNumber(typedValue)) {\n return typedValue;\n }\n return undefined;\n }\n\n case \"boolean\":\n return value === \"true\" ? true : false;\n default:\n return value;\n }\n}\n\nconst getDataSource = (\n dataSource?: DataSource,\n schema?: TableSchema\n): DataSource => {\n if (dataSource) {\n return dataSource;\n } else if (schema) {\n return new VuuDataSource({\n bufferSize: 0,\n table: schema.table,\n columns: schema.columns.map((col) => col.name),\n }) as DataSource;\n } else {\n throw Error(\n \"SessionEditingForm: either a DataSource or a TableSchema must be provided\"\n );\n }\n};\n\ntype FormValues = { [key: string]: VuuRowDataItemType | undefined };\n\nexport const SessionEditingForm = ({\n className,\n config: { fields, key: keyField },\n dataSource: dataSourceProp,\n id: idProp,\n onClose,\n schema,\n ...htmlAttributes\n}: SessionEditingFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-session-editing-form\",\n css: sessionEditingFormCss,\n window: targetWindow,\n });\n\n const [fieldStatusValues, setFieldStatusValues] = useState<\n Record<string, string | undefined>\n >({});\n const [values, setValues] = useState<FormValues>();\n const [errorMessage, setErrorMessage] = useState(\"\");\n const formContentRef = useRef<HTMLDivElement>(null);\n const initialDataRef = useRef<FormValues>();\n const dataStatusRef = useRef(Status.uninitialised);\n\n const dataSource = useMemo(() => {\n const ds = getDataSource(dataSourceProp, schema);\n const { columns } = ds;\n const columnMap = buildColumnMap(ds.columns);\n\n const applyServerData = (data: VuuDataRow) => {\n if (columnMap) {\n const values: { [key: string]: VuuRowDataItemType } = {};\n for (const column of columns) {\n values[column] = data[columnMap[column]];\n }\n if (dataStatusRef.current === Status.uninitialised) {\n dataStatusRef.current = Status.unchanged;\n initialDataRef.current = values;\n }\n setValues(values);\n }\n };\n\n ds.subscribe({ range: { from: 0, to: 5 } }, (message) => {\n if (message.type === \"viewport-update\" && message.rows) {\n if (dataStatusRef.current === Status.uninitialised) {\n applyServerData(message.rows[0]);\n } else {\n console.log(\"what do we do with server updates\");\n }\n }\n });\n return ds;\n }, [dataSourceProp, schema]);\n\n const id = useIdMemo(idProp);\n\n const handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type);\n setValues((values = {}) => {\n const newValues = {\n ...values,\n [field]: typedValue,\n };\n const notUpdated = shallowEquals(newValues, initialDataRef.current);\n dataStatusRef.current = notUpdated\n ? Status.unchanged\n : typedValue !== undefined\n ? Status.changed\n : Status.invalid;\n return newValues;\n });\n },\n [fields]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const rowKey = values?.[keyField];\n // TODO link this with client side validation if we're going to use it\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type, true);\n if (typeof rowKey === \"string\") {\n dataSource\n .menuRpcCall({\n rowKey,\n field: field,\n value: typedValue,\n type: \"VP_EDIT_CELL_RPC\",\n })\n .then((response) => {\n if (response?.type === \"VP_EDIT_RPC_REJECT\") {\n console.log(`edit rejected ${response.error}`);\n setFieldStatusValues((map) => ({\n ...map,\n [field]: response.error,\n }));\n } else {\n setFieldStatusValues((map) => ({\n ...map,\n [field]: undefined,\n }));\n }\n });\n }\n },\n [dataSource, fields, keyField, values]\n );\n\n const applyAction = useCallback(\n (action: unknown) => {\n if (typeof action === \"object\" && action !== null) {\n if (\"type\" in action && action.type === \"CLOSE_DIALOG_ACTION\") {\n onClose?.();\n }\n }\n },\n [onClose]\n );\n\n const handleSubmit = useCallback(async () => {\n const response = await dataSource.menuRpcCall({\n type: \"VP_EDIT_SUBMIT_FORM_RPC\",\n });\n if (isErrorResponse(response)) {\n setErrorMessage(response.error);\n } else if (hasAction(response)) {\n applyAction(response.action);\n }\n }, [applyAction, dataSource]);\n\n const handleKeyDown = useCallback(\n (evt) => {\n if (evt.key === \"Enter\" && dataStatusRef.current === Status.changed) {\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const handleCancel = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const getFormControl = (field: FormFieldDescriptor) => {\n const value = String(values?.[field.name] ?? \"\");\n if (field.readonly || field.name === keyField) {\n return (\n <div className={`${classBase}-fieldValue vuuReadOnly`}>{value}</div>\n );\n } else {\n return (\n <Input\n className={`${classBase}-fieldValue`}\n onBlur={handleBlur}\n onChange={handleChange}\n value={value}\n id={`${id}-input-${field.name}`}\n />\n );\n }\n };\n\n useEffect(() => {\n if (formContentRef.current) {\n const firstInput = formContentRef.current.querySelector(\n \"input\"\n ) as HTMLInputElement;\n if (firstInput) {\n setTimeout(() => {\n firstInput.focus();\n firstInput.select();\n }, 100);\n }\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (dataSource) {\n dataSource.unsubscribe();\n }\n };\n }, [dataSource]);\n\n const isDirty = dataStatusRef.current === Status.changed;\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {errorMessage ? (\n <div\n className={`${classBase}-errorBanner`}\n data-icon=\"error\"\n title={errorMessage}\n >\n Error, edit(s) not saved\n </div>\n ) : undefined}\n <div\n className={`${classBase}-content`}\n ref={formContentRef}\n onKeyDown={handleKeyDown}\n >\n {fields.map((field) => (\n <FormField\n className={`${classBase}-field`}\n data-field={field.name}\n key={field.name}\n necessity={field.required ? \"required\" : \"optional\"}\n readOnly={field.readonly}\n validationStatus={\n fieldStatusValues[field.name] ? \"error\" : undefined\n }\n >\n <FormFieldLabel>{field?.label ?? field.description}</FormFieldLabel>\n {getFormControl(field)}\n <FormFieldHelperText>\n {fieldStatusValues[field.name] ?? \"\"}\n </FormFieldHelperText>\n </FormField>\n ))}\n </div>\n <div className={`${classBase}-buttonbar salt-theme salt-density-high`}>\n <Button\n type=\"submit\"\n variant=\"cta\"\n disabled={!isDirty}\n onClick={handleSubmit}\n >\n Submit\n </Button>\n <Button variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n"],"names":["queryClosest","isValidNumber","VuuDataSource","useWindow","useComponentCssInjection","sessionEditingFormCss","useState","useRef","useMemo","buildColumnMap","values","useIdMemo","useCallback","shallowEquals","isErrorResponse","hasAction","jsx","Input","useEffect","jsxs","FormField","FormFieldLabel","FormFieldHelperText","Button"],"mappings":"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"}
1
+ {"version":3,"file":"SessionEditingForm.js","sources":["../../src/session-editing-form/SessionEditingForm.tsx"],"sourcesContent":["import { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n hasAction,\n isErrorResponse,\n isValidNumber,\n queryClosest,\n shallowEquals,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldHelperText,\n FormFieldLabel,\n Input,\n useIdMemo,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n ChangeEvent,\n ChangeEventHandler,\n FocusEvent,\n FocusEventHandler,\n HTMLAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport sessionEditingFormCss from \"./SessionEditingForm.css\";\n\nexport type FormFieldDescriptor = {\n isKeyField?: boolean;\n label?: string;\n name: string;\n type: VuuColumnDataType;\n description: string;\n readonly?: boolean;\n required?: boolean;\n};\n\nexport type FormConfig = {\n title: string;\n key: string;\n fields: FormFieldDescriptor[];\n};\n\nexport interface SessionEditingFormProps\n extends HTMLAttributes<HTMLDivElement> {\n config: FormConfig;\n onClose?: () => void;\n dataSource?: DataSource;\n schema?: TableSchema;\n}\n\nconst classBase = \"vuuSessionEditingForm\";\n\nconst getField = (\n fields: FormFieldDescriptor[],\n name: string\n): FormFieldDescriptor => {\n const field = fields.find((f) => f.name === name);\n if (field) {\n return field;\n } else {\n throw Error(`SessionEditingForm, no field '${name}' found`);\n }\n};\n\nconst getFieldNameAndValue = ({\n target,\n}: ChangeEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>): [\n string,\n string\n] => {\n const formField = queryClosest(target, \".saltFormField\");\n if (formField) {\n const {\n dataset: { field },\n } = formField;\n if (field === undefined) {\n throw Error(\"SessionEditingForm, form field has no field data attribute\");\n }\n return [field, target.value];\n } else {\n throw Error(\"Form control is not enclosed in FormField\");\n }\n};\n\nconst Status = {\n uninitialised: 0,\n unchanged: 1,\n changed: 2,\n invalid: 3,\n};\n\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined?: false\n): VuuRowDataItemType | undefined;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined: true\n): VuuRowDataItemType;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined = false\n): VuuRowDataItemType | undefined {\n switch (type) {\n case \"int\":\n case \"long\": {\n const typedValue = parseInt(value, 10);\n if (isValidNumber(typedValue)) {\n return typedValue;\n } else if (throwIfUndefined) {\n throw Error(\"SessionEditingForm getTypedValue\");\n } else {\n return undefined;\n }\n }\n\n case \"double\": {\n const typedValue = parseFloat(value);\n if (isValidNumber(typedValue)) {\n return typedValue;\n }\n return undefined;\n }\n\n case \"boolean\":\n return value === \"true\" ? true : false;\n default:\n return value;\n }\n}\n\nconst getDataSource = (\n dataSource?: DataSource,\n schema?: TableSchema\n): DataSource => {\n if (dataSource) {\n return dataSource;\n } else if (schema) {\n return new VuuDataSource({\n bufferSize: 0,\n table: schema.table,\n columns: schema.columns.map((col) => col.name),\n }) as DataSource;\n } else {\n throw Error(\n \"SessionEditingForm: either a DataSource or a TableSchema must be provided\"\n );\n }\n};\n\ntype FormValues = { [key: string]: VuuRowDataItemType | undefined };\n\nexport const SessionEditingForm = ({\n className,\n config: { fields, key: keyField },\n dataSource: dataSourceProp,\n id: idProp,\n onClose,\n schema,\n ...htmlAttributes\n}: SessionEditingFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-session-editing-form\",\n css: sessionEditingFormCss,\n window: targetWindow,\n });\n\n const [fieldStatusValues, setFieldStatusValues] = useState<\n Record<string, string | undefined>\n >({});\n const [values, setValues] = useState<FormValues>();\n const [errorMessage, setErrorMessage] = useState(\"\");\n const formContentRef = useRef<HTMLDivElement>(null);\n const initialDataRef = useRef<FormValues>();\n const dataStatusRef = useRef(Status.uninitialised);\n\n const dataSource = useMemo(() => {\n const ds = getDataSource(dataSourceProp, schema);\n const { columns } = ds;\n const columnMap = buildColumnMap(ds.columns);\n\n const applyServerData = (data: VuuDataRow) => {\n if (columnMap) {\n const values: { [key: string]: VuuRowDataItemType } = {};\n for (const column of columns) {\n values[column] = data[columnMap[column]];\n }\n if (dataStatusRef.current === Status.uninitialised) {\n dataStatusRef.current = Status.unchanged;\n initialDataRef.current = values;\n }\n setValues(values);\n }\n };\n\n ds.subscribe({ range: { from: 0, to: 5 } }, (message) => {\n if (message.type === \"viewport-update\" && message.rows) {\n if (dataStatusRef.current === Status.uninitialised) {\n applyServerData(message.rows[0]);\n } else {\n console.log(\"what do we do with server updates\");\n }\n }\n });\n return ds;\n }, [dataSourceProp, schema]);\n\n const id = useIdMemo(idProp);\n\n const handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type);\n setValues((values = {}) => {\n const newValues = {\n ...values,\n [field]: typedValue,\n };\n const notUpdated = shallowEquals(newValues, initialDataRef.current);\n dataStatusRef.current = notUpdated\n ? Status.unchanged\n : typedValue !== undefined\n ? Status.changed\n : Status.invalid;\n return newValues;\n });\n },\n [fields]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const rowKey = values?.[keyField];\n // TODO link this with client side validation if we're going to use it\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type, true);\n if (typeof rowKey === \"string\") {\n dataSource\n .menuRpcCall({\n rowKey,\n field: field,\n value: typedValue,\n type: \"VP_EDIT_CELL_RPC\",\n })\n .then((response) => {\n if (isErrorResponse(response)) {\n console.log(`edit rejected ${response.error}`);\n setFieldStatusValues((map) => ({\n ...map,\n [field]: response.error,\n }));\n } else {\n setFieldStatusValues((map) => ({\n ...map,\n [field]: undefined,\n }));\n }\n });\n }\n },\n [dataSource, fields, keyField, values]\n );\n\n const applyAction = useCallback(\n (action: unknown) => {\n if (typeof action === \"object\" && action !== null) {\n if (\"type\" in action && action.type === \"CLOSE_DIALOG_ACTION\") {\n onClose?.();\n }\n }\n },\n [onClose]\n );\n\n const handleSubmit = useCallback(async () => {\n const response = await dataSource.menuRpcCall({\n type: \"VP_EDIT_SUBMIT_FORM_RPC\",\n });\n if (isErrorResponse(response)) {\n setErrorMessage(response.error);\n } else if (hasAction(response)) {\n applyAction(response.action);\n }\n }, [applyAction, dataSource]);\n\n const handleKeyDown = useCallback(\n (evt) => {\n if (evt.key === \"Enter\" && dataStatusRef.current === Status.changed) {\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const handleCancel = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const getFormControl = (field: FormFieldDescriptor) => {\n const value = String(values?.[field.name] ?? \"\");\n if (field.readonly || field.name === keyField) {\n return (\n <div className={`${classBase}-fieldValue vuuReadOnly`}>{value}</div>\n );\n } else {\n return (\n <Input\n className={`${classBase}-fieldValue`}\n onBlur={handleBlur}\n onChange={handleChange}\n value={value}\n id={`${id}-input-${field.name}`}\n />\n );\n }\n };\n\n useEffect(() => {\n if (formContentRef.current) {\n const firstInput = formContentRef.current.querySelector(\n \"input\"\n ) as HTMLInputElement;\n if (firstInput) {\n setTimeout(() => {\n firstInput.focus();\n firstInput.select();\n }, 100);\n }\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (dataSource) {\n dataSource.unsubscribe();\n }\n };\n }, [dataSource]);\n\n const isDirty = dataStatusRef.current === Status.changed;\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {errorMessage ? (\n <div\n className={`${classBase}-errorBanner`}\n data-icon=\"error\"\n title={errorMessage}\n >\n Error, edit(s) not saved\n </div>\n ) : undefined}\n <div\n className={`${classBase}-content`}\n ref={formContentRef}\n onKeyDown={handleKeyDown}\n >\n {fields.map((field) => (\n <FormField\n className={`${classBase}-field`}\n data-field={field.name}\n key={field.name}\n necessity={field.required ? \"required\" : \"optional\"}\n readOnly={field.readonly}\n validationStatus={\n fieldStatusValues[field.name] ? \"error\" : undefined\n }\n >\n <FormFieldLabel>{field?.label ?? field.description}</FormFieldLabel>\n {getFormControl(field)}\n <FormFieldHelperText>\n {fieldStatusValues[field.name] ?? \"\"}\n </FormFieldHelperText>\n </FormField>\n ))}\n </div>\n <div className={`${classBase}-buttonbar salt-theme salt-density-high`}>\n <Button\n type=\"submit\"\n variant=\"cta\"\n disabled={!isDirty}\n onClick={handleSubmit}\n >\n Submit\n </Button>\n <Button variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n"],"names":["queryClosest","isValidNumber","VuuDataSource","useWindow","useComponentCssInjection","sessionEditingFormCss","useState","useRef","useMemo","buildColumnMap","values","useIdMemo","useCallback","shallowEquals","isErrorResponse","hasAction","jsx","Input","useEffect","jsxs","FormField","FormFieldLabel","FormFieldHelperText","Button"],"mappings":";;;;;;;;;;;;AAiEA,MAAM,SAAY,GAAA,uBAAA,CAAA;AAElB,MAAM,QAAA,GAAW,CACf,MAAA,EACA,IACwB,KAAA;AACxB,EAAA,MAAM,QAAQ,MAAO,CAAA,IAAA,CAAK,CAAC,CAAM,KAAA,CAAA,CAAE,SAAS,IAAI,CAAA,CAAA;AAChD,EAAA,IAAI,KAAO,EAAA;AACT,IAAO,OAAA,KAAA,CAAA;AAAA,GACF,MAAA;AACL,IAAM,MAAA,KAAA,CAAM,CAAiC,8BAAA,EAAA,IAAI,CAAS,OAAA,CAAA,CAAA,CAAA;AAAA,GAC5D;AACF,CAAA,CAAA;AAEA,MAAM,uBAAuB,CAAC;AAAA,EAC5B,MAAA;AACF,CAGK,KAAA;AACH,EAAM,MAAA,SAAA,GAAYA,qBAAa,CAAA,MAAA,EAAQ,gBAAgB,CAAA,CAAA;AACvD,EAAA,IAAI,SAAW,EAAA;AACb,IAAM,MAAA;AAAA,MACJ,OAAA,EAAS,EAAE,KAAM,EAAA;AAAA,KACf,GAAA,SAAA,CAAA;AACJ,IAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,MAAA,MAAM,MAAM,4DAA4D,CAAA,CAAA;AAAA,KAC1E;AACA,IAAO,OAAA,CAAC,KAAO,EAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,GACtB,MAAA;AACL,IAAA,MAAM,MAAM,2CAA2C,CAAA,CAAA;AAAA,GACzD;AACF,CAAA,CAAA;AAEA,MAAM,MAAS,GAAA;AAAA,EACb,aAAe,EAAA,CAAA;AAAA,EACf,SAAW,EAAA,CAAA;AAAA,EACX,OAAS,EAAA,CAAA;AAAA,EACT,OAAS,EAAA,CAAA;AACX,CAAA,CAAA;AAYA,SAAS,aACP,CAAA,KAAA,EACA,IACA,EAAA,gBAAA,GAAmB,KACa,EAAA;AAChC,EAAA,QAAQ,IAAM;AAAA,IACZ,KAAK,KAAA,CAAA;AAAA,IACL,KAAK,MAAQ,EAAA;AACX,MAAM,MAAA,UAAA,GAAa,QAAS,CAAA,KAAA,EAAO,EAAE,CAAA,CAAA;AACrC,MAAI,IAAAC,sBAAA,CAAc,UAAU,CAAG,EAAA;AAC7B,QAAO,OAAA,UAAA,CAAA;AAAA,iBACE,gBAAkB,EAAA;AAC3B,QAAA,MAAM,MAAM,kCAAkC,CAAA,CAAA;AAAA,OACzC,MAAA;AACL,QAAO,OAAA,KAAA,CAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,IAEA,KAAK,QAAU,EAAA;AACb,MAAM,MAAA,UAAA,GAAa,WAAW,KAAK,CAAA,CAAA;AACnC,MAAI,IAAAA,sBAAA,CAAc,UAAU,CAAG,EAAA;AAC7B,QAAO,OAAA,UAAA,CAAA;AAAA,OACT;AACA,MAAO,OAAA,KAAA,CAAA,CAAA;AAAA,KACT;AAAA,IAEA,KAAK,SAAA;AACH,MAAO,OAAA,KAAA,KAAU,SAAS,IAAO,GAAA,KAAA,CAAA;AAAA,IACnC;AACE,MAAO,OAAA,KAAA,CAAA;AAAA,GACX;AACF,CAAA;AAEA,MAAM,aAAA,GAAgB,CACpB,UAAA,EACA,MACe,KAAA;AACf,EAAA,IAAI,UAAY,EAAA;AACd,IAAO,OAAA,UAAA,CAAA;AAAA,aACE,MAAQ,EAAA;AACjB,IAAA,OAAO,IAAIC,2BAAc,CAAA;AAAA,MACvB,UAAY,EAAA,CAAA;AAAA,MACZ,OAAO,MAAO,CAAA,KAAA;AAAA,MACd,SAAS,MAAO,CAAA,OAAA,CAAQ,IAAI,CAAC,GAAA,KAAQ,IAAI,IAAI,CAAA;AAAA,KAC9C,CAAA,CAAA;AAAA,GACI,MAAA;AACL,IAAM,MAAA,KAAA;AAAA,MACJ,2EAAA;AAAA,KACF,CAAA;AAAA,GACF;AACF,CAAA,CAAA;AAIO,MAAM,qBAAqB,CAAC;AAAA,EACjC,SAAA;AAAA,EACA,MAAQ,EAAA,EAAE,MAAQ,EAAA,GAAA,EAAK,QAAS,EAAA;AAAA,EAChC,UAAY,EAAA,cAAA;AAAA,EACZ,EAAI,EAAA,MAAA;AAAA,EACJ,OAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAG,cAAA;AACL,CAA+B,KAAA;AAC7B,EAAA,MAAM,eAAeC,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,0BAAA;AAAA,IACR,GAAK,EAAAC,oBAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,MAAM,CAAC,iBAAmB,EAAA,oBAAoB,CAAI,GAAAC,cAAA,CAEhD,EAAE,CAAA,CAAA;AACJ,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,cAAqB,EAAA,CAAA;AACjD,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAIA,eAAS,EAAE,CAAA,CAAA;AACnD,EAAM,MAAA,cAAA,GAAiBC,aAAuB,IAAI,CAAA,CAAA;AAClD,EAAA,MAAM,iBAAiBA,YAAmB,EAAA,CAAA;AAC1C,EAAM,MAAA,aAAA,GAAgBA,YAAO,CAAA,MAAA,CAAO,aAAa,CAAA,CAAA;AAEjD,EAAM,MAAA,UAAA,GAAaC,cAAQ,MAAM;AAC/B,IAAM,MAAA,EAAA,GAAK,aAAc,CAAA,cAAA,EAAgB,MAAM,CAAA,CAAA;AAC/C,IAAM,MAAA,EAAE,SAAY,GAAA,EAAA,CAAA;AACpB,IAAM,MAAA,SAAA,GAAYC,uBAAe,CAAA,EAAA,CAAG,OAAO,CAAA,CAAA;AAE3C,IAAM,MAAA,eAAA,GAAkB,CAAC,IAAqB,KAAA;AAC5C,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,MAAMC,UAAgD,EAAC,CAAA;AACvD,QAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,UAAAA,QAAO,MAAM,CAAA,GAAI,IAAK,CAAA,SAAA,CAAU,MAAM,CAAC,CAAA,CAAA;AAAA,SACzC;AACA,QAAI,IAAA,aAAA,CAAc,OAAY,KAAA,MAAA,CAAO,aAAe,EAAA;AAClD,UAAA,aAAA,CAAc,UAAU,MAAO,CAAA,SAAA,CAAA;AAC/B,UAAA,cAAA,CAAe,OAAUA,GAAAA,OAAAA,CAAAA;AAAA,SAC3B;AACA,QAAA,SAAA,CAAUA,OAAM,CAAA,CAAA;AAAA,OAClB;AAAA,KACF,CAAA;AAEA,IAAG,EAAA,CAAA,SAAA,CAAU,EAAE,KAAA,EAAO,EAAE,IAAA,EAAM,CAAG,EAAA,EAAA,EAAI,CAAE,EAAA,EAAK,EAAA,CAAC,OAAY,KAAA;AACvD,MAAA,IAAI,OAAQ,CAAA,IAAA,KAAS,iBAAqB,IAAA,OAAA,CAAQ,IAAM,EAAA;AACtD,QAAI,IAAA,aAAA,CAAc,OAAY,KAAA,MAAA,CAAO,aAAe,EAAA;AAClD,UAAgB,eAAA,CAAA,OAAA,CAAQ,IAAK,CAAA,CAAC,CAAC,CAAA,CAAA;AAAA,SAC1B,MAAA;AACL,UAAA,OAAA,CAAQ,IAAI,mCAAmC,CAAA,CAAA;AAAA,SACjD;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AACD,IAAO,OAAA,EAAA,CAAA;AAAA,GACN,EAAA,CAAC,cAAgB,EAAA,MAAM,CAAC,CAAA,CAAA;AAE3B,EAAM,MAAA,EAAA,GAAKC,eAAU,MAAM,CAAA,CAAA;AAE3B,EAAA,MAAM,YAAe,GAAAC,iBAAA;AAAA,IACnB,CAAC,GAAQ,KAAA;AACP,MAAA,MAAM,CAAC,KAAA,EAAO,KAAK,CAAA,GAAI,qBAAqB,GAAG,CAAA,CAAA;AAC/C,MAAA,MAAM,EAAE,IAAA,EAAS,GAAA,QAAA,CAAS,QAAQ,KAAK,CAAA,CAAA;AACvC,MAAM,MAAA,UAAA,GAAa,aAAc,CAAA,KAAA,EAAO,IAAI,CAAA,CAAA;AAC5C,MAAU,SAAA,CAAA,CAACF,OAAS,GAAA,EAAO,KAAA;AACzB,QAAA,MAAM,SAAY,GAAA;AAAA,UAChB,GAAGA,OAAAA;AAAA,UACH,CAAC,KAAK,GAAG,UAAA;AAAA,SACX,CAAA;AACA,QAAA,MAAM,UAAa,GAAAG,sBAAA,CAAc,SAAW,EAAA,cAAA,CAAe,OAAO,CAAA,CAAA;AAClE,QAAc,aAAA,CAAA,OAAA,GAAU,aACpB,MAAO,CAAA,SAAA,GACP,eAAe,KACf,CAAA,GAAA,MAAA,CAAO,UACP,MAAO,CAAA,OAAA,CAAA;AACX,QAAO,OAAA,SAAA,CAAA;AAAA,OACR,CAAA,CAAA;AAAA,KACH;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AAEA,EAAA,MAAM,UAAa,GAAAD,iBAAA;AAAA,IACjB,CAAC,GAAQ,KAAA;AACP,MAAA,MAAM,CAAC,KAAA,EAAO,KAAK,CAAA,GAAI,qBAAqB,GAAG,CAAA,CAAA;AAC/C,MAAM,MAAA,MAAA,GAAS,SAAS,QAAQ,CAAA,CAAA;AAEhC,MAAA,MAAM,EAAE,IAAA,EAAS,GAAA,QAAA,CAAS,QAAQ,KAAK,CAAA,CAAA;AACvC,MAAA,MAAM,UAAa,GAAA,aAAA,CAAc,KAAO,EAAA,IAAA,EAAM,IAAI,CAAA,CAAA;AAClD,MAAI,IAAA,OAAO,WAAW,QAAU,EAAA;AAC9B,QAAA,UAAA,CACG,WAAY,CAAA;AAAA,UACX,MAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAO,EAAA,UAAA;AAAA,UACP,IAAM,EAAA,kBAAA;AAAA,SACP,CAAA,CACA,IAAK,CAAA,CAAC,QAAa,KAAA;AAClB,UAAI,IAAAE,wBAAA,CAAgB,QAAQ,CAAG,EAAA;AAC7B,YAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,cAAA,EAAiB,QAAS,CAAA,KAAK,CAAE,CAAA,CAAA,CAAA;AAC7C,YAAA,oBAAA,CAAqB,CAAC,GAAS,MAAA;AAAA,cAC7B,GAAG,GAAA;AAAA,cACH,CAAC,KAAK,GAAG,QAAS,CAAA,KAAA;AAAA,aAClB,CAAA,CAAA,CAAA;AAAA,WACG,MAAA;AACL,YAAA,oBAAA,CAAqB,CAAC,GAAS,MAAA;AAAA,cAC7B,GAAG,GAAA;AAAA,cACH,CAAC,KAAK,GAAG,KAAA,CAAA;AAAA,aACT,CAAA,CAAA,CAAA;AAAA,WACJ;AAAA,SACD,CAAA,CAAA;AAAA,OACL;AAAA,KACF;AAAA,IACA,CAAC,UAAA,EAAY,MAAQ,EAAA,QAAA,EAAU,MAAM,CAAA;AAAA,GACvC,CAAA;AAEA,EAAA,MAAM,WAAc,GAAAF,iBAAA;AAAA,IAClB,CAAC,MAAoB,KAAA;AACnB,MAAA,IAAI,OAAO,MAAA,KAAW,QAAY,IAAA,MAAA,KAAW,IAAM,EAAA;AACjD,QAAA,IAAI,MAAU,IAAA,MAAA,IAAU,MAAO,CAAA,IAAA,KAAS,qBAAuB,EAAA;AAC7D,UAAU,OAAA,IAAA,CAAA;AAAA,SACZ;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,OAAO,CAAA;AAAA,GACV,CAAA;AAEA,EAAM,MAAA,YAAA,GAAeA,kBAAY,YAAY;AAC3C,IAAM,MAAA,QAAA,GAAW,MAAM,UAAA,CAAW,WAAY,CAAA;AAAA,MAC5C,IAAM,EAAA,yBAAA;AAAA,KACP,CAAA,CAAA;AACD,IAAI,IAAAE,wBAAA,CAAgB,QAAQ,CAAG,EAAA;AAC7B,MAAA,eAAA,CAAgB,SAAS,KAAK,CAAA,CAAA;AAAA,KAChC,MAAA,IAAWC,kBAAU,CAAA,QAAQ,CAAG,EAAA;AAC9B,MAAA,WAAA,CAAY,SAAS,MAAM,CAAA,CAAA;AAAA,KAC7B;AAAA,GACC,EAAA,CAAC,WAAa,EAAA,UAAU,CAAC,CAAA,CAAA;AAE5B,EAAA,MAAM,aAAgB,GAAAH,iBAAA;AAAA,IACpB,CAAC,GAAQ,KAAA;AACP,MAAA,IAAI,IAAI,GAAQ,KAAA,OAAA,IAAW,aAAc,CAAA,OAAA,KAAY,OAAO,OAAS,EAAA;AACnE,QAAa,YAAA,EAAA,CAAA;AAAA,OACf;AAAA,KACF;AAAA,IACA,CAAC,YAAY,CAAA;AAAA,GACf,CAAA;AAEA,EAAM,MAAA,YAAA,GAAeA,kBAAY,MAAM;AACrC,IAAU,OAAA,IAAA,CAAA;AAAA,GACZ,EAAG,CAAC,OAAO,CAAC,CAAA,CAAA;AAEZ,EAAM,MAAA,cAAA,GAAiB,CAAC,KAA+B,KAAA;AACrD,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,GAAS,KAAM,CAAA,IAAI,KAAK,EAAE,CAAA,CAAA;AAC/C,IAAA,IAAI,KAAM,CAAA,QAAA,IAAY,KAAM,CAAA,IAAA,KAAS,QAAU,EAAA;AAC7C,MAAA,sCACG,KAAI,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,2BAA4B,QAAM,EAAA,KAAA,EAAA,CAAA,CAAA;AAAA,KAE3D,MAAA;AACL,MACE,uBAAAI,cAAA;AAAA,QAACC,UAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAW,GAAG,SAAS,CAAA,WAAA,CAAA;AAAA,UACvB,MAAQ,EAAA,UAAA;AAAA,UACR,QAAU,EAAA,YAAA;AAAA,UACV,KAAA;AAAA,UACA,EAAI,EAAA,CAAA,EAAG,EAAE,CAAA,OAAA,EAAU,MAAM,IAAI,CAAA,CAAA;AAAA,SAAA;AAAA,OAC/B,CAAA;AAAA,KAEJ;AAAA,GACF,CAAA;AAEA,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,eAAe,OAAS,EAAA;AAC1B,MAAM,MAAA,UAAA,GAAa,eAAe,OAAQ,CAAA,aAAA;AAAA,QACxC,OAAA;AAAA,OACF,CAAA;AACA,MAAA,IAAI,UAAY,EAAA;AACd,QAAA,UAAA,CAAW,MAAM;AACf,UAAA,UAAA,CAAW,KAAM,EAAA,CAAA;AACjB,UAAA,UAAA,CAAW,MAAO,EAAA,CAAA;AAAA,WACjB,GAAG,CAAA,CAAA;AAAA,OACR;AAAA,KACF;AAAA,GACF,EAAG,EAAE,CAAA,CAAA;AAEL,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,UAAY,EAAA;AACd,QAAA,UAAA,CAAW,WAAY,EAAA,CAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,UAAU,CAAC,CAAA,CAAA;AAEf,EAAM,MAAA,OAAA,GAAU,aAAc,CAAA,OAAA,KAAY,MAAO,CAAA,OAAA,CAAA;AACjD,EACE,uBAAAC,eAAA,CAAC,SAAK,GAAG,cAAA,EAAgB,WAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CACxD,EAAA,QAAA,EAAA;AAAA,IACC,YAAA,mBAAAH,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,GAAG,SAAS,CAAA,YAAA,CAAA;AAAA,QACvB,WAAU,EAAA,OAAA;AAAA,QACV,KAAO,EAAA,YAAA;AAAA,QACR,QAAA,EAAA,0BAAA;AAAA,OAAA;AAAA,KAGC,GAAA,KAAA,CAAA;AAAA,oBACJA,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,QACvB,GAAK,EAAA,cAAA;AAAA,QACL,SAAW,EAAA,aAAA;AAAA,QAEV,QAAA,EAAA,MAAA,CAAO,GAAI,CAAA,CAAC,KACX,qBAAAG,eAAA;AAAA,UAACC,cAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,GAAG,SAAS,CAAA,MAAA,CAAA;AAAA,YACvB,cAAY,KAAM,CAAA,IAAA;AAAA,YAElB,SAAA,EAAW,KAAM,CAAA,QAAA,GAAW,UAAa,GAAA,UAAA;AAAA,YACzC,UAAU,KAAM,CAAA,QAAA;AAAA,YAChB,gBACE,EAAA,iBAAA,CAAkB,KAAM,CAAA,IAAI,IAAI,OAAU,GAAA,KAAA,CAAA;AAAA,YAG5C,QAAA,EAAA;AAAA,8BAAAJ,cAAA,CAACK,mBAAgB,EAAA,EAAA,QAAA,EAAA,KAAA,EAAO,KAAS,IAAA,KAAA,CAAM,WAAY,EAAA,CAAA;AAAA,cAClD,eAAe,KAAK,CAAA;AAAA,6CACpBC,wBACE,EAAA,EAAA,QAAA,EAAA,iBAAA,CAAkB,KAAM,CAAA,IAAI,KAAK,EACpC,EAAA,CAAA;AAAA,aAAA;AAAA,WAAA;AAAA,UAXK,KAAM,CAAA,IAAA;AAAA,SAad,CAAA;AAAA,OAAA;AAAA,KACH;AAAA,oBACCH,eAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAC1B,uCAAA,CAAA,EAAA,QAAA,EAAA;AAAA,sBAAAH,cAAA;AAAA,QAACO,WAAA;AAAA,QAAA;AAAA,UACC,IAAK,EAAA,QAAA;AAAA,UACL,OAAQ,EAAA,KAAA;AAAA,UACR,UAAU,CAAC,OAAA;AAAA,UACX,OAAS,EAAA,YAAA;AAAA,UACV,QAAA,EAAA,QAAA;AAAA,SAAA;AAAA,OAED;AAAA,qCACCA,WAAO,EAAA,EAAA,OAAA,EAAQ,WAAY,EAAA,OAAA,EAAS,cAAc,QAEnD,EAAA,QAAA,EAAA,CAAA;AAAA,KACF,EAAA,CAAA;AAAA,GACF,EAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,28 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { getServerAPI, VuuDataSource } from '@vuu-ui/vuu-data-remote';
3
+ import { createContext, useContext } from 'react';
4
+
5
+ const DataSourceContext = createContext({
6
+ isLocalData: false,
7
+ getServerAPI,
8
+ VuuDataSource
9
+ });
10
+ const DataSourceProvider = ({
11
+ children,
12
+ getServerAPI: getServerAPI2,
13
+ isLocalData = true,
14
+ VuuDataSource: VuuDataSource2,
15
+ vuuModuleName
16
+ }) => {
17
+ return /* @__PURE__ */ jsx(
18
+ DataSourceContext.Provider,
19
+ {
20
+ value: { isLocalData, vuuModuleName, VuuDataSource: VuuDataSource2, getServerAPI: getServerAPI2 },
21
+ children
22
+ }
23
+ );
24
+ };
25
+ const useDataSource = () => useContext(DataSourceContext);
26
+
27
+ export { DataSourceProvider, useDataSource };
28
+ //# sourceMappingURL=DataSourceProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataSourceProvider.js","sources":["../../src/datasource-provider/DataSourceProvider.tsx"],"sourcesContent":["import {\n getServerAPI,\n ServerAPI,\n VuuDataSource,\n} from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, DataSourceConstructorProps } from \"@vuu-ui/vuu-data-types\";\nimport { createContext, ReactNode, useContext } from \"react\";\n\nexport type DataSourceConstructor = {\n new (props: DataSourceConstructorProps): DataSource;\n};\n\nexport interface DataSourceContextProps {\n isLocalData: boolean;\n VuuDataSource: DataSourceConstructor;\n vuuModuleName?: string;\n getServerAPI: () => Promise<\n Pick<ServerAPI, \"getTableList\" | \"getTableSchema\">\n >;\n}\n\nconst DataSourceContext = createContext<DataSourceContextProps>({\n isLocalData: false,\n getServerAPI,\n VuuDataSource,\n});\n\n/**\n * If a client is adding a DataSOurceProvider, it will ususlly be\n * to install local test data, so we default isLocalData to true\n */\nexport const DataSourceProvider = ({\n children,\n getServerAPI,\n isLocalData = true,\n VuuDataSource,\n vuuModuleName,\n}: Omit<DataSourceContextProps, \"isLocalData\"> & {\n children: ReactNode;\n isLocalData?: boolean;\n}) => {\n return (\n <DataSourceContext.Provider\n value={{ isLocalData, vuuModuleName, VuuDataSource, getServerAPI }}\n >\n {children}\n </DataSourceContext.Provider>\n );\n};\n\nexport const useDataSource = () => useContext(DataSourceContext);\n"],"names":["getServerAPI","VuuDataSource"],"mappings":";;;;AAqBA,MAAM,oBAAoB,aAAsC,CAAA;AAAA,EAC9D,WAAa,EAAA,KAAA;AAAA,EACb,YAAA;AAAA,EACA,aAAA;AACF,CAAC,CAAA,CAAA;AAMM,MAAM,qBAAqB,CAAC;AAAA,EACjC,QAAA;AAAA,EACA,YAAAA,EAAAA,aAAAA;AAAA,EACA,WAAc,GAAA,IAAA;AAAA,EACd,aAAAC,EAAAA,cAAAA;AAAA,EACA,aAAA;AACF,CAGM,KAAA;AACJ,EACE,uBAAA,GAAA;AAAA,IAAC,iBAAkB,CAAA,QAAA;AAAA,IAAlB;AAAA,MACC,OAAO,EAAE,WAAA,EAAa,eAAe,aAAAA,EAAAA,cAAAA,EAAe,cAAAD,aAAa,EAAA;AAAA,MAEhE,QAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,EAAA;AAEa,MAAA,aAAA,GAAgB,MAAM,UAAA,CAAW,iBAAiB;;;;"}
package/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { AppHeader } from './app-header/AppHeader.js';
2
2
  export { ConnectionStatusIndicator } from './connection-status/ConnectionStatusIndicator.js';
3
+ export { DataSourceProvider, useDataSource } from './datasource-provider/DataSourceProvider.js';
3
4
  export { Feature } from './feature/Feature.js';
4
5
  export { defaultApplicationJson, defaultLayoutJson, getDefaultApplicationLayout, loadingApplicationJson, warningLayout } from './layout-management/defaultApplicationJson.js';
5
6
  export { SaveLayoutPanel } from './layout-management/SaveLayoutPanel.js';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -157,8 +157,8 @@ class LocalPersistenceManager {
157
157
  const applicationJSON = getLocalEntity(__privateGet(this, _urlKey));
158
158
  if (applicationJSON) {
159
159
  __privateSet(this, _applicationJSON, applicationJSON);
160
- resolve(applicationJSON);
161
160
  }
161
+ resolve(applicationJSON);
162
162
  });
163
163
  }
164
164
  saveApplicationJSON(applicationJSON) {
@@ -1 +1 @@
1
- {"version":3,"file":"LocalPersistenceManager.js","sources":["../../src/persistence-manager/LocalPersistenceManager.ts"],"sourcesContent":["import {\n ApplicationJSON,\n LayoutJSON,\n Settings,\n formatDate,\n getLocalEntity,\n getUniqueId,\n saveLocalEntity,\n} from \"@vuu-ui/vuu-utils\";\n\nimport {\n Layout,\n LayoutMetadata,\n LayoutMetadataDto,\n WithId,\n} from \"../layout-management\";\nimport { getAuthDetailsFromCookies } from \"../login\";\nimport { IPersistenceManager } from \"./PersistenceManager\";\nconst baseMetadataSaveLocation = \"layouts/metadata\";\nconst baseLayoutsSaveLocation = \"layouts/layouts\";\n\nexport class LocalPersistenceManager implements IPersistenceManager {\n #username: string = getAuthDetailsFromCookies()[0];\n metadataSaveLocation = `${baseMetadataSaveLocation}/${this.#username}`;\n layoutsSaveLocation = `${baseLayoutsSaveLocation}/${this.#username}`;\n #urlKey = `api/vui/${this.#username}`;\n #applicationJSON: ApplicationJSON | undefined;\n\n constructor(urlKey?: string) {\n if (urlKey) {\n this.#urlKey = urlKey;\n }\n }\n\n createLayout(\n metadata: LayoutMetadataDto,\n layout: LayoutJSON\n ): Promise<LayoutMetadata> {\n return new Promise((resolve) => {\n Promise.all([this.loadLayouts(), this.loadMetadata()]).then(\n ([existingLayouts, existingMetadata]) => {\n const id = getUniqueId();\n const newMetadata: LayoutMetadata = {\n ...metadata,\n id,\n created: formatDate({ date: \"dd.mm.yyyy\" })(new Date()),\n };\n\n this.saveLayoutsWithMetadata(\n [...existingLayouts, { id, json: layout }],\n [...existingMetadata, newMetadata]\n );\n resolve(newMetadata);\n }\n );\n });\n }\n\n updateLayout(\n id: string,\n newMetadata: LayoutMetadataDto,\n newLayout: LayoutJSON\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const updatedLayouts = existingLayouts.map((layout) =>\n layout.id === id ? { ...layout, json: newLayout } : layout\n );\n const updatedMetadata = existingMetadata.map((metadata) =>\n metadata.id === id ? { ...metadata, ...newMetadata } : metadata\n );\n this.saveLayoutsWithMetadata(updatedLayouts, updatedMetadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n deleteLayout(id: string): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const layouts = existingLayouts.filter((layout) => layout.id !== id);\n const metadata = existingMetadata.filter(\n (metadata) => metadata.id !== id\n );\n this.saveLayoutsWithMetadata(layouts, metadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n loadLayout(id: string): Promise<LayoutJSON> {\n return new Promise((resolve, reject) => {\n this.validateId(id, \"layout\")\n .then(() => this.loadLayouts())\n .then((existingLayouts) => {\n const foundLayout = existingLayouts.find(\n (layout) => layout.id === id\n );\n if (foundLayout) {\n resolve(foundLayout.json);\n } else {\n reject(new Error(`no layout found matching id ${id}`));\n }\n })\n .catch((e) => reject(e));\n });\n }\n\n loadMetadata(): Promise<LayoutMetadata[]> {\n return new Promise((resolve) => {\n const metadata = getLocalEntity<LayoutMetadata[]>(\n this.metadataSaveLocation\n );\n resolve(metadata || []);\n });\n }\n\n async loadApplicationJSON(): Promise<ApplicationJSON | undefined> {\n return (\n this.#applicationJSON ||\n new Promise((resolve) => {\n const applicationJSON = getLocalEntity<ApplicationJSON>(this.#urlKey);\n if (applicationJSON) {\n this.#applicationJSON = applicationJSON;\n resolve(applicationJSON);\n }\n })\n );\n }\n\n saveApplicationJSON(applicationJSON: ApplicationJSON): Promise<void> {\n return new Promise((resolve, reject) => {\n const savedLayout = saveLocalEntity<ApplicationJSON>(\n this.#urlKey,\n applicationJSON\n );\n if (savedLayout) {\n this.#applicationJSON = applicationJSON;\n resolve();\n } else {\n reject(new Error(\"Application Json failed to save\"));\n }\n });\n }\n\n loadLayouts = (): Promise<Layout[]> => {\n return new Promise((resolve) => {\n const layouts = getLocalEntity<Layout[]>(this.layoutsSaveLocation);\n resolve(layouts || []);\n });\n };\n\n saveLayoutsWithMetadata = (\n layouts: Layout[],\n metadata: LayoutMetadata[]\n ): void => {\n saveLocalEntity<Layout[]>(this.layoutsSaveLocation, layouts);\n saveLocalEntity<LayoutMetadata[]>(this.metadataSaveLocation, metadata);\n };\n\n // Ensures that there is exactly one Layout entry and exactly one Metadata\n // entry in local storage corresponding to the provided ID.\n validateIds = async (id: string): Promise<void> => {\n return Promise.all([\n this.validateId(id, \"metadata\").catch((error) => error.message),\n this.validateId(id, \"layout\").catch((error) => error.message),\n ]).then((errorMessages: string[]) => {\n // filter() is used to remove any blank messages before joining.\n // Avoids orphaned delimiters in combined messages, e.g. \"; \" or \"; error 2\"\n const combinedMessage = errorMessages\n .filter((msg) => msg !== undefined)\n .join(\"; \");\n if (combinedMessage) {\n throw new Error(combinedMessage);\n }\n });\n };\n\n // Ensures that there is exactly one element (Layout or Metadata) in local\n // storage corresponding to the provided ID.\n validateId = (id: string, dataType: \"metadata\" | \"layout\"): Promise<void> => {\n return new Promise((resolve, reject) => {\n const loadFunc =\n dataType === \"metadata\"\n ? () => this.loadMetadata()\n : () => this.loadLayouts();\n\n loadFunc().then((array: WithId[]) => {\n const count = array.filter((element) => element.id === id).length;\n switch (count) {\n case 1: {\n resolve();\n break;\n }\n case 0: {\n reject(new Error(`No ${dataType} with ID ${id}`));\n break;\n }\n default:\n reject(new Error(`Non-unique ${dataType} with ID ${id}`));\n }\n });\n });\n };\n\n async getUserSettings() {\n if (this.#applicationJSON) {\n return this.#applicationJSON.userSettings ?? {};\n }\n\n try {\n const applicationJSON = await this.loadApplicationJSON();\n return applicationJSON?.userSettings ?? {};\n } catch (e) {\n return {};\n }\n }\n\n saveUserSettings(userSettings: Settings) {\n if (this.#applicationJSON) {\n this.saveApplicationJSON({\n ...this.#applicationJSON,\n userSettings,\n });\n }\n }\n}\n"],"names":["metadata"],"mappings":"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"}
1
+ {"version":3,"file":"LocalPersistenceManager.js","sources":["../../src/persistence-manager/LocalPersistenceManager.ts"],"sourcesContent":["import {\n ApplicationJSON,\n LayoutJSON,\n Settings,\n formatDate,\n getLocalEntity,\n getUniqueId,\n saveLocalEntity,\n} from \"@vuu-ui/vuu-utils\";\n\nimport {\n Layout,\n LayoutMetadata,\n LayoutMetadataDto,\n WithId,\n} from \"../layout-management\";\nimport { getAuthDetailsFromCookies } from \"../login\";\nimport { IPersistenceManager } from \"./PersistenceManager\";\nconst baseMetadataSaveLocation = \"layouts/metadata\";\nconst baseLayoutsSaveLocation = \"layouts/layouts\";\n\nexport class LocalPersistenceManager implements IPersistenceManager {\n #username: string = getAuthDetailsFromCookies()[0];\n metadataSaveLocation = `${baseMetadataSaveLocation}/${this.#username}`;\n layoutsSaveLocation = `${baseLayoutsSaveLocation}/${this.#username}`;\n #urlKey = `api/vui/${this.#username}`;\n #applicationJSON: ApplicationJSON | undefined;\n\n constructor(urlKey?: string) {\n if (urlKey) {\n this.#urlKey = urlKey;\n }\n }\n\n createLayout(\n metadata: LayoutMetadataDto,\n layout: LayoutJSON\n ): Promise<LayoutMetadata> {\n return new Promise((resolve) => {\n Promise.all([this.loadLayouts(), this.loadMetadata()]).then(\n ([existingLayouts, existingMetadata]) => {\n const id = getUniqueId();\n const newMetadata: LayoutMetadata = {\n ...metadata,\n id,\n created: formatDate({ date: \"dd.mm.yyyy\" })(new Date()),\n };\n\n this.saveLayoutsWithMetadata(\n [...existingLayouts, { id, json: layout }],\n [...existingMetadata, newMetadata]\n );\n resolve(newMetadata);\n }\n );\n });\n }\n\n updateLayout(\n id: string,\n newMetadata: LayoutMetadataDto,\n newLayout: LayoutJSON\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const updatedLayouts = existingLayouts.map((layout) =>\n layout.id === id ? { ...layout, json: newLayout } : layout\n );\n const updatedMetadata = existingMetadata.map((metadata) =>\n metadata.id === id ? { ...metadata, ...newMetadata } : metadata\n );\n this.saveLayoutsWithMetadata(updatedLayouts, updatedMetadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n deleteLayout(id: string): Promise<void> {\n return new Promise((resolve, reject) => {\n this.validateIds(id)\n .then(() => Promise.all([this.loadLayouts(), this.loadMetadata()]))\n .then(([existingLayouts, existingMetadata]) => {\n const layouts = existingLayouts.filter((layout) => layout.id !== id);\n const metadata = existingMetadata.filter(\n (metadata) => metadata.id !== id\n );\n this.saveLayoutsWithMetadata(layouts, metadata);\n resolve();\n })\n .catch((e) => reject(e));\n });\n }\n\n loadLayout(id: string): Promise<LayoutJSON> {\n return new Promise((resolve, reject) => {\n this.validateId(id, \"layout\")\n .then(() => this.loadLayouts())\n .then((existingLayouts) => {\n const foundLayout = existingLayouts.find(\n (layout) => layout.id === id\n );\n if (foundLayout) {\n resolve(foundLayout.json);\n } else {\n reject(new Error(`no layout found matching id ${id}`));\n }\n })\n .catch((e) => reject(e));\n });\n }\n\n loadMetadata(): Promise<LayoutMetadata[]> {\n return new Promise((resolve) => {\n const metadata = getLocalEntity<LayoutMetadata[]>(\n this.metadataSaveLocation\n );\n resolve(metadata || []);\n });\n }\n\n async loadApplicationJSON(): Promise<ApplicationJSON | undefined> {\n return (\n this.#applicationJSON ||\n new Promise((resolve) => {\n const applicationJSON = getLocalEntity<ApplicationJSON>(this.#urlKey);\n if (applicationJSON) {\n this.#applicationJSON = applicationJSON;\n }\n resolve(applicationJSON);\n })\n );\n }\n\n saveApplicationJSON(applicationJSON: ApplicationJSON): Promise<void> {\n return new Promise((resolve, reject) => {\n const savedLayout = saveLocalEntity<ApplicationJSON>(\n this.#urlKey,\n applicationJSON\n );\n if (savedLayout) {\n this.#applicationJSON = applicationJSON;\n resolve();\n } else {\n reject(new Error(\"Application Json failed to save\"));\n }\n });\n }\n\n loadLayouts = (): Promise<Layout[]> => {\n return new Promise((resolve) => {\n const layouts = getLocalEntity<Layout[]>(this.layoutsSaveLocation);\n resolve(layouts || []);\n });\n };\n\n saveLayoutsWithMetadata = (\n layouts: Layout[],\n metadata: LayoutMetadata[]\n ): void => {\n saveLocalEntity<Layout[]>(this.layoutsSaveLocation, layouts);\n saveLocalEntity<LayoutMetadata[]>(this.metadataSaveLocation, metadata);\n };\n\n // Ensures that there is exactly one Layout entry and exactly one Metadata\n // entry in local storage corresponding to the provided ID.\n validateIds = async (id: string): Promise<void> => {\n return Promise.all([\n this.validateId(id, \"metadata\").catch((error) => error.message),\n this.validateId(id, \"layout\").catch((error) => error.message),\n ]).then((errorMessages: string[]) => {\n // filter() is used to remove any blank messages before joining.\n // Avoids orphaned delimiters in combined messages, e.g. \"; \" or \"; error 2\"\n const combinedMessage = errorMessages\n .filter((msg) => msg !== undefined)\n .join(\"; \");\n if (combinedMessage) {\n throw new Error(combinedMessage);\n }\n });\n };\n\n // Ensures that there is exactly one element (Layout or Metadata) in local\n // storage corresponding to the provided ID.\n validateId = (id: string, dataType: \"metadata\" | \"layout\"): Promise<void> => {\n return new Promise((resolve, reject) => {\n const loadFunc =\n dataType === \"metadata\"\n ? () => this.loadMetadata()\n : () => this.loadLayouts();\n\n loadFunc().then((array: WithId[]) => {\n const count = array.filter((element) => element.id === id).length;\n switch (count) {\n case 1: {\n resolve();\n break;\n }\n case 0: {\n reject(new Error(`No ${dataType} with ID ${id}`));\n break;\n }\n default:\n reject(new Error(`Non-unique ${dataType} with ID ${id}`));\n }\n });\n });\n };\n\n async getUserSettings() {\n if (this.#applicationJSON) {\n return this.#applicationJSON.userSettings ?? {};\n }\n\n try {\n const applicationJSON = await this.loadApplicationJSON();\n return applicationJSON?.userSettings ?? {};\n } catch (e) {\n return {};\n }\n }\n\n saveUserSettings(userSettings: Settings) {\n if (this.#applicationJSON) {\n this.saveApplicationJSON({\n ...this.#applicationJSON,\n userSettings,\n });\n }\n }\n}\n"],"names":["metadata"],"mappings":"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"}
@@ -160,7 +160,7 @@ const SessionEditingForm = ({
160
160
  value: typedValue,
161
161
  type: "VP_EDIT_CELL_RPC"
162
162
  }).then((response) => {
163
- if (response?.type === "VP_EDIT_RPC_REJECT") {
163
+ if (isErrorResponse(response)) {
164
164
  console.log(`edit rejected ${response.error}`);
165
165
  setFieldStatusValues((map) => ({
166
166
  ...map,
@@ -1 +1 @@
1
- {"version":3,"file":"SessionEditingForm.js","sources":["../../src/session-editing-form/SessionEditingForm.tsx"],"sourcesContent":["import { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n hasAction,\n isErrorResponse,\n isValidNumber,\n queryClosest,\n shallowEquals,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldHelperText,\n FormFieldLabel,\n Input,\n useIdMemo,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n ChangeEvent,\n ChangeEventHandler,\n FocusEvent,\n FocusEventHandler,\n HTMLAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport sessionEditingFormCss from \"./SessionEditingForm.css\";\n\nexport type FormFieldDescriptor = {\n isKeyField?: boolean;\n label?: string;\n name: string;\n type: VuuColumnDataType;\n description: string;\n readonly?: boolean;\n required?: boolean;\n};\n\nexport type FormConfig = {\n title: string;\n key: string;\n fields: FormFieldDescriptor[];\n};\n\nexport interface SessionEditingFormProps\n extends HTMLAttributes<HTMLDivElement> {\n config: FormConfig;\n onClose?: () => void;\n dataSource?: DataSource;\n schema?: TableSchema;\n}\n\nconst classBase = \"vuuSessionEditingForm\";\n\nconst getField = (\n fields: FormFieldDescriptor[],\n name: string\n): FormFieldDescriptor => {\n const field = fields.find((f) => f.name === name);\n if (field) {\n return field;\n } else {\n throw Error(`SessionEditingForm, no field '${name}' found`);\n }\n};\n\nconst getFieldNameAndValue = ({\n target,\n}: ChangeEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>): [\n string,\n string\n] => {\n const formField = queryClosest(target, \".saltFormField\");\n if (formField) {\n const {\n dataset: { field },\n } = formField;\n if (field === undefined) {\n throw Error(\"SessionEditingForm, form field has no field data attribute\");\n }\n return [field, target.value];\n } else {\n throw Error(\"Form control is not enclosed in FormField\");\n }\n};\n\nconst Status = {\n uninitialised: 0,\n unchanged: 1,\n changed: 2,\n invalid: 3,\n};\n\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined?: false\n): VuuRowDataItemType | undefined;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined: true\n): VuuRowDataItemType;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined = false\n): VuuRowDataItemType | undefined {\n switch (type) {\n case \"int\":\n case \"long\": {\n const typedValue = parseInt(value, 10);\n if (isValidNumber(typedValue)) {\n return typedValue;\n } else if (throwIfUndefined) {\n throw Error(\"SessionEditingForm getTypedValue\");\n } else {\n return undefined;\n }\n }\n\n case \"double\": {\n const typedValue = parseFloat(value);\n if (isValidNumber(typedValue)) {\n return typedValue;\n }\n return undefined;\n }\n\n case \"boolean\":\n return value === \"true\" ? true : false;\n default:\n return value;\n }\n}\n\nconst getDataSource = (\n dataSource?: DataSource,\n schema?: TableSchema\n): DataSource => {\n if (dataSource) {\n return dataSource;\n } else if (schema) {\n return new VuuDataSource({\n bufferSize: 0,\n table: schema.table,\n columns: schema.columns.map((col) => col.name),\n }) as DataSource;\n } else {\n throw Error(\n \"SessionEditingForm: either a DataSource or a TableSchema must be provided\"\n );\n }\n};\n\ntype FormValues = { [key: string]: VuuRowDataItemType | undefined };\n\nexport const SessionEditingForm = ({\n className,\n config: { fields, key: keyField },\n dataSource: dataSourceProp,\n id: idProp,\n onClose,\n schema,\n ...htmlAttributes\n}: SessionEditingFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-session-editing-form\",\n css: sessionEditingFormCss,\n window: targetWindow,\n });\n\n const [fieldStatusValues, setFieldStatusValues] = useState<\n Record<string, string | undefined>\n >({});\n const [values, setValues] = useState<FormValues>();\n const [errorMessage, setErrorMessage] = useState(\"\");\n const formContentRef = useRef<HTMLDivElement>(null);\n const initialDataRef = useRef<FormValues>();\n const dataStatusRef = useRef(Status.uninitialised);\n\n const dataSource = useMemo(() => {\n const ds = getDataSource(dataSourceProp, schema);\n const { columns } = ds;\n const columnMap = buildColumnMap(ds.columns);\n\n const applyServerData = (data: VuuDataRow) => {\n if (columnMap) {\n const values: { [key: string]: VuuRowDataItemType } = {};\n for (const column of columns) {\n values[column] = data[columnMap[column]];\n }\n if (dataStatusRef.current === Status.uninitialised) {\n dataStatusRef.current = Status.unchanged;\n initialDataRef.current = values;\n }\n setValues(values);\n }\n };\n\n ds.subscribe({ range: { from: 0, to: 5 } }, (message) => {\n if (message.type === \"viewport-update\" && message.rows) {\n if (dataStatusRef.current === Status.uninitialised) {\n applyServerData(message.rows[0]);\n } else {\n console.log(\"what do we do with server updates\");\n }\n }\n });\n return ds;\n }, [dataSourceProp, schema]);\n\n const id = useIdMemo(idProp);\n\n const handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type);\n setValues((values = {}) => {\n const newValues = {\n ...values,\n [field]: typedValue,\n };\n const notUpdated = shallowEquals(newValues, initialDataRef.current);\n dataStatusRef.current = notUpdated\n ? Status.unchanged\n : typedValue !== undefined\n ? Status.changed\n : Status.invalid;\n return newValues;\n });\n },\n [fields]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const rowKey = values?.[keyField];\n // TODO link this with client side validation if we're going to use it\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type, true);\n if (typeof rowKey === \"string\") {\n dataSource\n .menuRpcCall({\n rowKey,\n field: field,\n value: typedValue,\n type: \"VP_EDIT_CELL_RPC\",\n })\n .then((response) => {\n if (response?.type === \"VP_EDIT_RPC_REJECT\") {\n console.log(`edit rejected ${response.error}`);\n setFieldStatusValues((map) => ({\n ...map,\n [field]: response.error,\n }));\n } else {\n setFieldStatusValues((map) => ({\n ...map,\n [field]: undefined,\n }));\n }\n });\n }\n },\n [dataSource, fields, keyField, values]\n );\n\n const applyAction = useCallback(\n (action: unknown) => {\n if (typeof action === \"object\" && action !== null) {\n if (\"type\" in action && action.type === \"CLOSE_DIALOG_ACTION\") {\n onClose?.();\n }\n }\n },\n [onClose]\n );\n\n const handleSubmit = useCallback(async () => {\n const response = await dataSource.menuRpcCall({\n type: \"VP_EDIT_SUBMIT_FORM_RPC\",\n });\n if (isErrorResponse(response)) {\n setErrorMessage(response.error);\n } else if (hasAction(response)) {\n applyAction(response.action);\n }\n }, [applyAction, dataSource]);\n\n const handleKeyDown = useCallback(\n (evt) => {\n if (evt.key === \"Enter\" && dataStatusRef.current === Status.changed) {\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const handleCancel = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const getFormControl = (field: FormFieldDescriptor) => {\n const value = String(values?.[field.name] ?? \"\");\n if (field.readonly || field.name === keyField) {\n return (\n <div className={`${classBase}-fieldValue vuuReadOnly`}>{value}</div>\n );\n } else {\n return (\n <Input\n className={`${classBase}-fieldValue`}\n onBlur={handleBlur}\n onChange={handleChange}\n value={value}\n id={`${id}-input-${field.name}`}\n />\n );\n }\n };\n\n useEffect(() => {\n if (formContentRef.current) {\n const firstInput = formContentRef.current.querySelector(\n \"input\"\n ) as HTMLInputElement;\n if (firstInput) {\n setTimeout(() => {\n firstInput.focus();\n firstInput.select();\n }, 100);\n }\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (dataSource) {\n dataSource.unsubscribe();\n }\n };\n }, [dataSource]);\n\n const isDirty = dataStatusRef.current === Status.changed;\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {errorMessage ? (\n <div\n className={`${classBase}-errorBanner`}\n data-icon=\"error\"\n title={errorMessage}\n >\n Error, edit(s) not saved\n </div>\n ) : undefined}\n <div\n className={`${classBase}-content`}\n ref={formContentRef}\n onKeyDown={handleKeyDown}\n >\n {fields.map((field) => (\n <FormField\n className={`${classBase}-field`}\n data-field={field.name}\n key={field.name}\n necessity={field.required ? \"required\" : \"optional\"}\n readOnly={field.readonly}\n validationStatus={\n fieldStatusValues[field.name] ? \"error\" : undefined\n }\n >\n <FormFieldLabel>{field?.label ?? field.description}</FormFieldLabel>\n {getFormControl(field)}\n <FormFieldHelperText>\n {fieldStatusValues[field.name] ?? \"\"}\n </FormFieldHelperText>\n </FormField>\n ))}\n </div>\n <div className={`${classBase}-buttonbar salt-theme salt-density-high`}>\n <Button\n type=\"submit\"\n variant=\"cta\"\n disabled={!isDirty}\n onClick={handleSubmit}\n >\n Submit\n </Button>\n <Button variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n"],"names":["values"],"mappings":"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"}
1
+ {"version":3,"file":"SessionEditingForm.js","sources":["../../src/session-editing-form/SessionEditingForm.tsx"],"sourcesContent":["import { VuuDataSource } from \"@vuu-ui/vuu-data-remote\";\nimport { DataSource, TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n hasAction,\n isErrorResponse,\n isValidNumber,\n queryClosest,\n shallowEquals,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n Button,\n FormField,\n FormFieldHelperText,\n FormFieldLabel,\n Input,\n useIdMemo,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport {\n ChangeEvent,\n ChangeEventHandler,\n FocusEvent,\n FocusEventHandler,\n HTMLAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport sessionEditingFormCss from \"./SessionEditingForm.css\";\n\nexport type FormFieldDescriptor = {\n isKeyField?: boolean;\n label?: string;\n name: string;\n type: VuuColumnDataType;\n description: string;\n readonly?: boolean;\n required?: boolean;\n};\n\nexport type FormConfig = {\n title: string;\n key: string;\n fields: FormFieldDescriptor[];\n};\n\nexport interface SessionEditingFormProps\n extends HTMLAttributes<HTMLDivElement> {\n config: FormConfig;\n onClose?: () => void;\n dataSource?: DataSource;\n schema?: TableSchema;\n}\n\nconst classBase = \"vuuSessionEditingForm\";\n\nconst getField = (\n fields: FormFieldDescriptor[],\n name: string\n): FormFieldDescriptor => {\n const field = fields.find((f) => f.name === name);\n if (field) {\n return field;\n } else {\n throw Error(`SessionEditingForm, no field '${name}' found`);\n }\n};\n\nconst getFieldNameAndValue = ({\n target,\n}: ChangeEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>): [\n string,\n string\n] => {\n const formField = queryClosest(target, \".saltFormField\");\n if (formField) {\n const {\n dataset: { field },\n } = formField;\n if (field === undefined) {\n throw Error(\"SessionEditingForm, form field has no field data attribute\");\n }\n return [field, target.value];\n } else {\n throw Error(\"Form control is not enclosed in FormField\");\n }\n};\n\nconst Status = {\n uninitialised: 0,\n unchanged: 1,\n changed: 2,\n invalid: 3,\n};\n\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined?: false\n): VuuRowDataItemType | undefined;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined: true\n): VuuRowDataItemType;\nfunction getTypedValue(\n value: string,\n type: VuuColumnDataType,\n throwIfUndefined = false\n): VuuRowDataItemType | undefined {\n switch (type) {\n case \"int\":\n case \"long\": {\n const typedValue = parseInt(value, 10);\n if (isValidNumber(typedValue)) {\n return typedValue;\n } else if (throwIfUndefined) {\n throw Error(\"SessionEditingForm getTypedValue\");\n } else {\n return undefined;\n }\n }\n\n case \"double\": {\n const typedValue = parseFloat(value);\n if (isValidNumber(typedValue)) {\n return typedValue;\n }\n return undefined;\n }\n\n case \"boolean\":\n return value === \"true\" ? true : false;\n default:\n return value;\n }\n}\n\nconst getDataSource = (\n dataSource?: DataSource,\n schema?: TableSchema\n): DataSource => {\n if (dataSource) {\n return dataSource;\n } else if (schema) {\n return new VuuDataSource({\n bufferSize: 0,\n table: schema.table,\n columns: schema.columns.map((col) => col.name),\n }) as DataSource;\n } else {\n throw Error(\n \"SessionEditingForm: either a DataSource or a TableSchema must be provided\"\n );\n }\n};\n\ntype FormValues = { [key: string]: VuuRowDataItemType | undefined };\n\nexport const SessionEditingForm = ({\n className,\n config: { fields, key: keyField },\n dataSource: dataSourceProp,\n id: idProp,\n onClose,\n schema,\n ...htmlAttributes\n}: SessionEditingFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-session-editing-form\",\n css: sessionEditingFormCss,\n window: targetWindow,\n });\n\n const [fieldStatusValues, setFieldStatusValues] = useState<\n Record<string, string | undefined>\n >({});\n const [values, setValues] = useState<FormValues>();\n const [errorMessage, setErrorMessage] = useState(\"\");\n const formContentRef = useRef<HTMLDivElement>(null);\n const initialDataRef = useRef<FormValues>();\n const dataStatusRef = useRef(Status.uninitialised);\n\n const dataSource = useMemo(() => {\n const ds = getDataSource(dataSourceProp, schema);\n const { columns } = ds;\n const columnMap = buildColumnMap(ds.columns);\n\n const applyServerData = (data: VuuDataRow) => {\n if (columnMap) {\n const values: { [key: string]: VuuRowDataItemType } = {};\n for (const column of columns) {\n values[column] = data[columnMap[column]];\n }\n if (dataStatusRef.current === Status.uninitialised) {\n dataStatusRef.current = Status.unchanged;\n initialDataRef.current = values;\n }\n setValues(values);\n }\n };\n\n ds.subscribe({ range: { from: 0, to: 5 } }, (message) => {\n if (message.type === \"viewport-update\" && message.rows) {\n if (dataStatusRef.current === Status.uninitialised) {\n applyServerData(message.rows[0]);\n } else {\n console.log(\"what do we do with server updates\");\n }\n }\n });\n return ds;\n }, [dataSourceProp, schema]);\n\n const id = useIdMemo(idProp);\n\n const handleChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type);\n setValues((values = {}) => {\n const newValues = {\n ...values,\n [field]: typedValue,\n };\n const notUpdated = shallowEquals(newValues, initialDataRef.current);\n dataStatusRef.current = notUpdated\n ? Status.unchanged\n : typedValue !== undefined\n ? Status.changed\n : Status.invalid;\n return newValues;\n });\n },\n [fields]\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLInputElement>>(\n (evt) => {\n const [field, value] = getFieldNameAndValue(evt);\n const rowKey = values?.[keyField];\n // TODO link this with client side validation if we're going to use it\n const { type } = getField(fields, field);\n const typedValue = getTypedValue(value, type, true);\n if (typeof rowKey === \"string\") {\n dataSource\n .menuRpcCall({\n rowKey,\n field: field,\n value: typedValue,\n type: \"VP_EDIT_CELL_RPC\",\n })\n .then((response) => {\n if (isErrorResponse(response)) {\n console.log(`edit rejected ${response.error}`);\n setFieldStatusValues((map) => ({\n ...map,\n [field]: response.error,\n }));\n } else {\n setFieldStatusValues((map) => ({\n ...map,\n [field]: undefined,\n }));\n }\n });\n }\n },\n [dataSource, fields, keyField, values]\n );\n\n const applyAction = useCallback(\n (action: unknown) => {\n if (typeof action === \"object\" && action !== null) {\n if (\"type\" in action && action.type === \"CLOSE_DIALOG_ACTION\") {\n onClose?.();\n }\n }\n },\n [onClose]\n );\n\n const handleSubmit = useCallback(async () => {\n const response = await dataSource.menuRpcCall({\n type: \"VP_EDIT_SUBMIT_FORM_RPC\",\n });\n if (isErrorResponse(response)) {\n setErrorMessage(response.error);\n } else if (hasAction(response)) {\n applyAction(response.action);\n }\n }, [applyAction, dataSource]);\n\n const handleKeyDown = useCallback(\n (evt) => {\n if (evt.key === \"Enter\" && dataStatusRef.current === Status.changed) {\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const handleCancel = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const getFormControl = (field: FormFieldDescriptor) => {\n const value = String(values?.[field.name] ?? \"\");\n if (field.readonly || field.name === keyField) {\n return (\n <div className={`${classBase}-fieldValue vuuReadOnly`}>{value}</div>\n );\n } else {\n return (\n <Input\n className={`${classBase}-fieldValue`}\n onBlur={handleBlur}\n onChange={handleChange}\n value={value}\n id={`${id}-input-${field.name}`}\n />\n );\n }\n };\n\n useEffect(() => {\n if (formContentRef.current) {\n const firstInput = formContentRef.current.querySelector(\n \"input\"\n ) as HTMLInputElement;\n if (firstInput) {\n setTimeout(() => {\n firstInput.focus();\n firstInput.select();\n }, 100);\n }\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (dataSource) {\n dataSource.unsubscribe();\n }\n };\n }, [dataSource]);\n\n const isDirty = dataStatusRef.current === Status.changed;\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n {errorMessage ? (\n <div\n className={`${classBase}-errorBanner`}\n data-icon=\"error\"\n title={errorMessage}\n >\n Error, edit(s) not saved\n </div>\n ) : undefined}\n <div\n className={`${classBase}-content`}\n ref={formContentRef}\n onKeyDown={handleKeyDown}\n >\n {fields.map((field) => (\n <FormField\n className={`${classBase}-field`}\n data-field={field.name}\n key={field.name}\n necessity={field.required ? \"required\" : \"optional\"}\n readOnly={field.readonly}\n validationStatus={\n fieldStatusValues[field.name] ? \"error\" : undefined\n }\n >\n <FormFieldLabel>{field?.label ?? field.description}</FormFieldLabel>\n {getFormControl(field)}\n <FormFieldHelperText>\n {fieldStatusValues[field.name] ?? \"\"}\n </FormFieldHelperText>\n </FormField>\n ))}\n </div>\n <div className={`${classBase}-buttonbar salt-theme salt-density-high`}>\n <Button\n type=\"submit\"\n variant=\"cta\"\n disabled={!isDirty}\n onClick={handleSubmit}\n >\n Submit\n </Button>\n <Button variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n </div>\n </div>\n );\n};\n"],"names":["values"],"mappings":"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"}
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
- "version": "0.8.73",
2
+ "version": "0.8.74",
3
3
  "description": "VUU UI Shell",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "0.8.73",
8
- "@vuu-ui/vuu-protocol-types": "0.8.73",
9
- "@vuu-ui/vuu-table-types": "0.8.73"
7
+ "@vuu-ui/vuu-data-types": "0.8.74",
8
+ "@vuu-ui/vuu-protocol-types": "0.8.74",
9
+ "@vuu-ui/vuu-table-types": "0.8.74"
10
10
  },
11
11
  "dependencies": {
12
12
  "@salt-ds/core": "1.27.1",
13
13
  "@salt-ds/styles": "0.2.1",
14
14
  "@salt-ds/window": "0.1.1",
15
- "@vuu-ui/vuu-data-remote": "0.8.73",
16
- "@vuu-ui/vuu-icons": "0.8.73",
17
- "@vuu-ui/vuu-layout": "0.8.73",
18
- "@vuu-ui/vuu-popups": "0.8.73",
19
- "@vuu-ui/vuu-table": "0.8.73",
20
- "@vuu-ui/vuu-ui-controls": "0.8.73",
21
- "@vuu-ui/vuu-utils": "0.8.73",
15
+ "@vuu-ui/vuu-data-remote": "0.8.74",
16
+ "@vuu-ui/vuu-icons": "0.8.74",
17
+ "@vuu-ui/vuu-layout": "0.8.74",
18
+ "@vuu-ui/vuu-popups": "0.8.74",
19
+ "@vuu-ui/vuu-table": "0.8.74",
20
+ "@vuu-ui/vuu-ui-controls": "0.8.74",
21
+ "@vuu-ui/vuu-utils": "0.8.74",
22
22
  "html-to-image": "^1.11.11"
23
23
  },
24
24
  "peerDependencies": {
@@ -0,0 +1,21 @@
1
+ import { ServerAPI } from "@vuu-ui/vuu-data-remote";
2
+ import { DataSource, DataSourceConstructorProps } from "@vuu-ui/vuu-data-types";
3
+ import { ReactNode } from "react";
4
+ export type DataSourceConstructor = {
5
+ new (props: DataSourceConstructorProps): DataSource;
6
+ };
7
+ export interface DataSourceContextProps {
8
+ isLocalData: boolean;
9
+ VuuDataSource: DataSourceConstructor;
10
+ vuuModuleName?: string;
11
+ getServerAPI: () => Promise<Pick<ServerAPI, "getTableList" | "getTableSchema">>;
12
+ }
13
+ /**
14
+ * If a client is adding a DataSOurceProvider, it will ususlly be
15
+ * to install local test data, so we default isLocalData to true
16
+ */
17
+ export declare const DataSourceProvider: ({ children, getServerAPI, isLocalData, VuuDataSource, vuuModuleName, }: Omit<DataSourceContextProps, "isLocalData"> & {
18
+ children: ReactNode;
19
+ isLocalData?: boolean | undefined;
20
+ }) => JSX.Element;
21
+ export declare const useDataSource: () => DataSourceContextProps;
@@ -0,0 +1 @@
1
+ export * from "./DataSourceProvider";
package/types/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./app-header";
2
2
  export * from "./connection-status";
3
+ export * from "./datasource-provider";
3
4
  export * from "./feature";
4
5
  export * from "./layout-management";
5
6
  export * from "./left-nav";