Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature archiver vil 320 #966

Merged
merged 4 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions server/controllers/archive.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AWS from 'aws-sdk';
import type { Request, Response, NextFunction } from 'express';

import { UserType } from '../entities/user';
Expand All @@ -17,4 +18,55 @@ archiveController.get({ path: '/*', userType: UserType.ADMIN }, async (req: Requ
}
});

/**
* Liste les dossiers dans un préfixe S3 spécifié.
* @param prefix - Le préfixe S3 à partir duquel lister les dossiers.
* @returns Une promesse qui résout avec un tableau de noms de dossiers.
*/
async function listS3Folders(prefix: string): Promise<string[]> {
// Configurer le client S3 avec les informations d'identification et la région
const s3 = new AWS.S3({
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
region: 'eu-west-3',
});

// Paramètres pour la requête S3
const params: AWS.S3.ListObjectsV2Request = {
Bucket: process.env.S3_BUCKET_NAME || '',
Prefix: prefix,
Delimiter: '/', // Utiliser le délimiteur '/' pour obtenir uniquement les dossiers
};

try {
// Effectuer la requête pour lister les objets
const data = await s3.listObjectsV2(params).promise();

if (!data.CommonPrefixes) {
return [];
}

// Extraire les noms de dossiers des préfixes communs
// Nettoyer les noms de dossiers (supprimer le préfixe et le délimiteur final)
return data.CommonPrefixes.map((prefixObj) => prefixObj.Prefix)
.filter((prefix): prefix is string => prefix !== undefined)
.map((folder) => folder.slice(prefix.length, -1));
} catch (error) {
console.error('Error while listing S3 folders:', error);
throw error;
}
}

archiveController.get({ path: '', userType: UserType.OBSERVATOR }, async (_req: Request, res: Response, next: NextFunction) => {
try {
const prefix = 'archives/';
const archiveFolders = await listS3Folders(prefix);
res.sendJSON(archiveFolders);
} catch (error) {
console.error('Error while listing archived S3 folders:', error);
next(error);
return;
}
});

export { archiveController };
12 changes: 12 additions & 0 deletions src/api/archive/archive.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import axios from 'axios';
import { useQuery } from 'react-query';

const BASE_URL = '/api/archives';

// Récupérer la liste des années déjà archivées
export const useListArchives = () => {
return useQuery(['archives'], async () => {
const { data } = await axios.get(`${BASE_URL}`);
return data;
});
};
18 changes: 0 additions & 18 deletions src/api/pelicoPresentation/pelicoPresentation.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,3 @@ export const usePelicoPresentatations = () => {
return data;
});
};

// async function getPelicoPresentation(id: number) {
// const { data } = await axios.get(`${BASE_URL}/${id}`);
// return data;
// }

// export const useGetPelicoPresentation = (id: number) => {
// return useQuery(['pelico-presentation'], getPelicoPresentation(id));
// };

// async function getPelicoPresentations() {
// const { data } = await axios.get(`${BASE_URL}`);
// return data;
// }

// export const useGetPelicoPresentations = () => {
// return useQuery(['pelico-presentation'], getPelicoPresentations);
// };
41 changes: 39 additions & 2 deletions src/pages/admin/newportal/manage/settings/archive/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import Link from 'next/link';
import React from 'react';
import { useSnackbar } from 'notistack';
import React, { useEffect, useState } from 'react';

import { Typography, Box, List, ListItem } from '@mui/material';

import { useListArchives } from 'src/api/archive/archive.get';
import { UserContext } from 'src/contexts/userContext';
import BackArrow from 'src/svg/back-arrow.svg';
import { UserType } from 'types/user.type';

const Archive = () => {
const { user } = React.useContext(UserContext);
const hasAccess = user?.type === UserType.SUPER_ADMIN;
const [archives, setArchives] = useState<string[]>([]);
const { enqueueSnackbar } = useSnackbar();

const { data: listArchive, isError: listArchiveError, isLoading: listArchiveLoading } = useListArchives();

useEffect(() => {
if (listArchive) {
setArchives(listArchive);
}
if (listArchiveError) {
enqueueSnackbar("Une erreur s'est produite lors de la récuperation des archives existantes !", {
variant: 'error',
});
}
}, [listArchive, listArchiveError, enqueueSnackbar]);

if (!hasAccess) {
return <h1>Vous n&apos;avez pas accès à cette page, vous devez être super admin.</h1>;
}

return (
<div>
<Link href="/admin/newportal/manage/settings">
Expand All @@ -20,7 +40,24 @@ const Archive = () => {
<h1 style={{ marginLeft: '10px' }}>Archiver</h1>
</div>
</Link>
<p>Archiver 1Village va fermer l&apos;accès à tous les utilisateurs à la plateforme. Voilà les anciennes archives d&apos;1Village :</p>
<p>Voilà la liste des archives existantes. Si tu souhaites effectuer une nouvelle archive d&apos;1Village, adresse toi au pôle tech.</p>
<Box display="flex" flexDirection="column" alignItems="center">
{listArchiveLoading ? (
<div>Chargement...</div>
) : (
<List>
{archives.map((archive, index) => (
<ListItem key={index}>
<Link href={`/api/archives/${archive}`} passHref legacyBehavior>
<a target="_blank" rel="noopener noreferrer">
<Typography variant="body1">{archive}</Typography>
</a>
</Link>
</ListItem>
))}
</List>
)}
</Box>
</div>
);
};
Expand Down
Loading