mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-30 00:45:28 +08:00
Add statuses validation on FE
This commit is contained in:
parent
b9d50263c4
commit
9bf948c3a8
7 changed files with 164 additions and 24 deletions
|
@ -73,13 +73,14 @@ var RepositoryListColumnType = (function() {
|
|||
function refreshCounter(number) {
|
||||
var $manageModal = $(manageModal);
|
||||
$manageModal.find('.list-items-count').html(number);
|
||||
$manageModal.find('.list-items-count').attr('data-count', number);
|
||||
|
||||
if (number > GLOBAL_CONSTANTS.REPOSITORY_LIST_ITEMS_PER_COLUMN) {
|
||||
if (number >= GLOBAL_CONSTANTS.REPOSITORY_LIST_ITEMS_PER_COLUMN) {
|
||||
$manageModal.find('.limit-counter-container').addClass('error-to-many-items');
|
||||
$manageModal.find('button[data-action="save"]').prop('disabled', true);
|
||||
$manageModal.find('button[data-action="save"]').addClass('disabled');
|
||||
} else {
|
||||
$manageModal.find('.limit-counter-container').removeClass('error-to-many-items');
|
||||
$manageModal.find('button[data-action="save"]').prop('disabled', false);
|
||||
$manageModal.find('button[data-action="save"]').removeClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,7 @@ var RepositoryListColumnType = (function() {
|
|||
refreshPreviewDropdownList();
|
||||
});
|
||||
|
||||
$manageModal.off('columnModal::partialLoaded').on('columnModal::partialLoaded', function() {
|
||||
$manageModal.off('columnModal::partialLoadedForLists').on('columnModal::partialLoadedForLists', function() {
|
||||
refreshPreviewDropdownList();
|
||||
});
|
||||
|
||||
|
@ -126,6 +127,11 @@ var RepositoryListColumnType = (function() {
|
|||
return {
|
||||
init: () => {
|
||||
initDropdownItemsTextArea();
|
||||
},
|
||||
checkValidation: () => {
|
||||
var $manageModal = $(manageModal);
|
||||
var count = $manageModal.find('.list-items-count').attr('data-count');
|
||||
return count < GLOBAL_CONSTANTS.REPOSITORY_LIST_ITEMS_PER_COLUMN;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global I18n */
|
||||
/* global GLOBAL_CONSTANTS I18n */
|
||||
/* eslint-disable no-unused-vars */
|
||||
var RepositoryStatusColumnType = (function() {
|
||||
var manageModal = '#manageRepositoryColumn';
|
||||
|
@ -13,24 +13,57 @@ var RepositoryStatusColumnType = (function() {
|
|||
<span class="status-item-icon-trash fas fa-trash"></span>
|
||||
</div>
|
||||
<div class="emojis-picker">
|
||||
<span data-emoji-code="128540">😜</span>
|
||||
<span data-emoji-code="128520">😈</span>
|
||||
<span data-emoji-code="128526">😎</span>
|
||||
<span data-emoji-code="128531">😓</span>
|
||||
<span data-emoji-code="128535">😗</span>
|
||||
<span data-emoji-code="128536">😘</span>
|
||||
<span data-emoji-code="😜">😜</span>
|
||||
<span data-emoji-code="😈">😈</span>
|
||||
<span data-emoji-code="😎">😎</span>
|
||||
<span data-emoji-code="😓">😓</span>
|
||||
<span data-emoji-code="😗">😗</span>
|
||||
<span data-emoji-code="😘">😘</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function validateForm() {
|
||||
var $manageModal = $(manageModal);
|
||||
var $statusRows = $manageModal.find('.status-item-container:not([data-removed])');
|
||||
|
||||
$.each($statusRows, (index, statusRow) => {
|
||||
var $row = $(statusRow);
|
||||
var $statusField = $row.find('input.status-item-field');
|
||||
var $icon = $row.find('.status-item-icon');
|
||||
var stringLength = $statusField.val().length;
|
||||
|
||||
if (stringLength < GLOBAL_CONSTANTS.NAME_MIN_LENGTH
|
||||
|| stringLength > GLOBAL_CONSTANTS.NAME_MAX_LENGTH
|
||||
|| !$icon.attr('data-icon')) {
|
||||
$row.addClass('error');
|
||||
} else {
|
||||
$row.removeClass('error');
|
||||
}
|
||||
});
|
||||
|
||||
if ($manageModal.find('.error').length > 0) {
|
||||
$manageModal.find('button[data-action="save"]').addClass('disabled');
|
||||
} else {
|
||||
$manageModal.find('button[data-action="save"]').removeClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
function highlightErrors() {
|
||||
$(manageModal).find('.error').addClass('error-highlight');
|
||||
}
|
||||
|
||||
function initActions() {
|
||||
var $manageModal = $(manageModal);
|
||||
var addStatusOptionBtn = '.add-status';
|
||||
var deleteStatusOptionBtn = '.status-item-icon-trash';
|
||||
var icon = '.status-item-icon';
|
||||
var emojis = '.emojis-picker>span';
|
||||
var statusInput = 'input.status-item-field';
|
||||
var buttonWrapper = '.button-wrapper';
|
||||
|
||||
$manageModal.off('click', addStatusOptionBtn).on('click', addStatusOptionBtn, function() {
|
||||
var newStatusRow = $(statusTemplate()).insertBefore($(this));
|
||||
validateForm();
|
||||
setTimeout(function() {
|
||||
newStatusRow.css('height', '34px');
|
||||
}, 0);
|
||||
|
@ -55,9 +88,12 @@ var RepositoryStatusColumnType = (function() {
|
|||
setTimeout(function() {
|
||||
if (isNewRow) {
|
||||
$statusRow.remove();
|
||||
validateForm();
|
||||
} else {
|
||||
$statusRow.attr('data-removed', 'true');
|
||||
$statusRow.removeClass('loading');
|
||||
$statusRow.removeClass('error');
|
||||
validateForm();
|
||||
}
|
||||
$emojis.remove();
|
||||
}, 300);
|
||||
|
@ -70,14 +106,37 @@ var RepositoryStatusColumnType = (function() {
|
|||
|
||||
$manageModal.off('click', emojis).on('click', emojis, function() {
|
||||
var $clickedEmoji = $(this);
|
||||
var $iconField = $clickedEmoji.parent().prev().find('.status-item-icon');
|
||||
$clickedEmoji.parent().hide();
|
||||
$clickedEmoji.parent().prev().find('.status-item-icon').html($clickedEmoji.html());
|
||||
$iconField.html($clickedEmoji.data('emoji-code'));
|
||||
$iconField.attr('data-icon', $clickedEmoji.data('emoji-code'));
|
||||
$iconField.trigger('data-attribute-changed', $iconField);
|
||||
});
|
||||
|
||||
$manageModal.off('keyup change', statusInput).on('keyup change', statusInput, function() {
|
||||
validateForm();
|
||||
});
|
||||
|
||||
$manageModal.off('data-attribute-changed').on('data-attribute-changed', function() {
|
||||
validateForm();
|
||||
});
|
||||
|
||||
$manageModal.off('columnModal::partialLoadedForStatuses').on('columnModal::partialLoadedForStatuses', function() {
|
||||
validateForm();
|
||||
});
|
||||
|
||||
$manageModal.off('click', buttonWrapper).on('click', buttonWrapper, function() {
|
||||
highlightErrors();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: () => {
|
||||
initActions();
|
||||
},
|
||||
checkValidation: () => {
|
||||
highlightErrors();
|
||||
return !($(manageModal).find('.error').length > 0);
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
|
|
@ -40,6 +40,15 @@ var RepositoryColumns = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function checkData() {
|
||||
var validators = {
|
||||
RepositoryListValue: 'RepositoryListColumnType',
|
||||
RepositoryStatusValue: 'RepositoryStatusColumnType'
|
||||
};
|
||||
var currentPartial = $('#repository-column-data-type').find(':selected').val();
|
||||
return eval(validators[currentPartial]).checkValidation();
|
||||
}
|
||||
|
||||
|
||||
function insertNewListItem(column) {
|
||||
var attributes = column.attributes;
|
||||
|
@ -80,11 +89,38 @@ var RepositoryColumns = (function() {
|
|||
$('li[data-id=' + column.id + ']').find('span').first().text(name);
|
||||
}
|
||||
|
||||
function loadSpecificParams(type, params) {
|
||||
function loadSpecificParams(type, params, modal) {
|
||||
var $modal = modal;
|
||||
var newParams = params;
|
||||
var $statusItems;
|
||||
|
||||
if (type === 'RepositoryListValue') {
|
||||
newParams.repository_column.repository_list_items_attributes = JSON.parse($('#dropdown_options').val());
|
||||
newParams.repository_column.delimiter = $('select#delimiter').data('used-delimiter');
|
||||
} else if (type === 'RepositoryStatusValue') {
|
||||
$statusItems = $modal.find('.status-item-container');
|
||||
// Load all new items
|
||||
// Load all existing items, delete flag included
|
||||
newParams.repository_column.repository_status_items_attributes = [];
|
||||
|
||||
$.each($statusItems, function(index, value) {
|
||||
var $item = $(value);
|
||||
var id = $item.data('id');
|
||||
var removed = $item.data('removed');
|
||||
var icon = $item.find('.status-item-icon').data('icon');
|
||||
var status = $item.find('input.status-item-field').val();
|
||||
|
||||
if (removed && id) { // flag as item for removing
|
||||
newParams.repository_column.repository_status_items_attributes
|
||||
.push({ id: id, _destroy: true });
|
||||
} else if (id) { // existing element, maybe values needs to be updated
|
||||
newParams.repository_column.repository_status_items_attributes
|
||||
.push({ id: id, icon: icon, status: status });
|
||||
} else { // new element
|
||||
newParams.repository_column.repository_status_items_attributes
|
||||
.push({ icon: icon, status: status });
|
||||
}
|
||||
});
|
||||
}
|
||||
return newParams;
|
||||
}
|
||||
|
@ -95,7 +131,9 @@ var RepositoryColumns = (function() {
|
|||
var url = $('#repository-column-data-type').find(':selected').data('create-url');
|
||||
var params = { repository_column: { name: $('#repository-column-name').val() } };
|
||||
var selectedType = $('#repository-column-data-type').find(':selected').val();
|
||||
params = loadSpecificParams(selectedType, params);
|
||||
params = loadSpecificParams(selectedType, params, $manageModal);
|
||||
// if (checkData() === false) return;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
|
@ -120,7 +158,9 @@ var RepositoryColumns = (function() {
|
|||
var url = $('#repository-column-data-type').find(':selected').data('edit-url');
|
||||
var params = { repository_column: { name: $('#repository-column-name').val() } };
|
||||
var selectedType = $('#repository-column-data-type').find(':selected').val();
|
||||
params = loadSpecificParams(selectedType, params);
|
||||
params = loadSpecificParams(selectedType, params, $manageModal);
|
||||
if (checkData() !== true) return;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'PUT',
|
||||
|
@ -150,7 +190,8 @@ var RepositoryColumns = (function() {
|
|||
$manageModal.modal('show').find('.modal-content').html(data.html)
|
||||
.find('#repository-column-name')
|
||||
.focus();
|
||||
$manageModal.trigger('columnModal::partialLoaded');
|
||||
$manageModal.trigger('columnModal::partialLoadedForLists');
|
||||
$manageModal.trigger('columnModal::partialLoadedForStatuses');
|
||||
|
||||
if (button.data('action') === 'new') {
|
||||
$('[data-column-type="RepositoryTextValue"]').show();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const GLOBAL_CONSTANTS = {
|
||||
NAME_TRUNCATION_LENGTH: <%= Constants::NAME_TRUNCATION_LENGTH %>,
|
||||
NAME_MAX_LENGTH: <%= Constants::NAME_MAX_LENGTH %>,
|
||||
NAME_MIN_LENGTH: <%= Constants::NAME_MIN_LENGTH %>,
|
||||
FILENAME_TRUNCATION_LENGTH: <%= Constants::FILENAME_TRUNCATION_LENGTH %>,
|
||||
FILE_MAX_SIZE_MB: <%= Rails.configuration.x.file_max_size_mb %>,
|
||||
IS_SAFARI: /^((?!chrome|android).)*safari/i.test(navigator.userAgent),
|
||||
|
|
|
@ -337,6 +337,20 @@
|
|||
&[data-removed="true"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.error.error-highlight {
|
||||
.status-item-icon {
|
||||
border-bottom: 1px solid $brand-danger;
|
||||
border-left: 1px solid $brand-danger;
|
||||
border-top: 1px solid $brand-danger;
|
||||
}
|
||||
|
||||
.status-item-field {
|
||||
border-bottom: 1px solid $brand-danger;
|
||||
border-right: 1px solid $brand-danger;
|
||||
border-top: 1px solid $brand-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-item-field {
|
||||
|
@ -352,11 +366,19 @@
|
|||
.status-item-icon {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px 0 0 4px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
width: 34px;
|
||||
|
||||
|
||||
&:not([data-icon])::before {
|
||||
content: "\f06a";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
}
|
||||
}
|
||||
|
||||
.status-item-icon-trash {
|
||||
|
|
|
@ -11,7 +11,7 @@ module RepositoryColumns
|
|||
def call
|
||||
return self unless valid?
|
||||
|
||||
if @column.update(@params)
|
||||
if @column.update(column_attributes)
|
||||
log_activity(:edit_column_inventory)
|
||||
else
|
||||
errors[:repository_column] = @column.errors.messages
|
||||
|
@ -19,5 +19,16 @@ module RepositoryColumns
|
|||
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def column_attributes
|
||||
@params[:repository_status_items_attributes]&.map do |m|
|
||||
# assign for new records only
|
||||
m.merge!(repository_id: @repository.id, created_by_id: @user.id, last_modified_by_id: @user.id) unless m[:id]
|
||||
end
|
||||
|
||||
@params
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="col-sm-9">
|
||||
<% column.repository_status_items.each do |item| %>
|
||||
<div class="status-item-container" data-id="<%= item.id %>">
|
||||
<div class="status-item-icon"><%= item.icon %></div>
|
||||
<div class="status-item-icon" data-icon="<%= item.icon %>"><span><%= item.icon %></span></div>
|
||||
<input placeholder="<%= t('libraries.manange_modal_column.name_placeholder') %>"
|
||||
class="status-item-field"
|
||||
type="text"
|
||||
|
@ -13,12 +13,12 @@
|
|||
<span class="status-item-icon-trash fas fa-trash"></span>
|
||||
</div>
|
||||
<div class="emojis-picker">
|
||||
<span data-emoji-code="128540">😜</span>
|
||||
<span data-emoji-code="128520">😈</span>
|
||||
<span data-emoji-code="128526">😎</span>
|
||||
<span data-emoji-code="128531">😓</span>
|
||||
<span data-emoji-code="128535">😗</span>
|
||||
<span data-emoji-code="128536">😘</span>
|
||||
<span data-emoji-code="😜">😜</span>
|
||||
<span data-emoji-code="😈">😈</span>
|
||||
<span data-emoji-code="😎">😎</span>
|
||||
<span data-emoji-code="😓">😓</span>
|
||||
<span data-emoji-code="😗">😗</span>
|
||||
<span data-emoji-code="😘">😘</span>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="add-status">
|
||||
|
|
Loading…
Add table
Reference in a new issue