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

chore: CE-1274 #827

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 frontend/src/app/common/validation-checkbox-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const ValidationCheckboxGroup: FC<ValidationCheckboxGroupProps> = ({

useEffect(() => {
setCheckedItems(checkedValues);
}, [checkedValues.length]);
}, [checkedValues, checkedValues.length]);

return (
<div id="checkbox-div">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/common/validation-phone-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const ValidationPhoneInput: FC<ValidationPhoneInputProps> = ({
international,
}) => {
const errClass = errMsg === "" ? "" : "error-message";
const calulatedClass = errMsg === "" ? "comp-form-control" : "comp-form-control" + " error-border";
const calulatedClass = errMsg === "" ? "comp-form-control" : "comp-form-control error-border";
return (
<div>
<div className={className}>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/app/components/common/attachments-carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const AttachmentsCarousel: FC<Props> = ({
if (complaintIdentifier) {
dispatch(getAttachments(complaintIdentifier, attachmentType));
}
}, [complaintIdentifier, dispatch]);
}, [attachmentType, complaintIdentifier, dispatch]);

//-- when the component unmounts clear the attachments from redux
useEffect(() => {
Expand All @@ -82,15 +82,15 @@ export const AttachmentsCarousel: FC<Props> = ({
if (typeof onSlideCountChange === "function") {
onSlideCountChange(slides.length);
}
}, [slides.length]);
}, [onSlideCountChange, slides.length]);

// Clear all pending upload attachments
useEffect(() => {
if (cancelPendingUpload) {
setSlides([]);
if (setCancelPendingUpload) setCancelPendingUpload(false); //reset cancelPendingUpload
}
}, [cancelPendingUpload]);
}, [cancelPendingUpload, setCancelPendingUpload]);

function sortAttachmentsByName(comsObjects: COMSObject[]): COMSObject[] {
// Create a copy of the array using slice() or spread syntax
Expand Down
256 changes: 137 additions & 119 deletions frontend/src/app/components/common/comp-coordinate-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useEffect, useState } from "react";
import { FC, useCallback, useEffect, useState } from "react";
import Option from "@apptypes/app/option";
import { CompRadioGroup } from "./comp-radiogroup";
import { bcBoundaries, bcUtmBoundaries, formatLatLongCoordinate } from "@common/methods";
Expand Down Expand Up @@ -46,141 +46,158 @@ export const CompCoordinateInput: FC<Props> = ({
const [zoneCoordinate, setZoneCoordinate] = useState<Option | undefined | null>();
const [zoneErrorMsg, setZoneErrorMsg] = useState<string | undefined>("");

const handleGeoPointChange = (latitude: string, longitude: string) => {
setYCoordinateErrorMsg("");
setXCoordinateErrorMsg("");
setYCoordinate(latitude);
setXCoordinate(longitude);
const handleGeoPointChange = useCallback(
(latitude: string, longitude: string) => {
setYCoordinateErrorMsg("");
setXCoordinateErrorMsg("");
setYCoordinate(latitude);
setXCoordinate(longitude);

// handling removal of coordinates here
if ([latitude?.trim(), longitude?.trim()].every((item) => item === "")) {
throwError(false);
syncCoordinates("", "");
return;
}
const regex = /^-?(?:\d+(\.\d+)?|.\d+)$/;
let hasErrors = false;
if (!regex.exec(latitude)) {
setYCoordinateErrorMsg("Latitude value must be a number");
hasErrors = true;
}
if (!regex.exec(longitude)) {
setXCoordinateErrorMsg("Longitude value must be a number");
hasErrors = true;
}
if (latitude && !Number.isNaN(latitude)) {
const item = parseFloat(latitude);
if (item > bcBoundaries.maxLatitude || item < bcBoundaries.minLatitude) {
setYCoordinateErrorMsg(
`Latitude value must be between ${bcBoundaries.maxLatitude} and ${bcBoundaries.minLatitude} degrees`,
);
// handling removal of coordinates here
if ([latitude?.trim(), longitude?.trim()].every((item) => item === "")) {
throwError(false);
syncCoordinates("", "");
return;
}
const regex = /^-?(?:\d+(\.\d+)?|.\d+)$/;
let hasErrors = false;
if (!regex.exec(latitude)) {
setYCoordinateErrorMsg("Latitude value must be a number");
hasErrors = true;
}
}
if (longitude && !Number.isNaN(longitude) && longitude.trim() !== "-") {
const item = parseFloat(longitude);
if (item > bcBoundaries.maxLongitude || item < bcBoundaries.minLongitude) {
setXCoordinateErrorMsg(
`Longitude value must be between ${bcBoundaries.minLongitude} and ${bcBoundaries.maxLongitude} degrees`,
);
if (!regex.exec(longitude)) {
setXCoordinateErrorMsg("Longitude value must be a number");
hasErrors = true;
} else {
syncCoordinates(latitude, longitude);
}
}
throwError(hasErrors);
};
if (latitude && !Number.isNaN(latitude)) {
const item = parseFloat(latitude);
if (item > bcBoundaries.maxLatitude || item < bcBoundaries.minLatitude) {
setYCoordinateErrorMsg(
`Latitude value must be between ${bcBoundaries.maxLatitude} and ${bcBoundaries.minLatitude} degrees`,
);
hasErrors = true;
}
}
if (longitude && !Number.isNaN(longitude) && longitude.trim() !== "-") {
const item = parseFloat(longitude);
if (item > bcBoundaries.maxLongitude || item < bcBoundaries.minLongitude) {
setXCoordinateErrorMsg(
`Longitude value must be between ${bcBoundaries.minLongitude} and ${bcBoundaries.maxLongitude} degrees`,
);
hasErrors = true;
} else {
syncCoordinates(latitude, longitude);
}
}
throwError(hasErrors);
},
[syncCoordinates, throwError],
);

const handleUtmGeoPointChange = (easting: string, northing: string, zone: string) => {
setEastingCoordinateErrorMsg("");
setNorthingCoordinateErrorMsg("");
setZoneErrorMsg("");
setYCoordinateErrorMsg("");
setXCoordinateErrorMsg("");
const handleUtmGeoPointChange = useCallback(
(easting: string, northing: string, zone: string) => {
setEastingCoordinateErrorMsg("");
setNorthingCoordinateErrorMsg("");
setZoneErrorMsg("");
setYCoordinateErrorMsg("");
setXCoordinateErrorMsg("");

setEastingCoordinate(easting);
setNorthingCoordinate(northing);
setZoneCoordinate(zone ? ({ label: zone, value: zone } as Option) : undefined);
setEastingCoordinate(easting);
setNorthingCoordinate(northing);
setZoneCoordinate(zone ? ({ label: zone, value: zone } as Option) : undefined);

if (
[easting.toString().trim(), northing.toString().trim()].every((item) => item === "") &&
[undefined, ""].includes(zone)
) {
throwError(false);
syncCoordinates("", "");
return;
}
const isEmpty = (value: string | undefined) => [undefined, ""].includes(value?.toString().trim());
if (isEmpty(easting) && isEmpty(northing) && isEmpty(zone)) {
throwError(false);
syncCoordinates("", "");
return;
}

const regex = /^-?(?:\d+(\.\d+)?|.\d+)$/;
let hasErrors = false;
let lat;
let lng;
const regex = /^-?(?:\d+(\.\d+)?|.\d+)$/;
let hasErrors = false;
let lat;
let lng;
const errorTextSuffixLat = `The corresponding latitude value must be between ${bcBoundaries.minLatitude} and ${bcBoundaries.maxLatitude} degrees`;
const errorTextSuffixLng = `The corresponding longitude value must be between ${bcBoundaries.minLongitude} and ${bcBoundaries.maxLongitude} degrees`;
const eastingErrorText =
`Invalid Easting. Easting value must be between 290220.6 and 720184.9 metres. ` + errorTextSuffixLng;
const northingErrorText =
`Invalid Northing. Northing value must be between 5346051.7 and 6655120.8 metres. ` + errorTextSuffixLat;
const zoneErrorText = `Invalid Zone. Must be in 7-11 range`;

const errorTextSuffixLat = `The corresponding latitude value must be between ${bcBoundaries.minLatitude} and ${bcBoundaries.maxLatitude} degrees`;
const errorTextSuffixLng = `The corresponding longitude value must be between ${bcBoundaries.minLongitude} and ${bcBoundaries.maxLongitude} degrees`;
const eastingErrorText =
`Invalid Easting. Easting value must be between 290220.6 and 720184.9 metres. ` + errorTextSuffixLng;
const northingErrorText =
`Invalid Northing. Northing value must be between 5346051.7 and 6655120.8 metres. ` + errorTextSuffixLat;
const zoneErrorText = `Invalid Zone. Must be in 7-11 range`;
let utm = new utmObj();

let utm = new utmObj();
if (!regex.exec(easting)) {
setEastingCoordinateErrorMsg("Easting value must be a number");
hasErrors = true;
}
if (!regex.exec(northing)) {
setNorthingCoordinateErrorMsg("Northing value must be a number");
hasErrors = true;
}
const validateCoordinate = (
value: string,
setErrorMsg: (msg: string) => void,
errorMsg: string,
min: number,
max: number,
) => {
if (!regex.exec(value)) {
setErrorMsg("Value must be a number");
return true;
}
const numValue = parseInt(value);
if (numValue > max || numValue < min) {
setErrorMsg(errorMsg);
return true;
}
return false;
};

if (easting && !Number.isNaN(easting)) {
const item = parseInt(easting);
if (item > bcUtmBoundaries.maxEasting || item < bcUtmBoundaries.minEasting) {
setEastingCoordinateErrorMsg(eastingErrorText);
hasErrors = true;
}
}
hasErrors =
validateCoordinate(
easting,
setEastingCoordinateErrorMsg,
eastingErrorText,
bcUtmBoundaries.minEasting,
bcUtmBoundaries.maxEasting,
) || hasErrors;
hasErrors =
validateCoordinate(
northing,
setNorthingCoordinateErrorMsg,
northingErrorText,
bcUtmBoundaries.minNorthing,
bcUtmBoundaries.maxNorthing,
) || hasErrors;

const isValidZone = (zone: string | undefined): boolean => {
return (
(typeof zone === "string" &&
!Number.isNaN(Number(zone)) &&
utmZones?.map((item) => item.value).includes(zone)) ||
false
);
};

if (northing && !Number.isNaN(northing)) {
const item = parseInt(northing);
if (item > bcUtmBoundaries.maxNorthing || item < bcUtmBoundaries.minNorthing) {
setNorthingCoordinateErrorMsg(northingErrorText);
if (!isValidZone(zone)) {
setZoneErrorMsg(zoneErrorText);
hasErrors = true;
}
}

if (
zone &&
!Number.isNaN(zone) &&
utmZones
?.map((item) => {
return item.value;
})
.includes(zone.toString())
) {
} else {
setZoneErrorMsg(zoneErrorText);
hasErrors = true;
}
if (!hasErrors && easting && !Number.isNaN(easting) && northing && !Number.isNaN(northing)) {
const latLongCoordinates = utm.convertUtmToLatLng(easting, northing, zone, "N");
lat = latLongCoordinates.lat.toFixed(7);
lng = latLongCoordinates.lng.toFixed(7);

if (hasErrors === false && easting && !Number.isNaN(easting) && northing && !Number.isNaN(northing)) {
const latLongCoordinates = utm.convertUtmToLatLng(easting, northing, zone, "N");
lat = latLongCoordinates.lat.toFixed(7);
if (lat > bcBoundaries.maxLatitude || lat < bcBoundaries.minLatitude) {
setNorthingCoordinateErrorMsg(northingErrorText);
hasErrors = true;
}
lng = latLongCoordinates.lng.toFixed(7);
if (lng > bcBoundaries.maxLongitude || lng < bcBoundaries.minLongitude) {
setEastingCoordinateErrorMsg(eastingErrorText);
hasErrors = true;
} else {
syncCoordinates(lat, lng);
if (lat < bcBoundaries.minLatitude || lat > bcBoundaries.maxLatitude) {
setNorthingCoordinateErrorMsg(northingErrorText);
hasErrors = true;
}

if (lng < bcBoundaries.minLongitude || lng > bcBoundaries.maxLongitude) {
setEastingCoordinateErrorMsg(eastingErrorText);
hasErrors = true;
} else {
syncCoordinates(lat, lng);
}
}
}
throwError(hasErrors);
};
throwError(hasErrors);
},
[syncCoordinates, throwError, utmZones],
);

const handleChangeCoordinateType = (coordinateType: string) => {
if (coordinateType === COORDINATE_TYPES.UTM) {
Expand Down Expand Up @@ -245,7 +262,8 @@ export const CompCoordinateInput: FC<Props> = ({
}
}
}
}, [initXCoordinate, initYCoordinate]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [coordinateType, initXCoordinate, initYCoordinate]);

const formatUtmCoordinate = (input: string | undefined): string => {
const regex = /^-?(?:\d+(\.\d+)?|.\d+)$/;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const ComplaintPagination: React.FC<ComplaintPaginationProps> = ({
useEffect(() => {
// Update the local state whenever selectedValue changes so that the pagination starts at 1 again.
onPageChange(1);
}, [totalItems]);
}, [onPageChange, totalItems]);

const handleEnterKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ export const FeatureManagement: FC = () => {

const [featureData, setFeatureData] = useState<any[]>([]);

const getAllFeatureFlags = async () => {
const parameters = generateApiParameters(`${config.API_BASE_URL}/v1/feature-flag/all`);
const response: any = await get(dispatch, parameters);
if (response) {
setFeatureData(response);
}
};

const updateFeatureFlag = async (id: string, active_ind: boolean) => {
try {
const update = {
Expand All @@ -36,8 +28,15 @@ export const FeatureManagement: FC = () => {
};

useEffect(() => {
const getAllFeatureFlags = async () => {
const parameters = generateApiParameters(`${config.API_BASE_URL}/v1/feature-flag/all`);
const response: any = await get(dispatch, parameters);
if (response) {
setFeatureData(response);
}
};
getAllFeatureFlags();
}, []);
}, [dispatch]);

const handleChange = (item: any, i: number) => {
const updateFeatureData = [...featureData];
Expand Down
Loading
Loading