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..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 @@ -6,112 +6,58 @@ 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 + 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: "60.110185093015" - y: "44.594594594595" - replies: [ ] - text: test + 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-11-28T16:30:56+01:00 - id: m41h238q + date: 2024-12-19T10:26:05+01:00 + id: e16a5304-330b-4460-acbd-a6e471f4cda2 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: "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 - 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 + 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 16ff498..09bcce7 100644 --- a/public/site/blueprints/users/admin.yml +++ b/public/site/blueprints/users/admin.yml @@ -4,4 +4,48 @@ home: /panel/pages/projects fields: notifications: - type: hidden + label: Notifications + type: structure + fields: + type: + type: text + disabled: true + location: + type: object + fields: + page: + type: object + fields: + label: Page d'origine + disabled: true + title: + 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: 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 fb21587..bfea8e2 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(), - ], + 'text' => "Nouveau brief", + '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..bdda519 --- /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/classes/Position.php b/public/site/plugins/classes/Position.php new file mode 100644 index 0000000..b85b596 --- /dev/null +++ b/public/site/plugins/classes/Position.php @@ -0,0 +1,32 @@ +pageIndex = $data['pageIndex']; + if (isset($data["x"])) { + $this->x = (float) $data['x']; + $this->y = (float) $data['y']; + } + } + + public function toArray() { + $array = [ + "pageIndex" => $this->pageIndex, + ]; + + if ($this->x) { + $array["x"] = $this->x; + $array["y"] = $this->y; + } + + return $array; + } +} diff --git a/public/site/plugins/classes/location/FileDetails.php b/public/site/plugins/classes/location/FileDetails.php new file mode 100644 index 0000000..ec2fa68 --- /dev/null +++ b/public/site/plugins/classes/location/FileDetails.php @@ -0,0 +1,23 @@ +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/classes/location/Location.php b/public/site/plugins/classes/location/Location.php new file mode 100644 index 0000000..bc91c0c --- /dev/null +++ b/public/site/plugins/classes/location/Location.php @@ -0,0 +1,53 @@ +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"]); + } + if (isset($data["parent"])) { + $this->parent = [ + "author" => [ + "name" => $data["parent"]["author"]["name"], + "email" => $data["parent"]["author"]["email"], + ], + "id" => $data["parent"]["id"] + ]; + } + } + + public function toArray() { + $array = [ + "page" => $this->page->toArray(), + "project" => $this->project->toArray(), + ]; + + if ($this->dialogUri) { + $array["dialogUri"] = $this->dialogUri; + } + + if ($this->file) { + $array["file"] = $this->file; + } + + if ($this->parent) { + $array["parent"] = $this->parent; + } + + return $array; + } +} diff --git a/public/site/plugins/classes/location/PageDetails.php b/public/site/plugins/classes/location/PageDetails.php new file mode 100644 index 0000000..1a38637 --- /dev/null +++ b/public/site/plugins/classes/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/classes/location/ProjectDetails.php b/public/site/plugins/classes/location/ProjectDetails.php new file mode 100644 index 0000000..3de7a99 --- /dev/null +++ b/public/site/plugins/classes/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/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..695d848 100644 --- a/public/site/plugins/comments/routes/create.php +++ b/public/site/plugins/comments/routes/create.php @@ -9,49 +9,51 @@ 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); + $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/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 6c0a70a..91c9ceb 100644 --- a/public/site/plugins/comments/routes/reply.php +++ b/public/site/plugins/comments/routes/reply.php @@ -9,39 +9,42 @@ 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, - ], - 'text' => $data->text, - 'author' => $user, - 'date' => (string) $data->date, - 'id' => $data->id, - 'type' => 'comment' - ]; - - $newReply = new Reply($data); + $comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value()); 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(); } } @@ -50,7 +53,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 47a58b6..407697c 100644 --- a/public/site/plugins/comments/src/BaseComment.php +++ b/public/site/plugins/comments/src/BaseComment.php @@ -1,123 +1,35 @@ 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->location = new Location($data["location"]); + $this->text = $data["text"]; + $this->author = new Author($data["author"]); + $this->date = $data["date"]; + $this->id = $data["id"]; + $this->position = new Position($data['position']); } - public function unread() { - $this->isRead = false; - return $this->isRead; - } - - public function pageIndex() { - $this->position['pageIndex']; - } - 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(), + "position" => $this->position->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..f7c818b 100644 --- a/public/site/plugins/comments/src/Comment.php +++ b/public/site/plugins/comments/src/Comment.php @@ -4,20 +4,17 @@ namespace adrienpayet\comments; class Comment extends BaseComment { - protected $position; + protected string $type = "comment"; + protected array $replies = []; public function __construct($data) { parent::__construct($data); - $this->position = $data['position'] ?? null; - } - - public function position() { - return $this->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/comments/src/Reply.php b/public/site/plugins/comments/src/Reply.php index 4ff9382..e425662 100644 --- a/public/site/plugins/comments/src/Reply.php +++ b/public/site/plugins/comments/src/Reply.php @@ -3,21 +3,15 @@ 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']; - } - - - public function parentId() { - return $this->parentId; } public function toArray() { $array = parent::toArray(); - $array['parentId'] = $this->parentId; + $array['type'] = $this->type; return $array; } diff --git a/public/site/plugins/notifications/index.php b/public/site/plugins/notifications/index.php index 6a0219e..0e05df4 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\\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/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..9d0dfbc --- /dev/null +++ b/public/site/plugins/notifications/src/Notification.php @@ -0,0 +1,42 @@ +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"]; + } + + 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, + ]; + + 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/public/site/plugins/notifications/user-methods/send.php b/public/site/plugins/notifications/user-methods/send.php index 589f6be..b6cd062 100644 --- a/public/site/plugins/notifications/user-methods/send.php +++ b/public/site/plugins/notifications/user-methods/send.php @@ -1,5 +1,7 @@ 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()) - : []; - - $notifications[] = $notificationData; + 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/Menu.vue b/src/components/Menu.vue index bf9fe38..fb1dad8 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 1fd5aa8..4158934 100644 --- a/src/components/comments/Comment.vue +++ b/src/components/comments/Comment.vue @@ -2,7 +2,7 @@
@@ -16,7 +16,7 @@ {{ formatDate(comment.date) }}

@@ -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); @@ -112,9 +113,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"); } } 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/notifications/Comment.vue b/src/components/notifications/Comment.vue new file mode 100644 index 0000000..3e66618 --- /dev/null +++ b/src/components/notifications/Comment.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/components/notifications/Content.vue b/src/components/notifications/Content.vue new file mode 100644 index 0000000..e61e495 --- /dev/null +++ b/src/components/notifications/Content.vue @@ -0,0 +1,45 @@ + + + diff --git a/src/components/notifications/Reply.vue b/src/components/notifications/Reply.vue new file mode 100644 index 0000000..363432d --- /dev/null +++ b/src/components/notifications/Reply.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/components/project/PdfViewer.vue b/src/components/project/PdfViewer.vue index e6af148..6b8a447 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(); @@ -45,6 +50,8 @@ watch(isCommentsOpen, (newVal) => { }); watch(openedFile, (newVal) => { + if (!location.href.includes("virtual-sample")) return; + isViewerDisabled.value = true; setTimeout(() => { diff --git a/src/components/project/ProjectStep.vue b/src/components/project/ProjectStep.vue index 6733659..b6e6aa6 100644 --- a/src/components/project/ProjectStep.vue +++ b/src/components/project/ProjectStep.vue @@ -223,7 +223,6 @@ function getFrontView(track) { const extension = track.files[0].name.split(".")[1]; const frontViewName = "0_" + xFrontView + "." + extension; const frontView = track.files.find((file) => file.name === frontViewName); - console.log(frontView); return frontView; } 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..2577942 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/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, ""); -} + + +