Fix inline edit vue component [SCI-9254]

This commit is contained in:
Anton 2023-09-11 17:15:00 +02:00
parent 67c6d66ff1
commit 982da48bbe
4 changed files with 21 additions and 88 deletions

View file

@ -15,13 +15,11 @@
margin-bottom: 1.2em; margin-bottom: 1.2em;
.step-element-header { .step-element-header {
align-items: baseline; align-items: flex-start;
border-radius: 4px;
display: flex; display: flex;
flex-basis: 100%; flex-basis: 100%;
position: relative; position: relative;
padding-top: .4em; gap: 1rem;
gap: .5em;
.step-name-edit-icon { .step-name-edit-icon {
background: linear-gradient(90deg, background: linear-gradient(90deg,
@ -44,7 +42,7 @@
} }
.step-collapse-link { .step-collapse-link {
display: inline-block; display: flex;
flex-shrink: 0; flex-shrink: 0;
line-height: 24px; line-height: 24px;
text-align: center; text-align: center;
@ -212,62 +210,6 @@
} }
} }
.step-element-header {
align-items: baseline;
border-radius: 4px;
display: flex;
min-height: 40px;
position: relative;
&.editing-name {
.step-element-controls {
display: none;
}
}
.step-controls {
display: flex;
align-items: center;
min-height: 35px;
}
.sci-inline-edit {
width: 100%;
}
.step-element-name {
font-weight: bold;
margin-bottom: 2em;
position: relative;
.step-element-number {
display: inline-block;
margin-right: 8px;
}
}
.step-element-controls {
background: linear-gradient(90deg,
transparent,
$color-concrete 15%,
$color-concrete 100%);
display: flex;
margin-left: auto;
position: absolute;
right: 0;
top: 0;
.fas {
font-size: 14px;
}
}
.step-element-controls,
.step-element-grip {
opacity: 0;
}
}
.step-element-grip { .step-element-grip {
color: $color-silver-chalice; color: $color-silver-chalice;
cursor: pointer; cursor: pointer;

View file

@ -12,7 +12,7 @@
</div> </div>
<div class="step-header"> <div class="step-header">
<div class="step-element-header" :class="{ 'no-hover': !urls.update_url }"> <div class="step-element-header" :class="{ 'no-hover': !urls.update_url }">
<div class="step-controls gap-4 mr-4"> <div class="flex items-center gap-4 py-1 border-0 border-y border-transparent border-solid">
<a class="step-collapse-link hover:no-underline focus:no-underline" <a class="step-collapse-link hover:no-underline focus:no-underline"
:href="'#stepBody' + step.id" :href="'#stepBody' + step.id"
data-toggle="collapse" data-toggle="collapse"
@ -32,7 +32,7 @@
{{ step.attributes.position + 1 }}. {{ step.attributes.position + 1 }}.
</div> </div>
</div> </div>
<div class="step-name-container flex-grow" :class="{'step-element--locked': !urls.update_url}"> <div class="step-name-container basis-[calc(100%_-_100px)]" :class="{'step-element--locked': !urls.update_url}">
<InlineEdit <InlineEdit
:value="step.attributes.name" :value="step.attributes.name"
:class="{ 'step-element--locked': !urls.update_url }" :class="{ 'step-element--locked': !urls.update_url }"

View file

@ -8,7 +8,7 @@
<i class="sn-icon sn-icon-drag"></i> <i class="sn-icon sn-icon-drag"></i>
</div> </div>
<div class="flex items-start gap-2 grow" :class="{ 'done': checklistItem.attributes.checked }"> <div class="flex items-start gap-2 grow" :class="{ 'done': checklistItem.attributes.checked }">
<div v-if="!inRepository" class="sci-checkbox-container my-2.5 w-6" :class="{ 'disabled': !toggleUrl }"> <div v-if="!inRepository" class="sci-checkbox-container my-1.5 border-y border-transparent border-solid w-6" :class="{ 'disabled': !toggleUrl }">
<input ref="checkbox" <input ref="checkbox"
type="checkbox" type="checkbox"
class="sci-checkbox" class="sci-checkbox"
@ -25,6 +25,7 @@
:characterLimit="10000" :characterLimit="10000"
:placeholder="'Add a checklist item...'" :placeholder="'Add a checklist item...'"
:allowBlank="true" :allowBlank="true"
:singleLine="false"
:autofocus="editingText" :autofocus="editingText"
:attributeName="`${i18n.t('ChecklistItem')} ${i18n.t('name')}`" :attributeName="`${i18n.t('ChecklistItem')} ${i18n.t('name')}`"
:multilinePaste="true" :multilinePaste="true"

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="w-full"> <div class="w-full relative">
<template v-if="editing"> <template v-if="editing">
<input type="text" <input type="text"
v-if="singleLine" v-if="singleLine"
@ -11,6 +11,7 @@
'border-b-sn-science-blue': !error, 'border-b-sn-science-blue': !error,
}" }"
:placeholder="placeholder" :placeholder="placeholder"
v-model="newValue"
@keydown="handleKeypress" @keydown="handleKeypress"
@paste="handlePaste" @paste="handlePaste"
@blur="handleBlur" @blur="handleBlur"
@ -18,13 +19,14 @@
@focus="setCaretAtEnd"/> @focus="setCaretAtEnd"/>
<textarea v-else <textarea v-else
ref="input" ref="input"
class="overflow-hidden inline-block box-size outline-none p-0 py-1 border-0 border-solid border-b w-full border-t-transparent" class="overflow-hidden inline-block outline-none px-0 py-1 border-0 border-solid border-b w-full border-t-transparent"
:class="{ :class="{
'inline-edit-placeholder text-sn-grey caret-black': isBlank, 'inline-edit-placeholder text-sn-grey caret-black': isBlank,
'border-sn-delete-red': error, 'border-sn-delete-red': error,
'border-sn-science-blue': !error, 'border-sn-science-blue': !error,
}" }"
:placeholder="placeholder" :placeholder="placeholder"
v-model="newValue"
@keydown="handleKeypress" @keydown="handleKeypress"
@paste="handlePaste" @paste="handlePaste"
@blur="handleBlur" @blur="handleBlur"
@ -33,8 +35,9 @@
</template> </template>
<div <div
v-else v-else
ref="view"
class="sci-cursor-edit border-0 py-1 outline-none inline-block border-solid border-y border-transparent" class="sci-cursor-edit border-0 py-1 outline-none inline-block border-solid border-y border-transparent"
:class="{ 'text-sn-grey': isBlank }" :class="{ 'text-sn-grey': isBlank, 'pb-1.5': !singleLine }"
@click="enableEdit($event)" @click="enableEdit($event)"
> >
<span v-if="smartAnnotation" v-html="sa_value || placeholder" ></span> <span v-if="smartAnnotation" v-html="sa_value || placeholder" ></span>
@ -42,7 +45,7 @@
</div> </div>
<div <div
class="mt-2 whitespace-nowrap text-xs font-normal" class="mt-2 whitespace-nowrap text-xs font-normal absolute bottom-[-.75rem]"
:class="{'text-sn-delete-red': editing && error}" :class="{'text-sn-delete-red': editing && error}"
> >
{{ editing && error ? error : timestamp }} {{ editing && error ? error : timestamp }}
@ -97,8 +100,8 @@
newValue() { newValue() {
if (this.newValue.length === 0 && this.editing) { if (this.newValue.length === 0 && this.editing) {
this.focus(); this.focus();
this.setCaretPosition();
} }
this.refreshTexareaHeight();
}, },
autofocus() { autofocus() {
this.handleAutofocus(); this.handleAutofocus();
@ -160,26 +163,11 @@
this.$refs.input.focus(); this.$refs.input.focus();
}); });
}, },
// Fixing Firefox specific caret placement issue
setCaretPosition() {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(this.$refs.input, 0);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
},
setCaretAtEnd() { setCaretAtEnd() {
if (this.isBlank || this.isContentDefault) return; if (this.isBlank || this.isContentDefault) return;
const el = this.$refs.input; const el = this.$refs.input;
let range = document.createRange(); el.focus();
range.selectNodeContents(el);
range.collapse(false);
let selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}, },
enableEdit(e) { enableEdit(e) {
if (e && $(e.target).hasClass('atwho-user-popover')) return; if (e && $(e.target).hasClass('atwho-user-popover')) return;
@ -250,7 +238,6 @@
this.newValue = this.allowNewLine ? e.target.textContent : e.target.textContent.replace(/^[\n\r]+|[\n\r]+$/g, ''); this.newValue = this.allowNewLine ? e.target.textContent : e.target.textContent.replace(/^[\n\r]+|[\n\r]+$/g, '');
sel.collapse(sel.anchorNode, offset); sel.collapse(sel.anchorNode, offset);
this.refreshTexareaHeight()
}, },
handleKeypress(e) { handleKeypress(e) {
if (e.key == 'Escape') { if (e.key == 'Escape') {
@ -264,6 +251,8 @@
} }
}, },
update() { update() {
this.refreshTexareaHeight();
if (!this.dirty && !this.isBlank) { if (!this.dirty && !this.isBlank) {
this.editing = false; this.editing = false;
return; return;
@ -271,8 +260,8 @@
if(this.error) return; if(this.error) return;
if(!this.$refs.input) return; if(!this.$refs.input) return;
this.newValue = this.$refs.input.value.trim() // Fix for smart annotation this.newValue = this.$refs.input.value.trim() // Fix for smart annotation
this.editing = false; this.editing = false;
this.$emit('editingDisabled'); this.$emit('editingDisabled');
this.$emit('update', this.newValue); this.$emit('update', this.newValue);
@ -280,7 +269,8 @@
refreshTexareaHeight() { refreshTexareaHeight() {
if (this.editing && !this.singleLine) { if (this.editing && !this.singleLine) {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.input.style.height = this.$refs.input.scrollHeight + 'px'; this.$refs.input.style.height = '0px';
this.$refs.input.style.height = this.$refs.input.scrollHeight - 3 + 'px';
}); });
} }
} }