Skip to content
Extraits de code Groupes Projets
Valider c5500a28 rédigé par Mohsine's avatar Mohsine
Parcourir les fichiers

Merge branch 'feature/VSN-1172' into 'develop'

Resolve VSN-1172 "Feature/Integrate status update in passenger list, Prevent sorting by circuit in schedule amendment"

Closes VSN-1172

See merge request !294
parents 3fcde351 7caba45e
Branches
Étiquettes v0.0.89
1 requête de fusion!294Resolve VSN-1172 "Feature/Integrate status update in passenger list, Prevent sorting by circuit in schedule amendment"
Pipeline #22027 réussi avec l'étape
in 20 secondes
......@@ -31,8 +31,8 @@ export const DEFAULT_AMENDMENT_PASSENGER_TABLE_HEAD: TableColumn[] = [
{ id: 'id', label: 'N° Avenant', type: 'text' },
{ id: 'startDate', label: 'A partir du', type: 'date' },
{ id: 'subject', label: 'Objet de l\'avenant', type: 'text' },
{ id: 'circuitCode', label: 'Code', type: 'text' },
{ id: 'circuitName', label: 'Circuit', type: 'text' },
{ id: 'circuitCode', label: 'Code', type: 'text', isNotSortable :true },
{ id: 'circuitName', label: 'Circuit', type: 'text', isNotSortable :true },
{ id: 'observation', label: 'Observation', type: 'text' },
];
export const DEFAULT_AMENDMENT_PASSENGER_CIRCUIT_TABLE_HEAD: TableColumn[] = [
......
import { CollaboratorStatus } from "@/shared/types/client";
import { State } from "@/shared/types/passenger";
const endpointPrefix = '/api/user';
......@@ -52,6 +53,7 @@ export const userEndpoints = {
exportPassengers: endpointPrefix + '/passenger/export',
getShortPassengers: endpointPrefix + '/passenger/search/short',
getRepresentativesByPassengerId : (passengerId: string) => endpointPrefix + `/passenger/representative/by-passenger/${passengerId}`,
updateStatus: (id : string, passengerState: State) => endpointPrefix + `/passenger/update-state?passengerId=${id}&newState=${passengerState}`,
},
team: {
getAllTeams: endpointPrefix + "/teams/search",
......
import axiosInstance from "@/utils/axios";
import { create } from "zustand";
import { userEndpoints } from "../endpoints/user";
import { IPassengerList, Representative, SearchPassengerParams } from "@/shared/types/passenger";
import { IPassengerList, Representative, SearchPassengerParams, State } from "@/shared/types/passenger";
type PassengerStore = {
passengers: IPassengerList[];
......@@ -18,6 +18,7 @@ type PassengerStore = {
getShortPassengers: (params?: SearchPassengerParams) => Promise<void>;
getRepresentativesByPassengerId: (passengerId: string) => Promise<Representative[]>;
getPassengerById: (id: string) => Promise<IPassengerList>;
updatePassengerStatus: (id: string, passengerState: State) => Promise<void>;
};
export const usePassengerStore = create<PassengerStore>((set, get) => ({
......@@ -172,5 +173,24 @@ export const usePassengerStore = create<PassengerStore>((set, get) => ({
});
throw error;
}
}
},
updatePassengerStatus: async (id, passengerState) => {
set({ loading: true, error: null });
try {
await axiosInstance.put<State>(
userEndpoints.user.passenger.updateStatus(id, passengerState)
);
set((state) => ({
passengers: state.passengers.map((c) => (c.id === id ? { ...c, state: passengerState } : c)),
loading: false,
}));
} catch (error: any) {
set({
error: error.message || 'Failed to update circuit status',
loading: false,
});
throw error;
}
},
}));
"use client"
import type React from "react"
import { useState } from "react"
import Button from "@mui/material/Button"
import Menu from "@mui/material/Menu"
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"
import { StyledMenuItem } from "@/shared/theme/css"
import { ADRESSE } from "@/shared/_mock"
interface AddressSelectorProps {
currentAddress: string
addresses: string[]
}
export function AddressSelector({ currentAddress, addresses }: AddressSelectorProps) {
const [selectedAddress, setSelectedAddress] = useState(currentAddress)
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
const open = Boolean(anchorEl)
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const handleAddressSelect = (address: string) => {
setSelectedAddress(address)
handleClose()
}
return (
<>
<Button
id="address-button"
aria-controls={open ? "address-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={handleClick}
endIcon={<KeyboardArrowDownIcon />}
size="small"
variant="text"
sx={{ textTransform: "none", color: "text.primary", fontSize: "12px" }}
>
{selectedAddress}
</Button>
<Menu
id="address-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "address-button",
}}
>
{(addresses).map((address, index) => (
<StyledMenuItem
key={index}
onClick={() => handleAddressSelect(address)}
selected={selectedAddress === address}
>
{address}
</StyledMenuItem>
))}
</Menu>
</>
)
}
......@@ -7,9 +7,8 @@ import {
Stack,
IconButton,
TableCell,
CircularProgress,
} from "@mui/material"
import { faArrowUpRightFromSquare, faEye, faRotate, faTrashCan } from "@fortawesome/free-solid-svg-icons"
import { faArrowUpRightFromSquare, faEye, faRotate } from "@fortawesome/free-solid-svg-icons"
import {
ActionsIconButton,
iconButtonStyles,
......@@ -27,7 +26,6 @@ import { useRouter } from "@/hooks/use-router"
import { paths } from "@/routes/paths"
import ConfirmDialog from "@/shared/components/dialog/confirmDialog"
import UserSelector from "./userSelector"
import { AddressSelector } from "./adressSelector"
import ExportButton from '@/shared/components/table/table-export-button';
import { TableType } from "@/shared/types/common"
import ScheduleAmendment, { UsagerForAmendment } from "./schedule-amendments"
......@@ -170,7 +168,7 @@ export default function CircuitUsager( {circuitId}: {circuitId: string} ) {
case "birthDate":
return formatDate(row.birthDate, dateFormat.isoDate)
case "address":
return <AddressSelector currentAddress={row.address[0]} addresses={row.address} />
return row.address[0] || '-'
case "scheduleAmendment":
return (
<CustomTooltip title="Avenant Horaires" arrow>
......@@ -210,11 +208,7 @@ export default function CircuitUsager( {circuitId}: {circuitId: string} ) {
<FontAwesome icon={faArrowUpRightFromSquare} width={14} />
</IconButton>
</CustomTooltip>
<CustomTooltip title="Désaffecter usager" arrow>
<IconButton onClick={() => handleDeleteDocument(row.id)} size="small" sx={ActionsIconButton}>
<FontAwesome icon={faTrashCan} width={14} />
</IconButton>
</CustomTooltip>
</TableCell>
</TrajetStyledRow>
)
......
......@@ -8,7 +8,7 @@ import TableActionColumn from '@/shared/components/table/table-action-column';
import { _CIRCUIT_STATUS } from '@/shared/_mock/_circuit';
import StatusMenu from '@/shared/components/table/StatusMenu';
import ConditionalComponent from '@/shared/components/table/ConditionalComponent';
import { _PassengerStatus, IPassengerList } from '@/shared/types/passenger';
import { _PassengerStatus, IPassengerList, State } from '@/shared/types/passenger';
import { usePassengerStore } from '@/shared/api/stores/passengerStore';
import { PassengerCircuitStatusChip } from '@/shared/theme/css';
import { getLabel } from '@/shared/_mock';
......@@ -41,7 +41,7 @@ export default function UsagerTableRow({
columns,
onStatusChange
}: Props) {
const { toggleArchive, passengers } = usePassengerStore();
const { toggleArchive, updatePassengerStatus } = usePassengerStore();
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
const handleToggleActivation = async () => {
......@@ -65,7 +65,14 @@ export default function UsagerTableRow({
const handleCancelToggle = () => {
setShowConfirmDialog(false);
};
const handleStatusChange = async (newStatus: string) => {
try {
await updatePassengerStatus(row.id, newStatus as State);
enqueueSnackbar("Statut de l'usager mis à jour avec succès", { variant: 'success' });
} catch (error: any) {
enqueueSnackbar(error.message || "Erreur lors de la mise à jour du statut", { variant: 'error' });
}
};
const renderCellContent = (columnId: string, value: any) => {
if (value === null) {
return '-';
......@@ -95,7 +102,7 @@ export default function UsagerTableRow({
<StatusMenu
value={value}
options={_PassengerStatus}
onChange={(newStatus) => onStatusChange(row, newStatus, 'state')}
onChange={(newStatus) => handleStatusChange(newStatus as State)}
chipComponent={PassengerCircuitStatusChip}
/>
);
......
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