update InputFile; AppFileList

This commit is contained in:
Ruidy Nemausat 2020-04-03 13:47:06 +02:00
parent 70d1df1e05
commit 12a8e9e289
6 changed files with 252 additions and 95 deletions

View file

@ -3,6 +3,7 @@ import { AppFile } from "../types/AppFile";
import { FileCollection } from "./FileCollection"; import { FileCollection } from "./FileCollection";
import { InputFile } from "./InputFile"; import { InputFile } from "./InputFile";
import { FilterBar } from "./FilterBar"; import { FilterBar } from "./FilterBar";
import { Grid, Typography } from "@material-ui/core";
type IProps = { type IProps = {
files: AppFile[]; files: AppFile[];
@ -18,14 +19,20 @@ export const FileList: FC<IProps> = ({ files }) => {
}; };
return ( return (
<> <>
<div className="row valign-wrapper"> <Grid container>
<h3>Files</h3> <Grid item xs>
<FilterBar <Typography variant="h4" component="h4">
filterText={filterText} Files
handleChange={handleChange} </Typography>
clearFilterText={clearFilterText} </Grid>
/> <Grid item xs={4}>
</div> <FilterBar
filterText={filterText}
handleChange={handleChange}
clearFilterText={clearFilterText}
/>
</Grid>
</Grid>
<InputFile /> <InputFile />
<FileCollection files={files} filterText={filterText} /> <FileCollection files={files} filterText={filterText} />
</> </>

View file

@ -13,7 +13,7 @@ export const AvatarList: FC<AvatarListProps> = ({ users }) => {
<></> <></>
) : ( ) : (
<> <>
<AvatarGroup max={2}> <AvatarGroup max={5}>
{users.map((user: User, i: number) => ( {users.map((user: User, i: number) => (
<Link to={`/users/${user.id}`} key={i}> <Link to={`/users/${user.id}`} key={i}>
<Avatar src={user.picture} alt={user.fullName} /> <Avatar src={user.picture} alt={user.fullName} />

View file

@ -1,27 +1,62 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { CloudUpload } from "@material-ui/icons";
import { makeStyles, createStyles, Theme } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
export const InputFile: FC = () => { export const InputFile: FC = () => {
return ( return (
<> <>
<form action="/upload"> <form action="/upload">
<div className="file-field input-field"> <div className="file-field input-field">
<div className="btn indigo lighten-1"> <UploadButton>
<i className="material-icons ">cloud_upload</i> <CloudUpload />
<input <input
type="file" type="file"
multiple multiple
accept=".doc,.docx,.pdf,.md,.gdoc,.zip,image/*" accept=".doc,.docx,.pdf,.md,.gdoc,.zip,image/*"
/> />
</div> </UploadButton>
<div className="file-path-wrapper">
<input
className="file-path validate"
type="text"
placeholder="Upload one or more files"
/>
</div>
</div> </div>
</form> </form>
</> </>
); );
}; };
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
"& > *": {
margin: theme.spacing(1)
}
},
input: {
display: "none"
}
})
);
const UploadButton: FC = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<input
accept=".doc,.docx,.pdf,.md,.gdoc,.zip,image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
/>
<label htmlFor="contained-button-file">
<Button
variant="contained"
color="primary"
component="span"
startIcon={<CloudUpload />}
>
Upload files
</Button>
</label>
</div>
);
};

View file

@ -0,0 +1,110 @@
import React, { FC } from "react";
import SwipeableViews from "react-swipeable-views";
import { makeStyles, Theme, useTheme } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import { Ticket } from "../types/Ticket";
import { Project } from "../types/Project";
import { FileList } from "./AppFileList";
import { TicketList } from "./TicketList";
import { AppFile } from "../types/AppFile";
interface TabProps {
children?: React.ReactNode;
dir?: string;
index: any;
value: any;
}
const TabPanel: FC<TabProps> = (props: TabProps) => {
const { children, value, index, ...other } = props;
return (
<Typography
component="div"
role="tabpanel"
hidden={value !== index}
id={`full-width-tabpanel-${index}`}
aria-labelledby={`full-width-tab-${index}`}
{...other}
>
{value === index && <Box p={3}>{children}</Box>}
</Typography>
);
};
const a11yProps = (index: any) => {
return {
id: `full-width-tab-${index}`,
"aria-controls": `full-width-tabpanel-${index}`
};
};
const useStyles = makeStyles((theme: Theme) => ({
root: {
backgroundColor: "#ffffff",
flexGrow: 1
}
}));
interface IProps {
tickets: Ticket[];
remainingDays?: number;
tabNames: string[];
files: AppFile[];
// activities: Activity[];
allProjects: Project[];
}
export const ProjectTabPanel: FC<IProps> = ({
tickets,
tabNames,
files
// allProjects
}) => {
const classes = useStyles();
const theme = useTheme();
const [value, setValue] = React.useState(0);
const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
setValue(newValue);
};
const handleChangeIndex = (index: number) => {
setValue(index);
};
return (
<div className={classes.root}>
<AppBar position="static" color="inherit">
<Tabs
value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
variant="fullWidth"
aria-label="full width tabs example"
>
{tabNames.map((t: string, i: number) => (
<Tab key={i} label={t} {...a11yProps({ i })} />
))}
</Tabs>
</AppBar>
<SwipeableViews
axis={theme.direction === "rtl" ? "x-reverse" : "x"}
index={value}
onChangeIndex={handleChangeIndex}
>
<TabPanel value={value} index={0} dir={theme.direction}>
<TicketList tickets={tickets} allProjects={[]} addButton={false} />
</TabPanel>
<TabPanel value={value} index={1} dir={theme.direction}>
<FileList files={files} />
</TabPanel>
</SwipeableViews>
</div>
);
};

View file

@ -42,58 +42,56 @@ export const TicketList: FC<TicketListProps> = ({
); );
return ( return (
<> <>
<div className="row valign-wrapper"> <NewTicketModal
<NewTicketModal handleClose={() => {
handleClose={() => { setShowNew(false);
setShowNew(false); }}
}} show={showNew}
show={showNew} allProjects={allProjects}
allProjects={allProjects} />
/>
<Grid container> <Grid container>
<Grid item xs> <Grid item xs>
<Typography variant="h4" component="h4"> <Typography variant="h4" component="h4">
Tickets Tickets
</Typography> </Typography>
</Grid>
<Grid item xs>
{addButton && (
<FloatingButton color="primary" size="small" onClick={onClick} />
)}
</Grid>
<Grid item xs={4}>
<FilterBar
filterText={filterText}
handleChange={handleChange}
clearFilterText={clearFilterText}
/>
</Grid>
<Grid item xs={12}>
<div className="col s12 grey lighten-1">
{filteredTickets.length === 0 ? (
<HorizontalCard />
) : (
filteredTickets.map((t: Ticket) => (
<HorizontalCard
key={t.id}
title={t.title}
remainingDays={t.endingDate}
link={`/tickets/${t.id}`}
validateTicket={async (e: MouseEvent) => {
e.preventDefault();
await put<HttpResponse<Ticket>>(
`${Constants.ticketsURI}/${t.id}/closed`,
{}
);
}}
/>
))
)}
</div>
</Grid>
</Grid> </Grid>
</div> <Grid item xs>
{addButton && (
<FloatingButton color="primary" size="small" onClick={onClick} />
)}
</Grid>
<Grid item xs={4}>
<FilterBar
filterText={filterText}
handleChange={handleChange}
clearFilterText={clearFilterText}
/>
</Grid>
<Grid item xs={12}>
<div className="col s12 grey lighten-1">
{filteredTickets.length === 0 ? (
<HorizontalCard />
) : (
filteredTickets.map((t: Ticket) => (
<HorizontalCard
key={t.id}
title={t.title}
remainingDays={t.endingDate}
link={`/tickets/${t.id}`}
validateTicket={async (e: MouseEvent) => {
e.preventDefault();
await put<HttpResponse<Ticket>>(
`${Constants.ticketsURI}/${t.id}/closed`,
{}
);
}}
/>
))
)}
</div>
</Grid>
</Grid>
</> </>
); );
}; };

View file

@ -6,6 +6,8 @@ import { ProgressBar } from "../components/ProgressBar";
import { TabRouter } from "../components/TabRouter"; import { TabRouter } from "../components/TabRouter";
import { FloatingButton } from "../components/FloatingButton"; import { FloatingButton } from "../components/FloatingButton";
import { UsersModal } from "../components/UsersModal"; import { UsersModal } from "../components/UsersModal";
import { Container, Grid } from "@material-ui/core";
import { ProjectTabPanel } from "../components/ProjectTabPanel";
interface IProps { interface IProps {
viewModel: ProjectVM; viewModel: ProjectVM;
@ -32,38 +34,43 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
const [showModal, setShowModal] = useState<boolean>(false); const [showModal, setShowModal] = useState<boolean>(false);
return ( return (
<div className="section"> <Container maxWidth="md">
<div className="container"> <Header title={title} description={description} />
<Header title={title} description={description} /> <UsersModal
<div className="row valign-wrapper"> show={showModal}
users={users}
allUsers={allUsers}
handleClose={() => setShowModal(false)}
/>
<Grid container>
<Grid item xs={3}>
<AvatarList users={users} /> <AvatarList users={users} />
</Grid>
<Grid item xs={9}>
<FloatingButton <FloatingButton
icon="add" icon="add"
color="default" color="default"
size="small" size="small"
onClick={() => setShowModal(true)} onClick={() => setShowModal(true)}
/> />
<UsersModal </Grid>
show={showModal} </Grid>
users={users}
allUsers={allUsers} <ProgressBar
handleClose={() => setShowModal(false)} value={progression}
/> tasksDone={ticketsDone}
</div> tasksTotalCount={ticketsTotalCount}
<ProgressBar remainingDays={remainingDays}
value={progression} />
tasksDone={ticketsDone}
tasksTotalCount={ticketsTotalCount} <ProjectTabPanel
remainingDays={remainingDays} tabNames={tabNames}
/> tickets={tickets}
<TabRouter files={files}
tabNames={tabNames} // activities={activities}
tickets={tickets} allProjects={allProjects}
files={files} />
activities={activities} </Container>
allProjects={allProjects}
/>
</div>
</div>
); );
}; };