feat(apps): add ag grid

This commit is contained in:
Ruben Fiszel
2023-02-25 13:11:50 +01:00
parent 104e4ac5e7
commit b690d801d4
6 changed files with 196 additions and 0 deletions
+32
View File
@@ -14,6 +14,7 @@
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
"@tanstack/svelte-table": "^8.7.6",
"ag-grid-svelte": "^0.1.4",
"async-mutex": "^0.4.0",
"chart.js": "^3.9.1",
"chartjs-adapter-date-fns": "^3.0.0",
@@ -1357,6 +1358,23 @@
"node": ">=0.4.0"
}
},
"node_modules/ag-grid-community": {
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.2.1.tgz",
"integrity": "sha512-DMZh/xD/FqYP17qJ1M92PolTYe+hrKuEaf+A4h13O6qn2x/xZQrTRGW5DgnQLR/uLMe1XXZQPKR3UKgAlKo69A==",
"peer": true
},
"node_modules/ag-grid-svelte": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/ag-grid-svelte/-/ag-grid-svelte-0.1.4.tgz",
"integrity": "sha512-yKJKZ1o3aE9dgaK4WtmjG+vA9GKqErznvFisDnzi+PPGWXDCSNWuoDGCUpEFJtHKrfooLoUZZHYHi8I9sZ+BCA==",
"dependencies": {
"svelte": "^3.55.0"
},
"peerDependencies": {
"ag-grid-community": "^28"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -7980,6 +7998,20 @@
"integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
"dev": true
},
"ag-grid-community": {
"version": "28.2.1",
"resolved": "https://registry.npmjs.org/ag-grid-community/-/ag-grid-community-28.2.1.tgz",
"integrity": "sha512-DMZh/xD/FqYP17qJ1M92PolTYe+hrKuEaf+A4h13O6qn2x/xZQrTRGW5DgnQLR/uLMe1XXZQPKR3UKgAlKo69A==",
"peer": true
},
"ag-grid-svelte": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/ag-grid-svelte/-/ag-grid-svelte-0.1.4.tgz",
"integrity": "sha512-yKJKZ1o3aE9dgaK4WtmjG+vA9GKqErznvFisDnzi+PPGWXDCSNWuoDGCUpEFJtHKrfooLoUZZHYHi8I9sZ+BCA==",
"requires": {
"svelte": "^3.55.0"
}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+1
View File
@@ -66,6 +66,7 @@
"@popperjs/core": "^2.11.6",
"@redocly/json-to-json-schema": "^0.0.1",
"@tanstack/svelte-table": "^8.7.6",
"ag-grid-svelte": "^0.1.4",
"async-mutex": "^0.4.0",
"chart.js": "^3.9.1",
"chartjs-adapter-date-fns": "^3.0.0",
@@ -0,0 +1,110 @@
<script lang="ts">
import AgGridSvelte from 'ag-grid-svelte/AgGridSvelte.svelte'
import 'ag-grid-community/styles/ag-grid.css'
import 'ag-grid-community/styles/ag-theme-alpine.css'
import { getContext, onMount } from 'svelte'
import type { Output } from '../../../rx'
import type { AppEditorContext } 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'
export let id: string
export let componentInput: AppInput | undefined
export let configuration: Record<string, AppInput>
export let initializing: boolean | undefined = undefined
export const staticOutputs: string[] = ['selectedRow', 'loading', 'result', 'selectedRowIndex']
let result: Record<string, any>[] | undefined = undefined
const {
worldStore,
staticOutputs: staticOutputsStore,
selectedComponent
} = getContext<AppEditorContext>('AppEditorContext')
let selectedRowIndex = -1
function toggleRow(row: Record<string, any>, rowIndex: number) {
if (selectedRowIndex !== rowIndex) {
selectedRowIndex = rowIndex
outputs?.selectedRow.set(row.original)
outputs?.selectedRowIndex.set(rowIndex)
}
}
let mounted = false
onMount(() => {
mounted = true
})
$: selectedRowIndex === -1 &&
Array.isArray(result) &&
result.length > 0 &&
// We need to wait until the component is mounted so the world is created
mounted &&
outputs &&
toggleRow({ original: result[0] }, 0)
$: outputs = $worldStore?.outputsById[id] as {
selectedRowIndex: Output<number>
selectedRow: Output<any>
result: Output<any>
}
$: outputs?.result?.set(result)
let clientHeight
let clientWidth
let columnDefs: any = undefined
let allEditable: boolean | undefined = undefined
function onCellValueChanged(event) {
if (result) {
let dataCell = event.newValue
try {
dataCell = JSON.parse(dataCell)
} catch (e) {}
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} />
<RunnableWrapper flexWrap bind:componentInput {id} bind:initializing bind:result>
{#if Array.isArray(result) && result.every(isObject)}
<div
class="border border-gray-300 shadow-sm divide-y divide-gray-300 flex flex-col h-full"
bind:clientHeight
bind:clientWidth
>
<div
on:pointerdown|stopPropagation={() => {
$selectedComponent = id
}}
style:height="{clientHeight}px"
style:width="{clientWidth}px"
class="ag-theme-alpine"
>
<AgGridSvelte
bind:rowData={result}
{columnDefs}
defaultColDef={{ flex: 1, editable: allEditable, onCellValueChanged }}
/>
</div>
</div>
{:else if result != undefined}
<Alert title="Parsing issues" type="error" size="xs">
The result should be an array of objects
</Alert>
{/if}
</RunnableWrapper>
@@ -35,6 +35,7 @@
AppContainer
} from '../../components'
import type { AppComponent } from './components'
import AppAggridTable from '../../components/display/table/AppAggridTable.svelte'
export let component: AppComponent
export let selected: boolean
@@ -143,6 +144,13 @@
bind:componentInput={component.componentInput}
bind:actionButtons={component.actionButtons}
/>
{:else if component.type === 'aggridcomponent'}
<AppAggridTable
{...component}
bind:initializing
bind:staticOutputs={$staticOutputs[component.id]}
bind:componentInput={component.componentInput}
/>
{:else if component.type === 'textcomponent'}
<AppText
{...component}
@@ -63,6 +63,7 @@ export type ScatterChartComponent = BaseComponent<'scatterchartcomponent'>
export type TableComponent = BaseComponent<'tablecomponent'> & {
actionButtons: (BaseAppComponent & ButtonComponent)[]
}
export type AggridComponent = BaseComponent<'aggridcomponent'>
export type DisplayComponent = BaseComponent<'displaycomponent'>
export type ImageComponent = BaseComponent<'imagecomponent'>
export type InputComponent = BaseComponent<'inputcomponent'>
@@ -110,6 +111,7 @@ export type AppComponent = BaseAppComponent &
| VerticalDividerComponent
| FileInputComponent
| ImageComponent
| AggridComponent
)
export type AppComponentDimensions = `${IntRange<
@@ -694,6 +696,48 @@ Hello \${ctx.username}
actionButtons: []
}
},
aggridcomponent: {
name: 'AgGrid Table',
icon: Table2,
dims: '3:10-6:10',
data: {
id: '',
type: 'aggridcomponent',
configuration: {
columnDefs: {
type: 'static',
fieldType: 'array',
subFieldType: 'object',
value: [{ field: 'id' }, { field: 'name', editable: true }, { field: 'age' }]
},
allEditable: {
type: 'static',
fieldType: 'boolean',
value: false,
onlyStatic: true
}
},
componentInput: {
type: 'static',
fieldType: 'array',
subFieldType: 'object',
value: [
{
id: 1,
name: 'A cell with a long name',
age: 42
},
{
id: 2,
name: 'A briefer cell',
age: 84
}
]
},
customCss: {},
card: true,
}
},
checkboxcomponent: {
name: 'Toggle',
icon: ToggleLeft,
@@ -39,6 +39,7 @@ const display: ComponentSet = {
'imagecomponent',
'htmlcomponent',
'tablecomponent',
'aggridcomponent',
'barchartcomponent',
'piechartcomponent',
'vegalitecomponent',