mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-25 09:13:05 +08:00
Add step layout [SCI-6755]
This commit is contained in:
parent
8aaab73856
commit
6dde945d61
10 changed files with 195 additions and 38 deletions
|
@ -39,6 +39,7 @@
|
||||||
@import "reports/*";
|
@import "reports/*";
|
||||||
@import "settings/*";
|
@import "settings/*";
|
||||||
@import "shared/*";
|
@import "shared/*";
|
||||||
|
@import "steps/*";
|
||||||
@import "themes/*";
|
@import "themes/*";
|
||||||
|
|
||||||
@import "*"
|
@import "*"
|
||||||
|
|
30
app/assets/stylesheets/my_modules/protocol.scss
Normal file
30
app/assets/stylesheets/my_modules/protocol.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
.task-protocol {
|
||||||
|
.insert-step {
|
||||||
|
align-items: center;
|
||||||
|
color: $color-concrete;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
background-color: $color-concrete;
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-plus {
|
||||||
|
margin: 0 .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $brand-primary;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
background-color: $brand-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-section {
|
.task-section {
|
||||||
border-left: 3px solid $color-concrete;
|
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
|
|
||||||
|
|
55
app/assets/stylesheets/steps/step.scss
Normal file
55
app/assets/stylesheets/steps/step.scss
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
.step-container {
|
||||||
|
padding: 8px 24px;
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
.step-header {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.step-collapse-link {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
width: 24px;
|
||||||
|
|
||||||
|
&:not(.collapsed) {
|
||||||
|
@include rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-state {
|
||||||
|
border: 2px solid $color-alto;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
width: 24px;
|
||||||
|
|
||||||
|
&.completed {
|
||||||
|
background: $brand-success;
|
||||||
|
border: 2px solid $brand-success;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
@include font-awesome;
|
||||||
|
color: $color-white;
|
||||||
|
content: $font-fas-check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-position {
|
||||||
|
@include font-main;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-name-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-actions-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,13 +32,21 @@ class StepsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
new_step = Step.new(
|
@step = Step.new(
|
||||||
name: t('protocols.steps.default_name'),
|
name: t('protocols.steps.default_name'),
|
||||||
completed: false,
|
completed: false,
|
||||||
user: current_user,
|
user: current_user,
|
||||||
last_modified_by: current_user
|
last_modified_by: current_user
|
||||||
)
|
)
|
||||||
render json: @protocol.insert_step(new_step, params[:position]), serializer: StepSerializer
|
|
||||||
|
@step = @protocol.insert_step(@step, params[:position])
|
||||||
|
# Generate activity
|
||||||
|
if @protocol.in_module?
|
||||||
|
log_activity(:create_step, @my_module.experiment.project, my_module: @my_module.id)
|
||||||
|
else
|
||||||
|
log_activity(:add_step_to_protocol_repository, nil, protocol: @protocol.id)
|
||||||
|
end
|
||||||
|
render json: @step, serializer: StepSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_old
|
def create_old
|
||||||
|
@ -143,6 +151,20 @@ class StepsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
if @step.update(step_params)
|
||||||
|
# Generate activity
|
||||||
|
if @protocol.in_module?
|
||||||
|
log_activity(:edit_step, @my_module.experiment.project, my_module: @my_module.id)
|
||||||
|
else
|
||||||
|
log_activity(:edit_step_in_protocol_repository, nil, protocol: @protocol.id)
|
||||||
|
end
|
||||||
|
render json: @step, serializer: StepSerializer
|
||||||
|
else
|
||||||
|
render json: {}, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_old
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
old_description = @step.description
|
old_description = @step.description
|
||||||
old_checklists = fetch_old_checklists_data(@step)
|
old_checklists = fetch_old_checklists_data(@step)
|
||||||
|
@ -327,19 +349,16 @@ class StepsController < ApplicationController
|
||||||
|
|
||||||
# Complete/uncomplete step
|
# Complete/uncomplete step
|
||||||
def toggle_step_state
|
def toggle_step_state
|
||||||
respond_to do |format|
|
@step.completed = params[:completed] == 'true'
|
||||||
completed = params[:completed] == 'true'
|
|
||||||
changed = @step.completed != completed
|
|
||||||
@step.completed = completed
|
|
||||||
@step.last_modified_by = current_user
|
@step.last_modified_by = current_user
|
||||||
|
|
||||||
if @step.save
|
if @step.save
|
||||||
# Create activity
|
# Create activity
|
||||||
if changed
|
if @step.saved_change_to_completed
|
||||||
completed_steps = @protocol.steps.where(completed: true).count
|
completed_steps = @protocol.steps.where(completed: true).count
|
||||||
all_steps = @protocol.steps.count
|
all_steps = @protocol.steps.count
|
||||||
|
|
||||||
type_of = completed ? :complete_step : :uncomplete_step
|
type_of = @step.completed ? :complete_step : :uncomplete_step
|
||||||
# Toggling step state can only occur in
|
# Toggling step state can only occur in
|
||||||
# module protocols, so my_module is always
|
# module protocols, so my_module is always
|
||||||
# not nil; nonetheless, check if my_module is present
|
# not nil; nonetheless, check if my_module is present
|
||||||
|
@ -351,10 +370,9 @@ class StepsController < ApplicationController
|
||||||
num_all: all_steps.to_s)
|
num_all: all_steps.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
format.json { render json: {}, status: :ok }
|
render json: @step, serializer: StepSerializer
|
||||||
else
|
else
|
||||||
format.json { render json: {}, status: :unprocessable_entity }
|
render json: {}, status: :unprocessable_entity
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -514,6 +532,10 @@ class StepsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def step_params
|
def step_params
|
||||||
|
params.require(:step).permit(:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def step_params_old
|
||||||
params.require(:step).permit(
|
params.require(:step).permit(
|
||||||
:name,
|
:name,
|
||||||
:description,
|
:description,
|
||||||
|
|
|
@ -73,13 +73,13 @@
|
||||||
<div class="protocol-steps">
|
<div class="protocol-steps">
|
||||||
<template v-for="(step, index) in steps">
|
<template v-for="(step, index) in steps">
|
||||||
<div class="step-block" :key="step.id">
|
<div class="step-block" :key="step.id">
|
||||||
<button v-if="index > 0" class="btn btn-primary" @click="addStep(index)">
|
<div v-if="index > 0" class="insert-step" @click="addStep(index)">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
{{ i18n.t("protocols.steps.new_step") }}
|
</div>
|
||||||
</button>
|
|
||||||
<Step
|
<Step
|
||||||
:step.sync="steps[index]"
|
:step.sync="steps[index]"
|
||||||
@step:delete="updateStepsPosition"
|
@step:delete="updateStepsPosition"
|
||||||
|
@step:update="updateStep"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -166,6 +166,9 @@
|
||||||
this.reorderSteps(unordered_steps)
|
this.reorderSteps(unordered_steps)
|
||||||
|
|
||||||
},
|
},
|
||||||
|
updateStep(step) {
|
||||||
|
this.$set(this.steps, step.attributes.position, step)
|
||||||
|
},
|
||||||
reorderSteps(steps) {
|
reorderSteps(steps) {
|
||||||
this.steps = steps.sort((a, b) => a.attributes.position - b.attributes.position);
|
this.steps = steps.sort((a, b) => a.attributes.position - b.attributes.position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,42 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="step-container">
|
<div class="step-container">
|
||||||
{{ step.attributes.position + 1 }}
|
<div class="step-header">
|
||||||
{{ step.attributes.name }}
|
<a class="step-collapse-link"
|
||||||
<button class="btn btn-danger" @click="deleteStep">
|
:href="'#stepBody' + step.id"
|
||||||
|
data-toggle="collapse"
|
||||||
|
data-remote="true">
|
||||||
|
<span class="fas fa-caret-right"></span>
|
||||||
|
</a>
|
||||||
|
<div class="step-complete-container">
|
||||||
|
<div :class="`step-state ${step.attributes.completed ? 'completed' : ''}`" @click="changeState"></div>
|
||||||
|
</div>
|
||||||
|
<div class="step-position">
|
||||||
|
{{ step.attributes.position + 1 }}.
|
||||||
|
</div>
|
||||||
|
<div class="step-name-container">
|
||||||
|
<InlineEdit
|
||||||
|
:value="step.attributes.name"
|
||||||
|
:characterLimit="255"
|
||||||
|
:allowBlank="false"
|
||||||
|
:attributeName="`${i18n.t('Step')} ${i18n.t('name')}`"
|
||||||
|
@update="updateName"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="step-actions-container">
|
||||||
|
<button class="btn icon-btn btn-light" @click="deleteStep">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
{{ i18n.t("protocols.steps.options.delete_title") }}
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapse in" :id="'stepBody' + step.id">
|
||||||
|
Components here
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import InlineEdit from 'vue/shared/inline_edit.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'StepContainer',
|
name: 'StepContainer',
|
||||||
props: {
|
props: {
|
||||||
|
@ -18,6 +45,7 @@
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: { InlineEdit },
|
||||||
methods: {
|
methods: {
|
||||||
deleteStep() {
|
deleteStep() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -31,6 +59,21 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
changeState() {
|
||||||
|
$.post(this.step.attributes.urls.state_url, {completed: !this.step.attributes.completed}, (result) => {
|
||||||
|
this.$emit('step:update', result.data)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateName(newName) {
|
||||||
|
$.ajax({
|
||||||
|
url: this.step.attributes.urls.update_url,
|
||||||
|
type: 'PATCH',
|
||||||
|
data: {step: {name: newName}},
|
||||||
|
success: (result) => {
|
||||||
|
this.$emit('step:update', result.data)
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created( ){
|
created( ){
|
||||||
this.newValue = this.value;
|
this.newValue = this.value || '';
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.autofocus) {
|
if (this.autofocus) {
|
||||||
|
|
|
@ -5,7 +5,9 @@ class StepSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
def urls
|
def urls
|
||||||
{
|
{
|
||||||
delete_url: step_path(object)
|
delete_url: step_path(object),
|
||||||
|
state_url: toggle_step_state_step_path(object),
|
||||||
|
update_url: step_path(object)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,6 +50,8 @@ CREATE FUNCTION public.trim_html_tags(input text, OUT output text) RETURNS text
|
||||||
|
|
||||||
SET default_tablespace = '';
|
SET default_tablespace = '';
|
||||||
|
|
||||||
|
SET default_table_access_method = heap;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: -
|
-- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
|
Loading…
Reference in a new issue