|
|
|
<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'
|
|
|
|
|
|
|
|
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.5 flex-1 items-center truncate items-center h-full">
|
|
|
|
<component :is="option.icon" class="!w-3.5 !h-3.5 !mx-0 !text-gray-500" />
|
|
|
|
<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>
|