Compare commits

..

No commits in common. "5a583a94ffe5ab001fba4a5ca70e378676d14926" and "a0ebf89ef853ca57f479a2a2e254f2171f4d2545" have entirely different histories.

7 changed files with 1185 additions and 1388 deletions

View File

@ -16,34 +16,3 @@ Funktionen:
- Erklärung MP3
- Quittierung MP3
- Verabschiedung MP3
## API Endpoint planning
alertContacts (CRUD Fully implemented)
alerts -> Only get
actionPlan (CRUD)
- select all prios
priorities (CRUD)
- select actionPlan
- Only allow changes to priority
content (CRUD)
- Howto handle upload?
POST /alert/[:alert_hook]
-> Check actionplan if hook exists and select current prios -> Write call request to XYXYX
1. create one or more alertContacts
2. create 4x content (all phases)
3. create actionplan with contents
4. create one or more priorities

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
//// THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
//// ------------------------------------------------------
Project "ATAS" {
Project "AssetFlow" {
database_type: ''
Note: ''
}
@ -10,11 +10,11 @@ Project "ATAS" {
Table alerts {
id Int [pk, increment]
type alertType [not null]
state alertState [not null]
description String
date DateTime [not null]
message String
actionplan actionPlan
actionplanId Int
date DateTime [not null]
state alertState [not null]
acknowledged_by alertContacts [not null]
acknowledged_at DateTime
}
@ -30,9 +30,9 @@ Table alertContacts {
Table actionPlan {
id Int [pk, increment]
name String [unique, not null]
name String [not null]
comment String
alerthook String [unique, not null]
alert_hook String [unique, not null]
prio priorities [not null]
content content [not null]
alerts alerts [not null]
@ -85,7 +85,7 @@ Enum alertType {
}
Enum alertState {
incoming
incomming
running
failed
acknowledged

View File

@ -26,7 +26,7 @@ generator dbml {
provider = "prisma-dbml-generator"
output = "../docs"
outputName = "schema.dbml"
projectName = "ATAS"
projectName = "AssetFlow"
}
@ -46,7 +46,7 @@ enum alertType {
}
enum alertState {
incoming // Incoming alerts
incomming // Incomming alerts
running // Started calling
failed // Failed to get acknowledgement of any alertContacts
acknowledged // Some user acknowledged alert
@ -55,20 +55,17 @@ enum alertState {
model alerts {
id Int @id @unique @default(autoincrement())
type alertType
state alertState
description String?
date DateTime
message String?
actionplan actionPlan? @relation(fields: [actionplanId], references: [id])
actionplanId Int?
date DateTime
state alertState
acknowledged_by alertContacts[]
acknowledged_at DateTime?
@@fulltext([description])
@@fulltext([message])
}
model alertContacts {
id Int @id @unique @default(autoincrement())
name String
@ -76,20 +73,17 @@ model alertContacts {
comment String?
prios priorities[]
alerts alerts[]
@@fulltext([name, phone, comment])
}
model actionPlan {
id Int @id @unique @default(autoincrement())
name String @unique
name String
comment String?
alerthook String @unique
alert_hook String @unique
prio priorities[]
content content[] // aka. all voice files
alerts alerts[]
@@fulltext([name, comment])
}
@ -110,10 +104,12 @@ model content {
name String
filename String
actionplan actionPlan[]
@@fulltext([name, filename])
}
// https://spacecdn.de/file/bma_stoe_v1.mp3
// https://spacecdn.de/file/quittiert_v1.mp3
// https://spacecdn.de/file/angenehmen_tag_v1.mp3

View File

@ -59,61 +59,8 @@ let _api = {
}
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}`;

View File

@ -39,9 +39,6 @@ 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 () {
@ -219,17 +216,9 @@ modalForms.forEach((modalForm) => {
jsonData[key] = value;
});
console.log('JSON Data: ', 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);
}
let resp = await createEntry(table, jsonData);
console.log('Response: ', resp);
if (resp['status'] == 'CREATED' || resp['status'] == 'UPDATED') {
if (resp['status'] == 'CREATED') {
console.log('Entry created successfully');
modalForm.closest('.modal').classList.remove('is-active');
modalForm.reset();
@ -369,18 +358,10 @@ 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'];
@ -476,100 +457,6 @@ 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 = '<i class="bi bi-pencil"></i>';
break;
}
case 'delete': {
icon = '<i class="bi bi-trash"></i>';
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 = ` <span class="icon is-small">${icon}</span> `;
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);
}
}

View File

@ -43,9 +43,8 @@
<i class="bi bi-arrow-clockwise title"></i>
</div>
<div class="box entryPhase">
<form data-targetTable="AlertContacts">
<h2 class="title">New Contact</h1>
<form data-targetTable="AlertContacts">
<div class="field">
<label class="label">Name</label>
<div class="control has-icons-left">
@ -109,7 +108,6 @@
<th data-dataCol = "name">Name</th>
<th data-dataCol = "phone">Telefon Nummer</th>
<th data-dataCol = "comment">Kommentar</th>
<th data-fnc="actions" data-actions="edit,delete">Aktionen</th>
</tr>
</thead>
<tbody>