Browse Source

Merge pull request #3898 from nocodb/fix/3896-select

fix: select options default value
pull/3904/head
Raju Udava 2 years ago committed by GitHub
parent
commit
6323e1fd64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 68
      packages/nc-gui/components/smartsheet/column/SelectOptions.vue
  2. 24
      packages/nocodb/src/lib/meta/api/columnApis.ts

68
packages/nc-gui/components/smartsheet/column/SelectOptions.vue

@ -11,7 +11,7 @@ const emit = defineEmits(['update:value'])
const vModel = useVModel(props, 'value', emit)
const { isPg } = useProject()
const { isPg, isMysql } = useProject()
const { setAdditionalValidations, validateInfos } = useColumnCreateStoreOrThrow()
@ -19,6 +19,7 @@ let options = $ref<any[]>([])
const colorMenus = $ref<any>({})
const colors = $ref(enumColor.light)
const inputs = ref()
const defaultOption = ref()
const validators = {
'colOptions.options': [
@ -47,6 +48,49 @@ setAdditionalValidations({
...validators,
})
onMounted(() => {
if (!vModel.value.colOptions?.options) {
vModel.value.colOptions = {
options: [],
}
}
options = vModel.value.colOptions.options
// Support for older options
for (const op of options.filter((el) => el.order === null)) {
op.title = op.title.replace(/^'/, '').replace(/'$/, '')
}
if (vModel.value.cdf) {
// Postgres returns default value wrapped with single quotes & casted with type so we have to get value between single quotes to keep it unified for all databases
if (isPg.value) {
vModel.value.cdf = vModel.value.cdf.substring(vModel.value.cdf.indexOf(`'`) + 1, vModel.value.cdf.lastIndexOf(`'`))
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
if (!isMysql.value) {
vModel.value.cdf = vModel.value.cdf.replace(/''/g, "'")
}
}
const fndDefaultOption = options.find((el) => el.title === vModel.value.cdf)
if (fndDefaultOption) {
defaultOption.value = fndDefaultOption
}
})
const optionChanged = (changedId: string) => {
if (changedId === defaultOption.value?.id) {
vModel.value.cdf = defaultOption.value.title
}
}
const optionDropped = (changedId: string) => {
if (changedId === defaultOption.value?.id) {
vModel.value.cdf = null
defaultOption.value = null
}
}
const getNextColor = () => {
let tempColor = colors[0]
if (options.length && options[options.length - 1].color) {
@ -65,27 +109,11 @@ const addNewOption = () => {
}
const removeOption = (index: number) => {
const optionId = options[index]?.id
options.splice(index, 1)
optionDropped(optionId)
}
onMounted(() => {
if (!vModel.value.colOptions?.options) {
vModel.value.colOptions = {
options: [],
}
}
options = vModel.value.colOptions.options
// Support for older options
for (const op of options.filter((el) => el.order === null)) {
op.title = op.title.replace(/^'/, '').replace(/'$/, '')
}
// Postgres returns default value wrapped with single quotes & casted with type so we have to get value between single quotes to keep it unified for all databases
if (isPg.value && vModel.value.cdf) {
vModel.value.cdf = vModel.value.cdf.substring(vModel.value.cdf.indexOf(`'`) + 1, vModel.value.cdf.lastIndexOf(`'`))
}
})
// focus last created input
watch(inputs, () => {
if (inputs.value?.$el) {
@ -116,7 +144,7 @@ watch(inputs, () => {
<MdiArrowDownDropCircle :style="{ 'font-size': '1.5em', 'color': element.color }" class="mr-2" />
</a-dropdown>
<a-input ref="inputs" v-model:value="element.title" class="caption" />
<a-input ref="inputs" v-model:value="element.title" class="caption" @change="optionChanged(element.id)" />
<MdiClose class="ml-2" :style="{ color: 'red' }" @click="removeOption(index)" />
</div>

24
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -524,20 +524,28 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
// Handle default values
if (colBody.cdf) {
if (colBody.uidt === UITypes.SingleSelect) {
if (!optionTitles.includes(colBody.cdf)) {
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${colBody.cdf}' is not a select option.`
);
}
} else {
for (const cdf of colBody.cdf.split(',')) {
if (!optionTitles.includes(cdf)) {
if (!optionTitles.includes(cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`
);
}
}
}
// handle single quote for default value
if (driverType === 'mysql' || driverType === 'mysql2') {
colBody.cdf = colBody.cdf.replace(/'/g, "\'");
} else {
colBody.cdf = colBody.cdf.replace(/'/g, "''");
}
if (driverType === 'pg') {
colBody.cdf = `'${colBody.cdf}'`;
}
@ -812,20 +820,28 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
);
if (colBody.cdf) {
if (colBody.uidt === UITypes.SingleSelect) {
if (!optionTitles.includes(colBody.cdf)) {
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${colBody.cdf}' is not a select option.`
);
}
} else {
for (const cdf of colBody.cdf.split(',')) {
if (!optionTitles.includes(cdf)) {
if (!optionTitles.includes(cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`
);
}
}
}
// handle single quote for default value
if (driverType === 'mysql' || driverType === 'mysql2') {
colBody.cdf = colBody.cdf.replace(/'/g, "\'");
} else {
colBody.cdf = colBody.cdf.replace(/'/g, "''");
}
if (driverType === 'pg') {
colBody.cdf = `'${colBody.cdf}'`;
}

Loading…
Cancel
Save