Skip to content

Commit 9166e7b

Browse files
committed
🚩(frontend) version MIT only
We have some packages that are not MIT compatible, so if the env var MIT_ONLY is set to true, we don't build the application with features that are not MIT compatible. For the moment, it concerns only the export packages.
1 parent f8a40cf commit 9166e7b

15 files changed

+488
-191
lines changed

.github/workflows/docker-hub.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ jobs:
7979
context: .
8080
file: ./src/frontend/Dockerfile
8181
target: frontend-production
82-
build-args: DOCKER_USER=${{ env.DOCKER_USER }}:-1000
82+
build-args: |
83+
DOCKER_USER=${{ env.DOCKER_USER }}:-1000
84+
MIT_ONLY=false
8385
push: ${{ github.event_name != 'pull_request' }}
8486
tags: ${{ steps.meta.outputs.tags }}
8587
labels: ${{ steps.meta.outputs.labels }}

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to
2020
- 🌐(i18n) activate chinese and spanish languages #884
2121
- 🔧(backend) allow overwriting the data directory #893
2222
- ➕(backend) add `django-lasuite` dependency #839
23+
- 🚩(frontend) version MIT only #911
2324

2425
## Changed
2526

docker-compose.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ services:
155155
target: frontend-production
156156
args:
157157
API_ORIGIN: "http://localhost:8071"
158-
Y_PROVIDER_URL: "ws://localhost:4444"
159-
MEDIA_URL: "http://localhost:8083"
158+
MIT_ONLY: "false"
160159
SW_DEACTIVATED: "true"
161160
image: impress:frontend-development
162161
ports:

src/frontend/Dockerfile

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ ENV NEXT_PUBLIC_API_ORIGIN=${API_ORIGIN}
3939
ARG SW_DEACTIVATED
4040
ENV NEXT_PUBLIC_SW_DEACTIVATED=${SW_DEACTIVATED}
4141

42+
ARG MIT_ONLY
43+
ENV MIT_ONLY=${MIT_ONLY}
44+
4245
RUN yarn build
4346

4447
# ---- Front-end image ----

src/frontend/apps/impress/.env

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
MIT_ONLY=true
12
NEXT_PUBLIC_API_ORIGIN=
23
NEXT_PUBLIC_SW_DEACTIVATED=
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
MIT_ONLY=false
12
NEXT_PUBLIC_API_ORIGIN=http://localhost:8071
23
NEXT_PUBLIC_SW_DEACTIVATED=true

src/frontend/apps/impress/next.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const nextConfig = {
1818
generateBuildId: () => buildId,
1919
env: {
2020
NEXT_PUBLIC_BUILD_ID: buildId,
21+
MIT_ONLY: process.env.MIT_ONLY,
2122
},
2223
webpack(config, { isServer }) {
2324
// Grab the existing rule that handles SVG imports

src/frontend/apps/impress/src/custom-next.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ declare module '*.svg?url' {
1919

2020
namespace NodeJS {
2121
interface ProcessEnv {
22+
MIT_ONLY?: string;
2223
NEXT_PUBLIC_API_ORIGIN?: string;
2324
NEXT_PUBLIC_SW_DEACTIVATED?: string;
2425
}

src/frontend/apps/impress/src/features/docs/doc-header/__tests__/DocToolBox.spec.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const doc = {
4242

4343
beforeEach(() => {
4444
Analytics.clearAnalytics();
45+
process.env.MIT_ONLY = 'false';
4546
});
4647

4748
describe('DocToolBox "Copy as HTML" option', () => {
@@ -51,7 +52,9 @@ describe('DocToolBox "Copy as HTML" option', () => {
5152
render(<DocToolBox doc={doc as any} />, {
5253
wrapper: AppWrapper,
5354
});
54-
const optionsButton = screen.getByLabelText('Open the document options');
55+
const optionsButton = await screen.findByLabelText(
56+
'Open the document options',
57+
);
5558
await userEvent.click(optionsButton);
5659
expect(await screen.findByText('Copy as HTML')).toBeInTheDocument();
5760
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { render, screen } from '@testing-library/react';
2+
import React from 'react';
3+
4+
import { AppWrapper } from '@/tests/utils';
5+
6+
import { DocToolBox } from '../components/DocToolBox';
7+
8+
const doc = {
9+
nb_accesses: 1,
10+
abilities: {
11+
versions_list: true,
12+
destroy: true,
13+
},
14+
};
15+
16+
jest.mock('@/features/docs/doc-export/', () => ({
17+
ModalExport: () => <span>ModalExport</span>,
18+
}));
19+
20+
it('DocToolBox dynamic import: loads DocToolBox when MIT_ONLY is false', async () => {
21+
process.env.MIT_ONLY = 'false';
22+
23+
render(<DocToolBox doc={doc as any} />, {
24+
wrapper: AppWrapper,
25+
});
26+
27+
expect(await screen.findByText('download')).toBeInTheDocument();
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { render, screen, waitFor } from '@testing-library/react';
2+
import React from 'react';
3+
4+
import { AppWrapper } from '@/tests/utils';
5+
6+
const doc = {
7+
nb_accesses: 1,
8+
abilities: {
9+
versions_list: true,
10+
destroy: true,
11+
},
12+
};
13+
14+
jest.mock('@/features/docs/doc-export/', () => ({
15+
ModalExport: () => <span>ModalExport</span>,
16+
}));
17+
18+
it('DocToolBox dynamic import: loads DocToolBox when MIT_ONLY is true', async () => {
19+
process.env.MIT_ONLY = 'true';
20+
21+
const { DocToolBox } = await import('../components/DocToolBox');
22+
23+
render(<DocToolBox doc={doc as any} />, {
24+
wrapper: AppWrapper,
25+
});
26+
27+
await waitFor(
28+
() => {
29+
expect(screen.queryByText('download')).not.toBeInTheDocument();
30+
},
31+
{
32+
timeout: 1000,
33+
},
34+
);
35+
});
Original file line numberDiff line numberDiff line change
@@ -1,170 +1,47 @@
1-
import {
2-
Button,
3-
VariantType,
4-
useModal,
5-
useToastProvider,
6-
} from '@openfun/cunningham-react';
1+
import { Button, useModal } from '@openfun/cunningham-react';
72
import { useQueryClient } from '@tanstack/react-query';
8-
import { useEffect, useState } from 'react';
3+
import dynamic from 'next/dynamic';
4+
import { useEffect } from 'react';
95
import { useTranslation } from 'react-i18next';
106
import { css } from 'styled-components';
117

12-
import {
13-
Box,
14-
DropdownMenu,
15-
DropdownMenuOption,
16-
Icon,
17-
IconOptions,
18-
} from '@/components';
8+
import { Box, Icon } from '@/components';
199
import { useCunninghamTheme } from '@/cunningham';
20-
import { useEditorStore } from '@/docs/doc-editor/';
21-
import { ModalExport } from '@/docs/doc-export/';
22-
import {
23-
Doc,
24-
KEY_DOC,
25-
KEY_LIST_DOC,
26-
ModalRemoveDoc,
27-
useCopyDocLink,
28-
useCreateFavoriteDoc,
29-
useDeleteFavoriteDoc,
30-
} from '@/docs/doc-management';
31-
import { DocShareModal } from '@/docs/doc-share';
32-
import {
33-
KEY_LIST_DOC_VERSIONS,
34-
ModalSelectVersion,
35-
} from '@/docs/doc-versioning';
36-
import { useAnalytics } from '@/libs';
10+
import { Doc } from '@/docs/doc-management';
11+
import { KEY_LIST_DOC_VERSIONS } from '@/docs/doc-versioning';
3712
import { useResponsiveStore } from '@/stores';
3813

3914
interface DocToolBoxProps {
4015
doc: Doc;
4116
}
4217

18+
const DocToolBoxLicence = dynamic(() =>
19+
process.env.MIT_ONLY === 'false'
20+
? import('./DocToolBoxLicenceAGPL').then((mod) => mod.DocToolBoxLicenceAGPL)
21+
: import('./DocToolBoxLicenceMIT').then((mod) => mod.DocToolBoxLicenceMIT),
22+
);
23+
4324
export const DocToolBox = ({ doc }: DocToolBoxProps) => {
4425
const { t } = useTranslation();
4526
const hasAccesses = doc.nb_accesses_direct > 1 && doc.abilities.accesses_view;
4627
const queryClient = useQueryClient();
4728

48-
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
29+
const { spacingsTokens } = useCunninghamTheme();
4930

50-
const [isModalRemoveOpen, setIsModalRemoveOpen] = useState(false);
51-
const [isModalExportOpen, setIsModalExportOpen] = useState(false);
52-
const selectHistoryModal = useModal();
31+
const modalHistory = useModal();
5332
const modalShare = useModal();
5433

55-
const { isSmallMobile, isDesktop } = useResponsiveStore();
56-
const { editor } = useEditorStore();
57-
const { toast } = useToastProvider();
58-
const copyDocLink = useCopyDocLink(doc.id);
59-
const { isFeatureFlagActivated } = useAnalytics();
60-
const removeFavoriteDoc = useDeleteFavoriteDoc({
61-
listInvalideQueries: [KEY_LIST_DOC, KEY_DOC],
62-
});
63-
const makeFavoriteDoc = useCreateFavoriteDoc({
64-
listInvalideQueries: [KEY_LIST_DOC, KEY_DOC],
65-
});
66-
67-
const options: DropdownMenuOption[] = [
68-
...(isSmallMobile
69-
? [
70-
{
71-
label: t('Share'),
72-
icon: 'group',
73-
callback: modalShare.open,
74-
},
75-
{
76-
label: t('Export'),
77-
icon: 'download',
78-
callback: () => {
79-
setIsModalExportOpen(true);
80-
},
81-
},
82-
{
83-
label: t('Copy link'),
84-
icon: 'add_link',
85-
callback: copyDocLink,
86-
},
87-
]
88-
: []),
89-
{
90-
label: doc.is_favorite ? t('Unpin') : t('Pin'),
91-
icon: 'push_pin',
92-
callback: () => {
93-
if (doc.is_favorite) {
94-
removeFavoriteDoc.mutate({ id: doc.id });
95-
} else {
96-
makeFavoriteDoc.mutate({ id: doc.id });
97-
}
98-
},
99-
testId: `docs-actions-${doc.is_favorite ? 'unpin' : 'pin'}-${doc.id}`,
100-
},
101-
{
102-
label: t('Version history'),
103-
icon: 'history',
104-
disabled: !doc.abilities.versions_list,
105-
callback: () => {
106-
selectHistoryModal.open();
107-
},
108-
show: isDesktop,
109-
},
110-
111-
{
112-
label: t('Copy as {{format}}', { format: 'Markdown' }),
113-
icon: 'content_copy',
114-
callback: () => {
115-
void copyCurrentEditorToClipboard('markdown');
116-
},
117-
},
118-
{
119-
label: t('Copy as {{format}}', { format: 'HTML' }),
120-
icon: 'content_copy',
121-
callback: () => {
122-
void copyCurrentEditorToClipboard('html');
123-
},
124-
show: isFeatureFlagActivated('CopyAsHTML'),
125-
},
126-
{
127-
label: t('Delete document'),
128-
icon: 'delete',
129-
disabled: !doc.abilities.destroy,
130-
callback: () => {
131-
setIsModalRemoveOpen(true);
132-
},
133-
},
134-
];
135-
136-
const copyCurrentEditorToClipboard = async (
137-
asFormat: 'html' | 'markdown',
138-
) => {
139-
if (!editor) {
140-
toast(t('Editor unavailable'), VariantType.ERROR, { duration: 3000 });
141-
return;
142-
}
143-
144-
try {
145-
const editorContentFormatted =
146-
asFormat === 'html'
147-
? await editor.blocksToHTMLLossy()
148-
: await editor.blocksToMarkdownLossy();
149-
await navigator.clipboard.writeText(editorContentFormatted);
150-
toast(t('Copied to clipboard'), VariantType.SUCCESS, { duration: 3000 });
151-
} catch (error) {
152-
console.error(error);
153-
toast(t('Failed to copy to clipboard'), VariantType.ERROR, {
154-
duration: 3000,
155-
});
156-
}
157-
};
34+
const { isSmallMobile } = useResponsiveStore();
15835

15936
useEffect(() => {
160-
if (selectHistoryModal.isOpen) {
37+
if (modalHistory.isOpen) {
16138
return;
16239
}
16340

16441
void queryClient.resetQueries({
16542
queryKey: [KEY_LIST_DOC_VERSIONS],
16643
});
167-
}, [selectHistoryModal.isOpen, queryClient]);
44+
}, [modalHistory.isOpen, queryClient]);
16845

16946
return (
17047
<Box
@@ -222,55 +99,12 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
22299
</>
223100
)}
224101

225-
{!isSmallMobile && (
226-
<Button
227-
color="tertiary-text"
228-
icon={
229-
<Icon iconName="download" $theme="primary" $variation="800" />
230-
}
231-
onClick={() => {
232-
setIsModalExportOpen(true);
233-
}}
234-
size={isSmallMobile ? 'small' : 'medium'}
235-
/>
236-
)}
237-
<DropdownMenu options={options}>
238-
<IconOptions
239-
isHorizontal
240-
$theme="primary"
241-
$padding={{ all: 'xs' }}
242-
$css={css`
243-
border-radius: 4px;
244-
&:hover {
245-
background-color: ${colorsTokens['greyscale-100']};
246-
}
247-
${isSmallMobile
248-
? css`
249-
padding: 10px;
250-
border: 1px solid ${colorsTokens['greyscale-300']};
251-
`
252-
: ''}
253-
`}
254-
aria-label={t('Open the document options')}
255-
/>
256-
</DropdownMenu>
257-
</Box>
258-
259-
{modalShare.isOpen && (
260-
<DocShareModal onClose={() => modalShare.close()} doc={doc} />
261-
)}
262-
{isModalExportOpen && (
263-
<ModalExport onClose={() => setIsModalExportOpen(false)} doc={doc} />
264-
)}
265-
{isModalRemoveOpen && (
266-
<ModalRemoveDoc onClose={() => setIsModalRemoveOpen(false)} doc={doc} />
267-
)}
268-
{selectHistoryModal.isOpen && (
269-
<ModalSelectVersion
270-
onClose={() => selectHistoryModal.close()}
102+
<DocToolBoxLicence
271103
doc={doc}
104+
modalHistory={modalHistory}
105+
modalShare={modalShare}
272106
/>
273-
)}
107+
</Box>
274108
</Box>
275109
);
276110
};

0 commit comments

Comments
 (0)