Skip to content

Commit

Permalink
Project Screen (#449)
Browse files Browse the repository at this point in the history
* Project Screen

* Showing empty message when there is no data
  • Loading branch information
javipacheco authored Sep 26, 2023
1 parent 0789c7a commit a2fe05a
Show file tree
Hide file tree
Showing 10 changed files with 585 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class ProjectRepositoryService(
throw OrganizationsException("You can't delete the project. User is not the owner of the organization")
}

organization.delete()
project.delete()

}
}
Expand Down
162 changes: 95 additions & 67 deletions server/web/src/components/Pages/Organizations/Organizations.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useAuth } from "@/state/Auth";
import { LoadingContext } from "@/state/Loading";
import { PostOrganizationProps, deleteOrganizations, getOrganizations, postOrganizations, putOrganizations } from "@/utils/api/organizations";
import { deleteOrganizations, getOrganizations, postOrganizations, putOrganizations } from "@/utils/api/organizations";
import {
Alert,
Box,
Button,
Dialog,
Expand All @@ -11,6 +12,7 @@ import {
DialogTitle,
Grid,
Paper,
Snackbar,
Table,
TableBody,
TableCell,
Expand All @@ -22,55 +24,68 @@ import {
} from "@mui/material";
import { ChangeEvent, useContext, useEffect, useState } from "react";

type UpdateOrganization = {
id?: number;
name: string;
}

const emptyUpdateOrganization = { name: "" }

export function Organizations() {

const auth = useAuth();

// Alerts

const [showAlert, setShowAlert] = useState<string>('');

// functions to open/close the add/edit organization dialog

const [openAddEditOrganization, setOpenAddEditOrganization] = useState(false);

const [organizationforUpdating, setOrganizationForUpdating] = useState<OrganizationResponse | undefined>(undefined); // when adding is undefined and updating has the organization

const [organizationDataInDialog, setOrganizationDataInDialog] = useState<PostOrganizationProps | undefined>(undefined);
const [organizationforUpdating, setOrganizationForUpdating] = useState<UpdateOrganization>(emptyUpdateOrganization);

const handleClickAddOrganization = () => {
setOpenAddEditOrganization(true);
setOrganizationForUpdating(undefined);
setOrganizationDataInDialog(undefined);
setOrganizationForUpdating(emptyUpdateOrganization);
};

const handleClickEditOrganization = (org: OrganizationResponse) => {
setOpenAddEditOrganization(true);
setOrganizationForUpdating(org);
setOrganizationDataInDialog({ name: org.name })
setOrganizationForUpdating({ ...org });
};

const handleCloseAddEditOrganization = () => {
setOpenAddEditOrganization(false);
};

const handleSaveAddEditOrganization = async () => {
if (organizationDataInDialog != undefined) {
if (organizationforUpdating == undefined)
await postOrganizations(auth.authToken, organizationDataInDialog);
else
await putOrganizations(auth.authToken, organizationforUpdating.id, organizationDataInDialog);

loadOrganizations();
if (organizationforUpdating.name == "") {
setShowAlert("Name must not be empty");
throw new Error("Name must not be emptyl");
}
if (organizationforUpdating.id == null) {
await postOrganizations(auth.authToken, { name: organizationforUpdating.name });
} else {
await putOrganizations(auth.authToken, organizationforUpdating.id, { name: organizationforUpdating.name });
}
loadOrganizations();

setOpenAddEditOrganization(false);
};

const nameEditingHandleChange = (event: ChangeEvent<HTMLInputElement>) => {
setOrganizationDataInDialog({ name: event.target.value })
setOrganizationForUpdating({
id: organizationforUpdating.id,
name: event.target.value,
});
};

// functions to open/close the delete organization dialog

const [openDeleteOrganization, setOpenDeleteOrganization] = useState(false);

const [organizationforDeleting, setOrganizationForDeleting] = useState<OrganizationResponse | undefined>(undefined);
const [organizationforDeleting, setOrganizationForDeleting] = useState<OrganizationResponse | undefined>(undefined);

const handleClickDeleteOrganization = (org: OrganizationResponse) => {
setOpenDeleteOrganization(true);
Expand All @@ -82,12 +97,12 @@ export function Organizations() {
};

const handleDeleteOrganization = async () => {
if (organizationforDeleting != undefined)
await deleteOrganizations(auth.authToken, organizationforDeleting.id);
if (organizationforDeleting != undefined)
await deleteOrganizations(auth.authToken, organizationforDeleting.id);

loadOrganizations();
setOpenDeleteOrganization(false);
loadOrganizations();

setOpenDeleteOrganization(false);
};

// function to load organizations
Expand Down Expand Up @@ -129,56 +144,61 @@ export function Organizations() {
</Button>
</Grid>
<Box sx={{ m: 2 }} />
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Users</TableCell>
<TableCell>Name</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{organizations.map((organization) => (
<TableRow
key={organization.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{organization.users}
</TableCell>
<TableCell component="th" scope="row" style={{ width: "90%" }}>
{organization.name}
</TableCell>
<TableCell align="right">
<Button
onClick={() => handleClickEditOrganization(organization)}
variant="text"
disableElevation>
<Typography variant="button">Edit</Typography>
</Button>
</TableCell>
<TableCell align="right">
<Button
onClick={() => handleClickDeleteOrganization(organization)}
variant="text"
disableElevation>
<Typography variant="button">Delete</Typography>
</Button>
</TableCell>
{organizations.length == 0 ?
<Typography >
No organizations at this moment
</Typography> :
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Users</TableCell>
<TableCell>Name</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</TableHead>
<TableBody>
{organizations.map((organization) => (
<TableRow
key={organization.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{organization.users}
</TableCell>
<TableCell component="th" scope="row" style={{ width: "90%" }}>
{organization.name}
</TableCell>
<TableCell align="right">
<Button
onClick={() => handleClickEditOrganization(organization)}
variant="text"
disableElevation>
<Typography variant="button">Edit</Typography>
</Button>
</TableCell>
<TableCell align="right">
<Button
onClick={() => handleClickDeleteOrganization(organization)}
variant="text"
disableElevation>
<Typography variant="button">Delete</Typography>
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
}
</>
}

{/* Add/Edit Organization Dialog */}

<Dialog open={openAddEditOrganization} onClose={handleCloseAddEditOrganization}>
<DialogTitle>{organizationforUpdating == undefined ? "New Organization" : "Update Organization"}</DialogTitle>
<DialogTitle>{organizationforUpdating.id == null ? "New Organization" : "Update Organization"}</DialogTitle>
<DialogContent>
<TextField
autoFocus
Expand All @@ -187,7 +207,7 @@ export function Organizations() {
label="Name"
fullWidth
variant="standard"
value={organizationDataInDialog?.name}
value={organizationforUpdating?.name}
onChange={nameEditingHandleChange}
sx={{
width: { xs: '100%', sm: 550 },
Expand All @@ -196,7 +216,7 @@ export function Organizations() {
</DialogContent>
<DialogActions>
<Button onClick={handleCloseAddEditOrganization}>Cancel</Button>
<Button onClick={handleSaveAddEditOrganization}>{organizationforUpdating == undefined ? "Create" : "Update"}</Button>
<Button onClick={handleSaveAddEditOrganization}>{organizationforUpdating.id == null ? "Create" : "Update"}</Button>
</DialogActions>
</Dialog>

Expand Down Expand Up @@ -225,5 +245,13 @@ export function Organizations() {
</DialogActions>
</Dialog>
</div>

{/* Alert */}
<Snackbar
open={!!showAlert}
onClose={(_, reason) => reason !== 'clickaway' && setShowAlert('')}
autoHideDuration={5000}>
<Alert severity="error">{showAlert}</Alert>
</Snackbar>
</>;
}
Loading

0 comments on commit a2fe05a

Please sign in to comment.