mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-28 11:14:24 +08:00
Adding inline editing to experiment title, project title and task title [SCI-3059] (#1524)
* Adding inline editing to experiment title, project title and task title
This commit is contained in:
parent
3acf9b71f8
commit
b1df8c9aa7
11 changed files with 259 additions and 8 deletions
|
@ -38,6 +38,7 @@
|
|||
//= require users/settings/teams/invite_users_modal
|
||||
//= require select2.min
|
||||
//= require select2_customization
|
||||
//= require shared/inline_editing
|
||||
//= require turbolinks
|
||||
|
||||
|
||||
|
|
63
app/assets/javascripts/shared/inline_editing.js
Normal file
63
app/assets/javascripts/shared/inline_editing.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
function initInlineEditing(title) {
|
||||
var editBlock = $('.' + title + '-editable-field');
|
||||
var inputString = editBlock.find('input');
|
||||
|
||||
function updateField() {
|
||||
var params = {};
|
||||
|
||||
if (inputString[0].value === editBlock[0].dataset.originalName) {
|
||||
inputString[0].disabled = true;
|
||||
return false;
|
||||
}
|
||||
params[editBlock[0].dataset.paramsGroup] = {};
|
||||
params[editBlock[0].dataset.paramsGroup][editBlock[0].dataset.fieldToUpdate] = inputString[0].value;
|
||||
$.ajax({
|
||||
url: editBlock[0].dataset.pathToUpdate,
|
||||
type: 'PUT',
|
||||
dataType: 'json',
|
||||
data: params,
|
||||
success: function() {
|
||||
editBlock[0].dataset.originalName = inputString[0].value;
|
||||
editBlock[0].dataset.error = false;
|
||||
inputString[0].disabled = true;
|
||||
},
|
||||
error: function(response) {
|
||||
var errors = response.responseJSON;
|
||||
editBlock[0].dataset.error = true;
|
||||
if (response.responseJSON.errors === undefined) {
|
||||
errors = errors[editBlock[0].dataset.fieldToUpdate][0];
|
||||
} else {
|
||||
errors = errors.errors[editBlock[0].dataset.fieldToUpdate][0];
|
||||
}
|
||||
editBlock.find('.error-block')[0].innerHTML = errors;
|
||||
inputString.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editBlock.click(e => {
|
||||
if (inputString[0].disabled) {
|
||||
inputString[0].disabled = false;
|
||||
inputString.focus();
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$(window).click(() => {
|
||||
if (inputString[0].disabled === false) {
|
||||
updateField();
|
||||
}
|
||||
});
|
||||
|
||||
$(editBlock.find('.save-button')).click(e => {
|
||||
updateField();
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$(editBlock.find('.cancel-button')).click(e => {
|
||||
inputString[0].disabled = true;
|
||||
editBlock[0].dataset.error = false;
|
||||
inputString[0].value = editBlock[0].dataset.originalName;
|
||||
e.stopPropagation();
|
||||
});
|
||||
}
|
94
app/assets/stylesheets/partials/_inline_editing.scss
Normal file
94
app/assets/stylesheets/partials/_inline_editing.scss
Normal file
|
@ -0,0 +1,94 @@
|
|||
@import "constants";
|
||||
@import "mixins";
|
||||
|
||||
|
||||
.inline-editing-container {
|
||||
position: relative;
|
||||
|
||||
.button-container {
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 72px;
|
||||
|
||||
span {
|
||||
color: $color-silver;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 36px;
|
||||
|
||||
&:nth-child(1) {left: 0;}
|
||||
|
||||
&:nth-child(2) {right: 0;}
|
||||
}
|
||||
}
|
||||
|
||||
.error-block {
|
||||
bottom: 3px;
|
||||
color: $brand-danger;
|
||||
display: none;
|
||||
font-size: $font-size-small;
|
||||
left: 5px;
|
||||
line-height: 12px;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
||||
&[data-error="true"] {
|
||||
|
||||
.error-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input {
|
||||
padding-bottom: 16px;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid $color-silver;
|
||||
border-radius: $border-radius-small;
|
||||
cursor: pointer;
|
||||
line-height: 20px;
|
||||
padding: 8px 5px;
|
||||
padding-right: 36px;
|
||||
width: calc(100% - 36px);
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: transparent;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
+ .button-container {
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 1px solid $color-gainsboro;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-name.editable {
|
||||
margin: 0;
|
||||
|
||||
.inline-editing-container {
|
||||
|
||||
input {
|
||||
line-height: 26px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -119,24 +119,24 @@ class ExperimentsController < ApplicationController
|
|||
)
|
||||
)
|
||||
@experiment.touch(:workflowimg_updated_at)
|
||||
flash[:success] = t('experiments.update.success_flash',
|
||||
experiment: @experiment.name)
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {}, status: :ok
|
||||
end
|
||||
format.html do
|
||||
flash[:success] = t('experiments.update.success_flash',
|
||||
experiment: @experiment.name)
|
||||
redirect_to project_path(@experiment.project)
|
||||
end
|
||||
end
|
||||
else
|
||||
flash[:alert] = t('experiments.update.error_flash')
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @experiment.errors, status: :unprocessable_entity
|
||||
end
|
||||
format.html do
|
||||
flash[:alert] = t('experiments.update.error_flash')
|
||||
redirect_back(fallback_location: root_path)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
<% provide(:head_title, t("experiments.canvas.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar", locals: { current_experiment: @experiment, page: 'canvas' } %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
<%= render partial: "shared/secondary_navigation" , locals: {
|
||||
editable: {
|
||||
name: 'title',
|
||||
active: true,
|
||||
width: 'calc(100% - 500px)',
|
||||
params_group: 'experiment',
|
||||
field_to_udpate: 'name',
|
||||
path_to_update: experiment_path(@experiment)
|
||||
}
|
||||
}%>
|
||||
|
||||
<div class="content-pane" id="experiment-canvas">
|
||||
<div class="row">
|
||||
|
|
4
app/views/global_activities/_team_selection.html.erb
Normal file
4
app/views/global_activities/_team_selection.html.erb
Normal file
|
@ -0,0 +1,4 @@
|
|||
<h5>Team</h5>
|
||||
<select name="team">
|
||||
<%=options_for_select @teams %>
|
||||
</select>
|
31
app/views/global_activities/index.html.erb
Normal file
31
app/views/global_activities/index.html.erb
Normal file
|
@ -0,0 +1,31 @@
|
|||
<div class="global-activities__container">
|
||||
<br>
|
||||
<div class="global-activities__top">
|
||||
<h2 class="global-activiteis__title">Global activities</h2>
|
||||
</div>
|
||||
|
||||
<div class="global-activities__main">
|
||||
<div class="global-activities__top-actions">
|
||||
<span><i class="fas fa-caret-square-down"></i> Expand All</span>
|
||||
|
||||
<span><i class="fas fa-caret-square-up"></i> Colapse All</span>
|
||||
</div>
|
||||
<div class="global-activities__search-container">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search..." aria-describedby="basic-addon1">
|
||||
<span class="input-group-addon" id="basic-addon1">
|
||||
<i class="fas fa-search"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="global-activities_activities-list">
|
||||
<h2>list of activities</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="global-activities__side">
|
||||
<%= render "team_selection" %>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -2,7 +2,16 @@
|
|||
|
||||
<%= render partial: 'shared/drag_n_drop_overlay' %>
|
||||
<%= render partial: "shared/sidebar", locals: { current_task: @my_module, page: 'task' } %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
<%= render partial: "shared/secondary_navigation", locals: {
|
||||
editable: {
|
||||
name: 'title',
|
||||
active: true,
|
||||
width: 'calc(100% - 580px)',
|
||||
params_group: 'my_module',
|
||||
field_to_udpate: 'name',
|
||||
path_to_update: my_module_path(@my_module)
|
||||
}
|
||||
} %>
|
||||
|
||||
<div class="content-pane my-modules-protocols-index">
|
||||
<%= render partial: "module_header" %>
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
<% provide(:head_title, t("projects.show.head_title", project: h(@project.name)).html_safe) %>
|
||||
<%= render partial: "shared/sidebar", locals: { current_project: @project, page: 'project' } %>
|
||||
<%= render partial: "shared/secondary_navigation" %>
|
||||
<%= render partial: "shared/secondary_navigation", locals: {
|
||||
editable: {
|
||||
name: 'title',
|
||||
active: true,
|
||||
width: 'calc(100% - 500px)',
|
||||
params_group: 'project',
|
||||
field_to_udpate: 'name',
|
||||
path_to_update: project_path(@project)
|
||||
}
|
||||
}%>
|
||||
|
||||
<div class="content-pane" id="project-show">
|
||||
<div class="row">
|
||||
|
|
19
app/views/shared/_inline_editing.html.erb
Normal file
19
app/views/shared/_inline_editing.html.erb
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div
|
||||
class="inline-editing-container <%= name %>-editable-field"
|
||||
style="width:<%= (defined? width) ? width.html_safe : '100%' %>"
|
||||
data-field-to-update="<%= field_to_udpate %>"
|
||||
data-params-group="<%= params_group %>"
|
||||
data-path-to-update="<%= path_to_update %>"
|
||||
data-original-name="<%= initial_value %>"
|
||||
error="false"
|
||||
>
|
||||
<input type="text" value="<%= initial_value %>" disabled/>
|
||||
<div class="button-container">
|
||||
<span class="save-button"><i class="fas fa-check"></i></span>
|
||||
<span class="cancel-button"><i class="fas fa-times"></i></span>
|
||||
</div>
|
||||
<span class="error-block"></span>
|
||||
</div>
|
||||
<script>
|
||||
initInlineEditing('<%= name %>')
|
||||
</script>
|
|
@ -149,9 +149,21 @@
|
|||
</ul>
|
||||
|
||||
<!-- Secondary navigation title -->
|
||||
<h4 class="nav-name">
|
||||
<%= truncate(title_element.name,
|
||||
<% editable = false if local_assigns[:editable].nil? %>
|
||||
<h4 class="nav-name <%= (editable && editable[:active]) ? 'editable' : '' %>">
|
||||
<% if editable && editable[:active] %>
|
||||
<%= render partial: "shared/inline_editing", locals: {
|
||||
initial_value: truncate(title_element.name, length: Constants::MAX_EDGE_LENGTH),
|
||||
width: editable[:width] || '100%',
|
||||
name: editable[:name],
|
||||
field_to_udpate: editable[:field_to_udpate],
|
||||
path_to_update: editable[:path_to_update],
|
||||
params_group: editable[:params_group]
|
||||
} %>
|
||||
<% else %>
|
||||
<%= truncate(title_element.name,
|
||||
length: Constants::MAX_EDGE_LENGTH) %>
|
||||
<% end %>
|
||||
</h4>
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue