Skip to content

Commit 90cc94a

Browse files
author
Michael Buchar
committed
feat(list): display interactive sessions (#436)
Add Only with sessions toggle bar to display only workflows that have interactive sessions opened. docs(readme): update local development instructions (#432) Write more comprehensive docs on how to run REANA-UI locally, especially for macOS developers.
1 parent af8c32b commit 90cc94a

File tree

10 files changed

+126
-10
lines changed

10 files changed

+126
-10
lines changed

AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The list of contributors in alphabetical order:
55
- [Alastair Lyall](https://orcid.org/0009-0000-4955-8935)
66
- [Alp Tuna](https://orcid.org/0009-0001-1915-3993)
77
- [Audrius Mecionis](https://orcid.org/0000-0002-3759-1663)
8+
- [Cameron McClymont](https://orcid.org/0009-0002-0176-5251)
89
- [Daan Rosendal](https://orcid.org/0000-0002-3447-9000)
910
- [Diego Rodriguez](https://orcid.org/0000-0003-0649-2002)
1011
- [Dinos Kousidis](https://orcid.org/0000-0002-4914-4289)

README.md

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,49 @@ The detailed information on how to install and use REANA can be found in
2727

2828
## Development
2929

30+
If you would like to develop this `reana-ui` package locally on your laptop
31+
(without compiling new container images of this component), you can proceed
32+
as follows.
33+
34+
Install a local REANA instance on your laptop, following [REANA developer
35+
wiki](https://github.com/reanahub/reana/wiki/Using-live-code-reload-and-debug-mode).
36+
37+
Install Node version 18 and Yarn version 4. If you are on macOS, beware that
38+
Yarn v4 may not be available in brew, so use the official upstream
39+
installation technique. For example:
40+
41+
```
42+
mise use -g node@18
43+
open https://yarnpkg.com/getting-started/install
44+
```
45+
46+
Clone this repository if you haven't already and go into the React package
47+
directory:
48+
49+
```console
50+
git clone https://github.com/reanahub/reana-ui.git
51+
cd reana-ui/reana-ui
52+
```
53+
54+
We can now install dependencies and start the development server:
55+
56+
```console
57+
yarn
58+
export REANA_SERVER_URL=https://localhost:30443
59+
yarn start
60+
```
61+
62+
You can now visit `https://localhost:3000` to see your local development
63+
interface and start seeing your code changes live.
64+
65+
Note that if you are using macOS and are having trouble running `yarn`, you may
66+
need to install several dependent packages:
67+
3068
```console
31-
$ git clone https://github.com/reanahub/reana-ui.git
32-
$ cd reana-ui/reana-ui
33-
$ yarn
34-
$ yarn start # make sure REANA_SERVER_URL env var is set
35-
$ firefox localhost:3000
69+
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman
3670
```
3771

38-
## Yarn scripts
72+
Available Yarn scripts:
3973

4074
- `start`: start a development server with live reload
4175
- `build`: build a production-ready bundle in the `build` folder

reana-ui/src/actions.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ export function fetchWorkflows({
282282
showLoader = true,
283283
workflowIdOrName,
284284
shared = false,
285+
type,
285286
}) {
286287
return async (dispatch) => {
287288
if (showLoader) {
@@ -298,6 +299,7 @@ export function fetchWorkflows({
298299
sort,
299300
workflowIdOrName,
300301
shared,
302+
...(type ? { type } : {}),
301303
})
302304
.then((resp) =>
303305
dispatch({

reana-ui/src/client.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class Client {
134134
sort,
135135
workflowIdOrName,
136136
shared,
137+
type,
137138
} = {}) {
138139
return this._request(
139140
WORKFLOWS_URL({
@@ -145,6 +146,7 @@ class Client {
145146
shared_by: sharedBy,
146147
shared_with: sharedWith,
147148
sort,
149+
type,
148150
}),
149151
);
150152
}

reana-ui/src/pages/workflowList/WorkflowList.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function Workflows() {
5050
const [refreshedAt, setRefreshedAt] = useState(currentUTCTime());
5151
const [pagination, setPagination] = useState({ page: 1, size: PAGE_SIZE });
5252
const [statusFilter, setStatusFilter] = useState(NON_DELETED_STATUSES);
53+
const [sessionFilter, setSessionFilter] = useState(false);
5354
const [searchFilter, setSearchFilter] = useState();
5455
const [ownedByFilter, setOwnedByFilter] = useState();
5556
const [sharedWithFilter, setSharedWithFilter] = useState();
@@ -91,6 +92,7 @@ function Workflows() {
9192
sharedBy,
9293
sharedWith: sharedWithFilter,
9394
sort: sortDir,
95+
...(sessionFilter ? { type: "interactive" } : {}),
9496
}),
9597
);
9698

@@ -108,6 +110,7 @@ function Workflows() {
108110
sharedWith: sharedWithFilter,
109111
sort: sortDir,
110112
showLoader,
113+
...(sessionFilter ? { type: "interactive" } : {}),
111114
}),
112115
);
113116
setRefreshedAt(currentUTCTime());
@@ -125,6 +128,7 @@ function Workflows() {
125128
sharedWithFilter,
126129
sortDir,
127130
workflowRefresh,
131+
sessionFilter,
128132
]);
129133

130134
const cleanPolling = () => {
@@ -175,6 +179,12 @@ function Workflows() {
175179
pagination,
176180
setPagination,
177181
)}
182+
sessionFilter={sessionFilter}
183+
setSessionFilter={applyFilter(
184+
setSessionFilter,
185+
pagination,
186+
setPagination,
187+
)}
178188
ownedByFilter={ownedByFilter}
179189
setOwnedByFilter={applyFilter(
180190
setOwnedByFilter,

reana-ui/src/pages/workflowList/WorkflowList.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@
4343
}
4444

4545
:global(.ui.text.container).workflow-list-container {
46-
max-width: 825px !important;
46+
max-width: 1200px !important;
4747
}

reana-ui/src/pages/workflowList/components/WorkflowFilters.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import WorkflowSorting from "./WorkflowSorting";
1616

1717
import styles from "./WorkflowFilters.module.scss";
1818
import WorkflowSharingFilters from "./WorkflowSharingFilter";
19+
import WorkflowSessionFilters from "~/pages/workflowList/components/WorkflowSessionFilters";
1920

2021
export default function WorkflowFilters({
2122
statusFilter,
@@ -26,6 +27,8 @@ export default function WorkflowFilters({
2627
setOwnedByFilter,
2728
sharedWithFilter,
2829
setSharedWithFilter,
30+
sessionFilter,
31+
setSessionFilter,
2932
}) {
3033
return (
3134
<div className={styles.container}>
@@ -34,6 +37,10 @@ export default function WorkflowFilters({
3437
statusFilter={statusFilter}
3538
filter={setStatusFilter}
3639
/>
40+
<WorkflowSessionFilters
41+
enabled={sessionFilter}
42+
filter={setSessionFilter}
43+
/>
3744
<WorkflowSharingFilters
3845
ownedByFilter={ownedByFilter}
3946
setOwnedByFilter={setOwnedByFilter}
@@ -57,4 +64,6 @@ WorkflowFilters.propTypes = {
5764
setOwnedByFilter: PropTypes.func.isRequired,
5865
sharedWithFilter: PropTypes.string,
5966
setSharedWithFilter: PropTypes.func.isRequired,
67+
sessionFilter: PropTypes.bool,
68+
setSessionFilter: PropTypes.func.isRequired,
6069
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
-*- coding: utf-8 -*-
3+
4+
This file is part of REANA.
5+
Copyright (C) 2025 CERN.
6+
7+
REANA is free software; you can redistribute it and/or modify it
8+
under the terms of the MIT License; see LICENSE file for more details.
9+
*/
10+
11+
import isEqual from "lodash/isEqual";
12+
import PropTypes from "prop-types";
13+
import { useEffect, useState } from "react";
14+
import { Checkbox, Grid } from "semantic-ui-react";
15+
16+
export default function WorkflowSessionFilters({
17+
enabled: enabledProp,
18+
filter,
19+
}) {
20+
const [enabled, setEnabled] = useState(false);
21+
22+
useEffect(() => {
23+
// Keep local UI in sync with the parent value
24+
if (!isEqual(enabled, enabledProp)) {
25+
setEnabled(enabledProp);
26+
}
27+
}, [enabledProp]);
28+
29+
useEffect(() => {
30+
// Notify parent when the toggle changes
31+
if (!isEqual(enabled, enabledProp)) {
32+
filter(enabled);
33+
}
34+
}, [enabled, enabledProp]);
35+
36+
return (
37+
<>
38+
<Grid.Column
39+
mobile={16}
40+
tablet={4}
41+
computer={3}
42+
className="center aligned"
43+
>
44+
<Checkbox
45+
toggle
46+
label="Only with sessions"
47+
checked={enabled}
48+
onChange={(_, { checked }) => setEnabled(!!checked)}
49+
/>
50+
</Grid.Column>
51+
</>
52+
);
53+
}
54+
55+
WorkflowSessionFilters.propTypes = {
56+
enabled: PropTypes.bool.isRequired,
57+
filter: PropTypes.func.isRequired,
58+
};

reana-ui/src/pages/workflowList/components/WorkflowSharingFilter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export default function WorkflowSharingFilters({
108108
};
109109

110110
return (
111-
<Grid.Column mobile={16} tablet={7} computer={6}>
111+
<Grid.Column mobile={16} tablet={7} computer={4}>
112112
<div style={{ display: "flex" }}>
113113
<Dropdown
114114
fluid

reana-ui/src/pages/workflowList/components/WorkflowStatusFilter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ export default function WorkflowStatusFilters({ statusFilter, filter }) {
6363
</Grid.Column>
6464
<Grid.Column
6565
mobile={16}
66-
tablet={5}
67-
computer={4}
66+
tablet={4}
67+
computer={3}
6868
className="center aligned"
6969
>
7070
<Checkbox

0 commit comments

Comments
 (0)