windmill-components 1.57.3 → 1.58.1

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 (35) hide show
  1. package/components/ArgInput.svelte +31 -13
  2. package/components/ArgInput.svelte.d.ts +1 -0
  3. package/components/IconedResourceType.svelte +1 -1
  4. package/components/NumberTypeNarrowing.svelte +19 -0
  5. package/components/NumberTypeNarrowing.svelte.d.ts +17 -0
  6. package/components/Range.svelte +304 -0
  7. package/components/Range.svelte.d.ts +37 -0
  8. package/components/SchemaForm.svelte +1 -0
  9. package/components/Tooltip.svelte +1 -1
  10. package/components/apps/components/helpers/RunnableComponent.svelte +1 -1
  11. package/components/apps/components/helpers/RunnableWrapper.svelte +1 -1
  12. package/components/apps/components/numberInputs/AppSliderInputs.svelte +37 -0
  13. package/components/apps/components/numberInputs/AppSliderInputs.svelte.d.ts +21 -0
  14. package/components/apps/editor/AppEditorHeader.svelte +58 -24
  15. package/components/apps/editor/AppExportButton.svelte +4 -7
  16. package/components/apps/editor/AppExportButton.svelte.d.ts +2 -0
  17. package/components/apps/editor/ComponentEditor.svelte +3 -0
  18. package/components/apps/editor/componentsPanel/data.js +22 -0
  19. package/components/apps/types.d.ts +2 -1
  20. package/components/apps/utils.js +5 -1
  21. package/components/common/table/AppRow.svelte +13 -1
  22. package/components/icons/AppwriteIcon.svelte +18 -0
  23. package/components/icons/AppwriteIcon.svelte.d.ts +17 -0
  24. package/components/icons/LinkdingIcon.svelte +13 -0
  25. package/components/icons/LinkdingIcon.svelte.d.ts +17 -0
  26. package/components/icons/index.d.ts +4 -0
  27. package/components/icons/index.js +4 -0
  28. package/gen/services/AppService.d.ts +1 -5
  29. package/gen/services/WorkspaceService.d.ts +17 -1
  30. package/gen/services/WorkspaceService.js +30 -2
  31. package/package.json +9 -2
  32. package/utils.d.ts +1 -0
  33. package/utils.js +5 -0
  34. package/components/apps/editor/AppPublishButton.svelte +0 -46
  35. package/components/apps/editor/AppPublishButton.svelte.d.ts +0 -19
@@ -1,6 +1,6 @@
1
1
  <script>import { faChevronDown, faChevronUp, faDollarSign, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';
2
2
  import { setInputCat as computeInputCat } from '../utils';
3
- import { Button } from './common';
3
+ import { Badge, Button } from './common';
4
4
  import { createEventDispatcher } from 'svelte';
5
5
  import Icon from 'svelte-awesome';
6
6
  import FieldHeader from './FieldHeader.svelte';
@@ -13,6 +13,8 @@ import SimpleEditor from './SimpleEditor.svelte';
13
13
  import autosize from 'svelte-autosize';
14
14
  import Toggle from './Toggle.svelte';
15
15
  import Password from './Password.svelte';
16
+ import NumberTypeNarrowing from './NumberTypeNarrowing.svelte';
17
+ import Range from './Range.svelte';
16
18
  export let label = '';
17
19
  export let value;
18
20
  export let defaultValue = undefined;
@@ -37,6 +39,7 @@ export let pickForField = undefined;
37
39
  export let variableEditor = undefined;
38
40
  export let itemPicker = undefined;
39
41
  export let noMargin = false;
42
+ export let extra = {};
40
43
  let seeEditable = enum_ != undefined || pattern != undefined;
41
44
  const dispatch = createEventDispatcher();
42
45
  $: maxHeight = maxRows ? `${1 + maxRows * 1.2}em` : `auto`;
@@ -159,6 +162,8 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
159
162
  />
160
163
  {#if type == 'string' && format != 'date-time'}
161
164
  <StringTypeNarrowing bind:format bind:pattern bind:enum_ bind:contentEncoding />
165
+ {:else if type == 'number'}
166
+ <NumberTypeNarrowing bind:min={extra['min']} bind:max={extra['max']} />
162
167
  {:else if type == 'object'}
163
168
  <ObjectTypeNarrowing bind:format />
164
169
  {:else if type == 'array'}
@@ -186,18 +191,31 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
186
191
 
187
192
  <div class="flex space-x-1">
188
193
  {#if inputCat == 'number'}
189
- <input
190
- {autofocus}
191
- on:focus
192
- {disabled}
193
- type="number"
194
- class={valid
195
- ? ''
196
- : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
197
- placeholder={defaultValue ?? ''}
198
- bind:value
199
- on:input={() => dispatch('input', { value, isRaw: true })}
200
- />
194
+ {#if extra['min'] != undefined && extra['max'] != undefined}
195
+ <div class="flex w-full gap-1">
196
+ <span>{extra['min']}</span>
197
+ <div class="grow">
198
+ <Range bind:value min={extra['min']} max={extra['max']} />
199
+ </div>
200
+ <span>{extra['max']}</span>
201
+ <span class="mx-2"><Badge large color="blue">{value}</Badge></span>
202
+ </div>
203
+ {:else}
204
+ <input
205
+ {autofocus}
206
+ on:focus
207
+ {disabled}
208
+ type="number"
209
+ class={valid
210
+ ? ''
211
+ : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}
212
+ placeholder={defaultValue ?? ''}
213
+ bind:value
214
+ min={extra['min']}
215
+ max={extra['max']}
216
+ on:input={() => dispatch('input', { value, isRaw: true })}
217
+ />
218
+ {/if}
201
219
  {:else if inputCat == 'boolean'}
202
220
  <Toggle
203
221
  {disabled}
@@ -35,6 +35,7 @@ declare const __propDef: {
35
35
  variableEditor?: VariableEditor | undefined;
36
36
  itemPicker?: ItemPicker | undefined;
37
37
  noMargin?: boolean | undefined;
38
+ extra?: Record<string, any> | undefined;
38
39
  editor?: SimpleEditor | undefined;
39
40
  evalValueToRaw?: (() => void) | undefined;
40
41
  focus?: (() => void) | undefined;
@@ -17,7 +17,7 @@ $: name_prefix = name.split('_')[0];
17
17
  <svelte:component this={APP_TO_ICON_COMPONENT[name_prefix]} {height} {width} />
18
18
  </span>
19
19
  {:else}
20
- <span style="width: {width}" class="bg-gray-100 rounded-full" />
20
+ <span style="width: {width}; height: {height}" class="bg-gray-100 rounded-full" />
21
21
  {/if}
22
22
  {#if !silent && after}
23
23
  {name}
@@ -0,0 +1,19 @@
1
+ <script>import Toggle from './Toggle.svelte';
2
+ export let min;
3
+ export let max;
4
+ let minChecked = min != undefined;
5
+ let maxChecked = max != undefined;
6
+ </script>
7
+
8
+ <div class="my-2" />
9
+
10
+ <div class="flex flex-col gap-2">
11
+ <div class="flex gap-2">
12
+ <Toggle bind:checked={minChecked} options={{ right: 'min' }} />
13
+ <input type="number" bind:value={min} disabled={!minChecked} />
14
+ </div>
15
+ <div class="flex gap-2">
16
+ <Toggle bind:checked={maxChecked} options={{ right: 'max' }} />
17
+ <input type="number" bind:value={max} disabled={!maxChecked} />
18
+ </div>
19
+ </div>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ min: number | undefined;
5
+ max: number | undefined;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export type NumberTypeNarrowingProps = typeof __propDef.props;
13
+ export type NumberTypeNarrowingEvents = typeof __propDef.events;
14
+ export type NumberTypeNarrowingSlots = typeof __propDef.slots;
15
+ export default class NumberTypeNarrowing extends SvelteComponentTyped<NumberTypeNarrowingProps, NumberTypeNarrowingEvents, NumberTypeNarrowingSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,304 @@
1
+ <script>
2
+ import { createEventDispatcher } from 'svelte'
3
+ import { fly, fade } from 'svelte/transition'
4
+
5
+ // Props
6
+ export let min = 0
7
+ export let max = 100
8
+ export let initialValue = 0
9
+ export let id = null
10
+ export let value = typeof initialValue === 'string' ? parseInt(initialValue) : initialValue
11
+
12
+ // Node Bindings
13
+ let container = null
14
+ let thumb = null
15
+ let progressBar = null
16
+ let element = null
17
+
18
+ // Internal State
19
+ let elementX = null
20
+ let currentThumb = null
21
+ let holding = false
22
+ let thumbHover = false
23
+ let keydownAcceleration = 0
24
+ let accelerationTimer = null
25
+
26
+ // Dispatch 'change' events
27
+ const dispatch = createEventDispatcher()
28
+
29
+ // Mouse shield used onMouseDown to prevent any mouse events penetrating other elements,
30
+ // ie. hover events on other elements while dragging. Especially for Safari
31
+ const mouseEventShield = document.createElement('div')
32
+ mouseEventShield.setAttribute('class', 'mouse-over-shield')
33
+ mouseEventShield.addEventListener('mouseover', (e) => {
34
+ e.preventDefault()
35
+ e.stopPropagation()
36
+ })
37
+
38
+ function resizeWindow() {
39
+ elementX = element.getBoundingClientRect().left
40
+ }
41
+
42
+ // Allows both bind:value and on:change for parent value retrieval
43
+ function setValue(val) {
44
+ value = val
45
+ dispatch('change', { value })
46
+ }
47
+
48
+ function onTrackEvent(e) {
49
+ // Update value immediately before beginning drag
50
+ updateValueOnEvent(e)
51
+ onDragStart(e)
52
+ }
53
+
54
+ function onHover(e) {
55
+ thumbHover = thumbHover ? false : true
56
+ }
57
+
58
+ function onDragStart(e) {
59
+ // If mouse event add a pointer events shield
60
+ if (e.type === 'mousedown') document.body.append(mouseEventShield)
61
+ currentThumb = thumb
62
+ }
63
+
64
+ function onDragEnd(e) {
65
+ // If using mouse - remove pointer event shield
66
+ if (e.type === 'mouseup') {
67
+ if (document.body.contains(mouseEventShield)) document.body.removeChild(mouseEventShield)
68
+ // Needed to check whether thumb and mouse overlap after shield removed
69
+ if (isMouseInElement(e, thumb)) thumbHover = true
70
+ }
71
+ currentThumb = null
72
+ }
73
+
74
+ // Check if mouse event cords overlay with an element's area
75
+ function isMouseInElement(event, element) {
76
+ let rect = element.getBoundingClientRect()
77
+ let { clientX: x, clientY: y } = event
78
+ if (x < rect.left || x >= rect.right) return false
79
+ if (y < rect.top || y >= rect.bottom) return false
80
+ return true
81
+ }
82
+
83
+ // Accessible keypress handling
84
+ function onKeyPress(e) {
85
+ // Max out at +/- 10 to value per event (50 events / 5)
86
+ // 100 below is to increase the amount of events required to reach max velocity
87
+ if (keydownAcceleration < 50) keydownAcceleration++
88
+ let throttled = Math.ceil(keydownAcceleration / 5)
89
+
90
+ if (e.key === 'ArrowUp' || e.key === 'ArrowRight') {
91
+ if (value + throttled > max || value >= max) {
92
+ setValue(max)
93
+ } else {
94
+ setValue(value + throttled)
95
+ }
96
+ }
97
+ if (e.key === 'ArrowDown' || e.key === 'ArrowLeft') {
98
+ if (value - throttled < min || value <= min) {
99
+ setValue(min)
100
+ } else {
101
+ setValue(value - throttled)
102
+ }
103
+ }
104
+
105
+ // Reset acceleration after 100ms of no events
106
+ clearTimeout(accelerationTimer)
107
+ accelerationTimer = setTimeout(() => (keydownAcceleration = 1), 100)
108
+ }
109
+
110
+ function calculateNewValue(clientX) {
111
+ // Find distance between cursor and element's left cord (20px / 2 = 10px) - Center of thumb
112
+ let delta = clientX - (elementX + 10)
113
+
114
+ // Use width of the container minus (5px * 2 sides) offset for percent calc
115
+ let percent = (delta * 100) / (container.clientWidth - 10)
116
+
117
+ // Limit percent 0 -> 100
118
+ percent = percent < 0 ? 0 : percent > 100 ? 100 : percent
119
+
120
+ // Limit value min -> max
121
+ setValue(Math.round((percent * (max - min)) / 100 + min))
122
+ }
123
+
124
+ // Handles both dragging of touch/mouse as well as simple one-off click/touches
125
+ function updateValueOnEvent(e) {
126
+ // touchstart && mousedown are one-off updates, otherwise expect a currentPointer node
127
+ if (!currentThumb && e.type !== 'touchstart' && e.type !== 'mousedown') return false
128
+
129
+ if (e.stopPropagation) e.stopPropagation()
130
+ if (e.preventDefault) e.preventDefault()
131
+
132
+ // Get client's x cord either touch or mouse
133
+ const clientX =
134
+ e.type === 'touchmove' || e.type === 'touchstart' ? e.touches[0].clientX : e.clientX
135
+
136
+ calculateNewValue(clientX)
137
+ }
138
+
139
+ // React to left position of element relative to window
140
+ $: if (element) elementX = element.getBoundingClientRect().left
141
+
142
+ // Set a class based on if dragging
143
+ $: holding = Boolean(currentThumb)
144
+
145
+ // Update progressbar and thumb styles to represent value
146
+ $: if (progressBar && thumb) {
147
+ // Limit value min -> max
148
+ value = value > min ? value : min
149
+ value = value < max ? value : max
150
+
151
+ let percent = ((value - min) * 100) / (max - min)
152
+ let offsetLeft = (container.clientWidth - 10) * (percent / 100) + 5
153
+
154
+ // Update thumb position + active range track width
155
+ thumb.style.left = `${offsetLeft}px`
156
+ progressBar.style.width = `${offsetLeft}px`
157
+ }
158
+ </script>
159
+
160
+ <svelte:window
161
+ on:touchmove|nonpassive={updateValueOnEvent}
162
+ on:touchcancel={onDragEnd}
163
+ on:touchend={onDragEnd}
164
+ on:mousemove={updateValueOnEvent}
165
+ on:mouseup={onDragEnd}
166
+ on:resize={resizeWindow}
167
+ />
168
+ <div class="range">
169
+ <div
170
+ class="range__wrapper"
171
+ tabindex="0"
172
+ on:keydown={onKeyPress}
173
+ bind:this={element}
174
+ role="slider"
175
+ aria-valuemin={min}
176
+ aria-valuemax={max}
177
+ aria-valuenow={value}
178
+ {id}
179
+ on:pointerdown|stopPropagation
180
+ on:mousedown|stopPropagation={onTrackEvent}
181
+ on:touchstart|stopPropagation={onTrackEvent}
182
+ >
183
+ <div class="range__track" bind:this={container}>
184
+ <div class="range__track--highlighted" bind:this={progressBar} />
185
+ <div
186
+ class="range__thumb"
187
+ class:range__thumb--holding={holding}
188
+ bind:this={thumb}
189
+ on:touchstart={onDragStart}
190
+ on:mousedown={onDragStart}
191
+ on:mouseover={() => (thumbHover = true)}
192
+ on:mouseout={() => (thumbHover = false)}
193
+ >
194
+ {#if holding || thumbHover}
195
+ <div class="range__tooltip" in:fly={{ y: 7, duration: 200 }} out:fade={{ duration: 100 }}>
196
+ {value}
197
+ </div>
198
+ {/if}
199
+ </div>
200
+ </div>
201
+ </div>
202
+ </div>
203
+
204
+ <svelte:head>
205
+ <style>
206
+ .mouse-over-shield {
207
+ position: fixed;
208
+ top: 0px;
209
+ left: 0px;
210
+ height: 100%;
211
+ width: 100%;
212
+ background-color: rgba(255, 0, 0, 0);
213
+ z-index: 10000;
214
+ cursor: grabbing;
215
+ }</style>
216
+ </svelte:head>
217
+
218
+ <style>
219
+ .range {
220
+ position: relative;
221
+ flex: 1;
222
+ }
223
+
224
+ .range__wrapper {
225
+ min-width: 100%;
226
+ position: relative;
227
+ padding: 0.5rem;
228
+ box-sizing: border-box;
229
+ outline: none;
230
+ }
231
+
232
+ .range__wrapper:focus-visible > .range__track {
233
+ box-shadow: 0 0 0 2px white, 0 0 0 3px var(--track-focus, #6185ff);
234
+ }
235
+
236
+ .range__track {
237
+ height: 6px;
238
+ background-color: var(--track-bgcolor, #d0d0d0);
239
+ border-radius: 999px;
240
+ }
241
+
242
+ .range__track--highlighted {
243
+ background-color: var(--track-highlight-bgcolor, #6185ff);
244
+ background: var(--track-highlight-bg, linear-gradient(90deg, #6185ff, #9c65ff));
245
+ width: 0;
246
+ height: 6px;
247
+ position: absolute;
248
+ border-radius: 999px;
249
+ }
250
+
251
+ .range__thumb {
252
+ display: flex;
253
+ align-items: center;
254
+ justify-content: center;
255
+ position: absolute;
256
+ width: 20px;
257
+ height: 20px;
258
+ background-color: var(--thumb-bgcolor, white);
259
+ cursor: pointer;
260
+ border-radius: 999px;
261
+ margin-top: -8px;
262
+ transition: box-shadow 100ms;
263
+ -webkit-user-select: none;
264
+ -moz-user-select: none;
265
+ user-select: none;
266
+ box-shadow: var(
267
+ --thumb-boxshadow,
268
+ 0 1px 1px 0 rgba(0, 0, 0, 0.14),
269
+ 0 0px 2px 1px rgba(0, 0, 0, 0.2)
270
+ );
271
+ }
272
+
273
+ .range__thumb--holding {
274
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 2px 1px rgba(0, 0, 0, 0.2),
275
+ 0 0 0 6px var(--thumb-holding-outline, rgba(113, 119, 250, 0.3));
276
+ }
277
+
278
+ .range__tooltip {
279
+ pointer-events: none;
280
+ position: absolute;
281
+ top: -33px;
282
+ color: var(--tooltip-text, white);
283
+ width: 38px;
284
+ padding: 4px 0;
285
+ border-radius: 4px;
286
+ text-align: center;
287
+ background-color: var(--tooltip-bgcolor, #6185ff);
288
+ background: var(--tooltip-bg, linear-gradient(45deg, #6185ff, #9c65ff));
289
+ }
290
+
291
+ .range__tooltip::after {
292
+ content: '';
293
+ display: block;
294
+ position: absolute;
295
+ height: 7px;
296
+ width: 7px;
297
+ background-color: var(--tooltip-bgcolor, #6185ff);
298
+ bottom: -3px;
299
+ left: calc(50% - 3px);
300
+ -webkit-clip-path: polygon(0% 0%, 100% 100%, 0% 100%);
301
+ clip-path: polygon(0% 0%, 100% 100%, 0% 100%);
302
+ transform: rotate(-45deg);
303
+ border-radius: 0 0 0 3px;
304
+ }</style>
@@ -0,0 +1,37 @@
1
+ /** @typedef {typeof __propDef.props} RangeProps */
2
+ /** @typedef {typeof __propDef.events} RangeEvents */
3
+ /** @typedef {typeof __propDef.slots} RangeSlots */
4
+ export default class Range extends SvelteComponentTyped<{
5
+ value?: number | undefined;
6
+ id?: null | undefined;
7
+ min?: number | undefined;
8
+ max?: number | undefined;
9
+ initialValue?: number | undefined;
10
+ }, {
11
+ pointerdown: PointerEvent;
12
+ change: CustomEvent<any>;
13
+ } & {
14
+ [evt: string]: CustomEvent<any>;
15
+ }, {}> {
16
+ }
17
+ export type RangeProps = typeof __propDef.props;
18
+ export type RangeEvents = typeof __propDef.events;
19
+ export type RangeSlots = typeof __propDef.slots;
20
+ import { SvelteComponentTyped } from "svelte";
21
+ declare const __propDef: {
22
+ props: {
23
+ value?: number | undefined;
24
+ id?: null | undefined;
25
+ min?: number | undefined;
26
+ max?: number | undefined;
27
+ initialValue?: number | undefined;
28
+ };
29
+ events: {
30
+ pointerdown: PointerEvent;
31
+ change: CustomEvent<any>;
32
+ } & {
33
+ [evt: string]: CustomEvent<any>;
34
+ };
35
+ slots: {};
36
+ };
37
+ export {};
@@ -86,6 +86,7 @@ let variableEditor = undefined;
86
86
  {variableEditor}
87
87
  {itemPicker}
88
88
  bind:pickForField
89
+ bind:extra={schema.properties[argName]}
89
90
  />
90
91
  {:else}
91
92
  Expected argument to be an object, got {JSON.stringify(args)} instead
@@ -3,7 +3,7 @@ import Icon from 'svelte-awesome';
3
3
  import Popover from './Popover.svelte';
4
4
  </script>
5
5
 
6
- <Popover notClickable class="flex">
6
+ <Popover notClickable>
7
7
  <Icon
8
8
  class="text-gray-500 font-thin inline-block align-middle w-4"
9
9
  data={faInfoCircle}
@@ -32,7 +32,7 @@ let executeTimeout = undefined;
32
32
  function setDebouncedExecute() {
33
33
  executeTimeout && clearTimeout(executeTimeout);
34
34
  executeTimeout = setTimeout(() => {
35
- executeComponent();
35
+ executeComponent(true);
36
36
  }, 200);
37
37
  }
38
38
  function computeStaticValues() {
@@ -11,7 +11,7 @@ export let autoRefresh = true;
11
11
  export let runnableComponent = undefined;
12
12
  export let forceSchemaDisplay = false;
13
13
  const { staticExporter, noBackend } = getContext('AppEditorContext');
14
- if (noBackend) {
14
+ if (noBackend && componentInput?.type == 'runnable') {
15
15
  result = componentInput?.['value'];
16
16
  }
17
17
  onMount(() => {
@@ -0,0 +1,37 @@
1
+ <script>import { Badge } from '../../../common';
2
+ import Range from '../../../Range.svelte';
3
+ import { getContext } from 'svelte';
4
+ import AlignWrapper from '../helpers/AlignWrapper.svelte';
5
+ import InputValue from '../helpers/InputValue.svelte';
6
+ export let id;
7
+ export let configuration;
8
+ export let verticalAlignment = undefined;
9
+ export const staticOutputs = ['result'];
10
+ const { worldStore } = getContext('AppEditorContext');
11
+ let value;
12
+ let min = 0;
13
+ let max = 42;
14
+ $: outputs = $worldStore?.outputsById[id];
15
+ $: if (value || !value) {
16
+ // Disallow 'e' character in numbers
17
+ // if(value && value.toString().includes('e')) {
18
+ // value = +value.toString().replaceAll('e', '')
19
+ // }
20
+ const num = isNaN(+value) ? null : +value;
21
+ outputs?.result.set(num);
22
+ }
23
+ </script>
24
+
25
+ <InputValue {id} input={configuration.min} bind:value={min} />
26
+ <InputValue {id} input={configuration.max} bind:value={max} />
27
+
28
+ <AlignWrapper {verticalAlignment}>
29
+ <div class="flex w-full gap-1 px-1">
30
+ <span>{min}</span>
31
+ <div class="grow">
32
+ <Range bind:value {min} {max} />
33
+ </div>
34
+ <span>{max}</span>
35
+ <span class="mx-2"><Badge large color="blue">{value}</Badge></span>
36
+ </div>
37
+ </AlignWrapper>
@@ -0,0 +1,21 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { AppInput } from '../../inputType';
3
+ declare const __propDef: {
4
+ props: {
5
+ id: string;
6
+ configuration: Record<string, AppInput>;
7
+ verticalAlignment?: 'top' | 'center' | 'bottom' | undefined;
8
+ staticOutputs?: string[] | undefined;
9
+ };
10
+ events: {
11
+ [evt: string]: CustomEvent<any>;
12
+ };
13
+ slots: {};
14
+ };
15
+ export type AppSliderInputsProps = typeof __propDef.props;
16
+ export type AppSliderInputsEvents = typeof __propDef.events;
17
+ export type AppSliderInputsSlots = typeof __propDef.slots;
18
+ export default class AppSliderInputs extends SvelteComponentTyped<AppSliderInputsProps, AppSliderInputsEvents, AppSliderInputsSlots> {
19
+ get staticOutputs(): string[];
20
+ }
21
+ export {};
@@ -7,6 +7,7 @@ import Skeleton from '../../common/skeleton/Skeleton.svelte';
7
7
  import ToggleButton from '../../common/toggleButton/ToggleButton.svelte';
8
8
  import ToggleButtonGroup from '../../common/toggleButton/ToggleButtonGroup.svelte';
9
9
  import DisplayResult from '../../DisplayResult.svelte';
10
+ import Dropdown from '../../Dropdown.svelte';
10
11
  import FlowProgressBar from '../../flows/FlowProgressBar.svelte';
11
12
  import FlowStatusViewer from '../../FlowStatusViewer.svelte';
12
13
  import JobArgs from '../../JobArgs.svelte';
@@ -17,14 +18,13 @@ import Toggle from '../../Toggle.svelte';
17
18
  import Tooltip from '../../Tooltip.svelte';
18
19
  import { AppService, Job, Policy } from '../../../gen';
19
20
  import { userStore, workspaceStore } from '../../../stores';
20
- import { faBug, faClipboard, faExternalLink, faSave } from '@fortawesome/free-solid-svg-icons';
21
- import { AlignHorizontalSpaceAround, Expand, Eye, Laptop2, Loader2, Pencil, Smartphone } from 'lucide-svelte';
21
+ import { faBug, faClipboard, faExternalLink, faFileExport, faGlobe, faSave } from '@fortawesome/free-solid-svg-icons';
22
+ import { AlignHorizontalSpaceAround, Expand, Eye, Laptop2, Loader2, MoreVertical, Pencil, Smartphone } from 'lucide-svelte';
22
23
  import { getContext } from 'svelte';
23
24
  import { Icon } from 'svelte-awesome';
24
25
  import { Pane, Splitpanes } from 'svelte-splitpanes';
25
- import { classNames, copyToClipboard, sendUserToast } from '../../../utils';
26
+ import { appToHubUrl, classNames, copyToClipboard, sendUserToast } from '../../../utils';
26
27
  import AppExportButton from './AppExportButton.svelte';
27
- import AppPublishButton from './AppPublishButton.svelte';
28
28
  import PanelSection from './settingsPanel/common/PanelSection.svelte';
29
29
  async function hash(message) {
30
30
  const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
@@ -41,12 +41,23 @@ const loading = {
41
41
  };
42
42
  let newPath = '';
43
43
  let pathError = undefined;
44
+ let appExport;
44
45
  let saveDrawerOpen = false;
45
46
  let jobsDrawerOpen = false;
46
47
  let publishDrawerOpen = false;
47
48
  function closeSaveDrawer() {
48
49
  saveDrawerOpen = false;
49
50
  }
51
+ function toStatic() {
52
+ const newApp = JSON.parse(JSON.stringify($app));
53
+ newApp.grid.forEach((x) => {
54
+ let c = x.data;
55
+ if (c.componentInput?.type == 'runnable') {
56
+ c.componentInput.value = $staticExporter[x.id]();
57
+ }
58
+ });
59
+ return { app: newApp, summary: $summary };
60
+ }
50
61
  async function computeTriggerables() {
51
62
  const allTriggers = await Promise.all($app.grid.map(async (x) => {
52
63
  let c = x.data;
@@ -307,7 +318,7 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
307
318
  </Drawer>
308
319
 
309
320
  <div
310
- class="border-b flex flex-row justify-between py-1 gap-4 overflow-x-auto gap-y-2 px-4 items-center"
321
+ class="border-b flex flex-row justify-between py-1 gap-4 gap-y-2 px-4 items-center overflow-y-visible"
311
322
  >
312
323
  <div class="min-w-64 w-64">
313
324
  <input type="text" placeholder="App summary" class="text-sm w-full" bind:value={$summary} />
@@ -318,11 +329,13 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
318
329
  <ToggleButton position="left" value="dnd" size="xs">
319
330
  <div class="inline-flex gap-1 items-center">
320
331
  <Pencil size={14} />
321
- Editor
332
+ <span class="hidden md:inline">Editor</span>
322
333
  </div>
323
334
  </ToggleButton>
324
335
  <ToggleButton position="right" value="preview" size="xs">
325
- <div class="inline-flex gap-1 items-center"> <Eye size={14} /> Preview</div>
336
+ <div class="inline-flex gap-1 items-center">
337
+ <Eye size={14} /> <span class="hidden md:inline">Preview</span>
338
+ </div>
326
339
  </ToggleButton>
327
340
  </ToggleButtonGroup>
328
341
  </div>
@@ -337,7 +350,7 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
337
350
  </ToggleButtonGroup>
338
351
  </div>
339
352
 
340
- <span class="hidden lg:block">
353
+ <div class="hidden lg:block">
341
354
  <ToggleButtonGroup bind:selected={$app.fullscreen}>
342
355
  <ToggleButton position="left" value={false} size="xs">
343
356
  <div class="flex gap-1 justify-start">
@@ -352,23 +365,44 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
352
365
  <Expand size={14} />
353
366
  </ToggleButton>
354
367
  </ToggleButtonGroup>
355
- </span>
368
+ </div>
356
369
  </div>
357
- <div class="flex flex-row grow gap-2 justify-end items-center">
358
- <Button
359
- on:click={() => (jobsDrawerOpen = true)}
360
- color="light"
361
- size="xs"
362
- variant="border"
363
- startIcon={{ icon: faBug }}
370
+ <div class="flex flex-row grow gap-2 justify-end items-center overflow-visible">
371
+ <Dropdown
372
+ placement="bottom-end"
373
+ btnClasses="!text-gray-700 !bg-transparent hover:!bg-gray-400/20 !p-[6px] hidden lg:block"
374
+ dropdownItems={[
375
+ {
376
+ displayName: 'JSON',
377
+ icon: faFileExport,
378
+ action: () => {
379
+ appExport.open()
380
+ }
381
+ },
382
+ {
383
+ displayName: 'Publish to Hub',
384
+ icon: faGlobe,
385
+ action: () => {
386
+ const url = appToHubUrl(toStatic())
387
+ window.open(url.toString(), '_blank')
388
+ }
389
+ }
390
+ ]}
364
391
  >
365
- Debug Runs
366
- </Button>
367
- <span class="hidden lg:inline-flex gap-1">
368
- <AppPublishButton summary={$summary} staticExporter={$staticExporter} app={$app} />
369
- <AppExportButton app={$app} />
392
+ <MoreVertical size={20} />
393
+ </Dropdown>
394
+ <span class="hidden md:inline">
395
+ <Button
396
+ on:click={() => (jobsDrawerOpen = true)}
397
+ color="light"
398
+ size="xs"
399
+ variant="border"
400
+ startIcon={{ icon: faBug }}
401
+ >
402
+ <span class="hidden md:inline">Debug Runs</span>
403
+ </Button>
370
404
  </span>
371
-
405
+ <AppExportButton bind:this={appExport} app={$app} />
372
406
  <Button
373
407
  on:click={() => (publishDrawerOpen = true)}
374
408
  color="light"
@@ -376,7 +410,7 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
376
410
  variant="border"
377
411
  startIcon={{ icon: faExternalLink }}
378
412
  >
379
- Publish
413
+ <span class="hidden md:inline">Publish</span>
380
414
  </Button>
381
415
  <Button
382
416
  loading={loading.save}
@@ -385,7 +419,7 @@ $: selectedJobId && testJobLoader?.watchJob(selectedJobId);
385
419
  color="dark"
386
420
  size="xs"
387
421
  >
388
- Save
422
+ <span class="hidden md:inline">Save</span>
389
423
  </Button>
390
424
  </div>
391
425
  </div>
@@ -1,20 +1,17 @@
1
1
  <script>import Drawer from '../../common/drawer/Drawer.svelte';
2
2
  import DrawerContent from '../../common/drawer/DrawerContent.svelte';
3
3
  import { copyToClipboard } from '../../../utils';
4
- import { faClipboard, faFileExport } from '@fortawesome/free-solid-svg-icons';
5
- import Icon from 'svelte-awesome';
4
+ import { faClipboard } from '@fortawesome/free-solid-svg-icons';
6
5
  import { Highlight } from 'svelte-highlight';
7
6
  import json from 'svelte-highlight/languages/json';
8
7
  import { Button } from '../../common';
9
8
  let jsonViewerDrawer;
9
+ export function open() {
10
+ jsonViewerDrawer?.toggleDrawer();
11
+ }
10
12
  export let app;
11
13
  </script>
12
14
 
13
- <Button size="xs" variant="border" color="light" on:click={() => jsonViewerDrawer.toggleDrawer()}>
14
- <Icon data={faFileExport} scale={0.6} class="inline mr-2" />
15
- JSON
16
- </Button>
17
-
18
15
  <Drawer bind:this={jsonViewerDrawer} size="800px">
19
16
  <DrawerContent title="App JSON" on:close={() => jsonViewerDrawer.toggleDrawer()}>
20
17
  <div class="relative">
@@ -2,6 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  import type { App } from '../types';
3
3
  declare const __propDef: {
4
4
  props: {
5
+ open?: (() => void) | undefined;
5
6
  app: App;
6
7
  };
7
8
  events: {
@@ -13,5 +14,6 @@ export type AppExportButtonProps = typeof __propDef.props;
13
14
  export type AppExportButtonEvents = typeof __propDef.events;
14
15
  export type AppExportButtonSlots = typeof __propDef.slots;
15
16
  export default class AppExportButton extends SvelteComponentTyped<AppExportButtonProps, AppExportButtonEvents, AppExportButtonSlots> {
17
+ get open(): () => void;
16
18
  }
17
19
  export {};
@@ -16,6 +16,7 @@ import AppForm from '../components/form/AppForm.svelte';
16
16
  import AppScatterChart from '../components/dataDisplay/AppScatterChart.svelte';
17
17
  import AppTimeseries from '../components/dataDisplay/AppTimeseries.svelte';
18
18
  import AppHtml from '../components/dataDisplay/AppHtml.svelte';
19
+ import AppSliderInputs from '../components/numberInputs/AppSliderInputs.svelte';
19
20
  export let component;
20
21
  export let selected;
21
22
  export let locked = false;
@@ -130,6 +131,8 @@ const { staticOutputs, mode, connectingInput } = getContext('AppEditorContext');
130
131
  />
131
132
  {:else if component.type === 'numberinputcomponent'}
132
133
  <NumberInputComponent {...component} bind:staticOutputs={$staticOutputs[component.id]} />
134
+ {:else if component.type === 'slidercomponent'}
135
+ <AppSliderInputs {...component} bind:staticOutputs={$staticOutputs[component.id]} />
133
136
  {/if}
134
137
  </div>
135
138
  </div>
@@ -50,6 +50,28 @@ const inputs = {
50
50
  },
51
51
  card: false
52
52
  },
53
+ {
54
+ softWrap: true,
55
+ verticalAlignment: 'center',
56
+ id: 'slidercomponent',
57
+ type: 'slidercomponent',
58
+ componentInput: undefined,
59
+ configuration: {
60
+ min: {
61
+ type: 'static',
62
+ value: 0,
63
+ fieldType: 'number',
64
+ onlyStatic: true,
65
+ },
66
+ max: {
67
+ type: 'static',
68
+ value: 42,
69
+ fieldType: 'number',
70
+ onlyStatic: true,
71
+ },
72
+ },
73
+ card: false
74
+ },
53
75
  {
54
76
  softWrap: true,
55
77
  verticalAlignment: 'center',
@@ -12,6 +12,7 @@ export type TextInputComponent = BaseComponent<'textinputcomponent'>;
12
12
  export type PasswordInputComponent = BaseComponent<'passwordinputcomponent'>;
13
13
  export type DateInputComponent = BaseComponent<'dateinputcomponent'>;
14
14
  export type NumberInputComponent = BaseComponent<'numberinputcomponent'>;
15
+ export type SliderComponent = BaseComponent<'slidercomponent'>;
15
16
  export type HtmlComponent = BaseComponent<'htmlcomponent'>;
16
17
  export type TimeseriesComponent = BaseComponent<'timeseriescomponent'>;
17
18
  export type ButtonComponent = BaseComponent<'buttoncomponent'> & {
@@ -53,7 +54,7 @@ export interface BaseAppComponent extends Partial<Aligned> {
53
54
  */
54
55
  softWrap?: boolean;
55
56
  }
56
- export type AppComponent = BaseAppComponent & (RunFormComponent | DisplayComponent | TextInputComponent | PasswordInputComponent | DateInputComponent | NumberInputComponent | BarChartComponent | TimeseriesComponent | HtmlComponent | TableComponent | TextComponent | TableComponent | ButtonComponent | PieChartComponent | ScatterChartComponent | ImageComponent | InputComponent | SelectComponent | CheckboxComponent | RadioComponent | FormComponent);
57
+ export type AppComponent = BaseAppComponent & (RunFormComponent | DisplayComponent | TextInputComponent | PasswordInputComponent | DateInputComponent | NumberInputComponent | SliderComponent | BarChartComponent | TimeseriesComponent | HtmlComponent | TableComponent | TextComponent | TableComponent | ButtonComponent | PieChartComponent | ScatterChartComponent | ImageComponent | InputComponent | SelectComponent | CheckboxComponent | RadioComponent | FormComponent);
57
58
  export type ComponentSet = {
58
59
  title: string;
59
60
  components: AppComponent[];
@@ -1,6 +1,6 @@
1
1
  import { FlowService, ScriptService } from '../../gen';
2
2
  import { inferArgs } from '../../infer';
3
- import { BarChart4, Binary, CircleDot, FormInput, Inspect, List, Monitor, PieChart, Play, Table2, Image, TextCursorInput, Type, Lock, Calendar, ToggleLeft, GripHorizontal, Code2 } from 'lucide-svelte';
3
+ import { BarChart4, Binary, CircleDot, FormInput, Inspect, List, Monitor, PieChart, Play, Table2, Image, TextCursorInput, Type, Lock, Calendar, ToggleLeft, GripHorizontal, Code2, SlidersHorizontal } from 'lucide-svelte';
4
4
  export async function loadSchema(workspace, path, runType) {
5
5
  if (runType === 'script') {
6
6
  const script = await ScriptService.getScriptByPath({
@@ -113,6 +113,10 @@ export const displayData = {
113
113
  name: 'Number',
114
114
  icon: Binary
115
115
  },
116
+ slidercomponent: {
117
+ name: 'Slider',
118
+ icon: SlidersHorizontal
119
+ },
116
120
  passwordinputcomponent: {
117
121
  name: 'Password',
118
122
  icon: Lock
@@ -2,7 +2,7 @@
2
2
  import SharedBadge from '../../SharedBadge.svelte';
3
3
  import { AppService } from '../../../gen';
4
4
  import { userStore, workspaceStore } from '../../../stores';
5
- import { faEdit, faEye, faFileExport, faPen, faShare, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
5
+ import { faCodeFork, faEdit, faEye, faFileExport, faPen, faShare, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
6
6
  import { MoreVertical } from 'lucide-svelte';
7
7
  import { createEventDispatcher } from 'svelte';
8
8
  import Button from '../button/Button.svelte';
@@ -44,6 +44,18 @@ const dispatch = createEventDispatcher();
44
44
  Edit
45
45
  </Button>
46
46
  </div>
47
+ {:else}
48
+ <div>
49
+ <Button
50
+ color="light"
51
+ size="xs"
52
+ variant="border"
53
+ startIcon={{ icon: faCodeFork }}
54
+ href="/apps/add?template={path}"
55
+ >
56
+ Fork
57
+ </Button>
58
+ </div>
47
59
  {/if}
48
60
  {/if}
49
61
 
@@ -0,0 +1,18 @@
1
+ <script>export let height = '24px';
2
+ export let width = '24px';
3
+ </script>
4
+
5
+ <svg x="0" y="0" {width} {height} viewBox="0 0 320 213.18964" fill="none" version="1.1" id="svg6">
6
+ <path
7
+ fill-rule="evenodd"
8
+ clip-rule="evenodd"
9
+ d="m 213.428,213.18799 c -19.465,0 -37.711,-5.218 -53.415,-14.332 -11.783,6.82 -24.876,11.384 -38.621,13.306 -27.992004,3.915 -56.393204,-3.451 -78.954904,-20.476 -11.1823,-8.427 -20.5946,-18.974 -27.6991,-31.039 -7.1043998,-12.065 -11.7616998,-25.412 -13.7057998,-39.278 -1.94400001,-13.866 -1.13660001,-27.979001 2.376,-41.533001 3.5126,-13.554 9.6615998,-26.2825 18.0955998,-37.4588 8.434,-11.1764 18.9877,-20.5813 31.0579,-27.6773 12.0703,-7.0959004 25.4203,-11.7438004 39.2883,-13.6781004 13.867004,-1.93420004 27.979004,-1.11690004 41.531004,2.4052 9.353,2.4311 18.313,6.118 26.639,10.9448004 C 175.723,5.2610886 193.966,0.04428856 213.428,0.04428856 272.287,0.04428856 320,47.757389 320,106.61599 c 0,58.859 -47.713,106.572 -106.572,106.572 z m -71.253,-185.825201 0.032,-0.028 c -14.799,-6.6401 -31.29,-9.0605 -47.611004,-6.7781 -22.824,3.1919 -43.4462,15.3201 -57.3285,33.7165 -13.8823,18.3968 -19.888,41.5538 -16.6961,64.378801 3.1919,22.824 15.3201,43.446 33.7165,57.328 18.3961,13.882 41.5541,19.888 64.378104,16.696 22.825,-3.192 43.447,-15.32 57.329,-33.716 13.882,-18.397 19.888,-41.554 16.696,-64.379001 -1.473,-10.53 -4.847,-20.591 -9.862,-29.738 -9.083,-16.4993 -23.372,-29.7302 -40.654,-37.4802 z"
10
+ fill="#000000"
11
+ id="path2"
12
+ />
13
+ <path
14
+ d="m 109.487,69.743989 c -0.128,0.315 -1.757,6.715 -3.512,14.306 -1.821,7.591 -4.707,19.573001 -6.335004,26.662001 -3.14,12.986 -5.022,21.518 -5.022,22.648 0,0.311 1.946,0.565 4.328,0.565 H 103.277 l 1.942,-8.66 c 1.132,-4.704 3.642,-15.495 5.649,-23.964 2.008,-8.470001 4.453,-18.758001 5.396,-22.900001 0.939,-4.141 1.88,-7.902 2.07,-8.342 0.189,-0.564 -0.88,-0.751 -4.141,-0.751 -2.448,0 -4.583,0.187 -4.706,0.436 z m -33.691004,27.165 -5.772,6.275001 1.696,2.006 c 0.938,1.128 3.513,3.953 5.709,6.275 l 4.015,4.264 h 11.418 l -5.394,-5.835 c -2.951,-3.133 -5.398,-6.146 -5.398,-6.522 0,-0.439 2.26,-3.261 5.021,-6.273001 2.759,-3.072 5.018,-5.711 5.018,-6.024 0,-0.251 -2.384,-0.439 -5.269,-0.439 h -5.207 z m 43.916004,-5.898 c 0,0.191 1.067,1.381 2.382,2.699 4.897,4.893 8.347,9.036001 8.158,9.849001 -0.124,0.441 -2.51,3.387 -5.394,6.462 l -5.205,5.708 h 5.832 l 5.835,-0.062 5.33,-5.833 c 2.951,-3.26 5.334,-6.15 5.334,-6.526 0,-0.311 -2.509,-3.261 -5.647,-6.584001 l -5.644,-6.088 h -5.461 c -3.074,0 -5.52,0.188 -5.52,0.375 z"
15
+ fill="#000000"
16
+ id="path4"
17
+ />
18
+ </svg>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ height?: string | undefined;
5
+ width?: string | undefined;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export type AppwriteIconProps = typeof __propDef.props;
13
+ export type AppwriteIconEvents = typeof __propDef.events;
14
+ export type AppwriteIconSlots = typeof __propDef.slots;
15
+ export default class AppwriteIcon extends SvelteComponentTyped<AppwriteIconProps, AppwriteIconEvents, AppwriteIconSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,13 @@
1
+ <script>export let height = '24px';
2
+ export let width = '24px';
3
+ </script>
4
+
5
+ <svg version="1.1" id="svg2" x=0 y=0 {width} {height} viewBox="0 0 56 56">
6
+ <g id="g8">
7
+ <path
8
+ style="fill:#000000"
9
+ d="M 21.934964,54.577686 C -1.2680732,49.62024 -6.9798152,18.503632 12.863299,5.1567822 32.772873,-8.2347712 58.966204,9.2924868 54.765887,33.195885 53.022738,43.115892 43.59487,52.995551 34.461449,54.473328 c -2.2,0.355957 -4.675,0.790728 -5.5,0.966157 -0.825,0.175429 -3.986918,-0.212381 -7.026485,-0.861799 z M 45.071867,32.670208 C 51.629793,25.125635 52.430122,21.8666 49.075771,16.36585 46.719483,12.501807 40.750657,9.5309908 37.156102,10.433166 c -1.449711,0.363855 -7.267103,5.218963 -12.927538,10.78913 -9.143972,8.998151 -10.124574,10.294702 -8.793078,11.626198 1.331496,1.331496 2.599723,0.416811 11.372216,-8.201994 5.862435,-5.759729 10.688216,-9.700615 11.878812,-9.700615 3.447831,0 7.274935,3.794342 7.274935,7.212657 0,2.529244 -1.664895,4.762079 -9.488223,12.724911 -8.933265,9.092559 -9.388707,9.75693 -7.786773,11.358864 1.601934,1.601934 1.958639,1.452934 6.098641,-2.547491 2.418455,-2.336917 7.047503,-7.297996 10.286773,-11.024618 z M 20.243568,44.55131 c 1.769834,-0.767016 7.407067,-5.639768 12.527183,-10.828339 8.223928,-8.333878 9.123338,-9.5881 7.71428,-10.757515 -1.387314,-1.151368 -2.874359,-0.06683 -11.419226,8.328339 -11.100401,10.90593 -13.206314,11.696497 -17.515462,6.575365 -1.423892,-1.692199 -2.5888942,-3.782435 -2.5888942,-4.64497 0,-0.862534 4.5088982,-6.150211 10.0197732,-11.750393 9.53558,-9.69011 9.931944,-10.261632 8.202286,-11.8269512 -1.717047,-1.553906 -2.319947,-1.135176 -10.909762,7.5771182 -5.000752,5.072057 -9.5917812,10.204837 -10.2022872,11.40618 -2.73924,5.390228 0.339025,13.302752 6.1596852,15.833154 4.065039,1.767185 4.136052,1.767965 8.012424,0.08801 z"
10
+ id="path116"
11
+ />
12
+ </g>
13
+ </svg>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ height?: string | undefined;
5
+ width?: string | undefined;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export type LinkdingIconProps = typeof __propDef.props;
13
+ export type LinkdingIconEvents = typeof __propDef.events;
14
+ export type LinkdingIconSlots = typeof __propDef.slots;
15
+ export default class LinkdingIcon extends SvelteComponentTyped<LinkdingIconProps, LinkdingIconEvents, LinkdingIconSlots> {
16
+ }
17
+ export {};
@@ -33,6 +33,8 @@ import NextcloudIcon from './NextcloudIcon.svelte';
33
33
  import FaunadbIcon from './FaunadbIcon.svelte';
34
34
  import ClickhouseIcon from './ClickhouseIcon.svelte';
35
35
  import OpenaiIcon from './OpenaiIcon.svelte';
36
+ import AppwriteIcon from './AppwriteIcon.svelte';
37
+ import LinkdingIconSvelte from './LinkdingIcon.svelte';
36
38
  export declare const APP_TO_ICON_COMPONENT: {
37
39
  readonly postgresql: typeof PostgresIcon;
38
40
  readonly mysql: typeof Mysql;
@@ -72,5 +74,7 @@ export declare const APP_TO_ICON_COMPONENT: {
72
74
  readonly faunadb: typeof FaunadbIcon;
73
75
  readonly clickhouse: typeof ClickhouseIcon;
74
76
  readonly openai: typeof OpenaiIcon;
77
+ readonly appwrite: typeof AppwriteIcon;
78
+ readonly linkding: typeof LinkdingIconSvelte;
75
79
  };
76
80
  export { AirtableIcon, DbIcon, DiscordIcon, GcalIcon, GCloudIcon, GdriveIcon, GithubIcon, GitlabIcon, GmailIcon, GSheetsIcon, HttpIcon, Mail, MastodonIcon, MatrixIcon, Mysql, PostgresIcon, S3Icon, Slack, TogglIcon, WindmillIcon, MailchimpIcon, SendgridIcon, LinkedinIcon, HubspotIcon, TelegramIcon, StripeIcon, DatadogIcon, FunkwhaleIcon, GdocsIcon, FaunadbIcon, ClickhouseIcon, OpenaiIcon, };
@@ -33,6 +33,8 @@ import NextcloudIcon from './NextcloudIcon.svelte';
33
33
  import FaunadbIcon from './FaunadbIcon.svelte';
34
34
  import ClickhouseIcon from './ClickhouseIcon.svelte';
35
35
  import OpenaiIcon from './OpenaiIcon.svelte';
36
+ import AppwriteIcon from './AppwriteIcon.svelte';
37
+ import LinkdingIconSvelte from './LinkdingIcon.svelte';
36
38
  export const APP_TO_ICON_COMPONENT = {
37
39
  postgresql: PostgresIcon,
38
40
  mysql: Mysql,
@@ -72,5 +74,7 @@ export const APP_TO_ICON_COMPONENT = {
72
74
  faunadb: FaunadbIcon,
73
75
  clickhouse: ClickhouseIcon,
74
76
  openai: OpenaiIcon,
77
+ appwrite: AppwriteIcon,
78
+ linkding: LinkdingIconSvelte
75
79
  };
76
80
  export { AirtableIcon, DbIcon, DiscordIcon, GcalIcon, GCloudIcon, GdriveIcon, GithubIcon, GitlabIcon, GmailIcon, GSheetsIcon, HttpIcon, Mail, MastodonIcon, MatrixIcon, Mysql, PostgresIcon, S3Icon, Slack, TogglIcon, WindmillIcon, MailchimpIcon, SendgridIcon, LinkedinIcon, HubspotIcon, TelegramIcon, StripeIcon, DatadogIcon, FunkwhaleIcon, GdocsIcon, FaunadbIcon, ClickhouseIcon, OpenaiIcon, };
@@ -28,11 +28,7 @@ export declare class AppService {
28
28
  }): CancelablePromise<{
29
29
  app: {
30
30
  summary: string;
31
- value: {
32
- staticApp: any;
33
- app: any;
34
- summary: string;
35
- };
31
+ value: any;
36
32
  };
37
33
  }>;
38
34
  /**
@@ -105,7 +105,23 @@ export declare class WorkspaceService {
105
105
  };
106
106
  }): CancelablePromise<string>;
107
107
  /**
108
- * delete workspace
108
+ * archive workspace
109
+ * @returns string status
110
+ * @throws ApiError
111
+ */
112
+ static archiveWorkspace({ workspace, }: {
113
+ workspace: string;
114
+ }): CancelablePromise<string>;
115
+ /**
116
+ * unarchive workspace
117
+ * @returns string status
118
+ * @throws ApiError
119
+ */
120
+ static unarchiveWorkspace({ workspace, }: {
121
+ workspace: string;
122
+ }): CancelablePromise<string>;
123
+ /**
124
+ * delete workspace (require super admin)
109
125
  * @returns string status
110
126
  * @throws ApiError
111
127
  */
@@ -121,14 +121,42 @@ export class WorkspaceService {
121
121
  });
122
122
  }
123
123
  /**
124
- * delete workspace
124
+ * archive workspace
125
+ * @returns string status
126
+ * @throws ApiError
127
+ */
128
+ static archiveWorkspace({ workspace, }) {
129
+ return __request(OpenAPI, {
130
+ method: 'POST',
131
+ url: '/w/{workspace}/workspaces/archive',
132
+ path: {
133
+ 'workspace': workspace,
134
+ },
135
+ });
136
+ }
137
+ /**
138
+ * unarchive workspace
139
+ * @returns string status
140
+ * @throws ApiError
141
+ */
142
+ static unarchiveWorkspace({ workspace, }) {
143
+ return __request(OpenAPI, {
144
+ method: 'POST',
145
+ url: '/workspaces/unarchive/{workspace}',
146
+ path: {
147
+ 'workspace': workspace,
148
+ },
149
+ });
150
+ }
151
+ /**
152
+ * delete workspace (require super admin)
125
153
  * @returns string status
126
154
  * @throws ApiError
127
155
  */
128
156
  static deleteWorkspace({ workspace, }) {
129
157
  return __request(OpenAPI, {
130
158
  method: 'DELETE',
131
- url: '/w/{workspace}/workspaces/delete',
159
+ url: '/workspaces/delete/{workspace}',
132
160
  path: {
133
161
  'workspace': workspace,
134
162
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-components",
3
- "version": "1.57.3",
3
+ "version": "1.58.1",
4
4
  "devDependencies": {
5
5
  "@playwright/test": "^1.29.1",
6
6
  "@sveltejs/adapter-static": "^1.0.0",
@@ -68,6 +68,9 @@
68
68
  "svelte-select": "^5.0.1",
69
69
  "vscode-ws-jsonrpc": "^2.0.1"
70
70
  },
71
+ "peerDependencies": {
72
+ "svelte": "^3.53.1"
73
+ },
71
74
  "exports": {
72
75
  "./package.json": "./package.json",
73
76
  "./assets/app.css": "./assets/app.css",
@@ -116,6 +119,7 @@
116
119
  "./components/ModuleStatus.svelte": "./components/ModuleStatus.svelte",
117
120
  "./components/MoveDrawer.svelte": "./components/MoveDrawer.svelte",
118
121
  "./components/Multiselect.svelte": "./components/Multiselect.svelte",
122
+ "./components/NumberTypeNarrowing.svelte": "./components/NumberTypeNarrowing.svelte",
119
123
  "./components/ObjectResourceInput.svelte": "./components/ObjectResourceInput.svelte",
120
124
  "./components/ObjectTypeNarrowing.svelte": "./components/ObjectTypeNarrowing.svelte",
121
125
  "./components/PageHeader.svelte": "./components/PageHeader.svelte",
@@ -123,6 +127,7 @@
123
127
  "./components/Path.svelte": "./components/Path.svelte",
124
128
  "./components/Popover.svelte": "./components/Popover.svelte",
125
129
  "./components/RadioButton.svelte": "./components/RadioButton.svelte",
130
+ "./components/Range.svelte": "./components/Range.svelte",
126
131
  "./components/Required.svelte": "./components/Required.svelte",
127
132
  "./components/ResourceEditor.svelte": "./components/ResourceEditor.svelte",
128
133
  "./components/ResourcePicker.svelte": "./components/ResourcePicker.svelte",
@@ -174,6 +179,7 @@
174
179
  "./components/apps/components/helpers/RunnableComponent.svelte": "./components/apps/components/helpers/RunnableComponent.svelte",
175
180
  "./components/apps/components/helpers/RunnableWrapper.svelte": "./components/apps/components/helpers/RunnableWrapper.svelte",
176
181
  "./components/apps/components/numberInputs/AppNumberInput.svelte": "./components/apps/components/numberInputs/AppNumberInput.svelte",
182
+ "./components/apps/components/numberInputs/AppSliderInputs.svelte": "./components/apps/components/numberInputs/AppSliderInputs.svelte",
177
183
  "./components/apps/components/selectInputs/AppCheckbox.svelte": "./components/apps/components/selectInputs/AppCheckbox.svelte",
178
184
  "./components/apps/components/selectInputs/AppSelect.svelte": "./components/apps/components/selectInputs/AppSelect.svelte",
179
185
  "./components/apps/components/table/AppTable.svelte": "./components/apps/components/table/AppTable.svelte",
@@ -184,7 +190,6 @@
184
190
  "./components/apps/editor/AppEditorHeader.svelte": "./components/apps/editor/AppEditorHeader.svelte",
185
191
  "./components/apps/editor/AppExportButton.svelte": "./components/apps/editor/AppExportButton.svelte",
186
192
  "./components/apps/editor/AppPreview.svelte": "./components/apps/editor/AppPreview.svelte",
187
- "./components/apps/editor/AppPublishButton.svelte": "./components/apps/editor/AppPublishButton.svelte",
188
193
  "./components/apps/editor/ComponentEditor.svelte": "./components/apps/editor/ComponentEditor.svelte",
189
194
  "./components/apps/editor/ComponentHeader.svelte": "./components/apps/editor/ComponentHeader.svelte",
190
195
  "./components/apps/editor/GridEditor.svelte": "./components/apps/editor/GridEditor.svelte",
@@ -342,6 +347,7 @@
342
347
  "./components/home/ListFilters.svelte": "./components/home/ListFilters.svelte",
343
348
  "./components/home/NoItemFound.svelte": "./components/home/NoItemFound.svelte",
344
349
  "./components/icons/AirtableIcon.svelte": "./components/icons/AirtableIcon.svelte",
350
+ "./components/icons/AppwriteIcon.svelte": "./components/icons/AppwriteIcon.svelte",
345
351
  "./components/icons/ClickhouseIcon.svelte": "./components/icons/ClickhouseIcon.svelte",
346
352
  "./components/icons/DatadogIcon.svelte": "./components/icons/DatadogIcon.svelte",
347
353
  "./components/icons/DbIcon.svelte": "./components/icons/DbIcon.svelte",
@@ -359,6 +365,7 @@
359
365
  "./components/icons/HatIcon.svelte": "./components/icons/HatIcon.svelte",
360
366
  "./components/icons/HttpIcon.svelte": "./components/icons/HttpIcon.svelte",
361
367
  "./components/icons/HubspotIcon.svelte": "./components/icons/HubspotIcon.svelte",
368
+ "./components/icons/LinkdingIcon.svelte": "./components/icons/LinkdingIcon.svelte",
362
369
  "./components/icons/LinkedinIcon.svelte": "./components/icons/LinkedinIcon.svelte",
363
370
  "./components/icons/Mail.svelte": "./components/icons/Mail.svelte",
364
371
  "./components/icons/MailchimpIcon.svelte": "./components/icons/MailchimpIcon.svelte",
package/utils.d.ts CHANGED
@@ -99,6 +99,7 @@ export declare function loadHubApps(): Promise<{
99
99
  }[] | undefined>;
100
100
  export declare function formatCron(inp: string): string;
101
101
  export declare function flowToHubUrl(flow: Flow): URL;
102
+ export declare function appToHubUrl(staticApp: any): URL;
102
103
  export declare function scriptToHubUrl(content: string, summary: string, description: string, kind: Script.kind, language: Script.language, schema: Schema | undefined, lock: string | undefined): URL;
103
104
  export declare function classNames(...classes: Array<string | undefined>): string;
104
105
  export declare function scriptLangToEditorLang(lang: Script.language): 'typescript' | 'python' | 'go' | 'shell';
package/utils.js CHANGED
@@ -491,6 +491,11 @@ export function flowToHubUrl(flow) {
491
491
  url.searchParams.append('flow', encodeState(openFlow));
492
492
  return url;
493
493
  }
494
+ export function appToHubUrl(staticApp) {
495
+ const url = new URL('https://hub.windmill.dev/apps/add');
496
+ url.searchParams.append('app', encodeState(staticApp));
497
+ return url;
498
+ }
494
499
  export function scriptToHubUrl(content, summary, description, kind, language, schema, lock) {
495
500
  const url = new URL('https://hub.windmill.dev/scripts/add');
496
501
  url.searchParams.append('content', content);
@@ -1,46 +0,0 @@
1
- <script>import Drawer from '../../common/drawer/Drawer.svelte';
2
- import DrawerContent from '../../common/drawer/DrawerContent.svelte';
3
- import { copyToClipboard } from '../../../utils';
4
- import { faClipboard, faFileExport, faGlobe } from '@fortawesome/free-solid-svg-icons';
5
- import Icon from 'svelte-awesome';
6
- import { Highlight } from 'svelte-highlight';
7
- import json from 'svelte-highlight/languages/json';
8
- import { Button } from '../../common';
9
- let jsonViewerDrawer;
10
- export let app;
11
- export let staticExporter;
12
- export let summary;
13
- function toStatic() {
14
- const newApp = JSON.parse(JSON.stringify(app));
15
- newApp.grid.forEach((x) => {
16
- let c = x.data;
17
- if (c.componentInput?.type == 'runnable') {
18
- c.componentInput.value = staticExporter[x.id]();
19
- }
20
- });
21
- return { app: newApp, summary };
22
- }
23
- </script>
24
-
25
- <Button size="sm" variant="border" color="light" on:click={() => jsonViewerDrawer.toggleDrawer()}>
26
- <Icon data={faGlobe} scale={0.6} class="inline mr-2" />
27
- Publish
28
- </Button>
29
-
30
- <Drawer bind:this={jsonViewerDrawer} size="800px">
31
- <DrawerContent title="App JSON" on:close={() => jsonViewerDrawer.toggleDrawer()}>
32
- <div class="relative">
33
- <Button
34
- on:click={() => copyToClipboard(JSON.stringify(toStatic(), null, 4))}
35
- color="dark"
36
- variant="border"
37
- size="sm"
38
- startIcon={{ icon: faClipboard }}
39
- btnClasses="absolute top-2 right-2"
40
- >
41
- Copy content
42
- </Button>
43
- <Highlight language={json} code={JSON.stringify(toStatic(), null, 4)} />
44
- </div>
45
- </DrawerContent>
46
- </Drawer>
@@ -1,19 +0,0 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- import type { App } from '../types';
3
- declare const __propDef: {
4
- props: {
5
- app: App;
6
- staticExporter: Record<string, () => any>;
7
- summary: string;
8
- };
9
- events: {
10
- [evt: string]: CustomEvent<any>;
11
- };
12
- slots: {};
13
- };
14
- export type AppPublishButtonProps = typeof __propDef.props;
15
- export type AppPublishButtonEvents = typeof __propDef.events;
16
- export type AppPublishButtonSlots = typeof __propDef.slots;
17
- export default class AppPublishButton extends SvelteComponentTyped<AppPublishButtonProps, AppPublishButtonEvents, AppPublishButtonSlots> {
18
- }
19
- export {};