mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-10-31 00:19:20 +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…
	
	Add table
		
		Reference in a new issue