Skip to content

Commit

Permalink
Nc feat/new date time cell UI (#8546)
Browse files Browse the repository at this point in the history
* feat(nc-gui): new date picker setup

* feat(nc-gui): new date picker

* fix(nc-gui): date cell form view validation issue

* fix(nc-gui): disable date cell type support in mobile view

* fix(nc-gui): small changes

* feat(nc-gui): new cell year and month picker

* fix(nc-gui): add updated date time picker setup

* feat: update date time cell picker

* fix(nc-gui): add now option in time picker

* fix(nc-gui): small changes

* fix(nc-gui): add support to update month, year from date picker

* fix(nc-gui): update date picker select mont/year flow

* fix(test): date selector test case

* fix(nc-gui): update dateTime cell time picker

* fix(test): update time picker test case

* chore(nc-gui): lint

* fix(nc-gui): invalid date issue

* fix(nc-gui): date time picker tab issue

* fix(nc-gui): year cell test fail issue

* fix(nc-gui): date picker filter test fail issue

* fix(test): survey form test fail issue

* fix(test): update year field fill handler test case

* fix(test): update bulk update test

* fix(nc-gui): datetime multiple api call issue

* fix(test): update timezone related test

* fix(test): timezone related test update

* fix(nc-gui): tab focus issue

* fix(test): filter datetime test udpate

* fix(test): ai review changes

* fix(nc-gui): date picker font weight issue

* fix(nc-gui): update year picker font weight

* fix(nc-gui): show full date from date time cell instead of truncate

* fix(nc-gui): date time picker ui changes

* fix(nc-gui): date time cell width issue

* fix(nc-gui): update datetime time option width according to time format

* fix(nc-gui): disable datetime input if cell is readonly

* fic(nc-gui): add new time picker

* feat(nc-gui): update time picker

* chore(nc-gui): cleanup unwanted code

* fix(test): update time cell test cases

* fix(nc-gui): multiple api calls

* fix(test): update time cell filter & bulk update test cases

* fix(test): revert unrelated changes

* fix(nc-gui): pr review changes

* fix(nc-gui): add clear datetime cell icon in non grid view
  • Loading branch information
rameshmane7218 committed May 23, 2024
1 parent 6a334f7 commit 56b5264
Show file tree
Hide file tree
Showing 21 changed files with 1,194 additions and 282 deletions.
145 changes: 116 additions & 29 deletions packages/nc-gui/components/cell/DatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const isClearedInputMode = ref<boolean>(false)
const open = ref<boolean>(false)
const tempDate = ref<dayjs.Dayjs | undefined>()
const localState = computed({
get() {
if (!modelValue || isClearedInputMode.value) {
Expand All @@ -56,7 +58,9 @@ const localState = computed({
const format = picker.value === 'month' ? dateFormat : 'YYYY-MM-DD'
return dayjs(/^\d+$/.test(modelValue) ? +modelValue : modelValue, format)
const value = dayjs(/^\d+$/.test(modelValue) ? +modelValue : modelValue, format)
return value
},
set(val?: dayjs.Dayjs) {
isClearedInputMode.value = false
Expand All @@ -79,20 +83,36 @@ const localState = computed({
},
})
watchEffect(() => {
if (localState.value) {
tempDate.value = localState.value
}
})
const randomClass = `picker_${Math.floor(Math.random() * 99999)}`
onClickOutside(datePickerRef, (e) => {
if ((e.target as HTMLElement)?.closest(`.${randomClass}`)) return
if ((e.target as HTMLElement)?.closest(`.${randomClass}, .nc-${randomClass}`)) return
datePickerRef.value?.blur?.()
open.value = false
})
const onBlur = (e) => {
if ((e?.relatedTarget as HTMLElement)?.closest(`.${randomClass}`)) return
if (
(e?.relatedTarget as HTMLElement)?.closest(`.${randomClass}, .nc-${randomClass}`) ||
(e?.target as HTMLElement)?.closest(`.${randomClass}, .nc-${randomClass}`)
) {
return
}
open.value = false
}
const onFocus = () => {
open.value = true
}
watch(
open,
(next) => {
Expand Down Expand Up @@ -165,14 +185,17 @@ const clickHandler = () => {
cellClickHandler()
}
const handleKeydown = (e: KeyboardEvent) => {
if (e.key !== 'Enter') {
const handleKeydown = (e: KeyboardEvent, _open?: boolean) => {
if (e.key !== 'Enter' && e.key !== 'Tab') {
e.stopPropagation()
}
switch (e.key) {
case 'Enter':
open.value = !open.value
e.preventDefault()
localState.value = tempDate.value
open.value = !_open
if (!open.value) {
editable.value = false
if (isGrid.value && !isExpandedForm.value && !isEditColumn.value) {
Expand All @@ -181,7 +204,7 @@ const handleKeydown = (e: KeyboardEvent) => {
}
return
case 'Escape':
if (open.value) {
if (_open) {
open.value = false
editable.value = false
if (isGrid.value && !isExpandedForm.value && !isEditColumn.value) {
Expand All @@ -193,9 +216,18 @@ const handleKeydown = (e: KeyboardEvent) => {
datePickerRef.value?.blur?.()
}
return
case 'Tab':
open.value = false
if (isGrid.value) {
editable.value = false
datePickerRef.value?.blur?.()
}
return
default:
if (!open.value && /^[0-9a-z]$/i.test(e.key)) {
if (!_open && /^[0-9a-z]$/i.test(e.key)) {
open.value = true
}
}
Expand Down Expand Up @@ -232,32 +264,87 @@ useEventListener(document, 'keydown', (e: KeyboardEvent) => {
}
}
})
const handleUpdateValue = (e: Event) => {
const targetValue = (e.target as HTMLInputElement).value
if (!targetValue) {
tempDate.value = undefined
return
}
const value = dayjs(targetValue, dateFormat.value)
if (value.isValid()) {
tempDate.value = value
}
}
function handleSelectDate(value?: dayjs.Dayjs) {
tempDate.value = value
localState.value = value
open.value = false
}
</script>

<template>
<a-date-picker
ref="datePickerRef"
v-model:value="localState"
:disabled="readOnly"
:picker="picker"
:tabindex="0"
:bordered="false"
class="nc-cell-field !w-full !py-1 !border-none !text-current"
<NcDropdown
:visible="isOpen"
:auto-close="false"
:trigger="['click']"
class="nc-cell-field"
:class="[`nc-${randomClass}`, { 'nc-null': modelValue === null && showNull }]"
:format="dateFormat"
:placeholder="placeholder"
:allow-clear="!readOnly && !isEditColumn"
:input-read-only="!!isMobileMode"
:dropdown-class-name="`${randomClass} nc-picker-date children:border-1 children:border-gray-200 ${open ? 'active' : ''} `"
:open="isOpen"
@blur="onBlur"
@click="clickHandler"
@keydown="handleKeydown"
@mouseup.stop
@mousedown.stop
:overlay-class-name="`${randomClass} nc-picker-date ${open ? 'active' : ''} !min-w-[260px]`"
>
<template #suffixIcon></template>
</a-date-picker>
<div
:title="localState?.format(dateFormat)"
class="nc-date-picker h-full flex items-center justify-between ant-picker-input relative group"
>
<input
ref="datePickerRef"
type="text"
:value="localState?.format(dateFormat) ?? ''"
:placeholder="placeholder"
class="nc-date-input border-none outline-none !text-current bg-transparent !focus:(border-none outline-none ring-transparent)"
:readonly="readOnly || !!isMobileMode"
@blur="onBlur"
@focus="onFocus"
@keydown="handleKeydown($event, open)"
@mouseup.stop
@mousedown.stop
@click="clickHandler"
@input="handleUpdateValue"
/>
<GeneralIcon
v-if="localState"
icon="closeCircle"
class="absolute right-0 top-[50%] transform -translate-y-1/2 invisible group-hover:visible cursor-pointer"
@click.stop="handleSelectDate()"
/>
</div>
<template #overlay>
<div class="w-[256px]">
<NcDatePicker
v-if="picker === 'month'"
v-model:page-date="tempDate"
v-model:selected-date="localState"
:is-open="isOpen"
type="month"
size="medium"
/>
<NcDatePicker
v-else
v-model:page-date="tempDate"
:is-open="isOpen"
:selected-date="localState"
:is-monday-first="false"
type="date"
size="medium"
@update:selected-date="handleSelectDate"
/>
</div>
</template>
</NcDropdown>
<div v-if="!editable && isGrid" class="absolute inset-0 z-90 cursor-pointer"></div>
</template>
Expand Down

0 comments on commit 56b5264

Please sign in to comment.