@poirazis/supercomponents-shared 1.0.8 → 1.0.11

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,149 @@
1
+ <script lang="ts">
2
+ import { getContext } from "svelte";
3
+ import InnerForm from "./InnerForm.svelte";
4
+ import { writable } from "svelte/store";
5
+ import type { FieldSchema } from "@budibase/types";
6
+
7
+ export let dataSource: any;
8
+ export let size: "Medium" | "Large" = "Medium";
9
+ export let disabled: boolean = false;
10
+ export let readonly: boolean = false;
11
+ export let actionType: "Create" | "Update" | "View" = "Create";
12
+ export let initialFormStep: string | number = 1;
13
+
14
+ // Not exposed as a builder setting. Used internally to disable validation
15
+ // for fields rendered in things like search blocks.
16
+ export let disableSchemaValidation: boolean = false;
17
+
18
+ // Not exposed as a builder setting. Used internally to allow searching on
19
+ // auto columns.
20
+ export let editAutoColumns: boolean = false;
21
+
22
+ const context = getContext("context");
23
+ const component = getContext("component");
24
+ const { fetchDatasourceSchema, fetchDatasourceDefinition } =
25
+ getContext("sdk");
26
+
27
+ const getInitialFormStep = () => {
28
+ const parsedFormStep = parseInt(initialFormStep.toString());
29
+ if (isNaN(parsedFormStep)) {
30
+ return 1;
31
+ }
32
+ return parsedFormStep;
33
+ };
34
+
35
+ let definition: any | undefined;
36
+ let schema: Record<string, FieldSchema> | undefined;
37
+ let loaded = false;
38
+ let currentStep =
39
+ getContext("current-step") || writable(getInitialFormStep());
40
+
41
+ $: fetchSchema(dataSource);
42
+ $: schemaKey = generateSchemaKey(schema);
43
+ $: initialValues = getInitialValues(
44
+ actionType,
45
+ dataSource,
46
+ $component.path,
47
+ $context
48
+ );
49
+ $: resetKey = hashString(
50
+ schemaKey + JSON.stringify(initialValues) + disabled + readonly
51
+ );
52
+
53
+ // Returns the closes data context which isn't a built in context
54
+ const getInitialValues = (
55
+ type: string,
56
+ dataSource: any,
57
+ path: string[],
58
+ context: Record<string, any>
59
+ ) => {
60
+ // Only inherit values for update forms
61
+ if (type !== "Update") {
62
+ return {};
63
+ }
64
+ // Only inherit values for forms targeting internal tables
65
+ const dsType = dataSource?.type;
66
+ if (dsType !== "table" && dsType !== "viewV2") {
67
+ return {};
68
+ }
69
+ // Look up the component tree and find something that is provided by an
70
+ // ancestor that matches our datasource. This is for backwards compatibility
71
+ // as previously we could use the "closest" context.
72
+ for (let id of [...path].reverse().slice(1)) {
73
+ // Check for matching view datasource
74
+ if (
75
+ dataSource.type === "viewV2" &&
76
+ context[id]?._viewId === dataSource.id
77
+ ) {
78
+ return context[id];
79
+ }
80
+ // Check for matching table datasource
81
+ if (
82
+ dataSource.type === "table" &&
83
+ context[id]?.tableId === dataSource.tableId
84
+ ) {
85
+ return context[id];
86
+ }
87
+ }
88
+ return {};
89
+ };
90
+
91
+ // Fetches the form schema from this form's dataSource
92
+ const fetchSchema = async (dataSource: any) => {
93
+ try {
94
+ definition = await fetchDatasourceDefinition(dataSource);
95
+ } catch (error) {
96
+ definition = undefined;
97
+ }
98
+ const res = await fetchDatasourceSchema(dataSource);
99
+ schema = res || {};
100
+ if (!loaded) {
101
+ loaded = true;
102
+ }
103
+ };
104
+
105
+ // Generates a predictable string that uniquely identifies a schema. We can't
106
+ // simply stringify the whole schema as there are array fields which have
107
+ // random order.
108
+ const generateSchemaKey = (
109
+ schema: Record<string, FieldSchema> | undefined
110
+ ) => {
111
+ if (!schema) {
112
+ return null;
113
+ }
114
+ const fields = Object.keys(schema);
115
+ fields.sort();
116
+ return fields.map((field) => `${field}:${schema[field].type}`).join("-");
117
+ };
118
+
119
+ // Helper function to generate a hash string from input
120
+ function hashString(str: string) {
121
+ let hash = 0;
122
+ if (str.length === 0) return hash.toString();
123
+ for (let i = 0; i < str.length; i++) {
124
+ const char = str.charCodeAt(i);
125
+ hash = (hash << 5) - hash + char;
126
+ hash = hash & hash; // Convert to 32bit integer
127
+ }
128
+ return hash.toString();
129
+ }
130
+ </script>
131
+
132
+ {#if loaded}
133
+ {#key resetKey}
134
+ <InnerForm
135
+ {dataSource}
136
+ {size}
137
+ {disabled}
138
+ {readonly}
139
+ {schema}
140
+ {definition}
141
+ {initialValues}
142
+ {disableSchemaValidation}
143
+ {editAutoColumns}
144
+ {currentStep}
145
+ >
146
+ <slot />
147
+ </InnerForm>
148
+ {/key}
149
+ {/if}
File without changes