Skip to content

Commit ee28ed0

Browse files
downiecsashakames
andauthored
Version 1.2.1 updates (#681)
* fix timezone with package (#680) * Joyride tutorials update (#679) * Merged in latest v1.2.1 * Updates to the joyride tutorials and some minor bugfixes. * Revert Markdown update to fix current jest testing error * Updated React Markdown library and fixed the jest test errors. * Update Vulnerability program link * update additonal VDP link --------- Co-authored-by: Sasha Ames <[email protected]>
1 parent 8e03a8a commit ee28ed0

File tree

16 files changed

+668
-382
lines changed

16 files changed

+668
-382
lines changed

backend/metagrid/api_globus/views.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import urllib.parse
55
import urllib.request
66
import uuid
7-
from datetime import datetime, timedelta
7+
from datetime import datetime, timedelta, timezone
88

99
from django.conf import settings
1010
from django.http import (
@@ -271,7 +271,7 @@ def submit_transfer(
271271
"""
272272

273273
# maximum time for completing the transfer
274-
deadline = datetime.now(datetime.timezone.utc) + timedelta(days=10)
274+
deadline = datetime.now(timezone.utc) + timedelta(days=10)
275275

276276
# create a transfer request
277277
if "%23" in target_endpoint:

backend/metagrid/api_proxy/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def do_request(request, urlbase):
202202
resp = requests.get(urlbase)
203203

204204
# print(resp.text)
205-
httpresp = HttpResponse(resp.text)
205+
httpresp = HttpResponse(resp.text, content_type="text/json")
206206
httpresp.status_code = resp.status_code
207207

208208
return httpresp

frontend/.envs/.react

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ REACT_APP_AUTHENTICATION_METHOD=globus
1313
# Globus
1414
# ------------------------------------------------------------------------------
1515
REACT_APP_GLOBUS_REDIRECT=http://localhost:3000/cart/items
16-
REACT_APP_CLIENT_ID=7fa7ac4a-a051-4b26-836f-b292b5c5b268
16+
REACT_APP_CLIENT_ID=8286db4d-269e-4c68-88a1-2af9a20f7f09
1717
REACT_APP_GLOBUS_NODES=aims3.llnl.gov,esgf-data1.llnl.gov,esgf-data2.llnl.gov
1818

1919
# ------------------------------------------------------------------------------

frontend/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "frontend",
3-
"version": "1.2.0",
3+
"version": "1.2.1",
44
"private": true,
55
"scripts": {
66
"build:local": "env-cmd -f .envs/.react react-scripts build",
@@ -59,7 +59,7 @@
5959
}
6060
},
6161
"moduleNameMapper": {
62-
"react-markdown": "<rootDir>/node_modules/react-markdown/react-markdown.min.js"
62+
"react-markdown": "<rootDir>/src/test/__mocks__/ReactMarkdownMock.tsx"
6363
}
6464
},
6565
"dependencies": {
@@ -83,7 +83,7 @@
8383
"react-dom": "18.2.0",
8484
"react-hotjar": "2.2.1",
8585
"react-joyride": "2.5.3",
86-
"react-markdown": "8.0.7",
86+
"react-markdown": "9.0.1",
8787
"react-router-dom": "^6.9.0",
8888
"react-scripts": "5.0.1",
8989
"recoil": "0.7.7",

frontend/public/changelog/v1.2.1.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Summary
2+
3+
1. Updates to the tutorials: added new tutorial for the Globus transfer feature.
4+
2. Minor bugfixes.

frontend/src/common/TargetObject.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('Test TourTarget class', () => {
3030
createTestTour('testGroup', {});
3131
});
3232

33-
it('Successfully creates joyride tour fron test targets', () => {
33+
it('Successfully creates joyride tour from test targets', () => {
3434
const testTargets = {
3535
test1: new TargetObject('test1'),
3636
test2: new TargetObject('test2'),

frontend/src/common/reactJoyrideSteps.ts

+74-7
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,21 @@ export const cartTourTargets = {
157157
libraryBtn: new TargetObject(),
158158
downloadAllType: new TargetObject(),
159159
downloadAllBtn: new TargetObject(),
160+
globusCollectionDropdown: new TargetObject(),
160161
removeItemsBtn: new TargetObject(),
161162
};
162163

164+
export const manageCollectionsTourTargets = {
165+
globusCollectionsForm: new TargetObject(),
166+
searchCollectionInput: new TargetObject(),
167+
globusSearchResultsPanel: new TargetObject(),
168+
globusSearchResults: new TargetObject(),
169+
mySavedCollectionsPanel: new TargetObject(),
170+
mySavedCollections: new TargetObject(),
171+
saveCollectionBtn: new TargetObject(),
172+
cancelCollectionBtn: new TargetObject(),
173+
};
174+
163175
export const savedSearchTourTargets = {
164176
savedSearches: new TargetObject(),
165177
projectDescription: new TargetObject(),
@@ -181,6 +193,7 @@ export const nodeTourTargets = {
181193
export enum TourTitles {
182194
Main = 'Main Search Page Tour',
183195
Cart = 'Data Cart Tour',
196+
ManageCollections = 'Manage My Collections Tour',
184197
Searches = 'Saved Searches Tour',
185198
Node = 'Node Status Tour',
186199
Welcome = 'Welcome Tour',
@@ -713,14 +726,29 @@ export const createCartItemsTour = (
713726
await delay(300);
714727
}
715728
)
729+
.addNextStep(
730+
cartTourTargets.removeItemsBtn.selector(),
731+
'We can remove all items from the cart with this button.',
732+
'right-start'
733+
)
716734
.addNextStep(
717735
cartTourTargets.downloadAllType.selector(),
718-
'This will select which download script to use (only wget is available currently).',
736+
'This will select which download method to use. The Globus download method is the default.',
737+
'top-start',
738+
/* istanbul ignore next */
739+
async () => {
740+
clickFirstElement(cartTourTargets.downloadAllType.selector());
741+
await delay(500);
742+
}
743+
)
744+
.addNextStep(
745+
cartTourTargets.globusCollectionDropdown.selector(),
746+
"For Globus downloads, you need to select a saved collection from this drop-down. If you haven't saved any collections, you can do so by clicking the 'Manage Collections' option.",
719747
'top-start'
720748
)
721749
.addNextStep(
722750
cartTourTargets.downloadAllBtn.selector(),
723-
'Then you would click this button to get the download script needed for all currently selected datasets in the cart.',
751+
'After selecting your collection, click this button to start the download for your selected cart items.',
724752
'top-start',
725753
/* istanbul ignore next */
726754
async () => {
@@ -730,11 +758,6 @@ export const createCartItemsTour = (
730758
await delay(300);
731759
}
732760
)
733-
.addNextStep(
734-
cartTourTargets.removeItemsBtn.selector(),
735-
'We can remove all items from the cart with this button.',
736-
'right-start'
737-
)
738761
.addNextStep('body', 'This concludes the cart page tour.', 'center')
739762
.setOnFinish(
740763
/* istanbul ignore next */
@@ -758,6 +781,50 @@ export const createCartItemsTour = (
758781
return tour;
759782
};
760783

784+
export const createCollectionsFormTour = (): JoyrideTour => {
785+
const tour = new JoyrideTour(TourTitles.ManageCollections)
786+
.addNextStep(
787+
manageCollectionsTourTargets.globusCollectionsForm.selector(),
788+
"The 'Manage My Collections' form allows you to search for and save Globus collections which you can then select to perform Globus transfers."
789+
)
790+
.addNextStep(
791+
manageCollectionsTourTargets.searchCollectionInput.selector(),
792+
"First, type your search text in here, then press 'Enter' or click the blue search button to the right."
793+
)
794+
.addNextStep(
795+
manageCollectionsTourTargets.globusSearchResults.selector(),
796+
"The search results will be displayed in this table, where you can click 'Add' for the collections you wish to save.",
797+
'auto',
798+
/* istanbul ignore next */
799+
async () => {
800+
clickFirstElement(
801+
manageCollectionsTourTargets.mySavedCollectionsPanel.selector()
802+
);
803+
await delay(500);
804+
}
805+
)
806+
.addNextStep(
807+
manageCollectionsTourTargets.mySavedCollections.selector(),
808+
"Your currently saved collections are displayed in this table, where you can also 'Set' or 'Update' the file path to use for a specific collection. If the path is set for a specific collection, you won't have to set the path again when doing transfers to that collection.",
809+
'auto'
810+
)
811+
.addNextStep('body', 'This concludes the cart page tour.', 'center')
812+
.setOnFinish(
813+
/* istanbul ignore next */
814+
() => {
815+
// Clean-up step for when the tour is complete (or skipped)
816+
return async () => {
817+
clickFirstElement(
818+
manageCollectionsTourTargets.mySavedCollectionsPanel.selector()
819+
);
820+
await delay(300);
821+
};
822+
}
823+
);
824+
825+
return tour;
826+
};
827+
761828
export const createSearchCardTour = (
762829
setCurrentPage: (page: number) => void
763830
): JoyrideTour => {

frontend/src/components/App/App.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,8 @@ const App: React.FC<React.PropsWithChildren<Props>> = ({ searchQuery }) => {
686686
<br />
687687
Learn about the Department of Energy&apos;s Vulnerability
688688
Disclosure Program (VDP):{' '}
689-
<a href="https://doe.responsibledisclosure.com/hc/en-us">
690-
https://doe.responsibledisclosure.com/hc/en-us
689+
<a href="https://www.energy.gov/vulnerability-disclosure-policy">
690+
https://www.energy.gov/vulnerability-disclosure-policy
691691
</a>
692692
</p>
693693
</Layout.Footer>

frontend/src/components/Globus/DatasetDownload.tsx

+57-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DownloadOutlined } from '@ant-design/icons';
1+
import { DownloadOutlined, QuestionOutlined } from '@ant-design/icons';
22
import {
33
Button,
44
Card,
@@ -25,7 +25,11 @@ import {
2525
REQUESTED_SCOPES,
2626
createGlobusAuthObject,
2727
} from '../../api';
28-
import { cartTourTargets } from '../../common/reactJoyrideSteps';
28+
import {
29+
cartTourTargets,
30+
createCollectionsFormTour,
31+
manageCollectionsTourTargets,
32+
} from '../../common/reactJoyrideSteps';
2933
import { globusEnabledNodes, globusRedirectUrl } from '../../env';
3034
import { RawSearchResults } from '../Search/types';
3135
import CartStateKeys, {
@@ -42,6 +46,10 @@ import {
4246
} from './types';
4347
import { NotificationType, showError, showNotice } from '../../common/utils';
4448
import { DataPersister } from '../../common/DataPersister';
49+
import {
50+
RawTourState,
51+
ReactJoyrideContext,
52+
} from '../../contexts/ReactJoyrideContext';
4553

4654
type AlertModalState = {
4755
onCancelAction: () => void;
@@ -67,6 +75,10 @@ const dp: DataPersister = DataPersister.Instance;
6775
const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
6876
const [messageApi, contextHolder] = message.useMessage();
6977

78+
// Tutorial state
79+
const tourState: RawTourState = React.useContext(ReactJoyrideContext);
80+
const { startSpecificTour } = tourState;
81+
7082
const [downloadIsLoading, setDownloadIsLoading] = useRecoilState<boolean>(
7183
cartDownloadIsLoading
7284
);
@@ -904,6 +916,7 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
904916
/>
905917
{selectedDownloadType === 'Globus' && (
906918
<Select
919+
className={cartTourTargets.globusCollectionDropdown.class()}
907920
data-testid="searchCollectionInput"
908921
defaultActiveFirstOption={false}
909922
filterOption={false}
@@ -989,10 +1002,31 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
9891002
</Button>
9901003
</Space>
9911004
<Modal
1005+
className={manageCollectionsTourTargets.globusCollectionsForm.class()}
9921006
data-testid="manageCollectionsForm"
993-
title="Manage My Collections"
1007+
title={
1008+
<>
1009+
Manage My Collections{' '}
1010+
<Button
1011+
shape="circle"
1012+
type="primary"
1013+
icon={
1014+
<QuestionOutlined
1015+
color="primary"
1016+
style={{ fontSize: '20px' }}
1017+
/>
1018+
}
1019+
onClick={() => {
1020+
startSpecificTour(createCollectionsFormTour());
1021+
}}
1022+
></Button>
1023+
</>
1024+
}
9941025
open={endpointSearchOpen}
9951026
okText="Save"
1027+
okButtonProps={{
1028+
className: manageCollectionsTourTargets.saveCollectionBtn.class(),
1029+
}}
9961030
onOk={async () => {
9971031
setEndpointSearchOpen(false);
9981032
await dp.setValue(
@@ -1007,6 +1041,9 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
10071041
);
10081042
}}
10091043
cancelText="Cancel Changes"
1044+
cancelButtonProps={{
1045+
className: manageCollectionsTourTargets.cancelCollectionBtn.class(),
1046+
}}
10101047
onCancel={async () => {
10111048
setEndpointSearchOpen(false);
10121049
await dp.setValue(
@@ -1019,6 +1056,7 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
10191056
width={1000}
10201057
>
10211058
<Input.Search
1059+
className={manageCollectionsTourTargets.searchCollectionInput.class()}
10221060
value={endpointSearchValue}
10231061
onChange={(e) => {
10241062
setEndpointSearchValue(e.target.value);
@@ -1034,9 +1072,16 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
10341072
items={[
10351073
{
10361074
key: '1',
1037-
label: 'Globus Collection Search Results',
1075+
label: (
1076+
<div
1077+
className={manageCollectionsTourTargets.globusSearchResultsPanel.class()}
1078+
>
1079+
Globus Collection Search Results
1080+
</div>
1081+
),
10381082
children: (
10391083
<Table
1084+
className={manageCollectionsTourTargets.globusSearchResults.class()}
10401085
data-testid="globusEndpointSearchResults"
10411086
loading={loadingEndpointSearchResults}
10421087
size="small"
@@ -1102,9 +1147,16 @@ const DatasetDownloadForm: React.FC<React.PropsWithChildren<unknown>> = () => {
11021147
},
11031148
{
11041149
key: '2',
1105-
label: 'My Saved Globus Collections',
1150+
label: (
1151+
<div
1152+
className={manageCollectionsTourTargets.mySavedCollectionsPanel.class()}
1153+
>
1154+
My Saved Globus Collections
1155+
</div>
1156+
),
11061157
children: (
11071158
<Table
1159+
className={manageCollectionsTourTargets.mySavedCollections.class()}
11081160
data-testid="savedGlobusEndpoints"
11091161
size="small"
11101162
pagination={

frontend/src/components/Messaging/MessageCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect } from 'react';
2-
import ReactMarkdown from 'react-markdown';
2+
import Markdown from 'react-markdown';
33
import { MarkdownMessage } from './types';
44

55
const MessageCard: React.FC<React.PropsWithChildren<MarkdownMessage>> = ({
@@ -18,7 +18,7 @@ const MessageCard: React.FC<React.PropsWithChildren<MarkdownMessage>> = ({
1818
});
1919
}, []);
2020

21-
return <ReactMarkdown>{content}</ReactMarkdown>;
21+
return <Markdown>{content}</Markdown>;
2222
};
2323

2424
export default MessageCard;

frontend/src/components/Messaging/Templates/Welcome.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// eslint-disable @typescript-eslint/no-unsafe-argument
2+
13
import { Button, Card, Col, Row } from 'antd';
24
import React from 'react';
35
import { useNavigate } from 'react-router-dom';

frontend/src/components/Messaging/messageDisplayData.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const rightDrawerMessages: MarkdownMessage[] = [
55
];
66

77
export const rightDrawerChanges: MarkdownMessage[] = [
8+
{ title: 'V1.2.1', fileName: 'changelog/v1.2.1.md' },
89
{ title: 'V1.2.0', fileName: 'changelog/v1.2.0.md' },
910
{ title: 'V1.1.3-pre', fileName: 'changelog/v1.1.3-pre.md' },
1011
{ title: 'V1.1.2-pre', fileName: 'changelog/v1.1.2-pre.md' },
@@ -16,9 +17,18 @@ export const rightDrawerChanges: MarkdownMessage[] = [
1617
];
1718

1819
const startupMessages: StartPopupData = {
19-
messageToShow: 'v1.2.0', // This is the version number that appears in the footer
20+
messageToShow: 'v1.2.1', // This is the version number that appears in the footer
2021
defaultMessageId: 'welcome',
2122
messageData: [
23+
{
24+
messageId: 'v1.2.1',
25+
template: MessageTemplates.ChangeLog,
26+
style: { minWidth: '700px' },
27+
data: {
28+
changesFile: 'changelog/v1.2.1.md',
29+
version: '1.2.1',
30+
},
31+
},
2232
{
2333
messageId: 'v1.2.0',
2434
template: MessageTemplates.ChangeLog,

0 commit comments

Comments
 (0)