mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-10-31 16:49:40 +08:00 
			
		
		
		
	Merge pull request #6123 from ivanscinote/SCI-9016-inline-edit-component-ui-rework
Rework inline edit vue component UI [SCI-9016]
This commit is contained in:
		
						commit
						b5883178a4
					
				
					 12 changed files with 155 additions and 174 deletions
				
			
		|  | @ -123,17 +123,17 @@ | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       .authors-data { |       .authors-data { | ||||||
|         align-items: center; |         align-items: baseline; | ||||||
|         display: flex; |         display: flex; | ||||||
|         margin-top: -12px; |         margin-top: -12px; | ||||||
|         min-height: 36px; |         min-height: 36px; | ||||||
| 
 | 
 | ||||||
|         .authors-list { |         .authors-list { | ||||||
|           flex-basis: calc(100% - 90px); |           font-weight: bold; | ||||||
|           flex-grow: 1; |  | ||||||
|           line-height: 32px; |           line-height: 32px; | ||||||
|           margin-left: 8px; |           margin-left: 8px; | ||||||
|           font-weight: bold; |           max-width: calc(100% - 90px); | ||||||
|  |           position: relative; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         * { |         * { | ||||||
|  | @ -260,10 +260,12 @@ | ||||||
| 
 | 
 | ||||||
| .protocol-content { | .protocol-content { | ||||||
|   .protocol-name { |   .protocol-name { | ||||||
|  |     display: inline-block; | ||||||
|     font-size: 1.7em; |     font-size: 1.7em; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     margin-bottom: 32px; |     margin-bottom: 32px; | ||||||
|     margin-top: 28px; |     margin-top: 28px; | ||||||
|  |     position: relative; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .repository-new-step { |   .repository-new-step { | ||||||
|  |  | ||||||
|  | @ -26,8 +26,10 @@ | ||||||
|       grid-template-columns: max-content auto; |       grid-template-columns: max-content auto; | ||||||
| 
 | 
 | ||||||
|       .step-checklist-text { |       .step-checklist-text { | ||||||
|  |         display: inline-block; | ||||||
|         margin-top: -.1em; |         margin-top: -.1em; | ||||||
|         width: 100%; |         position: relative; | ||||||
|  |         width: fit-content; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       &:hover.done .step-checklist-text { |       &:hover.done .step-checklist-text { | ||||||
|  | @ -42,7 +44,7 @@ | ||||||
|     border-radius: 50%; |     border-radius: 50%; | ||||||
|     height: 4px; |     height: 4px; | ||||||
|     margin-right: .5em; |     margin-right: .5em; | ||||||
|     margin-top: 1em; |     margin-top: .4em; | ||||||
|     width: 4px; |     width: 4px; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,95 +1,11 @@ | ||||||
| // scss-lint:disable SelectorDepth | // scss-lint:disable SelectorDepth | ||||||
| // scss-lint:disable NestingDepth | // scss-lint:disable NestingDepth | ||||||
| .sci-inline-edit { |  | ||||||
|   align-items: flex-start; |  | ||||||
|   display: flex; |  | ||||||
|   transition: .4s $timing-function-sharp border; |  | ||||||
| 
 | 
 | ||||||
|   &.editing .sci-inline-edit__content { | .sci-cursor-edit { | ||||||
|     .sci-inline-edit__content { |   cursor: url("/images/icon_small/edit.svg") 0 16, auto; | ||||||
|       padding-top: 0; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|   .sci-inline-edit__content { | .inline-edit-placeholder:empty::before { | ||||||
|     display: flex; |   content: attr(placeholder); | ||||||
|     flex-direction: column; |   display: block; | ||||||
|     flex-grow: 1; |  | ||||||
|     margin-left: -.25em; |  | ||||||
|     margin-right: .5rem; |  | ||||||
|     min-height: 30px; |  | ||||||
|     padding-left: .25em; |  | ||||||
|     position: relative; |  | ||||||
| 
 |  | ||||||
|     textarea, |  | ||||||
|     .sci-inline-edit__view { |  | ||||||
|       line-height: 26px; |  | ||||||
|       min-height: 30px; |  | ||||||
|       padding: .1em .2em; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     .sci-inline-edit__view { |  | ||||||
|       border: 1px solid transparent; |  | ||||||
|       cursor: pointer; |  | ||||||
|       white-space: pre-wrap; |  | ||||||
|       width: 100%; |  | ||||||
| 
 |  | ||||||
|       &.blank { |  | ||||||
|         color: $color-silver-chalice; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       &.hover-border:hover { |  | ||||||
|         border: 1px solid $color-silver; |  | ||||||
|         border-radius: 3px; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     textarea { |  | ||||||
|       background-color: $color-white; |  | ||||||
|       border: 1px solid $brand-focus; |  | ||||||
|       border-radius: 4px; |  | ||||||
|       outline: none; |  | ||||||
|       overflow: hidden; |  | ||||||
|       width: 100%; |  | ||||||
| 
 |  | ||||||
|       &:focus { |  | ||||||
|         outline: none; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     .sci-inline-edit__error { |  | ||||||
|       bottom: -16px; |  | ||||||
|       color: $brand-danger; |  | ||||||
|       font-size: 12px; |  | ||||||
|       font-weight: normal; |  | ||||||
|       line-height: 12px; |  | ||||||
|       position: absolute; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   &.editing { |  | ||||||
|     margin-top: 0; |  | ||||||
| 
 |  | ||||||
|     .sci-inline-edit__content { |  | ||||||
|       &.error { |  | ||||||
|         border-color: $brand-danger; |  | ||||||
|         margin-bottom: 16px; |  | ||||||
| 
 |  | ||||||
|         textarea { |  | ||||||
|           border-color: $brand-danger; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     .sci-inline-edit__control { |  | ||||||
|       margin: 0 .25em; |  | ||||||
|       max-height: 30px; |  | ||||||
|       max-width: 30px; |  | ||||||
| 
 |  | ||||||
|       &.btn-disabled { |  | ||||||
|         background: $color-silver-chalice; |  | ||||||
|         color: $color-concrete; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,9 +18,10 @@ | ||||||
|       align-items: baseline; |       align-items: baseline; | ||||||
|       border-radius: 4px; |       border-radius: 4px; | ||||||
|       display: flex; |       display: flex; | ||||||
|       flex-basis: 80%; |       flex-basis: 100%; | ||||||
|       position: relative; |       position: relative; | ||||||
|       padding-top: .4em; |       padding-top: .4em; | ||||||
|  |       gap: .5em; | ||||||
| 
 | 
 | ||||||
|       .step-name-edit-icon { |       .step-name-edit-icon { | ||||||
|         background: linear-gradient(90deg, |         background: linear-gradient(90deg, | ||||||
|  | @ -65,7 +66,6 @@ | ||||||
| 
 | 
 | ||||||
|     .step-name-container { |     .step-name-container { | ||||||
|       align-self: baseline; |       align-self: baseline; | ||||||
|       flex-grow: 1; |  | ||||||
|       font-size: 16px; |       font-size: 16px; | ||||||
|       font-weight: bold; |       font-weight: bold; | ||||||
| 
 | 
 | ||||||
|  | @ -221,7 +221,6 @@ | ||||||
|   border-radius: 4px; |   border-radius: 4px; | ||||||
|   display: flex; |   display: flex; | ||||||
|   min-height: 40px; |   min-height: 40px; | ||||||
|   overflow: hidden; |  | ||||||
|   position: relative; |   position: relative; | ||||||
| 
 | 
 | ||||||
|   &.editing-name { |   &.editing-name { | ||||||
|  | @ -242,8 +241,8 @@ | ||||||
| 
 | 
 | ||||||
|   .step-element-name { |   .step-element-name { | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     width: 100%; |     margin-bottom: 2em; | ||||||
| 
 |     position: relative; | ||||||
| 
 | 
 | ||||||
|     .step-element-number { |     .step-element-number { | ||||||
|       display: inline-block; |       display: inline-block; | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ | ||||||
|           :characterMinLimit="2" |           :characterMinLimit="2" | ||||||
|           :allowBlank="false" |           :allowBlank="false" | ||||||
|           :attributeName="i18n.t('label_templates.show.name_error_prefix')" |           :attributeName="i18n.t('label_templates.show.name_error_prefix')" | ||||||
|  |           :placeholder="i18n.t('label_templates.show.name_placeholder')" | ||||||
|           :autofocus="editingName" |           :autofocus="editingName" | ||||||
|           :editOnload="newLabel" |           :editOnload="newLabel" | ||||||
|           :customClasses="['hover-border']" |  | ||||||
|           @editingEnabled="editingName = true" |           @editingEnabled="editingName = true" | ||||||
|           @editingDisabled="editingName = false" |           @editingDisabled="editingName = false" | ||||||
|           @update="updateName" |           @update="updateName" | ||||||
|  | @ -35,7 +35,6 @@ | ||||||
|           :attributeName="i18n.t('label_templates.show.description_error_prefix')" |           :attributeName="i18n.t('label_templates.show.description_error_prefix')" | ||||||
|           :placeholder="i18n.t('label_templates.show.description_placeholder')" |           :placeholder="i18n.t('label_templates.show.description_placeholder')" | ||||||
|           :autofocus="editingDescription" |           :autofocus="editingDescription" | ||||||
|           :customClasses="['hover-border']" |  | ||||||
|           @editingEnabled="editingDescription = true" |           @editingEnabled="editingDescription = true" | ||||||
|           @editingDisabled="editingDescription = false" |           @editingDisabled="editingDescription = false" | ||||||
|           @update="updateDescription" |           @update="updateDescription" | ||||||
|  |  | ||||||
|  | @ -71,7 +71,6 @@ | ||||||
|             :placeholder="i18n.t('my_modules.protocols.protocol_status_bar.enter_name')" |             :placeholder="i18n.t('my_modules.protocols.protocol_status_bar.enter_name')" | ||||||
|             :allowBlank="!inRepository" |             :allowBlank="!inRepository" | ||||||
|             :attributeName="`${i18n.t('Protocol')} ${i18n.t('name')}`" |             :attributeName="`${i18n.t('Protocol')} ${i18n.t('name')}`" | ||||||
|             :customClasses="['hover-border']" |  | ||||||
|             @update="updateName" |             @update="updateName" | ||||||
|           /> |           /> | ||||||
|           <span v-else> |           <span v-else> | ||||||
|  |  | ||||||
|  | @ -56,7 +56,8 @@ | ||||||
|               :value="protocol.attributes.authors" |               :value="protocol.attributes.authors" | ||||||
|               :placeholder="i18n.t('protocols.header.add_authors')" |               :placeholder="i18n.t('protocols.header.add_authors')" | ||||||
|               :allowBlank="true" |               :allowBlank="true" | ||||||
|               :attributeName="`${i18n.t('Protocol')} ${i18n.t('authors')}`" |               :attributeName="`${i18n.t('Protocol')} ${i18n.t('protocols.header.authors_list')}`" | ||||||
|  |               :characterLimit="10000" | ||||||
|               @update="updateAuthors" |               @update="updateAuthors" | ||||||
|             /> |             /> | ||||||
|           </span> |           </span> | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ | ||||||
|             :allowBlank="false" |             :allowBlank="false" | ||||||
|             :attributeName="`${i18n.t('Step')} ${i18n.t('name')}`" |             :attributeName="`${i18n.t('Step')} ${i18n.t('name')}`" | ||||||
|             :autofocus="editingName" |             :autofocus="editingName" | ||||||
|  |             :timestamp="i18n.t('protocols.steps.timestamp', { date: step.attributes.created_at, user: step.attributes.created_by })" | ||||||
|             :placeholder="i18n.t('protocols.steps.placeholder')" |             :placeholder="i18n.t('protocols.steps.placeholder')" | ||||||
|             :defaultValue="i18n.t('protocols.steps.default_name')" |             :defaultValue="i18n.t('protocols.steps.default_name')" | ||||||
|             @editingEnabled="editingName = true" |             @editingEnabled="editingName = true" | ||||||
|  | @ -52,9 +53,6 @@ | ||||||
|             @update="updateName" |             @update="updateName" | ||||||
|           /> |           /> | ||||||
|         </div> |         </div> | ||||||
|         <button v-if="urls.update_url && !editingName" class="step-name-edit-icon btn btn-xs icon-btn btn-light my-1.5" @click="editingName = true"> |  | ||||||
|           <i class="sn-icon sn-icon-edit"></i> |  | ||||||
|         </button> |  | ||||||
|       </div> |       </div> | ||||||
|       <div class="elements-actions-container"> |       <div class="elements-actions-container"> | ||||||
|         <input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple /> |         <input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple /> | ||||||
|  | @ -158,7 +156,6 @@ | ||||||
|     </div> |     </div> | ||||||
|     <div class="collapse in" :id="'stepBody' + step.id"> |     <div class="collapse in" :id="'stepBody' + step.id"> | ||||||
|       <div class="step-elements"> |       <div class="step-elements"> | ||||||
|         <div class="step-timestamp">{{ i18n.t('protocols.steps.timestamp', {date: step.attributes.created_at, user: step.attributes.created_by}) }}</div> |  | ||||||
|         <template v-for="(element, index) in orderedElements"> |         <template v-for="(element, index) in orderedElements"> | ||||||
|           <component |           <component | ||||||
|             :is="elements[index].attributes.orderable_type" |             :is="elements[index].attributes.orderable_type" | ||||||
|  | @ -261,6 +258,7 @@ | ||||||
|         reordering: false, |         reordering: false, | ||||||
|         isCollapsed: false, |         isCollapsed: false, | ||||||
|         editingName: false, |         editingName: false, | ||||||
|  |         inlineEditError: null, | ||||||
|         wellPlateOptions: [ |         wellPlateOptions: [ | ||||||
|           { label: 'protocols.steps.insert.well_plate_options.32_x_48', dimensions: [32, 48] }, |           { label: 'protocols.steps.insert.well_plate_options.32_x_48', dimensions: [32, 48] }, | ||||||
|           { label: 'protocols.steps.insert.well_plate_options.16_x_24', dimensions: [16, 24] }, |           { label: 'protocols.steps.insert.well_plate_options.16_x_24', dimensions: [16, 24] }, | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ | ||||||
|           :value="element.attributes.orderable.name" |           :value="element.attributes.orderable.name" | ||||||
|           :sa_value="element.attributes.orderable.sa_name" |           :sa_value="element.attributes.orderable.sa_name" | ||||||
|           :characterLimit="10000" |           :characterLimit="10000" | ||||||
|           :placeholder="i18n.t('protocols.steps.checklist.checklist_name')" |           :placeholder="i18n.t('protocols.steps.checklist.placeholder')" | ||||||
|           :allowBlank="false" |           :allowBlank="false" | ||||||
|           :autofocus="editingName" |           :autofocus="editingName" | ||||||
|           :smartAnnotation="true" |           :smartAnnotation="true" | ||||||
|  | @ -173,6 +173,7 @@ | ||||||
|         this.$emit('update', this.element, skipRequest); |         this.$emit('update', this.element, skipRequest); | ||||||
|       }, |       }, | ||||||
|       postItem(item, callback) { |       postItem(item, callback) { | ||||||
|  |         console.log(this.element.attributes.orderable.urls.create_item_url) | ||||||
|         $.post(this.element.attributes.orderable.urls.create_item_url, item).done((result) => { |         $.post(this.element.attributes.orderable.urls.create_item_url, item).done((result) => { | ||||||
|           this.checklistItems.splice( |           this.checklistItems.splice( | ||||||
|             result.data.attributes.position, |             result.data.attributes.position, | ||||||
|  | @ -181,8 +182,8 @@ | ||||||
|           ); |           ); | ||||||
| 
 | 
 | ||||||
|           if(callback) callback(); |           if(callback) callback(); | ||||||
|         }).fail((xhr) => { |         }).fail((e) => { | ||||||
|           this.setFlashErrors(xhr.responseJSON.errors) |           HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger'); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         this.update(); |         this.update(); | ||||||
|  |  | ||||||
|  | @ -1,32 +1,41 @@ | ||||||
| <template> | <template> | ||||||
|   <div class="sci-inline-edit" :class="{ 'editing': editing }" tabindex="0" @keyup.enter="enableEdit($event)"> |   <div class="flex flex-col"> | ||||||
|     <div class="sci-inline-edit__content" :class="{ 'error': error }"> |     <span | ||||||
|       <textarea |  | ||||||
|         ref="input" |  | ||||||
|         rows="1" |  | ||||||
|       v-if="editing" |       v-if="editing" | ||||||
|  |       ref="input" | ||||||
|  |       contenteditable="true" | ||||||
|  |       class="outline-none p-0 pb-2 border-0 border-solid border-b w-fit" | ||||||
|  |       :class="{ 'inline-edit-placeholder text-sn-grey caret-black': isBlank, 'border-sn-delete-red': error, 'border-sn-science-blue': !error }" | ||||||
|       :placeholder="placeholder" |       :placeholder="placeholder" | ||||||
|         v-model="newValue" |  | ||||||
|       @input="handleInput" |       @input="handleInput" | ||||||
|       @keydown="handleKeypress" |       @keydown="handleKeypress" | ||||||
|       @paste="handlePaste" |       @paste="handlePaste" | ||||||
|       @blur="handleBlur" |       @blur="handleBlur" | ||||||
|       @keyup.escape="cancelEdit" |       @keyup.escape="cancelEdit" | ||||||
|       ></textarea> |       @focus="setCaretAtEnd" | ||||||
|       <div v-else-if="smartAnnotation" @click="enableEdit($event)" class="sci-inline-edit__view" v-html="sa_value || placeholder" :class="{ 'blank': isBlank }"></div> |     ></span> | ||||||
|       <div v-else @click="enableEdit($event)" class="sci-inline-edit__view" :class="[isBlank ? 'blank' : '', ...customClasses]">{{newValue || placeholder}}</div> |     <div  | ||||||
|       <div v-if="editing && error" class="sci-inline-edit__error"> |       v-else-if="smartAnnotation" | ||||||
|         {{ error }} |       class="sci-cursor-edit" | ||||||
|  |       :class="{ 'blank': isBlank }" | ||||||
|  |       v-html="sa_value || placeholder" | ||||||
|  |       @click="enableEdit($event)" | ||||||
|  |     ></div> | ||||||
|  |     <div  | ||||||
|  |       v-else | ||||||
|  |       class="sci-cursor-edit outline-none" | ||||||
|  |       :class="{ 'text-sn-grey': isBlank }" | ||||||
|  |       @click="enableEdit($event)" | ||||||
|  |     > | ||||||
|  |       {{newValue || placeholder}} | ||||||
|     </div> |     </div> | ||||||
|  |      | ||||||
|  |     <div  | ||||||
|  |       class="mt-2 whitespace-nowrap text-xs font-normal" | ||||||
|  |       :class="{'text-sn-delete-red': editing && error}" | ||||||
|  |     > | ||||||
|  |       {{ editing && error ? error : timestamp }} | ||||||
|     </div> |     </div> | ||||||
|     <template v-if="editing"> |  | ||||||
|       <div :class="{ 'btn-primary': !error, 'btn-disabled': error }" class="sci-inline-edit__control btn btn-sm icon-btn" @click="update"> |  | ||||||
|         <i class="sn-icon sn-icon-check"></i> |  | ||||||
|       </div> |  | ||||||
|       <div class="sci-inline-edit__control btn btn-light btn-sm icon-btn" @mousedown="cancelEdit"> |  | ||||||
|         <i class="sn-icon sn-icon-close"></i> |  | ||||||
|       </div> |  | ||||||
|     </template> |  | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
|  | @ -42,6 +51,7 @@ | ||||||
|       attributeName: { type: String, required: true }, |       attributeName: { type: String, required: true }, | ||||||
|       characterLimit: { type: Number }, |       characterLimit: { type: Number }, | ||||||
|       characterMinLimit: { type: Number }, |       characterMinLimit: { type: Number }, | ||||||
|  |       timestamp: { type: String}, | ||||||
|       placeholder: { type: String }, |       placeholder: { type: String }, | ||||||
|       autofocus: { type: Boolean, default: false }, |       autofocus: { type: Boolean, default: false }, | ||||||
|       saveOnEnter: { type: Boolean, default: true }, |       saveOnEnter: { type: Boolean, default: true }, | ||||||
|  | @ -49,8 +59,7 @@ | ||||||
|       multilinePaste: { type: Boolean, default: false }, |       multilinePaste: { type: Boolean, default: false }, | ||||||
|       smartAnnotation: { type: Boolean, default: false }, |       smartAnnotation: { type: Boolean, default: false }, | ||||||
|       editOnload: { type: Boolean, default: false }, |       editOnload: { type: Boolean, default: false }, | ||||||
|       defaultValue: { type: String, default: '' }, |       defaultValue: { type: String, default: '' } | ||||||
|       customClasses: { type: Array, default: () => [] } |  | ||||||
|     }, |     }, | ||||||
|     data() { |     data() { | ||||||
|       return { |       return { | ||||||
|  | @ -70,16 +79,22 @@ | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     watch: { |     watch: { | ||||||
|  |       newValue() { | ||||||
|  |         if (this.newValue.length === 0 && this.editing) { | ||||||
|  |           this.focus(); | ||||||
|  |           this.setCaretPosition(); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|       autofocus() { |       autofocus() { | ||||||
|         this.handleAutofocus(); |         this.handleAutofocus(); | ||||||
|       }, |  | ||||||
|       value() { |  | ||||||
|         this.newValue = this.value; |  | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     computed: { |     computed: { | ||||||
|       isBlank() { |       isBlank() { | ||||||
|         return this.newValue.length === 0 |         return this.newValue.length === 0; | ||||||
|  |       }, | ||||||
|  |       isContentDefault() { | ||||||
|  |         return this.newValue === this.defaultValue; | ||||||
|       }, |       }, | ||||||
|       error() { |       error() { | ||||||
|         if(!this.allowBlank && this.isBlank) { |         if(!this.allowBlank && this.isBlank) { | ||||||
|  | @ -118,7 +133,6 @@ | ||||||
|       }, |       }, | ||||||
|       handleBlur() { |       handleBlur() { | ||||||
|         if ($('.atwho-view:visible').length) return; |         if ($('.atwho-view:visible').length) return; | ||||||
| 
 |  | ||||||
|         if (this.allowBlank || !this.isBlank) { |         if (this.allowBlank || !this.isBlank) { | ||||||
|           this.$nextTick(this.update); |           this.$nextTick(this.update); | ||||||
|         } else { |         } else { | ||||||
|  | @ -128,21 +142,47 @@ | ||||||
|       focus() { |       focus() { | ||||||
|         this.$nextTick(() => { |         this.$nextTick(() => { | ||||||
|           if (!this.$refs.input) return; |           if (!this.$refs.input) return; | ||||||
| 
 |  | ||||||
|           this.$refs.input.focus(); |           this.$refs.input.focus(); | ||||||
|           this.resize(); |  | ||||||
|         }); |         }); | ||||||
|       }, |       }, | ||||||
|  |       // 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() { | ||||||
|  |         if (this.isBlank || this.isContentDefault) return; | ||||||
|  | 
 | ||||||
|  |         const el = this.$refs.input; | ||||||
|  |         let range = document.createRange(); | ||||||
|  |         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; | ||||||
|         if (e && $(e.target).hasClass('sa-link')) return; |         if (e && $(e.target).hasClass('sa-link')) return; | ||||||
|         if (e && $(e.target).parent().hasClass('atwho-inserted')) return; |         if (e && $(e.target).parent().hasClass('atwho-inserted')) return; | ||||||
| 
 | 
 | ||||||
|         this.editing = true; |         this.editing = true; | ||||||
|         this.focus(); |  | ||||||
|         this.$nextTick(() => { |         this.$nextTick(() => { | ||||||
|           if (this.$refs.input.value === this.defaultValue) { |           this.focus(); | ||||||
|             this.$refs.input.select(); |           this.$refs.input.innerText = this.newValue; | ||||||
|  | 
 | ||||||
|  |           // Select whole content if it is default | ||||||
|  |           if (this.isContentDefault) { | ||||||
|  |             let range = document.createRange(); | ||||||
|  |             range.selectNodeContents(this.$refs.input); | ||||||
|  |             let selection = window.getSelection(); | ||||||
|  |             selection.removeAllRanges(); | ||||||
|  |             selection.addRange(range); | ||||||
|           } |           } | ||||||
|           if (this.smartAnnotation) { |           if (this.smartAnnotation) { | ||||||
|             SmartAnnotation.init($(this.$refs.input), false); |             SmartAnnotation.init($(this.$refs.input), false); | ||||||
|  | @ -156,40 +196,57 @@ | ||||||
|         this.$emit('editingDisabled'); |         this.$emit('editingDisabled'); | ||||||
|       }, |       }, | ||||||
|       handlePaste(e) { |       handlePaste(e) { | ||||||
|  |         e.preventDefault(); | ||||||
|         this.dirty = true; |         this.dirty = true; | ||||||
| 
 | 
 | ||||||
|         if (!this.multilinePaste) return; |         const clipboardData = (e.clipboardData || window.clipboardData).getData("text"); | ||||||
|         let lines = (e.originalEvent || e).clipboardData.getData('text/plain').split(/[\n\r]/); |         let lines = clipboardData.split(/[\n\r]/).filter((l) => l).map((l) => l.trim()); | ||||||
|         lines = lines.filter((l) => l).map((l) => l.trim()); |  | ||||||
|          |          | ||||||
|         if (lines.length > 1) { |         const selection = window.getSelection(); | ||||||
|           this.newValue = lines[0]; |         if (!selection.rangeCount) return; | ||||||
|  | 
 | ||||||
|  |         selection.deleteFromDocument(); | ||||||
|  | 
 | ||||||
|  |         let textNode = document.createTextNode(lines[0]); | ||||||
|  |         selection.getRangeAt(0).insertNode(textNode); | ||||||
|  | 
 | ||||||
|  |         let range = document.createRange(); | ||||||
|  |         range.setStart(textNode, textNode.length); | ||||||
|  |         range.setEnd(textNode, textNode.length); | ||||||
|  | 
 | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           this.newValue = e.target.textContent; | ||||||
|  |           selection.removeAllRanges(); | ||||||
|  |           selection.addRange(range); | ||||||
|  |            | ||||||
|  |           // Handle multi-line paste | ||||||
|  |           if (this.multilinePaste && lines.length > 1) { | ||||||
|             this.$emit('multilinePaste', lines); |             this.$emit('multilinePaste', lines); | ||||||
|             this.update(); |             this.update(); | ||||||
|           } |           } | ||||||
|  |         }); | ||||||
|       }, |       }, | ||||||
|       handleInput() { |       handleInput(e) { | ||||||
|         this.dirty = true; |         this.dirty = true; | ||||||
|         if (!this.allowNewLine) { | 
 | ||||||
|           this.newValue = this.newValue.replace(/^[\n\r]+|[\n\r]+$/g, ''); |         const sel = document.getSelection(); | ||||||
|         } |         const offset = sel.anchorOffset; | ||||||
|         this.$nextTick(this.resize); | 
 | ||||||
|  |         this.newValue = this.allowNewLine ? e.target.textContent : e.target.textContent.replace(/^[\n\r]+|[\n\r]+$/g, ''); | ||||||
|  | 
 | ||||||
|  |         sel.collapse(sel.anchorNode, offset); | ||||||
|       }, |       }, | ||||||
|       handleKeypress(e) { |       handleKeypress(e) { | ||||||
|         if (e.key == 'Escape') { |         if (e.key == 'Escape') { | ||||||
|           this.cancelEdit(); |           this.cancelEdit(); | ||||||
|         } else if (e.key == 'Enter' && this.saveOnEnter) { |         } else if (e.key == 'Enter' && this.saveOnEnter) { | ||||||
|  |           e.preventDefault() | ||||||
|           this.update(); |           this.update(); | ||||||
|         } else { |         } else { | ||||||
|  |           if (!this.error) this.$emit('error-cleared'); | ||||||
|           this.dirty = true; |           this.dirty = true; | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       resize() { |  | ||||||
|         if (!this.$refs.input) return; |  | ||||||
| 
 |  | ||||||
|         this.$refs.input.style.height = "auto"; |  | ||||||
|         this.$refs.input.style.height = (this.$refs.input.scrollHeight) + "px"; |  | ||||||
|       }, |  | ||||||
|       update() { |       update() { | ||||||
|         if (!this.dirty && !this.isBlank) { |         if (!this.dirty && !this.isBlank) { | ||||||
|           this.editing = false; |           this.editing = false; | ||||||
|  | @ -198,8 +255,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 // Fix for smart annotation | 
 | ||||||
|         this.newValue = this.newValue.trim(); |         this.newValue = this.$refs.input.innerText.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); | ||||||
|  |  | ||||||
|  | @ -989,6 +989,7 @@ en: | ||||||
|     show: |     show: | ||||||
|       breadcrumb_index: 'Label templates' |       breadcrumb_index: 'Label templates' | ||||||
|       name_error_prefix: 'Label template name' |       name_error_prefix: 'Label template name' | ||||||
|  |       name_placeholder: 'Enter label template name' | ||||||
|       description_error_prefix: 'Label template description' |       description_error_prefix: 'Label template description' | ||||||
|       description_title: 'Template description' |       description_title: 'Template description' | ||||||
|       description_placeholder: 'Enter the template description (optional)' |       description_placeholder: 'Enter the template description (optional)' | ||||||
|  | @ -2918,6 +2919,7 @@ en: | ||||||
|       added_by: "Created by:" |       added_by: "Created by:" | ||||||
|       keywords: "Keywords:" |       keywords: "Keywords:" | ||||||
|       authors: "Authors:" |       authors: "Authors:" | ||||||
|  |       authors_list: "authors list" | ||||||
|       no_authors: "No authors" |       no_authors: "No authors" | ||||||
|       add_authors: "+ Add authors" |       add_authors: "+ Add authors" | ||||||
|       add_keywords: "+ Add keywords" |       add_keywords: "+ Add keywords" | ||||||
|  | @ -3118,6 +3120,7 @@ en: | ||||||
|           error: "Table name can't be empty" |           error: "Table name can't be empty" | ||||||
|         table_name: "Table name" |         table_name: "Table name" | ||||||
|       checklist: |       checklist: | ||||||
|  |         placeholder: 'Enter checklist name' | ||||||
|         default_name: 'Checklist %{position}' |         default_name: 'Checklist %{position}' | ||||||
|         checklist_name: "Checklist name" |         checklist_name: "Checklist name" | ||||||
|         empty_checklist: 'Doesn’t contain any checklist items' |         empty_checklist: 'Doesn’t contain any checklist items' | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								public/images/icon_small/edit.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								public/images/icon_small/edit.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||||
|  | <path d="M1.024 14.9594H2.1248L12.2624 4.65691L11.1616 3.53821L1.024 13.8407V14.9594ZM14.464 3.90244L11.904 1.32683L12.7232 0.494309C13.0304 0.16477 13.4144 0 13.8752 0C14.336 0 14.72 0.16477 15.0272 0.494309L15.6928 1.17073C15.8976 1.36152 16 1.60434 16 1.89919C16 2.19404 15.9061 2.43686 15.7184 2.62764L14.464 3.90244ZM13.7216 4.65691L2.56 16H0V13.3984L11.1616 2.05528L13.7216 4.65691Z" fill="#1D2939"/> | ||||||
|  | <path d="M1.024 14.9594H2.1248L12.2624 4.65691L11.1616 3.53821L1.024 13.8407V14.9594Z" fill="white"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 612 B | 
		Loading…
	
	Add table
		
		Reference in a new issue