Browse Source

fix(nc-gui): resolve conflicts

pull/6954/head
աɨռɢӄաօռɢ 12 months ago
parent
commit
ac71728746
  1. 262
      packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
  2. 268
      packages/nc-gui/components/smartsheet/grid/Table.vue

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

@ -139,8 +139,7 @@ async function updateProjectTitle() {
$e('a:base:rename') $e('a:base:rename')
useTitle(`${base.value?.title}`) useTitle(`${base.value?.title}`)
} } catch (e: any) {
catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
} }
@ -159,8 +158,7 @@ async function copyProjectInfo() {
// Copied to clipboard // Copied to clipboard
message.info(t('msg.info.copiedToClipboard')) message.info(t('msg.info.copiedToClipboard'))
} }
} } catch (e: any) {
catch (e: any) {
console.error(e) console.error(e)
message.error(e.message) message.error(e.message)
} }
@ -180,8 +178,7 @@ async function setIcon(icon: string, base: BaseType) {
basesStore.updateProject(base.id!, { meta: JSON.stringify(meta) }) basesStore.updateProject(base.id!, { meta: JSON.stringify(meta) })
$e('a:base:icon:navdraw', { icon }) $e('a:base:icon:navdraw', { icon })
} } catch (e: any) {
catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
} }
@ -227,6 +224,7 @@ function openTableCreateDialog(sourceIndex?: number | undefined) {
} }
const isAddNewProjectChildEntityLoading = ref(false) const isAddNewProjectChildEntityLoading = ref(false)
async function addNewProjectChildEntity() { async function addNewProjectChildEntity() {
if (isAddNewProjectChildEntityLoading.value) return if (isAddNewProjectChildEntityLoading.value) return
@ -246,8 +244,7 @@ async function addNewProjectChildEntity() {
if (!base.value.isExpanded && base.value.type !== NcProjectType.DB) { if (!base.value.isExpanded && base.value.type !== NcProjectType.DB) {
base.value.isExpanded = true base.value.isExpanded = true
} }
} } finally {
finally {
isAddNewProjectChildEntityLoading.value = false isAddNewProjectChildEntityLoading.value = false
} }
} }
@ -264,8 +261,7 @@ async function onProjectClick(base: NcProject, ignoreNavigation?: boolean, toggl
if (toggleIsExpanded) { if (toggleIsExpanded) {
base.isExpanded = !base.isExpanded base.isExpanded = !base.isExpanded
} } else {
else {
base.isExpanded = true base.isExpanded = true
} }
@ -315,8 +311,7 @@ function openErdView(source: SourceType) {
const contextMenuBase = computed(() => { const contextMenuBase = computed(() => {
if (contextMenuTarget.type === 'source') { if (contextMenuTarget.type === 'source') {
return contextMenuTarget.value return contextMenuTarget.value
} } else if (contextMenuTarget.type === 'table') {
else if (contextMenuTarget.type === 'table') {
const source = base.value?.sources?.find((b) => b.id === contextMenuTarget.value.source_id) const source = base.value?.sources?.find((b) => b.id === contextMenuTarget.value.source_id)
if (source) return source if (source) return source
} }
@ -402,8 +397,9 @@ function projectDelete() {
</NcButton> </NcButton>
<div class="flex items-center mr-1" @click="onProjectClick(base)"> <div class="flex items-center mr-1" @click="onProjectClick(base)">
<div class="flex items-center select-none w-6 h-full"> <div v-e="['c:base:emojiSelect']" class="flex items-center select-none w-6 h-full">
<a-spin v-if="base.isLoading" class="!ml-1.25 !flex !flex-row !items-center !my-0.5 w-8" :indicator="indicator" /> <a-spin v-if="base.isLoading" class="!ml-1.25 !flex !flex-row !items-center !my-0.5 w-8" :indicator="indicator" />
<LazyGeneralEmojiPicker <LazyGeneralEmojiPicker
v-else v-else
:key="base.meta?.icon" :key="base.meta?.icon"
@ -412,9 +408,7 @@ function projectDelete() {
size="small" size="small"
@emoji-selected="setIcon($event, base)" @emoji-selected="setIcon($event, base)"
> >
<div v-e="['c:base:emojiSelect']"> <GeneralProjectIcon :type="base.type" />
<GeneralProjectIcon :type="base.type" />
</div>
</LazyGeneralEmojiPicker> </LazyGeneralEmojiPicker>
</div> </div>
</div> </div>
@ -441,19 +435,35 @@ function projectDelete() {
</span> </span>
<div :class="{ 'flex flex-grow h-full': !editMode }" @click="onProjectClick(base)"></div> <div :class="{ 'flex flex-grow h-full': !editMode }" @click="onProjectClick(base)"></div>
<template v-if="!isSharedBase"> <NcDropdown v-if="!isSharedBase" v-model:visible="isOptionsOpen" :trigger="['click']">
<NcDropdown v-model:visible="isOptionsOpen" :trigger="['click']"> <NcButton
<NcButton v-e="['c:base:options']"
v-e="['c:base:options']" class="nc-sidebar-node-btn"
class="nc-sidebar-node-btn" :class="{ '!text-black !opacity-100': isOptionsOpen }"
:class="{ '!text-black !opacity-100': isOptionsOpen }" data-testid="nc-sidebar-context-menu"
data-testid="nc-sidebar-context-menu" type="text"
type="text" size="xxsmall"
size="xxsmall" @click.stop
@click.stop >
<GeneralIcon icon="threeDotHorizontal" class="text-xl w-4.75" />
</NcButton>
<template #overlay>
<NcMenu
class="nc-scrollbar-md"
:style="{
maxHeight: '70vh',
overflow: 'overlay',
}"
:data-testid="`nc-sidebar-base-${base.title}-options`"
@click="isOptionsOpen = false"
> >
<GeneralIcon icon="threeDotHorizontal" class="text-xl w-4.75" /> <template v-if="!isSharedBase">
</NcButton> <NcMenuItem v-if="isUIAllowed('baseRename')" data-testid="nc-sidebar-project-rename" @click="enableEditMode">
<div v-e="['c:base:rename']" class="flex gap-2 items-center">
<GeneralIcon icon="edit" class="group-hover:text-black" />
{{ $t('general.rename') }}
</div>
</NcMenuItem>
<NcMenuItem <NcMenuItem
v-if="isUIAllowed('baseDuplicate', { roles: [stringifyRolesObj(orgRoles), baseRole].join() })" v-if="isUIAllowed('baseDuplicate', { roles: [stringifyRolesObj(orgRoles), baseRole].join() })"
@ -482,11 +492,7 @@ function projectDelete() {
</NcMenuItem> </NcMenuItem>
<!-- ERD View --> <!-- ERD View -->
<NcMenuItem <NcMenuItem key="erd" data-testid="nc-sidebar-base-relations" @click="openErdView(base?.sources?.[0]!)">
key="erd"
data-testid="nc-sidebar-base-relations"
@click="openErdView(base?.sources?.[0]!)"
>
<div v-e="['c:base:erd']" class="flex gap-2 items-center"> <div v-e="['c:base:erd']" class="flex gap-2 items-center">
<GeneralIcon icon="erd" /> <GeneralIcon icon="erd" />
{{ $t('title.relations') }} {{ $t('title.relations') }}
@ -497,7 +503,6 @@ function projectDelete() {
<NcMenuItem <NcMenuItem
v-if="isUIAllowed('apiDocs')" v-if="isUIAllowed('apiDocs')"
key="api" key="api"
v-e="['c:base:api-docs']"
data-testid="nc-sidebar-base-rest-apis" data-testid="nc-sidebar-base-rest-apis"
@click.stop=" @click.stop="
() => { () => {
@ -523,121 +528,43 @@ function projectDelete() {
<NcMenuItem <NcMenuItem
v-if="isUIAllowed('baseMiscSettings')" v-if="isUIAllowed('baseMiscSettings')"
key="teamAndSettings" key="teamAndSettings"
v-e="['c:base:settings']"
data-testid="nc-sidebar-base-settings" data-testid="nc-sidebar-base-settings"
class="nc-sidebar-base-base-settings" class="nc-sidebar-base-base-settings"
@click="toggleDialog(true, 'teamAndAuth', undefined, base.id)" @click="toggleDialog(true, 'teamAndAuth', undefined, base.id)"
> >
<template v-if="!isSharedBase"> <div v-e="['c:base:settings']" class="flex gap-2 items-center">
<NcMenuItem v-if="isUIAllowed('baseRename')" data-testid="nc-sidebar-project-rename" @click="enableEditMode"> <GeneralIcon icon="settings" class="group-hover:text-black" />
<div v-e="['c:base:rename']" class="flex gap-2 items-center"> {{ $t('activity.settings') }}
<GeneralIcon icon="edit" class="group-hover:text-black" />
{{ $t('general.rename') }}
</div>
</NcMenuItem>
<NcMenuItem
v-if="isUIAllowed('baseDuplicate', { roles: [stringifyRolesObj(orgRoles), baseRole].join() })"
data-testid="nc-sidebar-base-duplicate"
@click="duplicateProject(base)"
>
<div v-e="['c:base:duplicate']" class="flex gap-2 items-center">
<GeneralIcon icon="duplicate" class="text-gray-700" />
{{ $t('general.duplicate') }}
</div>
</NcMenuItem>
<NcDivider v-if="['baseDuplicate', 'baseRename'].some((permission) => isUIAllowed(permission))" />
<!-- Copy Project Info -->
<NcMenuItem
v-if="!isEeUI"
key="copy"
data-testid="nc-sidebar-base-copy-base-info"
@click.stop="copyProjectInfo"
>
<div v-e="['c:base:copy-proj-info']" class="flex gap-2 items-center">
<GeneralIcon icon="copy" class="group-hover:text-black" />
{{ $t('activity.account.projInfo') }}
</div>
</NcMenuItem>
<!-- ERD View -->
<NcMenuItem key="erd" data-testid="nc-sidebar-base-relations" @click="openErdView(base?.sources?.[0]!)">
<div v-e="['c:base:erd']" class="flex gap-2 items-center">
<GeneralIcon icon="erd" />
{{ $t('title.relations') }}
</div>
</NcMenuItem>
<!-- Swagger: Rest APIs -->
<NcMenuItem
v-if="isUIAllowed('apiDocs')"
key="api"
data-testid="nc-sidebar-base-rest-apis"
@click.stop="
() => {
$e('c:base:api-docs')
openLink(`/api/v1/db/meta/projects/${base.id}/swagger`, appInfo.ncSiteUrl)
}
"
>
<div v-e="['c:base:api-docs']" class="flex gap-2 items-center">
<GeneralIcon icon="snippet" class="group-hover:text-black !max-w-3.9" />
{{ $t('activity.account.swagger') }}
</div>
</NcMenuItem>
</template>
<div v-if="base.sources && base.sources[0] && showBaseOption">
<NcDivider />
<DashboardTreeViewBaseOptions v-model:base="base" :source="base.sources[0]" />
</div> </div>
</NcMenuItem>
<NcMenuItem
v-if="isUIAllowed('baseDelete', { roles: [stringifyRolesObj(orgRoles), baseRole].join() })"
data-testid="nc-sidebar-base-delete"
class="!text-red-500 !hover:bg-red-50"
@click="projectDelete"
>
<div class="flex gap-2 items-center">
<GeneralIcon icon="delete" class="w-4" />
{{ $t('general.delete') }}
</div>
</NcMenuItem>
</NcMenu>
</template>
</NcDropdown>
<NcDivider v-if="['baseMiscSettings', 'baseDelete'].some((permission) => isUIAllowed(permission))" /> <NcButton
v-if="isUIAllowed('tableCreate', { roles: baseRole })"
<NcMenuItem v-e="['c:base:create-table']"
v-if="isUIAllowed('baseMiscSettings')" class="nc-sidebar-node-btn"
key="teamAndSettings" size="xxsmall"
data-testid="nc-sidebar-base-settings" type="text"
class="nc-sidebar-base-base-settings" data-testid="nc-sidebar-add-base-entity"
@click="toggleDialog(true, 'teamAndAuth', undefined, base.id)" :class="{ '!text-black !visible': isAddNewProjectChildEntityLoading, '!visible': isOptionsOpen }"
> :loading="isAddNewProjectChildEntityLoading"
<div v-e="['c:base:settings']" class="flex gap-2 items-center"> @click.stop="addNewProjectChildEntity"
<GeneralIcon icon="settings" class="group-hover:text-black" /> >
{{ $t('activity.settings') }} <GeneralIcon icon="plus" class="text-xl leading-5" style="-webkit-text-stroke: 0.15px" />
</div> </NcButton>
</NcMenuItem>
<NcMenuItem
v-if="isUIAllowed('baseDelete', { roles: [stringifyRolesObj(orgRoles), baseRole].join() })"
data-testid="nc-sidebar-base-delete"
class="!text-red-500 !hover:bg-red-50"
@click="projectDelete"
>
<div class="flex gap-2 items-center">
<GeneralIcon icon="delete" class="w-4" />
{{ $t('general.delete') }}
</div>
</NcMenuItem>
</NcMenu>
</template>
</NcDropdown>
</template>
<div v-if="isUIAllowed('tableCreate', { roles: baseRole })" v-e="['c:base:create-table']">
<NcButton
class="nc-sidebar-node-btn"
size="xxsmall"
type="text"
data-testid="nc-sidebar-add-base-entity"
:class="{ '!text-black !visible': isAddNewProjectChildEntityLoading, '!visible': isOptionsOpen }"
:loading="isAddNewProjectChildEntityLoading"
@click.stop="addNewProjectChildEntity"
>
<GeneralIcon icon="plus" class="text-xl leading-5" style="-webkit-text-stroke: 0.15px" />
</NcButton>
</div>
</div> </div>
</div> </div>
@ -679,7 +606,6 @@ function projectDelete() {
:class="{ '!rotate-180': isActive }" :class="{ '!rotate-180': isActive }"
/> />
</div> </div>
</template> </template>
<a-collapse-panel :key="`collapse-${source.id}`"> <a-collapse-panel :key="`collapse-${source.id}`">
<template #header> <template #header>
@ -718,18 +644,16 @@ function projectDelete() {
:trigger="['click']" :trigger="['click']"
@update:visible="isBasesOptionsOpen[source!.id!] = $event" @update:visible="isBasesOptionsOpen[source!.id!] = $event"
> >
<div v-e="['c:source:options']"> <NcButton
<NcButton v-e="['c:source:options']"
class="nc-sidebar-node-btn" class="nc-sidebar-node-btn"
:class="{ '!text-black !opacity-100': isBasesOptionsOpen[source!.id!] }" :class="{ '!text-black !opacity-100': isBasesOptionsOpen[source!.id!] }"
type="text" type="text"
size="xxsmall" size="xxsmall"
@click.stop="isBasesOptionsOpen[source!.id!] = !isBasesOptionsOpen[source!.id!]" @click.stop="isBasesOptionsOpen[source!.id!] = !isBasesOptionsOpen[source!.id!]"
> >
<GeneralIcon icon="threeDotHorizontal" class="text-xl w-4.75" /> <GeneralIcon icon="threeDotHorizontal" class="text-xl w-4.75" />
</NcButton> </NcButton>
</div>
<template #overlay> <template #overlay>
<NcMenu <NcMenu
class="nc-scrollbar-md" class="nc-scrollbar-md"
@ -752,16 +676,16 @@ function projectDelete() {
</template> </template>
</NcDropdown> </NcDropdown>
<div v-if="isUIAllowed('tableCreate', { roles: baseRole })" v-e="['c:source:add-table']"> <NcButton
<NcButton v-if="isUIAllowed('tableCreate', { roles: baseRole })"
type="text" v-e="['c:source:add-table']"
size="xxsmall" type="text"
class="nc-sidebar-node-btn" size="xxsmall"
@click.stop="openTableCreateDialog(sourceIndex)" class="nc-sidebar-node-btn"
> @click.stop="openTableCreateDialog(sourceIndex)"
<GeneralIcon icon="plus" class="text-xl leading-5" style="-webkit-text-stroke: 0.15px" /> >
</NcButton> <GeneralIcon icon="plus" class="text-xl leading-5" style="-webkit-text-stroke: 0.15px" />
</div> </NcButton>
</div> </div>
</div> </div>
</template> </template>
@ -773,7 +697,6 @@ function projectDelete() {
<DashboardTreeViewTableList :base="base" :source-index="sourceIndex" /> <DashboardTreeViewTableList :base="base" :source-index="sourceIndex" />
</div> </div>
</a-collapse-panel> </a-collapse-panel>
</a-collapse> </a-collapse>
</div> </div>
</div> </div>
@ -795,6 +718,7 @@ function projectDelete() {
{{ $t('general.rename') }} {{ $t('general.rename') }}
</div> </div>
</NcMenuItem> </NcMenuItem>
<NcMenuItem <NcMenuItem
v-if="isUIAllowed('tableDuplicate') && (contextMenuBase?.is_meta || contextMenuBase?.is_local)" v-if="isUIAllowed('tableDuplicate') && (contextMenuBase?.is_meta || contextMenuBase?.is_local)"
@click="duplicateTable(contextMenuTarget.value)" @click="duplicateTable(contextMenuTarget.value)"
@ -814,7 +738,6 @@ function projectDelete() {
</template> </template>
</NcMenu> </NcMenu>
</template> </template>
</NcDropdown> </NcDropdown>
<DlgTableDelete <DlgTableDelete
v-if="contextMenuTarget.value?.id && base?.id" v-if="contextMenuTarget.value?.id && base?.id"
@ -822,11 +745,8 @@ function projectDelete() {
:table-id="contextMenuTarget.value?.id" :table-id="contextMenuTarget.value?.id"
:base-id="base?.id" :base-id="base?.id"
/> />
<DlgProjectDelete v-model:visible="isProjectDeleteDialogVisible" :base-id="base?.id" /> <DlgProjectDelete v-model:visible="isProjectDeleteDialogVisible" :base-id="base?.id" />
<DlgProjectDuplicate v-if="selectedProjectToDuplicate" v-model="isDuplicateDlgOpen" :base="selectedProjectToDuplicate" /> <DlgProjectDuplicate v-if="selectedProjectToDuplicate" v-model="isDuplicateDlgOpen" :base="selectedProjectToDuplicate" />
<GeneralModal v-model:visible="isErdModalOpen" size="large"> <GeneralModal v-model:visible="isErdModalOpen" size="large">
<div class="h-[80vh]"> <div class="h-[80vh]">
<LazyDashboardSettingsErd :source-id="activeBaseId" /> <LazyDashboardSettingsErd :source-id="activeBaseId" />

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

@ -1471,144 +1471,146 @@ onKeyStroke('ArrowDown', onDown)
></td> ></td>
</tr> </tr>
</template> </template>
<LazySmartsheetRow v-for="(row, rowIndex) of dataRef" ref="rowRefs" :key="rowIndex" :row="row"> <template v-else>
<template v-show="!showSkeleton" #default="{ state }"> <LazySmartsheetRow v-for="(row, rowIndex) of dataRef" ref="rowRefs" :key="rowIndex" :row="row">
<tr <template #default="{ state }">
class="nc-grid-row !xs:h-14" <tr
:style="{ height: rowHeight ? `${rowHeight * 1.8}rem` : `1.8rem` }" class="nc-grid-row !xs:h-14"
:data-testid="`grid-row-${rowIndex}`" :style="{ height: rowHeight ? `${rowHeight * 1.8}rem` : `1.8rem` }"
> :data-testid="`grid-row-${rowIndex}`"
<td
key="row-index"
class="caption nc-grid-cell pl-5 pr-1"
:data-testid="`cell-Id-${rowIndex}`"
@contextmenu="contextMenuTarget = null"
> >
<div class="items-center flex gap-1 min-w-[60px]"> <td
<div key="row-index"
v-if="!readOnly || !isLocked || isMobileMode" class="caption nc-grid-cell pl-5 pr-1"
class="nc-row-no sm:min-w-4 text-xs text-gray-500" :data-testid="`cell-Id-${rowIndex}`"
:class="{ toggle: !readOnly, hidden: row.rowMeta.selected }" @contextmenu="contextMenuTarget = null"
> >
{{ ((paginationDataRef?.page ?? 1) - 1) * (paginationDataRef?.pageSize ?? 25) + rowIndex + 1 }} <div class="items-center flex gap-1 min-w-[60px]">
</div> <div
<div v-if="!readOnly || !isLocked || isMobileMode"
v-if="!readOnly" class="nc-row-no sm:min-w-4 text-xs text-gray-500"
:class="{ hidden: !row.rowMeta.selected, flex: row.rowMeta.selected }" :class="{ toggle: !readOnly, hidden: row.rowMeta.selected }"
class="nc-row-expand-and-checkbox" >
> {{ ((paginationDataRef?.page ?? 1) - 1) * (paginationDataRef?.pageSize ?? 25) + rowIndex + 1 }}
<a-checkbox v-model:checked="row.rowMeta.selected" /> </div>
<div
v-if="!readOnly"
:class="{ hidden: !row.rowMeta.selected, flex: row.rowMeta.selected }"
class="nc-row-expand-and-checkbox"
>
<a-checkbox v-model:checked="row.rowMeta.selected" />
</div>
<span class="flex-1" />
<div
v-if="isUIAllowed('expandedForm')"
class="nc-expand"
:data-testid="`nc-expand-${rowIndex}`"
:class="{ 'nc-comment': row.rowMeta?.commentCount }"
>
<a-spin
v-if="row.rowMeta.saving"
class="!flex items-center"
:data-testid="`row-save-spinner-${rowIndex}`"
/>
<template v-else-if="!isLocked">
<span
v-if="row.rowMeta?.commentCount && expandForm"
v-e="['c:expanded-form:open']"
class="py-1 px-3 rounded-full text-xs cursor-pointer select-none transform hover:(scale-110)"
:style="{ backgroundColor: enumColor.light[row.rowMeta.commentCount % enumColor.light.length] }"
@click="expandAndLooseFocus(row, state)"
>
{{ row.rowMeta.commentCount }}
</span>
<div
v-else
class="cursor-pointer flex items-center border-1 border-gray-100 active:ring rounded p-1 hover:(bg-gray-50)"
>
<component
:is="iconMap.expand"
v-if="expandForm"
v-e="['c:row-expand:open']"
class="select-none transform hover:(text-black scale-120) nc-row-expand"
@click="expandAndLooseFocus(row, state)"
/>
</div>
</template>
</div>
</div> </div>
<span class="flex-1" /> </td>
<SmartsheetTableDataCell
v-for="(columnObj, colIndex) of fields"
:key="columnObj.id"
class="cell relative nc-grid-cell cursor-pointer"
:class="{
'active': isCellSelected(rowIndex, colIndex),
'active-cell':
(activeCell.row === rowIndex && activeCell.col === colIndex) ||
(selectedRange._start?.row === rowIndex && selectedRange._start?.col === colIndex),
'last-cell':
rowIndex === (isNaN(selectedRange.end.row) ? activeCell.row : selectedRange.end.row) &&
colIndex === (isNaN(selectedRange.end.col) ? activeCell.col : selectedRange.end.col),
'nc-required-cell': isColumnRequiredAndNull(columnObj, row.row) && !isPublicView,
'align-middle': !rowHeight || rowHeight === 1,
'align-top': rowHeight && rowHeight !== 1,
'filling': isCellInFillRange(rowIndex, colIndex),
'readonly':
(isLookup(columnObj) || isRollup(columnObj) || isFormula(columnObj)) &&
hasEditPermission &&
isCellSelected(rowIndex, colIndex),
'!border-r-blue-400 !border-r-3': toBeDroppedColId === columnObj.id,
}"
:style="{
'min-width': gridViewCols[columnObj.id]?.width || '200px',
'max-width': gridViewCols[columnObj.id]?.width || '200px',
'width': gridViewCols[columnObj.id]?.width || '200px',
}"
:data-testid="`cell-${columnObj.title}-${rowIndex}`"
:data-key="`data-key-${rowIndex}-${columnObj.id}`"
:data-col="columnObj.id"
:data-title="columnObj.title"
:data-row-index="rowIndex"
:data-col-index="colIndex"
@mousedown="handleMouseDown($event, rowIndex, colIndex)"
@mouseover="handleMouseOver($event, rowIndex, colIndex)"
@click="handleCellClick($event, rowIndex, colIndex)"
@dblclick="makeEditable(row, columnObj)"
@contextmenu="showContextMenu($event, { row: rowIndex, col: colIndex })"
>
<div v-if="!switchingTab" class="w-full h-full">
<LazySmartsheetVirtualCell
v-if="isVirtualCol(columnObj) && columnObj.title"
v-model="row.row[columnObj.title]"
:column="columnObj"
:active="activeCell.col === colIndex && activeCell.row === rowIndex"
:row="row"
:read-only="!hasEditPermission"
@navigate="onNavigate"
@save="updateOrSaveRow?.(row, '', state)"
/>
<div <LazySmartsheetCell
v-if="isUIAllowed('expandedForm')" v-else-if="columnObj.title"
class="nc-expand" v-model="row.row[columnObj.title]"
:data-testid="`nc-expand-${rowIndex}`" :column="columnObj"
:class="{ 'nc-comment': row.rowMeta?.commentCount }" :edit-enabled="
> !!hasEditPermission && !!editEnabled && activeCell.col === colIndex && activeCell.row === rowIndex
<a-spin "
v-if="row.rowMeta.saving" :row-index="rowIndex"
class="!flex items-center" :active="activeCell.col === colIndex && activeCell.row === rowIndex"
:data-testid="`row-save-spinner-${rowIndex}`" :read-only="!hasEditPermission"
@update:edit-enabled="editEnabled = $event"
@save="updateOrSaveRow?.(row, columnObj.title, state)"
@navigate="onNavigate"
@cancel="editEnabled = false"
/> />
<template v-else-if="!isLocked">
<span
v-if="row.rowMeta?.commentCount && expandForm"
v-e="['c:expanded-form:open']"
class="py-1 px-3 rounded-full text-xs cursor-pointer select-none transform hover:(scale-110)"
:style="{ backgroundColor: enumColor.light[row.rowMeta.commentCount % enumColor.light.length] }"
@click="expandAndLooseFocus(row, state)"
>
{{ row.rowMeta.commentCount }}
</span>
<div
v-else
class="cursor-pointer flex items-center border-1 border-gray-100 active:ring rounded p-1 hover:(bg-gray-50)"
>
<component
:is="iconMap.expand"
v-if="expandForm"
v-e="['c:row-expand:open']"
class="select-none transform hover:(text-black scale-120) nc-row-expand"
@click="expandAndLooseFocus(row, state)"
/>
</div>
</template>
</div> </div>
</div> </SmartsheetTableDataCell>
</td> </tr>
<SmartsheetTableDataCell </template>
v-for="(columnObj, colIndex) of fields" </LazySmartsheetRow>
:key="columnObj.id" </template>
class="cell relative nc-grid-cell cursor-pointer"
:class="{
'active': isCellSelected(rowIndex, colIndex),
'active-cell':
(activeCell.row === rowIndex && activeCell.col === colIndex) ||
(selectedRange._start?.row === rowIndex && selectedRange._start?.col === colIndex),
'last-cell':
rowIndex === (isNaN(selectedRange.end.row) ? activeCell.row : selectedRange.end.row) &&
colIndex === (isNaN(selectedRange.end.col) ? activeCell.col : selectedRange.end.col),
'nc-required-cell': isColumnRequiredAndNull(columnObj, row.row) && !isPublicView,
'align-middle': !rowHeight || rowHeight === 1,
'align-top': rowHeight && rowHeight !== 1,
'filling': isCellInFillRange(rowIndex, colIndex),
'readonly':
(isLookup(columnObj) || isRollup(columnObj) || isFormula(columnObj)) &&
hasEditPermission &&
isCellSelected(rowIndex, colIndex),
'!border-r-blue-400 !border-r-3': toBeDroppedColId === columnObj.id,
}"
:style="{
'min-width': gridViewCols[columnObj.id]?.width || '200px',
'max-width': gridViewCols[columnObj.id]?.width || '200px',
'width': gridViewCols[columnObj.id]?.width || '200px',
}"
:data-testid="`cell-${columnObj.title}-${rowIndex}`"
:data-key="`data-key-${rowIndex}-${columnObj.id}`"
:data-col="columnObj.id"
:data-title="columnObj.title"
:data-row-index="rowIndex"
:data-col-index="colIndex"
@mousedown="handleMouseDown($event, rowIndex, colIndex)"
@mouseover="handleMouseOver($event, rowIndex, colIndex)"
@click="handleCellClick($event, rowIndex, colIndex)"
@dblclick="makeEditable(row, columnObj)"
@contextmenu="showContextMenu($event, { row: rowIndex, col: colIndex })"
>
<div v-if="!switchingTab" class="w-full h-full">
<LazySmartsheetVirtualCell
v-if="isVirtualCol(columnObj) && columnObj.title"
v-model="row.row[columnObj.title]"
:column="columnObj"
:active="activeCell.col === colIndex && activeCell.row === rowIndex"
:row="row"
:read-only="!hasEditPermission"
@navigate="onNavigate"
@save="updateOrSaveRow?.(row, '', state)"
/>
<LazySmartsheetCell
v-else-if="columnObj.title"
v-model="row.row[columnObj.title]"
:column="columnObj"
:edit-enabled="
!!hasEditPermission && !!editEnabled && activeCell.col === colIndex && activeCell.row === rowIndex
"
:row-index="rowIndex"
:active="activeCell.col === colIndex && activeCell.row === rowIndex"
:read-only="!hasEditPermission"
@update:edit-enabled="editEnabled = $event"
@save="updateOrSaveRow?.(row, columnObj.title, state)"
@navigate="onNavigate"
@cancel="editEnabled = false"
/>
</div>
</SmartsheetTableDataCell>
</tr>
</template>
</LazySmartsheetRow>
<tr <tr
v-if="isAddingEmptyRowAllowed && !isGroupBy" v-if="isAddingEmptyRowAllowed && !isGroupBy"

Loading…
Cancel
Save