Separate input type for Rating,Scale,Slider (#351)

* Separate input type for Rating,Scale,Slider

* rating, scale, slider add in test cases

* Allow field type change for new types

* Added options to db factory

* Fix linting

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
formsdev
2024-03-19 19:57:21 +05:30
committed by GitHub
parent c73fcd226b
commit c8628ed840
20 changed files with 1104 additions and 612 deletions

View File

@@ -1,78 +1,61 @@
<template>
<table :id="'table-'+tableHash" ref="table"
class="notion-table n-table whitespace-no-wrap bg-white dark:bg-notion-dark-light relative"
>
<thead :id="'table-header-'+tableHash" ref="header"
class="n-table-head top-0"
:class="{'absolute': data.length !== 0}"
style="will-change: transform; transform: translate3d(0px, 0px, 0px)"
>
<tr class="n-table-row overflow-x-hidden">
<resizable-th v-for="col, index in columns" :id="'table-head-cell-' + col.id" :key="col.id"
scope="col" :allow-resize="allowResize" :width="(col.cell_width ? col.cell_width + 'px':'auto')"
class="n-table-cell p-0 relative"
@resize-width="resizeCol(col, $event)"
>
<p class="bg-gray-50 border-r dark:bg-notion-dark truncate sticky top-0 border-b border-gray-200 dark:border-gray-800 px-4 py-2 text-gray-500 font-semibold tracking-wider uppercase text-xs"
>
{{ col.name }}
</p>
</resizable-th>
<th class="n-table-cell p-0 relative" style="width: 100px">
<p
class="bg-gray-50 dark:bg-notion-dark truncate sticky top-0 border-b border-gray-200 dark:border-gray-800 px-4 py-2 text-gray-500 font-semibold tracking-wider uppercase text-xs"
>
Actions
</p>
</th>
</tr>
<table :id="'table-' + tableHash" ref="table"
class="notion-table n-table whitespace-no-wrap bg-white dark:bg-notion-dark-light relative">
<thead :id="'table-header-' + tableHash" ref="header" class="n-table-head top-0"
:class="{ 'absolute': data.length !== 0 }" style="will-change: transform; transform: translate3d(0px, 0px, 0px)">
<tr class="n-table-row overflow-x-hidden">
<resizable-th v-for="col, index in columns" :id="'table-head-cell-' + col.id" :key="col.id" scope="col"
:allow-resize="allowResize" :width="(col.cell_width ? col.cell_width + 'px' : 'auto')"
class="n-table-cell p-0 relative" @resize-width="resizeCol(col, $event)">
<p
class="bg-gray-50 border-r dark:bg-notion-dark truncate sticky top-0 border-b border-gray-200 dark:border-gray-800 px-4 py-2 text-gray-500 font-semibold tracking-wider uppercase text-xs">
{{ col.name }}
</p>
</resizable-th>
<th class="n-table-cell p-0 relative" style="width: 100px">
<p
class="bg-gray-50 dark:bg-notion-dark truncate sticky top-0 border-b border-gray-200 dark:border-gray-800 px-4 py-2 text-gray-500 font-semibold tracking-wider uppercase text-xs">
Actions
</p>
</th>
</tr>
</thead>
<tbody v-if="data.length > 0" class="n-table-body bg-white dark:bg-notion-dark-light">
<tr v-if="$slots.hasOwnProperty('actions')"
:id="'table-actions-'+tableHash"
ref="actions-row"
class="action-row absolute w-full"
style="will-change: transform; transform: translate3d(0px, 32px, 0px)"
>
<td :colspan="columns.length" class="p-1">
<slot name="actions"/>
</td>
</tr>
<tr v-for="row, index in data" :key="row.id" class="n-table-row" :class="{'first':index===0}">
<td v-for="col, colIndex in columns"
:key="col.id"
:style="{width: col.cell_width + 'px'}"
class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 overflow-hidden"
:class="[{'border-b': index !== data.length - 1, 'border-r': colIndex !== columns.length - 1 || hasActions},
colClasses(col)]"
>
<component :is="fieldComponents[col.type]" class="border-gray-100 dark:border-gray-900"
:property="col" :value="row[col.id]"
/>
</td>
<td v-if="hasActions" class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 border-b"
style="width: 100px"
>
<record-operations :form="form" :structure="columns" :submission="row"
@deleted="(submission)=>$emit('deleted',submission)"
@updated="(submission)=>$emit('updated', submission)"/>
</td>
</tr>
<tr v-if="loading" class="n-table-row border-t bg-gray-50 dark:bg-gray-900">
<td :colspan="columns.length" class="p-8 w-full">
<Loader class="w-4 h-4 mx-auto"/>
</td>
</tr>
<tr v-if="$slots.hasOwnProperty('actions')" :id="'table-actions-' + tableHash" ref="actions-row"
class="action-row absolute w-full" style="will-change: transform; transform: translate3d(0px, 32px, 0px)">
<td :colspan="columns.length" class="p-1">
<slot name="actions" />
</td>
</tr>
<tr v-for="row, index in data" :key="row.id" class="n-table-row" :class="{ 'first': index === 0 }">
<td v-for="col, colIndex in columns" :key="col.id" :style="{ width: col.cell_width + 'px' }"
class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 overflow-hidden" :class="[{ 'border-b': index !== data.length - 1, 'border-r': colIndex !== columns.length - 1 || hasActions },
colClasses(col)]">
<component :is="fieldComponents[col.type]" class="border-gray-100 dark:border-gray-900" :property="col"
:value="row[col.id]" />
</td>
<td v-if="hasActions" class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 border-b"
style="width: 100px">
<record-operations :form="form" :structure="columns" :submission="row"
@deleted="(submission) => $emit('deleted', submission)"
@updated="(submission) => $emit('updated', submission)" />
</td>
</tr>
<tr v-if="loading" class="n-table-row border-t bg-gray-50 dark:bg-gray-900">
<td :colspan="columns.length" class="p-8 w-full">
<Loader class="w-4 h-4 mx-auto" />
</td>
</tr>
</tbody>
<tbody v-else key="body-content" class="n-table-body">
<tr class="n-table-row loader w-full">
<td :colspan="columns.length" class="n-table-cell w-full p-8">
<Loader v-if="loading" class="w-4 h-4 mx-auto"/>
<p v-else class="text-gray-500 text-center">
No data found.
</p>
</td>
</tr>
<tr class="n-table-row loader w-full">
<td :colspan="columns.length" class="n-table-cell w-full p-8">
<Loader v-if="loading" class="w-4 h-4 mx-auto" />
<p v-else class="text-gray-500 text-center">
No data found.
</p>
</td>
</tr>
</tbody>
</table>
</template>
@@ -87,11 +70,11 @@ import OpenCheckbox from './components/OpenCheckbox.vue'
import ResizableTh from './components/ResizableTh.vue'
import RecordOperations from '../components/RecordOperations.vue'
import clonedeep from 'clone-deep'
import {hash} from "~/lib/utils.js";
import { hash } from "~/lib/utils.js";
export default {
components: {ResizableTh, RecordOperations},
emits: ["updated", "deleted", "resize", "update-columns"],
components: { ResizableTh, RecordOperations },
emits: ["updated", "deleted", "resize", "update-columns"],
props: {
columns: {
type: Array,
@@ -131,6 +114,9 @@ export default {
fieldComponents: {
text: shallowRef(OpenText),
number: shallowRef(OpenText),
rating: shallowRef(OpenText),
scale: shallowRef(OpenText),
slider: shallowRef(OpenText),
select: shallowRef(OpenSelect),
multi_select: shallowRef(OpenSelect),
date: shallowRef(OpenDate),
@@ -164,7 +150,7 @@ export default {
const parent = this.scrollParent ?? document.getElementById('table-page')
this.tableHash = hash(JSON.stringify(this.form.properties))
if (parent) {
parent.addEventListener('scroll', this.handleScroll, {passive: false})
parent.addEventListener('scroll', this.handleScroll, { passive: false })
}
window.addEventListener('resize', this.handleScroll)
this.onStructureChange()
@@ -290,7 +276,8 @@ export default {
.n-table-row {
display: flex;
&.first, &.loader {
&.first,
&.loader {
margin-top: 33px;
}
}