Skip to content

Commit

Permalink
Merge pull request #1884 from Inist-CNRS/feat/import-hidden-resources
Browse files Browse the repository at this point in the history
Feat import hidden resources
  • Loading branch information
slax57 authored Feb 2, 2024
2 parents 82b79b6 + e982e3f commit 69cd231
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 2 deletions.
43 changes: 43 additions & 0 deletions src/api/controller/api/hiddenResource.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Koa from 'koa';
import route from 'koa-route';
import koaBodyParser from 'koa-bodyparser';
import asyncBusboy from '@recuperateur/async-busboy';
import mime from 'mime-types';
import fs from 'fs';

const app = new Koa();

Expand All @@ -9,6 +13,45 @@ const getExportHiddenResources = async ctx => {
ctx.status = 200;
};

const postImportHiddenResources = async ctx => {
const { files } = await asyncBusboy(ctx.req);

if (files.length !== 1) {
ctx.status = 400;
ctx.body = { message: 'File does not exist' };
return;
}

const type = mime.lookup(files[0].filename);
if (type !== 'application/json') {
ctx.status = 400;
ctx.body = { message: 'Wrong mime type, application/json required' };
return;
}
try {
const file = fs.readFileSync(files[0].path, 'utf8');
const hiddenResources = JSON.parse(file);
await ctx.hiddenResource.deleteMany({});
await ctx.hiddenResource.insertMany(hiddenResources);
for (const hiddenResource of hiddenResources) {
await ctx.publishedDataset.hide(
hiddenResource.uri,
hiddenResource.reason,
hiddenResource.date,
);
}
} catch (error) {
ctx.status = 400;
ctx.body = { message: error.message };
return;
}

ctx.body = { message: 'Imported' };
ctx.status = 200;
};

app.use(koaBodyParser());
app.use(route.get('/export', getExportHiddenResources));
app.use(route.post('/import', postImportHiddenResources));

export default app;
3 changes: 3 additions & 0 deletions src/app/custom/translations.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,6 @@
"root_panel_link" "Instances management" "Gestion des instances"
"admin_panel_link" "Instance administration" "Administration de l'instance"
"subresource_path_validation_error" "A subresource with this path already exists" "Une sous-ressource avec ce chemin existe déjà"
"import" "Import" "Importer"
"import_successful" "Import completed successfully" "Import réalisé avec succès"
"import_error" "Error during import" "Erreur lors de l'import"
13 changes: 12 additions & 1 deletion src/app/js/admin/api/hiddenResource.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getUserSessionStorageInfo } from '../api/tools';
import { getExportHiddenResources } from '../../user';
import { getExportHiddenResources, getImportHiddenResources } from '../../user';
import fetch from '../../lib/fetch';

export const exportHiddenResources = () => {
Expand All @@ -12,3 +12,14 @@ export const exportHiddenResources = () => {
return response;
});
};

export const importHiddenResources = async formData => {
const { token } = getUserSessionStorageInfo();
const request = getImportHiddenResources({ token }, formData);
return fetch(request).then(({ response, error }) => {
if (error) {
return error;
}
return response;
});
};
76 changes: 76 additions & 0 deletions src/app/js/admin/removedResources/ImportButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useEffect, useState } from 'react';
import { compose } from 'recompose';
import { polyglot as polyglotPropTypes } from '../../propTypes';
import translate from 'redux-polyglot/translate';
import UploadIcon from '@mui/icons-material/Upload';
import { Button, CircularProgress, styled } from '@mui/material';
import { importHiddenResources } from '../api/hiddenResource';
import { toast } from '../../../../common/tools/toast';
import { useLocation, Redirect } from 'react-router-dom';

const VisuallyHiddenInput = styled('input')({
clip: 'rect(0 0 0 0)',
clipPath: 'inset(50%)',
height: 1,
overflow: 'hidden',
position: 'absolute',
bottom: 0,
left: 0,
whiteSpace: 'nowrap',
width: 1,
});

const ImportButton = ({ p: polyglot }) => {
const buttonLabel = polyglot.t('import');
const location = useLocation();
const [uploading, setUploading] = useState(false);
const [done, setDone] = useState(false);

const handleFileChange = async event => {
setUploading(true);
const file = event.target.files[0];
const formData = new FormData();
formData.append('file', file);
const response = await importHiddenResources(formData);
setUploading(false);
if (response.error) {
toast(polyglot.t('import_error'), {
type: toast.TYPE.ERROR,
});
} else {
setDone(true);
toast(polyglot.t('import_successful'), {
type: toast.TYPE.SUCCESS,
});
}
};

if (done) {
return <Redirect to={location} />;
}

return (
<Button
component="label"
variant="text"
className="export"
startIcon={
uploading ? <CircularProgress size="1em" /> : <UploadIcon />
}
disabled={uploading}
>
{buttonLabel}
<VisuallyHiddenInput
onChange={handleFileChange}
type="file"
accept="application/json"
/>
</Button>
);
};

ImportButton.propTypes = {
p: polyglotPropTypes.isRequired,
};

export default compose(translate)(ImportButton);
8 changes: 7 additions & 1 deletion src/app/js/admin/removedResources/RemovedResourcePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ import RemovedResourceList from './RemovedResourceList';
import withInitialData from '../withInitialData';
import redirectToDashboardIfNoField from '../../admin/redirectToDashboardIfNoField';
import ExportButton from './ExportButton';
import ImportButton from './ImportButton';

export const RemovedResourcePageComponent = ({ p: polyglot }) => {
return (
<Card>
<CardHeader
title={<h3>{polyglot.t('hidden_resources')}</h3>}
action={<ExportButton />}
action={
<>
<ImportButton />
<ExportButton />
</>
}
/>
<Divider />
<RemovedResourceList />
Expand Down
11 changes: 11 additions & 0 deletions src/app/js/user/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,16 @@ export const getExportHiddenResources = state => {
});
};

export const getImportHiddenResources = (state, formData) => {
const req = getRequest(state, {
url: '/api/hiddenResource/import',
method: 'POST',
});
delete req.headers['Content-Type'];
req.body = formData;
return req;
};

export const selectors = {
isAdmin,
getRole,
Expand Down Expand Up @@ -726,4 +736,5 @@ export const selectors = {
getExportPrecomputedDataRequest,
getPreviewPrecomputedDataRequest,
getExportHiddenResources,
getImportHiddenResources,
};

0 comments on commit 69cd231

Please sign in to comment.