85 lines
2.1 KiB
Vue
85 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { AgGridVue } from 'ag-grid-vue3'
|
|
import {
|
|
ClientSideRowModelModule,
|
|
ColumnAutoSizeModule,
|
|
CellStyleModule,
|
|
ValidationModule,
|
|
TextFilterModule,
|
|
themeQuartz,
|
|
ModuleRegistry,
|
|
RowSelectionModule,
|
|
type ColDef,
|
|
type RowClickedEvent
|
|
} from 'ag-grid-community'
|
|
import type { UiGridColumn } from '../contracts'
|
|
|
|
ModuleRegistry.registerModules([
|
|
ClientSideRowModelModule,
|
|
ColumnAutoSizeModule,
|
|
CellStyleModule,
|
|
ValidationModule,
|
|
TextFilterModule,
|
|
RowSelectionModule
|
|
])
|
|
|
|
const props = withDefaults(defineProps<{
|
|
rows: unknown[]
|
|
columns: UiGridColumn[]
|
|
loading?: boolean
|
|
height?: string
|
|
rowSelection?: 'single' | 'multiple' | 'none'
|
|
}>(), { loading: false, height: '32rem', rowSelection: 'single' })
|
|
|
|
const emit = defineEmits<{ rowSelected: [row: unknown] }>()
|
|
|
|
const columnDefs = computed<ColDef[]>(() => props.columns.map(column => ({
|
|
field: column.field,
|
|
headerName: column.header,
|
|
width: column.width,
|
|
minWidth: column.minWidth ?? 120,
|
|
sortable: column.sortable ?? true,
|
|
filter: column.filterable ?? true,
|
|
valueFormatter: column.formatter
|
|
? params => column.formatter?.(params.value, params.data) ?? ''
|
|
: undefined
|
|
})))
|
|
|
|
const rowSelectionOptions = computed(() => {
|
|
if (props.rowSelection === 'none') return undefined
|
|
return props.rowSelection === 'multiple'
|
|
? ({ mode: 'multiRow' } as const)
|
|
: ({ mode: 'singleRow' } as const)
|
|
})
|
|
|
|
function onRowClicked(event: RowClickedEvent): void {
|
|
if (event.data) emit('rowSelected', event.data)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="ks-grid" :style="{ height }" :aria-busy="loading">
|
|
<AgGridVue
|
|
style="height: 100%; width: 100%"
|
|
:theme="themeQuartz"
|
|
:row-data="rows"
|
|
:column-defs="columnDefs"
|
|
:row-selection="rowSelectionOptions"
|
|
:loading="loading"
|
|
:suppress-no-rows-overlay="rows.length > 0"
|
|
@row-clicked="onRowClicked"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.ks-grid {
|
|
min-height: 12rem;
|
|
border: 1px solid var(--ks-color-neutral-200);
|
|
border-radius: var(--ks-radius-md);
|
|
overflow: hidden;
|
|
background: #fff;
|
|
}
|
|
</style>
|