new content notification working for client brief
This commit is contained in:
parent
8ae00d7657
commit
c1d2c73118
9 changed files with 277 additions and 70 deletions
|
|
@ -28,9 +28,93 @@ Comments:
|
||||||
url: file://s0lNtRA0Z7ybTCWG
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
position:
|
position:
|
||||||
pageIndex: 1
|
pageIndex: 1
|
||||||
x: '27.05459466102'
|
x: "27.05459466102"
|
||||||
y: '35.135135135135'
|
y: "35.135135135135"
|
||||||
replies: [ ]
|
replies:
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
replies: [ ]
|
||||||
|
text: test
|
||||||
|
author:
|
||||||
|
name: Utilisateur Dior
|
||||||
|
email: utilisateur@dior.com
|
||||||
|
uuid: user://HfuumN8s
|
||||||
|
role: client
|
||||||
|
date: 2024-11-22T08:08:39+01:00
|
||||||
|
id: m3seh19r
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
parentId: m3sdsq23
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
replies: [ ]
|
||||||
|
text: Deuxième réponse
|
||||||
|
author:
|
||||||
|
name: Utilisateur Dior
|
||||||
|
email: utilisateur@dior.com
|
||||||
|
uuid: user://HfuumN8s
|
||||||
|
role: client
|
||||||
|
date: 2024-11-22T08:10:12+01:00
|
||||||
|
id: m3sej19k
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
parentId: m3sdsq23
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
replies: [ ]
|
||||||
|
text: Encore
|
||||||
|
author:
|
||||||
|
name: Utilisateur Dior
|
||||||
|
email: utilisateur@dior.com
|
||||||
|
uuid: user://HfuumN8s
|
||||||
|
role: client
|
||||||
|
date: 2024-11-22T08:12:39+01:00
|
||||||
|
id: m3sem6sz
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
parentId: m3sdsq23
|
||||||
text: test
|
text: test
|
||||||
author:
|
author:
|
||||||
name: Adrien Payet
|
name: Adrien Payet
|
||||||
|
|
@ -41,3 +125,90 @@ Comments:
|
||||||
id: m3sdsq23
|
id: m3sdsq23
|
||||||
type: comment
|
type: comment
|
||||||
isRead: false
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "65.847110638459"
|
||||||
|
y: "53.474903474903"
|
||||||
|
replies: [ ]
|
||||||
|
text: test
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-22T08:50:41+01:00
|
||||||
|
id: m3sfz36o
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: "32.518325137231"
|
||||||
|
y: "62.548262548263"
|
||||||
|
replies: [ ]
|
||||||
|
text: test
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-22T09:18:05+01:00
|
||||||
|
id: m3sgybwq
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
-
|
||||||
|
location:
|
||||||
|
page:
|
||||||
|
uri: >
|
||||||
|
projects/miss-dior-blooming-bouquet/client-brief
|
||||||
|
title: Brief client
|
||||||
|
href: >
|
||||||
|
/projects/miss-dior-blooming-bouquet?dialog=client-brief
|
||||||
|
project:
|
||||||
|
title: Miss Dior Blooming Bouquet
|
||||||
|
uri: projects/miss-dior-blooming-bouquet
|
||||||
|
file:
|
||||||
|
uuid: file://s0lNtRA0Z7ybTCWG
|
||||||
|
url: file://s0lNtRA0Z7ybTCWG
|
||||||
|
position:
|
||||||
|
pageIndex: 1
|
||||||
|
x: '73.769521704789'
|
||||||
|
y: '83.204633204633'
|
||||||
|
replies: [ ]
|
||||||
|
text: 'Adrien Payet : test'
|
||||||
|
author:
|
||||||
|
name: Adrien Payet
|
||||||
|
email: adrien.payet@outlook.com
|
||||||
|
uuid: user://WWjXgPWk
|
||||||
|
role: admin
|
||||||
|
date: 2024-11-22T09:20:04+01:00
|
||||||
|
id: m3sh0vfu
|
||||||
|
type: comment
|
||||||
|
isRead: false
|
||||||
|
|
@ -1,32 +1,49 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'pattern' => '(:all)validate-brief.json',
|
'pattern' => 'validate-brief.json',
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'action' => function () {
|
'action' => function () {
|
||||||
$json = file_get_contents('php://input');
|
$json = file_get_contents('php://input');
|
||||||
$data = json_decode($json);
|
$data = json_decode($json);
|
||||||
|
|
||||||
$page = page($data->pageUri);
|
$brief = page($data->briefUri);
|
||||||
try {
|
$project = $brief->parent();
|
||||||
$newPage = $page->update([
|
$href = $data->dialogUri ? $data->dialogUri : $brief->url();
|
||||||
'isValidated' => 'true'
|
|
||||||
]);
|
|
||||||
echo json_encode([
|
|
||||||
"success" => "'" . $newPage->title()->value() . "' brief validated."
|
|
||||||
]);
|
|
||||||
|
|
||||||
kirby()->user()->sendNotification($newPage->parent(), [
|
try {
|
||||||
'date' => $newPage->modified('YYYY-MM-DD'),
|
$newPage = $brief->update([
|
||||||
'author' => kirby()->user()->name()->isNotEmpty() ? kirby()->user()->name() : kirby()->user()->email(),
|
'isValidated' => 'true'
|
||||||
'url' => $newPage->url(),
|
]);
|
||||||
'type' => 'content'
|
|
||||||
]);
|
$notification = [
|
||||||
} catch (\Throwable $th) {
|
'location' => [
|
||||||
return [
|
'href' => (string) $href,
|
||||||
"error" => "Can't validate '" . $page->title()->value() . "' brief.",
|
'project' => [
|
||||||
'details' => $th->getMessage()
|
'title' => (string) $project->title(),
|
||||||
];
|
'uri' => (string) $project->url()
|
||||||
}
|
]
|
||||||
|
],
|
||||||
|
'date' => $newPage->modified('YYYY-MM-DD'),
|
||||||
|
'author' => [
|
||||||
|
'name' => (string) kirby()->user()->name(),
|
||||||
|
'email' => (string) kirby()->user()->email(),
|
||||||
|
'uuid' => (string) kirby()->user()->uuid(),
|
||||||
|
'role' => (string) kirby()->user()->role(),
|
||||||
|
],
|
||||||
|
'type' => 'content'
|
||||||
|
];
|
||||||
|
|
||||||
|
kirby()->user()->sendNotification($project, $notification);
|
||||||
|
|
||||||
|
return [
|
||||||
|
"success" => "'" . $project->title()->value() . "' brief validated."
|
||||||
|
];
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
return [
|
||||||
|
"error" => "Can't validate '" . $brief->title()->value() . "' brief.",
|
||||||
|
'details' => $th->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
@ -35,7 +35,7 @@ class ProjectPage extends Page {
|
||||||
'slug' => $child->slug(),
|
'slug' => $child->slug(),
|
||||||
'index' => intval($child->stepIndex()->value()),
|
'index' => intval($child->stepIndex()->value()),
|
||||||
'modified' => $child->modified('Y-MM-dd'),
|
'modified' => $child->modified('Y-MM-dd'),
|
||||||
'isValidated' => $child->isValidated()->value() ?? false,
|
'isValidated' => (bool) $child->isValidated()->value() ?? false,
|
||||||
'uri' => $uri,
|
'uri' => $uri,
|
||||||
'files' => $files,
|
'files' => $files,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ return [
|
||||||
'y' => $data->position->y
|
'y' => $data->position->y
|
||||||
],
|
],
|
||||||
'replies' => [],
|
'replies' => [],
|
||||||
'text' => $data->text,
|
'text' => $user->name()->isNotEmpty() ? $user->name()->value() . ' : ' . $data->text : $user->email()->value() . ' : ' . $data->text,
|
||||||
'author' => $user,
|
'author' => $user,
|
||||||
'date' => (string) $data->date,
|
'date' => (string) $data->date,
|
||||||
'id' => $data->id,
|
'id' => $data->id,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,14 @@ return [
|
||||||
$json = file_get_contents('php://input');
|
$json = file_get_contents('php://input');
|
||||||
$data = json_decode($json);
|
$data = json_decode($json);
|
||||||
|
|
||||||
$page = page($data->pageUri);
|
$parsedUrl = parse_url($data->path);
|
||||||
|
$query = $parsedUrl['query'] ?? null;
|
||||||
|
parse_str($query, $queryParams);
|
||||||
|
$stepSlug = $queryParams['dialog'] ?? null;
|
||||||
|
|
||||||
|
$targetPageUri = $stepSlug ? $parsedUrl['path'] . '/' . $stepSlug : $parsedUrl['path'];
|
||||||
|
|
||||||
|
$page = page($targetPageUri);
|
||||||
$file = $page->file($data->fileName);
|
$file = $page->file($data->fileName);
|
||||||
$user = kirby()->user($data->userUuid);
|
$user = kirby()->user($data->userUuid);
|
||||||
|
|
||||||
|
|
@ -17,6 +24,7 @@ return [
|
||||||
$comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value());
|
$comments = $file->comments()->isEmpty() == true ? [] : Yaml::decode($file->comments()->value());
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
|
'href' => $data->path,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'parentId' => $data->parentId,
|
'parentId' => $data->parentId,
|
||||||
'file' => $file,
|
'file' => $file,
|
||||||
|
|
|
||||||
|
|
@ -13,25 +13,27 @@
|
||||||
* @throws Exception If an error occurs while updating a user's notifications.
|
* @throws Exception If an error occurs while updating a user's notifications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return function ($project, $notificationData) {
|
return function ($project, $notificationData) {
|
||||||
$recipients = $project->managers()->without($this);
|
$recipients = $project->managers()->without($this);
|
||||||
|
|
||||||
if (!$recipients) return;
|
if ($recipients->isEmpty()) return;
|
||||||
|
|
||||||
|
$notificationData['isRead'] = false;
|
||||||
|
|
||||||
$notificationData['isRead'];
|
|
||||||
foreach ($recipients as $otherUser) {
|
foreach ($recipients as $otherUser) {
|
||||||
try {
|
try {
|
||||||
$notifications = $otherUser->notifications()->isNotEmpty()
|
$notifications = $otherUser->notifications()->isNotEmpty()
|
||||||
? Yaml::decode($otherUser->notifications()->value())
|
? Yaml::decode($otherUser->notifications()->value())
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
$notifications[] = $notificationData;
|
$notifications[] = $notificationData;
|
||||||
|
|
||||||
$otherUser->update([
|
$otherUser->update([
|
||||||
'notifications' => $notifications
|
'notifications' => $notifications
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
throw new Exception("Error updating notifications: " . $th->getMessage() . ' line ' . $th->getLine(), 1);
|
error_log("Notification error for user " . $otherUser->email() . ": " . $th->getMessage());
|
||||||
}
|
throw new Exception("Error updating notifications: " . $th->getMessage() . ' line ' . $th->getLine(), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -183,12 +183,13 @@ function handleSubmit(event = null) {
|
||||||
userUuid: user.uuid,
|
userUuid: user.uuid,
|
||||||
text: draftComment.value.text,
|
text: draftComment.value.text,
|
||||||
date,
|
date,
|
||||||
position:
|
position: {
|
||||||
{
|
pageIndex: openedComment.value
|
||||||
pageIndex: draftComment.value.position.pageIndex,
|
? openedComment.value.position.pageIndex
|
||||||
x: draftComment.value.position?.x,
|
: draftComment.value.position.pageIndex,
|
||||||
y: draftComment.value.position?.y,
|
x: openedComment.value ? false : draftComment.value.position.x,
|
||||||
} ?? false,
|
y: openedComment.value ? false : draftComment.value.position.y,
|
||||||
|
},
|
||||||
id: uniqid(),
|
id: uniqid(),
|
||||||
};
|
};
|
||||||
if (openedComment.value) {
|
if (openedComment.value) {
|
||||||
|
|
@ -201,9 +202,7 @@ function handleSubmit(event = null) {
|
||||||
async function replyComment(newComment) {
|
async function replyComment(newComment) {
|
||||||
newComment.parentId = openedComment.value.id;
|
newComment.parentId = openedComment.value.id;
|
||||||
const newFile = await api.replyComment(newComment);
|
const newFile = await api.replyComment(newComment);
|
||||||
draftComment.value.text = "";
|
resetDraftComment();
|
||||||
draftComment.value.position = null;
|
|
||||||
draftComment.value.padeIndex = null;
|
|
||||||
isAddOpen.value = false;
|
isAddOpen.value = false;
|
||||||
dialog.updateFile(newFile);
|
dialog.updateFile(newFile);
|
||||||
openedComment.value = newFile.comments.find(
|
openedComment.value = newFile.comments.find(
|
||||||
|
|
@ -213,12 +212,15 @@ async function replyComment(newComment) {
|
||||||
|
|
||||||
async function addComment(newComment) {
|
async function addComment(newComment) {
|
||||||
const newFile = await api.addComment(newComment);
|
const newFile = await api.addComment(newComment);
|
||||||
|
resetDraftComment();
|
||||||
|
isAddOpen.value = false;
|
||||||
|
dialog.updateFile(newFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetDraftComment() {
|
||||||
draftComment.value.text = "";
|
draftComment.value.text = "";
|
||||||
draftComment.value.position = null;
|
draftComment.value.position = null;
|
||||||
draftComment.value.padeIndex = null;
|
draftComment.value.padeIndex = null;
|
||||||
isAddOpen.value = false;
|
|
||||||
|
|
||||||
dialog.updateFile(newFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeComment() {
|
function closeComment() {
|
||||||
|
|
@ -267,9 +269,7 @@ function handleCommentPositionClick(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function openComment(comment) {
|
function openComment(comment) {
|
||||||
if (comment.replies.length) {
|
openedComment.value = comment;
|
||||||
openedComment.value = comment;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@
|
||||||
<template #header>
|
<template #header>
|
||||||
<button
|
<button
|
||||||
v-if="
|
v-if="
|
||||||
dialog.content.id === 'clientBrief' && !dialog.content?.isValidated
|
dialog.content.id === 'clientBrief' &&
|
||||||
|
dialog.content.isValidated !== true
|
||||||
"
|
"
|
||||||
class="btn"
|
class="btn"
|
||||||
@click="validate()"
|
@click="validate()"
|
||||||
|
|
@ -191,8 +192,15 @@ function showDraftMarker(draftComment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validate() {
|
async function validate() {
|
||||||
const response = await api.validateBrief(route.path + "/client-brief");
|
const response = await api.validateBrief(
|
||||||
dialog.content.isValidated = true;
|
route.path + "/client-brief",
|
||||||
|
route.fullPath
|
||||||
|
);
|
||||||
|
if (response.success) {
|
||||||
|
dialog.content.isValidated = true;
|
||||||
|
} else {
|
||||||
|
console.alert(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -212,11 +212,12 @@ export const useApiStore = defineStore("api", () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validateBrief(briefUri) {
|
async function validateBrief(briefUri, dialogUri = null) {
|
||||||
const headers = {
|
const headers = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
pageUri: briefUri,
|
briefUri: briefUri,
|
||||||
|
dialogUri,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
|
|
@ -231,7 +232,7 @@ export const useApiStore = defineStore("api", () => {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue