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

v4.8.3 staging setup #6656

Merged
merged 27 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9d8d269
Remove `Map Swipe` tab if MapSwipe group ID not present
royallsilwallz Oct 17, 2024
1f1187d
Add MapSwipe group name to overview section in MapSwipe stats
royallsilwallz Oct 17, 2024
fa87273
Change `ds` to `days` in MapSwipe Stats page
royallsilwallz Oct 17, 2024
631d1b1
Fix content overflowing responsive issue in MapSwipe Stats page
royallsilwallz Oct 21, 2024
9813a67
Use `/stats` route instead of `/stats/leaderboard` for Partner Stats
royallsilwallz Oct 21, 2024
6e1d752
Move the stats info footer to the top of the stats cards
royallsilwallz Oct 22, 2024
2aae1cb
Change stats info design in homepage, project & feature stats page
royallsilwallz Oct 24, 2024
cd34616
Change cards layout in large screen size in Manage Stats
royallsilwallz Oct 25, 2024
60bd532
typo fixed
cquest Oct 26, 2024
f2ab8ad
Merge pull request #6607 from cquest/develop
ramyaragupathy Nov 5, 2024
571f76d
Create different route paths for `Instructions` & `Contributions`
royallsilwallz Sep 23, 2024
ca077ff
Add button to navigate to `Instructions` page from `Project Detail` page
royallsilwallz Sep 23, 2024
e372d2d
Show Project Detail Map instead of Task Map when not logged in
royallsilwallz Oct 8, 2024
8b7da1b
Change `View Instructions` button to link
royallsilwallz Oct 8, 2024
ef51caa
Show only `Instructions` tab when not logged in
royallsilwallz Oct 8, 2024
5c4ef1b
Navigate to login when `Map a Task` button is clicked without login
royallsilwallz Oct 8, 2024
69e4e8e
Navigate to login on route is not public
royallsilwallz Oct 8, 2024
cebb6ed
Redirect back to `Instructions` page after login from `Map a Task`
royallsilwallz Oct 8, 2024
e5f8083
Show Permission Error when trying to access Private Project Instructions
royallsilwallz Oct 8, 2024
a71a404
Fix search tasks functionality not working issue
royallsilwallz Nov 11, 2024
26ef91e
Fix test cases failure for Task page
royallsilwallz Nov 11, 2024
b2a90c5
Redirect to Tasks & Instructions page only when user clicks Contribute
royallsilwallz Nov 12, 2024
cb58a09
Add `from` state to MemoryRouter in Tasks page test cases
royallsilwallz Nov 12, 2024
ac37153
Merge pull request #6592 from hotosm/feature/6302-view-task-instructions
ramyaragupathy Nov 13, 2024
1f35f84
Merge pull request #6601 from hotosm/enhancement/6599-partners-mapswi…
ramyaragupathy Nov 13, 2024
b95e861
Add PYTHONPATH and bind mount for migrations
prabinoid Nov 22, 2024
505acfa
Merge pull request #6645 from hotosm/build/bind-mounts
dakotabenjamin Nov 25, 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
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONFAULTHANDLER=1 \
PATH="/home/appuser/.local/bin:$PATH" \
PYTHONPATH="/usr/src/app:$PYTHONPATH" \
PYTHON_LIB="/home/appuser/.local/lib/python$PYTHON_IMG_TAG/site-packages" \
SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ services:
- ./pyproject.toml:/usr/src/app/pyproject.toml:ro
- ./backend:/usr/src/app/backend:ro
- ./tests:/usr/src/app/tests:ro
- ./migrations:/src/migrations
restart: unless-stopped
healthcheck:
test: curl --fail http://localhost:5000 || exit 1
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const useProjectsQuery = (fullProjectsQuery, action, queryOptions) => {
});
};

export const useProjectQuery = (projectId) => {
export const useProjectQuery = (projectId, otherOptions) => {
const token = useSelector((state) => state.auth.token);
const locale = useSelector((state) => state.preferences['locale']);
const fetchProject = ({ signal }) => {
Expand All @@ -51,6 +51,7 @@ export const useProjectQuery = (projectId) => {
return useQuery({
queryKey: ['project', projectId],
queryFn: fetchProject,
...otherOptions,
});
};
export const useProjectSummaryQuery = (projectId, otherOptions = {}) => {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/footer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export function Footer() {

const footerDisabledPaths = [
'projects/:id/tasks',
'projects/:id/instructions',
'projects/:id/contributions',
'projects/:id/map',
'projects/:id/validate',
'projects/:id/live',
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/components/homepage/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import shortNumber from 'short-number';

import messages from './messages';
import { useOsmStatsQuery, useSystemStatisticsQuery } from '../../api/stats';
import StatsInfoFooter from '../statsInfoFooter';

export const StatsNumber = (props) => {
const value = shortNumber(props.value);
Expand Down Expand Up @@ -38,8 +39,10 @@ export const StatsSection = () => {
const hasStatsLoaded = hasTmStatsLoaded && hasOsmStatsLoaded;

return (
<>
<div className="pt5 pb2 ph6-l ph4 flex justify-around flex-wrap flex-nowrap-ns stats-container">
<div className="pt5 pb2 ph6-l ph4 ">
<StatsInfoFooter className="mb4" />

<div className="flex justify-around flex-wrap flex-nowrap-ns stats-container">
<StatsColumn
label={messages.buildingsStats}
value={hasStatsLoaded ? osmStatsData?.buildings : undefined}
Expand All @@ -61,6 +64,6 @@ export const StatsSection = () => {
value={hasStatsLoaded ? tmStatsData.data.mappersOnline : undefined}
/>
</div>
</>
</div>
);
};
7 changes: 5 additions & 2 deletions frontend/src/components/partnerMapswipeStats/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const formatSecondsToTwoUnits = (seconds, shortFormat = false) => {
years: 'yrs',
months: 'mos',
weeks: 'wks',
days: 'ds',
days: 'days',
hours: 'hrs',
minutes: 'mins',
seconds: 'secs',
Expand Down Expand Up @@ -82,8 +82,11 @@ export const Overview = () => {
customPlaceholder={<OverviewPlaceholder />}
ready={!isLoading && !isRefetching}
>
<h3 class="f2 blue-dark fw7 ma0 barlow-condensed v-mid dib mb3">
{data?.nameInsideProvider}
</h3>
<div
className="flex justify-between items-stretch flex-wrap flex-nowrap-ns"
className="flex justify-between items-stretch flex-wrap flex-nowrap-l"
style={{ gap: '1.6rem' }}
>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const ProjectTypeAreaStats = ({

return (
<div
className="flex justify-between items-center flex-wrap flex-nowrap-ns"
className="flex justify-between items-center flex-wrap flex-nowrap-l"
style={{ gap: '1.6rem' }}
>
<div className="pa4 flex items-center bg-white shadow-6 w-100" style={{ gap: '1.75rem' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,10 @@ export const SwipesByOrganization = ({ contributionsByOrganization = [] }) => {
}, []);

return (
<div style={{ width: '48.5%' }}>
<div className="mapswipe-stats-piechart">
<h3 className="f2 fw6 ttu barlow-condensed blue-dark mt0 pt2 mb4">
<FormattedMessage {...messages.swipesByOrganization} />
</h3>

<div className="bg-white pa4 shadow-6 relative" style={{ height: '450px' }}>
<canvas ref={chartRef}></canvas>
{contributionsByOrganization.length === 0 && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const SwipesByProjectType = ({ contributionsByProjectType = [] }) => {
}, []);

return (
<div style={{ width: '48.5%' }}>
<div className="mapswipe-stats-piechart">
<h3 className="f2 fw6 ttu barlow-condensed blue-dark mt0 pt2 mb4">
<FormattedMessage {...messages.swipesByProjectType} />
</h3>
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/partners/leaderboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import messages from '../../views/messages';
import { StatsSection } from './partnersStats';
import { Activity } from './partnersActivity';
import { CurrentProjects } from './currentProjects';
import StatsInfoFooter from '../statsInfoFooter';

export const Leaderboard = ({ partner, partnerStats }) => {
return (
<div className="pa4 bg-tan flex flex-column gap-1.25">
<StatsInfoFooter className="mv3" />

<div className="flex justify-between items-center">
<h3 className="f2 blue-dark fw7 ma0 barlow-condensed v-mid dib">
{partner.primary_hashtag
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/partners/partners.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export function PartnersCard({ details }) {
<FormattedMessage {...messages.edit} />
</CustomButton>
</Link>
<Link to={`/partners/${details.permalink}/stats/leaderboard`}>
<Link to={`/partners/${details.permalink}/stats`}>
<CustomButton
style={{ backgroundColor: '#e2e2e2' }}
className="blue-dark ba b--grey-light pa2 br1 f5 pointer"
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/components/partners/partnersStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import shortNumber from 'short-number';
import messages from './messages';
import { StatsCard } from '../statsCard';
import { MappingIcon, EditIcon, RoadIcon, HomeIcon } from '../svgIcons';
import StatsInfoFooter from '../statsInfoFooter';

const iconClass = 'h-50 w-50';
const iconStyle = { height: '45px' };
Expand Down Expand Up @@ -71,7 +70,6 @@ export const StatsSection = ({ partner }) => {
className={'w-25-l w-50-m w-100 mv1'}
/>
</div>
<StatsInfoFooter />
</div>
);
};
10 changes: 8 additions & 2 deletions frontend/src/components/projectDetail/footer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useRef, Fragment } from 'react';
import { Link } from 'react-router-dom';
import { Link, useLocation } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { FormattedMessage } from 'react-intl';

Expand Down Expand Up @@ -58,6 +58,7 @@ const menuItems = [
export const ProjectDetailFooter = ({ className, projectId }) => {
const userIsloggedIn = useSelector((state) => state.auth.token);
const menuItemsContainerRef = useRef(null);
const { pathname } = useLocation();

return (
<div
Expand Down Expand Up @@ -92,7 +93,12 @@ export const ProjectDetailFooter = ({ className, projectId }) => {
<div className="flex items-center ml-auto gap-1">
<ShareButton projectId={projectId} />
{userIsloggedIn && <AddToFavorites projectId={projectId} />}
<Link to={`./tasks`} className="">
<Link
to={`./tasks`}
// add previous path to history location to track
// if the user is from project detail page
state={{ from: pathname }}
>
<Button className="white bg-red h3 w5">
<FormattedMessage {...messages.contribute} />
</Button>
Expand Down
19 changes: 16 additions & 3 deletions frontend/src/components/projectDetail/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { lazy, Suspense, useState } from 'react';
import { Link } from 'react-router-dom';
import { lazy, Suspense, useState, useEffect } from 'react';
import { Link, useParams } from 'react-router-dom';
import ReactPlaceholder from 'react-placeholder';
import centroid from '@turf/centroid';
import { FormattedMessage } from 'react-intl';
Expand Down Expand Up @@ -35,9 +35,14 @@ import { ENABLE_EXPORT_TOOL } from '../../config/index.js';
/* lazy imports must be last import */
const ProjectTimeline = lazy(() => import('./timeline' /* webpackChunkName: "timeline" */));

const ProjectDetailMap = (props) => {
export const ProjectDetailMap = (props) => {
const [taskBordersOnly, setTaskBordersOnly] = useState(true);

useEffect(() => {
if (typeof props.taskBordersOnly !== 'boolean') return;
setTaskBordersOnly(props.taskBordersOnly);
}, [props.taskBordersOnly]);

const taskBordersGeoJSON = props.project.areaOfInterest && {
type: 'FeatureCollection',
features: [
Expand Down Expand Up @@ -139,6 +144,7 @@ export const ProjectDetailLeft = ({ project, contributors, className, type }) =>
export const ProjectDetail = (props) => {
useSetProjectPageTitleTag(props.project);
const size = useWindowSize();
const { id: projectId } = useParams();
const { data: contributors, status: contributorsStatus } = useProjectContributionsQuery(
props.project.projectId,
);
Expand Down Expand Up @@ -181,6 +187,12 @@ export const ProjectDetail = (props) => {
className="ph4 w-60-l w-80-m w-100 lh-title markdown-content blue-dark-abbey"
dangerouslySetInnerHTML={htmlDescription}
/>
<a
href={`/projects/${projectId}/instructions`}
className="ph4 ttu db f5 blue-dark fw6 project-instructions-link"
>
<FormattedMessage {...messages.viewProjectSpecificInstructions} />
</a>
<a href="#coordination" style={{ visibility: 'hidden' }} name="coordination">
<FormattedMessage {...messages.coordination} />
</a>
Expand Down Expand Up @@ -435,6 +447,7 @@ ProjectDetailMap.propTypes = {
type: PropTypes.string,
tasksError: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
projectLoading: PropTypes.bool,
taskBordersOnly: PropTypes.bool,
};

ProjectDetailLeft.propTypes = {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/components/projectDetail/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,8 @@ export default defineMessages({
id: 'project.noSimilarProjectsFound',
defaultMessage: 'Could not find any similar projects for this project',
},
viewProjectSpecificInstructions: {
id: 'project.viewProjectSpecificInstructions',
defaultMessage: 'View project specific instructions',
},
});
4 changes: 4 additions & 0 deletions frontend/src/components/projectDetail/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@
.react-tooltip#dueDateBoxTooltip {
z-index: 999;
}

.project-instructions-link {
letter-spacing: -0.0857513px;
}
50 changes: 26 additions & 24 deletions frontend/src/components/projectStats/edits.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import projectMessages from './messages';
import userDetailMessages from '../userDetail/messages';
import { MappingIcon, HomeIcon, RoadIcon, EditIcon } from '../svgIcons';
import { StatsCard } from '../statsCard';
import StatsTimestamp from '../statsTimestamp';
import StatsInfoFooter from '../statsInfoFooter';

export const EditsStats = ({ data }) => {
const { changesets, buildings, roads, edits } = data;
Expand All @@ -18,30 +18,32 @@ export const EditsStats = ({ data }) => {
<h3 className="barlow-condensed ttu f3">
<FormattedMessage {...projectMessages.edits} />
</h3>
<StatsTimestamp messageType="project" />
</div>
<div className="db pb2 project-edit-stats">
<StatsCard
field={'changesets'}
icon={<MappingIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...projectMessages.changesets} />}
value={changesets || 0}
/>
<StatsCard
icon={<EditIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...projectMessages.totalEdits} />}
value={edits || 0}
/>
<StatsCard
icon={<HomeIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...userDetailMessages.buildingsMapped} />}
value={buildings || 0}
/>
<StatsCard
icon={<RoadIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...userDetailMessages.roadMapped} />}
value={roads || 0}
/>
<div>
<StatsInfoFooter className="mb4" />
<div className="db pb2 project-edit-stats">
<StatsCard
field={'changesets'}
icon={<MappingIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...projectMessages.changesets} />}
value={changesets || 0}
/>
<StatsCard
icon={<EditIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...projectMessages.totalEdits} />}
value={edits || 0}
/>
<StatsCard
icon={<HomeIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...userDetailMessages.buildingsMapped} />}
value={buildings || 0}
/>
<StatsCard
icon={<RoadIcon className={iconClass} style={iconStyle} />}
description={<FormattedMessage {...userDetailMessages.roadMapped} />}
value={roads || 0}
/>
</div>
</div>
</div>
);
Expand Down
40 changes: 25 additions & 15 deletions frontend/src/components/statsInfoFooter/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,37 @@ import { useIntl } from 'react-intl';

import { useOsmStatsMetadataQuery } from '../../api/stats';
import { dateOptions } from '../statsTimestamp';
import { InfoIcon } from '../svgIcons';
import '../../views/partnersMapswipeStats.scss';

export default function StatsInfoFooter() {
export default function StatsInfoFooter({ className }) {
const intl = useIntl();

const { data: osmStatsMetadata } = useOsmStatsMetadataQuery();

return (
<div className="cf w-100 relative tr pt3">
<span className="ma0 f7 fw4 blue-grey mb1 i">
These statistics come from{' '}
<a
className="blue-grey fw7"
href="https://stats.now.ohsome.org/about"
target="_blank"
rel="noreferrer"
>
ohsomeNow Stats
</a>{' '}
and were last updated at{' '}
<strong>{intl.formatDate(osmStatsMetadata?.max_timestamp, dateOptions)}</strong> (
{intl.timeZone}).
<div
className={`pr3 pv2 pl0 relative inline-flex mapswipe-stats-info-banner
blue-dark ${className}`}
>
<span className="inline-flex items-center ">
<InfoIcon className="mr2" style={{ height: '20px' }} />
<span>
These statistics come from{' '}
<a
className="blue-grey"
href="https://stats.now.ohsome.org/about"
target="_blank"
rel="noreferrer"
>
ohsomeNow Stats
</a>{' '}
and were last updated at{' '}
<span className="fw5 stats-info-datetime">
{intl.formatDate(osmStatsMetadata?.max_timestamp, dateOptions)}
</span>{' '}
({intl.timeZone})
</span>
</span>
</div>
);
Expand Down
Loading
Loading