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.7.3 Release PR #6431

Merged
merged 43 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
036167b
made the main page static and enabled scrolling in the filters component
mtalhabaig3 Jun 21, 2023
88441ea
Solved the height issue of filters menu
mtalhabaig3 Jun 22, 2023
b18a98e
Merge branch 'hotosm:develop' into feature/5844/menu/height
mtalhabaig3 Jun 22, 2023
fde0541
minor changes
mtalhabaig3 Jun 22, 2023
7625f96
added dependency array
mtalhabaig3 Jun 23, 2023
f211ea0
remove the css for hiding scroll bar
mtalhabaig3 Jun 28, 2023
a68367f
Merge branch 'hotosm:develop' into feature/5844/menu/height
mtalhabaig3 Jun 28, 2023
66073a6
Merge branch 'hotosm:develop' into feature/5844/menu/height
mtalhabaig3 Jul 10, 2023
41d270c
Made dropdowns fixed and hide scroll bar
mtalhabaig3 Jul 10, 2023
e2b332a
removed comments
mtalhabaig3 Jul 11, 2023
585d461
Merge branch 'hotosm:develop' into feature/5844/menu/height
mtalhabaig3 Jul 11, 2023
c120198
Merge branch 'hotosm:develop' into feature/5844/menu/height
mtalhabaig3 Aug 17, 2023
8611239
solved the front end test error
mtalhabaig3 Aug 17, 2023
5dc659c
removed comments
mtalhabaig3 Aug 23, 2023
0ff9686
Merge branch 'develop' of github.com:hotosm/tasking-manager into enha…
spnayan Apr 10, 2024
67eee80
Prevent api call before filter apply in `Explore Projects` page
spnayan Apr 10, 2024
85dd23a
Fix z-index issue between select dropdown and toggle button in more f…
spnayan Apr 15, 2024
2309994
Increase padding in more filters footer button in more filter
spnayan Apr 15, 2024
d6e009a
Change More Filter to popover layout in laptop screen
spnayan Apr 15, 2024
39744bb
Add overlay on More Filter popover
spnayan Apr 15, 2024
aa3aea4
Close More Filter popover on outside click
spnayan Apr 15, 2024
982528b
Fix test case for More Filters
spnayan Apr 16, 2024
c733d67
Prevent More Filter popover close on clearing selected filter
spnayan Apr 22, 2024
16e82bc
Fix project page not scrolling on More Filter popover
spnayan Apr 29, 2024
a8bce27
Fix More Filter popover position on page scroll
spnayan Apr 29, 2024
c10fa27
Fix More Filter popover overlay height
spnayan Apr 29, 2024
1a0a32c
Resolve merge conflicts
spnayan May 3, 2024
46bcb21
Validate empty project name while creating project
royallsilwallz May 1, 2024
df967cb
Validate symbols and number in first charater of project name
royallsilwallz May 1, 2024
532d84a
Validate empty project name while editing project
royallsilwallz May 6, 2024
ec2a3fc
Validate symbols and number in first charater of project name during …
royallsilwallz May 7, 2024
90805b8
Merge pull request #6325 from spnayan/enhancement/projects-more-filter
ramyaragupathy May 8, 2024
84eb1c9
Merge pull request #6376 from hotosm/fix/6373-project-name-input-vali…
ramyaragupathy May 8, 2024
b019377
Merge pull request #6422 from hotosm/main
ramyaragupathy May 13, 2024
793cdfd
Add ohsome token to backend infrastructure config
dakotabenjamin May 9, 2024
5812627
Add docs clarity around setting envvars in deployment
dakotabenjamin May 9, 2024
9b3fe34
Merge pull request #6421 from hotosm/fix/ohsome-envvar-infra
ramyaragupathy May 13, 2024
c125470
Fix mismatch value for language json file for Nederlands
royallsilwallz May 10, 2024
6e53dc6
Fix test case failure for `nl_NL` language
royallsilwallz May 10, 2024
0f4a545
Fix undefined issue when language toggle to Nederlands
royallsilwallz May 13, 2024
15f4ad9
Fix map page crash due to unsupported language error
royallsilwallz May 14, 2024
2b5767a
Merge pull request #6426 from hotosm/fix/6425-crash-when-language-swi…
ramyaragupathy May 14, 2024
00120fd
Merge pull request #6430 from hotosm/fix/6429-mapbox-language-not-sup…
ramyaragupathy May 14, 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 .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ Notes for the reviewer. How to test this change?
- ✅ Provide tests for your changes.
- 📝 Use descriptive commit messages.
- 📗 Update any related documentation and include any relevant screenshots.
- 🔠 Does this PR introduce or change any environment variables? If so, make sure to specify this change in the description.

## [optional] What gif best describes this PR or how it makes you feel?
2 changes: 1 addition & 1 deletion docs/sysadmins/ci-cd.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ We use CircleCI to manage Continuous Integration and Continuous Deployment.
| TeachOSM | deployment/teachosm-tasking-manager |
| Indonesia | deployment/id-tasking-manager |

Each environment has its own set of environment variables which are stored as secrets in the CircleCI Organization Settings under Contexts.
Each environment has its own set of environment variables which are stored as secrets in the CircleCI Organization Settings under Contexts. At the moment, these variables are for the frontend builds only. See the [deployment docs](deployment.md) for updating backend variables.

- OPSGENIE_API
- TM_APP_API_URL
Expand Down
4 changes: 2 additions & 2 deletions docs/sysadmins/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ aws s3 sync build/ <TaskingManagerReactBucket> --delete
When deploying updates to the infrastructure or code, follow the steps below.

#### Backup Database
Before updating it's always recommended to backup the database. You can make a snapshot in AWS RDS console, or run the database dump directly. Make sure you have set your security group to allow access to the database on your local machine.
Before updating it's always recommended to backup the database. You can make a snapshot in AWS RDS console, or run the database dump directly. You will need sufficient access to a server on the same VPC as the RDS instance in order to connect to it directly.

```
PGPASSWORD=<PostgresPassword> pg_dump -Fc \
Expand All @@ -48,7 +48,7 @@ PGPASSWORD=<PostgresPassword> pg_dump -Fc \

#### Update backend infrastructure

If the deployment contains any changes to the cloudformation template, then we must update the infrastructure prior to deployment. These changes are deliberately outside the CI/CD process to prevent accidental deletion of data.
If the deployment contains any changes to the cloudformation template, including new or changes to environment variables, then we must update the infrastructure prior to deployment. These changes are deliberately set outside the CI/CD process to prevent accidental deletion of data. For the HOT Tasking Manager, only staff with sufficient AWS privileges have the ability to perform these functions.

1. Pull the latest changes locally
2. Run the `cfn-config update` command, keeping in mind to update any new parameters that were added.
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 @@ -7,7 +7,7 @@ import { remapParamsToAPI } from '../utils/remapParamsToAPI';
import api from './apiClient';
import { UNDERPASS_URL } from '../config';

export const useProjectsQuery = (fullProjectsQuery, action) => {
export const useProjectsQuery = (fullProjectsQuery, action, queryOptions) => {
const token = useSelector((state) => state.auth.token);
const locale = useSelector((state) => state.preferences['locale']);

Expand Down Expand Up @@ -35,6 +35,7 @@ export const useProjectsQuery = (fullProjectsQuery, action) => {
queryKey: ['projects', fullProjectsQuery, action],
queryFn: ({ signal, queryKey }) => fetchProjects(signal, queryKey),
keepPreviousData: true,
...queryOptions,
});
};

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const Header = () => {
) : null;

return (
<header className="w-100 bb b--grey-light">
<header id="top-header" className="w-100 bb b--grey-light">
<UpdateDialog />
{checkUserEmail()}
{showOrgBar && (
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/projectCreate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ const ProjectCreate = () => {

const handleCreate = useCallback(
(cloneProjectData) => {
if (!metadata.projectName.trim()) {
setErr({ error: true, message: intl.formatMessage(messages.noProjectName) });
throw new Error('Missing project name.');
}
if (!/^[a-zA-Z]/.test(metadata.projectName)) {
setErr({ error: true, message: intl.formatMessage(messages.projectNameValidationError) });
throw new Error('Project name validation error.');
}
if (!metadata.geom) {
setErr({ error: true, message: intl.formatMessage(messages.noGeometry) });
throw new Error('Missing geom.');
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/components/projectCreate/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ export default defineMessages({
id: 'management.projects.create.errors.closed_linestring',
defaultMessage: 'Points do not form a closed linestring',
},
noProjectName: {
id: 'management.projects.create.errors.no_project_name',
defaultMessage: 'Name is a required field.',
},
projectNameValidationError: {
id: 'management.projects.create.errors.project_name_validation_error',
defaultMessage: 'Project name should start with an alphabet.',
},
noGeometry: {
id: 'management.projects.create.errors.no_geometry',
defaultMessage: "You need to define the project's area of interest.",
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/components/projectCreate/projectCreationMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import MapboxLanguage from '@mapbox/mapbox-gl-language';
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
import { useDropzone } from 'react-dropzone';

import { mapboxLayerDefn } from '../projects/projectsMap';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

import {
MAPBOX_TOKEN,
Expand All @@ -31,7 +33,7 @@ try {

const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, uploadFile }) => {
const mapRef = createRef();
const locale = useSelector((state) => state.preferences['locale']);
const mapboxSupportedLanguage = useMapboxSupportedLanguage();
const token = useSelector((state) => state.auth.token);
const [showProjectsAOILayer, setShowProjectsAOILayer] = useState(true);
const [aoiCanBeActivated, setAOICanBeActivated] = useState(false);
Expand Down Expand Up @@ -85,7 +87,7 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step,
attributionControl: false,
})
.addControl(new mapboxgl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' }))
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage }))
.addControl(new mapboxgl.ScaleControl({ unit: 'metric' }));
if (MAPBOX_TOKEN) {
map.addControl(
Expand All @@ -94,7 +96,7 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step,
mapboxgl: mapboxgl,
marker: false,
collapsed: true,
language: locale.substr(0, 2) || 'en',
language: mapboxSupportedLanguage,
}),
'top-right',
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/projectEdit/messages.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineMessages } from 'react-intl';

import projectCreateMessages from '../projectCreate/messages';

/**
* Internationalized messages for use on project edit.
*/
Expand Down Expand Up @@ -439,6 +441,7 @@ export default defineMessages({
id: 'projects.formInputs.name',
defaultMessage: 'Name of the project',
},
projectNameValidationError: { ...projectCreateMessages.projectNameValidationError },
dueDate: {
id: 'projects.formInputs.dueDate',
defaultMessage: 'Due date',
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/projectEdit/priorityAreasForm.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState, useContext, useLayoutEffect, createRef } from 'react';
import { useSelector } from 'react-redux';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
Expand All @@ -25,6 +24,7 @@ import {
import { getErrorMsg } from '../projectCreate/fileUploadErrors';
import { Alert } from '../alert';
import WebglUnsupported from '../webglUnsupported';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

mapboxgl.accessToken = MAPBOX_TOKEN;
try {
Expand All @@ -35,7 +35,7 @@ try {

export const PriorityAreasForm = () => {
const { projectInfo, setProjectInfo } = useContext(StateContext);
const locale = useSelector((state) => state.preferences['locale']);
const mapboxSupportedLanguage = useMapboxSupportedLanguage();
const mapRef = createRef();
const [error, setError] = useState({ error: false, message: null });

Expand Down Expand Up @@ -129,7 +129,7 @@ export const PriorityAreasForm = () => {
attributionControl: false,
})
.addControl(new mapboxgl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' }))
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage }))
.addControl(new mapboxgl.NavigationControl());

setMapObj({ ...mapObj, map: map });
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/projects/moreFiltersForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const MoreFiltersForm = (props) => {
/>
</fieldset>
)}
<div className="tr w-100 mt3">
<div className="tr w-100 mt3 pb3 ph2">
<Link to="/explore">
<Button className="bg-white blue-dark mr1 f6 pv2">
<FormattedMessage {...messages.clear} />
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/projects/projectNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const ProjectNav = (props) => {
// onSelectedItemChange={(changes) => console.log(changes)}
return (
/* mb1 mb2-ns (removed for map, but now small gap for more-filters) */
<header className="bt bb b--tan w-100 ">
<header id="explore-nav" className="bt bb b--tan w-100 ">
<div className="mt2 mb1 ph3 dib lh-copy w-100 cf">
<div className="w-80-l w-90-m w-100 fl dib">
<div className="dib">
Expand All @@ -125,6 +125,7 @@ export const ProjectNav = (props) => {
<ProjectsActionFilter setQuery={setQuery} fullProjectsQuery={fullProjectsQuery} />
<Link
to={filterRouteToggled}
id="more-filter-id"
className={`dn mr3 dib-l lh-title f6 ${linkCombo} ${moreFiltersCurrentActiveStyle} blue-dark`}
>
<FormattedMessage {...messages.moreFilters} />
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/projects/projectsMap.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { createRef, useLayoutEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import MapboxLanguage from '@mapbox/mapbox-gl-language';

import WebglUnsupported from '../webglUnsupported';
import { MAPBOX_TOKEN, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config';
import mapMarker from '../../assets/img/mapMarker.png';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

let markerIcon = new Image(17, 20);
markerIcon.src = mapMarker;
Expand Down Expand Up @@ -97,8 +97,8 @@ export const mapboxLayerDefn = (map, mapResults, clickOnProjectID, disablePoiCli

export const ProjectsMap = ({ mapResults, fullProjectsQuery, setQuery, className }) => {
const mapRef = createRef();
const locale = useSelector((state) => state.preferences['locale']);
const [map, setMapObj] = useState(null);
const mapboxSupportedLanguage = useMapboxSupportedLanguage();

const clickOnProjectID = useCallback(
(projectIdSearch) =>
Expand Down Expand Up @@ -131,7 +131,7 @@ export const ProjectsMap = ({ mapResults, fullProjectsQuery, setQuery, className
attributionControl: false,
})
.addControl(new mapboxgl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })),
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })),
);

return () => {
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/taskSelection/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import messages from './messages';
import { MAPBOX_TOKEN, TASK_COLOURS, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config';
import lock from '../../assets/img/lock.png';
import redlock from '../../assets/img/red-lock.png';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

let lockIcon = new Image(17, 20);
lockIcon.src = lock;
Expand Down Expand Up @@ -42,7 +43,7 @@ export const TasksMap = ({
}) => {
const intl = useIntl();
const mapRef = createRef();
const locale = useSelector((state) => state.preferences['locale']);
const mapboxSupportedLanguage = useMapboxSupportedLanguage();
const authDetails = useSelector((state) => state.auth.userDetails);
const [hoveredTaskId, setHoveredTaskId] = useState(null);

Expand All @@ -62,7 +63,7 @@ export const TasksMap = ({
attributionControl: false,
})
.addControl(new mapboxgl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })),
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })),
);

return () => {
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/userDetail/countriesMapped.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { createRef, useLayoutEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import mapboxgl from 'mapbox-gl';
import MapboxLanguage from '@mapbox/mapbox-gl-language';
Expand All @@ -10,6 +9,7 @@ import { MAPBOX_TOKEN, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config';
import { mapboxLayerDefn } from '../projects/projectsMap';
import { BarListChart } from './barListChart';
import WebglUnsupported from '../webglUnsupported';
import useMapboxSupportedLanguage from '../../hooks/UseMapboxSupportedLanguage';

mapboxgl.accessToken = MAPBOX_TOKEN;
try {
Expand All @@ -20,7 +20,7 @@ try {

const UserCountriesMap = ({ projects }) => {
const navigate = useNavigate();
const locale = useSelector((state) => state.preferences['locale']);
const mapboxSupportedLanguage = useMapboxSupportedLanguage();

const [map, setMap] = useState(null);
const mapRef = createRef();
Expand All @@ -36,7 +36,7 @@ const UserCountriesMap = ({ projects }) => {
attributionControl: false,
})
.addControl(new mapboxgl.AttributionControl({ compact: false }))
.addControl(new MapboxLanguage({ defaultLanguage: locale.substr(0, 2) || 'en' })),
.addControl(new MapboxLanguage({ defaultLanguage: mapboxSupportedLanguage })),
);

return () => {
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/hooks/UseMapboxSupportedLanguage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useSelector } from 'react-redux';
import MapboxLanguage from '@mapbox/mapbox-gl-language';

const { supportedLanguages } = new MapboxLanguage();

const defaultLocale = 'en';

/**
* A React custom hook to check if the locale language is supported by Mapbox GL or not
*
* Returns `en` if the locale is not supported, else returns preferred locale
*
*/
export default function useMapboxSupportedLanguage() {
const locale = useSelector((state) => state.preferences.locale);

if (!locale) return defaultLocale;

const language = locale.substr(0, 2);
if (supportedLanguages.includes(language)) return language;

return defaultLocale;
}
7 changes: 4 additions & 3 deletions frontend/src/utils/countries.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getCountries, getCountry, getSupportedLangs } from '@hotosm/iso-countri

export function translateCountry(name, locale) {
const code = getCountryCode(name);
if (code && isLangSupported(locale)) return getCountry(locale.split('-')[0], code);
if (code && isLangSupported(locale)) return getCountry(locale.split(/[-_]/)[0], code);
return name;
}

Expand All @@ -20,13 +20,14 @@ export function getCountryCode(name) {
}

export function isLangSupported(code) {
if (getSupportedLangs().includes(code.split('-')[0])) return true;
// split with `-` or `_` to get the language initials
if (getSupportedLangs().includes(code.split(/[-_]/)[0])) return true;
return false;
}

export function formatCountryList(locale) {
if (locale && isLangSupported(locale)) {
const countries = getCountries(locale.split('-')[0]);
const countries = getCountries(locale.split(/[-_]/)[0]);
return Object.keys(countries).map((key) => ({ label: countries[key], value: key }));
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/utils/internationalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const supportedLocales = [
{ value: 'ko', label: '한국어' },
// { value: 'mg', label: 'Malagasy' },
// { value: 'ml', label: 'Malayalam' },
{ value: 'nl', label: 'Nederlands' },
{ value: 'nl_NL', label: 'Nederlands' },
{ value: 'pt', label: 'Português' },
{ value: 'pt-BR', label: 'Português (Brasil)' },
// { value: 'ru', label: 'Русский язык' },
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/utils/tests/internationalization.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('getSupportedLocale', () => {
it('returns a generic supported locale if the variation is not supported', () => {
expect(getSupportedLocale('en-gb')).toEqual({ label: 'English', value: 'en' });
expect(getSupportedLocale('es-AR')).toEqual({ label: 'Español', value: 'es' });
expect(getSupportedLocale('nl-NL')).toEqual({ label: 'Nederlands', value: 'nl' });
expect(getSupportedLocale('nl_NL')).toEqual({ label: 'Nederlands', value: 'nl_NL' });
});
it('returns the default locale if the code is not supported and does not have a variation', () => {
expect(getSupportedLocale('xt')).toEqual({ label: 'English', value: 'en' });
Expand Down
Loading
Loading