diff --git a/static/apiWrapper.js b/static/apiWrapper.js index 713ac87..22b1c0b 100644 --- a/static/apiWrapper.js +++ b/static/apiWrapper.js @@ -58,10 +58,63 @@ let _api = { return; } + return result; + }, + delete: async function (path, data) { + const options = { + method: 'DELETE', + headers: new Headers({ 'content-type': 'application/json' }), + body: JSON.stringify(data) + }; + const response = await fetch(_apiConfig.basePath + path, options); + // Handle the response + if (!response.ok) { + _testPageFail(response.statusText); + return; + } + const result = await response.json(); + // Handle the result, was json valid? + if (!result) { + _testPageFail('Invalid JSON response'); + return; + } + + return result; + }, + patch: async function (path, data) { + const options = { + method: 'PATCH', + headers: new Headers({ 'content-type': 'application/json' }), + body: JSON.stringify(data) + }; + const response = await fetch(_apiConfig.basePath + path, options); + // Handle the response + if (!response.ok) { + _testPageFail(response.statusText); + return; + } + const result = await response.json(); + // Handle the result, was json valid? + if (!result) { + _testPageFail('Invalid JSON response'); + return; + } + return result; } + }; +function updateRow(tableName, id, data) { + invalidateCache(tableName); + return _api.patch(`${tableName}`, { id: id, ...data }); +} + +function deleteRow(tableName, id) { + invalidateCache(tableName); + return _api.delete(`${tableName}`, { id: id }); +} + function getApiDescriptionByTable(tableName) { const keyDesc = `desc:${tableName}`; const keyTime = `${keyDesc}:time`; diff --git a/static/pageDriver.js b/static/pageDriver.js index 7618922..557f939 100644 --- a/static/pageDriver.js +++ b/static/pageDriver.js @@ -39,6 +39,9 @@ tables.forEach(async (table) => { // Get THs and attach onClick event to sort const ths = table.querySelectorAll('th'); ths.forEach((th) => { + if(th.getAttribute('fnc') == "actions") { + return; + } th.style.cursor = 'pointer'; th.style.userSelect = 'none'; th.addEventListener('click', async function () { @@ -216,9 +219,17 @@ modalForms.forEach((modalForm) => { jsonData[key] = value; }); console.log('JSON Data: ', jsonData); - let resp = await createEntry(table, jsonData); + let resp = {}; + if(modalForm.getAttribute('data-action') == 'edit') { + Rid = modalForm.getAttribute('data-rid'); + resp = await updateRow(table, Rid,jsonData); + modalForm.setAttribute('data-action', 'create'); + } else { + resp = await createEntry(table, jsonData); + } + console.log('Response: ', resp); - if (resp['status'] == 'CREATED') { + if (resp['status'] == 'CREATED' || resp['status'] == 'UPDATED') { console.log('Entry created successfully'); modalForm.closest('.modal').classList.remove('is-active'); modalForm.reset(); @@ -358,10 +369,18 @@ function writeDataToTable(table, data, paginationPassOn) { // All required cols let requiredCols = []; + let actionFields = []; columns.forEach((column) => { + // console.log('Column: ', column, ' FNC: ', column.getAttribute('data-fnc'), column.attributes); + if(column.getAttribute('data-fnc') == "actions") { + console.log('!!! Found actions column !!!'); + actionFields.push(column); + return; + } requiredCols.push(column.getAttribute('data-dataCol')); }); + // Get paginationPassOn const start = paginationPassOn['start']; const end = paginationPassOn['end']; @@ -457,6 +476,100 @@ function writeDataToTable(table, data, paginationPassOn) { td.innerText = row[column]; tr.appendChild(td); }); + + // Add action fields + actionFields.forEach((actionField) => { + const td = document.createElement('td'); + const actions = actionField.getAttribute('data-actions').split(','); + actions.forEach((action) => { + const button = document.createElement('button'); + let icon = ''; + let color = 'is-primary'; + switch(action) { + case 'edit': { + icon = ''; + break; + } + case 'delete': { + icon = ''; + color = 'is-danger'; + break; + } + } + // Add classes + button.classList.add('button'); + button.classList.add('is-small'); + button.classList.add(color); + button.classList.add('is-outlined'); + button.innerHTML = ` ${icon} `; + button.style.marginRight = '5px'; + + // Add data-action and data-id + button.setAttribute('data-action', action); + button.setAttribute("data-id", row["id"]); + + // Add event listener + button.addEventListener('click', async function() { + const table = actionField.closest('table'); + const row = button.closest('tr'); + const columns = table.querySelectorAll('th'); + const columnIndices = []; + columns.forEach((column, index) => { + columnIndices[column.getAttribute('data-dataCol')] = index; + }); + const data = []; + columns.forEach((column) => { + data[column.getAttribute('data-dataCol')] = row.children[columnIndices[column.getAttribute('data-dataCol')]].innerText; + }); + console.log('Data: ', data); + switch(action) { + case 'edit': { + // Open modal with form + const form = document.querySelector("form[data-targetTable='" + table.getAttribute('data-dataSource') + "']"); + const formTitle = form.querySelector('.title'); + const entryPhase = form.querySelector('.entryPhase'); + const loadPhase = form.querySelector('.loadPhase'); + const fields = form.querySelectorAll('input'); + // Set modal to edit mode + form.setAttribute('data-action', 'edit'); + form.setAttribute('data-rid', button.getAttribute('data-id')); + formTitle.innerText = 'Edit entry'; + fields.forEach((field) => { + // Skip for submit button + if(field.getAttribute('type') == 'submit') { + return; + } + field.value = data[field.getAttribute('name')]; + }); + form.closest('.modal').classList.add('is-active'); + // TBD + break; + } + case 'delete': { + // confirm + const confirm = window.confirm('Do you really want to delete this entry?'); + // Delete entry + if(confirm) { + const table = actionField.closest('table'); + const id = button.getAttribute('data-id'); + const resp = await deleteRow(table.getAttribute('data-dataSource'), id); + if(resp['status'] == 'DELETED') { + refreshTable(table); + updateSingeltonsByTableName(table.getAttribute('data-dataSource')); + } else { + // Show error message + // TODO: Show error message + } + } + break; + } + } + } + ); + td.appendChild(button); + }); + tr.appendChild(td); + }); tbody.appendChild(tr); } } diff --git a/views/test.eta b/views/test.eta index fb4e2e5..1d91583 100644 --- a/views/test.eta +++ b/views/test.eta @@ -43,8 +43,9 @@