mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-16 05:42:13 +08:00
Merge remote-tracking branch 'upstream/develop' into SCI-9008-share-task-modal
This commit is contained in:
commit
0553b5b0dc
129 changed files with 587 additions and 1358 deletions
2
Gemfile
2
Gemfile
|
|
@ -66,7 +66,7 @@ gem 'scenic', '~> 1.4'
|
|||
gem 'sdoc', '~> 1.0', group: :doc
|
||||
gem 'silencer' # Silence certain Rails logs
|
||||
gem 'sneaky-save', git: 'https://github.com/einzige/sneaky-save'
|
||||
gem 'turbolinks', '~> 5.1.1'
|
||||
gem 'turbolinks', '~> 5.2.0'
|
||||
gem 'underscore-rails'
|
||||
gem 'wicked_pdf'
|
||||
|
||||
|
|
|
|||
10
Gemfile.lock
10
Gemfile.lock
|
|
@ -478,7 +478,7 @@ GEM
|
|||
pry (>= 0.10.4)
|
||||
psych (3.3.4)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.3.0)
|
||||
puma (6.3.1)
|
||||
nio4r (~> 2.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.7.1)
|
||||
|
|
@ -644,8 +644,8 @@ GEM
|
|||
tilt (2.2.0)
|
||||
timecop (0.9.6)
|
||||
timeout (0.4.0)
|
||||
turbolinks (5.1.1)
|
||||
turbolinks-source (~> 5.1)
|
||||
turbolinks (5.2.1)
|
||||
turbolinks-source (~> 5.2)
|
||||
turbolinks-source (5.2.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
|
|
@ -752,7 +752,7 @@ DEPENDENCIES
|
|||
puma
|
||||
rack-attack
|
||||
rack-cors
|
||||
rails (~> 7.0.5.1)
|
||||
rails (~> 7.0.5)
|
||||
rails-controller-testing
|
||||
rails_12factor
|
||||
rails_autolink (~> 1.1, >= 1.1.6)
|
||||
|
|
@ -778,7 +778,7 @@ DEPENDENCIES
|
|||
sprockets-rails
|
||||
tailwindcss-rails (~> 2.0)
|
||||
timecop
|
||||
turbolinks (~> 5.1.1)
|
||||
turbolinks (~> 5.2.0)
|
||||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
underscore-rails
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// turbolinks MUST BE THE LAST inclusion
|
||||
|
||||
//= require moment
|
||||
//= require bootstrap-datetimepicker
|
||||
//= require bootstrap-colorselector
|
||||
//= require bootstrap-tagsinput.min
|
||||
|
|
|
|||
3
app/assets/javascripts/jquery_bundle.js
vendored
3
app/assets/javascripts/jquery_bundle.js
vendored
|
|
@ -1,2 +1 @@
|
|||
|
||||
//= require jquery.min
|
||||
//= require jquery
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
/*
|
||||
global Results ActiveStorage animateSpinner Comments ResultAssets FilePreviewModal
|
||||
TinyMCE getParam applyCreateWopiFileCallback initFormSubmitLinks textValidator
|
||||
GLOBAL_CONSTANTS
|
||||
GLOBAL_CONSTANTS ActiveStoragePreviews
|
||||
*/
|
||||
|
||||
(function(global) {
|
||||
|
|
@ -92,8 +93,9 @@
|
|||
// Handle the error
|
||||
} else {
|
||||
let formData = new FormData();
|
||||
const assetId = form.find('#result_asset_attributes_id').val();
|
||||
formData.append('result[name]', form.find('#result_name').val());
|
||||
formData.append('result[asset_attributes][id]', form.find('#result_asset_attributes_id').val());
|
||||
formData.append('result[asset_attributes][id]', assetId);
|
||||
formData.append('result[asset_attributes][signed_blob_id]', blob.signed_id);
|
||||
|
||||
$.ajax({
|
||||
|
|
@ -102,7 +104,7 @@
|
|||
data: formData,
|
||||
success: function(data) {
|
||||
animateSpinner(null, false);
|
||||
$('.edit_result').parent().remove();
|
||||
$('.edit-result-asset').parent().remove();
|
||||
$(data.html).prependTo('#results').promise().done(() => {
|
||||
$.each($('#results').find('.result'), function() {
|
||||
initFormSubmitLinks($(this));
|
||||
|
|
@ -113,13 +115,14 @@
|
|||
ResultAssets.initNewResultAsset();
|
||||
expandResult($(this));
|
||||
});
|
||||
ActiveStoragePreviews.reloadPreview(`.asset[data-asset-id=${assetId}] .attachment-preview img`);
|
||||
});
|
||||
|
||||
$('#results-toolbar').show();
|
||||
},
|
||||
error: function(XHR) {
|
||||
animateSpinner(null, false);
|
||||
$('.edit_result').renderFormErrors('result', XHR.responseJSON.errors);
|
||||
$('.edit-result-asset').renderFormErrors('result', XHR.responseJSON.errors);
|
||||
},
|
||||
processData: false,
|
||||
contentType: false
|
||||
|
|
|
|||
|
|
@ -147,7 +147,6 @@
|
|||
noRecentText.show();
|
||||
}
|
||||
bindSystemNotificationAjax();
|
||||
SystemNotificationsMarkAsSeen();
|
||||
}
|
||||
});
|
||||
$('#count-system-notifications').hide();
|
||||
|
|
|
|||
|
|
@ -416,12 +416,12 @@ var ProjectsIndex = (function() {
|
|||
viewContainer.removeClass('no-results no-data');
|
||||
viewContainer.find('.card, .projects-group, .no-results-container, .no-data-container').remove();
|
||||
|
||||
if (viewContainer.find('.list').length) {
|
||||
viewContainer.append(data.cards_html);
|
||||
|
||||
if (viewContainer.hasClass('list')) {
|
||||
viewContainer.find('.table-header').show();
|
||||
}
|
||||
|
||||
viewContainer.append(data.cards_html);
|
||||
|
||||
if (viewContainer.find('.no-results-container').length) {
|
||||
viewContainer.addClass('no-results');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ $.fn.dataTable.render.RepositoryAssetValue = function(data) {
|
|||
if (asset.id) {
|
||||
return `
|
||||
<div class="asset-value-cell">
|
||||
${asset.icon_html}
|
||||
<i class="sn-icon sn-icon-${asset.icon_html}"></i>
|
||||
<div>
|
||||
<a class="file-preview-link"
|
||||
id="modal_link${asset.id}"
|
||||
|
|
|
|||
|
|
@ -717,7 +717,9 @@ var RepositoryDatatable = (function(global) {
|
|||
}
|
||||
customColumns.each((i, column) => {
|
||||
var columnData = $(column).data('type') === 'RepositoryStockValue' ? 'stock' : String(columns.length);
|
||||
const className = $(column).data('type') === 'RepositoryChecklistValue' ? 'checklist-column' : '';
|
||||
columns.push({
|
||||
className: className,
|
||||
visible: true,
|
||||
searchable: true,
|
||||
data: columnData,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,20 @@
|
|||
'use strict';
|
||||
|
||||
global.ResultAssets = (function() {
|
||||
// New asset callback
|
||||
function createResultAssetCallback() {
|
||||
$('.new-result-assets-buttons')
|
||||
.on('click', '.save-result', (event) => {
|
||||
DragNDropResults.processResult(event); // eslint-disable-line no-undef
|
||||
})
|
||||
.on('click', '.cancel-new', () => {
|
||||
DragNDropResults.destroyAll(); // eslint-disable-line no-undef
|
||||
});
|
||||
|
||||
$('#new-result-assets-select').on('change', '#drag-n-drop-assets', function() {
|
||||
DragNDropResults.init(this.files); // eslint-disable-line no-undef
|
||||
});
|
||||
}
|
||||
// New result asset behaviour
|
||||
function initNewResultAsset() {
|
||||
$('#new-result-asset').on('click', function(event) {
|
||||
|
|
@ -24,6 +38,7 @@
|
|||
Results.initCancelFormButton($form, initNewResultAsset);
|
||||
Results.toggleResultEditButtons(false);
|
||||
dragNdropAssetsInit();
|
||||
createResultAssetCallback();
|
||||
},
|
||||
error: function(xhr, status, e) {
|
||||
$(this).renderFormErrors('result', xhr.responseJSON, true, e);
|
||||
|
|
@ -34,6 +49,13 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Save asset callback
|
||||
function saveResultAssetCallback() {
|
||||
$('.edit-result-assets-buttons').on('click', '.save-result', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.FILE); // eslint-disable-line no-undef
|
||||
});
|
||||
}
|
||||
|
||||
function applyEditResultAssetCallback() {
|
||||
$('.edit-result-asset').off('ajax:success ajax:error').on('ajax:success', function(e, data) {
|
||||
var $result = $(this).closest('.result');
|
||||
|
|
@ -55,6 +77,7 @@
|
|||
Results.toggleResultEditButtons(false);
|
||||
|
||||
$('#result_name').focus();
|
||||
saveResultAssetCallback();
|
||||
}).on('ajax:error', function(e, xhr, status, error) {
|
||||
animateSpinner(null, false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
/* global Results */
|
||||
|
||||
(function() {
|
||||
$('.edit-result-assets-buttons').on('click', '.save-result', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.FILE);
|
||||
});
|
||||
}());
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/* global DragNDropResults */
|
||||
|
||||
(function() {
|
||||
$('.new-result-assets-buttons')
|
||||
.on('click', '.save-result', (event) => {
|
||||
DragNDropResults.processResult(event);
|
||||
})
|
||||
.on('click', '.cancel-new', () => {
|
||||
DragNDropResults.destroyAll();
|
||||
});
|
||||
|
||||
$('#new-result-assets-select').on('change', '#drag-n-drop-assets', function() {
|
||||
DragNDropResults.init(this.files);
|
||||
});
|
||||
}());
|
||||
|
|
@ -64,6 +64,20 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Save result table callback
|
||||
function newResultTableCallback() {
|
||||
$('.new-result-tables-buttons .save-result').on('click', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.TABLE);
|
||||
});
|
||||
}
|
||||
|
||||
// Save result table callback
|
||||
function saveResultTableCallback() {
|
||||
$('.edit-result-tables-buttons .save-result').on('click', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.TABLE);
|
||||
});
|
||||
}
|
||||
|
||||
// Apply ajax callback to form
|
||||
function _formAjaxResultTable($form, $prevResult) {
|
||||
$form.on('ajax:success', function(e, data) {
|
||||
|
|
@ -111,6 +125,7 @@
|
|||
Results.toggleResultEditButtons(false);
|
||||
|
||||
$('#result_name').focus();
|
||||
saveResultTableCallback();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +152,7 @@
|
|||
Results.initCancelFormButton($form, initNewResultTable);
|
||||
Results.toggleResultEditButtons(false);
|
||||
$('#result_name').focus();
|
||||
newResultTableCallback();
|
||||
},
|
||||
error: function() {
|
||||
animateSpinner(null, false);
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
/* global Results */
|
||||
|
||||
(function() {
|
||||
$('.edit-result-tables-buttons').on('click', '.save-result', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.TABLE);
|
||||
});
|
||||
}());
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
/* global Results */
|
||||
|
||||
(function() {
|
||||
$('.new-result-tables-buttons').on('click', '.save-result', (event) => {
|
||||
Results.processResult(event, Results.ResultTypeEnum.TABLE);
|
||||
});
|
||||
}());
|
||||
|
|
@ -27,6 +27,12 @@ var ActiveStoragePreviews = (function() {
|
|||
showPreview: function(ev) {
|
||||
$(ev.target).css('opacity', 1);
|
||||
$(ev.target).parent().removeClass('processing');
|
||||
},
|
||||
reloadPreview: function(target) {
|
||||
$(target)
|
||||
.one('error', (event) => this.reCheckPreview(event))
|
||||
.one('load', (event) => this.showPreview(event))
|
||||
.trigger('error');
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
|
@ -37,9 +43,9 @@ $(document).on('turbolinks:load', function() {
|
|||
.one('error', (event) => ActiveStoragePreviews.reCheckPreview(event))
|
||||
.each(function() {
|
||||
if (this.complete) {
|
||||
$(this).load();
|
||||
$(this).trigger('load');
|
||||
} else if (this.error) {
|
||||
$(this).error();
|
||||
$(this).trigger('error');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ var DataTableHelpers = (function() {
|
|||
.removeClass('form-control input-sm')
|
||||
.css('margin', 0);
|
||||
$('.dataTables_filter').append(`
|
||||
<button class="btn btn-light btn-lg icon-btn search-icon btn-black"
|
||||
<button class="btn btn-light icon-btn search-icon btn-black"
|
||||
title="${I18n.t('repositories.show.button_tooltip.search')}">
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* global animateSpinner fabric PerfectScrollbar refreshProtocolStatusBar tui Uint8Array*/
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/* global animateSpinner fabric PerfectScrollbar refreshProtocolStatusBar tui Uint8Array ActiveStoragePreviews*/
|
||||
/* eslint-disable no-underscore-dangle no-unused-vars */
|
||||
|
||||
|
||||
var ImageEditorModal = (function() {
|
||||
|
||||
|
|
@ -364,9 +365,12 @@ var ImageEditorModal = (function() {
|
|||
contentType: false,
|
||||
processData: false,
|
||||
success: function(res) {
|
||||
$(`.asset[data-asset-id=${data.id}] .image-container img`).replaceWith($(res.html).find('.image-container img'));
|
||||
$(`.asset[data-asset-id=${data.id}] .attachment-preview img`).replaceWith($(res.html).find('attachment-preview img'));
|
||||
$(`.asset[data-asset-id=${data.id}] .image-container img`)
|
||||
.replaceWith($(res.html).find('.image-container img'));
|
||||
$(`.asset[data-asset-id=${data.id}] .attachment-preview img`)
|
||||
.replaceWith($(res.html).find('.attachment-preview img'));
|
||||
$(`.asset[data-asset-id=${data.id}]`).closest('.attachments').trigger('reorder');
|
||||
ActiveStoragePreviews.reloadPreview(`.asset[data-asset-id=${data.id}] .attachment-preview img`);
|
||||
closeEditor();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ function initShowPassword() {
|
|||
style="
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
top: ${$(e).position().top}px
|
||||
"></i>`).insertAfter(e);
|
||||
$(e).parent().addClass('right-icon');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// update selected notiifcations
|
||||
function SystemNotificationsMarkAsSeen() {
|
||||
if ($('.system-notification[data-new="1"]').length > 0) {
|
||||
$.post('/system_notifications/mark_as_seen');
|
||||
}
|
||||
}
|
||||
|
||||
function bindSystemNotificationAjax() {
|
||||
var SystemNotificationModal = null;
|
||||
var SystemNotificationModalBody = null;
|
||||
var SystemNotificationModalTitle = null;
|
||||
|
||||
SystemNotificationModal = $('#manage-module-system-notification-modal');
|
||||
SystemNotificationModalBody = SystemNotificationModal.find('.modal-body');
|
||||
SystemNotificationModalTitle = SystemNotificationModal.find('#manage-module-system-notification-modal-label');
|
||||
|
||||
$('.modal-system-notification')
|
||||
.on('ajax:success', function(ev, data) {
|
||||
var SystemNotification = $('.system-notification[data-system-notification-id=' + data.id + ']');
|
||||
SystemNotificationModalBody.html(data.modal_body);
|
||||
SystemNotificationModalTitle.text(data.modal_title);
|
||||
$('.dropdown.system-notifications').removeClass('open');
|
||||
// Open modal
|
||||
SystemNotificationModal.modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function initSystemNotificationsButton() {
|
||||
$('.btn-more-system-notifications')
|
||||
.on('ajax:success', function(e, data) {
|
||||
$(data.html).insertAfter($('.system-notifications-container .system-notification').last());
|
||||
bindSystemNotificationAjax();
|
||||
if (data.more_url) {
|
||||
$(this).attr('href', data.more_url);
|
||||
} else {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initSystemNotificationsButton();
|
||||
SystemNotificationsMarkAsSeen();
|
||||
bindSystemNotificationAjax();
|
||||
|
|
@ -1 +0,0 @@
|
|||
$('#manage-module-system-notification-modal').modal('show');
|
||||
|
|
@ -17,11 +17,8 @@
|
|||
.search-container {
|
||||
flex-basis: 36px;
|
||||
|
||||
.fa-search {
|
||||
animation-timing-function: $timing-function-sharp;
|
||||
color: $color-alto;
|
||||
transition: .3s;
|
||||
width: 26px;
|
||||
.sn-icon {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.task-search-field {
|
||||
|
|
@ -36,10 +33,6 @@
|
|||
border: $border-transparent;
|
||||
cursor: pointer;
|
||||
width: 36px;
|
||||
|
||||
+ .fa-search {
|
||||
color: $color-volcano;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
@ -50,10 +43,6 @@
|
|||
border: $border-focus;
|
||||
cursor: auto;
|
||||
width: 200px;
|
||||
|
||||
+ .fa-search {
|
||||
color: $color-alto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -617,12 +617,17 @@
|
|||
}
|
||||
|
||||
.status-label {
|
||||
@include font-small;
|
||||
@include font-button;
|
||||
flex-basis: 50%;
|
||||
font-weight: 700;
|
||||
margin-right: .5em;
|
||||
text-align: right;
|
||||
|
||||
.status-title {
|
||||
@include font-small;
|
||||
color: var(--sn-grey);
|
||||
margin-right: .2em;
|
||||
}
|
||||
|
||||
.status-note {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,15 @@
|
|||
.dropdown-toggle {
|
||||
border: 0;
|
||||
color: $color-white;
|
||||
padding: .5rem .5rem .5rem 1rem;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
&.btn-not-started {
|
||||
border: 1px solid var(--sn-sleepy-grey);
|
||||
color: var(--sn-black);
|
||||
}
|
||||
|
||||
.caret {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
|
@ -67,6 +73,11 @@
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-not-started {
|
||||
border: 1px solid var(--sn-sleepy-grey);
|
||||
color: var(--sn-black);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
@include font-small;
|
||||
color: $color-silver-chalice;
|
||||
|
|
@ -126,6 +137,11 @@
|
|||
line-height: 1em;
|
||||
padding: .5em;
|
||||
white-space: nowrap;
|
||||
|
||||
&.btn-not-started {
|
||||
border: 1px solid var(--sn-sleepy-grey);
|
||||
color: var(--sn-black);
|
||||
}
|
||||
}
|
||||
|
||||
.status-comment {
|
||||
|
|
|
|||
|
|
@ -58,24 +58,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sci--navigation--notificaitons-flyout-tabs {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-basis: 2.5rem;
|
||||
flex-shrink: 0;
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.sci--navigation--notificaitons-flyout-tab {
|
||||
cursor: pointer;
|
||||
padding: .5rem .625rem;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
color: $brand-focus;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: .625rem 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -967,6 +967,7 @@ li.module-hover {
|
|||
grid-column: 1 span;
|
||||
-webkit-box-orient: vertical;
|
||||
display: -webkit-box;
|
||||
display: flex;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@
|
|||
padding: .1em 0;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid $color-silver;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@
|
|||
}
|
||||
}
|
||||
td:nth-child(4) {
|
||||
min-width: min-content;
|
||||
min-width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,24 +42,20 @@ div.print-report {
|
|||
.report-project-header-element {
|
||||
& > .report-element-body .project-name {
|
||||
color: $color-black;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&:hover > .report-element-body .project-name {
|
||||
color: $color-black;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.report-module-element:hover {
|
||||
& > .report-element-body .module-name {
|
||||
color: $color-black;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&:hover > .report-element-body .module-name {
|
||||
color: $color-black;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,17 +81,20 @@
|
|||
}
|
||||
|
||||
// Cells
|
||||
td {
|
||||
white-space: nowrap;
|
||||
td.added-on,
|
||||
td.asset-value-cell {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Assigned
|
||||
|
||||
.assigned-column {
|
||||
overflow: unset;
|
||||
padding: 1px 8px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
|
||||
.sn-icon.sn-icon-edit {
|
||||
line-height: 35px;
|
||||
|
|
@ -170,6 +173,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.checklist-column {
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
padding: 2px 8px;
|
||||
|
||||
|
|
@ -414,6 +421,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.team-share-permission:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.team-description {
|
||||
display: inline-block;
|
||||
margin-top: 16px;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@
|
|||
font-size: 13px;
|
||||
}
|
||||
|
||||
.datepicker thead th {
|
||||
padding: 5px 5px !important;
|
||||
}
|
||||
|
||||
.timepicker-picker {
|
||||
padding: 0 60px;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
}
|
||||
|
||||
.sn-icon {
|
||||
bottom: 6px;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 25px;
|
||||
|
|
@ -79,10 +80,11 @@
|
|||
&.error {
|
||||
&::after {
|
||||
@include font-awesome;
|
||||
top: 0;
|
||||
bottom: 6px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
text-align: center;
|
||||
top: 6px;
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ input[type="checkbox"].sci-toggle-checkbox {
|
|||
}
|
||||
}
|
||||
|
||||
&:focus + .sci-toggle-checkbox-label {
|
||||
box-shadow: 0 0 0 4px var(--sn-science-blue-hover);
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&.hidden + .sci-toggle-checkbox-label {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,10 +85,6 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#wopi_file_edit_button {
|
||||
margin-left: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
.add-file-modal {
|
||||
|
|
|
|||
|
|
@ -83,9 +83,9 @@
|
|||
}
|
||||
|
||||
.btn.btn-shared {
|
||||
background-color: var(--sn-white);
|
||||
border: 1px solid var(--sn-coral);
|
||||
color: var(--sn-coral);
|
||||
background-color: var(--sn-science-blue);
|
||||
border: 1px solid var(--sn-white);
|
||||
color: var(--sn-white);
|
||||
}
|
||||
|
||||
.btn.btn-secondary:hover,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
@layer components {
|
||||
.sci-input-container-v2 {
|
||||
@apply relative h-[2.75rem] flex items-center;
|
||||
@apply relative h-[2.5rem] flex items-center;
|
||||
}
|
||||
|
||||
.sci-input-container-v2.input-sm {
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
}
|
||||
|
||||
.sci-input-container-v2 input:focus {
|
||||
border-color: var(--sn-sleepy-grey);
|
||||
border-color: var(--sn-science-blue);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class LabelTemplatesController < ApplicationController
|
|||
end
|
||||
|
||||
def load_label_templates
|
||||
@label_templates = LabelTemplate.where(team_id: current_team.id)
|
||||
@label_templates = LabelTemplate.enabled? ? current_team.label_templates : current_team.label_templates.default
|
||||
end
|
||||
|
||||
def load_label_template
|
||||
|
|
|
|||
|
|
@ -323,12 +323,13 @@ class ReportsController < ApplicationController
|
|||
|
||||
def load_wizard_vars
|
||||
@templates = Extends::REPORT_TEMPLATES
|
||||
live_repositories = Repository.accessible_by_teams(current_team).active
|
||||
live_repositories = Repository.accessible_by_teams(current_team).sort_by { |r| r.name.downcase }
|
||||
snapshots_of_deleted = RepositorySnapshot.left_outer_joins(:original_repository)
|
||||
.where(team: current_team)
|
||||
.where.not(original_repository: live_repositories)
|
||||
.select('DISTINCT ON ("repositories"."parent_id") "repositories".*')
|
||||
@repositories = (live_repositories + snapshots_of_deleted).sort_by { |r| r.name.downcase }
|
||||
.sort_by { |r| r.name.downcase }
|
||||
@repositories = live_repositories + snapshots_of_deleted
|
||||
@visible_projects = current_team.projects
|
||||
.active
|
||||
.joins(experiments: :my_modules)
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SystemNotificationsController < ApplicationController
|
||||
def show
|
||||
current_user.user_system_notifications.mark_as_read(params[:id])
|
||||
render json: current_user.system_notifications.modals
|
||||
.find_by_id(params[:id]) || {}
|
||||
end
|
||||
|
||||
# Update seen_at parameter for system notifications
|
||||
def mark_as_seen
|
||||
current_user.user_system_notifications.mark_as_seen
|
||||
render json: { result: 'ok' }
|
||||
rescue StandardError
|
||||
render json: { result: 'failed' }
|
||||
end
|
||||
|
||||
# Update read_at parameter for system notifications
|
||||
def mark_as_read
|
||||
current_user.user_system_notifications.mark_as_read(params[:id])
|
||||
render json: { result: 'ok' }
|
||||
rescue StandardError
|
||||
render json: { result: 'failed' }
|
||||
end
|
||||
|
||||
def unseen_counter
|
||||
render json: {
|
||||
notificationNmber: current_user.user_system_notifications.unseen.count
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_notifications
|
||||
page = (params[:page] || 1).to_i
|
||||
query = params[:search_queue]
|
||||
per_page = Constants::ACTIVITY_AND_NOTIF_SEARCH_LIMIT
|
||||
notifications = SystemNotification.last_notifications(current_user, query)
|
||||
.page(page)
|
||||
.per(per_page)
|
||||
|
||||
unless notifications.blank? || notifications.last_page?
|
||||
more_url = url_for(
|
||||
system_notifications_url(
|
||||
format: :json,
|
||||
page: page + 1,
|
||||
search_queue: query
|
||||
)
|
||||
)
|
||||
end
|
||||
@system_notifications = {
|
||||
notifications: notifications,
|
||||
more_notifications_url: more_url
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -13,44 +13,20 @@ class UserNotificationsController < ApplicationController
|
|||
UserNotification.where(
|
||||
notification_id: notifications.except(:select).where.not(type_of: 2).select(:id)
|
||||
).seen_by_user(current_user)
|
||||
|
||||
current_user.user_system_notifications.where(
|
||||
system_notification_id: notifications.except(:select).where(type_of: 2).select(:id)
|
||||
).mark_as_seen
|
||||
end
|
||||
|
||||
def unseen_counter
|
||||
render json: {
|
||||
unseen: load_notifications.where(checked: false).size
|
||||
unseen: load_notifications.where('user_notifications.checked = ?', false).size
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_notifications
|
||||
user_notifications = current_user.notifications
|
||||
.select(:id, :type_of, :title, :message, :created_at, 'user_notifications.checked')
|
||||
system_notifications = current_user.system_notifications
|
||||
.select(
|
||||
:id,
|
||||
'2 AS type_of',
|
||||
:title,
|
||||
'description AS message',
|
||||
:created_at,
|
||||
'CASE WHEN seen_at IS NULL THEN false ELSE true END AS checked'
|
||||
)
|
||||
notifications =
|
||||
case params[:type]
|
||||
when 'message'
|
||||
user_notifications
|
||||
when 'system'
|
||||
Notification.from("(#{system_notifications.to_sql}) AS notifications")
|
||||
else
|
||||
Notification.from(
|
||||
"((#{user_notifications.to_sql}) UNION ALL (#{system_notifications.to_sql})) AS notifications"
|
||||
)
|
||||
end
|
||||
notifications.order(created_at: :desc)
|
||||
current_user.notifications
|
||||
.select(:id, :type_of, :title, :message, :created_at, 'user_notifications.checked')
|
||||
.order(created_at: :desc)
|
||||
end
|
||||
|
||||
def notification_serializer(notifications)
|
||||
|
|
@ -62,8 +38,7 @@ class UserNotificationsController < ApplicationController
|
|||
message: notification.message,
|
||||
created_at: I18n.l(notification.created_at, format: :full),
|
||||
today: notification.created_at.today?,
|
||||
checked: notification.checked,
|
||||
action_url: (system_notification_path(notification.id) if notification.type_of == 'system_message')
|
||||
checked: notification.checked
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
class Users::SessionsController < Devise::SessionsController
|
||||
layout :session_layout
|
||||
after_action :after_sign_in, only: %i(create authenticate_with_two_factor)
|
||||
before_action :remove_authenticate_mesasge_if_root_path, only: :new
|
||||
prepend_before_action :skip_timeout, only: :expire_in
|
||||
|
||||
|
|
@ -58,10 +57,6 @@ class Users::SessionsController < Devise::SessionsController
|
|||
@initial_page = stored_location_for(:user)
|
||||
end
|
||||
|
||||
def after_sign_in
|
||||
flash[:system_notification_modal] = true
|
||||
end
|
||||
|
||||
def authenticate_with_two_factor
|
||||
user = User.find_by(id: session[:otp_user_id])
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class TeamUsersDatatable < CustomDatatable
|
|||
'2': record.user_role.name,
|
||||
'3': I18n.l(record.created_at, format: :full_date),
|
||||
'4': record.user.active_status_str,
|
||||
'5': ApplicationController.new.render_to_string(
|
||||
'5': @view.controller.render_to_string(
|
||||
partial: 'users/settings/teams/user_dropdown',
|
||||
locals: {
|
||||
user_assignment: record,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ require('jquery-ui/ui/widgets/droppable');
|
|||
require('jquery-ui/ui/effects/effect-slide');
|
||||
require('hammerjs');
|
||||
import 'bootstrap';
|
||||
window.moment = require('moment');
|
||||
import './bootstrap.less';
|
||||
require('bootstrap-select/js/bootstrap-select');
|
||||
|
||||
window.bwipjs = require('bwip-js');
|
||||
|
|
@ -37,3 +37,13 @@ $(document).on('click', '.btn', function() {
|
|||
$(this).blur();
|
||||
});
|
||||
|
||||
// Needed to support Turbolinks redirect_to responses as unsafe-inline is blocked by the CSP
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
'text script': function(text) {
|
||||
$.globalEval(text, { nonce: document.querySelector('meta[name="csp-nonce"]').getAttribute('content') });
|
||||
return text;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
140
app/javascript/packs/bootstrap.less
vendored
Normal file
140
app/javascript/packs/bootstrap.less
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
|
||||
@import '~bootstrap/less/variables.less';
|
||||
|
||||
@color-white: #fff;
|
||||
@color-concrete: #eaecf0;
|
||||
@color-alto: #d0d5dd;
|
||||
@color-silver-chalice: #98a2b3;
|
||||
@color-volcano: #475467;
|
||||
@color-black: #1d2939;
|
||||
|
||||
@brand-primary: #104da9;
|
||||
@brand-primary-hover: #2d5faa;
|
||||
@brand-primary-press: #07244f;
|
||||
@brand-primary-light: #7094cb;
|
||||
|
||||
@brand-focus: #3b99fd;
|
||||
@brand-focus-light: #f0f8ff;
|
||||
|
||||
@brand-success: #5ec66f;
|
||||
@brand-success-light: #cbefd7;
|
||||
|
||||
@brand-danger: #ce0c24;
|
||||
@brand-danger-hover: #ad0015;
|
||||
@brand-danger-press: #801515;
|
||||
@brand-danger-light: #f9c9c9;
|
||||
|
||||
@brand-warning: #f0ad4e;
|
||||
@brand-complementary: #ffcf26;
|
||||
@brand-warning-light: #fbebd3;
|
||||
|
||||
@gray-darker: @color-black;
|
||||
@gray-dark: @color-black;
|
||||
@gray: @color-black;
|
||||
@gray-light: @color-volcano;
|
||||
@gray-lighter: @color-concrete;
|
||||
|
||||
@state-success-text: @brand-success;
|
||||
@state-success-bg: @brand-success-light;
|
||||
@state-info-text: @brand-focus;
|
||||
@state-info-bg: @brand-focus-light;
|
||||
@state-warning-text: @brand-warning;
|
||||
@state-warning-bg: @brand-warning-light;
|
||||
@state-danger-text: @brand-danger;
|
||||
@state-danger-bg: @brand-danger-light;
|
||||
|
||||
@alert-padding: 15px;
|
||||
@alert-border-radius: @border-radius-base;
|
||||
@alert-link-font-weight: bold;
|
||||
@alert-success-bg: @brand-success-light;
|
||||
@alert-success-text: @brand-success;
|
||||
@alert-info-bg: @brand-focus-light;
|
||||
@alert-info-text: @brand-focus;
|
||||
@alert-warning-bg: @brand-warning-light;
|
||||
@alert-warning-text: @brand-warning;
|
||||
@alert-danger-bg: @brand-danger-light;
|
||||
@alert-danger-text: @brand-danger;
|
||||
|
||||
@padding-base-vertical: 6px;
|
||||
@padding-base-horizontal: 12px;
|
||||
@padding-large-vertical: 10px;
|
||||
@padding-large-horizontal: 16px;
|
||||
@padding-small-vertical: 5px;
|
||||
@padding-small-horizontal: 10px;
|
||||
@padding-xs-vertical: 1px;
|
||||
@padding-xs-horizontal: 5px;
|
||||
@line-height-large: 1.3333333;
|
||||
@line-height-small: 1.5;
|
||||
@border-radius-base: 4px;
|
||||
@border-radius-large: 6px;
|
||||
@border-radius-small: 3px;
|
||||
@component-active-color: @color-white;
|
||||
@component-active-bg: @brand-primary;
|
||||
@caret-width-base: 4px;
|
||||
@caret-width-large: 5px;
|
||||
|
||||
@font-size-base: 14px;
|
||||
@headings-font-weight: bold;
|
||||
|
||||
@font-size-h1: 24px;
|
||||
@font-size-h2: 18px;
|
||||
@font-size-h3: @font-size-base;
|
||||
@font-size-h4: @font-size-base;
|
||||
@font-size-h5: @font-size-base;
|
||||
@font-size-h6: 12px;
|
||||
|
||||
@container-tablet: auto;
|
||||
@container-sm: auto;
|
||||
@container-desktop: auto;
|
||||
@container-md: auto;
|
||||
@container-large-desktop: auto;
|
||||
@container-lg: auto;
|
||||
|
||||
@import "~bootstrap/less/mixins.less";
|
||||
|
||||
// Reset and dependencies
|
||||
@import "~bootstrap/less/normalize.less";
|
||||
@import "~bootstrap/less/print.less";
|
||||
@import "~bootstrap/less/glyphicons.less";
|
||||
|
||||
// Core CSS
|
||||
@import "~bootstrap/less/scaffolding.less";
|
||||
@import "~bootstrap/less/type.less";
|
||||
@import "~bootstrap/less/code.less";
|
||||
@import "~bootstrap/less/grid.less";
|
||||
@import "~bootstrap/less/tables.less";
|
||||
@import "~bootstrap/less/forms.less";
|
||||
|
||||
// Components
|
||||
@import "~bootstrap/less/component-animations.less";
|
||||
@import "~bootstrap/less/dropdowns.less";
|
||||
@import "~bootstrap/less/button-groups.less";
|
||||
@import "~bootstrap/less/input-groups.less";
|
||||
@import "~bootstrap/less/navs.less";
|
||||
@import "~bootstrap/less/navbar.less";
|
||||
@import "~bootstrap/less/breadcrumbs.less";
|
||||
@import "~bootstrap/less/pagination.less";
|
||||
@import "~bootstrap/less/pager.less";
|
||||
@import "~bootstrap/less/labels.less";
|
||||
@import "~bootstrap/less/badges.less";
|
||||
@import "~bootstrap/less/jumbotron.less";
|
||||
@import "~bootstrap/less/thumbnails.less";
|
||||
@import "~bootstrap/less/alerts.less";
|
||||
@import "~bootstrap/less/progress-bars.less";
|
||||
@import "~bootstrap/less/media.less";
|
||||
@import "~bootstrap/less/list-group.less";
|
||||
@import "~bootstrap/less/panels.less";
|
||||
@import "~bootstrap/less/responsive-embed.less";
|
||||
@import "~bootstrap/less/wells.less";
|
||||
@import "~bootstrap/less/close.less";
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "~bootstrap/less/modals.less";
|
||||
@import "~bootstrap/less/tooltip.less";
|
||||
@import "~bootstrap/less/popovers.less";
|
||||
@import "~bootstrap/less/carousel.less";
|
||||
|
||||
// Utility classes
|
||||
@import "~bootstrap/less/utilities.less";
|
||||
@import "~bootstrap/less/responsive-utilities.less";
|
||||
|
||||
1
app/javascript/packs/bootstrap.scss
vendored
1
app/javascript/packs/bootstrap.scss
vendored
|
|
@ -1 +0,0 @@
|
|||
@import "~bootstrap/dist/css/bootstrap.css";
|
||||
|
|
@ -9,8 +9,7 @@
|
|||
<div class="sci-navigation--notificaitons-flyout-notification-title"
|
||||
v-html="notification.title"
|
||||
:data-seen="notification.checked"></div>
|
||||
<div v-if="notification.type_of !== 'system_message'" v-html="notification.message" class="sci-navigation--notificaitons-flyout-notification-message"></div>
|
||||
<a v-else @click="showSystemNotification()" class="sci-navigation--notificaitons-flyout-notification-message" data-notification="system">{{ i18n.t('nav.notifications.read_more') }}</a>
|
||||
<div v-html="notification.message" class="sci-navigation--notificaitons-flyout-notification-message"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -25,26 +24,12 @@ export default {
|
|||
switch(this.notification.type_of) {
|
||||
case 'deliver':
|
||||
return 'fa-truck';
|
||||
case 'system_message':
|
||||
return 'fa-gift';
|
||||
case 'assignment':
|
||||
return 'fa-list-alt';
|
||||
case 'recent_changes':
|
||||
return 'fa-list-alt';
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showSystemNotification() {
|
||||
$.get(this.notification.action_url, (data) => {
|
||||
let systemNotificationModal = $('#manage-module-system-notification-modal');
|
||||
let systemNotificationModalBody = systemNotificationModal.find('.modal-body');
|
||||
let systemNotificationModalTitle = systemNotificationModal.find('#manage-module-system-notification-modal-label');
|
||||
systemNotificationModalBody.html(data.modal_body);
|
||||
systemNotificationModalTitle.text(data.modal_title);
|
||||
systemNotificationModal.modal('show');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -4,24 +4,6 @@
|
|||
{{ i18n.t('nav.notifications.title') }}
|
||||
<i class="sn-icon sn-icon-close" @click="$emit('close')"></i>
|
||||
</div>
|
||||
<div class="sci--navigation--notificaitons-flyout-tabs">
|
||||
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||
:data-unseen="unseenNotificationsCount"
|
||||
@click="setActiveTab('all')"
|
||||
:class="{'active': activeTab == 'all', 'has-unseen': unseenNotificationsCount > 0}">
|
||||
{{ i18n.t('nav.notifications.all') }}
|
||||
</div>
|
||||
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||
@click="setActiveTab('message')"
|
||||
:class="{'active': activeTab == 'message'}">
|
||||
{{ i18n.t('nav.notifications.message') }}
|
||||
</div>
|
||||
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||
@click="setActiveTab('system')"
|
||||
:class="{'active': activeTab == 'system'}">
|
||||
{{ i18n.t('nav.notifications.system') }}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<perfect-scrollbar ref="scrollContainer" class="sci--navigation--notificaitons-flyout-notifications">
|
||||
<div class="sci-navigation--notificaitons-flyout-subtitle" v-if="todayNotifications.length" >
|
||||
|
|
@ -55,7 +37,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
notifications: [],
|
||||
activeTab: 'all',
|
||||
nextPage: 1,
|
||||
scrollBar: null,
|
||||
loadingPage: false
|
||||
|
|
@ -66,8 +47,10 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
let container = this.$refs.scrollContainer.$el
|
||||
container.addEventListener('ps-y-reach-end', (e) => {
|
||||
this.loadNotifications();
|
||||
container.addEventListener('ps-scroll-y', (e) => {
|
||||
if (e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight - 20) {
|
||||
this.loadNotifications();
|
||||
}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -82,17 +65,11 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
setActiveTab(selection) {
|
||||
this.activeTab = selection;
|
||||
this.nextPage = 1;
|
||||
this.notifications = [];
|
||||
this.loadNotifications();
|
||||
},
|
||||
loadNotifications() {
|
||||
if (this.nextPage == null || this.loadingPage) return;
|
||||
|
||||
this.loadingPage = true;
|
||||
$.getJSON(this.notificationsUrl, { type: this.activeTab, page: this.nextPage }, (result) => {
|
||||
$.getJSON(this.notificationsUrl, { page: this.nextPage }, (result) => {
|
||||
this.notifications = this.notifications.concat(result.notifications);
|
||||
this.nextPage = result.next_page;
|
||||
this.loadingPage = false;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
class="flex items-center mr-3 flex-nowrap relative"
|
||||
v-click-outside="{handler: 'closeSearchInputs', exclude: ['searchInput', 'searchInputBtn', 'barcodeSearchInput', 'barcodeSearchInputBtn']}"
|
||||
>
|
||||
<button :class="{hidden: searchOpened}" ref='searchInputBtn' class="btn btn-light btn-lg btn-black icon-btn" :title="i18n.t('repositories.show.search_button_tooltip')" @click="openSearch">
|
||||
<button :class="{hidden: searchOpened}" ref='searchInputBtn' class="btn btn-light btn-black icon-btn" :title="i18n.t('repositories.show.search_button_tooltip')" @click="openSearch">
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
</button>
|
||||
<div v-if="searchOpened || barcodeSearchOpened" class="w-52 flex">
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
<i class='sn-icon sn-icon-barcode barcode-scanner !mr-2.5'></i>
|
||||
</div>
|
||||
</div>
|
||||
<button :class="{hidden: barcodeSearchOpened}" ref='barcodeSearchInputBtn' class="btn btn-light btn-lg btn-black icon-btn ml-2" :title="i18n.t('repositories.show.ean_search_button_tooltip')" @click="openBarcodeSearch">
|
||||
<button :class="{hidden: barcodeSearchOpened}" ref='barcodeSearchInputBtn' class="btn btn-light btn-black icon-btn ml-2" :title="i18n.t('repositories.show.ean_search_button_tooltip')" @click="openBarcodeSearch">
|
||||
<i class='sn-icon sn-icon-barcode barcode-scanner'></i>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<button type="button" class="close" data-dismiss="modal" tabindex="0" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="modal-destroy-shareable-link">
|
||||
{{ i18n.t('shareable_links.destroy_modal.title')}}
|
||||
</h4>
|
||||
|
|
@ -12,8 +12,8 @@
|
|||
<p>{{ i18n.t('shareable_links.destroy_modal.description')}}</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" @click="cancel">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-danger" @click="confirm">{{ i18n.t('shareable_links.destroy_modal.deactivate')}}</button>
|
||||
<button class="btn btn-secondary" tabindex="0" @click="cancel">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-danger" tabindex="0" @click="confirm">{{ i18n.t('shareable_links.destroy_modal.deactivate')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
type="button"
|
||||
class="close float-right !ml-auto"
|
||||
data-dismiss="modal"
|
||||
tabindex="0"
|
||||
aria-label="Close"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
v-model="sharedEnabled"
|
||||
id="checkbox"
|
||||
class="sci-toggle-checkbox"
|
||||
tabindex="0"
|
||||
@change="checkboxChange"
|
||||
@keyup.enter="handleCheckboxEnter"/>
|
||||
<span class="sci-toggle-checkbox-label"></span>
|
||||
|
|
@ -40,6 +42,7 @@
|
|||
<div>
|
||||
<div class="sci-input-container-v2 textarea-lg mb-2">
|
||||
<textarea ref="textarea"
|
||||
tabindex="0"
|
||||
class="sci-input-field"
|
||||
:class="{ 'error': error }"
|
||||
v-model="description"
|
||||
|
|
@ -54,8 +57,8 @@
|
|||
|
||||
<div class="mb-2" v-if="editing">
|
||||
<div class="sci-btn-group flex justify-end">
|
||||
<button class="btn btn-secondary btn-sm" tabindex="-1" @mousedown="cancelDescriptionEdit">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-secondary btn-sm" tabindex="-1" @mousedown="saveDescription" :disabled="error">{{ i18n.t('general.save') }}</button>
|
||||
<button class="btn btn-secondary btn-sm" tabindex="0" @mousedown="cancelDescriptionEdit">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-secondary btn-sm" tabindex="0" @mousedown="saveDescription" :disabled="error">{{ i18n.t('general.save') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -71,6 +74,7 @@
|
|||
:disabled="true"
|
||||
/>
|
||||
<button class="btn btn-primary share-link-copy"
|
||||
tabindex="0"
|
||||
@click="copy($refs.clone.value)"
|
||||
:disabled="!sharedEnabled">{{ i18n.t('shareable_links.modal.copy_button') }}
|
||||
</button>
|
||||
|
|
@ -159,8 +163,11 @@
|
|||
$(this.$refs.modal).modal('hide');
|
||||
},
|
||||
copy(value) {
|
||||
navigator.clipboard.writeText(value);
|
||||
HelperModule.flashAlertMsg(this.i18n.t('shareable_links.modal.copy_success'), 'success');
|
||||
navigator.clipboard.writeText(value).then(
|
||||
() => {
|
||||
HelperModule.flashAlertMsg(this.i18n.t('shareable_links.modal.copy_success'), 'success');
|
||||
}
|
||||
);
|
||||
},
|
||||
saveDescription() {
|
||||
this.dirty = true;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
defaul: true
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@
|
|||
}
|
||||
},
|
||||
setValue(value) {
|
||||
this.focusElement.blur();
|
||||
this.$emit('change', value);
|
||||
},
|
||||
updateOptionPosition() {
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ module Protocols
|
|||
|
||||
def create_step_table_element!(step, step_element_json)
|
||||
table = Table.create!(
|
||||
name: step_element_json['name'],
|
||||
contents: step_element_json['table']['contents'],
|
||||
name: step_element_json['name'].presence || 'New table',
|
||||
contents: step_element_json['contents'],
|
||||
created_by: @user,
|
||||
last_modified_by: @user,
|
||||
team: @team
|
||||
|
|
@ -100,13 +100,13 @@ module Protocols
|
|||
|
||||
def create_step_list_element!(step, step_element_json)
|
||||
checklist = Checklist.create!(
|
||||
name: step_element_json['list']['name'].presence || 'New list',
|
||||
name: step_element_json['name'].presence || 'New list',
|
||||
step: step,
|
||||
created_by: @user,
|
||||
last_modified_by: @user
|
||||
)
|
||||
|
||||
step_element_json['list']['contents'].each do |item|
|
||||
step_element_json['contents'].each do |item|
|
||||
checklist.checklist_items.create!(
|
||||
text: item.truncate(Constants::TEXT_MAX_LENGTH),
|
||||
checked: false,
|
||||
|
|
|
|||
|
|
@ -22,16 +22,4 @@ class AppMailer < Devise::Mailer
|
|||
}.merge(opts)
|
||||
mail(headers)
|
||||
end
|
||||
|
||||
def system_notification(user, system_notification, opts = {})
|
||||
@user = user
|
||||
@system_notification = system_notification
|
||||
|
||||
headers = {
|
||||
to: @user.email,
|
||||
subject: t('system_notifications.emails.subject')
|
||||
}.merge(opts)
|
||||
|
||||
mail(headers)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class LabelTemplate < ApplicationRecord
|
|||
|
||||
validate :ensure_single_default_template!
|
||||
|
||||
scope :default, -> { where(default: true) }
|
||||
|
||||
def self.enabled?
|
||||
ApplicationSettings.instance.values['label_templates_enabled'] == true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SystemNotification < ApplicationRecord
|
||||
include PgSearch::Model
|
||||
|
||||
scope :modals, -> { select(:modal_title, :modal_body, :id) }
|
||||
# Full text postgreSQL search configuration
|
||||
pg_search_scope :search_notifications, against: %i(title description),
|
||||
using: {
|
||||
tsearch: {
|
||||
dictionary: 'english'
|
||||
}
|
||||
}
|
||||
# ignoring: :accents
|
||||
|
||||
has_many :user_system_notifications, dependent: :destroy
|
||||
has_many :users, through: :user_system_notifications
|
||||
|
||||
validates :title, :modal_title, :modal_body, :description, :source_created_at, :source_id, :last_time_changed_at,
|
||||
presence: true
|
||||
validates :title, :description, :modal_title, length: { maximum: Constants::NAME_MAX_LENGTH }
|
||||
validates :modal_body, length: { maximum: Constants::RICH_TEXT_MAX_LENGTH }
|
||||
|
||||
def self.last_notifications(
|
||||
user,
|
||||
query = nil
|
||||
)
|
||||
notifications = order(created_at: :DESC)
|
||||
notifications = notifications.search_notifications(query) if query.present?
|
||||
notifications.joins(:user_system_notifications)
|
||||
.where('user_system_notifications.user_id = ?', user.id)
|
||||
.select(
|
||||
'system_notifications.id',
|
||||
:title,
|
||||
:description,
|
||||
:last_time_changed_at,
|
||||
:created_at,
|
||||
'user_system_notifications.seen_at',
|
||||
'user_system_notifications.read_at'
|
||||
)
|
||||
end
|
||||
|
||||
def self.last_sync_timestamp
|
||||
# If no notifications are present, the created_at of the
|
||||
# first user is used as the "initial sync time-point"
|
||||
SystemNotification
|
||||
.order(last_time_changed_at: :desc)
|
||||
.first&.last_time_changed_at&.to_i ||
|
||||
User.order(created_at: :asc).first&.created_at&.to_i
|
||||
end
|
||||
end
|
||||
|
|
@ -307,8 +307,6 @@ class User < ApplicationRecord
|
|||
|
||||
has_many :user_notifications, inverse_of: :user
|
||||
has_many :notifications, through: :user_notifications
|
||||
has_many :user_system_notifications, dependent: :destroy
|
||||
has_many :system_notifications, through: :user_system_notifications
|
||||
has_many :zip_exports, inverse_of: :user, dependent: :destroy
|
||||
has_many :view_states, dependent: :destroy
|
||||
|
||||
|
|
@ -514,12 +512,6 @@ class User < ApplicationRecord
|
|||
user_identities.exists?(provider: provider)
|
||||
end
|
||||
|
||||
# This method must be overwriten for addons that will be installed
|
||||
def show_login_system_notification?
|
||||
user_system_notifications.show_on_login.present? &&
|
||||
(ENV['ENABLE_TUTORIAL'] != 'true' || settings['tutorial_completed'])
|
||||
end
|
||||
|
||||
# json friendly attributes
|
||||
NOTIFICATIONS_TYPES = %w(assignments_notification recent_notification
|
||||
assignments_email_notification
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UserSystemNotification < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :system_notification
|
||||
|
||||
validates :system_notification, uniqueness: { scope: :user }
|
||||
|
||||
scope :unseen, -> { where(seen_at: nil) }
|
||||
|
||||
def self.mark_as_seen
|
||||
unseen.update_all(seen_at: Time.now)
|
||||
end
|
||||
|
||||
def self.mark_as_read(notification_id)
|
||||
notification = find_by_system_notification_id(notification_id)
|
||||
notification.update(read_at: Time.now) if notification && notification.read_at.nil?
|
||||
end
|
||||
|
||||
def self.show_on_login(update_read_time = false)
|
||||
# for notification check leave update_read_time empty
|
||||
notification = joins(:system_notification)
|
||||
.where('system_notifications.show_on_login = true')
|
||||
.order('system_notifications.created_at DESC')
|
||||
.select(
|
||||
:modal_title,
|
||||
:modal_body,
|
||||
'user_system_notifications.id',
|
||||
:read_at,
|
||||
:user_id,
|
||||
:system_notification_id,
|
||||
:created_at
|
||||
)
|
||||
.first
|
||||
if notification && notification.read_at.nil?
|
||||
if update_read_time
|
||||
notification.update(
|
||||
read_at: Time.now,
|
||||
seen_at: Time.now
|
||||
)
|
||||
end
|
||||
notification
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@ module RepositoryDatatable
|
|||
url: rails_blob_path(asset.file, disposition: 'attachment'),
|
||||
preview_url: asset_file_preview_path(asset),
|
||||
file_name: escape_input(asset.file_name),
|
||||
icon_html: FileIconsHelper.file_extension_icon_html(asset)
|
||||
icon_html: FileIconsHelper.sn_icon_for(asset)
|
||||
}
|
||||
rescue StandardError => e
|
||||
Rails.logger.error e.message
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Notifications
|
||||
class HandleSystemNotificationInCommunicationChannelService
|
||||
extend Service
|
||||
|
||||
attr_reader :errors
|
||||
|
||||
def initialize(system_notification)
|
||||
@system_notification = system_notification
|
||||
@errors = {}
|
||||
end
|
||||
|
||||
def call
|
||||
@system_notification.user_system_notifications.find_each do |usn|
|
||||
user = usn.user
|
||||
AppMailer.delay.system_notification(user, @system_notification) if user.system_message_email_notification
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def succeed?
|
||||
@errors.none?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Notifications
|
||||
class PushToCommunicationChannelService
|
||||
extend Service
|
||||
|
||||
WHITELISTED_ITEM_TYPES = %w(SystemNotification).freeze
|
||||
|
||||
attr_reader :errors
|
||||
|
||||
def initialize(item_id:, item_type:)
|
||||
@item_type = item_type
|
||||
@item = item_type.constantize.find item_id
|
||||
@errors = {}
|
||||
end
|
||||
|
||||
def call
|
||||
return self unless valid?
|
||||
|
||||
"Notifications::Handle#{@item_type}InCommunicationChannelService".constantize.call(@item)
|
||||
self
|
||||
end
|
||||
|
||||
def succeed?
|
||||
@errors.none?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid?
|
||||
raise 'Dont know how to handle this type of items' unless WHITELISTED_ITEM_TYPES.include?(@item_type)
|
||||
|
||||
if @item.nil?
|
||||
@errors[:invalid_arguments] = 'Can\'t find item' if @item.nil?
|
||||
return false
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Notifications
|
||||
class SyncSystemNotificationsService
|
||||
extend Service
|
||||
include HTTParty
|
||||
base_uri Rails.application.secrets.system_notifications_uri
|
||||
|
||||
SYNC_TIMESTAMP_CACHE_KEY = 'system_notifications_last_sync_timestamp'
|
||||
|
||||
attr_reader :errors
|
||||
|
||||
def initialize
|
||||
@errors = {}
|
||||
end
|
||||
|
||||
def call
|
||||
call_api
|
||||
|
||||
save_new_notifications if succeed?
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def succeed?
|
||||
@errors.none?
|
||||
end
|
||||
|
||||
def self.available?
|
||||
channel = Rails.application.secrets.system_notifications_channel
|
||||
query = { query: { last_sync_timestamp: Time.now.to_i, channels_slug: channel },
|
||||
headers: { 'accept': 'application/vnd.system-notifications.1+json' } }
|
||||
response = get('/api/system_notifications', query)
|
||||
response.code < Rack::Utils::SYMBOL_TO_STATUS_CODE[:bad_request]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def call_api
|
||||
last_sync =
|
||||
Rails.cache.fetch(SYNC_TIMESTAMP_CACHE_KEY, expires_in: 24.hours, skip_nil: true) do
|
||||
SystemNotification.last_sync_timestamp
|
||||
end
|
||||
channel = Rails.application.secrets.system_notifications_channel
|
||||
|
||||
unless last_sync
|
||||
@errors[:last_sync_timestamp] = 'Cannot find last_sync_timestamp'
|
||||
return false
|
||||
end
|
||||
|
||||
query = { query: { last_sync_timestamp: last_sync,
|
||||
channels_slug: channel },
|
||||
headers: { 'accept':
|
||||
'application/vnd.system-notifications.1+json' } }
|
||||
|
||||
# rubocop:disable Lint/ShadowedException:
|
||||
begin
|
||||
@api_call = self.class.get('/api/system_notifications', query)
|
||||
|
||||
if @api_call.response.code.to_i != 200
|
||||
@errors[:api_error] =
|
||||
[@api_call.response.code.to_s, @api_call.response.message].join('-')
|
||||
|
||||
# Add message for logging if exists
|
||||
if @api_call.parsed_response.try('error')
|
||||
@errors[:api_error] += ': ' + @api_call
|
||||
.parsed_response['error']
|
||||
.flatten&.join(' - ').to_s
|
||||
end
|
||||
end
|
||||
rescue SocketError, HTTParty::Error, StandardError => e
|
||||
@errors[e.class.to_s.downcase.to_sym] = e.message
|
||||
end
|
||||
# rubocop:enable Lint/ShadowedException:
|
||||
end
|
||||
|
||||
def save_new_notifications
|
||||
received_notifications = @api_call.parsed_response['notifications']
|
||||
return if received_notifications.blank?
|
||||
|
||||
received_notifications.each do |received_notification|
|
||||
# Save new notification if not exists or override old 1
|
||||
attrs = received_notification
|
||||
.slice('title', 'description', 'modal_title', 'modal_body', 'show_on_login', 'source_id')
|
||||
.merge('source_created_at': Time.zone.parse(received_notification['source_created_at']),
|
||||
'last_time_changed_at': Time.zone.parse(received_notification['last_time_changed_at']))
|
||||
.symbolize_keys
|
||||
|
||||
notification = SystemNotification.where(source_id: attrs[:source_id]).first_or_initialize(attrs)
|
||||
|
||||
if notification.new_record?
|
||||
save_notification(notification)
|
||||
elsif notification.last_time_changed_at < attrs[:last_time_changed_at]
|
||||
notification.update!(attrs)
|
||||
end
|
||||
end
|
||||
|
||||
Rails.cache.delete(SYNC_TIMESTAMP_CACHE_KEY)
|
||||
end
|
||||
|
||||
def save_notification(notification)
|
||||
ActiveRecord::Base.transaction do
|
||||
notification.save!
|
||||
|
||||
User.find_in_batches do |user_ids|
|
||||
user_system_notifications = user_ids.pluck(:id).collect do |item|
|
||||
Hash[:user_id, item, :system_notification_id, notification.id]
|
||||
end
|
||||
UserSystemNotification.import user_system_notifications, validate: false
|
||||
end
|
||||
end
|
||||
|
||||
Notifications::PushToCommunicationChannelService.delay.call(item_id: notification.id,
|
||||
item_type: notification.class.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
id: 'wopi_file_edit_button',
|
||||
class: 'btn btn-light',
|
||||
target: '_blank' do %>
|
||||
<%= file_application_icon(asset) %>
|
||||
<i class="sn-icon sn-icon-<%= sn_icon_for(asset) %>"></i>
|
||||
<%= wopi_button_text(asset, 'edit') %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
target: '_blank',
|
||||
title: title,
|
||||
disabled: true do %>
|
||||
<%= file_application_icon(asset) %>
|
||||
<i class="sn-icon sn-icon-<%= sn_icon_for(asset) %>"></i>
|
||||
<%= wopi_button_text(asset, 'edit') %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<div class="sci-input-container left-icon ">
|
||||
<input type="text" class="sci-input-field task-search-field" placeholder="<%= t("dashboard.current_tasks.search") %>"></input>
|
||||
<div class="sci-input-container-v2 left-icon h-[2.25rem]">
|
||||
<input type="text" class="sci-input-field task-search-field" placeholder="<%= t("dashboard.current_tasks.search") %>" />
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
role="dialog"
|
||||
aria-labelledby="move-experiment-modal-label">
|
||||
<%= form_with model: @experiment,
|
||||
url: move_experiment_path(@experiment),
|
||||
method: :post,
|
||||
remote: true,
|
||||
html: { class: 'experiment-action-form' } do |f| %>
|
||||
url: move_experiment_path(@experiment),
|
||||
method: :post,
|
||||
data: { remote: true },
|
||||
html: { class: 'experiment-action-form' } do |f| %>
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
|
|
|||
|
|
@ -11,9 +11,8 @@
|
|||
<meta name="expiration-url" content="<%= users_expire_in_path %>">
|
||||
<meta name="revive-url" content="<%= users_revive_session_path %>">
|
||||
<% end %>
|
||||
<%= stylesheet_link_tag 'bootstrap', media: 'all' %>
|
||||
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
|
||||
<%= stylesheet_link_tag 'application_pack_styles', media: 'all' %>
|
||||
<% if ::NewRelic::Agent.instance.started? %>
|
||||
<%= ::NewRelic::Agent.browser_timing_header(controller.request.content_security_policy_nonce) %>
|
||||
|
|
@ -24,6 +23,7 @@
|
|||
<%= javascript_include_tag 'application' %>
|
||||
<%= javascript_include_tag 'session_end' %>
|
||||
<%= javascript_include_tag 'sidebar_toggle' %>
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
|
||||
|
||||
<% if MarvinJsService.enabled? && ENV['MARVINJS_API_KEY'] %>
|
||||
|
|
@ -114,12 +114,6 @@
|
|||
<%= render "label_printers/label_printer_modal" %>
|
||||
<% end %>
|
||||
|
||||
<% if user_signed_in? && flash[:system_notification_modal] && current_user.show_login_system_notification? %>
|
||||
<%= render partial: "/system_notifications/system_notification_modal", locals: { notification: current_user.user_system_notifications.show_on_login(true) } %>
|
||||
<% else %>
|
||||
<%= render partial: "/system_notifications/system_notification_modal", locals: { notification: nil} %>
|
||||
<% end %>
|
||||
|
||||
<span style="display: none;" data-hook="application-body-end-html"></span>
|
||||
|
||||
<%= javascript_include_tag 'prism' %>
|
||||
|
|
|
|||
|
|
@ -9,20 +9,18 @@
|
|||
<style media="all">
|
||||
html, body { height: 100%; min-height: 100%; }
|
||||
</style>
|
||||
<%= stylesheet_link_tag 'bootstrap', media: 'all' %>
|
||||
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
<%= stylesheet_link_tag 'application_pack', media: 'all' %>
|
||||
|
||||
<%= stylesheet_link_tag 'application_pack_styles', media: 'all' %>
|
||||
<%= javascript_include_tag 'jquery_bundle' %>
|
||||
<%= javascript_include_tag 'application' %>
|
||||
<%= javascript_include_tag 'application_pack_styles' %>
|
||||
<%= javascript_include_tag 'application_pack' %>
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
|
||||
<%= favicon_link_tag "favicon.ico" %>
|
||||
<%= favicon_link_tag "favicon-16.png", type: "image/png", size: "16x16" %>
|
||||
<%= favicon_link_tag "favicon-32.png", type: "image/png", size: "32x32" %>
|
||||
<%= favicon_link_tag "favicon-48.png", type: "image/png", size: "48x48" %>
|
||||
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
||||
<%= stylesheet_link_tag 'fontawesome' %>
|
||||
|
||||
<%= csrf_meta_tags %>
|
||||
</head>
|
||||
|
|
@ -31,7 +29,7 @@
|
|||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<span class="navbar-brand" title="<% t('nav.label.scinote') %>">
|
||||
<%= image_tag('/images/scinote_icon.svg', id: 'logo') %>
|
||||
<%= image_tag('scinote_logo.svg', id: 'logo') %>
|
||||
</span>
|
||||
</div>
|
||||
<% if user_signed_in? %>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
<%= t('my_modules.modals.status_flow_modal.current_status') %><i class="fas fa-long-arrow-alt-right"></i>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="status-block" style="background: <%= status[:color] %>">
|
||||
<div class="status-block <%= 'btn-not-started' if status.name == 'Not started' %>"
|
||||
style="background: <%= status[:color] %>">
|
||||
<%= status[:name] %>
|
||||
</div>
|
||||
<div class="status-comment">
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@
|
|||
<% if current_team.shareable_links_enabled? %>
|
||||
<div class="share-task-container" data-behaviour="vue">
|
||||
<share-task-container
|
||||
<%= 'shared' if @my_module.shared? %>
|
||||
shareable-link-url="<%= my_module_shareable_link_path(@my_module) %>"
|
||||
<%= 'disabled' if !can_manage_my_module?(current_user, @my_module) %> />
|
||||
:shared="<%= @my_module.shared? %>"
|
||||
:disabled="<%= !can_share_my_module?(@my_module) %>" />
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag 'vue_share_task_container' %>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<% status = my_module.my_module_status %>
|
||||
<div class="status-label">
|
||||
<%= t('my_module_statuses.dropdown.status_label') %>
|
||||
<div class="status-title"><%= t('my_module_statuses.dropdown.status_label') %></div>
|
||||
<div class="status-note">
|
||||
<% if my_module.last_transition_error %>
|
||||
<div class="status-transition-error">
|
||||
|
|
@ -22,7 +22,9 @@
|
|||
<div class="dropdown sci-dropdown status-flow-dropdown"
|
||||
data-status-changing="<%= my_module.status_changing %>"
|
||||
data-status-check-url="<%= status_state_my_module_path(my_module) %>">
|
||||
<button class="btn btn-secondary dropdown-toggle <%= 'disabled' if my_module.status_changing || my_module.archived_branch? %>"
|
||||
<button class="btn btn-secondary dropdown-toggle
|
||||
<%= 'disabled' if my_module.status_changing || my_module.archived_branch? %>
|
||||
<%= 'btn-not-started' if status.name == 'Not started' %>"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
|
|
@ -45,8 +47,9 @@
|
|||
<li data-state-id="<%= previous_s.id %>" id="previousStatusSelector" class="<%= 'disabled' if previous_s_errors.any? %>">
|
||||
<span><%= t('my_module_statuses.dropdown.return_label') %></span>
|
||||
<i class="fas fa-long-arrow-alt-right"></i>
|
||||
<div class=" status-container">
|
||||
<div class="status-name" style="<%= "background-color: #{previous_s.color}" %>"><%= previous_s.name %></div>
|
||||
<div class="status-container">
|
||||
<div class="status-name <%= 'btn-not-started' if previous_s.name == 'Not started' %>"
|
||||
style="<%= "background-color: #{previous_s.color}" %>"><%= previous_s.name %></div>
|
||||
</div>
|
||||
</li>
|
||||
<span class="error-message"><% previous_s_errors.each do |error| %>
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@
|
|||
<div class="checkbox">
|
||||
<%= f.check_box :visibility,
|
||||
{ label: t('projects.index.modal_new_project.visibility_html'),
|
||||
data: { action: 'toggle-visibility', target: 'role_select_wrapper' },
|
||||
data: { action: 'toggle-visibility', target: 'edit_project_role_select_wrapper' },
|
||||
checked: f.object.visible? },
|
||||
:visible,
|
||||
:hidden %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row <%= f.object.hidden? ? 'hidden' : '' %>" id="role_select_wrapper">
|
||||
<div class="row <%= f.object.hidden? ? 'hidden' : '' %>" id="edit_project_role_select_wrapper">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<%= f.select :default_public_user_role_id,
|
||||
options_for_select(user_roles_collection(@project), selected: f.object.default_public_user_role_id),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="modal-body">
|
||||
<%= t('projects.index.modal_move_folder.description', items: items_label) %>
|
||||
|
||||
<div class="sci-input-container left-icon">
|
||||
<div class="sci-input-container-v2 left-icon my-4 h-[2.25rem]">
|
||||
<input type="search" class="form-control sci-input-field" id="searchFolderTree" placeholder="Find a folder"/>
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<div class="flex items-center gap-4 text-xs">
|
||||
<div class="sci-checkbox-container">
|
||||
<%= f.check_box :visibility,
|
||||
{ class: 'sci-checkbox' ,data: { action: 'toggle-visibility', target: 'role_select_wrapper' } },
|
||||
{ class: 'sci-checkbox' ,data: { action: 'toggle-visibility', target: 'new_project_role_select_wrapper' } },
|
||||
:visible,
|
||||
:hidden %>
|
||||
<span class="sci-checkbox-label"></span>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row hidden" id="role_select_wrapper">
|
||||
<div class="row hidden" id="new_project_role_select_wrapper">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 sci-input-container mt-4">
|
||||
<%= f.select :default_public_user_role_id,
|
||||
options_for_select(user_roles_collection(@project), UserRole.find_by(name: I18n.t('user_roles.predefined.viewer')).id),
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<%= wicked_pdf_stylesheet_link_tag "application" %>
|
||||
<%= wicked_pdf_stylesheet_link_tag "reports_pdf" %>
|
||||
<%= font_awesome_cdn_link_tag %>
|
||||
<%= wicked_pdf_javascript_include_tag "jquery" %>
|
||||
<%= wicked_pdf_javascript_include_tag "jquery_bundle" %>
|
||||
<%= wicked_pdf_javascript_include_tag "handsontable.full" %>
|
||||
<!-- Libraries for formulas -->
|
||||
<%= wicked_pdf_javascript_include_tag "lodash" %>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="modal" id="create-repo-modal" tabindex="-1" role="dialog" aria-labelledby="create-repo-modal-label">
|
||||
<%= form_with url: [current_team, @repository], remote: :true do |f| %>
|
||||
<%= form_with model: @repository, url: repositories_path, html: { data: { remote: true } } do |f| %>
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<div class="well">
|
||||
<%= form_with(model: @result, url: result_asset_path(format: :json), data: { remote: true }) do |f| %>
|
||||
<%= f.text_field :name, style: "margin-top: 10px;" %><br />
|
||||
<%= form_with(model: @result, url: result_asset_path(format: :json), data: { remote: true }, html: { class: 'edit-result-asset' }) do |f| %>
|
||||
<div class="sci-input-container mb-4">
|
||||
<label><%= t('result_assets.edit.label.name') %></label>
|
||||
<%= f.text_field :name, class: 'sci-input-field' %>
|
||||
</div>
|
||||
<%= f.fields_for :asset do |ff| %>
|
||||
<span><strong><%=t "result_assets.edit.uploaded_asset" %></strong></span>
|
||||
<p style="margin: 10px;">
|
||||
|
|
@ -18,5 +21,4 @@
|
|||
class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= javascript_include_tag 'results/result_assets/edit' %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,5 +27,4 @@
|
|||
|
||||
</div>
|
||||
<% end %>
|
||||
<%= javascript_include_tag 'results/result_assets/new' %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<div id="table-form" class="well">
|
||||
<%= form_with(model: @result, url: result_table_path(format: :json),
|
||||
data: { remote: true, 'name-max-length': Constants::NAME_MAX_LENGTH }) do |f| %>
|
||||
<%= f.text_field :name, style: "margin-top: 10px;" %><br />
|
||||
<div class="sci-input-container mb-4">
|
||||
<label><%= t('result_tables.edit.label.name') %></label>
|
||||
<%= f.text_field :name, class: 'sci-input-field' %>
|
||||
</div>
|
||||
<div class="editable-table">
|
||||
<%= f.fields_for :table do |ff| %>
|
||||
<%= ff.hidden_field(:contents, value: ff.object.contents_utf_8, class: "hot-contents" ) %>
|
||||
|
|
@ -17,7 +20,6 @@
|
|||
</button>
|
||||
<%= f.button t("general.save"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= javascript_include_tag 'results/result_tables/edit' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<div id="table-form" class="well">
|
||||
<%= form_with(model: @result, url: my_module_result_tables_path(format: :json, page: params[:page], order: params[:order]),
|
||||
data: { remote: true, 'name-max-length': Constants::NAME_MAX_LENGTH }) do |f| %>
|
||||
<%= f.text_field :name, style: "margin-top: 10px;" %><br />
|
||||
<div class="sci-input-container mb-4">
|
||||
<label><%= t('result_tables.new.label.name') %></label>
|
||||
<%= f.text_field :name, class: 'sci-input-field' %>
|
||||
</div>
|
||||
<div class="editable-table" style="margin-bottom: 25px;">
|
||||
<%= f.fields_for :table do |ff| %>
|
||||
<%= ff.hidden_field(:contents, value: ff.object.contents, class: "hot-contents" ) %>
|
||||
|
|
@ -16,7 +19,6 @@
|
|||
</button>
|
||||
<%= f.button t("result_tables.new.create"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= javascript_include_tag 'results/result_tables/new' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
<div class="text-3xl font-bold"><%= @my_module.name %></div>
|
||||
<div class="text-3xl font-semibold flex flex-row flex-nowrap">
|
||||
<span class="inline-block whitespace-nowrap mr-1">
|
||||
<%= t "labels.archived" if @my_module.archived? %>
|
||||
</span>
|
||||
<span class="inline-block truncate w-[calc(100vw-27rem)]" title="<%= @my_module.name %>">
|
||||
<%= @my_module.name %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="my-5 max-w-4xl flex-1 bg-sn-white">
|
||||
<div class="my-module-position-container">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="text-3xl font-bold"><%= @my_module.name %></div>
|
||||
<div class="text-3xl font-semibold"><%= @my_module.name %></div>
|
||||
|
||||
<div class="px-4 my-5 flex-1 bg-sn-white">
|
||||
<div class="content-pane flexible">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<span class="due-date-label <%= get_task_alert_color(my_module) %>">
|
||||
<span class="due-date-label font-medium <%= get_task_alert_color(my_module) %>">
|
||||
<% if (my_module.archived_branch? || my_module.completed? ) && my_module.due_date %>
|
||||
<span class="iso-formatted-date"><%= my_module.due_date.iso8601 %></span>
|
||||
<% elsif my_module.is_one_day_prior? %>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="flex items-center uppercase text-bold">
|
||||
<div class="flex items-center uppercase">
|
||||
<a class="p-4 border-b-4 border-transparent hover:no-underline capitalize <%= is_module_protocols? ? "text-sn-blue" : "text-sn-grey" %>"
|
||||
href="<%= shared_protocol_url(@shareable_link.uuid) %>"
|
||||
title="<%= t("nav2.modules.steps") %>"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<%= t("shareable_links.left_navigation.welcome")%>
|
||||
</h3>
|
||||
<div class="flex flex-col p-6 bg-sn-super-light-blue gap-4">
|
||||
<span class="font-bold">
|
||||
<span class="font-semibold">
|
||||
<%= t("shareable_links.left_navigation.title")%>
|
||||
</span>
|
||||
<span class="text-[.75rem]">
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<span class="hidden-xs hidden-sm hidden-md"><%= t('my_modules.details.completed_date') %></span>
|
||||
</div>
|
||||
<div class="datetime-container">
|
||||
<span class="date-text iso-formatted-date">
|
||||
<span class="iso-formatted-date font-medium">
|
||||
<%= @my_module.completed_on.iso8601 %>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<span class="start-date-label">
|
||||
<% if my_module.started_on.present? %>
|
||||
<span class="iso-formatted-date font-bold"><%= my_module.started_on.iso8601 %></span>
|
||||
<span class="iso-formatted-date font-medium"><%= my_module.started_on.iso8601 %></span>
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -104,4 +104,4 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= javascript_include_tag 'shared/file_preview' %>
|
||||
<%= javascript_include_tag 'shared/file_preview', nonce: true %>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<div class="sci--navigation--top-menu-logo">
|
||||
<a title="SciNote" href="/">
|
||||
<%= image_tag "/images/sn-icon.svg", class: "logo small" %>
|
||||
<%= image_tag "/images/scinote_icon.svg", class: "logo large" %>
|
||||
<%= image_tag "scinote_logo.svg", class: "logo large" %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
<div class="modal" id="manage-module-system-notification-modal" tabindex="-1" role="dialog" aria-labelledby="manage-module-system-notification-modal-label">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<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" id="manage-module-system-notification-modal-label">
|
||||
<%= notification ? notification.modal_title.html_safe : '' %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<%= notification ? notification.modal_body.html_safe : '' %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if notification %>
|
||||
<%= javascript_include_tag 'system_notifications/system_notification_modal' %>
|
||||
<% end %>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<p>
|
||||
<%= I18n.t("system_notifications.emails.intro_paragraph", user_name: @user.name) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= link_to @system_notification.title.html_safe, system_notifications_url %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= @system_notification.description.html_safe %>
|
||||
</p>
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<%= t("users.settings.teams.edit.modal_destroy_team.message", team: team.name) %>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<%= bootstrap_form_tag url: destroy_team_path(team), method: :delete do |f| %>
|
||||
<%= form_with url: destroy_team_path(team), method: :delete do |f| %>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%= t('general.cancel') %></button>
|
||||
<%= f.submit t("users.settings.teams.edit.modal_destroy_team.confirm"), class: "btn btn-danger" %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
<div class="form-group" style="max-width: 500px;">
|
||||
<%= f.text_area :description, label: t('users.settings.teams.new.description_label') %>
|
||||
<br>
|
||||
<small>
|
||||
<%=t 'users.settings.teams.new.description_sublabel' %>
|
||||
</small>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<%= form_with model: user_assignment,
|
||||
url: destroy_user_team_path(user_assignment, format: :json),
|
||||
data: { remote: true },
|
||||
method: :delete,
|
||||
data: { id: 'destroy-user-team-form' } do |f| %>
|
||||
data: { remote: true, id: 'destroy-user-team-form' },
|
||||
method: :delete do |f| %>
|
||||
<p><%= t("users.settings.user_teams.destroy_uo_message",
|
||||
user: user_assignment.user.full_name,
|
||||
team: user_assignment.assignable.name) %></p>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ Rails.application.config.assets.precompile += %w(jszip.min.js)
|
|||
Rails.application.config.assets.precompile += %w(comments.js)
|
||||
Rails.application.config.assets.precompile += %w(projects/show.js)
|
||||
Rails.application.config.assets.precompile += %w(notifications.js)
|
||||
Rails.application.config.assets.precompile += %w(system_notifications/index.js)
|
||||
Rails.application.config.assets.precompile += %w(users/invite_users_modal.js)
|
||||
Rails.application.config.assets.precompile += %w(search.js)
|
||||
Rails.application.config.assets.precompile += %w(label_printers/index.js)
|
||||
|
|
@ -98,7 +97,6 @@ Rails.application.config.assets.precompile += %w(users/login_disclaimer.js)
|
|||
Rails.application.config.assets.precompile += %w(assets/office_form.js)
|
||||
Rails.application.config.assets.precompile += %w(global_activities/date_picker.js)
|
||||
Rails.application.config.assets.precompile += %w(shared/color_picker_select.js)
|
||||
Rails.application.config.assets.precompile += %w(system_notifications/system_notification_modal.js)
|
||||
Rails.application.config.assets.precompile += %w(users/confirmation/new.js)
|
||||
Rails.application.config.assets.precompile += %w(users/invitations/team_errors.js)
|
||||
Rails.application.config.assets.precompile += %w(users/invitations/resource_errors.js)
|
||||
|
|
@ -108,10 +106,6 @@ Rails.application.config.assets.precompile += %w(users/registrations/new_with_pr
|
|||
Rails.application.config.assets.precompile += %w(team_zip_exports/load_handson.js)
|
||||
Rails.application.config.assets.precompile += %w(repository_columns/manage_column_partials/number.js)
|
||||
Rails.application.config.assets.precompile += %w(repository_columns/manage_column_partials/stock.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_assets/new.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_assets/edit.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_tables/new.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_tables/edit.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_texts/new.js)
|
||||
Rails.application.config.assets.precompile += %w(results/result_texts/edit.js)
|
||||
Rails.application.config.assets.precompile += %w(shared/file_preview.js)
|
||||
|
|
@ -138,3 +132,6 @@ Rails.application.config.assets.precompile += %w(big.min.js)
|
|||
|
||||
# JQuery related includes
|
||||
Rails.application.config.assets.precompile += %w(jquery_bundle.js)
|
||||
|
||||
# Add stuff installed by yarn
|
||||
Rails.application.config.assets.paths << Rails.root.join('node_modules')
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
ActiveSupport::Reloader.to_prepare do
|
||||
azure_app_ids = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
||||
settings = ApplicationSettings.instance
|
||||
settings.values['azure_ad_apps'] ||= []
|
||||
|
||||
azure_app_ids.each do |name, value|
|
||||
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ class Extends
|
|||
83, 101, 112, 123, 125, 117, 119, 129, 131, 170, 173, 179, 187, 186,
|
||||
190, 191, *204..215, 220, 221, 223, 227, 228, 229, *230..235, *237..240],
|
||||
team: [92, 94, 93, 97, 104, 244, 245],
|
||||
label_repository: [*216..219]
|
||||
label_templates: [*216..219]
|
||||
}
|
||||
|
||||
TOP_LEVEL_ASSIGNABLES = %w(Project Team Protocol Repository).freeze
|
||||
|
|
@ -494,9 +494,9 @@ class Extends
|
|||
DEFAULT_FLOW_NAME = 'SciNote Free default task flow'
|
||||
|
||||
DEFAULT_FLOW_STATUSES = [
|
||||
{ name: 'Not started', color: '#406d86' },
|
||||
{ name: 'In progress', color: '#0065ff', consequences: ['MyModuleStatusConsequences::Uncompletion'] },
|
||||
{ name: 'Completed', color: '#00b900', consequences: ['MyModuleStatusConsequences::Completion'] }
|
||||
{ name: 'Not started', color: '#FFFFFF' },
|
||||
{ name: 'In progress', color: '#3070ED', consequences: ['MyModuleStatusConsequences::Uncompletion'] },
|
||||
{ name: 'Completed', color: '#5EC66F', consequences: ['MyModuleStatusConsequences::Completion'] }
|
||||
]
|
||||
|
||||
REPORT_TEMPLATES = {}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ AZURE_SETUP_PROC = lambda do |env|
|
|||
env['omniauth.strategy'].options[:tenant_id] = provider_conf['tenant_id']
|
||||
env['omniauth.strategy'].options[:sign_in_policy] = provider_conf['sign_in_policy']
|
||||
env['omniauth.strategy'].options[:name] = 'customazureactivedirectory'
|
||||
env['omniauth.strategy'].options[:conf_url] = provider_conf['conf_url']
|
||||
conf_uri = URI.parse(provider_conf['conf_url'])
|
||||
env['omniauth.strategy'].options[:base_azure_url] = "#{conf_uri.scheme || 'https'}://#{conf_uri.host}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,23 +16,6 @@ if ENV['ENABLE_TEMPLATES_SYNC'] == 'true'
|
|||
end
|
||||
end
|
||||
|
||||
if Rails.application.secrets.system_notifications_uri.present? &&
|
||||
Rails.application.secrets.system_notifications_channel.present?
|
||||
|
||||
# System notifications periodic task
|
||||
scheduler.every '1h' do
|
||||
Rails.logger.info('System Notifications syncing')
|
||||
Rails.logger.info(Process.pid)
|
||||
result = Notifications::SyncSystemNotificationsService.call
|
||||
if result.errors.any?
|
||||
Rails.logger.info('System Notifications sync error: ')
|
||||
Rails.logger.info(result.errors.to_s)
|
||||
else
|
||||
Rails.logger.info('System Notifications sync done')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ENV['ENABLE_FLUICS_SYNC'] == 'true'
|
||||
scheduler.every '24h' do
|
||||
LabelPrinters::Fluics::SyncService.new.sync_templates! if LabelPrinter.fluics.any?
|
||||
|
|
|
|||
|
|
@ -1679,6 +1679,8 @@ en:
|
|||
uploaded_asset: "Uploaded file"
|
||||
update: "Update"
|
||||
locked_file_error: 'This file is being edited by someone else.'
|
||||
label:
|
||||
name: 'Name'
|
||||
create:
|
||||
success_flash: "Successfully added file result to task <strong>%{module}</strong>"
|
||||
update:
|
||||
|
|
@ -1700,10 +1702,14 @@ en:
|
|||
head_title: "%{project} | %{module} | Add table result"
|
||||
title: "Add result to task %{module}"
|
||||
create: "Add"
|
||||
label:
|
||||
name: 'Name'
|
||||
edit:
|
||||
head_title: "%{project} | %{module} | Edit table result"
|
||||
title: "Edit result from task %{module}"
|
||||
update: "Update"
|
||||
label:
|
||||
name: 'Name'
|
||||
create:
|
||||
success_flash: "Successfully added table result to task <strong>%{module}</strong>"
|
||||
update:
|
||||
|
|
@ -2332,19 +2338,6 @@ en:
|
|||
my_to_team_message: 'My protocols to Team protocols'
|
||||
team_to_my_message: 'Team protocols to My protocols'
|
||||
|
||||
system_notifications:
|
||||
navbar:
|
||||
tooltip: 'What’s new notifications'
|
||||
emails:
|
||||
subject: "You've received a What's new notification"
|
||||
intro_paragraph: "Hi %{user_name}, you've received What's new notification in SciNote:"
|
||||
index:
|
||||
whats_new_html: "What's New"
|
||||
more_notifications: "Show more notifications"
|
||||
no_notifications: "No more notifications"
|
||||
settings: "Settings"
|
||||
see_all: "show all"
|
||||
|
||||
user_my_modules:
|
||||
new:
|
||||
head_title: "%{project} | %{module} | Add user"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue