@openneuro/app 4.29.9 → 4.30.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.scss-lint.yml +11 -11
- package/maintenance.html +26 -20
- package/package.json +3 -3
- package/src/@types/custom.d.ts +2 -4
- package/src/index.html +14 -10
- package/src/scripts/datalad/routes/dataset-redirect.tsx +2 -0
- package/src/scripts/dataset/mutations/__tests__/update-permissions.spec.jsx +1 -1
- package/src/scripts/dataset/mutations/update-permissions.tsx +1 -1
- package/src/scripts/routes.tsx +16 -3
- package/src/scripts/users/__tests__/user-account-view.spec.tsx +146 -63
- package/src/scripts/users/__tests__/user-card.spec.tsx +62 -47
- package/src/scripts/users/__tests__/user-query.spec.tsx +65 -60
- package/src/scripts/users/__tests__/user-routes.spec.tsx +71 -40
- package/src/scripts/users/__tests__/user-tabs.spec.tsx +63 -66
- package/src/scripts/users/components/edit-list.tsx +53 -29
- package/src/scripts/users/components/edit-string.tsx +63 -22
- package/src/scripts/users/components/editable-content.tsx +85 -50
- package/src/scripts/users/user-account-view.tsx +101 -21
- package/src/scripts/users/user-card.tsx +26 -24
- package/src/scripts/users/user-container.tsx +39 -38
- package/src/scripts/users/user-datasets-view.tsx +22 -22
- package/src/scripts/users/user-notifications-view.tsx +9 -10
- package/src/scripts/users/user-query.tsx +62 -66
- package/src/scripts/users/user-routes.tsx +31 -24
- package/src/scripts/users/user-tabs.tsx +25 -21
- package/src/scripts/utils/__tests__/markdown.spec.tsx +1 -2
- package/src/scripts/utils/validationUtils.ts +2 -3
- package/src/scripts/validation/validation.tsx +11 -8
|
@@ -1,48 +1,49 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Outlet } from
|
|
3
|
-
import { UserCard } from
|
|
4
|
-
import { UserAccountTabs } from
|
|
5
|
-
import styles from
|
|
6
|
-
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Outlet } from "react-router-dom"
|
|
3
|
+
import { UserCard } from "./user-card"
|
|
4
|
+
import { UserAccountTabs } from "./user-tabs"
|
|
5
|
+
import styles from "./scss/usercontainer.module.scss"
|
|
7
6
|
|
|
8
7
|
interface User {
|
|
9
|
-
id: string
|
|
10
|
-
name: string
|
|
11
|
-
location: string
|
|
12
|
-
github?: string
|
|
13
|
-
institution: string
|
|
14
|
-
email: string
|
|
15
|
-
avatar: string
|
|
16
|
-
orcid: string
|
|
17
|
-
links: string[]
|
|
8
|
+
id: string
|
|
9
|
+
name: string
|
|
10
|
+
location: string
|
|
11
|
+
github?: string
|
|
12
|
+
institution: string
|
|
13
|
+
email: string
|
|
14
|
+
avatar: string
|
|
15
|
+
orcid: string
|
|
16
|
+
links: string[]
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
interface AccountContainerProps {
|
|
21
|
-
user: User
|
|
22
|
-
hasEdit: boolean
|
|
20
|
+
user: User
|
|
21
|
+
hasEdit: boolean
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export const UserAccountContainer: React.FC<AccountContainerProps> = ({
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
user,
|
|
26
|
+
hasEdit,
|
|
28
27
|
}) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
<div className="container">
|
|
31
|
+
<header className={styles.userHeader}>
|
|
32
|
+
{user.avatar && (
|
|
33
|
+
<img className={styles.avatar} src={user.avatar} alt={user.name} />
|
|
34
|
+
)}
|
|
35
|
+
<h2 className={styles.username}>{user.name}</h2>
|
|
36
|
+
</header>
|
|
37
|
+
</div>
|
|
38
|
+
<div className={styles.usercontainer + " container"}>
|
|
39
|
+
<section className={styles.userSidebar}>
|
|
40
|
+
<UserCard user={user} />
|
|
41
|
+
<UserAccountTabs hasEdit={hasEdit} />
|
|
42
|
+
</section>
|
|
43
|
+
<section className={styles.userViews}>
|
|
44
|
+
<Outlet />
|
|
45
|
+
</section>
|
|
46
|
+
</div>
|
|
47
|
+
</>
|
|
48
|
+
)
|
|
48
49
|
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from "react"
|
|
2
2
|
|
|
3
3
|
interface User {
|
|
4
|
-
name: string
|
|
4
|
+
name: string
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
interface Dataset {
|
|
8
|
-
id: string
|
|
9
|
-
created: string
|
|
10
|
-
ownerId: string
|
|
11
|
-
name: string
|
|
12
|
-
type: string
|
|
8
|
+
id: string
|
|
9
|
+
created: string
|
|
10
|
+
ownerId: string
|
|
11
|
+
name: string
|
|
12
|
+
type: string
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
interface UserDatasetsViewProps {
|
|
16
|
-
user: User
|
|
16
|
+
user: User
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const dummyDatasets: Dataset[] = [
|
|
20
20
|
{
|
|
21
|
-
id:
|
|
22
|
-
created:
|
|
23
|
-
ownerId:
|
|
24
|
-
name:
|
|
25
|
-
type:
|
|
21
|
+
id: "ds00001",
|
|
22
|
+
created: "2023-11-01T12:00:00Z",
|
|
23
|
+
ownerId: "1",
|
|
24
|
+
name: "Dataset 1",
|
|
25
|
+
type: "public",
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
id:
|
|
29
|
-
created:
|
|
30
|
-
ownerId:
|
|
31
|
-
name:
|
|
32
|
-
type:
|
|
28
|
+
id: "ds00002",
|
|
29
|
+
created: "2023-11-02T12:00:00Z",
|
|
30
|
+
ownerId: "2",
|
|
31
|
+
name: "Dataset 2",
|
|
32
|
+
type: "private",
|
|
33
33
|
},
|
|
34
|
-
]
|
|
34
|
+
]
|
|
35
35
|
|
|
36
36
|
export const UserDatasetsView: React.FC<UserDatasetsViewProps> = ({ user }) => {
|
|
37
37
|
return (
|
|
@@ -47,7 +47,7 @@ export const UserDatasetsView: React.FC<UserDatasetsViewProps> = ({ user }) => {
|
|
|
47
47
|
))}
|
|
48
48
|
</div>
|
|
49
49
|
</div>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
52
|
|
|
53
|
-
export default UserDatasetsView
|
|
53
|
+
export default UserDatasetsView
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import React from "react"
|
|
1
|
+
import React from "react"
|
|
2
2
|
|
|
3
3
|
export const UserNotificationsView = ({ user }) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
4
|
+
// this is a placeholder for the user notification feature
|
|
5
|
+
return (
|
|
6
|
+
<div data-testid="user-notifications-view">
|
|
7
|
+
<h3>UserNotificationsPAge for {user.name}</h3>
|
|
8
|
+
<p>This should show user info</p>
|
|
9
|
+
</div>
|
|
10
|
+
)
|
|
11
|
+
}
|
|
@@ -1,80 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Dummy user data
|
|
12
|
-
const dummyUsers: Record<string, User> = {
|
|
13
|
-
'0000-0001-6755-0259': {
|
|
14
|
-
id: '1',
|
|
15
|
-
name: 'Gregory Noack',
|
|
16
|
-
location: 'Stanford, CA',
|
|
17
|
-
github: 'thinknoack',
|
|
18
|
-
institution: 'Stanford University',
|
|
19
|
-
email: 'gregorynoack@thinknoack.com',
|
|
20
|
-
avatar: 'https://dummyimage.com/200x200/000/fff',
|
|
21
|
-
orcid: '0000-0001-6755-0259',
|
|
22
|
-
links: ['onelink.com', 'https://www.twolink.com'],
|
|
23
|
-
},
|
|
24
|
-
'0000-0002-1234-5678': {
|
|
25
|
-
id: '2',
|
|
26
|
-
name: 'Jane Doe',
|
|
27
|
-
location: 'Stanford, CA',
|
|
28
|
-
institution: 'Stanford University',
|
|
29
|
-
email: 'janedoe@example.com',
|
|
30
|
-
avatar: 'https://dummyimage.com/200x200/000/fff',
|
|
31
|
-
orcid: '0000-0002-1234-5678',
|
|
32
|
-
links: ['onelink.com', 'https://www.twolink.com'],
|
|
33
|
-
},
|
|
34
|
-
'0000-0003-2345-6789': {
|
|
35
|
-
id: '3',
|
|
36
|
-
name: 'John Smith',
|
|
37
|
-
location: 'Stanford, CA',
|
|
38
|
-
institution: 'Stanford University',
|
|
39
|
-
email: 'johnsmith@example.com',
|
|
40
|
-
avatar: 'https://dummyimage.com/200x200/000/fff',
|
|
41
|
-
orcid: '0000-0003-2345-6789',
|
|
42
|
-
links: ['onelink.com', 'https://www.twolink.com'],
|
|
43
|
-
},
|
|
44
|
-
};
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { useParams } from "react-router-dom"
|
|
3
|
+
import { UserRoutes } from "./user-routes"
|
|
4
|
+
import FourOFourPage from "../errors/404page"
|
|
5
|
+
import { isValidOrcid } from "../utils/validationUtils"
|
|
6
|
+
import { gql, useQuery } from "@apollo/client"
|
|
7
|
+
import { isAdmin } from "../authentication/admin-user"
|
|
8
|
+
import { useCookies } from "react-cookie"
|
|
9
|
+
import { getProfile } from "../authentication/profile"
|
|
45
10
|
|
|
11
|
+
// GraphQL query to fetch user by ORCID
|
|
12
|
+
export const GET_USER_BY_ORCID = gql`
|
|
13
|
+
query User($userId: ID!) {
|
|
14
|
+
user(id: $userId) {
|
|
15
|
+
id
|
|
16
|
+
name
|
|
17
|
+
orcid
|
|
18
|
+
email
|
|
19
|
+
avatar
|
|
20
|
+
location
|
|
21
|
+
institution
|
|
22
|
+
links
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`
|
|
46
26
|
|
|
27
|
+
export const UPDATE_USER = gql`
|
|
28
|
+
mutation updateUser($id: ID!, $location: String, $links: [String], $institution: String) {
|
|
29
|
+
updateUser(id: $id, location: $location, links: $links, institution: $institution) {
|
|
30
|
+
id
|
|
31
|
+
location
|
|
32
|
+
links
|
|
33
|
+
institution
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
`
|
|
47
37
|
|
|
48
38
|
export interface User {
|
|
49
|
-
id: string
|
|
50
|
-
name: string
|
|
51
|
-
location: string
|
|
52
|
-
github?: string
|
|
53
|
-
institution: string
|
|
54
|
-
email: string
|
|
55
|
-
avatar: string
|
|
56
|
-
orcid: string
|
|
57
|
-
links: string[]
|
|
39
|
+
id: string
|
|
40
|
+
name: string
|
|
41
|
+
location: string
|
|
42
|
+
github?: string
|
|
43
|
+
institution: string
|
|
44
|
+
email: string
|
|
45
|
+
avatar: string
|
|
46
|
+
orcid: string
|
|
47
|
+
links: string[]
|
|
58
48
|
}
|
|
59
49
|
|
|
60
50
|
export const UserQuery: React.FC = () => {
|
|
61
|
-
const { orcid } = useParams
|
|
51
|
+
const { orcid } = useParams()
|
|
52
|
+
const isOrcidValid = orcid && isValidOrcid(orcid)
|
|
53
|
+
const { data, loading, error } = useQuery(GET_USER_BY_ORCID, {
|
|
54
|
+
variables: { userId: orcid },
|
|
55
|
+
skip: !isOrcidValid,
|
|
56
|
+
})
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
const [cookies] = useCookies()
|
|
59
|
+
const profile = getProfile(cookies)
|
|
60
|
+
|
|
61
|
+
if (!isOrcidValid) {
|
|
62
|
+
return <FourOFourPage />
|
|
66
63
|
}
|
|
67
64
|
|
|
68
|
-
|
|
69
|
-
const user = dummyUsers[orcid];
|
|
65
|
+
if (loading) return <div>Loading...</div>
|
|
70
66
|
|
|
71
|
-
if (!user) {
|
|
72
|
-
|
|
73
|
-
return <FourOFourPage />;
|
|
67
|
+
if (error || !data?.user || data.user.orcid !== orcid) {
|
|
68
|
+
return <FourOFourPage />
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
//
|
|
77
|
-
const hasEdit = true
|
|
71
|
+
// is admin or profile matches id from the user data being returned
|
|
72
|
+
const hasEdit = isAdmin || data.user.id !== profile.sub ? true : false
|
|
78
73
|
|
|
79
|
-
|
|
80
|
-
}
|
|
74
|
+
// Render user data with UserRoutes
|
|
75
|
+
return <UserRoutes user={data.user} hasEdit={hasEdit} />
|
|
76
|
+
}
|
|
@@ -1,45 +1,52 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
import { Route, Routes } from "react-router-dom"
|
|
3
|
-
import { UserAccountContainer } from "./user-container"
|
|
4
|
-
import { UserAccountView } from "./user-account-view"
|
|
5
|
-
import { UserNotificationsView } from "./user-notifications-view"
|
|
6
|
-
import { UserDatasetsView } from "./user-datasets-view"
|
|
7
|
-
import FourOFourPage from "../errors/404page"
|
|
8
|
-
import FourOThreePage from "../errors/403page"
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { Route, Routes } from "react-router-dom"
|
|
3
|
+
import { UserAccountContainer } from "./user-container"
|
|
4
|
+
import { UserAccountView } from "./user-account-view"
|
|
5
|
+
import { UserNotificationsView } from "./user-notifications-view"
|
|
6
|
+
import { UserDatasetsView } from "./user-datasets-view"
|
|
7
|
+
import FourOFourPage from "../errors/404page"
|
|
8
|
+
import FourOThreePage from "../errors/403page"
|
|
9
9
|
|
|
10
10
|
export interface User {
|
|
11
|
-
id: string
|
|
12
|
-
name: string
|
|
13
|
-
location: string
|
|
14
|
-
github?: string
|
|
15
|
-
institution: string
|
|
16
|
-
email: string
|
|
17
|
-
avatar: string
|
|
18
|
-
orcid: string
|
|
19
|
-
links: string[]
|
|
11
|
+
id: string
|
|
12
|
+
name: string
|
|
13
|
+
location: string
|
|
14
|
+
github?: string
|
|
15
|
+
institution: string
|
|
16
|
+
email: string
|
|
17
|
+
avatar: string
|
|
18
|
+
orcid: string
|
|
19
|
+
links: string[]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface UserRoutesProps {
|
|
23
|
-
user: User
|
|
24
|
-
hasEdit: boolean
|
|
23
|
+
user: User
|
|
24
|
+
hasEdit: boolean
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const UserRoutes: React.FC<UserRoutesProps> = ({ user, hasEdit }) => {
|
|
28
28
|
return (
|
|
29
29
|
<Routes>
|
|
30
30
|
<Route path="/*" element={<FourOFourPage />} />
|
|
31
|
-
<Route
|
|
31
|
+
<Route
|
|
32
|
+
path="*"
|
|
33
|
+
element={<UserAccountContainer user={user} hasEdit={hasEdit} />}
|
|
34
|
+
>
|
|
32
35
|
<Route path="" element={<UserDatasetsView user={user} />} />
|
|
33
36
|
<Route
|
|
34
37
|
path="account"
|
|
35
|
-
element={hasEdit
|
|
38
|
+
element={hasEdit
|
|
39
|
+
? <UserAccountView user={user} />
|
|
40
|
+
: <FourOThreePage />}
|
|
36
41
|
/>
|
|
37
42
|
<Route
|
|
38
43
|
path="notifications"
|
|
39
|
-
element={hasEdit
|
|
44
|
+
element={hasEdit
|
|
45
|
+
? <UserNotificationsView user={user} />
|
|
46
|
+
: <FourOThreePage />}
|
|
40
47
|
/>
|
|
41
48
|
<Route path="*" element={<FourOFourPage />} />
|
|
42
49
|
</Route>
|
|
43
50
|
</Routes>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
51
|
+
)
|
|
52
|
+
}
|
|
@@ -1,39 +1,43 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from "react"
|
|
2
|
-
import { NavLink, useLocation } from "react-router-dom"
|
|
3
|
-
import styles from "./scss/usertabs.module.scss"
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react"
|
|
2
|
+
import { NavLink, useLocation } from "react-router-dom"
|
|
3
|
+
import styles from "./scss/usertabs.module.scss"
|
|
4
4
|
|
|
5
5
|
export interface UserAccountTabsProps {
|
|
6
|
-
hasEdit: boolean
|
|
6
|
+
hasEdit: boolean
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export const UserAccountTabs: React.FC<UserAccountTabsProps> = (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
9
|
+
export const UserAccountTabs: React.FC<UserAccountTabsProps> = (
|
|
10
|
+
{ hasEdit },
|
|
11
|
+
) => {
|
|
12
|
+
const ulRef = useRef<HTMLUListElement>(null)
|
|
13
|
+
const [activePosition, setActivePosition] = useState<number>(0)
|
|
14
|
+
const [clicked, setClicked] = useState(false)
|
|
15
|
+
const location = useLocation()
|
|
14
16
|
|
|
15
17
|
useEffect(() => {
|
|
16
|
-
const activeLink = ulRef.current?.querySelector(
|
|
18
|
+
const activeLink = ulRef.current?.querySelector(
|
|
19
|
+
`.${styles.active}`,
|
|
20
|
+
) as HTMLElement
|
|
17
21
|
if (activeLink) {
|
|
18
|
-
const li = activeLink.parentElement as HTMLElement
|
|
19
|
-
setActivePosition(li.offsetTop)
|
|
22
|
+
const li = activeLink.parentElement as HTMLElement
|
|
23
|
+
setActivePosition(li.offsetTop)
|
|
20
24
|
}
|
|
21
|
-
}, [location])
|
|
25
|
+
}, [location])
|
|
22
26
|
|
|
23
27
|
const handleClick = () => {
|
|
28
|
+
setClicked(true)
|
|
29
|
+
}
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
if (!hasEdit) return null;
|
|
31
|
+
if (!hasEdit) return null
|
|
30
32
|
|
|
31
33
|
return (
|
|
32
34
|
<div className={styles.userAccountTabLinks}>
|
|
33
35
|
<ul
|
|
34
36
|
ref={ulRef}
|
|
35
37
|
className={`${clicked ? "clicked" : ""} ${styles.userAccountTabLinks}`}
|
|
36
|
-
style={{
|
|
38
|
+
style={{
|
|
39
|
+
"--active-offset": `${activePosition}px`,
|
|
40
|
+
} as React.CSSProperties}
|
|
37
41
|
>
|
|
38
42
|
<li>
|
|
39
43
|
<NavLink
|
|
@@ -66,5 +70,5 @@ export const UserAccountTabs: React.FC<UserAccountTabsProps> = ({ hasEdit }) =>
|
|
|
66
70
|
</li>
|
|
67
71
|
</ul>
|
|
68
72
|
</div>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -27,8 +27,7 @@ describe("Test <Markdown> component", () => {
|
|
|
27
27
|
expect(asFragment()).toMatchSnapshot()
|
|
28
28
|
})
|
|
29
29
|
it("filters close-break tags", () => {
|
|
30
|
-
const hrefExample =
|
|
31
|
-
'<br>sample text</br>'
|
|
30
|
+
const hrefExample = "<br>sample text</br>"
|
|
32
31
|
const { asFragment } = render(<Markdown>{hrefExample}</Markdown>)
|
|
33
32
|
expect(asFragment()).toMatchSnapshot()
|
|
34
33
|
})
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
1
|
/**
|
|
3
2
|
* Validates an ORCID.
|
|
4
3
|
* @param orcid - The ORCID string to validate.
|
|
5
4
|
* @returns `true` if the ORCID is valid, `false` otherwise.
|
|
6
5
|
*/
|
|
7
6
|
export function isValidOrcid(orcid: string): boolean {
|
|
8
|
-
return /^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$/.test(orcid ||
|
|
9
|
-
}
|
|
7
|
+
return /^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$/.test(orcid || "")
|
|
8
|
+
}
|
|
@@ -31,12 +31,12 @@ const warningHeader = (count) => (
|
|
|
31
31
|
</div>
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
-
const errorHeader = (
|
|
34
|
+
const errorHeader = (errorCount) => (
|
|
35
35
|
<div>
|
|
36
36
|
<h3 className="metaheader">BIDS Validation</h3>
|
|
37
37
|
|
|
38
38
|
<span className="label text-warning pull-right">
|
|
39
|
-
{
|
|
39
|
+
{errorCount} {pluralize("Error", errorCount)}
|
|
40
40
|
</span>
|
|
41
41
|
<span className="dataset-status ds-danger">
|
|
42
42
|
<i className="fa fa-exclamation-circle" /> Invalid
|
|
@@ -53,10 +53,11 @@ const Valid = () => (
|
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
interface WarningsProps {
|
|
56
|
+
issues: DatasetIssues
|
|
56
57
|
warnings: DatasetIssues
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
const Warnings = ({ warnings }: WarningsProps) => (
|
|
60
|
+
const Warnings = ({ issues, warnings }: WarningsProps) => (
|
|
60
61
|
<ValidationPanel heading={warningHeader(warnings.size)}>
|
|
61
62
|
<div>
|
|
62
63
|
<span className="message error fade-in">
|
|
@@ -69,15 +70,17 @@ const Warnings = ({ warnings }: WarningsProps) => (
|
|
|
69
70
|
</span>
|
|
70
71
|
</div>
|
|
71
72
|
<br />
|
|
72
|
-
<Results issues={
|
|
73
|
+
<Results issues={issues} />
|
|
73
74
|
</ValidationPanel>
|
|
74
75
|
)
|
|
75
76
|
|
|
76
77
|
interface ErrorsProps {
|
|
78
|
+
issues: DatasetIssues
|
|
77
79
|
errors: DatasetIssues
|
|
80
|
+
warnings: DatasetIssues
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
const Errors = ({ errors }: ErrorsProps) => (
|
|
83
|
+
const Errors = ({ issues, errors }: ErrorsProps) => (
|
|
81
84
|
<ValidationPanel heading={errorHeader(errors.size)}>
|
|
82
85
|
<span className="message error fade-in">
|
|
83
86
|
Your dataset is no longer valid. You must fix the{" "}
|
|
@@ -86,7 +89,7 @@ const Errors = ({ errors }: ErrorsProps) => (
|
|
|
86
89
|
to use all of the site features.
|
|
87
90
|
</span>
|
|
88
91
|
<br />
|
|
89
|
-
<Results issues={
|
|
92
|
+
<Results issues={issues} />
|
|
90
93
|
</ValidationPanel>
|
|
91
94
|
)
|
|
92
95
|
|
|
@@ -100,9 +103,9 @@ export const Validation = ({ issues }: ValidationProps) => {
|
|
|
100
103
|
const warnings = grouped.get("warning")
|
|
101
104
|
const errors = grouped.get("error")
|
|
102
105
|
if (errors?.size) {
|
|
103
|
-
return <Errors
|
|
106
|
+
return <Errors issues={issues} errors={errors} warnings={warnings} />
|
|
104
107
|
} else if (warnings?.size) {
|
|
105
|
-
return <Warnings
|
|
108
|
+
return <Warnings issues={issues} warnings={warnings} />
|
|
106
109
|
} else {
|
|
107
110
|
return <Valid />
|
|
108
111
|
}
|