mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 00:01:55 +00:00
add more apps components
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
} from 'chart.js'
|
||||
import type { CompletedJob } from '$lib/gen'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { json } from 'svelte-highlight/languages'
|
||||
|
||||
export let jobs: CompletedJob[] | undefined = []
|
||||
|
||||
|
||||
@@ -359,6 +359,17 @@
|
||||
|
||||
languages.setLanguageConfiguration('template', conf)
|
||||
|
||||
meditor.defineTheme('myTheme', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [],
|
||||
colors: {
|
||||
'editorLineNumber.foreground': '#999',
|
||||
'editorGutter.background': '#F9FAFB'
|
||||
}
|
||||
})
|
||||
meditor.setTheme('myTheme')
|
||||
|
||||
let divEl: HTMLDivElement | null = null
|
||||
let editor: meditor.IStandaloneCodeEditor
|
||||
let model: meditor.ITextModel
|
||||
@@ -428,7 +439,7 @@
|
||||
lineNumbers: 'off',
|
||||
fontSize,
|
||||
suggestOnTriggerCharacters: true,
|
||||
lineDecorationsWidth: 24
|
||||
lineDecorationsWidth: 14
|
||||
})
|
||||
|
||||
const stdLib = { content: libStdContent, filePath: 'es5.d.ts' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Bar } from 'svelte-chartjs'
|
||||
import { Bar, Line } from 'svelte-chartjs'
|
||||
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
@@ -13,7 +13,6 @@
|
||||
BarElement
|
||||
} from 'chart.js'
|
||||
|
||||
import type { ChartData } from 'chart.js'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -35,9 +34,9 @@
|
||||
BarElement
|
||||
)
|
||||
|
||||
let result: ChartData<'bar', number[], unknown> | undefined = undefined
|
||||
let labels: string[] = []
|
||||
let result: { data: number[]; labels?: string[] } | undefined = undefined
|
||||
let theme: string = 'theme1'
|
||||
let lineChart = false
|
||||
|
||||
$: backgroundColor = {
|
||||
theme1: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'],
|
||||
@@ -59,10 +58,10 @@
|
||||
}
|
||||
|
||||
$: data = {
|
||||
labels,
|
||||
labels: result?.labels ?? [],
|
||||
datasets: [
|
||||
{
|
||||
data: result,
|
||||
data: result?.data ?? [],
|
||||
backgroundColor
|
||||
}
|
||||
]
|
||||
@@ -70,10 +69,14 @@
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.theme} bind:value={theme} />
|
||||
<InputValue {id} input={configuration.labels} bind:value={labels} />
|
||||
<InputValue {id} input={configuration.line} bind:value={lineChart} />
|
||||
|
||||
<RunnableWrapper autoRefresh bind:componentInput {id} bind:result>
|
||||
{#if result}
|
||||
<Bar {data} {options} />
|
||||
{#if lineChart}
|
||||
<Line {data} {options} />
|
||||
{:else}
|
||||
<Bar {data} {options} />
|
||||
{/if}
|
||||
{/if}
|
||||
</RunnableWrapper>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import type { AppInput } from '../../inputType'
|
||||
import AlignWrapper from '../helpers/AlignWrapper.svelte'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
export let horizontalAlignment: 'left' | 'center' | 'right' | undefined = 'left'
|
||||
export let verticalAlignment: 'top' | 'center' | 'bottom' | undefined = undefined
|
||||
export let configuration: Record<string, AppInput>
|
||||
|
||||
export const staticOutputs: string[] = ['result', 'loading']
|
||||
|
||||
let result: string | undefined = undefined
|
||||
</script>
|
||||
|
||||
<RunnableWrapper bind:componentInput {id} bind:result>
|
||||
<AlignWrapper {horizontalAlignment} {verticalAlignment}>
|
||||
<div
|
||||
on:pointerdown={(e) => {
|
||||
e?.preventDefault()
|
||||
}}
|
||||
class="h-full relative w-full overflow-hidden"
|
||||
>
|
||||
{@html result ?? 'No html'}
|
||||
</div>
|
||||
</AlignWrapper>
|
||||
</RunnableWrapper>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Pie } from 'svelte-chartjs'
|
||||
import { Doughnut, Pie } from 'svelte-chartjs'
|
||||
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
@@ -12,7 +12,6 @@
|
||||
CategoryScale,
|
||||
ArcElement
|
||||
} from 'chart.js'
|
||||
import type { ChartData } from 'chart.js'
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
@@ -34,9 +33,9 @@
|
||||
ArcElement
|
||||
)
|
||||
|
||||
let result: ChartData<'bar', number[], unknown> | undefined = undefined
|
||||
let labels: string[] = []
|
||||
let result: { data: number[]; labels?: string[] } | undefined = undefined
|
||||
let theme: string = 'theme1'
|
||||
let doughnut = false
|
||||
|
||||
$: backgroundColor = {
|
||||
theme1: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'],
|
||||
@@ -53,10 +52,10 @@
|
||||
}
|
||||
|
||||
$: data = {
|
||||
labels,
|
||||
labels: result?.labels ?? [],
|
||||
datasets: [
|
||||
{
|
||||
data: result,
|
||||
data: result?.data ?? [],
|
||||
backgroundColor: backgroundColor
|
||||
}
|
||||
]
|
||||
@@ -64,10 +63,14 @@
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.theme} bind:value={theme} />
|
||||
<InputValue {id} input={configuration.labels} bind:value={labels} />
|
||||
<InputValue {id} input={configuration.doughnutStyle} bind:value={doughnut} />
|
||||
|
||||
<RunnableWrapper autoRefresh bind:componentInput {id} bind:result>
|
||||
{#if result}
|
||||
<Pie {data} {options} />
|
||||
{#if doughnut}
|
||||
<Doughnut {data} {options} />
|
||||
{:else}
|
||||
<Pie {data} {options} />
|
||||
{/if}
|
||||
{/if}
|
||||
</RunnableWrapper>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<script lang="ts">
|
||||
import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale,
|
||||
BarElement
|
||||
} from 'chart.js'
|
||||
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import Scatter from 'svelte-chartjs/Scatter.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
export let configuration: Record<string, AppInput>
|
||||
|
||||
export const staticOutputs: string[] = ['loading', 'result']
|
||||
|
||||
ChartJS.register(
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale,
|
||||
BarElement,
|
||||
zoomPlugin
|
||||
)
|
||||
|
||||
const zoomOptions = {
|
||||
pan: {
|
||||
enabled: true
|
||||
},
|
||||
zoom: {
|
||||
drag: {
|
||||
enabled: false
|
||||
},
|
||||
wheel: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result: { data: { x: any[]; y: string[] } } | undefined = undefined
|
||||
|
||||
const options = {
|
||||
responsive: true,
|
||||
animation: false,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
zoom: zoomOptions
|
||||
}
|
||||
}
|
||||
|
||||
$: data = {
|
||||
datasets: result ?? []
|
||||
}
|
||||
</script>
|
||||
|
||||
<RunnableWrapper autoRefresh bind:componentInput {id} bind:result>
|
||||
{#if result}
|
||||
<Scatter {data} {options} />
|
||||
{/if}
|
||||
</RunnableWrapper>
|
||||
@@ -0,0 +1,90 @@
|
||||
<script lang="ts">
|
||||
import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
import 'chartjs-adapter-date-fns'
|
||||
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale,
|
||||
BarElement,
|
||||
TimeScale,
|
||||
LogarithmicScale
|
||||
} from 'chart.js'
|
||||
|
||||
import RunnableWrapper from '../helpers/RunnableWrapper.svelte'
|
||||
import type { AppInput } from '../../inputType'
|
||||
import Scatter from 'svelte-chartjs/Scatter.svelte'
|
||||
import InputValue from '../helpers/InputValue.svelte'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
export let configuration: Record<string, AppInput>
|
||||
|
||||
export const staticOutputs: string[] = ['loading', 'result']
|
||||
|
||||
let logarithmicScale = false
|
||||
|
||||
ChartJS.register(
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale,
|
||||
BarElement,
|
||||
zoomPlugin,
|
||||
TimeScale,
|
||||
LogarithmicScale
|
||||
)
|
||||
|
||||
const zoomOptions = {
|
||||
pan: {
|
||||
enabled: true
|
||||
},
|
||||
zoom: {
|
||||
drag: {
|
||||
enabled: false
|
||||
},
|
||||
wheel: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result: { data: { x: any[]; y: string[] } } | undefined = undefined
|
||||
|
||||
$: options = {
|
||||
responsive: true,
|
||||
animation: false,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
zoom: zoomOptions
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time'
|
||||
},
|
||||
y: {
|
||||
type: logarithmicScale ? 'logarithmic' : 'linear'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$: data = {
|
||||
datasets: result ?? []
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.logarithmicScale} bind:value={logarithmicScale} />
|
||||
|
||||
<RunnableWrapper autoRefresh bind:componentInput {id} bind:result>
|
||||
{#if result}
|
||||
<Scatter {data} {options} />
|
||||
{/if}
|
||||
</RunnableWrapper>
|
||||
@@ -156,7 +156,7 @@
|
||||
</SplitPanesWrapper>
|
||||
</Pane>
|
||||
<Pane size={21} minSize={5} maxSize={33}>
|
||||
<div class="relative">
|
||||
<div class="relative flex flex-col h-full">
|
||||
<Tabs bind:selected={selectedTab}>
|
||||
<Tab value="insert" size="xs">
|
||||
<div class="m-1 flex flex-row gap-2">
|
||||
@@ -171,7 +171,7 @@
|
||||
</div>
|
||||
</Tab>
|
||||
<svelte:fragment slot="content">
|
||||
<TabContent value="settings">
|
||||
<TabContent class="overflow-auto" value="settings">
|
||||
{#if $selectedComponent !== undefined}
|
||||
<SettingsPanel />
|
||||
{:else}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
import DateInputComponent from '../components/dateInputs/AppDateInput.svelte'
|
||||
import ComponentHeader from './ComponentHeader.svelte'
|
||||
import AppForm from '../components/form/AppForm.svelte'
|
||||
import AppScatterChart from '../components/dataDisplay/AppScatterChart.svelte'
|
||||
import AppTimeseries from '../components/dataDisplay/AppTimeseries.svelte'
|
||||
import AppHtml from '../components/dataDisplay/AppHtml.svelte'
|
||||
|
||||
export let component: AppComponent
|
||||
export let selected: boolean
|
||||
@@ -35,12 +38,18 @@
|
||||
{/if}
|
||||
|
||||
<div
|
||||
on:pointerdown={(e) => {
|
||||
if ($mode === 'preview') {
|
||||
e?.stopPropagation()
|
||||
}
|
||||
}}
|
||||
class={classNames(
|
||||
'border cursor-pointer h-full bg-white',
|
||||
'border h-full bg-white',
|
||||
selected && $mode !== 'preview' ? 'border-blue-500' : 'border-white',
|
||||
!selected && $mode !== 'preview' && !component.card ? 'border-gray-100' : '',
|
||||
$mode !== 'preview' && !$connectingInput.opened ? 'hover:border-blue-500' : '',
|
||||
component.softWrap ? '' : 'overflow-auto',
|
||||
$mode != 'preview' ? 'cursor-pointer' : '',
|
||||
'relative z-auto'
|
||||
)}
|
||||
>
|
||||
@@ -56,6 +65,24 @@
|
||||
bind:componentInput={component.componentInput}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'timeseriescomponent'}
|
||||
<AppTimeseries
|
||||
{...component}
|
||||
bind:componentInput={component.componentInput}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'htmlcomponent'}
|
||||
<AppHtml
|
||||
{...component}
|
||||
bind:componentInput={component.componentInput}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'scatterchartcomponent'}
|
||||
<AppScatterChart
|
||||
{...component}
|
||||
bind:componentInput={component.componentInput}
|
||||
bind:staticOutputs={$staticOutputs[component.id]}
|
||||
/>
|
||||
{:else if component.type === 'piechartcomponent'}
|
||||
<PieChartComponent
|
||||
{...component}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
const dimensions: Record<`${number}:${number}-${number}:${number}`, AppComponent['type'][]> = {
|
||||
'4:1-4:1': ['textcomponent'],
|
||||
'2:1-2:1': ['buttoncomponent'],
|
||||
'2:2-2:2': ['htmlcomponent'],
|
||||
'4:2-4:2': [
|
||||
'checkboxcomponent',
|
||||
'textinputcomponent',
|
||||
@@ -30,7 +31,13 @@
|
||||
'dateinputcomponent'
|
||||
],
|
||||
'3:5-6:5': ['formcomponent'],
|
||||
'4:12-4:12': ['barchartcomponent', 'piechartcomponent', 'displaycomponent'],
|
||||
'4:12-4:12': [
|
||||
'timeseriescomponent',
|
||||
'barchartcomponent',
|
||||
'piechartcomponent',
|
||||
'displaycomponent',
|
||||
'scatterchartcomponent'
|
||||
],
|
||||
'3:10-6:12': ['tablecomponent']
|
||||
}
|
||||
// Finds the key that is associated with the component type and extracts the dimensions from it
|
||||
|
||||
@@ -179,6 +179,24 @@ const buttons: ComponentSet = {
|
||||
const display: ComponentSet = {
|
||||
title: 'Display',
|
||||
components: [
|
||||
{
|
||||
softWrap: false,
|
||||
id: 'htmlcomponent',
|
||||
type: 'htmlcomponent',
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'template',
|
||||
value: `<img
|
||||
src="https://images.unsplash.com/photo-1554629947-334ff61d85dc?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1024&h=1280&q=80"
|
||||
>
|
||||
<div class="absolute top-4 left-2 text-white">
|
||||
Hello \${ctx.username}
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
configuration: {},
|
||||
card: false
|
||||
},
|
||||
{
|
||||
softWrap: true,
|
||||
horizontalAlignment: 'left',
|
||||
@@ -187,7 +205,7 @@ const display: ComponentSet = {
|
||||
type: 'textcomponent',
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'textarea',
|
||||
fieldType: 'template',
|
||||
value: 'Hello ${ctx.username}',
|
||||
},
|
||||
configuration: {
|
||||
@@ -260,19 +278,17 @@ const display: ComponentSet = {
|
||||
optionValuesKey: 'chartThemeOptions',
|
||||
value: 'theme1'
|
||||
},
|
||||
labels: {
|
||||
doughnutStyle: {
|
||||
type: 'static',
|
||||
value: ['First', 'Second', 'Third'],
|
||||
fieldType: 'array',
|
||||
subFieldType: 'text',
|
||||
onlyStatic: true,
|
||||
fieldType: 'boolean',
|
||||
value: false
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'number',
|
||||
value: [25, 50, 25],
|
||||
|
||||
fieldType: 'object',
|
||||
value: { data: [25, 50, 25], labels: ['Pie', 'Charts', '<3'] }
|
||||
},
|
||||
card: true
|
||||
},
|
||||
@@ -287,20 +303,93 @@ const display: ComponentSet = {
|
||||
optionValuesKey: 'chartThemeOptions',
|
||||
value: 'theme1'
|
||||
},
|
||||
labels: {
|
||||
line: {
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
fieldType: 'boolean',
|
||||
value: false
|
||||
}
|
||||
|
||||
fieldType: 'array',
|
||||
subFieldType: 'text',
|
||||
value: ['Lorem ipsum', 'Lorem ipsum', 'Lorem ipsum']
|
||||
},
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'object',
|
||||
value: { data: [25, 50, 25], labels: ['Bar', 'Charts', '<3'] }
|
||||
},
|
||||
card: true
|
||||
},
|
||||
{
|
||||
id: 'scatterchartcomponent',
|
||||
type: 'scatterchartcomponent',
|
||||
configuration: {},
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'object',
|
||||
value: [{
|
||||
label: 'foo',
|
||||
data: [
|
||||
{ x: 25, y: 50 },
|
||||
{ x: 23, y: 23 },
|
||||
{ x: 12, y: 37 }
|
||||
],
|
||||
backgroundColor: 'rgb(255, 12, 137)'
|
||||
},
|
||||
{
|
||||
label: 'foobar',
|
||||
data: [
|
||||
{ x: 32, y: 32 },
|
||||
{ x: 25, y: 42 },
|
||||
{ x: 3, y: 27 }
|
||||
],
|
||||
backgroundColor: 'orange'
|
||||
}]
|
||||
},
|
||||
card: true
|
||||
},
|
||||
{
|
||||
id: 'timeseriescomponent',
|
||||
type: 'timeseriescomponent',
|
||||
configuration: {
|
||||
logarithmicScale: {
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
fieldType: 'boolean',
|
||||
value: false
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
fieldType: 'array',
|
||||
subFieldType: 'number',
|
||||
value: [25, 50, 25],
|
||||
|
||||
subFieldType: 'object',
|
||||
value: [{
|
||||
label: 'foo',
|
||||
data: [{
|
||||
x: '2021-11-06 23:39:30',
|
||||
y: 50
|
||||
}, {
|
||||
x: '2021-11-07 01:00:28',
|
||||
y: 60
|
||||
}, {
|
||||
x: '2021-11-07 09:00:28',
|
||||
y: 20
|
||||
}],
|
||||
backgroundColor: 'rgb(255, 12, 137)'
|
||||
},
|
||||
{
|
||||
label: 'foobar',
|
||||
data: [{
|
||||
x: '2021-11-06 23:39:30',
|
||||
y: 20
|
||||
}, {
|
||||
x: '2021-11-07 01:00:28',
|
||||
y: 13
|
||||
}, {
|
||||
x: '2021-11-07 09:00:28',
|
||||
y: 45
|
||||
}],
|
||||
backgroundColor: 'orange'
|
||||
}]
|
||||
},
|
||||
card: true
|
||||
},
|
||||
@@ -315,7 +404,8 @@ const display: ComponentSet = {
|
||||
},
|
||||
configuration: {},
|
||||
card: false
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
|
||||
function getComponentNameById(componentId: string) {
|
||||
const component = $app.grid.find((c) => c.data.id === componentId)
|
||||
const component = $app.grid.find((c) => c?.data?.id === componentId)
|
||||
|
||||
if (component?.data.type) {
|
||||
return displayData[component?.data.type].name
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
import { emptySchema } from '$lib/utils'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import { fly } from 'svelte/transition'
|
||||
import { defaultCode } from '../../editorUtils'
|
||||
import type { AppEditorContext } from '../../types'
|
||||
|
||||
export let name: string
|
||||
export let id: string
|
||||
|
||||
const { appPath } = getContext<AppEditorContext>('AppEditorContext')
|
||||
const { appPath, app } = getContext<AppEditorContext>('AppEditorContext')
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
async function inferInlineScriptSchema(
|
||||
@@ -33,8 +35,12 @@
|
||||
path: string,
|
||||
subkind: 'pgsql' | 'mysql' | undefined = undefined
|
||||
) {
|
||||
const componentType = $app.grid.find((c) => c.data.id === id)?.data?.type
|
||||
|
||||
const fullPath = `${appPath}/inline-script/${path}`
|
||||
const content = initialCode(language, Script.kind.SCRIPT, subkind ?? 'flow')
|
||||
const content =
|
||||
defaultCode(componentType, language) ??
|
||||
initialCode(language, Script.kind.SCRIPT, subkind ?? 'flow')
|
||||
|
||||
let schema: Schema = emptySchema()
|
||||
|
||||
|
||||
+1
@@ -61,6 +61,7 @@
|
||||
/>
|
||||
{:else}
|
||||
<EmptyInlineScript
|
||||
{id}
|
||||
name={componentInput.runnable.name}
|
||||
on:new={(e) => {
|
||||
if (
|
||||
|
||||
@@ -44,16 +44,17 @@
|
||||
<div class="flex gap-2 flex-col mt-2">
|
||||
{#if componentInput.value}
|
||||
{#each componentInput.value as value, index (index)}
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
<div class="flex flex-row gap-2 items-center relative">
|
||||
<SubTypeEditor bind:componentInput bind:value />
|
||||
|
||||
<div>
|
||||
<div class="absolute top-4 right-4">
|
||||
<Button
|
||||
size="xs"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => deleteElementByType(index)}
|
||||
iconOnly
|
||||
btnClasses="!text-red-500"
|
||||
startIcon={{ icon: faTrashAlt }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@
|
||||
|
||||
const { onchange } = getContext<AppEditorContext>('AppEditorContext')
|
||||
|
||||
$: if (componentInput.fieldType == 'textarea' && componentInput.type == 'static') {
|
||||
$: if (componentInput.fieldType == 'template' && componentInput.type == 'static') {
|
||||
//@ts-ignore
|
||||
componentInput.type = 'template'
|
||||
componentInput['eval'] = componentInput.value
|
||||
@@ -24,7 +24,7 @@
|
||||
{#if componentInput.fieldType !== 'any'}
|
||||
<div class="w-full overflow-x-auto" bind:clientWidth>
|
||||
<ToggleButtonGroup on:selected={() => onchange?.()} bind:selected={componentInput.type}>
|
||||
{#if componentInput.fieldType === 'textarea'}
|
||||
{#if componentInput.fieldType === 'template'}
|
||||
<ToggleButton position="left" value="template" size="xs" disable={disableStatic}>
|
||||
{brackets} <span class="hidden lg:block">Template</span>
|
||||
</ToggleButton>
|
||||
|
||||
@@ -123,7 +123,7 @@ declare const ${k} = ${JSON.stringify(v)};
|
||||
<StaticInputEditor bind:componentInput={component.componentInput} />
|
||||
{:else if component.componentInput.type === 'template' && component.componentInput !== undefined}
|
||||
<div class="py-1 min-h-[28px] rounded border border-1 border-gray-500">
|
||||
<TemplateEditor bind:code={component.componentInput.eval} {extraLib} />
|
||||
<TemplateEditor fontSize={12} bind:code={component.componentInput.eval} {extraLib} />
|
||||
</div>
|
||||
{:else if component.componentInput.type === 'connected' && component.componentInput !== undefined}
|
||||
<ConnectedInputEditor bind:componentInput={component.componentInput} />
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
$: code && parseJson()
|
||||
</script>
|
||||
|
||||
<div class="border rounded-sm w-full">
|
||||
<SimpleEditor lang="json" bind:code class="few-lines-editor" />
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="border border-gray-300 w-full">
|
||||
<SimpleEditor autoHeight lang="json" bind:code />
|
||||
</div>
|
||||
{#if error != ''}
|
||||
<span class="text-red-600 text-xs">{error}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if error != ''}
|
||||
<span class="text-red-600 text-xs">{error}</span>
|
||||
{/if}
|
||||
|
||||
+10
@@ -103,6 +103,16 @@
|
||||
acc.push(componentInput.runnable.name)
|
||||
}
|
||||
|
||||
if (componentInput.type === 'tablecomponent') {
|
||||
componentInput.actionButtons.forEach((actionButton) => {
|
||||
if (actionButton.componentInput?.type === 'runnable') {
|
||||
if (actionButton.componentInput.runnable?.type === 'runnableByName') {
|
||||
acc.push(actionButton.componentInput.runnable.name)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [] as string[])
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export function defaultCode(component: string, language: string): string | undefined {
|
||||
return undefined
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import type { InlineScript } from './types'
|
||||
export type InputType =
|
||||
| 'text'
|
||||
| 'textarea'
|
||||
| 'template'
|
||||
| 'number'
|
||||
| 'boolean'
|
||||
| 'select'
|
||||
@@ -91,6 +92,7 @@ type InputConfiguration<T extends InputType, U, V extends InputType> = {
|
||||
export type AppInput =
|
||||
| AppInputSpec<'text', string>
|
||||
| AppInputSpec<'textarea', string>
|
||||
| AppInputSpec<'template', string>
|
||||
| AppInputSpec<'number', number>
|
||||
| AppInputSpec<'boolean', boolean>
|
||||
| AppInputSpec<'date', string>
|
||||
|
||||
@@ -20,6 +20,8 @@ export type TextInputComponent = BaseComponent<'textinputcomponent'>
|
||||
export type PasswordInputComponent = BaseComponent<'passwordinputcomponent'>
|
||||
export type DateInputComponent = BaseComponent<'dateinputcomponent'>
|
||||
export type NumberInputComponent = BaseComponent<'numberinputcomponent'>
|
||||
export type HtmlComponent = BaseComponent<'htmlcomponent'>
|
||||
export type TimeseriesComponent = BaseComponent<'timeseriescomponent'>
|
||||
export type ButtonComponent = BaseComponent<'buttoncomponent'> & {
|
||||
recomputeIds: string[] | undefined
|
||||
}
|
||||
@@ -31,6 +33,7 @@ export type FormComponent = BaseComponent<'formcomponent'> & {
|
||||
export type RunFormComponent = BaseComponent<'runformcomponent'>
|
||||
export type BarChartComponent = BaseComponent<'barchartcomponent'>
|
||||
export type PieChartComponent = BaseComponent<'piechartcomponent'>
|
||||
export type ScatterChartComponent = BaseComponent<'scatterchartcomponent'>
|
||||
export type TableComponent = BaseComponent<'tablecomponent'> & {
|
||||
actionButtons: (BaseAppComponent & ButtonComponent)[]
|
||||
}
|
||||
@@ -72,11 +75,14 @@ export type AppComponent = BaseAppComponent &
|
||||
| DateInputComponent
|
||||
| NumberInputComponent
|
||||
| BarChartComponent
|
||||
| TimeseriesComponent
|
||||
| HtmlComponent
|
||||
| TableComponent
|
||||
| TextComponent
|
||||
| TableComponent
|
||||
| ButtonComponent
|
||||
| PieChartComponent
|
||||
| ScatterChartComponent
|
||||
| ImageComponent
|
||||
| InputComponent
|
||||
| SelectComponent
|
||||
|
||||
@@ -17,7 +17,9 @@ import {
|
||||
Type,
|
||||
Lock,
|
||||
Calendar,
|
||||
ToggleLeft
|
||||
ToggleLeft,
|
||||
GripHorizontal,
|
||||
Code2
|
||||
} from 'lucide-svelte'
|
||||
import type { AppInput, InputType, ResultAppInput, StaticAppInput } from './inputType'
|
||||
import type { AppComponent } from './types'
|
||||
@@ -93,9 +95,21 @@ export const displayData: Record<AppComponent['type'], { name: string; icon: any
|
||||
icon: PieChart
|
||||
},
|
||||
barchartcomponent: {
|
||||
name: 'Bar Chart',
|
||||
name: 'Bar/Line Chart',
|
||||
icon: BarChart4
|
||||
},
|
||||
htmlcomponent: {
|
||||
name: 'Html',
|
||||
icon: Code2
|
||||
},
|
||||
timeseriescomponent: {
|
||||
name: 'Timeseries',
|
||||
icon: GripHorizontal
|
||||
},
|
||||
scatterchartcomponent: {
|
||||
name: 'Scatter Chart',
|
||||
icon: GripHorizontal
|
||||
},
|
||||
tablecomponent: {
|
||||
name: 'Table',
|
||||
icon: Table2
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<div
|
||||
class={classNames(
|
||||
'border-b border-gray-200 flex flex-row whitespace-nowrap overflow-y-auto scrollbar-hidden',
|
||||
'border-b border-gray-200 flex flex-row whitespace-nowrap scrollbar-hidden',
|
||||
$$props.class
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user