Browse Source

Merge pull request #6584 from nocodb/nc-fix/default-re

fix: default value for select options
pull/6597/head
Raju Udava 11 months ago committed by GitHub
parent
commit
9cd1623a9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 2
      packages/nc-gui/components/cell/SingleSelect.vue
  3. 5
      packages/nc-gui/components/smartsheet/Cell.vue
  4. 53
      packages/nc-gui/components/smartsheet/column/DefaultValue.vue
  5. 25
      packages/nc-gui/components/smartsheet/column/SelectOptions.vue
  6. 6
      packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts
  7. 90
      packages/nocodb/src/services/columns.service.ts

2
packages/nc-gui/components/cell/MultiSelect.vue

@ -255,7 +255,7 @@ async function addIfMissingAndSave() {
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
if (!isMysql(column.value.source_id)) {
if (!isMysql(column.value.source_id) && !isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}

2
packages/nc-gui/components/cell/SingleSelect.vue

@ -183,7 +183,7 @@ async function addIfMissingAndSave() {
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
if (!isMysql(column.value.source_id)) {
if (!isMysql(column.value.source_id) && !isPg(column.value.source_id)) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}

5
packages/nc-gui/components/smartsheet/Cell.vue

@ -63,7 +63,7 @@ interface Props {
const props = defineProps<Props>()
const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editEnabled', 'update:value'])
const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editEnabled', 'update:cdf'])
const column = toRef(props, 'column')
@ -118,8 +118,7 @@ const vModel = computed({
},
set: (val) => {
if (isEditColumnMenu.value) {
column.value.cdf = val
emit('update:value', val)
emit('update:cdf', val)
} else if (val !== props.modelValue) {
currentRow.value.rowMeta.changed = true
emit('update:modelValue', val)

53
packages/nc-gui/components/smartsheet/column/DefaultValue.vue

@ -5,54 +5,49 @@ import { iconMap } from '#imports'
const props = defineProps<{
value: any
}>()
const emit = defineEmits(['update:value'])
const emits = defineEmits(['update:value'])
const meta = inject(MetaInj, ref())
provide(EditColumnInj, ref(true))
const vModel = useVModel(props, 'value', emit)
const vModel = useVModel(props, 'value', emits)
const rowRef = ref({
row: {},
oldRow: {},
rowMeta: {
isUpdatedFromCopyNPaste: [vModel?.value.title],
isUpdatedFromCopyNPaste: [vModel.value?.title],
},
})
const cdfValue = computed({
get: () => {
if (vModel.value.uidt === UITypes.MultiSelect || vModel.value.uidt === UITypes.SingleSelect) {
return (vModel.value.cdf ?? '').replaceAll("'", '')
} else if (
vModel.value.uidt === UITypes.SingleLineText ||
vModel.value.uidt === UITypes.LongText ||
vModel.value.uidt === UITypes.Email ||
vModel.value.uidt === UITypes.URL ||
vModel.value.uidt === UITypes.JSON ||
vModel.value.uidt === UITypes.DateTime ||
vModel.value.uidt === UITypes.Time ||
vModel.value.uidt === UITypes.Year ||
vModel.value.uidt === UITypes.Date
) {
return (vModel.value.cdf ?? '').replace(/^'/, '').replace(/'$/, '')
}
return vModel.value.cdf
},
set: (value) => {
vModel.value.cdf = value
},
})
useProvideSmartsheetRowStore(meta, rowRef)
useProvideSmartsheetRowStore(vModel, rowRef)
const cdfValue = ref<string | null>(null)
const updateCdfValue = (cdf: string | null) => {
vModel.value.cdf = cdf
cdfValue.value = vModel.value.cdf
}
onMounted(() => {
updateCdfValue(vModel.value?.cdf ? vModel.value.cdf : null)
})
</script>
<template>
<div class="!my-3 text-xs">{{ $t('placeholder.defaultValue') }}</div>
<div class="flex flex-row gap-2">
<div class="border-1 flex items-center w-full px-3 my-[-4px] border-gray-300 rounded-md">
<LazySmartsheetCell :column="vModel" :model-value="cdfValue" :edit-enabled="true" class="!border-none" />
<LazySmartsheetCell
:model-value="cdfValue"
:column="vModel"
:edit-enabled="true"
class="!border-none"
@update:cdf="updateCdfValue"
/>
<component
:is="iconMap.close"
v-if="vModel.uidt !== UITypes.Year"
v-if="![UITypes.Year, UITypes.SingleSelect, UITypes.MultiSelect].includes(vModel.uidt)"
class="w-4 h-4 cursor-pointer rounded-full !text-black-500 text-gray-500 cursor-pointer hover:bg-gray-50"
@click="cdfValue = null"
/>

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

@ -21,7 +21,7 @@ const emit = defineEmits(['update:value'])
const vModel = useVModel(props, 'value', emit)
const { setAdditionalValidations, validateInfos, isMysql } = useColumnCreateStoreOrThrow()
const { setAdditionalValidations, validateInfos, isMysql, isPg } = useColumnCreateStoreOrThrow()
// const { base } = storeToRefs(useBase())
@ -101,9 +101,9 @@ onMounted(() => {
}
if (vModel.value.cdf) {
// 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.value.find((el) => el.title === vModel.value.cdf)
if (!fndDefaultOption) {
vModel.value.cdf = vModel.value.cdf.replace(/^'/, '').replace(/'$/, '')
}
}
@ -181,23 +181,6 @@ const undoRemoveRenderedOption = (index: number) => {
}
}
// focus last created input
// watch(inputs, () => {
// if (inputs.value?.$el) {
// inputs.value.$el.focus()
// }
// })
// Removes the Select Option from cdf if the option is removed
watch(vModel.value, (next) => {
const cdfs = (next.cdf ?? '').split(',')
const values = (next.colOptions.options ?? []).map((col) => {
return col.title.replace(/^'/, '').replace(/'$/, '')
})
const newCdf = cdfs.filter((c: string) => values.includes(c)).join(',')
next.cdf = newCdf.length === 0 ? null : newCdf
})
const loadListData = async ($state: any) => {
if (loadedOptionCount.value === options.value.length) {
$state.complete()

6
packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts

@ -2090,7 +2090,7 @@ class SqliteClient extends KnexClient {
addNewColumnQuery +=
n.dtxp && n.dt !== 'text' ? `(${this.genRaw(n.dtxp)})` : '';
addNewColumnQuery += n.cdf
? ` DEFAULT ${this.sanitiseDefaultValue(n.cdf)}`
? ` DEFAULT ${this.genValue(n.cdf)}`
: !n.rqd
? ' '
: ` DEFAULT ''`;
@ -2122,7 +2122,7 @@ class SqliteClient extends KnexClient {
shouldSanitize,
);
query += n.dtxp && n.dt !== 'text' ? `(${this.genRaw(n.dtxp)})` : '';
query += n.cdf ? ` DEFAULT ${this.sanitiseDefaultValue(n.cdf)}` : ' ';
query += n.cdf ? ` DEFAULT ${this.genValue(n.cdf)}` : ' ';
query += n.rqd ? ` NOT NULL` : ' ';
} else if (change === 1) {
shouldSanitize = true;
@ -2133,7 +2133,7 @@ class SqliteClient extends KnexClient {
);
query += n.dtxp && n.dt !== 'text' ? `(${this.genRaw(n.dtxp)})` : '';
query += n.cdf
? ` DEFAULT ${this.sanitiseDefaultValue(n.cdf)}`
? ` DEFAULT ${this.genValue(n.cdf)}`
: !n.rqd
? ' '
: ` DEFAULT ''`;

90
packages/nocodb/src/services/columns.service.ts

@ -371,23 +371,48 @@ export class ColumnsService {
);
if (colBody.cdf) {
if (colBody.uidt === UITypes.SingleSelect) {
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.replace(/'/g, "''"))) {
try {
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`,
`Default value '${colBody.cdf}' is not a select option.`,
);
}
} catch (e) {
colBody.cdf = colBody.cdf.replace(/^'/, '').replace(/'$/, '');
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${colBody.cdf}' is not a select option.`,
);
}
}
} else {
try {
for (const cdf of colBody.cdf.split(',')) {
if (!optionTitles.includes(cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`,
);
}
}
} catch (e) {
colBody.cdf = colBody.cdf.replace(/^'/, '').replace(/'$/, '');
for (const cdf of colBody.cdf.split(',')) {
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') {
if (
driverType === 'mysql' ||
driverType === 'mysql2' ||
driverType === 'pg' ||
driverType === 'sqlite3'
) {
colBody.cdf = colBody.cdf.replace(/'/g, "'");
} else {
colBody.cdf = colBody.cdf.replace(/'/g, "''");
@ -1142,23 +1167,48 @@ export class ColumnsService {
// Handle default values
if (colBody.cdf) {
if (colBody.uidt === UITypes.SingleSelect) {
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.replace(/'/g, "''"))) {
try {
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${colBody.cdf}' is not a select option.`,
);
}
} catch (e) {
colBody.cdf = colBody.cdf.replace(/^'/, '').replace(/'$/, '');
if (!optionTitles.includes(colBody.cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`,
`Default value '${colBody.cdf}' is not a select option.`,
);
}
}
} else {
try {
for (const cdf of colBody.cdf.split(',')) {
if (!optionTitles.includes(cdf.replace(/'/g, "''"))) {
NcError.badRequest(
`Default value '${cdf}' is not a select option.`,
);
}
}
} catch (e) {
colBody.cdf = colBody.cdf.replace(/^'/, '').replace(/'$/, '');
for (const cdf of colBody.cdf.split(',')) {
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') {
if (
driverType === 'mysql' ||
driverType === 'mysql2' ||
driverType === 'pg' ||
driverType === 'sqlite3'
) {
colBody.cdf = colBody.cdf.replace(/'/g, "'");
} else {
colBody.cdf = colBody.cdf.replace(/'/g, "''");

Loading…
Cancel
Save