mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-20 14:31:30 +08:00
Merge pull request #6152 from aignatov-bio/ai-sci-9223-add-archive-mode-for-results
Add archive view to results [SCI-9223]
This commit is contained in:
commit
38e62c9835
15 changed files with 116 additions and 85 deletions
|
@ -27,7 +27,7 @@
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.content__text-body:hover:not(.edit):not(.locked) {
|
||||
.content__text-body:hover:not(.edit):not(.component__element--locked) {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ class ResultsController < ApplicationController
|
|||
include Breadcrumbs
|
||||
skip_before_action :verify_authenticity_token, only: %i(create update destroy duplicate)
|
||||
before_action :load_my_module
|
||||
before_action :load_vars, only: %i(destroy elements assets upload_attachment
|
||||
before_action :load_vars, only: %i(destroy elements assets upload_attachment archive restore destroy
|
||||
update_view_state update_asset_view_mode update duplicate)
|
||||
before_action :check_destroy_permissions, only: :destroy
|
||||
before_action :set_breadcrumbs_items, only: %i(index)
|
||||
|
@ -14,7 +14,11 @@ class ResultsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.json do
|
||||
# API endpoint
|
||||
@results = @my_module.results.active
|
||||
@results = if params[:view_mode] == 'archived'
|
||||
@my_module.results.archived
|
||||
else
|
||||
@my_module.results.active
|
||||
end
|
||||
|
||||
apply_sort!
|
||||
apply_filters!
|
||||
|
@ -56,23 +60,18 @@ class ResultsController < ApplicationController
|
|||
end
|
||||
|
||||
def archive
|
||||
result = @my_module.results.find(params[:result_id])
|
||||
result.archive(current_user)
|
||||
if @result.archive(current_user)
|
||||
render json: {}, status: :ok
|
||||
else
|
||||
render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
if result.save
|
||||
Activities::CreateActivityService
|
||||
.call(activity_type: :destroy_result,
|
||||
owner: current_user,
|
||||
subject: result,
|
||||
team: @my_module.team,
|
||||
project: @my_module.project,
|
||||
message_items: { result: result.id })
|
||||
|
||||
flash[:success] = t('my_modules.module_archive.archive_flash',
|
||||
result: result.name,
|
||||
module: @my_module.name)
|
||||
|
||||
redirect_to my_module_results_path(@my_module)
|
||||
def restore
|
||||
if @result.restore(current_user)
|
||||
render json: {}, status: :ok
|
||||
else
|
||||
render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -126,26 +125,11 @@ class ResultsController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
result_type = if @result.is_text
|
||||
t('activities.result_type.text')
|
||||
elsif @result.is_table
|
||||
t('activities.result_type.table')
|
||||
elsif @result.is_asset
|
||||
t('activities.result_type.asset')
|
||||
end
|
||||
Activities::CreateActivityService
|
||||
.call(activity_type: :destroy_result,
|
||||
owner: current_user,
|
||||
subject: @result,
|
||||
team: @my_module.team,
|
||||
project: @my_module.project,
|
||||
message_items: { result: @result.id,
|
||||
type_of_result: result_type })
|
||||
flash[:success] = t('my_modules.module_archive.delete_flash',
|
||||
result: @result.name,
|
||||
module: @my_module.name)
|
||||
@result.destroy
|
||||
redirect_to archive_my_module_path(@my_module)
|
||||
if @result.destroy
|
||||
render json: {}, status: :ok
|
||||
else
|
||||
render json: { errors: @result.errors.full_messages }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def duplicate
|
||||
|
|
|
@ -41,7 +41,7 @@ module SecondaryNavigationHelper
|
|||
end
|
||||
|
||||
def is_module_results?
|
||||
%w(index).include?(action_name) && controller_name == 'results'
|
||||
%w(index).include?(action_name) && controller_name == 'results' && !%w(archived).include?(params[:view_mode])
|
||||
end
|
||||
|
||||
def is_module_activities?
|
||||
|
@ -49,7 +49,7 @@ module SecondaryNavigationHelper
|
|||
end
|
||||
|
||||
def is_module_archive?
|
||||
action_name == 'archive'
|
||||
%w(index).include?(action_name) && controller_name == 'results' && %w(archived).include?(params[:view_mode])
|
||||
end
|
||||
|
||||
def title_element
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="result-head-left">
|
||||
<InlineEdit
|
||||
:value="result.attributes.name"
|
||||
:class="{ 'result-element--locked': !urls.update_url }"
|
||||
:class="{ 'pointer-events-none': !urls.update_url }"
|
||||
:characterLimit="255"
|
||||
:allowBlank="false"
|
||||
:attributeName="`${i18n.t('Result')} ${i18n.t('name')}`"
|
||||
|
@ -87,15 +87,21 @@
|
|||
<i class="sn-icon sn-icon-more-hori"></i>
|
||||
</button>
|
||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right insert-element-dropdown" :aria-labelledby="'resultOptionsMenu_' + result.attributes.id">
|
||||
<li class="action" @click="openReorderModal">
|
||||
<li class="action" @click="openReorderModal" v-if="urls.reorder_elements_url">
|
||||
{{ i18n.t('my_modules.results.actions.rearrange') }}
|
||||
</li>
|
||||
<li class="action" @click="duplicateResult">
|
||||
<li class="action" @click="duplicateResult" v-if="urls.duplicate_url && !result.attributes.archived">
|
||||
{{ i18n.t('my_modules.results.actions.duplicate') }}
|
||||
</li>
|
||||
<li class="action" @click="archiveResult">
|
||||
<li class="action" @click="archiveResult" v-if="urls.archive_url">
|
||||
{{ i18n.t('my_modules.results.actions.archive') }}
|
||||
</li>
|
||||
<li class="action" @click="restoreResult" v-if="urls.restore_url">
|
||||
{{ i18n.t('my_modules.results.actions.restore') }}
|
||||
</li>
|
||||
<li class="action" @click="deleteResult" v-if="urls.delete_url">
|
||||
{{ i18n.t('my_modules.results.actions.delete') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -334,16 +340,23 @@
|
|||
});
|
||||
},
|
||||
archiveResult() {
|
||||
if (this.urls.archive_url) {
|
||||
axios.post(this.urls.archive_url).then((response) => {
|
||||
this.$emit('resultArchived', response.data);
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
axios.post(this.urls.archive_url).then((response) => {
|
||||
this.$emit('result:archived', this.result.attributes.id);
|
||||
});
|
||||
},
|
||||
restoreResult() {
|
||||
axios.post(this.urls.restore_url).then((response) => {
|
||||
this.$emit('result:restored', this.result.attributes.id);
|
||||
});
|
||||
},
|
||||
deleteResult() {
|
||||
axios.delete(this.urls.delete_url).then((response) => {
|
||||
this.$emit('result:deleted', this.result.attributes.id);
|
||||
});
|
||||
},
|
||||
duplicateResult() {
|
||||
axios.post(this.urls.duplicate_url).then((_) => {
|
||||
this.$emit('duplicated');
|
||||
this.$emit('result:duplicated');
|
||||
});
|
||||
},
|
||||
moveElement(position, target_id) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="results-wrapper">
|
||||
<ResultsToolbar :sort="sort"
|
||||
:canCreate="canCreate == 'true'"
|
||||
@setSort="setSort"
|
||||
@setFilters="setFilters"
|
||||
@newResult="createResult"
|
||||
|
@ -16,7 +17,10 @@
|
|||
@result:move_element="reloadResult"
|
||||
@result:attachments:loaded="resultToReload = null"
|
||||
@result:move_attachment="reloadResult"
|
||||
@duplicated="resetPageAndReload"
|
||||
@result:duplicated="resetPageAndReload"
|
||||
@result:archived="removeResult"
|
||||
@result:deleted="removeResult"
|
||||
@result:restored="removeResult"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,7 +35,8 @@
|
|||
name: 'Results',
|
||||
components: { ResultsToolbar, Result },
|
||||
props: {
|
||||
url: { type: String, required: true }
|
||||
url: { type: String, required: true },
|
||||
canCreate: { type: String, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -114,6 +119,9 @@
|
|||
},
|
||||
collapseAll() {
|
||||
$('.result-wrapper .collapse').collapse('hide')
|
||||
},
|
||||
removeResult(result_id) {
|
||||
this.results = this.results.filter((r) => r.attributes.id != result_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="result-toolbar p-3 flex justify-between rounded-md bg-sn-white">
|
||||
<div class="result-toolbar__left">
|
||||
<button class="btn btn-secondary" @click="$emit('newResult')">
|
||||
<button v-if="canCreate" class="btn btn-secondary" @click="$emit('newResult')">
|
||||
<i class="sn-icon sn-icon-new-task"></i>
|
||||
{{ i18n.t('my_modules.results.add_label') }}
|
||||
</button>
|
||||
|
@ -48,6 +48,7 @@
|
|||
name: 'ResultsToolbar',
|
||||
props: {
|
||||
sort: { type: String, required: true },
|
||||
canCreate: { type: Boolean, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
@click="$emit('reorder')">
|
||||
<i class="sn-icon sn-icon-sort"></i>
|
||||
</div>
|
||||
<div class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold">
|
||||
<div class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold" :class="{ 'pointer-events-none': locked } ">
|
||||
<InlineEdit
|
||||
:value="element.attributes.orderable.name"
|
||||
:sa_value="element.attributes.orderable.sa_name"
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
</div>
|
||||
|
||||
<div v-if="!locked || element.attributes.orderable.name" :key="reloadHeader"
|
||||
class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold">
|
||||
class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold"
|
||||
:class="{'pointer-events-none': locked}">
|
||||
<InlineEdit
|
||||
:value="element.attributes.orderable.name"
|
||||
:characterLimit="255"
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
</div>
|
||||
|
||||
<div v-if="element.attributes.orderable.urls.update_url || element.attributes.orderable.name"
|
||||
class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold">
|
||||
class="grow-1 text-ellipsis whitespace-nowrap grow my-1 font-bold"
|
||||
:class="{'pointer-events-none': !element.attributes.orderable.urls.update_url}"
|
||||
>
|
||||
<InlineEdit
|
||||
:value="element.attributes.orderable.name"
|
||||
:characterLimit="255"
|
||||
|
|
|
@ -11,6 +11,12 @@ Canaid::Permissions.register_for(Result) do
|
|||
result.my_module.permission_granted?(user, MyModulePermissions::RESULTS_MANAGE)
|
||||
end
|
||||
|
||||
can :restore_result do |user, result|
|
||||
result.archived? &&
|
||||
!result.my_module.archived_branch? &&
|
||||
result.my_module.permission_granted?(user, MyModulePermissions::RESULTS_MANAGE)
|
||||
end
|
||||
|
||||
can :delete_result do |user, result|
|
||||
result.archived? &&
|
||||
result.unlocked?(result) &&
|
||||
|
|
|
@ -8,8 +8,8 @@ class ResultSerializer < ActiveModel::Serializer
|
|||
include InputSanitizeHelper
|
||||
|
||||
attributes :name, :id, :urls, :updated_at, :created_at_formatted, :updated_at_formatted, :user,
|
||||
:my_module_id, :attachments_manageble, :marvinjs_enabled, :type, :marvinjs_context,
|
||||
:wopi_enabled, :wopi_context, :created_at, :created_by
|
||||
:my_module_id, :attachments_manageble, :marvinjs_enabled, :marvinjs_context, :type,
|
||||
:wopi_enabled, :wopi_context, :created_at, :created_by, :archived
|
||||
|
||||
def marvinjs_enabled
|
||||
MarvinJsService.enabled?
|
||||
|
@ -19,6 +19,18 @@ class ResultSerializer < ActiveModel::Serializer
|
|||
'Result'
|
||||
end
|
||||
|
||||
def name
|
||||
if archived
|
||||
"(A) #{object.name}"
|
||||
else
|
||||
object.name
|
||||
end
|
||||
end
|
||||
|
||||
def archived
|
||||
object.archived?
|
||||
end
|
||||
|
||||
def current_user
|
||||
scope
|
||||
end
|
||||
|
@ -76,21 +88,26 @@ class ResultSerializer < ActiveModel::Serializer
|
|||
|
||||
if can_manage_result?(object)
|
||||
urls_list.merge!({
|
||||
delete_url: result_path(object),
|
||||
archive_url: my_module_result_archive_path(object.my_module, object),
|
||||
update_url: my_module_result_path(object.my_module, object),
|
||||
create_table_url: my_module_result_tables_path(object.my_module, object),
|
||||
create_text_url: my_module_result_texts_path(object.my_module, object),
|
||||
update_asset_view_mode_url: update_asset_view_mode_my_module_result_path(object.my_module, object),
|
||||
update_view_state_url: update_view_state_my_module_result_path(object.my_module, object),
|
||||
direct_upload_url: rails_direct_uploads_url,
|
||||
upload_attachment_url: upload_attachment_my_module_result_path(object.my_module, object),
|
||||
reorder_elements_url: reorder_result_result_orderable_elements_path(result_id: object.id)
|
||||
})
|
||||
archive_url: archive_my_module_result_path(object.my_module, object),
|
||||
update_url: my_module_result_path(object.my_module, object),
|
||||
create_table_url: my_module_result_tables_path(object.my_module, object),
|
||||
create_text_url: my_module_result_texts_path(object.my_module, object),
|
||||
update_asset_view_mode_url: update_asset_view_mode_my_module_result_path(object.my_module,
|
||||
object),
|
||||
update_view_state_url: update_view_state_my_module_result_path(object.my_module, object),
|
||||
direct_upload_url: rails_direct_uploads_url,
|
||||
upload_attachment_url: upload_attachment_my_module_result_path(object.my_module, object),
|
||||
reorder_elements_url: reorder_my_module_result_result_orderable_elements_path(
|
||||
object.my_module, object
|
||||
)
|
||||
})
|
||||
end
|
||||
|
||||
urls_list[:restore_url] = restore_my_module_result_path(object.my_module, object) if can_restore_result?(object)
|
||||
urls_list[:delete_url] = my_module_result_path(object.my_module, object) if can_delete_result?(object)
|
||||
if can_create_results?(object.my_module)
|
||||
urls_list[:duplicate_url] = duplicate_my_module_result_url(object.my_module, object)
|
||||
urls_list[:duplicate_url] =
|
||||
duplicate_my_module_result_url(object.my_module, object)
|
||||
end
|
||||
|
||||
urls_list
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<div data-hook="secondary-navigation-tabs"></div>
|
||||
<% if can_read_experiment?(@my_module.experiment) && !@my_module.archived_branch? %>
|
||||
<a class="p-3 border-b-4 border-transparent hover:no-underline uppercase text-bold capitalize <%= is_module_archive? ? "text-sn-blue" : "text-sn-grey" %>"
|
||||
href="<%= archive_my_module_url(@my_module) %>"
|
||||
href="<%= my_module_results_path(@my_module, view_mode: :archived) %>"
|
||||
title="<%= t'nav2.modules.archive' %>"
|
||||
>
|
||||
<%= t("nav2.modules.archive") %>
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
<%= render partial: 'my_modules/header_actions' %>
|
||||
|
||||
<div id="results" data-behaviour="vue">
|
||||
<results url="<%= my_module_results_url(@my_module) %>">
|
||||
<results url="<%= my_module_results_url(@my_module, view_mode: params[:view_mode]) %>"
|
||||
can-create=<%= can_create_results?(@my_module) && params[:view_mode].blank? %>>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ en:
|
|||
full_name: "Full name"
|
||||
initials: "Initials"
|
||||
avatar: "Avatar"
|
||||
|
||||
|
||||
activejob:
|
||||
failure_notifiable_job:
|
||||
general_notification_title: "Your export failed. Please contact support."
|
||||
|
@ -1312,6 +1312,8 @@ en:
|
|||
rearrange: "Rearrange"
|
||||
archive: "Archive"
|
||||
duplicate: "Duplicate"
|
||||
restore: "Restore"
|
||||
delete: "Delete"
|
||||
move_modal:
|
||||
search_placeholder: "Enter result name"
|
||||
no_options_placeholder: "No results available to select"
|
||||
|
|
|
@ -539,6 +539,12 @@ Rails.application.routes.draw do
|
|||
post :update_view_state
|
||||
post :update_asset_view_mode
|
||||
post :duplicate
|
||||
post :archive
|
||||
post :restore
|
||||
end
|
||||
|
||||
resources :result_orderable_elements do
|
||||
post :reorder, on: :collection
|
||||
end
|
||||
|
||||
resources :tables, controller: 'result_elements/tables', only: %i(create destroy update) do
|
||||
|
@ -555,7 +561,6 @@ Rails.application.routes.draw do
|
|||
post :duplicate
|
||||
end
|
||||
end
|
||||
post 'archive', to: 'results#archive'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -614,15 +619,6 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :results, only: [:update, :destroy] do
|
||||
resources :result_orderable_elements do
|
||||
post :reorder, on: :collection
|
||||
end
|
||||
resources :result_comments,
|
||||
path: '/comments',
|
||||
only: %i(create index update destroy)
|
||||
end
|
||||
|
||||
resources :result_texts, only: [:edit, :update, :destroy]
|
||||
get 'result_texts/:id/download' => 'result_texts#download',
|
||||
as: :result_text_download
|
||||
|
|
Loading…
Reference in a new issue