Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 98ff1aa

Browse files
authored
feat: add file image previews (#212)
* add file image previews * simple styling improvements
1 parent 4f4e9c5 commit 98ff1aa

File tree

13 files changed

+114
-30
lines changed

13 files changed

+114
-30
lines changed

src/shared/App.less

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@
33
@import 'styles/close-button.less';
44
@import 'styles/project-banner.less';
55

6+
.resource-view {
7+
padding: 2em 0;
8+
}
9+
10+
.project-view {
11+
}
12+
13+
.projects-view {
14+
max-width: @maxConstrainedItemWidth;
15+
margin: 0 auto;
16+
padding: 2em 0;
17+
}
18+
19+
.orgs-view {
20+
max-width: @maxConstrainedItemWidth;
21+
margin: 0 auto;
22+
padding: 2em 0;
23+
}
24+
625
.ant-pagination-prev,
726
.ant-pagination-jump-prev,
827
.ant-pagination-jump-next,

src/shared/components/Animations/ListItem.stories.tsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,44 @@ const exampleItems = [
1616
{
1717
label: 'nexus',
1818
projectNumber: 1200,
19+
avatar: {
20+
src:
21+
'https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Morocco_Africa_Flickr_Rosino_December_2005_84514010.jpg/800px-Morocco_Africa_Flickr_Rosino_December_2005_84514010.jpg',
22+
},
1923
description:
2024
"Yeah, but your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should. You're a very talented young man, with your own clever thoughts and ideas. Do you need a manager? They're using our own satellites against us. And the clock is ticking.",
2125
},
22-
{ label: 'bbp', projectNumber: 300, deprecated: true, action: true },
23-
{ label: 'hbp', projectNumber: 1 },
26+
{
27+
label: 'bbp',
28+
projectNumber: 300,
29+
deprecated: true,
30+
action: true,
31+
avatar: {
32+
src: 'https://i.gifer.com/embedded/download/7U30.gif',
33+
},
34+
},
35+
{
36+
label: 'hbp',
37+
projectNumber: 1,
38+
avatar: {
39+
src:
40+
'https://upload.wikimedia.org/wikipedia/commons/3/34/Gusev_Crater%2C_Mars.jpg',
41+
},
42+
},
2443
{
2544
label: 'nasa',
2645
projectNumber: 912839,
2746
description:
2847
"God creates dinosaurs. God destroys dinosaurs. God creates Man. Man destroys God. Man creates Dinosaurs. Hey, you know how I'm, like, always trying to save the planet? Here's my chance. You really think you can fly that thing? Did he just throw my cat out of the window?",
2948
},
3049
{ label: 'tesla', projectNumber: 3, deprecated: true },
31-
{ label: 'rolex', projectNumber: 3424 },
50+
{
51+
label: 'rolex',
52+
projectNumber: 3424,
53+
avatar: {
54+
src: 'https://cdn.jsdelivr.net/emojione/assets/3.1/png/32/1f31e.png',
55+
},
56+
},
3257
];
3358

3459
storiesOf('Components/ListItem', module)
@@ -48,6 +73,7 @@ storiesOf('Components/ListItem', module)
4873
<ul style={{ margin: 0, padding: 0 }}>
4974
{exampleItems.map((element, index) => {
5075
const {
76+
avatar,
5177
label,
5278
action: elementAction,
5379
projectNumber,
@@ -57,6 +83,7 @@ storiesOf('Components/ListItem', module)
5783
return (
5884
<ListItem
5985
id={`element-${index}`}
86+
avatar={avatar}
6087
label={label}
6188
onClick={action('element-clicked')}
6289
details={

src/shared/components/Animations/ListItem.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import * as React from 'react';
22
import './list-item.less';
3+
import useMeasure from '../hooks/useMeasure';
34

45
export interface ListItemProps {
56
label: React.ReactComponentElement<any> | string;
67
id: string;
78
description?: string;
89
details?: React.ReactComponentElement<any> | null;
10+
avatar?: { src: string } | null;
911
action?: React.ReactComponentElement<any> | null;
1012
onClick?: (id: string, event: React.MouseEvent) => void;
1113
}
@@ -17,10 +19,13 @@ const ListItem: React.FunctionComponent<ListItemProps> = ({
1719
onClick,
1820
details,
1921
action,
22+
avatar,
2023
}) => {
24+
const [bind, bounds] = useMeasure();
25+
const avatarClassSwitch = bounds && bounds.height > 100 ? `-big` : `-small`;
2126
return (
2227
<li
23-
className="list-item -compact"
28+
className={`list-item -compact ${avatar ? avatarClassSwitch : ''}`}
2429
tabIndex={1}
2530
onClick={
2631
onClick
@@ -29,6 +34,17 @@ const ListItem: React.FunctionComponent<ListItemProps> = ({
2934
}
3035
key={id}
3136
>
37+
{avatar && (
38+
// @ts-ignore can't bothered to figure out which HTMLELEMENT type I need for this
39+
<div {...bind} className={`avatar ${avatarClassSwitch}`}>
40+
<div
41+
className="wrapper"
42+
style={{ backgroundImage: `url(${avatar.src})` }}
43+
>
44+
<img src={avatar.src} />
45+
</div>
46+
</div>
47+
)}
3248
<div className="content">
3349
<span className="label">{label}</span>
3450
{details && <div className="details">{details}</div>}

src/shared/components/Animations/list-item.less

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
.list-item {
1616
.listItemLike();
17+
display: flex;
18+
flex-direction: column;
1719
&:focus,
1820
&:focus-within {
1921
background-color: fade(@primary-color, 5%);
@@ -24,10 +26,33 @@
2426
&:hover > .content > .actions {
2527
display: block;
2628
}
29+
> .avatar {
30+
background-color: @header-background-color;
31+
margin-bottom: @default-pad;
32+
border-radius: @border-radius-base;
33+
}
34+
> .avatar.-small {
35+
margin: 0;
36+
width: fit-content;
37+
height: 100%;
38+
margin: 0 1em 0 0;
39+
}
40+
> .avatar > .wrapper {
41+
background-size: contain;
42+
background-position: 50%;
43+
background-repeat: no-repeat;
44+
max-height: 260px;
45+
}
46+
> .avatar > .wrapper > img {
47+
visibility: hidden;
48+
max-height: 100%;
49+
max-width: 100%;
50+
}
2751
> .content {
2852
display: flex;
2953
justify-content: space-between;
3054
height: 24px;
55+
flex-grow: 1;
3156
}
3257
> .content > .label {
3358
.ellipsis();
@@ -51,4 +76,7 @@
5176
z-index: 1;
5277
.ellipsis();
5378
}
79+
&.-small {
80+
flex-direction: row;
81+
}
5482
}

src/shared/components/Workspace/Queries/QueriesBoard.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,16 @@ interface QueriesComponentProps extends QueriesContainerProps {}
1010
const QueriesComponent: React.FunctionComponent<
1111
QueriesComponentProps
1212
> = props => {
13-
const {
14-
lists,
15-
pageSize,
16-
queryResources,
17-
goToResource,
18-
goToQuery,
19-
updateList,
20-
deleteList,
21-
cloneList,
22-
createList,
23-
} = props;
13+
const { lists, updateList, deleteList, cloneList, createList } = props;
2414
return (
2515
<div className="queries-board">
2616
<div className="wrapper">
2717
{lists.map((list: List, index: number) => {
2818
return (
2919
<Query
3020
{...{
21+
...props,
3122
list,
32-
pageSize,
33-
queryResources,
34-
goToResource,
35-
goToQuery,
3623
updateList: (list: List) => updateList(index, list),
3724
deleteList: () => deleteList(index),
3825
cloneList: (list: List) => cloneList(index, list),

src/shared/components/Workspace/Queries/QueriesContainer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Project,
66
Resource,
77
PaginationSettings,
8+
NexusFile,
89
} from '@bbp/nexus-sdk';
910
import { RootState } from '../../../store/reducers';
1011
import { List } from '../../../store/reducers/lists';
@@ -36,6 +37,7 @@ export interface QueriesContainerProps {
3637
deleteList: (listIndex: number) => void;
3738
cloneList: (listIndex: number, list: List) => void;
3839
createList: () => void;
40+
getFilePreview: (selfUrl: string) => Promise<NexusFile>;
3941
queryResources: (
4042
id: string,
4143
paginationSettings: PaginationSettings,
@@ -103,6 +105,7 @@ const mapDispatchToProps = (
103105
dispatch(cloneList(makeOrgProjectFilterKey(org, project), listIndex, list)),
104106
initialize: () =>
105107
dispatch(initializeProjectList(makeOrgProjectFilterKey(org, project))),
108+
getFilePreview: (selfUrl: string) => NexusFile.getSelf(selfUrl, true),
106109
queryResources: (
107110
id: string,
108111
paginationSettings: PaginationSettings,

src/shared/components/Workspace/Queries/Query/QueryComponent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import './query-component.less';
44
import InfiniteScroll from '../../../Animations/InfiniteScroll';
55
import ListItem from '../../../Animations/ListItem';
66
import { FetchableState } from '../../../../store/reducers/utils';
7-
import { PaginatedList, Resource } from '@bbp/nexus-sdk';
7+
import { PaginatedList, Resource, NexusFile } from '@bbp/nexus-sdk';
88
import ResourceMetadataCard from '../../../Resources/MetadataCard';
99
import { Popover, Icon, Tooltip, Button, Spin } from 'antd';
1010
import TypesIconList from '../../../Types/TypesIcon';
@@ -18,6 +18,7 @@ const MOUSE_ENTER_DELAY = 0.5;
1818
interface QueryComponentProps {
1919
list: List;
2020
goToResource: (resource: Resource) => void;
21+
getFilePreview: (selfUrl: string) => Promise<NexusFile>;
2122
goToQuery: (list: List) => void;
2223
next: VoidFunction;
2324
updateList: (list: List) => void;
@@ -40,6 +41,7 @@ const QueryComponent: React.FunctionComponent<QueryComponentProps> = props => {
4041
updateList,
4142
deleteList,
4243
cloneList,
44+
getFilePreview,
4345
next,
4446
showSpinner,
4547
} = props;
@@ -95,6 +97,7 @@ const QueryComponent: React.FunctionComponent<QueryComponentProps> = props => {
9597
};
9698
const total =
9799
(fetchablePaginatedList.data && fetchablePaginatedList.data.total) || 0;
100+
98101
return (
99102
<div className="query-component">
100103
<h3 className="header">

src/shared/components/Workspace/Queries/Query/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { PaginationSettings, Resource } from '@bbp/nexus-sdk';
2+
import { PaginationSettings, Resource, NexusFile } from '@bbp/nexus-sdk';
33
import { FilterQuery } from '../../../../store/actions/queryResource';
44
import { List } from '../../../../store/reducers/lists';
55
import QueryComponent from './QueryComponent';
@@ -12,6 +12,7 @@ interface QueryContainerProps {
1212
cloneList: (list: List) => void;
1313
goToResource: (resource: Resource) => void;
1414
goToQuery: (list: List) => void;
15+
getFilePreview: (selfUrl: string) => Promise<NexusFile>;
1516
queryResources: (
1617
id: string,
1718
paginationSettings: PaginationSettings,

src/shared/store/actions/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,10 @@ const pollProjectCreated = async (project: Project): Promise<void> => {
153153
// TODO: maybe do something if not 404?
154154
await asyncTimeout(pollingTimeInMilliseconds);
155155
iterations += 1;
156-
if (iterations >= shortCircuitIterationCount) {
156+
if (iterations > shortCircuitIterationCount) {
157157
projectReady = true;
158158
notification.warning({
159-
message: `Project ${project.label} is taking too long to set up`,
159+
message: `Project is taking too long to set up`,
160160
description:
161161
'This process is taking longer than usual. You might have to grab a coffee and come back later.',
162162
duration: 0,

src/shared/views/Home.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ const Home: React.FunctionComponent<HomeProps> = ({
235235
}
236236

237237
return (
238-
<>
238+
<div className="projects-view">
239239
<h1 style={{ marginBottom: 0, marginRight: 8 }}>{activeOrg.label}</h1>
240240
{activeOrg.description && <p>{activeOrg.description}</p>}
241241
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 20 }}>
@@ -312,7 +312,7 @@ const Home: React.FunctionComponent<HomeProps> = ({
312312
/>
313313
)}
314314
</Drawer>
315-
</>
315+
</div>
316316
);
317317
};
318318

0 commit comments

Comments
 (0)