Skip to content

Commit 58ef2f7

Browse files
feat(component): Add edit mode on native date object (#2086)
1 parent 9039c4d commit 58ef2f7

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

packages/app-frontend/src/features/inspector/DataField.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ export default defineComponent({
370370
class="edit-input value-input text-black"
371371
:class="{ error: !valueValid }"
372372
list="special-tokens"
373+
:type="inputType"
373374
@keydown.esc.capture.stop.prevent="cancelEdit()"
374375
@keydown.enter="submitEdit()"
375376
>

packages/app-frontend/src/mixins/data-field-edit.js

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default {
7272

7373
isValueEditable () {
7474
const type = this.interpretedValueType
75-
const customType = this.field.value?._custom?.type
75+
const customType = this.customField?.type
7676

7777
return this.isEditable &&
7878
(
@@ -81,16 +81,27 @@ export default {
8181
type === 'string' ||
8282
type === 'array' ||
8383
type === 'plain-object' ||
84-
customType === 'bigint'
84+
customType === 'bigint' ||
85+
customType === 'date'
8586
)
8687
},
8788

89+
customField () {
90+
return this.field.value?._custom
91+
},
92+
93+
inputType () {
94+
if (this.customField?.type === 'date') return 'datetime-local'
95+
return 'text'
96+
},
97+
8898
isSubfieldsEditable () {
8999
return this.isEditable && (this.interpretedValueType === 'array' || this.interpretedValueType === 'plain-object')
90100
},
91101

92102
valueValid () {
93103
try {
104+
if (this.customField?.skipSerialize) return true
94105
parse(this.transformSpecialTokens(this.editedValue, false))
95106
return true
96107
} catch (e) {
@@ -153,14 +164,22 @@ export default {
153164
if (this.valueType === 'custom') {
154165
valueToEdit = valueToEdit._custom.value
155166
}
156-
this.editedValue = this.transformSpecialTokens(JSON.stringify(valueToEdit), true)
167+
if (this.customField?.skipSerialize) {
168+
this.editedValue = valueToEdit
169+
} else {
170+
this.editedValue = this.transformSpecialTokens(JSON.stringify(valueToEdit), true)
171+
}
172+
157173
this.editedKey = this.field.key
158174
this.editing = true
159175
currentEditedField = this
160176
this.$nextTick(() => {
161177
const el = this.$refs[focusKey && this.renamable ? 'keyInput' : 'editInput']
162-
el.focus()
163-
el.setSelectionRange(0, el.value.length)
178+
try {
179+
el.focus()
180+
// Will cause DOMEException on the datetime-local input.
181+
el.setSelectionRange(0, el.value.length)
182+
} catch {}
164183
})
165184
}
166185
},
@@ -174,13 +193,13 @@ export default {
174193
submitEdit () {
175194
if (this.editValid) {
176195
this.editing = false
177-
let value = this.transformSpecialTokens(this.editedValue, false)
196+
let value = this.customField.skipSerialize ? this.editedValue : this.transformSpecialTokens(this.editedValue, false)
178197
// We need to send the entire custom value data object
179198
if (this.valueType === 'custom') {
180199
value = JSON.stringify({
181200
_custom: {
182-
...this.field.value._custom,
183-
value: JSON.parse(value), // Input
201+
...this.customField,
202+
value: this.customField.skipSerialize ? value : JSON.parse(value), // Input
184203
},
185204
})
186205
}

packages/shared-utils/src/util.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ function replacerForInternal (key) {
227227
// special handling of native type
228228
return `[native RegExp ${RegExp.prototype.toString.call(val)}]`
229229
} else if (proto === '[object Date]') {
230-
return `[native Date ${Date.prototype.toString.call(val)}]`
230+
return getCustomDateDetails(val)
231231
} else if (proto === '[object Error]') {
232232
return `[native Error ${val.message}<>${val.stack}]`
233233
} else if (val.state && val._vm) {
@@ -342,6 +342,21 @@ export function getCustomBigIntDetails (val) {
342342
}
343343
}
344344

345+
export function getCustomDateDetails (val: Date) {
346+
const dateCopy = new Date(val.getTime())
347+
dateCopy.setMinutes(dateCopy.getMinutes() - dateCopy.getTimezoneOffset())
348+
349+
const displayedTime = Date.prototype.toString.call(val)
350+
return {
351+
_custom: {
352+
type: 'date',
353+
display: displayedTime,
354+
value: dateCopy.toISOString().slice(0, -1),
355+
skipSerialize: true,
356+
},
357+
}
358+
}
359+
345360
// Use a custom basename functions instead of the shimed version
346361
// because it doesn't work on Windows
347362
function basename (filename, ext) {
@@ -512,6 +527,8 @@ export function revive (val) {
512527
return reviveSet(val)
513528
} else if (custom.type === 'bigint') {
514529
return BigInt(custom.value)
530+
} else if (custom.type === 'date') {
531+
return new Date(custom.value)
515532
} else if (custom._reviveId) {
516533
return reviveCache.read(custom._reviveId)
517534
} else {

packages/shell-dev-vue3/src/NativeTypes.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030

3131
<h3>BigInt</h3>
3232
<pre>{{ bigInt }}</pre>
33+
34+
<h3>Date</h3>
35+
<pre>{{ localDate }}</pre>
3336
</div>
3437
</template>
3538

0 commit comments

Comments
 (0)