Browse Source

Merge pull request #5805 from nocodb/enhancement/5789-sticky-add-new-row

enhancement: sticky add new row
pull/5845/head
Raju Udava 1 year ago committed by GitHub
parent
commit
c0425d68a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 72
      packages/nc-gui/components/smartsheet/Grid.vue
  2. 28
      packages/nc-gui/components/smartsheet/Pagination.vue
  3. 1
      packages/nc-gui/composables/useMultiSelect/index.ts
  4. 6
      tests/playwright/pages/Dashboard/Grid/index.ts

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

@ -117,7 +117,7 @@ const {
formattedData: data,
updateOrSaveRow,
changePage,
addEmptyRow,
addEmptyRow: _addEmptyRow,
deleteRow,
deleteSelectedRows,
selectedAllRecords,
@ -200,6 +200,7 @@ const {
isCellActive,
tbodyEl,
resetSelectedRange,
makeActive,
selectedRange,
} = useMultiSelect(
meta,
@ -774,9 +775,17 @@ eventBus.on(async (event, payload) => {
}
})
const closeAddColumnDropdown = () => {
const closeAddColumnDropdown = (scrollToLastCol = false) => {
columnOrder.value = null
addColumnDropdown.value = false
if (scrollToLastCol) {
setTimeout(() => {
const lastAddNewRowHeader = tableHead.value?.querySelector('th:last-child')
if (lastAddNewRowHeader) {
lastAddNewRowHeader.scrollIntoView({ behavior: 'smooth' })
}
}, 200)
}
}
const confirmDeleteRow = (row: number) => {
@ -803,6 +812,15 @@ const deleteSelectedRangeOfRows = () => {
activeCell.col = null
})
}
function addEmptyRow(row?: number) {
const rowObj = _addEmptyRow(row)
nextTick().then(() => {
makeActive(row ?? data.value.length - 1, 0)
scrollToCell?.()
})
return rowObj
}
</script>
<template>
@ -826,7 +844,7 @@ const deleteSelectedRangeOfRows = () => {
>
<thead ref="tableHead">
<tr class="nc-grid-header">
<th class="w-[80px] min-w-[80px]" data-testid="grid-id-column">
<th class="w-[85px] min-w-[85px]" data-testid="grid-id-column">
<div class="w-full h-full bg-gray-100 flex pl-5 pr-1 items-center" data-testid="nc-check-all">
<template v-if="!readOnly">
<div class="nc-no-label text-gray-500" :class="{ hidden: selectedAllRecords }">#</div>
@ -879,8 +897,8 @@ const deleteSelectedRangeOfRows = () => {
<SmartsheetColumnEditOrAddProvider
v-if="addColumnDropdown"
:column-position="columnOrder"
@submit="closeAddColumnDropdown"
@cancel="closeAddColumnDropdown"
@submit="closeAddColumnDropdown(true)"
@cancel="closeAddColumnDropdown()"
@click.stop
@keydown.stop
/>
@ -955,7 +973,8 @@ const deleteSelectedRangeOfRows = () => {
:key="columnObj.id"
class="cell relative nc-grid-cell"
:class="{
'active': isCellSelected(rowIndex, colIndex),
'cursor-pointer': hasEditPermission,
'active': hasEditPermission && isCellSelected(rowIndex, colIndex),
'nc-required-cell': isColumnRequiredAndNull(columnObj, row.row),
'align-middle': !rowHeight || rowHeight === 1,
'align-top': rowHeight && rowHeight !== 1,
@ -1003,21 +1022,19 @@ const deleteSelectedRangeOfRows = () => {
</template>
</LazySmartsheetRow>
<tr v-if="isAddingEmptyRowAllowed">
<td
v-e="['c:row:add:grid-bottom']"
:colspan="visibleColLength + 1"
class="text-left pointer nc-grid-add-new-cell cursor-pointer"
@click="addEmptyRow()"
>
<tr
v-if="isAddingEmptyRowAllowed"
v-e="['c:row:add:grid-bottom']"
class="cursor-pointer"
@mouseup.stop
@click="addEmptyRow()"
>
<td class="text-left pointer nc-grid-add-new-cell sticky left-0 !z-5 !border-r-0">
<div class="px-2 w-full flex items-center text-gray-500">
<component :is="iconMap.plus" class="text-pint-500 text-xs ml-2 text-primary" />
<span class="ml-1">
{{ $t('activity.addRow') }}
</span>
</div>
</td>
<td :colspan="visibleColLength"></td>
</tr>
</tbody>
</table>
@ -1079,8 +1096,23 @@ const deleteSelectedRangeOfRows = () => {
</a-dropdown>
</div>
<LazySmartsheetPagination />
<div
v-if="isAddingEmptyRowAllowed"
class="absolute bottom-1px left-2 z-4"
data-testid="nc-grid-add-new-row"
@click="addEmptyRow()"
>
<a-button v-e="['c:row:add:grid-bottom', { footer: true }]" class="!rounded-xl" size="small">
<div class="flex items-center">
<component :is="iconMap.plus" class="text-pint-500 text-xs" />
<span class="ml-1">
{{ $t('activity.addRow') }}
</span>
</div>
</a-button>
</div>
<LazySmartsheetPagination align-count-on-right> </LazySmartsheetPagination>
<Suspense>
<LazySmartsheetExpandedForm
v-if="expandedFormRow && expandedFormDlg"
@ -1179,14 +1211,14 @@ const deleteSelectedRangeOfRows = () => {
thead th:nth-child(2) {
position: sticky !important;
left: 80px;
left: 85px;
z-index: 5;
@apply border-r-2 border-r-gray-300;
}
tbody td:nth-child(2) {
position: sticky !important;
left: 80px;
left: 85px;
z-index: 4;
background: white;
@apply border-r-2 border-r-gray-300;

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

@ -1,6 +1,10 @@
<script setup lang="ts">
import { ChangePageInj, PaginationDataInj, computed, iconMap, inject } from '#imports'
const props = defineProps<{
alignCountOnRight?: boolean
}>()
const paginatedData = inject(PaginationDataInj)!
const changePage = inject(ChangePageInj)!
@ -19,11 +23,15 @@ const page = computed({
<template>
<div class="flex items-center mb-1">
<span v-if="count !== null && count !== Infinity" class="caption ml-5 text-gray-500" data-testid="grid-pagination">
{{ count }} {{ count !== 1 ? $t('objects.records') : $t('objects.record') }}
</span>
<div class="flex-1" />
<div class="flex-1">
<span
v-if="!alignCountOnRight && count !== null && count !== Infinity"
class="caption ml-5 text-gray-500"
data-testid="grid-pagination"
>
{{ count }} {{ count !== 1 ? $t('objects.records') : $t('objects.record') }}
</span>
</div>
<a-pagination
v-if="count !== Infinity"
@ -44,7 +52,15 @@ const page = computed({
</a-input>
</div>
<div class="flex-1" />
<div class="flex-1 text-right pr-2">
<span
v-if="alignCountOnRight && count !== null && count !== Infinity"
class="caption mr-5 text-gray-500"
data-testid="grid-pagination"
>
{{ count }} {{ count !== 1 ? $t('objects.records') : $t('objects.record') }}
</span>
</div>
</div>
</template>

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

@ -453,5 +453,6 @@ export function useMultiSelect(
tbodyEl,
resetSelectedRange,
selectedRange,
makeActive,
}
}

6
tests/playwright/pages/Dashboard/Grid/index.ts

@ -77,8 +77,9 @@ export class GridPage extends BasePage {
if (index !== 0) await this.get().locator('.nc-grid-row').nth(0).waitFor({ state: 'attached' });
const rowCount = await this.get().locator('.nc-grid-row').count();
await (await this.get().locator('.nc-grid-add-new-cell').elementHandle())?.waitForElementState('stable');
await this.get().locator('.nc-grid-add-new-cell').click();
const addNewRowButton: Locator = await this.rootPage.locator(`[data-testid="nc-grid-add-new-row"]`);
await addNewRowButton.waitFor({ state: 'visible' });
await addNewRowButton.click();
await expect(await this.get().locator('.nc-grid-row')).toHaveCount(rowCount + 1);
@ -168,6 +169,7 @@ export class GridPage extends BasePage {
async addRowRightClickMenu(index: number) {
const rowCount = await this.get().locator('.nc-grid-row').count();
await this.get().locator(`td[data-testid="cell-Title-${index}"]`).click();
await this.get().locator(`td[data-testid="cell-Title-${index}"]`).click({
button: 'right',
});

Loading…
Cancel
Save