add / show comments working

This commit is contained in:
isUnknown 2024-10-23 11:32:51 +02:00
parent a9992b0ff5
commit 6bffbc1707
10 changed files with 163 additions and 40 deletions

6
package-lock.json generated
View file

@ -16,6 +16,7 @@
"primevue": "^4.0.6", "primevue": "^4.0.6",
"slugify": "^1.6.6", "slugify": "^1.6.6",
"three": "^0.168.0", "three": "^0.168.0",
"uniqid": "^5.4.0",
"vue": "^3.5.6", "vue": "^3.5.6",
"vue-router": "^4.4.5" "vue-router": "^4.4.5"
}, },
@ -1827,6 +1828,11 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"optional": true "optional": true
}, },
"node_modules/uniqid": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/uniqid/-/uniqid-5.4.0.tgz",
"integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A=="
},
"node_modules/util-deprecate": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View file

@ -17,6 +17,7 @@
"primevue": "^4.0.6", "primevue": "^4.0.6",
"slugify": "^1.6.6", "slugify": "^1.6.6",
"three": "^0.168.0", "three": "^0.168.0",
"uniqid": "^5.4.0",
"vue": "^3.5.6", "vue": "^3.5.6",
"vue-router": "^4.4.5" "vue-router": "^4.4.5"
}, },

View file

@ -6,4 +6,31 @@ Uuid: s0lNtRA0Z7ybTCWG
---- ----
Template: document Template: document
----
Comments:
1:
m2lmqu2u:
text: test
username: Adrien Payet
date: 2024-10-23T10:46:08+02:00
m2lo4obv:
text: nouveau commentaire
username: Adrien Payet
date: 2024-10-23T11:24:53+02:00
m2lo6ckw:
text: Encore un autre commentaire
username: Adrien Payet
date: 2024-10-23T11:26:11+02:00
2:
m2loaj2f:
text: Autre commentaire
username: Adrien Payet
date: 2024-10-23T11:29:26+02:00
m2loam7s:
text: Autre commentaire
username: Adrien Payet
date: 2024-10-23T11:29:30+02:00

View file

@ -26,6 +26,7 @@ return [
require(__DIR__ . '/routes/save-file.php'), require(__DIR__ . '/routes/save-file.php'),
require(__DIR__ . '/routes/remove-file.php'), require(__DIR__ . '/routes/remove-file.php'),
require(__DIR__ . '/routes/upload-pdf.php'), require(__DIR__ . '/routes/upload-pdf.php'),
require(__DIR__ . '/routes/add-comment.php'),
], ],
'hooks' => [ 'hooks' => [
'page.create:after' => require_once(__DIR__ . '/hooks/create-steps.php'), 'page.create:after' => require_once(__DIR__ . '/hooks/create-steps.php'),

View file

@ -0,0 +1,32 @@
<?php
return [
'pattern' => '(:all)add-comment.json',
'method' => 'POST',
'action' => function () {
$json = file_get_contents('php://input');
$data = json_decode($json);
// return json_encode($data->pageUri);
$page = page($data->pageUri);
$file = $page->file($data->fileName);
$user = kirby()->user($data->userUuid);
$comments = $file->comments()->isEmpty() == true ? [] : Data::decode($file->comments()->toArray()['comments'], 'yaml');
$comments[$data->targetPage][$data->id] = [
'text' => $data->text,
'username' => (string) $user->name(),
'date' => (string) $data->date,
];
$newFile = $file->update([
'comments' => $comments
]);
return $comments;
}
];

View file

@ -5,7 +5,7 @@ function getFileData($file) {
'url' => $file->url(), 'url' => $file->url(),
'uuid' => (string) $file->uuid(), 'uuid' => (string) $file->uuid(),
'name' => $file->filename(), 'name' => $file->filename(),
'type' => (string) $file->type() 'type' => (string) $file->type(),
]; ];
if ($file->description()->exists()) { if ($file->description()->exists()) {
@ -13,5 +13,9 @@ function getFileData($file) {
$data['tags'] = $file->tags()->split(); $data['tags'] = $file->tags()->split();
}; };
if($file->comments()->exists()) {
$data['comments'] = Data::decode($file->comments()->value(), 'yaml');
}
return $data; return $data;
} }

View file

@ -2,20 +2,31 @@
<aside id="comments-container" aria-labelledby="comments-label"> <aside id="comments-container" aria-labelledby="comments-label">
<h2 id="comments-label" class="sr-only">Commentaires</h2> <h2 id="comments-label" class="sr-only">Commentaires</h2>
<div class="comments | flow"> <div class="comments | flow">
<article class="comment | flow" data-status="unread"> <div
<header> v-for="(page, pageIndex) in localComments"
<p> class="comments__page-group"
<strong>François</strong> >
<span class="comment__id">#1</span> <article
<span class="comment__page">Page 12</span> v-for="(comment, commentIndex) in Object.values(page)"
<time datetime="2024-10-22">Hier</time> :key="pageIndex + commentIndex"
class="comment | flow"
data-status="unread"
>
<header>
<p>
<strong>{{ comment.username }}</strong>
<span class="comment__id">#{{ commentIndex + 1 }}</span>
<span class="comment__page">Page {{ pageIndex }}</span>
<time :datetime="dayjs(comment.date).format('YYYY-MM-DD')">{{
formatDate(comment.date)
}}</time>
</p>
</header>
<p class="comment__body">
{{ comment.text }}
</p> </p>
</header> </article>
<p class="comment__body"> </div>
Lectus adipiscing nulla quis odio in aliquam. Adipiscing libero in
consequat porta mauris hendrerit malesuada viverra turpis.
</p>
</article>
</div> </div>
<button <button
id="add-comment" id="add-comment"
@ -50,28 +61,66 @@
</template> </template>
<script setup> <script setup>
import dayjs from "dayjs";
import "dayjs/locale/fr";
import uniqid from "uniqid";
import { ref } from "vue"; import { ref } from "vue";
import { useUserStore } from "../../stores/user"; import { useUserStore } from "../../stores/user";
import dayjs from "dayjs"; import { usePageStore } from "../../stores/page";
const { currentPage } = defineProps({ dayjs.locale("fr");
currentPage: Number,
const { currentPageIndex, file, comments } = defineProps({
currentPageIndex: Number,
file: Object,
comments: Object,
}); });
const { user } = useUserStore(); const { user } = useUserStore();
const { page } = usePageStore();
const newCommentText = ref(""); const newCommentText = ref("");
const isAddOpen = ref(false); const isAddOpen = ref(false);
const localComments = ref(comments);
// Functions // Functions
function addComment(event) { function addComment(event) {
event.preventDefault(); event.preventDefault();
const date = dayjs().format();
const comment = { const comment = {
pageUri: page.uri + "/client-brief",
targetPage: currentPageIndex,
fileName: file.name,
userUuid: user.uuid, userUuid: user.uuid,
text: newCommentText.value, text: newCommentText.value,
page: currentPage, date,
date: dayjs().format(), id: uniqid(),
}; };
console.log(comment);
const headers = {
method: "POST",
body: JSON.stringify(comment),
};
fetch("/add-comment.json", headers)
.then((res) => res.json())
.then((json) => (localComments.value = json))
.catch((error) => {
console.error("Erreur lors de la sauvegarde :", error);
});
}
function formatDate(date) {
const todayNumber = parseInt(dayjs().format("YYMMD"));
const dateNumber = parseInt(dayjs(date).format("YYMMD"));
if (dateNumber === todayNumber) {
return "Aujourd'hui";
}
if (dateNumber === todayNumber - 1) {
return "hier";
}
return dayjs(date).format("D MMM YY");
} }
</script> </script>

View file

@ -16,6 +16,7 @@
}}</time> }}</time>
</div> </div>
<!-- Images -->
<template v-if="step.files[0]?.type === 'image'"> <template v-if="step.files[0]?.type === 'image'">
<figure <figure
class="card__images" class="card__images"
@ -31,6 +32,8 @@
/> />
</figure> </figure>
</template> </template>
<!-- PDF -->
<template v-if="step.files[0]?.type === 'document'"> <template v-if="step.files[0]?.type === 'document'">
<div <div
@click="showPdf" @click="showPdf"
@ -53,7 +56,7 @@ const { step } = defineProps({
step: Object, step: Object,
}); });
const emit = defineEmits(["update:pdf"]); const emit = defineEmits(["update:file"]);
dayjs.locale("fr"); dayjs.locale("fr");
@ -79,7 +82,7 @@ function setStatus() {
function showPdf(event) { function showPdf(event) {
event.preventDefault(); event.preventDefault();
emit("update:pdf", step.files[0].url); emit("update:file", step.files[0]);
} }
</script> </script>

View file

@ -16,7 +16,7 @@
<VPdfViewer <VPdfViewer
:darkMode="true" :darkMode="true"
:initialThumbnailsVisible="true" :initialThumbnailsVisible="true"
:src="src" :src="file.url"
local="fr_FR" local="fr_FR"
@loaded="onPdfLoaded" @loaded="onPdfLoaded"
/> />
@ -29,7 +29,12 @@
> >
<span class="sr-only">Afficher les commentaires</span> <span class="sr-only">Afficher les commentaires</span>
</button> </button>
<Comments v-if="isCommentsOpen" :current-page="currentPage" /> <Comments
v-if="isCommentsOpen"
:current-page-index="currentPageIndex"
:file="file"
:comments="file.comments"
/>
</div> </div>
</Dialog> </Dialog>
</template> </template>
@ -40,8 +45,8 @@ import Comments from "../../comments/Comments.vue";
import { VPdfViewer, useLicense } from "@vue-pdf-viewer/viewer"; import { VPdfViewer, useLicense } from "@vue-pdf-viewer/viewer";
import { ref, watch } from "vue"; import { ref, watch } from "vue";
const { src } = defineProps({ const { file } = defineProps({
src: String, file: Object,
}); });
const emit = defineEmits("close"); const emit = defineEmits("close");
@ -55,7 +60,7 @@ watch(isOpen, (newValue) => {
emit("close"); emit("close");
}); });
const isCommentsOpen = ref(false); const isCommentsOpen = ref(false);
const currentPage = ref(1); const currentPageIndex = ref(1);
// Functions // Functions
const onPdfLoaded = () => { const onPdfLoaded = () => {
@ -65,7 +70,7 @@ const onPdfLoaded = () => {
(entries) => { (entries) => {
entries.forEach((entry, index) => { entries.forEach((entry, index) => {
if (entry.intersectionRatio > 0.5) { if (entry.intersectionRatio > 0.5) {
currentPage.value = parseInt( currentPageIndex.value = parseInt(
entry.target.getAttribute("aria-label").split(" ")[1] entry.target.getAttribute("aria-label").split(" ")[1]
); );
} }

View file

@ -3,14 +3,14 @@
<Header :title="page.content.title" /> <Header :title="page.content.title" />
<!-- Kanban: Status Brief Enrichi --> <!-- Kanban: Status Brief Enrichi -->
<PdfViewer v-if="pdf" :src="pdf" @close="pdf = null" /> <PdfViewer v-if="file" :file="file" @close="file = null" />
<div class="kanban"> <div class="kanban">
<ProjectStep <ProjectStep
v-for="step in page.steps" v-for="step in page.steps"
:key="step" :key="step"
:step="step" :step="step"
@update:pdf="changePdf" @update:file="changeFile"
> >
</ProjectStep> </ProjectStep>
<!-- <section <!-- <section
@ -168,7 +168,7 @@ import { ref } from "vue";
const { page } = storeToRefs(usePageStore()); const { page } = storeToRefs(usePageStore());
const user = useUserStore().user; const user = useUserStore().user;
const pdf = ref(null); const file = ref(null);
function setStepStatus(stepName) { function setStepStatus(stepName) {
const stepIndex = steps.indexOf(stepName); const stepIndex = steps.indexOf(stepName);
@ -178,13 +178,8 @@ function setStepStatus(stepName) {
} }
} }
function changePdf(src) { function changeFile(newFile) {
pdf.value = src; file.value = newFile;
}
function hidePdf() {
console.log("test");
pdf.value = null;
} }
</script> </script>