diff --git a/assets/functions.js b/assets/functions.js index aea5dee..9400fa6 100644 --- a/assets/functions.js +++ b/assets/functions.js @@ -4,14 +4,12 @@ let currentItem; if (addr.includes("/docs")) { currentItem = document.querySelector("#textmenu a[href^='/docs']"); - if (currentItem) currentItem.classList.add("chosenmenu"); } else if (addr.includes("/team")) { currentItem = document.querySelector("#textmenu a[href^='/team']"); - if (currentItem) currentItem.classList.add("chosenmenu"); } else if (addr.includes("/task")) { currentItem = document.querySelector("#textmenu a[href^='/task']"); - if (currentItem) currentItem.classList.add("chosenmenu"); } + if (currentItem) currentItem.classList.add("chosenmenu"); })(); /* Translates the page - aka i18n */ @@ -59,7 +57,8 @@ function translateAll(rootElem, lang) { if (c0 == '+' && s.charAt(0) != '+') s = '+ ' + s; if (c0 == '×' && s.charAt(0) != '×') s = '× ' + s; if (c1 == ':' && c2 != '*' && s.charAt(s.length - 1) != ':') {s += ':'; - } else if (c1 == ':' && c2 == '*' && s.charAt(s.length - 2) != '*') {s += '*:';} + } else if (c1 == ':' && c2 == '*' && s.charAt(s.length - 2) != '*') {s += '*:'; + } else if (c1 == ' ' && c2 == ':') {s += ': ';} return s; } @@ -301,31 +300,48 @@ function processTableSelection(removeAllowed) { const checkhead = document.getElementById('chead'); const checkboxes = document.querySelectorAll('input[class="chbox"]'); const styleRoot = getComputedStyle(document.body); + const tableEvenRowBkgColor = styleRoot.getPropertyValue('--defaultBackgroundColor'); const tableOddRowBkgColor = styleRoot.getPropertyValue('--tableOddRowBkgColor'); const tableSelectionColor = styleRoot.getPropertyValue('--tableSelectionColor'); const cbListLength = checkboxes.length; const deleteButton = document.getElementById('deleteButton'); const statusButtons = document.querySelectorAll('input[class="sbut statusMultiControl"]'); + + document.getElementById("mainTable").addEventListener("click", function (event) { + if (event.target.classList.contains('grideven') || event.target.classList.contains('gridodd')) { + let id = (+event.target.classList[0].split('-')[1]); + let cb = document.getElementById(id); + cb.checked = !cb.checked; + checkOne(cb.checked, '.' + cb.parentNode.classList[0]); + } + }); for (let i = 0; i < cbListLength; i++) { let cb = checkboxes[i]; cb.onclick = function() { - let state = cb.checked; - let currentRow = this.parentNode.parentNode; - if (state) { - currentRow.style.backgroundColor = tableSelectionColor; - if (removeAllowed) deleteButton.disabled = false; - if (statusButtons) statusButtons.forEach(btn => btn.disabled = false); + checkOne(this.checked, '.' + this.parentNode.classList[0]); + }; + } + + function checkOne(state, currentRowClass) { + if (state) { + changeRowBkgColor(currentRowClass, true); + if (removeAllowed) deleteButton.disabled = false; + if (statusButtons) statusButtons.forEach(btn => btn.disabled = false); + } else { + processAllCBDisabledCheckup(); + changeRowBkgColor(currentRowClass, false); + } + } + + function changeRowBkgColor(classSelector, select){ + document.querySelectorAll(classSelector).forEach((elem) => { + if (select) { + elem.style.backgroundColor = tableSelectionColor; } else { - processAllCBDisabledCheckup(); - currentRow.style.backgroundColor = "inherit"; - if (currentRow.rowIndex % 2 == 0) { - currentRow.style.backgroundColor = "inherit"; - } else { - currentRow.style.backgroundColor = tableOddRowBkgColor; - } + elem.style.backgroundColor = (elem.classList.contains('gridodd')) ? tableOddRowBkgColor : tableEvenRowBkgColor; } - } + }); } function processAllCBDisabledCheckup() { @@ -340,42 +356,27 @@ function processTableSelection(removeAllowed) { } checkhead.onclick = function() { - let chstate = checkhead.checked; - if (chstate) { - checkAll(); - if (removeAllowed) deleteButton.disabled = false; - if (statusButtons) statusButtons.forEach(btn => btn.disabled = false); + if (checkhead.checked) { + checkAll(true); } else { - uncheckAll(); - if (removeAllowed) deleteButton.disabled = true; - if (statusButtons) statusButtons.forEach(btn => btn.disabled = true); + checkAll(false); } } - function checkAll() { - checkboxes.forEach(function(cb) { - cb.checked = true; - let currentRow = cb.parentNode.parentNode; - currentRow.style.backgroundColor = tableSelectionColor; - }); - } - - function uncheckAll() { + function checkAll(select) { + if (removeAllowed) deleteButton.disabled = !select; + if (statusButtons) statusButtons.forEach(btn => btn.disabled = !select); checkboxes.forEach(function(cb) { - cb.checked = false; - let currentRow = cb.parentNode.parentNode; - if (currentRow.rowIndex % 2 == 0) { - currentRow.style.backgroundColor = "inherit"; - } else { - currentRow.style.backgroundColor = tableOddRowBkgColor; - } + cb.checked = select; + let currentRowClass = '.' + cb.parentNode.classList[0]; + changeRowBkgColor(currentRowClass, select); }); } } /* Hides control buttons and disables checkboxes */ -function disableControlButtons() { +function disableControlButtons(mainTablePresent) { document.getElementById('controlButtons').style.display = 'none'; if (mainTablePresent) { const checkhead = document.getElementById('chead'); @@ -581,33 +582,38 @@ function applyTextFilter(searchPhrase) { } /* Iterate over table data cells to insert a highlight tag */ -function highlightSearchResults(textFilter, columns) { +function highlightSearchResults(textFilter) { textFilter = textFilter.toLowerCase().replace('<', '<').replace('>', '>'); - let tds; - const tb = document.getElementById('mainTable'); - if (tb) { - tds = tb.getElementsByTagName('td'); + let elems; + const content = document.getElementById('mainTable'); + if (content) { + elems = content.getElementsByClassName('textsearch'); } - if (textFilter && tds) { - for (let td of tds) { - if (columns.indexOf(td.cellIndex) !== -1) { - td.innerHTML = insertCaseInsensitive(td.innerHTML.replace('&', '&'), textFilter, '', ''); - let subElems = td.children; - for (let i = 0; i < subElems.length; i++) { - subElems[i].classList.add('clampbig'); - } - } + if (textFilter && elems) { + for (let elem of elems) { + recursiveChildrenSearch(elem, textFilter); } } } +function recursiveChildrenSearch(elem, textFilter) { + if (elem.children && elem.children.length > 0) { + for (subelem of elem.children) { + recursiveChildrenSearch(subelem, textFilter); + } + } else { + if (elem.classList && elem.classList.contains('mobile')) return; + elem.innerHTML = insertCaseInsensitive(elem.innerHTML.replace('&', '&'), textFilter, '', ''); + } +} + /* Insert a highlight tag */ function insertCaseInsensitive(srcStr, lowerCaseFilter, before, after) { let lowStr = srcStr.toLowerCase(); let flen = lowerCaseFilter.length; let i = -1; while ((i = lowStr.indexOf(lowerCaseFilter, i + 1)) != -1) { - if (insideTag(i, srcStr)) continue; + //if (insideTag(i, srcStr)) continue; srcStr = srcStr.slice(0, i) + before + srcStr.slice(i, i+flen) + after + srcStr.slice(i+flen); lowStr = srcStr.toLowerCase(); i += before.length + after.length; @@ -694,8 +700,9 @@ function addSeekPagination(formID, filteredNum){ addHiddenElem(frm, 'filteredNum', filteredNum); addHiddenElem(frm, 'previousPage', pageNumber); const mainTable = document.getElementById('mainTable'); - addHiddenElem(frm, 'firstElemOnPage', mainTable.rows[1].cells[1].innerText); - addHiddenElem(frm, 'lastElemOnPage', mainTable.rows[mainTable.rows.length-1].cells[1].innerText); + //console.log(mainTable.getElementsByClassName('firstcell')[0].lastElementChild.innerText, mainTable.getElementsByClassName('firstcell')[mainTable.getElementsByClassName('firstcell').length-1].lastElementChild.innerText); + addHiddenElem(frm, 'firstElemOnPage', mainTable.getElementsByClassName('firstcell')[0].lastElementChild.innerText); + addHiddenElem(frm, 'lastElemOnPage', mainTable.getElementsByClassName('firstcell')[mainTable.getElementsByClassName('firstcell').length-1].lastElementChild.innerText); } function processAddingFilters(frm, filters) { @@ -833,7 +840,7 @@ function printAppliedFilters(classFilterArr, dateFilterArr, sumFilterArr, textFi if (langCode != 'en') { timeout = 20; getLang(langCode).then(lang => { - if (lang.appliedFilters) appliedFilters = lang.appliedFilters; + if (lang.appliedFilters) appliedFilters = lang.appliedFilters + ": "; if (lang.noFiltersApplied) noFiltersApplied = lang.noFiltersApplied; if (lang.diapason) diapason = lang.diapason; runAllowed = true; @@ -975,7 +982,7 @@ function processPagesCalculations(elemsOnPage, filteredNum) { } function getElemsOnCurrentPage() { - return document.getElementById('mainTable').getElementsByTagName('tr').length - 1; + return document.getElementById('mainTable').getElementsByClassName('firstcell').length; } /* Text formatting in multiline elements */ diff --git a/assets/i18n/en.json b/assets/i18n/en.json index a3abf39..557cee0 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -79,7 +79,7 @@ "totalElemsFound": "Total objects by search criteria", "onThisPage": "On this page", "totalPages": "Total pages", - "appliedFilters": "Applied filters: ", + "appliedFilters": "Applied filters", "noFiltersApplied": "No filters applied.", "seeAlso": "See also:", @@ -229,8 +229,8 @@ "category": "Category", "docAbout": "About", "docSum": "Sum", - "currencyLabel": "currency: ", - "sumLabel": "sum: ", + "currencyLabel": "currency", + "sumLabel": "sum", "authors": "Authors", "addressees": "Addressees", "note": "Note", @@ -255,7 +255,7 @@ "myApprovals": "My approvals", "approvalBreak": "This will break any approval if present!", "approvalSign": [ - "For approval", + "Pending", "Approved", "Rejected", "Broken" diff --git a/assets/i18n/es.json b/assets/i18n/es.json index 2ba036f..300ab34 100644 --- a/assets/i18n/es.json +++ b/assets/i18n/es.json @@ -79,7 +79,7 @@ "totalElemsFound": "Total de objetos por criterio de búsqueda", "onThisPage": "En esta página", "totalPages": "Total de páginas", - "appliedFilters": "Filtros aplicados: ", + "appliedFilters": "Filtros aplicados", "noFiltersApplied": "No se aplicaron filtros.", "seeAlso": "Ver también:", @@ -229,8 +229,8 @@ "category": "Categoría", "docAbout": "Acerca de", "docSum": "Suma", - "currencyLabel": "moneda: ", - "sumLabel": "suma: ", + "currencyLabel": "moneda", + "sumLabel": "suma", "authors": "Autores", "addressees": "Destinatarios", "note": "Nota", @@ -255,7 +255,7 @@ "myApprovals": "Mis aprobaciones", "approvalBreak": "¡Esto romperá cualquier aprobación si está presente!", "approvalSign": [ - "Para aprobación", + "Bajo aprobación", "Aprobado", "Rechazado", "Roto" diff --git a/assets/i18n/fr.json b/assets/i18n/fr.json index f402369..81541a8 100644 --- a/assets/i18n/fr.json +++ b/assets/i18n/fr.json @@ -79,7 +79,7 @@ "totalElemsFound": "Total des objets par critère de recherche", "onThisPage": "Sur cette page", "totalPages": "Pages totales", - "appliedFilters": "Filtres appliqués: ", + "appliedFilters": "Filtres appliqués", "noFiltersApplied": "Aucun filtre appliqué.", "seeAlso": "Voir également:", @@ -229,8 +229,8 @@ "category": "Catégorie", "docAbout": "À propos", "docSum": "Somme", - "currencyLabel": "devise: ", - "sumLabel": "somme: ", + "currencyLabel": "devise", + "sumLabel": "somme", "authors": "Auteurs", "addressees": "Destinataires", "note": "Remarque", @@ -255,7 +255,7 @@ "myApprovals": "Mes approbations", "approvalBreak": "Cela cassera toute approbation si elle est présente!", "approvalSign": [ - "Pour approbation", + "En cours", "Approuvé", "Rejeté", "Cassé" diff --git a/assets/i18n/ru.json b/assets/i18n/ru.json index f981c73..6de644f 100644 --- a/assets/i18n/ru.json +++ b/assets/i18n/ru.json @@ -79,7 +79,7 @@ "totalElemsFound": "Всего объектов по критериям поиска", "onThisPage": "На этой странице", "totalPages": "Всего страниц", - "appliedFilters": "Примененные фильтры: ", + "appliedFilters": "Примененные фильтры", "noFiltersApplied": "Фильтры не применены.", "seeAlso": "См. также:", @@ -229,8 +229,8 @@ "category": "Категория", "docAbout": "О чем", "docSum": "Сумма", - "currencyLabel": "валюта: ", - "sumLabel": "сумма: ", + "currencyLabel": "валюта", + "sumLabel": "сумма", "authors": "Авторы", "addressees": "Адресаты", "note": "Примечание", @@ -255,7 +255,7 @@ "myApprovals": "Мои согласования", "approvalBreak": "Это действие сбросит все согласования если они имеются!", "approvalSign": [ - "На согласование", + "Ожидается", "Согласовано", "Отклонено", "Сброшено" diff --git a/assets/manual-admin.html b/assets/manual-admin.html index d0c017c..8eb2d02 100644 --- a/assets/manual-admin.html +++ b/assets/manual-admin.html @@ -4,6 +4,7 @@
Please, read user documentation before this administrator documentation in order to understand some basic concepts.
The software should be installed on a server machine and configured to use a database management system selected by you.
This software utilizes Go programming language, sqla module and drivers for each database type to directly connect to a database server.
Probably all platforms where Go programming language is available are supported (Linux, Mac, Windows, etc.).
-The software should be installed on a server machine and configured to use a database management system selected by you.
The following RDBMS are supported:
--filldb
- fill database with showcase data. Useful only for presentation and testing.
--nobrowser
- the server should not run a browser on launch.
--consolelog
- print messages to console instead of a log file.
The program can display a responce in JSON format. It is applicable for almost any page. This might be useful for connecting this server to other services.
+To load a page as JSON use the following key and value in GET or POST request: api=json
.
The simplest way to build the software is to run go build
command, and then you can run ./edm
(edm.exe
for windows) app in the current directory.
To add a new language you need to create those two JSON files with the same structure as existing files. Language codes list is defined in main()
function of the program. You need to add language code to the list, and rebuild the application. You also need to edit config.tmpl file to add a language name there.