Browse Source

refactor(nc-gui): remove useColumn and useVirtualCell

pull/3847/head
braks 2 years ago
parent
commit
9daa6d8b47
  1. 37
      packages/nc-gui/components/smartsheet/VirtualCell.vue
  2. 140
      packages/nc-gui/components/smartsheet/header/CellIcon.ts
  3. 89
      packages/nc-gui/components/smartsheet/header/CellIcon.vue
  4. 27
      packages/nc-gui/components/smartsheet/header/VirtualCell.vue
  5. 10
      packages/nc-gui/components/smartsheet/header/VirtualCellIcon.vue
  6. 22
      packages/nc-gui/components/virtual-cell/Lookup.vue
  7. 53
      packages/nc-gui/composables/useColumn.ts
  8. 24
      packages/nc-gui/composables/useVirtualCell.ts

37
packages/nc-gui/components/smartsheet/VirtualCell.vue

@ -1,8 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import { ActiveCellInj, CellValueInj, ColumnInj, IsFormInj, RowInj, inject, provide, ref, toRef, useVirtualCell } from '#imports' import {
ActiveCellInj,
CellValueInj,
ColumnInj,
FormInj,
RowInj,
computed,
isBt,
isCount,
isFormula,
isHm,
isLookup,
isMm,
isRollup,
provide,
toRef,
} from '#imports'
import type { Row } from '~/lib' import type { Row } from '~/lib'
import { NavigateDir } from '~/lib' import { NavigateDir } from '~/lib'
import HasMany from '~/components/virtual-cell/HasMany.vue'
import ManyToMany from '~/components/virtual-cell/ManyToMany.vue'
import BelongsTo from '~/components/virtual-cell/BelongsTo.vue'
import Lookup from '~/components/virtual-cell/Lookup.vue'
import Rollup from '~/components/virtual-cell/Rollup.vue'
import Formula from '~/components/virtual-cell/Formula.vue'
import Count from '~/components/virtual-cell/Count.vue'
const props = defineProps<{ const props = defineProps<{
column: ColumnType column: ColumnType
@ -24,7 +47,17 @@ provide(CellValueInj, toRef(props, 'modelValue'))
const isForm = inject(IsFormInj, ref(false)) const isForm = inject(IsFormInj, ref(false))
const virtualCell = useVirtualCell(column) const virtualCell = computed(() => {
if (!column.value) return null
if (isHm(column.value)) return HasMany
if (isMm(column.value)) return ManyToMany
if (isBt(column.value)) return BelongsTo
if (isLookup(column.value)) return Lookup
if (isRollup(column.value)) return Rollup
if (isFormula(column.value)) return Formula
if (isCount(column.value)) return Count
})
function onNavigate(dir: NavigateDir, e: KeyboardEvent) { function onNavigate(dir: NavigateDir, e: KeyboardEvent) {
emit('navigate', dir) emit('navigate', dir)

140
packages/nc-gui/components/smartsheet/header/CellIcon.ts

@ -0,0 +1,140 @@
import type { ColumnType } from 'nocodb-sdk'
import type { PropType } from '@vue/runtime-core'
import { SqlUiFactory, isVirtualCol } from 'nocodb-sdk'
import {
ColumnInj,
computed,
defineComponent,
h,
inject,
isAttachment,
isBoolean,
isCurrency,
isDate,
isDateTime,
isDecimal,
isDuration,
isEmail,
isFloat,
isInt,
isJSON,
isPercent,
isPhoneNumber,
isPrimary,
isRating,
isSet,
isSingleSelect,
isSpecificDBType,
isString,
isTextArea,
isTime,
isURL,
isYear,
toRef,
useProject,
} from '#imports'
import FilePhoneIcon from '~icons/mdi/file-phone'
import KeyIcon from '~icons/mdi/key-variant'
import JSONIcon from '~icons/mdi/code-json'
import ClockIcon from '~icons/mdi/clock-time-five'
import WebIcon from '~icons/mdi/web'
import TextAreaIcon from '~icons/mdi/card-text-outline'
import StringIcon from '~icons/mdi/alpha-a-box-outline'
import BooleanIcon from '~icons/mdi/check-box-outline'
import CalendarIcon from '~icons/mdi/calendar'
import SingleSelectIcon from '~icons/mdi/arrow-down-drop-circle'
import MultiSelectIcon from '~icons/mdi/format-list-bulleted-square'
import DatetimeIcon from '~icons/mdi/calendar-clock'
import RatingIcon from '~icons/mdi/star'
import GenericIcon from '~icons/mdi/square-rounded'
import NumericIcon from '~icons/mdi/numeric'
import AttachmentIcon from '~icons/mdi/image-multiple-outline'
import EmailIcon from '~icons/mdi/email'
import CurrencyIcon from '~icons/mdi/currency-usd-circle-outline'
import PercentIcon from '~icons/mdi/percent-outline'
import DecimalIcon from '~icons/mdi/decimal'
import SpecificDBTypeIcon from '~icons/mdi/database-settings'
import DurationIcon from '~icons/mdi/timer-outline'
const renderIcon = (column: ColumnType, abstractType: any) => {
if (isPrimary(column)) {
return KeyIcon
} else if (isJSON(column)) {
return JSONIcon
} else if (isDate(column, abstractType)) {
return CalendarIcon
} else if (isDateTime(column, abstractType)) {
return DatetimeIcon
} else if (isSet(column)) {
return MultiSelectIcon
} else if (isSingleSelect(column)) {
return SingleSelectIcon
} else if (isBoolean(column)) {
return BooleanIcon
} else if (isTextArea(column)) {
return TextAreaIcon
} else if (isEmail(column)) {
return EmailIcon
} else if (isYear(column, abstractType)) {
return CalendarIcon
} else if (isTime(column, abstractType)) {
return ClockIcon
} else if (isRating(column)) {
return RatingIcon
} else if (isAttachment(column)) {
return AttachmentIcon
} else if (isDecimal(column)) {
return DecimalIcon
} else if (isPhoneNumber(column)) {
return FilePhoneIcon
} else if (isURL(column)) {
return WebIcon
} else if (isCurrency(column)) {
return CurrencyIcon
} else if (isDuration(column)) {
return DurationIcon
} else if (isPercent(column)) {
return PercentIcon
} else if (isInt(column, abstractType) || isFloat(column, abstractType)) {
return NumericIcon
} else if (isString(column, abstractType)) {
return StringIcon
} else if (isSpecificDBType(column)) {
return SpecificDBTypeIcon
} else {
return GenericIcon
}
}
export default defineComponent({
name: 'CellIcon',
props: {
columnMeta: {
type: Object as PropType<ColumnType>,
required: false,
},
},
setup(props) {
const columnMeta = toRef(props, 'columnMeta')
const column = inject(ColumnInj, columnMeta)
const { project } = useProject()
const abstractType = computed(() => {
// kludge: CY test hack; column is being received NULL during attach cell delete operation
return (column.value && isVirtualCol(column.value)) || !column.value
? null
: SqlUiFactory.create(
project.value?.bases?.[0]?.type ? { client: project.value.bases[0].type } : { client: 'mysql2' },
).getAbstractType(column.value)
})
return () => {
if (!column.value) return null
return h(renderIcon(column.value, abstractType.value), { class: 'text-grey mx-1 !text-sm' })
}
},
})

89
packages/nc-gui/components/smartsheet/header/CellIcon.vue

@ -1,89 +0,0 @@
<script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import { ColumnInj, computed, inject, toRef, useColumn } from '#imports'
import FilePhoneIcon from '~icons/mdi/file-phone'
import KeyIcon from '~icons/mdi/key-variant'
import JSONIcon from '~icons/mdi/code-json'
import ClockIcon from '~icons/mdi/clock-time-five'
import WebIcon from '~icons/mdi/web'
import TextAreaIcon from '~icons/mdi/card-text-outline'
import StringIcon from '~icons/mdi/alpha-a-box-outline'
import BooleanIcon from '~icons/mdi/check-box-outline'
import CalendarIcon from '~icons/mdi/calendar'
import SingleSelectIcon from '~icons/mdi/arrow-down-drop-circle'
import MultiSelectIcon from '~icons/mdi/format-list-bulleted-square'
import DatetimeIcon from '~icons/mdi/calendar-clock'
import RatingIcon from '~icons/mdi/star'
import GenericIcon from '~icons/mdi/square-rounded'
import NumericIcon from '~icons/mdi/numeric'
import AttachmentIcon from '~icons/mdi/image-multiple-outline'
import EmailIcon from '~icons/mdi/email'
import CurrencyIcon from '~icons/mdi/currency-usd-circle-outline'
import PercentIcon from '~icons/mdi/percent-outline'
import DecimalIcon from '~icons/mdi/decimal'
import SpecificDBTypeIcon from '~icons/mdi/database-settings'
import DurationIcon from '~icons/mdi/timer-outline'
const props = defineProps<{ columnMeta?: ColumnType }>()
const columnMeta = toRef(props, 'columnMeta')
const column = inject(ColumnInj, columnMeta)
const additionalColMeta = useColumn(column as Ref<ColumnType>)
const icon = computed(() => {
if (column?.value?.pk) {
return KeyIcon
} else if (additionalColMeta.isJSON.value) {
return JSONIcon
} else if (additionalColMeta.isDate.value) {
return CalendarIcon
} else if (additionalColMeta.isDateTime.value) {
return DatetimeIcon
} else if (additionalColMeta.isSet.value) {
return MultiSelectIcon
} else if (additionalColMeta.isSingleSelect.value) {
return SingleSelectIcon
} else if (additionalColMeta.isBoolean.value) {
return BooleanIcon
} else if (additionalColMeta.isTextArea.value) {
return TextAreaIcon
} else if (additionalColMeta.isEmail.value) {
return EmailIcon
} else if (additionalColMeta.isYear.value) {
return CalendarIcon
} else if (additionalColMeta.isTime.value) {
return ClockIcon
} else if (additionalColMeta.isRating.value) {
return RatingIcon
} else if (additionalColMeta.isAttachment.value) {
return AttachmentIcon
} else if (additionalColMeta.isDecimal.value) {
return DecimalIcon
} else if (additionalColMeta.isPhoneNumber.value) {
return FilePhoneIcon
} else if (additionalColMeta.isURL.value) {
return WebIcon
} else if (additionalColMeta.isCurrency.value) {
return CurrencyIcon
} else if (additionalColMeta.isDuration.value) {
return DurationIcon
} else if (additionalColMeta.isPercent.value) {
return PercentIcon
} else if (additionalColMeta.isInt.value || additionalColMeta.isFloat.value) {
return NumericIcon
} else if (additionalColMeta.isString.value) {
return StringIcon
} else if (additionalColMeta.isSpecificDBType.value) {
return SpecificDBTypeIcon
} else {
return GenericIcon
}
})
</script>
<template>
<component :is="icon" class="text-grey mx-1 !text-xs" />
</template>

27
packages/nc-gui/components/smartsheet/header/VirtualCell.vue

@ -7,6 +7,12 @@ import {
MetaInj, MetaInj,
computed, computed,
inject, inject,
isBt,
isFormula,
isHm,
isLookup,
isMm,
isRollup,
isVirtualColRequired, isVirtualColRequired,
provide, provide,
ref, ref,
@ -14,7 +20,6 @@ import {
useI18n, useI18n,
useMetas, useMetas,
useUIPermission, useUIPermission,
useVirtualCell,
} from '#imports' } from '#imports'
const props = defineProps<{ column: ColumnType; hideMenu?: boolean; required?: boolean | number }>() const props = defineProps<{ column: ColumnType; hideMenu?: boolean; required?: boolean | number }>()
@ -37,14 +42,12 @@ const meta = inject(MetaInj, ref())
const isForm = inject(IsFormInj, ref(false)) const isForm = inject(IsFormInj, ref(false))
const { isLookup, isBt, isRollup, isMm, isHm, isFormula } = useVirtualCell(column)
const colOptions = $computed(() => column.value?.colOptions) const colOptions = $computed(() => column.value?.colOptions)
const tableTile = $computed(() => meta?.value?.title) const tableTile = $computed(() => meta?.value?.title)
const relationColumnOptions = $computed<LinkToAnotherRecordType | null>(() => { const relationColumnOptions = $computed<LinkToAnotherRecordType | null>(() => {
if (isMm.value || isHm.value || isBt.value) { if (isMm(column.value) || isHm(column.value) || isBt(column.value)) {
return column.value?.colOptions as LinkToAnotherRecordType return column.value?.colOptions as LinkToAnotherRecordType
} else if ((column?.value?.colOptions as LookupType | RollupType)?.fk_relation_column_id) { } else if ((column?.value?.colOptions as LookupType | RollupType)?.fk_relation_column_id) {
return meta?.value?.columns?.find( return meta?.value?.columns?.find(
@ -62,10 +65,10 @@ const relatedTableTitle = $computed(() => relatedTableMeta?.title)
const childColumn = $computed(() => { const childColumn = $computed(() => {
if (relatedTableMeta?.columns) { if (relatedTableMeta?.columns) {
if (isRollup.value) { if (isRollup(column.value)) {
return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as RollupType).fk_rollup_column_id) return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as RollupType).fk_rollup_column_id)
} }
if (isLookup.value) { if (isLookup(column.value)) {
return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as LookupType).fk_lookup_column_id) return relatedTableMeta?.columns.find((c: ColumnType) => c.id === (colOptions as LookupType).fk_lookup_column_id)
} }
} }
@ -76,22 +79,22 @@ const tooltipMsg = computed(() => {
if (!column.value) { if (!column.value) {
return '' return ''
} }
if (isHm.value) { if (isHm(column.value)) {
return `'${tableTile}' ${t('labels.hasMany')} '${relatedTableTitle}'` return `'${tableTile}' ${t('labels.hasMany')} '${relatedTableTitle}'`
} else if (isMm.value) { } else if (isMm(column.value)) {
return `'${tableTile}' & '${relatedTableTitle}' ${t('labels.manyToMany')}` return `'${tableTile}' & '${relatedTableTitle}' ${t('labels.manyToMany')}`
} else if (isBt.value) { } else if (isBt(column.value)) {
return `'${column?.value?.title}' ${t('labels.belongsTo')} '${relatedTableTitle}'` return `'${column?.value?.title}' ${t('labels.belongsTo')} '${relatedTableTitle}'`
} else if (isLookup.value) { } else if (isLookup(column.value)) {
return `'${childColumn.title}' from '${relatedTableTitle}' (${childColumn.uidt})` return `'${childColumn.title}' from '${relatedTableTitle}' (${childColumn.uidt})`
} else if (isFormula.value) { } else if (isFormula(column.value)) {
const formula = substituteColumnIdWithAliasInFormula( const formula = substituteColumnIdWithAliasInFormula(
(column.value?.colOptions as FormulaType)?.formula, (column.value?.colOptions as FormulaType)?.formula,
meta?.value?.columns as ColumnType[], meta?.value?.columns as ColumnType[],
(column.value?.colOptions as any)?.formula_raw, (column.value?.colOptions as any)?.formula_raw,
) )
return `Formula - ${formula}` return `Formula - ${formula}`
} else if (isRollup.value) { } else if (isRollup(column.value)) {
return `'${childColumn.title}' of '${relatedTableTitle}' (${childColumn.uidt})` return `'${childColumn.title}' of '${relatedTableTitle}' (${childColumn.uidt})`
} }
return '' return ''

10
packages/nc-gui/components/smartsheet/header/VirtualCellIcon.vue

@ -2,7 +2,7 @@
import type { ColumnType, LinkToAnotherRecordType, LookupType } from 'nocodb-sdk' import type { ColumnType, LinkToAnotherRecordType, LookupType } from 'nocodb-sdk'
import { RelationTypes, UITypes } from 'nocodb-sdk' import { RelationTypes, UITypes } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { ColumnInj, inject, ref, toRef } from '#imports' import { ColumnInj, MetaInj, computed, inject, isBt, isHm, isLookup, isMm, isRollup, ref, toRef } from '#imports'
import GenericIcon from '~icons/mdi/square-rounded' import GenericIcon from '~icons/mdi/square-rounded'
import HMIcon from '~icons/mdi/table-arrow-right' import HMIcon from '~icons/mdi/table-arrow-right'
import BTIcon from '~icons/mdi/table-arrow-left' import BTIcon from '~icons/mdi/table-arrow-left'
@ -22,9 +22,7 @@ const column = inject(ColumnInj, ref(columnMeta)) as Ref<ColumnType & { colOptio
let relationColumn: ColumnType & { colOptions: LookupType } let relationColumn: ColumnType & { colOptions: LookupType }
if (column) { if (column) {
const { isLookup, isBt, isRollup, isMm, isHm } = useVirtualCell(column as Ref<ColumnType>) if (isLookup(column.value) || isBt(column.value) || isRollup(column.value) || isMm(column.value) || isHm(column.value)) {
if (isLookup || isBt || isRollup || isMm || isHm) {
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())
relationColumn = meta.value?.columns?.find((c) => c.id === column.value?.colOptions?.fk_relation_column_id) as ColumnType & { relationColumn = meta.value?.columns?.find((c) => c.id === column.value?.colOptions?.fk_relation_column_id) as ColumnType & {
@ -34,9 +32,9 @@ if (column) {
} }
const icon = computed(() => { const icon = computed(() => {
switch (column?.value?.uidt) { switch (column.value?.uidt) {
case UITypes.LinkToAnotherRecord: case UITypes.LinkToAnotherRecord:
switch ((column?.value?.colOptions as LinkToAnotherRecordType)?.type) { switch ((column.value?.colOptions as LinkToAnotherRecordType)?.type) {
case RelationTypes.MANY_TO_MANY: case RelationTypes.MANY_TO_MANY:
return { icon: MMIcon, color: 'text-accent' } return { icon: MMIcon, color: 'text-accent' }
case RelationTypes.HAS_MANY: case RelationTypes.HAS_MANY:

22
packages/nc-gui/components/virtual-cell/Lookup.vue

@ -10,9 +10,12 @@ import {
ReadonlyInj, ReadonlyInj,
computed, computed,
inject, inject,
isAttachment,
provide, provide,
refAutoReset, refAutoReset,
ref,
useMetas, useMetas,
watch,
} from '#imports' } from '#imports'
const { metas, getMeta } = useMetas() const { metas, getMeta } = useMetas()
@ -27,13 +30,22 @@ const value = inject(CellValueInj)
const arrValue = computed(() => (Array.isArray(value?.value) ? value?.value : [value?.value]) ?? []) const arrValue = computed(() => (Array.isArray(value?.value) ? value?.value : [value?.value]) ?? [])
const relationColumn = meta.value?.columns?.find((c) => c.id === column.value.colOptions?.fk_relation_column_id) as ColumnType & { const relationColumn = computed(
colOptions: LinkToAnotherRecordType () =>
} meta.value?.columns?.find((c) => c.id === column.value.colOptions?.fk_relation_column_id) as ColumnType & {
colOptions: LinkToAnotherRecordType
},
)
await getMeta(relationColumn.colOptions.fk_related_model_id!) watch(
relationColumn,
async () => {
await getMeta(relationColumn.value.colOptions.fk_related_model_id!)
},
{ immediate: true },
)
const lookupTableMeta = computed(() => metas.value[relationColumn.colOptions.fk_related_model_id!]) const lookupTableMeta = computed(() => metas.value[relationColumn.value.colOptions.fk_related_model_id!])
const lookupColumn = computed<any>( const lookupColumn = computed<any>(
() => () =>

53
packages/nc-gui/composables/useColumn.ts

@ -1,53 +0,0 @@
import type { ColumnType } from 'nocodb-sdk'
import { SqlUiFactory, UITypes, isVirtualCol } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue'
import { computed, dataTypeLow, isBoolean, isPrimary, isString, isTextArea, useProject } from '#imports'
export function useColumn(column: Ref<ColumnType | undefined>) {
const { project } = useProject()
const data = computed(() => {
if (!column.value) return null
const abstractType = computed(() => {
// kludge: CY test hack; column.value is being received NULL during attach cell delete operation
return (column.value && isVirtualCol(column.value)) || !column.value
? null
: SqlUiFactory.create(
project.value?.bases?.[0]?.type ? { client: project.value.bases[0].type } : { client: 'mysql2' },
).getAbstractType(column.value)
})
return {
abstractType,
dataTypeLow: dataTypeLow(column.value),
isPrimary: isPrimary(column.value),
isBoolean: isBoolean(abstractType.value),
isString: isString(column.value, abstractType.value),
isTextArea: isTextArea(column.value),
isInt,
isFloat,
isDate,
isYear,
isTime,
isDateTime,
isJSON,
isEnum,
isSet,
isURL,
isEmail,
isAttachment,
isRating,
isCurrency,
isDecimal,
isDuration,
isAutoSaved,
isManualSaved,
isSingleSelect,
isMultiSelect,
isPercent,
isPhoneNumber,
isSpecificDBType,
}
})
}

24
packages/nc-gui/composables/useVirtualCell.ts

@ -1,24 +0,0 @@
import type { ColumnType } from 'nocodb-sdk'
import type { Ref } from 'vue'
import { computed, isBt, isCount, isFormula, isHm, isLookup, isMm, isRollup } from '#imports'
import HasMany from '~/components/virtual-cell/HasMany.vue'
import ManyToMany from '~/components/virtual-cell/ManyToMany.vue'
import BelongsTo from '~/components/virtual-cell/BelongsTo.vue'
import Lookup from '~/components/virtual-cell/Lookup.vue'
import Rollup from '~/components/virtual-cell/Rollup.vue'
import Formula from '~/components/virtual-cell/Formula.vue'
import Count from '~/components/virtual-cell/Count.vue'
export function useVirtualCell(column: Ref<ColumnType | undefined>) {
return computed(() => {
if (!column.value) return null
if (isHm(column.value)) return HasMany
if (isMm(column.value)) return ManyToMany
if (isBt(column.value)) return BelongsTo
if (isLookup(column.value)) return Lookup
if (isRollup(column.value)) return Rollup
if (isFormula(column.value)) return Formula
if (isCount(column.value)) return Count
})
}
Loading…
Cancel
Save