diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java index f9c3e4e4d6f..79d9d189024 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java @@ -19,6 +19,7 @@ import de.symeda.sormas.api.externaljournal.PatientDiaryConfig; import de.symeda.sormas.api.externaljournal.SymptomJournalConfig; import de.symeda.sormas.api.geo.GeoLatLon; +import de.symeda.sormas.api.news.eios.EiosConfig; import de.symeda.sormas.api.sormastosormas.SormasToSormasConfig; @Remote @@ -167,4 +168,8 @@ public interface ConfigFacade { long getMinimumEmancipatedAge(); long getMinimumAdultAge(); + + EiosConfig getEIOSConfig(); + + String getEiosBoardIds(); } diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java index b530e4fd4da..4560448447f 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/FacadeProvider.java @@ -83,6 +83,7 @@ import de.symeda.sormas.api.infrastructure.region.RegionFacade; import de.symeda.sormas.api.infrastructure.subcontinent.SubcontinentFacade; import de.symeda.sormas.api.manualmessagelog.ManualMessageLogFacade; +import de.symeda.sormas.api.news.NewsFacade; import de.symeda.sormas.api.outbreak.OutbreakFacade; import de.symeda.sormas.api.person.PersonFacade; import de.symeda.sormas.api.report.AggregateReportFacade; @@ -559,6 +560,10 @@ public static SurveyTokenFacade getSurveyTokenFacade() { return get().lookupEjbRemote(SurveyTokenFacade.class); } + public static NewsFacade getNewsFacade() { + return get().lookupEjbRemote(NewsFacade.class); + } + @SuppressWarnings("unchecked") public

P lookupEjbRemote(Class

clazz) { try { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java index 7cb2d730131..fda24ae7f6d 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/feature/FeatureType.java @@ -332,7 +332,8 @@ public enum FeatureType { CASE_SURVEILANCE, CONTACT_TRACING }, null, - ImmutableMap.of(FeatureTypeProperty.S2S_SHARING, Boolean.FALSE)); + ImmutableMap.of(FeatureTypeProperty.S2S_SHARING, Boolean.FALSE)), + NEWS_FEATURE(true, false, null, null, null); public static final FeatureType[] SURVEILLANCE_FEATURE_TYPES = { FeatureType.CASE_SURVEILANCE, diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java index 345bc885f33..be627f13d1b 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Captions.java @@ -1170,6 +1170,8 @@ public interface Captions { String countryActiveCountries = "countryActiveCountries"; String countryAllCountries = "countryAllCountries"; String countryArchivedCountries = "countryArchivedCountries"; + String createEvent = "createEvent"; + String createNew = "createNew"; String createSymptomJournalAccountButton = "createSymptomJournalAccountButton"; String creationDate = "creationDate"; String CustomizableEnum_hasDetails = "CustomizableEnum.hasDetails"; @@ -1921,6 +1923,7 @@ public interface Captions { String HealthConditions_otherConditions = "HealthConditions.otherConditions"; String HealthConditions_sickleCellDisease = "HealthConditions.sickleCellDisease"; String HealthConditions_tuberculosis = "HealthConditions.tuberculosis"; + String hideDescription = "hideDescription"; String humanSampleViewType = "humanSampleViewType"; String Immunization = "Immunization"; String Immunization_additionalDetails = "Immunization.additionalDetails"; @@ -2116,6 +2119,22 @@ public interface Captions { String moreActions = "moreActions"; String name = "name"; String nationalHealthId = "nationalHealthId"; + String news = "news"; + String News_community = "News.community"; + String News_description = "News.description"; + String News_disease = "News.disease"; + String News_district = "News.district"; + String News_link = "News.link"; + String News_newsDate = "News.newsDate"; + String News_region = "News.region"; + String News_riskLevel = "News.riskLevel"; + String News_status = "News.status"; + String News_title = "News.title"; + String newsAction = "newsAction"; + String NewsCriteria_endDate = "NewsCriteria.endDate"; + String NewsCriteria_startDate = "NewsCriteria.startDate"; + String newsList = "newsList"; + String newsUpdate = "newsUpdate"; String notAvailableShort = "notAvailableShort"; String notificationType = "notificationType"; String notificationType_caption = "notificationType.caption"; @@ -2128,6 +2147,7 @@ public interface Captions { String openInPatientDiaryButton = "openInPatientDiaryButton"; String openInSymptomJournalButton = "openInSymptomJournalButton"; String openLinkedCaseToImmunizationButton = "openLinkedCaseToImmunizationButton"; + String openLinkInTab = "openLinkInTab"; String options = "options"; String otherDeletionReason = "otherDeletionReason"; String outbreakAffectedDistricts = "outbreakAffectedDistricts"; @@ -2588,6 +2608,7 @@ public interface Captions { String selfReportProcess = "selfReportProcess"; String selfReportSelfReportsList = "selfReportSelfReportsList"; String sex = "sex"; + String showDescription = "showDescription"; String showPlacesOnMap = "showPlacesOnMap"; String singleDayEventDate = "singleDayEventDate"; String singleDayEventEvolutionDate = "singleDayEventEvolutionDate"; @@ -3068,6 +3089,7 @@ public interface Captions { String treatmentOpenPrescription = "treatmentOpenPrescription"; String unassigned = "unassigned"; String unknown = "unknown"; + String updateNews = "updateNews"; String User = "User"; String User_active = "User.active"; String User_address = "User.address"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java index 0cfea2d8e6e..39ae3b784ea 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/i18n/Strings.java @@ -326,6 +326,7 @@ public interface Strings { String errorDocumentGeneration = "errorDocumentGeneration"; String errorDocumentGenerationMultipleDiseasses = "errorDocumentGenerationMultipleDiseasses"; String errorDocumentTemplateWorkflowChangeNotAllowed = "errorDocumentTemplateWorkflowChangeNotAllowed"; + String errorEiosRequestToken = "errorEiosRequestToken"; String errorEntityNotEditable = "errorEntityNotEditable"; String errorEntityOutdated = "errorEntityOutdated"; String errorEnvironmentSampleNoDispatchRight = "errorEnvironmentSampleNoDispatchRight"; @@ -1598,6 +1599,10 @@ public interface Strings { String mmhg = "mmhg"; String month = "month"; String nameOf = "nameOf"; + String newsData = "newsData"; + String newsEndDate = "newsEndDate"; + String newsFilterText = "newsFilterText"; + String newsStartDate = "newsStartDate"; String no = "no"; String none = "none"; String notAnswered = "notAnswered"; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsBodyResponse.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsBodyResponse.java new file mode 100644 index 00000000000..1ce09e3d941 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsBodyResponse.java @@ -0,0 +1,29 @@ +package de.symeda.sormas.api.news; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NewsBodyResponse { + + @JsonProperty("data") + private List newsList; + @JsonProperty("meta") + private NewsMetaResponseDto newsMetaResponse; + + public List getNewsList() { + return newsList; + } + + public void setNewsList(List newsList) { + this.newsList = newsList; + } + + public NewsMetaResponseDto getNewsMetaResponse() { + return newsMetaResponse; + } + + public void setNewsMetaResponse(NewsMetaResponseDto newsMetaResponse) { + this.newsMetaResponse = newsMetaResponse; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsConfig.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsConfig.java new file mode 100644 index 00000000000..62d0a749eba --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsConfig.java @@ -0,0 +1,26 @@ +package de.symeda.sormas.api.news; + +import de.symeda.sormas.api.audit.AuditedClass; + +@AuditedClass +public class NewsConfig { + + private String baseUrl; + private String authToken; + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getAuthToken() { + return authToken; + } + + public void setAuthToken(String authToken) { + this.authToken = authToken; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsCriteria.java new file mode 100644 index 00000000000..d537132c7ff --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsCriteria.java @@ -0,0 +1,107 @@ +package de.symeda.sormas.api.news; + +import java.util.Date; + +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto; +import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; +import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; +import de.symeda.sormas.api.news.eios.NewsStatus; +import de.symeda.sormas.api.utils.IgnoreForUrl; +import de.symeda.sormas.api.utils.criteria.BaseCriteria; + +public class NewsCriteria extends BaseCriteria { + + public static final String I18N_PREFIX = "NewsCriteria"; + public static final String REGION = "region"; + public static final String DISTRICT = "district"; + public static final String COMMUNITY = "community"; + public final static String RISK_LEVE = "riskLevel"; + public final static String STATUS = "status"; + public final static String START_DATE = "startDate"; + public final static String END_DATE = "endDate"; + public final static String IS_USER_LEVEL_FILER = "onlyInMyJurisdiction"; + public final static String NEWS_LIKE = "newsLike"; + private RegionReferenceDto region; + private DistrictReferenceDto district; + private CommunityReferenceDto community; + private RiskLevel riskLevel; + private NewsStatus status; + private Date startDate; + private Date endDate; + private Boolean onlyInMyJurisdiction; + private String newsLike; + + public RegionReferenceDto getRegion() { + return region; + } + + public void setRegion(RegionReferenceDto region) { + this.region = region; + } + + public DistrictReferenceDto getDistrict() { + return district; + } + + public void setDistrict(DistrictReferenceDto district) { + this.district = district; + } + + public CommunityReferenceDto getCommunity() { + return community; + } + + public void setCommunity(CommunityReferenceDto community) { + this.community = community; + } + + public RiskLevel getRiskLevel() { + return riskLevel; + } + + public void setRiskLevel(RiskLevel riskLevel) { + this.riskLevel = riskLevel; + } + + public NewsStatus getStatus() { + return status; + } + + public void setStatus(NewsStatus status) { + this.status = status; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public Boolean getOnlyInMyJurisdiction() { + return onlyInMyJurisdiction; + } + + public void setOnlyInMyJurisdiction(Boolean onlyInMyJurisdiction) { + this.onlyInMyJurisdiction = onlyInMyJurisdiction; + } + + @IgnoreForUrl + public String getNewsLike() { + return newsLike; + } + + public void setNewsLike(String newsLike) { + this.newsLike = newsLike; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsDto.java new file mode 100644 index 00000000000..2fdf672dfec --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsDto.java @@ -0,0 +1,170 @@ +package de.symeda.sormas.api.news; + +import java.util.Date; + +import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.audit.AuditedClass; +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto; +import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; +import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; +import de.symeda.sormas.api.news.eios.NewsStatus; +import de.symeda.sormas.api.utils.DataHelper; + +@AuditedClass +public class NewsDto extends EntityDto { + + public static final String I18N_PREFIX = "News"; + public static final String TITLE = "title"; + public static final String LINK = "link"; + public static final String DESCRIPTION = "description"; + public static final String NEWS_DATE = "newsDate"; + public static final String RISK_LEVEL = "riskLevel"; + public static final String STATUS = "status"; + public static final String REGION = "region"; + public static final String DISTRICT = "district"; + public static final String COMMUNITY = "community"; + public static final String DISEASE = "disease"; + private Long eiosId; + private String title; + private String eiosUrl; + private String link; + private String description; + private Date newsDate; + private RegionReferenceDto region; + private DistrictReferenceDto district; + private CommunityReferenceDto community; + private RiskLevel riskLevel; + + private NewsStatus status; + private Disease disease; + private Disease communicableDisease; + private String otherNewsCategory; + + public static NewsDto build() { + NewsDto dto = new NewsDto(); + dto.setUuid(DataHelper.createUuid()); + dto.setNewsDate(new Date()); + return dto; + } + + public Long getEiosId() { + return eiosId; + } + + public void setEiosId(Long eiosId) { + this.eiosId = eiosId; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getEiosUrl() { + return eiosUrl; + } + + public void setEiosUrl(String eiosUrl) { + this.eiosUrl = eiosUrl; + } + + public Date getNewsDate() { + return newsDate; + } + + public void setNewsDate(Date newsDate) { + this.newsDate = newsDate; + } + + public RegionReferenceDto getRegion() { + return region; + } + + public void setRegion(RegionReferenceDto region) { + this.region = region; + } + + public DistrictReferenceDto getDistrict() { + return district; + } + + public void setDistrict(DistrictReferenceDto district) { + this.district = district; + } + + public CommunityReferenceDto getCommunity() { + return community; + } + + public void setCommunity(CommunityReferenceDto community) { + this.community = community; + } + + public RiskLevel getRiskLevel() { + return riskLevel; + } + + public void setRiskLevel(RiskLevel riskLevel) { + this.riskLevel = riskLevel; + } + + public NewsStatus getStatus() { + return status; + } + + public void setStatus(NewsStatus status) { + this.status = status; + } + + public Disease getDisease() { + return disease; + } + + public void setDisease(Disease disease) { + this.disease = disease; + } + + public Disease getCommunicableDisease() { + return communicableDisease; + } + + public void setCommunicableDisease(Disease communicableDisease) { + this.communicableDisease = communicableDisease; + } + + public String getOtherNewsCategory() { + return otherNewsCategory; + } + + public void setOtherNewsCategory(String otherNewsCategory) { + this.otherNewsCategory = otherNewsCategory; + } + + @Override + public String toString() { + return "EiosArticleDto{" + "eiosId=" + eiosId + ", title='" + title + '\'' + ", eiosUrl='" + eiosUrl + '\'' + ", link='" + link + '\'' + + ", description='" + description + '\'' + ", processedOnDate=" + newsDate + ", region=" + region + ", district=" + district + + ", community=" + community + ", riskLevel=" + riskLevel + ", status=" + status + '}'; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsFacade.java new file mode 100644 index 00000000000..5f05e66a368 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsFacade.java @@ -0,0 +1,20 @@ +package de.symeda.sormas.api.news; + +import java.util.List; + +import javax.ejb.Remote; + +import de.symeda.sormas.api.BaseFacade; +import de.symeda.sormas.api.EditPermissionFacade; +import de.symeda.sormas.api.common.Page; +import de.symeda.sormas.api.utils.SortProperty; + +@Remote +public interface NewsFacade extends BaseFacade, EditPermissionFacade { + + void markApprove(NewsReferenceDto newsRef); + + void markUnUseful(NewsReferenceDto newsRef); + + Page getNewsPage(NewsCriteria newsCriteria, int offset, int size, List sortProperties); +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsIndexDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsIndexDto.java new file mode 100644 index 00000000000..329547cec7a --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsIndexDto.java @@ -0,0 +1,201 @@ +package de.symeda.sormas.api.news; + +import java.util.Date; + +import de.symeda.sormas.api.Disease; +import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.news.eios.NewsStatus; + +public class NewsIndexDto extends EntityDto { + + public static final String I18N_PREFIX = "News"; + public static final String NEWS_LINK = "newsLink"; + public static final String TITLE = "title"; + public static final String DESCRIPTION = "description"; + public static final String REGION = "region"; + public static final String DISTRICT = "district"; + public static final String NEWS_DATE = "newsDate"; + public static final String COMMUNITY = "community"; + public static final String RISK_LEVEL = "riskLevel"; + public static final String STATUS = "status"; + public static final String DISEASE = "disease"; + + long id; + private Date newsDate; + + private String newsLink; + + private String title; + + private String description; + + private String categories; + + private String area; + + private String region; + + private String district; + + private String community; + + private String village; + + private String newsSource; + + private RiskLevel riskLevel; + + private NewsStatus status; + private Disease disease; + + public NewsIndexDto() { + } + + public NewsIndexDto( + Long id, + String uuid, + String title, + String link, + String description, + String region, + String district, + String community, + Date newsDate, + RiskLevel riskLevel, + NewsStatus status, + Disease disease) { + this.id = id; + setUuid(uuid); + this.title = title; + this.newsLink = link; + this.description = description; + this.region = region; + this.district = district; + this.community = community; + this.newsDate = newsDate; + this.riskLevel = riskLevel; + this.status = status; + this.disease = disease; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Date getNewsDate() { + return newsDate; + } + + public void setNewsDate(Date newsDate) { + this.newsDate = newsDate; + } + + public String getNewsLink() { + return newsLink; + } + + public void setNewsLink(String newsLink) { + this.newsLink = newsLink; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCategories() { + return categories; + } + + public void setCategories(String categories) { + this.categories = categories; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getDistrict() { + return district; + } + + public void setDistrict(String district) { + this.district = district; + } + + public String getCommunity() { + return community; + } + + public void setCommunity(String community) { + this.community = community; + } + + public String getVillage() { + return village; + } + + public void setVillage(String village) { + this.village = village; + } + + public String getNewsSource() { + return newsSource; + } + + public void setNewsSource(String newsSource) { + this.newsSource = newsSource; + } + + public RiskLevel getRiskLevel() { + return riskLevel; + } + + public void setRiskLevel(RiskLevel riskLevel) { + this.riskLevel = riskLevel; + } + + public NewsStatus getStatus() { + return status; + } + + public void setStatus(NewsStatus status) { + this.status = status; + } + + public Disease getDisease() { + return disease; + } + + public void setDisease(Disease disease) { + this.disease = disease; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsMetaResponseDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsMetaResponseDto.java new file mode 100644 index 00000000000..74181e00e58 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsMetaResponseDto.java @@ -0,0 +1,74 @@ +package de.symeda.sormas.api.news; + +public class NewsMetaResponseDto { + + String path; + + int perPage; + + int to; + + int total; + + int currentPage; + + int from; + + int lastPage; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getPerPage() { + return perPage; + } + + public void setPerPage(int perPage) { + this.perPage = perPage; + } + + public int getTo() { + return to; + } + + public void setTo(int to) { + this.to = to; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getCurrentPage() { + return currentPage; + } + + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + } + + public int getFrom() { + return from; + } + + public void setFrom(int from) { + this.from = from; + } + + public int getLastPage() { + return lastPage; + } + + public void setLastPage(int lastPage) { + this.lastPage = lastPage; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsReferenceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsReferenceDto.java new file mode 100644 index 00000000000..ba1118467c7 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/NewsReferenceDto.java @@ -0,0 +1,18 @@ +package de.symeda.sormas.api.news; + +import de.symeda.sormas.api.ReferenceDto; + +public class NewsReferenceDto extends ReferenceDto { + + public NewsReferenceDto() { + + } + + public NewsReferenceDto(String uuid) { + super(uuid); + } + + public NewsReferenceDto(String uuid, String caption) { + super(uuid, caption); + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/ArticleDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/ArticleDto.java new file mode 100644 index 00000000000..06a8ee301a6 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/ArticleDto.java @@ -0,0 +1,137 @@ +package de.symeda.sormas.api.news.eios; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import de.symeda.sormas.api.EntityDto; +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto; +import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; +import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ArticleDto extends EntityDto { + + public static final String I18N_PREFIX = "News"; + public static final String TITLE = "title"; + public static final String LINK = "link"; + public static final String DESCRIPTION = "description"; + public static final String PROCESSED_ON_DATE = "processedOnDate"; + public static final String RISK_LEVEL = "riskLevel"; + public static final String STATUS = "status"; + public static final String REGION = "region"; + public static final String DISTRICT = "district"; + public static final String COMMUNITY = "community"; + @JsonProperty("id") + private Long eiosId; + private String title; + private String eiosUrl; + private String link; + private String description; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + private Date processedOnDate; + private RegionReferenceDto region; + private DistrictReferenceDto district; + private CommunityReferenceDto community; + private RiskLevel riskLevel; + + private NewsStatus status; + + public Long getEiosId() { + return eiosId; + } + + public void setEiosId(Long eiosId) { + this.eiosId = eiosId; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getEiosUrl() { + return eiosUrl; + } + + public void setEiosUrl(String eiosUrl) { + this.eiosUrl = eiosUrl; + } + + public Date getProcessedOnDate() { + return processedOnDate; + } + + public void setProcessedOnDate(Date processedOnDate) { + this.processedOnDate = processedOnDate; + } + + public RegionReferenceDto getRegion() { + return region; + } + + public void setRegion(RegionReferenceDto region) { + this.region = region; + } + + public DistrictReferenceDto getDistrict() { + return district; + } + + public void setDistrict(DistrictReferenceDto district) { + this.district = district; + } + + public CommunityReferenceDto getCommunity() { + return community; + } + + public void setCommunity(CommunityReferenceDto community) { + this.community = community; + } + + public RiskLevel getRiskLevel() { + return riskLevel; + } + + public void setRiskLevel(RiskLevel riskLevel) { + this.riskLevel = riskLevel; + } + + public NewsStatus getStatus() { + return status; + } + + public void setStatus(NewsStatus status) { + this.status = status; + } + + @Override + public String toString() { + return "EiosArticleDto{" + "eiosId=" + eiosId + ", title='" + title + '\'' + ", eiosUrl='" + eiosUrl + '\'' + ", link='" + link + '\'' + + ", description='" + description + '\'' + ", processedOnDate=" + processedOnDate + ", region=" + region + ", district=" + district + + ", community=" + community + ", riskLevel=" + riskLevel + ", status=" + status + '}'; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosAritcleReferenceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosAritcleReferenceDto.java new file mode 100644 index 00000000000..53d45224745 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosAritcleReferenceDto.java @@ -0,0 +1,6 @@ +package de.symeda.sormas.api.news.eios; + +import de.symeda.sormas.api.ReferenceDto; + +public class EiosAritcleReferenceDto extends ReferenceDto { +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleCriteria.java new file mode 100644 index 00000000000..e36aa9a0508 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleCriteria.java @@ -0,0 +1,52 @@ +package de.symeda.sormas.api.news.eios; + +import de.symeda.sormas.api.utils.criteria.BaseCriteria; + +public class EiosArticleCriteria extends BaseCriteria { + + private Long timespan; + private Long untilTimespan; + private Integer start; + private Integer limit; + private Long boardId; + + public Long getTimespan() { + return timespan; + } + + public void setTimespan(Long timespan) { + this.timespan = timespan; + } + + public Long getUntilTimespan() { + return untilTimespan; + } + + public void setUntilTimespan(Long untilTimespan) { + this.untilTimespan = untilTimespan; + } + + public Integer getStart() { + return start; + } + + public void setStart(Integer start) { + this.start = start; + } + + public Integer getLimit() { + return limit; + } + + public void setLimit(Integer limit) { + this.limit = limit; + } + + public Long getBoardId() { + return boardId; + } + + public void setBoardId(Long boardId) { + this.boardId = boardId; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleSourceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleSourceDto.java new file mode 100644 index 00000000000..d87d8763809 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticleSourceDto.java @@ -0,0 +1,213 @@ +package de.symeda.sormas.api.news.eios; + +public class EiosArticleSourceDto { + + private Long sourceId; + private String id; + private String name; + private String language; + private String country; + private String countryIso; + private String subject; + private String url; + private String languageCode; + private Object sourceTags; + private String category; + private String region; + private String type; + private String period; + private Long frequency; + private String state; + private Object feeds; + private String lastUpdateDate; + private String continentCode; + private String whoRegionCode; + private String continent; + private String whoRegion; + private Object restrictionType; + + public Long getSourceId() { + return sourceId; + } + + public void setSourceId(Long sourceId) { + this.sourceId = sourceId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCountryIso() { + return countryIso; + } + + public void setCountryIso(String countryIso) { + this.countryIso = countryIso; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getLanguageCode() { + return languageCode; + } + + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + + public Object getSourceTags() { + return sourceTags; + } + + public void setSourceTags(Object sourceTags) { + this.sourceTags = sourceTags; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPeriod() { + return period; + } + + public void setPeriod(String period) { + this.period = period; + } + + public Long getFrequency() { + return frequency; + } + + public void setFrequency(Long frequency) { + this.frequency = frequency; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Object getFeeds() { + return feeds; + } + + public void setFeeds(Object feeds) { + this.feeds = feeds; + } + + public String getLastUpdateDate() { + return lastUpdateDate; + } + + public void setLastUpdateDate(String lastUpdateDate) { + this.lastUpdateDate = lastUpdateDate; + } + + public String getContinentCode() { + return continentCode; + } + + public void setContinentCode(String continentCode) { + this.continentCode = continentCode; + } + + public String getWhoRegionCode() { + return whoRegionCode; + } + + public void setWhoRegionCode(String whoRegionCode) { + this.whoRegionCode = whoRegionCode; + } + + public String getContinent() { + return continent; + } + + public void setContinent(String continent) { + this.continent = continent; + } + + public String getWhoRegion() { + return whoRegion; + } + + public void setWhoRegion(String whoRegion) { + this.whoRegion = whoRegion; + } + + public Object getRestrictionType() { + return restrictionType; + } + + public void setRestrictionType(Object restrictionType) { + this.restrictionType = restrictionType; + } + +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticlesResponse.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticlesResponse.java new file mode 100644 index 00000000000..2cb5b369770 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosArticlesResponse.java @@ -0,0 +1,40 @@ +package de.symeda.sormas.api.news.eios; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class EiosArticlesResponse { + + @JsonProperty("result") + private List eiosArticlesDto; + private Long count; + private Boolean isCountAccurate; + + public List getArticles() { + return eiosArticlesDto; + } + + public void setArticles(List articleDtos) { + this.eiosArticlesDto = articleDtos; + } + + public Long getCount() { + return count; + } + + public void setCount(Long count) { + this.count = count; + } + + public Boolean getIsCountAccurate() { + return isCountAccurate; + } + + public void setIsCountAccurate(Boolean isCountAccurate) { + this.isCountAccurate = isCountAccurate; + } + +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosConfig.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosConfig.java new file mode 100644 index 00000000000..3ed21a3a4f3 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosConfig.java @@ -0,0 +1,53 @@ +package de.symeda.sormas.api.news.eios; + +import de.symeda.sormas.api.audit.AuditedClass; + +@AuditedClass +public class EiosConfig { + + private String eiosUrl; + private String oidUrl; + private String oidcClientId; + private String oidcClientSecret; + private String oidScope; + + public String getEiosUrl() { + return eiosUrl; + } + + public void setEiosUrl(String eiosUrl) { + this.eiosUrl = eiosUrl; + } + + public String getOidUrl() { + return oidUrl; + } + + public void setOidUrl(String oidUrl) { + this.oidUrl = oidUrl; + } + + public String getOidcClientId() { + return oidcClientId; + } + + public void setOidcClientId(String oidcClientId) { + this.oidcClientId = oidcClientId; + } + + public String getOidcClientSecret() { + return oidcClientSecret; + } + + public void setOidcClientSecret(String oidcClientSecret) { + this.oidcClientSecret = oidcClientSecret; + } + + public String getOidScope() { + return oidScope; + } + + public void setOidScope(String oidScope) { + this.oidScope = oidScope; + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosFacade.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosFacade.java new file mode 100644 index 00000000000..6bcdb73bcf9 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosFacade.java @@ -0,0 +1,8 @@ +package de.symeda.sormas.api.news.eios; + +import javax.ejb.Remote; + +@Remote +public interface EiosFacade { + +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosSourceReferenceDto.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosSourceReferenceDto.java new file mode 100644 index 00000000000..d22dbe1876e --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/EiosSourceReferenceDto.java @@ -0,0 +1,6 @@ +package de.symeda.sormas.api.news.eios; + +import de.symeda.sormas.api.ReferenceDto; + +public class EiosSourceReferenceDto extends ReferenceDto { +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/GeoData.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/GeoData.java new file mode 100644 index 00000000000..a53126d968b --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/GeoData.java @@ -0,0 +1,24 @@ +package de.symeda.sormas.api.news.eios; + +public class GeoData { + + private Float latitude; + private Float longitude; + + public Float getLatitude() { + return latitude; + } + + public void setLatitude(Float latitude) { + this.latitude = latitude; + } + + public Float getLongitude() { + return longitude; + } + + public void setLongitude(Float longitude) { + this.longitude = longitude; + } + +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/Location.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/Location.java new file mode 100644 index 00000000000..42916ca016e --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/Location.java @@ -0,0 +1,107 @@ +package de.symeda.sormas.api.news.eios; + +import java.util.List; + +public class Location { + + private GeoData geoData; + private List areas; + private List areaFullName; + private String areaId; + private String iso2; + private String countryName; + private Long emmAreaId; + private String trigger; + private Boolean hasMaxEmmScore; + private String whoRegionCode; + private String continentCode; + + public GeoData getGeoData() { + return geoData; + } + + public void setGeoData(GeoData geoData) { + this.geoData = geoData; + } + + public List getAreas() { + return areas; + } + + public void setAreas(List areas) { + this.areas = areas; + } + + public List getAreaFullName() { + return areaFullName; + } + + public void setAreaFullName(List areaFullName) { + this.areaFullName = areaFullName; + } + + public String getAreaId() { + return areaId; + } + + public void setAreaId(String areaId) { + this.areaId = areaId; + } + + public String getIso2() { + return iso2; + } + + public void setIso2(String iso2) { + this.iso2 = iso2; + } + + public String getCountryName() { + return countryName; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public Long getEmmAreaId() { + return emmAreaId; + } + + public void setEmmAreaId(Long emmAreaId) { + this.emmAreaId = emmAreaId; + } + + public String getTrigger() { + return trigger; + } + + public void setTrigger(String trigger) { + this.trigger = trigger; + } + + public Boolean getHasMaxEmmScore() { + return hasMaxEmmScore; + } + + public void setHasMaxEmmScore(Boolean hasMaxEmmScore) { + this.hasMaxEmmScore = hasMaxEmmScore; + } + + public String getWhoRegionCode() { + return whoRegionCode; + } + + public void setWhoRegionCode(String whoRegionCode) { + this.whoRegionCode = whoRegionCode; + } + + public String getContinentCode() { + return continentCode; + } + + public void setContinentCode(String continentCode) { + this.continentCode = continentCode; + } + +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/NewsStatus.java b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/NewsStatus.java new file mode 100644 index 00000000000..aee42ba8d11 --- /dev/null +++ b/sormas-api/src/main/java/de/symeda/sormas/api/news/eios/NewsStatus.java @@ -0,0 +1,15 @@ +package de.symeda.sormas.api.news.eios; + +import de.symeda.sormas.api.i18n.I18nProperties; + +public enum NewsStatus { + + PENDING, + UNUSEFUL, + APPROVED; + + @Override + public String toString() { + return I18nProperties.getEnumCaption(this); + } +} diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java index b87b3dac0a7..2e869403d98 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/DefaultUserRole.java @@ -17,7 +17,234 @@ *******************************************************************************/ package de.symeda.sormas.api.user; -import static de.symeda.sormas.api.user.UserRight.*; +import static de.symeda.sormas.api.user.UserRight.ACTION_CREATE; +import static de.symeda.sormas.api.user.UserRight.ACTION_DELETE; +import static de.symeda.sormas.api.user.UserRight.ACTION_EDIT; +import static de.symeda.sormas.api.user.UserRight.ADDITIONAL_TEST_CREATE; +import static de.symeda.sormas.api.user.UserRight.ADDITIONAL_TEST_DELETE; +import static de.symeda.sormas.api.user.UserRight.ADDITIONAL_TEST_EDIT; +import static de.symeda.sormas.api.user.UserRight.ADDITIONAL_TEST_VIEW; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_CREATE; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_DELETE; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_EDIT; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_EXPORT; +import static de.symeda.sormas.api.user.UserRight.ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_VIEW; +import static de.symeda.sormas.api.user.UserRight.AGGREGATE_REPORT_EDIT; +import static de.symeda.sormas.api.user.UserRight.AGGREGATE_REPORT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.AGGREGATE_REPORT_VIEW; +import static de.symeda.sormas.api.user.UserRight.BAG_EXPORT; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_DELETE; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_EDIT; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_DELETE; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_EDIT; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_EXPORT; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_VIEW; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_FORM_DATA_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_VIEW; +import static de.symeda.sormas.api.user.UserRight.CAMPAIGN_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.CASE_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.CASE_CHANGE_DISEASE; +import static de.symeda.sormas.api.user.UserRight.CASE_CHANGE_EPID_NUMBER; +import static de.symeda.sormas.api.user.UserRight.CASE_CLASSIFY; +import static de.symeda.sormas.api.user.UserRight.CASE_CLINICIAN_VIEW; +import static de.symeda.sormas.api.user.UserRight.CASE_CREATE; +import static de.symeda.sormas.api.user.UserRight.CASE_DELETE; +import static de.symeda.sormas.api.user.UserRight.CASE_EDIT; +import static de.symeda.sormas.api.user.UserRight.CASE_EXPORT; +import static de.symeda.sormas.api.user.UserRight.CASE_IMPORT; +import static de.symeda.sormas.api.user.UserRight.CASE_INVESTIGATE; +import static de.symeda.sormas.api.user.UserRight.CASE_MERGE; +import static de.symeda.sormas.api.user.UserRight.CASE_REFER_FROM_POE; +import static de.symeda.sormas.api.user.UserRight.CASE_RESPONSIBLE; +import static de.symeda.sormas.api.user.UserRight.CASE_SHARE; +import static de.symeda.sormas.api.user.UserRight.CASE_TRANSFER; +import static de.symeda.sormas.api.user.UserRight.CASE_VIEW; +import static de.symeda.sormas.api.user.UserRight.CASE_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.CLINICAL_COURSE_EDIT; +import static de.symeda.sormas.api.user.UserRight.CLINICAL_COURSE_VIEW; +import static de.symeda.sormas.api.user.UserRight.CLINICAL_VISIT_CREATE; +import static de.symeda.sormas.api.user.UserRight.CLINICAL_VISIT_DELETE; +import static de.symeda.sormas.api.user.UserRight.CLINICAL_VISIT_EDIT; +import static de.symeda.sormas.api.user.UserRight.CONTACT_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_CONVERT; +import static de.symeda.sormas.api.user.UserRight.CONTACT_CREATE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_DELETE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_EDIT; +import static de.symeda.sormas.api.user.UserRight.CONTACT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.CONTACT_IMPORT; +import static de.symeda.sormas.api.user.UserRight.CONTACT_MERGE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_REASSIGN_CASE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_RESPONSIBLE; +import static de.symeda.sormas.api.user.UserRight.CONTACT_VIEW; +import static de.symeda.sormas.api.user.UserRight.CONTACT_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.CUSTOMIZABLE_ENUM_MANAGEMENT; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_ADVERSE_EVENTS_FOLLOWING_IMMUNIZATION_VIEW; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_CAMPAIGNS_VIEW; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_CONTACT_VIEW; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_CONTACT_VIEW_TRANSMISSION_CHAINS; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_SAMPLES_VIEW; +import static de.symeda.sormas.api.user.UserRight.DASHBOARD_SURVEILLANCE_VIEW; +import static de.symeda.sormas.api.user.UserRight.DATABASE_EXPORT_ACCESS; +import static de.symeda.sormas.api.user.UserRight.DEV_MODE; +import static de.symeda.sormas.api.user.UserRight.DOCUMENT_DELETE; +import static de.symeda.sormas.api.user.UserRight.DOCUMENT_TEMPLATE_MANAGEMENT; +import static de.symeda.sormas.api.user.UserRight.DOCUMENT_UPLOAD; +import static de.symeda.sormas.api.user.UserRight.DOCUMENT_VIEW; +import static de.symeda.sormas.api.user.UserRight.EDIT_NEWS; +import static de.symeda.sormas.api.user.UserRight.EMAIL_TEMPLATE_MANAGEMENT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_CREATE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_DELETE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_EDIT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_IMPORT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_PATHOGEN_TEST_CREATE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_PATHOGEN_TEST_DELETE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_PATHOGEN_TEST_EDIT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_CREATE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_DELETE; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_EDIT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_EDIT_DISPATCH; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_EDIT_RECEIVAL; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_EXPORT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_IMPORT; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_SAMPLE_VIEW; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_VIEW; +import static de.symeda.sormas.api.user.UserRight.ENVIRONMENT_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_CREATE; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_DELETE; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_EDIT; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_LINK; +import static de.symeda.sormas.api.user.UserRight.EVENTGROUP_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_CREATE; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_DELETE; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_EDIT; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_IMPORT; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_VIEW; +import static de.symeda.sormas.api.user.UserRight.EVENTPARTICIPANT_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.EVENT_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.EVENT_CREATE; +import static de.symeda.sormas.api.user.UserRight.EVENT_DELETE; +import static de.symeda.sormas.api.user.UserRight.EVENT_EDIT; +import static de.symeda.sormas.api.user.UserRight.EVENT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.EVENT_IMPORT; +import static de.symeda.sormas.api.user.UserRight.EVENT_RESPONSIBLE; +import static de.symeda.sormas.api.user.UserRight.EVENT_VIEW; +import static de.symeda.sormas.api.user.UserRight.EVENT_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.EXPORT_DATA_PROTECTION_DATA; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_EMAIL_ATTACH_DOCUMENTS; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_EMAIL_SEND; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_MESSAGE_DELETE; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_MESSAGE_PROCESS; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_MESSAGE_VIEW; +import static de.symeda.sormas.api.user.UserRight.EXTERNAL_VISITS; +import static de.symeda.sormas.api.user.UserRight.GRANT_SPECIAL_CASE_ACCESS; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_CREATE; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_DELETE; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_EDIT; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_VIEW; +import static de.symeda.sormas.api.user.UserRight.IMMUNIZATION_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_CREATE; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_EDIT; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_EXPORT; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_IMPORT; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_VIEW; +import static de.symeda.sormas.api.user.UserRight.INFRASTRUCTURE_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.LINE_LISTING_CONFIGURE; +import static de.symeda.sormas.api.user.UserRight.MANAGE_EXTERNAL_SYMPTOM_JOURNAL; +import static de.symeda.sormas.api.user.UserRight.MANAGE_PUBLIC_EXPORT_CONFIGURATION; +import static de.symeda.sormas.api.user.UserRight.OUTBREAK_EDIT; +import static de.symeda.sormas.api.user.UserRight.OUTBREAK_VIEW; +import static de.symeda.sormas.api.user.UserRight.PATHOGEN_TEST_CREATE; +import static de.symeda.sormas.api.user.UserRight.PATHOGEN_TEST_DELETE; +import static de.symeda.sormas.api.user.UserRight.PATHOGEN_TEST_EDIT; +import static de.symeda.sormas.api.user.UserRight.PERFORM_BULK_OPERATIONS; +import static de.symeda.sormas.api.user.UserRight.PERFORM_BULK_OPERATIONS_PSEUDONYM; +import static de.symeda.sormas.api.user.UserRight.PERSON_CONTACT_DETAILS_DELETE; +import static de.symeda.sormas.api.user.UserRight.PERSON_DELETE; +import static de.symeda.sormas.api.user.UserRight.PERSON_EDIT; +import static de.symeda.sormas.api.user.UserRight.PERSON_EXPORT; +import static de.symeda.sormas.api.user.UserRight.PERSON_MERGE; +import static de.symeda.sormas.api.user.UserRight.PERSON_VIEW; +import static de.symeda.sormas.api.user.UserRight.POPULATION_MANAGE; +import static de.symeda.sormas.api.user.UserRight.PORT_HEALTH_INFO_EDIT; +import static de.symeda.sormas.api.user.UserRight.PORT_HEALTH_INFO_VIEW; +import static de.symeda.sormas.api.user.UserRight.PRESCRIPTION_CREATE; +import static de.symeda.sormas.api.user.UserRight.PRESCRIPTION_DELETE; +import static de.symeda.sormas.api.user.UserRight.PRESCRIPTION_EDIT; +import static de.symeda.sormas.api.user.UserRight.QUARANTINE_ORDER_CREATE; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_CREATE; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_DELETE; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_EDIT; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_EDIT_NOT_OWNED; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_EXPORT; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_TRANSFER; +import static de.symeda.sormas.api.user.UserRight.SAMPLE_VIEW; +import static de.symeda.sormas.api.user.UserRight.SEE_PERSONAL_DATA_IN_JURISDICTION; +import static de.symeda.sormas.api.user.UserRight.SEE_PERSONAL_DATA_OUTSIDE_JURISDICTION; +import static de.symeda.sormas.api.user.UserRight.SEE_SENSITIVE_DATA_IN_JURISDICTION; +import static de.symeda.sormas.api.user.UserRight.SEE_SENSITIVE_DATA_OUTSIDE_JURISDICTION; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_CREATE; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_DELETE; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_EDIT; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_IMPORT; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_PROCESS; +import static de.symeda.sormas.api.user.UserRight.SELF_REPORT_VIEW; +import static de.symeda.sormas.api.user.UserRight.SEND_MANUAL_EXTERNAL_MESSAGES; +import static de.symeda.sormas.api.user.UserRight.SORMAS_REST; +import static de.symeda.sormas.api.user.UserRight.SORMAS_UI; +import static de.symeda.sormas.api.user.UserRight.STATISTICS_ACCESS; +import static de.symeda.sormas.api.user.UserRight.STATISTICS_EXPORT; +import static de.symeda.sormas.api.user.UserRight.SURVEY_CREATE; +import static de.symeda.sormas.api.user.UserRight.SURVEY_DELETE; +import static de.symeda.sormas.api.user.UserRight.SURVEY_EDIT; +import static de.symeda.sormas.api.user.UserRight.SURVEY_TOKEN_CREATE; +import static de.symeda.sormas.api.user.UserRight.SURVEY_TOKEN_DELETE; +import static de.symeda.sormas.api.user.UserRight.SURVEY_TOKEN_EDIT; +import static de.symeda.sormas.api.user.UserRight.SURVEY_TOKEN_IMPORT; +import static de.symeda.sormas.api.user.UserRight.SURVEY_TOKEN_VIEW; +import static de.symeda.sormas.api.user.UserRight.SURVEY_VIEW; +import static de.symeda.sormas.api.user.UserRight.TASK_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.TASK_ASSIGN; +import static de.symeda.sormas.api.user.UserRight.TASK_CREATE; +import static de.symeda.sormas.api.user.UserRight.TASK_DELETE; +import static de.symeda.sormas.api.user.UserRight.TASK_EDIT; +import static de.symeda.sormas.api.user.UserRight.TASK_EXPORT; +import static de.symeda.sormas.api.user.UserRight.TASK_VIEW; +import static de.symeda.sormas.api.user.UserRight.TASK_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.THERAPY_VIEW; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_ARCHIVE; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_CREATE; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_DELETE; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_EDIT; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_MANAGEMENT_ACCESS; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_VIEW; +import static de.symeda.sormas.api.user.UserRight.TRAVEL_ENTRY_VIEW_ARCHIVED; +import static de.symeda.sormas.api.user.UserRight.TREATMENT_CREATE; +import static de.symeda.sormas.api.user.UserRight.TREATMENT_DELETE; +import static de.symeda.sormas.api.user.UserRight.TREATMENT_EDIT; +import static de.symeda.sormas.api.user.UserRight.USER_CREATE; +import static de.symeda.sormas.api.user.UserRight.USER_EDIT; +import static de.symeda.sormas.api.user.UserRight.USER_ROLE_DELETE; +import static de.symeda.sormas.api.user.UserRight.USER_ROLE_EDIT; +import static de.symeda.sormas.api.user.UserRight.USER_ROLE_VIEW; +import static de.symeda.sormas.api.user.UserRight.USER_VIEW; +import static de.symeda.sormas.api.user.UserRight.VIEW_NEWS; +import static de.symeda.sormas.api.user.UserRight.VISIT_CREATE; +import static de.symeda.sormas.api.user.UserRight.VISIT_DELETE; +import static de.symeda.sormas.api.user.UserRight.VISIT_EDIT; +import static de.symeda.sormas.api.user.UserRight.VISIT_EXPORT; +import static de.symeda.sormas.api.user.UserRight.WEEKLYREPORT_CREATE; +import static de.symeda.sormas.api.user.UserRight.WEEKLYREPORT_VIEW; import java.util.Arrays; import java.util.Collection; @@ -1469,7 +1696,9 @@ public Set getDefaultUserRights() { EXTERNAL_EMAIL_SEND, EXTERNAL_EMAIL_ATTACH_DOCUMENTS, SORMAS_REST, - SORMAS_UI)); + SORMAS_UI, + EDIT_NEWS, + VIEW_NEWS)); break; case POE_INFORMANT: userRights.addAll( diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java index 99f2d8b3a4f..bfef3500994 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRight.java @@ -310,7 +310,9 @@ public enum UserRight { EMAIL_TEMPLATE_MANAGEMENT(UserRightGroup.EXTERNAL_EMAILS), EXTERNAL_EMAIL_SEND(UserRightGroup.EXTERNAL_EMAILS), EXTERNAL_EMAIL_ATTACH_DOCUMENTS(UserRightGroup.EXTERNAL_EMAILS, UserRight._EXTERNAL_EMAIL_SEND), - CUSTOMIZABLE_ENUM_MANAGEMENT(UserRightGroup.CONFIGURATION); + CUSTOMIZABLE_ENUM_MANAGEMENT(UserRightGroup.CONFIGURATION), + VIEW_NEWS(UserRightGroup.NEWS), + EDIT_NEWS(UserRightGroup.NEWS, UserRight._VIEW_NEWS); //@formatter:on @@ -551,7 +553,8 @@ public enum UserRight { public static final String _EXTERNAL_EMAIL_SEND = "EXTERNAL_EMAIL_SEND"; public static final String _EXTERNAL_EMAIL_ATTACH_DOCUMENTS = "EXTERNAL_EMAIL_ATTACH_DOCUMENTS"; public static final String _CUSTOMIZABLE_ENUM_MANAGEMENT = "CUSTOMIZABLE_ENUM_MANAGEMENT"; - + public static final String _VIEW_NEWS = "VIEW_NEWS"; + public static final String _EDIT_NEWS = "EDIT_NEWS"; private static final Map> userRightDependencies = buildUserRightDependencies(); private final UserRightGroup userRightGroup; diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRightGroup.java b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRightGroup.java index 9e7ba605031..8ca13ada8c9 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRightGroup.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/user/UserRightGroup.java @@ -49,7 +49,8 @@ public enum UserRightGroup { EXPORT, CONFIGURATION, - EXTERNAL; + EXTERNAL, + NEWS; @Override public String toString() { diff --git a/sormas-api/src/main/java/de/symeda/sormas/api/utils/criteria/BaseCriteria.java b/sormas-api/src/main/java/de/symeda/sormas/api/utils/criteria/BaseCriteria.java index 54d7647b5e2..80e3b7726d6 100644 --- a/sormas-api/src/main/java/de/symeda/sormas/api/utils/criteria/BaseCriteria.java +++ b/sormas-api/src/main/java/de/symeda/sormas/api/utils/criteria/BaseCriteria.java @@ -81,6 +81,8 @@ public String toUrlParams() { stringValue = (String) value; } else if (Integer.class.isAssignableFrom(type)) { stringValue = String.valueOf(value); + } else if (Long.class.isAssignableFrom(type)) { + stringValue = String.valueOf(value); } else if (EpiWeek.class.isAssignableFrom(type)) { stringValue = ((EpiWeek) value).toUrlString(); } else if (CriteriaDateType.class.isAssignableFrom(type)) { diff --git a/sormas-api/src/main/resources/captions.properties b/sormas-api/src/main/resources/captions.properties index e18afc5c795..c67bf7c1ef8 100644 --- a/sormas-api/src/main/resources/captions.properties +++ b/sormas-api/src/main/resources/captions.properties @@ -3394,6 +3394,29 @@ selfReportAllActiveAndArchivedEnvironments=All active and archived self reports selfReportDeletedEnvironments=Deleted self reports selfReportSelfReportsList=Self reports list selfReportProcess=Process +#News +news=News +createNew=Create New +createEvent=Create Event +openLinkInTab=Open Link In Tab +updateNews=Update News +NewsCriteria.startDate=Start Date +NewsCriteria.endDate=End Date +News.title=Title +News.link=Link +News.description=Description +News.newsDate=News Date +News.region=Region +News.district=District +News.community=Community +News.riskLevel=Risk Level +News.status=Status +News.disease=Disease +newsList=News List +newsAction=Action +showDescription=Show Description +hideDescription=Hide Description +newsUpdate=News Updated confirmChangesField=Field: confirmChangesValue=Will be changed to: diff --git a/sormas-api/src/main/resources/enum.properties b/sormas-api/src/main/resources/enum.properties index 9bfa9001b0a..8f5f9021008 100644 --- a/sormas-api/src/main/resources/enum.properties +++ b/sormas-api/src/main/resources/enum.properties @@ -1627,6 +1627,8 @@ UserRight.SURVEY_TOKEN_CREATE=Create survey tokens UserRight.SURVEY_TOKEN_EDIT=Edit survey tokens UserRight.SURVEY_TOKEN_DELETE=Delete survey tokens UserRight.SURVEY_TOKEN_IMPORT=Import survey tokens +UserRight.VIEW_NEWS=View news +UserRight.EDIT_NEWS=Edit news # UserRight descriptions UserRight.Desc.CASE_ARCHIVE = Able to archive cases @@ -2329,26 +2331,6 @@ WeatherCondition.CLOUDY = Cloudy WeatherCondition.RAINING = Raining WeatherCondition.WINDY = Windy -#Pathogen Customizable enum -Pathogen.CAMPYLOBACTER_JEJUNI = Campylobacter jejuni -Pathogen.ESCHERICHIA_COLI = Escherichia coli -Pathogen.SALMONELLA_SPP = Salmonella spp. -Pathogen.SHIGELLA_SPP = Shigella spp. -Pathogen.VIBRIO_CHOLERAE = Vibrio cholerae -Pathogen.YERSINIA_SPP = Yersinia spp. -Pathogen.SARS_COV_2 = SARS-CoV-2 -Pathogen.ADENOVIRUS = Adenovirus -Pathogen.ASTROVIRUS = Astrovirus -Pathogen.COXSACKIE_VIRUS = Coxsackie virus -Pathogen.ECHOVIRUS = Echovirus -Pathogen.HEPATITIS_A_VIRUS = Hepatitis A virus -Pathogen.HEPATITIS_E_VIRUS = Hepatitis E virus -Pathogen.HUMAN_CALICIVIRUS = Human calicivirus -Pathogen.POLIO_VIRUS = Polio virus 2 -Pathogen.REOVIRUS = Reovirus -Pathogen.ROTAVIRUS = Rotavirus -Pathogen.TT_HEPATITIS = TT hepatitis -Pathogen.OTHER = Other # SelfReportType SelfReportType.CASE=Case SelfReportType.CONTACT=Contact @@ -2360,6 +2342,10 @@ SelfReportInvestigationStatus.REJECTED=Rejected # SelfReportProcessingStatus SelfReportProcessingStatus.UNPROCESSED=Unprocessed SelfReportProcessingStatus.PROCESSED=Processed +# News +NewsStatus.PENDING=Pending +NewsStatus.UNUSEFUL=Unuseful +NewsStatus.APPROVED=Approved # AefiAgeGroup AefiAgeGroup.ZERO_TO_ONE = 0 < 1 year diff --git a/sormas-api/src/main/resources/strings.properties b/sormas-api/src/main/resources/strings.properties index 1dbc349d737..461bd51377c 100644 --- a/sormas-api/src/main/resources/strings.properties +++ b/sormas-api/src/main/resources/strings.properties @@ -1901,4 +1901,10 @@ confirmationSelfReportLinkContactsByCaseReference=Some contacts without a case h headingSelfReportCaseReportWithSameReferenceFound=Case self report with same case reference found confirmationSelfReportCaseReportWithSameReferenceFound=There is a case self report with the same case reference number as the processed self report.
It is recommended to process case reports first.

Do you want to continue processing this self report? headingSelfReportCaseWithSameReferenceNumberFound=Case with same reference number found -confirmationSelfReportLinkContactToCaseWithSameReferenceNumber=There is a case with the same reference number as the contact found

Do you want to link this contact to that case? \ No newline at end of file +confirmationSelfReportLinkContactToCaseWithSameReferenceNumber=There is a case with the same reference number as the contact found

Do you want to link this contact to that case? +newsData=News Data +newsFilterText=title, description +newsStartDate=Start Date +newsEndDate=End Date +errorEiosRequestToken=Error requesting token from EIOS + diff --git a/sormas-api/src/test/java/de/symeda/sormas/api/i18n/I18nConstantGenerator.java b/sormas-api/src/test/java/de/symeda/sormas/api/i18n/I18nConstantGenerator.java index 87b29880c55..12b853732a8 100644 --- a/sormas-api/src/test/java/de/symeda/sormas/api/i18n/I18nConstantGenerator.java +++ b/sormas-api/src/test/java/de/symeda/sormas/api/i18n/I18nConstantGenerator.java @@ -22,7 +22,7 @@ /** * Generates Constants out of the corresponding property files. - * + * * @see Captions * @see Strings * @see Validations @@ -30,7 +30,6 @@ public class I18nConstantGenerator { private static final String FILE_PATH_PATTERN = "src/main/java/de/symeda/sormas/api/i18n/%s.java"; - private final String propertiesFileName; private final String outputClassName; private final String outputClassFilePath; @@ -78,7 +77,7 @@ public boolean isIgnoreChildren() { private void generateI18nConstantClass() throws IOException { - Path path = Paths.get(outputClassFilePath); + Path path = Paths.get("sormas-api\\" + outputClassFilePath); String sep = determineLineSeparator(path); try (Writer writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) { @@ -180,7 +179,7 @@ public static void main(String[] args) throws IOException { long startTime = System.currentTimeMillis(); // Check if this program is started with the module directory as working directory. - Path path = Paths.get(FILE_PATH_PATTERN.split("/")[0]); + Path path = Paths.get("sormas-api\\" + FILE_PATH_PATTERN.split("\\\\")[0]); if (!Files.exists(path)) { throw new IOException( String.format( diff --git a/sormas-app/app/build.gradle b/sormas-app/app/build.gradle index 1a8455112be..c79e9ab11b5 100644 --- a/sormas-app/app/build.gradle +++ b/sormas-app/app/build.gradle @@ -134,7 +134,7 @@ dependencies { implementation 'androidx.paging:paging-runtime:3.1.1' implementation 'androidx.work:work-runtime-ktx:2.8.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'me.dm7.barcodescanner:zxing:1.9.13' + implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'io.crowdcode.sormas.lbds:lbds-android-messaging:1.4.8' implementation 'org.slf4j:slf4j-api:2.0.7' // Align versions of all Kotlin components diff --git a/sormas-app/app/src/main/AndroidManifest.xml b/sormas-app/app/src/main/AndroidManifest.xml index 18d3de04c70..2ea3a9ed596 100644 --- a/sormas-app/app/src/main/AndroidManifest.xml +++ b/sormas-app/app/src/main/AndroidManifest.xml @@ -489,7 +489,14 @@ - + + { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(browserIntent); + }); + } + + private void showProgressBar() { + binding.progressBar.setVisibility(View.VISIBLE); + } + + private void hideProgressBar() { + binding.progressBar.setVisibility(View.GONE); + } + + private class CustomWebViewClient extends WebViewClient { + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + hideProgressBar(); + super.onPageStarted(view, url, favicon); + } + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/event/edit/EventNewActivity.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/event/edit/EventNewActivity.java index bb275c23ca8..8cca1cf955e 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/event/edit/EventNewActivity.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/event/edit/EventNewActivity.java @@ -22,9 +22,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; - import androidx.annotation.NonNull; - import de.symeda.sormas.api.caze.CaseReferenceDto; import de.symeda.sormas.api.event.EventStatus; import de.symeda.sormas.api.utils.ValidationException; @@ -66,6 +64,10 @@ public static Bundler buildBundleWithCase(String caseUuid) { return BaseEditActivity.buildBundle(null).setCaseUuid(caseUuid); } + public static void startActivity(Context fromActivity, Bundler bundler) { + BaseEditActivity.startActivity(fromActivity, EventNewActivity.class, bundler); + } + @Override protected Event queryRootEntity(String recordUuid) { throw new UnsupportedOperationException(); diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/News.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/News.java new file mode 100644 index 00000000000..b345c31fb9c --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/News.java @@ -0,0 +1,14 @@ +package de.symeda.sormas.app.news; + +import java.util.Date; + +import de.symeda.sormas.api.news.NewsIndexDto; +import de.symeda.sormas.app.backend.common.HasLocalChangeDate; + +public class News extends NewsIndexDto implements HasLocalChangeDate { + + @Override + public Date getLocalChangeDate() { + return getNewsDate(); + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsFilterCriteria.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsFilterCriteria.java new file mode 100644 index 00000000000..491dc480ea2 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsFilterCriteria.java @@ -0,0 +1,85 @@ +package de.symeda.sormas.app.news; + +import java.util.Date; + +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.news.eios.NewsStatus; +import de.symeda.sormas.app.backend.region.Community; +import de.symeda.sormas.app.backend.region.District; +import de.symeda.sormas.app.backend.region.Region; + +public class NewsFilterCriteria { + + private Region region; + private District district; + private Community community; + private RiskLevel riskLevel; + private NewsStatus status; + private Date startDate; + private Date endDate; + private Boolean onlyInMyJurisdiction; + + public Region getRegion() { + return region; + } + + public void setRegion(Region region) { + this.region = region; + } + + public District getDistrict() { + return district; + } + + public void setDistrict(District district) { + this.district = district; + } + + public Community getCommunity() { + return community; + } + + public void setCommunity(Community community) { + this.community = community; + } + + public RiskLevel getRiskLevel() { + return riskLevel; + } + + public void setRiskLevel(RiskLevel riskLevel) { + this.riskLevel = riskLevel; + } + + public NewsStatus getStatus() { + return status; + } + + public void setStatus(NewsStatus status) { + this.status = status; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public Boolean getOnlyInMyJurisdiction() { + return onlyInMyJurisdiction; + } + + public void setOnlyInMyJurisdiction(Boolean onlyInMyJurisdiction) { + this.onlyInMyJurisdiction = onlyInMyJurisdiction; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListActivity.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListActivity.java new file mode 100644 index 00000000000..982466a8a88 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListActivity.java @@ -0,0 +1,102 @@ +package de.symeda.sormas.app.news; + +import java.util.List; + +import android.os.Bundle; +import android.view.View; +import androidx.databinding.DataBindingUtil; +import androidx.lifecycle.ViewModelProvider; +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.app.PagedBaseListActivity; +import de.symeda.sormas.app.PagedBaseListFragment; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.component.Item; +import de.symeda.sormas.app.component.menu.PageMenuItem; +import de.symeda.sormas.app.databinding.FilterNewsListLayoutBinding; +import de.symeda.sormas.app.util.DataUtils; +import de.symeda.sormas.app.util.InfrastructureDaoHelper; +import de.symeda.sormas.app.util.InfrastructureFieldsDependencyHandler; + +public class NewsListActivity extends PagedBaseListActivity { + + NewsListViewModel viewModel; + FilterNewsListLayoutBinding filterBinding; + Boolean isFirstCreate = true; + + @Override + public void onCreate(Bundle saveInstanceState) { + super.onCreate(saveInstanceState); + adapter = new NewsListAdapter(getContext()); + viewModel = new ViewModelProvider(this).get(NewsListViewModel.class); + viewModel.setContext(this); + viewModel.getNewsList().observe(this, news -> { + adapter.submitList(news); + hidePreloader(); + }); + filterBinding.setCriteria(viewModel.getNewsFilterCriteria()); + } + + @Override + public void onResume() { + super.onResume(); + if (isFirstCreate) { + isFirstCreate = false; + showPreloader(); + } + } + + @Override + protected int getActivityTitle() { + return R.string.heading_activityNews; + } + + @Override + public void addFiltersToPageMenu() { + View newsListFilterView = getLayoutInflater().inflate(R.layout.filter_news_list_layout, null); + filterBinding = DataBindingUtil.bind(newsListFilterView); + pageMenu.addFilter(newsListFilterView); + + runOnUiThread(() -> { + List initialRegions = InfrastructureDaoHelper.loadRegionsByServerCountry(); + InfrastructureFieldsDependencyHandler.instance.initializeRegionFields( + filterBinding.regionFilter, + initialRegions, + null, + filterBinding.districtFilter, + List.of(), + null, + filterBinding.communityFilter, + List.of(), + null); + }); + filterBinding.priorityFilter.initializeSpinner(DataUtils.getEnumItems(RiskLevel.class)); + filterBinding.startDateFilter.initializeDateField(getSupportFragmentManager()); + filterBinding.endDateFilter.initializeDateField(getSupportFragmentManager()); + filterBinding.applyFilters.setOnClickListener(e -> { + showPreloader(); + pageMenu.hideAll(); + viewModel.notifyCriteriaUpdated(); + }); + filterBinding.resetFilters.setOnClickListener(e -> resetFilter()); + } + + private void resetFilter() { + showPreloader(); + pageMenu.hideAll(); + viewModel.getNewsFilterCriteria().setRegion(null); + viewModel.getNewsFilterCriteria().setDistrict(null); + viewModel.getNewsFilterCriteria().setCommunity(null); + viewModel.getNewsFilterCriteria().setRiskLevel(null); + viewModel.getNewsFilterCriteria().setStartDate(null); + viewModel.getNewsFilterCriteria().setEndDate(null); + filterBinding.invalidateAll(); + viewModel.notifyCriteriaUpdated(); + } + + @Override + protected PagedBaseListFragment buildListFragment(PageMenuItem menuItem) { + NewsListFragment newsListFragment = NewsListFragment.newInstance(); + newsListFragment.setResetFilterCallBack(this::resetFilter); + return newsListFragment; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListAdapter.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListAdapter.java new file mode 100644 index 00000000000..bba3f98aa3b --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListAdapter.java @@ -0,0 +1,70 @@ +package de.symeda.sormas.app.news; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; +import de.symeda.sormas.api.event.EventSourceType; +import de.symeda.sormas.api.event.RiskLevel; +import de.symeda.sormas.api.user.UserRight; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.common.DatabaseHelper; +import de.symeda.sormas.app.backend.config.ConfigProvider; +import de.symeda.sormas.app.backend.event.Event; +import de.symeda.sormas.app.core.adapter.databinding.BindingPagedListAdapter; +import de.symeda.sormas.app.core.adapter.databinding.BindingViewHolder; +import de.symeda.sormas.app.databinding.RowNewsListItemLayoutBinding; +import de.symeda.sormas.app.event.edit.EventNewActivity; +import de.symeda.sormas.app.util.Bundler; + +public class NewsListAdapter extends BindingPagedListAdapter { + + private final Context context; + + public NewsListAdapter(Context context) { + super(R.layout.row_news_list_item_layout); + this.context = context; + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + if (holder instanceof BindingViewHolder) { + BindingViewHolder pageHolder = (BindingViewHolder) holder; + pageHolder.setOnListItemClickListener(this.mOnListItemClickListener); + News data = pageHolder.getData(); + setColorInPriorityButton(pageHolder.binding.newsDataActionPriority, data.getRiskLevel()); + if (ConfigProvider.hasUserRight(UserRight.EVENT_CREATE)) { + pageHolder.binding.newsDataPriorityContainer.setOnClickListener(l -> createNewEvent(data)); + } + } + } + + private void setColorInPriorityButton(View pageHolder, RiskLevel riskLevel) { + if (context != null) { + if (riskLevel == RiskLevel.HIGH) { + pageHolder.setBackground(context.getDrawable(R.drawable.background_legend_high_priority)); + } else if (riskLevel == RiskLevel.MODERATE) { + pageHolder.setBackground(context.getDrawable(R.drawable.background_legend_normal_priority)); + } else if (riskLevel == RiskLevel.LOW) { + pageHolder.setBackground(context.getDrawable(R.drawable.background_legend_low_priority)); + } + } + } + + private void createNewEvent(News news) { + Bundle bundle = new Bundle(); + Event event = DatabaseHelper.getEventDao().build(); + event.setEventTitle(news.getTitle()); + event.setEventDesc(news.getDescription()); + event.setRiskLevel(news.getRiskLevel()); + event.setStartDate(news.getCreationDate()); + event.setSrcType(EventSourceType.MEDIA_NEWS); + event.setSrcMediaWebsite(news.getNewsLink()); + event.setSrcMediaName(news.getNewsSource()); + bundle.putSerializable(Event.I18N_PREFIX, event); + Bundler bundler = new Bundler(bundle); + EventNewActivity.startActivity(context, bundler); + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListFragment.java new file mode 100644 index 00000000000..ad901aec7f9 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListFragment.java @@ -0,0 +1,71 @@ +package de.symeda.sormas.app.news; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import de.symeda.sormas.app.CustomWebView; +import de.symeda.sormas.app.PagedBaseListFragment; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.core.adapter.databinding.OnListItemClickListener; +import de.symeda.sormas.app.util.Callback; + +public class NewsListFragment extends PagedBaseListFragment implements OnListItemClickListener { + + private LinearLayoutManager linearLayoutManager; + private RecyclerView recyclerViewForList; + private Callback resetFilterCallBack; + + public static NewsListFragment newInstance() { + return newInstance(NewsListFragment.class, null); + } + + public void setResetFilterCallBack(Callback resetFilterCallBack) { + this.resetFilterCallBack = resetFilterCallBack; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + linearLayoutManager = new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, false); + recyclerViewForList = view.findViewById(R.id.recyclerViewForList); + + return view; + } + + @Override + public NewsListAdapter getNewListAdapter() { + return (NewsListAdapter) ((NewsListActivity) getActivity()).getAdapter(); + } + + @Override + public void onListItemClick(View view, int position, Object item) { + News news = (News) item; + CustomWebView.startActivity(getContext(), news.getNewsLink()); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + recyclerViewForList.setAdapter(getListAdapter()); + recyclerViewForList.setLayoutManager(linearLayoutManager); + } + + @Override + public void onResume() { + super.onResume(); + final SwipeRefreshLayout swiperefresh = this.getView().findViewById(R.id.swiperefresh); + if (swiperefresh != null) { + swiperefresh.setOnRefreshListener(() -> { + swiperefresh.setRefreshing(false); + if (resetFilterCallBack != null) { + resetFilterCallBack.call(); + } + }); + } + } + +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListViewModel.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListViewModel.java new file mode 100644 index 00000000000..ad9a24fb85c --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/news/NewsListViewModel.java @@ -0,0 +1,160 @@ +package de.symeda.sormas.app.news; + +import java.util.function.Consumer; + +import android.content.Context; +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; +import androidx.paging.DataSource; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; +import androidx.paging.PositionalDataSource; +import de.symeda.sormas.api.caze.CriteriaWithSorting; +import de.symeda.sormas.api.common.Page; +import de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto; +import de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto; +import de.symeda.sormas.api.infrastructure.region.RegionReferenceDto; +import de.symeda.sormas.api.news.NewsCriteria; +import de.symeda.sormas.api.news.eios.NewsStatus; +import de.symeda.sormas.app.core.async.AsyncTaskResult; +import de.symeda.sormas.app.core.async.DefaultAsyncTask; +import de.symeda.sormas.app.core.async.TaskResultHolder; +import de.symeda.sormas.app.rest.RetroProvider; +import retrofit2.Call; +import retrofit2.Response; + +public class NewsListViewModel extends ViewModel { + + private LiveData> newsList; + private NewsDataFactory newsDataFactory; + private static Context context; + + private static final Integer NEWS_PAGE_SIZE = 16; + + public NewsListViewModel() { + newsDataFactory = new NewsDataFactory(); + newsDataFactory.setCriteria(new NewsFilterCriteria()); + PagedList.Config config = + new PagedList.Config.Builder().setEnablePlaceholders(true).setInitialLoadSizeHint(NEWS_PAGE_SIZE).setPageSize(NEWS_PAGE_SIZE).build(); + LivePagedListBuilder newsPageListBuilder = new LivePagedListBuilder(newsDataFactory, config); + newsList = newsPageListBuilder.build(); + } + + void notifyCriteriaUpdated() { + if (newsList.getValue() != null) { + newsList.getValue().getDataSource().invalidate(); + if (!newsList.getValue().isEmpty()) { + newsList.getValue().loadAround(0); + } + } + } + + public void setContext(Context context) { + NewsListViewModel.context = context; + } + + public NewsFilterCriteria getNewsFilterCriteria() { + return newsDataFactory.getCriteria(); + } + + public LiveData> getNewsList() { + return newsList; + } + + public static class NewsDataSource extends PositionalDataSource { + + NewsFilterCriteria criteria; + + public NewsDataSource(NewsFilterCriteria criteria) { + this.criteria = criteria; + } + + @Override + public void loadInitial(@NonNull LoadInitialParams loadInitialParams, @NonNull LoadInitialCallback loadInitialCallback) { + loadNewsList(0, criteria, page -> loadInitialCallback.onResult(page.getElements(), 0, page.getTotalElementCount().intValue())); + + } + + @Override + public void loadRange(@NonNull LoadRangeParams loadRangeParams, @NonNull LoadRangeCallback loadRangeCallback) { + loadNewsList(loadRangeParams.startPosition, criteria, page -> loadRangeCallback.onResult(page.getElements())); + } + + private void loadNewsList(int offset, NewsFilterCriteria criteria, Consumer> consumer) { + + DefaultAsyncTask task = new DefaultAsyncTask(context) { + + @Override + protected void doInBackground(TaskResultHolder resultHolder) throws Exception { + CriteriaWithSorting criteriaWithSorting = new CriteriaWithSorting<>(); + criteriaWithSorting.setCaseCriteria(toNewCriteria(criteria)); + RetroProvider.connect(context); + Call> pageCall = RetroProvider.getNewsFacade().pullNewsIndexList(criteriaWithSorting, offset, NEWS_PAGE_SIZE); + Response> response = pageCall.execute(); + if (response.isSuccessful()) { + Page newsListPage = response.body(); + Log.i("NewsDataSource", "loadNewsList: " + newsListPage); + consumer.accept(newsListPage); + } else { + Log.e("NewsDataSource", "loadNewsList: " + response.errorBody().string()); + } + } + + @Override + protected void onPostExecute(AsyncTaskResult taskResult) { + super.onPostExecute(taskResult); + RetroProvider.disconnect(); + } + + }; + task.executeOnThreadPool(); + } + + private NewsCriteria toNewCriteria(NewsFilterCriteria criteria) { + NewsCriteria newCriteria = new NewsCriteria(); + // Only receiving approved news + newCriteria.setStatus(NewsStatus.APPROVED); + if (criteria.getRegion() != null) + newCriteria.setRegion(new RegionReferenceDto(criteria.getRegion().getUuid())); + if (criteria.getDistrict() != null) + newCriteria.setDistrict(new DistrictReferenceDto(criteria.getDistrict().getUuid())); + if (criteria.getCommunity() != null) + newCriteria.setCommunity(new CommunityReferenceDto(criteria.getCommunity().getUuid())); + newCriteria.setRiskLevel(criteria.getRiskLevel()); + newCriteria.setStartDate(criteria.getStartDate()); + newCriteria.setEndDate(criteria.getEndDate()); + return newCriteria; + } + + } + + public static class NewsDataFactory extends DataSource.Factory { + + private MutableLiveData mutableLiveData; + private NewsFilterCriteria criteria; + + public NewsDataFactory() { + this.mutableLiveData = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + NewsDataSource dataSource = new NewsDataSource(criteria); + mutableLiveData.postValue(dataSource); + return dataSource; + } + + public NewsFilterCriteria getCriteria() { + return criteria; + } + + public void setCriteria(NewsFilterCriteria criteria) { + this.criteria = criteria; + } + } + +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/NewsFacadeRetro.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/NewsFacadeRetro.java new file mode 100644 index 00000000000..3d4fc6982c6 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/NewsFacadeRetro.java @@ -0,0 +1,19 @@ +package de.symeda.sormas.app.rest; + +import de.symeda.sormas.api.caze.CriteriaWithSorting; +import de.symeda.sormas.api.common.Page; +import de.symeda.sormas.api.news.NewsCriteria; +import de.symeda.sormas.app.news.News; +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.POST; +import retrofit2.http.Query; + +public interface NewsFacadeRetro { + + @POST("news/indexList") + Call> pullNewsIndexList( + @Body CriteriaWithSorting criteriaWithSorting, + @Query("offset") int offset, + @Query("size") int size); +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/RetroProvider.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/RetroProvider.java index f1b0cec8e7d..8638c5808ac 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/RetroProvider.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/rest/RetroProvider.java @@ -20,38 +20,15 @@ import java.util.Date; import java.util.concurrent.TimeUnit; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonNull; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializer; +import com.google.gson.*; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.util.Log; - import androidx.fragment.app.FragmentActivity; - -import de.symeda.sormas.api.caze.classification.ClassificationAllOfCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationAllSymptomsCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationAnyOfSymptomsCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationCaseCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationEpiDataCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationEventClusterCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationExposureCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationNoneOfCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationPathogenTestCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationPathogenTestNegativeResultCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationPathogenTestOtherPositiveResultCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationPathogenTestPositiveResultCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationPersonAgeBetweenYearsCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationSymptomsCriteriaDto; -import de.symeda.sormas.api.caze.classification.ClassificationVaccinationDateNotInStartDateRangeDto; -import de.symeda.sormas.api.caze.classification.ClassificationXOfCriteriaDto; +import de.symeda.sormas.api.caze.classification.*; import de.symeda.sormas.api.environment.WaterUse; import de.symeda.sormas.api.environment.environmentsample.WeatherCondition; import de.symeda.sormas.api.utils.CompatibilityCheckResponse; @@ -70,11 +47,7 @@ import de.symeda.sormas.app.util.BiConsumer; import de.symeda.sormas.app.util.Consumer; import de.symeda.sormas.app.util.EnumMapKeySerializer; -import okhttp3.Credentials; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.ResponseBody; +import okhttp3.*; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; @@ -132,7 +105,7 @@ public final class RetroProvider { private AggregateReportFacadeRetro aggregateReportFacadeRetro; private EnvironmentFacadeRetro environmentFacadeRetro; private EnvironmentSampleFacadeRetro environmentSampleFacadeRetro; - + private NewsFacadeRetro newsFacadeRetro; private RetroProvider(Context context) throws ServerConnectionException, ServerCommunicationException, ApiVersionException { lastConnectionId = this.hashCode(); @@ -1013,6 +986,19 @@ public static EnvironmentSampleFacadeRetro getEnvironmentSampleFacade() throws N return instance.environmentSampleFacadeRetro; } + public static NewsFacadeRetro getNewsFacade() throws NoConnectionException { + if (instance == null) + throw new NoConnectionException(); + if (instance.newsFacadeRetro == null) { + synchronized ((RetroProvider.class)) { + if (instance.newsFacadeRetro == null) { + instance.newsFacadeRetro = instance.retrofit.create(NewsFacadeRetro.class); + } + } + } + return instance.newsFacadeRetro; + } + public static void throwException(Response response) throws ServerConnectionException, ServerCommunicationException { if (ServerConnectionException.RelatedErrorCodes.contains(response.code())) { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java index 79cb6ba94ec..b01ffb74841 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/util/NavigationHelper.java @@ -17,11 +17,9 @@ import android.content.Context; import android.content.Intent; - import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NavUtils; import androidx.core.app.TaskStackBuilder; - import de.symeda.sormas.api.task.TaskStatus; import de.symeda.sormas.app.campaign.list.CampaignFormDataListActivity; import de.symeda.sormas.app.caze.edit.CaseNewActivity; @@ -32,6 +30,7 @@ import de.symeda.sormas.app.environmentsample.list.EnvironmentSampleListActivity; import de.symeda.sormas.app.event.list.EventListActivity; import de.symeda.sormas.app.immunization.list.ImmunizationListActivity; +import de.symeda.sormas.app.news.NewsListActivity; import de.symeda.sormas.app.report.ReportActivity; import de.symeda.sormas.app.report.aggregate.AggregateReportsActivity; import de.symeda.sormas.app.sample.list.SampleListActivity; @@ -100,6 +99,11 @@ public static void goToReports(Context context) { context.startActivity(intent); } + public static void goToNews(Context context) { + Intent intent = new Intent(context, NewsListActivity.class); + context.startActivity(intent); + } + public static void goToSettings(Context context) { Intent intent = new Intent(context, SettingsActivity.class); context.startActivity(intent); diff --git a/sormas-app/app/src/main/res/layout/activity_custom_web_view.xml b/sormas-app/app/src/main/res/layout/activity_custom_web_view.xml new file mode 100644 index 00000000000..e2942be228f --- /dev/null +++ b/sormas-app/app/src/main/res/layout/activity_custom_web_view.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/activity_news_list.xml b/sormas-app/app/src/main/res/layout/activity_news_list.xml new file mode 100644 index 00000000000..57efd279fa2 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/activity_news_list.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/filter_news_list_layout.xml b/sormas-app/app/src/main/res/layout/filter_news_list_layout.xml new file mode 100644 index 00000000000..430dec669a6 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/filter_news_list_layout.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/row_news_list_item_layout.xml b/sormas-app/app/src/main/res/layout/row_news_list_item_layout.xml new file mode 100644 index 00000000000..4f149e6f2f5 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_news_list_item_layout.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + +