This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit d193ac8ff671230742299a4d8cc6210d5b3df773 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Thu Jun 15 13:28:31 2017 +0200 Signalement de contenu inapproprié (ref #63) --- .../pollen/persistence/entity/ReportResume.java | 43 + .../pollen/persistence/entity/ReportTopiaDao.java | 26 + .../db/migration/h2/V3_0_0_3__add_reports.sql | 11 + .../migration/postgresql/V3_0_0_3__add_reports.sql | 11 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 25580 -> 26098 bytes .../rest/api/PollenRestApiApplicationListener.java | 4 +- .../org/chorem/pollen/rest/api/v1/ChoiceApi.java | 20 + .../org/chorem/pollen/rest/api/v1/CommentApi.java | 22 + .../org/chorem/pollen/rest/api/v1/PollApi.java | 20 + pollen-rest-api/src/main/resources/mapping | 64 +- pollen-services/src/main/config/PollenServices.ini | 8 +- .../chorem/pollen/services/PollenUIContext.java | 9 + .../chorem/pollen/services/bean/ChoiceBean.java | 10 + .../chorem/pollen/services/bean/CommentBean.java | 10 + .../org/chorem/pollen/services/bean/PollBean.java | 10 + .../chorem/pollen/services/bean/ReportBean.java | 65 ++ .../chorem/pollen/services/bean/ReportLevel.java | 30 + .../pollen/services/bean/ReportResumeBean.java | 53 + .../org/chorem/pollen/services/bean/VoteBean.java | 10 + .../pollen/services/service/ChoiceService.java | 4 + .../pollen/services/service/CommentService.java | 4 + .../service/FavoriteListImportFromLdap.java | 3 +- .../services/service/NotificationService.java | 89 ++ .../pollen/services/service/PollService.java | 4 + .../services/service/PollenServiceSupport.java | 9 + .../services/service/PollenUIUrlRenderService.java | 11 + .../pollen/services/service/ReportService.java | 191 ++++ .../pollen/services/service/VoteService.java | 4 + .../services/service/mail/AbstractReportEmail.java | 70 ++ .../service/mail/AbstractReportForAdminEmail.java | 49 + .../services/service/mail/ChoiceReportEmail.java | 35 + .../service/mail/ChoiceReportForAdminEmail.java | 35 + .../services/service/mail/CommentReportEmail.java | 26 + .../service/mail/CommentReportForAdminEmail.java | 26 + .../pollen/services/service/mail/EmailService.java | 145 +++ .../services/service/mail/PollReportEmail.java | 22 + .../service/mail/PollReportForAdminEmail.java | 22 + .../pollen/services/service/mail/PollenMail.java | 16 +- .../resources/email/ChoiceReportEmail.mustache | 8 + .../resources/email/ChoiceReportEmail_fr.mustache | 8 + .../email/ChoiceReportForAdminEmail.mustache | 14 + .../email/ChoiceReportForAdminEmail_fr.mustache | 14 + .../resources/email/CommentReportEmail.mustache | 8 + .../resources/email/CommentReportEmail_fr.mustache | 8 + .../email/CommentReportForAdminEmail.mustache | 14 + .../email/CommentReportForAdminEmail_fr.mustache | 14 + .../main/resources/email/PollReportEmail.mustache | 8 + .../resources/email/PollReportEmail_fr.mustache | 8 + .../email/PollReportForAdminEmail.mustache | 14 + .../email/PollReportForAdminEmail_fr.mustache | 14 + .../i18n/pollen-services_en_GB.properties | 10 + .../i18n/pollen-services_fr_FR.properties | 10 + .../src/main/web/css/{main.css => blaze.css} | 561 ++++----- pollen-ui-riot-js/src/main/web/css/main.css | 1193 +------------------- pollen-ui-riot-js/src/main/web/i18n.json | 38 +- pollen-ui-riot-js/src/main/web/index.html | 1 + pollen-ui-riot-js/src/main/web/js/ChoiceService.js | 24 + .../src/main/web/js/CommentService.js | 24 + pollen-ui-riot-js/src/main/web/js/Poll.js | 48 + pollen-ui-riot-js/src/main/web/js/PollService.js | 24 + pollen-ui-riot-js/src/main/web/js/Session.js | 3 +- .../src/main/web/tag/poll/ChoiceView.tag.html | 7 + .../src/main/web/tag/poll/Comments.tag.html | 3 +- .../src/main/web/tag/poll/Poll.tag.html | 3 +- .../src/main/web/tag/poll/Report.tag.html | 232 ++++ .../src/main/web/tag/popup/Modal.tag.html | 3 +- .../src/main/web/tag/popup/NewPassword.tag.html | 4 +- .../main/web/tag/popup/ResendValidation.tag.html | 2 +- .../web/tag/voterList/VoterListActions.tag.html | 2 +- 70 files changed, 1965 insertions(+), 1552 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportResume.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportResume.java new file mode 100644 index 00000000..19265ff5 --- /dev/null +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportResume.java @@ -0,0 +1,43 @@ +package org.chorem.pollen.persistence.entity; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ReportResume { + + protected long score; + + protected long count; + + protected long ignore; + + public ReportResume(Long score, Long count, Long ignore) { + this.score = score == null ? 0 : score; + this.count = count == null ? 0 : count; + this.ignore = ignore == null ? 0 : ignore; + } + + public long getScore() { + return score; + } + + public void setScore(long score) { + this.score = score; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public long getIgnore() { + return ignore; + } + + public void setIgnore(long ignore) { + this.ignore = ignore; + } +} diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportTopiaDao.java new file mode 100644 index 00000000..09a24ef0 --- /dev/null +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/ReportTopiaDao.java @@ -0,0 +1,26 @@ +package org.chorem.pollen.persistence.entity; + +import com.google.common.collect.Maps; + +import java.util.Map; + +public class ReportTopiaDao extends AbstractReportTopiaDao<Report> { + + public static final String REPORT_REQUEST = "SELECT new "+ ReportResume.class.getCanonicalName() +"(" + + "sum(" + Report.PROPERTY_LEVEL + "), " + + "count(*), " + + "sum(CASE WHEN " + Report.PROPERTY_IGNORE + " = true THEN 1 ELSE 0 END)) " + + "FROM " + Report.class.getCanonicalName() + " " + + "WHERE " + Report.PROPERTY_TARGET_ID + " = :" + Report.PROPERTY_TARGET_ID + " "; + + public ReportResume getReportResume(String targetId) { + + Map<String, Object> parameters = Maps.newHashMap(); + parameters.put(Report.PROPERTY_TARGET_ID, targetId); + + ReportResume report = findAnyOrNull(REPORT_REQUEST, parameters); + + return report; + } + +} //ReportingTopiaDao diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_3__add_reports.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_3__add_reports.sql new file mode 100644 index 00000000..41ddb425 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_3__add_reports.sql @@ -0,0 +1,11 @@ +-- reporting + +CREATE TABLE REPORT ( + TOPIAID VARCHAR(255) NOT NULL PRIMARY KEY, + TOPIAVERSION BIGINT NOT NULL, + TOPIACREATEDATE TIMESTAMP, + LEVEL INTEGER, + EMAIL VARCHAR(255), + IGNORE BOOLEAN, + TARGETID VARCHAR(255) +); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_3__add_reports.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_3__add_reports.sql new file mode 100644 index 00000000..4762588d --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_3__add_reports.sql @@ -0,0 +1,11 @@ +-- reporting + +CREATE TABLE report ( + topiaid character varying(255) NOT NULL PRIMARY KEY, + topiaversion bigint NOT NULL, + topiacreatedate timestamp without time zone, + level integer, + email character varying(255), + ignore boolean, + targetid character varying(255) +); diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index a388b72a..997cd1b8 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.0.0.2 +model.tagvalue.version=3.0.0.3 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index d62821be..2ad42e70 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java index 48f76140..98bdc852 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java @@ -41,6 +41,7 @@ import org.chorem.pollen.services.bean.FavoriteListMemberBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenUserBean; +import org.chorem.pollen.services.bean.ReportBean; import org.chorem.pollen.services.bean.VoteBean; import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.bean.VoterListBean; @@ -91,7 +92,8 @@ public class PollenRestApiApplicationListener implements WebMotionServerListener VoterListBean.class, VoterListMemberBean.class, PaginationParameterBean.class, - PollenUIContext.class + PollenUIContext.class, + ReportBean.class ); private Scheduler scheduler; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ChoiceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ChoiceApi.java index 6d6a6a71..8db3babf 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ChoiceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ChoiceApi.java @@ -23,11 +23,14 @@ package org.chorem.pollen.rest.api.v1; import org.chorem.pollen.persistence.entity.Choice; import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportBean; import org.chorem.pollen.services.service.ChoiceService; import org.chorem.pollen.services.service.InvalidFormException; +import org.chorem.pollen.services.service.ReportService; import org.debux.webmotion.server.WebMotionController; import java.util.List; @@ -70,4 +73,21 @@ public class ChoiceApi extends WebMotionController { } + public void addReport(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Choice> choiceId, ReportBean report) throws InvalidFormException { + + reportService.addChoiceReport(pollId.getEntityId(), choiceId.getEntityId(), report); + + } + + public List<ReportBean> getReports(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Choice> choiceId) { + + return reportService.getChoiceReports(pollId.getEntityId(), choiceId.getEntityId()); + } + + public void ignoreReport(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Choice> choiceId, PollenEntityId<Report> reportId) { + + reportService.ignoreChoiceReport(pollId.getEntityId(), choiceId.getEntityId(), reportId.getEntityId()); + + } + } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/CommentApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/CommentApi.java index d36c8bd5..f8d074e7 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/CommentApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/CommentApi.java @@ -23,15 +23,20 @@ package org.chorem.pollen.rest.api.v1; import org.chorem.pollen.persistence.entity.Comment; import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.services.bean.CommentBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportBean; import org.chorem.pollen.services.service.CommentService; import org.chorem.pollen.services.service.InvalidFormException; +import org.chorem.pollen.services.service.ReportService; import org.debux.webmotion.server.WebMotionController; +import java.util.List; + /** * TODO @@ -77,4 +82,21 @@ public class CommentApi extends WebMotionController { } + public void addReport(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Comment> commentId, ReportBean report) throws InvalidFormException { + + reportService.addCommentReport(pollId.getEntityId(), commentId.getEntityId(), report); + + } + + public List<ReportBean> getReports(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Comment> commentId) { + + return reportService.getCommentReports(pollId.getEntityId(), commentId.getEntityId()); + } + + public void ignoreReport(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Comment> commentId, PollenEntityId<Report> reportId) { + + reportService.ignoreCommentReport(pollId.getEntityId(), commentId.getEntityId(), reportId.getEntityId()); + + } + } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java index 7df49fc3..4bc7d89f 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java @@ -24,17 +24,20 @@ package org.chorem.pollen.rest.api.v1; import com.google.common.collect.Lists; import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportBean; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; import org.chorem.pollen.services.service.FeedService; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollService; +import org.chorem.pollen.services.service.ReportService; import org.debux.webmotion.server.WebMotionController; import org.debux.webmotion.server.render.Render; @@ -141,4 +144,21 @@ public class PollApi extends WebMotionController { public Render getFeedForPoll(FeedService feedService, PollenEntityId<Poll> pollId) { return renderAtom(feedService.getFeedForPoll(pollId.getEntityId())); } + + public void addReport(ReportService reportService, PollenEntityId<Poll> pollId, ReportBean report) throws InvalidFormException { + + reportService.addPollReport(pollId.getEntityId(), report); + + } + + public List<ReportBean> getReports(ReportService reportService, PollenEntityId<Poll> pollId) { + + return reportService.getPollReports(pollId.getEntityId()); + } + + public void ignoreReport(ReportService reportService, PollenEntityId<Poll> pollId, PollenEntityId<Report> reportId) { + + reportService.ignorePollReport(pollId.getEntityId(), reportId.getEntityId()); + + } } diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index 2d1c78cc..63300517 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -61,9 +61,12 @@ POST,PUT /v1/resendValidation AuthApi.resendValidation # ChoiceApi -GET /v1/polls/{pollId}/choices ChoiceApi.getChoices -POST /v1/polls/{pollId}/choices ChoiceApi.addChoice -GET /v1/polls/{pollId}/choices/{choiceId} ChoiceApi.getChoice +GET /v1/polls/{pollId}/choices ChoiceApi.getChoices +POST /v1/polls/{pollId}/choices ChoiceApi.addChoice +GET /v1/polls/{pollId}/choices/{choiceId} ChoiceApi.getChoice +POST /v1/polls/{pollId}/choices/{choiceId}/reports ChoiceApi.addReport +GET /v1/polls/{pollId}/choices/{choiceId}/reports ChoiceApi.getReports +GET /v1/polls/{pollId}/choices/{choiceId}/reports/{reportId}/ignore ChoiceApi.ignoreReport #fix me POST,PUT /v1/polls/{pollId}/choices/{choiceId} ChoiceApi.editChoice @@ -72,12 +75,15 @@ DELETE /v1/polls/{pollId}/choices/{choiceId} ChoiceApi.deleteChoice # CommentApi -GET /v1/polls/{pollId}/comments CommentApi.getComments -POST /v1/polls/{pollId}/comments CommentApi.addComment -GET /v1/polls/{pollId}/comments/new CommentApi.getNewComment -GET /v1/polls/{pollId}/comments/{commentId} CommentApi.getComment -PUT,POST /v1/polls/{pollId}/comments/{commentId} CommentApi.editComment -DELETE /v1/polls/{pollId}/comments/{commentId} CommentApi.deleteComment +GET /v1/polls/{pollId}/comments CommentApi.getComments +POST /v1/polls/{pollId}/comments CommentApi.addComment +GET /v1/polls/{pollId}/comments/new CommentApi.getNewComment +GET /v1/polls/{pollId}/comments/{commentId} CommentApi.getComment +PUT,POST /v1/polls/{pollId}/comments/{commentId} CommentApi.editComment +DELETE /v1/polls/{pollId}/comments/{commentId} CommentApi.deleteComment +POST /v1/polls/{pollId}/comments/{commentId}/reports CommentApi.addReport +GET /v1/polls/{pollId}/comments/{commentId}/reports CommentApi.getReports +GET /v1/polls/{pollId}/comments/{commentId}/reports/{reportId}/ignore CommentApi.ignoreReport # FavoriteListApi @@ -104,30 +110,34 @@ DELETE /v1/favoriteLists/{favoriteListId}/lists/{childListId} FavoriteListApi. # PollApi -GET /v1/polls/new PollApi.getNewPoll -GET /v1/polls PollApi.getPolls -GET /v1/polls/created PollApi.getCreatedPolls -GET /v1/polls/invited PollApi.getInvitedPolls -GET /v1/polls/participated PollApi.getParticipatedPolls -POST /v1/polls PollApi.createPoll -POST,GET /v1/polls/create PollApi.createPoll -GET /v1/polls/edit PollApi.editPoll +GET /v1/polls/new PollApi.getNewPoll +GET /v1/polls PollApi.getPolls +GET /v1/polls/created PollApi.getCreatedPolls +GET /v1/polls/invited PollApi.getInvitedPolls +GET /v1/polls/participated PollApi.getParticipatedPolls +POST /v1/polls PollApi.createPoll +POST,GET /v1/polls/create PollApi.createPoll +GET /v1/polls/edit PollApi.editPoll #fix me -POST,PUT /v1/polls/{pollId} PollApi.editPoll -POST /v1/polls/{pollId}/edit PollApi.editPoll +POST,PUT /v1/polls/{pollId} PollApi.editPoll +POST /v1/polls/{pollId}/edit PollApi.editPoll -GET /v1/polls/{pollId} PollApi.getPoll -DELETE /v1/polls/{pollId} PollApi.deletePoll +GET /v1/polls/{pollId} PollApi.getPoll +DELETE /v1/polls/{pollId} PollApi.deletePoll -POST /v1/polls/{pollId}/clone PollApi.clonePoll +POST /v1/polls/{pollId}/clone PollApi.clonePoll -GET /v1/polls/{pollId}/export PollApi.exportPoll -PUT /v1/polls/{pollId}/close PollApi.closePoll -PUT /v1/polls/{pollId}/reopen PollApi.reopenPoll -PUT /v1/polls/{pollId}/assign PollApi.assignPoll +GET /v1/polls/{pollId}/export PollApi.exportPoll +PUT /v1/polls/{pollId}/close PollApi.closePoll +PUT /v1/polls/{pollId}/reopen PollApi.reopenPoll +PUT /v1/polls/{pollId}/assign PollApi.assignPoll -GET /v1/polls/{pollId}/feed PollApi.getFeedForPoll +GET /v1/polls/{pollId}/feed PollApi.getFeedForPoll + +POST /v1/polls/{pollId}/reports PollApi.addReport +GET /v1/polls/{pollId}/reports PollApi.getReports +GET /v1/polls/{pollId}/reports/{reportId}/ignore PollApi.ignoreReport # PollenResourceApi diff --git a/pollen-services/src/main/config/PollenServices.ini b/pollen-services/src/main/config/PollenServices.ini index ac25e9bb..147756c5 100644 --- a/pollen-services/src/main/config/PollenServices.ini +++ b/pollen-services/src/main/config/PollenServices.ini @@ -164,4 +164,10 @@ type = string description = pollen.configuration.resendEmailsCronSchedule key = pollen.resendEmailsCronSchedule type = string -defaultValue = "0 0/5 * * * ?" \ No newline at end of file +defaultValue = "0 0/5 * * * ?" + +[option reportMaxScore] +description = pollen.configuration.report.maxScore +key = pollen.report.maxScore +type = long +defaultValue = 100 \ No newline at end of file diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java b/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java index 01d0a137..e2b07a45 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java @@ -17,6 +17,7 @@ public class PollenUIContext implements Serializable { private String pollEditUrl; + private String resourceUrl; public String getUiEndPoint() { return uiEndPoint; @@ -57,4 +58,12 @@ public class PollenUIContext implements Serializable { public void setPollEditUrl(String pollEditUrl) { this.pollEditUrl = pollEditUrl; } + + public String getResourceUrl() { + return resourceUrl; + } + + public void setResourceUrl(String resourceUrl) { + this.resourceUrl = resourceUrl; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ChoiceBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ChoiceBean.java index 61df736a..7f8d42e5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ChoiceBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ChoiceBean.java @@ -45,6 +45,8 @@ public class ChoiceBean extends PollenBean<Choice> { protected boolean choiceIsDeletable; + protected ReportResumeBean report; + public ChoiceBean() { super(Choice.class); } @@ -124,4 +126,12 @@ public class ChoiceBean extends PollenBean<Choice> { public void setChoiceIsDeletable(boolean choiceIsDeletable) { this.choiceIsDeletable = choiceIsDeletable; } + + public ReportResumeBean getReport() { + return report; + } + + public void setReport(ReportResumeBean report) { + this.report = report; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java index de911b15..e4d235da 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/CommentBean.java @@ -43,6 +43,8 @@ public class CommentBean extends PollenBean<Comment> { protected Date postDate; + protected ReportResumeBean report; + public CommentBean() { super(Comment.class); } @@ -120,4 +122,12 @@ public class CommentBean extends PollenBean<Comment> { public void setAuthorName(String authorName) { this.authorName = authorName; } + + public ReportResumeBean getReport() { + return report; + } + + public void setReport(ReportResumeBean report) { + this.report = report; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index 806ab670..3a64b9d2 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -137,6 +137,8 @@ public class PollBean extends PollenBean<Poll> { protected String notificationLocale; + protected ReportResumeBean report; + @Override public void fromEntity(Poll entity) { @@ -528,4 +530,12 @@ public class PollBean extends PollenBean<Poll> { public void setParticipantCount(long participantCount) { this.participantCount = participantCount; } + + public ReportResumeBean getReport() { + return report; + } + + public void setReport(ReportResumeBean report) { + this.report = report; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportBean.java new file mode 100644 index 00000000..1b8f209b --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportBean.java @@ -0,0 +1,65 @@ +package org.chorem.pollen.services.bean; + +import org.chorem.pollen.persistence.entity.Report; +import org.chorem.pollen.persistence.entity.ReportImpl; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ReportBean extends PollenBean<Report> { + + protected ReportLevel level; + + protected String email; + + protected boolean ignore; + + public ReportBean() { + super(Report.class); + } + + public ReportLevel getLevel() { + return level; + } + + public void setLevel(ReportLevel level) { + this.level = level; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isIgnore() { + return ignore; + } + + public void setIgnore(boolean ignore) { + this.ignore = ignore; + } + + @Override + public void fromEntity(Report entity) { + setEntityId(entity.getTopiaId()); + + setLevel(ReportLevel.of(entity.getLevel())); + setEmail(entity.getEmail()); + setIgnore(entity.isIgnore()); + } + + @Override + public Report toEntity() { + Report entity = new ReportImpl(); + + entity.setTopiaId(getEntityId()); + entity.setLevel(getLevel().getScore()); + entity.setEmail(getEmail()); + entity.setIgnore(isIgnore()); + + return entity; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportLevel.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportLevel.java new file mode 100644 index 00000000..7eb76378 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportLevel.java @@ -0,0 +1,30 @@ +package org.chorem.pollen.services.bean; + +import java.util.stream.Stream; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public enum ReportLevel { + + OFF_TOPIC(1), + SPAM(5), + ILLEGAL(100); + + protected int score; + + ReportLevel(int score) { + this.score = score; + } + + public int getScore() { + return score; + } + + public static ReportLevel of(int score) { + return Stream.of(values()) + .filter(level -> score == level.getScore()) + .findAny() + .orElse(null); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportResumeBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportResumeBean.java new file mode 100644 index 00000000..bb46b5c7 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ReportResumeBean.java @@ -0,0 +1,53 @@ +package org.chorem.pollen.services.bean; + +import org.chorem.pollen.persistence.entity.ReportResume; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ReportResumeBean { + + public static ReportResumeBean of(ReportResume report) { + ReportResumeBean reportBean = null; + + if (report.getCount() > 0) { + + reportBean = new ReportResumeBean(); + + reportBean.setScore(report.getScore()); + reportBean.setCount(report.getCount()); + reportBean.setIgnore(report.getIgnore()); + } + return reportBean; + } + + protected long score; + + protected long count; + + protected long ignore; + + public long getScore() { + return score; + } + + public void setScore(long score) { + this.score = score; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public long getIgnore() { + return ignore; + } + + public void setIgnore(long ignore) { + this.ignore = ignore; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java index 0f138661..3be138ca 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java @@ -59,6 +59,8 @@ public class VoteBean extends PollenBean<Vote> { protected final Set<VoteToChoiceBean> choice = new LinkedHashSet<>(); + private ReportResumeBean report; + public VoteBean() { super(Vote.class); } @@ -200,4 +202,12 @@ public class VoteBean extends PollenBean<Vote> { public void setWeight(double weight) { this.weight = weight; } + + public void setReport(ReportResumeBean report) { + this.report = report; + } + + public ReportResumeBean getReport() { + return report; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java index a35790aa..e3c908b5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportResumeBean; import org.chorem.pollen.services.service.security.PermissionVerb; import java.util.Calendar; @@ -52,6 +53,9 @@ public class ChoiceService extends PollenServiceSupport { protected final Function<ChoiceBean, ChoiceBean> choiceBeanFunction = input -> { if (isNotPermitted(PermissionVerb.editChoice, input.getEntityId())) { input.setPermission(null); + } else { + ReportResumeBean report = getReportService().getReport(input.getEntityId()); + input.setReport(report); } if (input.getChoiceType() == ChoiceType.RESOURCE) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java index eb2a2cd1..91642546 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java @@ -30,6 +30,7 @@ import org.chorem.pollen.services.bean.CommentBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportResumeBean; import org.chorem.pollen.services.service.security.PermissionVerb; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; @@ -49,6 +50,9 @@ public class CommentService extends PollenServiceSupport { private final Function<CommentBean, CommentBean> commentFunction = input -> { if (isNotPermitted(PermissionVerb.editComment, input.getEntityId())) { input.setPermission(null); + } else { + ReportResumeBean report = getReportService().getReport(input.getEntityId()); + input.setReport(report); } return input; }; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromLdap.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromLdap.java index bb8d4468..1b9210ca 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromLdap.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/FavoriteListImportFromLdap.java @@ -93,9 +93,10 @@ public class FavoriteListImportFromLdap extends PollenServiceSupport implements Pattern loginLdapPattern = Pattern.compile("ldaps?://(([^:]+):([^@]+)@)?.*"); Matcher matcher = loginLdapPattern.matcher(ldap); if (matcher.find() && matcher.group(1) != null) { + env.put(Context.SECURITY_AUTHENTICATION, "simple"); if (matcher.group(2) != null) { String login = URLDecoder.decode(matcher.group(2), "UTF-8"); - env.put(Context.SECURITY_PRINCIPAL, login); + env.put(Context.SECURITY_PRINCIPAL, "cn=" + login); } if (matcher.group(3) != null) { String password = URLDecoder.decode(matcher.group(3), "UTF-8"); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java index d132ee2f..90fce101 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java @@ -28,20 +28,27 @@ import org.chorem.pollen.persistence.entity.FavoriteList; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.service.mail.ChoiceAddedEmail; +import org.chorem.pollen.services.service.mail.ChoiceReportEmail; +import org.chorem.pollen.services.service.mail.ChoiceReportForAdminEmail; import org.chorem.pollen.services.service.mail.CommentAddedEmail; import org.chorem.pollen.services.service.mail.CommentDeletedEmail; import org.chorem.pollen.services.service.mail.CommentEditedEmail; +import org.chorem.pollen.services.service.mail.CommentReportEmail; +import org.chorem.pollen.services.service.mail.CommentReportForAdminEmail; import org.chorem.pollen.services.service.mail.EmailService; import org.chorem.pollen.services.service.mail.LostPasswordEmail; import org.chorem.pollen.services.service.mail.PollClosedEmail; import org.chorem.pollen.services.service.mail.PollCreatedEmail; import org.chorem.pollen.services.service.mail.PollEndReminderEmail; import org.chorem.pollen.services.service.mail.PollInvitationEmail; +import org.chorem.pollen.services.service.mail.PollReportEmail; +import org.chorem.pollen.services.service.mail.PollReportForAdminEmail; import org.chorem.pollen.services.service.mail.ResendValidationEmail; import org.chorem.pollen.services.service.mail.RestrictedPollInvitationEmail; import org.chorem.pollen.services.service.mail.UserAccountCreatedEmail; @@ -52,7 +59,9 @@ import org.chorem.pollen.services.service.mail.UserAccountPasswordChangedEmail; import org.chorem.pollen.services.service.mail.VoteAddedEmail; import org.chorem.pollen.services.service.mail.VoteDeletedEmail; import org.chorem.pollen.services.service.mail.VoteEditedEmail; +import org.nuiton.topia.persistence.TopiaEntity; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -296,4 +305,84 @@ public class NotificationService extends PollenServiceSupport { pollEndReminderEmail.addTo(poll.getCreator().getEmail()); emailService.send(pollEndReminderEmail); } + + public void onAddCommentReport(Poll poll, Comment comment, Report report) { + + EmailService emailService = getEmailService(); + + // email to poll creator + if (StringUtils.isNotBlank(poll.getCreator().getEmail())) { + CommentReportEmail commentReportEmail = emailService.newCommentReportEmail(poll, comment, report); + + commentReportEmail.addTo(poll.getCreator().getEmail()); + emailService.send(commentReportEmail); + } + + // email to administrators + getAdminsToSentReport(poll, comment).forEach(admin -> { + CommentReportForAdminEmail commentReportForAdminEmail = emailService.newCommentReportForAdminEmail(poll, comment, report, admin); + + commentReportForAdminEmail.addTo(admin.getEmail()); + emailService.send(commentReportForAdminEmail); + }); + + } + + protected List<PollenUser> getAdminsToSentReport(Poll poll, TopiaEntity target) { + long score = getReportService().getScore(target); + + List<PollenUser> admins = Collections.emptyList(); + + if (StringUtils.isBlank(poll.getCreator().getEmail()) || score >= getPollenServiceConfig().getReportMaxScore()) { + + admins = getPollenUserDao().forAdministratorEquals(true).findAll(); + + } + + return admins; + } + + public void onAddChoiceReport(Poll poll, Choice choice, Report report) { + + EmailService emailService = getEmailService(); + + // email to poll creator + if (StringUtils.isNotBlank(poll.getCreator().getEmail())) { + ChoiceReportEmail choiceReportEmail = emailService.newChoiceReportEmail(poll, choice, report); + + choiceReportEmail.addTo(poll.getCreator().getEmail()); + emailService.send(choiceReportEmail); + } + + // email to administrators + getAdminsToSentReport(poll, choice).forEach(admin -> { + ChoiceReportForAdminEmail choiceReportForAdminEmail = emailService.newChoiceReportForAdminEmail(poll, choice, report, admin); + + choiceReportForAdminEmail.addTo(admin.getEmail()); + emailService.send(choiceReportForAdminEmail); + }); + + } + + public void onAddPollReport(Poll poll, Report report) { + + EmailService emailService = getEmailService(); + + // email to poll creator + if (StringUtils.isNotBlank(poll.getCreator().getEmail())) { + PollReportEmail pollReportEmail = emailService.newPollReportEmail(poll, report); + + pollReportEmail.addTo(poll.getCreator().getEmail()); + emailService.send(pollReportEmail); + } + + // email to administrators + getAdminsToSentReport(poll, poll).forEach(admin -> { + PollReportForAdminEmail pollReportForAdminEmail = emailService.newPollReportForAdminEmail(poll, report, admin); + + pollReportForAdminEmail.addTo(admin.getEmail()); + emailService.send(pollReportForAdminEmail); + }); + + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index 4e572fa9..3b270f76 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -36,6 +36,7 @@ import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportResumeBean; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; import org.chorem.pollen.services.config.PollenServicesConfig; @@ -71,6 +72,9 @@ public class PollService extends PollenServiceSupport { input.setCreatorEmail(null); input.setCreatorName(null); + } else { + ReportResumeBean report = getReportService().getReport(input.getEntityId()); + input.setReport(report); } boolean commentIsVisible = isPermitted(PermissionVerb.readComment, input.getEntityId()); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java index f78d185a..88b0a6ca 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java @@ -39,6 +39,7 @@ import org.chorem.pollen.persistence.entity.PollenPrincipalTopiaDao; import org.chorem.pollen.persistence.entity.PollenResourceTopiaDao; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; +import org.chorem.pollen.persistence.entity.ReportTopiaDao; import org.chorem.pollen.persistence.entity.SessionTokenTopiaDao; import org.chorem.pollen.persistence.entity.VoteToChoiceTopiaDao; import org.chorem.pollen.persistence.entity.VoteTopiaDao; @@ -142,6 +143,10 @@ public abstract class PollenServiceSupport implements PollenService { return newService(SecurityService.class); } + protected ReportService getReportService() { + return newService(ReportService.class); + } + protected PollenResourceService getPollenResourceService() { return newService(PollenResourceService.class); } @@ -208,6 +213,10 @@ public abstract class PollenServiceSupport implements PollenService { return getPersistenceContext().getPollenUserDao(); } + protected ReportTopiaDao getReportTopiaDao() { + return getPersistenceContext().getReportDao(); + } + protected SessionTokenTopiaDao getSessionTokenDao() { return getPersistenceContext().getSessionTokenDao(); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java index 31c11eed..6b7f4573 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java @@ -96,4 +96,15 @@ public class PollenUIUrlRenderService extends PollenServiceSupport { } return url; } + + public String getResourceUrl(String resourceUrl, String resourceId) { + String url = null; + + if (resourceUrl != null) { + checkNotNull(resourceId); + + url = resourceUrl.replace("{resourceId}", resourceId); + } + return url; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/ReportService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/ReportService.java new file mode 100644 index 00000000..746db08e --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/ReportService.java @@ -0,0 +1,191 @@ +package org.chorem.pollen.services.service; + +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.persistence.entity.Comment; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Report; +import org.chorem.pollen.persistence.entity.ReportResume; +import org.chorem.pollen.services.bean.ReportBean; +import org.chorem.pollen.services.bean.ReportResumeBean; +import org.chorem.pollen.services.service.security.PermissionVerb; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.List; + +import static org.nuiton.i18n.I18n.l; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ReportService extends PollenServiceSupport { + + + public void addPollReport(String pollId, ReportBean reportBean) throws InvalidFormException { + + checkNotNull(pollId); + checkPermission(PermissionVerb.readPoll, pollId); + + Poll poll = getPollService().getPoll0(pollId); + + Report report = getReportService().addReport(reportBean, poll); + + getNotificationService().onAddPollReport(poll, report); + + } + + public List<ReportBean> getPollReports(String pollId) { + + checkNotNull(pollId); + checkPermission(PermissionVerb.editPoll, pollId); + + return getReportService().getReports(pollId); + + } + + public void ignorePollReport(String pollId, String reportId) { + checkNotNull(pollId); + checkNotNull(reportId); + checkPermission(PermissionVerb.editPoll, pollId); + + ignoreReport(reportId, pollId); + } + + public void addChoiceReport(String pollId, String choiceId, ReportBean reportBean) throws InvalidFormException { + + checkNotNull(pollId); + checkNotNull(choiceId); + checkPermission(PermissionVerb.readChoice, choiceId); + + Poll poll = getPollService().getPoll0(pollId); + + Choice choice = getChoiceService().getChoice(poll, choiceId); + + Report report = getReportService().addReport(reportBean, choice); + + getNotificationService().onAddChoiceReport(poll, choice, report); + + } + + public List<ReportBean> getChoiceReports(String pollId, String choiceId) { + + checkNotNull(pollId); + checkNotNull(choiceId); + checkPermission(PermissionVerb.editPoll, pollId); + + return getReportService().getReports(choiceId); + + } + + public void ignoreChoiceReport(String pollId, String choiceId, String reportId) { + checkNotNull(pollId); + checkNotNull(choiceId); + checkNotNull(reportId); + checkPermission(PermissionVerb.editPoll, pollId); + + ignoreReport(reportId, choiceId); + } + + public void addCommentReport(String pollId, String commentId, ReportBean reportBean) throws InvalidFormException { + + checkNotNull(pollId); + checkNotNull(commentId); + checkPermission(PermissionVerb.readComment, commentId); + + Poll poll = getPollService().getPoll0(pollId); + + Comment comment = getCommentService().getComment(poll, commentId); + + Report report = getReportService().addReport(reportBean, comment); + + getNotificationService().onAddCommentReport(poll, comment, report); + + } + + public List<ReportBean> getCommentReports(String pollId, String commentId) { + + checkNotNull(pollId); + checkNotNull(commentId); + checkPermission(PermissionVerb.editPoll, pollId); + + return getReportService().getReports(commentId); + + } + + public void ignoreCommentReport(String pollId, String commentId, String reportId) { + checkNotNull(pollId); + checkNotNull(commentId); + checkNotNull(reportId); + checkPermission(PermissionVerb.editPoll, pollId); + + ignoreReport(reportId, commentId); + } + + + protected List<ReportBean> getReports(String targetId) { + checkNotNull(targetId); + + List<Report> reports = getReportTopiaDao().forTargetIdEquals(targetId).findAll(); + + return toBeanList(ReportBean.class, reports); + } + + protected Report addReport(ReportBean report, TopiaEntity target) throws InvalidFormException { + + checkNotNull(report); + checkIsNotPersisted(report); + + checkNotNull(target); + checkIsPersisted(target); + + ErrorMap errorMap = checkReport(report); + errorMap.failIfNotEmpty(); + + Report reportEntity = report.toEntity(); + reportEntity.setTargetId(target.getTopiaId()); + + reportEntity = getReportTopiaDao().create(reportEntity); + + commit(); + + return reportEntity; + + } + + protected ErrorMap checkReport(ReportBean report) { + ErrorMap errors = new ErrorMap(); + + checkNotNull(errors, Report.PROPERTY_LEVEL, report.getLevel(), l(getLocale(), "pollen.error.report.level.mandatory")); + checkNotNull(errors, Report.PROPERTY_EMAIL, report.getEmail(), l(getLocale(), "pollen.error.report.email.mandatory")); + checkValidEmail(errors, Report.PROPERTY_EMAIL, report.getEmail(), l(getLocale(), "pollen.error.report.email.invalid")); + + return errors; + } + + protected void ignoreReport(String reportId, String targetId) { + + checkNotNull(reportId); + checkNotNull(targetId); + + Report report = getReportTopiaDao() + .forTopiaIdEquals(reportId) + .addEquals(Report.PROPERTY_TARGET_ID, targetId) + .findUnique(); + + report.setIgnore(true); + + commit(); + } + + public ReportResumeBean getReport(String targetId) { + + ReportResume report = getReportTopiaDao().getReportResume(targetId); + + return ReportResumeBean.of(report); + } + + public long getScore(TopiaEntity target) { + + ReportResume report = getReportTopiaDao().getReportResume(target.getTopiaId()); + return report.getScore(); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index ab933ac4..d526b1f9 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -34,6 +34,7 @@ import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.ReportResumeBean; import org.chorem.pollen.services.bean.VoteBean; import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.service.security.PermissionVerb; @@ -63,6 +64,9 @@ public class VoteService extends PollenServiceSupport { if (input.isAnonymous()) { input.setVoterName(null); } + } else { + ReportResumeBean report = getReportService().getReport(input.getEntityId()); + input.setReport(report); } return input; }; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportEmail.java new file mode 100644 index 00000000..9f3cd340 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportEmail.java @@ -0,0 +1,70 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Report; +import org.chorem.pollen.services.bean.ReportLevel; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public abstract class AbstractReportEmail<T extends TopiaEntity> extends PollenMail { + + protected Poll poll; + + protected T target; + + protected Report report; + + protected String url; + + public AbstractReportEmail(Locale locale) { + super(locale); + } + + public Poll getPoll() { + return poll; + } + + public void setPoll(Poll poll) { + this.poll = poll; + } + + public T getTarget() { + return target; + } + + public void setTarget(T target) { + this.target = target; + } + + public Report getReport() { + return report; + } + + public void setReport(Report report) { + this.report = report; + } + + public boolean isIllegal() { + return ReportLevel.ILLEGAL.getScore() == report.getLevel(); + } + + public boolean isSpam() { + return ReportLevel.SPAM.getScore() == report.getLevel(); + } + + public boolean isOffTopic() { + return ReportLevel.OFF_TOPIC.getScore() == report.getLevel(); + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportForAdminEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportForAdminEmail.java new file mode 100644 index 00000000..a5544bc3 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractReportForAdminEmail.java @@ -0,0 +1,49 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.Report; +import org.chorem.pollen.persistence.entity.ReportResume; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.List; +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public abstract class AbstractReportForAdminEmail<T extends TopiaEntity> extends AbstractReportEmail<T> { + + protected PollenUser administrator; + + protected List<Report> reports; + + protected ReportResume resume; + + public AbstractReportForAdminEmail(Locale locale) { + super(locale); + } + + public PollenUser getAdministrator() { + return administrator; + } + + public void setAdministrator(PollenUser administrator) { + this.administrator = administrator; + } + + public List<Report> getReports() { + return reports; + } + + public void setReports(List<Report> reports) { + this.reports = reports; + } + + public ReportResume getResume() { + return resume; + } + + public void setResume(ReportResume resume) { + this.resume = resume; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportEmail.java new file mode 100644 index 00000000..ec4bf50c --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportEmail.java @@ -0,0 +1,35 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Choice; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ChoiceReportEmail extends AbstractReportEmail<Choice> { + + private String choiceValue; + + public ChoiceReportEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.ChoiceReportEmail.subject", poll.getTitle()); + } + + public String getChoiceValue() { + return choiceValue; + } + + public void setChoiceValue(String choiceValue) { + this.choiceValue = choiceValue; + } + + public String getChoiceCreateDate() { + return formatDate(target.getTopiaCreateDate()); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportForAdminEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportForAdminEmail.java new file mode 100644 index 00000000..86a51ccf --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/ChoiceReportForAdminEmail.java @@ -0,0 +1,35 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Choice; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ChoiceReportForAdminEmail extends AbstractReportForAdminEmail<Choice> { + + private String choiceValue; + + public ChoiceReportForAdminEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.ChoiceReportForAdminEmail.subject", poll.getTitle()); + } + + public String getChoiceValue() { + return choiceValue; + } + + public void setChoiceValue(String choiceValue) { + this.choiceValue = choiceValue; + } + + public String getChoiceCreateDate() { + return formatDate(target.getTopiaCreateDate()); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportEmail.java new file mode 100644 index 00000000..2c841968 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportEmail.java @@ -0,0 +1,26 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Comment; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CommentReportEmail extends AbstractReportEmail<Comment> { + + public CommentReportEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.CommentReportEmail.subject", poll.getTitle()); + } + + public String getCommentPostDate() { + return formatDate(target.getPostDate()); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportForAdminEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportForAdminEmail.java new file mode 100644 index 00000000..7db8bf08 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/CommentReportForAdminEmail.java @@ -0,0 +1,26 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Comment; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CommentReportForAdminEmail extends AbstractReportForAdminEmail<Comment> { + + public CommentReportForAdminEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.CommentReportForAdminEmail.subject", poll.getTitle()); + } + + public String getCommentPostDate() { + return formatDate(target.getPostDate()); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java index de62686e..8552b21c 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java @@ -41,7 +41,9 @@ import org.chorem.pollen.persistence.entity.EmailToResendImpl; import org.chorem.pollen.persistence.entity.EmailToResendTopiaDao; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollenPrincipal; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.bean.PollenEntityId; @@ -53,6 +55,7 @@ import org.nuiton.topia.persistence.TopiaConfigurationBuilder; import java.io.StringWriter; import java.util.Arrays; import java.util.Collection; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -414,4 +417,146 @@ public class EmailService extends PollenServiceSupport { return stringWriter.toString(); } + public CommentReportEmail newCommentReportEmail(Poll poll, Comment comment, Report report) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + CommentReportEmail email = new CommentReportEmail(getLocale()); + email.setPoll(poll); + email.setTarget(comment); + + comment.getAuthor().getName(); //FIXME BAVENCOFF 14/06/2017 pb de lazy hibernate + + email.setReport(report); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + poll.getCreator().getPermission().getToken()); + email.setUrl(pollUrl); + + return email; + } + + public CommentReportForAdminEmail newCommentReportForAdminEmail(Poll poll, Comment comment, Report report, PollenUser admin) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + CommentReportForAdminEmail email = new CommentReportForAdminEmail(getLocale()); + email.setPoll(poll); + email.setTarget(comment); + + comment.getAuthor().getName(); //FIXME BAVENCOFF 14/06/2017 pb de lazy hibernate + + email.setReport(report); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + null); + email.setUrl(pollUrl); + + email.setAdministrator(admin); + email.setReports(getReportTopiaDao().forTargetIdEquals(comment.getTopiaId()).findAll()); + email.setResume(getReportTopiaDao().getReportResume(comment.getTopiaId())); + + return email; + } + + public ChoiceReportEmail newChoiceReportEmail(Poll poll, Choice choice, Report report) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + ChoiceReportEmail email = new ChoiceReportEmail(getLocale()); + email.setPoll(poll); + email.setTarget(choice); + email.setReport(report); + email.setChoiceValue(getChoiceValue(choice)); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + poll.getCreator().getPermission().getToken()); + email.setUrl(pollUrl); + + return email; + } + + public ChoiceReportForAdminEmail newChoiceReportForAdminEmail(Poll poll, Choice choice, Report report, PollenUser admin) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + ChoiceReportForAdminEmail email = new ChoiceReportForAdminEmail(getLocale()); + email.setPoll(poll); + email.setTarget(choice); + email.setReport(report); + email.setChoiceValue(getChoiceValue(choice)); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + null); + email.setUrl(pollUrl); + + email.setAdministrator(admin); + email.setReports(getReportTopiaDao().forTargetIdEquals(choice.getTopiaId()).findAll()); + email.setResume(getReportTopiaDao().getReportResume(choice.getTopiaId())); + + return email; + } + + public PollReportEmail newPollReportEmail(Poll poll, Report report) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + PollReportEmail email = new PollReportEmail(getLocale()); + email.setPoll(poll); + email.setTarget(poll); + email.setReport(report); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + poll.getCreator().getPermission().getToken()); + email.setUrl(pollUrl); + + return email; + } + + public PollReportForAdminEmail newPollReportForAdminEmail(Poll poll, Report report, PollenUser admin) { + // FIXME BAVENCOFF 15/06/2017 la local du mail devrait etre celle du destinataire + PollReportForAdminEmail email = new PollReportForAdminEmail(getLocale()); + email.setPoll(poll); + email.setTarget(poll); + email.setReport(report); + + PollenEntityId<Poll> pollId = getPollenEntityId(poll); + String pollUrl = getPollenUIUrlRenderService().getPollVoteUrl( + getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + null); + email.setUrl(pollUrl); + + email.setAdministrator(admin); + email.setReports(getReportTopiaDao().forTargetIdEquals(poll.getTopiaId()).findAll()); + email.setResume(getReportTopiaDao().getReportResume(poll.getTopiaId())); + + return email; + } + + protected String getChoiceValue(Choice choice) { + String value; + switch (choice.getChoiceType()) { + case DATE: + case DATETIME: + Date date = new Date(Long.parseLong(choice.getChoiceValue())); + value = PollenMail.formatDate(date, getLocale()); + break; + case RESOURCE: + PollenResource resource = getPollenResourceDao().forTopiaIdEquals(choice.getChoiceValue()).findUnique(); + PollenEntityId<PollenResource> resourceId = getPollenEntityId(resource); + value = getPollenUIUrlRenderService().getResourceUrl( + getUIContext().getResourceUrl(), + resourceId.getReducedId()); + break; + default: + value = choice.getChoiceValue(); + } + return value; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportEmail.java new file mode 100644 index 00000000..9dfcf4f8 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportEmail.java @@ -0,0 +1,22 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Poll; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class PollReportEmail extends AbstractReportEmail<Poll> { + + public PollReportEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.PollReportEmail.subject", poll.getTitle()); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportForAdminEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportForAdminEmail.java new file mode 100644 index 00000000..dcf38ffa --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollReportForAdminEmail.java @@ -0,0 +1,22 @@ +package org.chorem.pollen.services.service.mail; + +import org.chorem.pollen.persistence.entity.Poll; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class PollReportForAdminEmail extends AbstractReportForAdminEmail<Poll> { + + public PollReportForAdminEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + return I18n.l(locale, "pollen.service.mail.PollReportForAdminEmail.subject", poll.getTitle()); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollenMail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollenMail.java index f1f59166..38b7f734 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollenMail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollenMail.java @@ -38,6 +38,15 @@ import java.util.Set; */ public abstract class PollenMail { + public static String formatDate(Date date, Locale locale) { + String result = null; + if (date != null) { + DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, locale); + result = formatter.format(date); + } + return result; + } + protected final Locale locale; protected Set<String> tos; @@ -89,12 +98,7 @@ public abstract class PollenMail { } protected String formatDate(Date date) { - String result = null; - if (date != null) { - DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, locale); - result = formatter.format(date); - } - return result; + return formatDate(date, locale); } public String getSigning() { diff --git a/pollen-services/src/main/resources/email/ChoiceReportEmail.mustache b/pollen-services/src/main/resources/email/ChoiceReportEmail.mustache new file mode 100644 index 00000000..837877db --- /dev/null +++ b/pollen-services/src/main/resources/email/ChoiceReportEmail.mustache @@ -0,0 +1,8 @@ +Hello {{poll.creator.name}}, + +A choice of poll "{{poll.title}}" is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. + +This choice has been created by {{target.creator.name}} on {{choiceCreateDate}} : +"{{choiceValue}}" + +You can delete this choice ou ignore this report here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/ChoiceReportEmail_fr.mustache b/pollen-services/src/main/resources/email/ChoiceReportEmail_fr.mustache new file mode 100644 index 00000000..4d722b4a --- /dev/null +++ b/pollen-services/src/main/resources/email/ChoiceReportEmail_fr.mustache @@ -0,0 +1,8 @@ +Bonjour {{poll.creator.name}}, + +Un choix du votre sondage "{{poll.title}}" est signalé comme {{#isIllegal}}manifestement illégal{{/isIllegal}}{{#isSpam}}un Spam ou une publicité{{/isSpam}}{{#isOffTopic}}hors sujet{{/isOffTopic}} par {{report.email}}. + +Le choix a été créé par {{target.creator.name}} le {{choiceCreateDate}} : +"{{choiceValue}}" + +Vous pouvez supprimer ce choix ou ignorer ce signalement ici : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail.mustache b/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail.mustache new file mode 100644 index 00000000..f3eb95d4 --- /dev/null +++ b/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail.mustache @@ -0,0 +1,14 @@ +Hello {{administrator.name}}, + +A choice of poll "{{poll.title}}" (created by {{poll.creator.name}} {{poll.creator.email}}) is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. + +This choice has been created by {{target.creator.name}} on {{choiceCreateDate}} : +"{{choiceValue}}" + +For this choice, there are {{resume.count}} reports (including {{resume.ignore}} ignores) for a total score of {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignore{{/ignore}} +{{/reports}} + +You can see this choice here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail_fr.mustache b/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail_fr.mustache new file mode 100644 index 00000000..0e55a286 --- /dev/null +++ b/pollen-services/src/main/resources/email/ChoiceReportForAdminEmail_fr.mustache @@ -0,0 +1,14 @@ +Hello {{administrator.name}}, + +A choice of poll "{{poll.title}}" (created by {{poll.creator.name}} {{poll.creator.email}}) is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. + +This choice has been created by {{target.creator.name}} on {{choiceCreateDate}} : +"{{choiceValue}}" + +Pour ce choix il y a {{resume.count}} signalements (dont {{resume.ignore}} ignorés) pour un score total de {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignore{{/ignore}} +{{/reports}} + +You can see this choice here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/CommentReportEmail.mustache b/pollen-services/src/main/resources/email/CommentReportEmail.mustache new file mode 100644 index 00000000..d20199ad --- /dev/null +++ b/pollen-services/src/main/resources/email/CommentReportEmail.mustache @@ -0,0 +1,8 @@ +Hello {{poll.creator.name}}, + +A comment of your poll "{{poll.title}}" is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. + +This comment has been created by {{target.creator.name}} on {{choiceCreateDate}} : +"{{target.text}}" + +You can delete this comment ou ignore this report here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/CommentReportEmail_fr.mustache b/pollen-services/src/main/resources/email/CommentReportEmail_fr.mustache new file mode 100644 index 00000000..880edfef --- /dev/null +++ b/pollen-services/src/main/resources/email/CommentReportEmail_fr.mustache @@ -0,0 +1,8 @@ +Bonjour {{poll.creator.name}}, + +Un commentaire de votre sondage "{{poll.title}}" est signalé comme {{#isIllegal}}manifestement illégal{{/isIllegal}}{{#isSpam}}un Spam ou une publicité{{/isSpam}}{{#isOffTopic}}hors sujet{{/isOffTopic}} par {{report.email}}. + +Le commentaire a été écrit par {{target.author.name}} le {{commentPostDate}} : +"{{target.text}}" + +Vous pouvez supprimer ce commentaire ou ignorer ce signalement ici : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/CommentReportForAdminEmail.mustache b/pollen-services/src/main/resources/email/CommentReportForAdminEmail.mustache new file mode 100644 index 00000000..f0cc793e --- /dev/null +++ b/pollen-services/src/main/resources/email/CommentReportForAdminEmail.mustache @@ -0,0 +1,14 @@ +Hello {{administrator.name}}, + +A comment of poll "{{poll.title}}" (created by {{poll.creator.name}} {{poll.creator.email}}) is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. + +This comment has been created by {{target.creator.name}} on {{commentPostDate}} : +"{{target.text}}" + +For this comment, there are {{resume.count}} reports (including {{resume.ignore}} ignores) for a total score of {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignore{{/ignore}} +{{/reports}} + +You can see this comment here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/CommentReportForAdminEmail_fr.mustache b/pollen-services/src/main/resources/email/CommentReportForAdminEmail_fr.mustache new file mode 100644 index 00000000..e30d2423 --- /dev/null +++ b/pollen-services/src/main/resources/email/CommentReportForAdminEmail_fr.mustache @@ -0,0 +1,14 @@ +Bonjour {{administrator.name}}, + +Un commentaire du sondage "{{poll.title}}" (créé par {{poll.creator.name}} {{poll.creator.email}}) est signalé comme {{#isIllegal}}manifestement illégal{{/isIllegal}}{{#isSpam}}un Spam ou une publicité{{/isSpam}}{{#isOffTopic}}hors sujet{{/isOffTopic}} par {{report.email}}. + +Le commentaire a été écrit par {{target.author.name}} le {{commentPostDate}} : +"{{target.text}}" + +Pour ce commentaire il y a {{resume.count}} signalements (dont {{resume.ignore}} ignorés) pour un score total de {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignoré{{/ignore}} +{{/reports}} + +Vous pouvez voir ce commentaire ici : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/PollReportEmail.mustache b/pollen-services/src/main/resources/email/PollReportEmail.mustache new file mode 100644 index 00000000..2bce3a7f --- /dev/null +++ b/pollen-services/src/main/resources/email/PollReportEmail.mustache @@ -0,0 +1,8 @@ +Hello {{poll.creator.name}}, + +Your poll "{{poll.title}}" is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. +{{#target.description}} + {{target.description}} +{{/target.description}} + +You can delete this poll ou ignore this report here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/PollReportEmail_fr.mustache b/pollen-services/src/main/resources/email/PollReportEmail_fr.mustache new file mode 100644 index 00000000..845ee385 --- /dev/null +++ b/pollen-services/src/main/resources/email/PollReportEmail_fr.mustache @@ -0,0 +1,8 @@ +Bonjour {{user.name}}, + +Votre sondage "{{poll.title}}" est signalé comme {{#isIllegal}}manifestement illégal{{/isIllegal}}{{#isSpam}}un Spam ou une publicité{{/isSpam}}{{#isOffTopic}}hors sujet{{/isOffTopic}} par {{report.email}}. +{{#target.description}} + {{target.description}} +{{/target.description}} + +Vous pouvez supprimer votre sondage ou ignorer ce signalement ici : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/PollReportForAdminEmail.mustache b/pollen-services/src/main/resources/email/PollReportForAdminEmail.mustache new file mode 100644 index 00000000..47671876 --- /dev/null +++ b/pollen-services/src/main/resources/email/PollReportForAdminEmail.mustache @@ -0,0 +1,14 @@ +Hello {{administrator.name}}, + +A poll "{{poll.title}}" (created by {{poll.creator.name}} {{poll.creator.email}}) is report as {{#isIllegal}}patently illegal{{/isIllegal}}{{#isSpam}}a Spam or advertising{{/isSpam}}{{#isOffTopic}}off topic{{/isOffTopic}} by {{report.email}}. +{{#target.description}} + {{target.description}} +{{/target.description}} + +For this poll, there are {{resume.count}} reports (including {{resume.ignore}} ignores) for a total score of {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignore{{/ignore}} +{{/reports}} + +You can see this poll here : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/PollReportForAdminEmail_fr.mustache b/pollen-services/src/main/resources/email/PollReportForAdminEmail_fr.mustache new file mode 100644 index 00000000..7382a74d --- /dev/null +++ b/pollen-services/src/main/resources/email/PollReportForAdminEmail_fr.mustache @@ -0,0 +1,14 @@ +Bonjour {{administrator.name}}, + +Le sondage "{{poll.title}}" (créé par {{poll.creator.name}} {{poll.creator.email}}) est signalé comme {{#isIllegal}}manifestement illégal{{/isIllegal}}{{#isSpam}}un Spam ou une publicité{{/isSpam}}{{#isOffTopic}}hors sujet{{/isOffTopic}} par {{report.email}}. +{{#target.description}} + {{target.description}} +{{/target.description}} + +Pour ce sondage il y a {{resume.count}} signalements (dont {{resume.ignore}} ignorés) pour un score total de {{resume.score}} + +{{#reports}} + - {{level}} {{email}} {{#ignore}}Ignoré{{/ignore}} +{{/reports}} + +Vous pouvez voir ce sondage ici : {{url}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties index a6fda29f..0b78d8bd 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties @@ -21,6 +21,7 @@ pollen.configuration.defaultVoteVisibility=Default vote visiblity pollen.configuration.devMode=Dev mode pollen.configuration.logConfigurationFile=Path to log configuration file pollen.configuration.registration.emailAddressPattern=Regular expression that the user email address must match for registration +pollen.configuration.report.maxScore=Maximum score for reporting before administrators are notified pollen.configuration.resendEmailsCronSchedule=Time between two cron jobs of email resending pollen.configuration.resource.maxSize=Maximum size of pollen resource pollen.configuration.secret= @@ -79,6 +80,9 @@ pollen.error.poll.unique.voterList.mandatory.for.restrictedPoll=A voter list is pollen.error.poll.voteCountingType.mandatory=vote counting type is mandatory pollen.error.poll.voteVisibility.mandatory=vote visibility is mandatory pollen.error.poll.voterList.mandatory.for.groupedPoll=At least one voter list ins mandatory for a grouped poll +pollen.error.report.email.invalid=Email invalid +pollen.error.report.email.mandatory=Email can not be empty +pollen.error.report.level.mandatory=Report level can not be empty pollen.error.resource.empty=No resource sent pollen.error.resource.maxSize=File "%s" of %4.2f %s can't be over %4.2f %s. pollen.error.resource.notExist=Image don't exist @@ -123,15 +127,21 @@ pollen.service.feed.voteEdited.title=%s edited his vote pollen.service.mail.ChoiceAddedEmail.subject=[Pollen] A choice was added in poll %s pollen.service.mail.ChoiceDeletedEmail.subject=[Pollen] A choice was deleted in poll %s pollen.service.mail.ChoiceEditedEmail.subject=[Pollen] A choice was edited in poll %s +pollen.service.mail.ChoiceReportEmail.subject=[Pollen] A choice was reported in your poll %s +pollen.service.mail.ChoiceReportForAdminEmail.subject=[Pollen] A choice was reported in poll %s pollen.service.mail.CommentAddedEmail.subject=[Pollen] A comment was added in poll %s pollen.service.mail.CommentDeletedEmail.subject=[Pollen] A comment was deleted in poll %s pollen.service.mail.CommentEditedEmail.subject=[Pollen] A comment was edited in poll %s +pollen.service.mail.CommentReportEmail.subject=[Pollen] A comment was reported in your poll %s +pollen.service.mail.CommentReportForAdminEmail.subject=[Pollen] A comment was reported in poll %s pollen.service.mail.LostPasswordEmail.subject=[Pollen] Lost password for %s pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Add Choice period ended for poll %s pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Add Choice period started for poll %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Poll %s is closed pollen.service.mail.PollCreatedEmail.subject=[Pollen] Poll creation (%s) pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Your poll %s ends soon +pollen.service.mail.PollReportEmail.subject=[Pollen] Your poll %s was reported +pollen.service.mail.PollReportForAdminEmail.subject=[Pollen] A poll %s was reported pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Vote period ended for poll %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Vote period started for poll %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Reminder to vote on poll %s diff --git a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties index 0119f0d5..2675ce7c 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties @@ -21,6 +21,7 @@ pollen.configuration.defaultVoteVisibility=Visibilité des votes par défaut pollen.configuration.devMode=Mode développement pollen.configuration.logConfigurationFile=Chemin vers le fichier de configuration des logs pollen.configuration.registration.emailAddressPattern=Expression régulière que doivent vérifier les adresses email des utilisateurs lors de l'inscription +pollen.configuration.report.maxScore=Score maximum pour un signalement avant que les administrateurs soient avertis pollen.configuration.resendEmailsCronSchedule=Intervalle entre deux lancements de la tâche de renvoi des emails en erreur pollen.configuration.resource.maxSize=Taille maximal pour un fichier de resource de Pollen pollen.configuration.secret= @@ -78,6 +79,9 @@ pollen.error.poll.unique.voterList.mandatory.for.restrictedPoll=une liste de vot pollen.error.poll.voteCountingType.mandatory=le type de vote est obligatoire pollen.error.poll.voteVisibility.mandatory=la visiblité des votes est obligatoire pollen.error.poll.voterList.mandatory.for.groupedPoll=Au moins une liste de votant est obligatoire pour un sondage groupé +pollen.error.report.email.invalid=Le courriel n'est pas valid +pollen.error.report.email.mandatory=Le courriel est obligatoire +pollen.error.report.level.mandatory=Le type de signalement est obligatoire pollen.error.resource.empty=Aucune resource envoyé pollen.error.resource.maxSize=Le fichier « %s » de %4.2f %s ne doit pas dépasser %4.2f %s. pollen.error.resource.notExist=L'image n'existe pas sur le serveur @@ -122,15 +126,21 @@ pollen.service.feed.voteEdited.title=%s a modifié son vote pollen.service.mail.ChoiceAddedEmail.subject=[Pollen] Un choix a été ajouté au sondage %s pollen.service.mail.ChoiceDeletedEmail.subject=[Pollen] Un choix a été supprimé du sondage %s pollen.service.mail.ChoiceEditedEmail.subject=[Pollen] Un choix a été modifié sur le sondage %s +pollen.service.mail.ChoiceReportEmail.subject=[Pollen] Un choix a été signalé comme inapproprié sur votre sondage %s +pollen.service.mail.ChoiceReportForAdminEmail.subject=[Pollen] Un choix a été signalé comme inapproprié sur le sondage %s pollen.service.mail.CommentAddedEmail.subject=[Pollen] Un commentaire a été ajouté au sondage %s pollen.service.mail.CommentDeletedEmail.subject=[Pollen] Un commentaire a été supprimé du sondage %s pollen.service.mail.CommentEditedEmail.subject=[Pollen] Un commentaire a été modifié sur le sondage %s +pollen.service.mail.CommentReportEmail.subject=[Pollen] Un commentaire a été signalé comme inapproprié sur votre sondage %s +pollen.service.mail.CommentReportForAdminEmail.subject=[Pollen] Un commentaire a été signalé comme inapproprié sur le sondage %s pollen.service.mail.LostPasswordEmail.subject=[Pollen] Mot de passe perdu du compte %s pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Période d'ajout de choix terminée pour le sondage %s pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Période d'ajout de choix commencée pour le sondage %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Le sondage %s est clôt pollen.service.mail.PollCreatedEmail.subject=[Pollen] Création du sondage %s pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Votre sondage %s se termine bientôt +pollen.service.mail.PollReportEmail.subject=[Pollen] Votre sondage %s a été signalé comme inapproprié +pollen.service.mail.PollReportForAdminEmail.subject=[Pollen] Le sondage %s a été signalé comme inapproprié pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Période de vote terminée pour le sondage %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Période de vote commencée pour le sondage %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Rappel du vote au sondage %s diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/blaze.css similarity index 80% copy from pollen-ui-riot-js/src/main/web/css/main.css copy to pollen-ui-riot-js/src/main/web/css/blaze.css index c2f43b2e..e51d83cb 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/blaze.css @@ -1,316 +1,3 @@ -/*- - * #%L - * Pollen :: UI (Riot Js) - * %% - * Copyright (C) 2009 - 2017 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - - -html { - -webkit-text-size-adjust:none; -} - -body { - font-size: 16px; -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: 'Open Sans', sans-serif; - - -webkit-user-select: none; /* Chrome all / Safari all */ - -moz-user-select: none; /* Firefox all */ - -ms-user-select: none; /* IE 10+ */ - user-select: none; -} - -input, textarea { - -webkit-user-select: text; /* Chrome all / Safari all */ - -moz-user-select: text; /* Firefox all */ - -ms-user-select: text; /* IE 10+ */ - user-select: text; -} - -.body-wrapper { - width: 100%; - min-height: 100%; - display: flex; - flex-direction: column; - position: absolute; -} - -.body-container { - display: flex; - flex-wrap: wrap; - margin-left: auto; - margin-right: auto; - justify-content: center; - margin-bottom: 30px; -} - -.instance-title::before { - content: var(--title); - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; -} - -.body-content { - flex-grow: 1; - overflow: hidden; -} - -@media (orientation: portrait) { - .body-content { - width: 100%; - flex-direction: row; - } -} - -@media (orientation: landscape) { - .body-content { - height: 100%; - flex-direction: column; - } -} - -a { - text-decoration: none; - color: var(--main); - cursor: pointer; -} - -.container { - max-width: 1024px; - margin: 15px auto 0 auto; -} - -@media (max-width: 1034px) { - .container { - margin: 15px 5px 0 5px; - } -} - -.actions { - padding: 5px 0; - display: flex; - justify-content: space-between; -} - -.actions .c-button, -.actions-left .c-button, -.actions-right .c-button { - margin: 2px; -} - -.actions-left { - padding: 5px 0; - display: flex; - justify-content: flex-start; - flex-wrap: wrap-reverse; -} - -.actions-right { - padding: 5px 0; - display: flex; - justify-content: flex-end; - flex-wrap: wrap; -} - -.actions .actions-left, -.actions .actions-right { - padding: 0; -} - -a.c-button, -input.c-button, -button.c-button { - display: inline-block; -} - -ul { - margin-left: .5em; -} - -.cursor-pointer { - cursor: pointer; -} - -.c-overlay, .o-modal { - position: fixed; -} - -.colors-main, -.colors-main input, -.colors-main textarea, -.colors-main select { - background-color: var(--background); - color: var(--default); -} - -.colors-main-invers, -.colors-main-invers a { - background-color: var(--main); - color: var(--background); -} - -.card { - display: block; - margin: 5px auto; - padding: 0.5em; - border-radius: 4px; - border: 1px solid var(--main); - box-shadow: 0 0 1px hsla(0,0%,7%,.6); - color: var(--main); -} - -.poll-created { - color: var(--poll-created); - border-color: var(--poll-created); -} - -.poll-adding_choices { - color: var(--poll-adding_choices); - border-color: var(--poll-adding_choices); -} - -.poll-voting { - color: var(--poll-voting); - border-color: var(--poll-voting); -} - -.poll-closed { - color: var(--poll-closed); - border-color: var(--poll-closed); -} - -.info-label { - font-size: 0.5em; - color: var(--info); -} - -/* Steps */ -.tabs { - border-bottom: 1px solid var(--separator); - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - margin: 0 auto; -} - -.tab { - margin-left: 12px; - margin-right: 12px; -} - -.tab button, -.tab a { - border: none; - font-size: 1em; - color: var(--default); - background: transparent; -} - -.tab.selected, -.tab.selected a { - color: var(--main); - border-bottom: 2px solid; -} - -@media (max-width: 640px) { - .tabs.tabs-one-small .tab { - display: none; - } - - .tabs.tabs-one-small .tab.selected { - display: block; - width: 100%; - text-align: center; - border-bottom: none; - } -} - -time-picker .next, -time-picker .prev { - border-color: var(--brand); -} - -time-picker .prev:hover, -time-picker .next:hover { - background-color: var(--brand); -} - -.dropdown-content { - background-color: var(--dropdown); - box-shadow: 0 8px 16px 0 var(--dropdown-shadow); -} - -.dropdown-content a { - background-color: var(--dropdown); - color: var(--dropdown-text); -} - -.dropdown-content a:hover { - background-color: var(--dropdown-hover); -} - -.separator-top { - border-top: 1px solid var(--separator); -} - -.separator-bottom { - border-bottom: 1px solid var(--separator); -} - -.separator-left { - border-left: 1px solid var(--separator); -} - -.separator-right { - border-right: 1px solid var(--separator); -} - -.winner { - color: var(--winner); -} - -.anonymous-voter { - color: var(--anonymous); - font-style: italic; -} - -qrcodebutton .o-modal, -qrcode { - background-color: var(--qrcode); -} - -pollenfooter, -pollenfooter a { - background-color: var(--footer); - color: var(--footer-text); -} - -pollenfooter a:hover { - color: var(--footer-text-hover); -} - /************************************************************** ***** Reprise de blaze CSS ******************************** ***************************************************************/ @@ -1070,7 +757,7 @@ select.c-field:not([multiple]) { display:block; border-radius:4px; background-color:var(--background); - box-shadow:0 0 1px hsla(0,0%,7%,.6); + box-shadow:0 0 1px var(--shadow); overflow:hidden; } @@ -1090,9 +777,7 @@ select.c-field:not([multiple]) { padding:0; } -.c-card__body, -.c-card__footer, -.c-card__item { +.c-card__body,.c-card__footer,.c-card__item { padding:.5em; } @@ -1118,6 +803,139 @@ select.c-field:not([multiple]) { border-bottom:1px solid rgba(202,212,216,.5); } +.c-card--accordion label.c-card__item { + display:block; + position:relative; + width:100%; + padding-left:2em; + cursor:pointer; +} + +.c-card--accordion label.c-card__item:before { + position:absolute; + left:.75em; + content:"+"; +} + +.c-card--accordion>input,.c-card--accordion>input+.c-card__item+.c-card__item { + display:none; +} + +.c-card--accordion>input:checked+.c-card__item+.c-card__item { + display:block; +} + +.c-card--accordion>input:checked+.c-card__item:before { + transform:rotate(45deg); +} + +.c-card--menu { + display:block; + width:100%; + max-height:280px; + margin:.5em 0 0; + z-index:1; + overflow-y:auto; + overflow-x:hidden; + -webkit-overflow-scrolling:touch; +} + +.c-card--grouped .c-card__item:not(:last-child) { + border-bottom:0; +} + +.c-card__divider { + height:1px; + background-color:var(--defaut); + overflow:hidden; +} + +.c-card__item--divider { + background-color:var(--defaut); + color:var(--background); + font-weight:700; +} + +.c-card__item--brand { + background-color:var(--brand); + color:var(--background);; +} + +.c-card__item--info { + background-color:var(--info); + color:var(--background); +} + +.c-card__item--warning { + background-color:var(--warning); + color:var(--background); +} + +.c-card__item--success { + background-color:#4caf50; + color:var(--background); +} + +.c-card__item--error { + background-color:var(--error); + color:var(--background); +} + +.c-card__item--disabled { + cursor:not-allowed; + opacity:.6; +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover { + background-color:var(--disabled); + cursor:pointer; +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--brand,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--brand { + background-color:var(--brand-over); +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--info,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--info { + background-color:var(--info-hover); +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--warning,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--warning { + background-color:var(--warbning-hover); +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--success,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--success { + background-color:var(--success-hover); +} + +.c-card--accordion label.c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--error,.c-card--menu .c-card__item:not(.c-card__item--disabled):not(.c-card__item--divider):hover.c-card__item--error { + background-color:var(--error-hover); +} + +.c-card--accordion>input:checked+.c-card__item,.c-card__item--active { + background-color:rgba(202,212,216,.5); + font-weight:700; +} + +.c-card--accordion>input:checked+.c-card__item.c-card__item--brand,.c-card__item--active.c-card__item--brand { + background-color:var(--brand-active); +} + +.c-card--accordion>input:checked+.c-card__item.c-card__item--info,.c-card__item--active.c-card__item--info { + background-color:var(--info-active); +} + +.c-card--accordion>input:checked+.c-card__item.c-card__item--warning,.c-card__item--active.c-card__item--warning { + background-color:var(--warning-active); +} + +.c-card--accordion>input:checked+.c-card__item.c-card__item--success,.c-card__item--active.c-card__item--success { + background-color:var(--success-active); +} + +.c-card--accordion>input:checked+.c-card__item.c-card__item--error,.c-card__item--active.c-card__item--error { + background-color:var(--error-active); +} + .c-overlay { display:block; position:absolute; @@ -1498,3 +1316,112 @@ h5.c-heading { h6.c-heading{ font-size:.67em; } + +.o-fieldset, +.o-fieldset.c-list { + display:block; + width:100%; + margin:.5em 0; + padding:0; + border:0; +} + +.o-fieldset__legend { + display:block; + width:100%; + padding:1em 0; + cursor:pointer; + padding:.25em 0; +} + +.o-form-element { + position:relative; + padding:1em 0; +} + +.o-form-element .c-label:first-child { + padding:0 0 .5em; +} + +.c-badge { + border:1px solid var(--default); + background-color:var(--default); + color:var(--background); + display:inline-block; + margin:0; + padding:.25em .5em; + border-radius:4px; + font-size:.8em; + font-weight:700; + line-height:1.2; +} + +.c-badge.c-badge--ghost { + border:1px solid var(--default); + background-color:transparent; + color:var(--default); +} + +.c-badge--rounded { + border-radius:30em; +} + +.c-badge--brand { + border:1px solid var(--brand); + background-color:var(--brand); + color:var(--background); +} + +.c-badge--brand.c-badge--ghost { + border:1px solid var(--brand); + background-color:transparent; + color:var(--brand); +} + +.c-badge--info { + border:1px solid var(--info); + background-color:var(--info); + color:var(--background); +} + +.c-badge--info.c-badge--ghost { + border:1px solid var(--info); + background-color:transparent; + color:var(--info); +} + +.c-badge--warning { + border:1px solid var(--warning); + background-color:var(--warning); + color:var(--background); +} + +.c-badge--warning.c-badge--ghost { + border:1px solid var(--warning); + background-color:transparent; + color:var(--warning); +} + +.c-badge--success { + border:1px solid var(--success); + background-color:var(--success); + color:var(--background); +} + +.c-badge--success.c-badge--ghost { + border:1px solid var(--success); + background-color:transparent; + color:var(--success); +} + +.c-badge--error { + border:1px solid var(--error); + background-color:var(--error); + color:var(--background); +} + +.c-badge--error.c-badge--ghost { + border:1px solid var(--error); + background-color:transparent; + color:var(--error); +} diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index c2f43b2e..d04b499b 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -205,6 +205,11 @@ ul { color: var(--info); } +.error-label { + font-size: 0.5em; + color: var(--error); +} + /* Steps */ .tabs { border-bottom: 1px solid var(--separator); @@ -310,1191 +315,3 @@ pollenfooter a { pollenfooter a:hover { color: var(--footer-text-hover); } - -/************************************************************** -***** Reprise de blaze CSS ******************************** -***************************************************************/ -.c-button{ - border:1px solid transparent; - background-color:var(--default); - color:var(--background); - display:inline; - max-width:100%; - margin:0; - padding:.5em; - border-radius:4px; - outline:0; - font-family:inherit; - font-size:1em; - line-height:normal; - text-align:center; - text-decoration:none; - text-overflow:ellipsis; - white-space:nowrap; - cursor:pointer; - overflow:hidden; - vertical-align:middle; - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - -webkit-user-select:none; - -moz-user-select:none; - -ms-user-select:none; - user-select:none; -} - -.c-button.c-button--active { - background-color:var(--active); -} - -.c-button:not(:disabled):hover { - background-color:var(--btn-hover); -} - -.c-button:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button:not(:disabled):active { - background-color:var(--active); -} - -.c-button:disabled { - cursor:not-allowed; - opacity:.5; -} - -.c-button--close { - border:1px solid transparent; - color:inherit; - position:absolute; - right:.5em; - padding:0; - outline:0; - font-size:1.4em; - font-weight:700; - line-height:1; -} - - -.c-button--close,.c-button--close.c-button--active { - background-color:transparent; -} - -.c-button--close:not(:disabled):hover { - background-color:hsla(0,0%,9%,0); -} - -.c-button--close:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--close:not(:disabled):active { - background-color:transparent; -} - -.c-button--block { - display:inline-block; - width:100%; -} - -.c-button--rounded { - border-radius:30em; -} - -.c-button--brand { - border:1px solid transparent; - background-color:var(--brand); - color:var(--background); -} - -.c-button--brand.c-button--active { - background-color:var(--brand-active); -} - -.c-button--brand:not(:disabled):hover { - background-color:var(--brand-hover); -} - -.c-button--brand:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--brand:not(:disabled):active { - background-color:var(--brand-active); -} - -.c-button--info { - border:1px solid transparent; - background-color:var(--info); - color:var(--background); -} - -.c-button--info.c-button--active { - background-color:var(--info-active); -} - -.c-button--info:not(:disabled):hover { - background-color:var(--info-hover); -} - -.c-button--info:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--info:not(:disabled):active { - background-color:var(--info-active); -} - -.c-button--warning { - border:1px solid transparent; - background-color:var(--warning); - color:var(--background); -} - -.c-button--warning.c-button--active { - background-color:var(--warning-active); -} - -.c-button--warning:not(:disabled):hover { - background-color:var(--warning-hover); -} - -.c-button--warning:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--warning:not(:disabled):active { - background-color:var(--warning-active); -} - -.c-button--success { - border:1px solid transparent; - background-color:var(--success); - color:var(--background); -} - -.c-button--success.c-button--active { - background-color:var(--success-active); -} - -.c-button--success:not(:disabled):hover { - background-color:var(--success-hover); -} - -.c-button--success:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--success:not(:disabled):active { - background-color:var(--success-active); -} - -.c-button--error { - border:1px solid transparent; - background-color:var(--error); - color:var(--background); -} - -.c-button--error.c-button--active { - background-color:var(--error-active); -} - -.c-button--error:not(:disabled):hover { - background-color:var(--error-hover); -} - -.c-button--error:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--error:not(:disabled):active { - background-color:var(--error-active); -} - -.c-button--ghost { - border:1px solid var(--default); - background-color:transparent; - color:var(--default); -} - -.colors-main-invers .c-button--ghost, -.colors-main-invers .c-button--ghost-brand, -.colors-main-invers .c-button--ghost-info, -.colors-main-invers .c-button--ghost-warning, -.colors-main-invers .c-button--ghost-success, -.colors-main-invers .c-button--ghost-error { - background-color: var(--background); -} - -.c-button--ghost.c-button--active { - border-color:var(--active); - background-color:var(--active); - color:var(--background); -} - -.c-button--ghost:not(:disabled):hover { - background-color:var(--default); - color:var(--background); -} - -.c-button--ghost:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost:not(:disabled):active { - border-color:var(--active); - background-color:var(--active); - color:var(--background); -} - -.c-button--ghost-brand { - border:1px solid var(--brand); - background-color:transparent; - color:var(--brand); -} - -.c-button--ghost-brand.c-button--active { - border-color:var(--brand-active); - background-color:var(--brand-active); - color:var(--background); -} - -.c-button--ghost-brand:not(:disabled):hover { - background-color:var(--brand); - color:var(--background); -} - -.c-button--ghost-brand:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost-brand:not(:disabled):active { - border-color:var(--brand-active); - background-color:var(--brand-active); - color:var(--background); -} - -.c-button--ghost-info { - border:1px solid var(--info); - background-color:transparent; - color:var(--info); -} - -.c-button--ghost-info.c-button--active { - border-color:var(--info-active); - background-color:var(--info-active); - color:var(--background); -} - -.c-button--ghost-info:not(:disabled):hover { - background-color:var(--info); - color:var(--background); -} - -.c-button--ghost-info:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost-info:not(:disabled):active { - border-color:var(--info-active); - background-color:var(--info-active); - color:var(--background); -} - -.c-button--ghost-warning { - border:1px solid var(--warning); - background-color:transparent; - color:var(--warning); -} - -.c-button--ghost-warning.c-button--active { - border-color:var(--warning-active); - background-color:var(--warning-active); - color:var(--background); -} - -.c-button--ghost-warning:not(:disabled):hover { - background-color:var(--warning); - color:var(--background); -} - -.c-button--ghost-warning:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost-warning:not(:disabled):active { - border-color:var(--warning-active); - background-color:var(--warning-active); - color:var(--background); -} - -.c-button--ghost-success { - border:1px solid var(--success); - background-color:transparent; - color:var(--success); -} - -.c-button--ghost-success.c-button--active { - border-color:var(--success-active); - background-color:var(--success-active); - color:var(--background); -} - -.c-button--ghost-success:not(:disabled):hover { - background-color:var(--success); - color:var(--background); -} - -.c-button--ghost-success:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost-success:not(:disabled):active { - border-color:var(--success-active); - background-color:var(--success-active); - color:var(--background); -} - -.c-button--ghost-error { - border:1px solid var(--error); - background-color:transparent; - color:var(--error); -} - -.c-button--ghost-error.c-button--active { - border-color:var(--error-active); - background-color:var(--error-active); - color:var(--background); -} - -.c-button--ghost-error:not(:disabled):hover { - background-color:var(--error); - color:var(--background); -} - -.c-button--ghost-error:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-button--ghost-error:not(:disabled):active { - border-color:var(--error-active); - background-color:var(--error-active); - color:var(--background); -} - -.c-button__icon-left { - padding-right:.5em; -} - -.c-button__icon-right { - padding-left:.5em; -} - -.c-input-group { - display:-ms-flexbox; - display:flex; -} - -.c-input-group .c-button { - border-radius:0; -} - -.c-input-group .c-button:not(:first-child) { - border-left-width:0; -} - -.c-input-group .c-button:first-child { - border-top-left-radius:4px; - border-bottom-left-radius:4px; -} - -.c-input-group .c-button:last-child { - border-top-right-radius:4px; - border-bottom-right-radius:4px; -} - -.c-input-group .o-field { - -ms-flex:1; - flex:1; -} - -.c-input-group .o-field .c-field { - border-radius:0; -} - -.c-input-group .o-field:not(:first-child) .c-field { - border-left-width:0; -} - -.c-input-group .o-field:first-child .c-field { - border-top-left-radius:4px; - border-bottom-left-radius:4px; -} - -.c-input-group .o-field:last-child .c-field { - border-top-right-radius:4px; - border-bottom-right-radius:4px; -} - -.c-input-group .o-field--fixed { - -ms-flex:0 1 auto; - flex:0 1 auto; -} - -.c-input-group--rounded .c-button:first-child { - border-top-left-radius:30em; - border-bottom-left-radius:30em; -} - -.c-input-group--rounded .c-button:last-child { - border-top-right-radius:30em; - border-bottom-right-radius:30em; -} - -.c-input-group--rounded .o-field:first-child .c-field { - border-top-left-radius:30em; - border-bottom-left-radius:30em; -} - -.c-input-group--rounded .o-field:last-child .c-field { - border-top-right-radius:30em; - border-bottom-right-radius:30em; -} - -.c-input-group--rounded-left .c-button:first-child,.c-input-group--rounded-left .o-field:first-child .c-field { - border-top-left-radius:30em; - border-bottom-left-radius:30em; -} - -.c-input-group--rounded-right .c-button:last-child,.c-input-group--rounded-right .o-field:last-child .c-field { - border-top-right-radius:30em; - border-bottom-right-radius:30em; -} - -.c-input-group--stacked { - display:-ms-flexbox; - display:flex; - -ms-flex-wrap:wrap; - flex-wrap:wrap; -} - -.c-input-group--stacked .c-button:not(:first-child),.c-input-group--stacked .o-field:not(:first-child) .c-field { - border-left-width:1px; -} - -.c-input-group--stacked .c-button,.c-input-group--stacked .o-field { - -ms-flex:0 0 100%; - flex:0 0 100%; - max-width:100%; - margin-left:0; -} - -.c-input-group--stacked .c-button:not(:first-child) { - border-top:0; -} - -.c-input-group--stacked .c-button:not(:first-child):not(:last-child) { - border-radius:0; -} - -.c-input-group--stacked .c-button:first-child { - border-radius:4px 4px 0 0; -} - -.c-input-group--stacked .c-button:last-child { - border-radius:0 0 4px 4px; -} - -.c-input-group--stacked .o-field:not(:first-child) .c-field { - border-top:0; -} - -.c-input-group--stacked .o-field:not(:first-child):not(:last-child) .c-field { - border-radius:0; -} - -.c-input-group--stacked .o-field:first-child .c-field { - border-radius:4px 4px 0 0; -} - -.c-input-group--stacked .o-field:last-child .c-field { - border-radius:0 0 4px 4px; -} - -.o-field { - position:relative; -} - -.o-field .c-field--success~.c-icon { - color:var(--success); -} - -.o-field .c-field--error~.c-icon { - color:var(--error); -} - -.o-field .c-field:disabled~.c-icon { - color:var(--default); -} - -.o-field .c-icon { - position:absolute;top:50%; - transform:translateY(-50%); - color:var(--default); -} - -.o-field--icon-right .c-field+.c-icon { - right:.5em; -} - -.o-field--icon-right .c-field { - padding-right:2em; -} - -.o-field--icon-left .c-icon:first-child { - left:.5em; -} - -.o-field--icon-left .c-field { - padding-left:2em; -} - -.c-label { - padding:1em 0; -} - -.c-field { - display:block; - width:100%; - margin:0; - padding:.5em; - border:1px solid var(--default); - border-radius:4px; - outline:0; - background-color:var(--background); - font-family:inherit; - font-size:1em; - font-weight:400; - resize:vertical; - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; -} - -.c-field:focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); - -} - -select.c-field { - cursor:pointer; -} - -select.c-field:not([multiple]) { - padding-right:1em; - background:url("data:image/png;base64,R0lGODlhDwAUAIABAAAAAP///yH5BAEAAAEALAAAAAAPABQAAAIXjI+py+0Po5wH2HsXzmw//lHiSJZmUAAAOw==") no-repeat 99% 50%; -} - -.c-field input { - margin-right:.125em; - outline:0; - font-size:1em; -} - -.c-field--label { - margin:.5em 0 0; -} - -.c-field--error { - border-color:var(--error); - color:var(--error); -} - -.c-field--success { - border-color:var(--success); - color:inherit; -} - -.c-field--choice { - border:0; - border-radius:0; - background-color:transparent; -} - -.c-field--disabled, -.c-field:disabled { - color:var(--default); - cursor:not-allowed; - border-color:var(--default); - background-color:var(--disabled); -} - -.c-field--disabled.c-field--choice, -.c-field:disabled.c-field--choice { - background-color:transparent; -} - -.c-field input:disabled { - color:var(--default); - cursor:not-allowed; -} - -.o-form-element { - position:relative; - padding:1em 0 -} - -.o-form-element .c-label:first-child { - padding:0 0 .5em -} - -.c-toggle { - display:-ms-flexbox; - display:flex; - -ms-flex-align:center; - align-items:center; - width:auto; - cursor:pointer; - -webkit-user-select:none; - -moz-user-select:none; - -ms-user-select:none; - user-select:none; -} - -.c-toggle input:not(:checked)+.c-toggle__track { - background-color:var(--disabled); -} - -.c-toggle input:not(:checked)+.c-toggle__track .c-toggle__handle { - transform:translateZ(0); -} - -.c-toggle input:disabled+.c-toggle__track, -.c-toggle input:disabled+.c-toggle__track .c-toggle__handle { - background-color:var(--disabled); - cursor:not-allowed; -} - -.c-toggle--brand .c-toggle__track { - background-color:var(--brand); -} - -.c-toggle--info .c-toggle__track { - background-color:var(--info); -} - -.c-toggle--warning .c-toggle__track { - background-color:var(--warning); -} - -.c-toggle--success .c-toggle__track { - background-color:var(--success); -} - -.c-toggle--error .c-toggle__track { - background-color:var(--error); -} - -.c-toggle input { - display:none; -} - -.c-toggle__track { - -ms-flex:1; - flex:1; - padding-right:1em; - padding-left:1em; - -ms-flex:0 1 auto; - flex:0 1 auto; - background-color:var(--default); - position:relative; - width:1em; - height:.5em; - margin:0 .5em; - border-radius:30em; -} - -.c-toggle__handle { - position:absolute; - top:-.25em; - left:0; - width:1em; - height:1em; - transform:translateX(100%); - border-radius:30em; - background-color:var(--toggle); - box-shadow:0 1px 4px -1px var(--toggle-shadow); -} - -.o-modal { - position:absolute; - top:50%; - left:50%; - transform:translate(-50%,-50%); - display:block; - width:80%; - border:0 solid var(--default); - border-radius:4px; - background-color:var(--background); - overflow:hidden; - z-index:1; -} - -.o-modal .c-card { - background-color:transparent; - box-shadow:none; -} - -.o-modal .c-card__body { - position:relative; -} - -.c-card { - padding:0; - list-style:none; - display:block; - border-radius:4px; - background-color:var(--background); - box-shadow:0 0 1px hsla(0,0%,7%,.6); - overflow:hidden; -} - -.c-card>.o-image:not(:first-child) { - padding:1em 0 0; -} - -.c-card+.c-card { - margin:.5em 0 0; -} - -.c-card__header { - padding:.5em .5em 0; -} - -.c-card__header .c-heading { - padding:0; -} - -.c-card__body, -.c-card__footer, -.c-card__item { - padding:.5em; -} - -.c-card__item+.c-card__footer--block { - padding:0; -} - -.c-card__footer--block { - padding:.5em 0 0; -} - -.c-card__footer--block .c-input-group .c-button:first-child { - border-top-left-radius:0; - border-bottom-left-radius:0; -} - -.c-card__footer--block .c-input-group .c-button:last-child { - border-top-right-radius:0; - border-bottom-right-radius:0; -} - -.c-card__item:not(:last-child) { - border-bottom:1px solid rgba(202,212,216,.5); -} - -.c-overlay { - display:block; - position:absolute; - top:0; - right:0; - bottom:0; - left:0; - width:100%; - height:100%; - background-color: var(--overlay); - z-index:1; -} - -.c-hint { - position:absolute; - padding:0 .5em; - transform:scale(.8); - transform-origin:top left; - color:var(--active); - font-size:1em; - opacity:0; - pointer-events:none; -} - -.c-field:focus~.c-hint, -.c-hint--static, -.c-label__field:focus~.c-hint { - transform:scale(.9);opacity:1; -} - -.c-hint--success { - color:var(--success); -} - -.c-hint--error { - color:var(--error); -} - -.c-alerts { - display:block; - position:absolute; - width:250px; - max-height:100%; - background-color:transparent; - z-index:1; - overflow-y:auto -} - -.c-alert { - background-color:var(--default); - color:var(--background); - position:relative; - margin:0 0 1em; - padding:1em 3em 1em 1em; - border-radius:4px; -} - -.c-alert--brand { - background-color:var(--brand); - color:var(--background); -} - -.c-alert--info { - background-color:var(--info); - color:var(--background); -} - -.c-alert--warning { - background-color:var(--warning); - color:var(--background); -} - -.c-alert--success { - background-color:var(--success); - color:var(--background); -} - -.c-alert--error { - background-color:var(--error); - color:var(--background); -} - -.c-pagination { - display:block; - width:100%; - padding:1em; - font-size:.83em; - text-align:center; -} - -.c-pagination__controls { - display:inline-block; - text-align:center; -} - -.c-pagination__controls--backward { - float:left; - text-align:left; -} - -.c-pagination__controls--forward { - float:right; - text-align:right; -} - -.c-pagination__control,.c-pagination__page { - border:1px solid transparent; - background-color: var(--default); - color: var(--background); - display:inline; - max-width:100%; - margin:0; - padding:.5em; - border-radius:4px; - outline:0; - font-family:inherit; - font-size:1em; - line-height:normal; - text-align:center; - text-decoration:none; - text-overflow:ellipsis; - white-space:nowrap; - cursor:pointer; - overflow:hidden; - vertical-align:middle; - -webkit-appearance:none; - -moz-appearance:none; - appearance:none; - -webkit-user-select:none; - -moz-user-select:none; - -ms-user-select:none; - user-select:none; - border:1px solid var(--brand); - background-color:transparent; - color: var(--brand); - min-width:2.4em; - border-radius:30em; -} - -.c-pagination__control.c-button--active,.c-pagination__page.c-button--active { - background-color:var(--active); -} - -.c-pagination__control:not(:disabled):hover,.c-pagination__page:not(:disabled):hover { - background-color:var(--btn-hover); -} - -.c-pagination__control:not(:disabled):active,.c-pagination__page:not(:disabled):active { - background-color:var(--active); -} - -.c-pagination__control:disabled,.c-pagination__page:disabled { - cursor:not-allowed; - opacity:.5; -} - -.c-pagination__control.c-button--active,.c-pagination__page.c-button--active { - border-color: var(--brand-active); - background-color: var(--brand-active); - color: var(--background); -} - -.c-pagination__control:not(:disabled):hover,.c-pagination__page:not(:disabled):hover { - background-color: var(--brand); - color: var(--background); -} - -.c-pagination__control:not(:disabled):focus,.c-pagination__page:not(:disabled):focus { - border-color: var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-pagination__control:not(:disabled):active,.c-pagination__page:not(:disabled):active { - border-color: var(--brand-active); - background-color: var(--brand-active); - color: var(--background); -} - -.c-pagination__page--current { - background-color: var(--brand); - color: var(--background); -} - -.c-pagination__ellipsis { - padding:0 1em; -} -.c-code { - margin:-.125em; - padding:.25em .25em .125em; - background-color: var(--code); - color: var(--code-text); - display:inline; - font-family:Consolas,Andale Mono WT,Andale Mono,Lucida Console,Lucida Sans Typewriter,DejaVu Sans Mono,Bitstream Vera Sans Mono,Liberation Mono,Nimbus Mono L,Monaco,Courier New,Courier,monospace; - font-weight:400; -} - -.c-code--multiline { - display:block; - padding:.5em 1em; - border-radius:4px; - white-space:pre; - overflow-x:auto; -} - -.c-calendar { - display:-ms-flexbox; - display:flex; - -ms-flex-wrap:wrap; - flex-wrap:wrap; - -ms-flex-align:center; - align-items:center; - padding-right:.001em; - padding-left:.001em; - max-width:400px; - padding:.25em; - border:1px solid var(--default); - border-radius:4px; - background-color: var(--background); - text-align:center; - z-index:1; -} - -.c-calendar__control,.c-calendar__date { - background-color: var(--background); - color:var(--default); - display:inline; - -ms-flex:0 0 14.28%; - flex:0 0 14.28%; - max-width:14.28%; - margin:0; - padding:1em .5em; - border:1px solid transparent; - border-radius:4px; - outline:0; - font-size:1em; - cursor:pointer; - -webkit-user-select:none; - -moz-user-select:none; - -ms-user-select:none; - user-select:none; -} - -.c-calendar__control.c-button--active,.c-calendar__date.c-button--active { - background-color: var(--active); -} - -.c-calendar__control:not(:disabled):hover,.c-calendar__date:not(:disabled):hover { - background-color: var(--background); -} - -.c-calendar__control:not(:disabled):focus,.c-calendar__date:not(:disabled):focus { - border-color: var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-calendar__control:not(:disabled):active,.c-calendar__date:not(:disabled):active { - background-color:var(--active); -} - -.c-calendar__header { - -ms-flex:1; - flex:1; - -ms-flex:0 0 70%; - flex:0 0 70%; - max-width:70%; -} - -.c-calendar__day,.c-calendar__header { - padding-right:1em; - padding-left:1em; - padding-right:.001em; - padding-left:.001em; - padding:.5em 0; -} - -.c-calendar__day { - -ms-flex:1; - flex:1; - -ms-flex:0 0 14.28%; - flex:0 0 14.28%; - max-width:14.28%; - font-weight:700; -} - -.c-calendar__date:hover { - border:1px solid var(--default); -} - -.c-calendar__date--in-month { - color: var(--default); -} - -.c-calendar__date--today { - border-color: var(--info); -} - -.c-calendar__date--selected,.c-calendar__date--selected:hover { - border:1px solid transparent; - background-color:var(--brand); - color: var(--background); - border-color:var(--brand); -} - -.c-calendar__date--selected.c-button--active,.c-calendar__date--selected:hover.c-button--active { - background-color: var(--brand-active); -} - -.c-calendar__date--selected:hover:not(:disabled):hover,.c-calendar__date--selected:not(:disabled):hover { - background-color:var(--brand-hover); -} - -.c-calendar__date--selected:hover:not(:disabled):focus,.c-calendar__date--selected:not(:disabled):focus { - border-color:var(--focus); - box-shadow:inset 0 0 0 2px var(--shadow); -} - -.c-calendar__date--selected:hover:not(:disabled):active,.c-calendar__date--selected:not(:disabled):active { - background-color: var(--brand-active); -} - -.u-super { - font-size:2em; -} - -.u-xlarge { - font-size:1.5em; -} - -.u-large { - font-size:1.17em; -} - -.u-medium { - font-size:1em; -} - -.u-small { - font-size:.83em; -} - -.u-xsmall{ - font-size:.67em; -} - -.c-heading, -.c-heading__sub { - margin:0; - padding:1em 0 .5em; - font-weight:400; -} - -.c-heading__sub { - padding:0; - font-size:.8em; - opacity:.6; -} - -h1.c-heading { - font-size:2em; -} - -h2.c-heading { - font-size:1.5em; -} - -h3.c-heading { - font-size:1.17em; -} - -h4.c-heading { - font-size:1em; -} - -h5.c-heading { - font-size:.83em; -} - -h6.c-heading{ - font-size:.67em; -} diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 4866404c..115077db 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -438,7 +438,24 @@ "modal_ok": "Ok", "confirm_cancel": "Annuler", "confirm_delete": "Supprimer", - "information_ok": "Ok" + "information_ok": "Ok", + "report_title": "Signaler !", + "report_add_title": "Signaler comme inapproprié !", + "report_add_action": "Signaler", + "report_level": "Que souhaitez-vous signaler ?", + "report_level_spam": "Spam", + "report_level_spam_detail": "Un Spam ou une publicité", + "report_level_off_topic": "Hors-sujet", + "report_level_off_topic_detail": "Un contenu hors-sujet", + "report_level_illegal": "Illégal", + "report_level_illegal_detail": "Un contenu manifestement illégal", + "report_email": "Votre courriel", + "report_email_placeholder": "Votre-courriel@exemple.com", + "report_count": "Signalement", + "report_score": "Score", + "report_reports_title": "Signalements", + "report_toIgnore": "Ignorer", + "report_ignores": "Ignorés" }, "en": { "main_pollen_title": "Pollen - ", @@ -867,6 +884,23 @@ "modal_ok": "Ok", "confirm_cancel": "Cancel", "confirm_delete": "Delete", - "information_ok": "Ok" + "information_ok": "Ok", + "report_title": "Report !", + "report_add_title": "Report as inappropriate !", + "report_add_action": "Report", + "report_level": "What whould you report ?", + "report_level_spam": "Spam", + "report_level_spam_detail": "A Spam or advertising", + "report_level_off_topic": "Oft topic", + "report_level_off_topic_detail": "A off topic content", + "report_level_illegal": "Illegal", + "report_level_illegal_detail": "A manifestly illegal content", + "report_email": "Your email", + "report_email_placeholder": "your-email@exemple.com", + "report_count": "Reporting", + "report_score": "Score", + "report_reports_title": "Reports", + "report_toIgnore": "Ignore", + "report_ignores": "Ignores" } } diff --git a/pollen-ui-riot-js/src/main/web/index.html b/pollen-ui-riot-js/src/main/web/index.html index 1b1aaa44..5d8f1ed7 100644 --- a/pollen-ui-riot-js/src/main/web/index.html +++ b/pollen-ui-riot-js/src/main/web/index.html @@ -27,6 +27,7 @@ <title>Pollen</title> <link href="./css/font-awesome.css" rel="stylesheet"> <link href="./css/custom.css" rel="stylesheet"> + <link href="./css/blaze.css" rel="stylesheet"> <link href="./css/main.css" rel="stylesheet"> </head> <body> diff --git a/pollen-ui-riot-js/src/main/web/js/ChoiceService.js b/pollen-ui-riot-js/src/main/web/js/ChoiceService.js index 381c4d9f..c48203f0 100644 --- a/pollen-ui-riot-js/src/main/web/js/ChoiceService.js +++ b/pollen-ui-riot-js/src/main/web/js/ChoiceService.js @@ -54,6 +54,30 @@ class ChoiceService extends FetchService { } return this.doDelete(url); } + + addReport(pollId, choiceId, report, permission) { + let url = "/v1/polls/" + pollId + "/choices/" + choiceId + "/reports"; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {report: report}); + } + + getReports(pollId, choiceId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/choices/" + choiceId + "/reports", args); + } + + ignoreReport(pollId, choiceId, reportId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/choices/" + choiceId + "/reports/" + reportId + "/ignore", args); + } } module.exports = singleton(ChoiceService); diff --git a/pollen-ui-riot-js/src/main/web/js/CommentService.js b/pollen-ui-riot-js/src/main/web/js/CommentService.js index 43decbbd..b9de087a 100644 --- a/pollen-ui-riot-js/src/main/web/js/CommentService.js +++ b/pollen-ui-riot-js/src/main/web/js/CommentService.js @@ -62,6 +62,30 @@ class CommentService extends FetchService { } return this.doDelete(url); } + + addReport(pollId, commentId, report, permission) { + let url = "/v1/polls/" + pollId + "/comments/" + commentId + "/reports"; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {report: report}); + } + + getReports(pollId, commentId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/comments/" + commentId + "/reports", args); + } + + ignoreReport(pollId, commentId, reportId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/comments/" + commentId + "/reports/" + reportId + "/ignore", args); + } } module.exports = singleton(CommentService); diff --git a/pollen-ui-riot-js/src/main/web/js/Poll.js b/pollen-ui-riot-js/src/main/web/js/Poll.js index c16d2739..b8357a3e 100644 --- a/pollen-ui-riot-js/src/main/web/js/Poll.js +++ b/pollen-ui-riot-js/src/main/web/js/Poll.js @@ -342,6 +342,54 @@ class Poll { return Promise.reject("Init poll after delete comment"); } + isPoll(target) { + return this === target; + } + + isComment(target) { + return this.comments && this.comments.indexOf(target) >= 0; + } + + isChoice(target) { + return this.choices && this.choices.indexOf(target) >= 0; + } + + _getService(target) { + let service; + if (this.isPoll(target)) { + service = pollService; + } else if (this.isComment(target)) { + service = commentService; + } else if (this.isChoice(target)) { + service = choiceService; + } + return service; + } + + addReport(target, report) { + if (this.id) { + let service = this._getService(target); + return service.addReport(this.id, target.id, report, this.permission || ""); + } + return Promise.reject("Init poll after add report"); + } + + getReports(target) { + if (this.id) { + let service = this._getService(target); + return service.getReports(this.id, target.id, this.permission || ""); + } + return Promise.reject("Init poll after load reports"); + } + + ignoreReport(target, report) { + if (this.id) { + let service = this._getService(target); + return service.ignoreReport(this.id, target.id, report.id, this.permission || ""); + } + return Promise.reject("Init poll after ignore report"); + } + } module.exports = singleton(Poll); diff --git a/pollen-ui-riot-js/src/main/web/js/PollService.js b/pollen-ui-riot-js/src/main/web/js/PollService.js index 12bd3f98..3db34cca 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -87,6 +87,30 @@ class PollService extends FetchService { } return this.put(url); } + + addReport(pollId, targetId, report, permission) { + let url = "/v1/polls/" + pollId + "/reports"; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {report: report}); + } + + getReports(pollId, targetId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/reports", args); + } + + ignoreReport(pollId, targetId, reportId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/reports/" + reportId + "/ignore", args); + } } module.exports = singleton(PollService); diff --git a/pollen-ui-riot-js/src/main/web/js/Session.js b/pollen-ui-riot-js/src/main/web/js/Session.js index d3144848..52c7c7ad 100644 --- a/pollen-ui-riot-js/src/main/web/js/Session.js +++ b/pollen-ui-riot-js/src/main/web/js/Session.js @@ -41,7 +41,8 @@ class Session { userValidateUrl: window.location.origin + "/#signcheck/{userId}/{token}", pollVoteUrl: window.location.origin + "/#poll/{pollId}/vote/{token}", pollVoteEditUrl: window.location.origin + "/#poll/{pollId}/vote/{voteId}/{token}", - pollEditUrl: window.location.origin + "/#poll/{pollId}/edit/{token}" + pollEditUrl: window.location.origin + "/#poll/{pollId}/edit/{token}", + resourceUrl: this.configuration.endPoint + "/v1/resources/{resourceId}/download" }; // pour contenir les traductions this.i18n = require("../i18n.json"); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html index 53e0b7ef..b08d405d 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html @@ -1,3 +1,4 @@ +require("./Report.tag.html"); <ChoiceView> <div class="choice-view {with-info : opts.choice.choiceType === 'RESOURCE' || opts.choice.description}" onclick={openModalImage} @@ -26,6 +27,7 @@ <i class="fa fa-question-circle" aria-hidden="true"></i> </div> </div> + <Report target={opts.choice}/> <div if={showModalImage} onclick={closeModalImage}> <div class="c-overlay"></div> @@ -104,7 +106,12 @@ </script> <style> + choiceview { + display: flex; + } + .choice-view { + flex-grow: 1; display: flex; justify-content: center; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html index 9865aeed..7f09740f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Comments.tag.html @@ -1,5 +1,5 @@ require("../Pagination.tag.html"); - +require("./Report.tag.html"); <Comments> <form show="{loaded}" onsubmit="{addComment}" class="comment-form"> <div class="comment"> @@ -69,6 +69,7 @@ require("../Pagination.tag.html"); </div> <div class="user"> {comment.authorName} + <Report target={comment}/> <div class="comment-date"> {formatDate(comment.postDate)} </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html index f433e424..d79da368 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html @@ -4,7 +4,7 @@ require("./Results.tag.html"); require("./Choices.tag.html"); require("./Settings.tag.html"); require("../popup/QrCodeButton.tag.html"); - +require("./Report.tag.html"); <Poll> <div class="tabs"> @@ -120,6 +120,7 @@ require("../popup/QrCodeButton.tag.html"); <h1> <QrCodeButton if={poll.pollType === "FREE"} value="{window.location.origin}{window.location.pathname}#poll/{poll.id}/vote"/> {poll.title} + <Report target={poll}/> <a href="{session.configuration.endPoint}/v1/polls/{poll.id}/feed?permission={poll.permission}" class="fa fa-rss-square" aria-hidden="true"></a> </h1> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html new file mode 100644 index 00000000..689b518a --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Report.tag.html @@ -0,0 +1,232 @@ +require("../popup/Modal.tag.html"); +<Report> + + <span class="label info-label" + show={!poll.permission} + onclick={openModalAddReport} title={__.title}> + <i class="fa fa-bell" aria-hidden="true"></i> + </span> + + <span class="label {opts.target.report.count > opts.target.report.ignore ? 'error-label' : 'info-label'}" + if={poll.permission && opts.target.report && opts.target.report.count} + onclick={openReports} + title="{__.count} : {opts.target.report.count}{opts.target.report.ignore > 0 ? ' (' + opts.target.report.ignore + ' ' + __.ignores + ')' : ''} {__.score} : {opts.target.report.score}"> + <i class="fa fa-exclamation-circle" aria-hidden="true"></i> + </span> + + <modal ref="modalAddReport" header={__.add_title} onsubmit={submitAddReport} label={__.add_action} type="warning"> + <fieldset class="o-fieldset"> + <legend class="o-fieldset__legend">{parent.__.level}</legend> + <label class="c-field c-field--choice"> + <input type="radio" + name="level" + ref="level" + required + value="SPAM"> + {parent.__.level_spam_detail} + </label> + <label class="c-field c-field--choice"> + <input type="radio" + name="level" + ref="level" + value="OFF_TOPIC"> + {parent.__.level_off_topic_detail} + </label> + <label class="c-field c-field--choice"> + <input type="radio" + name="level" + ref="level" + value="ILLEGAL"> + {parent.__.level_illegal_detail} + </label> + </fieldset> + + <div class="o-form-element"> + <label class="c-label" for="email">{parent.__.email}</label> + <input type="email" + id="email" + ref="email" + placeholder="{parent.__.email_placeholder}" + value={parent.session.getUser() && parent.session.getUser().email} + required + class="c-field"> + </div> + </modal> + + <modal ref="modalReports" header={__.reports_title} only-ok="true"> + <div show={hasReports(false, 'ILLEGAL')}> + <div class="c-card__item c-card__item--error">{parent.__.level_illegal}</div> + <div class="c-card__item"> + <div each={report in parent.filterReports(false, 'ILLEGAL')} class="report"> + <div class="report-email"> + {report.email} + </div> + <div onclick={parent.parent.ignoreReport(report)} title={parent.parent.__.toIgnore}> + <i class="fa fa-ban" aria-hidden="true"></i> + </div> + </div> + </div> + </div> + <div show={hasReports(false, 'SPAM')}> + <div class="c-card__item c-card__item--warning">{parent.__.level_spam}</div> + <div class="c-card__item"> + <div each={report in parent.filterReports(false, 'SPAM')} class="report"> + <div class="report-email"> + {report.email} + </div> + <div onclick={parent.parent.ignoreReport(report)} title={parent.parent.__.toIgnore}> + <i class="fa fa-ban" aria-hidden="true"></i> + </div> + </div> + </div> + </div> + <div show={hasReports(false, 'OFF_TOPIC')}> + <div class="c-card__item c-card__item--info">{parent.__.level_off_topic}</div> + <div class="c-card__item"> + <div each={report in parent.filterReports(false, 'OFF_TOPIC')} class="report"> + <div class="report-email"> + {report.email} + </div> + <div onclick={parent.parent.ignoreReport(report)} title={parent.parent.__.toIgnore}> + <i class="fa fa-ban" aria-hidden="true"></i> + </div> + </div> + </div> + </div> + <div class="c-card__item" + show={hasIgnoreReports()}> + {parent.__.ignores} : + <button type="button" + show={hasReports(true, 'ILLEGAL')} + onclick={parent.showIgnoreReports('ILLEGAL')} + class="c-button c-button--rounded c-button--error u-small"> + {parent.filterReports(true, 'ILLEGAL').length} + {parent.__.level_illegal} + </button> + <button type="button" + show={hasReports(true, 'SPAM')} + onclick={parent.showIgnoreReports('SPAM')} + class="c-button c-button--rounded c-button--warning u-small"> + {parent.filterReports(true, 'SPAM').length} + {parent.__.level_spam} + </button> + <button type="button" + show={hasReports(true, 'OFF_TOPIC')} + onclick={parent.showIgnoreReports('OFF_TOPIC')} + class="c-button c-button--rounded c-button--info u-small"> + {parent.filterReports(true, 'OFF_TOPIC').length} + {parent.__.level_off_topic} + </button> + <div each={report in parent.ignoreReports}> + <div class="report-email"> + {report.email} + </div> + </div> + </div> + </modal> + + <script type="es6"> + this.session = require("../../js/Session"); + this.installBundle(this.session, "report"); + this.poll = require("../../js/Poll.js"); + this.reports = []; + this.ignoreReports = []; + + this.openModalAddReport = e => { + e.preventDefault(); + e.stopPropagation(); + this.refs.modalAddReport.refs.level.forEach(radio => {radio.checked = false;}); + this.refs.modalAddReport.open().then(() => {this.update();}, () => {}); + }; + + this.submitAddReport = () => { + let report = { + level: this.refs.modalAddReport.refs.level.find(radio => radio.checked).value, + email: this.refs.modalAddReport.refs.email.value + }; + + return this.poll.addReport(this.opts.target, report); + + }; + + this.openReports = e => { + e.preventDefault(); + e.stopPropagation(); + this.poll.getReports(this.opts.target).then(reports => { + this.reports = reports; + this.refs.modalReports.open().then(() => { + if (this.poll.isPoll(this.opts.target)) { + this.poll.reloadPoll(); + } else if (this.poll.isComment(this.opts.target)) { + this.poll.loadComments(); + } else if (this.poll.isChoice(this.opts.target)) { + this.poll.loadChoices(); + } else { + this.update(); + } + }, () => {}); + this.update(); + }); + }; + + this.ignoreReport = report => () => { + this.poll.ignoreReport(this.opts.target, report).then(() => { + this.poll.getReports(this.opts.target).then(reports => { + this.reports = reports; + this.update(); + }); + }); + }; + + this.hasReports = (ignore, level) => { + return this.filterReports(ignore, level).length > 0; + }; + + this.hasIgnoreReports = () => { + return this.reports.filter(report => report.ignore).length > 0; + }; + + this.filterReports = (ignore, level) => { + return this.reports.filter(report => report.ignore === ignore && report.level === level); + }; + + this.showIgnoreReports = (level) => () => { + this.ignoreReports = this.filterReports(true, level); + }; + + + </script> + + <style> + report { + float: right; + font-size: 1rem; + text-align: left; + } + + .label { + vertical-align: text-top; + } + + td { + padding-right: 10px; + padding-left: 10px; + } + + .ignore { + text-decoration: line-through; + } + + .report { + display: flex; + justify-content: space-between; + align-items: baseline; + } + + .report-email { + padding-right: 20px; + } + + </style> + +</Report> diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html index ce3e435a..3781f995 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/Modal.tag.html @@ -5,7 +5,7 @@ <form class="c-card c-card--higher" onsubmit={submit}> <header class="c-card__header"> <h2 class="c-heading"> - {opts.title} + {opts.header} </h2> </header> <div class="c-card__body"> @@ -14,6 +14,7 @@ <footer class="c-card__footer c-card__footer--block"> <div class="c-input-group"> <button type="button" + show={!opts.onlyOk} class="c-button c-button--block c-button--brand" onclick={cancel}> {__.cancel} diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html index af23b655..418988e7 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/NewPassword.tag.html @@ -19,7 +19,7 @@ * #L% */ <NewPassword> - <Modal ref="modal" title={__.title} onsubmit={submit} label={__.action}> + <Modal ref="modal" header={__.title} onsubmit={submit} label={__.action}> <input class="c-field {c-field--error : parent.error}" ref="email" type="email" @@ -34,7 +34,7 @@ <i class="fa fa-envelope"></i> {parent.__.sent} </div> </Modal> - + <script type="es6"> let session = require("../../js/Session"); let authService = require("../../js/AuthService"); diff --git a/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html b/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html index 341dda46..be682276 100644 --- a/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/popup/ResendValidation.tag.html @@ -19,7 +19,7 @@ * #L% */ <ResendValidation> - <Modal ref="modal" title={__.title} onsubmit={submit} label={__.action}> + <Modal ref="modal" header={__.title} onsubmit={submit} label={__.action}> <input class="c-field {c-field--error : parent.error}" ref="email" type="email" diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html index dcb11adf..7e3436eb 100644 --- a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html @@ -57,7 +57,7 @@ <i class="fa fa-times" aria-hidden="true"></i> </button> - <modal title={__.importFavoriteList} + <modal header={__.importFavoriteList} ref="importFavoriteListModal"> <div show={favoriteLists.length === 0}> {__.importFavoriteList_none} -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.