Skip to content

Commit

Permalink
chore(web): reorganize project creation code in webapp
Browse files Browse the repository at this point in the history
  • Loading branch information
stephane-ruhlmann committed Jan 14, 2025
1 parent 992c196 commit bce3a90
Show file tree
Hide file tree
Showing 176 changed files with 422 additions and 320 deletions.
2 changes: 1 addition & 1 deletion apps/web/src/app/application/rootReducer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { combineReducers } from "@reduxjs/toolkit";

import projectCreation from "@/features/create-project/application/createProject.reducer";
import projectCreation from "@/features/create-project/core/createProject.reducer";
import siteCreation from "@/features/create-site/application/createSite.reducer";
import siteMunicipalityData from "@/features/create-site/application/siteMunicipalityData.reducer";
import siteCarbonStorage from "@/features/create-site/application/siteSoilsCarbonStorage.reducer";
Expand Down
12 changes: 6 additions & 6 deletions apps/web/src/app/application/store.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { configureStore, Reducer } from "@reduxjs/toolkit";

import { SiteMunicipalityDataGateway as CreateProjectMunicipalityDataGateway } from "@/features/create-project/application/getSiteLocalAuthorities.action";
import { PhotovoltaicPerformanceGateway } from "@/features/create-project/application/renewable-energy/getPhotovoltaicExpectedPerformance.action";
import { SaveReconversionProjectGateway } from "@/features/create-project/application/saveReconversionProject.action";
import { SaveExpressReconversionProjectGateway } from "@/features/create-project/application/urban-project/urbanProject.actions";
import { SiteMunicipalityDataGateway as CreateProjectMunicipalityDataGateway } from "@/features/create-project/core/getSiteLocalAuthorities.action";
import { PhotovoltaicPerformanceGateway } from "@/features/create-project/core/renewable-energy/actions/getPhotovoltaicExpectedPerformance.action";
import { SaveReconversionProjectGateway } from "@/features/create-project/core/saveReconversionProject.action";
import { SaveExpressReconversionProjectGateway } from "@/features/create-project/core/urban-project/actions/urbanProject.actions";
import { SiteMunicipalityDataGateway as CreateSiteMunicipalityDataGateway } from "@/features/create-site/application/siteMunicipalityData.actions";
import { ReconversionProjectImpactsGateway } from "@/features/projects/application/fetchReconversionProjectImpacts.action";
import { ProjectFeaturesGateway } from "@/features/projects/application/project-features/projectFeatures.actions";
Expand All @@ -12,8 +12,8 @@ import { AppSettingsGateway } from "@/shared/app-settings/core/AppSettingsGatewa
import { CreateUserGateway } from "@/users/application/createUser.action";
import { CurrentUserGateway } from "@/users/application/initCurrentUser.action";

import { GetSitesByIdGateway } from "../../features/create-project/application/createProject.actions";
import { SoilsCarbonStorageGateway as ProjectSoilsCarbonStorageGateway } from "../../features/create-project/application/soilsCarbonStorage.action";
import { GetSitesByIdGateway } from "../../features/create-project/core/createProject.actions";
import { SoilsCarbonStorageGateway as ProjectSoilsCarbonStorageGateway } from "../../features/create-project/core/soilsCarbonStorage.action";
import { CreateSiteGateway } from "../../features/create-site/application/createSite.actions";
import { SoilsCarbonStorageGateway as SiteSoilsCarbonStorageGateway } from "../../features/create-site/application/siteSoilsCarbonStorage.actions";
import { ReconversionProjectsListGateway } from "../../features/projects/application/projectsList.actions";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { createStore, RootState } from "@/app/application/store";
import { AdministrativeDivisionMock } from "@/shared/infrastructure/administrative-division-service/administrativeDivisionMock";
import { getTestAppDependencies } from "@/test/testAppDependencies";

import { Address } from "../../domain/project.types";
import { getInitialState as getInitialProjectCreationState } from "../createProject.reducer";
import { fetchSiteLocalAuthorities } from "../getSiteLocalAuthorities.action";
import { Address } from "../project.types";
import { relatedSiteData } from "./siteData.mock";

const API_MOCKED_RESULT = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ProjectSite } from "../../domain/project.types";
import { ProjectSite } from "../project.types";

export const relatedSiteData = {
id: "28b53918-a6f6-43f2-9554-7b5434428f8b",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createAppAsyncThunk } from "@/app/application/appAsyncThunk";

import { ProjectSite } from "../domain/project.types";
import { ProjectSite } from "./project.types";

export interface GetSitesByIdGateway {
getById(siteId: string): Promise<ProjectSite | undefined>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import reduceReducers from "reduce-reducers";
import { DevelopmentPlanCategory } from "shared";
import { v4 as uuid } from "uuid";

import { ProjectSite } from "@/features/create-project/domain/project.types";
import { ProjectSite } from "@/features/create-project/core/project.types";

import { projectCreationInitiated } from "./createProject.actions";
import { fetchSiteLocalAuthorities } from "./getSiteLocalAuthorities.action";
Expand All @@ -12,7 +12,7 @@ import {
INITIAL_STATE as renenewableEnergyProjectInitialState,
renewableEnergyProjectReducer,
} from "./renewable-energy/renewableEnergy.reducer";
import { createModeStepReverted } from "./urban-project/urbanProject.actions";
import { createModeStepReverted } from "./urban-project/actions/urbanProject.actions";
import urbanProjectReducer, {
initialState as urbanProjectInitialState,
UrbanProjectState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {

import { RootState } from "@/app/application/store";

import { Address } from "../domain/project.types";
import { ProjectCreationState, ProjectCreationStep } from "./createProject.reducer";
import { Address } from "./project.types";

const selectSelf = (state: RootState) => state.projectCreation;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/unbound-method */
import { createStore } from "@/app/application/store";
import { ProjectSite } from "@/features/create-project/domain/project.types";
import { ProjectSite } from "@/features/create-project/core/project.types";
import { ExpectedPhotovoltaicPerformanceMock } from "@/features/create-project/infrastructure/photovoltaic-performance-service/photovoltaicPerformanceMock";
import { SitesServiceMock } from "@/features/create-project/infrastructure/sites-service/SitesServiceMock";
import { getTestAppDependencies } from "@/test/testAppDependencies";
Expand All @@ -9,8 +9,8 @@ import { projectCreationInitiated } from "../../createProject.actions";
import {
fetchPhotovoltaicExpectedAnnulPowerPerformanceForLocation,
PhotovoltaicPerformanceApiResult,
} from "../getPhotovoltaicExpectedPerformance.action";
import { completePhotovoltaicInstallationElectricalPower } from "../renewableEnergy.actions";
} from "../actions/getPhotovoltaicExpectedPerformance.action";
import { completePhotovoltaicInstallationElectricalPower } from "../actions/renewableEnergy.actions";

const API_MOCKED_RESULT = {
expectedPerformance: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReconversionProjectCreationData } from "@/features/create-project/domain/project.types";
import { ReconversionProjectCreationData } from "@/features/create-project/core/project.types";

export const projectWithMinimalData = {
relatedSiteId: "f590f643-cd9a-4187-8973-f90e9f1998c8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { buildUser } from "@/users/domain/user.mock";
import { InMemorySaveReconversionProjectService } from "../../../infrastructure/save-project-service/InMemorySaveReconversionProjectService";
import { relatedSiteData } from "../../__tests__/siteData.mock";
import { getInitialState } from "../../createProject.reducer";
import { saveReconversionProject } from "../saveReconversionProject.action";
import { saveReconversionProject } from "../actions/saveReconversionProject.action";
import { projectWithExhaustiveData, projectWithMinimalData } from "./projectData.mock";

describe("renewableEnergy.reducer.spec reducer", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import {
getRenewableEnergyProjectAvailableLocalAuthoritiesStakeholders,
getRenewableEnergyProjectAvailableStakeholders,
} from "../stakeholders.selectors";
} from "../selectors/stakeholders.selectors";
import { projectWithExhaustiveData, projectWithMinimalData } from "./projectData.mock";

const siteData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
PhotovoltaicKeyParameter,
ReconversionProjectCreationData,
Schedule,
} from "../../domain/project.types";
import { SoilsTransformationProject } from "../../domain/soilsTransformation";
} from "../../project.types";
import { SoilsTransformationProject } from "../soilsTransformation";

export function prefixActionType(actionType: string) {
return `projectCreation/renewableEnergyProject/${actionType}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createAppAsyncThunk } from "@/app/application/appAsyncThunk";

import { saveProjectSchema } from "../saveReconversionProject.action";
import { saveProjectSchema } from "../../saveReconversionProject.action";

export const saveReconversionProject = createAppAsyncThunk(
"projectCreation/renewableEnergyProject/save",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createAppAsyncThunk } from "@/app/application/appAsyncThunk";

import { selectSiteAddress, selectSiteSoilsDistribution } from "../createProject.selectors";
import { selectProjectSoilsDistribution } from "../renewable-energy/renewableEnergy.selector";
import { CurrentAndProjectedSoilsCarbonStorageResult } from "../soilsCarbonStorage.action";
import { selectSiteAddress, selectSiteSoilsDistribution } from "../../createProject.selectors";
import { CurrentAndProjectedSoilsCarbonStorageResult } from "../../soilsCarbonStorage.action";
import { selectProjectSoilsDistribution } from "../selectors/renewableEnergy.selector";
import { prefixActionType } from "./renewableEnergy.actions";

export const fetchCurrentAndProjectedSoilsCarbonStorage =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,11 @@ import {
} from "@reduxjs/toolkit";
import { SoilsDistribution, stripEmptySurfaces } from "shared";

import { ReconversionProjectCreationData } from "@/features/create-project/domain/project.types";
import { ReconversionProjectCreationData } from "@/features/create-project/core/project.types";

import {
getRecommendedPhotovoltaicPanelsAccessPathSurfaceArea,
getRecommendedPhotovoltaicPanelsFoundationsSurfaceArea,
} from "../../domain/photovoltaic";
import {
canSiteAccomodatePhotovoltaicPanels,
hasSiteSignificantBiodiversityAndClimateSensibleSoils,
preserveCurrentSoils,
transformNonSuitableSoils,
transformSoilsForRenaturation,
} from "../../domain/soilsTransformation";
import { ProjectCreationState } from "../createProject.reducer";
import { SoilsCarbonStorageResult } from "../soilsCarbonStorage.action";
import { fetchPhotovoltaicExpectedAnnulPowerPerformanceForLocation } from "./getPhotovoltaicExpectedPerformance.action";
import { fetchPhotovoltaicExpectedAnnulPowerPerformanceForLocation } from "./actions/getPhotovoltaicExpectedPerformance.action";
import {
completeNonSuitableSoilsNoticeStep,
completeNonSuitableSoilsSelectionStep,
Expand Down Expand Up @@ -99,9 +88,20 @@ import {
revertYearlyProjectedExpenses,
revertYearlyProjectedRevenue,
revertSoilsDecontaminationIntroductionStep,
} from "./renewableEnergy.actions";
import { saveReconversionProject } from "./saveReconversionProject.action";
import { fetchCurrentAndProjectedSoilsCarbonStorage } from "./soilsCarbonStorage.actions";
} from "./actions/renewableEnergy.actions";
import { saveReconversionProject } from "./actions/saveReconversionProject.action";
import { fetchCurrentAndProjectedSoilsCarbonStorage } from "./actions/soilsCarbonStorage.actions";
import {
getRecommendedPhotovoltaicPanelsAccessPathSurfaceArea,
getRecommendedPhotovoltaicPanelsFoundationsSurfaceArea,
} from "./photovoltaic";
import {
canSiteAccomodatePhotovoltaicPanels,
hasSiteSignificantBiodiversityAndClimateSensibleSoils,
preserveCurrentSoils,
transformNonSuitableSoils,
transformSoilsForRenaturation,
} from "./soilsTransformation";

export type RenewableEneryProjectState = {
saveState: "idle" | "loading" | "success" | "error";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createSelector } from "@reduxjs/toolkit";

import { selectSiteSurfaceArea } from "../../createProject.selectors";
import {
getRecommendedPhotovoltaicPanelsSurfaceAreaFromElectricalPower,
getRecommendedPowerKWcFromPhotovoltaicPanelsSurfaceArea,
} from "../../domain/photovoltaic";
import { selectSiteSurfaceArea } from "../createProject.selectors";
} from "../photovoltaic";
import { selectCreationData } from "./renewableEnergy.selector";

export const selectPhotovoltaicPanelsSurfaceArea = createSelector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { ProjectSchedule, ProjectScheduleBuilder, SoilsDistribution } from "shar
import { RootState } from "@/app/application/store";
import { RenewableEnergyDevelopmentPlanType } from "@/shared/domain/reconversionProject";

import { ProjectCreationState } from "../../createProject.reducer";
import { selectDefaultSchedule } from "../../createProject.selectors";
import { generateRenewableEnergyProjectName } from "../../projectName";
import {
computeDefaultPhotovoltaicOtherAmountExpenses,
computeDefaultPhotovoltaicTechnicalStudiesAmountExpenses,
Expand All @@ -12,11 +15,8 @@ import {
computeDefaultPhotovoltaicYearlyRecurringRevenueAmount,
computeDefaultPhotovoltaicYearlyRentAmount,
computeDefaultPhotovoltaicYearlyTaxesAmount,
} from "../../domain/photovoltaic";
import { generateRenewableEnergyProjectName } from "../../domain/projectName";
import { ProjectCreationState } from "../createProject.reducer";
import { selectDefaultSchedule } from "../createProject.selectors";
import { RenewableEneryProjectState } from "./renewableEnergy.reducer";
} from "../photovoltaic";
import { RenewableEneryProjectState } from "../renewableEnergy.reducer";

const selectSelf = (state: RootState) => state.projectCreation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { SoilsDistribution, SoilType, sumSoilsSurfaceAreasWhere } from "shared";

import { typedObjectKeys } from "@/shared/services/object-keys/objectKeys";

import { selectSiteData, selectSiteSoilsDistribution } from "../../createProject.selectors";
import {
getBioversityAndClimateSensitiveSoilsSurfaceAreaDestroyed,
getNonSuitableSoilsForPhotovoltaicPanels,
getSuitableSoilsForTransformation,
getSuitableSurfaceAreaForPhotovoltaicPanels,
isBiodiversityAndClimateSensibleSoil,
willTransformationNoticeablyImpactBiodiversityAndClimate,
} from "../../domain/soilsTransformation";
import { selectSiteData, selectSiteSoilsDistribution } from "../createProject.selectors";
} from "../soilsTransformation";
import { selectPhotovoltaicPanelsSurfaceArea } from "./photovoltaicPowerStation.selectors";
import { selectCreationData, selectProjectSoilsDistribution } from "./renewableEnergy.selector";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { createSelector } from "@reduxjs/toolkit";

import { ProjectStakeholder } from "../../domain/project.types";
import { ProjectStakeholder } from "../../project.types";
import {
AvailableProjectStakeholder,
getAvailableLocalAuthoritiesStakeholders,
getProjectAvailableStakeholders,
hasStakeholder,
} from "../stakeholders.selectors";
} from "../../stakeholders.selectors";
import { selectCreationData } from "./renewableEnergy.selector";

export const getRenewableEnergyProjectAvailableStakeholders = createSelector(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { createSelector } from "@reduxjs/toolkit";
import { SoilsDistribution, SoilType, sumSoilsSurfaceAreasWhere } from "shared";

import { typedObjectKeys } from "@/shared/services/object-keys/objectKeys";

import { selectSiteData, selectSiteSoilsDistribution } from "../createProject.selectors";
import { selectPhotovoltaicPanelsSurfaceArea } from "./selectors/photovoltaicPowerStation.selectors";
import {
selectCreationData,
selectProjectSoilsDistribution,
} from "./selectors/renewableEnergy.selector";
import {
getNonSuitableSoilsForPhotovoltaicPanels,
getSuitableSoilsForTransformation,
getSuitableSurfaceAreaForPhotovoltaicPanels,
isBiodiversityAndClimateSensibleSoil,
willTransformationNoticeablyImpactBiodiversityAndClimate,
getBioversityAndClimateSensitiveSoilsSurfaceAreaDestroyed,
} from "./soilsTransformation";

export const selectSuitableSurfaceAreaForPhotovoltaicPanels = createSelector(
selectSiteData,
(state): number => {
return getSuitableSurfaceAreaForPhotovoltaicPanels(state?.soilsDistribution ?? {});
},
);

export const selectNonSuitableSoilsForPhototovoltaicPanels = createSelector(
selectSiteData,
(state): SoilsDistribution => {
return state ? getNonSuitableSoilsForPhotovoltaicPanels(state.soilsDistribution) : {};
},
);

export const selectMissingSuitableSurfaceAreaForPhotovoltaicPanels = createSelector(
[selectPhotovoltaicPanelsSurfaceArea, selectSuitableSurfaceAreaForPhotovoltaicPanels],
(neededSurfaceArea, suitableSurfaceArea): number => {
return neededSurfaceArea - suitableSurfaceArea;
},
);

const selectNonSuitableSoilsSelected = createSelector(
selectCreationData,
(creationData): SoilType[] => creationData.nonSuitableSoilsToTransform ?? [],
);

export const selectNonSuitableSoilsForPhototovoltaicPanelsToTransform = createSelector(
[selectNonSuitableSoilsForPhototovoltaicPanels, selectNonSuitableSoilsSelected],
(nonSuitableSoils, selectedNonSuitableSoilsToTransform): SoilsDistribution => {
return typedObjectKeys(nonSuitableSoils)
.filter((soilType) => selectedNonSuitableSoilsToTransform.includes(soilType))
.reduce((soilsDistribution, soilType) => {
return { ...soilsDistribution, [soilType]: nonSuitableSoils[soilType] };
}, {});
},
);

export const selectFutureSoils = createSelector(selectCreationData, (creationData): SoilType[] => {
return creationData.futureSoilsSelection ?? [];
});

export const selectBiodiversityAndClimateSensibleSoilsSurfaceAreaDestroyed = createSelector(
[selectSiteSoilsDistribution, selectProjectSoilsDistribution],
(siteSoilsDistribution, projectSoilsDistribution): number => {
return getBioversityAndClimateSensitiveSoilsSurfaceAreaDestroyed(
siteSoilsDistribution,
projectSoilsDistribution,
);
},
);

export const selectWillSoilsTransformationHaveNegativeImpactOnBiodiversityAndClimate =
createSelector(
[selectSiteSoilsDistribution, selectProjectSoilsDistribution],
(siteSoilsDistribution, projectSoilsDistribution): boolean => {
return willTransformationNoticeablyImpactBiodiversityAndClimate(
siteSoilsDistribution,
projectSoilsDistribution,
);
},
);

export const selectFutureBiodiversityAndClimateSensibleSoilsSurfaceArea = createSelector(
selectProjectSoilsDistribution,
(futureSoilsDistribution): number => {
return sumSoilsSurfaceAreasWhere(futureSoilsDistribution, isBiodiversityAndClimateSensibleSoil);
},
);

export const selectBaseSoilsDistributionForTransformation = createSelector(
selectCreationData,
selectSiteData,
(creationData, siteData): SoilsDistribution => {
return creationData.baseSoilsDistributionForTransformation ?? siteData?.soilsDistribution ?? {};
},
);

export const selectTransformableSoils = createSelector(
selectBaseSoilsDistributionForTransformation,
(baseSoilsDistributionForTransformation): SoilType[] => {
const currentSoils = typedObjectKeys(baseSoilsDistributionForTransformation);
return getSuitableSoilsForTransformation(currentSoils);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { LocalAuthority } from "shared/dist/local-authority";

import { RootState } from "@/app/application/store";

import { ProjectStakeholderStructure } from "../domain/project.types";
import { selectSiteData } from "./createProject.selectors";
import { ProjectStakeholderStructure } from "./project.types";

export type AvailableProjectStakeholder = {
name: string;
Expand Down
Loading

0 comments on commit bce3a90

Please sign in to comment.