Browse Source

Merge branch 'develop' into fix/add-missing-isUIAllowed

pull/3087/head
Wing-Kam Wong 2 years ago
parent
commit
0934135363
  1. 10
      packages/nc-gui-v2/components/cell/MultiSelect.vue
  2. 5
      packages/nc-gui-v2/components/cell/SingleSelect.vue
  3. 7
      packages/nc-gui-v2/components/smartsheet-header/Menu.vue
  4. 2
      packages/nc-gui-v2/components/smartsheet/expanded-form/Header.vue
  5. 4
      packages/nc-gui-v2/components/tabs/Auth.vue
  6. 2
      packages/nc-gui-v2/layouts/base.vue
  7. 18
      packages/nc-gui-v2/pages/nc/[projectId]/index.vue
  8. 67
      packages/nocodb/src/lib/meta/api/columnApis.ts

10
packages/nc-gui-v2/components/cell/MultiSelect.vue

@ -5,7 +5,7 @@ import { ActiveCellInj, ColumnInj, ReadonlyInj, computed, inject } from '#import
import MdiCloseCircle from '~icons/mdi/close-circle'
interface Props {
modelValue: string | string[] | undefined
modelValue?: string | string[]
}
const { modelValue } = defineProps<Props>()
@ -42,7 +42,7 @@ const options = computed(() => {
})
const vModel = computed({
get: () => selectedIds.value.map((el) => options.value.find((op: SelectOptionType) => op.id === el).title),
get: () => selectedIds.value.map((el) => options.value.find((op: SelectOptionType) => op.id === el)?.title),
set: (val) => emit('update:modelValue', val.length === 0 ? null : val.join(',')),
})
@ -135,7 +135,7 @@ watch(isOpen, (n, _o) => {
:close-icon="h(MdiCloseCircle, { class: ['ms-close-icon'] })"
@close="onClose"
>
<span class="text-slate-500">{{ val }}</span>
<span class="w-full text-slate-500">{{ val }}</span>
</a-tag>
</template>
</a-select>
@ -174,6 +174,10 @@ watch(isOpen, (n, _o) => {
:deep(.ant-tag-close-icon) {
@apply "text-slate-500";
}
:deep(.ant-select-selection-overflow-item) {
@apply "flex overflow-hidden";
}
</style>
<!--
/**

5
packages/nc-gui-v2/components/cell/SingleSelect.vue

@ -4,7 +4,7 @@ import type { SelectOptionType } from 'nocodb-sdk'
import { ActiveCellInj, ColumnInj, ReadonlyInj, computed, inject } from '#imports'
interface Props {
modelValue: string | undefined
modelValue?: string
}
const { modelValue } = defineProps<Props>()
@ -76,11 +76,12 @@ watch(isOpen, (n, _o) => {
:bordered="false"
:open="isOpen"
:disabled="!editEnabled"
:show-arrow="active || vModel === null"
@select="isOpen = false"
@keydown="handleKeys"
@click="isOpen = !isOpen"
>
<a-select-option v-for="op of options" :key="op.title" @click.stop>
<a-select-option v-for="op of options" :key="op.title" :value="op.title" @click.stop>
<a-tag class="rounded-tag" :color="op.color">
<span class="text-slate-500">{{ op.title }}</span>
</a-tag>

7
packages/nc-gui-v2/components/smartsheet-header/Menu.vue

@ -18,7 +18,7 @@ const column = inject(ColumnInj)
const meta = inject(MetaInj)
const { $api } = useNuxtApp()
const { $api, $e } = useNuxtApp()
const { t } = useI18n()
@ -45,6 +45,7 @@ const setAsPrimaryValue = async () => {
await $api.dbTableColumn.primaryColumnSet(column?.value?.id as string)
getMeta(meta?.value?.id as string, true)
message.success('Successfully updated as primary column')
$e('a:column:set-primary')
} catch (e) {
message.error('Failed to update primary column')
}
@ -63,8 +64,8 @@ const setAsPrimaryValue = async () => {
{{ $t('general.edit') }}
</div>
</a-menu-item>
<a-menu-item v-if="!virtual" v-t="['a:column:set-primary']" @click="setAsPrimaryValue">
<div class="nc-column-edit nc-header-menu-item">
<a-menu-item v-if="!virtual" @click="setAsPrimaryValue">
<div class="nc-column-set-primary nc-header-menu-item">
<MdiStarIcon class="text-primary" />
<!-- todo : tooltip -->

2
packages/nc-gui-v2/components/smartsheet/expanded-form/Header.vue

@ -54,7 +54,7 @@ const iconColor = '#1890ff'
v-if="isUIAllowed('rowComments')"
class="cursor-pointer select-none"
@click="commentsDrawer = !commentsDrawer"
/>
/>>
<a-button class="!text" @click="emit('cancel')">
<!-- Cancel -->
{{ $t('general.cancel') }}

4
packages/nc-gui-v2/components/tabs/Auth.vue

@ -27,13 +27,13 @@ const selectedTab = $computed(() => tabsInfo[selectedTabKey])
<template>
<div>
<a-tabs v-model:active-key="selectedTabKey" :open-keys="[]" mode="horizontal" class="nc-auth-tabs mx-6">
<a-tabs-tab-pane v-for="(tab, key) of tabsInfo" :key="key" class="select-none">
<a-tab-pane v-for="(tab, key) of tabsInfo" :key="key" class="select-none">
<template #tab>
<span>
{{ tab.title }}
</span>
</template>
</a-tabs-tab-pane>
</a-tab-pane>
</a-tabs>
<div class="mx-4 py-6 mt-2">

2
packages/nc-gui-v2/layouts/base.vue

@ -25,7 +25,7 @@ const logout = () => {
v-if="
route.name === 'index' || route.name === 'project-index-create' || route.name === 'project-index-create-external'
"
class="transition-all duration-200 p-2 cursor-pointer transform hover:scale-105"
class="transition-all duration-200 p-2 cursor-pointer transform hover:scale-105 nc-noco-brand-icon"
@click="navigateTo('/')"
>
<img width="35" alt="NocoDB" src="~/assets/img/icons/512x512-trans.png" />

18
packages/nc-gui-v2/pages/nc/[projectId]/index.vue

@ -65,11 +65,11 @@ await loadTables()
<img alt="NocoDB" src="~/assets/img/icons/512x512-trans.png" />
</div>
<a-dropdown v-model:visible="dropdownOpen" :trigger="['click']" placement="bottom">
<a-dropdown :trigger="['click']" placement="bottom">
<div
:style="{ width: isOpen ? 'calc(100% - 40px) pr-2' : '100%' }"
:class="[isOpen ? '' : 'justify-center']"
class="group cursor-pointer flex gap-4 items-center"
class="group cursor-pointer flex gap-4 items-center nc-project-menu"
>
<template v-if="isOpen">
<div class="text-xl font-semibold truncate">{{ project.title }}</div>
@ -102,7 +102,7 @@ await loadTables()
<a-menu-item key="copy">
<div class="nc-project-menu-item group">
<MdiContentCopy class="group-hover:text-pink-500" />
<MdiContentCopy class="group-hover:text-pink-500 nc-copy-project-info" />
Copy Project Info
</div>
</a-menu-item>
@ -114,7 +114,7 @@ await loadTables()
class="nc-project-menu-item group"
@click.stop="openLink(`/api/v1/db/meta/projects/${route.params.projectId}/swagger`)"
>
<MdiApi class="group-hover:text-pink-500" />
<MdiApi class="group-hover:text-pink-500 nc-swagger-api-docs" />
Swagger: Rest APIs
</div>
</a-menu-item>
@ -128,7 +128,7 @@ await loadTables()
class="nc-project-menu-item group"
@click="toggleDialog(true, 'teamAndAuth')"
>
<MdiAccountGroup class="group-hover:text-pink-500" />
<MdiAccountGroup class="group-hover:text-pink-500 nc-team-and-auth" />
Team & Auth
</div>
</a-menu-item>
@ -140,7 +140,7 @@ await loadTables()
class="nc-project-menu-item group"
@click="toggleDialog(true, 'appStore')"
>
<MdiStore class="group-hover:text-pink-500" />
<MdiStore class="group-hover:text-pink-500 nc-app-store" />
App Store
</div>
</a-menu-item>
@ -152,7 +152,7 @@ await loadTables()
class="nc-project-menu-item group"
@click="toggleDialog(true, 'metaData')"
>
<MdiTableBorder class="group-hover:text-pink-500" />
<MdiTableBorder class="group-hover:text-pink-500 nc-meta-data" />
Project Metadata
</div>
</a-menu-item>
@ -164,7 +164,7 @@ await loadTables()
class="nc-project-menu-item group"
@click="toggleDialog(true, 'audit')"
>
<MdiNotebookCheckOutline class="group-hover:text-pink-500" />
<MdiNotebookCheckOutline class="group-hover:text-pink-500 nc-audit" />
Audit
</div>
</a-menu-item>
@ -174,7 +174,7 @@ await loadTables()
<a-sub-menu v-if="isUIAllowed('previewAs')" key="preview-as" v-t="['c:navdraw:preview-as']">
<template #title>
<div class="nc-project-menu-item group">
<MdiContentCopy class="group-hover:text-pink-500" />
<MdiContentCopy class="group-hover:text-pink-500 nc-project-preview" />
Preview Project As
<div class="flex-1" />

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

@ -748,13 +748,13 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
// MultiSelect to SingleSelect
if (column.uidt === UITypes.MultiSelect && colBody.uidt === UITypes.SingleSelect) {
if (driverType === 'mysql' || driverType === 'mysql2') {
await dbDriver.raw(`UPDATE ?? SET ?? = SUBSTRING_INDEX(??, ',', 1) WHERE ?? LIKE '%,%';`, [table.table_name, column.title, column.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = SUBSTRING_INDEX(??, ',', 1) WHERE ?? LIKE '%,%';`, [table.table_name, column.column_name, column.column_name, column.column_name]);
} else if (driverType === 'pg') {
await dbDriver.raw(`UPDATE ?? SET ?? = split_part(??, ',', 1);`, [table.table_name, column.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = split_part(??, ',', 1);`, [table.table_name, column.column_name, column.column_name]);
} else if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = LEFT(cast(?? as varchar(max)), CHARINDEX(',', ??) - 1) WHERE CHARINDEX(',', ??) > 0;`, [table.table_name, column.title, column.title, column.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = LEFT(cast(?? as varchar(max)), CHARINDEX(',', ??) - 1) WHERE CHARINDEX(',', ??) > 0;`, [table.table_name, column.column_name, column.column_name, column.column_name, column.column_name]);
} else if (driverType === 'sqlite3') {
await dbDriver.raw(`UPDATE ?? SET ?? = substr(??, 1, instr(??, ',') - 1) WHERE ?? LIKE '%,%';`, [table.table_name, column.title, column.title, column.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = substr(??, 1, instr(??, ',') - 1) WHERE ?? LIKE '%,%';`, [table.table_name, column.column_name, column.column_name, column.column_name, column.column_name]);
}
}
@ -764,16 +764,21 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
}
// Handle default values
const optionTitles = colBody.colOptions.options.map(el => el.title);
if (colBody.cdf) {
if (driverType === 'mysql' || driverType === 'mysql2') {
} else if (driverType === 'pg') {
} else if (driverType === 'mssql') {
} else if (driverType === 'sqlite3') {
if (colBody.uidt === UITypes.SingleSelect) {
if (!optionTitles.includes(colBody.cdf)) {
NcError.badRequest(`Default value '${colBody.cdf}' is not a select option.`);
}
} else {
for (const cdf of colBody.cdf.split(',')) {
if (!optionTitles.includes(cdf)) {
NcError.badRequest(`Default value '${cdf}' is not a select option.`);
}
}
}
if (driverType === 'pg') {
colBody.cdf = `'${colBody.cdf}'`;
}
}
@ -811,19 +816,19 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
}
if (column.uidt === UITypes.SingleSelect) {
if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = NULL WHERE ?? LIKE ?`, [table.table_name, column.title, column.title, option.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = NULL WHERE ?? LIKE ?`, [table.table_name, column.column_name, column.column_name, option.title]);
} else {
await baseModel.bulkUpdateAll({ where: `(${column.title},eq,${option.title})` }, { [column.title]: null });
await baseModel.bulkUpdateAll({ where: `(${column.column_name},eq,${option.title})` }, { [column.column_name]: null });
}
} else if (column.uidt === UITypes.MultiSelect) {
if (driverType === 'mysql' || driverType === 'mysql2') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), ',')) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.title, column.title, option.title, option.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), ',')) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.column_name, column.column_name, option.title, option.title, column.column_name]);
} else if (driverType === 'pg') {
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_remove(string_to_array(??, ','), ?), ',')`, [table.table_name, column.title, column.title, option.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_remove(string_to_array(??, ','), ?), ',')`, [table.table_name, column.column_name, column.column_name, option.title]);
} else if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), ','), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), ',')) - 2)`, [table.table_name, column.title, column.title, option.title, column.title, option.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), ','), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), ',')) - 2)`, [table.table_name, column.column_name, column.column_name, option.title, column.column_name, option.title]);
} else if (driverType === 'sqlite3') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ','), ',')`, [table.table_name, column.title, column.title, option.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ','), ',')`, [table.table_name, column.column_name, column.column_name, option.title]);
}
}
}
@ -909,19 +914,19 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
if (column.uidt === UITypes.SingleSelect) {
if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = ? WHERE ?? LIKE ?`, [table.table_name, column.title, newOp.title, column.title, option.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = ? WHERE ?? LIKE ?`, [table.table_name, column.column_name, newOp.title, column.column_name, option.title]);
} else {
await baseModel.bulkUpdateAll({ where: `(${column.title},eq,${option.title})` }, { [column.title]: newOp.title });
await baseModel.bulkUpdateAll({ where: `(${column.column_name},eq,${option.title})` }, { [column.column_name]: newOp.title });
}
} else if (column.uidt === UITypes.MultiSelect) {
if (driverType === 'mysql' || driverType === 'mysql2') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.title, column.title, option.title, newOp.title, option.title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.column_name, column.column_name, option.title, newOp.title, option.title, column.column_name]);
} else if (driverType === 'pg') {
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, [table.table_name, column.title, column.title, option.title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, [table.table_name, column.column_name, column.column_name, option.title, newOp.title]);
} else if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ',')), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ','))) - 2)`, [table.table_name, column.title, column.title, option.title, newOp.title, column.title, option.title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ',')), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ','))) - 2)`, [table.table_name, column.column_name, column.column_name, option.title, newOp.title, column.column_name, option.title, newOp.title]);
} else if (driverType === 'sqlite3') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ',' || ? || ','), ',')`, [table.table_name, column.title, column.title, option.title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ',' || ? || ','), ',')`, [table.table_name, column.column_name, column.column_name, option.title, newOp.title]);
}
}
}
@ -930,19 +935,19 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
let newOp = ch.def_option;
if (column.uidt === UITypes.SingleSelect) {
if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = ? WHERE ?? LIKE ?`, [table.table_name, column.title, newOp.title, column.title, ch.temp_title]);
await dbDriver.raw(`UPDATE ?? SET ?? = ? WHERE ?? LIKE ?`, [table.table_name, column.column_name, newOp.title, column.column_name, ch.temp_title]);
} else {
await baseModel.bulkUpdateAll({ where: `(${column.title},eq,${ch.temp_title})` }, { [column.title]: newOp.title });
await baseModel.bulkUpdateAll({ where: `(${column.column_name},eq,${ch.temp_title})` }, { [column.column_name]: newOp.title });
}
} else if (column.uidt === UITypes.MultiSelect) {
if (driverType === 'mysql' || driverType === 'mysql2') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.title, column.title, ch.temp_title, newOp.title, ch.temp_title, column.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, [table.table_name, column.column_name, column.column_name, ch.temp_title, newOp.title, ch.temp_title, column.column_name]);
} else if (driverType === 'pg') {
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, [table.table_name, column.title, column.title, ch.temp_title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, [table.table_name, column.column_name, column.column_name, ch.temp_title, newOp.title]);
} else if (driverType === 'mssql') {
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ',')), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ','))) - 2)`, [table.table_name, column.title, column.title, ch.temp_title, newOp.title, column.title, ch.temp_title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = substring(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ',')), 2, len(replace(concat(',', ??, ','), concat(',', ?, ','), concat(',', ?, ','))) - 2)`, [table.table_name, column.column_name, column.column_name, ch.temp_title, newOp.title, column.column_name, ch.temp_title, newOp.title]);
} else if (driverType === 'sqlite3') {
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ',' || ? || ','), ',')`, [table.table_name, column.title, column.title, ch.temp_title, newOp.title]);
await dbDriver.raw(`UPDATE ?? SET ?? = TRIM(REPLACE(',' || ?? || ',', ',' || ? || ',', ',' || ? || ','), ',')`, [table.table_name, column.column_name, column.column_name, ch.temp_title, newOp.title]);
}
}
}

Loading…
Cancel
Save