@overmap-ai/core 1.0.58-export-overmap-reducer.0 → 1.0.58-export-overmap-reducer.3

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.
@@ -6,7 +6,7 @@ import { FieldOptions } from "./typings";
6
6
  import { FormikUserFormRevision } from "../../builder";
7
7
  export declare abstract class BaseFormElement<TIdentifier extends FieldTypeIdentifier = FieldTypeIdentifier> {
8
8
  readonly type: TIdentifier;
9
- protected readonly identifier: string;
9
+ readonly identifier: string;
10
10
  readonly description: string | null;
11
11
  protected constructor(options: BaseSerializedObject);
12
12
  getId(): string;
@@ -47,4 +47,6 @@ export declare abstract class BaseField<TValue extends FieldValue, TIdentifier e
47
47
  abstract serialize(): ISerializedOnlyField;
48
48
  getFieldValidators(): InputFieldLevelValidator<TValue>[];
49
49
  getFormValidators(): InputFormLevelValidator<TValue>[];
50
+ encodeValueToJson(value: TValue): string;
51
+ decodeJsonToValue(json: string): TValue;
50
52
  }
@@ -2,8 +2,8 @@ import { BaseField, ChildFieldOptions } from "../BaseField";
2
2
  import { GetInputProps, InputFieldLevelValidator } from "../typings";
3
3
  import { ChangeEvent, ReactNode } from "react";
4
4
  import { RiListCheck } from "react-icons/ri";
5
- import { ISerializedField, SelectFieldOption, SerializedMultiStringField } from "../../typings";
6
- type MultiStringFieldOptions = ChildFieldOptions<SelectFieldOption[]> & {
5
+ import { ISerializedField, SerializedMultiStringField } from "../../typings";
6
+ type MultiStringFieldOptions = ChildFieldOptions<string[]> & {
7
7
  minimum_length?: number;
8
8
  maximum_length?: number;
9
9
  placeholder?: string;
@@ -21,7 +21,7 @@ export declare const emptyMultiStringField: {
21
21
  * - Specifying the options of a SelectField (used in `SelectField.getFieldCreationSchema`
22
22
  * - Listing serial numbers and similar
23
23
  */
24
- export declare class MultiStringField extends BaseField<SelectFieldOption[], "multi-string"> {
24
+ export declare class MultiStringField extends BaseField<string[], "multi-string"> {
25
25
  static readonly fieldTypeName = "Multi-string";
26
26
  static readonly fieldTypeDescription = "Allows the user to provide multiple unique strings.";
27
27
  readonly minLength: number;
@@ -30,11 +30,11 @@ export declare class MultiStringField extends BaseField<SelectFieldOption[], "mu
30
30
  readonly placeholder: string;
31
31
  static Icon: typeof RiListCheck;
32
32
  constructor(options: MultiStringFieldOptions);
33
- getValueFromChangeEvent(event: ChangeEvent<HTMLInputElement> | SelectFieldOption[]): SelectFieldOption[];
33
+ getValueFromChangeEvent(event: ChangeEvent<HTMLInputElement> | string[]): string[];
34
34
  getInput(props: GetInputProps<this>): ReactNode;
35
35
  serialize(): SerializedMultiStringField;
36
- protected isBlank(value: SelectFieldOption[]): boolean;
37
- getFieldValidators(): InputFieldLevelValidator<SelectFieldOption[]>[];
36
+ protected isBlank(value: string[]): boolean;
37
+ getFieldValidators(): InputFieldLevelValidator<string[]>[];
38
38
  static deserialize(data: ISerializedField): MultiStringField;
39
39
  }
40
40
  export {};
@@ -23,5 +23,5 @@ export interface ComponentProps<TField extends BaseFormElement> extends Omit<HTM
23
23
  showInputOnly?: boolean;
24
24
  }
25
25
  export type GetInputProps<TField extends BaseFormElement> = Omit<ComponentProps<TField>, "field">;
26
- export type AnyField = BaseField<any>;
26
+ export type AnyField = BaseField<any, any>;
27
27
  export type ISerializedOnlyField = Exclude<ISerializedField, SerializedFieldSection>;
@@ -10,5 +10,8 @@ export declare const deserializeField: (serializedField: ISerializedOnlyField) =
10
10
  export declare const deserialize: (serialized: ISerializedField) => AnyField | FieldSection;
11
11
  export type PartialFormRevision = Pick<UserFormRevision, "title" | "fields" | "description"> & Partial<UserFormRevision>;
12
12
  export declare function formRevisionToSchema(formRevision: PartialFormRevision, meta?: Partial<SchemaMeta>): ISchema;
13
+ export declare function flattenFields(schema: ISchema): AnyField[];
14
+ export declare function decodeFormValues(schema: ISchema, values: Record<string, string>): Record<string, FieldValue>;
15
+ export declare function encodeFormValues(schema: ISchema, values: Record<string, FieldValue>): Record<string, string>;
13
16
  export declare function valueIsFile(v: FieldValue | Promise<File>[] | undefined): v is File[] | Promise<File>[];
14
17
  export declare function isConditionMet<TValue extends FieldValue | Promise<File>[]>(condition: TValue extends FieldValue ? SerializedCondition<TValue> | null : null, value: TValue): boolean;
@@ -2,3 +2,4 @@ export * from "./typings";
2
2
  export * from "./builder";
3
3
  export * from "./fields";
4
4
  export * from "./renderer";
5
+ export { validateForm, initialFormValues } from "./utils";
@@ -28,7 +28,7 @@ export interface BaseSerializedField<TIdentifier extends FieldTypeIdentifier = F
28
28
  image?: File | Promise<File>;
29
29
  }
30
30
  /** All the possible field values */
31
- export type FieldValue = string | number | boolean | string[] | SelectFieldOption[] | File[] | Date | Marker | null;
31
+ export type FieldValue = string | number | boolean | string[] | File[] | Date | Marker | null;
32
32
  export interface SerializedCondition<TValue extends FieldValue = FieldValue> {
33
33
  identifier: string;
34
34
  value: TValue;
@@ -1462,6 +1462,16 @@ const assetSlice = createSlice({
1462
1462
  }
1463
1463
  prevAssets = null;
1464
1464
  },
1465
+ updateAssets: (state, action) => {
1466
+ for (const asset of action.payload) {
1467
+ if (asset.offline_id in state.assets) {
1468
+ state.assets[asset.offline_id] = asset;
1469
+ } else {
1470
+ throw new Error(`Tried to update asset with ID that doesn't exist: ${asset.offline_id}`);
1471
+ }
1472
+ }
1473
+ prevAssets = null;
1474
+ },
1465
1475
  removeAsset: (state, action) => {
1466
1476
  if (action.payload in state.assets) {
1467
1477
  delete state.assets[action.payload];
@@ -1470,6 +1480,16 @@ const assetSlice = createSlice({
1470
1480
  }
1471
1481
  prevAssets = null;
1472
1482
  },
1483
+ removeAssets: (state, action) => {
1484
+ for (const assetId of action.payload) {
1485
+ if (assetId in state.assets) {
1486
+ delete state.assets[assetId];
1487
+ } else {
1488
+ throw new Error(`Failed to remove asset because ID doesn't exist: ${assetId}`);
1489
+ }
1490
+ }
1491
+ prevAssets = null;
1492
+ },
1473
1493
  removeAllAssetsOfType: (state, action) => {
1474
1494
  var _a2;
1475
1495
  for (const componentId in state.assets) {
@@ -1493,7 +1513,9 @@ const assetSlice = createSlice({
1493
1513
  const {
1494
1514
  addAsset,
1495
1515
  updateAsset,
1516
+ updateAssets,
1496
1517
  removeAsset,
1518
+ removeAssets,
1497
1519
  addAssetsInBatches,
1498
1520
  setAssets,
1499
1521
  removeAllAssetsOfType,
@@ -5110,6 +5132,15 @@ class CategoryService extends BaseApiService {
5110
5132
  store.dispatch(setCategories(result));
5111
5133
  }
5112
5134
  }
5135
+ function chunkArray(arr, chunkSize) {
5136
+ const chunks = [];
5137
+ let index2 = 0;
5138
+ const arrLength = arr.length;
5139
+ while (index2 < arrLength) {
5140
+ chunks.push(arr.slice(index2, index2 += chunkSize));
5141
+ }
5142
+ return chunks;
5143
+ }
5113
5144
  class AssetService extends BaseApiService {
5114
5145
  // Basic CRUD functions
5115
5146
  add(asset, workspaceId) {
@@ -5186,36 +5217,55 @@ class AssetService extends BaseApiService {
5186
5217
  throw err;
5187
5218
  });
5188
5219
  }
5189
- async addBatch(assetsToCreate, workspaceId, assetTypeId) {
5190
- const fullAssets = assetsToCreate.map((asset) => {
5191
- return { ...offline(asset), submitted_at: (/* @__PURE__ */ new Date()).toISOString() };
5192
- });
5220
+ // TODO: payload does not require asset_type
5221
+ bulkAdd(assetsToCreate, workspaceId, assetTypeId, batchSize) {
5193
5222
  const { store } = this.client;
5194
- store.dispatch(addAssetsInBatches(fullAssets));
5195
- const promise = this.client.enqueueRequest({
5196
- description: "Batch create assets",
5197
- method: HttpMethod.POST,
5198
- url: `/assets/types/${assetTypeId}/add-assets/`,
5199
- queryParams: {
5200
- workspace_id: workspaceId.toString()
5201
- },
5202
- payload: {
5203
- assets: fullAssets
5204
- },
5205
- blockers: [assetTypeId],
5206
- blocks: fullAssets.map((c) => c.offline_id)
5223
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5224
+ const transactionId = v4();
5225
+ const assetBatches = chunkArray(assetsToCreate, batchSize).map((assetBatch) => {
5226
+ const assetPayloads = assetBatch.map((assetPayload) => {
5227
+ return offline({
5228
+ ...assetPayload,
5229
+ submitted_at: submittedAt
5230
+ });
5231
+ });
5232
+ return {
5233
+ batchId: v4(),
5234
+ payload: {
5235
+ transaction_id: transactionId,
5236
+ assets: assetPayloads
5237
+ }
5238
+ };
5207
5239
  });
5208
- void promise.then((result) => {
5209
- for (const assets of Object.values(result)) {
5210
- store.dispatch(updateAsset(assets));
5211
- }
5212
- }).catch((e) => {
5213
- for (const asset of fullAssets) {
5214
- store.dispatch(removeAsset(asset.offline_id));
5215
- }
5216
- throw e;
5240
+ const batchPromises = [];
5241
+ let prevBatchId = null;
5242
+ for (const assetBatch of assetBatches) {
5243
+ const { batchId, payload } = assetBatch;
5244
+ const batchAssetOfflineIds = payload.assets.map((c) => c.offline_id);
5245
+ const blockers = [assetTypeId];
5246
+ if (prevBatchId)
5247
+ blockers.push(prevBatchId);
5248
+ const blocks = batchAssetOfflineIds;
5249
+ blocks.push(batchId);
5250
+ const promise = this.client.enqueueRequest({
5251
+ description: "Batch create assets",
5252
+ method: HttpMethod.POST,
5253
+ url: `/assets/types/${assetTypeId}/add-assets/`,
5254
+ queryParams: {
5255
+ workspace_id: workspaceId.toString()
5256
+ },
5257
+ payload,
5258
+ blockers,
5259
+ blocks
5260
+ });
5261
+ prevBatchId = assetBatch.batchId;
5262
+ batchPromises.push(promise);
5263
+ }
5264
+ void Promise.all(batchPromises).then((result) => {
5265
+ const allCreatedAssets = result.flat();
5266
+ store.dispatch(addAssetsInBatches(allCreatedAssets));
5217
5267
  });
5218
- return promise;
5268
+ return batchPromises;
5219
5269
  }
5220
5270
  async refreshStore() {
5221
5271
  const { store } = this.client;
@@ -7081,100 +7131,120 @@ class UserFormSubmissionService extends BaseApiService {
7081
7131
  }
7082
7132
  // Note currently the bulkAdd method is specific to form submissions for assets
7083
7133
  // TODO: adapt the support bulk adding to any model type
7084
- async bulkAdd(args) {
7085
- const { formRevision, values: argsValues, assetOfflineIds } = args;
7134
+ async bulkAdd(args, batchSize) {
7086
7135
  const { store } = this.client;
7087
- const offlineSubmissions = [];
7088
- const offlineAttachments = [];
7089
- const submissionOfflineIds = [];
7090
- const submissionsPayload = [];
7091
- const attachmentsPayload = [];
7092
- const { values, files } = separateFilesFromValues(argsValues);
7136
+ const { formRevision, commonFieldValues, fieldValuesByAsset } = args;
7137
+ const allFilesRecord = {};
7138
+ const { values: fileSeperatedCommonFieldValues, files: commonFiles } = separateFilesFromValues(commonFieldValues);
7093
7139
  const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
7094
- const createdBy = store.getState().userReducer.currentUser.id;
7095
- for (const assetId of assetOfflineIds) {
7096
- const submission = offline({
7097
- form_revision: formRevision,
7098
- values,
7099
- created_by: createdBy,
7100
- submitted_at: submittedAt,
7101
- asset: assetId
7102
- });
7103
- submissionOfflineIds.push(submission.offline_id);
7104
- submissionsPayload.push({ offline_id: submission.offline_id, asset_id: assetId });
7105
- offlineSubmissions.push(submission);
7106
- for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7107
- for (const file of fileArray) {
7108
- const sha1 = await hashFile(file);
7109
- await this.client.files.addCache(file, sha1);
7110
- const offlineAttachment = offline({
7111
- file_name: file.name,
7112
- file_sha1: sha1,
7113
- file: URL.createObjectURL(file),
7114
- submission: submission.offline_id,
7115
- field_identifier: fieldIdentifier
7140
+ const transactionId = v4();
7141
+ const assetIdBatches = chunkArray(Object.keys(fieldValuesByAsset), batchSize);
7142
+ const bulkAddBatches = await Promise.all(
7143
+ assetIdBatches.map(async (assetIdBatch) => {
7144
+ const batchId = v4();
7145
+ const submissionPayloads = [];
7146
+ const attachmentPayloads = [];
7147
+ const files = { ...commonFiles };
7148
+ for (const assetId of assetIdBatch) {
7149
+ const { values: fileSeperatedSubmissionSpecificValues, files: submissionSpecificFiles } = separateFilesFromValues(fieldValuesByAsset[assetId] ?? {});
7150
+ Object.assign(files, submissionSpecificFiles);
7151
+ const submissionPayload = offline({
7152
+ asset_id: assetId,
7153
+ form_data: fileSeperatedSubmissionSpecificValues
7116
7154
  });
7117
- offlineAttachments.push(offlineAttachment);
7118
- attachmentsPayload.push({
7119
- offline_id: offlineAttachment.offline_id,
7120
- submission_id: submission.offline_id,
7155
+ submissionPayloads.push(submissionPayload);
7156
+ for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7157
+ for (const file of fileArray) {
7158
+ const sha1 = await hashFile(file);
7159
+ await this.client.files.addCache(file, sha1);
7160
+ const attachmentPayload = offline({
7161
+ submission_id: submissionPayload.offline_id,
7162
+ sha1,
7163
+ name: file.name,
7164
+ field_identifier: fieldIdentifier
7165
+ });
7166
+ attachmentPayloads.push(attachmentPayload);
7167
+ }
7168
+ }
7169
+ }
7170
+ const filePaylods = [];
7171
+ for (const file of Object.values(files).flat()) {
7172
+ const sha1 = await hashFile(file);
7173
+ const filePayload = {
7121
7174
  sha1,
7122
- name: file.name,
7123
- field_identifier: fieldIdentifier
7175
+ extension: file.name.split(".").pop() || "",
7176
+ file_type: file.type,
7177
+ size: file.size
7178
+ };
7179
+ allFilesRecord[sha1] = filePayload;
7180
+ filePaylods.push(filePayload);
7181
+ }
7182
+ return {
7183
+ batchId,
7184
+ payload: {
7185
+ transaction_id: transactionId,
7186
+ form_data: fileSeperatedCommonFieldValues,
7187
+ submitted_at: submittedAt,
7188
+ submissions: submissionPayloads,
7189
+ attachments: attachmentPayloads,
7190
+ files: filePaylods
7191
+ }
7192
+ };
7193
+ })
7194
+ );
7195
+ const batchPromises = [];
7196
+ let prevBatchId = null;
7197
+ for (const batch of bulkAddBatches) {
7198
+ const { payload, batchId } = batch;
7199
+ const batchAssetIds = payload.submissions.map((x) => x.asset_id);
7200
+ const batchSubmissionOfflineIds = payload.submissions.map((x) => x.offline_id);
7201
+ const batchAttachmentsOfflineIds = payload.attachments.map((x) => x.offline_id);
7202
+ const blockers = batchAssetIds;
7203
+ if (prevBatchId)
7204
+ blockers.push(prevBatchId);
7205
+ const blocks = [...batchSubmissionOfflineIds, ...batchAttachmentsOfflineIds, batchId];
7206
+ const promise = this.client.enqueueRequest({
7207
+ description: "Bulk add form submissions",
7208
+ method: HttpMethod.POST,
7209
+ url: `/forms/revisions/${formRevision}/bulk-respond/`,
7210
+ payload,
7211
+ blockers,
7212
+ blocks
7213
+ });
7214
+ void promise.then(({ presigned_urls }) => {
7215
+ for (const [sha1, presignedUrl] of Object.entries(presigned_urls)) {
7216
+ const file = allFilesRecord[sha1];
7217
+ if (!file)
7218
+ continue;
7219
+ void this.client.enqueueRequest({
7220
+ url: presignedUrl.url,
7221
+ description: "Upload file",
7222
+ method: HttpMethod.POST,
7223
+ isExternalUrl: true,
7224
+ isAuthNeeded: false,
7225
+ attachmentHash: sha1,
7226
+ blockers: [`s3-${file.sha1}.${file.extension}`],
7227
+ blocks: [sha1],
7228
+ s3url: presignedUrl
7124
7229
  });
7125
7230
  }
7126
- }
7127
- }
7128
- const filesRecord = {};
7129
- for (const file of Object.values(files).flat()) {
7130
- const sha1 = await hashFile(file);
7131
- filesRecord[sha1] = {
7132
- sha1,
7133
- extension: file.name.split(".").pop() || "",
7134
- file_type: file.type,
7135
- size: file.size
7136
- };
7137
- }
7138
- store.dispatch(addFormSubmissions(offlineSubmissions));
7139
- store.dispatch(addFormSubmissionAttachments(offlineAttachments));
7140
- const promise = this.client.enqueueRequest({
7141
- description: "Bulk add form submissions",
7142
- method: HttpMethod.POST,
7143
- url: `/forms/revisions/${formRevision}/bulk-respond/`,
7144
- payload: {
7145
- form_data: values,
7146
- submitted_at: submittedAt,
7147
- submissions: submissionsPayload,
7148
- attachments: attachmentsPayload,
7149
- files: Object.values(filesRecord)
7150
- },
7151
- blockers: assetOfflineIds,
7152
- blocks: submissionOfflineIds
7153
- });
7154
- promise.then(({ submissions, attachments, presigned_urls }) => {
7155
- store.dispatch(updateFormSubmissions(submissions));
7156
- store.dispatch(updateFormSubmissionAttachments(attachments));
7157
- for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
7158
- const file = filesRecord[sha1];
7159
- if (!file)
7160
- continue;
7161
- void this.client.enqueueRequest({
7162
- url: presigned_url.url,
7163
- description: "Upload file",
7164
- method: HttpMethod.POST,
7165
- isExternalUrl: true,
7166
- isAuthNeeded: false,
7167
- attachmentHash: sha1,
7168
- blockers: [`s3-${file.sha1}.${file.extension}`],
7169
- blocks: [sha1],
7170
- s3url: presigned_url
7171
- });
7172
- }
7173
- }).catch(() => {
7174
- store.dispatch(deleteFormSubmissions(submissionOfflineIds));
7175
- store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
7231
+ });
7232
+ prevBatchId = batchId;
7233
+ batchPromises.push(promise);
7234
+ }
7235
+ void Promise.all(batchPromises).then((results) => {
7236
+ const createdSubmissions = [];
7237
+ const createdAttachments = [];
7238
+ for (const result of results) {
7239
+ for (const createdSubmission of result.submissions)
7240
+ createdSubmissions.push(createdSubmission);
7241
+ for (const createdAttachment of result.attachments)
7242
+ createdAttachments.push(createdAttachment);
7243
+ }
7244
+ store.dispatch(addFormSubmissions(createdSubmissions));
7245
+ store.dispatch(addFormSubmissionAttachments(createdAttachments));
7176
7246
  });
7177
- return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
7247
+ return batchPromises;
7178
7248
  }
7179
7249
  update(submission) {
7180
7250
  const { store } = this.client;
@@ -8529,6 +8599,12 @@ class BaseField extends BaseFormElement {
8529
8599
  getFormValidators() {
8530
8600
  return [...this.formValidators];
8531
8601
  }
8602
+ encodeValueToJson(value) {
8603
+ return JSON.stringify(value);
8604
+ }
8605
+ decodeJsonToValue(json) {
8606
+ return JSON.parse(json);
8607
+ }
8532
8608
  }
8533
8609
  __publicField(BaseField, "fieldTypeName");
8534
8610
  __publicField(BaseField, "fieldTypeDescription");
@@ -16942,10 +17018,7 @@ const MultiStringInput = memo((props) => {
16942
17018
  helpText = showInputOnly ? null : helpText;
16943
17019
  label = showInputOnly ? "" : label;
16944
17020
  const color = useSeverityColor(severity);
16945
- const value = useMemo(
16946
- () => Array.isArray(fieldProps.value) ? fieldProps.value : [],
16947
- [fieldProps.value]
16948
- );
17021
+ const value = useMemo(() => Array.isArray(fieldProps.value) ? fieldProps.value : [], [fieldProps.value]);
16949
17022
  const { onChange, onBlur } = fieldProps;
16950
17023
  const droppableId = `${inputId}-droppable`;
16951
17024
  const { disabled } = rest;
@@ -16962,7 +17035,7 @@ const MultiStringInput = memo((props) => {
16962
17035
  );
16963
17036
  const handleChange = useCallback(
16964
17037
  (e) => {
16965
- if (value.findIndex((option) => option.value === e.target.value.trim()) >= 0) {
17038
+ if (value.findIndex((option) => option === e.target.value.trim()) >= 0) {
16966
17039
  setInternalError("All options must be unique");
16967
17040
  } else if (!e.target.value) {
16968
17041
  setInternalError("Option cannot be empty");
@@ -16981,7 +17054,7 @@ const MultiStringInput = memo((props) => {
16981
17054
  return;
16982
17055
  }
16983
17056
  const trimmedValue = intermediateValue.trim();
16984
- setValueAndTouched([...value, { value: trimmedValue, label: trimmedValue }]);
17057
+ setValueAndTouched([...value, trimmedValue]);
16985
17058
  setIntermediateValue("");
16986
17059
  }, [intermediateValue, internalError, setValueAndTouched, value]);
16987
17060
  const handleKeyDown = useCallback(
@@ -17051,7 +17124,7 @@ const MultiStringInput = memo((props) => {
17051
17124
  value.map((option, index2) => /* @__PURE__ */ jsx(
17052
17125
  Draggable,
17053
17126
  {
17054
- draggableId: `${option.value}-draggable`,
17127
+ draggableId: `${option}-draggable`,
17055
17128
  index: index2,
17056
17129
  isDragDisabled: disabled,
17057
17130
  children: ({ draggableProps, dragHandleProps, innerRef }) => /* @__PURE__ */ jsx(
@@ -17066,7 +17139,7 @@ const MultiStringInput = memo((props) => {
17066
17139
  mb: "1",
17067
17140
  asChild: true,
17068
17141
  children: /* @__PURE__ */ jsxs(Badge, { color: "gray", size: "2", children: [
17069
- /* @__PURE__ */ jsx("span", { children: option.label }),
17142
+ /* @__PURE__ */ jsx("span", { children: option }),
17070
17143
  /* @__PURE__ */ jsx(
17071
17144
  IconButton,
17072
17145
  {
@@ -17086,7 +17159,7 @@ const MultiStringInput = memo((props) => {
17086
17159
  }
17087
17160
  )
17088
17161
  },
17089
- option.value
17162
+ option
17090
17163
  )),
17091
17164
  droppableProvided.placeholder
17092
17165
  ] }) })
@@ -18754,6 +18827,44 @@ function formRevisionToSchema(formRevision, meta = {}) {
18754
18827
  meta: { readonly }
18755
18828
  };
18756
18829
  }
18830
+ function flattenFields(schema) {
18831
+ const allFields = [];
18832
+ for (const field of schema.fields) {
18833
+ if (field instanceof FieldSection) {
18834
+ for (const subField of field.fields) {
18835
+ allFields.push(subField);
18836
+ }
18837
+ } else {
18838
+ if (!(field instanceof BaseField)) {
18839
+ throw new Error(`Invalid field type: ${field.type}`);
18840
+ }
18841
+ allFields.push(field);
18842
+ }
18843
+ }
18844
+ return allFields;
18845
+ }
18846
+ function decodeFormValues(schema, values) {
18847
+ const allFields = flattenFields(schema);
18848
+ const result = {};
18849
+ for (const field of allFields) {
18850
+ const value = values[field.identifier] ?? null;
18851
+ if (value !== null) {
18852
+ result[field.identifier] = field.decodeJsonToValue(value);
18853
+ } else {
18854
+ result[field.identifier] = value;
18855
+ }
18856
+ }
18857
+ return result;
18858
+ }
18859
+ function encodeFormValues(schema, values) {
18860
+ const allFields = flattenFields(schema);
18861
+ const result = {};
18862
+ for (const field of allFields) {
18863
+ const value = values[field.identifier];
18864
+ result[field.identifier] = field.encodeValueToJson(value);
18865
+ }
18866
+ return result;
18867
+ }
18757
18868
  function valueIsFile(v) {
18758
18869
  return Array.isArray(v) && v.some((v2) => v2 instanceof File || v2 instanceof Promise);
18759
18870
  }
@@ -20433,6 +20544,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
20433
20544
  StringInput,
20434
20545
  TextField,
20435
20546
  TextInput,
20547
+ decodeFormValues,
20436
20548
  deserialize,
20437
20549
  deserializeField,
20438
20550
  emptyBaseField,
@@ -20445,11 +20557,15 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
20445
20557
  emptySelectField,
20446
20558
  emptyStringField,
20447
20559
  emptyTextField,
20560
+ encodeFormValues,
20561
+ flattenFields,
20448
20562
  formRevisionToSchema,
20563
+ initialFormValues,
20449
20564
  isConditionMet,
20450
20565
  useFieldInput,
20451
20566
  useFieldInputs,
20452
20567
  useFormikInput,
20568
+ validateForm,
20453
20569
  valueIsFile
20454
20570
  }, Symbol.toStringTag, { value: "Module" }));
20455
20571
  export {
@@ -20641,6 +20757,7 @@ export {
20641
20757
  coordinatesToUrlText,
20642
20758
  createOfflineAction,
20643
20759
  createPointMarker,
20760
+ decodeFormValues,
20644
20761
  defaultBadgeColor,
20645
20762
  deleteAssetType,
20646
20763
  deleteForm,
@@ -20675,6 +20792,7 @@ export {
20675
20792
  emptySelectField,
20676
20793
  emptyStringField,
20677
20794
  emptyTextField,
20795
+ encodeFormValues,
20678
20796
  enqueue,
20679
20797
  enqueueRequest,
20680
20798
  errorColor,
@@ -20682,6 +20800,7 @@ export {
20682
20800
  fileReducer,
20683
20801
  fileSlice,
20684
20802
  fileToBlob,
20803
+ flattenFields,
20685
20804
  flipCoordinates,
20686
20805
  formReducer,
20687
20806
  formRevisionReducer,
@@ -20705,6 +20824,7 @@ export {
20705
20824
  hashFile,
20706
20825
  hideAllCategories,
20707
20826
  hideCategory,
20827
+ initialFormValues,
20708
20828
  isConditionMet,
20709
20829
  isToday,
20710
20830
  issueReducer,
@@ -20758,6 +20878,7 @@ export {
20758
20878
  removeAssetAttachments,
20759
20879
  removeAssetTypeAttachment,
20760
20880
  removeAssetTypeAttachments,
20881
+ removeAssets,
20761
20882
  removeAttachmentsOfIssue,
20762
20883
  removeCategory,
20763
20884
  removeColor,
@@ -21077,6 +21198,7 @@ export {
21077
21198
  updateAssetAttachments,
21078
21199
  updateAssetTypeAttachment,
21079
21200
  updateAssetTypeAttachments,
21201
+ updateAssets,
21080
21202
  updateConversation,
21081
21203
  updateDocumentAttachment,
21082
21204
  updateDocumentAttachments,
@@ -21105,6 +21227,7 @@ export {
21105
21227
  useSDK,
21106
21228
  userReducer,
21107
21229
  userSlice,
21230
+ validateForm,
21108
21231
  valueIsFile,
21109
21232
  warningColor,
21110
21233
  workspaceReducer,