mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 08:07:15 +00:00
fix(frontend): improve app tables
This commit is contained in:
@@ -4,15 +4,15 @@
|
||||
import 'ag-grid-community/styles/ag-theme-alpine.css'
|
||||
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import type { Output } from '../../../rx'
|
||||
import type { AppViewerContext, RichConfiguration, RichConfigurations } from '../../../types'
|
||||
import InputValue from '../../helpers/InputValue.svelte'
|
||||
import type { AppInput } from '../../../inputType'
|
||||
import RunnableWrapper from '../../helpers/RunnableWrapper.svelte'
|
||||
import { isObject } from '$lib/utils'
|
||||
|
||||
import Alert from '$lib/components/common/alert/Alert.svelte'
|
||||
import { initOutput } from '$lib/components/apps/editor/appUtils'
|
||||
import { initConfig, initOutput } from '$lib/components/apps/editor/appUtils'
|
||||
import ResolveConfig from '../../helpers/ResolveConfig.svelte'
|
||||
import { components } from '$lib/components/apps/editor/component'
|
||||
|
||||
export let id: string
|
||||
export let componentInput: AppInput | undefined
|
||||
@@ -24,12 +24,18 @@
|
||||
|
||||
const { worldStore, selectedComponent } = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
let resolvedConfig = initConfig(
|
||||
components['aggridcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
selectedRowIndex: 0,
|
||||
selectedRow: {},
|
||||
result: [] as Record<number, any>[],
|
||||
loading: false,
|
||||
page: 0
|
||||
page: 0,
|
||||
newChange: { row: 0, column: '', value: undefined }
|
||||
})
|
||||
|
||||
let selectedRowIndex = -1
|
||||
@@ -60,27 +66,32 @@
|
||||
let clientHeight
|
||||
let clientWidth
|
||||
|
||||
let columnDefs: any = undefined
|
||||
|
||||
let allEditable: boolean | undefined = undefined
|
||||
let pagination: boolean | undefined = undefined
|
||||
let pageSize: number | undefined = 10
|
||||
|
||||
function onCellValueChanged(event) {
|
||||
if (result) {
|
||||
console.log(event)
|
||||
|
||||
let dataCell = event.newValue
|
||||
try {
|
||||
dataCell = JSON.parse(dataCell)
|
||||
} catch (e) {}
|
||||
outputs?.newChange?.set({
|
||||
row: event.node.rowIndex,
|
||||
column: event.colDef.field,
|
||||
value: dataCell
|
||||
})
|
||||
result[event.node.rowIndex][event.column.colId] = dataCell
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputValue {id} input={configuration.columnDefs} bind:value={columnDefs} />
|
||||
<InputValue {id} input={configuration.allEditable} bind:value={allEditable} />
|
||||
<InputValue {id} input={configuration.pagination} bind:value={pagination} />
|
||||
<InputValue {id} input={configuration.pageSize} bind:value={pageSize} />
|
||||
{#each Object.keys(components['aggridcomponent'].initialData.configuration) as key (key)}
|
||||
<ResolveConfig
|
||||
{id}
|
||||
{key}
|
||||
bind:resolvedConfig={resolvedConfig[key]}
|
||||
configuration={configuration[key]}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<RunnableWrapper {outputs} {render} {componentInput} {id} bind:initializing bind:result>
|
||||
{#if Array.isArray(result) && result.every(isObject)}
|
||||
@@ -97,13 +108,16 @@
|
||||
style:width="{clientWidth}px"
|
||||
class="ag-theme-alpine"
|
||||
>
|
||||
{#key pagination}
|
||||
{#key resolvedConfig?.pagination}
|
||||
<AgGridSvelte
|
||||
bind:rowData={result}
|
||||
{columnDefs}
|
||||
{pagination}
|
||||
paginationPageSize={pageSize}
|
||||
defaultColDef={{ flex: 1, editable: allEditable, onCellValueChanged }}
|
||||
columnDefs={resolvedConfig?.columnDefs}
|
||||
pagination={resolvedConfig?.pagination}
|
||||
paginationAutoPageSize={resolvedConfig?.pagination}
|
||||
defaultColDef={{ flex: 1, editable: resolvedConfig?.allEditable, onCellValueChanged }}
|
||||
onPaginationChanged={(event) => {
|
||||
outputs?.page.set(event.api.paginationGetCurrentPage())
|
||||
}}
|
||||
/>
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
@@ -66,10 +66,7 @@
|
||||
let resolvedConfig = initConfig(
|
||||
components['tablecomponent'].initialData.configuration,
|
||||
configuration
|
||||
) as {
|
||||
search: 'By Component' | 'By Runnable' | 'Disabled' | undefined
|
||||
manualPagination: boolean
|
||||
}
|
||||
)
|
||||
|
||||
let selectedRowIndex = -1
|
||||
|
||||
@@ -124,7 +121,8 @@
|
||||
filteredResult = searchInResult(result ?? [], searchValue)
|
||||
}
|
||||
}
|
||||
$: (result || resolvedConfig.search || searchValue) && setFilteredResult()
|
||||
$: (result || resolvedConfig.search || searchValue || resolvedConfig.pagination) &&
|
||||
setFilteredResult()
|
||||
|
||||
$: outputs.page.set($table.getState().pagination.pageIndex)
|
||||
|
||||
@@ -139,7 +137,20 @@
|
||||
|
||||
$options = {
|
||||
...tableOptions,
|
||||
manualPagination: resolvedConfig.manualPagination,
|
||||
...(resolvedConfig?.pagination?.selected != 'manual'
|
||||
? {
|
||||
initialState: {
|
||||
pagination: {
|
||||
pageSize: resolvedConfig?.pagination?.configuration?.auto?.pageSize ?? 20
|
||||
}
|
||||
}
|
||||
}
|
||||
: {}),
|
||||
manualPagination: resolvedConfig?.pagination?.selected == 'manual',
|
||||
pageCount:
|
||||
resolvedConfig?.pagination?.selected == 'manual'
|
||||
? resolvedConfig?.pagination?.configuration.manual.pageCount ?? -1
|
||||
: undefined,
|
||||
data: filteredResult,
|
||||
columns: headers.map((header) => {
|
||||
return {
|
||||
@@ -381,8 +392,8 @@
|
||||
</div>
|
||||
|
||||
<AppTableFooter
|
||||
paginationEnabled
|
||||
manualPagination={resolvedConfig.manualPagination}
|
||||
pageSize={resolvedConfig?.pagination?.configuration?.auto?.pageSize ?? 20}
|
||||
manualPagination={resolvedConfig?.pagination?.selected == 'manual'}
|
||||
result={filteredResult}
|
||||
{table}
|
||||
class={css?.tableFooter?.class}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
type T = Record<string, any>
|
||||
|
||||
export let result: Array<T>
|
||||
export let paginationEnabled: boolean = false
|
||||
export let manualPagination: boolean
|
||||
export let pageSize: number
|
||||
export let table: Readable<Table<T>>
|
||||
let c = ''
|
||||
export { c as class }
|
||||
@@ -32,7 +32,7 @@
|
||||
class={twMerge('px-2 py-1 text-xs gap-2 items-center justify-between', c, 'flex flex-row')}
|
||||
{style}
|
||||
>
|
||||
{#if (paginationEnabled && result.length > (tableOptions.initialState?.pagination?.pageSize ?? 25)) || manualPagination}
|
||||
{#if result.length > pageSize || manualPagination}
|
||||
<div class="flex items-center gap-2 flex-row">
|
||||
<Button
|
||||
size="xs"
|
||||
|
||||
@@ -144,7 +144,6 @@
|
||||
$: if ($selectedComponent?.[0] != befSelected) {
|
||||
befSelected = $selectedComponent?.[0]
|
||||
selectedTab = 'settings'
|
||||
console.log('focusedGrid1', befSelected)
|
||||
|
||||
if (befSelected) {
|
||||
if (!['ctx', 'state'].includes(befSelected) && !befSelected?.startsWith('bg_')) {
|
||||
|
||||
@@ -264,6 +264,34 @@ const onSuccessClick = {
|
||||
}
|
||||
} as const
|
||||
|
||||
const paginationOneOf = {
|
||||
type: 'oneOf',
|
||||
selected: 'auto',
|
||||
labels: {
|
||||
auto: 'Auto',
|
||||
manual: 'Manual'
|
||||
},
|
||||
configuration: {
|
||||
auto: {
|
||||
pageSize: {
|
||||
type: 'static',
|
||||
fieldType: 'number',
|
||||
value: 20,
|
||||
onlyStatic: true,
|
||||
tooltip: 'Number of rows per page'
|
||||
}
|
||||
},
|
||||
manual: {
|
||||
pageCount: {
|
||||
type: 'static',
|
||||
fieldType: 'number',
|
||||
value: -1,
|
||||
tooltip: 'Number of pages (-1 if you do not know)'
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const
|
||||
|
||||
export const components = {
|
||||
displaycomponent: {
|
||||
name: 'Rich Result',
|
||||
@@ -787,23 +815,9 @@ Hello \${ctx.username}
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
selectOptions: selectOptions.tableSearchOptions,
|
||||
value: 'Disabled'
|
||||
value: 'Disabled' as string
|
||||
},
|
||||
manualPagination: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
onlyStatic: true,
|
||||
value: false,
|
||||
tooltip:
|
||||
'Pagination would not be handled by the component but by the script itself. Connect to the pagination output'
|
||||
},
|
||||
pageSize: {
|
||||
type: 'static',
|
||||
fieldType: 'number',
|
||||
value: 25,
|
||||
onlyStatic: true,
|
||||
tooltip: 'Number of rows per page'
|
||||
}
|
||||
pagination: paginationOneOf
|
||||
},
|
||||
componentInput: {
|
||||
type: 'static',
|
||||
@@ -850,13 +864,6 @@ Hello \${ctx.username}
|
||||
fieldType: 'boolean',
|
||||
value: false,
|
||||
onlyStatic: true
|
||||
},
|
||||
pageSize: {
|
||||
type: 'static',
|
||||
fieldType: 'number',
|
||||
value: 10,
|
||||
onlyStatic: true,
|
||||
tooltip: 'Number of rows per page'
|
||||
}
|
||||
},
|
||||
componentInput: {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
{#if inputSpecs}
|
||||
<div class="w-full flex flex-col gap-4">
|
||||
{#each Object.keys(inputSpecsConfiguration) as k}
|
||||
{#if inputSpecs[k] && inputSpecs[k]?.type == 'oneOf'}
|
||||
{#if inputSpecsConfiguration[k]?.type == 'oneOf'}
|
||||
<OneOfInputSpecsEditor
|
||||
key={k}
|
||||
bind:oneOf={inputSpecs[k]}
|
||||
|
||||
@@ -13,13 +13,26 @@
|
||||
export let rowColumns: boolean
|
||||
export let tooltip: string | undefined
|
||||
|
||||
$: if (oneOf.configuration[oneOf.selected] == undefined) {
|
||||
oneOf.configuration[oneOf.selected] = {}
|
||||
$: {
|
||||
if (oneOf == undefined) {
|
||||
oneOf = { configuration: {}, selected: '' }
|
||||
}
|
||||
if (oneOf.configuration == undefined) {
|
||||
oneOf.configuration = {}
|
||||
}
|
||||
if (oneOf.selected == undefined) {
|
||||
oneOf.selected = ''
|
||||
}
|
||||
if (oneOf?.configuration[oneOf?.selected] == undefined) {
|
||||
oneOf.configuration[oneOf.selected] = {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="p-2 border">
|
||||
<h4 class="mb-2">{key} <Tooltip>{tooltip}</Tooltip></h4>
|
||||
<h4 class="mb-2"
|
||||
>{key} {#if tooltip}<Tooltip>{tooltip}</Tooltip>{/if}</h4
|
||||
>
|
||||
<select
|
||||
class="w-full border border-gray-300 rounded-md p-2"
|
||||
value={oneOf.selected}
|
||||
@@ -49,6 +62,7 @@
|
||||
format={config?.['format']}
|
||||
selectOptions={config?.['selectOptions']}
|
||||
placeholder={config?.['placeholder']}
|
||||
onlyStatic={config?.['onlyStatic']}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user