windmill-components 1.28.2 → 1.28.5

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.
@@ -50,14 +50,16 @@ $: {
50
50
  evalValueToRaw();
51
51
  validateInput(pattern, value);
52
52
  }
53
- if (defaultValue) {
54
- let stringified = JSON.stringify(defaultValue, null, 4);
55
- if (stringified.length > 50) {
56
- minRows = 3;
57
- }
58
- if (type != 'string') {
59
- minRows = Math.max(minRows, Math.min(stringified.split(/\r\n|\r|\n/).length + 1, maxRows));
60
- }
53
+ }
54
+ $: {
55
+ defaultValue && recomputeRowSize(JSON.stringify(defaultValue, null, 4));
56
+ }
57
+ function recomputeRowSize(str) {
58
+ if (str.length > 50) {
59
+ minRows = 3;
60
+ }
61
+ if (type != 'string') {
62
+ minRows = Math.max(minRows, Math.min(str.split(/\r\n|\r|\n/).length + 1, maxRows));
61
63
  }
62
64
  }
63
65
  export function evalValueToRaw() {
@@ -112,7 +114,7 @@ export let inputCat = 'string';
112
114
  $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncoding);
113
115
  </script>
114
116
 
115
- <div class="flex flex-col w-full">
117
+ <div class="flex flex-col w-full mb-2">
116
118
  <div>
117
119
  {#if displayHeader}
118
120
  <FieldHeader {label} {required} {type} {contentEncoding} {format} {itemsType} />
@@ -156,13 +158,18 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
156
158
  {/if}
157
159
 
158
160
  <div class="grid grid-cols-2">
159
- <div class="text-sm italic pb-1">
160
- {description}
161
- </div>
162
- <div class="text-right text-xs {error === '' ? 'text-white' : 'font-bold text-red-600'}">
163
- {error === '' ? '...' : error}
164
- </div>
161
+ {#if description || error}
162
+ <div class="text-sm italic pb-1">
163
+ {description}
164
+ </div>
165
+ <div class="text-right text-xs {error === '' ? 'text-white' : 'font-bold text-red-600'}">
166
+ {error === '' ? '...' : error}
167
+ </div>
168
+ {:else}
169
+ <div class="mt-1" />
170
+ {/if}
165
171
  </div>
172
+
166
173
  <div class="flex space-x-1">
167
174
  {#if inputCat == 'number'}
168
175
  <input
@@ -240,6 +247,7 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
240
247
  <textarea
241
248
  {disabled}
242
249
  style="min-height: {minHeight}; max-height: {maxHeight}"
250
+ on:input={async () => recomputeRowSize(rawValue ?? '')}
243
251
  class="col-span-10 {valid
244
252
  ? ''
245
253
  : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
@@ -290,7 +298,10 @@ $: inputCat = computeInputCat(type, format, itemsType?.type, enum_, contentEncod
290
298
  : 'border border-red-700 border-opacity-30 focus:border-red-700 focus:border-opacity-30 bg-red-100'}"
291
299
  placeholder={defaultValue ?? ''}
292
300
  bind:value
293
- on:input={() => dispatch('input', { rawValue: value, isRaw: false })}
301
+ on:input={async () => {
302
+ recomputeRowSize(value)
303
+ dispatch('input', { rawValue: value, isRaw: false })
304
+ }}
294
305
  />
295
306
  {/if}
296
307
  {#if !required && inputCat != 'resource-object'}
@@ -179,13 +179,32 @@ export async function reloadWebsocket() {
179
179
  async function connectToLanguageServer(url, name, options) {
180
180
  try {
181
181
  const webSocket = new WebSocket(url);
182
- webSocket.onopen = () => {
182
+ webSocket.onopen = async () => {
183
183
  const socket = toSocket(webSocket);
184
184
  const reader = new WebSocketMessageReader(socket);
185
185
  const writer = new WebSocketMessageWriter(socket);
186
186
  const languageClient = createLanguageClient({ reader, writer }, name, options);
187
187
  websockets.push([languageClient, webSocket]);
188
- languageClient.start();
188
+ reader.onClose(async () => {
189
+ try {
190
+ console.log('CLOSE');
191
+ websocketAlive[name] = false;
192
+ await languageClient.stop();
193
+ }
194
+ catch (err) {
195
+ console.error(err);
196
+ }
197
+ });
198
+ socket.onClose((_code, _reason) => {
199
+ websocketAlive[name] = false;
200
+ });
201
+ try {
202
+ await languageClient.start();
203
+ }
204
+ catch (err) {
205
+ console.error(err);
206
+ throw new Error(err);
207
+ }
189
208
  lastWsAttempt = new Date();
190
209
  nbWsAttempt = 0;
191
210
  if (name == 'deno') {
@@ -200,18 +219,6 @@ export async function reloadWebsocket() {
200
219
  }
201
220
  });
202
221
  }
203
- reader.onClose(() => {
204
- try {
205
- console.log('CLOSE');
206
- languageClient.stop();
207
- }
208
- catch (err) {
209
- console.error(err);
210
- }
211
- });
212
- socket.onClose((_code, _reason) => {
213
- websocketAlive[name] = false;
214
- });
215
222
  websocketAlive[name] = true;
216
223
  };
217
224
  }
@@ -329,9 +336,6 @@ async function loadMonaco() {
329
336
  minimap: {
330
337
  enabled: false
331
338
  },
332
- scrollbar: {
333
- alwaysConsumeMouseWheel: false
334
- },
335
339
  lightbulb: {
336
340
  enabled: true
337
341
  }
@@ -123,7 +123,7 @@ onDestroy(() => {
123
123
  </script>
124
124
 
125
125
  <div class="flex flex-row w-full h-full justify-between">
126
- <div class={`flex flex-col mb-96 m-auto w-1/2`}>
126
+ <div class={`flex flex-col mb-96 m-auto w-full sm:w-3/4 lg:w-2/3 xl:w-1/2`}>
127
127
  <!-- Nav between steps-->
128
128
  <div class="justify-between flex flex-row w-full my-4">
129
129
  <Breadcrumb>
@@ -205,7 +205,7 @@ onDestroy(() => {
205
205
  <div class={`relative h-screen w-1/3 ${previewOpen ? '' : 'hidden'}`}>
206
206
  <div class="absolute top-0 h-full">
207
207
  {#if $flowStore && step === 1}
208
- <div class="fixed border-l-2 right-0 h-screen w-1/3">
208
+ <div class="fixed border-l-2 right-0 h-screen w-1/2 sm:w-1/3">
209
209
  <FlowPreviewContent
210
210
  bind:args={scheduleArgs}
211
211
  on:close={() => (previewOpen = !previewOpen)}
@@ -55,7 +55,11 @@ let args = {};
55
55
  <ModuleStep bind:open bind:mod bind:args {i} mode={$mode} />
56
56
  {#if i == 0 && $mode == 'pull'}
57
57
  <div class="flex justify-center bg-white shadow p-2">
58
- Starting from here, the flow for loop over items from step 1's result above &nbsp;
58
+ <p>
59
+ Starting from here, the flow for loop over items from the 1rst step's result right above
60
+ &nbsp; <br />We do not support any other kind of for-loop at the moment but we will very
61
+ soon (See <a href="https://github.com/windmill-labs/windmill/issues/350">#350</a>)
62
+ </p>
59
63
  <Tooltip>
60
64
  This flow being in 'Pull' mode, the rest of the flow will for loop over the list of
61
65
  items returned by the trigger script right above. Retrieve the item value using
@@ -27,8 +27,7 @@ $: dispatch('change', jobs);
27
27
  export async function runPreview(args) {
28
28
  viewPreview = true;
29
29
  intervalId && clearInterval(intervalId);
30
- let newFlow = flowToMode(flow, mode);
31
- newFlow = tab == 'upto' ? truncateFlow(newFlow) : extractStep(newFlow);
30
+ let newFlow = tab == 'upto' ? truncateFlow(flow) : setInputTransformFromArgs(extractStep(flow), args);
32
31
  jobId = await runFlowPreview(args, newFlow);
33
32
  jobs = [];
34
33
  intervalId = setInterval(loadJob, 1000);
@@ -43,14 +42,19 @@ function extractStep(flow) {
43
42
  const localFlow = JSON.parse(JSON.stringify(flow));
44
43
  localFlow.value.modules = flow.value.modules.slice(i, i + 1);
45
44
  localFlow.schema = schemas[i];
46
- stepArgs = {};
47
- Object.entries(flow.value.modules[i].input_transform).forEach((x) => {
48
- if (x[1].type == 'static') {
49
- stepArgs[x[0]] = x[1].value;
50
- }
51
- });
52
45
  return localFlow;
53
46
  }
47
+ function setInputTransformFromArgs(flow, args) {
48
+ let input_transform = {};
49
+ Object.entries(args).forEach(([key, value]) => {
50
+ input_transform[key] = {
51
+ type: 'static',
52
+ value: value
53
+ };
54
+ });
55
+ flow.value.modules[0].input_transform = input_transform;
56
+ return flow;
57
+ }
54
58
  async function loadJob() {
55
59
  try {
56
60
  job = await JobService.getJob({ workspace: $workspaceStore, id: jobId });
@@ -41,8 +41,8 @@ onDestroy(() => {
41
41
  });
42
42
  </script>
43
43
 
44
- <div class="flex flex-col space-y-4 h-screen bg-white ">
45
- <div class="flex flex-col space-y-4 p-6 border-b-2">
44
+ <div class="flex flex-col space-y-4 h-screen bg-white">
45
+ <div class="flex flex-col space-y-4 p-6 border-b-2 overflow-y-auto grow">
46
46
  <div class="flex justify-between">
47
47
  <h3 class="text-lg leading-6 font-bold text-gray-900">Flow Preview</h3>
48
48
 
@@ -51,11 +51,11 @@ onDestroy(() => {
51
51
  </Button>
52
52
  </div>
53
53
  <SchemaForm schema={$flowStore.schema} bind:isValid bind:args />
54
- <Button disabled={!isValid} class="blue-button" on:click={() => runPreview(args)} size="md">
55
- Preview
56
- </Button>
57
54
  </div>
58
- <div class="h-full overflow-y-auto mb-16">
55
+ <Button disabled={!isValid} class="blue-button mx-4" on:click={() => runPreview(args)} size="md">
56
+ Preview
57
+ </Button>
58
+ <div class="h-full overflow-y-auto mb-16 grow">
59
59
  {#if job}
60
60
  <div class="w-full">
61
61
  <FlowStatusViewer {job} bind:jobs />
@@ -185,6 +185,9 @@ $: $workspaceStore && job && loadResults();
185
185
  >
186
186
  {#if forloop_selected == job.id}
187
187
  <svelte:self {job} />
188
+ {#if `result` in job}
189
+ <FlowJobResult {job} />
190
+ {/if}
188
191
  {/if}
189
192
  {/each}
190
193
  </div>
@@ -8,7 +8,9 @@ import Tabs from './Tabs.svelte';
8
8
  import SchemaViewer from './SchemaViewer.svelte';
9
9
  import FieldHeader from './FieldHeader.svelte';
10
10
  import InputTransformsViewer from './InputTransformsViewer.svelte';
11
+ import SvelteMarkdown from 'svelte-markdown';
11
12
  export let flow;
13
+ export let initialOpen = undefined;
12
14
  let flowFiltered = {
13
15
  summary: flow.summary,
14
16
  description: flow.description,
@@ -18,7 +20,9 @@ let flowFiltered = {
18
20
  export let embedded = false;
19
21
  export let tab = 'ui';
20
22
  let open = {};
21
- let hubCode = {};
23
+ if (initialOpen) {
24
+ open[initialOpen] = true;
25
+ }
22
26
  function toAny(x) {
23
27
  return x;
24
28
  }
@@ -38,7 +42,7 @@ function toAny(x) {
38
42
  <div class="flow-root w-full pb-4">
39
43
  {#if !embedded}
40
44
  <h2 class="mt-4">{flow.summary}</h2>
41
- <h3 class="mt-4">{flow.description}</h3>
45
+ <SvelteMarkdown source={flow.description ?? ''} />
42
46
 
43
47
  <p class="font-black text-lg w-full my-4">
44
48
  <span>Inputs</span>
@@ -90,6 +94,7 @@ function toAny(x) {
90
94
  </div>
91
95
  <div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4 w-full">
92
96
  <div class="w-full">
97
+ <span class="text-black">{mod?.summary ?? ''}</span>
93
98
  <p class="text-sm text-gray-500">
94
99
  {#if mod?.value?.type == 'script'}
95
100
  Script at path <a
@@ -8,6 +8,7 @@ declare const __propDef: {
8
8
  value: FlowValue;
9
9
  schema?: any;
10
10
  };
11
+ initialOpen?: number | undefined;
11
12
  embedded?: boolean | undefined;
12
13
  tab?: "json" | "schema" | "ui" | undefined;
13
14
  };
@@ -78,7 +78,7 @@ $: checked = propertyType == 'javascript';
78
78
  </script>
79
79
 
80
80
  {#if arg != undefined}
81
- <div class="flex justify-between items-center">
81
+ <div class="flex justify-between items-center mb-2">
82
82
  <div class="flex items-center">
83
83
  <FieldHeader
84
84
  label={argName}
@@ -199,7 +199,7 @@ $: checked = propertyType == 'javascript';
199
199
  />
200
200
  </div>
201
201
  </OverlayPropertyPicker>
202
- <DynamicInputHelpBox />
202
+ <DynamicInputHelpBox {i} />
203
203
  {/if}
204
204
  {:else}
205
205
  <p>Not recognized arg type {arg.type}</p>
@@ -10,7 +10,7 @@ export let inputTransforms;
10
10
  <span class="font-black text-gray-700">{key}</span>: {#if val.type == 'static'}<ObjectViewer
11
11
  json={val.value}
12
12
  />{:else}
13
- <span class="inline-block inline-highlight">
13
+ <span class="inline-highlight">
14
14
  <Highlight offsetTop={0} language={typescript} code={val.expr} />
15
15
  </span>
16
16
  {/if}
@@ -82,7 +82,7 @@ const isTrigger = mode === 'pull' && i === 0;
82
82
  <div class="mb-2 overflow-hidden">
83
83
  <EditorBar {editor} {websocketAlive} lang={mod.value.language ?? 'deno'} />
84
84
  </div>
85
- <div>
85
+ <div on:mouseleave={() => loadSchema(i)}>
86
86
  <Editor
87
87
  bind:websocketAlive
88
88
  bind:this={editor}
@@ -42,8 +42,8 @@ function valueToPath() {
42
42
  $: value && valueToPath();
43
43
  </script>
44
44
 
45
- <div class="flex flex-row w-full gap-2">
46
- <div class="shrink w-40">
45
+ <div class="flex flex-row w-full flex-wrap gap-x-2">
46
+ <div class="shrink">
47
47
  <RadioButton
48
48
  options={[
49
49
  [`Resource (${resourceTypeName})`, 'resource'],
@@ -12,7 +12,7 @@ const dispatch = createEventDispatcher();
12
12
  {#each options as [label, val]}
13
13
  <label
14
14
  class:item-button-selected={val == value}
15
- class="item-button text-center text-sm h-full p-2 grow"
15
+ class="item-button text-center text-sm h-full p-2 grow whitespace-nowrap"
16
16
  >
17
17
  <input
18
18
  type="radio"
@@ -23,7 +23,9 @@ const dispatch = createEventDispatcher();
23
23
  on:click={() => dispatch('change', val)}
24
24
  />
25
25
  <p>
26
- {#if typeof label !== 'string'}{label.title} <Tooltip>{label.desc}</Tooltip>
26
+ {#if typeof label !== 'string'}
27
+ {label.title}
28
+ <Tooltip>{label.desc}</Tooltip>
27
29
  {:else}{label}{/if}
28
30
  </p>
29
31
  </label>
@@ -126,7 +126,7 @@ function switchTab() {
126
126
  </script>
127
127
 
128
128
  <div class="flex flex-col">
129
- <div class="flex justify-between">
129
+ <div class="flex justify-between gap-x-2">
130
130
  <Button
131
131
  on:click={() => {
132
132
  modalProperty = Object.assign({}, DEFAULT_PROPERTY)
@@ -176,8 +176,12 @@ function switchTab() {
176
176
  <SchemaEditorProperty {property} />
177
177
  </td>
178
178
  <td>{property.description}</td>
179
- <td>{JSON.stringify(property.default) ?? ''}</td>
180
- <td>{schema.required.includes(name) ? 'Required' : 'Optional'}</td>
179
+ <td>{property.default ? JSON.stringify(property.default) : ''}</td>
180
+ <td
181
+ >{#if schema.required.includes(name)}
182
+ <span class="text-red-600 font-bold text-lg">*</span>
183
+ {/if}</td
184
+ >
181
185
  <td class="justify-end flex">
182
186
  <Button
183
187
  color="red"
@@ -2,10 +2,12 @@
2
2
  export let property;
3
3
  </script>
4
4
 
5
- <Badge color="blue">{property.type?.toUpperCase() ?? 'ANY'}</Badge>
6
- {#if property.format}
7
- <Badge color="green">{property.format?.toUpperCase()}</Badge>
8
- {/if}
9
- {#if property.contentEncoding}
10
- <Badge color="indigo">{property.contentEncoding?.toUpperCase()}</Badge>
11
- {/if}
5
+ <div class="flex flex-row flex-wrap gap-1">
6
+ <Badge color="blue">{property.type?.toUpperCase() ?? 'ANY'}</Badge>
7
+ {#if property.format}
8
+ <Badge color="green">{property.format?.toUpperCase()}</Badge>
9
+ {/if}
10
+ {#if property.contentEncoding}
11
+ <Badge color="indigo">{property.contentEncoding?.toUpperCase()}</Badge>
12
+ {/if}
13
+ </div>
@@ -58,7 +58,11 @@ let viewJsonSchema = false;
58
58
  >{property.format ?? ''}
59
59
  {property.contentEncoding ? `(encoding: ${property.contentEncoding})` : ''}</td
60
60
  >
61
- <td>{schema.required.includes(name) ? 'required' : 'optional'}</td>
61
+ <td
62
+ >{#if schema.required.includes(name)}
63
+ <span class="text-red-600 font-bold text-lg">*</span>
64
+ {/if}</td
65
+ >
62
66
  </tr>
63
67
  {/each}
64
68
  </tbody>
@@ -206,7 +206,13 @@ onDestroy(() => {
206
206
  <div class="header">
207
207
  <EditorBar {editor} {lang} {websocketAlive} />
208
208
  </div>
209
- <div class="flex-1 overflow-hidden border p-2 rounded">
209
+ <div
210
+ class="flex-1 overflow-hidden border p-2 rounded"
211
+ on:mouseleave={() => {
212
+ code = getEditor().getCode()
213
+ inferSchema()
214
+ }}
215
+ >
210
216
  <Editor
211
217
  {code}
212
218
  bind:websocketAlive
@@ -1,6 +1,7 @@
1
1
  <script>import { faChevronDown, faChevronUp } from '@fortawesome/free-solid-svg-icons';
2
2
  import Icon from 'svelte-awesome';
3
3
  import { slide } from 'svelte/transition';
4
+ export let i = 1;
4
5
  $: opened = false;
5
6
  </script>
6
7
 
@@ -25,29 +26,29 @@ $: opened = false;
25
26
  >
26
27
  <p class="font-bold">Dynamic arg help</p>
27
28
  <p>
28
- When a field is "dynamic", its value is computed dynamically as the evaluation of its
29
- corresponding typescript snippet.
29
+ When a field is using the "Raw Javascript Editor", its value is computed dynamically as the
30
+ evaluation of its corresponding javascript snippet.
30
31
  </p>
31
- That snippet can be single line:
32
+ That snippet can be a single line:
32
33
  <pre><code>last_result.myarg</code></pre>
33
- or multiline:
34
+ or a multiline:
34
35
  <pre><code
35
36
  >let x = 5;
36
37
  x + 2</code
37
38
  ></pre>
38
39
  <p>
39
- If it is multiline, the last statement before the final expression<b
40
+ If it is multiline, the statement before the final expression <b
40
41
  >MUST END WITH ; and a newline</b
41
42
  >
42
43
  </p>
43
44
  The snippet can also be a string template:
44
- <pre><code
45
- >`Hello $&#123;params.name&#125;, all your base $&#123;previous_result.base_name&#125;
46
- belong to us`</code
47
- ></pre>
45
+ <code
46
+ >`Hello $&#123;params.name&#125;, all your base $&#123;previous_result.base_name&#125; belong
47
+ to us`</code
48
+ >
48
49
  However, the last line must always be the final expression.
49
50
  <p>
50
- The snippet can use any typescript primitives, and the following flow specific objects and
51
+ The snippet can use any javascript primitives, and the following flow specific objects and
51
52
  functions:
52
53
  </p>
53
54
  <ul class="ml-4">
@@ -68,5 +69,9 @@ belong to us`</code
68
69
  <b>resource(path)</b>: the function returning the resource at a given path as an object
69
70
  </li>
70
71
  </ul>
72
+ <p>To re-enable editor assistance, import the helper functions types using:</p>
73
+ <code
74
+ >{`import { previous_result, flow_input, step, variable, resource, params } from 'windmill@${i}'`}</code
75
+ >
71
76
  </div>
72
77
  {/if}
@@ -1,6 +1,8 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
- props: {};
3
+ props: {
4
+ i?: number | undefined;
5
+ };
4
6
  events: {
5
7
  [evt: string]: CustomEvent<any>;
6
8
  };
@@ -161,12 +161,13 @@ let jsonValue = '';
161
161
  right: 'enabled'
162
162
  }}
163
163
  />
164
- <div class="p-2 mt-2 rounded" class:bg-gray-300={!scheduleEnabled}>
164
+ <div class="p-2 my-2 rounded" class:bg-gray-300={!scheduleEnabled}>
165
165
  {#if !scheduleEnabled}
166
166
  <span class="font-black">No next scheduled run when disabled</span>
167
167
  {/if}
168
168
  <CronInput bind:schedule={scheduleCron} />
169
169
  </div>
170
+
170
171
  <SchemaForm schema={$flowStore.schema} bind:args={scheduleArgs} />
171
172
  </CollapseLink>
172
173
  {/if}
@@ -33,7 +33,8 @@ export function flowToMode(flow, mode) {
33
33
  newFlow.value.modules = newFlow.value.modules.slice(0, 1);
34
34
  if (oldModules.length > 0) {
35
35
  newFlow.value.modules.push({
36
- input_transform: oldModules[0].input_transform,
36
+ //TODO: once we allow arbitrary for loop, we will also allow arbitrary input transform here
37
+ input_transform: {},
37
38
  value: {
38
39
  type: 'forloopflow',
39
40
  iterator: { type: 'javascript', expr: 'result' },
@@ -122,18 +123,14 @@ export async function loadSchemaFromModule(module) {
122
123
  schema: emptySchema()
123
124
  };
124
125
  }
126
+ const returnStatementRegex = new RegExp(/\$\{(.*)\}/);
125
127
  export function isCodeInjection(expr) {
126
128
  if (!expr) {
127
129
  return false;
128
130
  }
129
131
  const lines = expr.split('\n');
130
132
  const [returnStatement] = lines.reverse();
131
- const returnStatementRegex = new RegExp(/\$\{(.*)\}/);
132
- if (returnStatementRegex.test(returnStatement)) {
133
- const [_, argName] = returnStatement.split(returnStatementRegex);
134
- return Boolean(argName);
135
- }
136
- return false;
133
+ return returnStatementRegex.test(returnStatement);
137
134
  }
138
135
  export function getDefaultExpr(i, key = 'myfield', previousExpr) {
139
136
  const expr = previousExpr ?? `previous_result.${key}`;
@@ -207,5 +204,5 @@ function computeFlowInputPull(previewResult, flowInputAsObject) {
207
204
  index: 'The current index of the iteration as a number'
208
205
  }
209
206
  };
210
- return Object.assign(Object.assign(flowInputAsObject, previewResult), iteratorValues);
207
+ return Object.assign(flowInputAsObject, iteratorValues);
211
208
  }
@@ -7,6 +7,7 @@ export let level = 0;
7
7
  export let isLast = true;
8
8
  export let currentPath = '';
9
9
  export let pureViewer = false;
10
+ export let collapsed = level == 3 || Array.isArray(json);
10
11
  const collapsedSymbol = '...';
11
12
  let keys;
12
13
  let isArray;
@@ -18,7 +19,6 @@ $: {
18
19
  openBracket = isArray ? '[' : '{';
19
20
  closeBracket = isArray ? ']' : '}';
20
21
  }
21
- $: collapsed = level == 2;
22
22
  function collapse() {
23
23
  collapsed = !collapsed;
24
24
  }
@@ -6,6 +6,7 @@ declare const __propDef: {
6
6
  isLast?: boolean | undefined;
7
7
  currentPath?: string | undefined;
8
8
  pureViewer?: boolean | undefined;
9
+ collapsed?: boolean | undefined;
9
10
  };
10
11
  events: {
11
12
  select: CustomEvent<any>;
@@ -1,6 +1,6 @@
1
1
  export const OpenAPI = {
2
2
  BASE: '/api',
3
- VERSION: '1.27.2',
3
+ VERSION: '1.28.1',
4
4
  WITH_CREDENTIALS: false,
5
5
  CREDENTIALS: 'include',
6
6
  TOKEN: undefined,
@@ -5,4 +5,5 @@ export declare type FlowModule = {
5
5
  value: FlowModuleValue;
6
6
  stop_after_if_expr?: string;
7
7
  skip_if_stopped?: boolean;
8
+ summary?: string;
8
9
  };
package/logout.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare function logoutWithRedirect(rd?: string): void;
2
- export declare function logout(logoutMessage?: string): Promise<void>;
2
+ export declare function logout(): Promise<void>;
package/logout.js CHANGED
@@ -6,22 +6,24 @@ function clearCookies() {
6
6
  document.cookie.split(";").forEach(function (c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); });
7
7
  }
8
8
  export function logoutWithRedirect(rd) {
9
- const error = document.cookie.includes('token')
10
- ? `error=${encodeURIComponent('You have been logged out because your session has expired.')}&`
11
- : '';
12
- clearCookies();
13
- goto(`/user/login?${error}${rd ? 'rd=' + encodeURIComponent(rd) : ''}`);
9
+ if (rd?.split('?')[0] != '/user/login') {
10
+ const error = document.cookie.includes('token')
11
+ ? `error=${encodeURIComponent('You have been logged out because your session has expired.')}&`
12
+ : '';
13
+ clearCookies();
14
+ goto(`/user/login?${error}${rd ? 'rd=' + encodeURIComponent(rd) : ''}`);
15
+ }
14
16
  }
15
- export async function logout(logoutMessage) {
17
+ export async function logout() {
16
18
  try {
17
19
  clearStores();
18
20
  await UserService.logout();
19
21
  clearCookies();
20
- goto(`/user/login${logoutMessage ? '?error=' + encodeURIComponent(logoutMessage) : ''}`);
21
- sendUserToast('you have been logged out');
22
22
  }
23
23
  catch (error) {
24
- goto('/user/login');
25
24
  console.error(error);
25
+ clearCookies();
26
26
  }
27
+ goto(`/user/login`);
28
+ sendUserToast('you have been logged out');
27
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-components",
3
- "version": "1.28.2",
3
+ "version": "1.28.5",
4
4
  "devDependencies": {
5
5
  "@playwright/test": "^1.24.2",
6
6
  "@sveltejs/adapter-static": "^1.0.0-next.37",