Skip to content

Commit fa24d66

Browse files
committed
feat(project-page): Add option to select unit, org and project from project page
1 parent cf45ce0 commit fa24d66

File tree

6 files changed

+109
-23
lines changed

6 files changed

+109
-23
lines changed

components/UserSettings/UserSettingsContent/ContextSection/ContextSection.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Grid } from '@material-ui/core';
22

3+
import { OrganisationAutocomplete } from '../../../userContext/OrganisationAutocomplete';
4+
import { UnitAutocomplete } from '../../../userContext/UnitAutocomplete';
35
import { ContextActions } from './ContextActions';
4-
import { OrganisationAutocomplete } from './OrganisationAutocomplete';
5-
import { UnitAutocomplete } from './UnitAutocomplete';
66

77
/**
88
* Displays `Context` section in User Settings.

components/UserSettings/UserSettingsContent/ProjectStatsSection/ProjectStatsSection.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ export const ProjectStatsSection = () => {
164164
isLoading={isProjectSubscriptionsLoading}
165165
tableContainer={false}
166166
/>
167-
<br />
168167
<DataTable
169168
columns={storageColumns}
170169
customTableProps={{
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import { useQuery } from 'react-query';
33
import type { AsError, OrganisationDetail, UnitDetail } from '@squonk/account-server-client';
44

55
import { TextField, Typography } from '@material-ui/core';
6+
import type { AutocompleteProps } from '@material-ui/lab';
67
import { Autocomplete } from '@material-ui/lab';
78
import axios from 'axios';
89

9-
import { AS_API_URL } from '../../../../constants';
10-
import { useOrganisationUnit } from '../../../../context/organisationUnitContext';
11-
import { useCurrentProjectId } from '../../../../hooks/projectHooks';
12-
import { getErrorMessage } from '../../../../utils/orvalError';
10+
import { AS_API_URL } from '../../constants';
11+
import { useOrganisationUnit } from '../../context/organisationUnitContext';
12+
import { useCurrentProjectId } from '../../hooks/projectHooks';
13+
import { getErrorMessage } from '../../utils/orvalError';
1314

1415
// TODO remove these after AS client is updated
1516
interface OrganisationUnitsGetResponse {
@@ -21,10 +22,15 @@ interface UnitsGetResponse {
2122
units: OrganisationUnitsGetResponse[];
2223
}
2324

25+
type OrganisationAutocompleteProps = Omit<
26+
AutocompleteProps<OrganisationDetail, false, false, false>,
27+
'renderInput' | 'options'
28+
>;
29+
2430
/**
2531
* Autocomplete which lists organisations available to a user to select as context.
2632
*/
27-
export const OrganisationAutocomplete = () => {
33+
export const OrganisationAutocomplete = (props: OrganisationAutocompleteProps) => {
2834
// TODO remove these after AS client is updated
2935
const { data, isLoading, isError, error } = useQuery<UnitsGetResponse, AsError>(
3036
`${AS_API_URL}/unit`, // TODO change this once AS client is updated
@@ -44,13 +50,14 @@ export const OrganisationAutocomplete = () => {
4450

4551
return (
4652
<Autocomplete
53+
{...props}
4754
fullWidth
4855
getOptionLabel={(option) => option.name}
4956
getOptionSelected={(option, value) => option.id === value.id}
5057
id="organisation-selection"
5158
loading={isLoading}
5259
options={organisations}
53-
renderInput={(params) => <TextField {...params} label="Organisation" size="medium" />}
60+
renderInput={(params) => <TextField {...params} label="Organisation" />}
5461
value={organisationUnit.organisation ?? null}
5562
onChange={(_, organisation) => {
5663
// Not the best solution but I couldnt figure out anything better
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { ProductDmProjectTier } from '@squonk/account-server-client';
2+
3+
import { TextField } from '@material-ui/core';
4+
import type { AutocompleteProps } from '@material-ui/lab';
5+
import { Autocomplete } from '@material-ui/lab';
6+
7+
import { useCurrentProjectId } from '../../hooks/projectHooks';
8+
import { useProjectSubscriptions } from '../UserSettings/UserSettingsContent/ProjectStatsSection/useProjectSubscriptions';
9+
10+
export type ProjectAutocompleteProps = Omit<
11+
AutocompleteProps<ProductDmProjectTier, false, false, false>,
12+
'renderInput' | 'options'
13+
>;
14+
15+
export const ProjectAutocomplete = (props: ProjectAutocompleteProps) => {
16+
const { projectSubscriptions, isLoading: isProjectSubscriptionsLoading } =
17+
useProjectSubscriptions();
18+
19+
const { projectId, setCurrentProjectId } = useCurrentProjectId();
20+
21+
return (
22+
<Autocomplete
23+
{...props}
24+
fullWidth
25+
getOptionLabel={(option) => option.product.name ?? 'Missing name'}
26+
loading={isProjectSubscriptionsLoading}
27+
options={projectSubscriptions}
28+
renderInput={(params) => <TextField {...params} label="Project" />}
29+
value={projectSubscriptions.find((sub) => sub.claim?.id == projectId) ?? null}
30+
onChange={(_, value) => setCurrentProjectId(value?.claim?.id ?? undefined)}
31+
/>
32+
);
33+
};
Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1+
import type { UnitDetail } from '@squonk/account-server-client';
12
import { useGetOrganisationUnits } from '@squonk/account-server-client/unit';
23

34
import { IconButton, InputAdornment, TextField, Typography } from '@material-ui/core';
45
import { DeleteForever } from '@material-ui/icons';
6+
import type { AutocompleteProps } from '@material-ui/lab';
57
import { Autocomplete } from '@material-ui/lab';
68

7-
import { useOrganisationUnit } from '../../../../context/organisationUnitContext';
8-
import { useCurrentProjectId } from '../../../../hooks/projectHooks';
9-
import { useKeycloakUser } from '../../../../hooks/useKeycloakUser';
10-
import { getErrorMessage } from '../../../../utils/orvalError';
11-
import { WarningDeleteButton } from '../../../WarningDeleteButton';
9+
import { useOrganisationUnit } from '../../context/organisationUnitContext';
10+
import { useCurrentProjectId } from '../../hooks/projectHooks';
11+
import { useKeycloakUser } from '../../hooks/useKeycloakUser';
12+
import { getErrorMessage } from '../../utils/orvalError';
13+
import { WarningDeleteButton } from '../WarningDeleteButton';
14+
15+
type UnitAutocompleteProps = Omit<
16+
AutocompleteProps<UnitDetail, false, false, false>,
17+
'renderInput' | 'options'
18+
>;
1219

1320
/**
1421
* Autocomplete which lists context's organisation's units available to a user to select as context.
1522
*/
16-
export const UnitAutocomplete = () => {
23+
export const UnitAutocomplete = (props: UnitAutocompleteProps) => {
1724
const { organisationUnit, dispatchOrganisationUnit } = useOrganisationUnit();
1825
const { organisation, unit } = organisationUnit;
1926

@@ -37,6 +44,7 @@ export const UnitAutocomplete = () => {
3744

3845
return (
3946
<Autocomplete
47+
{...props}
4048
fullWidth
4149
getOptionLabel={(option) => option.name}
4250
getOptionSelected={(option, value) => option.id === value.id}
@@ -66,7 +74,6 @@ export const UnitAutocomplete = () => {
6674
),
6775
}}
6876
label="Unit"
69-
size="medium"
7077
/>
7178
)}
7279
value={unit ?? null}

pages/project.tsx

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
import { useGetProjects } from '@squonk/data-manager-client/project';
2+
13
import { withPageAuthRequired } from '@auth0/nextjs-auth0';
24
import { css } from '@emotion/react';
3-
import { Container, Typography } from '@material-ui/core';
5+
import { Box, Container, Grid, Typography } from '@material-ui/core';
46
import Head from 'next/head';
57
import Image from 'next/image';
68

9+
import { CenterLoader } from '../components/CenterLoader';
710
import Layout from '../components/Layout';
811
import { ProjectTable } from '../components/ProjectTable';
12+
import { OrganisationAutocomplete } from '../components/userContext/OrganisationAutocomplete';
13+
import { ProjectAutocomplete } from '../components/userContext/ProjectAutocomplete';
14+
import { UnitAutocomplete } from '../components/userContext/UnitAutocomplete';
915
import { useCurrentProject } from '../hooks/projectHooks';
1016
import { RoleRequired } from '../utils/RoleRequired';
1117

@@ -14,6 +20,7 @@ import { RoleRequired } from '../utils/RoleRequired';
1420
*/
1521
const Project = () => {
1622
const currentProject = useCurrentProject();
23+
const { isLoading } = useGetProjects();
1724

1825
return (
1926
<>
@@ -23,13 +30,33 @@ const Project = () => {
2330
<RoleRequired roles={process.env.NEXT_PUBLIC_KEYCLOAK_USER_ROLE?.split(' ')}>
2431
<Layout>
2532
<Container>
26-
{currentProject ? (
27-
<>
28-
<Typography gutterBottom variant="h1">
29-
Project: {currentProject.name}
30-
</Typography>
33+
{isLoading ? (
34+
<CenterLoader />
35+
) : currentProject ? (
36+
<Grid
37+
container
38+
css={css`
39+
display: flex;
40+
align-items: center;
41+
`}
42+
>
43+
<Grid item md={6} xs={12}>
44+
<Typography
45+
gutterBottom
46+
component="h1"
47+
css={css`
48+
word-break: break-all;
49+
`}
50+
variant={currentProject.name.length > 16 ? 'h2' : 'h1'}
51+
>
52+
Project: {currentProject.name}
53+
</Typography>
54+
</Grid>
55+
<Grid item md={6} xs={12}>
56+
<ProjectAutocomplete size="medium" />
57+
</Grid>
3158
<ProjectTable currentProject={currentProject} />
32-
</>
59+
</Grid>
3360
) : (
3461
<div
3562
css={css`
@@ -44,6 +71,19 @@ const Project = () => {
4471
src="https://squonk.informaticsmatters.org/assets/sadderSquonk.svg"
4572
width={150}
4673
/>
74+
<Box marginY={1}>
75+
<Grid container spacing={1}>
76+
<Grid container item alignItems="center" sm={6}>
77+
<OrganisationAutocomplete />
78+
</Grid>
79+
<Grid container item alignItems="center" sm={6}>
80+
<UnitAutocomplete />
81+
</Grid>
82+
<Grid container item alignItems="center" sm={12}>
83+
<ProjectAutocomplete size="medium" />
84+
</Grid>
85+
</Grid>
86+
</Box>
4787
</div>
4888
)}
4989
</Container>

0 commit comments

Comments
 (0)