Skip to content

Commit 46d2465

Browse files
authored
fix: Multiple UI/UX improvements (#2529)
This includes multiple improvements described in #2528
1 parent 6c829b9 commit 46d2465

File tree

12 files changed

+227
-115
lines changed

12 files changed

+227
-115
lines changed

src/course-unit/preview-changes/index.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
import {
55
ActionRow, Button, Icon, ModalDialog, useToggle,
66
} from '@openedx/paragon';
7-
import { Info, Warning } from '@openedx/paragon/icons';
7+
import { Info } from '@openedx/paragon/icons';
88
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
99

1010
import { ToastContext } from '@src/generic/toast-context';
@@ -150,7 +150,7 @@ export const PreviewLibraryXBlockChanges = ({
150150
return (
151151
<CompareChangesWidget
152152
usageKey={blockData.upstreamBlockId}
153-
oldUsageKey={isTextWithLocalChanges ? blockData.downstreamBlockId : undefined}
153+
oldUsageKey={blockData.downstreamBlockId}
154154
oldTitle={isTextWithLocalChanges ? blockData.displayName : undefined}
155155
oldVersion={blockData.upstreamBlockVersionSynced || 'published'}
156156
newVersion="published"
@@ -235,21 +235,14 @@ export const PreviewLibraryXBlockChanges = ({
235235
</ModalDialog.Title>
236236
</ModalDialog.Header>
237237
<ModalDialog.Body>
238-
{isTextWithLocalChanges ? (
238+
{isTextWithLocalChanges && (
239239
<AlertMessage
240240
show
241241
variant="info"
242242
icon={Info}
243243
title={intl.formatMessage(messages.localEditsAlert)}
244244
/>
245-
) : (!blockData.isContainer && (
246-
<AlertMessage
247-
show
248-
variant="warning"
249-
icon={Warning}
250-
title={intl.formatMessage(messages.olderVersionPreviewAlert)}
251-
/>
252-
))}
245+
)}
253246
{getBody()}
254247
</ModalDialog.Body>
255248
<ModalDialog.Footer>

src/course-unit/preview-changes/messages.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ const messages = defineMessages({
5151
defaultMessage: 'Ignore',
5252
description: 'Preview changes confirmation dialog confirm button text when user clicks on ignore changes.',
5353
},
54-
olderVersionPreviewAlert: {
55-
id: 'course-authoring.review-tab.preview.old-version-alert',
56-
defaultMessage: 'The old version preview is the previous library version',
57-
description: 'Alert message stating that older version in preview is of library block',
58-
},
5954
localEditsAlert: {
6055
id: 'course-authoring.review-tab.preview.loal-edits-alert',
6156
defaultMessage: 'This library content has local edits.',
@@ -73,7 +68,7 @@ const messages = defineMessages({
7368
},
7469
updateToPublishedLibraryContentBody: {
7570
id: 'course-authoring.review-tab.preview.update-to-published.modal.body',
76-
defaultMessage: 'Updating this block will discard local changes. Any eidts made within this course will be discarted, and cannot be recovered',
71+
defaultMessage: 'Updating this block will discard local changes. Any edits made within this course will be discarded, and cannot be recovered',
7772
description: 'Body of the modal to update a content to the published library content',
7873
},
7974
updateToPublishedLibraryContentConfirm: {
@@ -93,7 +88,7 @@ const messages = defineMessages({
9388
},
9489
keepCourseContentBody: {
9590
id: 'course-authoring.review-tab.preview.keep-course-content.modal.body',
96-
defaultMessage: 'This will keep the locally edited course content. if the component is published again in its library, you can choose to update to published library content',
91+
defaultMessage: 'This will keep the locally edited course content. If the component is published again in its library, you can choose to update to published library content',
9792
description: 'Body of the modal to keep the content of a course component',
9893
},
9994
});

src/legacy-libraries-migration/LegacyLibMigrationPage.test.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,23 @@ describe('<LegacyLibMigrationPage />', () => {
8282
});
8383

8484
it('should select legacy libraries', async () => {
85+
const user = userEvent.setup();
8586
renderPage();
8687
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
8788

8889
const nextButton = screen.getByRole('button', { name: /next/i });
8990
// The next button is disabled
9091
expect(nextButton).toBeDisabled();
9192

93+
// The filter is Unmigrated by default
94+
const filterButton = await screen.findByRole('button', { name: /unmigrated/i });
95+
expect(filterButton).toBeInTheDocument();
96+
97+
// Clear filter to show all
98+
await user.click(filterButton);
99+
const clearButton = await screen.findByRole('button', { name: /clear filter/i });
100+
await user.click(clearButton);
101+
92102
expect(await screen.findByText('MBA')).toBeInTheDocument();
93103
expect(await screen.findByText('Legacy library 1')).toBeInTheDocument();
94104
expect(await screen.findByText('MBA 1')).toBeInTheDocument();
@@ -116,6 +126,37 @@ describe('<LegacyLibMigrationPage />', () => {
116126
expect(nextButton).not.toBeDisabled();
117127
});
118128

129+
it('should select all legacy libraries', async () => {
130+
const user = userEvent.setup();
131+
renderPage();
132+
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
133+
134+
// The filter is Unmigrated by default
135+
const filterButton = await screen.findByRole('button', { name: /unmigrated/i });
136+
expect(filterButton).toBeInTheDocument();
137+
138+
// Clear filter to show all
139+
await user.click(filterButton);
140+
const clearButton = await screen.findByRole('button', { name: /clear filter/i });
141+
await user.click(clearButton);
142+
143+
const selectAll = screen.getByRole('checkbox', { name: /select all/i });
144+
await user.click(selectAll);
145+
146+
const library1 = screen.getByRole('checkbox', { name: 'MBA' });
147+
const library2 = screen.getByRole('checkbox', { name: /legacy library 1 imported library/i });
148+
const library3 = screen.getByRole('checkbox', { name: 'MBA 1' });
149+
150+
expect(library1).toBeChecked();
151+
expect(library2).toBeChecked();
152+
expect(library3).toBeChecked();
153+
154+
await user.click(selectAll);
155+
expect(library1).not.toBeChecked();
156+
expect(library2).not.toBeChecked();
157+
expect(library3).not.toBeChecked();
158+
});
159+
119160
it('should back to select legacy libraries', async () => {
120161
renderPage();
121162
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
@@ -250,10 +291,18 @@ describe('<LegacyLibMigrationPage />', () => {
250291
});
251292

252293
it('should confirm migration', async () => {
294+
const user = userEvent.setup();
253295
renderPage();
254296
expect(await screen.findByText('Migrate Legacy Libraries')).toBeInTheDocument();
255297
expect(await screen.findByText('MBA')).toBeInTheDocument();
256298

299+
// The filter is 'unmigrated' by default.
300+
// Clear the filter to select all libraries
301+
const filterButton = screen.getByRole('button', { name: /unmigrated/i });
302+
await user.click(filterButton);
303+
const clearButton = await screen.findByRole('button', { name: /clear filter/i });
304+
await user.click(clearButton);
305+
257306
const legacyLibrary1 = screen.getByRole('checkbox', { name: 'MBA' });
258307
const legacyLibrary2 = screen.getByRole('checkbox', { name: /legacy library 1 imported library/i });
259308
const legacyLibrary3 = screen.getByRole('checkbox', { name: 'MBA 1' });

src/legacy-libraries-migration/LegacyLibMigrationPage.tsx

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Header from '@src/header';
1616
import SubHeader from '@src/generic/sub-header/SubHeader';
1717
import type { ContentLibrary } from '@src/library-authoring/data/api';
1818
import type { LibraryV1Data } from '@src/studio-home/data/api';
19-
import LibrariesList from '@src/studio-home/tabs-section/libraries-tab';
19+
import { Filter, LibrariesList } from '@src/studio-home/tabs-section/libraries-tab';
2020

2121
import messages from './messages';
2222
import { SelectDestinationView } from './SelectDestinationView';
@@ -157,6 +157,8 @@ export const LegacyLibMigrationPage = () => {
157157
selectedIds={legacyLibrariesIds}
158158
handleCheck={handleUpdateLegacyLibraries}
159159
hideMigationAlert
160+
initialFilter={[Filter.unmigrated]}
161+
setSelectedLibraries={setLegacyLibraries}
160162
/>
161163
</Stepper.Step>
162164
<Stepper.Step
@@ -182,29 +184,30 @@ export const LegacyLibMigrationPage = () => {
182184
</Stepper.Step>
183185
</Stepper>
184186
</div>
185-
<div className="content-buttons d-flex justify-content-between">
186-
<Button variant="outline-primary" onClick={handleBack}>
187-
{currentStep === 'select-libraries'
188-
? intl.formatMessage(messages.cancel)
189-
: intl.formatMessage(messages.back)}
190-
</Button>
191-
{currentStep !== 'confirmation-view' ? (
192-
<Button onClick={handleNext} disabled={isNextDisabled()}>
193-
{intl.formatMessage(messages.next)}
194-
</Button>
195-
) : (
196-
<StatefulButton
197-
state={confirmationButtonState}
198-
disabledStates={['pending']}
199-
labels={{
200-
default: intl.formatMessage(messages.confirm),
201-
pending: intl.formatMessage(messages.confirm),
202-
}}
203-
onClick={handleNext}
204-
/>
205-
)}
206-
</div>
207187
</Container>
188+
<div className="content-buttons d-flex justify-content-between pl-6 pr-6 bg-white">
189+
<Button className="mt-2 mb-2" variant="outline-primary" onClick={handleBack}>
190+
{currentStep === 'select-libraries'
191+
? intl.formatMessage(messages.cancel)
192+
: intl.formatMessage(messages.back)}
193+
</Button>
194+
{currentStep !== 'confirmation-view' ? (
195+
<Button className="mt-2 mb-2" onClick={handleNext} disabled={isNextDisabled()}>
196+
{intl.formatMessage(messages.next)}
197+
</Button>
198+
) : (
199+
<StatefulButton
200+
className="mt-2 mb-2"
201+
state={confirmationButtonState}
202+
disabledStates={['pending']}
203+
labels={{
204+
default: intl.formatMessage(messages.confirm),
205+
pending: intl.formatMessage(messages.confirm),
206+
}}
207+
onClick={handleNext}
208+
/>
209+
)}
210+
</div>
208211
</div>
209212
<ExitModal
210213
isExitModalOpen={isExitModalOpen}

src/legacy-libraries-migration/SelectDestinationView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { ContentLibrary } from '@src/library-authoring/data/api';
77
import messages from './messages';
88

99
interface SelectDestinationViewProps {
10-
destinationId: string | undefined;
10+
destinationId?: string;
1111
setDestinationId: (library: ContentLibrary) => void;
1212
legacyLibCount: number;
1313
}
Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
.legacy-library-migration-page {
22
.migration-container {
3-
// Calculate all the screen size subtracting the height of the header and top/bottom margins
4-
min-height: calc(calc(100vh - 60px) - calc(var(--pgn-spacing-spacer-base) * 6));
5-
63
.courses-tab-container {
74
min-height: auto;
85
}
96

107
.migration-content {
118
flex: 1;
129
}
10+
11+
.card-item {
12+
margin: 0 0 16px !important;
13+
14+
&.selected {
15+
box-shadow: 0 0 0 2px var(--pgn-color-primary-700);
16+
}
17+
}
1318
}
1419

1520
.confirmation-view {
1621
.pgn__card-header-content {
1722
margin-top: calc(var(--pgn-spacing-spacer-base)) !important;;
1823
}
1924
}
25+
26+
.content-buttons {
27+
width: 100%;
28+
position: fixed;
29+
bottom: 0;
30+
}
2031
}

src/library-authoring/component-comparison/CompareChangesWidget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const CompareChangesWidget = ({
5252
{oldTitle}
5353
</div>
5454
)}
55-
<div style={hasLocalChanges ? { marginLeft: '-35px', marginTop: '-15px' } : {}}>
55+
<div style={hasLocalChanges ? { marginLeft: '-35px', marginTop: '-8px' } : {}}>
5656
<IframeProvider>
5757
<LibraryBlock
5858
usageKey={oldUsageKey || usageKey}

0 commit comments

Comments
 (0)