Browse Source

Merge pull request #9259 from nocodb/nc-feat/date-field-current-date-as-def

Nc feat/date field current date as def
pull/9293/head
Pranav C 4 months ago committed by GitHub
parent
commit
0cbaf95dd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      packages/nc-gui/components/cell/DatePicker.vue
  2. 12
      packages/nc-gui/components/cell/DateTimePicker.vue
  3. 7
      packages/nc-gui/components/nc/DatePicker.vue
  4. 19
      packages/nc-gui/components/nc/DateWeekSelector.vue
  5. 20
      packages/nc-gui/components/nc/MonthYearSelector.vue
  6. 19
      packages/nc-gui/components/nc/TimeSelector.vue
  7. 31
      packages/nc-gui/components/smartsheet/Cell.vue
  8. 51
      packages/nc-gui/components/smartsheet/column/DefaultValue.vue
  9. 2
      packages/nc-gui/lang/en.json
  10. 5
      packages/nocodb-sdk/src/lib/sqlUi/DatabricksUi.ts
  11. 5
      packages/nocodb-sdk/src/lib/sqlUi/MssqlUi.ts
  12. 20
      packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts
  13. 6
      packages/nocodb-sdk/src/lib/sqlUi/OracleUi.ts
  14. 8
      packages/nocodb-sdk/src/lib/sqlUi/PgUi.ts
  15. 5
      packages/nocodb-sdk/src/lib/sqlUi/SnowflakeUi.ts
  16. 5
      packages/nocodb-sdk/src/lib/sqlUi/SqliteUi.ts
  17. 4
      tests/playwright/pages/Dashboard/Grid/Column/UserOptionColumn.ts

12
packages/nc-gui/components/cell/DatePicker.vue

@ -5,11 +5,12 @@ import { isDateMonthFormat, isSystemColumn } from 'nocodb-sdk'
interface Props {
modelValue?: string | null
isPk?: boolean
showCurrentDateOption?: boolean | 'disabled'
}
const { modelValue, isPk } = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue', 'currentDate'])
const { t } = useI18n()
@ -287,6 +288,11 @@ function handleSelectDate(value?: dayjs.Dayjs) {
localState.value = value
open.value = false
}
const currentDate = ($event) => {
emit('currentDate', $event)
open.value = false
}
</script>
<template>
@ -336,6 +342,8 @@ function handleSelectDate(value?: dayjs.Dayjs) {
:is-open="isOpen"
type="month"
size="medium"
:show-current-date-option="showCurrentDateOption"
@current-date="currentDate"
/>
<NcDatePicker
v-else
@ -344,7 +352,9 @@ function handleSelectDate(value?: dayjs.Dayjs) {
:selected-date="localState"
type="date"
size="medium"
:show-current-date-option="showCurrentDateOption"
@update:selected-date="handleSelectDate"
@current-date="currentDate"
/>
</div>
</template>

12
packages/nc-gui/components/cell/DateTimePicker.vue

@ -5,12 +5,13 @@ import { dateFormats, isSystemColumn, timeFormats } from 'nocodb-sdk'
interface Props {
modelValue?: string | null
isPk?: boolean
showCurrentDateOption?: boolean | 'disabled'
isUpdatedFromCopyNPaste?: Record<string, boolean>
}
const { modelValue, isPk, isUpdatedFromCopyNPaste } = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue', 'currentDate'])
const timeFormatsObj = {
[timeFormats[0]]: 'hh:mm A',
@ -425,6 +426,11 @@ const cellValue = computed(
localState.value?.format(parseProp(column.value.meta).is12hrFormat ? timeFormatsObj[timeFormat.value] : timeFormat.value) ??
'',
)
const currentDate = ($event) => {
open.value = false
emit('currentDate', $event)
}
</script>
<template>
@ -510,7 +516,9 @@ const cellValue = computed(
:is-open="isOpen"
type="date"
size="medium"
:show-current-date-option="showCurrentDateOption"
@update:selected-date="handleSelectDate"
@current-date="currentDate"
/>
<template v-else>
@ -520,7 +528,9 @@ const cellValue = computed(
is-min-granularity-picker
:is12hr-format="!!parseProp(column.meta).is12hrFormat"
:is-open="isOpen"
:show-current-date-option="showCurrentDateOption"
@update:selected-date="handleSelectTime"
@current-date="currentDate"
/>
</template>
</div>

7
packages/nc-gui/components/nc/DatePicker.vue

@ -8,6 +8,7 @@ interface Props {
isCellInputField?: boolean
type: 'date' | 'time' | 'year' | 'month'
isOpen: boolean
showCurrentDateOption?: boolean | 'disabled'
}
const props = withDefaults(defineProps<Props>(), {
@ -18,7 +19,7 @@ const props = withDefaults(defineProps<Props>(), {
type: 'date',
isOpen: false,
})
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:selectedWeek'])
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:selectedWeek', 'currentDate'])
// Page date is the date we use to manage which month/date that is currently being displayed
const pageDate = useVModel(props, 'pageDate', emit)
@ -133,7 +134,9 @@ onMounted(() => {
:is-monday-first="false"
is-cell-input-field
size="medium"
:show-current-date-option="showCurrentDateOption"
@update:picker-type="handleUpdatePickerType"
@current-date="emit('currentDate', $event)"
/>
<NcMonthYearSelector
v-if="['month', 'year'].includes(tempPickerType)"
@ -143,7 +146,9 @@ onMounted(() => {
:is-year-picker="tempPickerType === 'year'"
is-cell-input-field
size="medium"
:show-current-date-option="showCurrentDateOption"
@update:picker-type="handleUpdatePickerType"
@current-date="emit('currentDate', $event)"
/>
</template>

19
packages/nc-gui/components/nc/DateWeekSelector.vue

@ -15,6 +15,7 @@ interface Props {
} | null
isCellInputField?: boolean
pickerType?: 'date' | 'time' | 'year' | 'month'
showCurrentDateOption?: boolean | 'disabled'
}
const props = withDefaults(defineProps<Props>(), {
@ -29,7 +30,7 @@ const props = withDefaults(defineProps<Props>(), {
isCellInputField: false,
pickerType: 'date',
})
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:selectedWeek', 'update:pickerType'])
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:selectedWeek', 'update:pickerType', 'currentDate'])
// Page date is the date we use to manage which month/date that is currently being displayed
const pageDate = useVModel(props, 'pageDate', emit)
@ -250,10 +251,24 @@ const paginate = (action: 'next' | 'prev') => {
</span>
</span>
</div>
<div v-if="isCellInputField" class="flex items-center justify-center px-2 pb-2 pt-1">
<div v-if="isCellInputField" class="flex items-center justify-center px-2 pb-2 pt-1 gap-2">
<NcButton class="nc-date-picker-now-btn !h-7" size="small" type="secondary" @click="handleSelectDate(dayjs())">
<span class="text-small"> {{ $t('labels.today') }} </span>
</NcButton>
<NcTooltip v-if="showCurrentDateOption" :disabled="showCurrentDateOption !== 'disabled'">
<template #title>
{{ $t('tooltip.currentDateNotAvail') }}
</template>
<NcButton
class="nc-date-picker-current-date-btn !h-7"
size="small"
type="secondary"
:disabled="showCurrentDateOption === 'disabled'"
@click="emit('currentDate')"
>
<span class="text-small"> {{ $t('labels.currentDate') }} </span>
</NcButton>
</NcTooltip>
</div>
</div>
</div>

20
packages/nc-gui/components/nc/MonthYearSelector.vue

@ -8,6 +8,7 @@ interface Props {
hideCalendar?: boolean
isCellInputField?: boolean
pickerType?: 'date' | 'time' | 'year' | 'month'
showCurrentDateOption?: boolean | 'disabled'
}
const props = withDefaults(defineProps<Props>(), {
@ -18,7 +19,7 @@ const props = withDefaults(defineProps<Props>(), {
isCellInputField: false,
pickerType: 'date',
})
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:pickerType'])
const emit = defineEmits(['update:selectedDate', 'update:pageDate', 'update:pickerType', 'currentDate'])
const pageDate = useVModel(props, 'pageDate', emit)
@ -183,6 +184,23 @@ const compareYear = (date1: dayjs.Dayjs, date2: dayjs.Dayjs) => {
</span>
</template>
</div>
<div v-if="showCurrentDateOption" class="flex items-center justify-center px-2 pb-2 pt-1">
<NcTooltip :disabled="showCurrentDateOption !== 'disabled'">
<template #title>
{{ $t('tooltip.currentDateNotAvail') }}
</template>
<NcButton
class="nc-date-picker-now-btn !h-7"
size="small"
type="secondary"
:disabled="showCurrentDateOption === 'disabled'"
@click="emit('currentDate')"
>
<span class="text-small"> {{ $t('labels.currentDate') }} </span>
</NcButton>
</NcTooltip>
</div>
</div>
</div>
</template>

19
packages/nc-gui/components/nc/TimeSelector.vue

@ -7,6 +7,7 @@ interface Props {
isMinGranularityPicker?: boolean
minGranularity?: number
isOpen?: boolean
showCurrentDateOption?: boolean | 'disabled'
}
const props = withDefaults(defineProps<Props>(), {
@ -16,7 +17,7 @@ const props = withDefaults(defineProps<Props>(), {
minGranularity: 30,
isOpen: false,
})
const emit = defineEmits(['update:selectedDate'])
const emit = defineEmits(['update:selectedDate', 'currentDate'])
const pageDate = ref<dayjs.Dayjs>(dayjs())
@ -93,10 +94,24 @@ onMounted(() => {
</div>
</div>
<div v-else></div>
<div class="px-2 py-1 box-border flex items-center justify-center">
<div class="px-2 py-1 box-border flex items-center justify-center gap-2">
<NcButton :tabindex="-1" class="!h-7" size="small" type="secondary" @click="handleSelectTime(dayjs())">
<span class="text-small"> {{ $t('general.now') }} </span>
</NcButton>
<NcTooltip v-if="showCurrentDateOption" :disabled="showCurrentDateOption !== 'disabled'">
<template #title>
{{ $t('tooltip.currentDateNotAvail') }}
</template>
<NcButton
class="nc-date-picker-now-btn !h-7"
size="small"
type="secondary"
:disabled="showCurrentDateOption === 'disabled'"
@click="emit('currentDate')"
>
<span class="text-small"> {{ $t('labels.currentDate') }} </span>
</NcButton>
</NcTooltip>
</div>
</div>
</template>

31
packages/nc-gui/components/smartsheet/Cell.vue

@ -19,6 +19,8 @@ const emit = defineEmits(['update:modelValue', 'save', 'navigate', 'update:editE
const column = toRef(props, 'column')
const meta = inject(MetaInj, ref())
const active = toRef(props, 'active', false)
const readOnly = toRef(props, 'readOnly', false)
@ -51,11 +53,9 @@ const { currentRow } = useSmartsheetRowStoreOrThrow()
const { sqlUis } = storeToRefs(useBase())
const sqlUi = ref(
column.value?.source_id && sqlUis.value[column.value?.source_id]
? sqlUis.value[column.value?.source_id]
: Object.values(sqlUis.value)[0],
)
const sourceId = meta.value?.source_id || column.value?.source_id
const sqlUi = ref(sourceId && sqlUis.value[sourceId] ? sqlUis.value[sourceId] : Object.values(sqlUis.value)[0])
const abstractType = computed(() => column.value && sqlUi.value.getAbstractType(column.value))
@ -123,6 +123,17 @@ const onContextmenu = (e: MouseEvent) => {
e.stopPropagation()
}
}
const showCurrentDateOption = computed(() => {
if (!isEditColumnMenu.value || (!isDate(column.value, abstractType.value) && !isDateTime(column.value, abstractType.value)))
return false
return sqlUi.value?.getCurrentDateDefault?.(column.value) ? true : 'disabled'
})
const currentDate = () => {
vModel.value = sqlUi.value?.getCurrentDateDefault?.(column.value)
}
</script>
<template>
@ -166,13 +177,21 @@ const onContextmenu = (e: MouseEvent) => {
:disable-option-creation="!!isEditColumnMenu"
:row-index="props.rowIndex"
/>
<LazyCellDatePicker v-else-if="isDate(column, abstractType)" v-model="vModel" :is-pk="isPrimaryKey(column)" />
<LazyCellDatePicker
v-else-if="isDate(column, abstractType)"
v-model="vModel"
:is-pk="isPrimaryKey(column)"
:show-current-date-option="showCurrentDateOption"
@current-date="currentDate"
/>
<LazyCellYearPicker v-else-if="isYear(column, abstractType)" v-model="vModel" :is-pk="isPrimaryKey(column)" />
<LazyCellDateTimePicker
v-else-if="isDateTime(column, abstractType)"
v-model="vModel"
:is-pk="isPrimaryKey(column)"
:is-updated-from-copy-n-paste="currentRow.rowMeta.isUpdatedFromCopyNPaste"
:show-current-date-option="showCurrentDateOption"
@current-date="currentDate"
/>
<LazyCellTimePicker v-else-if="isTime(column, abstractType)" v-model="vModel" :is-pk="isPrimaryKey(column)" />
<LazyCellRating v-else-if="isRating(column)" v-model="vModel" />

51
packages/nc-gui/components/smartsheet/column/DefaultValue.vue

@ -10,6 +10,8 @@ provide(EditColumnInj, ref(true))
const vModel = useVModel(props, 'value', emits)
const meta = inject(MetaInj, ref())
const isVisibleDefaultValueInput = useVModel(props, 'isVisibleDefaultValueInput', emits)
const rowRef = ref({
@ -41,6 +43,21 @@ watch(
cdfValue.value = newValue
},
)
const { sqlUis } = storeToRefs(useBase())
const sqlUi = computed(() =>
meta.value?.source_id && sqlUis.value[meta.value?.source_id]
? sqlUis.value[meta.value?.source_id]
: Object.values(sqlUis.value)[0],
)
const showCurrentDateOption = computed(() => {
return [UITypes.Date, UITypes.DateTime].includes(vModel.value?.uidt) && sqlUi.value?.getCurrentDateDefault?.(vModel.value)
})
const isCurrentDate = computed(() => {
return showCurrentDateOption.value && cdfValue.value?.toUpperCase?.() === sqlUi.value?.getCurrentDateDefault?.(vModel.value)
})
</script>
<template>
@ -63,27 +80,37 @@ watch(
<div class="w-full flex items-center gap-2 mb-2">
<div class="text-small leading-[18px] flex-1 text-gray-700">{{ $t('placeholder.defaultValue') }}</div>
</div>
<div class="flex flex-row gap-2">
<div class="flex flex-row gap-2 relative">
<div
class="nc-default-value-wrapper border-1 flex items-center w-full px-3 border-gray-300 rounded-lg sm:min-h-[32px] xs:min-h-13 flex items-center focus-within:(border-brand-500 shadow-selected ring-0) transition-all duration-0.3s"
>
<LazySmartsheetCell
:edit-enabled="true"
:model-value="cdfValue"
:column="vModel"
class="!border-none h-auto my-auto"
@update:cdf="updateCdfValue"
@update:edit-enabled="editEnabled = $event"
@click="editEnabled = true"
/>
<div class="relative flex-grow">
<div
v-if="isCurrentDate"
class="absolute pointer-events-none h-full w-full bg-white z-2 top-0 left-0 rounded-full items-center flex bg-white"
>
<div class="-ml-2">
<NcBadge>{{ $t('labels.currentDate') }}</NcBadge>
</div>
</div>
<LazySmartsheetCell
:edit-enabled="true"
:model-value="cdfValue"
:column="vModel"
class="!border-none h-auto my-auto"
@update:cdf="updateCdfValue"
@update:edit-enabled="editEnabled = $event"
@click="editEnabled = true"
/>
</div>
<component
:is="iconMap.close"
v-if="
![UITypes.Year, UITypes.Date, UITypes.Time, UITypes.DateTime, UITypes.SingleSelect, UITypes.MultiSelect].includes(
vModel.uidt,
)
) || isCurrentDate
"
class="w-4 h-4 cursor-pointer rounded-full !text-black-500 text-gray-500 cursor-pointer hover:bg-gray-50"
class="w-4 h-4 cursor-pointer rounded-full z-3 !text-black-500 text-gray-500 cursor-pointer hover:bg-gray-50"
@click="updateCdfValue(null)"
/>
</div>

2
packages/nc-gui/lang/en.json

@ -662,6 +662,7 @@
"metaSync": "Meta Sync",
"mention": "Mention",
"today": "Today",
"currentDate": "Current date",
"workspace": "Workspace",
"txt": "TXT Record value",
"transferOwnership": "Transfer Ownership",
@ -1244,6 +1245,7 @@
"goToDocs": "Go to Docs"
},
"tooltip": {
"currentDateNotAvail": "Current date option not available for this data source / data type",
"privateConnection": "Enable to make this connection private and hidden from other creators in this workspace.",
"optionalDatabaseName": "Optional. Uses default database \"{database}\" if left blank",
"optionalSchemaName": "Optional. Uses default schema \"{schema}\" if left blank.",

5
packages/nocodb-sdk/src/lib/sqlUi/DatabricksUi.ts

@ -1,5 +1,6 @@
import UITypes from '../UITypes';
import { IDType } from './index';
import { ColumnType } from '~/lib';
const dbTypes = [
'BIGINT',
@ -794,6 +795,10 @@ export class DatabricksUi {
];
}
static getCurrentDateDefault(_col: Partial<ColumnType>) {
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

5
packages/nocodb-sdk/src/lib/sqlUi/MssqlUi.ts

@ -1,5 +1,6 @@
import UITypes from '../UITypes';
import { IDType } from './index';
import { ColumnType } from '~/lib';
const dbTypes = [
'bigint',
@ -969,6 +970,10 @@ export class MssqlUi {
];
}
static getCurrentDateDefault(_col: Partial<ColumnType>) {
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

20
packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts

@ -1,5 +1,5 @@
import UITypes from '../UITypes';
import { IDType } from '~/lib';
import { ColumnType, IDType } from '~/lib';
const dbTypes = [
'int',
@ -1335,6 +1335,24 @@ export class MysqlUi {
return ['COUNTA', 'COUNT', 'DATESTR'];
}
static getCurrentDateDefault(col: Partial<ColumnType>) {
// if database datatype timestamp or datetime then return CURRENT_TIMESTAMP
if (
col.dt &&
(col.dt.toLowerCase() === 'timestamp' ||
col.dt.toLowerCase() === 'datetime')
) {
return 'CURRENT_TIMESTAMP';
}
// database type is not defined(means column create) and ui datatype is datetime then return CURRENT_TIMESTAMP
// in this scenario it will create column with datatype timestamp/datetime
if (!col.dt && col.uidt === UITypes.DateTime) {
return 'CURRENT_TIMESTAMP';
}
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

6
packages/nocodb-sdk/src/lib/sqlUi/OracleUi.ts

@ -1,4 +1,4 @@
import { NormalColumnRequestType } from '../Api';
import { ColumnType, NormalColumnRequestType } from '../Api';
import UITypes from '../UITypes';
import { IDType } from './index';
@ -952,6 +952,10 @@ export class OracleUi {
];
}
static getCurrentDateDefault(_col: Partial<ColumnType>) {
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

8
packages/nocodb-sdk/src/lib/sqlUi/PgUi.ts

@ -1,5 +1,6 @@
import UITypes from '../UITypes';
import { IDType } from './index';
import { ColumnType } from '~/lib';
const dbTypes = [
'int',
@ -2032,6 +2033,13 @@ export class PgUi {
return [];
}
static getCurrentDateDefault(col: Partial<ColumnType>) {
if (col.uidt === UITypes.DateTime || col.uidt === UITypes.Date) {
return 'NOW()';
}
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1?.toLowerCase() === dataType2?.toLowerCase()) return true;

5
packages/nocodb-sdk/src/lib/sqlUi/SnowflakeUi.ts

@ -1,5 +1,6 @@
import UITypes from '../UITypes';
import { IDType } from './index';
import { ColumnType } from '~/lib';
const dbTypes = [
'NUMBER',
@ -1035,6 +1036,10 @@ export class SnowflakeUi {
];
}
static getCurrentDateDefault(_col: Partial<ColumnType>) {
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

5
packages/nocodb-sdk/src/lib/sqlUi/SqliteUi.ts

@ -1,5 +1,6 @@
import UITypes from '../UITypes';
import { IDType } from './index';
import { ColumnType } from '~/lib';
const dbTypes = [
'int',
@ -930,6 +931,10 @@ export class SqliteUi {
];
}
static getCurrentDateDefault(_col: Partial<ColumnType>) {
return null;
}
static isEqual(dataType1: string, dataType2: string) {
if (dataType1 === dataType2) return true;

4
tests/playwright/pages/Dashboard/Grid/Column/UserOptionColumn.ts

@ -80,7 +80,7 @@ export class UserOptionColumnPageObject extends BasePage {
}
async clearDefaultValue(): Promise<void> {
await this.get().locator('.nc-cell-user + svg.nc-icon').click();
await this.get().locator('.nc-default-value-wrapper > svg.nc-icon').click();
}
async verifyDefaultValueOptionCount({
@ -92,7 +92,7 @@ export class UserOptionColumnPageObject extends BasePage {
}): Promise<void> {
await this.column.openEdit({ title: columnTitle });
await this.column.get().locator('.nc-cell-user > .nc-user-select').click();
await this.column.get().locator('.nc-default-value-wrapper > .relative > .nc-cell-user').click();
await this.rootPage.locator('.nc-dropdown-user-select-cell').waitFor({ state: 'visible' });

Loading…
Cancel
Save