Skip to content

Commit

Permalink
Conflict merge
Browse files Browse the repository at this point in the history
  • Loading branch information
heymanpi committed Dec 14, 2020
2 parents a5ecf54 + ce994cf commit 59e3a8b
Show file tree
Hide file tree
Showing 62 changed files with 2,641 additions and 2,078 deletions.
6 changes: 6 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
10 changes: 5 additions & 5 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/store';
import actions from './redux/actions';
import { Box } from '@material-ui/core';
import apiActions from './redux/actions/api';

// Style
import { Box } from '@material-ui/core';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';
Expand All @@ -29,7 +29,7 @@ import Error404 from './pages/Error404';
// Public pages
import Sales from './pages/public/Sales';
import SaleDetail from './pages/public/SaleDetail';
import Orders from './pages/public/Orders';
import UserOrders from './pages/public/UserOrders';
import OrderDetail from './pages/public/OrderDetail';
import ContactForm from "./pages/public/ContactForm";

Expand Down Expand Up @@ -58,7 +58,7 @@ class App extends React.Component {

componentDidMount() {
// Get connected user
store.dispatch(actions.auth().all());
store.dispatch(apiActions.authUser.get());
}

render() {
Expand All @@ -81,7 +81,7 @@ class App extends React.Component {
<Route path="/sales/:sale_id" exact component={SaleDetail} />
<Route path="/contact" exact component={ContactForm} />
<ProtectedRoute path="/account" exact component={Account} />
<ProtectedRoute path="/orders" exact component={Orders} />
<ProtectedRoute path="/orders" exact component={UserOrders} />
<ProtectedRoute path="/orders/:order_id" exact component={OrderDetail} />
<Route path="/login" exact render={props => <LoginLogout {...props} action="login" />} />
<Route path="/logout" exact render={props => <LoginLogout {...props} action="logout" />} />
Expand Down
13 changes: 7 additions & 6 deletions src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import actions from '../redux/actions';
import apiActions from 'redux/actions/api';

import { makeStyles } from '@material-ui/core/styles';
import { AppBar, Toolbar, Container, Button, Menu, Divider, useMediaQuery } from '@material-ui/core';
import { MoreVert, Home, ShoppingCart, AccountCircle } from '@material-ui/icons';
import { NavLink } from 'react-router-dom';
import { NavButton, NavMenuItem } from './common/Nav.jsx';
import { hasManagerRights, textOrIcon } from '../utils';
import { NavButton, NavMenuItem } from 'components/common/Nav.jsx';
import { textOrIcon } from 'utils/format';
import { hasManagerRights } from 'utils/api';


const useStyles = makeStyles(theme => ({
Expand All @@ -30,12 +31,12 @@ export default function Header(props) {
const [menuTarget, setMenuTarget] = React.useState(null);

const dispatch = useDispatch();
const auth = useSelector(store => store.getData('auth', {}));
const userAssos = useSelector(store => store.getAuthRelatedData('associations', null));
const auth = useSelector(store => store.api.getData('auth', {}));
const userAssos = useSelector(store => store.api.getAuthRelatedData('associations', null));

React.useEffect(() => {
if (auth.user && !userAssos)
dispatch(actions.auth(auth.user.id).associations.all({ page_size: 'max' }));
dispatch(apiActions.authUser(auth.user.id).associations.all({ page_size: 'max' }));
});

return (
Expand Down
3 changes: 2 additions & 1 deletion src/components/MainLoader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ const useStyles = makeStyles({
export default function MainLoader(props) {

const classes = useStyles();
const auth = useSelector(store => store.get('auth'));
const auth = useSelector(store => store.api.get('auth'));

// Fail if cannot get auth
if (auth.error) {
console.warn(auth.error)
// TODO Deal with errors
throw new Error("Impossible de contacter le serveur")
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/MessageSystem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Snackbar } from '@material-ui/core';
import { Alert, AlertTitle } from '@material-ui/lab';
import { messagesActions } from '../redux/actions';
import messagesActions from '../redux/actions/messages';


export function Message({ title, details=null, severity="info", onClose, ...props }) {
Expand Down
110 changes: 110 additions & 0 deletions src/components/common/APIDataTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from "react";
import PropTypes from "prop-types";
import { useStoreAPIData } from "redux/hooks";
import { processPagination, pathToArray } from "redux/reducers/api";
import { DEFAULT_PAGE_SIZE, PAGE_SIZES } from "utils/constants";

import MaterialTable from "material-table";
import {
Add, Check, Clear, Delete, Edit, GetApp, FilterList, ArrowUpward,
FirstPage, LastPage, NavigateNext, NavigateBefore, Search, ViewColumn
} from '@material-ui/icons';


export const MaterialTableIcons = {
Add: Add,
Check: Check,
Clear: Clear,
Delete: Delete,
// DetailPanel: DetailPanel,
Edit: Edit,
Export: GetApp,
Filter: FilterList,
FirstPage: FirstPage,
LastPage: LastPage,
NextPage: NavigateNext,
PreviousPage: NavigateBefore,
ResetSearch: Clear,
Search: Search,
SortArrow: ArrowUpward,
// ThirdStateCheck: ThirdStateCheck,
ViewColumn: ViewColumn,
};

/*
query = {
error: undefined,
filters: [],
orderBy: undefined,
orderDirection: "",
page: 0,
pageSize: 5,
search: "",
totalCount: 12,
}
*/
// TODO Add sort, search, filtering functionalities
export function paginateResource(resource, transformData = null) {
async function paginateData(query) {
const page = query.page + 1;
const shouldFetch = (
!resource.fetched
|| !resource.pagination
|| query.pageSize !== resource.pagination.pageSize
|| (resource.pagination.fetchedPages || {})[page] == null
);

if (shouldFetch) {
const queryParams = { page, page_size: query.pageSize };
const resp = await resource.fetchData(queryParams, true).payload;
const { data, pagination } = processPagination(resp.data);
return {
data: transformData ? transformData(data) : data,
page: query.page,
totalCount: pagination ? pagination.count : data.length,
}
} else {
const pagination = resource.pagination;
const data = pagination
? pagination.fetchedPages[page].map(id => resource.data[id])
: resource.data;
return {
data: transformData ? transformData(data) : data,
page: query.page,
totalCount: pagination ? pagination.count : data.length,
};
}
}
return paginateData;
}

export default function APIDataTable({ path, queryParams = {}, apiOptions = {}, transformData = null, options = {}, ...props }) {
const [pageSize, setPageSize] = React.useState(options.pageSize || DEFAULT_PAGE_SIZE);
const _queryParams = { ...queryParams, page_size: pageSize };
const resource = useStoreAPIData(pathToArray(path), _queryParams, apiOptions);

return (
<MaterialTable
data={paginateResource(resource, transformData)}
icons={MaterialTableIcons}
onChangeRowsPerPage={setPageSize}
options={{
...options,
pageSizeOptions: options.pageSizeOptions || PAGE_SIZES,
pageSize,
}}
{...props}
/>
);
}

APIDataTable.propTypes = {
path: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
]).isRequired,
queryParams: PropTypes.object,
apiOptions: PropTypes.object,
transformData: PropTypes.func,
options: PropTypes.object,
};
97 changes: 50 additions & 47 deletions src/components/common/DetailsTable.jsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,66 @@
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import { TableContainer, Table, TableBody, TableCell, TableRow } from '@material-ui/core';
import { SkeletonTable } from './Skeletons';

import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import { TableContainer, Table, TableBody, TableCell, TableRow } from "@material-ui/core";
import { SkeletonTable } from "./Skeletons";

const useStyles = makeStyles({
topborder: {
borderTop: '1px solid rgba(224, 224, 224, 1)',
},
label: {
fontWeight: 500,
fontSize: '1em',
paddingRight: '1em',
},
value: {
fontWeight: 200,
},
topborder: {
borderTop: "1px solid rgba(224, 224, 224, 1)",
},
label: {
fontWeight: 500,
fontSize: "1em",
paddingRight: "1em",
},
value: {
fontWeight: 200,
},
});

function renderDetailValue(value) {
if (typeof value === "object")
return JSON.stringify(value);
if (typeof value === "object") {
return JSON.stringify(value);
}

return value;
return value;
}

export default function DetailsTable({ data, labels, renderValue }) {
const classes = useStyles();
if (!data)
return <SkeletonTable nRows={4} nCols={2} />
export default function DetailsTable({ data, fetched, labels, renderValue }) {
const classes = useStyles();
if (!fetched) {
return <SkeletonTable nRows={4} nCols={2} />;
}

const keys = Object.keys(labels || data);
return (
<TableContainer>
<Table>
<TableBody>
{keys.map((key, index) => (
<TableRow key={key} className={index === 0 ? classes.topborder : ''}>
<TableCell className={classes.label}>
{labels ? labels[key] : key}
</TableCell>
<TableCell className={classes.value}>
{renderValue(data[key])}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
const keys = Object.keys(labels || data);
return (
<TableContainer>
<Table>
<TableBody>
{keys.map((key, index) => (
<TableRow key={key} className={index === 0 ? classes.topborder : ""}>
<TableCell className={classes.label}>
{labels ? labels[key] : key}
</TableCell>
<TableCell className={classes.value}>{renderValue(data[key])}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}

DetailsTable.propTypes = {
data: PropTypes.object,
labels: PropTypes.object,
renderValue: PropTypes.func,
data: PropTypes.object,
fetched: PropTypes.bool,
labels: PropTypes.object,
renderValue: PropTypes.func,
};

DetailsTable.defaultProps = {
renderValue: renderDetailValue,
data: undefined,
fetched: undefined,
labels: undefined,
renderValue: renderDetailValue,
};
4 changes: 2 additions & 2 deletions src/components/common/Loader.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import { CircularProgress } from '@material-ui/core';
import { capitalFirst } from '../../utils';
import { CircularProgress } from '@material-ui/core';
import { capitalFirst } from 'utils/format';

const FLEX_DIRECTIONS = {
right: 'row',
Expand Down
12 changes: 6 additions & 6 deletions src/components/common/ProtectedRoute.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { Route, Redirect } from 'react-router-dom';
import { hasManagerRights } from '../../utils';
import { hasManagerRights } from 'utils/api';


const authFunctions = {
logged(auth, userAssos, props) {
return auth.authenticated;
},
admin(auth, userAssos, props) {
return auth.authenticated && auth.is_admin;
return auth.authenticated && auth.user?.is_admin;
},
manager(auth, userAssos, props) {
return hasManagerRights(auth, userAssos);
},
asso_manager(auth, userAssos, props) {
const asso_id = this.props.computedMatch.params.asso_id;
return hasManagerRights(auth, userAssos, props) && (asso_id in userAssos || auth.is_admin);
return hasManagerRights(auth, userAssos, props) && (asso_id in userAssos || auth.user?.is_admin);
},
};

export default function ProtectedRoute({ only, authOptions, redirection, component: Component, ...routeProps }) {
const auth = useSelector(store => store.getData('auth'));
const userAssos = useSelector(store => store.getAuthRelatedData('associations'));
const auth = useSelector(store => store.api.getData('auth'));
const userAssos = useSelector(store => store.api.getAuthRelatedData('associations'));

const isAuthorized = (
typeof only == 'function'
Expand All @@ -32,7 +32,7 @@ export default function ProtectedRoute({ only, authOptions, redirection, compone
);
return (
<Route
{...routeProps}
{...routeProps}
render={props => (
isAuthorized ? <Component {...props} />
: <Redirect to={redirection} />
Expand Down
Loading

0 comments on commit 59e3a8b

Please sign in to comment.