@stubber/form-fields 1.4.6 → 1.5.0
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.
- package/README.md +61 -295
- package/dist/fields2/FieldLabel.svelte +8 -0
- package/dist/fields2/FieldLabel.svelte.d.ts +20 -0
- package/dist/fields2/FieldMessage.svelte +16 -0
- package/dist/fields2/FieldMessage.svelte.d.ts +20 -0
- package/dist/fields2/Form.svelte +29 -0
- package/dist/fields2/Form.svelte.d.ts +23 -0
- package/dist/fields2/fileserver.d.ts +15 -0
- package/dist/fields2/fileserver.js +52 -0
- package/dist/fields2/form-field.svelte +10 -0
- package/dist/fields2/form-field.svelte.d.ts +20 -0
- package/dist/fields2/interfaces.d.ts +207 -0
- package/dist/fields2/interfaces.js +82 -0
- package/dist/fields2/sub/array-builder-field.svelte +110 -0
- package/dist/fields2/sub/array-builder-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/checkbox-autocomplete.svelte +56 -0
- package/dist/fields2/sub/checkbox-autocomplete.svelte.d.ts +27 -0
- package/dist/fields2/sub/checkbox-field.svelte +41 -0
- package/dist/fields2/sub/checkbox-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/code-field.svelte +146 -0
- package/dist/fields2/sub/code-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/contact-selector-field.svelte +84 -0
- package/dist/fields2/sub/contact-selector-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/currency-field.svelte +197 -0
- package/dist/fields2/sub/currency-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/data-indication-field.svelte +19 -0
- package/dist/fields2/sub/data-indication-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/date-field.svelte +31 -0
- package/dist/fields2/sub/date-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/date-time-field.svelte +31 -0
- package/dist/fields2/sub/date-time-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/email-field.svelte +40 -0
- package/dist/fields2/sub/email-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/field-builder-field.svelte +525 -0
- package/dist/fields2/sub/field-builder-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/file-field.svelte +150 -0
- package/dist/fields2/sub/file-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/grid-field.svelte +54 -0
- package/dist/fields2/sub/grid-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/heading-field.svelte +28 -0
- package/dist/fields2/sub/heading-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/hidden-field.svelte +142 -0
- package/dist/fields2/sub/hidden-field.svelte.d.ts +37 -0
- package/dist/fields2/sub/hidden-location-field.svelte +23 -0
- package/dist/fields2/sub/hidden-location-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/html-field.svelte +22 -0
- package/dist/fields2/sub/html-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/json-editor-bound.svelte +17 -0
- package/dist/fields2/sub/json-editor-bound.svelte.d.ts +65 -0
- package/dist/fields2/sub/jsoneditor-field.svelte +23 -0
- package/dist/fields2/sub/jsoneditor-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/map-field.svelte +144 -0
- package/dist/fields2/sub/map-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/multi-checkbox-field.svelte +83 -0
- package/dist/fields2/sub/multi-checkbox-field.svelte.d.ts +34 -0
- package/dist/fields2/sub/multistep-field.svelte +70 -0
- package/dist/fields2/sub/multistep-field.svelte.d.ts +24 -0
- package/dist/fields2/sub/note-field.svelte +18 -0
- package/dist/fields2/sub/note-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/number-field.svelte +77 -0
- package/dist/fields2/sub/number-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/object-builder-field.svelte +123 -0
- package/dist/fields2/sub/object-builder-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/qr-code-scanner-field.svelte +86 -0
- package/dist/fields2/sub/qr-code-scanner-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/radio-field.svelte +69 -0
- package/dist/fields2/sub/radio-field.svelte.d.ts +30 -0
- package/dist/fields2/sub/screenrecorder-field.svelte +182 -0
- package/dist/fields2/sub/screenrecorder-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/screenshot-field.svelte +165 -0
- package/dist/fields2/sub/screenshot-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/scroll-and-read-display-field.svelte +92 -0
- package/dist/fields2/sub/scroll-and-read-display-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/section-field.svelte +27 -0
- package/dist/fields2/sub/section-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/select-field.svelte +138 -0
- package/dist/fields2/sub/select-field.svelte.d.ts +34 -0
- package/dist/fields2/sub/selectresource-field.svelte +69 -0
- package/dist/fields2/sub/selectresource-field.svelte.d.ts +29 -0
- package/dist/fields2/sub/signature-field.svelte +84 -0
- package/dist/fields2/sub/signature-field.svelte.d.ts +23 -0
- package/dist/fields2/sub/slider-field.svelte +28 -0
- package/dist/fields2/sub/slider-field.svelte.d.ts +28 -0
- package/dist/fields2/sub/smart-text-field.svelte +245 -0
- package/dist/fields2/sub/smart-text-field.svelte.d.ts +36 -0
- package/dist/fields2/sub/telephone-field.svelte +68 -0
- package/dist/fields2/sub/telephone-field.svelte.d.ts +26 -0
- package/dist/fields2/sub/text-field.svelte +46 -0
- package/dist/fields2/sub/text-field.svelte.d.ts +27 -0
- package/dist/fields2/sub/voicenote-field.svelte +161 -0
- package/dist/fields2/sub/voicenote-field.svelte.d.ts +26 -0
- package/dist/fields2/utils.d.ts +9 -0
- package/dist/fields2/utils.js +116 -0
- package/dist/fields2/validations/validate_field.d.ts +11 -0
- package/dist/fields2/validations/validate_field.js +121 -0
- package/package.json +6 -9
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import { Input } from "@stubber/ui/input";
|
|
4
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
5
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
6
|
+
import { set_value_details } from "../utils";
|
|
7
|
+
export let fieldStore;
|
|
8
|
+
const field = $fieldStore;
|
|
9
|
+
const formStore = field.formStore;
|
|
10
|
+
$: value = $fieldStore.value;
|
|
11
|
+
$: {
|
|
12
|
+
const regex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
|
13
|
+
const is_valid_email = regex.test(value);
|
|
14
|
+
const username = is_valid_email ? value.split("@")[0] : null;
|
|
15
|
+
const domain = is_valid_email ? value.split("@")[1] : null;
|
|
16
|
+
const email_details = {
|
|
17
|
+
is_valid_email,
|
|
18
|
+
username,
|
|
19
|
+
domain,
|
|
20
|
+
raw: value
|
|
21
|
+
};
|
|
22
|
+
if (value) set_value_details(field, "details", email_details);
|
|
23
|
+
}
|
|
24
|
+
function on_input(event) {
|
|
25
|
+
const input = event.target;
|
|
26
|
+
const new_value = input.value.trim().toLowerCase();
|
|
27
|
+
field.value = new_value;
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<FieldLabel {fieldStore} />
|
|
32
|
+
<Input
|
|
33
|
+
id={$fieldStore.id}
|
|
34
|
+
{value}
|
|
35
|
+
placeholder={$fieldStore.label}
|
|
36
|
+
on:input={on_input}
|
|
37
|
+
aria-invalid={$fieldStore.validation_result?.type == "error" ? true : undefined}
|
|
38
|
+
aria-describedby="message-{$fieldStore.id}"
|
|
39
|
+
/>
|
|
40
|
+
<FieldMessage {fieldStore} />
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { Writable } from "svelte/store";
|
|
3
|
+
import type { IBaseField, IBuiltField } from "../interfaces";
|
|
4
|
+
export interface IEmailField extends IBaseField<{}> {
|
|
5
|
+
fieldtype: "email";
|
|
6
|
+
}
|
|
7
|
+
declare const __propDef: {
|
|
8
|
+
props: {
|
|
9
|
+
fieldStore: Writable<IBuiltField>;
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
exports?: {} | undefined;
|
|
16
|
+
bindings?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
export type EmailFieldProps = typeof __propDef.props;
|
|
19
|
+
export type EmailFieldEvents = typeof __propDef.events;
|
|
20
|
+
export type EmailFieldSlots = typeof __propDef.slots;
|
|
21
|
+
export default class EmailField extends SvelteComponent<EmailFieldProps, EmailFieldEvents, EmailFieldSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
<script context="module">import { writable } from "svelte/store";
|
|
2
|
+
import {
|
|
3
|
+
fields,
|
|
4
|
+
validation_types
|
|
5
|
+
} from "../interfaces";
|
|
6
|
+
import { text_field_param_spec } from "./text-field.svelte";
|
|
7
|
+
const field_params_spec_lookup = {
|
|
8
|
+
text: text_field_param_spec,
|
|
9
|
+
checkbox: checkbox_field_param_spec,
|
|
10
|
+
smart_text: smart_text_field_param_spec,
|
|
11
|
+
file: file_field_param_spec,
|
|
12
|
+
heading: heading_field_param_spec,
|
|
13
|
+
hidden: hidden_field_param_spec,
|
|
14
|
+
html: html_field_param_spec,
|
|
15
|
+
map: map_field_param_spec,
|
|
16
|
+
checkbox_autocomplete: merge({}, checkbox_field_param_spec, smart_text_field_param_spec),
|
|
17
|
+
code: code_field_param_spec,
|
|
18
|
+
currency: currency_field_param_spec,
|
|
19
|
+
dataindication: null,
|
|
20
|
+
telephone: null,
|
|
21
|
+
email: null,
|
|
22
|
+
arraybuilder: array_builder_field_param_spec,
|
|
23
|
+
contactselector: contact_selector_field_param_spec,
|
|
24
|
+
date: null,
|
|
25
|
+
datetime: null,
|
|
26
|
+
fieldbuilder: null,
|
|
27
|
+
grid: grid_field_param_spec,
|
|
28
|
+
hiddenlocation: null,
|
|
29
|
+
jsoneditor: jsoneditor_field_param_spec,
|
|
30
|
+
multicheckbox: multi_checkbox_field_param_spec,
|
|
31
|
+
multistep: null,
|
|
32
|
+
// todo: fields for multistep
|
|
33
|
+
note: null,
|
|
34
|
+
number: number_field_param_spec,
|
|
35
|
+
objectbuilder: object_builder_field_param_spec,
|
|
36
|
+
qrcodescanner: null,
|
|
37
|
+
radio: radio_field_param_spec,
|
|
38
|
+
screenrecorder: max_files_param_spec,
|
|
39
|
+
screenshot: max_files_param_spec,
|
|
40
|
+
voicenote: max_files_param_spec,
|
|
41
|
+
signature: null,
|
|
42
|
+
scrollandreaddisplay: scroll_and_read_display_field_param_spec,
|
|
43
|
+
section: null,
|
|
44
|
+
// todo: fields for section
|
|
45
|
+
select: select_field_param_spec,
|
|
46
|
+
slider: number_field_param_spec,
|
|
47
|
+
selectresource: select_resource_field_param_spec,
|
|
48
|
+
unknown: null
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<script>import Form from "../Form.svelte";
|
|
53
|
+
import { Button } from "@stubber/ui/button";
|
|
54
|
+
import { Checkbox } from "@stubber/ui/checkbox";
|
|
55
|
+
import * as Collapsible from "@stubber/ui/collapsible";
|
|
56
|
+
import * as Command from "@stubber/ui/command";
|
|
57
|
+
import { Input } from "@stubber/ui/input";
|
|
58
|
+
import { Label } from "@stubber/ui/label";
|
|
59
|
+
import * as Popover from "@stubber/ui/popover";
|
|
60
|
+
import * as Select from "@stubber/ui/select";
|
|
61
|
+
import { Textarea } from "@stubber/ui/textarea";
|
|
62
|
+
import { cloneDeep, isEmpty, isEqual, isUndefined, merge, omitBy } from "lodash-es";
|
|
63
|
+
import { tick } from "svelte";
|
|
64
|
+
import FieldLabel from "../FieldLabel.svelte";
|
|
65
|
+
import FieldMessage from "../FieldMessage.svelte";
|
|
66
|
+
import { checkbox_field_param_spec } from "./checkbox-field.svelte";
|
|
67
|
+
import { file_field_param_spec } from "./file-field.svelte";
|
|
68
|
+
import { heading_field_param_spec } from "./heading-field.svelte";
|
|
69
|
+
import { hidden_field_param_spec } from "./hidden-field.svelte";
|
|
70
|
+
import { html_field_param_spec } from "./html-field.svelte";
|
|
71
|
+
import JsonEditorBound from "./json-editor-bound.svelte";
|
|
72
|
+
import { map_field_param_spec } from "./map-field.svelte";
|
|
73
|
+
import { smart_text_field_param_spec } from "./smart-text-field.svelte";
|
|
74
|
+
import { code_field_param_spec } from "./code-field.svelte";
|
|
75
|
+
import { currency_field_param_spec } from "./currency-field.svelte";
|
|
76
|
+
import { array_builder_field_param_spec } from "./array-builder-field.svelte";
|
|
77
|
+
import { contact_selector_field_param_spec } from "./contact-selector-field.svelte";
|
|
78
|
+
import { grid_field_param_spec } from "./grid-field.svelte";
|
|
79
|
+
import { jsoneditor_field_param_spec } from "./jsoneditor-field.svelte";
|
|
80
|
+
import { multi_checkbox_field_param_spec } from "./multi-checkbox-field.svelte";
|
|
81
|
+
import { number_field_param_spec } from "./number-field.svelte";
|
|
82
|
+
import { object_builder_field_param_spec } from "./object-builder-field.svelte";
|
|
83
|
+
import { radio_field_param_spec } from "./radio-field.svelte";
|
|
84
|
+
import { max_files_param_spec } from "./screenrecorder-field.svelte";
|
|
85
|
+
import { scroll_and_read_display_field_param_spec } from "./scroll-and-read-display-field.svelte";
|
|
86
|
+
import { select_field_param_spec } from "./select-field.svelte";
|
|
87
|
+
import { select_resource_field_param_spec } from "./selectresource-field.svelte";
|
|
88
|
+
export let fieldStore;
|
|
89
|
+
let value = cloneDeep($fieldStore.value) || {
|
|
90
|
+
details: {},
|
|
91
|
+
initvalue: {}
|
|
92
|
+
};
|
|
93
|
+
if (!value.details) {
|
|
94
|
+
value.details = {};
|
|
95
|
+
}
|
|
96
|
+
if (!value.initvalue) {
|
|
97
|
+
value.initvalue = {};
|
|
98
|
+
}
|
|
99
|
+
$: update_fieldStore(value);
|
|
100
|
+
function update_fieldStore(new_value) {
|
|
101
|
+
const cleaned_value = omitBy(
|
|
102
|
+
cloneDeep(new_value),
|
|
103
|
+
(v) => isUndefined(v) || typeof v === "object" && isEmpty(v)
|
|
104
|
+
);
|
|
105
|
+
if (!isEqual($fieldStore, cleaned_value)) {
|
|
106
|
+
$fieldStore.value = cleaned_value;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
$: update_value($fieldStore.value);
|
|
110
|
+
function update_value(new_value) {
|
|
111
|
+
if (!isEqual(value, new_value)) {
|
|
112
|
+
value = {
|
|
113
|
+
details: {},
|
|
114
|
+
initvalue: {},
|
|
115
|
+
...cloneDeep(new_value)
|
|
116
|
+
};
|
|
117
|
+
update_params_from_value(value.params);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const field_types = Object.keys(fields).map((key) => ({
|
|
121
|
+
label: key,
|
|
122
|
+
value: key
|
|
123
|
+
}));
|
|
124
|
+
let open = false;
|
|
125
|
+
$: selectedValue = field_types.find((f) => f.value === value.fieldtype)?.label ?? "Select a fieldtype";
|
|
126
|
+
function closeAndFocusTrigger(trigger_id) {
|
|
127
|
+
open = false;
|
|
128
|
+
tick().then(() => {
|
|
129
|
+
document.getElementById(trigger_id)?.focus();
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function add_condition() {
|
|
133
|
+
if (!value.conditions) {
|
|
134
|
+
value.conditions = [];
|
|
135
|
+
}
|
|
136
|
+
value.conditions = [...value.conditions, ""];
|
|
137
|
+
}
|
|
138
|
+
function move_condition_up(index) {
|
|
139
|
+
if (index > 0 && value.conditions) {
|
|
140
|
+
const temp = value.conditions[index];
|
|
141
|
+
value.conditions[index] = value.conditions[index - 1];
|
|
142
|
+
value.conditions[index - 1] = temp;
|
|
143
|
+
value.conditions = [...value.conditions];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function move_condition_down(index) {
|
|
147
|
+
if (value.conditions && index < value.conditions.length - 1) {
|
|
148
|
+
const temp = value.conditions[index];
|
|
149
|
+
value.conditions[index] = value.conditions[index + 1];
|
|
150
|
+
value.conditions[index + 1] = temp;
|
|
151
|
+
value.conditions = [...value.conditions];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function remove_condition(index) {
|
|
155
|
+
if (value.conditions) {
|
|
156
|
+
value.conditions = value.conditions.filter((_, i) => i !== index);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function add_validation() {
|
|
160
|
+
if (!value.validations) {
|
|
161
|
+
value.validations = [];
|
|
162
|
+
}
|
|
163
|
+
value.validations = [...value.validations, { validationtype: "required", invalid_message: "" }];
|
|
164
|
+
}
|
|
165
|
+
function move_validation_up(index) {
|
|
166
|
+
if (index > 0 && value.validations) {
|
|
167
|
+
const temp = value.validations[index];
|
|
168
|
+
value.validations[index] = value.validations[index - 1];
|
|
169
|
+
value.validations[index - 1] = temp;
|
|
170
|
+
value.validations = [...value.validations];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function move_validation_down(index) {
|
|
174
|
+
if (value.validations && index < value.validations.length - 1) {
|
|
175
|
+
const temp = value.validations[index];
|
|
176
|
+
value.validations[index] = value.validations[index + 1];
|
|
177
|
+
value.validations[index + 1] = temp;
|
|
178
|
+
value.validations = [...value.validations];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function remove_validation(index) {
|
|
182
|
+
if (value.validations) {
|
|
183
|
+
value.validations = value.validations.filter((_, i) => i !== index);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function handle_validation_selected(val, index) {
|
|
187
|
+
if (val && value.validations) {
|
|
188
|
+
let current_validation;
|
|
189
|
+
let prev_validation = value.validations[index];
|
|
190
|
+
if (val.value === "required") {
|
|
191
|
+
current_validation = {
|
|
192
|
+
validationtype: "required",
|
|
193
|
+
invalid_message: prev_validation.invalid_message
|
|
194
|
+
};
|
|
195
|
+
} else if (val.value === "regex") {
|
|
196
|
+
current_validation = {
|
|
197
|
+
validationtype: "regex",
|
|
198
|
+
invalid_message: prev_validation.invalid_message,
|
|
199
|
+
params: { regex: prev_validation.params?.regex ?? "" }
|
|
200
|
+
};
|
|
201
|
+
} else {
|
|
202
|
+
current_validation = {
|
|
203
|
+
validationtype: "jsonata",
|
|
204
|
+
invalid_message: prev_validation.invalid_message,
|
|
205
|
+
params: { jsonata: prev_validation.params?.jsonata ?? "" }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
value.validations[index] = current_validation;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const params_store = writable({});
|
|
212
|
+
$: update_params($params_store);
|
|
213
|
+
function update_params(new_params) {
|
|
214
|
+
const cloned_new_params = cloneDeep(new_params);
|
|
215
|
+
if (!isEqual(value.params, cloned_new_params) && !isEmpty(cloned_new_params)) {
|
|
216
|
+
value.params = cloned_new_params;
|
|
217
|
+
update_fieldStore(value);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function update_params_from_value(new_value) {
|
|
221
|
+
if (!isEqual(new_value, $params_store)) {
|
|
222
|
+
params_store.set(cloneDeep(new_value) || {});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function select_field_type(newValue, trigger) {
|
|
226
|
+
value.fieldtype = newValue;
|
|
227
|
+
closeAndFocusTrigger(trigger);
|
|
228
|
+
}
|
|
229
|
+
</script>
|
|
230
|
+
|
|
231
|
+
<FieldLabel {fieldStore} />
|
|
232
|
+
<div class="flex flex-col gap-y-2">
|
|
233
|
+
<!-- fieldtype picker -->
|
|
234
|
+
<Popover.Root bind:open let:ids>
|
|
235
|
+
<Popover.Trigger asChild let:builder>
|
|
236
|
+
<Button
|
|
237
|
+
builders={[builder]}
|
|
238
|
+
variant="outline"
|
|
239
|
+
role="combobox"
|
|
240
|
+
aria-expanded={open}
|
|
241
|
+
class="w-full border-input bg-white bg-opacity-[15] ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 justify-between"
|
|
242
|
+
>
|
|
243
|
+
{selectedValue}
|
|
244
|
+
<i class="fas fa-sort ml-2 h-4 w-4 shrink-0 opacity-50" />
|
|
245
|
+
</Button>
|
|
246
|
+
</Popover.Trigger>
|
|
247
|
+
<Popover.Content class="p-0" sameWidth>
|
|
248
|
+
<Command.Root>
|
|
249
|
+
<Command.Input placeholder="Search framework..." />
|
|
250
|
+
<Command.Empty>No fieldtype found.</Command.Empty>
|
|
251
|
+
<Command.Group>
|
|
252
|
+
{#each field_types as fieldtype_item}
|
|
253
|
+
<Command.Item
|
|
254
|
+
value={fieldtype_item.value}
|
|
255
|
+
onSelect={(newValue) => select_field_type(newValue, ids.trigger)}
|
|
256
|
+
class={value.fieldtype === fieldtype_item.value ? "bg-primary-100" : ""}
|
|
257
|
+
>
|
|
258
|
+
{fieldtype_item.label}
|
|
259
|
+
</Command.Item>
|
|
260
|
+
{/each}
|
|
261
|
+
</Command.Group>
|
|
262
|
+
</Command.Root>
|
|
263
|
+
</Popover.Content>
|
|
264
|
+
</Popover.Root>
|
|
265
|
+
<!-- basic props -->
|
|
266
|
+
<Collapsible.Root open={true} class="w-full">
|
|
267
|
+
<Collapsible.Trigger asChild let:builder>
|
|
268
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
269
|
+
<Label>Basic Info</Label>
|
|
270
|
+
|
|
271
|
+
<i class="fa fa-sort" />
|
|
272
|
+
</Button>
|
|
273
|
+
</Collapsible.Trigger>
|
|
274
|
+
|
|
275
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2">
|
|
276
|
+
<div>
|
|
277
|
+
<Label for="title">Title</Label>
|
|
278
|
+
<Input
|
|
279
|
+
id="title"
|
|
280
|
+
placeholder="Optional custom title for the field"
|
|
281
|
+
bind:value={value.title}
|
|
282
|
+
/>
|
|
283
|
+
</div>
|
|
284
|
+
<div class="w-full flex items-center space-x-2">
|
|
285
|
+
<Checkbox id="without_value_details" bind:checked={value.without_value_details} />
|
|
286
|
+
<Label for="without_value_details">Without Value Details</Label>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="w-full flex items-center space-x-2">
|
|
289
|
+
<Checkbox id="hide_label" bind:checked={value.hide_label} />
|
|
290
|
+
<Label for="hide_label">Hide Label</Label>
|
|
291
|
+
</div>
|
|
292
|
+
<div>
|
|
293
|
+
<Label for="help">Help</Label>
|
|
294
|
+
<Textarea
|
|
295
|
+
id="help"
|
|
296
|
+
placeholder="Optional help text for the field"
|
|
297
|
+
bind:value={value.help}
|
|
298
|
+
/>
|
|
299
|
+
</div>
|
|
300
|
+
</Collapsible.Content>
|
|
301
|
+
</Collapsible.Root>
|
|
302
|
+
<hr />
|
|
303
|
+
<!-- params -->
|
|
304
|
+
<Collapsible.Root open={true} class="w-full">
|
|
305
|
+
<Collapsible.Trigger asChild let:builder>
|
|
306
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
307
|
+
<Label>Params</Label>
|
|
308
|
+
|
|
309
|
+
<i class="fa fa-sort" />
|
|
310
|
+
</Button>
|
|
311
|
+
</Collapsible.Trigger>
|
|
312
|
+
|
|
313
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2 pt-2">
|
|
314
|
+
{@const field_param_spec = field_params_spec_lookup[value.fieldtype ?? "unknown"]}
|
|
315
|
+
{#if field_param_spec}
|
|
316
|
+
<Form
|
|
317
|
+
initial_form={field_param_spec}
|
|
318
|
+
form={params_store}
|
|
319
|
+
attachments={$fieldStore.attachmentsStore}
|
|
320
|
+
/>
|
|
321
|
+
{:else}
|
|
322
|
+
<span class="text-muted-foreground text-xs">No params available for this fieldtype.</span>
|
|
323
|
+
{/if}
|
|
324
|
+
</Collapsible.Content>
|
|
325
|
+
</Collapsible.Root>
|
|
326
|
+
<hr />
|
|
327
|
+
<!-- details -->
|
|
328
|
+
<Collapsible.Root open={false} class="w-full">
|
|
329
|
+
<Collapsible.Trigger asChild let:builder>
|
|
330
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
331
|
+
<Label>Details</Label>
|
|
332
|
+
|
|
333
|
+
<i class="fa fa-sort" />
|
|
334
|
+
</Button>
|
|
335
|
+
</Collapsible.Trigger>
|
|
336
|
+
|
|
337
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2">
|
|
338
|
+
<div>
|
|
339
|
+
<Label for="keyname">Keyname</Label>
|
|
340
|
+
<Input
|
|
341
|
+
id="keyname"
|
|
342
|
+
placeholder="Custom key underwhich to store the value"
|
|
343
|
+
bind:value={value.details.keyname}
|
|
344
|
+
/>
|
|
345
|
+
</div>
|
|
346
|
+
<div>
|
|
347
|
+
<Label for="data_path">Data Path</Label>
|
|
348
|
+
<Input
|
|
349
|
+
id="data_path"
|
|
350
|
+
placeholder="Optional custom data path for the field"
|
|
351
|
+
bind:value={value.details.data_path}
|
|
352
|
+
/>
|
|
353
|
+
</div>
|
|
354
|
+
</Collapsible.Content>
|
|
355
|
+
</Collapsible.Root>
|
|
356
|
+
<hr />
|
|
357
|
+
<!-- initial value -->
|
|
358
|
+
<Collapsible.Root open={false} class="w-full">
|
|
359
|
+
<Collapsible.Trigger asChild let:builder>
|
|
360
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
361
|
+
<Label>Initial Value</Label>
|
|
362
|
+
|
|
363
|
+
<i class="fa fa-sort" />
|
|
364
|
+
</Button>
|
|
365
|
+
</Collapsible.Trigger>
|
|
366
|
+
|
|
367
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2">
|
|
368
|
+
<div>
|
|
369
|
+
<div class="w-full flex items-center space-x-2">
|
|
370
|
+
<Checkbox id="has_default" bind:checked={value.initvalue.has_default} />
|
|
371
|
+
<Label for="has_default">Has Default</Label>
|
|
372
|
+
</div>
|
|
373
|
+
<JsonEditorBound bind:value={value.initvalue.default} />
|
|
374
|
+
</div>
|
|
375
|
+
<div>
|
|
376
|
+
<div class="w-full flex items-center space-x-2">
|
|
377
|
+
<Checkbox id="has_override" bind:checked={value.initvalue.has_override} />
|
|
378
|
+
<Label for="has_override">Has Override</Label>
|
|
379
|
+
</div>
|
|
380
|
+
<JsonEditorBound bind:value={value.initvalue.override} />
|
|
381
|
+
</div>
|
|
382
|
+
</Collapsible.Content>
|
|
383
|
+
</Collapsible.Root>
|
|
384
|
+
<hr />
|
|
385
|
+
<!-- conditions -->
|
|
386
|
+
<Collapsible.Root open={false} class="w-full">
|
|
387
|
+
<Collapsible.Trigger asChild let:builder>
|
|
388
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
389
|
+
<Label>Conditions</Label>
|
|
390
|
+
|
|
391
|
+
<i class="fa fa-sort" />
|
|
392
|
+
</Button>
|
|
393
|
+
</Collapsible.Trigger>
|
|
394
|
+
|
|
395
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2">
|
|
396
|
+
<Button variant="outline" size="icon" class="self-start" on:click={add_condition}>
|
|
397
|
+
<i class="fa fa-plus" />
|
|
398
|
+
</Button>
|
|
399
|
+
|
|
400
|
+
{#if value.conditions && value.conditions.length > 0}
|
|
401
|
+
{#each value.conditions as condition, index}
|
|
402
|
+
<div class="flex items-center space-x-2 w-full">
|
|
403
|
+
<!-- up and down sort buttons -->
|
|
404
|
+
<div class="flex flex-col items-center">
|
|
405
|
+
<Button
|
|
406
|
+
variant="ghost"
|
|
407
|
+
class="h-5 w-5 p-2"
|
|
408
|
+
disabled={index === 0}
|
|
409
|
+
on:click={() => move_condition_up(index)}
|
|
410
|
+
>
|
|
411
|
+
<i class="fa fa-chevron-up" />
|
|
412
|
+
</Button>
|
|
413
|
+
<Button
|
|
414
|
+
variant="ghost"
|
|
415
|
+
class="h-5 w-5 p-2"
|
|
416
|
+
disabled={index === value.conditions.length - 1}
|
|
417
|
+
on:click={() => move_condition_down(index)}
|
|
418
|
+
>
|
|
419
|
+
<i class="fa fa-chevron-down" />
|
|
420
|
+
</Button>
|
|
421
|
+
</div>
|
|
422
|
+
<Input
|
|
423
|
+
placeholder="JSONata condition"
|
|
424
|
+
class="w-full"
|
|
425
|
+
bind:value={value.conditions[index]}
|
|
426
|
+
/>
|
|
427
|
+
<Button
|
|
428
|
+
variant="destructive"
|
|
429
|
+
class="h-5 w-5 p-2"
|
|
430
|
+
on:click={() => remove_condition(index)}
|
|
431
|
+
>
|
|
432
|
+
<i class="fa fa-trash" />
|
|
433
|
+
</Button>
|
|
434
|
+
</div>
|
|
435
|
+
{/each}
|
|
436
|
+
{/if}
|
|
437
|
+
</Collapsible.Content>
|
|
438
|
+
</Collapsible.Root>
|
|
439
|
+
<hr />
|
|
440
|
+
<!-- validations -->
|
|
441
|
+
<Collapsible.Root open={false} class="w-full">
|
|
442
|
+
<Collapsible.Trigger asChild let:builder>
|
|
443
|
+
<Button builders={[builder]} variant="ghost" class="w-full justify-between pl-0">
|
|
444
|
+
<Label>Validations</Label>
|
|
445
|
+
|
|
446
|
+
<i class="fa fa-sort" />
|
|
447
|
+
</Button>
|
|
448
|
+
</Collapsible.Trigger>
|
|
449
|
+
|
|
450
|
+
<Collapsible.Content class="flex flex-col gap-y-2 pl-2">
|
|
451
|
+
<Button variant="outline" size="icon" class="self-start" on:click={add_validation}>
|
|
452
|
+
<i class="fa fa-plus" />
|
|
453
|
+
</Button>
|
|
454
|
+
|
|
455
|
+
{#if value.validations && value.validations.length > 0}
|
|
456
|
+
{#each value.validations as validation, index}
|
|
457
|
+
<div class="flex items-start space-x-2 w-full">
|
|
458
|
+
<!-- up and down sort buttons -->
|
|
459
|
+
<div class="flex flex-col items-center">
|
|
460
|
+
<Button
|
|
461
|
+
variant="ghost"
|
|
462
|
+
class="h-5 w-5 p-2"
|
|
463
|
+
disabled={index === 0}
|
|
464
|
+
on:click={() => move_validation_up(index)}
|
|
465
|
+
>
|
|
466
|
+
<i class="fa fa-chevron-up" />
|
|
467
|
+
</Button>
|
|
468
|
+
<Button
|
|
469
|
+
variant="ghost"
|
|
470
|
+
class="h-5 w-5 p-2"
|
|
471
|
+
disabled={index === value.validations.length - 1}
|
|
472
|
+
on:click={() => move_validation_down(index)}
|
|
473
|
+
>
|
|
474
|
+
<i class="fa fa-chevron-down" />
|
|
475
|
+
</Button>
|
|
476
|
+
</div>
|
|
477
|
+
<div class="w-full flex flex-col items-stretch gap-1">
|
|
478
|
+
<Select.Root
|
|
479
|
+
selected={{
|
|
480
|
+
label: value.validations[index].validationtype,
|
|
481
|
+
value: value.validations[index].validationtype,
|
|
482
|
+
}}
|
|
483
|
+
onSelectedChange={(v) => handle_validation_selected(v, index)}
|
|
484
|
+
>
|
|
485
|
+
<Select.Trigger class="w-full">
|
|
486
|
+
<Select.Value placeholder="Validation Type" />
|
|
487
|
+
</Select.Trigger>
|
|
488
|
+
<Select.Content>
|
|
489
|
+
{#each validation_types as vt}
|
|
490
|
+
<Select.Item value={vt}>{vt}</Select.Item>
|
|
491
|
+
{/each}
|
|
492
|
+
</Select.Content>
|
|
493
|
+
</Select.Root>
|
|
494
|
+
<Input
|
|
495
|
+
placeholder="Invalid Message"
|
|
496
|
+
bind:value={value.validations[index].invalid_message}
|
|
497
|
+
/>
|
|
498
|
+
{#if value.validations[index].validationtype === "regex"}
|
|
499
|
+
<Input
|
|
500
|
+
placeholder="Regex Pattern"
|
|
501
|
+
bind:value={value.validations[index].params.regex}
|
|
502
|
+
/>
|
|
503
|
+
{/if}
|
|
504
|
+
{#if value.validations[index].validationtype === "jsonata"}
|
|
505
|
+
<Input
|
|
506
|
+
placeholder="JSONata Expression"
|
|
507
|
+
bind:value={value.validations[index].params.jsonata}
|
|
508
|
+
/>
|
|
509
|
+
{/if}
|
|
510
|
+
</div>
|
|
511
|
+
<Button
|
|
512
|
+
variant="destructive"
|
|
513
|
+
class="h-5 w-5 p-2"
|
|
514
|
+
on:click={() => remove_validation(index)}
|
|
515
|
+
>
|
|
516
|
+
<i class="fa fa-trash" />
|
|
517
|
+
</Button>
|
|
518
|
+
</div>
|
|
519
|
+
{/each}
|
|
520
|
+
{/if}
|
|
521
|
+
</Collapsible.Content>
|
|
522
|
+
</Collapsible.Root>
|
|
523
|
+
<hr />
|
|
524
|
+
</div>
|
|
525
|
+
<FieldMessage {fieldStore} />
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type Writable } from "svelte/store";
|
|
3
|
+
import { type IBaseField, type IBuiltField } from "../interfaces";
|
|
4
|
+
export interface IFieldBuilderField extends IBaseField<{}> {
|
|
5
|
+
fieldtype: "fieldbuilder";
|
|
6
|
+
}
|
|
7
|
+
declare const __propDef: {
|
|
8
|
+
props: {
|
|
9
|
+
fieldStore: Writable<IBuiltField>;
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
exports?: {} | undefined;
|
|
16
|
+
bindings?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
export type FieldBuilderFieldProps = typeof __propDef.props;
|
|
19
|
+
export type FieldBuilderFieldEvents = typeof __propDef.events;
|
|
20
|
+
export type FieldBuilderFieldSlots = typeof __propDef.slots;
|
|
21
|
+
export default class FieldBuilderField extends SvelteComponent<FieldBuilderFieldProps, FieldBuilderFieldEvents, FieldBuilderFieldSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|