Merge pull request #4215 from aignatov-bio/ai-sci-6939-fix-smart-annotation-in-new-steps

Fix smart annotation for step editing [SCI-6939]
This commit is contained in:
aignatov-bio 2022-07-11 10:38:42 +02:00 committed by GitHub
commit fa623a9f19
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 73 additions and 48 deletions

View file

@ -5,28 +5,21 @@
position: relative;
width: calc(100% + 16px);
.action-container {
cursor: pointer;
height: 100%;
left: 0;
position: absolute;
width: 100%;
z-index: 100;
.buttons-container {
background: linear-gradient(
90deg,
transparent 0%,
$color-concrete 25%,
$color-concrete 100%
);
display: none;
padding-left: 2em;
position: absolute;
right: 0;
}
.buttons-container {
background: linear-gradient(
90deg,
transparent 0%,
$color-concrete 25%,
$color-concrete 100%
);
display: none;
padding-left: 2em;
position: absolute;
right: 0;
}
.element-grip {
align-items: center;
color: $color-silver-chalice;
@ -66,7 +59,8 @@
}
&.edit {
.action-container {
.buttons-container,
.element-grip {
display: none;
}
}

View file

@ -298,14 +298,14 @@
let index = this.elements.findIndex((e) => e.id === element.id);
if (skipRequest) {
this.elements[index].orderable = element;
this.elements[index].attributes.orderable = element.attributes.orderable;
} else {
$.ajax({
url: element.attributes.orderable.urls.update_url,
method: 'PUT',
data: element.attributes.orderable,
success: (result) => {
this.elements[index].orderable = result;
this.elements[index].attributes.orderable = result.data.attributes;
}
}).error(() => {
HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger');

View file

@ -8,10 +8,12 @@
<InlineEdit
v-if="element.attributes.orderable.urls.update_url"
:value="element.attributes.orderable.name"
:sa_value="element.attributes.orderable.sa_name"
:characterLimit="255"
:placeholder="''"
:allowBlank="false"
:autofocus="editingName"
:smartAnnotation="true"
:attributeName="`${i18n.t('Checklist')} ${i18n.t('name')}`"
@editingEnabled="editingName = true"
@editingDisabled="editingName = false"
@ -149,13 +151,16 @@
},
saveItem(item) {
if (item.attributes.id) {
this.checklistItems.splice(
item.attributes.position, 1, item
);
$.ajax({
url: item.attributes.urls.update_url,
type: 'PATCH',
data: item,
success: (result) => {
let updatedItem = this.checklistItems[item.attributes.position]
updatedItem.attributes = result.data.attributes
updatedItem.attributes.id = item.attributes.id
this.$set(this.checklistItems, item.attributes.position, updatedItem)
},
error: () => HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger')
});
} else {

View file

@ -17,12 +17,14 @@
<InlineEdit
v-if="!checklistItem.attributes.urls || updateUrl"
:value="checklistItem.attributes.text"
:sa_value="checklistItem.attributes.sa_text"
:characterLimit="10000"
:placeholder="''"
:allowBlank="true"
:autofocus="editingText"
:attributeName="`${i18n.t('ChecklistItem')} ${i18n.t('name')}`"
:multilinePaste="true"
:smartAnnotation="true"
@editingEnabled="enableTextEdit"
@editingDisabled="disableTextEdit"
@update="updateText"

View file

@ -1,21 +1,18 @@
<template>
<div class="step-text-container" :class="{ 'edit': inEditMode }" @keyup.enter="enableEditMode($event)" tabindex="0">
<div ref="actionContainer" class="action-container" @click="enableEditMode($event)">
<div v-if="reorderElementUrl" class="element-grip" @click="$emit('reorder')">
<i class="fas fa-grip-vertical"></i>
</div>
<div class="buttons-container">
<button v-if="element.attributes.orderable.urls.update_url" class="btn icon-btn btn-light" tabindex="-1">
<i class="fas fa-pen"></i>
</button>
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="-1">
<i class="fas fa-trash"></i>
</button>
</div>
<div v-if="reorderElementUrl" class="element-grip" @click="$emit('reorder')">
<i class="fas fa-grip-vertical"></i>
</div>
<div class="buttons-container">
<button v-if="element.attributes.orderable.urls.update_url" class="btn icon-btn btn-light" tabindex="-1" @click="enableEditMode($event)">
<i class="fas fa-pen"></i>
</button>
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="-1">
<i class="fas fa-trash"></i>
</button>
</div>
<Tinymce
v-if="element.attributes.orderable.urls.update_url"
:inEditMode="inEditMode"
:value="element.attributes.orderable.text"
:value_html="element.attributes.orderable.text_view"
:placeholder="i18n.t('protocols.steps.text.placeholder')"
@ -26,6 +23,7 @@
:lastUpdated="element.attributes.orderable.updated_at"
@update="update"
@editingDisabled="disableEditMode"
@editingEnabled="enableEditMode"
/>
<div v-else v-html="element.attributes.orderable.text_view"></div>
<deleteElementModal v-if="confirmingDelete" @confirm="deleteElement($event)" @cancel="closeDeleteModal"/>
@ -70,10 +68,6 @@
},
methods: {
enableEditMode() {
if (
$(this.$refs.actionContainer).hasClass('fas fa-grip-vertical') ||
$(this.$refs.actionContainer).hasClass('element-grip')
) return
if (!this.element.attributes.orderable.urls.update_url) return
if (this.inEditMode == true) return
this.inEditMode = true

View file

@ -1,5 +1,5 @@
<template>
<div class="sci-inline-edit" :class="{ 'editing': editing }" tabindex="0" @keyup.enter="enableEdit">
<div class="sci-inline-edit" :class="{ 'editing': editing }" tabindex="0" @keyup.enter="enableEdit($event)">
<div class="sci-inline-edit__content">
<textarea
ref="input"
@ -13,7 +13,7 @@
@paste="handlePaste"
@blur="handleBlur"
></textarea>
<div v-else @click="enableEdit" class="sci-inline-edit__view" :class="{ 'blank': isBlank }">{{ value || placeholder }}</div>
<div v-else @click="enableEdit($event)" class="sci-inline-edit__view" v-html="sa_value || value || placeholder" :class="{ 'blank': isBlank }"></div>
<div v-if="editing && error" class="sci-inline-edit__error">
{{ error }}
</div>
@ -34,12 +34,14 @@
name: 'InlineEdit',
props: {
value: { type: String, default: '' },
sa_value: { type: String},
allowBlank: { type: Boolean, default: true },
attributeName: { type: String, required: true },
characterLimit: { type: Number },
placeholder: { type: String },
autofocus: { type: Boolean, default: false },
multilinePaste: { type: Boolean, default: false },
smartAnnotation: { type: Boolean, default: false },
editOnload: { type: Boolean, default: false }
},
data() {
@ -89,6 +91,8 @@
}
},
handleBlur() {
if ($('.atwho-view:visible').length) return;
if (this.allowBlank || !this.isBlank) {
this.$nextTick(this.update);
} else {
@ -103,9 +107,15 @@
this.resize();
});
},
enableEdit() {
enableEdit(e) {
if (e && $(e.target).hasClass('atwho-user-popover')) return
this.editing = true;
this.focus();
this.$nextTick(() => {
if (this.smartAnnotation) {
SmartAnnotation.init($(this.$refs.input));
}
})
this.$emit('editingEnabled');
},
cancelEdit() {
@ -145,7 +155,7 @@
setTimeout(() => {
if(!this.allowBlank && this.isBlank) return;
if(!this.editing) return;
this.newValue = this.$refs.input.value // Fix for smart annotation
this.newValue = this.newValue.trim();
this.editing = false;
this.$emit('editingDisabled');

View file

@ -3,8 +3,18 @@
class ChecklistItemSerializer < ActiveModel::Serializer
include Canaid::Helpers::PermissionsHelper
include Rails.application.routes.url_helpers
include ApplicationHelper
include ActionView::Helpers::TextHelper
attributes :id, :text, :checked, :position, :urls
attributes :id, :text, :checked, :position, :urls, :sa_text
def sa_text
@user = scope[:user] || @instance_options[:user]
custom_auto_link(object.text,
simple_format: false,
tags: %w(img),
team: object.checklist.step.protocol.team)
end
def urls
return {} if object.destroyed? ||

View file

@ -3,14 +3,24 @@
class ChecklistSerializer < ActiveModel::Serializer
include Canaid::Helpers::PermissionsHelper
include Rails.application.routes.url_helpers
include ApplicationHelper
include ActionView::Helpers::TextHelper
attributes :id, :name, :urls, :icon
attributes :id, :name, :urls, :icon, :sa_name
has_many :checklist_items, serializer: ChecklistItemSerializer
def icon
'fa-list-ul'
end
def sa_name
@user = scope[:user] || @instance_options[:user]
custom_auto_link(object.name,
simple_format: false,
tags: %w(img),
team: object.step.protocol.team)
end
def urls
return {} if object.destroyed? || !can_manage_step?(scope[:user] || @instance_options[:user], object.step)