Browse Source

feat(gui-v2): select column options

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/3022/head
mertmit 2 years ago
parent
commit
8c28ec92e0
  1. 1
      packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue
  2. 104
      packages/nc-gui-v2/components/smartsheet-column/SelectOptions.vue

1
packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue

@ -139,6 +139,7 @@ watch(
/>
<SmartsheetColumnSpecificDBTypeOptions v-if="formState.uidt === UITypes.SpecificDBType" />
<SmartsheetColumnPercentOptions v-if="formState.uidt === UITypes.Percent" />
<SmartsheetColumnSelectOptions v-if="formState.uidt === UITypes.SingleSelect || formState.uidt === UITypes.MultiSelect" />
<div
v-if="!isVirtualCol(formState.uidt)"

104
packages/nc-gui-v2/components/smartsheet-column/SelectOptions.vue

@ -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…
Cancel
Save