@vuu-ui/vuu-data-react 0.8.91 → 0.8.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/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 +97 -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 +36 -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 +54 -0
  16. package/cjs/data-editing/get-data-item-edit-control.js.map +1 -0
  17. package/cjs/data-editing/useEditForm.js +244 -0
  18. package/cjs/data-editing/useEditForm.js.map +1 -0
  19. package/cjs/hooks/useVuuMenuActions.js +1 -1
  20. package/cjs/hooks/useVuuMenuActions.js.map +1 -1
  21. package/cjs/index.js +10 -2
  22. package/cjs/index.js.map +1 -1
  23. package/esm/data-editing/EditForm.css.js +4 -0
  24. package/esm/data-editing/EditForm.css.js.map +1 -0
  25. package/esm/data-editing/EditForm.js +95 -0
  26. package/esm/data-editing/EditForm.js.map +1 -0
  27. package/esm/data-editing/UnsavedChangesReport.css.js +4 -0
  28. package/esm/data-editing/UnsavedChangesReport.css.js.map +1 -0
  29. package/esm/data-editing/UnsavedChangesReport.js +27 -0
  30. package/esm/data-editing/UnsavedChangesReport.js.map +1 -0
  31. package/esm/data-editing/edit-rule-validation-checker.js +32 -0
  32. package/esm/data-editing/edit-rule-validation-checker.js.map +1 -0
  33. package/esm/data-editing/edit-validation-rules.js +50 -0
  34. package/esm/data-editing/edit-validation-rules.js.map +1 -0
  35. package/esm/data-editing/form-edit-state.js +23 -0
  36. package/esm/data-editing/form-edit-state.js.map +1 -0
  37. package/esm/data-editing/get-data-item-edit-control.js +52 -0
  38. package/esm/data-editing/get-data-item-edit-control.js.map +1 -0
  39. package/esm/data-editing/useEditForm.js +242 -0
  40. package/esm/data-editing/useEditForm.js.map +1 -0
  41. package/esm/hooks/useVuuMenuActions.js +1 -1
  42. package/esm/hooks/useVuuMenuActions.js.map +1 -1
  43. package/esm/index.js +4 -1
  44. package/esm/index.js.map +1 -1
  45. package/package.json +13 -13
  46. package/types/data-editing/EditForm.d.ts +8 -0
  47. package/types/data-editing/UnsavedChangesReport.d.ts +7 -0
  48. package/types/data-editing/edit-rule-validation-checker.d.ts +4 -0
  49. package/types/data-editing/edit-validation-rules.d.ts +1 -0
  50. package/types/data-editing/form-edit-state.d.ts +7 -0
  51. package/types/data-editing/get-data-item-edit-control.d.ts +17 -0
  52. package/types/data-editing/index.d.ts +4 -1
  53. package/types/data-editing/useEditForm.d.ts +17 -0
  54. package/cjs/data-editing/date-editing-utils.js +0 -31
  55. package/cjs/data-editing/date-editing-utils.js.map +0 -1
  56. package/esm/data-editing/date-editing-utils.js +0 -29
  57. package/esm/data-editing/date-editing-utils.js.map +0 -1
  58. package/types/data-editing/date-editing-utils.d.ts +0 -13
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEditForm.js","sources":["../../src/data-editing/useEditForm.tsx"],"sourcesContent":["import { DataSource, DataValueDescriptor } from \"@vuu-ui/vuu-data-types\";\nimport { useDialogContext } from \"@vuu-ui/vuu-popups\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n Entity,\n buildColumnMap,\n dataSourceRowToEntity,\n messageHasDataRows,\n queryClosest,\n viewportRpcRequest,\n} from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport {\n FocusEventHandler,\n SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { EditFormProps } from \"./EditForm\";\nimport { UnsavedChangesReport } from \"./UnsavedChangesReport\";\nimport {\n buildValidationChecker,\n getEditValidationRules,\n} from \"./edit-rule-validation-checker\";\nimport {\n CLEAN_FORM,\n FormEditState,\n buildFormEditState,\n} from \"./form-edit-state\";\n\nexport type EditFormHookProps = Pick<\n EditFormProps,\n \"dataSource\" | \"formFieldDescriptors\" | \"onSubmit\"\n>;\n\ntype ValidationState = {\n ok: boolean;\n messages: Record<string, string>;\n};\n\nconst getValidationChecker = (\n descriptor: DataValueDescriptor,\n apply: \"change\" | \"commit\",\n) => {\n const rules = getEditValidationRules(descriptor, apply);\n return buildValidationChecker(rules);\n};\n\nconst nextValidationState = (\n state: ValidationState,\n dataDescriptor: DataValueDescriptor,\n value: VuuRowDataItemType,\n): ValidationState => {\n const check = getValidationChecker(dataDescriptor, \"change\");\n const result = check(value);\n const { name } = dataDescriptor;\n\n const { ok: wasOk, messages: existingMessages } = state;\n\n if (result.ok) {\n if (!wasOk) {\n // if this field was the only one in error, the overall state\n // will now be ok, but not if there is still one or more other\n // field still in error.\n const fieldsInError = Object.keys(existingMessages);\n if (fieldsInError.includes(name)) {\n if (fieldsInError.length === 1) {\n return { ok: true, messages: {} };\n } else {\n const messages = { ...existingMessages };\n delete messages[name];\n return { ok: false, messages };\n }\n }\n }\n } else {\n return {\n ok: false,\n messages: {\n ...existingMessages,\n [name]: result.messages.join(\"\\n\"),\n },\n };\n }\n\n return state;\n};\n\nfunction find(descriptors: DataValueDescriptor[], fieldname: string) {\n const d = descriptors.find(({ name }) => name === fieldname);\n if (d) {\n return d;\n }\n throw Error(`DataValueDescriptor not found for field ${fieldname}`);\n}\n\nconst getField = (target: EventTarget | HTMLElement) => {\n const fieldElement = queryClosest(target, \"[data-field]\");\n if (fieldElement) {\n return fieldElement.dataset.field as string;\n } else {\n throw Error(\"no field \");\n }\n};\n\ntype Resolver = (value: unknown) => void;\n\nexport const useEditForm = ({\n dataSource,\n formFieldDescriptors,\n onSubmit,\n}: EditFormHookProps) => {\n const { showDialog, closeDialog } = useDialogContext();\n\n const currentDataSource = useRef<DataSource>();\n const formFieldsContainerRef = useRef<HTMLDivElement>(null);\n const entityRef = useRef<Entity>();\n const focusedFieldRef = useRef(\"\");\n const originalEntityRef = useRef<Entity>();\n const formEditStateRef = useRef<FormEditState>(CLEAN_FORM);\n const validationStateRef = useRef<ValidationState>({\n ok: true,\n messages: {},\n });\n\n const [entity, _setEntity] = useState<Entity>();\n const [, forceUpdate] = useState({});\n\n const setFormEditState = useCallback((newState: FormEditState) => {\n formEditStateRef.current = newState;\n }, []);\n\n const setEntity = useCallback(\n (newEntity: Entity) => {\n setFormEditState(\n buildFormEditState(originalEntityRef.current, newEntity),\n );\n entityRef.current = newEntity;\n _setEntity(newEntity);\n },\n [setFormEditState],\n );\n\n const submitChanges = useCallback(async () => {\n const rpcResponse = await currentDataSource.current?.rpcCall?.(\n viewportRpcRequest(\"VP_BULK_EDIT_SUBMIT_RPC\"),\n );\n console.log({ rpcResponse });\n }, []);\n\n const showSaveOrDiscardPrompt = useCallback(async () => {\n const { current: currentEntity } = entityRef;\n const { current: originalEntity } = originalEntityRef;\n let resolver: Resolver | undefined = undefined;\n const save = async () => {\n await submitChanges();\n closeDialog();\n resolver?.(\"saved\");\n };\n\n const discard = () => {\n closeDialog();\n resolver?.(\"discarded\");\n };\n\n requestAnimationFrame(() => {\n showDialog(\n <UnsavedChangesReport\n entity={originalEntity as Entity}\n editedEntity={currentEntity as Entity}\n />,\n \"Unsaved Changes\",\n [\n <Button key=\"cancel\" onClick={discard}>\n Discard Changes\n </Button>,\n <Button key=\"submit\" onClick={save}>\n Save Changes\n </Button>,\n ],\n true, // hideCloseButton\n );\n });\n\n return new Promise((resolve) => {\n resolver = resolve;\n });\n }, [closeDialog, showDialog, submitChanges]);\n\n useMemo(async () => {\n if (dataSource) {\n if (formEditStateRef.current.isClean === false) {\n await showSaveOrDiscardPrompt();\n }\n\n currentDataSource.current = dataSource;\n\n originalEntityRef.current = undefined;\n\n const columnMap = buildColumnMap(dataSource.columns);\n\n dataSource?.subscribe({ range: { from: 0, to: 1 } }, (message) => {\n if (messageHasDataRows(message)) {\n const [row] = message.rows;\n if (row) {\n const entity = dataSourceRowToEntity(row, columnMap);\n if (originalEntityRef.current === undefined) {\n originalEntityRef.current = entity;\n setEntity(entity);\n }\n\n const { editedFields } = buildFormEditState(\n entityRef.current,\n entity,\n );\n\n // for controls which do not yield incremental changes, e.g dropdown, calendar\n // we apply the server update to our entity.\n if (editedFields.length === 1) {\n setEntity(entity);\n }\n\n // Do not overwrite entity here, just check that values returned by server\n // match whats expected\n }\n }\n });\n }\n }, [dataSource, setEntity, showSaveOrDiscardPrompt]);\n\n const setValidationState = useCallback((state: ValidationState) => {\n validationStateRef.current = state;\n forceUpdate({});\n }, []);\n\n const handleFieldCommit = useCallback(\n (evt, value) => {\n const { current: fieldName } = focusedFieldRef;\n const dataDescriptor = find(formFieldDescriptors, fieldName);\n\n const { current: state } = validationStateRef;\n const newState = nextValidationState(state, dataDescriptor, value);\n if (newState !== state) {\n setValidationState(newState);\n }\n\n if (newState.ok && dataSource?.tableSchema) {\n const { key } = dataSource.tableSchema;\n const keyValue = entity?.[key] as string;\n dataSource\n ?.applyEdit(keyValue, fieldName, value)\n .then((rpcResponse) => {\n console.log({ rpcResponse });\n });\n }\n },\n [dataSource, entity, formFieldDescriptors, setValidationState],\n );\n\n const handleFieldChange = useCallback(\n (evt: SyntheticEvent<HTMLInputElement>) => {\n const { current: fieldName } = focusedFieldRef;\n if (fieldName) {\n const input = queryClosest<HTMLInputElement>(evt.target, \"input\", true);\n const dataDescriptor = find(formFieldDescriptors, fieldName);\n const value = input.value as string;\n const { current: state } = validationStateRef;\n const newState = nextValidationState(state, dataDescriptor, value);\n if (newState !== state) {\n setValidationState(newState);\n }\n\n setEntity({ ...entity, [fieldName]: value });\n }\n },\n [entity, formFieldDescriptors, setEntity, setValidationState],\n );\n\n const handleFormSubmit = useCallback(async () => {\n submitChanges();\n setFormEditState(CLEAN_FORM);\n originalEntityRef.current = entity;\n onSubmit?.();\n forceUpdate({});\n }, [entity, onSubmit, setFormEditState, submitChanges]);\n\n const handleFormCancel = useCallback(async () => {\n // const rpcResponse = await dataSource?.rpcCall?.(\n // viewportRpcRequest(\"VP_BULK_EDIT_CANCEL_RPC\"),\n // );\n setFormEditState(CLEAN_FORM);\n // console.log({ rpcResponse });\n setEntity(originalEntityRef.current as Entity);\n }, [setEntity, setFormEditState]);\n\n const handleFocus = useCallback<FocusEventHandler>((evt) => {\n // Ignore focus on popup Calendars, Lists etc\n if (formFieldsContainerRef.current?.contains(evt.target)) {\n const fieldName = getField(evt.target);\n if (fieldName) {\n if (fieldName) {\n focusedFieldRef.current = fieldName;\n }\n }\n }\n }, []);\n\n const {\n current: { ok, messages: errorMessages },\n } = validationStateRef;\n\n const {\n current: { isClean, editedFields },\n } = formEditStateRef;\n\n return {\n editedFields,\n editEntity: entity,\n errorMessages,\n formFieldsContainerRef,\n isClean,\n ok,\n onCancel: handleFormCancel,\n onChange: handleFieldChange,\n onCommit: handleFieldCommit,\n onFocus: handleFocus,\n onSubmit: handleFormSubmit,\n };\n};\n"],"names":["getEditValidationRules","buildValidationChecker","queryClosest","useDialogContext","useRef","CLEAN_FORM","useState","useCallback","buildFormEditState","viewportRpcRequest","jsx","UnsavedChangesReport","Button","useMemo","buildColumnMap","messageHasDataRows","entity","dataSourceRowToEntity","editedFields"],"mappings":"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"}
@@ -110,7 +110,7 @@ const useVuuMenuActions = ({
110
110
  return true;
111
111
  }
112
112
  },
113
- [VuuDataSource, closeDialog, showDialog]
113
+ [VuuDataSource, closeDialog, dataSource, showDialog]
114
114
  );
115
115
  const showSessionEditingForm = react.useCallback(
116
116
  (action) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useVuuMenuActions.js","sources":["../../src/hooks/useVuuMenuActions.tsx"],"sourcesContent":["import {\n ContextMenuItemDescriptor,\n DataSource,\n DataSourceVisualLinkCreatedMessage,\n MenuActionHandler,\n MenuBuilder,\n RpcResponseHandler,\n TableSchema,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n useDialogContext,\n useNotifications,\n type MenuActionClosePopup,\n} from \"@vuu-ui/vuu-popups\";\nimport type {\n LinkDescriptorWithLabel,\n OpenDialogAction,\n VuuMenu,\n VuuMenuItem,\n VuuRpcResponse,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { BulkEditPanel } from \"@vuu-ui/vuu-table\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n VuuServerMenuOptions,\n buildMenuDescriptorFromVuuMenu,\n getMenuRpcRequest,\n hasShowNotificationAction,\n isActionMessage,\n isGroupMenuItemDescriptor,\n isOpenBulkEditResponse,\n isRoot,\n isSessionTableActionMessage,\n isTableLocation,\n useDataSource,\n viewportRpcRequest,\n} from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useCallback } from \"react\";\nimport {\n FormConfig,\n FormFieldDescriptor,\n SessionEditingForm,\n} from \"../session-editing-form\";\n\nconst NO_CONFIG: MenuActionConfig = {};\n\nexport type VuuMenuActionHandler = (type: string, options: unknown) => boolean;\n\nexport interface ViewServerHookResult {\n buildViewserverMenuOptions: MenuBuilder;\n handleMenuAction: MenuActionHandler;\n}\n\nexport interface MenuActionConfig {\n vuuMenu?: VuuMenu;\n visualLink?: DataSourceVisualLinkCreatedMessage;\n visualLinks?: LinkDescriptorWithLabel[];\n}\n\nexport interface VuuMenuActionHookProps {\n /**\n * By default, vuuMenuActions will be handled automatically. When activated, a\n * message will be sent to server and response will be handled here too.\n * This prop allows client to provide a custom handler for a menu Item. This will\n * take priority and if handler returns true, no further processing for the menu\n * item will be handled by Vuu. This can also be used to prevent an item from being\n * actioned, even when no custom handling is intended. If the handler returns false,\n * Vuu will process the menuItem.\n */\n clientSideMenuActionHandler?: VuuMenuActionHandler;\n dataSource: DataSource;\n menuActionConfig?: MenuActionConfig;\n onRpcResponse?: RpcResponseHandler;\n}\n\nconst keyFirst = (c1: FormFieldDescriptor, c2: FormFieldDescriptor) =>\n c1.isKeyField ? -1 : c2.isKeyField ? 1 : 0;\n\nconst defaultFormConfig = {\n fields: [],\n key: \"\",\n title: \"\",\n};\n\nconst configFromSchema = (schema?: TableSchema): FormConfig | undefined => {\n if (schema) {\n const { columns, key } = schema;\n return {\n key,\n title: `Parameters for command`,\n fields: columns\n .map((col) => ({\n description: col.name,\n label: col.name,\n name: col.name,\n type: col.serverDataType,\n isKeyField: col.name === key,\n }))\n .sort(keyFirst),\n };\n }\n};\n\nconst getFormConfig = (\n action: OpenDialogAction & { tableSchema: TableSchema },\n) => {\n const { tableSchema: schema } = action;\n const config = configFromSchema(schema) ?? defaultFormConfig;\n\n return {\n config,\n schema,\n };\n};\n\nexport const useVuuMenuActions = ({\n clientSideMenuActionHandler,\n dataSource,\n menuActionConfig = NO_CONFIG,\n onRpcResponse,\n}: VuuMenuActionHookProps): ViewServerHookResult => {\n const { VuuDataSource } = useDataSource();\n const buildViewserverMenuOptions: MenuBuilder = useCallback(\n (location, options) => {\n const { links, menu } = dataSource;\n const { visualLink } = menuActionConfig;\n const descriptors: ContextMenuItemDescriptor[] = [];\n\n if (location === \"grid\" && links && !visualLink) {\n links.forEach((linkDescriptor: LinkDescriptorWithLabel) => {\n const { link, label: linkLabel } = linkDescriptor;\n const label = linkLabel ? linkLabel : link.toTable;\n descriptors.push({\n label: `Link to ${label}`,\n action: \"link-table\",\n options: linkDescriptor,\n });\n });\n }\n\n if (menu && isTableLocation(location)) {\n const menuDescriptor = buildMenuDescriptorFromVuuMenu(\n menu,\n location,\n options as VuuServerMenuOptions,\n );\n if (isRoot(menu) && isGroupMenuItemDescriptor(menuDescriptor)) {\n descriptors.push(...menuDescriptor.children);\n } else if (menuDescriptor) {\n descriptors.push(menuDescriptor);\n }\n }\n\n return descriptors;\n },\n [dataSource, menuActionConfig],\n );\n\n const { showDialog, closeDialog } = useDialogContext();\n const showNotification = useNotifications();\n\n const showBulkEditDialog = useCallback(\n (table: VuuTable, columns?: ColumnDescriptor[]) => {\n // NO send BULK_EDIT_BEGIN\n const sessionDs = new VuuDataSource({\n table,\n viewport: table.table,\n });\n const handleSubmit = () => {\n sessionDs?.rpcCall?.(viewportRpcRequest(\"VP_BULK_EDIT_SUBMIT_RPC\"));\n closeDialog();\n };\n\n if (sessionDs) {\n showDialog(\n <BulkEditPanel\n columns={columns}\n dataSource={sessionDs}\n onSubmit={handleSubmit}\n parentDs={dataSource}\n />,\n \"Bulk Amend\",\n [\n <Button key=\"cancel\" onClick={closeDialog}>\n Cancel\n </Button>,\n <Button key=\"submit\" onClick={handleSubmit}>\n Save\n </Button>,\n ],\n );\n\n return true;\n }\n },\n [VuuDataSource, closeDialog, showDialog],\n );\n\n const showSessionEditingForm = useCallback(\n (action: OpenDialogAction & { tableSchema: TableSchema }) => {\n const { tableSchema } = action;\n if (tableSchema) {\n const formConfig = getFormConfig(action);\n showDialog(\n <SessionEditingForm {...formConfig} onClose={closeDialog} />,\n \"Set Parameters\",\n );\n }\n\n const sessionDs = dataSource.createSessionDataSource?.(action.table);\n const handleSubmit = () => {\n sessionDs?.rpcCall?.(viewportRpcRequest(\"VP_BULK_EDIT_SUBMIT_RPC\"));\n closeDialog();\n };\n\n if (sessionDs) {\n showDialog(\n <BulkEditPanel\n dataSource={sessionDs}\n onSubmit={handleSubmit}\n parentDs={dataSource}\n />,\n \"Multi Row Edit\",\n [\n <Button key=\"cancel\" onClick={closeDialog}>\n Cancel\n </Button>,\n <Button key=\"submit\" onClick={handleSubmit}>\n Save\n </Button>,\n ],\n );\n\n return true;\n }\n },\n [closeDialog, dataSource, showDialog],\n );\n\n const handleMenuAction = useCallback(\n ({ menuId, options }: MenuActionClosePopup) => {\n if (clientSideMenuActionHandler?.(menuId, options)) {\n return true;\n } else if (menuId === \"MENU_RPC_CALL\") {\n const rpcRequest = getMenuRpcRequest(options as unknown as VuuMenuItem);\n\n dataSource\n .menuRpcCall(rpcRequest)\n .then((rpcResponse: Omit<VuuRpcResponse, \"requestId\">) => {\n if (rpcResponse) {\n if (onRpcResponse?.(rpcResponse) === true) {\n return true;\n }\n if (isActionMessage(rpcResponse)) {\n if (hasShowNotificationAction(rpcResponse)) {\n const {\n action: { message, title = \"Success\" },\n } = rpcResponse;\n showNotification({\n type: \"success\",\n body: message,\n header: title,\n });\n } else if (isOpenBulkEditResponse(rpcResponse)) {\n showBulkEditDialog(rpcResponse.action.table, options.columns);\n } else if (isSessionTableActionMessage(rpcResponse)) {\n showSessionEditingForm(rpcResponse.action);\n }\n }\n }\n });\n return true;\n } else if (menuId === \"link-table\") {\n dataSource.visualLink = options as LinkDescriptorWithLabel;\n return true;\n } else {\n console.log(\n `useViewServer handleMenuAction, can't handle action type ${menuId}`,\n );\n }\n\n return false;\n },\n [\n clientSideMenuActionHandler,\n dataSource,\n onRpcResponse,\n showBulkEditDialog,\n showNotification,\n showSessionEditingForm,\n ],\n );\n\n return {\n buildViewserverMenuOptions,\n handleMenuAction,\n };\n};\n"],"names":["useDataSource","useCallback","isTableLocation","buildMenuDescriptorFromVuuMenu","isRoot","isGroupMenuItemDescriptor","useDialogContext","useNotifications","viewportRpcRequest","jsx","BulkEditPanel","Button","SessionEditingForm","getMenuRpcRequest","isActionMessage","hasShowNotificationAction","isOpenBulkEditResponse","isSessionTableActionMessage"],"mappings":"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"}
1
+ {"version":3,"file":"useVuuMenuActions.js","sources":["../../src/hooks/useVuuMenuActions.tsx"],"sourcesContent":["import {\n ContextMenuItemDescriptor,\n DataSource,\n DataSourceVisualLinkCreatedMessage,\n MenuActionHandler,\n MenuBuilder,\n RpcResponseHandler,\n TableSchema,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n useDialogContext,\n useNotifications,\n type MenuActionClosePopup,\n} from \"@vuu-ui/vuu-popups\";\nimport type {\n LinkDescriptorWithLabel,\n OpenDialogAction,\n VuuMenu,\n VuuMenuItem,\n VuuRpcResponse,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { BulkEditPanel } from \"@vuu-ui/vuu-table\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n VuuServerMenuOptions,\n buildMenuDescriptorFromVuuMenu,\n getMenuRpcRequest,\n hasShowNotificationAction,\n isActionMessage,\n isGroupMenuItemDescriptor,\n isOpenBulkEditResponse,\n isRoot,\n isSessionTableActionMessage,\n isTableLocation,\n useDataSource,\n viewportRpcRequest,\n} from \"@vuu-ui/vuu-utils\";\nimport { Button } from \"@salt-ds/core\";\nimport { useCallback } from \"react\";\nimport {\n FormConfig,\n FormFieldDescriptor,\n SessionEditingForm,\n} from \"../session-editing-form\";\n\nconst NO_CONFIG: MenuActionConfig = {};\n\nexport type VuuMenuActionHandler = (type: string, options: unknown) => boolean;\n\nexport interface ViewServerHookResult {\n buildViewserverMenuOptions: MenuBuilder;\n handleMenuAction: MenuActionHandler;\n}\n\nexport interface MenuActionConfig {\n vuuMenu?: VuuMenu;\n visualLink?: DataSourceVisualLinkCreatedMessage;\n visualLinks?: LinkDescriptorWithLabel[];\n}\n\nexport interface VuuMenuActionHookProps {\n /**\n * By default, vuuMenuActions will be handled automatically. When activated, a\n * message will be sent to server and response will be handled here too.\n * This prop allows client to provide a custom handler for a menu Item. This will\n * take priority and if handler returns true, no further processing for the menu\n * item will be handled by Vuu. This can also be used to prevent an item from being\n * actioned, even when no custom handling is intended. If the handler returns false,\n * Vuu will process the menuItem.\n */\n clientSideMenuActionHandler?: VuuMenuActionHandler;\n dataSource: DataSource;\n menuActionConfig?: MenuActionConfig;\n onRpcResponse?: RpcResponseHandler;\n}\n\nconst keyFirst = (c1: FormFieldDescriptor, c2: FormFieldDescriptor) =>\n c1.isKeyField ? -1 : c2.isKeyField ? 1 : 0;\n\nconst defaultFormConfig = {\n fields: [],\n key: \"\",\n title: \"\",\n};\n\nconst configFromSchema = (schema?: TableSchema): FormConfig | undefined => {\n if (schema) {\n const { columns, key } = schema;\n return {\n key,\n title: `Parameters for command`,\n fields: columns\n .map((col) => ({\n description: col.name,\n label: col.name,\n name: col.name,\n type: col.serverDataType,\n isKeyField: col.name === key,\n }))\n .sort(keyFirst),\n };\n }\n};\n\nconst getFormConfig = (\n action: OpenDialogAction & { tableSchema: TableSchema },\n) => {\n const { tableSchema: schema } = action;\n const config = configFromSchema(schema) ?? defaultFormConfig;\n\n return {\n config,\n schema,\n };\n};\n\nexport const useVuuMenuActions = ({\n clientSideMenuActionHandler,\n dataSource,\n menuActionConfig = NO_CONFIG,\n onRpcResponse,\n}: VuuMenuActionHookProps): ViewServerHookResult => {\n const { VuuDataSource } = useDataSource();\n const buildViewserverMenuOptions: MenuBuilder = useCallback(\n (location, options) => {\n const { links, menu } = dataSource;\n const { visualLink } = menuActionConfig;\n const descriptors: ContextMenuItemDescriptor[] = [];\n\n if (location === \"grid\" && links && !visualLink) {\n links.forEach((linkDescriptor: LinkDescriptorWithLabel) => {\n const { link, label: linkLabel } = linkDescriptor;\n const label = linkLabel ? linkLabel : link.toTable;\n descriptors.push({\n label: `Link to ${label}`,\n action: \"link-table\",\n options: linkDescriptor,\n });\n });\n }\n\n if (menu && isTableLocation(location)) {\n const menuDescriptor = buildMenuDescriptorFromVuuMenu(\n menu,\n location,\n options as VuuServerMenuOptions,\n );\n if (isRoot(menu) && isGroupMenuItemDescriptor(menuDescriptor)) {\n descriptors.push(...menuDescriptor.children);\n } else if (menuDescriptor) {\n descriptors.push(menuDescriptor);\n }\n }\n\n return descriptors;\n },\n [dataSource, menuActionConfig],\n );\n\n const { showDialog, closeDialog } = useDialogContext();\n const showNotification = useNotifications();\n\n const showBulkEditDialog = useCallback(\n (table: VuuTable, columns?: ColumnDescriptor[]) => {\n // NO send BULK_EDIT_BEGIN\n const sessionDs = new VuuDataSource({\n table,\n viewport: table.table,\n });\n const handleSubmit = () => {\n sessionDs?.rpcCall?.(viewportRpcRequest(\"VP_BULK_EDIT_SUBMIT_RPC\"));\n closeDialog();\n };\n\n if (sessionDs) {\n showDialog(\n <BulkEditPanel\n columns={columns}\n dataSource={sessionDs}\n onSubmit={handleSubmit}\n parentDs={dataSource}\n />,\n \"Bulk Amend\",\n [\n <Button key=\"cancel\" onClick={closeDialog}>\n Cancel\n </Button>,\n <Button key=\"submit\" onClick={handleSubmit}>\n Save\n </Button>,\n ],\n );\n\n return true;\n }\n },\n [VuuDataSource, closeDialog, dataSource, showDialog],\n );\n\n const showSessionEditingForm = useCallback(\n (action: OpenDialogAction & { tableSchema: TableSchema }) => {\n const { tableSchema } = action;\n if (tableSchema) {\n const formConfig = getFormConfig(action);\n showDialog(\n <SessionEditingForm {...formConfig} onClose={closeDialog} />,\n \"Set Parameters\",\n );\n }\n\n const sessionDs = dataSource.createSessionDataSource?.(action.table);\n const handleSubmit = () => {\n sessionDs?.rpcCall?.(viewportRpcRequest(\"VP_BULK_EDIT_SUBMIT_RPC\"));\n closeDialog();\n };\n\n if (sessionDs) {\n showDialog(\n <BulkEditPanel\n dataSource={sessionDs}\n onSubmit={handleSubmit}\n parentDs={dataSource}\n />,\n \"Multi Row Edit\",\n [\n <Button key=\"cancel\" onClick={closeDialog}>\n Cancel\n </Button>,\n <Button key=\"submit\" onClick={handleSubmit}>\n Save\n </Button>,\n ],\n );\n\n return true;\n }\n },\n [closeDialog, dataSource, showDialog],\n );\n\n const handleMenuAction = useCallback(\n ({ menuId, options }: MenuActionClosePopup) => {\n if (clientSideMenuActionHandler?.(menuId, options)) {\n return true;\n } else if (menuId === \"MENU_RPC_CALL\") {\n const rpcRequest = getMenuRpcRequest(options as unknown as VuuMenuItem);\n\n dataSource\n .menuRpcCall(rpcRequest)\n .then((rpcResponse: Omit<VuuRpcResponse, \"requestId\">) => {\n if (rpcResponse) {\n if (onRpcResponse?.(rpcResponse) === true) {\n return true;\n }\n if (isActionMessage(rpcResponse)) {\n if (hasShowNotificationAction(rpcResponse)) {\n const {\n action: { message, title = \"Success\" },\n } = rpcResponse;\n showNotification({\n type: \"success\",\n body: message,\n header: title,\n });\n } else if (isOpenBulkEditResponse(rpcResponse)) {\n showBulkEditDialog(rpcResponse.action.table, options.columns);\n } else if (isSessionTableActionMessage(rpcResponse)) {\n showSessionEditingForm(rpcResponse.action);\n }\n }\n }\n });\n return true;\n } else if (menuId === \"link-table\") {\n dataSource.visualLink = options as LinkDescriptorWithLabel;\n return true;\n } else {\n console.log(\n `useViewServer handleMenuAction, can't handle action type ${menuId}`,\n );\n }\n\n return false;\n },\n [\n clientSideMenuActionHandler,\n dataSource,\n onRpcResponse,\n showBulkEditDialog,\n showNotification,\n showSessionEditingForm,\n ],\n );\n\n return {\n buildViewserverMenuOptions,\n handleMenuAction,\n };\n};\n"],"names":["useDataSource","useCallback","isTableLocation","buildMenuDescriptorFromVuuMenu","isRoot","isGroupMenuItemDescriptor","useDialogContext","useNotifications","viewportRpcRequest","jsx","BulkEditPanel","Button","SessionEditingForm","getMenuRpcRequest","isActionMessage","hasShowNotificationAction","isOpenBulkEditResponse","isSessionTableActionMessage"],"mappings":"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"}
package/cjs/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var dateEditingUtils = require('./data-editing/date-editing-utils.js');
3
+ var getDataItemEditControl = require('./data-editing/get-data-item-edit-control.js');
4
+ var EditForm = require('./data-editing/EditForm.js');
5
+ var editRuleValidationChecker = require('./data-editing/edit-rule-validation-checker.js');
6
+ var UnsavedChangesReport = require('./data-editing/UnsavedChangesReport.js');
4
7
  var VuuDataSourceProvider = require('./datasource-provider/VuuDataSourceProvider.js');
5
8
  var useLookupValues = require('./hooks/useLookupValues.js');
6
9
  var useVuuMenuActions = require('./hooks/useVuuMenuActions.js');
@@ -13,7 +16,12 @@ var SessionEditingForm = require('./session-editing-form/SessionEditingForm.js')
13
16
 
14
17
 
15
18
 
16
- exports.getDataItemEditControl = dateEditingUtils.getDataItemEditControl;
19
+ exports.getDataItemEditControl = getDataItemEditControl.getDataItemEditControl;
20
+ exports.EditForm = EditForm.EditForm;
21
+ exports.OK = editRuleValidationChecker.OK;
22
+ exports.buildValidationChecker = editRuleValidationChecker.buildValidationChecker;
23
+ exports.getEditValidationRules = editRuleValidationChecker.getEditValidationRules;
24
+ exports.UnsavedChangesReport = UnsavedChangesReport.UnsavedChangesReport;
17
25
  exports.VuuDataSourceProvider = VuuDataSourceProvider.VuuDataSourceProvider;
18
26
  exports.useLookupValues = useLookupValues.useLookupValues;
19
27
  exports.useVuuMenuActions = useVuuMenuActions.useVuuMenuActions;
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,4 @@
1
+ var editFormCss = ".EditForm {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-400);\n height: 100%;\n padding: var(--salt-spacing-200) var(--salt-spacing-200)\n var(--salt-spacing-200) var(--salt-spacing-400);\n width: 100%;\n}\n\n.EditForm-form-fields {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-400);\n}\n\n.EditForm-buttons {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-200);\n justify-content: flex-end;\n}\n\n.EditForm-field {\n display: flex;\n\n .saltFormField {\n flex: 1 1 auto;\n }\n\n .EditForm-edit-indicator {\n flex: 0 0 14px;\n position: relative;\n }\n\n &[data-edited=\"true\"] {\n .EditForm-edit-indicator:after {\n background-color: var(--salt-content-secondary-foreground);\n border-radius: 5px;\n content: \"\";\n height: 10px;\n position: absolute;\n top: 50%;\n right: -3px;\n width: 10px;\n }\n }\n}\n";
2
+
3
+ export { editFormCss as default };
4
+ //# sourceMappingURL=EditForm.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditForm.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,95 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { getDataItemEditControl } from './get-data-item-edit-control.js';
3
+ import '@vuu-ui/vuu-utils';
4
+ import { useComponentCssInjection } from '@salt-ds/styles';
5
+ import { useWindow } from '@salt-ds/window';
6
+ import '@vuu-ui/vuu-data-remote';
7
+ import 'react';
8
+ import '@vuu-ui/vuu-popups';
9
+ import '@vuu-ui/vuu-table';
10
+ import { FormField, FormFieldLabel, Button } from '@salt-ds/core';
11
+ import cx from 'clsx';
12
+ import '@vuu-ui/vuu-layout';
13
+ import '@vuu-ui/vuu-ui-controls';
14
+ import { registerRules } from './edit-validation-rules.js';
15
+ import { useEditForm } from './useEditForm.js';
16
+ import editFormCss from './EditForm.css.js';
17
+
18
+ const classBase = "EditForm";
19
+ registerRules();
20
+ const EditForm = ({
21
+ className,
22
+ dataSource,
23
+ formFieldDescriptors,
24
+ onSubmit: onSubmitProp,
25
+ ...htmlAttributes
26
+ }) => {
27
+ const targetWindow = useWindow();
28
+ useComponentCssInjection({
29
+ testId: "vuu-edit-form",
30
+ css: editFormCss,
31
+ window: targetWindow
32
+ });
33
+ const {
34
+ editedFields,
35
+ editEntity,
36
+ errorMessages,
37
+ formFieldsContainerRef,
38
+ isClean,
39
+ ok,
40
+ onCancel,
41
+ onChange,
42
+ onCommit,
43
+ onFocus,
44
+ onSubmit
45
+ } = useEditForm({
46
+ dataSource,
47
+ formFieldDescriptors,
48
+ onSubmit: onSubmitProp
49
+ });
50
+ return /* @__PURE__ */ jsxs(
51
+ "div",
52
+ {
53
+ ...htmlAttributes,
54
+ className: cx(classBase, className),
55
+ onFocus,
56
+ children: [
57
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-form-fields`, ref: formFieldsContainerRef, children: formFieldDescriptors.map((dataDescriptor) => {
58
+ const { name, label = name } = dataDescriptor;
59
+ const errorMessage = errorMessages[name];
60
+ const isEdited = !isClean && editedFields.includes(name);
61
+ return /* @__PURE__ */ jsxs(
62
+ "div",
63
+ {
64
+ className: `${classBase}-field`,
65
+ "data-edited": isEdited,
66
+ children: [
67
+ /* @__PURE__ */ jsxs(FormField, { "data-field": name, children: [
68
+ /* @__PURE__ */ jsx(FormFieldLabel, { children: label }),
69
+ getDataItemEditControl({
70
+ InputProps: {
71
+ onChange,
72
+ value: editEntity?.[name]?.toString() ?? ""
73
+ },
74
+ dataDescriptor,
75
+ errorMessage,
76
+ onCommit
77
+ })
78
+ ] }),
79
+ /* @__PURE__ */ jsx("div", { className: `${classBase}-edit-indicator` })
80
+ ]
81
+ },
82
+ name
83
+ );
84
+ }) }),
85
+ /* @__PURE__ */ jsxs("div", { className: `${classBase}-buttons`, children: [
86
+ /* @__PURE__ */ jsx(Button, { disabled: isClean, onClick: onCancel, children: "Cancel" }),
87
+ /* @__PURE__ */ jsx(Button, { onClick: onSubmit, disabled: !ok || isClean, children: "Save" })
88
+ ] })
89
+ ]
90
+ }
91
+ );
92
+ };
93
+
94
+ export { EditForm };
95
+ //# sourceMappingURL=EditForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditForm.js","sources":["../../src/data-editing/EditForm.tsx"],"sourcesContent":["import { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { DataSource, DataValueDescriptor } from \"@vuu-ui/vuu-data-types\";\nimport { Button, FormField, FormFieldLabel } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes } from \"react\";\nimport { registerRules } from \"./edit-validation-rules\";\nimport { useEditForm } from \"./useEditForm\";\n\nimport editFormCss from \"./EditForm.css\";\n\nconst classBase = \"EditForm\";\n\nregisterRules();\n\nexport interface EditFormProps extends HTMLAttributes<HTMLDivElement> {\n dataSource?: DataSource;\n formFieldDescriptors: DataValueDescriptor[];\n onSubmit?: () => void;\n}\n\nexport const EditForm = ({\n className,\n dataSource,\n formFieldDescriptors,\n onSubmit: onSubmitProp,\n ...htmlAttributes\n}: EditFormProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-edit-form\",\n css: editFormCss,\n window: targetWindow,\n });\n\n const {\n editedFields,\n editEntity,\n errorMessages,\n formFieldsContainerRef,\n isClean,\n ok,\n onCancel,\n onChange,\n onCommit,\n onFocus,\n onSubmit,\n } = useEditForm({\n dataSource,\n formFieldDescriptors,\n onSubmit: onSubmitProp,\n });\n\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className)}\n onFocus={onFocus}\n >\n <div className={`${classBase}-form-fields`} ref={formFieldsContainerRef}>\n {formFieldDescriptors.map((dataDescriptor) => {\n const { name, label = name } = dataDescriptor;\n const errorMessage = errorMessages[name];\n const isEdited = !isClean && editedFields.includes(name);\n\n return (\n <div\n className={`${classBase}-field`}\n key={name}\n data-edited={isEdited}\n >\n <FormField data-field={name}>\n <FormFieldLabel>{label}</FormFieldLabel>\n {getDataItemEditControl({\n InputProps: {\n onChange,\n value: editEntity?.[name]?.toString() ?? \"\",\n },\n dataDescriptor,\n errorMessage,\n onCommit,\n })}\n </FormField>\n <div className={`${classBase}-edit-indicator`} />\n </div>\n );\n })}\n </div>\n <div className={`${classBase}-buttons`}>\n <Button disabled={isClean} onClick={onCancel}>\n Cancel\n </Button>\n <Button onClick={onSubmit} disabled={!ok || isClean}>\n Save\n </Button>\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ var unsavedChangesCss = ".vuuUnsavedChanges-table {\n border-collapse: collapse;\n width: 100%;\n}\n\n.vuuUnsavedChanges-row {\n box-sizing: content-box;\n border-bottom: solid 1px var(--salt-separable-secondary-borderColor);\n height: 32px;\n\n td {\n padding: 0 var(--salt-spacing-200);\n }\n}\n\n.vuuUnsavedChanges-fieldName {\n text-transform: capitalize;\n}\n\n.vuuUnsavedChanges-new {\n font-weight: bold;\n}\n";
2
+
3
+ export { unsavedChangesCss as default };
4
+ //# sourceMappingURL=UnsavedChangesReport.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnsavedChangesReport.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,27 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useComponentCssInjection } from '@salt-ds/styles';
3
+ import { useWindow } from '@salt-ds/window';
4
+ import { buildFormEditState } from './form-edit-state.js';
5
+ import unsavedChangesCss from './UnsavedChangesReport.css.js';
6
+
7
+ const classBase = "vuuUnsavedChanges";
8
+ const UnsavedChangesReport = ({
9
+ entity,
10
+ editedEntity
11
+ }) => {
12
+ const targetWindow = useWindow();
13
+ useComponentCssInjection({
14
+ testId: "vuu-unsaved-changes-report",
15
+ css: unsavedChangesCss,
16
+ window: targetWindow
17
+ });
18
+ const { editedFields } = buildFormEditState(entity, editedEntity);
19
+ return /* @__PURE__ */ jsx("div", { className: classBase, children: /* @__PURE__ */ jsx("table", { className: `${classBase}-table`, children: /* @__PURE__ */ jsx("tbody", { children: editedFields.map((fieldName, i) => /* @__PURE__ */ jsxs("tr", { className: `${classBase}-row`, children: [
20
+ /* @__PURE__ */ jsx("td", { className: `${classBase}-fieldName`, children: fieldName }),
21
+ /* @__PURE__ */ jsx("td", { className: `${classBase}-old`, children: entity[fieldName] }),
22
+ /* @__PURE__ */ jsx("td", { className: `${classBase}-new`, children: editedEntity[fieldName] })
23
+ ] }, i)) }) }) });
24
+ };
25
+
26
+ export { UnsavedChangesReport };
27
+ //# sourceMappingURL=UnsavedChangesReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UnsavedChangesReport.js","sources":["../../src/data-editing/UnsavedChangesReport.tsx"],"sourcesContent":["import { Entity } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { buildFormEditState } from \"./form-edit-state\";\n\nimport unsavedChangesCss from \"./UnsavedChangesReport.css\";\n\nconst classBase = \"vuuUnsavedChanges\";\n\nexport interface UnsavedChangesReportProps<T extends Entity = Entity> {\n entity: T;\n editedEntity: T;\n}\n\nexport const UnsavedChangesReport = ({\n entity,\n editedEntity,\n}: UnsavedChangesReportProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-unsaved-changes-report\",\n css: unsavedChangesCss,\n window: targetWindow,\n });\n\n const { editedFields } = buildFormEditState(entity, editedEntity);\n\n return (\n <div className={classBase}>\n <table className={`${classBase}-table`}>\n <tbody>\n {editedFields.map((fieldName, i) => (\n <tr className={`${classBase}-row`} key={i}>\n <td className={`${classBase}-fieldName`}>{fieldName}</td>\n <td className={`${classBase}-old`}>{entity[fieldName]}</td>\n <td className={`${classBase}-new`}>{editedEntity[fieldName]}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;AAOA,MAAM,SAAY,GAAA,mBAAA,CAAA;AAOX,MAAM,uBAAuB,CAAC;AAAA,EACnC,MAAA;AAAA,EACA,YAAA;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,4BAAA;AAAA,IACR,GAAK,EAAA,iBAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAA,MAAM,EAAE,YAAA,EAAiB,GAAA,kBAAA,CAAmB,QAAQ,YAAY,CAAA,CAAA;AAEhE,EACE,uBAAA,GAAA,CAAC,SAAI,SAAW,EAAA,SAAA,EACd,8BAAC,OAAM,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CAC5B,MAAA,CAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,WACE,QAAa,EAAA,YAAA,CAAA,GAAA,CAAI,CAAC,SAAW,EAAA,CAAA,0BAC3B,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,CACzB,IAAA,CAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAG,EAAA,EAAA,SAAA,EAAW,CAAG,EAAA,SAAS,cAAe,QAAU,EAAA,SAAA,EAAA,CAAA;AAAA,oBACpD,GAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,MAAA,CAAO,SAAS,CAAE,EAAA,CAAA;AAAA,oBACtD,GAAA,CAAC,QAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAS,IAAA,CAAA,EAAA,QAAA,EAAA,YAAA,CAAa,SAAS,CAAE,EAAA,CAAA;AAAA,GAAA,EAAA,EAHtB,CAIxC,CACD,CACH,EAAA,CAAA,EACF,CACF,EAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,32 @@
1
+ import { isTypeDescriptor, getEditRuleValidator } from '@vuu-ui/vuu-utils';
2
+
3
+ const OK = { ok: true };
4
+ const NO_VALIDATION_RULES = [];
5
+ function getEditValidationRules(descriptor, apply) {
6
+ if (isTypeDescriptor(descriptor.type)) {
7
+ return descriptor.type.rules?.filter(({ apply: a = "commit" }) => a === apply) ?? NO_VALIDATION_RULES;
8
+ }
9
+ return NO_VALIDATION_RULES;
10
+ }
11
+ const buildValidationChecker = (rules) => (value) => applyRules(rules, value);
12
+ function applyRules(rules, value) {
13
+ const result = { ok: true };
14
+ for (const rule of rules) {
15
+ const applyRuleToValue = getEditRuleValidator(rule.name);
16
+ if (applyRuleToValue) {
17
+ const res = applyRuleToValue(rule, value);
18
+ if (!res.ok) {
19
+ result.ok = false;
20
+ (result.messages ?? (result.messages = [])).push(res.message);
21
+ }
22
+ } else {
23
+ throw Error(
24
+ `editable-utils applyRules, no validator registered for rule '${rule.name}'`
25
+ );
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+
31
+ export { OK, buildValidationChecker, getEditValidationRules };
32
+ //# sourceMappingURL=edit-rule-validation-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-rule-validation-checker.js","sources":["../../src/data-editing/edit-rule-validation-checker.ts"],"sourcesContent":["import type {\n DataValueDescriptor,\n DataValueValidationChecker,\n DataValueValidationResult,\n EditRuleValidationSuccessResult,\n EditValidationRule,\n} from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { getEditRuleValidator, isTypeDescriptor } from \"@vuu-ui/vuu-utils\";\n\nexport const OK: EditRuleValidationSuccessResult = { ok: true };\n\nconst NO_VALIDATION_RULES: EditValidationRule[] = [] as const;\n\nexport function getEditValidationRules(\n descriptor: DataValueDescriptor,\n apply: \"change\" | \"commit\",\n) {\n if (isTypeDescriptor(descriptor.type)) {\n return (\n descriptor.type.rules?.filter(({ apply: a = \"commit\" }) => a === apply) ??\n NO_VALIDATION_RULES\n );\n }\n\n return NO_VALIDATION_RULES;\n}\n\nexport const buildValidationChecker =\n (rules: EditValidationRule[]): DataValueValidationChecker =>\n (value?: VuuRowDataItemType) =>\n applyRules(rules, value);\n\nfunction applyRules(rules: EditValidationRule[], value?: VuuRowDataItemType) {\n const result: { ok: boolean; messages?: string[] } = { ok: true };\n for (const rule of rules) {\n const applyRuleToValue = getEditRuleValidator(rule.name);\n if (applyRuleToValue) {\n const res = applyRuleToValue(rule, value);\n if (!res.ok) {\n result.ok = false;\n (result.messages ?? (result.messages = [])).push(res.message);\n }\n } else {\n throw Error(\n `editable-utils applyRules, no validator registered for rule '${rule.name}'`,\n );\n }\n }\n return result as DataValueValidationResult;\n}\n"],"names":[],"mappings":";;AAUa,MAAA,EAAA,GAAsC,EAAE,EAAA,EAAI,IAAK,GAAA;AAE9D,MAAM,sBAA4C,EAAC,CAAA;AAEnC,SAAA,sBAAA,CACd,YACA,KACA,EAAA;AACA,EAAI,IAAA,gBAAA,CAAiB,UAAW,CAAA,IAAI,CAAG,EAAA;AACrC,IAAA,OACE,UAAW,CAAA,IAAA,CAAK,KAAO,EAAA,MAAA,CAAO,CAAC,EAAE,KAAO,EAAA,CAAA,GAAI,QAAS,EAAA,KAAM,CAAM,KAAA,KAAK,CACtE,IAAA,mBAAA,CAAA;AAAA,GAEJ;AAEA,EAAO,OAAA,mBAAA,CAAA;AACT,CAAA;AAEO,MAAM,yBACX,CAAC,KAAA,KACD,CAAC,KACC,KAAA,UAAA,CAAW,OAAO,KAAK,EAAA;AAE3B,SAAS,UAAA,CAAW,OAA6B,KAA4B,EAAA;AAC3E,EAAM,MAAA,MAAA,GAA+C,EAAE,EAAA,EAAI,IAAK,EAAA,CAAA;AAChE,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAM,MAAA,gBAAA,GAAmB,oBAAqB,CAAA,IAAA,CAAK,IAAI,CAAA,CAAA;AACvD,IAAA,IAAI,gBAAkB,EAAA;AACpB,MAAM,MAAA,GAAA,GAAM,gBAAiB,CAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AACxC,MAAI,IAAA,CAAC,IAAI,EAAI,EAAA;AACX,QAAA,MAAA,CAAO,EAAK,GAAA,KAAA,CAAA;AACZ,QAAC,CAAA,MAAA,CAAO,aAAa,MAAO,CAAA,QAAA,GAAW,EAAK,CAAA,EAAA,IAAA,CAAK,IAAI,OAAO,CAAA,CAAA;AAAA,OAC9D;AAAA,KACK,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,CAAA,6DAAA,EAAgE,KAAK,IAAI,CAAA,CAAA,CAAA;AAAA,OAC3E,CAAA;AAAA,KACF;AAAA,GACF;AACA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,50 @@
1
+ import { registerComponent } from '@vuu-ui/vuu-utils';
2
+ import { OK } from './edit-rule-validation-checker.js';
3
+
4
+ const isString = (value) => typeof value === "string";
5
+ const NUMERIC = /^(?:[0-9]|\.)+$/;
6
+ const CharValidatorNumeric = (rule, value) => {
7
+ if (isString(value)) {
8
+ if (value.trim() === "") {
9
+ return OK;
10
+ } else if (value.match(NUMERIC)) {
11
+ return OK;
12
+ }
13
+ }
14
+ return { ok: false, message: "only numeric characters are permitted" };
15
+ };
16
+ const ValueValidatorInteger = (rule, value) => {
17
+ if (isString(value)) {
18
+ if (value.trim() === "") {
19
+ return OK;
20
+ } else {
21
+ if (!value.match(NUMERIC)) {
22
+ return {
23
+ ok: false,
24
+ message: "value must be an integer, invalid character"
25
+ };
26
+ }
27
+ if (parseFloat(value) === parseInt(value)) {
28
+ return OK;
29
+ }
30
+ }
31
+ }
32
+ return { ok: false, message: "must be an integer value" };
33
+ };
34
+ const registerRules = () => {
35
+ registerComponent(
36
+ "char-numeric",
37
+ CharValidatorNumeric,
38
+ "data-edit-validator",
39
+ {}
40
+ );
41
+ registerComponent(
42
+ "value-integer",
43
+ ValueValidatorInteger,
44
+ "data-edit-validator",
45
+ {}
46
+ );
47
+ };
48
+
49
+ export { registerRules };
50
+ //# sourceMappingURL=edit-validation-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-validation-rules.js","sources":["../../src/data-editing/edit-validation-rules.ts"],"sourcesContent":["import { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { EditRuleValidator } from \"@vuu-ui/vuu-data-types\";\nimport { OK } from \"./edit-rule-validation-checker\";\n\nconst isString = (value?: VuuRowDataItemType): value is string =>\n typeof value === \"string\";\n\nconst NUMERIC = /^(?:[0-9]|\\.)+$/;\n\nconst CharValidatorNumeric: EditRuleValidator = (rule, value) => {\n if (isString(value)) {\n if (value.trim() === \"\") {\n return OK;\n } else if (value.match(NUMERIC)) {\n return OK;\n }\n }\n return { ok: false, message: \"only numeric characters are permitted\" };\n};\n\nconst ValueValidatorInteger: EditRuleValidator = (rule, value) => {\n if (isString(value)) {\n if (value.trim() === \"\") {\n return OK;\n } else {\n if (!value.match(NUMERIC)) {\n return {\n ok: false,\n message: \"value must be an integer, invalid character\",\n };\n }\n if (parseFloat(value) === parseInt(value)) {\n return OK;\n }\n }\n }\n return { ok: false, message: \"must be an integer value\" };\n};\n\nexport const registerRules = () => {\n registerComponent(\n \"char-numeric\",\n CharValidatorNumeric,\n \"data-edit-validator\",\n {},\n );\n registerComponent(\n \"value-integer\",\n ValueValidatorInteger,\n \"data-edit-validator\",\n {},\n );\n};\n"],"names":[],"mappings":";;;AAKA,MAAM,QAAW,GAAA,CAAC,KAChB,KAAA,OAAO,KAAU,KAAA,QAAA,CAAA;AAEnB,MAAM,OAAU,GAAA,iBAAA,CAAA;AAEhB,MAAM,oBAAA,GAA0C,CAAC,IAAA,EAAM,KAAU,KAAA;AAC/D,EAAI,IAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACnB,IAAI,IAAA,KAAA,CAAM,IAAK,EAAA,KAAM,EAAI,EAAA;AACvB,MAAO,OAAA,EAAA,CAAA;AAAA,KACE,MAAA,IAAA,KAAA,CAAM,KAAM,CAAA,OAAO,CAAG,EAAA;AAC/B,MAAO,OAAA,EAAA,CAAA;AAAA,KACT;AAAA,GACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,uCAAwC,EAAA,CAAA;AACvE,CAAA,CAAA;AAEA,MAAM,qBAAA,GAA2C,CAAC,IAAA,EAAM,KAAU,KAAA;AAChE,EAAI,IAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACnB,IAAI,IAAA,KAAA,CAAM,IAAK,EAAA,KAAM,EAAI,EAAA;AACvB,MAAO,OAAA,EAAA,CAAA;AAAA,KACF,MAAA;AACL,MAAA,IAAI,CAAC,KAAA,CAAM,KAAM,CAAA,OAAO,CAAG,EAAA;AACzB,QAAO,OAAA;AAAA,UACL,EAAI,EAAA,KAAA;AAAA,UACJ,OAAS,EAAA,6CAAA;AAAA,SACX,CAAA;AAAA,OACF;AACA,MAAA,IAAI,UAAW,CAAA,KAAK,CAAM,KAAA,QAAA,CAAS,KAAK,CAAG,EAAA;AACzC,QAAO,OAAA,EAAA,CAAA;AAAA,OACT;AAAA,KACF;AAAA,GACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAO,EAAA,OAAA,EAAS,0BAA2B,EAAA,CAAA;AAC1D,CAAA,CAAA;AAEO,MAAM,gBAAgB,MAAM;AACjC,EAAA,iBAAA;AAAA,IACE,cAAA;AAAA,IACA,oBAAA;AAAA,IACA,qBAAA;AAAA,IACA,EAAC;AAAA,GACH,CAAA;AACA,EAAA,iBAAA;AAAA,IACE,eAAA;AAAA,IACA,qBAAA;AAAA,IACA,qBAAA;AAAA,IACA,EAAC;AAAA,GACH,CAAA;AACF;;;;"}
@@ -0,0 +1,23 @@
1
+ const CLEAN_FORM = {
2
+ isClean: true,
3
+ editedFields: []
4
+ };
5
+ const buildFormEditState = (entity, newEntity) => {
6
+ if (entity === void 0) {
7
+ return CLEAN_FORM;
8
+ } else {
9
+ const editedFields = [];
10
+ for (const [fieldName, value] of Object.entries(entity)) {
11
+ if (value !== newEntity[fieldName]) {
12
+ editedFields.push(fieldName);
13
+ }
14
+ }
15
+ return {
16
+ isClean: editedFields.length === 0,
17
+ editedFields
18
+ };
19
+ }
20
+ };
21
+
22
+ export { CLEAN_FORM, buildFormEditState };
23
+ //# sourceMappingURL=form-edit-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-edit-state.js","sources":["../../src/data-editing/form-edit-state.ts"],"sourcesContent":["import { Entity } from \"@vuu-ui/vuu-utils\";\n\nexport type FormEditState = {\n isClean: boolean;\n editedFields: string[];\n};\n\nexport const CLEAN_FORM: FormEditState = {\n isClean: true,\n editedFields: [],\n};\n\nexport const buildFormEditState = (\n entity: Entity | undefined,\n newEntity: Entity,\n): FormEditState => {\n if (entity === undefined) {\n return CLEAN_FORM;\n } else {\n const editedFields: string[] = [];\n for (const [fieldName, value] of Object.entries(entity)) {\n if (value !== newEntity[fieldName]) {\n editedFields.push(fieldName);\n }\n }\n\n return {\n isClean: editedFields.length === 0,\n editedFields,\n };\n }\n};\n"],"names":[],"mappings":"AAOO,MAAM,UAA4B,GAAA;AAAA,EACvC,OAAS,EAAA,IAAA;AAAA,EACT,cAAc,EAAC;AACjB,EAAA;AAEa,MAAA,kBAAA,GAAqB,CAChC,MAAA,EACA,SACkB,KAAA;AAClB,EAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,IAAO,OAAA,UAAA,CAAA;AAAA,GACF,MAAA;AACL,IAAA,MAAM,eAAyB,EAAC,CAAA;AAChC,IAAA,KAAA,MAAW,CAAC,SAAW,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,MAAM,CAAG,EAAA;AACvD,MAAI,IAAA,KAAA,KAAU,SAAU,CAAA,SAAS,CAAG,EAAA;AAClC,QAAA,YAAA,CAAa,KAAK,SAAS,CAAA,CAAA;AAAA,OAC7B;AAAA,KACF;AAEA,IAAO,OAAA;AAAA,MACL,OAAA,EAAS,aAAa,MAAW,KAAA,CAAA;AAAA,MACjC,YAAA;AAAA,KACF,CAAA;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,52 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { VuuInput, VuuDatePicker, VuuTypeaheadInput } from '@vuu-ui/vuu-ui-controls';
3
+ import { isDateTimeDataValue } from '@vuu-ui/vuu-utils';
4
+
5
+ const getDataItemEditControl = ({
6
+ InputProps: InputProps2,
7
+ dataDescriptor,
8
+ errorMessage,
9
+ onCommit,
10
+ suggestionProvider,
11
+ table
12
+ }) => {
13
+ const handleCommitNumber = (evt, value) => {
14
+ console.log(`value`);
15
+ onCommit(evt, value.toString());
16
+ };
17
+ if (dataDescriptor.editable === false) {
18
+ return /* @__PURE__ */ jsx(
19
+ VuuInput,
20
+ {
21
+ variant: "secondary",
22
+ ...InputProps2,
23
+ onCommit,
24
+ readOnly: true
25
+ }
26
+ );
27
+ } else if (isDateTimeDataValue(dataDescriptor)) {
28
+ return /* @__PURE__ */ jsx(VuuDatePicker, { onCommit: handleCommitNumber });
29
+ } else if (dataDescriptor.serverDataType === "string" && suggestionProvider && table) {
30
+ return /* @__PURE__ */ jsx(
31
+ VuuTypeaheadInput,
32
+ {
33
+ column: dataDescriptor.name,
34
+ onCommit,
35
+ suggestionProvider,
36
+ table
37
+ }
38
+ );
39
+ }
40
+ return /* @__PURE__ */ jsx(
41
+ VuuInput,
42
+ {
43
+ variant: "secondary",
44
+ ...InputProps2,
45
+ onCommit,
46
+ errorMessage
47
+ }
48
+ );
49
+ };
50
+
51
+ export { getDataItemEditControl };
52
+ //# sourceMappingURL=get-data-item-edit-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-data-item-edit-control.js","sources":["../../src/data-editing/get-data-item-edit-control.tsx"],"sourcesContent":["import {\n DataValueDescriptor,\n SuggestionProvider,\n TableSchemaTable,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuDatePicker,\n VuuInput,\n VuuTypeaheadInput,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport { CommitHandler, isDateTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { InputProps } from \"@salt-ds/core\";\n\nexport interface DataItemEditControlProps {\n InputProps?: Partial<InputProps>;\n /**\n * A table column or form field Descriptor.\n */\n dataDescriptor: DataValueDescriptor;\n errorMessage?: string;\n onCommit: CommitHandler<HTMLElement, string | undefined>;\n suggestionProvider?: SuggestionProvider;\n table?: TableSchemaTable;\n}\n\nexport type ValidationStatus = \"initial\" | true | string;\n\nexport const getDataItemEditControl = ({\n InputProps,\n dataDescriptor,\n errorMessage,\n onCommit,\n suggestionProvider,\n table,\n}: DataItemEditControlProps) => {\n const handleCommitNumber: CommitHandler<HTMLElement, number> = (\n evt,\n value,\n ) => {\n console.log(`value`);\n onCommit(evt, value.toString());\n };\n\n if (dataDescriptor.editable === false) {\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n onCommit={onCommit}\n readOnly\n />\n );\n } else if (isDateTimeDataValue(dataDescriptor)) {\n return <VuuDatePicker onCommit={handleCommitNumber} />;\n } else if (\n dataDescriptor.serverDataType === \"string\" &&\n suggestionProvider &&\n table\n ) {\n return (\n <VuuTypeaheadInput\n column={dataDescriptor.name}\n onCommit={onCommit}\n suggestionProvider={suggestionProvider}\n table={table}\n />\n );\n }\n return (\n <VuuInput\n variant=\"secondary\"\n {...InputProps}\n onCommit={onCommit}\n errorMessage={errorMessage}\n />\n );\n};\n"],"names":["InputProps"],"mappings":";;;;AA2BO,MAAM,yBAAyB,CAAC;AAAA,EACrC,UAAAA,EAAAA,WAAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,KAAA;AACF,CAAgC,KAAA;AAC9B,EAAM,MAAA,kBAAA,GAAyD,CAC7D,GAAA,EACA,KACG,KAAA;AACH,IAAA,OAAA,CAAQ,IAAI,CAAO,KAAA,CAAA,CAAA,CAAA;AACnB,IAAS,QAAA,CAAA,GAAA,EAAK,KAAM,CAAA,QAAA,EAAU,CAAA,CAAA;AAAA,GAChC,CAAA;AAEA,EAAI,IAAA,cAAA,CAAe,aAAa,KAAO,EAAA;AACrC,IACE,uBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAQ,EAAA,WAAA;AAAA,QACP,GAAGA,WAAAA;AAAA,QACJ,QAAA;AAAA,QACA,QAAQ,EAAA,IAAA;AAAA,OAAA;AAAA,KACV,CAAA;AAAA,GAEJ,MAAA,IAAW,mBAAoB,CAAA,cAAc,CAAG,EAAA;AAC9C,IAAO,uBAAA,GAAA,CAAC,aAAc,EAAA,EAAA,QAAA,EAAU,kBAAoB,EAAA,CAAA,CAAA;AAAA,GAEpD,MAAA,IAAA,cAAA,CAAe,cAAmB,KAAA,QAAA,IAClC,sBACA,KACA,EAAA;AACA,IACE,uBAAA,GAAA;AAAA,MAAC,iBAAA;AAAA,MAAA;AAAA,QACC,QAAQ,cAAe,CAAA,IAAA;AAAA,QACvB,QAAA;AAAA,QACA,kBAAA;AAAA,QACA,KAAA;AAAA,OAAA;AAAA,KACF,CAAA;AAAA,GAEJ;AACA,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACP,GAAGA,WAAAA;AAAA,MACJ,QAAA;AAAA,MACA,YAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ;;;;"}