/* global I18n GLOBAL_CONSTANTS InfiniteScroll
initBSTooltips filterDropdown dropdownSelector Sidebar HelperModule notTurbolinksPreview _ */
var ExperimnetTable = {
selectedId: [],
table: '.experiment-table',
tableContainer: '.experiment-table-container',
selectedMyModules: [],
activeFilters: {},
filters: [], // Filter {name: '', init(), closeFilter(), apply(), active(), clearFilter()}
myModulesCurrentSort: '',
pageSize: GLOBAL_CONSTANTS.DEFAULT_ELEMENTS_PER_PAGE,
provisioningStatusTimeout: '',
render: {
task_name: function(data) {
let tooltip = ` title="${_.escape(data.name)}" data-toggle="tooltip" data-placement="bottom"`;
if (data.provisioning_status === 'in_progress') {
return `${data.name}`;
}
return `${data.name}`;
},
id: function(data) {
return `
${data.id}
`;
},
due_date: function(data) {
return data.data;
},
archived: function(data) {
return data;
},
age: function(data) {
return data;
},
results: function(data) {
return `${data.count}`;
},
status: function(data) {
return `${data.name}
`;
},
assigned: function(data) {
return data.html;
},
tags: function(data) {
const value = parseInt(data.tags, 10) === 0 ? I18n.t('experiments.table.add_tag') : data.tags;
if (data.tags === 0 && !data.can_create) {
return `${I18n.t('experiments.table.not_set')}`;
}
return `${value}`;
},
comments: function(data) {
if (data.count === 0 && !data.can_create) return '0';
return ``;
}
},
getUrls: function(id) {
return $(`.table-row[data-id="${id}"]`).data('urls');
},
loadPlaceholder: function() {
let placeholder = '';
$.each(Array(this.pageSize), function() {
placeholder += $('#experimentTablePlaceholder').html();
});
$(placeholder).insertAfter($(this.table).find('.table-body'));
},
appendRows: function(result) {
$.each(result, (_j, data) => {
let row;
const isProvisioning = data.provisioning_status === 'in_progress';
const provisioningTooltipAttrs = `title="${I18n.t('experiments.duplicate_tasks.duplicating')}"
data-toggle="tooltip"`;
// Checkbox selector
row = `
`;
// Task columns
$.each(data.columns, (_i, cell) => {
let hidden = '';
if ($(`.table-display-modal .sn-icon-visibility-hide[data-column="${cell.column_type}"]`).length === 1) {
hidden = 'hidden';
}
row += `
${ExperimnetTable.render[cell.column_type](cell.data)}
`;
});
// Menu
row += `
`;
let tableRowClass = `table-row ${isProvisioning ? 'table-row-provisioning' : ''}`;
$(`${row}
`)
.appendTo(`${this.table} .table-body`);
});
},
initDueDatePicker: function(data) {
// eslint-disable-next-line no-unused-vars
$.each(data, (_, row) => {
let element = `#calendarDueDate${row.id}`;
let dueDateContainer = $(element).closest('#dueDateContainer');
let dateText = $(element).closest('.date-text');
let clearDate = $(element).closest('.datetime-container').find('.clear-date');
$(`#calendarDueDateContainer${row.id}`).parent().on('dp:ready', () => {
$(element).data('dateTimePicker').onChange = () => {
$.ajax({
url: dueDateContainer.data('update-url'),
type: 'PATCH',
dataType: 'json',
data: { my_module: { due_date: $(element).val() } },
success: function(result) {
dueDateContainer.find('#dueDateLabelContainer').html(result.table_due_date_label.html);
dateText.data('due-status', result.table_due_date_label.due_status);
if ($(result.table_due_date_label.html).data('due-date')) {
clearDate.removeClass('tw-hidden');
} else {
clearDate.addClass('tw-hidden');
}
}
});
}
clearDate.on('click', () => {
$(element).data('dateTimePicker').clearDate();
});
});
window.initDateTimePickerComponent(`#calendarDueDateContainer${row.id}`);
});
},
initMyModuleActions: function() {
$(this.table).on('show.bs.dropdown', '.my-module-menu', (e) => {
let menu = $(e.target).find('.dropdown-menu');
$.get(e.currentTarget.dataset.url, (result) => {
$(menu).find('li').remove();
$(result.html).appendTo(menu);
});
});
$(this.table).on('click', '.archive-my-module', (e) => {
e.preventDefault();
e.stopPropagation();
this.archiveMyModules(e.currentTarget.href, e.currentTarget.dataset.id);
});
$(this.table).on('click', '.restore-my-module', (e) => {
e.preventDefault();
e.stopPropagation();
this.restoreMyModules(e.currentTarget.href, e.currentTarget.dataset.id);
});
$(this.table).on('click', '.duplicate-my-module', (e) => {
e.preventDefault();
e.stopPropagation();
this.duplicateMyModules(e.currentTarget.href, e.currentTarget.dataset.id);
});
$(this.table).on('click', '.move-my-module', (e) => {
e.preventDefault();
e.stopPropagation();
this.openMoveModulesModal([e.currentTarget.dataset.id]);
});
$(this.table).on('click', '.edit-my-module', (e) => {
e.preventDefault();
$('#modal-edit-module').modal('show');
$('#modal-edit-module').data('id', e.currentTarget.dataset.id);
$('#edit-module-name-input').val($(`#taskName${$('#modal-edit-module').data('id')}`).data('full-name'));
});
},
initDuplicateMyModules: function() {
$(this.tableContainer).on('click', '#duplicateTasks', (e) => {
e.stopPropagation();
this.duplicateMyModules(e.currentTarget.dataset.url, this.selectedMyModules);
});
},
duplicateMyModules: function(url, ids) {
$.post(url, { my_module_ids: ids }, () => {
this.loadTable();
window.navigatorContainer.reloadChildrenLevel = true;
}).fail((data) => {
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
});
},
initArchiveMyModules: function() {
$(this.tableContainer).on('click', '#archiveTask', (e) => {
e.stopPropagation();
this.archiveMyModules(e.currentTarget.dataset.url, this.selectedMyModules);
});
},
archiveMyModules: function(url, ids) {
$.post(url, { my_modules: ids }, (data) => {
HelperModule.flashAlertMsg(data.message, 'success');
this.loadTable();
window.navigatorContainer.reloadChildrenLevel = true;
}).fail((data) => {
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
});
},
initRestoreMyModules: function() {
$(this.tableContainer).on('click', '#restoreTask', (e) => {
e.stopPropagation();
this.restoreMyModules(e.currentTarget.dataset.url, this.selectedMyModules);
});
},
restoreMyModules: function(url, ids) {
$.post(url, { my_modules_ids: ids, view: 'table' });
},
initRenameModal: function() {
$(this.tableContainer).on('click', '#editTask', (e) => {
e.preventDefault();
$('#modal-edit-module').modal('show');
$('#modal-edit-module').data('id', this.selectedMyModules[0]);
$('#edit-module-name-input').val($(`#taskName${$('#modal-edit-module').data('id')}`).data('full-name'));
});
const handleRenameModal = () => {
let id = $('#modal-edit-module').data('id');
let newValue = $('#edit-module-name-input').val();
$(`.my-module-selector[data-my-module="${id}"]`).trigger('click');
if (newValue === $(`#taskName${id}`).data('full-name')) {
$('#modal-edit-module').modal('hide');
return false;
}
$.ajax({
url: this.getUrls(id).name_update,
type: 'PATCH',
dataType: 'json',
data: { my_module: { name: $('#edit-module-name-input').val() } },
success: () => {
$(`#taskName${id}`).text(newValue);
$(`#taskName${id}`).data('full-name', newValue);
$('#edit-module-name-input').closest('.sci-input-container').removeClass('error');
$('#modal-edit-module').modal('hide');
},
error: function(response) {
let error = response.responseJSON.name.join(', ');
$('#edit-module-name-input')
.closest('.sci-input-container')
.addClass('error')
.attr('data-error-text', error);
}
});
if ($(`.my-module-selector[data-my-module="${id}"]`).prop('checked')) {
$(`.my-module-selector[data-my-module="${id}"]`).trigger('click');
}
this.clearRowTaskSelection();
return true;
};
$('#modal-edit-module')
.on('click', 'button[data-action="confirm"]', handleRenameModal)
.on('submit', 'form', (e) => {
e.preventDefault();
handleRenameModal();
});
},
initManageUsersDropdown: function() {
$(this.table).on('show.bs.dropdown', '.assign-users-dropdown', (e) => {
setTimeout(() => {
$('.sci-input-field.user-search').each(function() {
this.focus();
});
}, 200);
let usersList = $(e.target).find('.users-list');
let isArchivedView = $('#experimentTable').hasClass('archived');
let viewOnly = $(e.target).data('view-only');
let checkbox = '';
usersList.find('.user-container').remove();
$.get(usersList.data('list-url'), (result) => {
$.each(result, (_i, user) => {
if (!isArchivedView && !viewOnly) {
checkbox = `
`;
}
$(`
${checkbox}
${user.label}
`).appendTo(usersList);
});
});
});
$(this.table).on('click', '.assign-users-dropdown .dropdown-menu', (e) => {
if (e.target.tagName === 'INPUT') return;
e.preventDefault();
e.stopPropagation();
});
$(this.table).on('keyup', '.assigned-users-container, .open-my-module-menu, .calendar-input', (e) => {
if (e.keyCode === 13) { // Enter
e.currentTarget.click();
}
});
$(this.table).on('change keyup', '.assign-users-dropdown .user-search', (e) => {
let query = e.currentTarget.value;
let usersList = $(e.target).closest('.dropdown-menu').find('.user-container');
$.each(usersList, (_i, user) => {
$(user).removeClass('hidden');
if (query.length && !$(user).find('.user-name').text().toLowerCase()
.includes(query.toLowerCase())) {
$(user).addClass('hidden');
}
});
});
$(this.table).on('change', '.assign-users-dropdown .user-selector', (e) => {
let checkbox = e.target;
if (checkbox.checked) {
$.post(checkbox.dataset.assignUrl, {
table: true,
user_my_module: {
my_module_id: $(checkbox).closest('.table-row').data('id'),
user_id: checkbox.value
}
}, (result) => {
checkbox.dataset.unassignUrl = result.unassign_url;
$(checkbox).closest('.table-row').find('.assigned-users-container')
.replaceWith($(result.html).find('.assigned-users-container'));
}).fail((data) => {
HelperModule.flashAlertMsg(data.responseJSON.errors, 'danger');
});
} else {
$.ajax({
url: checkbox.dataset.unassignUrl,
method: 'DELETE',
data: { table: true },
success: (result) => {
$(checkbox).closest('.table-row').find('.assigned-users-container')
.replaceWith($(result.html).find('.assigned-users-container'));
},
error: (data) => {
HelperModule.flashAlertMsg(data.responseJSON.errors, 'danger');
}
});
}
});
},
initModalInputFocus: function() {
$(document).on('shown.bs.modal', function() {
var inputField = $('#edit-module-name-input');
var value = inputField.val();
inputField.focus().val('').val(value);
});
},
initMoveModulesModal: function() {
$(this.tableContainer).on('click', '#moveTask', (e) => {
e.stopPropagation();
this.openMoveModulesModal(this.selectedMyModules);
});
},
openMoveModulesModal: function(ids) {
let table = $(this.table);
$.get(table.data('move-modules-modal-url'), (modalData) => {
if ($('#modal-move-modules').length > 0) {
$('#modal-move-modules').replaceWith(modalData.html);
} else {
$('#experimentTable').append(modalData.html);
}
$('#modal-move-modules').on('shown.bs.modal', function() {
$(this).find('.selectpicker').selectpicker().focus();
});
$('#modal-move-modules').on('click', 'button[data-action="confirm"]', () => {
let moveParams = {
to_experiment_id: $('#modal-move-modules').find('.selectpicker').val(),
my_module_ids: ids
};
$.post(table.data('move-modules-url'), moveParams, (data) => {
HelperModule.flashAlertMsg(data.message, 'success');
this.loadTable();
window.navigatorContainer.reloadChildrenLevel = true;
}).fail((data) => {
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
});
$('#modal-move-modules').modal('hide');
});
$('#modal-move-modules').modal('show');
});
},
checkActionPermission: function(permission) {
let allMyModules;
allMyModules = this.selectedMyModules.every((id) => {
return $(`.table-row[data-id="${id}"]`).data(permission);
});
return allMyModules;
},
updateSelectAllCheckbox: function() {
const tableWrapper = $(this.table);
const checkboxesCount = $('.sci-checkbox.my-module-selector', tableWrapper).length;
const selectedCheckboxesCount = this.selectedMyModules.length;
const selectAllCheckbox = $('.select-all-checkboxes .sci-checkbox', tableWrapper);
selectAllCheckbox.prop('indeterminate', false);
if (selectedCheckboxesCount === 0) {
selectAllCheckbox.prop('checked', false);
} else if (selectedCheckboxesCount === checkboxesCount) {
selectAllCheckbox.prop('checked', true);
} else {
selectAllCheckbox.prop('indeterminate', true);
}
},
initSelectAllCheckbox: function() {
$(this.table).on('click', '.select-all-checkboxes .sci-checkbox', (e1) => {
$.each($('.my-module-selector'), (_i, e2) => {
if (e1.target.checked !== e2.checked) e2.click();
});
});
},
initSelector: function() {
$(this.table).on('click', '.my-module-selector', (e) => {
let checkbox = e.target;
let myModuleId = checkbox.dataset.myModule;
let index = $.inArray(myModuleId, this.selectedMyModules);
// If checkbox is checked and row ID is not in list of selected project IDs
if (checkbox.checked && index === -1) {
$(checkbox).closest('.table-row').addClass('selected');
this.selectedMyModules.push(myModuleId);
// Otherwise, if checkbox is not checked and ID is in list of selected IDs
} else if (!this.checked && index !== -1) {
$(checkbox).closest('.table-row').removeClass('selected');
this.selectedMyModules.splice(index, 1);
}
this.updateSelectAllCheckbox();
this.updateExperimentToolbar();
});
},
updateExperimentToolbar: function() {
if (window.actionToolbarComponent) {
window.actionToolbarComponent.fetchActions({ my_module_ids: this.selectedMyModules });
}
},
selectDate: function($field) {
var datePicker = $field.data('dateTimePicker');
if (datePicker && datePicker.date) {
return datePicker.date.toString();
}
return null;
},
initManageColumnsModal: function() {
$.each($('.table-display-modal .sn-icon-visibility-hide'), (_i, column) => {
$(column).parent().removeClass('visible');
});
$('.experiment-table')[0].style
.setProperty('--columns-count', $('.table-display-modal .sn-icon-visibility-show:not(.disabled)').length + 1);
$('.table-display-modal').on('click', '.column-container .sn-icon', (e) => {
let icon = $(e.target);
if (icon.hasClass('sn-icon-visibility-show')) {
$(`.experiment-table .${icon.data('column')}-column`).addClass('hidden');
icon.removeClass('sn-icon-visibility-show').addClass('sn-icon-visibility-hide');
icon.parent().removeClass('visible');
} else {
if (icon.hasClass('disabled')) return;
$(`.experiment-table .${icon.data('column')}-column`).removeClass('hidden');
icon.addClass('sn-icon-visibility-show').removeClass('sn-icon-visibility-hide');
icon.parent().addClass('visible');
}
let visibleColumns = $('.table-display-modal .sn-icon-visibility-show').map((_i, col) => col.dataset.column).toArray();
// Update columns on backend - $.post('', { columns: visibleColumns }, () => {});
$.post($('.table-display-modal').data('column-state-url'), { columns: visibleColumns }, () => {});
$('.experiment-table')[0].style
.setProperty('--columns-count', $('.table-display-modal .sn-icon-visibility-show:not(.disabled)').length + 1);
});
},
clearRowTaskSelection: function() {
this.selectedMyModules = [];
this.updateSelectAllCheckbox();
this.updateExperimentToolbar();
},
initNewTaskModal: function(table) {
$('.experiment-new-my_module').on('ajax:success', '#new-my-module-modal', function() {
table.loadTable();
window.navigatorContainer.reloadChildrenLevel = true;
});
},
initSorting: function(table) {
$('#sortMenuDropdown a').click(function() {
if (table.myModulesCurrentSort !== $(this).data('sort')) {
$('#sortMenuDropdown a').removeClass('selected');
// eslint-disable-next-line no-param-reassign
table.myModulesCurrentSort = $(this).data('sort');
table.loadTable();
$(this).addClass('selected');
$('#sortMenu').dropdown('toggle');
}
});
},
getFilterValues: function() {
let $experimentFilter = $('#experimentTable .my-modules-filters');
$.each(this.filters, (_i, filter) => {
this.activeFilters[filter.name] = filter.apply($experimentFilter);
});
// filters are active if they have any non-empty value
let filtersEmpty = Object.values(this.activeFilters).every(value => /^\s+$/.test(value)
|| value === null
|| value === undefined
|| (value && value.length === 0));
this.filtersActive = !filtersEmpty;
},
filtersEnabled: function() {
this.getFilterValues();
return this.filters.some((filter) => {
return filter.active(this.activeFilters[filter.name]);
});
},
initFilters: function() {
let $experimentFilter = $('#experimentTable .my-modules-filters');
this.filterDropdown = filterDropdown.init(() => this.filtersEnabled());
$.each(this.filters, (_i, filter) => {
filter.init($experimentFilter);
});
this.filterDropdown.on('filter:apply', () => {
filterDropdown.toggleFilterMark(this.filterDropdown, this.filtersEnabled());
this.loadTable();
});
this.filterDropdown.on('filter:clickBody', () => {
$.each(this.filters, (_i, filter) => {
filter.closeFilter($experimentFilter);
});
});
this.filterDropdown.on('filter:clear', () => {
$.each(this.filters, (_i, filter) => {
filter.clearFilter($experimentFilter);
});
});
},
loadTable: function() {
var tableParams = {
filters: this.activeFilters,
sort: this.myModulesCurrentSort
};
var dataUrl = $(this.table).data('my-modules-url');
$(this.table).find('.table-row').remove();
this.loadPlaceholder();
$.get(dataUrl, tableParams, (result) => {
$(this.table).find('.table-row-placeholder, .table-row-placeholder-divider').remove();
setTimeout(() => {
this.appendRows(result.data);
this.initDueDatePicker(result.data);
this.handleNoResults();
}, 100);
InfiniteScroll.init(this.table, {
url: dataUrl,
eventTarget: window,
placeholderTemplate: '#experimentTablePlaceholder',
endOfListTemplate: '#experimentTableEndOfList',
pageSize: this.pageSize,
lastPage: !result.next_page,
customResponse: (response) => {
setTimeout(() => {
this.appendRows(response.data);
this.initDueDatePicker(response.data);
this.initProvisioningStatusPolling();
}, 100);
},
customParams: (params) => {
return { ...params, ...tableParams };
}
});
initBSTooltips();
this.clearRowTaskSelection();
this.initProvisioningStatusPolling();
});
},
initProvisioningStatusPolling: function() {
let provisioningStatusUrls = $('.table-row-provisioning').toArray()
.map((u) => $(u).data('urls').provisioning_status)
.filter((u) => !!u);
this.provisioningMyModulesCount = provisioningStatusUrls.length;
if (this.provisioningMyModulesCount > 0) this.pollProvisioningStatuses(provisioningStatusUrls);
},
handleNoResults: function() {
let tableRowLength = document.getElementsByClassName('table-row').length;
let noResultsContainer = document.getElementById('tasksNoResultsContainer');
$('.no-data-container').hide();
if (this.filtersActive && tableRowLength === 0) {
noResultsContainer.style.display = 'block';
} else if (tableRowLength === 0) {
$(this.table).find('.table-header').hide();
$(this.table).addClass('no-data');
$('.no-data-container').show();
} else {
noResultsContainer.style.display = 'none';
$(this.table).find('.table-header').show();
}
},
pollProvisioningStatuses: function(provisioningStatusUrls) {
let remainingUrls = [];
provisioningStatusUrls.forEach((url) => {
jQuery.ajax({
url: url,
success: (data) => {
if (data.provisioning_status === 'in_progress') remainingUrls.push(url);
},
async: false
});
});
if (remainingUrls.length > 0) {
clearTimeout(this.provisioningStatusTimeout);
this.provisioningStatusTimeout = setTimeout(() => {
this.pollProvisioningStatuses(remainingUrls);
}, 10000);
} else {
HelperModule.flashAlertMsg(
I18n.t('experiments.duplicate_tasks.success', { count: this.provisioningMyModulesCount }),
'success'
);
this.loadTable();
}
},
init: function() {
window.initActionToolbar();
this.initSelector();
this.initSelectAllCheckbox();
this.initFilters();
this.initSorting(this);
this.loadTable();
this.initRenameModal();
this.initDuplicateMyModules();
this.initMoveModulesModal();
this.initArchiveMyModules();
this.initManageColumnsModal();
this.initNewTaskModal(this);
this.initMyModuleActions();
this.initRestoreMyModules();
this.initManageUsersDropdown();
this.initModalInputFocus();
}
};
// Filters
ExperimnetTable.filters.push({
name: 'name',
init: () => {},
closeFilter: ($container) => {
$('#textSearchFilterHistory').hide();
$('#textSearchFilterInput', $container).closest('.dropdown').removeClass('open');
},
apply: ($container) => {
return $('#textSearchFilterInput', $container).val();
},
active: (value) => { return value; },
clearFilter: ($container) => {
$('#textSearchFilterInput', $container).val('');
}
});
ExperimnetTable.filters.push({
name: 'due_date_from',
init: () => {},
closeFilter: () => {},
apply: ($container) => {
return ExperimnetTable.selectDate($('.due-date-filter .from-date', $container));
},
active: (value) => { return value; },
clearFilter: ($container) => {
$('.due-date-filter .from-date', $container).data('dateTimePicker')?.clearDate();
}
});
ExperimnetTable.filters.push({
name: 'due_date_to',
init: () => {},
closeFilter: () => {},
apply: ($container) => {
return ExperimnetTable.selectDate($('.due-date-filter .to-date', $container));
},
active: (value) => { return value; },
clearFilter: ($container) => {
$('.due-date-filter .to-date', $container).data('dateTimePicker')?.clearDate();
}
});
ExperimnetTable.filters.push({
name: 'archived_on_from',
init: () => {},
closeFilter: () => {},
apply: ($container) => {
return ExperimnetTable.selectDate($('.archived-on-filter .from-date', $container));
},
active: (value) => { return value; },
clearFilter: ($container) => {
$('.archived-on-filter .from-date', $container).data('dateTimePicker')?.clearDate();
}
});
ExperimnetTable.filters.push({
name: 'archived_on_to',
init: () => {},
closeFilter: () => {},
apply: ($container) => {
return ExperimnetTable.selectDate($('.archived-on-filter .to-date', $container));
},
active: (value) => { return value; },
clearFilter: ($container) => {
$('.archived-on-filter .to-date', $container).data('dateTimePicker')?.clearDate();
}
});
ExperimnetTable.filters.push({
name: 'assigned_users',
init: ($container) => {
dropdownSelector.init($('.assigned-filter', $container), {
optionClass: 'checkbox-icon users-dropdown-list',
optionLabel: (data) => {
return ` ${data.label}`;
},
tagLabel: (data) => {
return ` ${data.label}`;
},
labelHTML: true,
tagClass: 'users-dropdown-list'
});
},
closeFilter: ($container) => {
dropdownSelector.closeDropdown($('.assigned-filter', $container));
},
apply: ($container) => {
return dropdownSelector.getValues($('.assigned-filter', $container));
},
active: (value) => { return value && value.length !== 0; },
clearFilter: ($container) => {
dropdownSelector.clearData($('.assigned-filter', $container));
}
});
ExperimnetTable.filters.push({
name: 'statuses',
init: ($container) => {
dropdownSelector.init($('.status-filter', $container), {
singleSelect: true,
closeOnSelect: true,
selectAppearance: 'simple'
});
},
closeFilter: ($container) => {
dropdownSelector.closeDropdown($('.status-filter', $container));
},
apply: ($container) => {
return dropdownSelector.getValues($('.status-filter', $container));
},
active: (value) => { return value && value.length !== 0; },
clearFilter: ($container) => {
dropdownSelector.clearData($('.status-filter', $container));
}
});
if (notTurbolinksPreview()) {
ExperimnetTable.init();
}