Commit e993fcdd authored by ira.maier's avatar ira.maier
Browse files

Create file attachment for sample; Select and delete single files (with shift...

Create file attachment for sample; Select and delete single files (with shift key function to select multiple files at once); add new files; Turned off Turbolinks in Gemfile for reloading JavaScript
parent f26a3582
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0'
gem 'rails','5.2.0'
gem 'bcrypt','~>3.1.11'
......@@ -44,7 +43,7 @@ gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'jquery-turbolinks'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
......@@ -74,6 +73,7 @@ group :development do
gem 'capistrano-rails'
gem 'capistrano-rvm'
# gem 'capistrano3-delayed-job'
gem 'activestorage'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
......
......@@ -5,7 +5,9 @@ application up and running.
Things you may want to cover:
* Ruby version
* Ruby version: 2.6.6
* Bootstrap 3
* System dependencies
......
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
document.addEventListener('DOMContentLoaded', function() {
console.log("test js from assets");
let selectAllCheckbox= document.querySelector('#article_delete_files');
let filenameCheckboxes = document.querySelectorAll('[name="article[delete_file][]"]');
function shiftToSelect() {
let lastChecked;
function handleCheck(event) {
// Check if shift key is down and check if checkbox is checked
let inBetween = false;
if (event.shiftKey && this.checked) {
filenameCheckboxes.forEach(checkbox => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
if (inBetween) {
checkbox.checked = true;
}
});
}
lastChecked = this;
}
filenameCheckboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck, false));
}
function selectAll(){
function handleSelectAll(event){
if(selectAllCheckbox.checked === true){
filenameCheckboxes.forEach(checkbox => {
checkbox.checked=true;
})
}else{
filenameCheckboxes.forEach(checkbox => {
checkbox.checked=false;
})
}
}
selectAllCheckbox.addEventListener('click', handleSelectAll, false);
}
shiftToSelect();
selectAll();
})
// $(document).ready(function(){
// $('#tb tr.y_n').each(function(i){
......
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
......@@ -3,19 +3,25 @@
@import "font-awesome";
/* universal*/
*, *:before, *:after {
}
h1 {
font-size: 4em;
letter-spacing: -3px;
margin-bottom: 30px;
}
p {
font-size: 1.1em;
line-height: 1.5em;
}
.navbar {
margin-top: 0;
margin-bottom: 0;
border-radius: 0;
//position: fixed;
}
/* Set height of the grid so .sidenav can be 100% (adjust as needed) */
......@@ -52,7 +58,8 @@ footer {
}
body {
padding-top: 25px;
// done removed --> navbar sticks on the top
//padding-top: 25px;
}
......@@ -172,8 +179,9 @@ input {
.timestamp {
color: $gray-light;
//todo
display: block;
margin-left: 60px;
margin-left: 4rem;
}
.gravatar {
float: left;
......@@ -198,7 +206,7 @@ span.picture {
}
}
.table-sortable tbody tr {
cursor: move;
cursor: move;
}
// .table-nonfluid {
// width: auto !important;
......@@ -214,27 +222,30 @@ span.picture {
// }
input.transparent-input{
background-color:transparent !important;
border:none !important;
}
background-color:transparent !important;
border:none !important;
}
.button-link {
background-color: transparent;
border: none;
color:#008fb3;
margin-left: 0;
background-color: transparent;
border: none;
color:#008fb3;
margin-left: 0;
}
.button-link:hover {
color: #006680;
text-decoration: underline;
color: #006680;
text-decoration: underline;
}
// todo?
.panel-default{
max-height:400px;
//max-height:400px;
width: 145%;
border: 0;
overflow-y: auto;
overflow-x: hidden;
}
@font-face {
font-family: "FontAwesome";
src: url('<%= asset_path("fontawesome-webfont.eot") %>');
......@@ -242,8 +253,9 @@ text-decoration: underline;
font-weight: normal;
font-style: normal;
}
div.absolute {
margin-top:10px;
margin-top:10px;
}
.div-table{
display:table;
......@@ -270,6 +282,11 @@ div.absolute {
}
.form_with{
class: "btn btn-info";
}
.remember-me {
display: flex;
#user_remember_me {
......@@ -280,3 +297,12 @@ div.absolute {
.rm-mg-bottom {
margin-bottom: unset;
}
.form-inline {
//display: inline-block;
//float: left;
}
#file_list td{
width: 10rem;
}
\ No newline at end of file
......@@ -33,6 +33,7 @@
display:inline-block;
float: left;
margin: 0rem 0.5rem 0.5rem 0rem;
// err scrolling not working
overflow-y: scroll;
max-width:49%;
width:25%;
......
// Place all the styles related to the StaticPages controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.about{
display:inline-block;
float: left;
// margin-top, margin-right, margin-bottom, margin-left
margin: 0.0rem 1rem 0.5rem 0.0rem;
}
#text{
max-width: 50%;
text-align: left;
}
\ No newline at end of file
class FileStoragesController < ApplicationController
# CRUD order: index, show, new, edit, create, update, destroy and private methods
# GET /file_storages
# GET /file_storages.json
def index
#@file_storages = FileStorage.with_attached_single_file
# FileStorage --> model
@file_storages = FileStorage.with_attached_single_files
@id = params[:id]
end
# GET /file_storages/1
# GET /file_storages/1.json
def show
@file_storage = FileStorage.find(params[:id])
@id = params[:id]
end
# GET /file_storages/new
def new
@file_storage = FileStorage.new
end
# GET /file_storages/1/edit
def edit
end
# POST /file_storages
# POST /file_storages.json
def create
@file_storage = FileStorage.new(file_storage_params)
#todo show current tab
if @file_storage.save
flash[:success] = "Files were saved."
else
flash[:danger] = @file_storage.errors.full_messages.to_sentence
end
end
# PATCH/PUT /file_storages/1
# PATCH/PUT /file_storages/1.json
def update
respond_to do |format|
if @file_storage.update(file_storage_params)
format.html { redirect_to @file_storage, notice: 'File was successfully updated.' }
format.json { render :show, status: :ok, location: @file_storage }
else
format.html { render :edit }
format.json { render json: @file_storage.errors, status: :unprocessable_entity }
end
end
end
# todo delete single file
# changed @file_storage --> @file_storages
def delete
@file_storage = FileStorage.find(params[:id])
if @file_storage.present?
@file_storage.delete
end
redirect_to file_storages_path, :notice => "Your file has been deleted."
end
# DELETE /file_storages/1
# DELETE /file_storages/1.json
# routing error
def destroy
@file_storage = FileStorage.find(params[:id])
if @file_storage.present?
@file_storage.destroy
end
redirect_to file_storages_path, :notice => "Your file has been destroyed."
end
#?
def get_file_storage
@file_storage = FileStorage.find_by(id: params[:id])
end
private
def file_storage_params
params.require(:file_storage).permit(single_files: [])
end
end
require 'RMagick'
class SamplesController < ApplicationController
include SamplesHelper
before_action :authenticate_user!
before_action :correct_user, only: :destroy
before_action :set_sample, only: [:show, :edit, :update, :destroy,:update_status]
respond_to? :html, :js
def new
@sample=Sample.new
@admin=false
end
def create
@sample = current_user.samples.build(sample_params.merge(status:"in preparation"))
if @sample.save
flash[:success] = "Sample created!"
else
flash[:danger] = @sample.errors.full_messages.to_sentence
@samples = current_user.samples[0..-2]
end
redirect_to :back
end
def index
@sample = if params[:display_sample].present?
Sample.find_by(id: params[:display_sample].to_i)
else
current_user.samples.build
end
@title = "Listing Samples"
status = params[:status]
@admin = (current_user.type == 'Operator') && (@admin || params[:is_admin].present?)
status = @sample.status if (status == nil || status == "")
case status
when "in preparation"
@samples = current_user.samples.where('status IN (?)' , ["in preparation"])
when "measured"
@samples = current_user.samples.where('status IN (?)', ["measured"]) unless @admin
@samples = Sample.where('status IN (?)', ["measured"]) if @admin
when "submitted"
@samples = current_user.samples.where('status IN (?)', ["submitted"]) unless @admin
@samples = Sample.where('status IN (?)', ["submitted"]) if @admin
else
redirect_to root_url if @admin
redirect_to root_url+'chemists/'+current_user.id.to_s unless @admin
end
end
def edit
@sample = Sample.find(params[:id])
@sample = params[:id] && Sample.find(params[:id]) || nil
redirect_to(root_url) unless operator? || @user == current_user || @sample.status=="in preparation"
if @sample.status == "measured"
redirect_to :back
end
end
def update
sample = Sample.find(params[:id])
unless sample_params.nil?
sample_params['results_attributes'] && sample_params['results_attributes'].each do |key, val|
Sample::PREDEF_ELEMENTS.each do |el|
if val["element_#{el}"]&.include? ','
sample_params['results_attributes'][key]["element_#{el}"] = val["element_#{el}"].gsub!(',', '.')
end
end
end
if sample.update_attributes(sample_params)
sample.touch
flash[:success] = "Sample updated"
else
flash[:danger] = sample.errors.full_messages.to_sentence
end
else
flash[:warning] = "no results"
end
redirect_to URI(request.referer).path + "?display_sample=#{sample.id}"
end
def show
if operator?
@sample = Sample.find(params[:id])
@user = @sample && @sample.user
else
@sample = current_user.samples.find(params[:id])
@user = @sample && @sample.user
end
file_type = params["format"]
if file_type == 'pdf'
respond_to do |format|
format.html
format.js
format.pdf do
pdf = SamplePdf.new(@sample,operator?,@user)
send_data pdf.render, filename: "sample_#{@sample.id}.pdf",
type:"application/pdf",
disposition: "inline"
end
end
end
if file_type == 'png'
respond_to do |format|
format.html
format.js
format.png do
pdf = SamplePdf.new(@sample,operator?,@user)
send_image(pdf)
end
end
end
end
def destroy
@sample.destroy
flash[:success] = "Sample deleted"
redirect_to :back || root_url
end
def Measured
sample = Sample.find(params[:id])
if sample.status == "in preparation"
sample.status = "submitted"
sample.submitted_at = Time.new
sample.save
end
redirect_to URI(request.referer).path + "?display_sample=#{sample.id}"
end
def Withdraw
sample = Sample.find(params[:id])
if sample.status == "submitted"
sample.status = "in preparation"
sample.submitted_at = nil
sample.save
end
redirect_to URI(request.referer).path + "?display_sample=#{sample.id}"
end
def ReleaseMeasurment
sample = Sample.find(params[:id])
@user = sample && sample.user
if sample.status == "submitted"
sample.status = "measured"
sample.measured_at = Time.new
sample.operator_name = current_user.name
sample.save
end
UserMailer.delay.measured_email(@user,sample)
redirect_to URI(request.referer).path + "?display_sample=#{sample.id}"
flash[:success]= "Sending e-mail to user"
end
def send_image(pdf)
pdf_file_name = "sample_#{@sample.id}.pdf"
png_file_name = "sample_#{@sample.id}.png"
result = pdf_to_png(pdf, pdf_file_name, png_file_name)
send_data result.to_blob, filename: png_file_name, type: "image/png" , disposition: "inline"
end
private
def sample_params
keys=Sample::ELEMENTS.keys
params.require(:sample).permit(:name, :formula, :comment_by_operator, :comment_by_user, results_attributes: [:id, :_destroy, :element_N, :element_C,:element_H, :element_S]) if params[:sample].present?
end
def correct_user
@sample = current_user.samples.find_by(id: params[:id])
redirect_to root_url if @sample.nil?
end
def set_sample
@sample = Sample.find(params[:id])
@result = @sample.results
end
end
class FileStorage < ApplicationRecord
# has_one_attached :single_file
has_many_attached :single_files
end
# <% todo delete?%>
def purge_file(ref)
end
json.extract! file_storage, :id, :created_at, :updated_at
json.url file_storage_url(file_storage, format: :json)
<h1>Editing File Storage</h1>
<%= render 'form', file_storage: @file_storage %>
<%= link_to 'Show', @file_storage %> |
<%= link_to 'Back', file_storages_path %>
<p>
<table id="file_list">
<tr>
<th>line</th>
<th>File Storage ID</th>
<!-- <td>name</td>-->
</tr>
<% @file_storages.each.with_index(1) do |file_storage, i| %>
<tr>
<td><%=i%></td>
<td ><%= file_storage.id%></td>
<td><%= link_to 'Show', file_storage_path(file_storage) %></td>
<!-- purge_file(@refAttach),-->
<!-- <td><%#= link_to 'Delete', method: :delete,data: { confirm: 'Are you sure you want to delete?' } %></td>-->
</tr>
<% end %>
</table>
</p>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment