Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:hotosm/tasking-manager into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
royallsilwallz committed Nov 29, 2023
2 parents 5475b68 + 3e43f21 commit 3420409
Show file tree
Hide file tree
Showing 17 changed files with 84 additions and 52 deletions.
53 changes: 32 additions & 21 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
version: 2.1

orbs:
aws-cli: circleci/[email protected]
aws-cli: circleci/[email protected]
aws-ecs: circleci/[email protected]
opsgenie: opsgenie/[email protected]


jobs:
frontend-code-test:
resource_class: large
Expand Down Expand Up @@ -68,7 +70,7 @@ jobs:
TM_ORG_CODE: "CICode"
TM_ORG_NAME: "CircleCI Test Organisation"

- image: cimg/postgres:14.2-postgis
- image: cimg/postgres:14.9-postgis
environment:
POSTGRES_USER: taskingmanager
POSTGRES_DB: test_tm
Expand All @@ -79,12 +81,6 @@ jobs:
- run: sudo apt-get update
- run: sudo apt-get -y install libgeos-dev # Required for shapely
- run: sudo apt-get -y install proj-bin libproj-dev
- run:
name: Configure Postgresql Test database
command: |
psql \
-d $SQLALCHEMY_DATABASE_URI \
-c "CREATE EXTENSION postgis;"
- run: pip install --upgrade pip pdm
- run: pdm config --global python.use_venv False
- run: pdm export --dev --without-hashes > requirements.txt
Expand Down Expand Up @@ -113,13 +109,13 @@ jobs:
description: "Cloudformation stack name"
type: string
docker:
- image: cimg/postgres:15.1-postgis
- image: cimg/postgres:15.4-postgis
steps:
- aws-cli/setup:
role-arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile-name: "OIDC-Profile"
role-session-name: "database-snapshot"
session-duration: "2700"
role_arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile_name: "OIDC-Profile"
role_session_name: "database-snapshot"
session_duration: "2700"
- run:
name: Find the instance ID of the database in the stack to backup
command: |
Expand Down Expand Up @@ -193,10 +189,10 @@ jobs:
steps:
- checkout
- aws-cli/setup:
role-arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile-name: "OIDC-Profile"
role-session-name: "backend-deploy"
session-duration: "2700"
role_arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile_name: "OIDC-Profile"
role_session_name: "backend-deploy"
session_duration: "2700"
- run: sudo apt-get update
- run: sudo apt-get -y install libgeos-dev jq
- run: sudo yarn global add @mapbox/cfn-config @mapbox/cloudfriend
Expand All @@ -222,6 +218,21 @@ jobs:
export JSON_CONFIG="$(< $CIRCLE_WORKING_DIRECTORY/cfn-config-<< parameters.stack_name >>.json)"
cfn-config update << parameters.stack_name >> $CIRCLE_WORKING_DIRECTORY/scripts/aws/cloudformation/tasking-manager.template.js -f -c hot-cfn-config -t hot-cfn-config -r $AWS_REGION -p "$JSON_CONFIG"
backend_deploy_containers:
working_directory: /home/circleci/tasking-manager
docker:
- image: cimg/python:3.10.7
steps:
- checkout
- aws-cli/setup:
role_arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile_name: "OIDC-Profile"
role_session_name: "backend-deploy-containers"
session_duration: "2700"
- run: sudo apt-get update
- run: sudo apt-get -y install curl
- run: echo "Run AWS Fargate"

frontend_deploy:
working_directory: /home/circleci/tasking-manager
resource_class: large
Expand All @@ -234,10 +245,10 @@ jobs:
steps:
- checkout
- aws-cli/setup:
role-arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile-name: "OIDC-Profile"
role-session-name: "frontend-deploy"
session-duration: "1800"
role_arn: "arn:aws:iam::$ORG_AWS_ACCOUNT_ID:role/CircleCI-OIDC-Connect"
profile_name: "OIDC-Profile"
role_session_name: "frontend-deploy"
session_duration: "1800"
- run:
name: Deploy Frontend to S3
command: |
Expand Down
8 changes: 4 additions & 4 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"Component: Frontend":
"codebase: frontend":
- frontend/**/*
"Component: Backend":
"codebase: backend":
- backend/**/*
- tests/**/*
- migrations/**/*
- ./manage.py
- ./pyproject.toml
"Component: Infrastructure":
"infrastructure":
- .circleci/*
- .github/**/*
- scripts/aws/**/*
Expand All @@ -20,5 +20,5 @@
- frontend/yarn.lock
"python":
- ./pyproject.toml
"Type: Translations":
"type: translations":
- frontend/src/locales/*
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ This is Free and Open Source Software. You are welcome to use the code and set u
* Read the monthly update blogs on [OSM Discourse](https://community.openstreetmap.org/c/general/38/all).

## Product Roadmap
We have included below a high level roadmap/plan [subject to change] that can be used as an overview.
![image](https://user-images.githubusercontent.com/98902727/218763601-f08e3879-51f3-40a7-ae6e-bdf96f8a5979.png)

We have included below a [high level roadmap/plan](https://github.com/orgs/hotosm/projects/28/) [subject to change] that can be used as an overview.


## Developers
Expand Down
3 changes: 1 addition & 2 deletions backend/api/teams/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ def delete(self, team_id):
"SubCode": "UserNotTeamManager",
}, 401

TeamService.delete_team(team_id)
return {"Success": "Team deleted"}, 200
return TeamService.delete_team(team_id)


class TeamsAllAPI(Resource):
Expand Down
2 changes: 1 addition & 1 deletion backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class EnvironmentConfig:
"""
import json

_params = json.loads(os.getenv("OAUTH2_APP_CREDENTIALS"), None)
_params = json.loads(os.getenv("OAUTH2_APP_CREDENTIALS", None))
OAUTH_CLIENT_ID = _params.get("CLIENT_ID", None)
OAUTH_CLIENT_SECRET = _params.get("CLIENT_SECRET", None)
OAUTH_REDIRECT_URI = _params.get("REDIRECT_URI", None)
Expand Down
6 changes: 5 additions & 1 deletion backend/services/team_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,12 @@ def delete_team(team_id: int):

if team.can_be_deleted():
team.delete()
return {"Success": "Team deleted"}, 200
else:
raise TeamServiceError("Team has projects, cannot be deleted")
return {
"Error": "Team has projects, cannot be deleted",
"SubCode": "This team has projects associated. Before deleting team, unlink any associated projects.",
}, 400

@staticmethod
def check_team_membership(project_id: int, allowed_roles: list, user_id: int):
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/api/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ export const useProjectsQuery = (fullProjectsQuery, action) => {
};

export const useProjectQuery = (projectId) => {
const token = useSelector((state) => state.auth.token);
const locale = useSelector((state) => state.preferences['locale']);
const fetchProject = ({ signal }) => {
return api().get(`projects/${projectId}/`, {
return api(token, locale).get(`projects/${projectId}/`, {
signal,
});
};
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/assets/styles/_extra.scss
Original file line number Diff line number Diff line change
Expand Up @@ -616,3 +616,8 @@ a[href="https://www.mapbox.com/map-feedback/"]
.link:focus {
outline: revert;
}

// Override tachyons font-family for code tag
.code {
font-family: inherit;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export const PostProjectComment = ({ projectId, refetchComments, contributors })
isShowUserPicture
isShowFooter
isShowTabNavs
contributors={contributors?.userContributions?.map((user) => user.username)}
contributors={
Array.isArray(contributors) ? contributors.map((user) => user.username) : undefined
}
/>
</div>

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/projects/projectCardPaginator.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const ProjectCardPaginator = ({ status, pagination, fullProjectsQuery, se
);
};

if (!apiIsFetched) {
// do not show pagination when the data is being fetched or it has zero results
if (!apiIsFetched || !pagination?.total) {
return null;
}
const activePage = (apiIsFetched && pagination?.page) || 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('ProjectCardPaginator Component', () => {
hasPrev: false,
page: 1,
pages: 3,
total: 10,
}}
/>,
);
Expand All @@ -32,6 +33,7 @@ describe('ProjectCardPaginator Component', () => {
hasPrev: false,
page: 1,
pages: 3,
total: 10,
}}
/>,
);
Expand Down
18 changes: 7 additions & 11 deletions frontend/src/components/taskSelection/actionSidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ export function CompletionTabForMapping({
)}
{showReadCommentsAlert && (
<div
className="tc pa2 mb1 bg-grey-light blue-dark pointer"
role="button"
className="tc pa2 mb1 bg-grey-light blue-dark pointer"
onClick={() => historyTabSwitch()}
onKeyDown={() => {}}
>
<InfoIcon className="v-mid h1 w1" />
<span className="ml2 fw1 pa1">
Expand Down Expand Up @@ -586,19 +587,12 @@ const TaskValidationSelector = ({
// the contributors is filled only on the case of single task validation,
// so we need to fetch the task history in the case of multiple task validation
useEffect(() => {
if (showCommentInput && isValidatingMultipleTasks && !contributors.length) {
if (showCommentInput && isValidatingMultipleTasks) {
fetchLocalJSONAPI(`projects/${projectId}/tasks/${id}/`).then((response) =>
setContributorsList(getTaskContributors(response.taskHistory, userDetails.username)),
);
}
}, [
isValidatingMultipleTasks,
showCommentInput,
contributors,
id,
projectId,
userDetails.username,
]);
}, [isValidatingMultipleTasks, showCommentInput, id, projectId, userDetails.username]);

return (
<div className="cf w-100 db pt1 pv2 blue-dark">
Expand Down Expand Up @@ -650,7 +644,7 @@ const TaskValidationSelector = ({
<CommentInputField
comment={comment}
setComment={setComment}
contributors={contributors.length ? contributors : contributorsList}
contributors={isValidatingMultipleTasks ? contributorsList : contributors}
enableHashtagPaste
enableContributorsHashtag
isShowTabNavs
Expand Down Expand Up @@ -713,6 +707,7 @@ function CompletionInstructions({ setVisibility }: Object) {
<span
className="br-100 bg-grey-light white h1 w1 fr pointer tc v-mid di"
onClick={() => setVisibility(false)}
onKeyDown={() => {}}
>
<CloseIcon className="pv1" aria-label="hide instructions" />
</span>
Expand Down Expand Up @@ -834,6 +829,7 @@ function TaskSpecificInstructions({ instructions, open = true }: Object) {
className="ttu blue-grey mt1 mb0 pointer"
role="button"
onClick={() => setIsOpen(!isOpen)}
onKeyDown={() => {}}
>
{isOpen ? (
<ChevronDownIcon style={{ height: '14px' }} className="pr1 pb1 v-mid" />
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/views/contributions.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ export const ContributionsPage = () => {
<section className="pb5 pt180 pull-center">
<MyTasksNav />
<TaskResults retryFn={forceUpdate} state={state} />
<ProjectCardPaginator projectAPIstate={state} setQueryParam={setContributionsQuery} />
<ProjectCardPaginator
projectAPIstate={state}
status={state.isLoading ? 'pending' : 'success'}
pagination={state?.pagination}
setQueryParam={setContributionsQuery}
/>
</section>
);
};
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function Settings() {
</div>
<div className="fl w-100 w-40-l pb3 pl3-l">
<PersonalInformationForm />
<OSMCard username={userDetails.username} />
{userDetails?.username && <OSMCard username={userDetails.username} />}
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/teams.js
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ export function TeamDetail() {
const [error, loading, team] = useFetch(`teams/${id}/`);
// eslint-disable-next-line
const [projectsError, projectsLoading, projects] = useFetch(
`projects/?teamId=${id}&omitMapResults=true`,
`projects/?teamId=${id}&omitMapResults=true&projectStatuses=PUBLISHED,DRAFT,ARCHIVED`,
id,
);
const [isMember, setIsMember] = useState(false);
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/views/userDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { CountriesMapped } from '../components/userDetail/countriesMapped';
import { TopProjects } from '../components/userDetail/topProjects';
import { ContributionTimeline } from '../components/userDetail/contributionTimeline';
import { NotFound } from './notFound';
import { OHSOME_STATS_BASE_URL } from '../config';
import { OHSOME_STATS_BASE_URL, OSM_SERVER_URL } from '../config';
import { fetchExternalJSONAPI } from '../network/genericJSONRequest';
import { useFetch } from '../hooks/UseFetch';
import { useSetTitleTag } from '../hooks/UseMetaTags';
Expand All @@ -33,6 +33,7 @@ export const UserDetail = ({ withHeader = true }) => {
const token = useSelector((state) => state.auth.token);
const currentUser = useSelector((state) => state.auth.userDetails);
const [osmStats, setOsmStats] = useState({});
const [userOsmDetails, setUserOsmDetails] = useState({});
const [errorDetails, loadingDetails, userDetails] = useFetch(
`users/queries/${username}/`,
username !== undefined,
Expand All @@ -54,6 +55,9 @@ export const UserDetail = ({ withHeader = true }) => {

useEffect(() => {
if (userDetails.id) {
fetchExternalJSONAPI(`${OSM_SERVER_URL}/api/0.6/user/${userDetails.id}.json`, false)
.then((res) => setUserOsmDetails(res?.user))
.catch((e) => console.log(e));
fetchExternalJSONAPI(`${OHSOME_STATS_BASE_URL}/hot-tm-user?userId=${userDetails.id}`, true)
.then((res) => setOsmStats(res.result))
.catch((e) => console.log(e));
Expand All @@ -74,7 +78,7 @@ export const UserDetail = ({ withHeader = true }) => {
rows={5}
ready={!errorDetails && !loadingDetails}
>
<HeaderProfile userDetails={userDetails} changesets={osmStats.changesets} />
<HeaderProfile userDetails={userDetails} changesets={userOsmDetails?.changesets?.count} />
</ReactPlaceholder>
</div>
)}
Expand Down
5 changes: 4 additions & 1 deletion scripts/aws/cloudformation/tasking-manager.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,9 @@ const Resources = {
Name: cf.stackName,
SecurityGroups: [cf.importValue(cf.join('-', ['hotosm-network-production', cf.ref('NetworkEnvironment'), 'elbs-security-group', cf.region]))],
Subnets: cf.ref('ELBSubnets'),
Type: 'application'
Type: 'application',
IpAddressType: 'dualstack',
Tags: [ { "Key": "stack_name", "Value": cf.stackName } ]
}
},
TaskingManagerLoadBalancerRoute53: {
Expand Down Expand Up @@ -651,6 +653,7 @@ const Resources = {
DBInstanceClass: cf.ref('DatabaseInstanceType'),
DBSnapshotIdentifier: cf.if('UseASnapshot', cf.ref('DBSnapshot'), cf.noValue),
VPCSecurityGroups: [cf.importValue(cf.join('-', ['hotosm-network-production', cf.ref('NetworkEnvironment'), 'ec2s-security-group', cf.region]))],
PubliclyAccessible: false
}
},
TaskingManagerReactBucket: {
Expand Down

0 comments on commit 3420409

Please sign in to comment.