mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-06 03:46:39 +08:00
Print status backend + FE integration [SCI-5942]
This commit is contained in:
parent
43571b5692
commit
123e415a4f
15 changed files with 171 additions and 81 deletions
24
app/assets/javascripts/sitewide/print_progress_modal.js
Normal file
24
app/assets/javascripts/sitewide/print_progress_modal.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
$(document).on('click', '.label-printing-progress-modal .close', function() {
|
||||
$(this).parent().parent().remove();
|
||||
});
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
var modal = $(document).find('.label-printing-progress-modal');
|
||||
if (modal.length > 0) {
|
||||
window.printerModalReloadInterval = setInterval(function() {
|
||||
modal = $(document).find('.label-printing-progress-modal');
|
||||
|
||||
if (modal.length === 0) {
|
||||
clearInterval(window.printerModalReloadInterval);
|
||||
return;
|
||||
}
|
||||
$.getJSON(
|
||||
`/label_printers/${modal.data('labelPrinterId')}/update_progress_modal`
|
||||
+ `?starting_item_count=${modal.data('startingItemCount')}`,
|
||||
function(data) { modal.replaceWith(data.html); }
|
||||
);
|
||||
}, 3000);
|
||||
} else if (window.printerModalReloadInterval) {
|
||||
clearInterval(window.printerModalReloadInterval);
|
||||
}
|
||||
});
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,27 @@ class RepositoryRowsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def print
|
||||
label_printer = LabelPrinter.find(params[:label_printer_id])
|
||||
label_printer.update!(status: :ready) # reset potential error state
|
||||
|
||||
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)
|
||||
|
|
|
@ -14,8 +14,26 @@ 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'
|
||||
loop do
|
||||
status =
|
||||
LabelPrinters::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
|
||||
|
||||
label_printer.with_lock do
|
||||
label_printer.current_print_job_ids.delete(job_id)
|
||||
label_printer.save!
|
||||
end
|
||||
end
|
||||
rescue StandardError => e
|
||||
label_printer.update(status: :error)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
# 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
|
||||
end
|
||||
|
|
25
app/views/label_printers/_print_progress_modal.html.erb
Normal file
25
app/views/label_printers/_print_progress_modal.html.erb
Normal file
|
@ -0,0 +1,25 @@
|
|||
<div class="label-printing-progress-modal" 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') %>
|
||||
<% 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.status %>">
|
||||
<%= t("label_printers.modal_printing_status.printing_status.#{label_printer.current_print_job_ids.length == 0 ? 'done' : 'printing'}") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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.id) %>
|
||||
</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>
|
|
@ -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,17 @@ 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"
|
||||
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."
|
||||
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…
Add table
Reference in a new issue