Browse Source

Merge pull request #4445 from nocodb/misc

UI improvements and corrections
pull/4405/head
Pranav C 2 years ago committed by GitHub
parent
commit
96ebbd99fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      packages/nc-gui/assets/style.scss
  2. 1
      packages/nc-gui/components.d.ts
  3. 4
      packages/nc-gui/components/cell/Text.vue
  4. 8
      packages/nc-gui/components/dlg/TableCreate.vue
  5. 2
      packages/nc-gui/components/dlg/ViewCreate.vue
  6. 13
      packages/nc-gui/components/smartsheet/Grid.vue
  7. 7
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  8. 4
      packages/nc-gui/components/smartsheet/column/SelectOptions.vue
  9. 10
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  10. 108
      packages/nc-gui/components/smartsheet/toolbar/ShareView.vue
  11. 6
      packages/nc-gui/components/tabs/auth/user-management/UsersModal.vue
  12. 2
      packages/nc-gui/components/virtual-cell/Lookup.vue
  13. 1
      packages/nc-gui/composables/useMultiSelect/index.ts
  14. 4
      packages/nc-gui/pages/[projectType]/form/[viewId]/index/survey.vue
  15. 6
      packages/nc-gui/pages/index/index/index.vue
  16. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  17. 2
      packages/nocodb/src/lib/models/Model.ts
  18. 2
      tests/playwright/pages/Dashboard/common/Toolbar/AddEditKanbanStack.ts

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

@ -214,17 +214,13 @@ a {
@apply z-1 relative color-transition rounded-md px-4 py-2 text-white;
&::after {
@apply ring-opacity-100 ring-[2px] ring-slate-300 rounded absolute top-0 left-0 right-0 bottom-0 transition-all duration-150 ease-in-out bg-primary bg-opacity-100;
@apply rounded absolute top-0 left-0 right-0 bottom-0 transition-all duration-150 ease-in-out bg-primary bg-opacity-100;
content: '';
z-index: -1;
}
&:hover::after {
@apply transform scale-110 ring ring-accent;
}
&:active::after {
@apply ring ring-accent;
@apply transform scale-110;
}
}
@ -261,7 +257,7 @@ a {
}
.ant-dropdown-menu-item, .ant-menu-item {
@apply !py-0 active:(ring ring-accent ring-opacity-100);
@apply !py-0;
}
.ant-dropdown-menu-title-content,

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

@ -200,6 +200,7 @@ declare module '@vue/runtime-core' {
MdiPlus: typeof import('~icons/mdi/plus')['default']
MdiPlusCircleOutline: typeof import('~icons/mdi/plus-circle-outline')['default']
MdiPlusOutline: typeof import('~icons/mdi/plus-outline')['default']
MdiPlusThick: typeof import('~icons/mdi/plus-thick')['default']
MdiReddit: typeof import('~icons/mdi/reddit')['default']
MdiRefresh: typeof import('~icons/mdi/refresh')['default']
MdiReload: typeof import('~icons/mdi/reload')['default']

4
packages/nc-gui/components/cell/Text.vue

@ -16,7 +16,9 @@ const readonly = inject(ReadonlyInj, ref(false))
const vModel = useVModel(props, 'modelValue', emits)
const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
const focus: VNodeRef = (el) => {
;(el as HTMLInputElement)?.focus()
}
</script>
<template>

8
packages/nc-gui/components/dlg/TableCreate.vue

@ -1,5 +1,5 @@
<script setup lang="ts">
import { Form, computed, onMounted, ref, useProject, useTable, useTabs, useVModel, validateTableName } from '#imports'
import { Form, computed, nextTick, onMounted, ref, useProject, useTable, useTabs, useVModel, validateTableName } from '#imports'
import { TabType } from '~/lib'
const props = defineProps<{
@ -89,8 +89,10 @@ const _createTable = async () => {
onMounted(() => {
generateUniqueTitle()
inputEl.value?.focus()
nextTick(() => {
inputEl.value?.focus()
inputEl.value?.select()
})
})
</script>

2
packages/nc-gui/components/dlg/ViewCreate.vue

@ -184,7 +184,7 @@ async function onSubmit() {
<template>
<a-modal v-model:visible="vModel" class="!top-[35%]" :confirm-loading="loading" wrap-class-name="nc-modal-view-create">
<template #title>
{{ $t(`general.${selectedViewId ? 'duplicate' : 'create'}`) }} <span class="text-capitalize">{{ typeAlias }}</span>
{{ $t(`general.${selectedViewId ? 'duplicate' : 'create'}`) }} <span class="capitalize">{{ typeAlias }}</span>
{{ $t('objects.view') }}
</template>

13
packages/nc-gui/components/smartsheet/Grid.vue

@ -850,8 +850,7 @@ watch(
text-overflow: ellipsis;
}
td.active::after,
td.active::before {
td.active::after {
content: '';
position: absolute;
z-index: 3;
@ -864,12 +863,14 @@ watch(
// todo: replace with css variable
td.active::after {
@apply border-2 border-solid border-primary;
@apply border-2 border-solid text-primary border-current bg-primary bg-opacity-5;
}
td.active::before {
@apply bg-primary bg-opacity-5;
}
//td.active::before {
// content: '';
// z-index:4;
// @apply absolute !w-[10px] !h-[10px] !right-[-5px] !bottom-[-5px] bg-primary;
//}
}
:deep {

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

@ -1,4 +1,5 @@
<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
import { UITypes, isVirtualCol } from 'nocodb-sdk'
import {
IsFormInj,
@ -116,6 +117,12 @@ onMounted(() => {
formState.value.column_name = formState.value?.title
}
})
useEventListener('keydown', (e: KeyboardEvent) => {
if (e.key === 'Escape') {
emit('cancel')
}
})
</script>
<template>

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

@ -163,12 +163,12 @@ watch(inputs, () => {
v-model:value="element.title"
class="caption"
:data-testid="`select-column-option-input-${index}`"
@keydown.enter.prevent="element.title?.trim() && addNewOption()"
@change="optionChanged(element.id)"
/>
<MdiClose
class="ml-2 hover:!text-black"
:style="{ color: 'red' }"
class="ml-2 hover:!text-black-500 text-gray-500 cursor-pointer"
:data-testid="`select-column-option-remove-${index}`"
@click="removeOption(index)"
/>

10
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -121,6 +121,12 @@ if (isKanban.value) {
}
}
}
const cellWrapperEl = (wrapperEl: HTMLElement) => {
nextTick(() => {
;(wrapperEl?.querySelector('input,select,textarea') as HTMLInputElement)?.focus()
})
}
</script>
<script lang="ts">
@ -146,7 +152,7 @@ export default {
<div class="flex-1 overflow-auto scrollbar-thin-dull nc-form-fields-container">
<div class="w-[500px] mx-auto">
<div
v-for="col of fields"
v-for="(col, i) of fields"
v-show="!isVirtualCol(col) || !isNew || col.uidt === UITypes.LinkToAnotherRecord"
:key="col.title"
class="mt-2 py-2"
@ -157,7 +163,7 @@ export default {
<LazySmartsheetHeaderCell v-else :column="col" />
<div class="!bg-white rounded px-1 min-h-[35px] flex items-center mt-2">
<div :ref="i ? null : cellWrapperEl" class="!bg-white rounded px-1 min-h-[35px] flex items-center mt-2">
<LazySmartsheetVirtualCell v-if="isVirtualCol(col)" v-model="row.row[col.title]" :row="row" :column="col" />
<LazySmartsheetCell

108
packages/nc-gui/components/smartsheet/toolbar/ShareView.vue

@ -5,12 +5,12 @@ import tinycolor from 'tinycolor2'
import {
computed,
extractSdkResponseErrorMsg,
isRtlLang,
message,
projectThemeColors,
ref,
useCopy,
useDashboard,
useDebounceFn,
useI18n,
useNuxtApp,
useProject,
@ -48,12 +48,12 @@ const withRTL = computed({
},
})
const transitionDuration = computed({
get: () => shared.value.meta.transitionDuration || 250,
set: (duration) => {
shared.value.meta = { ...shared.value.meta, transitionDuration: duration > 5000 ? 5000 : duration }
},
})
// const transitionDuration = computed({
// get: () => shared.value.meta.transitionDuration || 50,
// set: (duration) => {
// shared.value.meta = { ...shared.value.meta, transitionDuration: duration > 5000 ? 5000 : duration }
// },
// })
const allowCSVDownload = computed({
get: () => !!shared.value.meta.allowCSVDownload,
@ -131,7 +131,7 @@ async function saveTheme() {
$e(`a:view:share:${viewTheme.value ? 'enable' : 'disable'}-theme`)
}
const saveTransitionDuration = useDebounceFn(updateSharedViewMeta, 1000, { maxWait: 2000 })
// const saveTransitionDuration = useDebounceFn(updateSharedViewMeta, 1000, { maxWait: 2000 })
async function updateSharedViewMeta() {
try {
@ -192,6 +192,10 @@ watch(passwordProtected, (value) => {
saveShareLinkPassword()
}
})
const { locale } = useI18n()
const isRtl = computed(() => isRtlLang(locale.value as any))
</script>
<template>
@ -248,7 +252,7 @@ watch(passwordProtected, (value) => {
Use Survey Mode
</a-checkbox>
<Transition name="layout" mode="out-in">
<!-- <Transition name="layout" mode="out-in">
<div v-if="surveyMode" class="flex flex-col justify-center pl-6">
<a-form-item class="!my-1" :has-feedback="false" name="transitionDuration">
<template #label>
@ -264,46 +268,7 @@ watch(passwordProtected, (value) => {
/>
</a-form-item>
</div>
</Transition>
</div>
<div>
<!-- todo: i18n -->
<a-checkbox
v-if="shared.type === ViewTypes.FORM"
v-model:checked="viewTheme"
data-testid="nc-modal-share-view__with-theme"
class="!text-sm"
>
Use Theme
</a-checkbox>
<Transition name="layout" mode="out-in">
<div v-if="viewTheme" class="flex pl-6">
<LazyGeneralColorPicker
data-testid="nc-modal-share-view__theme-picker"
class="!p-0"
:model-value="shared.meta.theme?.primaryColor"
:colors="projectThemeColors"
:row-size="9"
:advanced="false"
@input="onChangeTheme"
/>
</div>
</Transition>
</div>
<div>
<!-- use RTL orientation in form - todo: i18n -->
<a-checkbox
v-if="shared.type === ViewTypes.FORM"
v-model:checked="withRTL"
data-testid="nc-modal-share-view__locale"
class="!text-sm"
>
<!-- todo i18n -->
RTL Orientation
</a-checkbox>
</Transition> -->
</div>
<div>
@ -339,20 +304,45 @@ watch(passwordProtected, (value) => {
</Transition>
</div>
<div>
<div
v-if="
shared && (shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN || shared.type === ViewTypes.GALLERY)
"
>
<!-- Allow Download -->
<a-checkbox
v-if="
shared &&
(shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN || shared.type === ViewTypes.GALLERY)
"
v-model:checked="allowCSVDownload"
data-testid="nc-modal-share-view__with-csv-download"
class="!text-sm"
>
<a-checkbox v-model:checked="allowCSVDownload" data-testid="nc-modal-share-view__with-csv-download" class="!text-sm">
{{ $t('labels.downloadAllowed') }}
</a-checkbox>
</div>
<div v-if="shared.type === ViewTypes.FORM">
<!-- todo: i18n -->
<a-checkbox v-model:checked="viewTheme" data-testid="nc-modal-share-view__with-theme" class="!text-sm">
Use Theme
</a-checkbox>
<Transition name="layout" mode="out-in">
<div v-if="viewTheme" class="flex pl-6">
<LazyGeneralColorPicker
data-testid="nc-modal-share-view__theme-picker"
class="!p-0"
:model-value="shared.meta.theme?.primaryColor"
:colors="projectThemeColors"
:row-size="9"
:advanced="false"
@input="onChangeTheme"
/>
</div>
</Transition>
</div>
<div v-if="shared.type === ViewTypes.FORM && isRtl">
<!-- use RTL orientation in form - todo: i18n -->
<a-checkbox v-model:checked="withRTL" data-testid="nc-modal-share-view__locale" class="!text-sm">
<!-- todo i18n -->
RTL Orientation
</a-checkbox>
</div>
</div>
</div>
</a-modal>

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

@ -1,4 +1,5 @@
<script setup lang="ts">
import type { Input } from 'ant-design-vue'
import {
Form,
computed,
@ -133,6 +134,10 @@ const clickInviteMore = () => {
usersData.role = ProjectRole.Viewer
usersData.emails = undefined
}
const emailField = (inputEl: typeof Input) => {
inputEl?.$el?.focus()
}
</script>
<template>
@ -222,6 +227,7 @@ const clickInviteMore = () => {
<div class="ml-1 mb-1 text-xs text-gray-500">{{ $t('datatype.Email') }}:</div>
<a-input
:ref="emailField"
v-model:value="usersData.emails"
validate-trigger="onBlur"
:placeholder="$t('labels.email')"

2
packages/nc-gui/components/virtual-cell/Lookup.vue

@ -11,8 +11,8 @@ import {
inject,
isAttachment,
provide,
refAutoReset,
ref,
refAutoReset,
useMetas,
watch,
} from '#imports'

1
packages/nc-gui/composables/useMultiSelect/index.ts

@ -41,6 +41,7 @@ export function useMultiSelect(
function selectCell(row: number, col: number) {
clearRangeRows()
if (selected.row === row && selected.col === col) return
editEnabled.value = false
selected.row = row
selected.col = col

4
packages/nc-gui/pages/[projectType]/form/[viewId]/index/survey.vue

@ -44,7 +44,7 @@ const el = ref<HTMLDivElement>()
provide(DropZoneRef, el)
const transitionDuration = computed(() => sharedViewMeta.value.transitionDuration || 250)
const transitionDuration = computed(() => sharedViewMeta.value.transitionDuration || 50)
const steps = computed(() => {
if (!formColumns.value) return []
@ -305,7 +305,7 @@ onMounted(() => {
</button>
</div>
<div v-else-if="!submitted" class="flex items-center gap-3">
<div v-else-if="!submitted" class="flex items-center gap-3 flex-col">
<a-tooltip
:title="v$.localState[field.title]?.$error ? v$.localState[field.title].$errors[0].$message : 'Go to next'"
:mouse-enter-delay="0.25"

6
packages/nc-gui/pages/index/index/index.vue

@ -316,11 +316,7 @@ const copyProjectMeta = async () => {
}
&:hover::after {
@apply transform scale-110 ring ring-accent;
}
&:active::after {
@apply ring ring-accent;
@apply transform scale-110;
}
}

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -2240,7 +2240,7 @@ class BaseModelSqlv2 {
for (let i = 0; i < this.model.columns.length; ++i) {
const column = this.model.columns[i];
// skip validation if `validate` is undefined or false
if (!column?.meta?.validate && !column?.validate) continue;
if (!column?.meta?.validate || !column?.validate) continue;
const validate = column.getValidators();
const cn = column.column_name;

2
packages/nocodb/src/lib/models/Model.ts

@ -248,7 +248,6 @@ export default class Model implements TableType {
));
if (!modelData) {
modelData = await ncMeta.metaGet2(null, null, MetaTable.MODELS, k);
await NocoCache.set(`${CacheScope.MODEL}:${modelData.id}`, modelData);
// if (
// this.baseModels?.[modelData.base_id]?.[modelData.db_alias]?.[
// modelData.title
@ -269,6 +268,7 @@ export default class Model implements TableType {
// }
}
if (modelData) {
await NocoCache.set(`${CacheScope.MODEL}:${modelData.id}`, modelData);
return new Model(modelData);
}
return null;

2
tests/playwright/pages/Dashboard/common/Toolbar/AddEditKanbanStack.ts

@ -16,7 +16,7 @@ export class ToolbarAddEditStackPage extends BasePage {
async addOption({ title }: { title: string }) {
await this.get().locator(`.ant-btn-dashed`).click();
await this.get().locator(`.nc-select-option >> input`).last().fill(title);
await this.get().locator(`.nc-select-option >> input`).last().press('Enter');
await this.get().locator(`[type="submit"]`).click();
await this.verifyToast({ message: 'Column updated' });
}
}

Loading…
Cancel
Save