merge and add opened comment view

This commit is contained in:
isUnknown 2024-10-29 16:13:07 +01:00
parent c3860d4a38
commit 4e4216f8d3
6 changed files with 164 additions and 134 deletions

View file

@ -12,11 +12,11 @@ Template: document
Comments: Comments:
m2u905al: m2ucagze:
pageUri: > pageUri: >
projects/miss-dior-blooming-bouquet/client-brief projects/miss-dior-blooming-bouquet/client-brief
fileUuid: file://s0lNtRA0Z7ybTCWG fileUuid: file://s0lNtRA0Z7ybTCWG
filePageTarget: 1 filePageIndex: 1
position: position:
x: null x: null
y: null y: null
@ -27,22 +27,22 @@ m2u905al:
email: adrien.payet@outlook.com email: adrien.payet@outlook.com
uuid: user://WWjXgPWk uuid: user://WWjXgPWk
role: admin role: admin
date: 2024-10-29T10:31:23+01:00 date: 2024-10-29T12:03:24+01:00
id: m2u905al id: m2ucagze
m2u955a7: m2ucgaoe:
pageUri: > pageUri: >
projects/miss-dior-blooming-bouquet/client-brief projects/miss-dior-blooming-bouquet/client-brief
fileUuid: file://s0lNtRA0Z7ybTCWG fileUuid: file://s0lNtRA0Z7ybTCWG
filePageTarget: 1 filePageIndex: 1
position: position:
x: null x: null
y: null y: null
replies: [ ] replies: [ ]
text: come2 text: Deuxième commentaire
user: user:
name: Adrien Payet name: Adrien Payet
email: adrien.payet@outlook.com email: adrien.payet@outlook.com
uuid: user://WWjXgPWk uuid: user://WWjXgPWk
role: admin role: admin
date: 2024-10-29T10:35:16+01:00 date: 2024-10-29T12:07:55+01:00
id: m2u955a7 id: m2ucgaoe

View file

@ -17,7 +17,7 @@ return [
$newComment = [ $newComment = [
'pageUri' => $data->pageUri, 'pageUri' => $data->pageUri,
'fileUuid' => (string) $file->uuid(), 'fileUuid' => (string) $file->uuid(),
'filePageTarget' => $data->targetPage, 'filePageIndex' => $data->filePageIndex,
'position' => [ 'position' => [
'x' => null, 'x' => null,
'y' => null 'y' => null
@ -40,7 +40,7 @@ return [
'comments' => $comments 'comments' => $comments
]); ]);
$user->sendNotification('comments', $newComment); // $user->sendNotification('comments', $newComment);
return getFileData($newFile); return getFileData($newFile);
} }

View file

@ -0,0 +1,16 @@
<?php
return function ($group, $notificationId) {
$notifications = Yaml::decode($this->notifications()->value());
try {
$notifications[$group][$notificationId]['isRead'] = true;
} catch (\Throwable $th) {
//throw $th;
}
$this->update([
"notifications" => $notifications
]);
return $notifications;
};

View file

@ -0,0 +1,26 @@
<?php
return function ($group, $data) {
foreach (kirby()->users()->not($this) as $otherUser) {
try {
$notifications = $otherUser->notifications()->isNotEmpty()
? Yaml::decode($otherUser->notifications()->value())
: [];
if (!isset($notifications[$group])) {
$notifications[$group] = [];
}
$data['isRead'] = false;
$notifications[$group][$data['id']] = $data;
$otherUser->update([
'notifications' => $notifications
]);
} catch (\Throwable $th) {
throw new Exception("Error updating notifications: " . $th->getMessage() . ' line ' . $th->getLine(), 1);
}
}
};

View file

@ -0,0 +1,78 @@
<template>
<article class="comment | flow" :data-status="setStatus(comment)">
<header>
<p>
<strong>{{ comment.user.name ?? comment.user.email }}</strong>
<template v-if="commentIndex">
<span class="comment__id">#{{ commentIndex }}</span>
</template>
<span class="comment__page">Page {{ comment.filePageIndex }}</span>
<time :datetime="dayjs(comment.date).format('YYYY-MM-DD')">{{
formatDate(comment.date)
}}</time>
</p>
</header>
<p class="comment__body">
{{ comment.text }}
</p>
<footer v-if="comment.replies?.length > 0" class="comment__replies">
<span>{{ comment.replies.length }} réponse</span>
</footer>
</article>
</template>
<script setup>
import dayjs from "dayjs";
import "dayjs/locale/fr";
dayjs.locale("fr");
const { comment, commentIndex } = defineProps({
comment: Object,
commentIndex: Number,
});
// Functions
function setStatus(comment) {
try {
if (!user?.notifications?.comments[comment.id].isRead) {
return "unread";
} else {
return undefined;
}
} catch (error) {
return undefined;
}
}
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");
}
function closeAddField() {
isAddOpen.value = false;
newCommentText.value = "";
}
async function readNotification(notificationId) {
const newNotifications = await api.readNotification(
user.uuid,
"comments",
notificationId
);
user.notifications = newNotifications;
}
</script>

View file

@ -2,87 +2,38 @@
<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">
<template v-if="!openedComment"> <template v-if="comments">
<!-- TODO: faire un composant comment --> <template v-if="!openedComment">
<article <Comment
v-for="(comment, commentIndex) in Object.values(comments).reverse()" v-for="(comment, commentIndex) in Object.values(comments).reverse()"
:key="commentIndex" :comment="comment"
class="comment | flow" :commentIndex="commentIndex + 1"
:data-status="setStatus(comment)" :key="comment.id"
@click="open(comment)" @click="openedComment = comment"
> />
<header> </template>
<p> <template v-else>
<strong>{{ comment.user.name ?? comment.user.email }}</strong> <button
<span class="comment__id">#{{ commentIndex + 1 }}</span> class="btn | justify-start w-full | bg-white-10 text-white | px-8"
<span class="comment__page">Page {{ pageIndex }}</span> data-icon="chevron-single-left"
<time :datetime="dayjs(comment.date).format('YYYY-MM-DD')">{{ @click="openedComment = null"
formatDate(comment.date)
}}</time>
</p>
</header>
<p class="comment__body">
{{ comment.text }}
</p>
<!-- TODO: à dynamiser (affichage ou non si replies + nombre de replies)-->
<footer class="comment__replies">
<span>1 réponse</span>
</footer>
</article>
</template>
<template v-else>
<!-- TODO: mettre la bonne cible pour to: -->
<router-link
:to="'/' + page.parent"
class="btn | justify-start w-full | bg-white-10 text-white | px-8"
data-icon="chevron-single-left"
>
<span>Retour à la liste</span>
</router-link>
<!-- TODO: utiliser le composant comment ici -->
<article
class="comment"
data-opened="true"
>
<header>
<p>
<strong>{{ openedComment.user.name ?? openedComment.user.email }}</strong>
<span class="comment__id">#{{ commentIndex + 1 }}</span>
<span class="comment__page">Page {{ pageIndex }}</span>
<time :datetime="dayjs(openedComment.date).format('YYYY-MM-DD')">{{
formatDate(openedComment.date)
}}</time>
</p>
</header>
<p class="comment__body">
{{ openedComment.text }}
</p>
<footer class="comment__replies">
<span>1 réponse</span>
</footer>
</article>
<div class="replies">
<!-- TODO: utiliser le composant comment ici -->
<article
v-for="comment in openedComment.replies"
class="comment reply"
> >
<header> <span>Retour à la liste</span>
<p> </button>
<strong>{{ comment.user.name ?? comment.user.email }}</strong> <Comment :comment="openedComment" />
<span class="comment__id">#{{ commentIndex + 1 }}</span> <div v-if="openedComment?.replies?.length > 0" class="replies">
<span class="comment__page">Page {{ pageIndex }}</span> <Comment
<time :datetime="dayjs(comment.date).format('YYYY-MM-DD')">{{ v-for="(reply, commentIndex) in Object.values(
formatDate(comment.date) openedComment.replies
}}</time> ).reverse()"
</p> :comment="reply"
</header> :commentIndex="commentIndex + 1"
<p class="comment__body"> :key="reply.id"
{{ comment.text }} />
</p> </div>
</article> </template>
</div>
</template> </template>
<template v-else> état aucun commentaire </template>
</div> </div>
<button <button
v-if="!openedComment && !isAddOpen" v-if="!openedComment && !isAddOpen"
@ -93,7 +44,7 @@
Ajouter un commentaire Ajouter un commentaire
</button> </button>
<button <button
v-if="openedComment && !isReplyOpen" v-else
id="reply-comment" id="reply-comment"
class="btn btn--white-20 | justify-start w-full | text-white-50" class="btn btn--white-20 | justify-start w-full | text-white-50"
@click="isReplyOpen = true" @click="isReplyOpen = true"
@ -135,6 +86,7 @@ import { ref } from "vue";
import { useUserStore } from "../../stores/user"; import { useUserStore } from "../../stores/user";
import { usePageStore } from "../../stores/page"; import { usePageStore } from "../../stores/page";
import { useApiStore } from "../../stores/api"; import { useApiStore } from "../../stores/api";
import Comment from "./Comment.vue";
dayjs.locale("fr"); dayjs.locale("fr");
@ -160,7 +112,7 @@ async function addComment(event) {
const date = dayjs().format(); const date = dayjs().format();
const comment = { const comment = {
pageUri: page.uri + "/client-brief", pageUri: page.uri + "/client-brief",
targetPage: currentPageIndex, filePageIndex: currentPageIndex,
fileName: file.name, fileName: file.name,
userUuid: user.uuid, userUuid: user.uuid,
text: newCommentText.value, text: newCommentText.value,
@ -172,46 +124,4 @@ async function addComment(event) {
isAddOpen.value = false; isAddOpen.value = false;
emits("update:file", newFile); emits("update:file", newFile);
} }
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");
}
function closeAddField() {
isAddOpen.value = false;
newCommentText.value = "";
}
function setStatus(comment) {
try {
if (!user?.notifications?.comments[comment.id].isRead) {
return "unread";
} else {
return undefined;
}
} catch (error) {
return undefined;
}
}
async function readNotification(notificationId) {
const newNotifications = await api.readNotification(
user.uuid,
"comments",
notificationId
);
user.notifications = newNotifications;
}
</script> </script>