Browse Source

fix(nc-gui): field followup

pull/7673/head
DarkPhoenix2704 10 months ago
parent
commit
c49671cacc
  1. 2
      packages/nc-gui/components/nc/Select.vue
  2. 52
      packages/nc-gui/components/smartsheet/calendar/DayView/DateField.vue
  3. 52
      packages/nc-gui/components/smartsheet/calendar/DayView/DateTimeField.vue
  4. 66
      packages/nc-gui/components/smartsheet/calendar/MonthView.vue
  5. 13
      packages/nc-gui/components/smartsheet/calendar/RecordCard.vue
  6. 9
      packages/nc-gui/components/smartsheet/calendar/VRecordCard.vue
  7. 54
      packages/nc-gui/components/smartsheet/calendar/WeekView/DateField.vue
  8. 52
      packages/nc-gui/components/smartsheet/calendar/WeekView/DateTimeField.vue
  9. 4
      packages/nc-gui/components/smartsheet/calendar/index.vue
  10. 37
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  11. 13
      packages/nc-gui/composables/useViewColumns.ts
  12. 3
      packages/nc-gui/lib/types.ts
  13. 6
      packages/nc-gui/utils/iconUtils.ts
  14. 13
      packages/nocodb/src/models/View.ts

2
packages/nc-gui/components/nc/Select.vue

@ -82,7 +82,7 @@ const onChange = (value: string) => {
height: fit-content; height: fit-content;
.ant-select-selector { .ant-select-selector {
box-shadow: 0px 5px 3px -2px rgba(0, 0, 0, 0.02), 0px 3px 1px -2px rgba(0, 0, 0, 0.06); box-shadow: 0px 5px 3px -2px rgba(0, 0, 0, 0.02), 0px 3px 1px -2px rgba(0, 0, 0, 0.06);
@apply border-1 border-gray-200 !rounded-lg; @apply border-1 border-gray-200 rounded-lg;
} }
.ant-select-selection-item { .ant-select-selection-item {

52
packages/nc-gui/components/smartsheet/calendar/DayView/DateField.vue

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import { type Row, computed, ref } from '#imports' import { type Row, computed, isPrimary, ref, useViewColumnsOrThrow } from '#imports'
import { isRowEmpty } from '~/utils' import { isRowEmpty } from '~/utils'
const emit = defineEmits(['expand-record', 'new-record']) const emit = defineEmits(['expand-record', 'new-record'])
@ -15,6 +15,22 @@ const { isUIAllowed } = useRoles()
const { selectedDate, formattedData, formattedSideBarData, calendarRange, updateRowProperty, displayField } = const { selectedDate, formattedData, formattedSideBarData, calendarRange, updateRowProperty, displayField } =
useCalendarViewStoreOrThrow() useCalendarViewStoreOrThrow()
const fields = inject(FieldsInj, ref())
const { fields: _fields } = useViewColumnsOrThrow()
const getFieldStyle = (field: ColumnType) => {
const fi = _fields.value.find((f) => f.title === field.title)
return {
underline: fi.underline,
bold: fi.bold,
italic: fi.italic,
}
}
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
// We loop through all the records and calculate the position of each record based on the range // We loop through all the records and calculate the position of each record based on the range
// We only need to calculate the top, of the record since there is no overlap in the day view of date Field // We only need to calculate the top, of the record since there is no overlap in the day view of date Field
const recordsAcrossAllRange = computed<Row[]>(() => { const recordsAcrossAllRange = computed<Row[]>(() => {
@ -196,27 +212,25 @@ const dropEvent = (event: DragEvent) => {
@click="emit('expand-record', record)" @click="emit('expand-record', record)"
> >
<template v-if="!isRowEmpty(record, displayField)"> <template v-if="!isRowEmpty(record, displayField)">
<div <LazySmartsheetCalendarCell
:class="{ v-if="!isRowEmpty(record, displayField!)"
'!mt-1.5 ml-1': displayField.uidt === UITypes.SingleLineText,
'!mt-1': displayField.uidt === UITypes.MultiSelect || displayField.uidt === UITypes.SingleSelect,
}"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField!)"
v-model="record.row[displayField!.title!]" v-model="record.row[displayField!.title!]"
:bold="getFieldStyle(displayField).bold"
:column="displayField" :column="displayField"
:row="record" :italic="getFieldStyle(displayField).italic"
:underline="getFieldStyle(displayField).underline"
/> />
</template>
<LazySmartsheetCell <template v-for="(field, id) in fieldsWithoutDisplay">
v-else <LazySmartsheetCalendarCell
v-model="record.row[displayField!.title!]" v-if="!isRowEmpty(record, field)"
:column="displayField" :key="id"
:edit-enabled="false" v-model="record.row[field!.title!]"
:read-only="true" :bold="getFieldStyle(field).bold"
:column="field"
:italic="getFieldStyle(field).italic"
:underline="getFieldStyle(field).underline"
/> />
</div>
</template> </template>
</LazySmartsheetCalendarRecordCard> </LazySmartsheetCalendarRecordCard>
</LazySmartsheetRow> </LazySmartsheetRow>

52
packages/nc-gui/components/smartsheet/calendar/DayView/DateTimeField.vue

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import { type Row, computed, ref } from '#imports' import { type Row, computed, isPrimary, ref, useViewColumnsOrThrow } from '#imports'
import { generateRandomNumber, isRowEmpty } from '~/utils' import { generateRandomNumber, isRowEmpty } from '~/utils'
const emit = defineEmits(['expandRecord', 'new-record']) const emit = defineEmits(['expandRecord', 'new-record'])
@ -24,6 +24,22 @@ const { isUIAllowed } = useRoles()
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())
const fields = inject(FieldsInj, ref())
const { fields: _fields } = useViewColumnsOrThrow()
const getFieldStyle = (field: ColumnType) => {
const fi = _fields.value.find((f) => f.title === field.title)
return {
underline: fi.underline,
bold: fi.bold,
italic: fi.italic,
}
}
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
const hours = computed(() => { const hours = computed(() => {
const hours: Array<dayjs.Dayjs> = [] const hours: Array<dayjs.Dayjs> = []
const _selectedDate = dayjs(selectedDate.value) const _selectedDate = dayjs(selectedDate.value)
@ -699,27 +715,25 @@ const viewMore = (hour: dayjs.Dayjs) => {
@resize-start="onResizeStart" @resize-start="onResizeStart"
> >
<template v-if="!isRowEmpty(record, displayField)"> <template v-if="!isRowEmpty(record, displayField)">
<div <LazySmartsheetCalendarCell
:class="{ v-if="!isRowEmpty(record, displayField!)"
'!mt-2': displayField!.uidt === UITypes.SingleLineText,
'!mt-1': displayField!.uidt === UITypes.MultiSelect || displayField!.uidt === UITypes.SingleSelect,
}"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField!)"
v-model="record.row[displayField!.title!]" v-model="record.row[displayField!.title!]"
:bold="getFieldStyle(displayField).bold"
:column="displayField" :column="displayField"
:row="record" :italic="getFieldStyle(displayField).italic"
:underline="getFieldStyle(displayField).underline"
/> />
</template>
<LazySmartsheetCell <template v-for="(field, id) in fieldsWithoutDisplay">
v-else <LazySmartsheetCalendarCell
v-model="record.row[displayField!.title!]" v-if="!isRowEmpty(record, field)"
:column="displayField" :key="id"
:edit-enabled="false" v-model="record.row[field!.title!]"
:read-only="true" :bold="getFieldStyle(field).bold"
:column="field"
:italic="getFieldStyle(field).italic"
:underline="getFieldStyle(field).underline"
/> />
</div>
</template> </template>
</LazySmartsheetCalendarVRecordCard> </LazySmartsheetCalendarVRecordCard>
</LazySmartsheetRow> </LazySmartsheetRow>

66
packages/nc-gui/components/smartsheet/calendar/MonthView.vue

@ -1,8 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import type { ColumnType } from 'nocodb-sdk'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import { type Row, computed, isPrimary, ref, useViewColumnsOrThrow } from '#imports'
import type { Row } from '#imports'
import { generateRandomNumber, isRowEmpty } from '~/utils' import { generateRandomNumber, isRowEmpty } from '~/utils'
const emit = defineEmits(['new-record', 'expandRecord']) const emit = defineEmits(['new-record', 'expandRecord'])
@ -61,6 +60,22 @@ const resizeDirection = ref<'right' | 'left'>()
const resizeRecord = ref<Row>() const resizeRecord = ref<Row>()
const fields = inject(FieldsInj, ref())
const { fields: _fields } = useViewColumnsOrThrow()
const getFieldStyle = (field: ColumnType) => {
const fi = _fields.value.find((f) => f.title === field.title)
return {
underline: fi.underline,
bold: fi.bold,
italic: fi.italic,
}
}
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
const dates = computed(() => { const dates = computed(() => {
const startOfMonth = selectedMonth.value.startOf('month') const startOfMonth = selectedMonth.value.startOf('month')
const endOfMonth = selectedMonth.value.endOf('month') const endOfMonth = selectedMonth.value.endOf('month')
@ -366,7 +381,6 @@ const calculateNewRow = (event: MouseEvent, updateSideBar?: boolean) => {
endDate = newStartDate.clone() endDate = newStartDate.clone()
} }
dragRecord.value = undefined
newRow.row[toCol!.title!] = dayjs(endDate).format('YYYY-MM-DD HH:mm:ssZ') newRow.row[toCol!.title!] = dayjs(endDate).format('YYYY-MM-DD HH:mm:ssZ')
updateProperty.push(toCol!.title!) updateProperty.push(toCol!.title!)
} }
@ -490,11 +504,14 @@ const onResizeStart = (direction: 'right' | 'left', event: MouseEvent, record: R
} }
const stopDrag = (event: MouseEvent) => { const stopDrag = (event: MouseEvent) => {
clearTimeout(dragTimeout.value)
console.log('stopDrag')
console.log('stopDrag', dragRecord.value, isDragging.value)
if (!isUIAllowed('dataEdit') || !dragRecord.value || !isDragging.value) return if (!isUIAllowed('dataEdit') || !dragRecord.value || !isDragging.value) return
console.log('stopDrag')
event.preventDefault() event.preventDefault()
clearTimeout(dragTimeout.value)
dragElement.value!.style.boxShadow = 'none' dragElement.value!.style.boxShadow = 'none'
const { newRow, updateProperty } = calculateNewRow(event, false) const { newRow, updateProperty } = calculateNewRow(event, false)
@ -772,27 +789,25 @@ const isDateSelected = (date: dayjs.Dayjs) => {
@dblclick.stop="emit('expand-record', record)" @dblclick.stop="emit('expand-record', record)"
> >
<template v-if="!isRowEmpty(record, displayField)"> <template v-if="!isRowEmpty(record, displayField)">
<div <LazySmartsheetCalendarCell
:class="{ v-if="!isRowEmpty(record, displayField!)"
'mt-1.4': displayField!.uidt === UITypes.SingleLineText,
'mt-1': displayField!.uidt === UITypes.MultiSelect || displayField!.uidt === UITypes.SingleSelect,
}"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField!)"
v-model="record.row[displayField!.title!]" v-model="record.row[displayField!.title!]"
:bold="getFieldStyle(displayField).bold"
:column="displayField" :column="displayField"
:row="record" :italic="getFieldStyle(displayField).italic"
:underline="getFieldStyle(displayField).underline"
/> />
</template>
<LazySmartsheetCell <template v-for="(field, id) in fieldsWithoutDisplay">
v-else <LazySmartsheetCalendarCell
v-model="record.row[displayField!.title!]" v-if="!isRowEmpty(record, field)"
:column="displayField" :key="id"
:edit-enabled="false" v-model="record.row[field!.title!]"
:read-only="true" :bold="getFieldStyle(field).bold"
:column="field"
:italic="getFieldStyle(field).italic"
:underline="getFieldStyle(field).underline"
/> />
</div>
</template> </template>
</LazySmartsheetCalendarRecordCard> </LazySmartsheetCalendarRecordCard>
</LazySmartsheetRow> </LazySmartsheetRow>
@ -802,11 +817,6 @@ const isDateSelected = (date: dayjs.Dayjs) => {
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.hide {
transition: 0.01s;
transform: translateX(-9999px);
}
.prevent-select { .prevent-select {
-webkit-user-select: none; /* Safari */ -webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */ -ms-user-select: none; /* IE 10 and IE 11 */

13
packages/nc-gui/components/smartsheet/calendar/RecordCard.vue

@ -56,7 +56,7 @@ const emit = defineEmits(['resize-start'])
class="block h-full min-h-5 w-1 rounded" class="block h-full min-h-5 w-1 rounded"
></div> ></div>
<div v-if="(position === 'leftRounded' || position === 'rounded') && resize" class="mt-0.1 h-7.1 absolute -left-4 resize"> <div v-if="(position === 'leftRounded' || position === 'rounded') && resize" class="mt-0.7 h-7.1 absolute -left-4 resize">
<NcButton <NcButton
:class="{ :class="{
'!block z-1 !border-brand-500': selected || hover, '!block z-1 !border-brand-500': selected || hover,
@ -70,15 +70,20 @@ const emit = defineEmits(['resize-start'])
</NcButton> </NcButton>
</div> </div>
<div class="overflow-hidden ml-2 h-8 absolute"> <div class="overflow-hidden flex w-full ml-2 h-8 absolute">
<span v-if="position === 'rightRounded' || position === 'none'" class="mr-1"> .... </span> <span v-if="position === 'rightRounded' || position === 'none'" class="mr-1"> .... </span>
<span class="text-sm !w-[80%] text-gray-800"> <span
:class="{
'pr-7': position === 'leftRounded',
}"
class="text-sm pt-1.5 pr-3 mr-3 break-word space-x-2 whitespace-nowrap gap-2 overflow-hidden text-ellipsis w-full truncate text-gray-800"
>
<slot /> <slot />
</span> </span>
<span v-if="position === 'leftRounded' || position === 'none'" class="absolute my-0 right-5"> .... </span> <span v-if="position === 'leftRounded' || position === 'none'" class="absolute my-0 right-5"> .... </span>
</div> </div>
<div v-if="(position === 'rightRounded' || position === 'rounded') && resize" class="absolute mt-0.1 z-1 -right-4 resize"> <div v-if="(position === 'rightRounded' || position === 'rounded') && resize" class="absolute mt-0.3 z-1 -right-4 resize">
<NcButton <NcButton
:class="{ :class="{
'!block !border-brand-500': selected || hover, '!block !border-brand-500': selected || hover,

9
packages/nc-gui/components/smartsheet/calendar/VRecordCard.vue

@ -69,11 +69,14 @@ const emit = defineEmits(['resize-start'])
<div v-if="position === 'bottomRounded' || position === 'none'" class="ml-3">....</div> <div v-if="position === 'bottomRounded' || position === 'none'" class="ml-3">....</div>
<div class="ml-3 pr-3 text-ellipsis overflow-hidden w-full h-8 absolute"> <span
<span class="text-sm text-gray-800"> :class="{
'!h-[40%]': position === 'none',
}"
class="mt-1.5 pl-4 pr-1 text-sm h-[70%] text-gray-800 leading-7 space-x-2 break-all whitespace-normal truncate w-full overflow-y-hidden absolute"
>
<slot /> <slot />
</span> </span>
</div>
<div v-if="position === 'topRounded' || position === 'none'" class="h-full pb-7 flex items-end ml-3">....</div> <div v-if="position === 'topRounded' || position === 'none'" class="h-full pb-7 flex items-end ml-3">....</div>
</div> </div>
<div <div

54
packages/nc-gui/components/smartsheet/calendar/WeekView/DateField.vue

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import { type ColumnType } from 'nocodb-sdk'
import type { Row } from '~/lib' import type { Row } from '~/lib'
import { ref } from '#imports' import { computed, isPrimary, ref, useViewColumnsOrThrow } from '#imports'
import { generateRandomNumber, isRowEmpty } from '~/utils' import { generateRandomNumber, isRowEmpty } from '~/utils'
const emits = defineEmits(['expandRecord']) const emits = defineEmits(['expandRecord'])
@ -18,6 +18,22 @@ const { isUIAllowed } = useRoles()
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())
const fields = inject(FieldsInj, ref())
const { fields: _fields } = useViewColumnsOrThrow()
const getFieldStyle = (field: ColumnType) => {
const fi = _fields.value.find((f) => f.title === field.title)
return {
underline: fi.underline,
bold: fi.bold,
italic: fi.italic,
}
}
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
// Calculate the dates of the week // Calculate the dates of the week
const weekDates = computed(() => { const weekDates = computed(() => {
const startOfWeek = new Date(selectedDateRange.value.start!) const startOfWeek = new Date(selectedDateRange.value.start!)
@ -567,27 +583,25 @@ const dropEvent = (event: DragEvent) => {
@resize-start="onResizeStart" @resize-start="onResizeStart"
> >
<template v-if="!isRowEmpty(record, displayField)"> <template v-if="!isRowEmpty(record, displayField)">
<div <LazySmartsheetCalendarCell
:class="{ v-if="!isRowEmpty(record, displayField!)"
'mt-2': displayField.uidt === UITypes.SingleLineText, v-model="record.row[displayField!.title!]"
'mt-1': displayField.uidt === UITypes.MultiSelect || displayField.uidt === UITypes.SingleSelect, :bold="getFieldStyle(displayField).bold"
}"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField)"
v-model="record.row[displayField.title]"
:column="displayField" :column="displayField"
:row="record" :italic="getFieldStyle(displayField).italic"
:underline="getFieldStyle(displayField).underline"
/> />
</template>
<LazySmartsheetCell <template v-for="(field, index) in fieldsWithoutDisplay">
v-else <LazySmartsheetCalendarCell
v-model="record.row[displayField.title]" v-if="!isRowEmpty(record, field)"
:column="displayField" :key="index"
:edit-enabled="false" v-model="record.row[field!.title!]"
:read-only="true" :bold="getFieldStyle(field).bold"
:column="field"
:italic="getFieldStyle(field).italic"
:underline="getFieldStyle(field).underline"
/> />
</div>
</template> </template>
</LazySmartsheetCalendarRecordCard> </LazySmartsheetCalendarRecordCard>
</LazySmartsheetRow> </LazySmartsheetRow>

52
packages/nc-gui/components/smartsheet/calendar/WeekView/DateTimeField.vue

@ -1,8 +1,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { UITypes, isVirtualCol } from 'nocodb-sdk' import { type ColumnType } from 'nocodb-sdk'
import type { Row } from '~/lib' import type { Row } from '~/lib'
import { computed, ref } from '#imports' import { computed, isPrimary, ref, useViewColumnsOrThrow } from '#imports'
import { generateRandomNumber, isRowEmpty } from '~/utils' import { generateRandomNumber, isRowEmpty } from '~/utils'
const emits = defineEmits(['expandRecord']) const emits = defineEmits(['expandRecord'])
@ -30,6 +30,22 @@ const { isUIAllowed } = useRoles()
const meta = inject(MetaInj, ref()) const meta = inject(MetaInj, ref())
const fields = inject(FieldsInj, ref())
const { fields: _fields } = useViewColumnsOrThrow()
const getFieldStyle = (field: ColumnType) => {
const fi = _fields.value.find((f) => f.title === field.title)
return {
underline: fi.underline,
bold: fi.bold,
italic: fi.italic,
}
}
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
// Since it is a datetime Week view, we need to create a 2D array of dayjs objects to represent the hours in a day for each day in the week // Since it is a datetime Week view, we need to create a 2D array of dayjs objects to represent the hours in a day for each day in the week
const datesHours = computed(() => { const datesHours = computed(() => {
const datesHours: Array<Array<dayjs.Dayjs>> = [] const datesHours: Array<Array<dayjs.Dayjs>> = []
@ -746,27 +762,25 @@ const viewMore = (hour: dayjs.Dayjs) => {
@resize-start="onResizeStart" @resize-start="onResizeStart"
> >
<template v-if="!isRowEmpty(record, displayField)"> <template v-if="!isRowEmpty(record, displayField)">
<div <LazySmartsheetCalendarCell
:class="{ v-if="!isRowEmpty(record, displayField!)"
'!mt-2': displayField!.uidt === UITypes.SingleLineText,
'!mt-1': displayField!.uidt === UITypes.MultiSelect || displayField!.uidt === UITypes.SingleSelect,
}"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField!)"
v-model="record.row[displayField!.title!]" v-model="record.row[displayField!.title!]"
:bold="getFieldStyle(displayField).bold"
:column="displayField" :column="displayField"
:row="record" :italic="getFieldStyle(displayField).italic"
:underline="getFieldStyle(displayField).underline"
/> />
</template>
<LazySmartsheetCell <template v-for="(field, id) in fieldsWithoutDisplay">
v-else <LazySmartsheetCalendarCell
v-model="record.row[displayField!.title!]" v-if="!isRowEmpty(record, field)"
:column="displayField" :key="id"
:edit-enabled="false" v-model="record.row[field!.title!]"
:read-only="true" :bold="getFieldStyle(field).bold"
:column="field"
:italic="getFieldStyle(field).italic"
:underline="getFieldStyle(field).underline"
/> />
</div>
</template> </template>
</LazySmartsheetCalendarVRecordCard> </LazySmartsheetCalendarVRecordCard>
</LazySmartsheetRow> </LazySmartsheetRow>

4
packages/nc-gui/components/smartsheet/calendar/index.vue

@ -181,8 +181,8 @@ const headerText = computed(() => {
</NcTooltip> </NcTooltip>
<NcDropdown v-model:visible="calendarRangeDropdown" :auto-close="false" :trigger="['click']"> <NcDropdown v-model:visible="calendarRangeDropdown" :auto-close="false" :trigger="['click']">
<NcButton :class="{ '!w-24': activeCalendarView === 'year' }" class="w-45" full-width size="small" type="secondary"> <NcButton :class="{ '!w-22': activeCalendarView === 'year' }" class="w-45" full-width size="small" type="secondary">
<div class="flex w-full px-3 py-1 w-full items-center justify-between"> <div class="flex px-2 w-full items-center justify-between">
<span class="font-bold text-center text-brand-500" data-testid="nc-calendar-active-date">{{ headerText }}</span> <span class="font-bold text-center text-brand-500" data-testid="nc-calendar-active-date">{{ headerText }}</span>
<component :is="iconMap.arrowDown" class="h-4 w-4 text-gray-700" /> <component :is="iconMap.arrowDown" class="h-4 w-4 text-gray-700" />
</div> </div>

37
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -50,6 +50,7 @@ const {
saveOrUpdate, saveOrUpdate,
metaColumnById, metaColumnById,
loadViewColumns, loadViewColumns,
toggleFieldStyles,
toggleFieldVisibility, toggleFieldVisibility,
} = useViewColumnsOrThrow() } = useViewColumnsOrThrow()
@ -396,7 +397,41 @@ useMenuCloseOnEsc(open)
</template> </template>
<template #default>{{ field.title }}</template> <template #default>{{ field.title }}</template>
</NcTooltip> </NcTooltip>
<div v-if="activeView.type === ViewTypes.CALENDAR" class="flex mr-2">
<NcButton
:class="{
'!bg-gray-800 !text-white': field.bold,
}"
class="!rounded-r-none"
size="xxsmall"
type="secondary"
@click.stop="toggleFieldStyles(field, 'bold', !field.bold)"
>
<component :is="iconMap.bold" />
</NcButton>
<NcButton
:class="{
'!bg-gray-800 !text-white': field.italic,
}"
class="!rounded-x-none !border-x-0"
size="xxsmall"
type="secondary"
@click.stop="toggleFieldStyles(field, 'italic', !field.italic)"
>
<component :is="iconMap.italic" />
</NcButton>
<NcButton
:class="{
'!bg-gray-800 !text-white': field.underline,
}"
class="!rounded-l-none"
size="xxsmall"
type="secondary"
@click.stop="toggleFieldStyles(field, 'underline', !field.underline)"
>
<component :is="iconMap.underline" />
</NcButton>
</div>
<NcSwitch :checked="field.show" :disabled="field.isViewEssentialField" @change="$t('a:fields:show-hide')" /> <NcSwitch :checked="field.show" :disabled="field.isViewEssentialField" @change="$t('a:fields:show-hide')" />
</div> </div>

13
packages/nc-gui/composables/useViewColumns.ts

@ -1,8 +1,8 @@
import { ViewTypes, isHiddenCol, isSystemColumn } from 'nocodb-sdk'
import type { ColumnType, GridColumnReqType, GridColumnType, MapType, TableType, ViewType } from 'nocodb-sdk' import type { ColumnType, GridColumnReqType, GridColumnType, MapType, TableType, ViewType } from 'nocodb-sdk'
import { ViewTypes, isHiddenCol, isSystemColumn } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue' import type { ComputedRef, Ref } from 'vue'
import { computed, ref, storeToRefs, useBase, useNuxtApp, useRoles, useUndoRedo, watch } from '#imports'
import type { Field } from '#imports' import type { Field } from '#imports'
import { computed, ref, storeToRefs, useBase, useNuxtApp, useRoles, useUndoRedo, watch } from '#imports'
const [useProvideViewColumns, useViewColumns] = useInjectionState( const [useProvideViewColumns, useViewColumns] = useInjectionState(
( (
@ -160,6 +160,7 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
} }
const saveOrUpdate = async (field: any, index: number, disableDataReload: boolean = false) => { const saveOrUpdate = async (field: any, index: number, disableDataReload: boolean = false) => {
console.log('saveOrUpdate', field, index, disableDataReload)
if (isLocalMode.value && fields.value) { if (isLocalMode.value && fields.value) {
fields.value[index] = field fields.value[index] = field
meta.value!.columns = meta.value!.columns?.map((column: ColumnType) => { meta.value!.columns = meta.value!.columns?.map((column: ColumnType) => {
@ -278,6 +279,13 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
saveOrUpdate(field, fieldIndex) saveOrUpdate(field, fieldIndex)
} }
const toggleFieldStyles = (field: any, style: 'underline' | 'bold' | 'italic', status: boolean) => {
const fieldIndex = fields.value?.findIndex((f) => f.fk_column_id === field.fk_column_id)
if (!fieldIndex && fieldIndex !== 0) return
field[style] = status
saveOrUpdate(field, fieldIndex, true)
}
// reload view columns when active view changes // reload view columns when active view changes
// or when columns changes(delete/add) // or when columns changes(delete/add)
watch( watch(
@ -351,6 +359,7 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
showSystemFields, showSystemFields,
metaColumnById, metaColumnById,
toggleFieldVisibility, toggleFieldVisibility,
toggleFieldStyles,
isViewColumnsLoading, isViewColumnsLoading,
updateGridViewColumn, updateGridViewColumn,
gridViewCols, gridViewCols,

3
packages/nc-gui/lib/types.ts

@ -32,6 +32,9 @@ interface ProjectMetaInfo {
interface Field { interface Field {
order: number order: number
show: number | boolean show: number | boolean
bold: boolean | number
italic: boolean | number
underline: boolean | number
title: string title: string
fk_column_id?: string fk_column_id?: string
system?: boolean system?: boolean

6
packages/nc-gui/utils/iconUtils.ts

@ -123,6 +123,9 @@ import NcUpload from '~icons/nc-icons/upload'
import NcDownload from '~icons/nc-icons/download' import NcDownload from '~icons/nc-icons/download'
// import NcProjectGray from '~icons/nc-icons/project-gray' // import NcProjectGray from '~icons/nc-icons/project-gray'
import NcPhoneCall from '~icons/nc-icons/phone-call' import NcPhoneCall from '~icons/nc-icons/phone-call'
import NcItalic from '~icons/nc-icons/italic'
import NcBold from '~icons/nc-icons/bold'
import NcUnderline from '~icons/nc-icons/underline'
import NcCrop from '~icons/nc-icons/crop' import NcCrop from '~icons/nc-icons/crop'
// keep it for reference // keep it for reference
@ -483,6 +486,9 @@ export const iconMap = {
ncEdit: NcEdit, ncEdit: NcEdit,
ncArrowUp: NcArrowUp, ncArrowUp: NcArrowUp,
ncArrowDown: NcArrowDown, ncArrowDown: NcArrowDown,
underline: NcUnderline,
bold: NcBold,
italic: NcItalic,
phoneCall: NcPhoneCall, phoneCall: NcPhoneCall,
crop: NcCrop, crop: NcCrop,
} }

13
packages/nocodb/src/models/View.ts

@ -797,6 +797,9 @@ export default class View implements ViewType {
colData: { colData: {
order?: number; order?: number;
show?: BoolType; show?: BoolType;
underline?: BoolType;
bold?: BoolType;
italic?: BoolType;
}, },
ncMeta = Noco.ncMeta, ncMeta = Noco.ncMeta,
) { ) {
@ -828,10 +831,10 @@ export default class View implements ViewType {
table = MetaTable.CALENDAR_VIEW_COLUMNS; table = MetaTable.CALENDAR_VIEW_COLUMNS;
cacheScope = CacheScope.CALENDAR_VIEW_COLUMN; cacheScope = CacheScope.CALENDAR_VIEW_COLUMN;
} }
const updateObj = extractProps(colData, ['order', 'show']); let updateObj = extractProps(colData, ['order', 'show']);
// keep primary_value_column always visible and first in grid view // keep primary_value_column always visible and first in grid view
if (view.type === ViewTypes.GRID || view.type === ViewTypes.CALENDAR) { if (view.type === ViewTypes.GRID) {
const primary_value_column_meta = await ncMeta.metaGet2( const primary_value_column_meta = await ncMeta.metaGet2(
null, null,
null, null,
@ -857,6 +860,12 @@ export default class View implements ViewType {
updateObj.show = true; updateObj.show = true;
} }
} }
if (view.type === ViewTypes.CALENDAR) {
updateObj = {
...updateObj,
...extractProps(colData, ['underline', 'bold', 'italic']),
};
}
// get existing cache // get existing cache
const key = `${cacheScope}:${colId}`; const key = `${cacheScope}:${colId}`;

Loading…
Cancel
Save