mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-04-14 16:21:14 +08:00
Low stock flyout reminders [SCI-6502] (#3932)
* Display low stock flyout reminder [SCI-6502] * Display low stock flyout reminder [SCI-6502] * Adapt showing stock reminders for every bell icon click [SCI-6502] * Correct hound error [SCI-6502] * Fix event registration for fetching reminder data [SCI-6502] * Fix event registration for fetching reminder data [SCI-6502] * Fix hound [SCI-6502] * Remove not needed line [SCI-6502] * Add reminder template [SCI-6502] * Add clearing messages [SCI-6502]
This commit is contained in:
parent
8b8e2c6d92
commit
d1610fba53
10 changed files with 156 additions and 20 deletions
app
assets
javascripts
my_modules
repositories
sitewide
stylesheets
controllers
models/concerns
views/shared
config/locales
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable no-param-reassign, no-use-before-define */
|
/* eslint-disable no-param-reassign, no-use-before-define */
|
||||||
/* global DataTableHelpers PerfectScrollbar FilePreviewModal animateSpinner HelperModule
|
/* global DataTableHelpers PerfectScrollbar FilePreviewModal animateSpinner HelperModule
|
||||||
initAssignedTasksDropdown I18n prepareRepositoryHeaderForExport */
|
initAssignedTasksDropdown I18n prepareRepositoryHeaderForExport initReminderDropdown */
|
||||||
|
|
||||||
var MyModuleRepositories = (function() {
|
var MyModuleRepositories = (function() {
|
||||||
const FULL_VIEW_MODAL = $('#myModuleRepositoryFullViewModal');
|
const FULL_VIEW_MODAL = $('#myModuleRepositoryFullViewModal');
|
||||||
|
@ -215,6 +215,9 @@ var MyModuleRepositories = (function() {
|
||||||
},
|
},
|
||||||
createdRow: function(row, data) {
|
createdRow: function(row, data) {
|
||||||
$(row).find('.item-name').attr('data-state', data.DT_RowAttr['data-state']);
|
$(row).find('.item-name').attr('data-state', data.DT_RowAttr['data-state']);
|
||||||
|
},
|
||||||
|
fnInitComplete: function() {
|
||||||
|
initReminderDropdown(tableContainer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -268,6 +271,7 @@ var MyModuleRepositories = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
initAssignedTasksDropdown(tableContainer);
|
initAssignedTasksDropdown(tableContainer);
|
||||||
|
initReminderDropdown(tableContainer);
|
||||||
},
|
},
|
||||||
|
|
||||||
drawCallback: function() {
|
drawCallback: function() {
|
||||||
|
|
|
@ -191,7 +191,6 @@ $.fn.dataTable.render.AssignedTasksValue = function(data, row) {
|
||||||
return `<div class="dropdown row-reminders-dropdown" data-row-reminders-url="${row.rowRemindersUrl}">
|
return `<div class="dropdown row-reminders-dropdown" data-row-reminders-url="${row.rowRemindersUrl}">
|
||||||
<i class="fas fa-bell dropdown-toggle row-reminders-icon" data-toggle="dropdown" id="rowReminders${row.DT_RowId}}"></i>
|
<i class="fas fa-bell dropdown-toggle row-reminders-icon" data-toggle="dropdown" id="rowReminders${row.DT_RowId}}"></i>
|
||||||
<ul class="dropdown-menu" role="menu" aria-labelledby="rowReminders${row.DT_RowId}">
|
<ul class="dropdown-menu" role="menu" aria-labelledby="rowReminders${row.DT_RowId}">
|
||||||
List of reminders
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>`
|
</div>`
|
||||||
+ tasksLinkHTML;
|
+ tasksLinkHTML;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
globals I18n _ SmartAnnotation FilePreviewModal animateSpinner DataTableHelpers
|
globals I18n _ SmartAnnotation FilePreviewModal animateSpinner DataTableHelpers
|
||||||
HelperModule RepositoryDatatableRowEditor prepareRepositoryHeaderForExport
|
HelperModule RepositoryDatatableRowEditor prepareRepositoryHeaderForExport
|
||||||
initAssignedTasksDropdown initBMTFilter
|
initAssignedTasksDropdown initBMTFilter initReminderDropdown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//= require jquery-ui/widgets/sortable
|
//= require jquery-ui/widgets/sortable
|
||||||
|
@ -605,6 +605,7 @@ var RepositoryDatatable = (function(global) {
|
||||||
$('#manage-repository-column .back-to-column-modal').trigger('click');
|
$('#manage-repository-column .back-to-column-modal').trigger('click');
|
||||||
|
|
||||||
initAssignedTasksDropdown(TABLE_ID);
|
initAssignedTasksDropdown(TABLE_ID);
|
||||||
|
initReminderDropdown(TABLE_ID);
|
||||||
renderFiltersDropdown();
|
renderFiltersDropdown();
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
adjustTableHeader();
|
adjustTableHeader();
|
||||||
|
@ -674,17 +675,6 @@ var RepositoryDatatable = (function(global) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateReminderDropdownPosition(reminderContainer) {
|
|
||||||
let row = $(reminderContainer).closest('tr');
|
|
||||||
let screenHeight = screen.height;
|
|
||||||
let rowPosition = row[0].getBoundingClientRect().y;
|
|
||||||
if ((screenHeight / 2) < rowPosition) {
|
|
||||||
$(reminderContainer).find('.dropdown-menu').css({ top: 'unset', bottom: '100%' });
|
|
||||||
} else {
|
|
||||||
$(reminderContainer).find('.dropdown-menu').css({ bottom: 'unset', top: '100%' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.repository-show')
|
$('.repository-show')
|
||||||
.on('click', '#addRepositoryRecord', function() {
|
.on('click', '#addRepositoryRecord', function() {
|
||||||
checkAvailableColumns();
|
checkAvailableColumns();
|
||||||
|
@ -782,9 +772,6 @@ var RepositoryDatatable = (function(global) {
|
||||||
})
|
})
|
||||||
.on('click', '#deleteRepositoryRecords', function() {
|
.on('click', '#deleteRepositoryRecords', function() {
|
||||||
$('#deleteRepositoryRecord').modal('show');
|
$('#deleteRepositoryRecord').modal('show');
|
||||||
})
|
|
||||||
.on('show.bs.dropdown', '.row-reminders-dropdown', function() {
|
|
||||||
updateReminderDropdownPosition(this);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle enter key
|
// Handle enter key
|
||||||
|
|
|
@ -62,3 +62,42 @@ function prepareRepositoryHeaderForExport(th) {
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initReminderDropdown(table) {
|
||||||
|
$(table).on('show.bs.dropdown', '.row-reminders-dropdown', function() {
|
||||||
|
let row = $(this).closest('tr');
|
||||||
|
let screenHeight = screen.height;
|
||||||
|
let rowPosition = row[0].getBoundingClientRect().y;
|
||||||
|
if ((screenHeight / 2) < rowPosition) {
|
||||||
|
$(this).find('.dropdown-menu').css({ top: 'unset', bottom: '100%' });
|
||||||
|
} else {
|
||||||
|
$(this).find('.dropdown-menu').css({ bottom: 'unset', top: '100%' });
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url: $(this).attr('data-row-reminders-url'),
|
||||||
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
$('.row-reminders-dropdown .dropdown-menu').html(data.html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(table).on('click', '.row-reminders-footer', function(e) {
|
||||||
|
var dropdownMenuLength = $(this).closest('.dropdown-menu').children().length;
|
||||||
|
var bellIcon = $(this).closest('.row-reminders-dropdown');
|
||||||
|
$.ajax({
|
||||||
|
url: $(this).attr('data-row-hide-reminders-url'),
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function() {
|
||||||
|
$(this).closest('.row-reminders-notification').remove();
|
||||||
|
|
||||||
|
if (dropdownMenuLength === 1) {
|
||||||
|
bellIcon.remove();
|
||||||
|
}
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -529,3 +529,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reminders
|
||||||
|
.row-reminders-notification {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 16px;
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
|
||||||
|
.row-reminders-title {
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-reminders-body {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 35px;
|
||||||
|
margin-top: 5px;
|
||||||
|
text-align: center;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: $color-alto;
|
||||||
|
border-width: 0;
|
||||||
|
height: 1px;
|
||||||
|
margin: 0 16px 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -222,6 +222,39 @@
|
||||||
color: $color-silver-chalice;
|
color: $color-silver-chalice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reminders
|
||||||
|
|
||||||
|
.row-reminders-notification {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 16px;
|
||||||
|
width: 300px;
|
||||||
|
|
||||||
|
|
||||||
|
.row-reminders-title {
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-reminders-body {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas {
|
||||||
|
margin-top: 5px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
background-color: $color-alto;
|
||||||
|
border-width: 0;
|
||||||
|
height: 1px;
|
||||||
|
margin: 0 16px 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DateTime
|
// DateTime
|
||||||
.datetime-container {
|
.datetime-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class RepositoryRowsController < ApplicationController
|
||||||
|
|
||||||
before_action :load_repository, except: %i(show print_modal print)
|
before_action :load_repository, except: %i(show print_modal print)
|
||||||
before_action :load_repository_or_snapshot, only: %i(print_modal print)
|
before_action :load_repository_or_snapshot, only: %i(print_modal print)
|
||||||
before_action :load_repository_row, only: %i(update assigned_task_list)
|
before_action :load_repository_row, only: %i(update assigned_task_list active_reminder_repository_cells)
|
||||||
before_action :check_read_permissions, except: %i(show create update delete_records copy_records reminder_repository_cells)
|
before_action :check_read_permissions, except: %i(show create update delete_records copy_records reminder_repository_cells)
|
||||||
before_action :check_snapshotting_status, only: %i(create update delete_records copy_records)
|
before_action :check_snapshotting_status, only: %i(create update delete_records copy_records)
|
||||||
before_action :check_create_permissions, only: :create
|
before_action :check_create_permissions, only: :create
|
||||||
|
@ -229,7 +229,7 @@ class RepositoryRowsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def reminder_repository_cells
|
def reminder_repository_cells
|
||||||
render json: @repository_row.repository_cells.with_active_reminder
|
render json: @repository_row.repository_cells.with_active_reminder(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def archive_records
|
def archive_records
|
||||||
|
@ -258,6 +258,15 @@ class RepositoryRowsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_reminder_repository_cells
|
||||||
|
reminder_cells = @repository_row.repository_cells.with_active_reminder(current_user).distinct
|
||||||
|
render json: {
|
||||||
|
html: render_to_string(partial: 'shared/repository_row_reminder.html.erb', locals: {
|
||||||
|
reminders: reminder_cells
|
||||||
|
})
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
include StringUtility
|
include StringUtility
|
||||||
|
|
|
@ -22,7 +22,7 @@ module ReminderRepositoryCellJoinable
|
||||||
'"hidden_repository_cell_reminders"."user_id" = ' + user.id.to_s
|
'"hidden_repository_cell_reminders"."user_id" = ' + user.id.to_s
|
||||||
).where(
|
).where(
|
||||||
'hidden_repository_cell_reminders.id IS NULL AND '\
|
'hidden_repository_cell_reminders.id IS NULL AND '\
|
||||||
'repository_date_time_values.id IS NOT NULL OR repository_stock_values.id IS NOT NULL'
|
'(repository_date_time_values.id IS NOT NULL OR repository_stock_values.id IS NOT NULL)'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
25
app/views/shared/_repository_row_reminder.html.erb
Normal file
25
app/views/shared/_repository_row_reminder.html.erb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<% reminders.each_with_index do |reminder, index| %>
|
||||||
|
<li class="row-reminders-notification">
|
||||||
|
<% if reminder.value_type == 'RepositoryStockValue' %>
|
||||||
|
<div class="row-reminders-title"><strong><%= t('repository_row.reminder.low_stock_title') %></strong></div>
|
||||||
|
<div class="row-reminders-body">
|
||||||
|
<% if reminder.value.amount <= 0 %>
|
||||||
|
<%= t('repository_row.reminder.stock_empty') %>
|
||||||
|
<% else %>
|
||||||
|
<%= t('repository_row.reminder.stock_low', stock_formated: reminder.value.formatted ).html_safe %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<div class="row-reminders-footer" data-row-hide-reminders-url="
|
||||||
|
<%= repository_repository_row_repository_cell_hide_reminder_url(reminder.repository_row.repository,
|
||||||
|
reminder.repository_row,
|
||||||
|
reminder) %> ">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
<%= t('repository_row.reminder.clear') %>
|
||||||
|
</div>
|
||||||
|
<%if index + 1 < reminders.length %>
|
||||||
|
<hr>
|
||||||
|
<%end%>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -1845,6 +1845,11 @@ en:
|
||||||
title: "There seems to be no printer available"
|
title: "There seems to be no printer available"
|
||||||
description: "To learn more about printing labels and label printers please visit our blog."
|
description: "To learn more about printing labels and label printers please visit our blog."
|
||||||
visit_blog: "Visit blog"
|
visit_blog: "Visit blog"
|
||||||
|
reminder:
|
||||||
|
clear: "Clear"
|
||||||
|
low_stock_title: "Item running low"
|
||||||
|
stock_low: "Only <strong>%{stock_formated}</strong> left."
|
||||||
|
stock_empty: "There is no stock left."
|
||||||
label_printers:
|
label_printers:
|
||||||
modal_printing_status:
|
modal_printing_status:
|
||||||
printer_status:
|
printer_status:
|
||||||
|
|
Loading…
Add table
Reference in a new issue