Skip to content

Commit

Permalink
Env table update (#341)
Browse files Browse the repository at this point in the history
* use material ui click away listener to clean up props and function of table

* index environments by id, delete environement by id
  • Loading branch information
D-B-Hawk authored Oct 18, 2023
1 parent dbf32e0 commit 33f0d02
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 92 deletions.
34 changes: 4 additions & 30 deletions components/environmentsTable/environmentsTable.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Meta, StoryObj } from '@storybook/react';

import { mockEnvironmentsResponse } from '../../tests/mocks/mockEnvironmentsResponse';
import { useAppDispatch, useAppSelector } from '../../redux/store';
import { setEnvironments } from '../../redux/slices/environments.slice';
import { ClusterEnvironment } from '../../types/provision';
import { noop } from '../../utils/noop';
import { createEnvMap } from '../../utils/createEnvMap';

Expand All @@ -18,31 +14,9 @@ const meta: Meta<typeof EnvironmentsTable> = {

export default meta;

const EnvironmentsTableWithHooks = () => {
const [selectedEnv, setSelectedEnv] = useState<ClusterEnvironment>();
const { environments } = useAppSelector(({ environments }) => environments);

const dispatch = useAppDispatch();

const handleMenuButtonClick = (env: ClusterEnvironment) => {
setSelectedEnv((curEnv) => (curEnv?.name === env.name ? undefined : env));
};

useEffect(() => {
dispatch(setEnvironments(mockEnvironments));
}, [dispatch]);

return (
<EnvironmentsTable
environments={environments}
onDeleteEnvironment={noop}
onMenuButtonClick={handleMenuButtonClick}
selectedEnvironment={selectedEnv}
// onEditEnvironment={noop}
/>
);
};

export const Default: StoryObj<typeof EnvironmentsTable> = {
render: () => <EnvironmentsTableWithHooks />,
args: {
onDeleteEnvironment: noop,
environments: mockEnvironments,
},
};
55 changes: 24 additions & 31 deletions components/environmentsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import List from '@mui/material/List';
import TableSortLabel from '@mui/material/TableSortLabel';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
import { ClickAwayListener } from '@mui/material';
import moment from 'moment';

import { ECHO_BLUE, FIRE_BRICK, MAGNOLIA, PRIMARY, SALTBOX_BLUE } from '../../constants/colors';
Expand All @@ -29,6 +30,8 @@ import {
StyledTable,
} from './environmentsTable.styled';

import useToggle from '@/hooks/useToggle';

const MyButton = styled.button<{ selected?: boolean }>`
display: flex;
justify-content: center;
Expand All @@ -50,20 +53,18 @@ const MyButton = styled.button<{ selected?: boolean }>`

interface EnvironmentRowProps {
environment: ClusterEnvironment;
onDeleteEnvironment: () => void;
onMenuButtonClick: (env: ClusterEnvironment) => void;
selected?: boolean;
onDeleteEnvironment: (envId: string) => void;
// onEditEnvironment: () => void;
}

const EnvironmentRow: FunctionComponent<EnvironmentRowProps> = ({
environment,
onDeleteEnvironment,
// onEditEnvironment,
onMenuButtonClick,
selected,
}) => {
const { name, description, color, creationDate } = environment;
const { id, name, description, color, creationDate } = environment;
const { isOpen, close, toggle } = useToggle();

return (
<StyledTableRow>
<StyledTableCell scope="row">
Expand All @@ -81,30 +82,28 @@ const EnvironmentRow: FunctionComponent<EnvironmentRowProps> = ({
</StyledTableCell>
<StyledTableCell>
<div style={{ position: 'relative' }}>
<MyButton
aria-label="more info"
onClick={() => onMenuButtonClick(environment)}
selected={selected}
>
<MyButton aria-label="more info" onClick={toggle} selected={isOpen}>
<MoreHorizIcon />
</MyButton>
{selected && (
<Menu>
<List>
{/* <ListItem disablePadding>
{isOpen && (
<ClickAwayListener onClickAway={close}>
<Menu>
<List>
{/* <ListItem disablePadding>
<ListItemButton onClick={onEditEnvironment}>
<Typography variant="body2">Edit</Typography>
</ListItemButton>
</ListItem> */}
<ListItem disablePadding>
<ListItemButton onClick={onDeleteEnvironment}>
<Typography variant="body2" style={{ color: `${FIRE_BRICK}` }}>
Delete environment
</Typography>
</ListItemButton>
</ListItem>
</List>
</Menu>
<ListItem disablePadding>
<ListItemButton onClick={() => onDeleteEnvironment(id)}>
<Typography variant="body2" style={{ color: `${FIRE_BRICK}` }}>
Delete environment
</Typography>
</ListItemButton>
</ListItem>
</List>
</Menu>
</ClickAwayListener>
)}
</div>
</StyledTableCell>
Expand Down Expand Up @@ -180,19 +179,15 @@ const EnvironmentTableHead: FunctionComponent<EnvironmentTableHeadProps> = ({

interface EnvironmentsTableProps extends Omit<ComponentPropsWithRef<'tbody'>, 'key'> {
environments: EnvMap;
selectedEnvironment?: ClusterEnvironment;
onDeleteEnvironment: () => void;
onMenuButtonClick: (env: ClusterEnvironment) => void;
onDeleteEnvironment: (envId: string) => void;
customRef?: React.Ref<HTMLTableSectionElement>;
// onEditEnvironment: () => void;
}

export const EnvironmentsTable: FunctionComponent<EnvironmentsTableProps> = ({
environments,
selectedEnvironment,
onDeleteEnvironment,
// onEditEnvironment,
onMenuButtonClick,
customRef,
}) => {
const [orderBy, setOrderBy] = useState<EnvKey>('creationDate');
Expand Down Expand Up @@ -221,8 +216,6 @@ export const EnvironmentsTable: FunctionComponent<EnvironmentsTableProps> = ({
environment={environment}
onDeleteEnvironment={onDeleteEnvironment}
// onEditEnvironment={onEditEnvironment}
onMenuButtonClick={onMenuButtonClick}
selected={environment.name === selectedEnvironment?.name}
/>
))}
</StyledTableBody>
Expand Down
39 changes: 14 additions & 25 deletions containers/environments/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import React, { FunctionComponent, useEffect, useState, useCallback, useRef } from 'react';
import React, { FunctionComponent, useEffect, useState, useCallback } from 'react';
import styled from 'styled-components';
import Image from 'next/image';

Expand All @@ -23,12 +23,10 @@ import { ClusterEnvironment } from '../../types/provision';
import DeleteEnvironment from '../../components/deleteEnvironment';
import { clearEnvironmentError } from '../../redux/slices/environments.slice';

import { useOnClickOutside } from '@/hooks/useOnClickOutside';
import { noop } from '@/utils/noop';

const Environments: FunctionComponent = () => {
const { isOpen, close, open } = useToggle();
const { isOpen: deleteEnv, close: closeDeleteEnv, open: openDeleteEnv } = useToggle();

const [selectedEnv, setSelectedEnv] = useState<ClusterEnvironment>();

Expand All @@ -37,10 +35,6 @@ const Environments: FunctionComponent = () => {
);
const dispatch = useAppDispatch();

const handleMenuButtonClick = useCallback((env: ClusterEnvironment) => {
setSelectedEnv((curEnv) => (curEnv?.name === env.name ? undefined : env));
}, []);

const handleAddEnvironment = useCallback(
(env: ClusterEnvironment) => {
dispatch(createEnvironment(env))
Expand All @@ -59,16 +53,14 @@ const Environments: FunctionComponent = () => {
.unwrap()
.then(() => {
setSelectedEnv(undefined);
closeDeleteEnv();
})
.catch(noop);
}
}, [selectedEnv, dispatch, closeDeleteEnv]);
}, [selectedEnv, dispatch]);

const handleDeleteModal = useCallback(() => {
setSelectedEnv(undefined);
closeDeleteEnv();
}, [closeDeleteEnv]);
}, []);

const handleErrorClose = useCallback(() => {
dispatch(clearEnvironmentError());
Expand All @@ -79,19 +71,19 @@ const Environments: FunctionComponent = () => {
close();
}, [dispatch, close]);

const handleDeleteEnv = useCallback(
(id: string) => {
if (environments[id]) {
setSelectedEnv(environments[id]);
}
},
[environments],
);

useEffect(() => {
dispatch(getAllEnvironments());
}, [dispatch]);

const ref = useRef<HTMLTableSectionElement>(null);

useOnClickOutside(ref, () => {
if (!isOpen && !deleteEnv) {
handleDeleteModal();
handleModalClose();
}
});

return (
<Column style={{ width: '100%' }}>
<Header>
Expand All @@ -111,11 +103,8 @@ const Environments: FunctionComponent = () => {

{Object.keys(environments).length ? (
<EnvironmentsTable
ref={ref}
environments={environments}
onDeleteEnvironment={openDeleteEnv}
onMenuButtonClick={handleMenuButtonClick}
selectedEnvironment={selectedEnv}
onDeleteEnvironment={handleDeleteEnv}
// onEditEnvironment={noop}
/>
) : (
Expand Down Expand Up @@ -145,7 +134,7 @@ const Environments: FunctionComponent = () => {
</Modal>
{selectedEnv && (
<DeleteEnvironment
isOpen={deleteEnv}
isOpen={!!selectedEnv}
environment={selectedEnv}
boundToCluster={boundEnvironments[selectedEnv.name]}
onClose={handleDeleteModal}
Expand Down
4 changes: 2 additions & 2 deletions redux/slices/environments.slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ const environmentsSlice = createSlice({
state.loading = false;
state.error = action.error.message;
})
.addCase(deleteEnvironment.fulfilled, (state, { payload: envName }) => {
.addCase(deleteEnvironment.fulfilled, (state, { payload: envId }) => {
state.loading = false;
delete state.environments[envName];
delete state.environments[envId];
});
},
});
Expand Down
6 changes: 3 additions & 3 deletions redux/thunks/environments.thunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ export const createEnvironment = createAsyncThunk<ClusterEnvironment, ClusterEnv
},
);

export const deleteEnvironment = createAsyncThunk<ClusterEnvironment['name'], ClusterEnvironment>(
export const deleteEnvironment = createAsyncThunk<ClusterEnvironment['id'], ClusterEnvironment>(
'environments/deleteEnvironment',
async (environment, { dispatch }) => {
try {
await axios.delete(
`/api/proxy?${createQueryString('url', `/environment/${environment.name}`)}`,
`/api/proxy?${createQueryString('url', `/environment/${environment.id}`)}`,
);

dispatch(
Expand All @@ -65,7 +65,7 @@ export const deleteEnvironment = createAsyncThunk<ClusterEnvironment['name'], Cl
}),
);

return environment.name;
return environment.id;
} catch (error) {
if (axios.isAxiosError(error)) {
throw error.response?.data.error;
Expand Down
2 changes: 1 addition & 1 deletion utils/createEnvMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { mapEnvironmentFromRaw } from './mapEnvironmentFromRaw';

export function createEnvMap(environments: EnvironmentResponse[]): EnvMap {
return environments.reduce<EnvMap>((acc, curVal) => {
acc[curVal.name] = mapEnvironmentFromRaw(curVal);
acc[curVal._id] = mapEnvironmentFromRaw(curVal);
return acc;
}, {});
}

0 comments on commit 33f0d02

Please sign in to comment.