Add name prompt for tables with empty names [SCI-7082] (#4348)

* Add name prompt for tables with empty names [SCI-7082]

* Move to separate component [SCI-7082]
This commit is contained in:
artoscinote 2022-08-12 10:17:45 +02:00 committed by GitHub
parent 32c53e223b
commit e4a7aa3dad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 4 deletions

View file

@ -2,6 +2,10 @@
width: 370px;
}
.modal-md {
width: 450px;
}
.modal {
.modal-absolute-close-button {
position: absolute;

View file

@ -68,4 +68,9 @@
margin-left: .5em;
}
}
.table-name-error {
color: $brand-danger;
font-size: 12px;
}
}

View file

@ -0,0 +1,80 @@
<template>
<div ref="modal" class="modal" :id="`tableNameModal${element.attributes.orderable.id}`" tabindex="-1" role="dialog">
<div class="modal-dialog modal-md" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" @click="cancel" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="modal-destroy-team-label">
{{ i18n.t('protocols.steps.table.name_modal.title')}}
</h4>
</div>
<div class="modal-body">
<p>{{ i18n.t('protocols.steps.table.name_modal.description')}}</p>
<div class="sci-input-container" :class="{ 'error': error }">
<input ref="input" v-model="name" type="text" class="sci-input-field" @keyup.enter="!error && update(name)" required="true" />
<div v-if="error" class="table-name-error">
{{ i18n.t('protocols.steps.table.name_modal.error') }}
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" @click="cancel">{{ i18n.t('general.cancel') }}</button>
<button class="btn btn-primary" @click="update(name)">{{ i18n.t('protocols.steps.table.name_modal.save')}}</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TableNameModal',
props: {
element: {
type: Object,
required: true
}
},
data() {
return {
name: null
}
},
computed: {
defaultName() {
return this.i18n.t('protocols.steps.table.default_name', { position: this.element.attributes.position + 1 });
},
error() {
return !this.name;
}
},
mounted() {
this.initModal();
$(this.$refs.modal).modal('show');
},
methods: {
initModal() {
this.name = this.defaultName;
$(this.$refs.modal).on('shown.bs.modal', () => {
$(this.$refs.input).focus();
});
},
cancel() {
this.hide(() => {
this.$emit('cancel');
});
},
update() {
this.hide(() => {
this.$emit('update', this.name);
})
},
hide(callback) {
$(this.$refs.modal).on('hidden.bs.modal', () => {
callback();
});
$(this.$refs.modal).modal('hide');
}
}
}
</script>

View file

@ -327,7 +327,7 @@
this.reorderElements(unorderedElements)
this.$emit('stepUpdated')
},
updateElement(element, skipRequest=false) {
updateElement(element, skipRequest=false, callback) {
let index = this.elements.findIndex((e) => e.id === element.id);
this.elements[index].isNew = false;
@ -342,6 +342,11 @@
success: (result) => {
this.elements[index].attributes.orderable = result.data.attributes;
this.$emit('stepUpdated');
// optional callback after successful update
if(typeof callback === 'function') {
callback();
}
}
}).error(() => {
HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger');

View file

@ -5,7 +5,7 @@
<i class="fas fas-rotated-90 fa-exchange-alt"></i>
</div>
<div v-else class="step-element-grip-placeholder"></div>
<div v-if="!locked || element.attributes.orderable.name" class="step-element-name">
<div v-if="!locked || element.attributes.orderable.name" :key="reloadHeader" class="step-element-name">
<InlineEdit
:value="element.attributes.orderable.name"
:characterLimit="255"
@ -51,6 +51,7 @@
</button>
</div>
<deleteElementModal v-if="confirmingDelete" @confirm="deleteElement" @cancel="closeDeleteModal"/>
<tableNameModal v-if="nameModalOpen" :element="element" @update="updateEmptyName" @cancel="nameModalOpen = false" />
</div>
</template>
@ -58,10 +59,11 @@
import DeleteMixin from 'vue/protocol/mixins/components/delete.js'
import deleteElementModal from 'vue/protocol/modals/delete_element.vue'
import InlineEdit from 'vue/shared/inline_edit.vue'
import TableNameModal from 'vue/protocol/modals/table_name_modal.vue'
export default {
name: 'StepTable',
components: { deleteElementModal, InlineEdit },
components: { deleteElementModal, InlineEdit, TableNameModal },
mixins: [DeleteMixin],
props: {
element: {
@ -83,7 +85,9 @@
return {
editingName: false,
editingTable: false,
tableObject: null
tableObject: null,
nameModalOpen: false,
reloadHeader: 0
}
},
computed: {
@ -104,6 +108,11 @@
},
methods: {
enableTableEdit() {
if (!this.element.attributes.orderable.name) {
this.openNameModal();
return;
}
this.editingTable = true;
this.$nextTick(() => this.tableObject.selectCell(0,0));
},
@ -120,6 +129,22 @@
this.element.attributes.orderable.name = name;
this.update();
},
openNameModal() {
this.tableObject.deselectCell();
this.nameModalOpen = true;
},
updateEmptyName(name) {
this.disableNameEdit();
// force reload header to properly reset name inline edit
this.reloadHeader = this.reloadHeader + 1;
this.element.attributes.orderable.name = name;
this.$emit('update', this.element, false, () => {
this.nameModalOpen = false;
this.enableTableEdit();
});
},
updateTable() {
if (this.editingTable == false) return;

View file

@ -2570,6 +2570,11 @@ en:
table:
default_name: 'Table %{position}'
edit_message: 'Use right click for table options'
name_modal:
title: 'Please enter the table title'
description: 'Tables have become content blocks and require a name. To be able to edit the table, please add the name now:'
save: 'Save table title'
error: "Table name can't be empty"
checklist:
default_name: 'Checklist %{position}'
empty_checklist: 'Doesnt contain any checklist items'