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 - @@ -58,7 +54,8 @@ function setInitialStep() { function validate() { api.validateBrief(page.value.uri).then((res) => { - location.href = "/" + page.value.parent; + console.log(res); + // location.href = "/" + page.value.parent; }); } From 6ab18b10668d5d6baca76055830c109223925976 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 18 Dec 2024 14:11:00 +0100 Subject: [PATCH 02/10] #68 - add notifications display fields in blueprint --- public/site/blueprints/users/admin.yml | 42 +++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/public/site/blueprints/users/admin.yml b/public/site/blueprints/users/admin.yml index 691d29c..1f67800 100644 --- a/public/site/blueprints/users/admin.yml +++ b/public/site/blueprints/users/admin.yml @@ -7,15 +7,47 @@ fields: label: Notifications type: structure fields: + type: + type: text + disabled: true location: type: object fields: page: type: object fields: - uri: + label: Page d'origine + disabled: true + title: type: text - href: - type: url - type: - type: text + uri: + disabled: true + type: text + project: + label: Projet correspondant + type: object + fields: + title: + disabled: true + type: text + uri: + disabled: true + type: text + author: + label: Auteur + type: object + fields: + name: + label: Nom + disabled: true + type: text + email: + type: email + disabled: true + date: + type: date + display: DD-MM-YY + disabled: true + isRead: + type: toggle + disabled: true From 3d4ddc12fc5c3049625aaabd66cc3c3500f9d070 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 18 Dec 2024 15:05:42 +0100 Subject: [PATCH 03/10] #68 - refactor some of the notification classes to classes plugin to share them with comments --- public/site/plugins/classes/Author.php | 2 +- .../src => classes}/Position.php | 2 +- .../src => classes}/location/FileDetails.php | 2 +- .../src => classes}/location/Location.php | 2 +- .../src => classes}/location/PageDetails.php | 2 +- .../location/ProjectDetails.php | 2 +- .../site/plugins/comments/src/BaseComment.php | 97 ++----------------- public/site/plugins/notifications/index.php | 12 +-- .../notifications/src/Notification.php | 6 +- 9 files changed, 22 insertions(+), 105 deletions(-) rename public/site/plugins/{notifications/src => classes}/Position.php (92%) rename public/site/plugins/{notifications/src => classes}/location/FileDetails.php (88%) rename public/site/plugins/{notifications/src => classes}/location/Location.php (94%) rename public/site/plugins/{notifications/src => classes}/location/PageDetails.php (87%) rename public/site/plugins/{notifications/src => classes}/location/ProjectDetails.php (89%) diff --git a/public/site/plugins/classes/Author.php b/public/site/plugins/classes/Author.php index 1df1b9d..bdda519 100644 --- a/public/site/plugins/classes/Author.php +++ b/public/site/plugins/classes/Author.php @@ -1,6 +1,6 @@ template() == 'project' ? $page : $page->parent(); - $file = $data['file']; - $position = $data['position']; - $replies = $data['replies'] ?? []; - $text = $data['text']; - $author = $data['author']; - $date = $data['date']; - $id = $data['id']; - $type = $data['type'] ?? 'comment'; - - $this->location = [ - 'page' => [ - 'uri' => (string) $page->uri(), - 'title' => (string) $page->title(), - ], - 'href' => (string) $data['href'], - 'project' => [ - 'title' => (string) $project->title(), - 'uri' => (string) $project->uri(), - ], - 'file' => $file ? [ - 'uuid' => (string) $file->uuid(), - 'url' => (string) $file->uuid() - ] : false, - ]; - - $this->replies = $replies ?? []; - $this->text = $text; - $this->author = [ - 'name' => (string) $author->name(), - 'email' => (string) $author->email(), - 'uuid' => (string) $author->uuid(), - 'role' => (string) $author->role(), - ]; - $this->date = $date; - $this->id = $id; - $this->type = $type; - $this->isRead = false; - $this->position = $position; - } - - public function location() { - return $this->location; - } - - public function file() { - return $this->location['file']; - } - - public function replies() { - return $this->replies; - } - - public function text() { - return $this->text; - } - - public function author() { - return $this->author; - } - - public function date() { - return $this->date; - } - - public function id() { - return $this->id; - } - - public function type() { - return $this->type; - } - - public function isRead() { - return $this->isRead; - } - - public function read() { - $this->isRead = true; - return $this->isRead; + $this->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 = "false"; } - public function unread() { - $this->isRead = false; - return $this->isRead; - } - - public function pageIndex() { - $this->position['pageIndex']; - } - public function toArray() { return [ 'location' => $this->location, diff --git a/public/site/plugins/notifications/index.php b/public/site/plugins/notifications/index.php index 1a5c6ea..0e05df4 100644 --- a/public/site/plugins/notifications/index.php +++ b/public/site/plugins/notifications/index.php @@ -6,12 +6,12 @@ load([ 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' + 'adrienpayet\\D2P\\data\\Position' => __DIR__ . '/../classes/Position.php', + 'adrienpayet\\D2P\data\Author' => __DIR__ . '/../classes/Author.php', + 'adrienpayet\\D2P\\data\\location\\Location' => __DIR__ . '/../classes/location/Location.php', + 'adrienpayet\\D2P\\data\\location\\PageDetails' => __DIR__ . '/../classes/location/PageDetails.php', + 'adrienpayet\\D2P\\data\\location\\ProjectDetails' => __DIR__ . '/../classes/location/ProjectDetails.php', + 'adrienpayet\\D2P\\data\\location\\FileDetails' => __DIR__ . '/../classes/location/FileDetails.php', ]); diff --git a/public/site/plugins/notifications/src/Notification.php b/public/site/plugins/notifications/src/Notification.php index b9f040b..6f2dc69 100644 --- a/public/site/plugins/notifications/src/Notification.php +++ b/public/site/plugins/notifications/src/Notification.php @@ -1,8 +1,8 @@ author = new Author($data["author"]); $this->date = $data["date"]; $this->id = $data["id"]; - $this->isRead = $data["isRead"]; + $this->isRead = "false"; if ($data["type"] === "comment") { $this->position = new Position($data["position"]); From cf83edc1e64a5a08bf2fb6a93b8cdc5a26fed91e Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 18 Dec 2024 16:26:55 +0100 Subject: [PATCH 04/10] #68 - create comment create working (notification to adapt) --- ...mise-au-service-de-sarkozy-le-boss.pdf.txt | 102 ++++-------------- .../plugins/classes/location/FileDetails.php | 3 +- public/site/plugins/comments/index.php | 9 +- .../site/plugins/comments/routes/create.php | 44 ++++---- .../site/plugins/comments/src/BaseComment.php | 34 +++--- public/site/plugins/comments/src/Comment.php | 15 +-- .../notifications/src/Notification.php | 10 +- .../notifications/user-methods/send.php | 37 ++++--- src/components/comments/Comments.vue | 2 +- src/components/project/PdfViewer.vue | 2 + src/views/Brief.vue | 6 +- 11 files changed, 106 insertions(+), 158 deletions(-) diff --git a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt index 800de37..ded5934 100644 --- a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt +++ b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt @@ -6,112 +6,56 @@ Comments: uri: > projects/miss-dior-blooming-bouquet/proposal title: Offre commerciale - href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' project: title: Miss Dior Blooming Bouquet uri: projects/miss-dior-blooming-bouquet + dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' file: uuid: file://3vTh1tMFeFM2JxaN - url: file://3vTh1tMFeFM2JxaN - position: - pageIndex: 1 - x: "60.110185093015" - y: "44.594594594595" - replies: [ ] + url: > + http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf text: test author: name: Adrien Payet email: adrien.payet@outlook.com uuid: user://WWjXgPWk role: admin - date: 2024-11-28T16:30:56+01:00 - id: m41h238q + date: 2024-12-18T16:20:04+01:00 + id: 6dbb6d56-a6b7-467b-8341-3d8112a73684 + position: + pageIndex: 1 + x: "73.3181571571" + y: "27.272727272727" type: comment - isRead: false + replies: [ ] - location: page: uri: > projects/miss-dior-blooming-bouquet/proposal title: Offre commerciale - href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' project: title: Miss Dior Blooming Bouquet uri: projects/miss-dior-blooming-bouquet + dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' file: uuid: file://3vTh1tMFeFM2JxaN - url: file://3vTh1tMFeFM2JxaN + url: > + http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf + text: est + author: + name: Adrien Payet + email: adrien.payet@outlook.com + uuid: user://WWjXgPWk + role: admin + date: 2024-12-18T16:23:42+01:00 + id: 5b2d93f9-fc44-4a69-955a-bf282fba8966 position: pageIndex: 1 - x: "26.098441098196" - y: "64.864864864865" - replies: [ ] - text: Nouveau commentaire - author: - name: Utilisateur Dior - email: utilisateur@dior.com - uuid: user://HfuumN8s - role: client - date: 2024-12-04T15:00:15+01:00 - id: m49ygks2 + x: '43.56742057598' + y: '65.340909090909' type: comment - isRead: false -- - location: - page: - uri: > - projects/miss-dior-blooming-bouquet/proposal - title: Offre commerciale - href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' - project: - title: Miss Dior Blooming Bouquet - uri: projects/miss-dior-blooming-bouquet - file: - uuid: file://3vTh1tMFeFM2JxaN - url: file://3vTh1tMFeFM2JxaN - position: - pageIndex: 1 - x: "64.481172808783" - y: "76.447876447876" replies: [ ] - text: encore un commentaire - author: - name: Utilisateur Dior - email: utilisateur@dior.com - uuid: user://HfuumN8s - role: client - date: 2024-12-04T15:03:53+01:00 - id: m49yl8zc - type: comment - isRead: false -- - location: - page: - uri: > - projects/miss-dior-blooming-bouquet/proposal - title: Offre commerciale - href: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' - project: - title: Miss Dior Blooming Bouquet - uri: projects/miss-dior-blooming-bouquet - file: - uuid: file://3vTh1tMFeFM2JxaN - url: file://3vTh1tMFeFM2JxaN - position: - pageIndex: 1 - x: '29.786457814876' - y: '83.397683397683' - replies: [ ] - text: et encore un - author: - name: Utilisateur Dior - email: utilisateur@dior.com - uuid: user://HfuumN8s - role: client - date: 2024-12-04T15:05:10+01:00 - id: m49ymwuw - type: comment - isRead: false ---- diff --git a/public/site/plugins/classes/location/FileDetails.php b/public/site/plugins/classes/location/FileDetails.php index 212bc09..ec2fa68 100644 --- a/public/site/plugins/classes/location/FileDetails.php +++ b/public/site/plugins/classes/location/FileDetails.php @@ -1,13 +1,14 @@ uuid = (string) $data->uuid(); $this->url = (string) $data->url(); diff --git a/public/site/plugins/comments/index.php b/public/site/plugins/comments/index.php index 703fd41..92cf431 100644 --- a/public/site/plugins/comments/index.php +++ b/public/site/plugins/comments/index.php @@ -3,7 +3,14 @@ F::loadClasses([ 'adrienpayet\\comments\\BaseComment' => __DIR__ . '/src/BaseComment.php', 'adrienpayet\\comments\\Comment' => __DIR__ . '/src/Comment.php', - 'adrienpayet\\comments\\Reply' => __DIR__ . '/src/Reply.php' + 'adrienpayet\\comments\\Reply' => __DIR__ . '/src/Reply.php', + + 'adrienpayet\\D2P\\data\\Position' => __DIR__ . '/../classes/Position.php', + 'adrienpayet\\D2P\data\Author' => __DIR__ . '/../classes/Author.php', + 'adrienpayet\\D2P\\data\\location\\Location' => __DIR__ . '/../classes/location/Location.php', + 'adrienpayet\\D2P\\data\\location\\PageDetails' => __DIR__ . '/../classes/location/PageDetails.php', + 'adrienpayet\\D2P\\data\\location\\ProjectDetails' => __DIR__ . '/../classes/location/ProjectDetails.php', + 'adrienpayet\\D2P\\data\\location\\FileDetails' => __DIR__ . '/../classes/location/FileDetails.php', ]); Kirby::plugin('adrienpayet/kirby4-comments', [ diff --git a/public/site/plugins/comments/routes/create.php b/public/site/plugins/comments/routes/create.php index b4f84b9..cd1d26c 100644 --- a/public/site/plugins/comments/routes/create.php +++ b/public/site/plugins/comments/routes/create.php @@ -9,49 +9,53 @@ return [ $json = file_get_contents('php://input'); $data = json_decode($json); - $parsedUrl = parse_url($data->path); + $parsedUrl = parse_url($data->dialogUri); $query = $parsedUrl['query'] ?? null; parse_str($query, $queryParams); $stepSlug = $queryParams['dialog'] ?? null; $targetPageUri = $stepSlug ? $parsedUrl['path'] . '/' . $stepSlug : $parsedUrl['path']; + $project = page($parsedUrl['path']); $page = page($targetPageUri); $file = $page->file($data->fileName); - $user = kirby()->user($data->userUuid); - + $user = kirby()->user($data->userUuid); $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); - $data = [ - 'href' => $data->path, - 'page' => $page, - 'file' => $file, - 'position' => [ - 'pageIndex' => $data->position->pageIndex, - 'x' => $data->position->x, - 'y' => $data->position->y + $commentData = [ + "location" => [ + "page" => $page, + "project" => $project, + "dialogUri" => $data->dialogUri, + "file" => $file ], - 'replies' => [], - 'text' => $data->text, - 'author' => $user, - 'date' => (string) $data->date, - 'id' => $data->id, - 'type' => 'comment' + "position" => [ + "pageIndex" => $data->position->pageIndex, + "x" => $data->position->x, + "y" => $data->position->y + ], + "date" => (string) $data->date, + "text" => $data->text, + "author" => kirby()->user(), + "id" => Str::uuid(), + "type" => "comment", ]; - $newComment = new Comment($data); + $user->sendNotification($project, $commentData); + + $newComment = new Comment($commentData); $comments[] = $newComment->toArray(); $newFile = $file->update([ 'comments' => $comments - ]); + ]); echo json_encode(getFileData($newFile)); try { - $user->sendNotification($page->parent(), $newComment->toArray()); + $user->sendNotification($project, $commentData); } catch (\Throwable $th) { echo json_encode([ "error" => $th->getMessage() . " in " . $th->getFile() . " line " . $th->getLine(), diff --git a/public/site/plugins/comments/src/BaseComment.php b/public/site/plugins/comments/src/BaseComment.php index e9d55c2..67c89ed 100644 --- a/public/site/plugins/comments/src/BaseComment.php +++ b/public/site/plugins/comments/src/BaseComment.php @@ -1,40 +1,32 @@ 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 = "false"; } public function toArray() { return [ - 'location' => $this->location, - 'position' => $this->position, - 'replies' => $this->replies, - 'text' => $this->text, - 'author' => $this->author, - 'date' => $this->date, - 'id' => $this->id, - 'type' => $this->type, - 'isRead' => $this->isRead + "location" => $this->location->toArray(), + "text" => $this->text, + "author" => $this->author->toArray(), + "date" => $this->date, + "id" => $this->id, ]; } } diff --git a/public/site/plugins/comments/src/Comment.php b/public/site/plugins/comments/src/Comment.php index 64cfb61..223223b 100644 --- a/public/site/plugins/comments/src/Comment.php +++ b/public/site/plugins/comments/src/Comment.php @@ -1,23 +1,26 @@ position = $data['position'] ?? null; - } - - public function position() { - return $this->position; + if (isset($data["position"])) { + $this->position = new Position($data['position']); + } } public function toArray() { $array = parent::toArray(); $array['position'] = $this->position; + $array['type'] = $this->type; + $array['replies'] = $this->replies; return $array; } diff --git a/public/site/plugins/notifications/src/Notification.php b/public/site/plugins/notifications/src/Notification.php index 6f2dc69..614413a 100644 --- a/public/site/plugins/notifications/src/Notification.php +++ b/public/site/plugins/notifications/src/Notification.php @@ -12,7 +12,7 @@ class Notification protected Author $author; protected string $date; protected string $id; - protected string $isRead; + protected string $isRead = "false"; protected ?Position $position = null; @@ -23,11 +23,6 @@ class Notification $this->author = new Author($data["author"]); $this->date = $data["date"]; $this->id = $data["id"]; - $this->isRead = "false"; - - if ($data["type"] === "comment") { - $this->position = new Position($data["position"]); - } } public function toArray() { @@ -40,9 +35,6 @@ class Notification "id" => $this->id, "isRead" => $this->isRead, ]; - if ($this->type === "comment") { - $array["position"] = $this->position->toArray(); - } return $array; } diff --git a/public/site/plugins/notifications/user-methods/send.php b/public/site/plugins/notifications/user-methods/send.php index 28f145f..b6cd062 100644 --- a/public/site/plugins/notifications/user-methods/send.php +++ b/public/site/plugins/notifications/user-methods/send.php @@ -16,27 +16,26 @@ use adrienpayet\notifications\Notification; */ return function ($project, $notificationData) { - $recipients = $project->managers()->without($this); + $recipients = $project->managers()->without($this); - if ($recipients->isEmpty()) return; + if ($recipients->isEmpty()) return; - $notificationData['isRead'] = false; + $newNotification = new Notification($notificationData); - foreach ($recipients as $otherUser) { - try { - $notifications = $otherUser->notifications()->isNotEmpty() - ? Yaml::decode($otherUser->notifications()->value()) - : []; - - $newNotification = new Notification($notificationData); - $notifications[] = $newNotification->toArray(); + foreach ($recipients as $otherUser) { + try { + $notifications = $otherUser->notifications()->isNotEmpty() + ? Yaml::decode($otherUser->notifications()->value()) + : []; + + $notifications[] = $newNotification->toArray(); - $otherUser->update([ - 'notifications' => $notifications - ]); - } catch (\Throwable $th) { - error_log("Notification error for user " . $otherUser->email() . ": " . $th->getMessage()); - throw new Exception("Error updating notifications: " . $th->getMessage() . ' line ' . $th->getLine(), 1); - } - } + $otherUser->update([ + 'notifications' => $notifications + ]); + } catch (\Throwable $th) { + error_log("Notification error for user " . $otherUser->email() . ": " . $th->getMessage()); + throw new Exception("Error updating notifications: " . $th->getMessage() . ' line ' . $th->getLine(), 1); + } + } }; diff --git a/src/components/comments/Comments.vue b/src/components/comments/Comments.vue index d2f366f..7fb7d5f 100644 --- a/src/components/comments/Comments.vue +++ b/src/components/comments/Comments.vue @@ -178,7 +178,7 @@ function handleSubmit(event = null) { } const date = dayjs().format(); const newComment = { - path: route.fullPath, + dialogUri: route.fullPath, fileName: openedFile ? openedFile.value.name : false, userUuid: user.uuid, text: draftComment.value.text, diff --git a/src/components/project/PdfViewer.vue b/src/components/project/PdfViewer.vue index 5aa8b56..834e16e 100644 --- a/src/components/project/PdfViewer.vue +++ b/src/components/project/PdfViewer.vue @@ -45,6 +45,8 @@ watch(isCommentsOpen, (newVal) => { }); watch(openedFile, (newVal) => { + if (!location.href.includes("virtual-sample")) return; + isViewerDisabled.value = true; setTimeout(() => { diff --git a/src/views/Brief.vue b/src/views/Brief.vue index dd5cbc9..1b30267 100644 --- a/src/views/Brief.vue +++ b/src/views/Brief.vue @@ -9,7 +9,11 @@ > Retour au projet - From 231bb21a4f6ee4044c28ce517a75496f35da2cc7 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 18 Dec 2024 18:22:41 +0100 Subject: [PATCH 05/10] #68 - reply working + remove marker on comment delete --- ...mise-au-service-de-sarkozy-le-boss.pdf.txt | 59 +------------------ public/site/plugins/classes/Position.php | 21 ++++--- .../plugins/classes/location/Location.php | 15 +++++ .../site/plugins/comments/routes/create.php | 2 - public/site/plugins/comments/routes/reply.php | 36 ++++++----- .../site/plugins/comments/src/BaseComment.php | 6 +- public/site/plugins/comments/src/Comment.php | 6 -- public/site/plugins/comments/src/Reply.php | 9 ++- src/components/project/PdfViewer.vue | 5 ++ 9 files changed, 64 insertions(+), 95 deletions(-) diff --git a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt index ded5934..6872059 100644 --- a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt +++ b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt @@ -1,61 +1,4 @@ -Comments: - -- - location: - page: - uri: > - projects/miss-dior-blooming-bouquet/proposal - title: Offre commerciale - project: - title: Miss Dior Blooming Bouquet - uri: projects/miss-dior-blooming-bouquet - dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' - file: - uuid: file://3vTh1tMFeFM2JxaN - url: > - http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf - text: test - author: - name: Adrien Payet - email: adrien.payet@outlook.com - uuid: user://WWjXgPWk - role: admin - date: 2024-12-18T16:20:04+01:00 - id: 6dbb6d56-a6b7-467b-8341-3d8112a73684 - position: - pageIndex: 1 - x: "73.3181571571" - y: "27.272727272727" - type: comment - replies: [ ] -- - location: - page: - uri: > - projects/miss-dior-blooming-bouquet/proposal - title: Offre commerciale - project: - title: Miss Dior Blooming Bouquet - uri: projects/miss-dior-blooming-bouquet - dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' - file: - uuid: file://3vTh1tMFeFM2JxaN - url: > - http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf - text: est - author: - name: Adrien Payet - email: adrien.payet@outlook.com - uuid: user://WWjXgPWk - role: admin - date: 2024-12-18T16:23:42+01:00 - id: 5b2d93f9-fc44-4a69-955a-bf282fba8966 - position: - pageIndex: 1 - x: '43.56742057598' - y: '65.340909090909' - type: comment - replies: [ ] +Comments: ---- diff --git a/public/site/plugins/classes/Position.php b/public/site/plugins/classes/Position.php index 5707606..b85b596 100644 --- a/public/site/plugins/classes/Position.php +++ b/public/site/plugins/classes/Position.php @@ -5,21 +5,28 @@ namespace adrienpayet\D2P\data; class Position { public int $pageIndex; - public float $x; - public float $y; + public ?float $x = null; + public ?float $y = null; public function __construct(array $data) { $this->pageIndex = $data['pageIndex']; - $this->x = (float) $data['x']; - $this->y = (float) $data['y']; + if (isset($data["x"])) { + $this->x = (float) $data['x']; + $this->y = (float) $data['y']; + } } public function toArray() { - return [ + $array = [ "pageIndex" => $this->pageIndex, - "x" => $this->x, - "y" => $this->y, ]; + + if ($this->x) { + $array["x"] = $this->x; + $array["y"] = $this->y; + } + + return $array; } } diff --git a/public/site/plugins/classes/location/Location.php b/public/site/plugins/classes/location/Location.php index f1e8e3c..c9ace9b 100644 --- a/public/site/plugins/classes/location/Location.php +++ b/public/site/plugins/classes/location/Location.php @@ -8,6 +8,7 @@ class Location protected ?string $dialogUri = null; protected ProjectDetails $project; protected ?FileDetails $file = null; + protected ?string $parentCommentId = null; public function __construct(array $data) { @@ -18,6 +19,17 @@ class Location if (isset($data['file'])) { $this->file = new FileDetails($data["file"]); } + if (isset($data["parentCommentId"])) { + $this->parentCommentId(); + } + } + + public function setParentCommentId($id) { + $this->parentCommentId = $id; + } + + public function parentId() { + return $this->parentCommentId; } public function toArray() { @@ -28,6 +40,9 @@ class Location if ($this->dialogUri) { $array["dialogUri"] = $this->dialogUri; + } + + if ($this->file) { $array["file"] = $this->file; } diff --git a/public/site/plugins/comments/routes/create.php b/public/site/plugins/comments/routes/create.php index cd1d26c..695d848 100644 --- a/public/site/plugins/comments/routes/create.php +++ b/public/site/plugins/comments/routes/create.php @@ -42,8 +42,6 @@ return [ "type" => "comment", ]; - $user->sendNotification($project, $commentData); - $newComment = new Comment($commentData); $comments[] = $newComment->toArray(); diff --git a/public/site/plugins/comments/routes/reply.php b/public/site/plugins/comments/routes/reply.php index 6c0a70a..383b19d 100644 --- a/public/site/plugins/comments/routes/reply.php +++ b/public/site/plugins/comments/routes/reply.php @@ -9,36 +9,40 @@ return [ $json = file_get_contents('php://input'); $data = json_decode($json); - $parsedUrl = parse_url($data->path); + $parsedUrl = parse_url($data->dialogUri); $query = $parsedUrl['query'] ?? null; parse_str($query, $queryParams); $stepSlug = $queryParams['dialog'] ?? null; $targetPageUri = $stepSlug ? $parsedUrl['path'] . '/' . $stepSlug : $parsedUrl['path']; + $project = page($parsedUrl['path']); $page = page($targetPageUri); $file = $page->file($data->fileName); - $user = kirby()->user($data->userUuid); + $user = kirby()->user($data->userUuid); $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); - $data = [ - 'href' => $data->path, - 'page' => $page, - 'parentId' => $data->parentId, - 'file' => $file, - 'position' => [ - 'pageIndex' => $data->position->pageIndex, + $replyData = [ + "location" => [ + "page" => $page, + "project" => $project, + "dialogUri" => $data->dialogUri, + "file" => $file, ], - 'text' => $data->text, - 'author' => $user, - 'date' => (string) $data->date, - 'id' => $data->id, - 'type' => 'comment' + "parentId" => $data->parentId, + "position" => [ + "pageIndex" => $data->position->pageIndex, + ], + "date" => (string) $data->date, + "text" => $data->text, + "author" => kirby()->user(), + "id" => Str::uuid(), + "type" => "comment", ]; - $newReply = new Reply($data); + $newReply = new Reply($replyData); foreach ($comments as &$comment) { if ($comment['id'] === $newReply->parentId()) { @@ -50,7 +54,7 @@ return [ 'comments' => $comments ]); - $user->sendNotification($page->parent(), $newReply->toArray()); + $user->sendNotification($project, $replyData); return getFileData($newFile); } diff --git a/public/site/plugins/comments/src/BaseComment.php b/public/site/plugins/comments/src/BaseComment.php index 67c89ed..a98d40e 100644 --- a/public/site/plugins/comments/src/BaseComment.php +++ b/public/site/plugins/comments/src/BaseComment.php @@ -3,14 +3,16 @@ namespace adrienpayet\comments; use adrienpayet\D2P\data\location\Location; use adrienpayet\D2P\data\Author; +use adrienpayet\D2P\data\Position; class BaseComment { protected string $type; protected Location $location; - protected string $text; protected Author $author; + protected string $text; protected string $date; protected string $id; + protected Position $position; public function __construct($data) { $this->location = new Location($data["location"]); @@ -18,11 +20,13 @@ class BaseComment { $this->author = new Author($data["author"]); $this->date = $data["date"]; $this->id = $data["id"]; + $this->position = new Position($data['position']); } public function toArray() { return [ "location" => $this->location->toArray(), + "position" => $this->position->toArray(), "text" => $this->text, "author" => $this->author->toArray(), "date" => $this->date, diff --git a/public/site/plugins/comments/src/Comment.php b/public/site/plugins/comments/src/Comment.php index 223223b..f7c818b 100644 --- a/public/site/plugins/comments/src/Comment.php +++ b/public/site/plugins/comments/src/Comment.php @@ -1,24 +1,18 @@ position = new Position($data['position']); - } } public function toArray() { $array = parent::toArray(); - $array['position'] = $this->position; $array['type'] = $this->type; $array['replies'] = $this->replies; diff --git a/public/site/plugins/comments/src/Reply.php b/public/site/plugins/comments/src/Reply.php index 4ff9382..7ab2b04 100644 --- a/public/site/plugins/comments/src/Reply.php +++ b/public/site/plugins/comments/src/Reply.php @@ -3,21 +3,20 @@ namespace adrienpayet\comments; class Reply extends BaseComment { - protected $parentId; + protected string $type = "comment-reply"; public function __construct($data) { parent::__construct($data); - $this->parentId = $data['parentId']; + $this->location->setParentCommentId($data["parentId"]); } - public function parentId() { - return $this->parentId; + return $this->location->parentId(); } public function toArray() { $array = parent::toArray(); - $array['parentId'] = $this->parentId; + $array['type'] = $this->type; return $array; } diff --git a/src/components/project/PdfViewer.vue b/src/components/project/PdfViewer.vue index 834e16e..7cc203c 100644 --- a/src/components/project/PdfViewer.vue +++ b/src/components/project/PdfViewer.vue @@ -36,6 +36,11 @@ const draftComment = ref(null); const isViewerDisabled = ref(false); +watch(openedFile, () => { + removeCommentMarkers(); + setCommentMarkers(); +}); + watch(isCommentsOpen, (newVal) => { if (newVal) { setCommentMarkers(); From ffb8252808a53173168ab1b4b780b5e1d5867e68 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Wed, 18 Dec 2024 18:39:45 +0100 Subject: [PATCH 06/10] delete reply working --- public/site/plugins/classes/location/Location.php | 4 ++++ public/site/plugins/comments/routes/delete.php | 4 ++-- public/site/plugins/comments/routes/reply.php | 2 +- src/components/comments/Comment.vue | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/public/site/plugins/classes/location/Location.php b/public/site/plugins/classes/location/Location.php index c9ace9b..8c85bfd 100644 --- a/public/site/plugins/classes/location/Location.php +++ b/public/site/plugins/classes/location/Location.php @@ -46,6 +46,10 @@ class Location $array["file"] = $this->file; } + if ($this->parentCommentId) { + $array["parentId"] = $this->parentCommentId; + } + return $array; } } diff --git a/public/site/plugins/comments/routes/delete.php b/public/site/plugins/comments/routes/delete.php index 4bf55c3..b7b0895 100644 --- a/public/site/plugins/comments/routes/delete.php +++ b/public/site/plugins/comments/routes/delete.php @@ -10,13 +10,13 @@ return [ $page = page($data->location->page->uri); $project = page($data->location->project->uri); $file = $page->file($data->location->file->uuid); - $isReply = $data->parentId ?? false; + $isReply = $data->location->parentId ?? false; $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); foreach ($comments as $key => &$comment) { if ($isReply) { - if ($comment['id'] === $data->parentId) { + if ($comment['id'] === $data->location->parentId) { foreach ($comment['replies'] as $replyKey => $reply) { if ($reply['id'] === $data->id) { unset($comment['replies'][$replyKey]); diff --git a/public/site/plugins/comments/routes/reply.php b/public/site/plugins/comments/routes/reply.php index 383b19d..3eb04c2 100644 --- a/public/site/plugins/comments/routes/reply.php +++ b/public/site/plugins/comments/routes/reply.php @@ -22,7 +22,7 @@ return [ $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()); $replyData = [ "location" => [ diff --git a/src/components/comments/Comment.vue b/src/components/comments/Comment.vue index 1fd5aa8..9f6db40 100644 --- a/src/components/comments/Comment.vue +++ b/src/components/comments/Comment.vue @@ -112,9 +112,10 @@ async function read() { async function deleteComment(event) { event.stopPropagation(); + console.log(comment); const newFile = await api.deleteComment(comment); dialog.updateFile(newFile); - if (comment.parentId) { + if (comment.type === "comment-reply") { emits("close:comment"); } } From 94c5737245acb038ec9b976b29db604473d56468 Mon Sep 17 00:00:00 2001 From: isUnknown Date: Thu, 19 Dec 2024 10:32:48 +0100 Subject: [PATCH 07/10] content notification read working --- ...mise-au-service-de-sarkozy-le-boss.pdf.txt | 61 ++++++++- ...venchy-lcp-morphoz-vc-50-100-200ml.pdf.txt | 4 +- public/site/blueprints/users/admin.yml | 6 +- public/site/config/routes/validate-brief.php | 2 +- .../plugins/classes/location/Location.php | 24 ++-- public/site/plugins/comments/routes/reply.php | 41 +++--- .../site/plugins/comments/src/BaseComment.php | 1 - public/site/plugins/comments/src/Reply.php | 5 - .../notifications/src/Notification.php | 4 +- .../notifications/user-methods/read.php | 2 +- .../notifications/user-methods/readAll.php | 2 +- src/components/Menu.vue | 4 +- src/components/comments/Comment.vue | 4 +- src/components/notifications/Comment.vue | 44 ++++++ src/components/notifications/Content.vue | 42 ++++++ src/components/notifications/Reply.vue | 49 +++++++ src/stores/notifications.js | 45 +++++++ src/stores/user.js | 4 +- src/utils/string.js | 6 +- src/views/Brief.vue | 3 +- src/views/Notifications.vue | 127 ++++-------------- 21 files changed, 317 insertions(+), 163 deletions(-) create mode 100644 src/components/notifications/Comment.vue create mode 100644 src/components/notifications/Content.vue create mode 100644 src/components/notifications/Reply.vue create mode 100644 src/stores/notifications.js diff --git a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt index 6872059..623c4e1 100644 --- a/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt +++ b/public/content/projects/1_miss-dior-blooming-bouquet/2_proposal/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf.txt @@ -1,4 +1,63 @@ -Comments: +Comments: + +- + location: + page: + uri: > + projects/miss-dior-blooming-bouquet/proposal + title: Offre commerciale + project: + title: Miss Dior Blooming Bouquet + uri: projects/miss-dior-blooming-bouquet + dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' + file: + uuid: file://3vTh1tMFeFM2JxaN + url: > + http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf + position: + pageIndex: 1 + x: "57.105131038425" + y: "13.127413127413" + text: un commentaire + author: + name: Adrien Payet + email: adrien.payet@outlook.com + uuid: user://WWjXgPWk + role: admin + date: 2024-12-19T10:26:05+01:00 + id: e16a5304-330b-4460-acbd-a6e471f4cda2 + type: comment + replies: + - + location: + page: + uri: > + projects/miss-dior-blooming-bouquet/proposal + title: Offre commerciale + project: + title: Miss Dior Blooming Bouquet + uri: projects/miss-dior-blooming-bouquet + dialogUri: '/projects/miss-dior-blooming-bouquet?dialog=proposal&fileIndex=0' + file: + uuid: file://3vTh1tMFeFM2JxaN + url: > + http://localhost:8888/media/pages/projects/miss-dior-blooming-bouquet/proposal/788ddebfe3-1731941917/des-textos-revelent-comment-bfm-sest-mise-au-service-de-sarkozy-le-boss.pdf + parent: + author: + name: Adrien Payet + email: adrien.payet@outlook.com + id: e16a5304-330b-4460-acbd-a6e471f4cda2 + position: + pageIndex: 1 + text: une réponse + author: + name: Adrien Payet + email: adrien.payet@outlook.com + uuid: user://WWjXgPWk + role: admin + date: 2024-12-19T10:26:09+01:00 + id: bc64e066-299d-4d80-a651-2c17482cda2f + type: comment-reply ---- diff --git a/public/content/projects/3_projet-lcp2025/2_proposal/20241203-devis-givenchy-lcp-morphoz-vc-50-100-200ml.pdf.txt b/public/content/projects/3_projet-lcp2025/2_proposal/20241203-devis-givenchy-lcp-morphoz-vc-50-100-200ml.pdf.txt index eec360f..ac4afe7 100644 --- a/public/content/projects/3_projet-lcp2025/2_proposal/20241203-devis-givenchy-lcp-morphoz-vc-50-100-200ml.pdf.txt +++ b/public/content/projects/3_projet-lcp2025/2_proposal/20241203-devis-givenchy-lcp-morphoz-vc-50-100-200ml.pdf.txt @@ -26,7 +26,7 @@ Comments: date: 2024-12-03T13:42:18+01:00 id: m48g8hrb type: comment - isRead: false + isread: false - location: page: @@ -53,7 +53,7 @@ Comments: date: 2024-12-03T13:43:08+01:00 id: m48g9kau type: comment - isRead: false + isread: false ---- diff --git a/public/site/blueprints/users/admin.yml b/public/site/blueprints/users/admin.yml index 1f67800..09bcce7 100644 --- a/public/site/blueprints/users/admin.yml +++ b/public/site/blueprints/users/admin.yml @@ -45,9 +45,7 @@ fields: type: email disabled: true date: - type: date - display: DD-MM-YY - disabled: true - isRead: + type: hidden + isread: type: toggle disabled: true diff --git a/public/site/config/routes/validate-brief.php b/public/site/config/routes/validate-brief.php index d9d7e32..bfea8e2 100644 --- a/public/site/config/routes/validate-brief.php +++ b/public/site/config/routes/validate-brief.php @@ -26,7 +26,7 @@ return [ 'dialogUri' => (string) $dialogUri, ], 'date' => $dateTime->format('Y-m-d\TH:i:sP'), - 'text' => "Brief (" . $project->title()->value() . ")", + 'text' => "Nouveau brief", 'author' => kirby()->user(), 'id' => Str::uuid(), 'type' => 'content' diff --git a/public/site/plugins/classes/location/Location.php b/public/site/plugins/classes/location/Location.php index 8c85bfd..bc91c0c 100644 --- a/public/site/plugins/classes/location/Location.php +++ b/public/site/plugins/classes/location/Location.php @@ -8,7 +8,7 @@ class Location protected ?string $dialogUri = null; protected ProjectDetails $project; protected ?FileDetails $file = null; - protected ?string $parentCommentId = null; + protected ?array $parent = null; public function __construct(array $data) { @@ -19,19 +19,17 @@ class Location if (isset($data['file'])) { $this->file = new FileDetails($data["file"]); } - if (isset($data["parentCommentId"])) { - $this->parentCommentId(); + if (isset($data["parent"])) { + $this->parent = [ + "author" => [ + "name" => $data["parent"]["author"]["name"], + "email" => $data["parent"]["author"]["email"], + ], + "id" => $data["parent"]["id"] + ]; } } - public function setParentCommentId($id) { - $this->parentCommentId = $id; - } - - public function parentId() { - return $this->parentCommentId; - } - public function toArray() { $array = [ "page" => $this->page->toArray(), @@ -46,8 +44,8 @@ class Location $array["file"] = $this->file; } - if ($this->parentCommentId) { - $array["parentId"] = $this->parentCommentId; + if ($this->parent) { + $array["parent"] = $this->parent; } return $array; diff --git a/public/site/plugins/comments/routes/reply.php b/public/site/plugins/comments/routes/reply.php index 3eb04c2..91c9ceb 100644 --- a/public/site/plugins/comments/routes/reply.php +++ b/public/site/plugins/comments/routes/reply.php @@ -24,28 +24,27 @@ return [ $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); - $replyData = [ - "location" => [ - "page" => $page, - "project" => $project, - "dialogUri" => $data->dialogUri, - "file" => $file, - ], - "parentId" => $data->parentId, - "position" => [ - "pageIndex" => $data->position->pageIndex, - ], - "date" => (string) $data->date, - "text" => $data->text, - "author" => kirby()->user(), - "id" => Str::uuid(), - "type" => "comment", - ]; - - $newReply = new Reply($replyData); - foreach ($comments as &$comment) { - if ($comment['id'] === $newReply->parentId()) { + $isParentComment = $comment['id'] === $data->parentId; + if ($isParentComment) { + $replyData = [ + "location" => [ + "page" => $page, + "project" => $project, + "dialogUri" => $data->dialogUri, + "file" => $file, + "parent" => $comment + ], + "position" => [ + "pageIndex" => $data->position->pageIndex, + ], + "date" => (string) $data->date, + "text" => $data->text, + "author" => kirby()->user(), + "id" => Str::uuid(), + "type" => "comment-reply", + ]; + $newReply = new Reply($replyData); $comment['replies'][] = $newReply->toArray(); } } diff --git a/public/site/plugins/comments/src/BaseComment.php b/public/site/plugins/comments/src/BaseComment.php index a98d40e..407697c 100644 --- a/public/site/plugins/comments/src/BaseComment.php +++ b/public/site/plugins/comments/src/BaseComment.php @@ -6,7 +6,6 @@ use adrienpayet\D2P\data\Author; use adrienpayet\D2P\data\Position; class BaseComment { - protected string $type; protected Location $location; protected Author $author; protected string $text; diff --git a/public/site/plugins/comments/src/Reply.php b/public/site/plugins/comments/src/Reply.php index 7ab2b04..e425662 100644 --- a/public/site/plugins/comments/src/Reply.php +++ b/public/site/plugins/comments/src/Reply.php @@ -7,11 +7,6 @@ class Reply extends BaseComment { public function __construct($data) { parent::__construct($data); - $this->location->setParentCommentId($data["parentId"]); - } - - public function parentId() { - return $this->location->parentId(); } public function toArray() { diff --git a/public/site/plugins/notifications/src/Notification.php b/public/site/plugins/notifications/src/Notification.php index 614413a..9d0dfbc 100644 --- a/public/site/plugins/notifications/src/Notification.php +++ b/public/site/plugins/notifications/src/Notification.php @@ -12,7 +12,7 @@ class Notification protected Author $author; protected string $date; protected string $id; - protected string $isRead = "false"; + protected string $isread = "false"; protected ?Position $position = null; @@ -33,7 +33,7 @@ class Notification "author" => $this->author->toArray(), "date" => $this->date, "id" => $this->id, - "isRead" => $this->isRead, + "isread" => $this->isread, ]; return $array; diff --git a/public/site/plugins/notifications/user-methods/read.php b/public/site/plugins/notifications/user-methods/read.php index cb61db0..01f0c3f 100644 --- a/public/site/plugins/notifications/user-methods/read.php +++ b/public/site/plugins/notifications/user-methods/read.php @@ -10,7 +10,7 @@ return function($notificationId) { foreach ($notifications as $key => $notification) { if (!isset($notification['id'])) continue; if ($notification['id'] === $notificationId) { - $notifications[$key]['isRead'] = true; + $notifications[$key]['isread'] = "true"; $newNotification = $notifications[$key]; } } diff --git a/public/site/plugins/notifications/user-methods/readAll.php b/public/site/plugins/notifications/user-methods/readAll.php index 4a16156..988547a 100644 --- a/public/site/plugins/notifications/user-methods/readAll.php +++ b/public/site/plugins/notifications/user-methods/readAll.php @@ -8,7 +8,7 @@ return function() { $newNotification = null; foreach ($notifications as $key => $notification) { - $notifications[$key]['isRead'] = true; + $notifications[$key]['isread'] = true; } $updatedUser = $this->update([ diff --git a/src/components/Menu.vue b/src/components/Menu.vue index ea63424..dbe088d 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 ).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 9f6db40..e5d485c 100644 --- a/src/components/comments/Comment.vue +++ b/src/components/comments/Comment.vue @@ -16,7 +16,7 @@ {{ formatDate(comment.date) }}

@@ -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 @@ + + + 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 @@ + + + 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 @@ + + + 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" > -
-
-

- Nouveau - {{ - notification.type === "comment" ? "commentaire" : "contenu" - }} - {{ - notification.location.project.title - }} - -

-
-

- {{ 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 @@

@@ -70,11 +70,11 @@ const api = useApiStore(); const dialog = useDialogStore(); // Functions -const status = computed(() => { +const getStatus = computed(() => { const correspondingNotification = userStore.notifications.find( (notification) => notification.id === comment.id ); - if (correspondingNotification && !correspondingNotification.isread) { + if (correspondingNotification && correspondingNotification.isread != "true") { return "unread"; } return undefined; @@ -101,9 +101,10 @@ function closeAddField() { } async function read() { - if (status.value !== "unread") return; + if (getStatus.value !== "unread") return; try { const newNotification = await api.readNotification(comment.id); + console.log(newNotification); userStore.readNotification(comment.id); } catch (error) { console.log("Erreur lors de la lecture de la notification : ", error); diff --git a/src/components/notifications/Comment.vue b/src/components/notifications/Comment.vue index 31cfc42..3e66618 100644 --- a/src/components/notifications/Comment.vue +++ b/src/components/notifications/Comment.vue @@ -1,7 +1,7 @@