Skip to content

Commit

Permalink
Merge pull request #496 from wri/release/outstanding-oak
Browse files Browse the repository at this point in the history
[RELEASE] Outstanding Oak
  • Loading branch information
roguenet committed Sep 20, 2024
2 parents 2ec6044 + f4711ec commit 5d034ef
Show file tree
Hide file tree
Showing 64 changed files with 3,338 additions and 799 deletions.
63 changes: 48 additions & 15 deletions src/admin/components/Dialogs/StatusChangeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@ import {
DialogTitle,
TextField
} from "@mui/material";
import { useT } from "@transifex/react";
import { useMemo, useState } from "react";
import { AutocompleteArrayInput, Form, useShowContext } from "react-admin";
import { When } from "react-if";
import * as yup from "yup";

import modules from "@/admin/modules";
import { validateForm } from "@/admin/utils/forms";
import { useNotificationContext } from "@/context/notification.provider";
import {
GetV2FormsENTITYUUIDResponse,
useGetV2FormsENTITYUUID,
usePostV2AdminENTITYUUIDReminder,
usePutV2AdminENTITYUUIDSTATUS
} from "@/generated/apiComponents";
import { optionToChoices } from "@/utils/options";

interface StatusChangeModalProps extends DialogProps {
handleClose: () => void;
status: "approve" | "moreinfo" | "restoration-in-progress" | undefined;
status: "approve" | "moreinfo" | "restoration-in-progress" | "reminder" | undefined;
}

const moreInfoValidationSchema = yup.object({
Expand All @@ -38,6 +41,8 @@ const genericValidationSchema = yup.object({
const StatusChangeModal = ({ handleClose, status, ...dialogProps }: StatusChangeModalProps) => {
const { record, refetch, resource } = useShowContext();
const [feedbackValue, setFeedbackValue] = useState("");
const { openNotification } = useNotificationContext();
const t = useT();

const resourceName = (() => {
switch (resource as keyof typeof modules) {
Expand Down Expand Up @@ -90,6 +95,9 @@ const StatusChangeModal = ({ handleClose, status, ...dialogProps }: StatusChange

case "restoration-in-progress":
return `Are you sure you want to mark ${name} as Restoration In Progress?`;

case "reminder":
return `Send a reminder for ${name}`;
}
})();

Expand Down Expand Up @@ -119,6 +127,11 @@ const StatusChangeModal = ({ handleClose, status, ...dialogProps }: StatusChange
refetch();
}
});
const { mutateAsync: mutateAsyncReminder, isLoading: isLoadingReminder } = usePostV2AdminENTITYUUIDReminder({
onSuccess: () => {
openNotification("success", "Success!", t("Reminder sent successfully."));
}
});

const handleSave = async (data: any) => {
if (!record || !status) return;
Expand All @@ -131,14 +144,24 @@ const StatusChangeModal = ({ handleClose, status, ...dialogProps }: StatusChange
body.feedback_fields = data.feedback_fields;
}

await mutateAsync({
pathParams: {
uuid: record.id,
entity: resourceName,
status
},
body
});
if (status === "reminder") {
await mutateAsyncReminder({
pathParams: {
uuid: record.id,
entity: resourceName
},
body
});
} else {
await mutateAsync({
pathParams: {
uuid: record.id,
entity: resourceName,
status
},
body
});
}
setFeedbackValue("");
handleClose();
};
Expand Down Expand Up @@ -176,12 +199,22 @@ const StatusChangeModal = ({ handleClose, status, ...dialogProps }: StatusChange

<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button variant="contained" type="submit" disabled={isLoading}>
<When condition={isLoading}>
<CircularProgress size={18} sx={{ marginRight: 1 }} />
</When>
Update Status
</Button>
<When condition={status !== "reminder"}>
<Button variant="contained" type="submit" disabled={isLoading}>
<When condition={isLoading}>
<CircularProgress size={18} sx={{ marginRight: 1 }} />
</When>
Update Status
</Button>
</When>
<When condition={status === "reminder"}>
<Button variant="contained" type="submit" disabled={isLoadingReminder}>
<When condition={isLoadingReminder}>
<CircularProgress size={18} sx={{ marginRight: 1 }} />
</When>
Send Reminder
</Button>
</When>
</DialogActions>
</Form>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const getTextForActionTable = (item: { type: string; status: string; request_rem
return "Change Request Updated";
} else if (item.request_removed) {
return "Change Request Removed";
} else if (item.type === "reminder-sent") {
return "Reminder Sent";
} else {
return "Change Requested";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {
DialogActions,
DialogContent,
DialogProps,
DialogTitle
DialogTitle,
TextField
} from "@mui/material";
import { useMemo } from "react";
import { AutocompleteArrayInput, Form, TextInput, useNotify } from "react-admin";
import { useMemo, useState } from "react";
import { AutocompleteArrayInput, Form, useNotify } from "react-admin";
import { If } from "react-if";
import * as yup from "yup";

Expand Down Expand Up @@ -47,6 +48,7 @@ const ChangeRequestRequestMoreInfoModal = ({
...dialogProps
}: ChangeRequestRequestMoreInfoModalProps) => {
const notify = useNotify();
const [feedbackValue, setFeedbackValue] = useState("");

const questions: Option[] | undefined = useMemo(() => {
const flat = form?.form_sections
Expand All @@ -72,7 +74,7 @@ const ChangeRequestRequestMoreInfoModal = ({
const handleSave = async (data: any) => {
if (status) {
const body: any = {
feedback: data.feedback
feedback: feedbackValue
};

if (data.feedback_fields && status === "moreinfo") {
Expand All @@ -87,7 +89,7 @@ const ChangeRequestRequestMoreInfoModal = ({
body
});
}

setFeedbackValue("");
return handleClose();
};

Expand All @@ -101,7 +103,15 @@ const ChangeRequestRequestMoreInfoModal = ({
<DialogTitle>{statusTitles[status as IStatus]}</DialogTitle>
</If>
<DialogContent>
<TextInput source="_feedback" label="Feedback" fullWidth multiline margin="dense" helperText={false} />
<TextField
value={feedbackValue}
onChange={e => setFeedbackValue(e.target.value)}
label="Feedback"
fullWidth
multiline
margin="dense"
helperText={false}
/>
<If condition={status === "moreinfo" && feebdackFields.length > 0}>
<AutocompleteArrayInput
source="feedback_fields"
Expand Down
61 changes: 0 additions & 61 deletions src/admin/components/ResourceTabs/GalleryTab/GalleryImageItem.tsx

This file was deleted.

76 changes: 46 additions & 30 deletions src/admin/components/ResourceTabs/GalleryTab/GalleryTab.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
import { FC, useState } from "react";
import { FC, useEffect, useState } from "react";
import { TabbedShowLayout, TabProps, useShowContext } from "react-admin";
import { When } from "react-if";

import ImageGallery from "@/components/elements/ImageGallery/ImageGallery";
import { useGetV2MODELUUIDFiles } from "@/generated/apiComponents";
import ImageGalleryItem from "@/components/elements/ImageGallery/ImageGalleryItem";
import { useDeleteV2FilesUUID, useGetV2MODELUUIDFiles } from "@/generated/apiComponents";
import { EntityName } from "@/types/common";

import GalleryImageItem from "./GalleryImageItem";

interface IProps extends Omit<TabProps, "label" | "children"> {
label?: string;
entity?: EntityName;
Expand All @@ -17,7 +15,14 @@ interface IProps extends Omit<TabProps, "label" | "children"> {
const GalleryTab: FC<IProps> = ({ label, entity, ...rest }) => {
const ctx = useShowContext();
const [pagination, setPagination] = useState({ page: 1, pageSize: 10 });
const [filter, setFilter] = useState<string>("all");
const [filter] = useState<string>("all");
const [searchString, setSearchString] = useState<string>("");
const [isGeotagged, setIsGeotagged] = useState<number>(0);
const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
const [filters, setFilters] = useState<{ isPublic: boolean | undefined; modelType: string | undefined }>({
isPublic: undefined,
modelType: undefined
});
const resource = entity ?? ctx.resource;

const queryParams: any = {
Expand All @@ -29,8 +34,16 @@ const GalleryTab: FC<IProps> = ({ label, entity, ...rest }) => {
if (filter !== "all") {
queryParams["filter[is_public]"] = filter === "public";
}

const { data } = useGetV2MODELUUIDFiles(
if (filters.isPublic !== undefined) {
queryParams["filter[is_public]"] = filters.isPublic;
}
if (filters.modelType) {
queryParams["filter[model_type]"] = filters.modelType;
}
queryParams["search"] = searchString;
queryParams["is_geotagged"] = isGeotagged;
queryParams["sort_order"] = sortOrder;
const { data, refetch, isLoading } = useGetV2MODELUUIDFiles(
{
// Currently only projects, sites, nurseries, projectReports, nurseryReports and siteReports are set up
pathParams: { model: resource, uuid: ctx?.record?.uuid },
Expand All @@ -41,46 +54,49 @@ const GalleryTab: FC<IProps> = ({ label, entity, ...rest }) => {
}
);

const { mutate: deleteFile } = useDeleteV2FilesUUID({
onSuccess() {
refetch();
}
});
useEffect(() => {
refetch();
}, [filters, pagination, searchString, isGeotagged, sortOrder, refetch]);

return (
<When condition={!ctx.isLoading}>
<TabbedShowLayout.Tab label={label ?? "Gallery"} {...rest}>
<FormControl sx={{ maxWidth: 200 }} margin="dense">
<InputLabel id="visibility-label" shrink sx={{ top: -10, fontFamily: "Acumin Pro" }}>
Visibility
</InputLabel>
<Select
labelId="visibility-label"
id="visibility-select"
value={filter}
label="Visibility"
onChange={e => {
setFilter(e.target.value);
}}
>
<MenuItem value="all">All Images</MenuItem>
<MenuItem value="public">Public</MenuItem>
<MenuItem value="private">Private</MenuItem>
</Select>
</FormControl>
<ImageGallery
data={
data?.data?.map(file => ({
//@ts-ignore
uuid: file.uuid!,
fullImageUrl: file.file_url!,
thumbnailImageUrl: file.thumb_url!,
label: file.file_name!,
label: file.model_name!,
isPublic: file.is_public!,
isGeotagged: file?.location?.lat !== 0 && file?.location?.lng !== 0,
isCover: file.is_cover,
raw: file
})) || []
}
entity={resource}
entityData={ctx.record}
pageCount={data?.meta?.last_page || 1}
onGalleryStateChange={pagination => {
setPagination(pagination);
}}
onDeleteConfirm={() => {}}
ItemComponent={GalleryImageItem}
hasFilter={false}
onDeleteConfirm={uuid => deleteFile({ pathParams: { uuid } })}
ItemComponent={ImageGalleryItem}
onChangeSearch={setSearchString}
onChangeGeotagged={setIsGeotagged}
reloadGalleryImages={refetch}
sortOrder={sortOrder}
setSortOrder={setSortOrder}
setFilters={setFilters}
className="mt-3"
isAdmin={true}
isLoading={isLoading}
/>
</TabbedShowLayout.Tab>
</When>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ const HighLevelMetics: FC = () => {
<Labeled label="Hectares Under Restoration" sx={inlineLabelSx}>
<NumberField source="total_hectares_restored_sum" emptyText="0" />
</Labeled>
<ContextCondition frameworksShow={[Framework.PPC]}>
<Labeled label="Trees Restored" sx={inlineLabelSx}>
<NumberField
source="trees_restored_ppc"
emptyText="0"
options={{ minimumFractionDigits: 0, maximumFractionDigits: 0 }}
/>
</Labeled>
</ContextCondition>
</Stack>
</Card>
);
Expand Down
Loading

0 comments on commit 5d034ef

Please sign in to comment.