implementovane zobrazenie archivu,

TODO: dorobit load dalsich stran,
zmena FullScreenLoader namiesto zatmavenia na rozmazanie,
pridana podmienka na editable pre zobrazenie BUG, pouzitelne ked sa otvara archivovany bug
This commit is contained in:
Igor Miňo 2025-05-17 21:21:42 +02:00
parent 506e847b5d
commit e6f3ef4ab2
7 changed files with 157 additions and 20 deletions

13
api.php
View File

@ -32,7 +32,10 @@ switch ($action) {
$result = reportGetAll($_REQUEST['status']); $result = reportGetAll($_REQUEST['status']);
break; break;
case 'getAllGrouped': case 'getAllGrouped':
$result = reportGetAllGrouped($_REQUEST['status']); $result = reportGetAllGrouped(json_decode($_REQUEST['status'], true), $_REQUEST['page'] == 'null' ? null : $_REQUEST['page']);
break;
case 'getArchived':
$result = reportGetArchived($_REQUEST['page'] == 'null' ? null : $_REQUEST['page']);
break; break;
case 'updateOrdNum': case 'updateOrdNum':
$suc = reportUpdateOrdnum($_REQUEST['ordnums']); $suc = reportUpdateOrdnum($_REQUEST['ordnums']);
@ -137,6 +140,14 @@ function help()
'description' => 'Get all reports grouped by group', 'description' => 'Get all reports grouped by group',
'params' => [ 'params' => [
'status' => '(ptional) Report status, default: 0,1,2,3', 'status' => '(ptional) Report status, default: 0,1,2,3',
'page' => '(ptional) Page number, default: null = vsetky',
]
],
'getArchived' => [
'name' => 'getArchived',
'description' => 'Get archived reports',
'params' => [
'page' => '(ptional) Page number, default: null = vsetky',
] ]
], ],
'updateOrdNum' => [ 'updateOrdNum' => [

View File

@ -235,19 +235,21 @@ function reportGet($report_id)
]); ]);
} }
function reportGetAll($status = null) function reportGetAll($status = null, $page = null)
{ {
global $db; global $db;
if ($status === null) $status = array(0, 1, 2, 3); if ($status === null) $status = array(0, 1, 2, 3);
return $db->select('reports', '*', [ $params = [
'ORDER' => ['report_priority' => 'DESC', 'ordnum' => 'ASC'], 'ORDER' => ['report_priority' => 'DESC', 'ordnum' => 'ASC'],
'report_status' => $status 'report_status' => $status
]); ];
if ($page !== null) $params['LIMIT'] = [$page * 10, 10];
return $db->select('reports', '*', $params);
} }
function reportGetAllGrouped($status = null) function reportGetAllGrouped($status = null, $page = null)
{ {
$all = reportGetAll($status); $all = reportGetAll($status, $page);
$groups = []; $groups = [];
foreach ($all as $report) { foreach ($all as $report) {
$groups[$report['report_status']][] = $report; $groups[$report['report_status']][] = $report;
@ -255,6 +257,17 @@ function reportGetAllGrouped($status = null)
return $groups; return $groups;
} }
function reportGetArchived($page = null)
{
global $db;
$params = [
'ORDER' => ['created_dt' => 'DESC'],
'report_status' => '4'
];
if ($page !== null) $params['LIMIT'] = [$page * 10, 10];
return $db->select('reports', '*', $params);
}
/** /**
* Attachments * Attachments
*/ */

View File

@ -358,6 +358,72 @@ button:focus-visible,
/* ---------------------------------------------------- /* ----------------------------------------------------
05 - ARCHIVE 05 - ARCHIVE
*/ */
#archive {
margin: 0 auto;
padding: 20px;
}
#archive .reports {
/* border: 1px red solid; */
display: flex;
flex-direction: column;
gap: 10px;
}
#archive .report-row {
/* border: 1px blue solid; */
display: flex;
flex-direction: row;
background-color: var(--color-bg2);
justify-content: space-between;
align-content: stretch;
transition: all 0.3s;
cursor: pointer;
}
#archive .report-row:hover {
filter: brightness(1.4);
}
#archive .report-row .report-id,
#archive .report-row .title,
#archive .report-row .date,
#archive .report-row .group {
/* border: 1px yellow solid; */
width: auto;
padding: 10px;
flex: 1;
}
#archive .report-row .report-id {
width: 50px;
text-align: center;
background-color: var(--color-bg0);
flex: 0 1 auto;
}
@media (max-width: 900px) {
#archive .report-row {
flex-wrap: wrap;
justify-content: left;
}
#archive .report-row .title,
#archive .report-row .date,
#archive .report-row .group {
flex: 0 0 auto;
}
#archive .report-row .title {
width: calc(100% - 100px);
}
#archive .report-row .date {
margin-left: 70px;
}
#archive .report-row .date,
#archive .report-row .group {
width: calc((100% - 140px) / 2);
}
}
@media (max-width: 600px) {
#archive .report-row .date,
#archive .report-row .group {
margin-left: 70px;
width: calc(100% - 100px);
}
}
/* ---------------------------------------------------- /* ----------------------------------------------------

View File

@ -73,8 +73,12 @@ export const backend = {
return this.callPromise('getAll', {}); return this.callPromise('getAll', {});
}, },
getAllGrouped(status) { getAllGrouped(status, page = null) {
return this.callPromise('getAllGrouped', {}); return this.callPromise('getAllGrouped', {status: status, page: page});
},
getArchived(page = null) {
return this.callPromise('getArchived', {page: page});
}, },
updateOrdnum(ordnums) { updateOrdnum(ordnums) {

View File

@ -11,11 +11,16 @@
left: 0; left: 0;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
z-index: 9999; z-index: 9999;
/* zatmavene */
/* background-color: rgba(0, 0, 0, 0.8); */
/* rozmazane */
background-color: rgba(255, 255, 255, 0.1); /* jemne priehľadné alebo aj 0 */
backdrop-filter: blur(8px); /* rozmazanie pozadia */
-webkit-backdrop-filter: blur(8px); /* podpora pre Safari */
} }
.spinner { .spinner {

View File

@ -1,6 +1,41 @@
<template> <template>
<div> <FullScreenLoader v-if="loading" />
<div id="archive">
<h1>Archív</h1> <h1>Archív</h1>
<router-link to="/">Späť domov</router-link>
<div class="reports">
<div class="report-row" v-for="report in reports" :key="report.report_id" @click="$router.push('/report/' + report.report_id)">
<div class="report-id">
<font-awesome-icon :icon="['fas', 'hashtag']" />
{{ report.report_id }}
</div>
<div class="title">{{ report.report_title }}</div>
<div class="date">{{ report.created_dt }}</div>
<div class="group">{{ report.report_group }}</div>
</div>
</div>
</div> </div>
</template> </template>
<script setup>
import { onMounted, ref } from "vue";
import { backend } from "../backend";
import FullScreenLoader from "../components/FullScreenLoader.vue";
const reports = ref([]);
const loading = ref(false);
onMounted(async () => {
loadReports();
});
function loadReports() {
loading.value = true;
backend.getArchived(0).then((data) => {
console.log(data);
reports.value = data;
loading.value = false;
});
}
</script>

View File

@ -28,18 +28,18 @@
<font-awesome-icon :icon="['fas', 'trash-can']" /> Zmazať <font-awesome-icon :icon="['fas', 'trash-can']" /> Zmazať
</button> </button>
</div> </div>
<div> <div v-if="editable">
<button @click="reportDone"> <button @click="reportDone">
<font-awesome-icon :icon="['fas', 'circle-check']" /> Hotovo, presunut do archivu <font-awesome-icon :icon="['fas', 'circle-check']" /> Hotovo, presunut do archivu
</button> </button>
</div> </div>
</div> </div>
<h1 contenteditable="true" @blur="onTitleChange" ref="reportTitle"> <h1 :contenteditable="editable" @blur="onTitleChange" ref="reportTitle">
{{ report.report_title }} {{ report.report_title }}
</h1> </h1>
<p <p
class="description" class="description"
contenteditable="true" :contenteditable="editable"
@blur="onDescriptionChange" @blur="onDescriptionChange"
ref="reportDescription" ref="reportDescription"
> >
@ -77,7 +77,7 @@
v-if="attachment.attachment_type == 'comment'" v-if="attachment.attachment_type == 'comment'"
class="attachment-content" class="attachment-content"
:contenteditable="attachment.editable ?? false" :contenteditable="attachment.editable ?? false"
@dblclick="attachment.editable = true" @dblclick="attachment.editable = true && editable"
@blur=" @blur="
attachment.editable = false; attachment.editable = false;
updateAttachmentContent($event, attachment); updateAttachmentContent($event, attachment);
@ -98,7 +98,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="attachment-new"> <div class="attachment-new" v-if="editable">
<div class="form-group"> <div class="form-group">
<label for="description">Nový komentár:</label> <label for="description">Nový komentár:</label>
<textarea <textarea
@ -149,6 +149,9 @@ import { backend } from "../backend";
import FullScreenLoader from "../components/FullScreenLoader.vue"; import FullScreenLoader from "../components/FullScreenLoader.vue";
import JSConfetti from 'js-confetti' import JSConfetti from 'js-confetti'
let tadas = ['/sounds/tada.mp3', '/sounds/tada2.mp3', '/sounds/crazy-phrog-short.mp3'];
const jungle = new Audio(tadas[Math.floor(Math.random() * tadas.length)]);
export default { export default {
name: "Report", name: "Report",
components: { FullScreenLoader }, components: { FullScreenLoader },
@ -160,12 +163,13 @@ export default {
report_id: 0, report_id: 0,
report_title: "Nacitavam report", report_title: "Nacitavam report",
report_description: "...", report_description: "...",
report_status: 0, report_status: 4,
report_group: "--", report_group: "--",
report_priority: 1, report_priority: 1,
created_dt: "--", created_dt: "--",
ordnum: 0, ordnum: 0,
}, },
editable: true,
attachments: [ attachments: [
{ {
attachment_id: 0, attachment_id: 0,
@ -188,6 +192,7 @@ export default {
backend.get(this.report_id).then((report) => { backend.get(this.report_id).then((report) => {
this.report = report; this.report = report;
// console.log(this.report); // console.log(this.report);
this.editable = report.report_status < 4;
}); });
backend.attachmentGetAll(this.report_id).then((attachments) => { backend.attachmentGetAll(this.report_id).then((attachments) => {
this.attachments = attachments; this.attachments = attachments;
@ -213,9 +218,7 @@ export default {
backend.update(this.report_id, { backend.update(this.report_id, {
report_status: 4, report_status: 4,
}).then(() => { }).then(() => {
let tadas = ['/sounds/tada.mp3', '/sounds/tada2.mp3', '/sounds/crazy-phrog-short.mp3']; jungle.play();
const audio = new Audio(tadas[Math.floor(Math.random() * tadas.length)]);
audio.play();
const confetti = new JSConfetti(); const confetti = new JSConfetti();
confetti.addConfetti(); confetti.addConfetti();
setTimeout(() => { setTimeout(() => {