Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up server side row model for table visualization #12272

Open
wants to merge 46 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
ab02b00
set up ssrm for table
marthasharkey Feb 13, 2025
2ccb883
update tests
marthasharkey Feb 13, 2025
ca95f05
format
marthasharkey Feb 14, 2025
3771f09
wip to pass sort
marthasharkey Feb 14, 2025
5f4ef89
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 14, 2025
18a282c
WIP sort
marthasharkey Feb 14, 2025
102664d
lint issues
marthasharkey Feb 14, 2025
faa4b74
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 17, 2025
cb55ff5
sort working
marthasharkey Feb 17, 2025
70d7b29
remove logs
marthasharkey Feb 17, 2025
11c6586
add multisort
marthasharkey Feb 18, 2025
b711695
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 18, 2025
b5a9353
add distinct options
marthasharkey Feb 19, 2025
dc5734b
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 19, 2025
ec29c6a
single filter working
marthasharkey Feb 20, 2025
09b4f60
filtering working for single numeric column
marthasharkey Feb 20, 2025
e634537
send value as string
marthasharkey Feb 21, 2025
d774643
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 21, 2025
ea2bb55
filtering wip
marthasharkey Feb 24, 2025
074b04b
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 24, 2025
f1b33a9
date filtering working
marthasharkey Feb 24, 2025
514fa00
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 26, 2025
d3b9abe
update for text filter
marthasharkey Feb 26, 2025
ce14bb8
send integer and char type
marthasharkey Feb 26, 2025
437d9fd
individual filtering working
marthasharkey Feb 26, 2025
39f1a55
multi filter working
marthasharkey Feb 26, 2025
9cb2992
fix types
marthasharkey Feb 27, 2025
d6604d0
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 27, 2025
a443b0b
send in format function
marthasharkey Feb 28, 2025
c7f2e8b
add types to format functions
marthasharkey Feb 28, 2025
036ac77
move functions around
marthasharkey Feb 28, 2025
b24a8ff
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Feb 28, 2025
843b8a6
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Mar 3, 2025
e63ab0a
basic index row
marthasharkey Mar 3, 2025
39fc8ea
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Mar 4, 2025
2edf87d
use temp name for index column
marthasharkey Mar 4, 2025
0aa1690
for db use non ssrm
marthasharkey Mar 4, 2025
5648519
fix for non ssrm
marthasharkey Mar 4, 2025
803ea18
add correct row count for non ssrm
marthasharkey Mar 4, 2025
2894b28
re add filter/sort check
marthasharkey Mar 4, 2025
eb0ea19
update test files
marthasharkey Mar 4, 2025
6294b78
Merge branch 'develop' into wip/mk/ssrm
marthasharkey Mar 5, 2025
16bff25
use ssrm for all tables no matter what size
marthasharkey Mar 6, 2025
b9334b2
update metod comments
marthasharkey Mar 6, 2025
20ebd52
rename
marthasharkey Mar 6, 2025
b18546e
remove unused props
marthasharkey Mar 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const {
setToolbarDefinition,
visualizationDefinedToolbar,
toolbarOverlay,
executeExpression,
} = useVisualizationData({
selectedVis: toRef(props, 'currentType'),
dataSource: toRef(props, 'dataSource'),
Expand Down Expand Up @@ -190,6 +191,7 @@ const visParams = computed(() => {
data: effectiveVisualizationData.value,
size: contentElementSize.value,
nodeType: props.typename,
executeExpression,
}
})
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import LoadingErrorVisualization from '@/components/visualizations/LoadingErrorVisualization.vue'
import LoadingVisualization from '@/components/visualizations/LoadingVisualization.vue'
import type { ToolbarItem } from '@/components/visualizations/toolbar'
import { useGraphStore } from '@/stores/graph'
import { NodeId } from '@/stores/graph/graphDatabase'
import { useProjectStore } from '@/stores/project'
import type { NodeVisualizationConfiguration } from '@/stores/project/executionContext'
import {
Expand Down Expand Up @@ -56,6 +58,7 @@ export function useVisualizationData({

const projectStore = useProjectStore()
const visualizationStore = useVisualizationStore()
const graph = useGraphStore()

// Flag used to prevent rendering the visualization with a stale preprocessor while the new preprocessor is being
// prepared asynchronously.
Expand Down Expand Up @@ -92,6 +95,50 @@ export function useVisualizationData({
},
)

const executeExpression = async (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this function is part of the API for visualizations, its signature should be as simple as possible, and shouldn't contain any any types. I think it could be generalized to: executeExpression(expression: (nodeOutputIdentifier: string) => string): Promise<Result<unknown> | null>. The logic for constructing the expression (L116-L140) can be left to the caller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I did think it had started to get too specific for this usecase, thank you

visulizationModule: string,
expressionString: string,
formatFunction:
| ((arg: any, tempModule: Ast.MutableModule) => Ast.Owned<Ast.MutableExpression>)
| null,
...positionalArgumentsExpressions: any[]
) => {
const dataSourceValue = toValue(dataSource)
if (dataSourceValue?.type !== 'node') return
const graphDb = graph.db
const nodeFirstOurputPort = graphDb.getNodeFirstOutputPort(dataSourceValue.nodeId as NodeId)
const identifier = graphDb.getOutputPortIdentifier(nodeFirstOurputPort)
if (identifier === undefined) return
const contextId =
dataSourceValue.nodeId &&
graphDb.nodeIdToNode.get(dataSourceValue.nodeId as NodeId)?.outerAst.externalId
if (contextId === undefined) return
try {
const tempModule = Ast.MutableModule.Transient()
const preprocessorModule = Ast.parseExpression(visulizationModule, tempModule)!
const preprocessorQn = Ast.PropertyAccess.new(
tempModule,
preprocessorModule,
Ast.identifier(expressionString)!,
)

const preprocessorInvocation = Ast.App.PositionalSequence(preprocessorQn, [
Ast.Wildcard.new(tempModule),
...positionalArgumentsExpressions.map((arg) => {
const parsedArg =
formatFunction ? formatFunction(arg, tempModule) : Ast.parseExpression(arg, tempModule)!
return Ast.Group.new(tempModule, parsedArg)
}),
])
const rhs = Ast.parseExpression(identifier, tempModule)!
const expression = Ast.OprApp.new(tempModule, preprocessorInvocation, '<|', rhs)
return projectStore.executeExpression(contextId, expression.code())
} catch (e) {
console.error(e)
throw e
}
}

const currentType = computed(() => {
const selectedTypeValue = toValue(selectedVis)
if (selectedTypeValue) return selectedTypeValue
Expand Down Expand Up @@ -260,5 +307,19 @@ export function useVisualizationData({
(toolbarDefinition.value = definition),
visualizationDefinedToolbar: computed(() => toValue(toolbarDefinition.value)),
toolbarOverlay,
executeExpression: (
visulizationModule: string,
expressionString: string,
formatFunction:
| ((arg: any, tempModule: Ast.MutableModule) => Ast.Owned<Ast.MutableExpression>)
| null,
...positionalArgumentsExpressions: string[]
) =>
executeExpression(
visulizationModule,
expressionString,
formatFunction,
...positionalArgumentsExpressions,
),
Comment on lines +310 to +323
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary lambda.

}
}
34 changes: 9 additions & 25 deletions app/gui/src/project-view/components/shared/AgGridTableView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,14 @@ import type {
ICellEditorComp,
IHeaderComp,
IHeaderParams,
IServerSideDatasource,
MenuItemDef,
ProcessDataFromClipboardParams,
RowDataUpdatedEvent,
RowEditingStartedEvent,
RowEditingStoppedEvent,
RowHeightParams,
SortChangedEvent,
} from 'ag-grid-enterprise'
import * as iter from 'enso-common/src/utilities/data/iter'
import { LINE_BOUNDARIES } from 'enso-common/src/utilities/data/string'
import {
Component,
type ComponentInstance,
Expand All @@ -110,8 +108,6 @@ import {
tableToEnsoExpression,
} from '../GraphEditor/widgets/WidgetTableEditor/tableParsing'

const DEFAULT_ROW_HEIGHT = 22

const props = defineProps<{
rowData: TData[]
columnDefs: (ColDef<TData, TValue> | ColGroupDef<TData>)[] | null
Expand All @@ -124,6 +120,9 @@ const props = defineProps<{
suppressMoveWhenColumnDragging?: boolean
textFormatOption?: TextFormatOptions
processDataFromClipboard?: (params: ProcessDataFromClipboardParams<TData>) => string[][] | null
datasource?: IServerSideDatasource
rowCount?: number
isServerSideModel?: boolean
}>()
const emit = defineEmits<{
cellEditingStarted: [event: CellEditingStartedEvent]
Expand All @@ -145,24 +144,7 @@ function onGridReady(event: GridReadyEvent<TData>) {
gridApi.value = event.api
}

function getRowHeight(params: RowHeightParams): number {
if (props.textFormatOption === 'off') {
return DEFAULT_ROW_HEIGHT
}
const rowData = Object.values(params.data)
const textValues = rowData.filter((r): r is string => typeof r === 'string')

if (!textValues.length) {
return DEFAULT_ROW_HEIGHT
}

const returnCharsCount = iter.map(textValues, (text) =>
iter.count(text.matchAll(LINE_BOUNDARIES)),
)

const maxReturnCharsCount = iter.reduce(returnCharsCount, Math.max, 0)
return (maxReturnCharsCount + 1) * DEFAULT_ROW_HEIGHT
}
const rowModelType = computed(() => (props.isServerSideModel ? 'serverSide' : 'clientSide'))

watch(
() => props.textFormatOption,
Expand Down Expand Up @@ -360,8 +342,10 @@ const { AgGridVue } = await import('./AgGridTableView/AgGridVue')
ref="grid"
class="ag-theme-alpine inner"
:headerHeight="26"
:getRowHeight="getRowHeight"
:rowData="rowData"
:rowModelType="rowModelType"
:serverSideDatasource="datasource"
:rowCount="rowCount"
:rowData="rowModelType === 'clientSide' ? rowData : null"
:columnDefs="columnDefs"
:defaultColDef="defaultColDef"
:copyHeadersToClipboard="true"
Expand Down
Loading
Loading