多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

202 lines
5.4 KiB

<script lang="ts" setup>
import type { ColumnType } from 'nocodb-sdk'
import {
ColumnInj,
Empty,
IsFormInj,
IsPublicInj,
Modal,
ReadonlyInj,
computed,
h,
inject,
ref,
useLTARStoreOrThrow,
useSmartsheetRowStoreOrThrow,
useVModel,
watch,
} from '#imports'
const props = defineProps<{ modelValue?: boolean; cellValue: any }>()
const emit = defineEmits(['update:modelValue', 'attachRecord'])
const vModel = useVModel(props, 'modelValue', emit)
const isForm = inject(IsFormInj, ref(false))
const isPublic = inject(IsPublicInj, ref(false))
const column = inject(ColumnInj)
const readonly = inject(ReadonlyInj, ref(false))
const {
childrenList,
deleteRelatedRow,
loadChildrenList,
childrenListPagination,
relatedTablePrimaryValueProp,
unlink,
getRelatedTableRowId,
relatedTableMeta,
} = useLTARStoreOrThrow()
const { isNew, state, removeLTARRef } = useSmartsheetRowStoreOrThrow()
watch(
[vModel, isForm],
(nextVal) => {
if ((nextVal[0] || nextVal[1]) && !isNew.value) {
loadChildrenList()
}
},
{ immediate: true },
)
const unlinkRow = async (row: Record<string, any>) => {
if (isNew.value) {
await removeLTARRef(row, column?.value as ColumnType)
} else {
await unlink(row)
await loadChildrenList()
}
}
const unlinkIfNewRow = async (row: Record<string, any>) => {
if (isNew.value) {
await removeLTARRef(row, column?.value as ColumnType)
}
}
const container = computed(() =>
isForm.value
? h('div', {
class: 'w-full p-2',
})
: Modal,
)
const expandedFormDlg = ref(false)
const expandedFormRow = ref()
/** reload children list whenever cell value changes and list is visible */
watch(
() => props.cellValue,
() => {
if (!isNew.value && vModel.value) loadChildrenList()
},
)
</script>
<template>
<component
:is="container"
v-model:visible="vModel"
:footer="null"
title="Child list"
:body-style="{ padding: 0 }"
wrap-class-name="nc-modal-child-list"
>
<div class="max-h-[max(calc(100vh_-_300px)_,500px)] flex flex-col py-6">
<div class="flex mb-4 items-center gap-2 px-12">
<div class="flex-1" />
<MdiReload
v-if="!isForm"
class="cursor-pointer text-gray-500"
data-testid="nc-child-list-reload"
@click="loadChildrenList"
/>
<a-button
v-if="!readonly"
type="primary"
ghost
class="!text-xs"
data-testid="nc-child-list-button-link-to"
size="small"
@click="emit('attachRecord')"
>
<div class="flex items-center gap-1">
<MdiLinkVariantRemove class="text-xs" type="primary" @click="unlinkRow(row)" />
Link to '{{ relatedTableMeta.title }}'
</div>
</a-button>
</div>
<template v-if="(isNew && state?.[column?.title]?.length) || childrenList?.pageInfo?.totalRows">
<div class="flex-1 overflow-auto min-h-0 scrollbar-thin-dull px-12 cursor-pointer">
<a-card
v-for="(row, i) of childrenList?.list ?? state?.[column?.title] ?? []"
:key="i"
class="!my-4 hover:(!bg-gray-200/50 shadow-md)"
@click="
() => {
if (readonly) return
expandedFormRow = row
expandedFormDlg = true
}
"
>
<div class="flex items-center">
<div class="flex-1 overflow-hidden min-w-0">
{{ row[relatedTablePrimaryValueProp] }}
<span class="text-gray-400 text-[11px] ml-1">(Primary key : {{ getRelatedTableRowId(row) }})</span>
</div>
<div v-if="!readonly" class="flex gap-2">
<MdiLinkVariantRemove
class="text-xs text-grey hover:(!text-red-500) cursor-pointer"
data-testid="nc-child-list-icon-unlink"
@click.stop="unlinkRow(row)"
/>
<MdiDeleteOutline
v-if="!readonly && !isPublic"
class="text-xs text-grey hover:(!text-red-500) cursor-pointer"
data-testid="nc-child-list-icon-delete"
@click.stop="deleteRelatedRow(row, unlinkIfNewRow)"
/>
</div>
</div>
</a-card>
</div>
<div class="flex justify-center mt-6">
<a-pagination
v-if="!isNew && childrenList?.pageInfo"
v-model:current="childrenListPagination.page"
v-model:page-size="childrenListPagination.size"
class="mt-2 mx-auto"
size="small"
:total="childrenList.pageInfo.totalRows"
show-less-items
/>
</div>
</template>
<a-empty
v-else
:class="{ 'my-10': !isForm, 'my-1 !text-xs': isForm }"
:image="Empty.PRESENTED_IMAGE_SIMPLE"
:image-style="isForm ? { height: '20px' } : {}"
/>
</div>
<Suspense>
<LazySmartsheetExpandedForm
v-if="expandedFormRow && expandedFormDlg"
v-model="expandedFormDlg"
:row="{ row: expandedFormRow, oldRow: expandedFormRow, rowMeta: {} }"
:meta="relatedTableMeta"
load-row
use-meta-fields
/>
</Suspense>
</component>
</template>
<style scoped lang="scss">
:deep(.ant-pagination-item a) {
line-height: 21px !important;
}
</style>