Browse Source

Merge branch 'develop' into feat/kanban-view

pull/3818/head
Wing-Kam Wong 2 years ago
parent
commit
92f84f24f3
  1. 38
      packages/nc-gui/components.d.ts
  2. 8
      packages/nc-gui/components/api-client/Headers.vue
  3. 1
      packages/nc-gui/components/cell/MultiSelect.vue
  4. 1
      packages/nc-gui/components/cell/SingleSelect.vue
  5. 2
      packages/nc-gui/components/smartsheet-column/AdvancedOptions.vue
  6. 2
      packages/nc-gui/components/smartsheet-column/CheckboxOptions.vue
  7. 2
      packages/nc-gui/components/smartsheet-column/CurrencyOptions.vue
  8. 2
      packages/nc-gui/components/smartsheet-column/DateOptions.vue
  9. 2
      packages/nc-gui/components/smartsheet-column/DurationOptions.vue
  10. 1
      packages/nc-gui/components/smartsheet-column/EditOrAdd.vue
  11. 17
      packages/nc-gui/components/smartsheet-column/LinkedToAnotherRecordOptions.vue
  12. 13
      packages/nc-gui/components/smartsheet-column/LookupOptions.vue
  13. 2
      packages/nc-gui/components/smartsheet-column/PercentOptions.vue
  14. 4
      packages/nc-gui/components/smartsheet-column/RatingOptions.vue
  15. 19
      packages/nc-gui/components/smartsheet-column/RollupOptions.vue
  16. 1
      packages/nc-gui/components/smartsheet-toolbar/FieldListAutoCompleteDropdown.vue
  17. 8
      packages/nc-gui/components/smartsheet-toolbar/FieldsMenu.vue
  18. 2
      packages/nc-gui/components/smartsheet-toolbar/SearchData.vue
  19. 2
      packages/nc-gui/components/smartsheet-toolbar/SortListMenu.vue
  20. 7
      packages/nc-gui/components/smartsheet/ApiSnippet.vue
  21. 12
      packages/nc-gui/components/smartsheet/Form.vue
  22. 7
      packages/nc-gui/components/tabs/auth/user-management/ShareBase.vue
  23. 2
      packages/nc-gui/components/tabs/auth/user-management/UsersModal.vue
  24. 9
      packages/nc-gui/components/template/Editor.vue
  25. 8
      packages/nc-gui/components/webhook/ChannelMultiSelect.vue
  26. 9
      packages/nc-gui/components/webhook/Editor.vue
  27. 9
      packages/nc-gui/composables/useProject.ts
  28. 17
      packages/nc-gui/pages/error/404.vue
  29. 19
      packages/nc-gui/pages/index/index/create-external.vue
  30. 2
      scripts/cypress/integration/common/1b_table_column_operations.js
  31. 2
      scripts/cypress/integration/common/3b_formula_column.js
  32. 6
      scripts/cypress/integration/common/3c_lookup_column.js
  33. 8
      scripts/cypress/integration/common/3d_rollup_column.js
  34. 6
      scripts/cypress/integration/common/3e_duration_column.js
  35. 4
      scripts/cypress/integration/common/3f_link_to_another_record.js
  36. 4
      scripts/cypress/integration/common/6g_base_share.js
  37. 4
      scripts/cypress/integration/common/8a_webhook.js
  38. 4
      scripts/cypress/support/page_objects/mainPage.js
  39. 2
      scripts/cypress/support/page_objects/navigation.js

38
packages/nc-gui/components.d.ts vendored

@ -8,7 +8,6 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
AAutoComplete: typeof import('ant-design-vue/es')['AutoComplete']
ABadgeRibbon: typeof import('ant-design-vue/es')['BadgeRibbon']
AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card']
@ -24,7 +23,6 @@ declare module '@vue/runtime-core' {
ADivider: typeof import('ant-design-vue/es')['Divider']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
ADropdownButton: typeof import('ant-design-vue/es')['DropdownButton']
AEmpty: typeof import('ant-design-vue/es')['Empty']
AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem']
@ -67,21 +65,16 @@ declare module '@vue/runtime-core' {
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATimePicker: typeof import('ant-design-vue/es')['TimePicker']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATypography: typeof import('ant-design-vue/es')['Typography']
ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
BiFiletypeJson: typeof import('~icons/bi/filetype-json')['default']
BiFiletypeXlsx: typeof import('~icons/bi/filetype-xlsx')['default']
CilFullscreen: typeof import('~icons/cil/fullscreen')['default']
CilFullscreenExit: typeof import('~icons/cil/fullscreen-exit')['default']
ClarityColorPickerLine: typeof import('~icons/clarity/color-picker-line')['default']
ClarityColorPickerSolid: typeof import('~icons/clarity/color-picker-solid')['default']
ClarityImageLine: typeof import('~icons/clarity/image-line')['default']
ClaritySuccessLine: typeof import('~icons/clarity/success-line')['default']
EvaEmailOutline: typeof import('~icons/eva/email-outline')['default']
'Ic:twotoneWidthFull': typeof import('~icons/ic/twotone-width-full')['default']
IcBaselineMoreVert: typeof import('~icons/ic/baseline-more-vert')['default']
IcBaselineWidthFull: typeof import('~icons/ic/baseline-width-full')['default']
IcOutlineInsertDriveFile: typeof import('~icons/ic/outline-insert-drive-file')['default']
IcRoundEdit: typeof import('~icons/ic/round-edit')['default']
IcRoundKeyboardArrowDown: typeof import('~icons/ic/round-keyboard-arrow-down')['default']
@ -94,7 +87,6 @@ declare module '@vue/runtime-core' {
MaterialSymbolsArrowCircleLeftRounded: typeof import('~icons/material-symbols/arrow-circle-left-rounded')['default']
MaterialSymbolsArrowCircleRightRounded: typeof import('~icons/material-symbols/arrow-circle-right-rounded')['default']
MaterialSymbolsAttachFile: typeof import('~icons/material-symbols/attach-file')['default']
MaterialSymbolsChevronLeftRounded: typeof import('~icons/material-symbols/chevron-left-rounded')['default']
MaterialSymbolsChevronRightRounded: typeof import('~icons/material-symbols/chevron-right-rounded')['default']
MaterialSymbolsCloseRounded: typeof import('~icons/material-symbols/close-rounded')['default']
MaterialSymbolsFileCopyOutline: typeof import('~icons/material-symbols/file-copy-outline')['default']
@ -102,30 +94,20 @@ declare module '@vue/runtime-core' {
MaterialSymbolsSendOutline: typeof import('~icons/material-symbols/send-outline')['default']
MaterialSymbolsTranslate: typeof import('~icons/material-symbols/translate')['default']
MaterialSymbolsWarning: typeof import('~icons/material-symbols/warning')['default']
MaterialSymbolsWidthFull: typeof import('~icons/material-symbols/width-full')['default']
MaterialSymbolsWidthWideOutline: typeof import('~icons/material-symbols/width-wide-outline')['default']
'Mdi:arrowExpandHorizontal': typeof import('~icons/mdi/arrow-expand-horizontal')['default']
MdiAccount: typeof import('~icons/mdi/account')['default']
MdiAccountCircle: typeof import('~icons/mdi/account-circle')['default']
MdiAccountGroup: typeof import('~icons/mdi/account-group')['default']
MdiAccountGroupIcon: typeof import('~icons/mdi/account-group-icon')['default']
MdiAccountIcon: typeof import('~icons/mdi/account-icon')['default']
MdiAccountOutline: typeof import('~icons/mdi/account-outline')['default']
MdiAccountPlus: typeof import('~icons/mdi/account-plus')['default']
MdiAccountPlusOutline: typeof import('~icons/mdi/account-plus-outline')['default']
MdiAccountSupervisorOutline: typeof import('~icons/mdi/account-supervisor-outline')['default']
MdiAlpha: typeof import('~icons/mdi/alpha')['default']
MdiAlphaA: typeof import('~icons/mdi/alpha-a')['default']
MdiApi: typeof import('~icons/mdi/api')['default']
MdiArrowCollapse: typeof import('~icons/mdi/arrow-collapse')['default']
MdiArrowDownDropCircleOutline: typeof import('~icons/mdi/arrow-down-drop-circle-outline')['default']
MdiArrowExpand: typeof import('~icons/mdi/arrow-expand')['default']
MdiArrowExpandHorizontal: typeof import('~icons/mdi/arrow-expand-horizontal')['default']
MdiArrowLeftBold: typeof import('~icons/mdi/arrow-left-bold')['default']
MdiAt: typeof import('~icons/mdi/at')['default']
MdiBackburger: typeof import('~icons/mdi/backburger')['default']
MdiBookOpenOutline: typeof import('~icons/mdi/book-open-outline')['default']
MdiBookOpenPageVariantOutline: typeof import('~icons/mdi/book-open-page-variant-outline')['default']
MdiBugOutline: typeof import('~icons/mdi/bug-outline')['default']
MdiCalculator: typeof import('~icons/mdi/calculator')['default']
MdiCalendarMonth: typeof import('~icons/mdi/calendar-month')['default']
@ -133,7 +115,6 @@ declare module '@vue/runtime-core' {
MdiCellphoneMessage: typeof import('~icons/mdi/cellphone-message')['default']
MdiChat: typeof import('~icons/mdi/chat')['default']
MdiCheck: typeof import('~icons/mdi/check')['default']
MdiChevronDoubleLeft: typeof import('~icons/mdi/chevron-double-left')['default']
MdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
MdiChevronLeft: typeof import('~icons/mdi/chevron-left')['default']
MdiClose: typeof import('~icons/mdi/close')['default']
@ -147,7 +128,6 @@ declare module '@vue/runtime-core' {
MdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
MdiContentSave: typeof import('~icons/mdi/content-save')['default']
MdiCurrencyUsd: typeof import('~icons/mdi/currency-usd')['default']
MdiDatabase: typeof import('~icons/mdi/database')['default']
MdiDatabaseOutline: typeof import('~icons/mdi/database-outline')['default']
MdiDelete: typeof import('~icons/mdi/delete')['default']
MdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
@ -171,28 +151,20 @@ declare module '@vue/runtime-core' {
MdiFileUploadOutline: typeof import('~icons/mdi/file-upload-outline')['default']
MdiFilterOutline: typeof import('~icons/mdi/filter-outline')['default']
MdiFlag: typeof import('~icons/mdi/flag')['default']
MdiFlashOutline: typeof import('~icons/mdi/flash-outline')['default']
MdiFolder: typeof import('~icons/mdi/folder')['default']
MdiFullscreen: typeof import('~icons/mdi/fullscreen')['default']
MdiFullscreenExit: typeof import('~icons/mdi/fullscreen-exit')['default']
MdiFunction: typeof import('~icons/mdi/function')['default']
MdiGestureDoubleTap: typeof import('~icons/mdi/gesture-double-tap')['default']
MdiGithub: typeof import('~icons/mdi/github')['default']
MdiGmail: typeof import('~icons/mdi/gmail')['default']
MdiGridLarge: typeof import('~icons/mdi/grid-large')['default']
MdiHeart: typeof import('~icons/mdi/heart')['default']
MdiHook: typeof import('~icons/mdi/hook')['default']
MdiInformation: typeof import('~icons/mdi/information')['default']
MdiJson: typeof import('~icons/mdi/json')['default']
MdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
MdiKeyChange: typeof import('~icons/mdi/key-change')['default']
MdiKeyPlus: typeof import('~icons/mdi/key-plus')['default']
MdiKeyStar: typeof import('~icons/mdi/key-star')['default']
MdiLink: typeof import('~icons/mdi/link')['default']
MdiLinkVariant: typeof import('~icons/mdi/link-variant')['default']
MdiLinkVariantRemove: typeof import('~icons/mdi/link-variant-remove')['default']
MdiLoading: typeof import('~icons/mdi/loading')['default']
MdiLockOutlineIcon: typeof import('~icons/mdi/lock-outline-icon')['default']
MdiLogin: typeof import('~icons/mdi/login')['default']
MdiLogout: typeof import('~icons/mdi/logout')['default']
MdiMagnify: typeof import('~icons/mdi/magnify')['default']
@ -201,32 +173,23 @@ declare module '@vue/runtime-core' {
MdiMicrosoftTeams: typeof import('~icons/mdi/microsoft-teams')['default']
MdiMinusCircleOutline: typeof import('~icons/mdi/minus-circle-outline')['default']
MdiMoonFull: typeof import('~icons/mdi/moon-full')['default']
MdiNotebookCheckOutline: typeof import('~icons/mdi/notebook-check-outline')['default']
MdiNull: typeof import('~icons/mdi/null')['default']
MdiNumeric: typeof import('~icons/mdi/numeric')['default']
MdiOpenInNew: typeof import('~icons/mdi/open-in-new')['default']
MdiPencil: typeof import('~icons/mdi/pencil')['default']
MdiPlus: typeof import('~icons/mdi/plus')['default']
MdiPlusBoxOutline: typeof import('~icons/mdi/plus-box-outline')['default']
MdiPlusCircleOutline: typeof import('~icons/mdi/plus-circle-outline')['default']
MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default']
MdiPlusRoundedOutline: typeof import('~icons/mdi/plus-rounded-outline')['default']
MdiRefresh: typeof import('~icons/mdi/refresh')['default']
MdiReload: typeof import('~icons/mdi/reload')['default']
MdiRocketLaunchOutline: typeof import('~icons/mdi/rocket-launch-outline')['default']
MdiScriptTextKeyOutline: typeof import('~icons/mdi/script-text-key-outline')['default']
MdiScriptTextOutline: typeof import('~icons/mdi/script-text-outline')['default']
MdiSearch: typeof import('~icons/mdi/search')['default']
MdiShieldLockOutline: typeof import('~icons/mdi/shield-lock-outline')['default']
MdiSlack: typeof import('~icons/mdi/slack')['default']
MdiSort: typeof import('~icons/mdi/sort')['default']
MdiStar: typeof import('~icons/mdi/star')['default']
MdiStarOutline: typeof import('~icons/mdi/star-outline')['default']
MdiStore: typeof import('~icons/mdi/store')['default']
MdiTable: typeof import('~icons/mdi/table')['default']
MdiTableArrowRight: typeof import('~icons/mdi/table-arrow-right')['default']
MdiTableBorder: typeof import('~icons/mdi/table-border')['default']
MdiTableLarge: typeof import('~icons/mdi/table-large')['default']
MdiText: typeof import('~icons/mdi/text')['default']
MdiThumbUp: typeof import('~icons/mdi/thumb-up')['default']
MdiTrashCan: typeof import('~icons/mdi/trash-can')['default']
@ -241,6 +204,5 @@ declare module '@vue/runtime-core' {
PhFileCsv: typeof import('~icons/ph/file-csv')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SystemUiconsExpandWidth: typeof import('~icons/system-uicons/expand-width')['default']
}
}

8
packages/nc-gui/components/api-client/Headers.vue

@ -87,7 +87,13 @@ const deleteHeaderRow = (idx: number) => vModel.value.splice(idx, 1)
</td>
<td class="px-2 w-min-[400px]">
<a-form-item>
<a-select v-model:value="headerRow.name" size="large" placeholder="Key" class="nc-input-hook-header-key">
<a-select
v-model:value="headerRow.name"
size="large"
placeholder="Key"
class="nc-input-hook-header-key"
dropdown-class-name="nc-dropdown-webhook-header"
>
<a-select-option v-for="(header, i) in headerList" :key="i" :value="header">
{{ header }}
</a-select-option>

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

@ -134,6 +134,7 @@ watch(isOpen, (n, _o) => {
:show-search="false"
:open="isOpen"
:disabled="readOnly"
dropdown-class-name="nc-dropdown-multi-select-cell"
@keydown="handleKeys"
@click="isOpen = !isOpen"
>

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

@ -73,6 +73,7 @@ watch(isOpen, (n, _o) => {
:open="isOpen"
:disabled="readOnly"
:show-arrow="!readOnly && (active || vModel === null)"
dropdown-class-name="nc-dropdown-single-select-cell"
@select="isOpen = false"
@keydown="handleKeys"
@click="isOpen = !isOpen"

2
packages/nc-gui/components/smartsheet-column/AdvancedOptions.vue

@ -82,7 +82,7 @@ onBeforeMount(() => {
</a-form-item>
</div>
<a-form-item :label="$t('labels.databaseType')" v-bind="validateInfos.dt">
<a-select v-model:value="vModel.dt" @change="onDataTypeChange">
<a-select v-model:value="vModel.dt" dropdown-class-name="nc-dropdown-db-type" @change="onDataTypeChange">
<a-select-option v-for="type in dataTypes" :key="type" :value="type">
{{ type }}
</a-select-option>

2
packages/nc-gui/components/smartsheet-column/CheckboxOptions.vue

@ -78,7 +78,7 @@ watch(
<a-row>
<a-col :span="24">
<a-form-item label="Icon">
<a-select v-model:value="vModel.meta.iconIdx" class="w-52">
<a-select v-model:value="vModel.meta.iconIdx" class="w-52" dropdown-class-name="nc-dropdown-checkbox-icon">
<a-select-option v-for="(icon, i) of iconList" :key="i" :value="i">
<div class="flex items-center">
<component

2
packages/nc-gui/components/smartsheet-column/CurrencyOptions.vue

@ -83,6 +83,7 @@ vModel.value.meta = {
show-search
:filter-option="filterOption"
:disabled="isMoney && isPg"
dropdown-class-name="nc-dropdown-currency-cell-locale"
>
<a-select-option v-for="(currencyLocale, i) of currencyLocaleList" :key="i" :value="currencyLocale.value">
{{ currencyLocale.text }}
@ -98,6 +99,7 @@ vModel.value.meta = {
show-search
:filter-option="filterOption"
:disabled="isMoney && isPg"
dropdown-class-name="nc-dropdown-currency-cell-code"
>
<a-select-option v-for="(currencyCode, i) of currencyList" :key="i" :value="currencyCode">
{{ currencyCode }}

2
packages/nc-gui/components/smartsheet-column/DateOptions.vue

@ -17,7 +17,7 @@ if (!vModel.value.meta?.date_format) {
<template>
<a-form-item label="Date Format">
<a-select v-model:value="vModel.meta.date_format">
<a-select v-model:value="vModel.meta.date_format" dropdown-class-name="nc-dropdown-date-format">
<a-select-option v-for="(format, i) of dateFormats" :key="i" :value="format">
<div class="flex flex-row items-center">
<div class="text-xs">

2
packages/nc-gui/components/smartsheet-column/DurationOptions.vue

@ -30,7 +30,7 @@ vModel.value.meta = {
</a-col>
<a-col :span="24">
<a-form-item label="Duration Format">
<a-select v-model:value="vModel.meta.duration" class="w-52">
<a-select v-model:value="vModel.meta.duration" class="w-52" dropdown-class-name="nc-dropdown-duration-option">
<a-select-option v-for="(duration, i) of durationOptionList" :key="i" :value="duration.id">
{{ duration.title }}
</a-select-option>

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

@ -143,6 +143,7 @@ onMounted(() => {
show-search
class="nc-column-type-input"
:disabled="isKanban"
dropdown-class-name="nc-dropdown-column-type"
@change="onUidtOrIdTypeChange"
>
<a-select-option v-for="opt of uiTypesOptions" :key="opt.name" :value="opt.name" v-bind="validateInfos.uidt">

17
packages/nc-gui/components/smartsheet-column/LinkedToAnotherRecordOptions.vue

@ -66,6 +66,7 @@ const refTables = $computed(() => {
v-model:value="vModel.childId"
show-search
:filter-option="(value, option) => option.key.toLowerCase().includes(value.toLowerCase())"
dropdown-class-name="nc-dropdown-ltar-child-table"
@change="onDataTypeChange"
>
<a-select-option v-for="table in refTables" :key="table.title" :value="table.id">
@ -86,14 +87,26 @@ const refTables = $computed(() => {
<div v-if="advancedOptions" class="flex flex-col p-6 gap-4 border-2 mt-2">
<div class="flex flex-row space-x-2">
<a-form-item class="flex w-1/2" :label="$t('labels.onUpdate')">
<a-select v-model:value="vModel.onUpdate" :disabled="vModel.virtual" name="onUpdate" @change="onDataTypeChange">
<a-select
v-model:value="vModel.onUpdate"
:disabled="vModel.virtual"
name="onUpdate"
dropdown-class-name="nc-dropdown-on-update"
@change="onDataTypeChange"
>
<a-select-option v-for="(option, index) in onUpdateDeleteOptions" :key="index" :value="option">
{{ option }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item class="flex w-1/2" :label="$t('labels.onDelete')">
<a-select v-model:value="vModel.onDelete" :disabled="vModel.virtual" name="onDelete" @change="onDataTypeChange">
<a-select
v-model:value="vModel.onDelete"
:disabled="vModel.virtual"
name="onDelete"
dropdown-class-name="nc-dropdown-on-delete"
@change="onDataTypeChange"
>
<a-select-option v-for="(option, index) in onUpdateDeleteOptions" :key="index" :value="option">
{{ option }}
</a-select-option>

13
packages/nc-gui/components/smartsheet-column/LookupOptions.vue

@ -62,7 +62,11 @@ const columns = $computed(() => {
<div class="p-6 w-full flex flex-col border-2 mb-2 mt-4">
<div class="w-full flex flex-row space-x-2">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.childTable')" v-bind="validateInfos.fk_relation_column_id">
<a-select v-model:value="vModel.fk_relation_column_id" dropdown-class-name="!w-64" @change="onDataTypeChange">
<a-select
v-model:value="vModel.fk_relation_column_id"
dropdown-class-name="!w-64 nc-dropdown-relation-table"
@change="onDataTypeChange"
>
<a-select-option v-for="(table, index) in refTables" :key="index" :value="table.col.fk_column_id">
<div class="flex flex-row space-x-0.5 h-full pb-0.5 items-center justify-between">
<div class="font-semibold text-xs">{{ table.column.title }}</div>
@ -74,7 +78,12 @@ const columns = $computed(() => {
</a-select>
</a-form-item>
<a-form-item class="flex w-1/2" :label="$t('labels.childColumn')" v-bind="validateInfos.fk_lookup_column_id">
<a-select v-model:value="vModel.fk_lookup_column_id" name="fk_lookup_column_id" @change="onDataTypeChange">
<a-select
v-model:value="vModel.fk_lookup_column_id"
name="fk_lookup_column_id"
dropdown-class-name="nc-dropdown-relation-column"
@change="onDataTypeChange"
>
<a-select-option v-for="(column, index) of columns" :key="index" :value="column.id">
{{ column.title }}
</a-select-option>

2
packages/nc-gui/components/smartsheet-column/PercentOptions.vue

@ -21,7 +21,7 @@ if (!vModel.value.meta?.precision) vModel.value.meta.precision = precisions[0].i
<div class="flex flex-col mt-2 gap-2">
<div class="flex flex-row space-x-2">
<a-form-item class="flex w-1/2" label="Precision">
<a-select v-model:value="vModel.meta.precision">
<a-select v-model:value="vModel.meta.precision" dropdown-class-name="nc-dropdown-precision">
<a-select-option v-for="(precision, i) of precisions" :key="i" :value="precision.id">
<div class="flex flex-row items-center">
<div class="text-xs">

4
packages/nc-gui/components/smartsheet-column/RatingOptions.vue

@ -72,7 +72,7 @@ watch(
<a-row :gutter="8">
<a-col :span="12">
<a-form-item label="Icon">
<a-select v-model:value="vModel.meta.iconIdx" class="w-52">
<a-select v-model:value="vModel.meta.iconIdx" class="w-52" dropdown-class-name="nc-dropdown-rating-icon">
<a-select-option v-for="(icon, i) of iconList" :key="i" :value="i">
<div class="flex items-center">
<component
@ -95,7 +95,7 @@ watch(
</a-col>
<a-col :span="12">
<a-form-item label="Max">
<a-select v-model:value="vModel.meta.max" class="w-52">
<a-select v-model:value="vModel.meta.max" class="w-52" dropdown-class-name="nc-dropdown-rating-color">
<a-select-option v-for="(v, i) in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" :key="i" :value="v">
{{ v }}
</a-select-option>

19
packages/nc-gui/components/smartsheet-column/RollupOptions.vue

@ -75,7 +75,11 @@ const columns = $computed(() => {
<div class="p-6 w-full flex flex-col border-2 mb-2 mt-4">
<div class="w-full flex flex-row space-x-2">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.childTable')" v-bind="validateInfos.fk_relation_column_id">
<a-select v-model:value="vModel.fk_relation_column_id" dropdown-class-name="!w-64" @change="onDataTypeChange">
<a-select
v-model:value="vModel.fk_relation_column_id"
dropdown-class-name="!w-64 nc-dropdown-relation-table"
@change="onDataTypeChange"
>
<a-select-option v-for="(table, index) in refTables" :key="index" :value="table.col.fk_column_id">
<div class="flex flex-row space-x-0.5 h-full pb-0.5 items-center justify-between">
<div class="font-semibold text-xs">{{ table.column.title }}</div>
@ -87,7 +91,12 @@ const columns = $computed(() => {
</a-select>
</a-form-item>
<a-form-item class="flex w-1/2" :label="$t('labels.childColumn')" v-bind="validateInfos.fk_rollup_column_id">
<a-select v-model:value="vModel.fk_rollup_column_id" name="fk_rollup_column_id" @change="onDataTypeChange">
<a-select
v-model:value="vModel.fk_rollup_column_id"
name="fk_rollup_column_id"
dropdown-class-name="nc-dropdown-relation-column"
@change="onDataTypeChange"
>
<a-select-option v-for="(column, index) of columns" :key="index" :value="column.id">
{{ column.title }}
</a-select-option>
@ -95,7 +104,11 @@ const columns = $computed(() => {
</a-form-item>
</div>
<a-form-item label="Aggregate function" v-bind="validateInfos.rollup_function">
<a-select v-model:value="vModel.rollup_function" @change="onDataTypeChange">
<a-select
v-model:value="vModel.rollup_function"
dropdown-class-name="nc-dropdown-rollup-function"
@change="onDataTypeChange"
>
<a-select-option v-for="(func, index) of aggrFunctionsList" :key="index" :value="func.value">
{{ func.text }}
</a-select-option>

1
packages/nc-gui/components/smartsheet-toolbar/FieldListAutoCompleteDropdown.vue

@ -57,6 +57,7 @@ const filterOption = (input: string, option: any) => {
show-search
:placeholder="$t('placeholder.selectField')"
:filter-option="filterOption"
dropdown-class-name="nc-dropdown-toolbar-field-list"
>
<a-select-option v-for="option in options" :key="option.value" :value="option.value">
<div class="flex gap-2 items-center items-center h-full">

8
packages/nc-gui/components/smartsheet-toolbar/FieldsMenu.vue

@ -135,7 +135,13 @@ const getIcon = (c: ColumnType) =>
@click.stop
>
<a-card v-if="activeView.type === ViewTypes.GALLERY" size="small" title="Cover image">
<a-select v-model:value="coverImageColumnId" class="w-full" :options="coverOptions" @click.stop></a-select>
<a-select
v-model:value="coverImageColumnId"
class="w-full"
:options="coverOptions"
dropdown-class-name="nc-dropdown-cover-image"
@click.stop
></a-select>
</a-card>
<div class="p-1" @click.stop>
<a-input v-model:value="filterQuery" size="small" :placeholder="$t('placeholder.searchFields')" />

2
packages/nc-gui/components/smartsheet-toolbar/SearchData.vue

@ -41,7 +41,7 @@ function onPressEnter() {
size="small"
:dropdown-match-select-width="false"
:options="columns"
dropdown-class-name="!py-0 !rounded"
dropdown-class-name="!py-0 !rounded nc-dropdown-toolbar-search-field-option"
class="!absolute top-0 left-0 w-full h-full z-10 !text-xs opacity-0"
/>
</div>

2
packages/nc-gui/components/smartsheet-toolbar/SortListMenu.vue

@ -71,7 +71,7 @@ watch(
v-model:value="sort.direction"
class="shrink grow-0 nc-sort-dir-select !text-xs"
:label="$t('labels.operation')"
dropdown-class-name="sort-dir-dropdown"
dropdown-class-name="sort-dir-dropdown nc-dropdown-sort-dir"
@click.stop
@select="saveOrUpdate(sort, i)"
>

7
packages/nc-gui/components/smartsheet/ApiSnippet.vue

@ -171,7 +171,12 @@ watch($$(activeLang), (newLang) => {
hide-minimap
/>
<div v-if="activeLang.clients" class="flex flex-row w-full justify-end space-x-3 mt-4 uppercase">
<a-select v-if="activeLang" v-model:value="selectedClient" style="width: 6rem">
<a-select
v-if="activeLang"
v-model:value="selectedClient"
style="width: 6rem"
dropdown-class-name="nc-dropdown-snippet-active-lang"
>
<a-select-option v-for="(client, i) in activeLang?.clients" :key="i" class="!w-full uppercase" :value="client">
{{ client }}
</a-select-option>

12
packages/nc-gui/components/smartsheet/Form.vue

@ -243,8 +243,10 @@ async function checkSMTPStatus() {
emailMe.value = false
// Please activate SMTP plugin in App store for enabling email notification
message.info(t('msg.toast.formEmailSMTP'))
return false
}
}
return true
}
function setFormData() {
@ -263,7 +265,6 @@ function setFormData() {
} catch (e) {}
emailMe.value = data[state.user.value?.email as string]
checkSMTPStatus()
localColumns.value = col
.filter(
@ -306,12 +307,13 @@ function isRequired(_columnObj: Record<string, any>, required = false) {
return required || (columnObj && columnObj.rqd && !columnObj.cdf)
}
function updateEmail() {
async function updateEmail() {
try {
if (!(await checkSMTPStatus())) return
const data = formViewData.value?.email ? JSON.parse(formViewData.value?.email) : {}
data[state.user.value?.email as string] = emailMe.value
formViewData.value!.email = JSON.stringify(data)
checkSMTPStatus()
} catch (e) {}
}
@ -641,7 +643,7 @@ onMounted(async () => {
v-if="isVirtualCol(element)"
class="!m-0 gap-0 p-0"
:name="element.title"
:rules="[{ required: element.required, message: `${element.title} is required` }]"
:rules="[{ required: isRequired(element, element.required), message: `${element.title} is required` }]"
>
<SmartsheetVirtualCell
v-model="formState[element.title]"
@ -657,7 +659,7 @@ onMounted(async () => {
v-else
class="!m-0 gap-0 p-0"
:name="element.title"
:rules="[{ required: element.required, message: `${element.title} is required` }]"
:rules="[{ required: isRequired(element, element.required), message: `${element.title} is required` }]"
>
<SmartsheetCell
v-model="formState[element.title]"

7
packages/nc-gui/components/tabs/auth/user-management/ShareBase.vue

@ -210,7 +210,12 @@ onMounted(() => {
</template>
</a-dropdown>
<a-select v-if="base?.uuid" v-model:value="base.role" class="flex nc-shared-base-role">
<a-select
v-if="base?.uuid"
v-model:value="base.role"
class="flex nc-shared-base-role"
dropdown-class-name="nc-dropdown-share-base-role"
>
<template #suffixIcon>
<div class="flex flex-row">
<IcRoundKeyboardArrowDown class="text-black -mt-0.5 h-[1rem]" />

2
packages/nc-gui/components/tabs/auth/user-management/UsersModal.vue

@ -221,7 +221,7 @@ const clickInviteMore = () => {
<div class="flex flex-col w-1/4">
<a-form-item name="role" :rules="[{ required: true, message: 'Role required' }]">
<div class="ml-1 mb-1 text-xs text-gray-500">{{ $t('labels.selectUserRole') }}</div>
<a-select v-model:value="usersData.role" class="nc-user-roles">
<a-select v-model:value="usersData.role" class="nc-user-roles" dropdown-class-name="nc-dropdown-user-role">
<a-select-option v-for="(role, index) in projectRoles" :key="index" :value="role" class="nc-role-option">
<div class="flex flex-row h-full justify-start items-center">
<div

9
packages/nc-gui/components/template/Editor.vue

@ -579,7 +579,13 @@ function handleEditableTnChange(idx: number) {
</template>
<template v-else-if="column.key === 'destination_column'">
<a-select v-model:value="record.destCn" class="w-52" show-search :filter-option="filterOption">
<a-select
v-model:value="record.destCn"
class="w-52"
show-search
:filter-option="filterOption"
dropdown-class-name="nc-dropdown-filter-field"
>
<a-select-option v-for="(col, i) of columns" :key="i" :value="col.title">
<div class="flex items-center">
<component :is="getUIDTIcon(col.uidt)" />
@ -687,6 +693,7 @@ function handleEditableTnChange(idx: number) {
show-search
:options="uiTypeOptions"
:filter-option="filterOption"
dropdown-class-name="nc-dropdown-template-uidt"
/>
</a-form-item>
</template>

8
packages/nc-gui/components/webhook/ChannelMultiSelect.vue

@ -58,7 +58,13 @@ onMounted(() => {
</script>
<template>
<a-select v-model:value="localChannelValues" mode="multiple" :placeholder="placeholder" max-tag-count="responsive">
<a-select
v-model:value="localChannelValues"
mode="multiple"
:placeholder="placeholder"
max-tag-count="responsive"
dropdown-class-name="nc-dropdown-webhook-channel"
>
<a-select-option v-for="channel of availableChannelWithIdxList" :key="channel.idx" :value="channel.idx">
{{ channel.channel }}
</a-select-option>

9
packages/nc-gui/components/webhook/Editor.vue

@ -453,6 +453,7 @@ onMounted(async () => {
size="large"
:placeholder="$t('general.event')"
class="nc-text-field-hook-event"
dropdown-class-name="nc-dropdown-webhook-event"
>
<a-select-option v-for="(event, i) in eventList" :key="i" :value="event.value.join(' ')">
{{ event.text.join(' ') }}
@ -467,6 +468,7 @@ onMounted(async () => {
size="large"
class="nc-select-hook-notification-type"
:placeholder="$t('general.notification')"
dropdown-class-name="nc-dropdown-webhook-notification"
@change="onNotTypeChange(true)"
>
<a-select-option v-for="(notificationOption, i) in notificationList" :key="i" :value="notificationOption.type">
@ -497,7 +499,12 @@ onMounted(async () => {
<a-row v-if="hook.notification.type === 'URL'" class="mb-5" type="flex" :gutter="[16, 0]">
<a-col :span="6">
<a-select v-model:value="hook.notification.payload.method" size="large" class="nc-select-hook-url-method">
<a-select
v-model:value="hook.notification.payload.method"
size="large"
class="nc-select-hook-url-method"
dropdown-class-name="nc-dropdown-hook-notification-url-method"
>
<a-select-option v-for="(method, i) in methodList" :key="i" :value="method.title">{{ method.title }}</a-select-option>
</a-select>
</a-col>

9
packages/nc-gui/composables/useProject.ts

@ -64,6 +64,8 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
const isPg = computed(() => projectBaseType === 'pg')
const isSharedBase = computed(() => projectType === 'base')
const router = useRouter()
async function loadProjectMetaInfo(force?: boolean) {
if (!projectMetaInfo.value || force) {
projectMetaInfo.value = await api.project.metaGet(project.value.id!, {}, {})
@ -104,8 +106,15 @@ const [setup, use] = useInjectionState((_projectId?: MaybeRef<string>) => {
if (id) {
project.value = await api.project.read(projectId.value)
} else if (projectType === 'base') {
try {
const baseData = await api.public.sharedBaseGet(route.params.projectId as string)
project.value = await api.project.read(baseData.project_id!)
} catch (e: any) {
if (e?.response?.status === 404) {
return router.push('/error/404')
}
throw e
}
} else if (projectId.value) {
project.value = await api.project.read(projectId.value)
} else {

17
packages/nc-gui/pages/error/404.vue

@ -0,0 +1,17 @@
<script lang="ts" setup>
import { definePageMeta } from '#imports'
definePageMeta({
requiresAuth: false,
public: true,
})
</script>
<template>
<div class="w-full h-[300px] flex justify-center items-center text-4xl">
<div class="text-gray-400 flex gap-2 items-center">
<MdiWarning />
Page Not Found
</div>
</div>
</template>

19
packages/nc-gui/pages/index/index/create-external.vue

@ -359,7 +359,12 @@ onMounted(() => {
</a-form-item>
<a-form-item :label="$t('labels.dbType')" v-bind="validateInfos['dataSource.client']">
<a-select v-model:value="formState.dataSource.client" class="nc-extdb-db-type" @change="onClientChange">
<a-select
v-model:value="formState.dataSource.client"
class="nc-extdb-db-type"
dropdown-class-name="nc-dropdown-ext-db-type"
@change="onClientChange"
>
<a-select-option v-for="client in clientTypes" :key="client.value" :value="client.value"
>{{ client.text }}
</a-select-option>
@ -433,7 +438,7 @@ onMounted(() => {
</div>
</template>
<a-form-item label="SSL mode">
<a-select v-model:value="formState.sslUse" @select="onSSLModeChange">
<a-select v-model:value="formState.sslUse" dropdown-class-name="nc-dropdown-ssl-mode" @select="onSSLModeChange">
<a-select-option v-for="opt in Object.values(SSLUsage)" :key="opt" :value="opt">{{ opt }}</a-select-option>
</a-select>
</a-form-item>
@ -505,13 +510,19 @@ onMounted(() => {
<a-divider />
<a-form-item :label="$t('labels.inflection.tableName')">
<a-select v-model:value="formState.inflection.inflectionTable">
<a-select
v-model:value="formState.inflection.inflectionTable"
dropdown-class-name="nc-dropdown-inflection-table-name"
>
<a-select-option v-for="type in inflectionTypes" :key="type" :value="type">{{ type }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="$t('labels.inflection.columnName')">
<a-select v-model:value="formState.inflection.inflectionColumn">
<a-select
v-model:value="formState.inflection.inflectionColumn"
dropdown-class-name="nc-dropdown-inflection-column-name"
>
<a-select-option v-for="type in inflectionTypes" :key="type" :value="type">{{ type }}</a-select-option>
</a-select>
</a-form-item>

2
scripts/cypress/integration/common/1b_table_column_operations.js

@ -70,7 +70,7 @@ export const genTest = (apiType, dbType) => {
// change column type and verify
cy.get(".nc-column-type-input").last().click();
cy.getActiveSelection().find('.ant-select-item-option').contains("LongText").click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains("LongText").click();
cy.get(".ant-btn-primary:visible").contains("Save").click();
cy.toastWait("Column updated");

2
scripts/cypress/integration/common/3b_formula_column.js

@ -58,7 +58,7 @@ export const genTest = (apiType, dbType) => {
.clear()
.type(columnName);
cy.get(".nc-column-type-input").last().click().type("Formula");
cy.getActiveSelection().find('.ant-select-item-option').contains("Formula").click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains("Formula").click();
cy.get('textarea.nc-formula-input').click().type(formula, { parseSpecialCharSequences: false });
cy.get(".ant-btn-primary").contains("Save").should('exist').click();

6
scripts/cypress/integration/common/3c_lookup_column.js

@ -53,14 +53,14 @@ export const genTest = (apiType, dbType) => {
.clear()
.type(childCol);
cy.get(".nc-column-type-input").last().click().type("Lookup");
cy.getActiveSelection().find('.ant-select-item-option').contains("Lookup").click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains("Lookup").click();
// Configure Child table & column names
fetchParentFromLabel("Child table");
cy.getActiveSelection().find('.ant-select-item-option').contains(childTable).click();
cy.getActiveSelection('.nc-dropdown-relation-table').find('.ant-select-item-option').contains(childTable).click();
fetchParentFromLabel("Child column");
cy.getActiveSelection().find('.ant-select-item-option').contains(childCol).click();
cy.getActiveSelection('.nc-dropdown-relation-column').find('.ant-select-item-option').contains(childCol).click();
cy.get(".ant-btn-primary").contains("Save").should('exist').click();
cy.toastWait(`Column created`);

8
scripts/cypress/integration/common/3d_rollup_column.js

@ -59,17 +59,17 @@ export const genTest = (apiType, dbType) => {
.clear()
.type(columnName);
cy.get(".nc-column-type-input").last().click().type("RollUp");
cy.getActiveSelection().find('.ant-select-item-option').contains("Rollup").click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains("Rollup").click();
// Configure Child table & column names
fetchParentFromLabel("Child table");
cy.getActiveSelection().find('.ant-select-item-option').contains(childTable).click();
cy.getActiveSelection('.nc-dropdown-relation-table').find('.ant-select-item-option').contains(childTable).click();
fetchParentFromLabel("Child column");
cy.getActiveSelection().find('.ant-select-item-option').contains(childCol).click();
cy.getActiveSelection('.nc-dropdown-relation-column').find('.ant-select-item-option').contains(childCol).click();
fetchParentFromLabel("Aggregate function");
cy.getActiveSelection().find('.ant-select-item-option').contains(aggregateFunc).click();
cy.getActiveSelection('.nc-dropdown-rollup-function').find('.ant-select-item-option').contains(aggregateFunc).click();
cy.get(".ant-btn-primary").contains("Save").should('exist').click();
cy.toastWait(`Column created`);

6
scripts/cypress/integration/common/3e_duration_column.js

@ -49,11 +49,11 @@ export const genTest = (apiType, dbType) => {
.clear()
.type(columnName);
cy.get(".nc-column-type-input").last().click().type("Duration");
cy.getActiveSelection().find('.ant-select-item-option').contains("Duration").click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains("Duration").click();
// Configure Duration format
fetchParentFromLabel("Duration Format");
cy.getActiveSelection().find('.ant-select-item-option').contains(durationFormat).click();
cy.getActiveSelection('.nc-dropdown-duration-option').find('.ant-select-item-option').contains(durationFormat).click();
cy.get(".ant-btn-primary").contains("Save").should('exist').click();
cy.toastWait(`Column created`);
@ -85,7 +85,7 @@ export const genTest = (apiType, dbType) => {
.type(newName);
// Configure Duration format
fetchParentFromLabel("Duration Format");
cy.getActiveSelection().find('.ant-select-item-option').contains(newDurationFormat).click();
cy.getActiveSelection('.nc-dropdown-duration-option').find('.ant-select-item-option').contains(newDurationFormat).click();
cy.get(".ant-btn-primary:visible").contains("Save").click();

4
scripts/cypress/integration/common/3f_link_to_another_record.js

@ -40,7 +40,7 @@ export const genTest = (apiType, dbType) => {
cy.get(".nc-column-type-input").last()
.click()
.type("Link");
cy.getActiveSelection()
cy.getActiveSelection('.nc-dropdown-column-type')
.find('.ant-select-item-option')
.contains("LinkToAnotherRecord").click();
@ -56,7 +56,7 @@ export const genTest = (apiType, dbType) => {
.last()
.click()
.type(foreignTable);
cy.getActiveSelection()
cy.getActiveSelection('.nc-dropdown-ltar-child-table')
.find('.ant-select-item-option')
.contains(foreignTable)
.click();

4
scripts/cypress/integration/common/6g_base_share.js

@ -85,7 +85,7 @@ export const genTest = (apiType, dbType) => {
cy.getActiveModal().find(".nc-shared-base-role").click();
cy.getActiveSelection()
cy.getActiveSelection('.nc-dropdown-share-base-role')
.find('.ant-select-item')
.eq(1)
.click();
@ -134,7 +134,7 @@ style="background: transparent; "></iframe>
cy.getActiveModal().find(".nc-shared-base-role").click();
cy.getActiveSelection()
cy.getActiveSelection('.nc-dropdown-share-base-role')
.find('.ant-select-item')
.eq(0)
.click();

4
scripts/cypress/integration/common/8a_webhook.js

@ -36,7 +36,7 @@ function createWebhook(hook, test) {
.type('{downarrow}')
.type('{downarrow}')
cy.getActiveSelection().find('.ant-select-item-option-content').contains('Content-Type').should('exist').click();
cy.getActiveSelection('.nc-dropdown-webhook-header').find('.ant-select-item-option-content').contains('Content-Type').should('exist').click();
cy.get("input.nc-input-hook-header-value")
.should("exist")
@ -78,7 +78,7 @@ function configureWebhook(hook, test) {
if (hook?.event) {
cy.get(".nc-text-field-hook-event").should("exist").click();
cy.getActiveSelection()
cy.getActiveSelection('.nc-dropdown-webhook-event')
.find(`.ant-select-item`)
.contains(hook.event)
.should("exist")

4
scripts/cypress/support/page_objects/mainPage.js

@ -119,7 +119,7 @@ export class _mainPage {
// opt-in requested role & submit
// cy.getActiveSelection().contains(roleType).click({force: true});
cy.getActiveSelection().find('.nc-role-option').eq(roleIndex).should('exist').click()
cy.getActiveSelection('.nc-dropdown-user-role').find('.nc-role-option').eq(roleIndex).should('exist').click()
cy.getActiveModal(".nc-modal-invite-user-and-share-base").find("button.ant-btn-primary").click();
cy.toastWait("Successfully updated the user details");
@ -204,7 +204,7 @@ export class _mainPage {
// change column type and verify
cy.get(".nc-column-type-input").last().click();
cy.getActiveSelection().find('.ant-select-item-option').contains(colType).click();
cy.getActiveSelection('.nc-dropdown-column-type').find('.ant-select-item-option').contains(colType).click();
cy.get(".ant-btn-primary:visible").contains("Save").click();
cy.toastWait(`Column created`);

2
scripts/cypress/support/page_objects/navigation.js

@ -187,7 +187,7 @@ export class _projectsPage {
if (cred.databaseType === 1) {
cy.get('.nc-extdb-db-type').should('exist').click();
cy.getActiveSelection().find('.ant-select-item-option').contains("PostgreSQL").click();
cy.getActiveSelection('.nc-dropdown-ext-db-type').find('.ant-select-item-option').contains("PostgreSQL").click();
}
if (cred.databaseName !== "") {

Loading…
Cancel
Save