Add delete all steps button [SCI-6921]

This commit is contained in:
Anton 2022-06-24 11:21:47 +02:00
parent 7cb9b9777f
commit 5296b50c2f
8 changed files with 197 additions and 66 deletions

View file

@ -122,3 +122,9 @@
margin-top: 28px; margin-top: 28px;
} }
} }
.delete-steps-modal {
.btn {
float: initial;
}
}

View file

@ -45,6 +45,7 @@ class ProtocolsController < ApplicationController
revert_modal revert_modal
update_from_parent update_from_parent
update_from_parent_modal update_from_parent_modal
delete_steps
) )
before_action :check_manage_parent_in_repository_permissions, only: %i( before_action :check_manage_parent_in_repository_permissions, only: %i(
update_parent update_parent
@ -257,6 +258,25 @@ class ProtocolsController < ApplicationController
end end
end end
def delete_steps
Protocol.transaction do
team = @protocol.team
previous_size = 0
@protocol.steps.each do |step|
previous_size += step.space_taken
step.destroy!
end
team.release_space(previous_size)
team.save
render json: { status: 'ok' }
rescue ActiveRecord::RecordNotDestroyed
render json: { status: 'error' }, status: :unprocessable_entity
raise ActiveRecord::Rollback
end
end
def clone def clone
cloned = nil cloned = nil
Protocol.transaction do Protocol.transaction do

View file

@ -19,7 +19,12 @@
<span class="fas fa-print" aria-hidden="true"></span> <span class="fas fa-print" aria-hidden="true"></span>
<span>{{ i18n.t("protocols.print.button") }}</span> <span>{{ i18n.t("protocols.print.button") }}</span>
</a> </a>
<ProtocolOptions v-if="protocol.attributes && protocol.attributes.urls" :protocol="protocol" /> <ProtocolOptions
v-if="protocol.attributes && protocol.attributes.urls"
:protocol="protocol"
@protocol:delete_steps="deleteSteps"
:canDeleteSteps="steps.length > 0 && urls.delete_steps_url !== null"
/>
</div> </div>
</div> </div>
<div v-if="protocol.id" id="protocol-content" class="protocol-content collapse in" aria-expanded="true"> <div v-if="protocol.id" id="protocol-content" class="protocol-content collapse in" aria-expanded="true">
@ -158,6 +163,13 @@
expandSteps() { expandSteps() {
$('.step-container .collapse').collapse('show') $('.step-container .collapse').collapse('show')
}, },
deleteSteps() {
$.post(this.urls.delete_steps_url, () => {
this.steps = []
}).error(() => {
HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger')
})
},
refreshProtocolStatus() { refreshProtocolStatus() {
if (this.inRepository) return if (this.inRepository) return
// legacy method from app/assets/javascripts/my_modules/protocols.js // legacy method from app/assets/javascripts/my_modules/protocols.js

View file

@ -0,0 +1,43 @@
<template>
<div ref="modal" @keydown.esc="cancel" class="modal delete-steps-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">
{{ i18n.t('protocols.steps.modals.delete_steps.title')}}
</h4>
</div>
<div class="modal-body">
<p>{{ i18n.t('protocols.steps.modals.delete_steps.description_1')}}</p>
<p><b>{{ i18n.t('protocols.steps.modals.delete_steps.description_2')}}</b></p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" @click="cancel">{{ i18n.t('general.cancel') }}</button>
<button class="btn btn-danger" @click="confirm">{{ i18n.t('protocols.steps.modals.delete_steps.confirm')}}</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'deleteStepsModal',
mounted() {
$(this.$refs.modal).modal('show');
$(this.$refs.modal).on('hidden.bs.modal', () => {
this.$emit('close');
});
},
methods: {
confirm() {
$(this.$refs.modal).modal('hide');
this.$emit('confirm');
},
cancel() {
$(this.$refs.modal).modal('hide');
}
}
}
</script>

View file

@ -1,79 +1,106 @@
<template> <template>
<div class="dropdown sci-dropdown protocol-options-dropdown"> <div>
<button <div class="dropdown sci-dropdown protocol-options-dropdown">
class="btn btn-secondary dropdown-toggle" <button
type="button" class="btn btn-secondary dropdown-toggle"
id="dropdownProtocolOptions" type="button"
data-toggle="dropdown" id="dropdownProtocolOptions"
aria-haspopup="true" data-toggle="dropdown"
aria-expanded="true" aria-haspopup="true"
> aria-expanded="true"
<span class="fas fa-cog"></span> >
<span>{{ i18n.t("my_modules.protocol.options_dropdown.title") }}</span> <span class="fas fa-cog"></span>
<span class="caret"></span> <span>{{ i18n.t("my_modules.protocol.options_dropdown.title") }}</span>
</button> <span class="caret"></span>
<ul </button>
class="dropdown-menu dropdown-menu-right" <ul
aria-labelledby="dropdownProtocolOptions" class="dropdown-menu dropdown-menu-right"
> aria-labelledby="dropdownProtocolOptions"
<li> >
<a <li>
ref="loadProtocol" <a
data-action="load-from-repository" ref="loadProtocol"
@click="loadProtocol" data-action="load-from-repository"
:class="{ disabled: !protocol.attributes.urls.load_from_repo_url }" @click="loadProtocol"
> :class="{ disabled: !protocol.attributes.urls.load_from_repo_url }"
<span class="fas fa-edit"></span> >
<span>{{ i18n.t("my_modules.protocol.options_dropdown.load_from_repo") }}</span> <span class="fas fa-edit"></span>
</a> <span>{{ i18n.t("my_modules.protocol.options_dropdown.load_from_repo") }}</span>
</li> </a>
<li> </li>
<a <li>
ref="saveProtocol" <a
data-action="copy-to-repository" ref="saveProtocol"
@click="saveProtocol" data-action="copy-to-repository"
:class="{ disabled: !protocol.attributes.urls.save_to_repo_url }" @click="saveProtocol"
> :class="{ disabled: !protocol.attributes.urls.save_to_repo_url }"
<span class="fas fa-check"></span> >
<span>{{ <span class="fas fa-check"></span>
i18n.t("my_modules.protocol.options_dropdown.save_to_repo") <span>{{
}}</span> i18n.t("my_modules.protocol.options_dropdown.save_to_repo")
</a> }}</span>
</li> </a>
<li> </li>
<a data-action="load-from-file" <li>
class="btn-open-file" <a data-action="load-from-file"
:data-import-url="protocol.attributes.urls.import_url" class="btn-open-file"
:class="{ disabled: !protocol.attributes.urls.import_url }"> :data-import-url="protocol.attributes.urls.import_url"
<span class="fas fa-download"></span> :class="{ disabled: !protocol.attributes.urls.import_url }">
<span>{{ i18n.t("my_modules.protocol.options_dropdown.import") }}</span> <span class="fas fa-download"></span>
<input type="file" value="" accept=".eln" data-turbolinks="false"> <span>{{ i18n.t("my_modules.protocol.options_dropdown.import") }}</span>
</a> <input type="file" value="" accept=".eln" data-turbolinks="false">
</li> </a>
<li> </li>
<a <li>
data-turbolinks="false" <a
:href="protocol.attributes.urls.export_url" data-turbolinks="false"
:class="{ disabled: !protocol.attributes.urls.export_url }" :href="protocol.attributes.urls.export_url"
> :class="{ disabled: !protocol.attributes.urls.export_url }"
<span class="fas fa-upload"></span> >
<span>{{ <span class="fas fa-upload"></span>
i18n.t("my_modules.protocol.options_dropdown.export") <span>{{
}}</span> i18n.t("my_modules.protocol.options_dropdown.export")
</a> }}</span>
</li> </a>
</ul> </li>
<li v-if="canDeleteSteps">
<a
data-turbolinks="false"
@click.prevent="openStepsDeletingModal()()"
>
<span class="fas fa-trash"></span>
<span>{{
i18n.t("my_modules.protocol.options_dropdown.delete_steps")
}}</span>
</a>
</li>
</ul>
</div>
<DeleteStepsModals v-if="stepsDeleting" @confirm="deleteSteps" @close="closeStartStepsDeletingModal" />
</div> </div>
</template> </template>
<script> <script>
import DeleteStepsModals from 'vue/protocol/modals/delete_steps'
export default { export default {
name: "ProtocolOptions", name: "ProtocolOptions",
components: { DeleteStepsModals },
data() {
return {
stepsDeleting: false
}
},
props: { props: {
protocol: { protocol: {
type: Object, type: Object,
required: true, required: true,
}, },
canDeleteSteps: {
type: Boolean,
required: true
}
}, },
mounted() { mounted() {
// Legacy global functions from app/assets/javascripts/my_modules/protocols.js // Legacy global functions from app/assets/javascripts/my_modules/protocols.js
@ -82,6 +109,12 @@ export default {
initImport(); initImport();
}, },
methods: { methods: {
openStepsDeletingModal() {
this.stepsDeleting = true;
},
closeStartStepsDeletingModal() {
this.stepsDeleting = false;
},
loadProtocol() { loadProtocol() {
$.get( $.get(
this.protocol.attributes.urls.load_from_repo_url + "?type=recent" this.protocol.attributes.urls.load_from_repo_url + "?type=recent"
@ -93,6 +126,9 @@ export default {
$.get(this.protocol.attributes.urls.save_to_repo_url).success((data) => { $.get(this.protocol.attributes.urls.save_to_repo_url).success((data) => {
$(this.$refs.saveProtocol).trigger("ajax:success", data); $(this.$refs.saveProtocol).trigger("ajax:success", data);
}); });
},
deleteSteps() {
this.$emit('protocol:delete_steps')
} }
}, },
}; };

View file

@ -56,7 +56,8 @@ class ProtocolSerializer < ActiveModel::Serializer
update_protocol_name_url: update_protocol_name_url, update_protocol_name_url: update_protocol_name_url,
update_protocol_description_url: update_protocol_description_url, update_protocol_description_url: update_protocol_description_url,
update_protocol_authors_url: update_protocol_authors_url, update_protocol_authors_url: update_protocol_authors_url,
update_protocol_keywords_url: update_protocol_keywords_url update_protocol_keywords_url: update_protocol_keywords_url,
delete_steps_url: delete_steps_url
} }
end end
@ -131,4 +132,10 @@ class ProtocolSerializer < ActiveModel::Serializer
def update_protocol_keywords_url def update_protocol_keywords_url
keywords_protocol_path(object) if in_repository && can_manage_protocol_in_repository?(object) keywords_protocol_path(object) if in_repository && can_manage_protocol_in_repository?(object)
end end
def delete_steps_url
return unless can_manage_protocol_in_module?(object) || can_manage_protocol_in_repository?(object)
delete_steps_protocol_path(object)
end
end end

View file

@ -840,6 +840,7 @@ en:
import: "Import protocol" import: "Import protocol"
export: "Export protocol" export: "Export protocol"
save_to_repo: "Save to repository" save_to_repo: "Save to repository"
delete_steps: "Delete all steps"
description: description:
title: "Edit task %{module} description" title: "Edit task %{module} description"
label: "Description" label: "Description"
@ -2552,6 +2553,11 @@ en:
description_1: 'Youre about to delete a whole step from your protocol. It might contain data you dont want to lose. You wont be able to get it back.' description_1: 'Youre about to delete a whole step from your protocol. It might contain data you dont want to lose. You wont be able to get it back.'
description_2: 'Are you sure you want to delete it?' description_2: 'Are you sure you want to delete it?'
confirm: 'Delete forever' confirm: 'Delete forever'
delete_steps:
title: 'Delete all protocol steps'
description_1: 'Youre about to delete all protocol steps from your protocol. It might contain data you dont want to lose. You wont be able to get it back.'
description_2: 'Are you sure you want to delete them?'
confirm: 'Delete forever'
reorder_elements: reorder_elements:
title: 'Rearrange %{step_name} content' title: 'Rearrange %{step_name} content'
options: options:

View file

@ -547,6 +547,7 @@ Rails.application.routes.draw do
get 'edit_keywords_modal', to: 'protocols#edit_keywords_modal' get 'edit_keywords_modal', to: 'protocols#edit_keywords_modal'
get 'edit_authors_modal', to: 'protocols#edit_authors_modal' get 'edit_authors_modal', to: 'protocols#edit_authors_modal'
get 'edit_description_modal', to: 'protocols#edit_description_modal' get 'edit_description_modal', to: 'protocols#edit_description_modal'
post 'delete_steps'
end end
collection do collection do
post 'datatable', to: 'protocols#datatable' post 'datatable', to: 'protocols#datatable'