Merge pull request #3460 from artoscinote/ma_SCI_5942

Integrated backend and frontend [SCI-5942]
This commit is contained in:
artoscinote 2021-08-02 15:55:03 +02:00 committed by GitHub
commit 919e583aa6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 221 additions and 85 deletions

View 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();
}
});

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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')

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View 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">&times;</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>

View file

@ -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 %>

View file

@ -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">&times;</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">&times;</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' %>

View file

@ -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">&times;</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>

View file

@ -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>

View file

@ -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',

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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
);