多维表格
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.
 
 
 
 
 
 

125 lines
4.1 KiB

<script setup lang="ts">
import type { SelectProps } from 'ant-design-vue'
import type { ColumnType, LinkToAnotherRecordType } from 'nocodb-sdk'
import { RelationTypes, UITypes, isHiddenCol, isLinksOrLTAR, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { MetaInj, computed, inject, ref, resolveComponent, useViewColumnsOrThrow } from '#imports'
const { modelValue, isSort, allowEmpty, ...restProps } = defineProps<{
modelValue?: string
isSort?: boolean
columns?: ColumnType[]
allowEmpty?: boolean
}>()
const emit = defineEmits(['update:modelValue'])
const customColumns = toRef(restProps, 'columns')
const meta = inject(MetaInj, ref())
const localValue = computed({
get: () => modelValue,
set: (val) => emit('update:modelValue', val),
})
const { showSystemFields, metaColumnById } = useViewColumnsOrThrow()
const options = computed<SelectProps['options']>(() =>
(
customColumns.value?.filter((c: ColumnType) => {
if (isSystemColumn(metaColumnById?.value?.[c.id!])) {
if (isHiddenCol(c)) {
/** ignore mm relation column, created by and last modified by system field */
return false
}
}
return true
}) ||
meta.value?.columns?.filter((c: ColumnType) => {
if (c.uidt === UITypes.Links) {
return true
}
if (isSystemColumn(metaColumnById?.value?.[c.id!])) {
if (isHiddenCol(c)) {
/** ignore mm relation column, created by and last modified by system field */
return false
}
return (
/** if the field is used in filter, then show it anyway */
localValue.value === c.id ||
/** hide system columns if not enabled */
showSystemFields.value
)
} else if (c.uidt === UITypes.QrCode || c.uidt === UITypes.Barcode || c.uidt === UITypes.ID) {
return false
} else if (isSort) {
/** ignore hasmany and manytomany relations if it's using within sort menu */
return !(isLinksOrLTAR(c) && (c.colOptions as LinkToAnotherRecordType).type !== RelationTypes.BELONGS_TO)
/** ignore virtual fields which are system fields ( mm relation ) and qr code fields */
} else {
const isVirtualSystemField = c.colOptions && c.system
return !isVirtualSystemField
}
})
)?.map((c: ColumnType) => ({
value: c.id,
label: c.title,
icon: h(
isVirtualCol(c) ? resolveComponent('SmartsheetHeaderVirtualCellIcon') : resolveComponent('SmartsheetHeaderCellIcon'),
{
columnMeta: c,
},
),
c,
})),
)
const filterOption = (input: string, option: any) => option.label.toLowerCase()?.includes(input.toLowerCase())
// when a new filter is created, select a field by default
if (!localValue.value && allowEmpty !== true) {
localValue.value = (options.value?.[0].value as string) || ''
}
</script>
<template>
<NcSelect
v-model:value="localValue"
:dropdown-match-select-width="false"
show-search
:placeholder="$t('placeholder.selectField')"
:filter-option="filterOption"
dropdown-class-name="nc-dropdown-toolbar-field-list"
>
<a-select-option v-for="option in options" :key="option.value" :label="option.label" :value="option.value">
<div class="flex items-center w-full justify-between w-full gap-2 max-w-50">
<div class="flex gap-1 flex-1 items-center truncate items-center h-full">
<component :is="option.icon" class="min-w-5 !mx-0" />
<NcTooltip
:style="{ wordBreak: 'keep-all', whiteSpace: 'nowrap', display: 'inline' }"
class="max-w-[15rem] truncate select-none"
show-on-truncate-only
>
<template #title> {{ option.label }}</template>
<span>
{{ option.label }}
</span>
</NcTooltip>
</div>
<component
:is="iconMap.check"
v-if="localValue === option.value"
id="nc-selected-item-icon"
class="text-primary w-4 h-4"
/>
</div>
</a-select-option>
</NcSelect>
</template>
<style lang="scss">
.ant-select-selection-search-input {
box-shadow: none !important;
}
</style>