Skip to content

Commit 337f039

Browse files
vlo-rtefreddidierRTE
authored andcommitted
Add an option to notify only on remind (#7883)
Signed-off-by: vlo-rte <[email protected]>
1 parent 22d0fc5 commit 337f039

File tree

13 files changed

+108
-16
lines changed

13 files changed

+108
-16
lines changed

client/cards/src/main/java/org/opfab/cards/model/CardActionEnum.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2024, RTE (http://www.rte-france.com)
1+
/* Copyright (c) 2024-2025, RTE (http://www.rte-france.com)
22
* See AUTHORS.txt
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,6 +17,7 @@
1717
* <dt>KEEP_EXISTING_ACKS_AND_READS</dt>
1818
* <dt>KEEP_EXISTING_PUBLISH_DATE</dt>
1919
* <dt>STORE_ONLY_IN_ARCHIVES</dt>
20+
* <dt>NOT_NOTIFIED</dt>
2021
* </dl>
2122
* Note : This enum is created by hand because Swagger can't handle enums. It should match the corresponding enum definition in the Cards API.
2223
*
@@ -26,5 +27,6 @@ public enum CardActionEnum {
2627
KEEP_CHILD_CARDS,
2728
KEEP_EXISTING_ACKS_AND_READS,
2829
KEEP_EXISTING_PUBLISH_DATE,
29-
STORE_ONLY_IN_ARCHIVES
30+
STORE_ONLY_IN_ARCHIVES,
31+
NOT_NOTIFIED
3032
}

services/cards-consultation/src/main/java/org/opfab/cards/consultation/model/CardActionEnum.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2024, RTE (http://www.rte-france.com)
1+
/* Copyright (c) 2024-2025, RTE (http://www.rte-france.com)
22
* See AUTHORS.txt
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -16,6 +16,6 @@ public enum CardActionEnum {
1616
KEEP_CHILD_CARDS,
1717
KEEP_EXISTING_ACKS_AND_READS,
1818
KEEP_EXISTING_PUBLISH_DATE,
19-
STORE_ONLY_IN_ARCHIVES
20-
19+
STORE_ONLY_IN_ARCHIVES,
20+
NOT_NOTIFIED
2121
}

services/cards-publication/src/main/java/org/opfab/cards/publication/model/CardActionEnum.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023-2024, RTE (http://www.rte-france.com)
1+
/* Copyright (c) 2023-2025, RTE (http://www.rte-france.com)
22
* See AUTHORS.txt
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -15,6 +15,7 @@ public enum CardActionEnum {
1515
KEEP_CHILD_CARDS,
1616
KEEP_EXISTING_ACKS_AND_READS,
1717
KEEP_EXISTING_PUBLISH_DATE,
18-
STORE_ONLY_IN_ARCHIVES
18+
STORE_ONLY_IN_ARCHIVES,
19+
NOT_NOTIFIED
1920
}
2021

services/cards-publication/src/main/java/org/opfab/cards/publication/mongo/CardRepositoryImpl.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
1+
/* Copyright (c) 2018-2025, RTE (http://www.rte-france.com)
22
* See AUTHORS.txt
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -202,7 +202,8 @@ public UserBasedOperationResult deleteAcksAndReads(String cardUid) {
202202
.unset(USERS_READS)
203203
.set(ENTITIES_ACKS,new LinkedList<String>())
204204
.set(LAST_UPDATE, Instant.now())
205-
.set("publishDate", Instant.now());
205+
.set("publishDate", Instant.now())
206+
.pull("actions", "NOT_NOTIFIED");
206207
UpdateResult updateFirst = template.updateFirst(Query.query(Criteria.where("uid").is(cardUid)),
207208
update, Card.class);
208209
log.debug("removed {} occurrence of Acks and read in the card with uid: {}", updateFirst.getModifiedCount(),

services/cards-publication/src/main/modeling/swagger.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,14 @@ definitions:
217217
* KEEP_EXISTING_ACKS_AND_READS,
218218
* KEEP_EXISTING_PUBLISH_DATE
219219
* STORE_ONLY_IN_ARCHIVES
220+
* NOT_NOTIFIED
220221
enum:
221222
- PROPAGATE_READ_ACK_TO_PARENT_CARD
222223
- KEEP_CHILD_CARDS
223224
- KEEP_EXISTING_ACKS_AND_READS
224225
- KEEP_EXISTING_PUBLISH_DATE
225226
- STORE_ONLY_IN_ARCHIVES
227+
- NOT_NOTIFIED
226228
example: PROPAGATE_READ_ACK_TO_PARENT_CARD
227229
Card:
228230
type: object

src/docs/asciidoc/reference_doc/card_structure.adoc

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018-2024 RTE (http://www.rte-france.com)
1+
// Copyright (c) 2018-2025 RTE (http://www.rte-france.com)
22
// See AUTHORS.txt
33
// This document is subject to the terms of the Creative Commons Attribution 4.0 International license.
44
// If a copy of the license was not distributed with this
@@ -166,6 +166,8 @@ A list of predetermined actions that will be executed upon receiving the card. T
166166
- PROPAGATE_READ_ACK_TO_PARENT_CARD : used only for response cards. When receiving the child card, the status of the parent card should be considered as 'unread' and 'not acknowledged' until the user reads or acknowledge it again.
167167
- KEEP_EXISTING_ACKS_AND_READS : used to keep existing reads and acks when updating a card
168168
- STORE_ONLY_IN_ARCHIVES : used to store the card only in archivedCards collection and not in cards collection. No notification will be sent to UI, so the card will not be displayed in the feed and in monitoring screen.
169+
- NOT_NOTIFIED : when this action is set, the card is not visible in the card feed except for the publisher but it is visible in all the other screens : monitoring screen / agenda / timeline.
170+
The card is visible in the feed when the card will be reminded.
169171

170172
=== Business period
171173

src/test/api/karate/cards/cardsReminder.feature

+52
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,24 @@ Scenario: ResetCardsReadsAndAcks
7676
}
7777
"""
7878

79+
* def cardWithNotNotifiedAction =
80+
"""
81+
{
82+
"publisher" : "operator1_fr",
83+
"processVersion" : "1",
84+
"process" :"api_test",
85+
"processInstanceId" : "cardWithNotNotifiedAction",
86+
"state": "messageState",
87+
"groupRecipients": ["Maintainer"],
88+
"severity" : "INFORMATION",
89+
"startDate" : 1553186770681,
90+
"summary" : {"key" : "defaultProcess.summary"},
91+
"title" : {"key" : "defaultProcess.title"},
92+
"data" : {"message":"a message"},
93+
"actions" : ["NOT_NOTIFIED"]
94+
}
95+
"""
96+
7997

8098
# Push card
8199
Given url opfabPublishCardUrl + 'cards'
@@ -178,6 +196,40 @@ Scenario: ResetCardsReadsAndAcks
178196
And match response.card.hasBeenAcknowledged == false
179197
And match response.card.uid == uid
180198

199+
#Send a card with action NOT_NOTIFIED and call resetReadAndAcks endpoint
200+
# Push card
201+
Given url opfabPublishCardUrl + 'cards'
202+
And header Authorization = 'Bearer ' + authToken
203+
And request cardWithNotNotifiedAction
204+
When method post
205+
Then status 201
206+
207+
Given url opfabUrl + 'cards-consultation/cards/api_test.cardWithNotNotifiedAction'
208+
And header Authorization = 'Bearer ' + authToken
209+
When method get
210+
Then status 200
211+
And match response.card.hasBeenRead == false
212+
And match response.card.hasBeenAcknowledged == false
213+
And match response.card.actions == ["NOT_NOTIFIED"]
214+
And def uid = response.card.uid
215+
216+
Given url opfabUrl + 'cards-publication/cards/resetReadAndAcks/' + uid
217+
And header Authorization = 'Bearer ' + authTokenInternal
218+
And request ''
219+
When method post
220+
Then status 200
221+
222+
#get card and check actions does not contain 'NOT_NOTIFIED' and hasBeenRead/hasBeenAcknowledged is set to false and entitiesAck is empty
223+
Given url opfabUrl + 'cards-consultation/cards/api_test.cardWithNotNotifiedAction'
224+
And header Authorization = 'Bearer ' + authToken
225+
When method get
226+
Then status 200
227+
And match response.card.hasBeenRead == false
228+
And match response.card.hasBeenAcknowledged == false
229+
And match response.card.entitiesAcks == '#notpresent'
230+
And match response.card.actions == '#notpresent'
231+
And match response.card.uid == uid
232+
181233
Scenario: Delete the test card
182234

183235
# delete card

ui/main/src/app/builtInTemplates/task/usercard/taskUserCardTemplateView.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023-2024, RTE (http://www.rte-france.com)
1+
/* Copyright (c) 2023-2025, RTE (http://www.rte-france.com)
22
* See AUTHORS.txt
33
* This Source Code Form is subject to the terms of the Mozilla Public
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -52,7 +52,8 @@ export class TaskUserCardTemplateView {
5252
minutesForReminder: minutesForReminder,
5353
durationInMinutes: durationInMinutes
5454
},
55-
rRule: rRule
55+
rRule: rRule,
56+
actions: ['NOT_NOTIFIED']
5657
};
5758

5859
return {

ui/main/src/app/components/feed/components/card-list/card-list.component.html

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
<div *ngFor="let currentLightCard of lightCards" style="margin-right: -10px">
3737
<div style="padding-right: 20px; margin-bottom: 10px">
3838
<of-light-card
39+
*ngIf="shouldLightcardBeNotified(currentLightCard)"
3940
[lightCard]="currentLightCard"
4041
[open]="
4142
currentLightCard.id === (selection | async) ||

ui/main/src/app/components/feed/components/card-list/card-list.component.ts

+7
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,13 @@ export class CardListComponent implements AfterViewChecked, OnInit {
204204
}
205205
}
206206

207+
protected shouldLightcardBeNotified(lightcard: Card): boolean {
208+
return (
209+
!lightcard.actions?.includes(CardAction.NOT_NOTIFIED) ||
210+
this.currentUserWithPerimeters.userData.entities.includes(lightcard.publisher)
211+
);
212+
}
213+
207214
isCardPublishedBeforeAckDemand(lightCard: Card): boolean {
208215
return lightCard.publishDate < this.ackAllCardsDemandTimestamp;
209216
}

ui/main/src/app/model/CardAction.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ export enum CardAction {
1212
KEEP_CHILD_CARDS = 'KEEP_CHILD_CARDS',
1313
KEEP_EXISTING_ACKS_AND_READS = 'KEEP_EXISTING_ACKS_AND_READS',
1414
KEEP_EXISTING_PUBLISH_DATE = 'KEEP_EXISTING_PUBLISH_DATE',
15-
STORE_ONLY_IN_ARCHIVES = 'STORE_ONLY_IN_ARCHIVES'
15+
STORE_ONLY_IN_ARCHIVES = 'STORE_ONLY_IN_ARCHIVES',
16+
NOT_NOTIFIED = 'NOT_NOTIFIED'
1617
}

ui/main/src/app/services/notifications/NotificationDecision.spec.ts

+17
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ describe('Sound decisions', () => {
3333
done();
3434
});
3535

36+
it(
37+
'No sound and system notification for card with action is NOT_NOTIFIED and user entities does not contains ' +
38+
'card publisher entity',
39+
(done) => {
40+
const publishDate = new Date().getTime();
41+
const card1 = getOneLightCard({
42+
publishDate: publishDate,
43+
publisher: 'ENTITY1_FR',
44+
actions: [CardAction.NOT_NOTIFIED]
45+
});
46+
NotificationDecision.setLastUserAction(publishDate - NotificationDecision.ERROR_MARGIN);
47+
expect(NotificationDecision.isSoundToBePlayedForCard(card1)).toBeFalse();
48+
expect(NotificationDecision.isSystemNotificationToBeShownForCard(card1)).toBeFalse();
49+
done();
50+
}
51+
);
52+
3653
it('No sound and system notification for cards recently sent by the user', (done) => {
3754
const publishDate = new Date().getTime();
3855
const card1 = getOneLightCard({publishDate: publishDate});

ui/main/src/app/services/notifications/NotificationDecision.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ export class NotificationDecision {
7878
return (
7979
!card.hasBeenRead &&
8080
this.checkCardHasBeenPublishAfterLastUserAction(card) &&
81-
this.checkCardIsRecent(card)
81+
this.checkCardIsRecent(card) &&
82+
this.shouldCardBeNotified(card)
8283
);
8384
}
8485
}
@@ -92,9 +93,9 @@ export class NotificationDecision {
9293

9394
public static isSystemNotificationToBeShownForCard(card: Card) {
9495
if (this.lastSentCards.get(card.id) && !this.checkSentCardIsRecentlyPublished(card))
95-
return false; // no sound as the card was sent by the current user
96+
return false; // no system notification as the card was sent by the current user
9697
else {
97-
return !card.hasBeenRead && this.checkCardIsRecent(card);
98+
return !card.hasBeenRead && this.checkCardIsRecent(card) && this.shouldCardBeNotified(card);
9899
}
99100
}
100101

@@ -150,4 +151,8 @@ export class NotificationDecision {
150151
this.cleanSentCards();
151152
}, this.CLEAN_CARDS_PERIOD);
152153
}
154+
155+
private static shouldCardBeNotified(card: Card): boolean {
156+
return !card.actions?.includes(CardAction.NOT_NOTIFIED);
157+
}
153158
}

0 commit comments

Comments
 (0)