Browse Source

Merge pull request #4459 from nocodb/fix/single-multi-select-followup

Refactor: Grid - Single/Multi select followup
pull/4465/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
8bb608f2e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      packages/nc-gui/assets/style.scss
  2. 4
      packages/nc-gui/components/account/UserList.vue
  3. 4
      packages/nc-gui/components/account/UsersModal.vue
  4. 42
      packages/nc-gui/components/cell/MultiSelect.vue
  5. 34
      packages/nc-gui/components/cell/SingleSelect.vue
  6. 9
      packages/nc-gui/components/smartsheet/column/SelectOptions.vue
  7. 12
      packages/nc-gui/composables/useColumnCreateStore.ts

5
packages/nc-gui/assets/style.scss

@ -281,3 +281,8 @@ a {
.ant-modal {
@apply !top-[50px];
}
.ant-select-item-option-active:not(.ant-select-item-option-disabled) {
@apply bg-primary bg-opacity-20;
}

4
packages/nc-gui/components/account/UserList.vue

@ -29,7 +29,9 @@ const searchText = ref<string>('')
const pagination = reactive({
total: 0,
pageSize: 10,
position: ['bottomCenter'],
})
const loadUsers = async (page = currentPage, limit = currentLimit) => {
currentPage = page
try {
@ -158,7 +160,7 @@ const copyPasswordResetUrl = async (user: User) => {
<a-table
:row-key="(record) => record.id"
:data-source="users"
:pagination="{ position: ['bottomCenter'] }"
:pagination="pagination"
:loading="isLoading"
size="small"
@change="loadUsers($event.current)"

4
packages/nc-gui/components/account/UsersModal.vue

@ -4,13 +4,13 @@ import {
Form,
computed,
extractSdkResponseErrorMsg,
isEmail,
message,
ref,
useCopy,
useDashboard,
useI18n,
useNuxtApp,
validateEmail,
} from '#imports'
import type { User } from '~/lib'
import { Role } from '~/lib'
@ -52,7 +52,7 @@ const validators = computed(() => {
callback('Email is required')
return
}
const invalidEmails = (value || '').split(/\s*,\s*/).filter((e: string) => !isEmail(e))
const invalidEmails = (value || '').split(/\s*,\s*/).filter((e: string) => !validateEmail(e))
if (invalidEmails.length > 0) {
callback(`${invalidEmails.length > 1 ? ' Invalid emails:' : 'Invalid email:'} ${invalidEmails.join(', ')} `)
} else {

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

@ -33,8 +33,6 @@ const { modelValue } = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
const { isMysql } = useProject()
const column = inject(ColumnInj)!
const readOnly = inject(ReadonlyInj)!
@ -59,6 +57,8 @@ const { $api } = useNuxtApp()
const { getMeta } = useMetas()
const { isPg, isMysql } = useProject()
// a variable to keep newly created options value
// temporary until it's add the option to column meta
const tempSelectedOptsState = reactive<string[]>([])
@ -171,8 +171,19 @@ useSelectedCellKeyupListener(active, (e) => {
isOpen.value = true
}
break
case 'ArrowUp':
case 'ArrowDown':
case 'ArrowRight':
case 'ArrowLeft':
case 'Delete':
// skip
break
default:
isOpen.value = true
// toggle only if char key pressed
if (e.key?.length === 1) {
e.stopPropagation()
isOpen.value = true
}
break
}
})
@ -195,9 +206,28 @@ async function addIfMissingAndSave() {
})
column.value.colOptions = { options: newOptions.map(({ value: _, ...rest }) => rest) }
await $api.dbTableColumn.update((column.value as { fk_column_id?: string })?.fk_column_id || (column.value?.id as string), {
...column.value,
})
const updatedColMeta = { ...column.value }
// todo: refactor and avoid repetition
if (updatedColMeta.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) {
updatedColMeta.cdf = updatedColMeta.cdf.substring(
updatedColMeta.cdf.indexOf(`'`) + 1,
updatedColMeta.cdf.lastIndexOf(`'`),
)
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
if (!isMysql.value) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}
await $api.dbTableColumn.update(
(column.value as { fk_column_id?: string })?.fk_column_id || (column.value?.id as string),
updatedColMeta,
)
activeOptCreateInProgress.value--
if (!activeOptCreateInProgress.value) {

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

@ -49,6 +49,8 @@ const searchVal = ref()
const { getMeta } = useMetas()
const { isPg, isMysql } = useProject()
// a variable to keep newly created option value
// temporary until it's add the option to column meta
const tempSelectedOptState = ref<string>()
@ -102,6 +104,13 @@ useSelectedCellKeyupListener(active, (e) => {
isOpen.value = true
}
break
default:
// toggle only if char key pressed
if (e.key?.length === 1) {
e.stopPropagation()
isOpen.value = true
}
break
}
})
@ -120,9 +129,28 @@ async function addIfMissingAndSave() {
})
column.value.colOptions = { options: options.value.map(({ value: _, ...rest }) => rest) }
await $api.dbTableColumn.update((column.value as { fk_column_id?: string })?.fk_column_id || (column.value?.id as string), {
...column.value,
})
const updatedColMeta = { ...column.value }
// todo: refactor and avoid repetition
if (updatedColMeta.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) {
updatedColMeta.cdf = updatedColMeta.cdf.substring(
updatedColMeta.cdf.indexOf(`'`) + 1,
updatedColMeta.cdf.lastIndexOf(`'`),
)
}
// Mysql escapes single quotes with backslash so we keep quotes but others have to unescaped
if (!isMysql.value) {
updatedColMeta.cdf = updatedColMeta.cdf.replace(/''/g, "'")
}
}
await $api.dbTableColumn.update(
(column.value as { fk_column_id?: string })?.fk_column_id || (column.value?.id as string),
updatedColMeta,
)
vModel.value = newOptValue
await getMeta(column.value.fk_model_id!, true)
} catch (e) {

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

@ -174,13 +174,12 @@ watch(inputs, () => {
/>
</div>
</template>
<template #footer>
<div v-if="validateInfos?.['colOptions.options']?.help?.[0]?.[0]" class="text-error text-[10px] my-2">
{{ validateInfos['colOptions.options'].help[0][0] }}
</div>
</template>
</Draggable>
</div>
<div v-if="validateInfos?.['colOptions.options']?.help?.[0]?.[0]" class="text-error text-[10px] mb-1 mt-2">
{{ validateInfos['colOptions.options'].help[0][0] }}
</div>
<a-button type="dashed" class="w-full caption mt-2" @click="addNewOption()">
<div class="flex items-center">
<MdiPlus />

12
packages/nc-gui/composables/useColumnCreateStore.ts

@ -195,9 +195,15 @@ const [useProvideColumnCreateStore, useColumnCreateStore] = createInjectionState
try {
if (!(await validate())) return
} catch (e) {
console.log(e)
console.trace()
message.error(t('msg.error.formValidationFailed'))
const errorMsgs = e.errorFields
?.map((e: any) => e.errors?.join(', '))
.filter(Boolean)
.join(', ')
if (errorMsgs) {
message.error(errorMsgs)
} else {
message.error(t('msg.error.formValidationFailed'))
}
return
}

Loading…
Cancel
Save