comments working

This commit is contained in:
isUnknown 2025-01-15 14:18:48 +01:00
parent 375bed1d01
commit 0b472988a2
14 changed files with 107 additions and 59 deletions

View file

@ -7,17 +7,20 @@ class FileDetails
{ {
public string $uuid; public string $uuid;
public string $url; public string $url;
public string $type;
public function __construct(Kirby\Cms\File $data) public function __construct(Kirby\Cms\File $data)
{ {
$this->uuid = (string) $data->uuid(); $this->uuid = (string) $data->uuid();
$this->url = (string) $data->url(); $this->url = (string) $data->url();
$this->type = (string) $data->type();
} }
public function toArray() { public function toArray() {
return [ return [
"uuid" => $this->uuid, "uuid" => $this->uuid,
"url" => $this->url "url" => $this->url,
"type" => $this->type
]; ];
} }
} }

View file

@ -5,16 +5,16 @@ namespace adrienpayet\D2P\data\location;
class Location class Location
{ {
protected PageDetails $page; protected PageDetails $page;
protected ?string $dialogUri = null; // protected ?string $dialogUri = null;
protected ProjectDetails $project; // protected ProjectDetails $project;
protected ?FileDetails $file = null; protected ?FileDetails $file = null;
protected ?array $parent = null; protected ?array $parent = null;
public function __construct(array $data) public function __construct(array $data)
{ {
$this->page = new PageDetails($data["page"]); $this->page = new PageDetails($data["page"]);
$this->dialogUri = $data["dialogUri"]; // $this->dialogUri = $data["dialogUri"];
$this->project = new ProjectDetails($data["project"]); // $this->project = new ProjectDetails($data["project"]);
if (isset($data['file'])) { if (isset($data['file'])) {
$this->file = new FileDetails($data["file"]); $this->file = new FileDetails($data["file"]);
@ -33,12 +33,12 @@ class Location
public function toArray() { public function toArray() {
$array = [ $array = [
"page" => $this->page->toArray(), "page" => $this->page->toArray(),
"project" => $this->project->toArray(), // "project" => $this->project->toArray(),
]; ];
if ($this->dialogUri) { // if ($this->dialogUri) {
$array["dialogUri"] = $this->dialogUri; // $array["dialogUri"] = $this->dialogUri;
} // }
if ($this->file) { if ($this->file) {
$array["file"] = $this->file; $array["file"] = $this->file;

View file

@ -14,6 +14,8 @@ class PageDetails
public function toArray() { public function toArray() {
return [ return [
"uuid" => (string) $this->page->uuid(),
"template" => (string) $this->page->template(),
"uri" => (string) $this->page->uri(), "uri" => (string) $this->page->uri(),
"title" => (string) $this->page->title(), "title" => (string) $this->page->title(),
]; ];

View file

@ -21,7 +21,6 @@ return [
"location" => [ "location" => [
"page" => $page, "page" => $page,
"project" => $project, "project" => $project,
"dialogUri" => $data->dialogUri,
"file" => $file "file" => $file
], ],
"position" => [ "position" => [

View file

@ -8,12 +8,11 @@ return [
$data = json_decode($json); $data = json_decode($json);
$page = page($data->location->page->uri); $page = page($data->location->page->uri);
$project = page($data->location->project->uri);
$file = $page->file($data->location->file->uuid); $file = $page->file($data->location->file->uuid);
$isReply = $data->location->parent->id ?? false;
$comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value());
$isReply = $data->location->parent->id ?? false;
foreach ($comments as $key => &$comment) { foreach ($comments as $key => &$comment) {
if ($isReply) { if ($isReply) {
if ($comment['id'] === $data->location->parent->id) { if ($comment['id'] === $data->location->parent->id) {
@ -39,6 +38,7 @@ return [
echo json_encode(getFileData($newFile)); echo json_encode(getFileData($newFile));
$project = $page->parents()->findBy("template", "project");
$project->deleteNotification($data->id); $project->deleteNotification($data->id);
exit; exit;

View file

@ -10,10 +10,8 @@ return [
$data = json_decode($json); $data = json_decode($json);
$page = page($data->fileParentUri); $page = page($data->fileParentUri);
$project = $page->parent()->template() == "project" ? $page->parent() : $page->parent()->parent();
$file = $page->file($data->fileName); $file = $page->file($data->fileName);
$user = kirby()->user($data->userUuid);
$comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value());
foreach ($comments as &$comment) { foreach ($comments as &$comment) {
@ -22,8 +20,6 @@ return [
$replyData = [ $replyData = [
"location" => [ "location" => [
"page" => $page, "page" => $page,
"project" => $project,
"dialogUri" => $data->dialogUri,
"file" => $file, "file" => $file,
"parent" => $comment "parent" => $comment
], ],
@ -45,7 +41,8 @@ return [
'comments' => $comments 'comments' => $comments
]); ]);
$user->sendNotification($project, $replyData); $project = $page->parents()->findBy("template", "project");
$project->createNotification($replyData);
return getFileData($newFile); return getFileData($newFile);
} }

View file

@ -8,7 +8,7 @@ return [
$data = json_decode($json); $data = json_decode($json);
try { try {
$project = page($data->projectUuid); $project = page($data->projectId);
$project->readNotification($data->notificationId); $project->readNotification($data->notificationId);
return json_encode([ return json_encode([
"status" => "success" "status" => "success"

View file

@ -85,6 +85,7 @@ import { useApiStore } from "../../stores/api";
import { useDialogStore } from "../../stores/dialog"; import { useDialogStore } from "../../stores/dialog";
import { computed, onMounted, ref, useTemplateRef } from "vue"; import { computed, onMounted, ref, useTemplateRef } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { usePageStore } from "../../stores/page";
dayjs.locale("fr"); dayjs.locale("fr");
@ -102,6 +103,7 @@ const { activeTracks, openedComment } = storeToRefs(useDialogStore());
const draftText = ref(comment.text); const draftText = ref(comment.text);
const editField = ref(null); const editField = ref(null);
const commentNode = useTemplateRef("comment-node"); const commentNode = useTemplateRef("comment-node");
const { page } = storeToRefs(usePageStore());
let correspondingMarker = null; let correspondingMarker = null;
// Functions // Functions
@ -143,7 +145,7 @@ function handleClick() {
async function read() { async function read() {
if (getStatus.value !== "unread") return; if (getStatus.value !== "unread") return;
try { try {
const newNotification = await api.readNotification(comment); const newNotification = await api.readNotification(comment, page.value.uri);
console.log(newNotification); console.log(newNotification);
userStore.readNotification(comment.id); userStore.readNotification(comment.id);
} catch (error) { } catch (error) {

View file

@ -179,7 +179,6 @@ function handleSubmit(event = null) {
} }
const date = dayjs().format(); const date = dayjs().format();
const newComment = { const newComment = {
dialogUri: route.fullPath,
fileName: openedFile.value ? openedFile.value.name : false, fileName: openedFile.value ? openedFile.value.name : false,
userUuid: user.uuid, userUuid: user.uuid,
text: draftComment.value.text, text: draftComment.value.text,
@ -202,7 +201,7 @@ function handleSubmit(event = null) {
async function replyComment(newComment) { async function replyComment(newComment) {
newComment.parentId = openedComment.value.id; newComment.parentId = openedComment.value.id;
const matchFileParentUri = openedComment.value.location.file.url.match( const matchFileParentUri = openedFile.value.url.match(
/projects\/.*?(?=\/[^/]+\/[^/]+$)/ /projects\/.*?(?=\/[^/]+\/[^/]+$)/
); );
newComment.fileParentUri = matchFileParentUri ? matchFileParentUri[0] : null; newComment.fileParentUri = matchFileParentUri ? matchFileParentUri[0] : null;
@ -224,14 +223,16 @@ async function addComment(newComment) {
resetDraftComment(); resetDraftComment();
isAddOpen.value = false; isAddOpen.value = false;
dialog.updateFile(newFile); dialog.updateFile(newFile);
activeTracks.value = activeTracks.value.map((track) => { if (activeTracks.value) {
if (track.files) { activeTracks.value = activeTracks.value.map((track) => {
track.files = track.files.map((file) => if (track.files) {
file.uuid === newFile.uuid ? newFile : file track.files = track.files.map((file) =>
); file.uuid === newFile.uuid ? newFile : file
} );
return track; }
}); return track;
});
}
} }
function resetDraftComment() { function resetDraftComment() {
@ -318,11 +319,15 @@ function openComment(comment) {
openedComment.value = comment; openedComment.value = comment;
if (activeTracks.value?.length === 1) { if (activeTracks.value?.length === 1) {
openedFile.value = activeTracks.value[0].files.find( showCorrespondingView();
(file) => file.uuid === openedComment.value.location.file.uuid
);
} }
} }
function showCorrespondingView() {
openedFile.value = activeTracks.value[0].files.find(
(file) => file.uuid === openedComment.value.location.file.uuid
);
}
</script> </script>
<style> <style>

View file

@ -2,7 +2,7 @@
<article <article
class="notification | bg-white rounded-lg | p-16 | flow" class="notification | bg-white rounded-lg | p-16 | flow"
data-type="comment" data-type="comment"
@click="router.push(targetUri + '&comments=true')" @click="router.push(href)"
> >
<header> <header>
<p class="flex"> <p class="flex">
@ -12,8 +12,10 @@
>Commentaire</strong >Commentaire</strong
> >
<span class="notification__client | text-grey-700" <span class="notification__client | text-grey-700"
>{{ project.title }} >{{ notification.project.title }}
{{ project?.status === "unlisted" ? "(archivé)" : "" }}</span {{
notification.project?.status === "unlisted" ? "(archivé)" : ""
}}</span
> >
<time <time
datetime="" datetime=""
@ -39,16 +41,29 @@
<script setup> <script setup>
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useNotificationsStore } from "../../stores/notifications"; import { useNotificationsStore } from "../../stores/notifications";
import { useProjectsStore } from "../../stores/projects";
const router = useRouter(); const router = useRouter();
const { notification } = defineProps({ notification: Object }); const { notification } = defineProps({ notification: Object });
const { formatDate } = useNotificationsStore(); const { formatDate } = useNotificationsStore();
const { getProjectByUuid } = useProjectsStore();
const project = getProjectByUuid(notification.location.project.uuid); const href = getTargetPath();
const targetUri = notification.location.dialoguri.replace(
/\/projects\/([a-z0-9\-]+)/, // Functions
"/projects/" + notification.target.slug function getTargetPath() {
); const uri = notification.location.page.uri;
const isDocumentBrief =
notification.location.page.template === "client-brief" &&
notification.location?.file.type === "document";
if (isDocumentBrief) {
return notification.project.uri + "?dialog=client-brief&comments=true";
}
if (notification.location.page.template === "track") {
return notification.project.uri + "?dialog=virtual-sample&comments=true";
}
return uri;
}
</script> </script>

View file

@ -34,6 +34,24 @@ const routes = [
path: "/projects/:id/extended-brief", path: "/projects/:id/extended-brief",
component: Brief, component: Brief,
}, },
// Redirections
{
path: "/projects/:id/industrial-ideation",
redirect: (to) => {
return (
"/projects/" +
to.params.id +
"?dialog=industrial-ideation&comments=true"
);
},
},
{
path: "/projects/:id/proposal",
redirect: (to) => {
return "/projects/" + to.params.id + "?dialog=proposal&comments=true";
},
},
]; ];
export default routes; export default routes;

View file

@ -1,4 +1,5 @@
import { defineStore } from "pinia"; import { defineStore, storeToRefs } from "pinia";
import { usePageStore } from "./page.js";
import uniqid from "uniqid"; import uniqid from "uniqid";
export const useApiStore = defineStore("api", () => { export const useApiStore = defineStore("api", () => {
@ -142,11 +143,17 @@ export const useApiStore = defineStore("api", () => {
} }
} }
async function readNotification(comment) { /**
*
* @param {string} comment
* @param {string} projectId UUID or URI
* @returns status with message if error
*/
async function readNotification(comment, projectId) {
const headers = { const headers = {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
projectUuid: comment.location.project.uuid, projectId,
notificationId: comment.id, notificationId: comment.id,
}), }),
}; };

View file

@ -11,21 +11,21 @@ export const useUserStore = defineStore("user", () => {
return projects.value.reduce((acc, project) => { return projects.value.reduce((acc, project) => {
if (!project.notifications) return acc; if (!project.notifications) return acc;
const projectNotifications = project.notifications.map( const projectNotifications = project.notifications.map((notification) => {
(notification) => ({ const newNotification = {
...notification, ...notification,
target: { project: project,
uuid: project.uuid, isRead: notification.readby?.includes(user.value.uuid),
title: project.title, };
slug: project.slug,
}, return newNotification;
isRead: });
notification.author.uuid === user.value.uuid ||
notification.readby?.includes(user.value.uuid), const userNotifications = projectNotifications.filter(
}) (notification) => notification.author.uuid !== user.value.uuid
); );
return [...acc, ...projectNotifications]; return [...acc, ...userNotifications];
}, []); }, []);
}); });