Browse Source

Merge pull request #2883 from nocodb/refactor/gui-v2-DateCell

refactor(gui-v2): Added Date Picker
pull/2908/head
navi 2 years ago committed by GitHub
parent
commit
7c7030c2ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/nc-gui-v2/components.d.ts
  2. 103
      packages/nc-gui-v2/components/cell/DatePicker.vue
  3. 74
      packages/nc-gui-v2/package-lock.json
  4. 3
      packages/nc-gui-v2/utils/dateTimeUtils.ts

3
packages/nc-gui-v2/components.d.ts vendored

@ -7,6 +7,7 @@ export {}
declare module '@vue/runtime-core' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
AAnchorLink: typeof import('ant-design-vue/es')['AnchorLink'] AAnchorLink: typeof import('ant-design-vue/es')['AnchorLink']
AAutoComplete: typeof import('ant-design-vue/es')['AutoComplete'] AAutoComplete: typeof import('ant-design-vue/es')['AutoComplete']
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
@ -15,6 +16,7 @@ declare module '@vue/runtime-core' {
ACol: typeof import('ant-design-vue/es')['Col'] ACol: typeof import('ant-design-vue/es')['Col']
ACollapse: typeof import('ant-design-vue/es')['Collapse'] ACollapse: typeof import('ant-design-vue/es')['Collapse']
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel'] ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADivider: typeof import('ant-design-vue/es')['Divider'] ADivider: typeof import('ant-design-vue/es')['Divider']
ADropdown: typeof import('ant-design-vue/es')['Dropdown'] ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AForm: typeof import('ant-design-vue/es')['Form'] AForm: typeof import('ant-design-vue/es')['Form']
@ -51,6 +53,7 @@ declare module '@vue/runtime-core' {
ATag: typeof import('ant-design-vue/es')['Tag'] ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea'] ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip'] ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATypographyText: typeof import('ant-design-vue/es')['TypographyText']
ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle'] ATypographyTitle: typeof import('ant-design-vue/es')['TypographyTitle']
AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger'] AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']

103
packages/nc-gui-v2/components/cell/DatePicker.vue

@ -1,91 +1,60 @@
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { computed } from '#imports' import { ColumnInj, ReadonlyInj } from '~/context'
const { modelValue } = defineProps<Props>()
const emit = defineEmits(['update:modelValue'])
interface Props { interface Props {
modelValue: string modelValue: string
} }
const { modelValue } = defineProps<Props>() const columnMeta = inject(ColumnInj, null)
const readOnlyMode = inject(ReadonlyInj, false)
const emit = defineEmits(['update:modelValue']) let isDateInvalid = $ref(false)
const dateFormat = columnMeta?.meta?.date_format ?? 'YYYY-MM-DD'
const localState = computed({ const localState = $computed({
get() { get() {
if (!modelValue || !dayjs(modelValue).isValid()) { if (!modelValue) {
return undefined return undefined
} }
return (/^\d+$/.test(modelValue) ? dayjs(+modelValue) : dayjs(modelValue)).format('YYYY-MM-DD') if (!dayjs(modelValue).isValid()) {
}, isDateInvalid = true
set(val?: string) { return undefined
if (dayjs(val).isValid()) {
emit('update:modelValue', val && dayjs(val).format('YYYY-MM-DD'))
} }
},
})
/*
export default { return /^\d+$/.test(modelValue) ? dayjs(+modelValue) : dayjs(modelValue)
name: 'DatePickerCell',
props: {
value: [String, Date],
}, },
computed: { set(val?: dayjs.Dayjs) {
localState: { if (!val) {
get() { emit('update:modelValue', null)
if (!this.value || !dayjs(this.value).isValid()) { return
return undefined }
}
return (/^\d+$/.test(this.value) ? dayjs(+this.value) : dayjs(this.value)).format('YYYY-MM-DD')
},
set(val) {
if (dayjs(val).isValid()) {
this.$emit('input', val && dayjs(val).format('YYYY-MM-DD'))
}
},
},
date() {
if (!this.value || this.localState) {
return this.localState
}
return 'Invalid Date'
},
parentListeners() {
const $listeners = {}
if (this.$listeners.blur) {
$listeners.blur = this.$listeners.blur
}
if (this.$listeners.focus) {
$listeners.focus = this.$listeners.focus
}
return $listeners if (val.isValid()) {
}, emit('update:modelValue', val?.format('YYYY-MM-DD'))
},
mounted() {
if (this.$el && this.$el.$el) {
this.$el.$el.focus()
} }
}, },
} */ })
</script> </script>
<template> <template>
<!-- <v-menu> --> <a-date-picker
<!-- <template #activator="{ on }"> --> v-model:value="localState"
<input v-model="localState" type="date" class="value" /> :bordered="false"
<!-- </template> --> class="!w-full px-1"
<!-- <v-date-picker v-model="localState" flat @click.native.stop v-on="parentListeners" /> --> :format="dateFormat"
<!-- </v-menu> --> :placeholder="isDateInvalid ? 'Invalid date' : !readOnlyMode ? 'Select date' : ''"
:allow-clear="!readOnlyMode"
:input-read-only="true"
:open="readOnlyMode ? false : undefined"
>
<template v-if="readOnlyMode" #suffixIcon></template>
</a-date-picker>
</template> </template>
<style scoped> <style scoped></style>
.value {
width: 100%;
min-height: 20px;
}
</style>

74
packages/nc-gui-v2/package-lock.json generated

@ -10478,14 +10478,15 @@
} }
}, },
"node_modules/@intlify/bundle-utils": { "node_modules/@intlify/bundle-utils": {
"version": "2.2.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-3.1.0.tgz",
"integrity": "sha512-ghlJ0kR2cCQ8D+poKknC0Xx0ncOt3J3os7CcIAqqIWVF7k6AtGoCDnIru+YzlZcvFRNmP9wEZ7jKliojCdAWNg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"@intlify/message-compiler": "^9.1.0", "@intlify/message-compiler": "next",
"@intlify/shared": "^9.1.0", "@intlify/shared": "next",
"jsonc-eslint-parser": "^1.0.1", "jsonc-eslint-parser": "^1.0.1",
"source-map": "^0.6.1", "source-map": "0.6.1",
"yaml-eslint-parser": "^0.3.2" "yaml-eslint-parser": "^0.3.2"
}, },
"engines": { "engines": {
@ -10500,6 +10501,28 @@
} }
} }
}, },
"node_modules/@intlify/bundle-utils/node_modules/@intlify/message-compiler": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.0-beta.40.tgz",
"integrity": "sha512-6QWTSYewmkew4nsRqgkwTVuGFKzxVCOK8EXsPt15N+tN1g+OYjC3PfGA2dPB6cVkNxqA9mV/hNK02uHPWU9t0A==",
"dev": true,
"dependencies": {
"@intlify/shared": "9.2.0-beta.40",
"source-map": "0.6.1"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/@intlify/bundle-utils/node_modules/@intlify/shared": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.0-beta.40.tgz",
"integrity": "sha512-xWz+SFjgt/LfaSbbHVn+V7gmvX4ZNP3cIFta790GWZ/tEgwJeC3tkV7i45iUbZ4ZimOerFgKH05b7qvJlKb6RQ==",
"dev": true,
"engines": {
"node": ">= 14"
}
},
"node_modules/@intlify/bundle-utils/node_modules/acorn": { "node_modules/@intlify/bundle-utils/node_modules/acorn": {
"version": "7.4.1", "version": "7.4.1",
"dev": true, "dev": true,
@ -10686,6 +10709,15 @@
} }
} }
}, },
"node_modules/@intlify/vite-plugin-vue-i18n/node_modules/@intlify/shared": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.0-beta.40.tgz",
"integrity": "sha512-xWz+SFjgt/LfaSbbHVn+V7gmvX4ZNP3cIFta790GWZ/tEgwJeC3tkV7i45iUbZ4ZimOerFgKH05b7qvJlKb6RQ==",
"dev": true,
"engines": {
"node": ">= 14"
}
},
"node_modules/@intlify/vite-plugin-vue-i18n/node_modules/source-map": { "node_modules/@intlify/vite-plugin-vue-i18n/node_modules/source-map": {
"version": "0.6.1", "version": "0.6.1",
"dev": true, "dev": true,
@ -23075,16 +23107,34 @@
} }
}, },
"@intlify/bundle-utils": { "@intlify/bundle-utils": {
"version": "2.2.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-3.1.0.tgz",
"integrity": "sha512-ghlJ0kR2cCQ8D+poKknC0Xx0ncOt3J3os7CcIAqqIWVF7k6AtGoCDnIru+YzlZcvFRNmP9wEZ7jKliojCdAWNg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@intlify/message-compiler": "^9.1.0", "@intlify/message-compiler": "next",
"@intlify/shared": "^9.1.0", "@intlify/shared": "next",
"jsonc-eslint-parser": "^1.0.1", "jsonc-eslint-parser": "^1.0.1",
"source-map": "^0.6.1", "source-map": "0.6.1",
"yaml-eslint-parser": "^0.3.2" "yaml-eslint-parser": "^0.3.2"
}, },
"dependencies": { "dependencies": {
"@intlify/message-compiler": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.2.0-beta.40.tgz",
"integrity": "sha512-6QWTSYewmkew4nsRqgkwTVuGFKzxVCOK8EXsPt15N+tN1g+OYjC3PfGA2dPB6cVkNxqA9mV/hNK02uHPWU9t0A==",
"dev": true,
"requires": {
"@intlify/shared": "9.2.0-beta.40",
"source-map": "0.6.1"
}
},
"@intlify/shared": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.0-beta.40.tgz",
"integrity": "sha512-xWz+SFjgt/LfaSbbHVn+V7gmvX4ZNP3cIFta790GWZ/tEgwJeC3tkV7i45iUbZ4ZimOerFgKH05b7qvJlKb6RQ==",
"dev": true
},
"acorn": { "acorn": {
"version": "7.4.1", "version": "7.4.1",
"dev": true "dev": true
@ -23195,6 +23245,12 @@
"source-map": "0.6.1" "source-map": "0.6.1"
}, },
"dependencies": { "dependencies": {
"@intlify/shared": {
"version": "9.2.0-beta.40",
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.2.0-beta.40.tgz",
"integrity": "sha512-xWz+SFjgt/LfaSbbHVn+V7gmvX4ZNP3cIFta790GWZ/tEgwJeC3tkV7i45iUbZ4ZimOerFgKH05b7qvJlKb6RQ==",
"dev": true
},
"source-map": { "source-map": {
"version": "0.6.1", "version": "0.6.1",
"dev": true "dev": true

3
packages/nc-gui-v2/utils/dateTimeUtils.ts

@ -2,8 +2,11 @@ import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc' import utc from 'dayjs/plugin/utc'
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(utc) dayjs.extend(utc)
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
dayjs.extend(customParseFormat)
export const timeAgo = (date: any) => { export const timeAgo = (date: any) => {
return dayjs.utc(date).fromNow() return dayjs.utc(date).fromNow()

Loading…
Cancel
Save