Browse Source

Nc fix: misc UI fixes (#8827)

* fix(nc-gui): external source text bold issue

* fix(nc-gui): make new record btn sticky to left in groupby

* fix(nc-gui): add some padding after add column header btn

* fix(nc-gui): links cell margin issue

* fix(nc-gui): groupby table footer issue

* chore(nc-gui): lint

* fix(test): pw test fail issue

* fix(test): pw test fail issue

* fix(test): remove only from test
pull/8829/head
Ramesh Mane 2 weeks ago committed by GitHub
parent
commit
5dda4c7d37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      packages/nc-gui/components/cell/attachment/index.vue
  2. 12
      packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
  3. 6
      packages/nc-gui/components/smartsheet/Pagination.vue
  4. 7
      packages/nc-gui/components/smartsheet/column/RatingOptions.vue
  5. 4
      packages/nc-gui/components/smartsheet/grid/GroupBy.vue
  6. 25
      packages/nc-gui/components/smartsheet/grid/GroupByTable.vue
  7. 194
      packages/nc-gui/components/smartsheet/grid/Table.vue
  8. 2
      packages/nc-gui/components/virtual-cell/BelongsTo.vue
  9. 4
      packages/nc-gui/components/virtual-cell/HasMany.vue
  10. 2
      packages/nc-gui/components/virtual-cell/Links.vue
  11. 11
      packages/nc-gui/components/virtual-cell/Lookup.vue
  12. 4
      packages/nc-gui/components/virtual-cell/ManyToMany.vue
  13. 4
      packages/nc-gui/components/virtual-cell/OneToOne.vue
  14. 2
      packages/nc-gui/components/virtual-cell/components/ItemChip.vue
  15. 2
      packages/nocodb/src/models/BaseUser.ts
  16. 4
      tests/playwright/pages/Dashboard/Grid/Column/index.ts
  17. 11
      tests/playwright/tests/db/features/multiFieldEditor.spec.ts

4
packages/nc-gui/components/cell/attachment/index.vue

@ -270,7 +270,7 @@ const handleFileDelete = (i: number) => {
'py-1': rowHeight === 1 && !isForm && !isExpandedForm,
'py-1.5': rowHeight !== 1 || isForm || isExpandedForm,
}"
class="nc-attachment-wrapper flex cursor-pointer w-full items-center flex-wrap gap-2 scrollbar-thin-dull overflow-hidden mt-0 items-start"
class="nc-attachment-wrapper flex cursor-pointer w-full items-center flex-wrap gap-2 nc-scrollbar-thin mt-0 items-start px-[1px]"
:style="{
maxHeight: isForm || isExpandedForm ? undefined : `max(100%, ${isGrid ? '22px' : '32px'})`,
}"
@ -318,7 +318,7 @@ const handleFileDelete = (i: number) => {
<IcOutlineInsertDriveFile v-else :class="{ 'h-13 w-13': isForm || isExpandedForm }" />
</div>
<a-tooltip v-if="isForm || isExpandedForm">
<a-tooltip v-if="!isReadonly && (isForm || isExpandedForm)">
<template #title> {{ $t('title.removeFile') }} </template>
<component
:is="iconMap.closeCircle"

12
packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue

@ -750,10 +750,7 @@ const getSource = (sourceId: string) => {
v-if="source.id && sourceRenameHelpers[source.id]?.editMode"
ref="input"
v-model="sourceRenameHelpers[source.id].tempTitle"
class="flex-grow leading-1 outline-0 ring-none capitalize !text-inherit !bg-transparent flex-1 mr-4"
:class="
activeProjectId === base.id && baseViewOpen ? '!text-brand-600 !font-semibold' : '!text-gray-700'
"
class="flex-grow leading-1 outline-0 ring-none capitalize !text-inherit !bg-transparent flex-1 mr-4 !text-gray-700"
:data-source-rename-input-id="source.id"
@click.stop
@keydown.enter.stop.prevent
@ -763,13 +760,8 @@ const getSource = (sourceId: string) => {
/>
<NcTooltip
v-else
class="nc-sidebar-node-title capitalize text-ellipsis overflow-hidden select-none"
class="nc-sidebar-node-title capitalize text-ellipsis overflow-hidden select-none text-gray-700"
:style="{ wordBreak: 'keep-all', whiteSpace: 'nowrap', display: 'inline' }"
:class="
activeProjectId === base.id && baseViewOpen && !isMobileMode
? 'text-brand-600 font-semibold'
: 'text-gray-700'
"
show-on-truncate-only
>
<template #title> {{ source.alias || '' }}</template>

6
packages/nc-gui/components/smartsheet/Pagination.vue

@ -93,12 +93,13 @@ const tempPageVal = ref(page.value)
:class="{ 'border-t-1': !isGroupBy, 'h-13': isMobileMode, 'h-10': !isMobileMode }"
:style="`${fixedSize ? `width: ${fixedSize}px;` : ''}${
isGroupBy ? 'margin-top:1px; border-radius: 0 0 8px 8px !important;' : ''
}${extraStyle}`"
} ${extraStyle}`"
>
<div
class="flex items-center"
:class="{
'flex-1': !alignLeft,
'sticky left-0': isGroupBy,
}"
>
<slot name="add-record" />
@ -117,6 +118,9 @@ const tempPageVal = ref(page.value)
:class="{
'-ml-17': isLeftSidebarOpen && !alignLeft,
'ml-8': alignLeft,
'sticky': isGroupBy,
'left-[159px]': isGroupBy && $slots['add-record'],
'left-[32px]': isGroupBy && !$slots['add-record'],
}"
>
<div v-if="isViewDataLoading" class="nc-pagination-skeleton flex flex-row justify-center item-center min-h-10 min-w-42">

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

@ -113,7 +113,12 @@ watch(
</a-col>
<a-col :span="8">
<a-form-item :label="$t('labels.max')">
<a-select v-model:value="vModel.meta.max" data-testid="nc-dropdown-rating-max" class="w-52" dropdown-class-name="nc-dropdown-rating-color">
<a-select
v-model:value="vModel.meta.max"
data-testid="nc-dropdown-rating-max"
class="w-52"
dropdown-class-name="nc-dropdown-rating-color"
>
<template #suffixIcon>
<GeneralIcon icon="arrowDown" class="text-gray-700" />
</template>

4
packages/nc-gui/components/smartsheet/grid/GroupBy.vue

@ -306,7 +306,6 @@ const computedWidth = computed(() => {
})
const bgColor = computed(() => {
console.log(props.group.key, 'props.maxDepth', props.maxDepth, _depth)
if (props.maxDepth === 3) {
switch (_depth) {
case 2:
@ -362,9 +361,8 @@ const bgColor = computed(() => {
<a-collapse-panel
v-for="[i, grp] of Object.entries(vGroup?.children ?? [])"
:key="`group-panel-${grp.key}`"
class="!border-1 border-gray-300 nc-group rounded-[8px]"
class="!border-1 border-gray-300 nc-group rounded-[8px] mb-2"
:style="`background: ${bgColor};`"
:class="{ 'mb-2': vGroup.children && +i !== vGroup.children.length - 1 }"
:show-arrow="false"
>
<template #header>

25
packages/nc-gui/components/smartsheet/grid/GroupByTable.vue

@ -118,34 +118,11 @@ reloadViewDataHook?.on(reloadTableData)
provide(IsGroupByInj, ref(true))
const scrollBump = computed<number>(() => {
let baseWidth = props.scrollLeft ?? 0
const depth = props.depth ?? 0
switch (depth) {
case 0:
baseWidth = baseWidth - 10
break
case 1:
baseWidth = baseWidth - 18
break
case 2:
baseWidth = baseWidth - 16
break
}
return Math.max(baseWidth, 0)
})
const pagination = computed(() => {
return {
fixedSize: props.paginationFixedSize ? props.paginationFixedSize - 2 : undefined,
hideSidebars: props.paginationHideSidebars,
extraStyle: `margin-left: ${scrollBump.value}px;
background: transparent !important; border-top: 0px
}`,
extraStyle: 'background: transparent !important; border-top: 0px;',
}
})

194
packages/nc-gui/components/smartsheet/grid/Table.vue

@ -1881,6 +1881,22 @@ onKeyStroke('ArrowDown', onDown)
</a-dropdown>
</div>
</th>
<th
class="!border-0 relative !xs:hidden"
:style="{
borderWidth: '0px !important',
}"
>
<div
class="absolute top-0 w-[40px]"
:class="{
'left-[60px]': isAddingColumnAllowed,
'left-0': !isAddingColumnAllowed,
}"
>
&nbsp;
</div>
</th>
</tr>
</thead>
</table>
@ -2321,102 +2337,104 @@ onKeyStroke('ArrowDown', onDown)
</NcDropdown>
</div>
<LazySmartsheetPagination
v-if="headerOnly !== true && paginationDataRef"
:key="`nc-pagination-${isMobileMode}`"
v-model:pagination-data="paginationDataRef"
:show-api-timing="!isGroupBy"
align-count-on-right
:align-left="isGroupBy"
:change-page="changePage"
:hide-sidebars="paginationStyleRef?.hideSidebars === true"
:fixed-size="paginationStyleRef?.fixedSize"
:extra-style="paginationStyleRef?.extraStyle"
:show-size-changer="!isGroupBy"
>
<template #add-record>
<div v-if="isAddingEmptyRowAllowed && !showSkeleton" class="flex ml-1">
<NcButton
v-if="isMobileMode"
v-e="[isAddNewRecordGridMode ? 'c:row:add:grid' : 'c:row:add:form']"
class="nc-grid-add-new-row"
type="secondary"
:disabled="isPaginationLoading"
@click="onNewRecordToFormClick()"
>
{{ $t('activity.newRecord') }}
</NcButton>
<a-dropdown-button
v-else
v-e="[isAddNewRecordGridMode ? 'c:row:add:grid:toggle' : 'c:row:add:form:toggle']"
class="nc-grid-add-new-row"
placement="top"
:disabled="isPaginationLoading"
@click="isAddNewRecordGridMode ? addEmptyRow() : onNewRecordToFormClick()"
>
<div data-testid="nc-pagination-add-record" class="flex items-center px-2 text-gray-600 hover:text-black">
<span>
<template v-if="isAddNewRecordGridMode">
{{ $t('activity.newRecord') }}
</template>
<template v-else> {{ $t('activity.newRecord') }} - {{ $t('objects.viewType.form') }} </template>
</span>
</div>
<template #overlay>
<div class="relative overflow-visible min-h-17 w-10">
<div
class="absolute -top-21 flex flex-col min-h-34.5 w-70 p-1.5 bg-white rounded-lg border-1 border-gray-200 justify-start overflow-hidden"
style="box-shadow: 0px 4px 6px -2px rgba(0, 0, 0, 0.06), 0px -12px 16px -4px rgba(0, 0, 0, 0.1)"
:class="{
'-left-32.5': !isAddNewRecordGridMode,
'-left-21.5': isAddNewRecordGridMode,
}"
>
<div
v-e="['c:row:add:grid']"
class="px-4 py-3 flex flex-col select-none gap-y-2 cursor-pointer rounded-md hover:bg-gray-100 text-gray-600 nc-new-record-with-grid group"
@click="onNewRecordToGridClick"
>
<div class="flex flex-row items-center justify-between w-full">
<div class="flex flex-row items-center justify-start gap-x-3">
<component :is="viewIcons[ViewTypes.GRID]?.icon" class="nc-view-icon text-inherit" />
{{ $t('activity.newRecord') }} - {{ $t('objects.viewType.grid') }}
</div>
<div class="relative">
<LazySmartsheetPagination
v-if="headerOnly !== true && paginationDataRef"
:key="`nc-pagination-${isMobileMode}`"
v-model:pagination-data="paginationDataRef"
:show-api-timing="!isGroupBy"
align-count-on-right
:align-left="isGroupBy"
:change-page="changePage"
:hide-sidebars="paginationStyleRef?.hideSidebars === true"
:fixed-size="paginationStyleRef?.fixedSize"
:extra-style="paginationStyleRef?.extraStyle"
:show-size-changer="!isGroupBy"
>
<template v-if="isAddingEmptyRowAllowed && !showSkeleton" #add-record>
<div class="flex ml-1">
<NcButton
v-if="isMobileMode"
v-e="[isAddNewRecordGridMode ? 'c:row:add:grid' : 'c:row:add:form']"
class="nc-grid-add-new-row"
type="secondary"
:disabled="isPaginationLoading"
@click="onNewRecordToFormClick()"
>
{{ $t('activity.newRecord') }}
</NcButton>
<a-dropdown-button
v-else
v-e="[isAddNewRecordGridMode ? 'c:row:add:grid:toggle' : 'c:row:add:form:toggle']"
class="nc-grid-add-new-row"
placement="top"
:disabled="isPaginationLoading"
@click="isAddNewRecordGridMode ? addEmptyRow() : onNewRecordToFormClick()"
>
<div data-testid="nc-pagination-add-record" class="flex items-center px-2 text-gray-600 hover:text-black">
<span>
<template v-if="isAddNewRecordGridMode">
{{ $t('activity.newRecord') }}
</template>
<template v-else> {{ $t('activity.newRecord') }} - {{ $t('objects.viewType.form') }} </template>
</span>
</div>
<GeneralIcon v-if="isAddNewRecordGridMode" icon="check" class="w-4 h-4 text-primary" />
</div>
<div class="flex flex-row text-xs text-gray-400 ml-7.25">
{{ $t('labels.addRowGrid') }}
</div>
</div>
<template #overlay>
<div class="relative overflow-visible min-h-17 w-10">
<div
v-e="['c:row:add:form']"
class="px-4 py-3 flex flex-col select-none gap-y-2 cursor-pointer rounded-md hover:bg-gray-100 text-gray-600 nc-new-record-with-form group"
@click="onNewRecordToFormClick"
class="absolute -top-21 flex flex-col min-h-34.5 w-70 p-1.5 bg-white rounded-lg border-1 border-gray-200 justify-start overflow-hidden"
style="box-shadow: 0px 4px 6px -2px rgba(0, 0, 0, 0.06), 0px -12px 16px -4px rgba(0, 0, 0, 0.1)"
:class="{
'-left-32.5': !isAddNewRecordGridMode,
'-left-21.5': isAddNewRecordGridMode,
}"
>
<div class="flex flex-row items-center justify-between w-full">
<div class="flex flex-row items-center justify-start gap-x-2.5">
<GeneralIcon class="h-4.5 w-4.5" icon="article" />
{{ $t('activity.newRecord') }} - {{ $t('objects.viewType.form') }}
</div>
<div
v-e="['c:row:add:grid']"
class="px-4 py-3 flex flex-col select-none gap-y-2 cursor-pointer rounded-md hover:bg-gray-100 text-gray-600 nc-new-record-with-grid group"
@click="onNewRecordToGridClick"
>
<div class="flex flex-row items-center justify-between w-full">
<div class="flex flex-row items-center justify-start gap-x-3">
<component :is="viewIcons[ViewTypes.GRID]?.icon" class="nc-view-icon text-inherit" />
{{ $t('activity.newRecord') }} - {{ $t('objects.viewType.grid') }}
</div>
<GeneralIcon v-if="!isAddNewRecordGridMode" icon="check" class="w-4 h-4 text-primary" />
<GeneralIcon v-if="isAddNewRecordGridMode" icon="check" class="w-4 h-4 text-primary" />
</div>
<div class="flex flex-row text-xs text-gray-400 ml-7.25">
{{ $t('labels.addRowGrid') }}
</div>
</div>
<div class="flex flex-row text-xs text-gray-400 ml-7.05">
{{ $t('labels.addRowForm') }}
<div
v-e="['c:row:add:form']"
class="px-4 py-3 flex flex-col select-none gap-y-2 cursor-pointer rounded-md hover:bg-gray-100 text-gray-600 nc-new-record-with-form group"
@click="onNewRecordToFormClick"
>
<div class="flex flex-row items-center justify-between w-full">
<div class="flex flex-row items-center justify-start gap-x-2.5">
<GeneralIcon class="h-4.5 w-4.5" icon="article" />
{{ $t('activity.newRecord') }} - {{ $t('objects.viewType.form') }}
</div>
<GeneralIcon v-if="!isAddNewRecordGridMode" icon="check" class="w-4 h-4 text-primary" />
</div>
<div class="flex flex-row text-xs text-gray-400 ml-7.05">
{{ $t('labels.addRowForm') }}
</div>
</div>
</div>
</div>
</div>
</template>
<template #icon>
<component :is="iconMap.arrowUp" class="text-gray-600 h-4 w-4" />
</template>
</a-dropdown-button>
</div>
</template>
</LazySmartsheetPagination>
</template>
<template #icon>
<component :is="iconMap.arrowUp" class="text-gray-600 h-4 w-4" />
</template>
</a-dropdown-button>
</div>
</template>
</LazySmartsheetPagination>
</div>
</div>
</template>

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

@ -87,7 +87,7 @@ watch(value, (next) => {
<template>
<div class="flex w-full chips-wrapper items-center" :class="{ active }">
<LazyVirtualCellComponentsLinkRecordDropdown v-model:is-open="isOpen">
<div class="flex items-center w-full min-h-7.7">
<div class="flex items-center w-full">
<div class="nc-cell-field chips flex items-center flex-1 max-w-[calc(100%_-_16px)]">
<template v-if="value && (relatedTableDisplayValueProp || relatedTableDisplayValuePropId)">
<VirtualCellComponentsItemChip

4
packages/nc-gui/components/virtual-cell/HasMany.vue

@ -127,7 +127,7 @@ watch(
<template>
<LazyVirtualCellComponentsLinkRecordDropdown v-model:is-open="isOpen">
<div class="flex items-center gap-1 w-full chips-wrapper min-h-7.7">
<div class="flex items-center gap-1 w-full chips-wrapper min-h-4">
<div class="chips flex items-center img-container flex-1 hm-items flex-nowrap min-w-0 overflow-hidden">
<template v-if="cells">
<VirtualCellComponentsItemChip
@ -144,7 +144,7 @@ watch(
</template>
</div>
<div v-if="!isUnderLookup && !isSystemColumn(column)" class="flex justify-end gap-1 min-h-[30px] items-center">
<div v-if="!isUnderLookup && !isSystemColumn(column)" class="flex justify-end gap-1 min-h-4 items-center">
<GeneralIcon
icon="expand"
class="select-none transform text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 nc-arrow-expand"

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

@ -139,7 +139,7 @@ watch(
<template>
<div class="nc-cell-field flex w-full group items-center nc-links-wrapper py-1" @dblclick.stop="openChildList">
<LazyVirtualCellComponentsLinkRecordDropdown v-model:is-open="isOpen">
<div class="flex w-full group items-center min-h-7.7">
<div class="flex w-full group items-center min-h-4">
<div class="block flex-shrink truncate">
<component
:is="isUnderLookup ? 'span' : 'a'"

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

@ -90,11 +90,12 @@ const { showEditNonEditableFieldWarning, showClearNonEditableFieldWarning, activ
class="nc-cell-field h-full w-full nc-lookup-cell"
tabindex="-1"
:style="{
height: isGroupByLabel
? undefined
: rowHeight
? `${rowHeight === 1 ? rowHeightInPx['1'] - 4 : rowHeightInPx[`${rowHeight}`] - 18}px`
: `2.85rem`,
height:
isGroupByLabel || (lookupColumn && isAttachment(lookupColumn))
? undefined
: rowHeight
? `${rowHeight === 1 ? rowHeightInPx['1'] - 4 : rowHeightInPx[`${rowHeight}`] - 18}px`
: `2.85rem`,
}"
@dblclick="activateShowEditNonEditableFieldWarning"
>

4
packages/nc-gui/components/virtual-cell/ManyToMany.vue

@ -126,7 +126,7 @@ watch(
<template>
<LazyVirtualCellComponentsLinkRecordDropdown v-model:is-open="isOpen">
<div class="flex items-center gap-1 w-full chips-wrapper min-h-7.7">
<div class="flex items-center gap-1 w-full chips-wrapper min-h-4">
<div class="chips flex items-center img-container flex-1 hm-items flex-nowrap min-w-0 overflow-hidden">
<template v-if="cells">
<VirtualCellComponentsItemChip
@ -143,7 +143,7 @@ watch(
</template>
</div>
<div v-if="!isUnderLookup || isForm" class="flex justify-end gap-1 min-h-[30px] items-center">
<div v-if="!isUnderLookup || isForm" class="flex justify-end gap-1 min-h-4 items-center">
<GeneralIcon
icon="expand"
class="text-sm nc-action-icon text-gray-500/50 hover:text-gray-500 nc-arrow-expand"

4
packages/nc-gui/components/virtual-cell/OneToOne.vue

@ -84,7 +84,7 @@ watch(
<template>
<LazyVirtualCellComponentsLinkRecordDropdown v-model:is-open="isOpen">
<div class="flex w-full chips-wrapper items-center min-h-7.7" :class="{ active }">
<div class="flex w-full chips-wrapper items-center min-h-4" :class="{ active }">
<div class="nc-cell-field chips flex items-center flex-1 max-w-[calc(100%_-_16px)]">
<template v-if="value && (relatedTableDisplayValueProp || relatedTableDisplayValuePropId)">
<VirtualCellComponentsItemChip
@ -103,7 +103,7 @@ watch(
<div
v-if="!readOnly && (isUIAllowed('dataEdit') || isForm) && !isUnderLookup"
class="flex justify-end group gap-1 min-h-[30px] items-center"
class="flex justify-end group gap-1 min-h-4 items-center"
tabindex="0"
@keydown.enter.stop="listItemsDlg = true"
>

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

@ -54,7 +54,7 @@ export default {
<template>
<div
v-e="['c:row-expand:open']"
class="chip group mr-1 my-1 flex items-center rounded-[2px] flex-row truncate"
class="chip group mr-1 my-0.5 flex items-center rounded-[2px] flex-row truncate"
:class="{ active, 'border-1 py-1 px-2': isAttachment(column) }"
@click="openExpandedForm"
>

2
packages/nocodb/src/models/BaseUser.ts

@ -196,7 +196,7 @@ export default class BaseUser {
`${MetaTable.USERS}.display_name`,
`${MetaTable.USERS}.invite_token`,
`${MetaTable.USERS}.roles as main_roles`,
`${MetaTable.USERS}.created_at as created_at`,
`${MetaTable.PROJECT_USERS}.created_at`,
`${MetaTable.PROJECT_USERS}.base_id`,
`${MetaTable.PROJECT_USERS}.roles as roles`,
);

4
tests/playwright/pages/Dashboard/Grid/Column/index.ts

@ -224,7 +224,9 @@ export class ColumnPageObject extends BasePage {
await this.save();
const headersText = [];
const locator = this.grid.get().locator(`th`);
const locator = this.grid.get().locator('th.nc-grid-column-header');
await locator.first().waitFor({ state: 'visible' });
const count = await locator.count();
for (let i = 0; i < count; i++) {
const header = locator.nth(i);

11
tests/playwright/tests/db/features/multiFieldEditor.spec.ts

@ -149,16 +149,19 @@ test.describe('Multi Field Editor', () => {
const verifyGridColumnHeaders = async ({ fields = [] }: { fields: string[] }) => {
await dashboard.grid.topbar.openDataTab();
const locator = dashboard.grid.get().locator(`th`);
const locator = dashboard.grid.get().locator('th.nc-grid-column-header');
await locator.first().waitFor({ state: 'visible' });
const count = await locator.count();
// exclude first checkbox and last add new column
expect(count - 2).toBe(fields.length);
expect(count).toBe(fields.length);
for (let i = 1; i < count - 1; i++) {
for (let i = 0; i < count; i++) {
const header = locator.nth(i);
const text = await getTextExcludeIconText(header);
expect(text).toBe(fields[i - 1]);
expect(text).toBe(fields[i]);
}
await openMultiFieldOfATable();

Loading…
Cancel
Save