Fix OpenTable performances
This commit is contained in:
parent
6aec718ef6
commit
28e55574e6
|
@ -1,13 +1,13 @@
|
||||||
NUXT_LOG_LEVEL=
|
NUXT_LOG_LEVEL=
|
||||||
NUXT_PUBLIC_APP_URL=http://localhost/
|
NUXT_PUBLIC_APP_URL=http://localhost/
|
||||||
NUXT_PUBLIC_API_BASE=http://localhost/api
|
NUXT_PUBLIC_API_BASE=http://localhost/api
|
||||||
NUXT_PUBLIC_AI_ENABLED=
|
NUXT_PUBLIC_AI_ENABLED=false
|
||||||
NUXT_PUBLIC_AMPLITUDE_CODE=
|
NUXT_PUBLIC_AMPLITUDE_CODE=
|
||||||
NUXT_PUBLIC_CRISP_WEBSITE_ID=
|
NUXT_PUBLIC_CRISP_WEBSITE_ID=
|
||||||
NUXT_PUBLIC_CUSTOM_DOMAINS_ENABLED=
|
NUXT_PUBLIC_CUSTOM_DOMAINS_ENABLED=false
|
||||||
NUXT_PUBLIC_ENV=local
|
NUXT_PUBLIC_ENV=local
|
||||||
NUXT_PUBLIC_GOOGLE_ANALYTICS_CODE=
|
NUXT_PUBLIC_GOOGLE_ANALYTICS_CODE=
|
||||||
NUXT_PUBLIC_H_CAPTCHA_SITE_KEY=
|
NUXT_PUBLIC_H_CAPTCHA_SITE_KEY=
|
||||||
NUXT_PUBLIC_PAID_PLANS_ENABLED=
|
NUXT_PUBLIC_PAID_PLANS_ENABLED=false
|
||||||
NUXT_PUBLIC_S3_ENABLED=
|
NUXT_PUBLIC_S3_ENABLED=false
|
||||||
NUXT_API_SECRET=
|
NUXT_API_SECRET=
|
||||||
|
|
|
@ -7,72 +7,70 @@
|
||||||
:class="{'absolute': data.length !== 0}"
|
:class="{'absolute': data.length !== 0}"
|
||||||
style="will-change: transform; transform: translate3d(0px, 0px, 0px)"
|
style="will-change: transform; transform: translate3d(0px, 0px, 0px)"
|
||||||
>
|
>
|
||||||
<tr class="n-table-row overflow-x-hidden">
|
<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"
|
<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')"
|
scope="col" :allow-resize="allowResize" :width="(col.cell_width ? col.cell_width + 'px':'auto')"
|
||||||
class="n-table-cell p-0 relative"
|
class="n-table-cell p-0 relative"
|
||||||
@resize-width="resizeCol(col, $event)"
|
@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"
|
||||||
>
|
>
|
||||||
<p
|
{{ col.name }}
|
||||||
:class="{'border-r': index < columns.length - 1 || hasActions}"
|
</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"
|
</resizable-th>
|
||||||
>
|
<th class="n-table-cell p-0 relative" style="width: 100px">
|
||||||
{{ col.name }}
|
<p
|
||||||
</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"
|
||||||
</resizable-th>
|
>
|
||||||
<th v-if="hasActions" class="n-table-cell p-0 relative" style="width: 100px">
|
Actions
|
||||||
<p
|
</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"
|
</th>
|
||||||
>
|
</tr>
|
||||||
Actions
|
|
||||||
</p>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody v-if="data.length > 0" class="n-table-body bg-white dark:bg-notion-dark-light">
|
<tbody v-if="data.length > 0" class="n-table-body bg-white dark:bg-notion-dark-light">
|
||||||
<tr v-if="$slots.hasOwnProperty('actions')"
|
<tr v-if="$slots.hasOwnProperty('actions')"
|
||||||
:id="'table-actions-'+tableHash"
|
:id="'table-actions-'+tableHash"
|
||||||
ref="actions-row"
|
ref="actions-row"
|
||||||
class="action-row absolute w-full"
|
class="action-row absolute w-full"
|
||||||
style="will-change: transform; transform: translate3d(0px, 32px, 0px)"
|
style="will-change: transform; transform: translate3d(0px, 32px, 0px)"
|
||||||
>
|
>
|
||||||
<td :colspan="columns.length" class="p-1">
|
<td :colspan="columns.length" class="p-1">
|
||||||
<slot name="actions" />
|
<slot name="actions"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="row, index in data" :key="index" class="n-table-row" :class="{'first':index===0}">
|
<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"
|
<td v-for="col, colIndex in columns"
|
||||||
:key="col.id"
|
:key="col.id"
|
||||||
:style="{width: col.cell_width + 'px'}"
|
:style="{width: col.cell_width + 'px'}"
|
||||||
class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 overflow-hidden"
|
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},
|
:class="[{'border-b': index !== data.length - 1, 'border-r': colIndex !== columns.length - 1 || hasActions},
|
||||||
colClasses(col)]"
|
colClasses(col)]"
|
||||||
>
|
>
|
||||||
<component :is="fieldComponents[col.type]" class="border-gray-100 dark:border-gray-900"
|
<component :is="fieldComponents[col.type]" class="border-gray-100 dark:border-gray-900"
|
||||||
:property="col" :value="row[col.id]"
|
:property="col" :value="row[col.id]"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td v-if="hasActions" class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 border-b"
|
<td v-if="hasActions" class="n-table-cell border-gray-100 dark:border-gray-900 text-sm p-2 border-b"
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
>
|
>
|
||||||
<record-operations :form="form" :structure="columns" :rowid="row.id" @deleted="$emit('deleted')" />
|
<record-operations :form="form" :structure="columns" :rowid="row.id" @deleted="$emit('deleted')"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="loading" class="n-table-row border-t bg-gray-50 dark:bg-gray-900">
|
<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">
|
<td :colspan="columns.length" class="p-8 w-full">
|
||||||
<Loader class="w-4 h-4 mx-auto" />
|
<Loader class="w-4 h-4 mx-auto"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tbody v-else key="body-content" class="n-table-body">
|
<tbody v-else key="body-content" class="n-table-body">
|
||||||
<tr class="n-table-row loader w-full">
|
<tr class="n-table-row loader w-full">
|
||||||
<td :colspan="columns.length" class="n-table-cell w-full p-8">
|
<td :colspan="columns.length" class="n-table-cell w-full p-8">
|
||||||
<Loader v-if="loading" class="w-4 h-4 mx-auto" />
|
<Loader v-if="loading" class="w-4 h-4 mx-auto"/>
|
||||||
<p v-else class="text-gray-500 text-center">
|
<p v-else class="text-gray-500 text-center">
|
||||||
No data found.
|
No data found.
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
@ -90,7 +88,7 @@ import clonedeep from 'clone-deep'
|
||||||
import {hash} from "~/lib/utils.js";
|
import {hash} from "~/lib/utils.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ResizableTh, RecordOperations },
|
components: {ResizableTh, RecordOperations},
|
||||||
props: {
|
props: {
|
||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -111,77 +109,64 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup () {
|
setup() {
|
||||||
const workingFormStore = useWorkingFormStore()
|
const workingFormStore = useWorkingFormStore()
|
||||||
return {
|
return {
|
||||||
workingFormStore
|
workingFormStore,
|
||||||
|
form: storeToRefs(workingFormStore).content,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableHash: null,
|
tableHash: null,
|
||||||
skip: false
|
skip: false,
|
||||||
}
|
hasActions: true,
|
||||||
},
|
internalColumns: [],
|
||||||
|
fieldComponents: {
|
||||||
computed: {
|
text: shallowRef(OpenText),
|
||||||
form: {
|
number: shallowRef(OpenText),
|
||||||
get () {
|
select: shallowRef(OpenSelect),
|
||||||
return this.workingFormStore.content
|
multi_select: shallowRef(OpenSelect),
|
||||||
},
|
date: shallowRef(OpenDate),
|
||||||
/* We add a setter */
|
files: shallowRef(OpenFile),
|
||||||
set (value) {
|
checkbox: shallowRef(OpenCheckbox),
|
||||||
this.workingFormStore.set(value)
|
url: shallowRef(OpenUrl),
|
||||||
}
|
email: shallowRef(OpenText),
|
||||||
},
|
phone_number: shallowRef(OpenText),
|
||||||
hasActions () {
|
signature: shallowRef(OpenFile)
|
||||||
// In future if want to hide based on condition
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
fieldComponents () {
|
|
||||||
return {
|
|
||||||
text: OpenText,
|
|
||||||
number: OpenText,
|
|
||||||
select: OpenSelect,
|
|
||||||
multi_select: OpenSelect,
|
|
||||||
date: OpenDate,
|
|
||||||
files: OpenFile,
|
|
||||||
checkbox: OpenCheckbox,
|
|
||||||
url: OpenUrl,
|
|
||||||
email: OpenText,
|
|
||||||
phone_number: OpenText,
|
|
||||||
signature: OpenFile
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
'columns': {
|
'columns': {
|
||||||
handler () {
|
handler() {
|
||||||
|
this.internalColumns = clonedeep(this.columns)
|
||||||
this.onStructureChange()
|
this.onStructureChange()
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
data () {
|
data() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.handleScroll()
|
this.handleScroll()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted() {
|
||||||
|
this.internalColumns = clonedeep(this.columns)
|
||||||
const parent = document.getElementById('table-page')
|
const parent = document.getElementById('table-page')
|
||||||
this.tableHash = hash(JSON.stringify(this.form.properties))
|
this.tableHash = hash(JSON.stringify(this.form.properties))
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.addEventListener('scroll', this.handleScroll, { passive: true })
|
parent.addEventListener('scroll', this.handleScroll, {passive: true})
|
||||||
}
|
}
|
||||||
window.addEventListener('resize', this.handleScroll)
|
window.addEventListener('resize', this.handleScroll)
|
||||||
this.onStructureChange()
|
this.onStructureChange()
|
||||||
this.handleScroll()
|
this.handleScroll()
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUnmount () {
|
beforeUnmount() {
|
||||||
const parent = document.getElementById('table-page')
|
const parent = document.getElementById('table-page')
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.removeEventListener('scroll', this.handleScroll)
|
parent.removeEventListener('scroll', this.handleScroll)
|
||||||
|
@ -190,7 +175,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
colClasses (col) {
|
colClasses(col) {
|
||||||
let colAlign, colColor, colFontWeight, colWrap
|
let colAlign, colColor, colFontWeight, colWrap
|
||||||
|
|
||||||
// Column align
|
// Column align
|
||||||
|
@ -215,12 +200,12 @@ export default {
|
||||||
|
|
||||||
return [colAlign, colColor, colWrap, colFontWeight]
|
return [colAlign, colColor, colWrap, colFontWeight]
|
||||||
},
|
},
|
||||||
onStructureChange () {
|
onStructureChange() {
|
||||||
if (this.columns) {
|
if (this.internalColumns) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.columns.forEach(col => {
|
this.internalColumns.forEach(col => {
|
||||||
if (!col.hasOwnProperty('cell_width')) {
|
if (!col.hasOwnProperty('cell_width')) {
|
||||||
if (this.allowResize && this.columns.length && document.getElementById('table-head-cell-' + col.id)) {
|
if (this.allowResize && this.internalColumns.length && document.getElementById('table-head-cell-' + col.id)) {
|
||||||
// Within editor
|
// Within editor
|
||||||
this.resizeCol(col, document.getElementById('table-head-cell-' + col.id).offsetWidth)
|
this.resizeCol(col, document.getElementById('table-head-cell-' + col.id).offsetWidth)
|
||||||
}
|
}
|
||||||
|
@ -229,17 +214,16 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resizeCol (col, width) {
|
resizeCol(col, width) {
|
||||||
if (!this.form) return
|
if (!this.form) return
|
||||||
const columns = clonedeep(this.columns)
|
const index = this.internalColumns.findIndex(c => c.id === col.id)
|
||||||
const index = this.columns.findIndex(c => c.id === col.id)
|
this.internalColumns[index].cell_width = width
|
||||||
columns[index].cell_width = width
|
this.setColumns(this.internalColumns)
|
||||||
this.setColumns(columns)
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$emit('resize')
|
this.$emit('resize')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleScroll () {
|
handleScroll() {
|
||||||
const parent = document.getElementById('table-page')
|
const parent = document.getElementById('table-page')
|
||||||
const posTop = parent.getBoundingClientRect().top
|
const posTop = parent.getBoundingClientRect().top
|
||||||
const tablePosition = Math.max(0, posTop - this.$refs.table.getBoundingClientRect().top)
|
const tablePosition = Math.max(0, posTop - this.$refs.table.getBoundingClientRect().top)
|
||||||
|
@ -269,7 +253,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setColumns(val) {
|
setColumns(val) {
|
||||||
this.$emit('update-columns',val)
|
this.$emit('update-columns', val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,87 +283,4 @@ export default {
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.notion-table {
|
|
||||||
|
|
||||||
td {
|
|
||||||
&.text-gray {
|
|
||||||
color: #787774;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-brown {
|
|
||||||
color: #9f6b53;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-orange {
|
|
||||||
color: #d9730d;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-yellow {
|
|
||||||
color: #cb912f;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-green {
|
|
||||||
color: #448361;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-blue {
|
|
||||||
color: #337ea9;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-purple {
|
|
||||||
color: #9065b0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-pink {
|
|
||||||
color: #c14c8a;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-red {
|
|
||||||
color: #d44c47;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
.notion-table {
|
|
||||||
td {
|
|
||||||
&.text-gray {
|
|
||||||
color: #9b9b9b;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-brown {
|
|
||||||
color: #ba856f;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-orange {
|
|
||||||
color: #c77d48;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-yellow {
|
|
||||||
color: #ca9849;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-green {
|
|
||||||
color: #529e72;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-blue {
|
|
||||||
color: #5e87c9;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-purple {
|
|
||||||
color: #9d68d3;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-pink {
|
|
||||||
color: #d15796;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-red {
|
|
||||||
color: #df5452;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,10 +13,7 @@ import OpenTag from './OpenTag.vue'
|
||||||
export default {
|
export default {
|
||||||
components: { OpenTag },
|
components: { OpenTag },
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {}
|
||||||
type: Object
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
|
@ -31,8 +28,5 @@ export default {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
|
||||||
},
|
|
||||||
methods: {}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,41 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<span v-if="!valueIsObject">
|
<span>
|
||||||
{{ value }}
|
{{ value }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>
|
|
||||||
<span
|
|
||||||
v-for="(item, i) in value.responseData"
|
|
||||||
:key="i"
|
|
||||||
:class="{
|
|
||||||
'font-semibold': item.annotations.bold && !item.annotations.code,
|
|
||||||
italic: item.annotations.italic,
|
|
||||||
'line-through': item.annotations.strikethrough,
|
|
||||||
underline: item.annotations.underline,
|
|
||||||
'bg-pink-100 py-1 px-2 rounded-lg text-pink-500': item.annotations.code,
|
|
||||||
'font-serif': item.type == 'equation',
|
|
||||||
}"
|
|
||||||
:style="{
|
|
||||||
color:
|
|
||||||
item.annotations.color != 'default'
|
|
||||||
? getColor(item.annotations.color)
|
|
||||||
: null,
|
|
||||||
'background-color':
|
|
||||||
item.annotations.color != 'default' &&
|
|
||||||
item.annotations.color.split('_')[1]
|
|
||||||
? getBgColor(item.annotations.color.split('_')[0])
|
|
||||||
: 'none',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
v-if="item.href"
|
|
||||||
:href="item.href"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
class="text-blue-600 underline"
|
|
||||||
>{{ item.plain_text }}</a>
|
|
||||||
<span v-else-if="!item.href">{{ item.plain_text }}</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -45,55 +11,6 @@ export default {
|
||||||
value: {
|
value: {
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
valueIsObject () {
|
|
||||||
if (
|
|
||||||
typeof this.value === 'object' &&
|
|
||||||
!Array.isArray(this.value) &&
|
|
||||||
this.value !== null
|
|
||||||
) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getColor (color) {
|
|
||||||
return {
|
|
||||||
red: '#e03e3e',
|
|
||||||
gray: '#9b9a97',
|
|
||||||
brown: '#64473a',
|
|
||||||
orange: '#d9730d',
|
|
||||||
yellow: '#dfab01',
|
|
||||||
teal: '#0f7b6c',
|
|
||||||
blue: '#0b6e99',
|
|
||||||
purple: '#6940a5',
|
|
||||||
pink: '#ad1a72'
|
|
||||||
}[color]
|
|
||||||
},
|
|
||||||
getBgColor (color) {
|
|
||||||
return {
|
|
||||||
red: '#fbe4e4',
|
|
||||||
gray: '#ebeced',
|
|
||||||
brown: '#e9e5e3',
|
|
||||||
orange: '#faebdd',
|
|
||||||
yellow: '#fbf3db',
|
|
||||||
teal: '#ddedea',
|
|
||||||
blue: '#ddebf1',
|
|
||||||
purple: '#eae4f2',
|
|
||||||
pink: '#f4dfeb'
|
|
||||||
}[color]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<th ref="th" :style="{width: width}">
|
<th ref="th" :style="{width: width}">
|
||||||
<slot />
|
<slot/>
|
||||||
<div v-if="allowResize" class="absolute right-0 top-0 w-0 z-10">
|
<div v-if="allowResize" class="absolute right-0 top-0 w-0 z-10">
|
||||||
<div class="resize-handler bg-transparent cursor-move hover:bg-blue-500 opacity-80 transition-colors"
|
<div class="resize-handler bg-transparent cursor-move hover:bg-blue-500 opacity-80 transition-colors"
|
||||||
@mousedown="mouseDownHandler"
|
@mousedown="mouseDownHandler"
|
||||||
|
@ -21,20 +21,18 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
x: 0,
|
x: 0,
|
||||||
w: 0
|
w: 0,
|
||||||
|
lastEmit: Date.now(),
|
||||||
|
throttlePeriod: 50 // milliseconds
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
mouseDownHandler (e) {
|
mouseDownHandler(e) {
|
||||||
|
if (process.server) return
|
||||||
// Get the current mouse position
|
// Get the current mouse position
|
||||||
this.x = e.clientX
|
this.x = e.clientX
|
||||||
|
|
||||||
|
@ -43,24 +41,21 @@ export default {
|
||||||
this.w = parseInt(styles.width, 10)
|
this.w = parseInt(styles.width, 10)
|
||||||
|
|
||||||
// Attach the listeners to `document`
|
// Attach the listeners to `document`
|
||||||
if (process.client) {
|
document.addEventListener('mousemove', this.mouseMoveHandler)
|
||||||
document.addEventListener('mousemove', this.mouseMoveHandler)
|
document.addEventListener('mouseup', this.mouseUpHandler)
|
||||||
document.addEventListener('mouseup', this.mouseUpHandler)
|
},
|
||||||
|
mouseMoveHandler(e) {
|
||||||
|
const now = Date.now()
|
||||||
|
if (now - this.lastEmit > this.throttlePeriod) {
|
||||||
|
const dx = e.clientX - this.x
|
||||||
|
this.$emit('resize-width', this.w + dx)
|
||||||
|
this.lastEmit = now
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mouseMoveHandler (e) {
|
mouseUpHandler() {
|
||||||
// How far the mouse has been moved
|
|
||||||
const dx = e.clientX - this.x
|
|
||||||
|
|
||||||
// Adjust the dimension of element
|
|
||||||
this.$emit('resize-width', this.w + dx)
|
|
||||||
},
|
|
||||||
mouseUpHandler () {
|
|
||||||
// Remove the handlers of `mousemove` and `mouseup`
|
// Remove the handlers of `mousemove` and `mouseup`
|
||||||
if (process.client) {
|
document.removeEventListener('mousemove', this.mouseMoveHandler)
|
||||||
document.removeEventListener('mousemove', this.mouseMoveHandler)
|
document.removeEventListener('mouseup', this.mouseUpHandler)
|
||||||
document.removeEventListener('mouseup', this.mouseUpHandler)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue