mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-01 13:13:22 +08:00
Merge pull request #3460 from artoscinote/ma_SCI_5942
Integrated backend and frontend [SCI-5942]
This commit is contained in:
commit
919e583aa6
18 changed files with 221 additions and 85 deletions
32
app/assets/javascripts/sitewide/print_progress_modal.js
Normal file
32
app/assets/javascripts/sitewide/print_progress_modal.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
function updateProgressModal() {
|
||||
var status;
|
||||
var modal = $(document).find('.label-printing-progress-modal');
|
||||
|
||||
if (modal.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.getJSON(
|
||||
`/label_printers/${modal.data('labelPrinterId')}/update_progress_modal`
|
||||
+ `?starting_item_count=${modal.data('startingItemCount')}`,
|
||||
function(data) {
|
||||
modal.replaceWith(data.html);
|
||||
|
||||
status = modal.data('label-printer-status');
|
||||
if (status !== 'done' && status !== 'error') {
|
||||
setTimeout(updateProgressModal, 3000);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).on('click', '.label-printing-progress-modal .close', function() {
|
||||
$(this).closest('.label-printing-progress-modal').remove();
|
||||
});
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
var modal = $(document).find('.label-printing-progress-modal');
|
||||
if (modal.length > 0) {
|
||||
updateProgressModal();
|
||||
}
|
||||
});
|
|
@ -67,7 +67,7 @@
|
|||
$(this).remove();
|
||||
});
|
||||
|
||||
dropdownSelector.init('#modal-print-repository-row-label #printers', {
|
||||
dropdownSelector.init('#modal-print-repository-row-label #label_printer_id', {
|
||||
noEmptyOption: true,
|
||||
singleSelect: true,
|
||||
closeOnSelect: true,
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
border-color: $brand-warning;
|
||||
color: $color-white;
|
||||
}
|
||||
|
||||
&[data-status="error"] {
|
||||
background: $brand-danger;
|
||||
border-color: $brand-danger;
|
||||
color: $color-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +58,7 @@
|
|||
color: $brand-success;
|
||||
}
|
||||
|
||||
&[data-status="waiting_labels"] {
|
||||
&[data-status="waiting_labels"], &[data-status="error"] {
|
||||
color: $brand-danger;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class LabelPrintersController < ApplicationController
|
||||
include InputSanitizeHelper
|
||||
|
||||
before_action :check_manage_permissions, except: :index
|
||||
before_action :check_manage_permissions, except: %i(index update_progress_modal)
|
||||
before_action :find_label_printer, only: %i(edit update destroy)
|
||||
|
||||
def index
|
||||
|
@ -59,8 +59,22 @@ class LabelPrintersController < ApplicationController
|
|||
render json: { job_id: print_job.job_id }
|
||||
end
|
||||
|
||||
def update_progress_modal
|
||||
render(
|
||||
json: {
|
||||
html:
|
||||
render_to_string(
|
||||
partial: 'label_printers/print_progress_modal',
|
||||
locals: {
|
||||
starting_item_count: params[:starting_item_count].to_i,
|
||||
label_printer: LabelPrinter.find(params[:id])
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def create_fluics
|
||||
# Placeholder for FLUICS printer management
|
||||
begin
|
||||
printers = LabelPrinters::Fluics::ApiClient.new(label_printer_params[:fluics_api_key]).list
|
||||
|
||||
|
@ -74,7 +88,10 @@ class LabelPrintersController < ApplicationController
|
|||
language_type: :zpl
|
||||
)
|
||||
|
||||
label_printer.update(name: fluics_printer['serviceName'])
|
||||
label_printer.update(
|
||||
name: fluics_printer['serviceName'],
|
||||
description: fluics_printer['comment']
|
||||
)
|
||||
end
|
||||
rescue LabelPrinters::Fluics::ApiClient::BadRequestError
|
||||
flash[:error] = t('users.settings.account.label_printer.api_key_error')
|
||||
|
|
|
@ -49,12 +49,8 @@ class RepositoriesController < ApplicationController
|
|||
@display_delete_button = can_delete_repository_rows?(@repository)
|
||||
@display_duplicate_button = can_create_repository_rows?(@repository)
|
||||
@snapshot_provisioning = @repository.repository_snapshots.provisioning.any?
|
||||
@printing = {
|
||||
printer_name: 'Fluics label printer',
|
||||
printer_status: :out_of_labels,
|
||||
items: RepositoryRow.all,
|
||||
printing_status: :waiting_labels
|
||||
}
|
||||
|
||||
@busy_printer = LabelPrinter.where.not(current_print_job_ids: []).first
|
||||
end
|
||||
|
||||
def table_toolbar
|
||||
|
|
|
@ -73,7 +73,7 @@ class RepositoryRowsController < ApplicationController
|
|||
|
||||
def print_modal
|
||||
@repository_rows = @repository.repository_rows.where(id: params[:rows])
|
||||
@printers = []
|
||||
@printers = LabelPrinter.all
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
|
@ -85,6 +85,29 @@ class RepositoryRowsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def print
|
||||
label_printer = LabelPrinter.find(params[:label_printer_id])
|
||||
|
||||
# reset potential error state
|
||||
label_printer.update!(status: :ready, current_print_job_ids: [])
|
||||
|
||||
job_ids = RepositoryRow.where(id: params[:repository_row_ids]).flat_map do |repository_row|
|
||||
Array.new(params[:copies].to_i).map do
|
||||
LabelPrinters::PrintJob.perform_later(
|
||||
label_printer,
|
||||
LabelTemplate.first.render( # Currently we will only use the default template
|
||||
item_id: repository_row.code,
|
||||
item_name: repository_row.name
|
||||
)
|
||||
).job_id
|
||||
end
|
||||
end
|
||||
|
||||
label_printer.update!(current_print_job_ids: job_ids)
|
||||
|
||||
redirect_to repository_path(@repository)
|
||||
end
|
||||
|
||||
def update
|
||||
row_update = RepositoryRows::UpdateRepositoryRowService
|
||||
.call(repository_row: @repository_row, user: current_user, params: update_params)
|
||||
|
|
|
@ -2,8 +2,15 @@
|
|||
|
||||
module LabelPrinters
|
||||
class PrintJob < ApplicationJob
|
||||
MAX_STATUS_UPDATES = 10
|
||||
|
||||
queue_as :high_priority
|
||||
|
||||
discard_on(StandardError) do |job, _error|
|
||||
label_printer = job.arguments.first
|
||||
label_printer.update!(status: :error)
|
||||
end
|
||||
|
||||
def perform(label_printer, payload)
|
||||
case label_printer.type_of
|
||||
when 'fluics'
|
||||
|
@ -14,7 +21,25 @@ module LabelPrinters
|
|||
api_client.print(label_printer.fluics_lid, payload)
|
||||
|
||||
# wait for FLUICS printer to stop being busy
|
||||
sleep(5) while api_clinet.status(label_printer.fluics_lid).dig('printerState', 'printerStatus') != '00'
|
||||
MAX_STATUS_UPDATES.times do
|
||||
status =
|
||||
LabelPrinter::FLUICS_STATUS_MAP[
|
||||
api_client.status(label_printer.fluics_lid).dig('printerState', 'printerStatus')
|
||||
]
|
||||
label_printer.update!(status: status)
|
||||
|
||||
break if status == :ready
|
||||
|
||||
sleep 5
|
||||
end
|
||||
end
|
||||
|
||||
# mark as unreachable if no final state is reached
|
||||
label_printer.update!(status: :unreachable) unless label_printer.status.in? %w(ready out_of_labels)
|
||||
|
||||
label_printer.with_lock do
|
||||
label_printer.current_print_job_ids.delete(job_id)
|
||||
label_printer.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class LabelPrinter < ApplicationRecord
|
||||
FLUICS_STATUS_MAP = Hash.new(:error).merge(
|
||||
{
|
||||
'00' => :ready,
|
||||
'50' => :busy,
|
||||
'60' => :busy,
|
||||
'01' => :out_of_labels,
|
||||
'02' => :out_of_labels
|
||||
}
|
||||
).freeze
|
||||
|
||||
enum type_of: { fluics: 0 }
|
||||
enum language_type: { zpl: 0 }
|
||||
enum status: { ready: 0, busy: 1, out_of_labels: 2, unreachable: 3, error: 4 }
|
||||
|
||||
validates :name, presence: true
|
||||
validates :type_of, presence: true
|
||||
validates :language_type, presence: true
|
||||
|
||||
def ready?
|
||||
true # TODO
|
||||
def display_name
|
||||
"#{name} • #{description}"
|
||||
end
|
||||
|
||||
def done?
|
||||
current_print_job_ids.blank? && ready?
|
||||
end
|
||||
|
||||
def printing?
|
||||
current_print_job_ids.any? && ready?
|
||||
end
|
||||
|
||||
def printing_status
|
||||
return 'printing' if printing?
|
||||
|
||||
return 'done' if done?
|
||||
|
||||
status
|
||||
end
|
||||
end
|
||||
|
|
27
app/views/label_printers/_print_progress_modal.html.erb
Normal file
27
app/views/label_printers/_print_progress_modal.html.erb
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div class="label-printing-progress-modal" data-label-printer-status="<%= label_printer.printing_status %>" data-label-printer-id="<%= label_printer.id %>" data-starting-item-count="<%= starting_item_count %>">
|
||||
<div class="modal-header">
|
||||
<div class="title">
|
||||
<%= label_printer.name %>
|
||||
</div>
|
||||
<div class="printer-status" data-status="<%= label_printer.status %>">
|
||||
<% if label_printer.ready? %>
|
||||
<%= t('label_printers.modal_printing_status.printer_status.ready') %>
|
||||
<% elsif label_printer.out_of_labels? %>
|
||||
<%= t('label_printers.modal_printing_status.printer_status.out_of_labels') %>
|
||||
<% elsif label_printer.error? %>
|
||||
<%= t('label_printers.modal_printing_status.printer_status.error') %>
|
||||
<% else %>
|
||||
<%= t('label_printers.modal_printing_status.printer_status.not_ready') %>
|
||||
<% end %>
|
||||
</div>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="printing-items">
|
||||
<%= t('label_printers.modal_printing_status.multiple_items', starting_item_count: starting_item_count, item_count: starting_item_count - label_printer.current_print_job_ids.length) %>
|
||||
</div>
|
||||
<div class="printing-status" data-status="<%= label_printer.printing_status %>">
|
||||
<%= t("label_printers.modal_printing_status.printing_status.#{label_printer.printing_status}") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -88,7 +88,7 @@
|
|||
<% if @label_printers.any? %>
|
||||
<% @label_printers.each do |printer| %>
|
||||
<li>
|
||||
<b><%= printer.name %></b>
|
||||
<b><%= printer.name %></b> • <%= printer.description %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% else %>
|
||||
|
|
|
@ -1,34 +1,38 @@
|
|||
<div class="modal fade" id="modal-print-repository-row-label" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
|
||||
<% if @printers.size > 0 %>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">
|
||||
<% if @repository_rows.size == 1 %>
|
||||
<%= t('repository_row.modal_print_label.head_title', repository_row: @repository_rows.first.name) %>
|
||||
<span class="id-label">
|
||||
<%= t('repository_row.modal_print_label.id_label', repository_row_id: @repository_rows.first.id) %>
|
||||
</span>
|
||||
<% else %>
|
||||
<%= t('repository_row.modal_print_label.head_title_multiple', repository_rows: @repository_rows.size) %>
|
||||
<% end %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class=printers-container>
|
||||
<label><%= t('repository_row.modal_print_label.printer') %></label>
|
||||
<%= select_tag "printers", options_for_select(@printers) %>
|
||||
<%= form_tag print_repository_repository_rows_path do %>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">
|
||||
<% if @repository_rows.size == 1 %>
|
||||
<%= t('repository_row.modal_print_label.head_title', repository_row: @repository_rows.first.name) %>
|
||||
<span class="id-label">
|
||||
<%= t('repository_row.modal_print_label.id_label', repository_row_id: @repository_rows.first.code) %>
|
||||
</span>
|
||||
<% else %>
|
||||
<%= t('repository_row.modal_print_label.head_title_multiple', repository_rows: @repository_rows.size) %>
|
||||
<% end %>
|
||||
</h4>
|
||||
</div>
|
||||
<p class="sci-input-container">
|
||||
<label><%= t('repository_row.modal_print_label.number_of_copies') %></label>
|
||||
<%= number_field_tag :copies, 1, min: 1, class: 'sci-input-field print-copies-input' %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal"><%= t('repository_row.modal_print_label.print_label') %></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<% @repository_rows.each do |repository_row| %>
|
||||
<%= hidden_field_tag 'repository_row_ids[]', repository_row.id %>
|
||||
<% end %>
|
||||
<div class=printers-container>
|
||||
<label><%= t('repository_row.modal_print_label.printer') %></label>
|
||||
<%= select_tag :label_printer_id, options_for_select(@printers.map { |p| [p.display_name, p.id] }) %>
|
||||
</div>
|
||||
<p class="sci-input-container">
|
||||
<label><%= t('repository_row.modal_print_label.number_of_copies') %></label>
|
||||
<%= number_field_tag :copies, 1, min: 1, class: 'sci-input-field print-copies-input' %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<%= submit_tag t('repository_row.modal_print_label.print_label'), class: 'btn btn-primary' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="modal-body no-printers-container">
|
||||
<%= image_tag 'printers/no_available_printers' %>
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<div class="label-printing-progress-modal">
|
||||
<div class="modal-header">
|
||||
<div class="title">
|
||||
<%= @printing[:printer_name] %>
|
||||
</div>
|
||||
<div class="printer-status" data-status="<%= @printing[:printer_status] %>">
|
||||
<% if @printing[:printer_status] == :ready %>
|
||||
<%= t('repository_row.modal_printing_status.printer_status.ready') %>
|
||||
<% elsif @printing[:printer_status] == :out_of_labels %>
|
||||
<%= t('repository_row.modal_printing_status.printer_status.not_ready') %>
|
||||
<% else %>
|
||||
<%= t('repository_row.modal_printing_status.printer_status.out_of_label') %>
|
||||
<% end %>
|
||||
</div>
|
||||
<button type="button" class="close"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="printing-items">
|
||||
<% if @printing[:items].size == 1 %>
|
||||
<%= @printing[:items].first.name %>
|
||||
<span class="id-label">
|
||||
<%= t('repository_row.modal_printing_status.id_label', repository_row_id: @printing[:items].first.id) %>
|
||||
</span>
|
||||
<% else %>
|
||||
<%= t('repository_row.modal_printing_status.multiple_items', repository_rows_count: @printing[:items].length) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="printing-status" data-status="<%= @printing[:printing_status] %>">
|
||||
<% if @printing[:printing_status] == :done %>
|
||||
<%= t('repository_row.modal_printing_status.printing_status.done') %>
|
||||
<% elsif @printing[:printing_status] == :waiting_labels %>
|
||||
<%= t('repository_row.modal_printing_status.printing_status.waiting_labels') %>
|
||||
<% else %>
|
||||
<%= t('repository_row.modal_printing_status.printing_status.printing') %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -20,7 +20,7 @@
|
|||
<p>
|
||||
<span>
|
||||
<%= t('repository_row.modal_info.ID') %>
|
||||
<%= @repository_row.parent_id || @repository_row.id %>
|
||||
<%= @repository_row.code %>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
|
|
|
@ -159,7 +159,11 @@
|
|||
<%= render partial: 'repositories/import_repository_records_modal',
|
||||
locals: { repository: @repository } %>
|
||||
|
||||
<%= render partial: 'repositories/print_progress_modal' %>
|
||||
<% if @busy_printer %>
|
||||
<%= render(
|
||||
partial: 'label_printers/print_progress_modal',
|
||||
locals: { starting_item_count: @busy_printer.current_print_job_ids.length, label_printer: @busy_printer }) %>
|
||||
<% end %>
|
||||
|
||||
<%= render partial: "repositories/delete_record_modal" %>
|
||||
<%= render partial: 'repositories/export_repository_modal',
|
||||
|
|
|
@ -1630,17 +1630,19 @@ en:
|
|||
title: "There seems to be no printer available"
|
||||
description: "To learn more about printing labels and label printers please visit our blog."
|
||||
visit_blog: "Visit blog"
|
||||
label_printers:
|
||||
modal_printing_status:
|
||||
printer_status:
|
||||
ready: "Ready"
|
||||
not_ready: "Not Ready"
|
||||
out_of_labels: "Out of labels"
|
||||
id_label: "ID: %{repository_row_id}"
|
||||
multiple_items: "%{repository_rows_count} labels"
|
||||
error: "Printer error"
|
||||
multiple_items: "%{item_count}/%{starting_item_count} labels"
|
||||
printing_status:
|
||||
done: "Done"
|
||||
printing: "Printing"
|
||||
waiting_labels: "Waiting for labels. Please, insert labels."
|
||||
out_of_labels: "Waiting for labels. Please, insert labels."
|
||||
error: "There is an issue with the printer."
|
||||
activities:
|
||||
index:
|
||||
global_activities_title: "Global activities"
|
||||
|
|
|
@ -46,7 +46,11 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :label_printers, except: :show, path: 'users/settings/account/addons/label_printers' do
|
||||
post :create_fluics, on: :collection
|
||||
end
|
||||
|
||||
resources :label_printers, only: [] do
|
||||
post :print, on: :member
|
||||
get :update_progress_modal, on: :member
|
||||
end
|
||||
|
||||
get 'users/settings/account/connected_accounts',
|
||||
|
@ -567,6 +571,7 @@ Rails.application.routes.draw do
|
|||
resources :repository_rows, only: %i(create show update) do
|
||||
collection do
|
||||
get :print_modal
|
||||
post :print
|
||||
end
|
||||
member do
|
||||
get :assigned_task_list
|
||||
|
|
|
@ -4,12 +4,15 @@ class CreateLabelPrinters < ActiveRecord::Migration[6.1]
|
|||
def change
|
||||
create_table :label_printers do |t|
|
||||
t.string :name, null: false
|
||||
t.string :description
|
||||
t.integer :type_of, null: false
|
||||
t.integer :language_type, null: false
|
||||
t.string :host
|
||||
t.integer :port
|
||||
t.string :fluics_api_key
|
||||
t.string :fluics_lid
|
||||
t.string :current_print_job_ids, array: true, default: []
|
||||
t.integer :status, default: 0
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
|
|
@ -562,12 +562,15 @@ ALTER SEQUENCE public.experiments_id_seq OWNED BY public.experiments.id;
|
|||
CREATE TABLE public.label_printers (
|
||||
id bigint NOT NULL,
|
||||
name character varying NOT NULL,
|
||||
description character varying,
|
||||
type_of integer NOT NULL,
|
||||
language_type integer NOT NULL,
|
||||
host character varying,
|
||||
port integer,
|
||||
fluics_api_key character varying,
|
||||
fluics_lid character varying,
|
||||
current_print_job_ids character varying[] DEFAULT '{}'::character varying[],
|
||||
status integer DEFAULT 0,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue