Skip to content

Commit 9f970ff

Browse files
NicolasRitouetemersion
authored andcommitted
Add import button
1 parent 9fadd73 commit 9f970ff

File tree

7 files changed

+115
-7
lines changed

7 files changed

+115
-7
lines changed

src/backend/core/api/viewsets.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ def notion_import_callback(request):
21082108
resp.raise_for_status()
21092109
data = resp.json()
21102110
request.session["notion_token"] = data["access_token"]
2111-
return redirect("/api/v1.0/notion_import/run")
2111+
return redirect(f"{settings.FRONTEND_URL}/import-notion/")
21122112

21132113

21142114
def _import_notion_child_page(imported_doc, parent_doc, user, imported_docs_by_page_id):
@@ -2155,8 +2155,7 @@ def _import_notion_root_page(imported_doc, user, imported_docs_by_page_id):
21552155
_import_notion_child_page(child, obj, user, imported_docs_by_page_id)
21562156

21572157

2158-
# @drf.decorators.api_view(["POST"])
2159-
@drf.decorators.api_view()
2158+
@drf.decorators.api_view(["POST"])
21602159
def notion_import_run(request):
21612160
if "notion_token" not in request.session:
21622161
raise drf.exceptions.PermissionDenied()

src/frontend/apps/impress/src/components/DropdownMenu.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type DropdownMenuOption = {
1414
danger?: boolean;
1515
isSelected?: boolean;
1616
disabled?: boolean;
17+
padding?: BoxProps['$padding'];
1718
show?: boolean;
1819
showSeparator?: boolean;
1920
};
@@ -134,7 +135,9 @@ export const DropdownMenu = ({
134135
$justify="space-between"
135136
$background={colorsTokens['greyscale-000']}
136137
$color={colorsTokens['primary-600']}
137-
$padding={{ vertical: 'xs', horizontal: 'base' }}
138+
$padding={
139+
option.padding ?? { vertical: 'xs', horizontal: 'base' }
140+
}
138141
$width="100%"
139142
$gap={spacingsTokens['base']}
140143
$css={css`
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { useMutation, useQueryClient } from '@tanstack/react-query';
2+
import { useRouter } from 'next/navigation';
3+
4+
import { APIError, errorCauses, fetchAPI } from '@/api';
5+
6+
import { KEY_LIST_DOC } from './useDocs';
7+
8+
export const importNotion = async (): Promise<void> => {
9+
const response = await fetchAPI('notion_import/run', {
10+
method: 'POST',
11+
});
12+
13+
if (!response.ok) {
14+
throw new APIError(
15+
'Failed to import the Notion',
16+
await errorCauses(response),
17+
);
18+
}
19+
};
20+
21+
export function useImportNotion() {
22+
const router = useRouter();
23+
const queryClient = useQueryClient();
24+
return useMutation<void, APIError, void>({
25+
mutationFn: importNotion,
26+
onSuccess: () => {
27+
void queryClient.resetQueries({
28+
queryKey: [KEY_LIST_DOC],
29+
});
30+
router.push('/');
31+
},
32+
});
33+
}

src/frontend/apps/impress/src/features/left-panel/components/LeftPanelHeaderButton.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Button } from '@openfun/cunningham-react';
2+
import { t } from 'i18next';
23
import { useRouter } from 'next/router';
34
import { useTranslation } from 'react-i18next';
45

5-
import { Icon } from '@/components';
6+
import { Box, DropdownMenu, Icon } from '@/components';
67
import { useCreateDoc } from '@/features/docs/doc-management';
78

89
import { useLeftPanelStore } from '../stores';
@@ -17,7 +18,14 @@ export const LeftPanelHeaderButton = () => {
1718
togglePanel();
1819
},
1920
});
20-
return (
21+
22+
const handleImportNotion = () => {
23+
const baseApiUrl = process.env.NEXT_PUBLIC_API_ORIGIN;
24+
const notionAuthUrl = `${baseApiUrl}/api/v1.0/notion_import/redirect`;
25+
window.location.href = notionAuthUrl;
26+
};
27+
28+
return (<Box $direction="row" $align="center">
2129
<Button
2230
color="primary"
2331
onClick={() => createDoc()}
@@ -26,5 +34,17 @@ export const LeftPanelHeaderButton = () => {
2634
>
2735
{t('New doc')}
2836
</Button>
29-
);
37+
<DropdownMenu
38+
showArrow
39+
disabled={isDocCreating}
40+
options={[
41+
{
42+
label: t('Import from Notion'),
43+
callback: handleImportNotion,
44+
padding: { vertical: 'xs', horizontal: 'md' },
45+
},
46+
]}
47+
>
48+
</DropdownMenu>
49+
</Box>);
3050
};

src/frontend/apps/impress/src/features/service-worker/service-worker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const precacheResources = [
110110
'/index.html',
111111
'/401/',
112112
'/404/',
113+
'/import-notion',
113114
FALLBACK.offline,
114115
FALLBACK.images,
115116
FALLBACK.docs,

src/frontend/apps/impress/src/i18n/translations.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@
274274
"No documents found": "Keine Dokumente gefunden",
275275
"No text selected": "Kein Text ausgewählt",
276276
"No versions": "Keine Versionen",
277+
"Notion import in progress...": "Notion-Import in Arbeit...",
277278
"OK": "OK",
278279
"Offline ?!": "Offline?!",
279280
"Only invited people can access": "Nur eingeladene Personen haben Zugriff",
@@ -291,6 +292,7 @@
291292
"Pin document icon": "Pinne das Dokumentenlogo an",
292293
"Pinned documents": "Angepinnte Dokumente",
293294
"Please download it only if it comes from a trusted source.": "Bitte laden Sie es nur herunter, wenn es von einer vertrauenswürdigen Quelle stammt.",
295+
"Please stay on this page and be patient": "Bitte bleiben Sie auf dieser Seite und haben Sie Geduld",
294296
"Private": "Privat",
295297
"Proconnect Login": "Proconnect-Anmeldung",
296298
"Public": "Öffentlich",
@@ -474,6 +476,7 @@
474476
"No documents found": "No se han encontrado documentos",
475477
"No text selected": "No hay texto seleccionado",
476478
"No versions": "No hay versiones",
479+
"Notion import in progress...": "Importación de Notion en curso...",
477480
"OK": "Ok",
478481
"Offline ?!": "¿¡Sin conexión!?",
479482
"Only invited people can access": "Solo las personas invitadas pueden acceder",
@@ -489,6 +492,7 @@
489492
"Pin document icon": "Icono para marcar el documento como favorito",
490493
"Pinned documents": "Documentos favoritos",
491494
"Please download it only if it comes from a trusted source.": "Por favor, descárguelo solo si viene de una fuente de confianza.",
495+
"Please stay on this page and be patient": "Rimanete su questa pagina e siate pazienti",
492496
"Private": "Privado",
493497
"Proconnect Login": "Iniciar sesión ProConnect",
494498
"Public": "Público",
@@ -685,6 +689,7 @@
685689
"No documents found": "Aucun document trouvé",
686690
"No text selected": "Aucun texte sélectionné",
687691
"No versions": "Aucune version",
692+
"Notion import in progress...": "Import Notion en cours...",
688693
"OK": "OK",
689694
"Offline ?!": "Hors-ligne ?!",
690695
"Only invited people can access": "Seules les personnes invitées peuvent accéder",
@@ -703,6 +708,7 @@
703708
"Pin document icon": "Icône épingler un document",
704709
"Pinned documents": "Documents épinglés",
705710
"Please download it only if it comes from a trusted source.": "Veuillez le télécharger uniquement s'il provient d'une source fiable.",
711+
"Please stay on this page and be patient": "Merci de rester sur cette page et de patienter un peu",
706712
"Private": "Privé",
707713
"Proconnect Login": "Login Proconnect",
708714
"Public": "Public",
@@ -867,6 +873,7 @@
867873
"No documents found": "Nessun documento trovato",
868874
"No text selected": "Non è stato selezionato nessun testo",
869875
"No versions": "Nessuna versione",
876+
"Notion import in progress...": "Importazione di nozioni in corso...",
870877
"OK": "OK",
871878
"Offline ?!": "Offline ?!",
872879
"Only invited people can access": "Solo le persone invitate possono accedere",
@@ -881,6 +888,7 @@
881888
"Pin document icon": "Icona \"fissa documento\"",
882889
"Pinned documents": "Documenti fissati",
883890
"Please download it only if it comes from a trusted source.": "Per favore scaricalo solo se proviene da una fonte attendibile",
891+
"Please stay on this page and be patient": "Rimanete su questa pagina e siate pazienti",
884892
"Private": "Privato",
885893
"Public": "Pubblico",
886894
"Public document": "Documento pubblico",
@@ -1029,6 +1037,7 @@
10291037
"No documents found": "Geen documenten gevonden",
10301038
"No text selected": "Geen tekst geselecteerd",
10311039
"No versions": "Geen versies",
1040+
"Notion import in progress...": "Notion import bezig...",
10321041
"OK": "Ok",
10331042
"Offline ?!": "Offline ?!",
10341043
"Only invited people can access": "Alleen uitgenodigde gebruikers hebben toegang",
@@ -1043,6 +1052,7 @@
10431052
"Pin document icon": "Document icoon vastzetten",
10441053
"Pinned documents": "Vastgepinde documenten",
10451054
"Please download it only if it comes from a trusted source.": "Alleen downloaden als het van een vertrouwde bron komt.",
1055+
"Please stay on this page and be patient": "Blijf op deze pagina en heb geduld",
10461056
"Private": "Privé",
10471057
"Proconnect Login": "Login",
10481058
"Public": "Publiek",
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Loader } from '@openfun/cunningham-react';
2+
import { ReactElement, useEffect } from 'react';
3+
import { useTranslation } from 'react-i18next';
4+
5+
import { Box, Text } from '@/components';
6+
import { useImportNotion } from '@/features/docs/doc-management/api/useImportNotion';
7+
import { MainLayout } from '@/layouts';
8+
import { NextPageWithLayout } from '@/types/next';
9+
10+
const Page: NextPageWithLayout = () => {
11+
const { t } = useTranslation();
12+
13+
const { mutate: importNotion } = useImportNotion();
14+
15+
useEffect(() => {
16+
importNotion();
17+
// eslint-disable-next-line react-hooks/exhaustive-deps
18+
}, []);
19+
20+
return (
21+
<Box
22+
$padding={{ top: 'large' }}
23+
$width="100%"
24+
$height="100%"
25+
$align="center"
26+
>
27+
<Text as="p" $margin={{ bottom: '0px' }}>
28+
{t('Notion import in progress...')}
29+
</Text>
30+
<Text as="p" $margin={{ top: '10px', bottom: '30px' }}>
31+
{t('Please stay on this page and be patient')}
32+
</Text>
33+
<Loader />
34+
</Box>
35+
);
36+
};
37+
38+
Page.getLayout = function getLayout(page: ReactElement) {
39+
return <MainLayout>{page}</MainLayout>;
40+
};
41+
42+
export default Page;

0 commit comments

Comments
 (0)