diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx index 3dff79d6f..bb8af6a2c 100644 --- a/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx +++ b/src/admin/components/ResourceTabs/PolygonReviewTab/components/PolygonDrawer/components/VersionHistory.tsx @@ -362,7 +362,8 @@ const VersionHistory = ({ placeholder="Select Polygon Version" options={polygonVersionData ?? []} optionVariant="text-12-light" - titleClassname="one-line-text !w-[96%] !text-nowrap" + titleClassname="one-line-text !w-full !text-nowrap" + titleContainerClassName="!w-[calc(100%-25px)] !text-nowrap" defaultValue={[selectPolygonVersion?.uuid ?? selectedPolygon?.uuid] as string[]} onChange={e => { const polygonVersionData = (data as SitePolygonsDataResponse)?.find(item => item.uuid === e[0]); diff --git a/src/admin/components/ResourceTabs/PolygonReviewTab/index.tsx b/src/admin/components/ResourceTabs/PolygonReviewTab/index.tsx index 9117e6456..3b5bd4d46 100644 --- a/src/admin/components/ResourceTabs/PolygonReviewTab/index.tsx +++ b/src/admin/components/ResourceTabs/PolygonReviewTab/index.tsx @@ -26,7 +26,6 @@ import LinearProgressBarMonitored from "@/components/elements/ProgressBar/Linear import Table from "@/components/elements/Table/Table"; import { VARIANT_TABLE_SITE_POLYGON_REVIEW } from "@/components/elements/Table/TableVariants"; import Text from "@/components/elements/Text/Text"; -import ToolTip from "@/components/elements/Tooltip/Tooltip"; import Icon from "@/components/extensive/Icon/Icon"; import { IconNames } from "@/components/extensive/Icon/Icon"; import ModalAdd from "@/components/extensive/Modal/ModalAdd"; @@ -629,9 +628,6 @@ const PolygonReviewTab: FC = props => {
Site Status - - - {record?.readable_status} @@ -640,9 +636,6 @@ const PolygonReviewTab: FC = props => {
Polygon Overview - - - @@ -660,9 +653,6 @@ const PolygonReviewTab: FC = props => {
Add or Edit Polygons - - - Add, remove or edit polygons that are associated to a site. Polygons may be edited in the map @@ -742,7 +732,7 @@ const PolygonReviewTab: FC = props => { pagination: { pageSize: 10000000 } }} columns={[ - { header: "Polygon Name", accessorKey: "polygon-name" }, + { header: "Polygon Name", accessorKey: "polygon-name", meta: { style: { width: "14.63%" } } }, { header: "Restoration Practice", accessorKey: "restoration-practice", @@ -751,15 +741,28 @@ const PolygonReviewTab: FC = props => { return ( ); - } + }, + meta: { style: { width: "17.63%" } } }, - { header: "Target Land Use System", accessorKey: "target-land-use-system" }, - { header: "Tree Distribution", accessorKey: "tree-distribution" }, - { header: "Planting Start Date", accessorKey: "planting-start-date" }, - { header: "Source", accessorKey: "source" }, + { + header: "Target Land Use System", + accessorKey: "target-land-use-system", + meta: { style: { width: "20.63%" } } + }, + { + header: "Tree Distribution", + accessorKey: "tree-distribution", + meta: { style: { width: "15.63%" } } + }, + { + header: "Planting Start Date", + accessorKey: "planting-start-date", + meta: { style: { width: "17.63%" } } + }, + { header: "Source", accessorKey: "source", meta: { style: { width: "10.63%" } } }, { header: "", accessorKey: "ellipse", diff --git a/src/components/elements/Inputs/Dropdown/Dropdown.tsx b/src/components/elements/Inputs/Dropdown/Dropdown.tsx index b6815374e..dff695d13 100644 --- a/src/components/elements/Inputs/Dropdown/Dropdown.tsx +++ b/src/components/elements/Inputs/Dropdown/Dropdown.tsx @@ -60,6 +60,7 @@ export interface DropdownProps { onInternalError?: (error: ErrorOption) => void; showSelectAll?: boolean; titleClassname?: string; + titleContainerClassName?: string; } const otherKey = "other#value#key"; const getAllowedValues = (values: OptionValue[], options: Option[]) => @@ -206,7 +207,13 @@ const Dropdown = (props: PropsWithChildren) => { )} > {props.prefix} -
+
void }) => { + const t = useT(); + const { closeModal } = useModalContext(); + + return ( + + + + + } + /> + ); +}; + +export default NonScientificConfirmationModal; diff --git a/src/components/elements/Inputs/TreeSpeciesInput/RHFTreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/RHFTreeSpeciesInput.tsx index 3bec5353a..2c48a4959 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/RHFTreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/RHFTreeSpeciesInput.tsx @@ -28,7 +28,7 @@ const RHFTreeSpeciesInput = (props: PropsWithChildren) return ( { + const { closeModal } = useModalContext(); + const t = useT(); + + return ( + + + + } + /> + ); +}; + +export default SpeciesAlreadyExistsModal; diff --git a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx index 8677e0eba..e3dacffc0 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx +++ b/src/components/elements/Inputs/TreeSpeciesInput/TreeSpeciesInput.tsx @@ -6,6 +6,8 @@ import { FieldError, FieldErrors } from "react-hook-form"; import { Else, If, Then, When } from "react-if"; import { v4 as uuidv4 } from "uuid"; +import NonScientificConfirmationModal from "@/components/elements/Inputs/TreeSpeciesInput/NonScientificConfirmationModal"; +import SpeciesAlreadyExistsModal from "@/components/elements/Inputs/TreeSpeciesInput/SpeciesAlreadyExistsModal"; import { useAutocompleteSearch } from "@/components/elements/Inputs/TreeSpeciesInput/useAutocompleteSearch"; import Icon, { IconNames } from "@/components/extensive/Icon/Icon"; import List from "@/components/extensive/List/List"; @@ -28,6 +30,7 @@ import InputWrapper, { InputWrapperProps } from "../InputElements/InputWrapper"; export interface TreeSpeciesInputProps extends Omit { title: string; + label?: string; buttonCaptionSuffix: string; withNumbers?: boolean; withPreviousCounts: boolean; @@ -43,45 +46,6 @@ export interface TreeSpeciesInputProps extends Omit export type TreeSpeciesValue = { uuid?: string; name?: string; taxon_id?: string; amount?: number }; -const NonScientificConfirmationModal = ({ onConfirm }: { onConfirm: () => void }) => { - const t = useT(); - const { closeModal } = useModalContext(); - - return ( -
-
- - - {t("Your input is a not a scientific name")} - -
-
-
-
- - {t("You can add this species, but it will be pending review from Admin.")} - -
-
-
- - -
-
-
- ); -}; - const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { const id = useId(); const t = useT(); @@ -183,8 +147,11 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { lastInputRef.current?.focus(); }; - if (!isEmpty(searchResult) && taxonId == null) { - // In this case the use had valid values to choose from, but decided to add a value that isn't + if (value.find(({ name }) => name === valueAutoComplete) != null) { + openModal(ModalId.ERROR_MODAL, ); + setValueAutoComplete(""); + } else if (!isEmpty(searchResult) && taxonId == null) { + // In this case the user had valid values to choose from, but decided to add a value that isn't // on the list, so they haven't been shown the warning yet. openModal(ModalId.ERROR_MODAL, ); } else { @@ -225,7 +192,7 @@ const TreeSpeciesInput = (props: TreeSpeciesInputProps) => { return ( ( +
+
+ + + {title} + +
+
+
+
+ + {content} + +
+
+
{buttons}
+
+
+); + +export default TreeSpeciesModal; diff --git a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot index 9810e81fc..bd502d0a0 100644 --- a/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot +++ b/src/components/elements/Inputs/TreeSpeciesInput/__snapshots__/TreeSpeciesInput.stories.storyshot @@ -9,7 +9,7 @@ exports[`Storyshots Components/Elements/Inputs/TreeSpeciesInput Default 1`] = ` data-testid="txt" htmlFor=":r23:" > - ADD TREE SPECIES * + Tree Species Grown *

- ADD TREE SPECIES * + Tree Species Grown *

({ const [sorting, setSorting] = useState(initialTableState?.sorting ?? []); const [filters, setFilters] = useState([]); + const spanRefs = useRef([]); + const iconRefs = useRef([]); + const { getHeaderGroups, getRowModel, @@ -183,7 +186,7 @@ function Table({ } >

({ fontFamily: "inherit" }} > - {flexRender(header.column.columnDef.header, header.getContext())} - - - +
+ { + if ( + el && + !spanRefs.current.includes(el) && + flexRender(header.column.columnDef.header, header.getContext()) + ) { + spanRefs.current.push(el); + } + }} + > + {flexRender(header.column.columnDef.header, header.getContext())} + + + { + if (el && !iconRefs.current.includes(el)) { + iconRefs.current.push(el); + } + }} + className="absolute left-[calc(100%+10px)] top-1/2 z-auto -translate-y-1/2 transform" + style={{ left: `${spanRefs.current[header.index]?.getBoundingClientRect().width}px` }} + > + + + +
); diff --git a/src/components/elements/Table/TableVariants.ts b/src/components/elements/Table/TableVariants.ts index fd80fb984..a444c5694 100644 --- a/src/components/elements/Table/TableVariants.ts +++ b/src/components/elements/Table/TableVariants.ts @@ -97,9 +97,9 @@ export const VARIANT_TABLE_SITE_POLYGON_REVIEW = { table: "border-collapse", name: "border-airtable", tableWrapper: "border border-neutral-200 rounded-lg overflow-hidden", - trHeader: "bg-neutral-150", + trHeader: "bg-neutral-150 sticky top-0 z-auto", thHeader: - "first:pl-4 first:pr-2 last:pl-2 last:pr-4 border-y border-neutral-200 text-14-semibold whitespace-normal px-2 border-t-0", + "first:pl-4 first:pr-2 last:pl-2 last:pr-4 border-y border-neutral-200 text-14-semibold whitespace-normal px-2 border-t-0 sticky top-0 z-auto", tBody: "", trBody: "bg-white border-y border-neutral-200 last:border-b-0", tdBody: "text-14-light px-2 py-3 first:pl-4 first:pr-2 last:pl-2 last:pr-4 ", diff --git a/src/components/elements/Table/__snapshots__/Table.stories.storyshot b/src/components/elements/Table/__snapshots__/Table.stories.storyshot index 4049211ad..ebac4acaa 100644 --- a/src/components/elements/Table/__snapshots__/Table.stories.storyshot +++ b/src/components/elements/Table/__snapshots__/Table.stories.storyshot @@ -124,7 +124,7 @@ exports[`Storyshots Components/Elements/Table Default 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -987,7 +1070,7 @@ exports[`Storyshots Components/Elements/Table Primary 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -1850,7 +2016,7 @@ exports[`Storyshots Components/Elements/Table Secundary White 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -2713,7 +2962,7 @@ exports[`Storyshots Components/Elements/Table Table Airtable 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -3579,7 +3911,7 @@ exports[`Storyshots Components/Elements/Table Table Airtable Dashboard 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -4443,7 +4858,7 @@ exports[`Storyshots Components/Elements/Table Table Border 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -5306,7 +5804,7 @@ exports[`Storyshots Components/Elements/Table Table Border All 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -6172,7 +6753,7 @@ exports[`Storyshots Components/Elements/Table Table Dashboard Countries 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -7039,7 +7703,7 @@ exports[`Storyshots Components/Elements/Table Table Dashboard Countries Modal 1` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -7906,7 +8653,7 @@ exports[`Storyshots Components/Elements/Table Table Organization 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -8756,11 +9586,11 @@ exports[`Storyshots Components/Elements/Table Table Site Polygon 1`] = ` className="bg-blueCustom-100" >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
@@ -9636,7 +10549,7 @@ exports[`Storyshots Components/Elements/Table Table Version 1`] = ` } >
- Funding type +
+ + Funding type + +
- Funding source
+ > + + Funding source + + +
+ +
- Funding amount
+ > + + Funding amount + + +
+ +
- Status +
+ + Status + +
+ > +
+ +
+
diff --git a/src/components/extensive/WizardForm/FormHeader.tsx b/src/components/extensive/WizardForm/FormHeader.tsx index b479cb014..2b9c61ae9 100644 --- a/src/components/extensive/WizardForm/FormHeader.tsx +++ b/src/components/extensive/WizardForm/FormHeader.tsx @@ -11,11 +11,15 @@ export interface WizardFormHeaderProps { errorMessage?: string; onClickSaveAndCloseButton?: () => void; title?: string; + subtitle?: string; } export const WizardFormHeader = (props: WizardFormHeaderProps) => { const t = useT(); + const subtitle = + props.subtitle ?? t("Progress: {number} steps complete", { number: `${props.currentStep}/${props.numberOfSteps}` }); + return (
@@ -27,9 +31,9 @@ export const WizardFormHeader = (props: WizardFormHeaderProps) => { )}
- + {subtitle} - + {t("Unsaved")} {t("Saving…")} diff --git a/src/components/extensive/WizardForm/index.tsx b/src/components/extensive/WizardForm/index.tsx index 4cea6fcb1..aeb1452c7 100644 --- a/src/components/extensive/WizardForm/index.tsx +++ b/src/components/extensive/WizardForm/index.tsx @@ -32,6 +32,7 @@ export interface WizardFormProps { formStatus?: "saving" | "saved"; title?: string; + subtitle?: string; errors?: ErrorWrapper; summaryOptions?: FormSummaryOptions & { downloadButtonText?: string; @@ -267,6 +268,7 @@ function WizardForm(props: WizardFormProps) { errorMessage={props.errors && t("Something went wrong")} onClickSaveAndCloseButton={!props.hideSaveAndCloseButton ? onClickSaveAndClose : undefined} title={props.title} + subtitle={props.subtitle} />
diff --git a/src/components/extensive/WizardForm/utils.ts b/src/components/extensive/WizardForm/utils.ts index 13893a348..e7f21f0a0 100644 --- a/src/components/extensive/WizardForm/utils.ts +++ b/src/components/extensive/WizardForm/utils.ts @@ -44,7 +44,7 @@ export const getSchemaFields = (fields: FormField[]) => { } }); } else { - schema[field.name] = field.validation?.nullable().label(field.label); + schema[field.name] = field.validation?.nullable().label(" "); } if (field.fieldProps.required) schema[field.name] = schema[field.name].required(); diff --git a/src/generated/apiFetcher.ts b/src/generated/apiFetcher.ts index 9c489d679..0b08d922b 100644 --- a/src/generated/apiFetcher.ts +++ b/src/generated/apiFetcher.ts @@ -193,11 +193,11 @@ async function processDelayedJob(signal: AbortSignal | undefined, delayed jobResult = await loadJob(signal, delayedJobId) ) { //@ts-ignore - const { total_content, processed_content, progress_message } = jobResult.data?.attributes; - if (total_content != null) { - ApiSlice.addTotalContent(total_content); - ApiSlice.addProgressContent(processed_content); - ApiSlice.addProgressMessage(progress_message); + const { totalContent, processedContent, progressMessage } = jobResult.data?.attributes; + if (totalContent != null) { + ApiSlice.addTotalContent(totalContent); + ApiSlice.addProgressContent(processedContent); + ApiSlice.addProgressMessage(progressMessage); } if (signal?.aborted || ApiSlice.apiDataStore.abort_delayed_job) throw new Error("Aborted"); diff --git a/src/pages/entity/[entityName]/edit/[uuid]/EditEntityForm.tsx b/src/pages/entity/[entityName]/edit/[uuid]/EditEntityForm.tsx index 8b7876904..c6832cb0d 100644 --- a/src/pages/entity/[entityName]/edit/[uuid]/EditEntityForm.tsx +++ b/src/pages/entity/[entityName]/edit/[uuid]/EditEntityForm.tsx @@ -64,7 +64,12 @@ const EditEntityForm = ({ entityName, entityUUID, entity, formData }: EditEntity ); const reportingWindow = useReportingWindow(entity?.due_at); - const formTitle = `${formData.form?.title} ${isReport ? reportingWindow : ""}`; + const formTitle = + entityName === "site-reports" + ? t("{siteName} Site Report", { siteName: entity.site.name }) + : `${formData.form?.title} ${isReport ? reportingWindow : ""}`; + const formSubtitle = + entityName === "site-reports" ? t("Reporting Period: {reportingWindow}", { reportingWindow }) : undefined; const saveAndCloseModalMapping: any = { projects: t( @@ -117,6 +122,7 @@ const EditEntityForm = ({ entityName, entityUUID, entity, formData }: EditEntity submitButtonDisable={isSubmitting} defaultValues={defaultValues} title={formTitle} + subtitle={formSubtitle} tabOptions={{ markDone: true, disableFutureTabs: true diff --git a/src/styles/extended-utilities.css b/src/styles/extended-utilities.css index a1ff1c221..13ee9b42f 100644 --- a/src/styles/extended-utilities.css +++ b/src/styles/extended-utilities.css @@ -674,6 +674,7 @@ -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; + text-wrap: nowrap; } .two-line-text{