Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Dev & Staging #1441

Merged
merged 64 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
6e1bb1b
Merge pull request #1280 from GSA/jdonis/CHAL-1751-update-JSON5
jdonis Apr 29, 2024
4de37bf
Circleci Chrome update
jdonis Jun 7, 2024
b43e5f4
Merge pull request #1333 from GSA/jdonis/circleci-chrome-update-1325
kkrug Jun 10, 2024
525794f
Merge pull request #1344 from GSA/jdonis/circleci-chrome-update-1325
kkrug Jun 18, 2024
ed5b0c4
update html_sanitize_ex
jdonis Jul 2, 2024
2fb15de
Merge branch 'staging' into jdonis/1218-html-sanitize-ex-update
jdonis Jul 2, 2024
915c6d0
Merge pull request #1353 from GSA/jdonis/1218-html-sanitize-ex-update
kkrug Jul 2, 2024
54357be
Upgrade quantum to 3.5.3 in staging
kkrug Jul 2, 2024
e3a9f98
Merge pull request #1370 from GSA/staging
kkrug Jul 11, 2024
c2056d1
Merge branch 'staging' of github.com:GSA/Challenge_gov into staging
jdonis Jul 12, 2024
67ef639
Quantum update
jdonis Jul 12, 2024
ce9f909
Revert "Updating PROD Dependencies "
jdonis Jul 12, 2024
e059fc1
downgrade
jdonis Jul 12, 2024
98f8ae7
Merge branch 'staging' of github.com:GSA/Challenge_gov into jdonis/qu…
jdonis Jul 12, 2024
0276500
Merge pull request #1373 from GSA/revert-1370-staging
kkrug Jul 15, 2024
29c9df2
Merge pull request #1375 from GSA/jdonis/quantum-2
kkrug Jul 15, 2024
85784f4
Merge branch 'staging' of github.com:GSA/Challenge_gov into staging
jdonis Jul 15, 2024
d1a789c
fix merge issues
jdonis Jul 15, 2024
e70a86f
Quantum 3.5.3
jdonis Jul 15, 2024
00f55a2
Merge pull request #1378 from GSA/dependency-patch-quantum-html-sanit…
kkrug Jul 15, 2024
9381408
moment -> js
jdonis Jul 29, 2024
c1874bb
remove uglifyjs-webpack-plugin (deprecated)
jdonis Jul 29, 2024
5ecb334
Merge pull request #1393 from GSA/jdonis/1372-serialize-javascript
kkrug Jul 29, 2024
8189c70
Remove Moment second part
jdonis Jul 29, 2024
95600b6
Merge branch 'staging' into jdonis/1310-moment-dependency
jdonis Jul 30, 2024
3247747
Merge pull request #1395 from GSA/jdonis/1310-moment-dependency
kkrug Jul 30, 2024
5078c2a
Adding year & new webpack configuration
jdonis Aug 8, 2024
c6bd79b
Merge branch 'staging' into jdonis/1310-moment-dependency
jdonis Aug 8, 2024
f110a67
Merge pull request #1402 from GSA/jdonis/1310-moment-dependency
kkrug Aug 8, 2024
88b971c
phases start & end
jdonis Aug 9, 2024
e448cf6
phases start & end
jdonis Aug 9, 2024
43ed00a
Merge pull request #1407 from GSA/staging
kkrug Aug 12, 2024
82b060e
Dependencies: row 5 #1358
kkrug Aug 8, 2024
6a9d5d8
yarn update assets
jdonis Aug 9, 2024
1b0007f
Non gov-mil users
jdonis Aug 13, 2024
ff54f74
Merge branch 'production' into staging
kkrug Aug 13, 2024
e59c7ac
Update jquery to 3.7.1
kkrug Aug 21, 2024
7caac94
Merge branch 'staging' into 1359-update-jquery
kkrug Aug 21, 2024
c22b5bf
Merge branch '1359-update-jquery' of github.com:GSA/Challenge_gov int…
jdonis Aug 22, 2024
cb8c3ad
Update jquery to 3.7.1
kkrug Aug 21, 2024
0a78939
Revert "Update jquery to 3.7.1"
kkrug Aug 22, 2024
ad88c57
Merge pull request #1415 from GSA/revert-1412-1359-update-jquery
kkrug Aug 22, 2024
22821b5
New yarn.lock
jdonis Aug 23, 2024
1f9bc0b
remove code non-gov
jdonis Aug 23, 2024
bf5a77a
Merge branch 'staging' into 1359-update-jquery
jdonis Aug 23, 2024
f4eea8a
Merge pull request #1416 from GSA/1359-update-jquery
kkrug Aug 23, 2024
c2cfc4d
dependency diverge 3.4 -> 3.9.2
jdonis Aug 23, 2024
8e3a605
non-gov validation, logs and testing
jdonis Aug 26, 2024
f018f25
fix testing
jdonis Aug 26, 2024
2a8c25e
Merge branch 'staging' into jdonis/1390-non-gov-access
jdonis Aug 26, 2024
8feb930
closing if
jdonis Aug 26, 2024
1c9c1b7
merge if/end issues
jdonis Aug 26, 2024
bd0257a
Merge pull request #1419 from GSA/jdonis/1390-non-gov-access
kkrug Aug 27, 2024
bc5d034
NG can't submit or create new Challenges
jdonis Sep 10, 2024
6b48e4d
Code scanning - DOM text reinterpreted as HTML #1427
kkrug Sep 16, 2024
e963b8b
Code scanning - DOM text reinterpreted as HTML #1427
kkrug Sep 17, 2024
aeee333
Code scanning - DOM text reinterpreted as HTML #1427
kkrug Sep 17, 2024
cc1fa08
Code scanning - DOM text reinterpreted as HTML #1427
kkrug Sep 18, 2024
2232775
fixed conflicts
jdonis Sep 21, 2024
2dd57e4
Updated ecto_sql
jdonis Sep 21, 2024
e4467ff
update yarn.lock
jdonis Sep 21, 2024
e183b2e
fix testing - Wallaby & dependencies
jdonis Oct 6, 2024
ccd939c
adding tesla configuration
jdonis Oct 6, 2024
f2606a2
upgrade wallaby
jdonis Oct 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
elixir 1.16.3
erlang 26.2.5
nodejs 20.14.0
yarn 1.22.5
yarn 1.22.19
7 changes: 5 additions & 2 deletions assets/client/src/components/ChallengeAnnouncement.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React from 'react';
import moment from 'moment';
import {formatDate, daysInMinutes, formatDateTime} from "../helpers/phaseHelpers"

export const ChallengeAnnouncement = ({challenge}) => {
const checkAnnouncementDate = ({announcement_datetime}) => {
return moment().diff(announcement_datetime, 'minutes') <= daysInMinutes(14)

let now = new Date();
let announcementDate = new Date(announcement_datetime);
let diffInMinutes = (now - announcementDate) / (1000 * 60);
return diffInMinutes <= daysInMinutes(14)
}

const renderAnnouncement = ({header, body}) => {
Expand Down
47 changes: 37 additions & 10 deletions assets/client/src/components/ChallengeDetails.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useContext, useEffect, useState } from 'react'
import moment from "moment"
import { stripHtml } from "string-strip-html";
import { Tooltip } from 'reactstrap';
import NumberFormat from 'react-number-format';
Expand Down Expand Up @@ -30,22 +29,50 @@ export const ChallengeDetails = ({challenge, challengePhases, preview, print, ta
const toggleShareTooltip = () => setShareTooltipOpen(!shareTooltipOpen)

const renderEndDate = (date) => {
const fiveDaysFromNow = moment().add(5,'d').utc().format()
const withinFiveDays = moment(date).diff(fiveDaysFromNow) <= 0

if (date > moment().utc().format()) {
let localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

let formatLocalDateTime = (date) => {
let dateObj = new Date(date);
let dateOptions = { year: 'numeric', month: '2-digit', day: '2-digit', timeZone: localTimeZone };
let timeOptions = { hour: '2-digit', minute: '2-digit', hour12: true, timeZone: localTimeZone };
let formattedDate = dateObj.toLocaleDateString('en-US', dateOptions);
let formattedTime = dateObj.toLocaleTimeString('en-US', timeOptions);
return `${formattedDate} ${formattedTime}`;
}

const fiveDaysFromNow = () => {
let now = new Date();
now.setDate(now.getDate() + 5);
let utcDate = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds()));
return utcDate.toDateString();
}

const withinFiveDays = (date) => {
let givenDate = new Date(date);
let now = new Date();
let futureDate = new Date(fiveDaysFromNow());
return givenDate <= futureDate;
}

let getUTCNow = () => {
let now = new Date();
return now.toISOString();
}

if (date > getUTCNow()) {
return (
<div className="item">
<p className="info-title">Open until:</p>
<p>{moment(date).local().format('L LT')}</p>
{ withinFiveDays && <p className="date-qualifier">Closing soon</p> }
<p>{formatLocalDateTime(date)}</p>
{ withinFiveDays() && <p className="date-qualifier">Closing soon</p> }
</div>
)
} else {
return (
<div className="item">
<p className="info-title">Closed on:</p>
<p>{moment(date).local().format('L LT')}</p>
<p>{formatLocalDateTime(date)}</p>
</div>
)
}
Expand Down Expand Up @@ -94,7 +121,7 @@ export const ChallengeDetails = ({challenge, challengePhases, preview, print, ta
<div className="follow-tooltip__section">
<h4>Follow challenge as guest</h4>
<p>Receive challenge updates to your email. No sign-in required</p>
<a href={preview ? null : challenge.gov_delivery_topic_subscribe_link}>
<a href={preview ? "#" : `${encodeURIComponent(challenge.gov_delivery_topic_subscribe_link)}`}>
<button className="follow-tooltip__button">Follow challenge</button>
</a>
</div>
Expand Down Expand Up @@ -323,7 +350,7 @@ export const ChallengeDetails = ({challenge, challengePhases, preview, print, ta
<div className="logos">
<img
className="agency-logo"
src={imageBase + challenge.agency_logo}
src={`${imageBase}${encodeURIComponent(challenge.agency_logo)}`}
alt={`Agency logo for ${challenge.agency_name}`}
/>

Expand Down Expand Up @@ -377,7 +404,7 @@ export const ChallengeDetails = ({challenge, challengePhases, preview, print, ta
</div>
}
{!print &&
<a className="follow__btn" href={apiUrl + `/public/previews/challenges?challenge=${challenge.uuid}&print=true`} target="_blank">
<a className="follow__btn" href={`${apiUrl}/public/previews/challenges?challenge=${encodeURIComponent(challenge.uuid)}&print=true`} target="_blank" rel="noopener noreferrer">
<span className="details__btn">
<svg className="usa-icon" aria-hidden="true" focusable="false" role="img"
style={{fill: "#FA9441", height: "21px", width: "21px", position: "relative", top: "5px", right: "5px"}}>
Expand Down
28 changes: 17 additions & 11 deletions assets/client/src/components/ChallengeTile.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import React, {useContext} from 'react'
import { Link } from "react-router-dom";
import moment from "moment"
import {getCurrentPhase, getNextPhase, phaseNumber, formatDateTime, formatTime, isSinglePhase, isPhaseless, daysInMinutes} from "../helpers/phaseHelpers"
import {truncateString} from '../helpers/stringHelpers'
import { ApiUrlContext } from '../ApiUrlContext'

export const ChallengeTile = ({challenge, preview}) => {
const { publicUrl, imageBase } = useContext(ApiUrlContext)

let diffMinutes = (d) =>{
let now = new Date();
let date = new Date(d);
return (now - date) / (1000 * 60)
}

const renderTags = ({is_archived, start_date, end_date, announcement_datetime}) => {
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const announcementDateDiff = moment().diff(announcement_datetime, 'minutes')

const startDateDiff = diffMinutes(start_date);
const endDateDiff = diffMinutes(end_date);
const announcementDateDiff = diffMinutes(announcement_datetime);

let tags = []

Expand Down Expand Up @@ -40,8 +46,8 @@ export const ChallengeTile = ({challenge, preview}) => {

const renderDate = (challenge) => {
const {start_date, end_date, phases} = challenge
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const startDateDiff = diffMinutes(start_date)
const endDateDiff = diffMinutes(end_date)

if (isPhaseless(challenge)) {
return handlePhaselessChallengeDate(challenge)
Expand Down Expand Up @@ -73,8 +79,8 @@ export const ChallengeTile = ({challenge, preview}) => {

// TODO: This is potentially temporary until the importer handles adding phases to imported challenges
const handlePhaselessChallengeDate = ({start_date, end_date}) => {
const startDateDiff = moment().diff(start_date, 'minutes')
const endDateDiff = moment().diff(end_date, 'minutes')
const startDateDiff = diffMinutes(start_date)
const endDateDiff = diffMinutes(end_date)

if (startDateDiff < 0) {
return `Opens on ${formatDateTime(start_date)}`
Expand Down Expand Up @@ -109,7 +115,7 @@ export const ChallengeTile = ({challenge, preview}) => {
<div className="agency_image_wrapper">
<img
className="agency-logo"
src={imageBase + challenge.agency_logo}
src={`${imageBase}${encodeURIComponent(challenge.agency_logo)}`}
alt={truncateString(`Agency Logo: ${challenge.agency_name}`, 90)}
/>
</div>
Expand All @@ -128,7 +134,7 @@ export const ChallengeTile = ({challenge, preview}) => {
<div className="image_wrapper">
<img
className="agency-logo"
src={imageBase + challenge.agency_logo}
src={`${imageBase}${encodeURIComponent(challenge.agency_logo)}`}
alt={truncateString(`Agency Logo: ${challenge.agency_name}`, 90)}
/>
</div>
Expand All @@ -138,7 +144,7 @@ export const ChallengeTile = ({challenge, preview}) => {
return (
challenge ? (
<div key={challenge.id} className="challenge-tile card">
<a href={challengeTileUrl(challenge, preview)} target={challenge.external_url ? "_blank" : ""} aria-label="">
<a href={encodeURI(challengeTileUrl(challenge, preview))} target={challenge.external_url ? "_blank" : ""} aria-label="">
{renderTileLogo()}
<div className="challenge-tile__text-wrapper">
<h2 className="challenge-tile__title test" aria-label="" style={{ textAlign: 'left', paddingLeft: '20px', paddingTop: '20px', lineHeight: '30px' }}>{truncateString(challenge.title, 90)}</h2>
Expand Down
52 changes: 36 additions & 16 deletions assets/client/src/components/ChallengeTiles.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react';
import moment from 'moment';
import { ChallengeTile } from './ChallengeTile';

const dateAddedOptions = [
Expand Down Expand Up @@ -75,6 +74,15 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
const [keyword, setKeyword] = useState('');
const [filteredChallenges, setFilteredChallenges] = useState([]);

const isBetween = (date, startDate, endDate) => {

let dateObj = new Date(date);
let startDateObj = new Date(startDate);
let endDateObj = new Date(endDate);
return dateObj >= startDateObj && dateObj < endDateObj;

}

useEffect(() => {
try {
if (data && data.collection) {
Expand All @@ -88,26 +96,32 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
}

if (dateAdded) {
const now = moment();
let fromDate = now.clone().subtract(1, "years");

const now = new Date();
let fromDate = new Date(now);
fromDate.setFullYear(fromDate.getFullYear() -1);


switch (dateAdded) {
case "Past Week":
fromDate = now.clone().subtract(7, "days");
fromDate = new Date(now);
fromDate.setDate(fromDate.getDate() -7);
break;
case "Past Month":
fromDate = now.clone().subtract(1, "months");
fromDate = new Date(now);
fromDate.setMonth(fromDate.getMonth() -1);
break;
case "Past 90 Days":
fromDate = now.clone().subtract(90, "days");
fromDate = new Date(now);
fromDate.setDate(fromDate.getDate() -90);
break;
default:
break;
}

filtered = filtered.filter((challenge) => {
const challengeDate = moment(challenge.inserted_at);
return challengeDate.isBetween(fromDate, now, null, "[)");
const challengeDate = new Date(challenge.inserted_at);
return isBetween(challengeDate, fromDate, now);
});
}

Expand All @@ -116,30 +130,35 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle
}

if (lastDay) {
const now = moment();
const now = new Date();
let toDate;

switch (lastDay) {
case "Next Week":
toDate = now.clone().add(7, "days");
toDate = new Date(now);
toDate.setDate(toDate.getDate() +7);
break;
case "Next Month":
toDate = now.clone().add(1, "months");
toDate = new Date(now);
toDate.setMonth(toDate.getMonth()+1);
break;
case "Next 90 days":
toDate = new Date(now);
toDate = now.clone().add(90, "days");
break;
case "Within Year":
toDate = now.clone().add(1, "years");
toDate = new Date(now);
toDate.setFullYear(toDate.getFullYear()+1);
break;
default:
toDate = now.clone().add(1, "years");
toDate = new Date(now);
toDate.setFullYear(toDate.getFullYear()+1);
break;
}

filtered = filtered.filter((challenge) => {
const challengeEnd = moment(challenge.end_date);
return challengeEnd.isBetween(now, toDate, null, "[)");
const challengeEnd = new Date(challenge.end_date);
return isBetween(challengeEnd, now, toDate);
});
}

Expand Down Expand Up @@ -296,7 +315,8 @@ export const ChallengeTiles = ({ data, loading, isArchived, selectedYear, handle

const renderYearFilter = () => {
const startYear = 2010;
const currentYear = moment().year();
let year = new Date();
const currentYear = year.getFullYear();
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + (i * step));
const years = range(currentYear, startYear, -1);

Expand Down
25 changes: 20 additions & 5 deletions assets/client/src/components/PreviewBanner.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import React, { useContext } from 'react'
import moment from 'moment'
import { ApiUrlContext } from '../ApiUrlContext'

export const PreviewBanner = ({challenge}) => {
const location = window.location.href.split('?')[0]
const { apiUrl } = useContext(ApiUrlContext)

const formatDateToLLLL = () => {

let now = new Date()
const options = {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: true
};

return new Intl.DateTimeFormat('en-US', options).format(now);
}

return (
challenge ? (
Expand All @@ -20,11 +35,11 @@ export const PreviewBanner = ({challenge}) => {
</div>
<br/>
<div>
<span className="me-3">Preview generated on {moment().format("llll")}</span>
<span className="me-3">Preview generated on {formatDateToLLLL()}</span>
<a className="me-3" href={window.location.href}>Refresh page</a>
{!challenge.external_url &&
<a href={apiUrl + `/public/previews/challenges?challenge=${challenge.uuid}&print=true`} target="_blank">Print</a>
}
{!challenge.external_url && (
<a href={`${apiUrl}/public/previews/challenges?challenge=${encodeURIComponent(challenge.uuid)}&print=true`} target="_blank">Print</a>
)}
</div>
<br/>
<div>Link to share for internal agency review:</div>
Expand Down
4 changes: 2 additions & 2 deletions assets/client/src/components/challenge_tabs/Winners.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const Winners = ({challenge, challengePhases, print}) => {
if (phaseWinner.overview_image_path) {
return (
<img
src={imageBase + phaseWinner.overview_image_path}
src={`${imageBase}${encodeURIComponent(phaseWinner.overview_image_path)}`}
alt="Phase Winner image"
title="Phase Winner image"
className="phase-winner-image mt-3"
Expand All @@ -23,7 +23,7 @@ export const Winners = ({challenge, challengePhases, print}) => {
const {id, image_path, name, place_title} = winner
return (
<div key={id} className="d-flex flex-row align-items-center usa-tbm-1rem">
{image_path && <img src={imageBase + winner.image_path} alt="winner image" title="winner image" className="phase-winner-image me-3" />}
{image_path && (<img src={`${imageBase}${encodeURIComponent(winner.image_path)}`} alt="winner image" title="winner image" className="phase-winner-image me-3" />)}
{name && <p>{name}</p>}
{place_title && <p>{` - ${place_title}`}</p>}
</div>
Expand Down
Loading
Loading