Skip to content
Extraits de code Groupes Projets
Valider faec20cb rédigé par Oussama Toumi's avatar Oussama Toumi
Parcourir les fichiers

Integrate getAmendmentByCircuit function

parent 22df097f
Branches
Étiquettes
1 requête de fusion!307Resolve VSN-1282 "Feature/integrate ammendment circuit"
......@@ -3,6 +3,7 @@ import { Etat, IAvenant } from "../types/circuit";
import { SelectedDaysType } from "../types/usager";
import dayjs from "dayjs";
import { WeeklyScheduleType } from "../sections/usager/components/usager-form/avenants-horaires/types/formik-types";
import { AmendmentCircuit } from "../types/ammendment-circuit";
export const _AVENANT_TYPE_MODIFICATIONS = [
"Changement d'adresse",
......@@ -74,22 +75,24 @@ export const DEFAULT_AVENANT_TABLE_HEAD: TableColumn[] = [
{ id: '', label: 'Action' },
];
export const INITIAL_AVENANT_DATA: IAvenant = {
export const INITIAL_AVENANT_DATA: AmendmentCircuit = {
id: '',
dateApplication: '',
etat: 'non_controle',
codeCircuit: '',
codeAvenant: '',
intitule: '',
objetAvenant: '',
type: '',
dateFin: '',
etablissement: '',
chauffeur: '',
departement: '',
clientDO: '',
subject: '',
observation: '',
creationType: '',
actionType: '',
startDate: '',
endDate: '',
amendmentType: '',
circuitState: '',
amendmentCode: '',
calculationType: '',
distanceKm: 0,
url: '',
idPassenger: [],
idTrips: [],
isActive: true,
objet: '',
circuitId: '',
};
export const MOCKED_SCHEDULE_DATA: WeeklyScheduleType = {
......
const endpointPrefix = '/api/circuit/amendment';
export const circuitAmendmentEndpoints = {
amendments: {
getByCircuitId: (circuitId: string) => endpointPrefix + `/byCircuitId/${circuitId}`,
},
};
import { create } from "zustand";
import axiosInstance from "@/utils/axios";
import { AddPassengerToCircuit, AddPassengersToCircuitResponse } from "@/shared/types/circuit";
import { circuitEndpoints } from "../../endpoints/circuit";
import { AmendmentCircuit } from "@/shared/types/ammendment-circuit";
import { circuitAmendmentEndpoints } from "../../endpoints/amendments";
import { SearchAmendmentCircuitParams } from "@/shared/types/ammendment-circuit";
import { Pageable } from "@/shared/types/client";
type AmendmentCircuitStore = {
loading: boolean;
error: string | null;
circuitAmendments: AmendmentCircuit[];
totalElements: number;
getAmendmentsByCircuitId: (params: SearchAmendmentCircuitParams) => Promise<void>;
};
export const useAmendmentCircuitStore = create<AmendmentCircuitStore>((set) => ({
loading: false,
error: null,
circuitAmendments: [],
totalElements: 0,
getAmendmentsByCircuitId: async (params: SearchAmendmentCircuitParams) => {
set({ loading: true, error: null });
try {
const response = await axiosInstance.get<Pageable<AmendmentCircuit>>(
circuitAmendmentEndpoints.amendments.getByCircuitId(params.circuitId.toString()),
{ params }
);
set({
loading: false,
circuitAmendments: response.data.content,
totalElements: response.data.totalElements
});
} catch (error: any) {
set({
error: error.message || "Erreur lors de la récupération des usagers du circuit",
loading: false,
});
throw error;
}
}
}));
\ No newline at end of file
......@@ -2,19 +2,17 @@
import React from 'react';
import { useTheme } from '@mui/material/styles';
import { Box, Stack, IconButton, TableCell, Checkbox } from '@mui/material';
import { faArrowUpRightFromSquare, faFileExport, faRotate } from '@fortawesome/free-solid-svg-icons';
import { Box, Stack, IconButton, TableCell } from '@mui/material';
import { faArrowUpRightFromSquare, faRotate } from '@fortawesome/free-solid-svg-icons';
import { ActionsIconButton, iconButtonStyles } from '@/shared/theme/css';
import FontAwesome from '@/shared/components/fontawesome';
import CustomTooltip from '@/shared/components/tooltips/tooltip-custom';
import { TableConfig, useTableManager } from '@/hooks/use-table-manager';
import { IAvenant } from '@/shared/types/circuit';
import { _avenants, DEFAULT_AVENANT_CIRCUIT_TABLE_HEAD, INITIAL_AVENANT_DATA } from '@/shared/_mock/_avenants';
import { circuitStateOptions, IAvenant } from '@/shared/types/circuit';
import { _avenants, INITIAL_AVENANT_DATA } from '@/shared/_mock/_avenants';
import TableManager from '@/shared/components/table/table-manager';
import { dateFormat, formatDate } from '@/utils/format-time';
import { StatusChip, TrajetStyledRow } from '@/shared/sections/contract/styles';
import { AntSwitch } from '@/shared/components/table/styles';
import { getEtatLabel } from '@/shared/_mock/_circuit';
import { _CIRCUIT_STATUS, getEtatLabel } from '@/shared/_mock/_circuit';
import { useRouter } from '@/hooks/use-router';
import { paths } from '@/routes/paths';
import { TabConfig, useTabsManager } from '@/hooks/use-tabs-manager';
......@@ -22,21 +20,19 @@ import TabsCustom from '@/shared/components/tabs/tabs-custom';
import AvenantForm from '@/shared/sections/avenant/view/avenant-new-view';
import ExportButton from '@/shared/components/table/table-export-button';
import { TableType } from '@/shared/types/common';
import { useAmendmentCircuitTable } from './hooks/use-amendment-circuit-table';
import { AmendmentCircuit } from '@/shared/types/ammendment-circuit';
import { getLabel } from '@/shared/_mock';
const avenantConfig: TableConfig<IAvenant> = {
initialData: _avenants(true),
defaultTableHead: DEFAULT_AVENANT_CIRCUIT_TABLE_HEAD,
};
const avenantTabsConfig: TabConfig<IAvenant> = {
const avenantTabsConfig: TabConfig<AmendmentCircuit> = {
type: 'avenant',
listTitle: 'Liste des avenants',
newItemTitle: 'Nouveau avenant',
initialData: INITIAL_AVENANT_DATA,
getItemCode: (avenant) => avenant.intitule,
getItemCode: (avenant) => avenant.subject,
};
export default function AvenantList() {
export default function AvenantList({ circuitId }: { circuitId: string }) {
const theme = useTheme();
const router = useRouter();
......@@ -49,7 +45,7 @@ export default function AvenantList() {
handleEdit,
handleView,
handleCancel,
} = useTabsManager<IAvenant>(avenantTabsConfig);
} = useTabsManager<AmendmentCircuit>(avenantTabsConfig);
const {
table,
......@@ -63,7 +59,8 @@ export default function AvenantList() {
handleResetColumns,
handleColumnsChange,
handleSave,
} = useTableManager<IAvenant>(avenantConfig);
} = useAmendmentCircuitTable(Number.parseInt(circuitId));
const activeTabData = React.useMemo(() => {
return tabs.find((tab) => tab.id === activeTab);
}, [tabs, activeTab]);
......@@ -74,19 +71,19 @@ export default function AvenantList() {
const renderCellContent = (columnId: string, value: any) => {
switch (columnId) {
case 'dateApplication':
case 'dateFin':
case 'startDate':
case 'endDate':
return formatDate(value, dateFormat.isoDate);
case 'etat':
case 'circuitState':
return (
<StatusChip label={getEtatLabel(value)} status={value} theme={theme} size="small" />
<StatusChip label={getLabel(value, circuitStateOptions)} status={value} theme={theme} size="small" />
);
default:
return value;
}
};
const renderRow = (row: IAvenant) => {
const renderRow = (row: AmendmentCircuit) => {
return (
<TrajetStyledRow
......@@ -102,7 +99,7 @@ export default function AvenantList() {
align={column.align || 'left'}
sx={{ whiteSpace: 'nowrap', py: column.id === 'etat' ? 0.2 : table.dense ? 0.5 : 1 }}
>
{renderCellContent(column.id, row[column.id as keyof IAvenant])}
{renderCellContent(column.id, row[column.id as keyof AmendmentCircuit])}
</TableCell>
))}
<TableCell
......@@ -113,7 +110,7 @@ export default function AvenantList() {
}}
>
<CustomTooltip title={'Consulter avenant'} arrow>
<IconButton onClick={()=> openAvenantPage(row.codeAvenant)} size="small" sx={ActionsIconButton}>
<IconButton onClick={()=> openAvenantPage(row.amendmentCode)} size="small" sx={ActionsIconButton}>
<FontAwesome icon={faArrowUpRightFromSquare} width={14} />
</IconButton>
</CustomTooltip>
......@@ -161,11 +158,13 @@ export default function AvenantList() {
sx={{ backgroundColor: 'primary.lighter' }}
fixedHeight={'450px'}
/>
</>):(
</>):
(
<AvenantForm
avenant={activeTabData?.content as IAvenant}
avenant={{} as IAvenant}
mode={activeTabData?.mode || 'view'}
onClose={() => handleCancel(activeTab)}
onClose={(isSaved) => handleCancel(activeTab, isSaved)}
tabId={activeTab}
hasBorder
tableHead={tableHead}
/>
......
import { TableConfig, useTableManager } from '@/hooks/use-table-manager';
import { TableType } from '@/shared/types/common';
import { useAmendmentPassengerStore } from '@/shared/api/stores/circuit-service/amendmentPassengerStore';
import { useEffect, useState, useCallback } from 'react';
import { AmendmentPassengerList, AmendmentPassengerDetails, SearchPassengerAmendmentParams } from '@/shared/types/ammendment-passenger';
import { enqueueSnackbar } from 'notistack';
import { DEFAULT_AMENDMENT_PASSENGER_CIRCUIT_TABLE_HEAD, DEFAULT_AMENDMENT_PASSENGER_TABLE_HEAD } from '@/shared/_mock/_avenantUsager';
import { useAmendmentCircuitStore } from '@/shared/api/stores/circuit-service/amendmentCircuitStore';
import { AmendmentCircuit, SearchAmendmentCircuitParams } from '@/shared/types/ammendment-circuit';
import { DEFAULT_AVENANT_CIRCUIT_TABLE_HEAD } from '@/shared/_mock/_avenants';
export const getAmendmentParams = (circuitId: number) => {
const params: SearchAmendmentCircuitParams = {
circuitId,
page: 0,
size: 20,
};
return params;
}
export function useAmendmentCircuitTable(circuitId: number) {
const [params, setParams] = useState<SearchAmendmentCircuitParams>(getAmendmentParams(circuitId));
const { circuitAmendments, loading, error, getAmendmentsByCircuitId, totalElements } = useAmendmentCircuitStore();
const amendmentConfig: TableConfig<AmendmentCircuit> = {
type: TableType.Avenant,
initialData: circuitAmendments || [],
defaultTableHead: DEFAULT_AVENANT_CIRCUIT_TABLE_HEAD,
};
const tableManager = useTableManager<AmendmentCircuit>(amendmentConfig);
useEffect(() => {
const baseParams: SearchAmendmentCircuitParams = {
circuitId,
page: tableManager.table.page || 0,
size: tableManager.table.rowsPerPage || 20,
};
const filterParams: Record<string, string | number> = {};
Object.entries(tableManager.filters).forEach(([key, { value }]) => {
if (value !== undefined && value !== null && value !== '') {
filterParams[key] = value;
}
});
const newParams: SearchAmendmentCircuitParams = {
...filterParams,
...baseParams,
};
const paramsChanged = JSON.stringify(newParams) !== JSON.stringify(params);
if (paramsChanged) {
setParams(newParams);
}
}, [circuitId, tableManager.table.page, tableManager.filters, tableManager.table.rowsPerPage, tableManager.table.orderBy, tableManager.table.order]);
useEffect(() => {
const fetch = async () => {
try {
await getAmendmentsByCircuitId(params);
} catch (error: any) {
enqueueSnackbar(error.message || 'Erreur lors de la recherche des avenants', { variant: 'error' });
}
};
fetch();
}, [params, getAmendmentsByCircuitId]);
return {
...tableManager,
loading,
error,
totalAmendments: totalElements || 0,
};
}
......@@ -122,7 +122,7 @@ export default function CircuitForm({ circuit, mode, onSave, onClose, onEdit, up
),
},
{ label: 'Usagers', content: <CircuitUsager circuitId={circuit.id} />, disabled: isAddMode },
{ label: 'Avenants', content: <AvenantList />, disabled: isAddMode },
{ label: 'Avenants', content: <AvenantList circuitId={circuit.id} />, disabled: isAddMode },
{ label: 'Trajets', content: <CircuittrajetsForm useTabs/>, disabled: isAddMode },
{ label: 'Contrats', content: <ContratForm />, disabled: isAddMode },
{ label: 'Chauffeurs', content: <ChauffeurList />, disabled: isAddMode },
......
import { IBaseEntity } from "./client";
export interface Amendment extends IBaseEntity{
subject: string;
observation: string;
isActive: boolean;
circuitId: string;
creationType: string;
actionType: string;
startDate: string;
endDate: string;
amendmentType: string;
}
export interface AmendmentCircuit extends Amendment {
circuitState: string;
amendmentCode: string;
calculationType: string;
distanceKm: number;
url: string;
idPassenger: number[];
idTrips: number[];
}
export interface SearchAmendmentCircuitParams {
circuitId: number;
page?: number;
size?: number;
}
\ No newline at end of file
0% ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter