Skip to content
Permalink
Browse files

Merged master changes for futures colab to homolog

  • Loading branch information...
carlosbpf committed May 1, 2019
2 parents 6b9a3f6 + b83e9e6 commit f679357b0101c3996932098c1f6d6d4dd02ed339
Showing with 290 additions and 36 deletions.
  1. +14 −0 ...ent/src/main/java/org/xcolab/client/admin/attributes/configuration/ConfigurationAttributeKey.java
  2. +3 −0 ...s/admin-client/src/main/java/org/xcolab/client/admin/util/TemplateReplacementUtilPlaceholder.java
  3. +1 −0 ...ices/clients/contest-client/src/main/java/org/xcolab/client/contest/enums/ProposalSortColumn.java
  4. +3 −0 ...contest-client/src/main/java/org/xcolab/client/contest/proposals/IProposalMemberRatingClient.java
  5. +3 −1 ...in/java/org/xcolab/service/admin/domain/configurationattribute/ConfigurationAttributeDaoImpl.java
  6. +3 −1 ...c/main/java/org/xcolab/service/admin/domain/contesttypeattribute/ContestTypeAttributeDaoImpl.java
  7. +1 −1 scripts/run/startView.sh
  8. +2 −1 util/xcolab-utils/src/main/java/org/xcolab/util/i18n/I18nUtils.java
  9. +2 −1 ...c/main/java/org/xcolab/view/activityentry/proposal/DiscussionAddProposalCommentActivityEntry.java
  10. +2 −0 view/src/main/java/org/xcolab/view/config/rewrite/rules/ProposalRewriteRules.java
  11. +4 −0 view/src/main/java/org/xcolab/view/config/spring/StartupVerifier.java
  12. +1 −1 view/src/main/java/org/xcolab/view/config/spring/beans/I18nBeanConfig.java
  13. +3 −0 view/src/main/java/org/xcolab/view/pages/contestmanagement/entities/massactions/OrderMassAction.java
  14. +1 −1 view/src/main/java/org/xcolab/view/pages/discussion/discussions/views/CategoryController.java
  15. +2 −1 view/src/main/java/org/xcolab/view/pages/profile/beans/UserBean.java
  16. +1 −1 view/src/main/java/org/xcolab/view/pages/profile/wrappers/UserProfileWrapper.java
  17. +9 −0 view/src/main/java/org/xcolab/view/pages/proposals/permissions/ProposalsDisplayPermissions.java
  18. +3 −1 view/src/main/java/org/xcolab/view/pages/proposals/requests/UpdateProposalDetailsBean.java
  19. +16 −0 view/src/main/java/org/xcolab/view/pages/proposals/view/action/VoteOnProposalActionController.java
  20. +17 −0 view/src/main/java/org/xcolab/view/pages/proposals/view/contest/ContestProposalsController.java
  21. +20 −0 view/src/main/java/org/xcolab/view/pages/proposals/view/proposal/CreateProposalController.java
  22. +2 −0 ...ain/java/org/xcolab/view/pages/proposals/view/proposal/tabs/ProposalDescriptionTabController.java
  23. +23 −0 view/src/main/java/org/xcolab/view/util/validation/ConfigurableProposalPitchMaxLength.java
  24. +61 −0 view/src/main/java/org/xcolab/view/util/validation/ConfigurableProposalPitchMaxLengthValidator.java
  25. +5 −1 view/src/main/resources/i18n/contests.properties
  26. +5 −1 view/src/main/resources/i18n/contests_es.properties
  27. +1 −0 view/src/main/resources/static/js/pages/admin/contest-manager.js
  28. +3 −0 view/src/main/resources/static/sass/partials/pages/_logingregister.scss
  29. +13 −8 view/src/main/webapp/WEB-INF/jsp/contestmanagement/manager/schedulesTab.jspx
  30. +15 −6 view/src/main/webapp/WEB-INF/jsp/proposals/contestProposals.jspx
  31. +2 −1 view/src/main/webapp/WEB-INF/jsp/proposals/proposalDetails/proposalPicker_widget.jspx
  32. +5 −3 view/src/main/webapp/WEB-INF/jsp/proposals/proposalDetails_edit.jspx
  33. +1 −1 view/src/main/webapp/WEB-INF/tags/proposalsPortlet/proposalSectionEdit.tagx
  34. +43 −5 view/src/main/webapp/WEB-INF/tags/proposalsPortlet/proposalsList.tagx
@@ -347,6 +347,20 @@ private ConfigurationAttributeKey() {
ConfigurationAttributes.newBooleanAttribute("PROPOSALS_COMMENTS_READ_ONLY")
.defaultValue(false)
.build();
public static final AttributeGetter<Long> PROPOSALS_PITCH_CHAR_LIMIT =
ConfigurationAttributes.newLongAttribute("PROPOSALS_PITCH_CHAR_LIMIT")
.defaultValue(140l)
.build();
public static final AttributeGetter<Long> PROPOSALS_MAX_PER_AUTHOR_IN_CONTEST =
ConfigurationAttributes.newLongAttribute("PROPOSALS_MAX_PER_AUTHOR_IN_CONTEST")
.defaultValue(0l)
.build();
public static final AttributeGetter<Boolean> PROPOSALS_VOTE_IN_CONTEST_PAGE =
ConfigurationAttributes.newBooleanAttribute("PROPOSALS_VOTE_IN_CONTEST_PAGE")
.defaultValue(false)
.build();



// Points
public static final AttributeGetter<Boolean> POINTS_IS_ACTIVE =
@@ -19,6 +19,9 @@ private TemplateReplacementUtilPlaceholder() {
}

public static String replacePlatformConstants(String text) {
if(text == null) {
return "";
}
final String colabName = ConfigurationAttributeKey.COLAB_NAME.get();
final String colabShortName = ConfigurationAttributeKey.COLAB_SHORT_NAME.get();
final String colabUrl = PlatformAttributeKey.COLAB_URL.get();
@@ -6,6 +6,7 @@
import java.util.Comparator;

public enum ProposalSortColumn {
PROPOSAL_ID(Comparator.comparing(o -> o.getId())),
NAME(Comparator.comparing(o -> o.getName().toLowerCase())),
AUTHOR(Comparator.comparing(o -> o.getAuthorName().toLowerCase())),
SUPPORTERS((o1, o2) -> (int) (o1.getSupportersCount() - o2.getSupportersCount())),
@@ -85,6 +85,9 @@ default int countProposalVotesInContestPhase(Long contestPhaseId) {
return countProposalVotes(contestPhaseId, null, null, true);
}

default int countVotesByUserInProposalAndPhase(long userId, long proposalId, long phaseId){
return countProposalVotes(phaseId, proposalId, userId, null);
}
default int countVotesByUserInPhase(long userId, long phaseId) {
return countProposalVotes(phaseId, null, userId, null);
}
@@ -10,14 +10,16 @@
import org.xcolab.client.admin.pojo.IConfigurationAttribute;
import org.xcolab.client.admin.pojo.tables.pojos.ConfigurationAttribute;

import org.xcolab.util.i18n.I18nUtils;

import java.util.Optional;

import static org.xcolab.model.Tables.CONFIGURATION_ATTRIBUTE;

@Repository
public class ConfigurationAttributeDaoImpl implements ConfigurationAttributeDao {

private static final String DEFAULT_LOCALE = "en";
private static final String DEFAULT_LOCALE = I18nUtils.DEFAULT_LANGUAGE;

private final DSLContext dslContext;

@@ -10,6 +10,8 @@
import org.xcolab.client.admin.pojo.IContestTypeAttribute;
import org.xcolab.client.admin.pojo.tables.pojos.ContestTypeAttribute;

import org.xcolab.util.i18n.I18nUtils;

import java.util.List;
import java.util.Optional;

@@ -18,7 +20,7 @@
@Repository
public class ContestTypeAttributeDaoImpl implements ContestTypeAttributeDao {

private static final String DEFAULT_LOCALE = "en";
private static final String DEFAULT_LOCALE = I18nUtils.DEFAULT_LANGUAGE;

private final DSLContext dslContext;

@@ -28,7 +28,7 @@ function startView {
fi
rm ${OUT_FILE} > /dev/null 2>&1
exec java -Xmx${maxMem} -Xms1G -XX:-OmitStackTraceInFastThrow \
-jar ${VIEW}-1.0-SNAPSHOT.war > ${OUT_FILE} & echo $! > ${PID_FILE}
-Duser.language=en -Duser.country=US -jar ${VIEW}-1.0-SNAPSHOT.war > ${OUT_FILE} & echo $! > ${PID_FILE}
fi
}

@@ -14,7 +14,8 @@
public final class I18nUtils {

public static final String MEMBER_LOCALE_SESSION_IDENTIFIER = "memberLocale";
public static final Locale DEFAULT_LOCALE = Locale.US;

public static final Locale DEFAULT_LOCALE = Locale.getDefault();
public static final String DEFAULT_LANGUAGE = DEFAULT_LOCALE.getLanguage();

private static final Map<String, String> codeToLocale = new HashMap<>();
@@ -34,6 +34,7 @@ protected String getBodyTemplate() {

@Override
protected String getProposalLinkUrl() {
return super.getProposalLinkUrl() + "/tab/COMMENTS";

return this.getProposal().getProposalDiscussionUrl();
}
}
@@ -23,6 +23,8 @@ public void configure(ConfigurationBuilder configurationBuilder) {
.or(Path.matches("/trends{path}"))
.or(Path.matches("/dialogues{path}"))
.or(Path.matches("/contributions{path}"))
.or(Path.matches("/ClimatePhilanthropy{path}"))
.or(Path.matches("/DisruptingSystems{path}"))
))
.perform(Forward.to("/contests{path}"))
.where("path").matches(".*");
@@ -9,6 +9,7 @@
import org.xcolab.client.admin.attributes.platform.PlatformAttributeKey;
import org.xcolab.client.admin.enums.ServerEnvironment;
import org.xcolab.commons.servlet.ManifestUtil;
import org.xcolab.util.i18n.I18nUtils;

import java.util.Optional;

@@ -41,5 +42,8 @@ public void run(ApplicationArguments applicationArguments) {
log.warn("Running in NON PRODUCTION environment. For production use, please set the"
+ " server environment to {}.", ServerEnvironment.PRODUCTION);
}

log.info("Running with default locale : {}", I18nUtils.DEFAULT_LOCALE.getCountry() + "_" + I18nUtils.DEFAULT_LOCALE.getLanguage());

}
}
@@ -41,7 +41,7 @@ public MessageSource messageSource() {
@Bean
public LocaleResolver localeResolver(AuthenticationService authenticationService) {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.US);
sessionLocaleResolver.setDefaultLocale(I18nUtils.DEFAULT_LOCALE);
sessionLocaleResolver.setLocaleAttributeName(I18nUtils.MEMBER_LOCALE_SESSION_IDENTIFIER);
return new MemberLocaleResolver(authenticationService, sessionLocaleResolver);
}
@@ -16,8 +16,11 @@ public OrderMassAction() {
@Override
public void execute(List<ContestWrapper> contests, boolean actionConfirmed,
MassActionDataWrapper dataWrapper, HttpServletResponse response) {
Integer newWeight;
for (ContestWrapper contest : contests) {
newWeight = contest.getWeight();
contest = StaticContestContext.getContestClient().getContest(contest.getId());
contest.setWeight(newWeight);
StaticContestContext.getContestClient().updateContest(contest);
}
}
@@ -79,7 +79,7 @@ public String showCategories(HttpServletRequest request, HttpServletResponse res
public String showCategory(HttpServletRequest request, HttpServletResponse response,
Model model, @PathVariable long categoryId,
@RequestParam(required = false) String sortColumn,
@RequestParam(defaultValue = "false") boolean sortAscending)
@RequestParam (required= false, defaultValue = "true") boolean sortAscending)
throws DiscussionAuthorizationException, CategoryNotFoundException {

long userId = MemberAuthUtil.getUserId();
@@ -9,6 +9,7 @@
import org.xcolab.client.user.pojo.wrapper.MessagingUserPreferenceWrapper;
import org.xcolab.client.user.pojo.wrapper.UserWrapper;
import org.xcolab.commons.CountryUtil;
import org.xcolab.util.i18n.I18nUtils;
import org.xcolab.view.util.validation.CompareStrings;
import org.xcolab.view.util.validation.HtmlMaxLength;
import org.xcolab.view.util.validation.PasswordLength;
@@ -82,7 +83,7 @@ public UserBean(UserWrapper member) {
if(member.getDefaultLocale()!=null){
defaultLocale = member.getDefaultLocale();
}else{
defaultLocale = "en"; //TODO COLAB-2621: migrate this to a single i18n file
defaultLocale = I18nUtils.DEFAULT_LOCALE.getLanguage();
}
if(member.getPortraitFileEntryId()==null){
imageId = 0;
@@ -135,7 +135,7 @@ private void init() {
if (proposalsInContestType != null) {
for (ProposalWrapper p : proposalsInContestType) {
contestTypeProposalWrappersByContestTypeId.get(contestType.getId())
.getProposals().add(p);
.getProposals().add(new ProposalWrapper(p));
}
}
}
@@ -61,6 +61,15 @@ public boolean getCanSeeVoteButton() {
return !isLoggedIn || (!isGuest && !hasVotedOnThisProposal());
}

public boolean getCanSeeVoteButtonForProposal(Long proposalId) {
return !isLoggedIn || (!isGuest && !(clientHelper.getProposalMemberRatingClient()
.hasUserVoted(proposalId, contestPhase.getId(), userId)));
}
public int countVotesByUserInPhase(Long proposalId) {
return clientHelper.getProposalMemberRatingClient()
.countVotesByUserInProposalAndPhase(userId, proposalId, contestPhase.getId());
}

private boolean hasVotedOnThisProposal() {
return proposal != null && proposal.getId() > 0
&& clientHelper.getProposalMemberRatingClient().hasUserVoted(
@@ -6,14 +6,16 @@
import org.xcolab.client.contest.pojo.wrapper.ProposalTemplateSectionDefinitionWrapper;
import org.xcolab.client.contest.pojo.wrapper.ProposalWrapper;
import org.xcolab.util.enums.proposal.MoveType;
import org.xcolab.view.util.validation.ConfigurableProposalPitchMaxLength;

import java.util.HashMap;
import java.util.Map;

public class UpdateProposalDetailsBean {
private Map<Long, String> sectionsContent = new HashMap<>();

@Length(max = 140, message = "The pitch is limited to 140 characters.")
//@Length(max = 140, message = "The pitch is limited to 140 characters.")
@ConfigurableProposalPitchMaxLength
private String pitch;

@NotBlank(message = "Please enter a title.")
@@ -10,6 +10,7 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import org.xcolab.client.activity.IActivityClient;
import org.xcolab.client.admin.attributes.configuration.ConfigurationAttributeKey;
@@ -61,6 +62,21 @@ public VoteOnProposalActionController(
this.userClient = userClient;
}

@PostMapping("voteInContestPage")
public String voteInContestPage(
HttpServletRequest request, HttpServletResponse response,
ProposalContext proposalContext,
Model model,
UserWrapper member,@RequestParam(defaultValue = "1") int voteValue) throws ProposalsAuthorizationException {

this.handleAction(request,response, model, proposalContext, member,voteValue);

return "redirect:" + proposalContext.getContest().getContestUrl();

}



@PostMapping("vote")
public String handleAction(HttpServletRequest request, HttpServletResponse response,
Model model, ProposalContext proposalContext, UserWrapper member,
@@ -140,11 +140,28 @@ private String showContestProposalsPage(HttpServletResponse response, Model mode
model.addAttribute("showContributorsColumn",
ConfigurationAttributeKey.CONTESTS_ALLOW_OPEN_PROPOSALS.get());

model.addAttribute("proposalVoteInContestPage", ConfigurationAttributeKey.PROPOSALS_VOTE_IN_CONTEST_PAGE.get());

boolean showEditLink = proposalContext.getPermissions().getCanEditContest();
boolean showDownloadLink = proposalContext.getPermissions().getCanDownload();
model.addAttribute("showEditLink", showEditLink);
model.addAttribute("showDownloadLink", showDownloadLink);

Long proposalCreationMaxPerAuthor = ConfigurationAttributeKey.PROPOSALS_MAX_PER_AUTHOR_IN_CONTEST.get();
model.addAttribute("proposalCreationMaxPerAuthor",proposalCreationMaxPerAuthor);
if(proposalCreationMaxPerAuthor != 0 ) {
int totalProposalsByAuthor = 0;
for(ProposalWrapper p: proposals){
if(p.getAuthor().getId() == loggedInMember.getId()) {
totalProposalsByAuthor = totalProposalsByAuthor + 1;
}
}

model.addAttribute("hasAuthorReachedLimit", (totalProposalsByAuthor>= proposalCreationMaxPerAuthor));

}


setBasePageAttributes(proposalContext, model);

return "/proposals/contestProposals";
@@ -30,6 +30,8 @@
import org.xcolab.view.pages.proposals.utils.edit.ProposalUpdateHelper;
import org.xcolab.view.util.entity.analytics.AnalyticsUtil;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@@ -52,6 +54,22 @@ public String createProposalsBasedOn(HttpServletRequest request, HttpServletResp
public String showCreateProposal(HttpServletRequest request, HttpServletResponse response,
Model model, ProposalContext proposalContext, UserWrapper loggedInMember) {


Long proposalCreationMaxPerAuthor = ConfigurationAttributeKey.PROPOSALS_MAX_PER_AUTHOR_IN_CONTEST.get();
if(proposalCreationMaxPerAuthor != 0 ) {
int totalProposalsByAuthor = 0;
List<ProposalWrapper> proposals = proposalContext.getClients().getProposalClient().getActiveProposalsInContestPhase(
proposalContext.getContestPhase().getId());
for(ProposalWrapper p: proposals){
if(p.getAuthor().getId() == loggedInMember.getId()) {
totalProposalsByAuthor = totalProposalsByAuthor + 1;
}
}
if((totalProposalsByAuthor>= proposalCreationMaxPerAuthor)) {
return "redirect:" + proposalContext.getContest().getContestUrl();
}

}
return showCreateProposal(request, response, model, proposalContext, loggedInMember, null, -1, null);
}

@@ -132,6 +150,8 @@ private String showCreateProposal(HttpServletRequest request, HttpServletRespons
ConfigurationAttributeKey.IMAGE_UPLOAD_EXTERNAL_SERVICE_URL.get());
request.setAttribute("imageUploadHelpText", ConfigurationAttributeKey.IMAGE_UPLOAD_HELP_TEXT.get());

model.addAttribute("proposalPitchCharLimit", ConfigurationAttributeKey.PROPOSALS_PITCH_CHAR_LIMIT.get());

return "proposals/proposalDetails_edit";
}

@@ -171,6 +171,8 @@ public String showProposalDetails(HttpServletRequest request, HttpServletRespons
model.addAttribute("userTeams", StaticUserContext.getPlatformTeamClient()
.listPlatformTeams(currentMember.getId()));

model.addAttribute("proposalPitchCharLimit", ConfigurationAttributeKey.PROPOSALS_PITCH_CHAR_LIMIT.get());

return "proposals/proposalDetails_edit";
}

@@ -0,0 +1,23 @@
package org.xcolab.view.util.validation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ConfigurableProposalPitchMaxLengthValidator.class)
@Documented
public @interface ConfigurableProposalPitchMaxLength {

String message() default "";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}

0 comments on commit f679357

Please sign in to comment.
You can’t perform that action at this time.