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

[atable] update table cell value reactively #224

Merged
merged 2 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading