Refactor web server and release workflow
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
(function () {
|
||||
function getTableHeaderText(headerCell) {
|
||||
return String(headerCell && headerCell.textContent ? headerCell.textContent : '').trim().toLowerCase();
|
||||
}
|
||||
|
||||
function cellHasButtonContent(cell) {
|
||||
return Boolean(cell && cell.querySelector && cell.querySelector('button, form, input, select, textarea'));
|
||||
}
|
||||
|
||||
function getCellSortValue(cell) {
|
||||
if (!cell) {
|
||||
return '';
|
||||
}
|
||||
var sortValue = cell.getAttribute && cell.getAttribute('data-sort-value');
|
||||
if (sortValue !== null && sortValue !== undefined && sortValue !== '') {
|
||||
return String(sortValue).trim();
|
||||
}
|
||||
return String(cell.textContent || '').replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
function getComparableSortValue(rawValue) {
|
||||
var value = String(rawValue || '').trim();
|
||||
if (!value) {
|
||||
return { type: 'empty', value: '' };
|
||||
}
|
||||
|
||||
var numericValue = Number(value.replace(/,/g, ''));
|
||||
if (!Number.isNaN(numericValue) && value !== '') {
|
||||
return { type: 'number', value: numericValue };
|
||||
}
|
||||
|
||||
var dateValue = Date.parse(value);
|
||||
if (!Number.isNaN(dateValue)) {
|
||||
return { type: 'date', value: dateValue };
|
||||
}
|
||||
|
||||
return { type: 'string', value: value.toLowerCase() };
|
||||
}
|
||||
|
||||
function compareSortValues(leftValue, rightValue) {
|
||||
if (leftValue.type === 'empty' && rightValue.type === 'empty') {
|
||||
return 0;
|
||||
}
|
||||
if (leftValue.type === 'empty') {
|
||||
return 1;
|
||||
}
|
||||
if (rightValue.type === 'empty') {
|
||||
return -1;
|
||||
}
|
||||
if (leftValue.type === rightValue.type) {
|
||||
if (leftValue.value < rightValue.value) {
|
||||
return -1;
|
||||
}
|
||||
if (leftValue.value > rightValue.value) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return String(leftValue.value).localeCompare(String(rightValue.value), undefined, { numeric: true, sensitivity: 'base' });
|
||||
}
|
||||
|
||||
function getSortableTableState(table) {
|
||||
if (!table._sortableState) {
|
||||
table._sortableState = {
|
||||
columnIndex: null,
|
||||
direction: 'asc'
|
||||
};
|
||||
}
|
||||
return table._sortableState;
|
||||
}
|
||||
|
||||
function isSortableTableColumn(table, columnIndex) {
|
||||
var headerCell = table.tHead && table.tHead.rows && table.tHead.rows.length ? table.tHead.rows[0].cells[columnIndex] : null;
|
||||
if (!headerCell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (/actions?|buttons?/i.test(getTableHeaderText(headerCell))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var bodies = table.tBodies ? Array.prototype.slice.call(table.tBodies) : [];
|
||||
for (var i = 0; i < bodies.length; i += 1) {
|
||||
var rows = Array.prototype.slice.call(bodies[i].rows || []);
|
||||
for (var j = 0; j < rows.length; j += 1) {
|
||||
var cell = rows[j].cells ? rows[j].cells[columnIndex] : null;
|
||||
if (cell && cellHasButtonContent(cell)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateSortableHeaderState(table) {
|
||||
var state = getSortableTableState(table);
|
||||
var headerCells = table.tHead && table.tHead.rows && table.tHead.rows.length ? Array.prototype.slice.call(table.tHead.rows[0].cells || []) : [];
|
||||
headerCells.forEach(function (headerCell, index) {
|
||||
if (!headerCell) {
|
||||
return;
|
||||
}
|
||||
headerCell.classList.remove('sort-asc', 'sort-desc', 'sortable', 'unsortable');
|
||||
headerCell.removeAttribute('aria-sort');
|
||||
headerCell.removeAttribute('role');
|
||||
headerCell.removeAttribute('tabindex');
|
||||
|
||||
if (isSortableTableColumn(table, index)) {
|
||||
headerCell.classList.add('sortable');
|
||||
headerCell.setAttribute('role', 'button');
|
||||
headerCell.setAttribute('tabindex', '0');
|
||||
if (state.columnIndex === index) {
|
||||
headerCell.classList.add(state.direction === 'desc' ? 'sort-desc' : 'sort-asc');
|
||||
headerCell.setAttribute('aria-sort', state.direction === 'desc' ? 'descending' : 'ascending');
|
||||
} else {
|
||||
headerCell.setAttribute('aria-sort', 'none');
|
||||
}
|
||||
} else {
|
||||
headerCell.classList.add('unsortable');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sortTable(table, columnIndex, direction) {
|
||||
var tbody = table.tBodies && table.tBodies[0] ? table.tBodies[0] : null;
|
||||
if (!tbody) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rows = Array.prototype.slice.call(tbody.rows || []);
|
||||
if (!rows.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var multiplier = direction === 'desc' ? -1 : 1;
|
||||
rows.sort(function (leftRow, rightRow) {
|
||||
var leftCell = leftRow.cells ? leftRow.cells[columnIndex] : null;
|
||||
var rightCell = rightRow.cells ? rightRow.cells[columnIndex] : null;
|
||||
var leftComparable = getComparableSortValue(getCellSortValue(leftCell));
|
||||
var rightComparable = getComparableSortValue(getCellSortValue(rightCell));
|
||||
return compareSortValues(leftComparable, rightComparable) * multiplier;
|
||||
});
|
||||
|
||||
rows.forEach(function (row) {
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
function applyTableSort(table) {
|
||||
var state = getSortableTableState(table);
|
||||
if (state.columnIndex === null || state.columnIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
sortTable(table, state.columnIndex, state.direction);
|
||||
updateSortableHeaderState(table);
|
||||
}
|
||||
|
||||
function initSortableTables() {
|
||||
var tables = Array.prototype.slice.call(document.querySelectorAll('table'));
|
||||
tables.forEach(function (table) {
|
||||
var headerRow = table.tHead && table.tHead.rows && table.tHead.rows.length ? table.tHead.rows[0] : null;
|
||||
if (!headerRow) {
|
||||
return;
|
||||
}
|
||||
|
||||
Array.prototype.forEach.call(headerRow.cells, function (headerCell, index) {
|
||||
if (!isSortableTableColumn(table, index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
headerCell.addEventListener('click', function () {
|
||||
var state = getSortableTableState(table);
|
||||
var nextDirection = state.columnIndex === index && state.direction === 'asc' ? 'desc' : 'asc';
|
||||
state.columnIndex = index;
|
||||
state.direction = nextDirection;
|
||||
sortTable(table, index, nextDirection);
|
||||
updateSortableHeaderState(table);
|
||||
});
|
||||
|
||||
headerCell.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
headerCell.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
updateSortableHeaderState(table);
|
||||
});
|
||||
}
|
||||
|
||||
window.applyTableSort = applyTableSort;
|
||||
window.initSortableTables = initSortableTables;
|
||||
}());
|
||||
Reference in New Issue
Block a user