Skip to content

Commit

Permalink
feat: distinguish between tasks locked by the current user and tasks …
Browse files Browse the repository at this point in the history
…locked by others (#1469)

* feat(mapStyles): add secondaryColor of red if task is locked by user itself

* feat(projectDetails): popup add if task locked by user itselft, arg add to getTaskStatusStyle

* fix(mapStyles): zIndex of locked task increase

* fix(mapStyles): strokeColor change to black

* feat(asyncPopup): dynamic popupId & className add

* fix(projectDetails): popupId & className add to asyncPopup props

* fix(ProjectTaskStatus): assign & clear userId to locked_by_user based on taskStatus
  • Loading branch information
NSUWAL123 authored Apr 22, 2024
1 parent a3e2ecf commit 9bd5839
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 19 deletions.
7 changes: 7 additions & 0 deletions src/frontend/src/api/ProjectTaskStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ const UpdateTaskStatus = (url, style, existingData, currentProjectId, feature, m
dispatch(ProjectActions.UpdateProjectTaskActivity(response.data));

await feature.setStyle(style);

// assign userId to locked_by_user if status is locked_for_mapping or locked_for_validation
const prevProperties = feature.getProperties();
const isTaskLocked = ['LOCKED_FOR_MAPPING', 'LOCKED_FOR_VALIDATION'].includes(response.data.status);
const updatedProperties = { ...prevProperties, locked_by_user: isTaskLocked ? body.id : null };
feature.setProperties(updatedProperties);

dispatch(CommonActions.SetLoading(false));
dispatch(
HomeActions.SetSnackBar({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ type asyncPopupPropType = {
loading?: boolean;
showOnHover?: string;
primaryKey?: string;
popupId?: string;
className?: string;
};

function hasKey(obj, key) {
return Object.keys(obj).some((item) => item === key);
}

const layerIds = ['code'];
const popupId = 'popupx';

const AsyncPopup = ({
map,
Expand All @@ -35,6 +36,8 @@ const AsyncPopup = ({
loading = false,
showOnHover = 'click',
primaryKey = 'uid',
popupId = 'popupx',
className,
}: asyncPopupPropType) => {
const popupRef = useRef<any>(null);
const popupCloserRef = useRef<any>(null);
Expand Down Expand Up @@ -103,7 +106,6 @@ const AsyncPopup = ({
if (!overlay) return;

map.on(showOnHover, (evt) => {
// map.updateSize();
overlay.setPosition(undefined);
setPopupHTML('');
setProperties(null);
Expand Down Expand Up @@ -131,7 +133,7 @@ const AsyncPopup = ({
setCoordinates(null);
}
});
}, [map, closePopupFn]);
}, [map, closePopupFn, showOnHover]);

// fetch popup data when properties is set
useEffect(() => {
Expand Down Expand Up @@ -166,7 +168,7 @@ const AsyncPopup = ({
<div
ref={popupRef}
id="popup"
className="ol-popup"
className={`ol-popup ${className}`}
style={{ zIndex: 100009 }}
onBlur={(e) => {
if (!e.currentTarget.contains(e.relatedTarget)) {
Expand Down
8 changes: 5 additions & 3 deletions src/frontend/src/hooks/MapStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function createPolygonStyle(fillColor, strokeColor) {
fill: new Fill({
color: fillColor,
}),
zIndex: 10,
});
}
function createIconStyle(iconSrc) {
Expand All @@ -36,17 +37,18 @@ function createIconStyle(iconSrc) {
export default function MapStyles() {
const mapTheme = CoreModules.useAppSelector((state) => state.theme.hotTheme);
const [style, setStyle] = useState({});
const strokeColor = 'rgb(0,0,0,0.5)';
const strokeColor = 'rgb(0,0,0,0.3)';
const secondaryStrokeColor = 'rgb(0,0,0,1)';

useEffect(() => {
// Example usage:
const lockedPolygonStyle = createPolygonStyle(
mapTheme.palette.mapFeatureColors.locked_for_mapping_rgb,
strokeColor,
secondaryStrokeColor,
);
const lockedValidationStyle = createPolygonStyle(
mapTheme.palette.mapFeatureColors.locked_for_validation_rgb,
strokeColor,
secondaryStrokeColor,
);
const iconStyle = createIconStyle(AssetModules.LockPng);
const redIconStyle = createIconStyle(AssetModules.RedLockPng);
Expand Down
29 changes: 19 additions & 10 deletions src/frontend/src/utilfunctions/getTaskStatusStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function createPolygonStyle(fillColor, strokeColor) {
fill: new Fill({
color: fillColor,
}),
zIndex: 10,
});
}
function createIconStyle(iconSrc) {
Expand All @@ -31,23 +32,31 @@ function createIconStyle(iconSrc) {
});
}

const strokeColor = 'rgb(0,0,0,0.5)';
const strokeColor = 'rgb(0,0,0,0.3)';
const secondaryStrokeColor = 'rgb(0,0,0,1)';

const getTaskStatusStyle = (feature, mapTheme) => {
const getTaskStatusStyle = (feature, mapTheme, taskLockedByUser) => {
let id = feature.getId().toString().replace('_', ',');
const status = id.split(',')[1];
const lockedPolygonStyle = createPolygonStyle(mapTheme.palette.mapFeatureColors.locked_for_mapping_rgb, strokeColor);

const isTaskStatusLocked = ['LOCKED_FOR_MAPPING', 'LOCKED_FOR_VALIDATION'].includes(status);
const borderStrokeColor = isTaskStatusLocked && taskLockedByUser ? secondaryStrokeColor : strokeColor;

const lockedPolygonStyle = createPolygonStyle(
mapTheme.palette.mapFeatureColors.locked_for_mapping_rgb,
borderStrokeColor,
);
const lockedValidationStyle = createPolygonStyle(
mapTheme.palette.mapFeatureColors.locked_for_validation_rgb,
strokeColor,
borderStrokeColor,
);
const iconStyle = createIconStyle(AssetModules.LockPng);
const redIconStyle = createIconStyle(AssetModules.RedLockPng);

const geojsonStyles = {
READY: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand All @@ -57,7 +66,7 @@ const getTaskStatusStyle = (feature, mapTheme) => {
LOCKED_FOR_MAPPING: [lockedPolygonStyle, iconStyle],
MAPPED: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand All @@ -68,7 +77,7 @@ const getTaskStatusStyle = (feature, mapTheme) => {

VALIDATED: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand All @@ -77,7 +86,7 @@ const getTaskStatusStyle = (feature, mapTheme) => {
}),
INVALIDATED: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand All @@ -86,7 +95,7 @@ const getTaskStatusStyle = (feature, mapTheme) => {
}),
BAD: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand All @@ -95,7 +104,7 @@ const getTaskStatusStyle = (feature, mapTheme) => {
}),
SPLIT: new Style({
stroke: new Stroke({
color: strokeColor,
color: borderStrokeColor,
width: 3,
}),
fill: new Fill({
Expand Down
27 changes: 25 additions & 2 deletions src/frontend/src/views/ProjectDetailsV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const Home = () => {
const geolocationStatus = useAppSelector((state) => state.project.geolocationStatus);
const taskModalStatus = CoreModules.useAppSelector((state) => state.project.taskModalStatus);
const projectOpfsBasemapPath = useAppSelector((state) => state?.project?.projectOpfsBasemapPath);
const token = CoreModules.useAppSelector((state) => state.login.loginToken);

useEffect(() => {
if (state.projectInfo.title) {
Expand Down Expand Up @@ -143,6 +144,7 @@ const Home = () => {
geometry: { ...taskObj.outline_geojson.geometry },
properties: {
...taskObj.outline_geojson.properties,
locked_by_user: taskObj?.locked_by_uid,
},
id: `${taskObj.id}_${taskObj.task_status}`,
}));
Expand Down Expand Up @@ -178,6 +180,10 @@ const Home = () => {
);
};

const lockedPopup = () => {
return <p>This task was locked by you</p>;
};

/**
* Handles the click event on a project task area.
*
Expand Down Expand Up @@ -448,7 +454,9 @@ const Home = () => {
mapOnClick={projectClickOnMapTask}
zoomToLayer
zIndex={5}
getTaskStatusStyle={(feature) => getTaskStatusStyle(feature, mapTheme)}
getTaskStatusStyle={(feature) => {
return getTaskStatusStyle(feature, mapTheme, feature.getProperties()?.locked_by_user == token?.id);
}}
/>
)}
{dataExtractUrl && isValidUrl(dataExtractUrl) && dataExtractExtent && (
Expand All @@ -466,7 +474,22 @@ const Home = () => {
zIndex={5}
/>
)}
<AsyncPopup map={map} popupUI={dataExtractDataPopup} primaryKey={'osm_id'} showOnHover="singleclick" />
<AsyncPopup
map={map}
popupUI={lockedPopup}
primaryKey={'locked_by_user'}
showOnHover="pointermove"
popupId="locked-popup"
className="fmtm-w-[235px]"
/>
<AsyncPopup
map={map}
popupUI={dataExtractDataPopup}
primaryKey={'osm_id'}
showOnHover="singleclick"
popupId="data-extract-popup"
className="fmtm-w-[300px]"
/>
<div className="fmtm-absolute fmtm-bottom-20 sm:fmtm-bottom-5 fmtm-left-3 fmtm-z-50 fmtm-rounded-lg">
<Accordion
body={<MapLegends defaultTheme={defaultTheme} />}
Expand Down

0 comments on commit 9bd5839

Please sign in to comment.