diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 292be95784..8b3400f1c3 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,7 +8,6 @@
"name": "windmill",
"version": "1.64.0",
"dependencies": {
- "@canutin/svelte-currency-input": "^0.8.0",
"@fortawesome/free-brands-svg-icons": "^6.2.1",
"@fortawesome/free-solid-svg-icons": "^6.2.1",
"@leeoniya/ufuzzy": "^0.9.1",
@@ -19,6 +18,7 @@
"chartjs-plugin-zoom": "^2.0.0",
"date-fns": "^2.29.3",
"highlight.js": "^11.7.0",
+ "lucide-svelte": "^0.115.0",
"monaco-editor": "0.33.0",
"monaco-editor-workers": "0.33.0",
"monaco-languageclient": "2.1.0",
@@ -48,7 +48,6 @@
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-svelte3": "^4.0.0",
- "lucide-svelte": "^0.104.0",
"openapi-typescript-codegen": "^0.23.0",
"path-browserify": "^1.0.1",
"postcss": "^8.4.18",
@@ -206,11 +205,6 @@
"node": ">=4"
}
},
- "node_modules/@canutin/svelte-currency-input": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@canutin/svelte-currency-input/-/svelte-currency-input-0.8.0.tgz",
- "integrity": "sha512-u/ywCjAQzBTU1GvoljNgVzA/xV6UjVXsFbe4KISxk3cZJOA3eN35qaGtNMJhWQ0JI+QbFjxv2I2nHbdzmmn1Nw=="
- },
"node_modules/@csstools/selector-specificity": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
@@ -3865,10 +3859,9 @@
}
},
"node_modules/lucide-svelte": {
- "version": "0.104.0",
- "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.104.0.tgz",
- "integrity": "sha512-PhckIn28E571Kx2gs2SVh5gc0RlDge521AE63ce4c8gRUMYeo9USPUr80bt/26J5+8qce+hw1zRjx/ag2BqBgw==",
- "dev": true,
+ "version": "0.115.0",
+ "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.115.0.tgz",
+ "integrity": "sha512-kR7XlwoSVjGX+jwOiHKjTCDMPcTKrsKGyYnJkgW55wyKmWAzfOSESDGuRHcfsRAIQgg133mDNtCm++S8V5rRjg==",
"peerDependencies": {
"svelte": "^3.49.0"
}
@@ -7284,11 +7277,6 @@
}
}
},
- "@canutin/svelte-currency-input": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@canutin/svelte-currency-input/-/svelte-currency-input-0.8.0.tgz",
- "integrity": "sha512-u/ywCjAQzBTU1GvoljNgVzA/xV6UjVXsFbe4KISxk3cZJOA3eN35qaGtNMJhWQ0JI+QbFjxv2I2nHbdzmmn1Nw=="
- },
"@csstools/selector-specificity": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
@@ -9843,10 +9831,9 @@
}
},
"lucide-svelte": {
- "version": "0.104.0",
- "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.104.0.tgz",
- "integrity": "sha512-PhckIn28E571Kx2gs2SVh5gc0RlDge521AE63ce4c8gRUMYeo9USPUr80bt/26J5+8qce+hw1zRjx/ag2BqBgw==",
- "dev": true,
+ "version": "0.115.0",
+ "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.115.0.tgz",
+ "integrity": "sha512-kR7XlwoSVjGX+jwOiHKjTCDMPcTKrsKGyYnJkgW55wyKmWAzfOSESDGuRHcfsRAIQgg133mDNtCm++S8V5rRjg==",
"requires": {}
},
"magic-string": {
diff --git a/frontend/package.json b/frontend/package.json
index 05526c3db5..ce75ee7391 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -33,7 +33,6 @@
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-svelte3": "^4.0.0",
- "lucide-svelte": "^0.104.0",
"openapi-typescript-codegen": "^0.23.0",
"path-browserify": "^1.0.1",
"postcss": "^8.4.18",
@@ -71,6 +70,7 @@
"chartjs-plugin-zoom": "^2.0.0",
"date-fns": "^2.29.3",
"highlight.js": "^11.7.0",
+ "lucide-svelte": "^0.115.0",
"monaco-editor": "0.33.0",
"monaco-editor-workers": "0.33.0",
"monaco-languageclient": "2.1.0",
diff --git a/frontend/src/lib/components/apps/components/AppDivider.svelte b/frontend/src/lib/components/apps/components/AppDivider.svelte
index 91984389fc..928de5ea13 100644
--- a/frontend/src/lib/components/apps/components/AppDivider.svelte
+++ b/frontend/src/lib/components/apps/components/AppDivider.svelte
@@ -1,24 +1,41 @@
-
-
-
-
-
-
+
+
+
diff --git a/frontend/src/lib/components/apps/components/dataDisplay/AppIcon.svelte b/frontend/src/lib/components/apps/components/dataDisplay/AppIcon.svelte
new file mode 100644
index 0000000000..9402e8f621
--- /dev/null
+++ b/frontend/src/lib/components/apps/components/dataDisplay/AppIcon.svelte
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+ {#if iconComponent}
+
+ {/if}
+
+
\ No newline at end of file
diff --git a/frontend/src/lib/components/apps/components/helpers/index.ts b/frontend/src/lib/components/apps/components/helpers/index.ts
new file mode 100644
index 0000000000..9aec864c40
--- /dev/null
+++ b/frontend/src/lib/components/apps/components/helpers/index.ts
@@ -0,0 +1,9 @@
+export { default as AlignWrapper } from './AlignWrapper.svelte'
+export { default as DebouncedInput } from './DebouncedInput.svelte'
+export { default as InputDefaultValue } from './InputDefaultValue.svelte'
+export { default as InputValue } from './InputValue.svelte'
+export { default as MissingConnectionWarning } from './MissingConnectionWarning.svelte'
+export { default as NonRunnableComponent } from './NonRunnableComponent.svelte'
+export { default as RefreshButton } from './RefreshButton.svelte'
+export { default as RunnableComponent } from './RunnableComponent.svelte'
+export { default as RunnableWrapper } from './RunnableWrapper.svelte'
\ No newline at end of file
diff --git a/frontend/src/lib/components/apps/editor/Component.svelte b/frontend/src/lib/components/apps/editor/Component.svelte
index 717f3cff18..4a899d0026 100644
--- a/frontend/src/lib/components/apps/editor/Component.svelte
+++ b/frontend/src/lib/components/apps/editor/Component.svelte
@@ -17,6 +17,7 @@
Code2,
SlidersHorizontal,
PlusSquare,
+ Smile,
DollarSign,
SeparatorHorizontal,
SeparatorVertical
@@ -28,7 +29,7 @@
}
/* How to add a new Svelte Component:
- 1. add the the type to the union below
+ 1. add the type to the union below
2. add the component to the components record
3. add the comoonent to one of the components set (buttons, inputs, display)
4. add the component in the svelte if switch
@@ -70,6 +71,7 @@
export type SelectComponent = BaseComponent<'selectcomponent'>
export type CheckboxComponent = BaseComponent<'checkboxcomponent'>
export type RadioComponent = BaseComponent<'radiocomponent'>
+ export type IconComponent = BaseComponent<'iconcomponent'>
export type HorizontalDividerComponent = BaseComponent<'horizontaldividercomponent'>
export type VerticalDividerComponent = BaseComponent<'verticaldividercomponent'>
@@ -98,6 +100,7 @@
| FormButtonComponent
| VegaLiteComponent
| PlotlyComponent
+ | IconComponent
| HorizontalDividerComponent
| VerticalDividerComponent
)
@@ -108,7 +111,7 @@
{ name: string; icon: any; dims: `${number}:${number}-${number}:${number}`; data: AppComponent }
> = {
displaycomponent: {
- name: 'Result',
+ name: 'Rich Result',
icon: Monitor,
dims: '2:8-6:8',
data: {
@@ -896,7 +899,7 @@
}
},
dateinputcomponent: {
- name: 'Date Input',
+ name: 'Date',
icon: Calendar,
dims: '2:1-3:1',
data: {
@@ -925,6 +928,44 @@
card: false
}
},
+ iconcomponent: {
+ name: 'Icon',
+ icon: Smile,
+ dims: '1:3-1:2',
+ data: {
+ softWrap: false,
+ horizontalAlignment: 'center',
+ verticalAlignment: 'center',
+ id: '',
+ type: 'iconcomponent',
+ componentInput: undefined,
+ configuration: {
+ icon: {
+ type: 'static',
+ value: 'Smile',
+ fieldType: 'icon-select'
+ },
+ color: {
+ type: 'static',
+ value: 'currentColor',
+ fieldType: 'text'
+ },
+ size: {
+ type: 'static',
+ value: 24,
+ fieldType: 'number',
+ onlyStatic: true
+ },
+ strokeWidth: {
+ type: 'static',
+ value: 2,
+ fieldType: 'number',
+ onlyStatic: true
+ }
+ },
+ card: false
+ }
+ },
horizontaldividercomponent: {
name: 'Divider X',
icon: SeparatorHorizontal,
@@ -939,14 +980,14 @@
type: 'static',
value: 2,
fieldType: 'number',
- onlyStatic: true,
+ onlyStatic: true
},
color: {
type: 'static',
value: '#00000060',
fieldType: 'text',
- onlyStatic: true,
- },
+ onlyStatic: true
+ }
},
card: false
}
@@ -965,18 +1006,18 @@
type: 'static',
value: 2,
fieldType: 'number',
- onlyStatic: true,
+ onlyStatic: true
},
color: {
type: 'static',
value: '#00000060',
fieldType: 'text',
- onlyStatic: true,
- },
+ onlyStatic: true
+ }
},
card: false
}
- },
+ }
}
const inputs: ComponentSet = {
@@ -1002,18 +1043,19 @@
const display: ComponentSet = {
title: 'Display',
components: [
+ 'textcomponent',
+ 'iconcomponent',
'htmlcomponent',
+ 'tablecomponent',
+ 'barchartcomponent',
+ 'piechartcomponent',
'vegalitecomponent',
'plotlycomponent',
- 'textcomponent',
- 'tablecomponent',
- 'piechartcomponent',
- 'barchartcomponent',
'scatterchartcomponent',
'timeseriescomponent',
'displaycomponent',
'horizontaldividercomponent',
- 'verticaldividercomponent',
+ 'verticaldividercomponent'
]
}
@@ -1329,6 +1371,13 @@
"backgroundColor": "orange"
}
]`
+ },
+ iconcomponent: {
+ deno: `export async function main() {
+ return "smile";
+}`,
+ python3: `def main():
+ return "smile"`
}
} as const
@@ -1375,6 +1424,7 @@
import PlotlyHtml from '../components/dataDisplay/PlotlyHtml.svelte'
import { defaultAlignement } from './componentsPanel/componentDefaultProps'
import AppRangeInput from '../components/numberInputs/AppRangeInput.svelte'
+ import AppIcon from '../components/dataDisplay/AppIcon.svelte'
import AppCurrencyInput from '../components/numberInputs/AppCurrencyInput.svelte'
import AppDivider from '../components/AppDivider.svelte'
@@ -1535,6 +1585,8 @@
{:else if component.type === 'rangecomponent'}
+ {:else if component.type === 'iconcomponent'}
+
{/if}
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte
new file mode 100644
index 0000000000..93a17b2fd1
--- /dev/null
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte
@@ -0,0 +1,98 @@
+
+
+
+{#if anchor}
+
+
+ {#if loading}
+
+
+
+ {:else}
+ {#if filteredItems}
+
+
+ {#each filteredItems as {label, icon}}
+ {@const formatedLabel = formatName(label)}
+
+ {:else}
+
+ No icons match your search
+
+ {/each}
+
+ {:else}
+
+ Couldn't load options
+
+ {/if}
+ {/if}
+
+
+{/if}
\ No newline at end of file
diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
index 208186811f..9ee9129132 100644
--- a/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
+++ b/frontend/src/lib/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte
@@ -7,6 +7,7 @@
import JsonEditor from './JsonEditor.svelte'
import { getContext } from 'svelte'
import type { AppEditorContext } from '$lib/components/apps/types'
+ import IconSelectInput from './IconSelectInput.svelte'
export let componentInput: StaticAppInput | undefined
@@ -32,6 +33,8 @@
{/each}
+ {:else if componentInput.fieldType === 'icon-select'}
+
{:else if componentInput.fieldType === 'object'}
{#if componentInput?.format?.startsWith('resource-')}
| AppInputSpec<'array', string[], 'text'>
| AppInputSpec<'array', string[], 'textarea'>
| AppInputSpec<'array', number[], 'number'>
diff --git a/frontend/src/lib/components/apps/utils.ts b/frontend/src/lib/components/apps/utils.ts
index c8205d0b7b..b64d470ecf 100644
--- a/frontend/src/lib/components/apps/utils.ts
+++ b/frontend/src/lib/components/apps/utils.ts
@@ -200,3 +200,15 @@ export function getAllScriptNames(app: App): string[] {
return [...names, ...unusedNames, ...backgroundNames]
}
+
+function clearAndUpper(text: string) {
+ return text.replace(/-/, "").toUpperCase();
+}
+
+export function toPascalCase(text: string) {
+ return text.replace(/(^\w|-\w)/g, clearAndUpper);
+}
+
+export function toKebabCase(text: string) {
+ return text.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
+}
diff --git a/frontend/src/lib/components/common/popup/Popup.svelte b/frontend/src/lib/components/common/popup/Popup.svelte
index f79c8419f2..53019d8017 100644
--- a/frontend/src/lib/components/common/popup/Popup.svelte
+++ b/frontend/src/lib/components/common/popup/Popup.svelte
@@ -1,41 +1,40 @@
@@ -139,9 +155,9 @@
aria-expanded={$stateMachine.currentState !== 'closed'}
>
{#if $stateMachine.currentState !== 'closed'}
-