From fa36c9ef4a26bc9fd6750a58c4540e3bbb5f9c01 Mon Sep 17 00:00:00 2001
From: isUnknown
Date: Wed, 18 Dec 2024 13:56:21 +0100
Subject: [PATCH 01/10] #68 - finish notification class. Content notification
on validate brief working
---
public/site/blueprints/users/admin.yml | 16 +++++-
public/site/config/routes/validate-brief.php | 25 ++++------
public/site/plugins/classes/Author.php | 27 ++++++++++
public/site/plugins/notifications/index.php | 11 ++++
.../notifications/src/Notification.php | 50 +++++++++++++++++++
.../plugins/notifications/src/Position.php | 25 ++++++++++
.../src/location/FileDetails.php | 22 ++++++++
.../notifications/src/location/Location.php | 36 +++++++++++++
.../src/location/PageDetails.php | 21 ++++++++
.../src/location/ProjectDetails.php | 23 +++++++++
.../notifications/user-methods/send.php | 5 +-
src/views/Brief.vue | 9 ++--
12 files changed, 246 insertions(+), 24 deletions(-)
create mode 100644 public/site/plugins/classes/Author.php
create mode 100644 public/site/plugins/notifications/src/Notification.php
create mode 100644 public/site/plugins/notifications/src/Position.php
create mode 100644 public/site/plugins/notifications/src/location/FileDetails.php
create mode 100644 public/site/plugins/notifications/src/location/Location.php
create mode 100644 public/site/plugins/notifications/src/location/PageDetails.php
create mode 100644 public/site/plugins/notifications/src/location/ProjectDetails.php
diff --git a/public/site/blueprints/users/admin.yml b/public/site/blueprints/users/admin.yml
index 16ff498..691d29c 100644
--- a/public/site/blueprints/users/admin.yml
+++ b/public/site/blueprints/users/admin.yml
@@ -4,4 +4,18 @@ home: /panel/pages/projects
fields:
notifications:
- type: hidden
+ label: Notifications
+ type: structure
+ fields:
+ location:
+ type: object
+ fields:
+ page:
+ type: object
+ fields:
+ uri:
+ type: text
+ href:
+ type: url
+ type:
+ type: text
diff --git a/public/site/config/routes/validate-brief.php b/public/site/config/routes/validate-brief.php
index fb21587..d9d7e32 100644
--- a/public/site/config/routes/validate-brief.php
+++ b/public/site/config/routes/validate-brief.php
@@ -7,12 +7,12 @@ return [
$json = file_get_contents('php://input');
$data = json_decode($json);
- $brief = page($data->briefUri);
- $project = $brief->parent();
- $href = $data->dialogUri ? $data->dialogUri : $brief->url();
+ $page = page($data->briefUri);
+ $project = $page->parent();
+ $dialogUri = $data->dialogUri ? $data->dialogUri : null;
try {
- $newPage = $brief->update([
+ $newPage = $page->update([
'isValidated' => 'true'
]);
@@ -21,20 +21,13 @@ return [
$notification = [
'location' => [
- 'href' => (string) $href,
- 'project' => [
- 'title' => (string) $project->title(),
- 'uri' => (string) $project->url()
- ]
+ 'page' => $page,
+ 'project' => $project,
+ 'dialogUri' => (string) $dialogUri,
],
'date' => $dateTime->format('Y-m-d\TH:i:sP'),
'text' => "Brief (" . $project->title()->value() . ")",
- 'author' => [
- 'name' => (string) kirby()->user()->name(),
- 'email' => (string) kirby()->user()->email(),
- 'uuid' => (string) kirby()->user()->uuid(),
- 'role' => (string) kirby()->user()->role(),
- ],
+ 'author' => kirby()->user(),
'id' => Str::uuid(),
'type' => 'content'
];
@@ -46,7 +39,7 @@ return [
];
} catch (\Throwable $th) {
return [
- "error" => "Can't validate '" . $brief->title()->value() . "' brief.",
+ "error" => "Can't validate '" . $page->title()->value() . "' brief.",
'details' => $th->getMessage()
];
}
diff --git a/public/site/plugins/classes/Author.php b/public/site/plugins/classes/Author.php
new file mode 100644
index 0000000..1df1b9d
--- /dev/null
+++ b/public/site/plugins/classes/Author.php
@@ -0,0 +1,27 @@
+name = (string) $author->name();
+ $this->email = (string) $author->email();
+ $this->uuid = (string) $author->uuid();
+ $this->role = (string) $author->role();
+ }
+
+ public function toArray() {
+ return [
+ "name" => $this->name,
+ "email" => $this->email,
+ "uuid" => $this->uuid,
+ "role" => $this->role,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/public/site/plugins/notifications/index.php b/public/site/plugins/notifications/index.php
index 6a0219e..1a5c6ea 100644
--- a/public/site/plugins/notifications/index.php
+++ b/public/site/plugins/notifications/index.php
@@ -4,6 +4,17 @@ load([
'ProjectPage' => 'models/ProjectPage.php',
], __DIR__);
+F::loadClasses([
+ 'adrienpayet\\notifications\\Notification' => __DIR__ . '/src/Notification.php',
+ 'adrienpayet\\notifications\\location\\Location' => __DIR__ . '/src/location/Location.php',
+ 'adrienpayet\\notifications\\location\\PageDetails' => __DIR__ . '/src/location/PageDetails.php',
+ 'adrienpayet\\notifications\\location\\ProjectDetails' => __DIR__ . '/src/location/ProjectDetails.php',
+ 'adrienpayet\\notifications\\location\\FileDetails' => __DIR__ . '/src/location/FileDetails.php',
+ 'adrienpayet\\notifications\\Position' => __DIR__ . '/src/Position.php',
+ 'adrienpayet\\Author' => __DIR__ . '/../classes/Author.php'
+]);
+
+
Kirby::plugin('adrienpayet/pdc-notifications', [
'routes' => [
require(__DIR__ . '/routes/readAll.php'),
diff --git a/public/site/plugins/notifications/src/Notification.php b/public/site/plugins/notifications/src/Notification.php
new file mode 100644
index 0000000..b9f040b
--- /dev/null
+++ b/public/site/plugins/notifications/src/Notification.php
@@ -0,0 +1,50 @@
+type = $data["type"];
+ $this->location = new Location($data["location"]);
+ $this->text = $data["text"];
+ $this->author = new Author($data["author"]);
+ $this->date = $data["date"];
+ $this->id = $data["id"];
+ $this->isRead = $data["isRead"];
+
+ if ($data["type"] === "comment") {
+ $this->position = new Position($data["position"]);
+ }
+ }
+
+ public function toArray() {
+ $array = [
+ "type" => $this->type,
+ "location" => $this->location->toArray(),
+ "text" => $this->text,
+ "author" => $this->author->toArray(),
+ "date" => $this->date,
+ "id" => $this->id,
+ "isRead" => $this->isRead,
+ ];
+ if ($this->type === "comment") {
+ $array["position"] = $this->position->toArray();
+ }
+
+ return $array;
+ }
+
+}
diff --git a/public/site/plugins/notifications/src/Position.php b/public/site/plugins/notifications/src/Position.php
new file mode 100644
index 0000000..01f319c
--- /dev/null
+++ b/public/site/plugins/notifications/src/Position.php
@@ -0,0 +1,25 @@
+pageIndex = $data['pageIndex'];
+ $this->x = (float) $data['x'];
+ $this->y = (float) $data['y'];
+ }
+
+ public function toArray() {
+ return [
+ "pageIndex" => $this->pageIndex,
+ "x" => $this->x,
+ "y" => $this->y,
+ ];
+ }
+}
diff --git a/public/site/plugins/notifications/src/location/FileDetails.php b/public/site/plugins/notifications/src/location/FileDetails.php
new file mode 100644
index 0000000..8d1ba42
--- /dev/null
+++ b/public/site/plugins/notifications/src/location/FileDetails.php
@@ -0,0 +1,22 @@
+uuid = (string) $data->uuid();
+ $this->url = (string) $data->url();
+ }
+
+ public function toArray() {
+ return [
+ "uuid" => $this->uuid,
+ "url" => $this->url
+ ];
+ }
+}
diff --git a/public/site/plugins/notifications/src/location/Location.php b/public/site/plugins/notifications/src/location/Location.php
new file mode 100644
index 0000000..619945f
--- /dev/null
+++ b/public/site/plugins/notifications/src/location/Location.php
@@ -0,0 +1,36 @@
+page = new PageDetails($data["page"]);
+ $this->dialogUri = $data["dialogUri"];
+ $this->project = new ProjectDetails($data["project"]);
+
+ if (isset($data['file'])) {
+ $this->file = new FileDetails($data["file"]);
+ }
+ }
+
+ public function toArray() {
+ $array = [
+ "page" => $this->page->toArray(),
+ "project" => $this->project->toArray(),
+ ];
+
+ if ($this->dialogUri) {
+ $array["dialogUri"] = $this->dialogUri;
+ $array["file"] = $this->file;
+ }
+
+ return $array;
+ }
+}
diff --git a/public/site/plugins/notifications/src/location/PageDetails.php b/public/site/plugins/notifications/src/location/PageDetails.php
new file mode 100644
index 0000000..e9b9ddc
--- /dev/null
+++ b/public/site/plugins/notifications/src/location/PageDetails.php
@@ -0,0 +1,21 @@
+page = $page;
+ }
+
+ public function toArray() {
+ return [
+ "uri" => (string) $this->page->uri(),
+ "title" => (string) $this->page->title(),
+ ];
+ }
+}
\ No newline at end of file
diff --git a/public/site/plugins/notifications/src/location/ProjectDetails.php b/public/site/plugins/notifications/src/location/ProjectDetails.php
new file mode 100644
index 0000000..822491c
--- /dev/null
+++ b/public/site/plugins/notifications/src/location/ProjectDetails.php
@@ -0,0 +1,23 @@
+title = (string) $page->title();
+ $this->uri = (string) $page->uri();
+ }
+
+ public function toArray() {
+ return [
+ "title" => $this->title,
+ "uri" => $this->uri
+ ];
+ }
+}
diff --git a/public/site/plugins/notifications/user-methods/send.php b/public/site/plugins/notifications/user-methods/send.php
index 589f6be..28f145f 100644
--- a/public/site/plugins/notifications/user-methods/send.php
+++ b/public/site/plugins/notifications/user-methods/send.php
@@ -1,5 +1,7 @@
notifications()->value())
: [];
- $notifications[] = $notificationData;
+ $newNotification = new Notification($notificationData);
+ $notifications[] = $newNotification->toArray();
$otherUser->update([
'notifications' => $notifications
diff --git a/src/views/Brief.vue b/src/views/Brief.vue
index a50cdc2..dd5cbc9 100644
--- a/src/views/Brief.vue
+++ b/src/views/Brief.vue
@@ -9,11 +9,7 @@
>
Retour au projet
-
@@ -74,7 +74,7 @@ const status = computed(() => {
const correspondingNotification = userStore.notifications.find(
(notification) => notification.id === comment.id
);
- if (correspondingNotification && !correspondingNotification.isRead) {
+ if (correspondingNotification && !correspondingNotification.isread) {
return "unread";
}
return undefined;
diff --git a/src/components/notifications/Comment.vue b/src/components/notifications/Comment.vue
new file mode 100644
index 0000000..df173fd
--- /dev/null
+++ b/src/components/notifications/Comment.vue
@@ -0,0 +1,44 @@
+
+
+
+
+ {{
+ notification.author.name
+ ? notification.author.name
+ : notification.author.email
+ }}
+ : {{ notification.text }}
+
+
+
+
+
diff --git a/src/components/notifications/Content.vue b/src/components/notifications/Content.vue
new file mode 100644
index 0000000..c87a812
--- /dev/null
+++ b/src/components/notifications/Content.vue
@@ -0,0 +1,42 @@
+
+
+
+
+ {{ notification.text }}
+
+
+
+
+
diff --git a/src/components/notifications/Reply.vue b/src/components/notifications/Reply.vue
new file mode 100644
index 0000000..aea2033
--- /dev/null
+++ b/src/components/notifications/Reply.vue
@@ -0,0 +1,49 @@
+
+
+
+
+ {{
+ notification.author.name
+ ? notification.author.name
+ : notification.author.email
+ }}
+ : {{ notification.text }}
+
+
+
+
+
diff --git a/src/stores/notifications.js b/src/stores/notifications.js
new file mode 100644
index 0000000..6c5470d
--- /dev/null
+++ b/src/stores/notifications.js
@@ -0,0 +1,45 @@
+import { defineStore } from "pinia";
+import dayjs from "dayjs";
+import "dayjs/locale/fr";
+import { useRouter } from "vue-router";
+import { useApiStore } from "./api";
+
+export const useNotificationsStore = defineStore("notifications", () => {
+ dayjs.locale("fr");
+
+ const router = useRouter();
+ const api = useApiStore();
+
+ function formatDate(notification) {
+ const notificationDigitalDate = parseInt(
+ dayjs(notification.date).format("YYYYMMDD")
+ );
+ const todayDigitalDate = parseInt(dayjs().format("YYYYMMDD"));
+ const isToday = notificationDigitalDate === todayDigitalDate;
+
+ if (isToday) {
+ return dayjs(notification.date).format("HH:mm");
+ } else if (todayDigitalDate === notificationDigitalDate + 1) {
+ return "hier";
+ } else {
+ return dayjs(notification.date).format("DD MMM YY");
+ }
+ }
+
+ function read(notification) {
+ if (!notification.id) {
+ console.error(
+ "Couldn't change notification status because it has no id."
+ );
+ } else if (notification.isread != true) {
+ api
+ .readNotification(notification.id)
+ .then((res) => {
+ console.log(res);
+ })
+ .catch((err) => console.error("Notification could not be read.", err));
+ }
+ }
+
+ return { formatDate, read };
+});
diff --git a/src/stores/user.js b/src/stores/user.js
index 63d798e..d7c9b03 100644
--- a/src/stores/user.js
+++ b/src/stores/user.js
@@ -13,14 +13,14 @@ export const useUserStore = defineStore("user", () => {
function readNotification(notificationId) {
user.value.notifications.forEach((notification) => {
if (notification.id === notificationId) {
- notification.isRead = true;
+ notification.isread = true;
}
});
}
function readAllNotifications(notificationId) {
user.value.notifications.forEach((notification) => {
- notification.isRead = true;
+ notification.isread = true;
});
}
diff --git a/src/utils/string.js b/src/utils/string.js
index c209cb0..34daf89 100644
--- a/src/utils/string.js
+++ b/src/utils/string.js
@@ -6,6 +6,10 @@ function toPascalCase(string) {
});
}
-const StringUtils = { toPascalCase };
+function urlToPath(url) {
+ return url.replace(window.location.origin, "");
+}
+
+const StringUtils = { toPascalCase, urlToPath };
export default StringUtils;
diff --git a/src/views/Brief.vue b/src/views/Brief.vue
index 1b30267..a50cdc2 100644
--- a/src/views/Brief.vue
+++ b/src/views/Brief.vue
@@ -58,8 +58,7 @@ function setInitialStep() {
function validate() {
api.validateBrief(page.value.uri).then((res) => {
- console.log(res);
- // location.href = "/" + page.value.parent;
+ location.href = "/" + page.value.parent;
});
}
diff --git a/src/views/Notifications.vue b/src/views/Notifications.vue
index 090e5c8..51bf62a 100644
--- a/src/views/Notifications.vue
+++ b/src/views/Notifications.vue
@@ -38,64 +38,11 @@
v-for="notification in sortedNotifications"
:key="notification.id"
>
-
-
-
- {{ notification.text }}
-
-
+
-
@@ -108,7 +55,9 @@ import { useUserStore } from "../stores/user";
import { ref, computed } from "vue";
import { storeToRefs } from "pinia";
import { useApiStore } from "../stores/api";
-import { useRouter } from "vue-router";
+import Comment from "../components/notifications/Comment.vue";
+import Reply from "../components/notifications/Reply.vue";
+import Content from "../components/notifications/Content.vue";
dayjs.locale("fr");
@@ -135,7 +84,11 @@ const tabs = computed(() => {
];
});
-const router = useRouter();
+const notificationComponents = {
+ comment: Comment,
+ "comment-reply": Reply,
+ content: Content,
+};
const sortedNotifications = computed(() => {
return [...notifications.value].sort((a, b) => {
@@ -147,22 +100,6 @@ function changeTab(newValue) {
currentTab.value = newValue;
}
-function formatDate(notification) {
- const notificationDigitalDate = parseInt(
- dayjs(notification.date).format("YYYYMMDD")
- );
- const todayDigitalDate = parseInt(dayjs().format("YYYYMMDD"));
- const isToday = notificationDigitalDate === todayDigitalDate;
-
- if (isToday) {
- return dayjs(notification.date).format("HH:mm");
- } else if (todayDigitalDate === notificationDigitalDate + 1) {
- return "hier";
- } else {
- return dayjs(notification.date).format("DD MMM YY");
- }
-}
-
function readAll() {
try {
api.readAllNotifications();
@@ -171,24 +108,6 @@ function readAll() {
console.log("Could not read all notifications : ", error);
}
}
-
-function read(notification) {
- if (!notification.id) {
- console.error("Couldn't change notification status because it has no id.");
- } else if (!notification.isRead) {
- api
- .readNotification(notification.id)
- .then((res) => {
- router.push(toPath(notification.location.href));
- })
- .catch((err) => console.error("Notification could not be read.", err));
- }
- router.push(toPath(notification.location.href));
-}
-
-function toPath(string) {
- return string.replace(window.location.origin, "");
-}
+
+
+
From 2b059742e9cce7d60fa45a063757181cfa248f65 Mon Sep 17 00:00:00 2001
From: isUnknown
Date: Thu, 19 Dec 2024 10:37:20 +0100
Subject: [PATCH 08/10] comment notification working
---
src/components/notifications/Comment.vue | 4 +++-
src/components/notifications/Content.vue | 5 ++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/components/notifications/Comment.vue b/src/components/notifications/Comment.vue
index df173fd..31cfc42 100644
--- a/src/components/notifications/Comment.vue
+++ b/src/components/notifications/Comment.vue
@@ -3,7 +3,7 @@
class="notification | bg-white rounded-lg | p-16 | flow"
:data-status="notification.isread == true ? 'read' : 'unread'"
data-type="comment"
- @click="read(notification)"
+ @click="router.push(notification.location.dialoguri + '&comments=true')"
>
@@ -37,8 +37,10 @@
diff --git a/src/components/notifications/Content.vue b/src/components/notifications/Content.vue
index c87a812..e61e495 100644
--- a/src/components/notifications/Content.vue
+++ b/src/components/notifications/Content.vue
@@ -3,7 +3,10 @@
class="notification | bg-white rounded-lg | p-16 | flow"
:data-status="notification.isread == 'true' ? 'read' : 'unread'"
data-type="content"
- @click="read(notification)"
+ @click="
+ read(notification);
+ router.push(notification.location.page.uri);
+ "
title="Aller au contenu"
>
From 51409bd0904313c9f80615861d156703b284ad5b Mon Sep 17 00:00:00 2001
From: isUnknown
Date: Thu, 19 Dec 2024 10:38:14 +0100
Subject: [PATCH 09/10] comment reply notification working
---
src/components/notifications/Reply.vue | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/components/notifications/Reply.vue b/src/components/notifications/Reply.vue
index aea2033..4f859ff 100644
--- a/src/components/notifications/Reply.vue
+++ b/src/components/notifications/Reply.vue
@@ -3,7 +3,7 @@
class="notification | bg-white rounded-lg | p-16 | flow"
:data-status="notification.isread == true ? 'read' : 'unread'"
data-type="comment"
- @click="read(notification)"
+ @click="router.push(notification.location.dialoguri + '&comments=true')"
>
@@ -42,8 +42,10 @@
From cce158e80afe0168f7e9476d674329ec8ff76e8c Mon Sep 17 00:00:00 2001
From: isUnknown
Date: Thu, 19 Dec 2024 11:11:43 +0100
Subject: [PATCH 10/10] read notification fully working (content, comment and
reply)
---
src/components/Menu.vue | 4 ++--
src/components/comments/Comment.vue | 9 +++++----
src/components/notifications/Comment.vue | 2 +-
src/components/notifications/Reply.vue | 2 +-
src/components/project/ProjectStep.vue | 1 -
src/stores/user.js | 2 +-
6 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/components/Menu.vue b/src/components/Menu.vue
index dbe088d..e832597 100644
--- a/src/components/Menu.vue
+++ b/src/components/Menu.vue
@@ -117,7 +117,7 @@ const { page } = storeToRefs(usePageStore());
const unreadNotificationsCount = computed(() => {
if (!user.value) return undefined;
const count = user.value.notifications.filter(
- (notification) => notification.isread
+ (notification) => notification.isread != "true"
).length;
if (count === 0) return undefined;
return count;
@@ -164,7 +164,7 @@ function hasUnreadNotification(project) {
if (!user.value) return false;
return user.value.notifications.some((notification) => {
return (
- notification.isread != true &&
+ notification.isread != "true" &&
project.uri.includes(notification.location.project.uri)
);
});
diff --git a/src/components/comments/Comment.vue b/src/components/comments/Comment.vue
index e5d485c..4158934 100644
--- a/src/components/comments/Comment.vue
+++ b/src/components/comments/Comment.vue
@@ -2,7 +2,7 @@