Skip to content

Commit

Permalink
[atable] update table cell value reactively (#224)
Browse files Browse the repository at this point in the history
* fix: update table cell value reactively

* fix: add changelogs

---------

Co-authored-by: Rohan Bansal <[email protected]>
  • Loading branch information
Alchez and Rohan Bansal authored Dec 17, 2024
1 parent 740abc2 commit 8a14784
Show file tree
Hide file tree
Showing 20 changed files with 162 additions and 121 deletions.
7 changes: 5 additions & 2 deletions aform/src/components/form/ADate.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<template>
<div>
<input
v-model="inputDate"
ref="date"
type="date"
:id="uuid"
:disabled="readonly"
:required="required"
:value="inputDate"
@click="showPicker" />
<label :for="uuid">{{ label }}</label>
<p v-show="validation.errorMessage" v-html="validation.errorMessage"></p>
Expand All @@ -26,7 +26,10 @@ const {
validation = { errorMessage: '&nbsp;' },
} = defineProps<ComponentProps>()
const inputDate = defineModel<string | number | Date>()
const inputDate = defineModel<string | number | Date>({
// format the date to be compatible with the native input datepicker
set: value => new Date(value).toISOString().split('T')[0],
})
const dateRef = useTemplateRef<HTMLInputElement>('date')
const showPicker = () => {
Expand Down
13 changes: 10 additions & 3 deletions atable/src/components/ACell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<script setup lang="ts">
import { KeypressHandlers, defaultKeypressHandlers, useKeyboardNav } from '@stonecrop/utilities'
import { useElementBounding } from '@vueuse/core'
import { computed, CSSProperties, ref, useTemplateRef } from 'vue'
import { computed, CSSProperties, ref, useTemplateRef, watch } from 'vue'
import { createTableStore } from '../stores/table'
import { isHtmlString } from '../utils'
Expand All @@ -53,7 +53,7 @@ const { bottom, left } = useElementBounding(cellRef)
// keep a shallow copy of the original cell value for comparison
const originalData = store.getCellData(colIndex, rowIndex)
const displayValue = store.getCellDisplayValue(colIndex, rowIndex)
const displayValue = ref(store.getCellDisplayValue(colIndex, rowIndex))
const currentData = ref('')
const cellModified = ref(false)
Expand All @@ -63,9 +63,16 @@ const row = store.rows[rowIndex]
const textAlign = column.align || 'center'
const cellWidth = column.width || '40ch'
watch(
() => store.getCellData(colIndex, rowIndex),
cellData => {
displayValue.value = store.getFormattedValue(colIndex, rowIndex, cellData)
}
)
const isHtmlValue = computed(() => {
// TODO: check if display value is a native DOM element
return typeof displayValue === 'string' ? isHtmlString(displayValue) : false
return typeof displayValue.value === 'string' ? isHtmlString(displayValue.value) : false
})
const cellStyle = computed((): CSSProperties => {
Expand Down
18 changes: 16 additions & 2 deletions atable/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,24 @@ export type TableColumn = {

cellComponent?: string
cellComponentProps?: Record<string, any>
modalComponent?: string | ((context?: CellContext) => string)
/**
* The component to use for the modal. If a function is provided, it will be called with the cell context.
* The following properties are available on the cell context:
* - `row` - the row object
* - `column` - the column object
* - `table` - the table object
*
* The function should return the name of the component to use for the modal.
*
* Additionally, the following properties will be automatically passed to the modal component:
* - `colIndex` - the column index of the current cell
* - `rowIndex` - the row index of the current cell
* - `store` - the table data store
*/
modalComponent?: string | ((context: CellContext) => string)
modalComponentExtraProps?: Record<string, any>

format?: string | ((value: any, context?: CellContext) => string)
format?: string | ((value: any, context: CellContext) => string)
mask?: (value: any) => any
}

Expand Down
15 changes: 6 additions & 9 deletions atable/tests/cell.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ import { mount } from '@vue/test-utils'

import ATable from '../src/components/ATable.vue'
import data from './data/http_logs.json'
import type { TableColumn, TableConfig } from '../src/types'

describe('table cell component', () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
type: 'Data',
align: 'left',
edit: false,
width: '35ch',
format: (value: { title?: string; value?: any }) => {
return value.title
},
format: (value: { title: string }) => value.title,
},
{
label: 'HTTP Method',
Expand All @@ -33,17 +32,15 @@ describe('table cell component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: number) => new Date(value).toLocaleDateString('en-US'),
},
]

const props = {
columns,
modelValue: data,
config: { view: 'list' },
config: { view: 'list' } as TableConfig,
}

beforeEach(() => {
Expand Down
15 changes: 6 additions & 9 deletions atable/tests/modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ import { mount } from '@vue/test-utils'

import ATable from '../src/components/ATable.vue'
import data from './data/http_logs.json'
import type { TableColumn, TableConfig } from '../src/types'

describe('table modal component', () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
type: 'Data',
align: 'left',
edit: false,
width: '35ch',
format: (value: { title?: string; value?: any }) => {
return value.title
},
format: (value: { title: string }) => value.title,
},
{
label: 'HTTP Method',
Expand All @@ -33,17 +32,15 @@ describe('table modal component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: string | number) => new Date(value).toLocaleDateString('en-US'),
},
]

const props = {
columns,
modelValue: data,
config: { view: 'list' },
config: { view: 'list' } as TableConfig,
}

beforeEach(() => {
Expand Down
13 changes: 5 additions & 8 deletions atable/tests/row.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ import { mount } from '@vue/test-utils'

import ATable from '../src/components/ATable.vue'
import listData from './data/http_logs.json'
import type { TableColumn } from '../src/types'

describe('table row component', () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
type: 'Data',
align: 'left',
edit: false,
width: '35ch',
format: (value: { title?: string; value?: any }) => {
return value.title
},
format: (value: { title: string }) => value.title,
},
{
label: 'HTTP Method',
Expand All @@ -33,10 +32,8 @@ describe('table row component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: string | number) => new Date(value).toLocaleDateString('en-US'),
},
]

Expand Down
31 changes: 12 additions & 19 deletions atable/tests/table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ import { mount } from '@vue/test-utils'

import ATable from '../src/components/ATable.vue'
import data from './data/http_logs.json'
import type { TableColumn, TableConfig } from '../src/types'

describe('table component', () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
type: 'Data',
align: 'left',
edit: false,
width: '35ch',
format: (value: { title?: string; value?: any }) => {
return value.title
},
format: (value: { title: string }) => value.title,
},
{
label: 'HTTP Method',
Expand All @@ -33,17 +32,15 @@ describe('table component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: string | number) => new Date(value).toLocaleDateString('en-US'),
},
]

const defaultProps = {
columns,
modelValue: data,
config: { view: 'list' },
config: { view: 'list' } as TableConfig,
}

beforeEach(() => {
Expand Down Expand Up @@ -90,7 +87,7 @@ describe('table component', () => {
})

it('verify data rows (format string)', async () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
Expand All @@ -115,10 +112,8 @@ describe('table component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: string | number) => new Date(value).toLocaleDateString('en-US'),
},
]

Expand All @@ -144,7 +139,7 @@ describe('table component', () => {
})

it('verify data rows (no format)', async () => {
const columns = [
const columns: TableColumn[] = [
{
label: 'Home Page',
name: 'home_page',
Expand All @@ -168,10 +163,8 @@ describe('table component', () => {
align: 'center',
edit: true,
width: '25ch',
modalComponent: 'ADate',
format: (value: number) => {
return new Date(Number(value)).toLocaleDateString('en-US')
},
modalComponent: 'DateInput',
format: (value: string | number) => new Date(value).toLocaleDateString('en-US'),
},
]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@stonecrop/aform",
"comment": "format adate emit response to fit native datepicker",
"type": "patch"
}
],
"packageName": "@stonecrop/aform"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@stonecrop/atable",
"comment": "update table cell value reactively",
"type": "patch"
}
],
"packageName": "@stonecrop/atable"
}
4 changes: 2 additions & 2 deletions common/reviews/api/aform.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ export type TableColumn = {
pinned?: boolean;
cellComponent?: string;
cellComponentProps?: Record<string, any>;
modalComponent?: string | ((context?: CellContext) => string);
modalComponent?: string | ((context: CellContext) => string);
modalComponentExtraProps?: Record<string, any>;
format?: string | ((value: any, context?: CellContext) => string);
format?: string | ((value: any, context: CellContext) => string);
mask?: (value: any) => any;
};

Expand Down
Loading

0 comments on commit 8a14784

Please sign in to comment.