mirror of https://github.com/nocodb/nocodb
mertmit
2 years ago
2 changed files with 105 additions and 0 deletions
@ -0,0 +1,104 @@
|
||||
<script setup lang="ts"> |
||||
import Draggable from 'vuedraggable' |
||||
import { UITypes } from 'nocodb-sdk' |
||||
import { useColumnCreateStoreOrThrow } from '#imports' |
||||
import { enumColor } from '@/utils' |
||||
import MdiDragIcon from '~icons/mdi/drag-vertical' |
||||
import MdiArrowDownDropCircle from '~icons/mdi/arrow-down-drop-circle' |
||||
import MdiClose from '~icons/mdi/close' |
||||
import MdiPlusIcon from '~icons/mdi/plus' |
||||
|
||||
const { formState, validateInfos, setAdditionalValidations, sqlUi, onDataTypeChange, onAlter } = useColumnCreateStoreOrThrow() |
||||
|
||||
let options = $ref<any[]>([]) |
||||
const colorMenus = $ref<any>({}) |
||||
const colors = $ref(enumColor.light) |
||||
|
||||
const validators = { |
||||
'colOptions.options': [ |
||||
{ |
||||
validator: (_: any, opt: any) => { |
||||
return new Promise<void>((resolve, reject) => { |
||||
for (const opt of options) { |
||||
if (!opt.title.length) { |
||||
return reject(new Error("Select options can't be null")) |
||||
} |
||||
if (formState.value.uidt === UITypes.MultiSelect && opt.title.includes(',')) { |
||||
return reject(new Error("MultiSelect columns can't have commas(',')")) |
||||
} |
||||
if (options.filter((el) => el.title === opt.title).length !== 1) { |
||||
return reject(new Error("Select options can't have duplicates")) |
||||
} |
||||
} |
||||
resolve() |
||||
}) |
||||
}, |
||||
}, |
||||
], |
||||
} |
||||
|
||||
setAdditionalValidations({ |
||||
...validators, |
||||
}) |
||||
|
||||
const getNextColor = () => { |
||||
let tempColor = colors[0] |
||||
if (options.length && options[options.length - 1].color) { |
||||
const lastColor = colors.indexOf(options[options.length - 1].color) |
||||
tempColor = colors[(lastColor + 1) % colors.length] |
||||
} |
||||
return tempColor |
||||
} |
||||
|
||||
const addNewOption = () => { |
||||
const tempOption = { |
||||
title: '', |
||||
color: getNextColor(), |
||||
} |
||||
options.push(tempOption) |
||||
} |
||||
|
||||
const removeOption = (index: number) => { |
||||
options.splice(index, 1) |
||||
} |
||||
|
||||
onMounted(() => { |
||||
if (!formState.value.colOptions?.options) { |
||||
formState.value.colOptions = { |
||||
options: [], |
||||
} |
||||
} |
||||
options = formState.value.colOptions.options |
||||
// Support for older options |
||||
for (const op of options.filter((el) => el.order === null)) { |
||||
op.title = op.title.replace(/^'/, '').replace(/'$/, '') |
||||
} |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<div class="w-full"> |
||||
<draggable :list="options" item-key="id" handle=".nc-child-draggable-icon"> |
||||
<template #item="{ element, index }"> |
||||
<div class="flex py-1 align-center"> |
||||
<MdiDragIcon small class="nc-child-draggable-icon handle" /> |
||||
<a-dropdown v-model:visible="colorMenus[index]" :trigger="['click']"> |
||||
<template #overlay> |
||||
<GeneralColorPicker v-model="element.color" @update:model-value="colorMenus[index] = false" /> |
||||
</template> |
||||
<MdiArrowDownDropCircle :style="{ 'font-size': '1.5em', 'color': element.color }" class="mr-2" /> |
||||
</a-dropdown> |
||||
<a-input v-model:value="element.title" class="caption" /> |
||||
<MdiClose class="ml-2" :style="{ color: 'red' }" @click="removeOption(index)" /> |
||||
</div> |
||||
</template> |
||||
<template #footer> |
||||
<a-button type="dashed" class="w-full caption mt-2" @click="addNewOption()"> |
||||
<div class="flex align-center"><MdiPlusIcon /><span class="flex-auto">Add option</span></div> |
||||
</a-button> |
||||
</template> |
||||
</draggable> |
||||
</div> |
||||
</template> |
||||
|
||||
<style scoped lang="scss"></style> |
Loading…
Reference in new issue