Skip to content

Commit

Permalink
chore: sauvegarde
Browse files Browse the repository at this point in the history
  • Loading branch information
ocruze committed Oct 9, 2024
1 parent 963f2e1 commit f82f64f
Show file tree
Hide file tree
Showing 21 changed files with 845 additions and 55 deletions.
9 changes: 9 additions & 0 deletions assets/@types/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export enum DatasheetDocumentTypeEnum {
export type DatasheetDetailed = Datasheet & {
vector_db_list: VectorDb[] | undefined;
pyramid_vector_list: PyramidVector[] | undefined;
pyramid_raster_list: PyramidRaster[] | undefined;
upload_list: Upload[] | undefined;
service_list: Service[] | undefined;
};
Expand Down Expand Up @@ -112,6 +113,14 @@ export type PyramidVector = StoredData & {
};
};

/** stored_data (donnée stockée) du type ROK4-PYRAMID-VECTOR */
export type PyramidRaster = StoredData & {
type: StoredDataPrivateDetailResponseDtoTypeEnum.ROK4PYRAMIDRASTER;
tags: {
datasheet_name?: string;
};
};

/** upload (livraison) */
export type Upload = UploadPrivateDetailResponseDto & {
tags: {
Expand Down
9 changes: 4 additions & 5 deletions assets/components/Utils/ZoomRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,24 @@ const ZoomRange: FC<ZoomRangeProps> = (props) => {
<div className={fr.cx("fr-my-2v")}>
<div className={fr.cx("fr-grid-row")}>
{(mode === "both" || mode === "top") && (
<div className={fr.cx("fr-col-6", "fr-px-2v")}>
<div className={fr.cx("fr-col", "fr-px-2v")}>
<div ref={leftMapTargetRef} className={cx(classes.map)} />
</div>
)}

{mode !== "both" && (
<div className={cx(fr.cx("fr-col-6", "fr-px-2v"))}>
<div className={cx(fr.cx("fr-col", "fr-px-2v"))}>
<div className={cx(classes.falseMapRoot)}>
<img src={mode === "top" ? imgMapZoomBottom : imgMapZoomTop} className={cx(classes.map, classes.falseMapImg)} />
<div className={cx(classes.falseMapOverlay)}>
{overlayContent && <div className={cx(classes.falseMapOverlayContent)}>{overlayContent}</div>}
{overlayContent && <div className={cx(fr.cx("fr-m-4v", "fr-p-2v"), classes.falseMapOverlayContent)}>{overlayContent}</div>}
</div>
</div>
</div>
)}

{(mode === "both" || mode === "bottom") && (
<div className={fr.cx("fr-col-6", "fr-px-2v")}>
<div className={fr.cx("fr-col", "fr-px-2v")}>
<div ref={rightMapTargetRef} className={cx(classes.map)} />
</div>
)}
Expand Down Expand Up @@ -248,6 +248,5 @@ const useStyles = tss.withName(ZoomRange.displayName).create(() => ({
falseMapOverlayContent: {
backgroundColor: fr.colors.decisions.background.default.grey.default,
color: fr.colors.decisions.text.default.grey.default,
padding: fr.spacing("2v"),
},
}));
2 changes: 2 additions & 0 deletions assets/entrepot/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import user from "./user";
import wfs from "./wfs";
import wmsVector from "./wms-vector";
import pyramidVector from "./pyramidVector";
import pyramidRaster from "./pyramidRaster";
import service from "./service";
import epsg from "./epsg";
import annexe from "./annexe";
Expand All @@ -32,6 +33,7 @@ const api = {
wfs,
wmsVector,
pyramidVector,
pyramidRaster,
service,
annexe,
style,
Expand Down
22 changes: 22 additions & 0 deletions assets/entrepot/api/pyramidRaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import SymfonyRouting from "../../modules/Routing";
import { jsonFetch } from "../../modules/jsonFetch";
import type { PyramidRaster } from "../../@types/app";

const add = (datastoreId: string, formData: FormData | object) => {
const url = SymfonyRouting.generate("cartesgouvfr_api_pyramid_raster_add", { datastoreId });
return jsonFetch<PyramidRaster>(
url,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
},
formData
);
};

export default {
add,
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { routes } from "../../../../../router/router";
import PyramidVectorList from "./PyramidVectorList/PyramidVectorList";
import UnfinishedUploadList from "./UnfinishedUploadList";
import VectorDbList from "./VectorDbList/VectorDbList";
import PyramidRasterList from "./PyramidRasterList/PyramidRasterList";

type DataListTabProps = {
datastoreId: string;
Expand Down Expand Up @@ -55,6 +56,11 @@ const DatasetListTab: FC<DataListTabProps> = ({ datastoreId, datasheet }) => {
<PyramidVectorList datastoreId={datastoreId} datasheetName={datasheet.name} pyramidList={datasheet.pyramid_vector_list} />
</div>
</div>
<div className={fr.cx("fr-grid-row", "fr-grid-row--center", "fr-grid-row--middle", "fr-mt-4w")}>
<div className={fr.cx("fr-col")}>
<PyramidRasterList datastoreId={datastoreId} datasheetName={datasheet.name} pyramidList={datasheet.pyramid_raster_list} />
</div>
</div>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { fr } from "@codegouvfr/react-dsfr";
import { FC, memo } from "react";
import { symToStr } from "tsafe/symToStr";

import { PyramidRaster } from "../../../../../../@types/app";
import PyramidRasterListItem from "./PyramidRasterListItem";

type PyramidRasterListProps = {
datasheetName: string;
datastoreId: string;
pyramidList: PyramidRaster[] | undefined;
};

const PyramidRasterList: FC<PyramidRasterListProps> = ({ datasheetName, datastoreId, pyramidList }) => {
return (
<>
<div className={fr.cx("fr-grid-row")}>
<h5>
<i className={"ri-stack-line"} />
&nbsp;Pyramides de tuiles raster ({pyramidList?.length})
</h5>
</div>
{pyramidList?.map((pyramid) => (
<PyramidRasterListItem key={pyramid._id} datasheetName={datasheetName} datastoreId={datastoreId} pyramid={pyramid} />
))}
</>
);
};

PyramidRasterList.displayName = symToStr({ PyramidRasterList });

export default memo(PyramidRasterList);
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import { fr } from "@codegouvfr/react-dsfr";
import Alert from "@codegouvfr/react-dsfr/Alert";
import Badge from "@codegouvfr/react-dsfr/Badge";
import Button from "@codegouvfr/react-dsfr/Button";
import { createModal } from "@codegouvfr/react-dsfr/Modal";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { FC, memo, useMemo } from "react";
import { createPortal } from "react-dom";

import { PyramidRaster, StoredDataStatusEnum } from "../../../../../../@types/app";
import StoredDataStatusBadge from "../../../../../../components/Utils/Badges/StoredDataStatusBadge";
import LoadingIcon from "../../../../../../components/Utils/LoadingIcon";
import LoadingText from "../../../../../../components/Utils/LoadingText";
import MenuList from "../../../../../../components/Utils/MenuList";
import Wait from "../../../../../../components/Utils/Wait";
import useToggle from "../../../../../../hooks/useToggle";
import { Translations, declareComponentKeys, getTranslation, useTranslation } from "../../../../../../i18n/i18n";
import RQKeys from "../../../../../../modules/entrepot/RQKeys";
import { routes } from "../../../../../../router/router";
import { formatDateFromISO, offeringTypeDisplayName } from "../../../../../../utils";
import api from "../../../../../api";
// import PyramidRasterDesc from "./PyramidRasterDesc";

type PyramidRasterListItemProps = {
datasheetName: string;
pyramid: PyramidRaster;
datastoreId: string;
};

const { t: tCommon } = getTranslation("Common");

const PyramidRasterListItem: FC<PyramidRasterListItemProps> = ({ datasheetName, datastoreId, pyramid }) => {
const { t } = useTranslation({ PyramidRasterListItem });

const [showDescription, toggleShowDescription] = useToggle(false);

const dataUsesQuery = useQuery({
queryKey: RQKeys.datastore_stored_data_uses(datastoreId, pyramid._id),
queryFn: ({ signal }) => api.storedData.getUses(datastoreId, pyramid._id, { signal }),
staleTime: 600000,
enabled: showDescription,
});

/* Suppression de la pyramide */
const queryClient = useQueryClient();

const deletePyramidMutation = useMutation({
mutationFn: () => api.storedData.remove(datastoreId, pyramid._id),
onSuccess() {
if (datasheetName) {
queryClient.invalidateQueries({ queryKey: RQKeys.datastore_datasheet(datastoreId, datasheetName) });
}
},
});

const confirmRemovePyramidModal = useMemo(
() =>
createModal({
id: `confirm-delete-pyramid-${pyramid._id}`,
isOpenedByDefault: false,
}),
[pyramid._id]
);

return (
<>
<div className={fr.cx("fr-p-2v", "fr-mt-2v")} style={{ backgroundColor: fr.colors.decisions.background.contrast.grey.default }}>
<div className={fr.cx("fr-grid-row", "fr-grid-row--middle")}>
<div className={fr.cx("fr-col")}>
<div className={fr.cx("fr-grid-row", "fr-grid-row--middle", "fr-my-2v")}>
<Button
iconId={showDescription ? "ri-subtract-fill" : "ri-add-fill"}
size="small"
title={t("show_linked_datas")}
className={fr.cx("fr-mr-2v")}
priority="secondary"
onClick={toggleShowDescription}
/>
{pyramid.name}
{pyramid.tags?.is_sample === "true" && (
<Badge noIcon={true} severity={"info"} className={fr.cx("fr-ml-2v")}>
Echantillon
</Badge>
)}
</div>
</div>

<div className={fr.cx("fr-col")}>
<div className={fr.cx("fr-grid-row", "fr-grid-row--right", "fr-grid-row--middle")}>
<p className={fr.cx("fr-m-auto", "fr-mr-2v")}>{pyramid?.last_event?.date && formatDateFromISO(pyramid?.last_event?.date)}</p>
<StoredDataStatusBadge status={pyramid.status} />
<Button
onClick={() => {
// routes.datastore_pyramid_Raster_tms_service_new({ datastoreId, pyramidId: pyramid._id, datasheetName }).push();
}}
className={fr.cx("fr-mr-2v")}
priority="secondary"
disabled={pyramid.status !== StoredDataStatusEnum.GENERATED}
>
{t("publish_tms_service")}
</Button>
<MenuList
menuOpenButtonProps={{
iconId: "fr-icon-menu-2-fill",
title: t("other_actions"),
priority: "secondary",
}}
// disabled={pyramid.status !== StoredDataStatuses.GENERATED}
items={[
{
text: t("show_details"),
iconId: "fr-icon-file-text-fill",
linkProps: routes.datastore_stored_data_details({ datastoreId, storedDataId: pyramid._id }).link,
},
{
text: tCommon("delete"),
iconId: "fr-icon-delete-line",
onClick: () => confirmRemovePyramidModal.open(),
},
]}
/>
</div>
</div>
</div>
{/* {showDescription && <PyramidRasterDesc datastoreId={datastoreId} pyramid={pyramid} dataUsesQuery={dataUsesQuery} />} */}
</div>
{deletePyramidMutation.error && (
<Alert
title={t("error_deleting", { pyramidName: pyramid.name })}
closable
description={deletePyramidMutation.error.message}
as="h2"
severity="error"
/>
)}
{deletePyramidMutation.isPending && (
<Wait>
<div className={fr.cx("fr-container")}>
<div className={fr.cx("fr-grid-row", "fr-grid-row--middle")}>
<LoadingIcon className={fr.cx("fr-mr-2v")} />
<h6 className={fr.cx("fr-m-0")}>{tCommon("removing")}</h6>
</div>
</div>
</Wait>
)}
{createPortal(
<confirmRemovePyramidModal.Component
title={t("confirm_delete_modal.title", { pyramidName: pyramid.name })}
buttons={[
{
children: tCommon("no"),
priority: "secondary",
},
{
children: tCommon("yes"),
onClick: () => deletePyramidMutation.mutate(),
priority: "primary",
},
]}
>
{dataUsesQuery.isFetching && <LoadingText withSpinnerIcon={true} />}

{dataUsesQuery.data?.offerings_list && dataUsesQuery.data?.offerings_list?.length > 0 && (
<div className={fr.cx("fr-grid-row", "fr-mt-2v", "fr-p-2v")}>
<p className={fr.cx("fr-h6")}>{t("following_services_deleted")}</p>
<div className={fr.cx("fr-col")}>
<ul className={fr.cx("fr-raw-list")}>
{dataUsesQuery.data?.offerings_list.map((offering, i) => (
<li
key={offering._id}
className={fr.cx(i + 1 !== dataUsesQuery.data?.offerings_list.length && "fr-mb-2v", "fr-text--xs")}
>
{offering.layer_name}
<Badge className={fr.cx("fr-ml-1v", "fr-text--xs")}>{offeringTypeDisplayName(offering.type)}</Badge>
</li>
))}
</ul>
</div>
</div>
)}
</confirmRemovePyramidModal.Component>,
document.body
)}
</>
);
};

export default memo(PyramidRasterListItem);

// traductions
export const { i18n } = declareComponentKeys<
| "show_linked_datas"
| "other_actions"
| "show_details"
| "publish_tms_service"
| { K: "confirm_delete_modal.title"; P: { pyramidName: string }; R: string }
| "following_services_deleted"
| { K: "error_deleting"; P: { pyramidName: string }; R: string }
>()({
PyramidRasterListItem,
});

export const PyramidRasterListItemFrTranslations: Translations<"fr">["PyramidRasterListItem"] = {
show_linked_datas: "Voir les données liées",
other_actions: "Autres actions",
show_details: "Voir les détails",
publish_tms_service: "Publier le service TMS",
"confirm_delete_modal.title": ({ pyramidName }) => `Êtes-vous sûr de vouloir supprimer la pyramide ${pyramidName} ?`,
following_services_deleted: "Les services suivants seront aussi supprimés :",
error_deleting: ({ pyramidName }) => `La suppression de la pyramide ${pyramidName} a échoué`,
};

export const PyramidRasterListItemEnTranslations: Translations<"en">["PyramidRasterListItem"] = {
show_linked_datas: "Show linked datas",
other_actions: "Other actions",
show_details: "Show details",
publish_tms_service: "Publish TMS service",
"confirm_delete_modal.title": ({ pyramidName }) => `Are you sure you want to delete pyramid ${pyramidName} ?`,
following_services_deleted: "The following services will be deleted :",
error_deleting: ({ pyramidName }) => `Deleting ${pyramidName} pyramid failed`,
};
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,10 @@ const DatasheetView: FC<DatasheetViewProps> = ({ datastoreId, datasheetName }) =
},
{
label: t("tab_label.datasets", {
num: (datasheetQuery.data?.vector_db_list?.length || 0) + (datasheetQuery.data?.pyramid_vector_list?.length || 0),
num:
(datasheetQuery.data?.vector_db_list?.length || 0) +
(datasheetQuery.data?.pyramid_vector_list?.length || 0) +
(datasheetQuery.data?.pyramid_raster_list?.length || 0),
}),
tabId: DatasheetViewActiveTabEnum.Dataset,
},
Expand Down
Loading

0 comments on commit f82f64f

Please sign in to comment.