Skip to content

Commit

Permalink
Add actions field to Card. Handle PROPAGATE_READ_ACK_TO_PARENT_CARD a…
Browse files Browse the repository at this point in the history
…ction (#5461)

Signed-off-by: Giovanni Ferrari <giovanni.ferrari@soft.it>
  • Loading branch information
quinarygio authored and freddidierRTE committed Jan 15, 2024
1 parent 46fd748 commit 32c20df
Show file tree
Hide file tree
Showing 21 changed files with 259 additions and 33 deletions.
@@ -0,0 +1,22 @@
/* Copyright (c) 2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
* This file is part of the OperatorFabric project.
*/

package org.opfab.cards.model;

/**
* Defines the actions to be done when card is received
* <dl>
* <dt>PROPAGATE_READ_ACK_TO_PARENT_CARD</dt>
* </dl>
* Note : This enum is created by hand because Swagger can't handle enums. It should match the corresponding enum definition in the Cards API.
*
*/
public enum CardActionEnum {
PROPAGATE_READ_ACK_TO_PARENT_CARD
}
3 changes: 2 additions & 1 deletion client/cards/src/main/modeling/config.json
Expand Up @@ -19,6 +19,7 @@
"FilterMatchTypeEnum": "org.opfab.cards.model.FilterMatchTypeEnum",
"FilterOperationTypeEnum": "org.opfab.cards.model.FilterOperationTypeEnum",
"FreqEnum": "org.opfab.cards.model.FreqEnum",
"DayEnum": "org.opfab.cards.model.DayEnum"
"DayEnum": "org.opfab.cards.model.DayEnum",
"CardActionEnum": "org.opfab.cards.model.CardActionEnum"
}
}
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -10,6 +10,7 @@
package org.opfab.cards.consultation.configuration.mongo;

import org.bson.Document;
import org.opfab.cards.consultation.model.CardActionEnum;
import org.opfab.cards.consultation.model.LightCard;
import org.opfab.cards.consultation.model.LightCardConsultationData;
import org.opfab.cards.consultation.model.PublisherTypeEnum;
Expand Down Expand Up @@ -91,6 +92,15 @@ public LightCardConsultationData convert(Document source) {
if (rRuleDoc != null)
builder.rRule(rRuleConverter.convert(rRuleDoc));

List<CardActionEnum> actionsEnumList = new ArrayList<>();
List<String> actionsStringList = source.getList("actions", String.class);
if (actionsStringList != null) {
for (String actionString : actionsStringList) {
actionsEnumList.add(CardActionEnum.valueOf(actionString));
}
}
builder.actions(actionsEnumList);

return builder.build();
}
}
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -13,6 +13,7 @@


import org.opfab.cards.consultation.model.CardsFilter;
import org.opfab.cards.consultation.model.CardActionEnum;
import org.opfab.cards.consultation.model.CardConsultationData;
import org.opfab.cards.consultation.model.CardData;
import org.opfab.cards.consultation.repositories.CardRepository;
Expand Down Expand Up @@ -69,8 +70,16 @@ private HandlerFunction<ServerResponse> cardGetRoute() {
card.setHasBeenRead(card.getUsersReads() != null && card.getUsersReads().contains(user.getUserData().getLogin()));
})
.flatMap(t2 -> {
CurrentUserWithPerimeters user = t2.getT1().getT1();
CardConsultationData card = t2.getT1().getT2();
List<CardConsultationData> childCards = t2.getT2();
childCards.forEach(child -> {
if (child.getActions() != null && child.getActions().contains(CardActionEnum.PROPAGATE_READ_ACK_TO_PARENT_CARD)) {
child.setHasBeenAcknowledged(child.getUsersAcks() != null && child.getUsersAcks().contains(user.getUserData().getLogin()));
child.setHasBeenRead(child.getUsersReads() != null && child.getUsersReads().contains(user.getUserData().getLogin()));
}
});

return ok()
.contentType(MediaType.APPLICATION_JSON)
.body(fromValue(CardData.builder().card(card).childCards(childCards).build()));
Expand Down
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -147,4 +147,6 @@ public void setDeletionDate(Instant deletionDate) {

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private RRule rRule;

private List<CardActionEnum> actions;
}
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -143,4 +143,8 @@ public class CardConsultationData implements Card {

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private RRule rRule;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<CardActionEnum> actions;

}
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -105,6 +105,10 @@ public class LightCardConsultationData implements LightCard {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private RRule rRule;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<CardActionEnum> actions;


/**
* @return timespans, may return null
*/
Expand Down Expand Up @@ -175,6 +179,9 @@ public static LightCardConsultationData copy(Card other) {
if (other.getUserRecipients() != null && !other.getUserRecipients().isEmpty()) {
builder.userRecipients(other.getUserRecipients());
}
if (other.getActions() != null && !other.getActions().isEmpty()) {
builder.actions(other.getActions());
}
return builder.build();

}
Expand Down
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -127,6 +127,8 @@ public class ArchivedCardPublicationData implements Card {

private RRule rRule;

private List<CardActionEnum> actions;

public Instant getDeletionDate() {
return this.deletionDate;
}
Expand Down Expand Up @@ -177,6 +179,9 @@ public ArchivedCardPublicationData(CardPublicationData card){
this.toNotify = card.getToNotify();

this.rRule = card.getRRule();

this.actions =ObjectUtils.getNotNullOrDefault(card.getActions(), null, ArrayList::new);

}

}
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -169,6 +169,8 @@ public class CardPublicationData implements Card {
@Indexed
private Instant lastAckDate;

private List<CardActionEnum> actions;

public void prepare(Instant publishDate) {
this.publishDate = publishDate;
this.id = process + "." + processInstanceId;
Expand Down Expand Up @@ -211,7 +213,9 @@ public LightCardPublicationData toLightCard() {
.userRecipients(this.getUserRecipients())
.groupRecipients(this.getGroupRecipients())
.entityRecipients(this.getEntityRecipients())
.entityRecipientsForInformation(this.getEntityRecipientsForInformation());
.entityRecipientsForInformation(this.getEntityRecipientsForInformation())
.actions(this.getActions());


if (this.getTimeSpans() != null)
result.timeSpansSet(new HashSet<>(this.getTimeSpans()));
Expand Down
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -104,6 +104,9 @@ public class LightCardPublicationData implements LightCard {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private RRule rRule;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<CardActionEnum> actions;

/**
* @return timespans, may be null
*/
Expand Down
12 changes: 12 additions & 0 deletions services/cards-publication/src/main/modeling/swagger.yaml
Expand Up @@ -241,6 +241,14 @@ definitions:
type: integer
minutes:
type: integer
CardActionEnum:
type: string
description: |-
Defines the action to be executed on card reception >
* PROPAGATE_READ_ACK_TO_PARENT_CARD
enum:
- PROPAGATE_READ_ACK_TO_PARENT_CARD
example: PROPAGATE_READ_ACK_TO_PARENT_CARD
Card:
type: object
description: >-
Expand Down Expand Up @@ -410,6 +418,10 @@ definitions:
toNotify:
type: boolean
description: Is false if the card must not be displayed in the feed and in monitoring screen
actions:
type: array
items:
$ref: '#/definitions/CardActionEnum'
required:
- publisher
- process
Expand Down
6 changes: 5 additions & 1 deletion src/docs/asciidoc/reference_doc/card_structure.adoc
@@ -1,4 +1,4 @@
// Copyright (c) 2018-2023 RTE (http://www.rte-france.com)
// Copyright (c) 2018-2024 RTE (http://www.rte-france.com)
// See AUTHORS.txt
// This document is subject to the terms of the Creative Commons Attribution 4.0 International license.
// If a copy of the license was not distributed with this
Expand Down Expand Up @@ -166,6 +166,10 @@ can be found at https://www.ogc.org/standards/wkt-crs[WKT Specification].

NOTE: Only the POINT and POLYGON are supported.

==== Actions (`actions`)
A list of predetermined actions that will be executed upon receiving the card. The available actions include:
- 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.

=== Business period

We define the business period as starting form startDate to endDate. The card will be visible on the UI if the business period overlap the user chosen period (i.e. the period selected on the timeline). If endDate is not set, the card will be visible as soon as the startDate is between start and end date of the chosen period.
Expand Down
6 changes: 4 additions & 2 deletions src/docs/asciidoc/reference_doc/response_cards.adoc
@@ -1,4 +1,4 @@
// Copyright (c) 2018-2023 RTE (http://www.rte-france.com)
// Copyright (c) 2018-2024 RTE (http://www.rte-france.com)
// See AUTHORS.txt
// This document is subject to the terms of the Creative Commons Attribution 4.0 International license.
// If a copy of the license was not distributed with this
Expand Down Expand Up @@ -117,14 +117,16 @@ response by returning it in the method registered by `opfab.currentCard.register
For the user to response you need to define the response form in the template with standard HTML syntax

To enable OperatorFabric to send the response, you need to implement a javascript function in your template
which returns an object containing four fields :
which returns an object containing the following fields :

- valid (_boolean_) : true if the user input is valid
- errorMsg (_string_) : message in case of invalid user input. If valid is true this field is not necessary.
- responseCardData (_any_) : the user input to send in the data field of the child card. If valid is false this field is not necessary.
- responseState : name of the response state to use. This field is not mandatory, if it is not set the state defined in
`config.json` will be used for the response.
- publisher (_string_) : the id of the Entity to be used as publisher of the response. This field is not mandatory, if it is not set the publisher will be the user entity, in case the user belongs to a single entity, or it will be choosen by the user between his available entities.
- actions (_string array_) : an optional field used to define a set of predetermined actions that will be executed upon receiving the response card. The available actions include:
* PROPAGATE_READ_ACK_TO_PARENT_CARD : 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.


This method is to be registered via `opfab.currentCard.registerFunctionToGetUserResponse`, the method will be called by OperatorFabric when the user clicks on the button to send the response.
Expand Down
Expand Up @@ -92,7 +92,9 @@
return {
valid: true,
publisher : publisher,
responseCardData: responseCardData
responseCardData: responseCardData,
actions: ['PROPAGATE_READ_ACK_TO_PARENT_CARD']
};
});
Expand Down
10 changes: 6 additions & 4 deletions ui/main/src/app/business/model/card.model.ts
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2023, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand All @@ -7,7 +7,7 @@
* This file is part of the OperatorFabric project.
*/

import {Day, Frequency, LightCard, PublisherType, Severity} from '@ofModel/light-card.model';
import {CardAction, Day, Frequency, LightCard, PublisherType, Severity} from '@ofModel/light-card.model';
import {I18n} from '@ofModel/i18n.model';

export class Card {
Expand Down Expand Up @@ -54,7 +54,8 @@ export class Card {
public timeSpans?: TimeSpan[],
readonly entitiesAcks?: string[],
readonly deletionDate?: number,
public rRule?: RRule
public rRule?: RRule,
public actions?: CardAction[]
) {}
}

Expand Down Expand Up @@ -92,7 +93,8 @@ export class CardForPublishing {
readonly wktProjection?: string,
readonly secondsBeforeTimeSpanForReminder?: number,
readonly timeSpans?: TimeSpan[],
readonly rRule?: RRule
readonly rRule?: RRule,
public actions?: CardAction[]
) {}
}

Expand Down
9 changes: 7 additions & 2 deletions ui/main/src/app/business/model/light-card.model.ts
@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2022, RTE (http://www.rte-france.com)
/* Copyright (c) 2018-2024, RTE (http://www.rte-france.com)
* See AUTHORS.txt
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -49,7 +49,8 @@ export class LightCard {
readonly entitiesRequiredToRespond?: string[],
readonly entitiesAllowedToEdit?: string[],
readonly publisherType?: PublisherType | string,
readonly secondsBeforeTimeSpanForReminder?: number
readonly secondsBeforeTimeSpanForReminder?: number,
readonly actions?: CardAction[]
) {}
}

Expand Down Expand Up @@ -89,3 +90,7 @@ export enum Day {
SA = 'SA',
SU = 'SU'
}

export enum CardAction {
PROPAGATE_READ_ACK_TO_PARENT_CARD = 'PROPAGATE_READ_ACK_TO_PARENT_CARD'
}

0 comments on commit 32c20df

Please sign in to comment.