Gestion des groupes de travail #14

Manually merged
wpetit merged 7 commits from feature/workgroups into develop 2020-07-23 08:28:40 +02:00
9 changed files with 62 additions and 67 deletions
Showing only changes of commit bc9aa1721a - Show all commits

View File

@ -2,6 +2,7 @@ import React from 'react';
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom"; import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
import { HomePage } from './HomePage/HomePage'; import { HomePage } from './HomePage/HomePage';
import { ProfilePage } from './ProfilePage/ProfilePage'; import { ProfilePage } from './ProfilePage/ProfilePage';
import { WorkgroupPage } from './WorkgroupPage/WorkgroupPage';
export class App extends React.Component { export class App extends React.Component {
render() { render() {
@ -10,6 +11,7 @@ export class App extends React.Component {
<Switch> <Switch>
<Route path="/" exact component={HomePage} /> <Route path="/" exact component={HomePage} />
<Route path="/profile" exact component={ProfilePage} /> <Route path="/profile" exact component={ProfilePage} />
<Route path="/workgroups/:id" exact component={WorkgroupPage} />
<Route component={() => <Redirect to="/" />} /> <Route component={() => <Redirect to="/" />} />
</Switch> </Switch>
</BrowserRouter> </BrowserRouter>

View File

@ -2,23 +2,18 @@ import React from 'react';
import { Page } from '../Page'; import { Page } from '../Page';
import { Dashboard } from './Dashboard'; import { Dashboard } from './Dashboard';
import { useUserProfileQuery } from '../../gql/queries/profile'; import { useUserProfileQuery } from '../../gql/queries/profile';
import { Loader } from '../Loader'; import { WithLoader } from '../WithLoader';
export function HomePage() { export function HomePage() {
const { data, loading } = useUserProfileQuery(); const { data, loading } = useUserProfileQuery();
if (loading) {
return (
<Loader />
);
}
const { userProfile } = (data || {}); const { userProfile } = (data || {});
return ( return (
<Page title={userProfile ? 'Tableau de bord' : 'Accueil'}> <Page title={userProfile ? 'Tableau de bord' : 'Accueil'}>
<div className="container is-fluid"> <div className="container is-fluid">
<section className="section"> <section className="section">
<WithLoader loading={loading}>
{ {
userProfile ? userProfile ?
<Dashboard /> : <Dashboard /> :
@ -30,6 +25,7 @@ export function HomePage() {
</div> </div>
</div> </div>
} }
</WithLoader>
</section> </section>
</div> </div>
</Page> </Page>

View File

@ -4,7 +4,7 @@ import { User } from '../../types/user';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useWorkgroupsQuery } from '../../gql/queries/workgroups'; import { useWorkgroupsQuery } from '../../gql/queries/workgroups';
import { useUserProfileQuery } from '../../gql/queries/profile'; import { useUserProfileQuery } from '../../gql/queries/profile';
import { Loader } from '../Loader'; import { WithLoader } from '../WithLoader';
export function WorkgroupsPanel() { export function WorkgroupsPanel() {
const workgroupsQuery = useWorkgroupsQuery(); const workgroupsQuery = useWorkgroupsQuery();
@ -12,18 +12,14 @@ export function WorkgroupsPanel() {
const [ state, setState ] = useState({ selectedTab: 0 }); const [ state, setState ] = useState({ selectedTab: 0 });
const isLoading = userProfileQuery.loading || workgroupsQuery.loading; const isLoading = userProfileQuery.loading || workgroupsQuery.loading;
if (isLoading) { const { userProfile } = (userProfileQuery.data || {});
return <Loader />; const { workgroups } = (workgroupsQuery.data || {});
}
let { data: { userProfile }} = userProfileQuery;
let { data: { workgroups }} = workgroupsQuery;
const filterTabs = [ const filterTabs = [
{ {
label: "Mes groupes", label: "Mes groupes",
filter: workgroups => workgroups.filter((wg: Workgroup) => { filter: workgroups => workgroups.filter((wg: Workgroup) => {
return wg.members.some((u: User) => u.id === userProfile.id); return wg.members.some((u: User) => u.id === (userProfile ? userProfile.id : ''));
}) })
}, },
{ {
@ -43,7 +39,7 @@ export function WorkgroupsPanel() {
let workgroupsItems = []; let workgroupsItems = [];
workgroupsItems = filterTabs[state.selectedTab].filter(workgroups).map((wg: Workgroup) => { workgroupsItems = filterTabs[state.selectedTab].filter(workgroups || []).map((wg: Workgroup) => {
return ( return (
<Link to={`/workgroups/${wg.id}`} key={`wg-${wg.id}`} className="panel-block"> <Link to={`/workgroups/${wg.id}`} key={`wg-${wg.id}`} className="panel-block">
<span className="panel-icon"> <span className="panel-icon">
@ -63,9 +59,9 @@ export function WorkgroupsPanel() {
</p> </p>
</div> </div>
<div className="level-right"> <div className="level-right">
<button className="button level-item is-outlined is-info is-inverted"> <Link to="/workgroups/new" className="button level-item is-outlined is-info is-inverted">
<i className="icon fa fa-plus"></i> <i className="icon fa fa-plus"></i>
</button> </Link>
</div> </div>
</div> </div>
{/* <div className="panel-block"> {/* <div className="panel-block">
@ -76,26 +72,28 @@ export function WorkgroupsPanel() {
</span> </span>
</p> </p>
</div> */} </div> */}
<p className="panel-tabs"> <WithLoader loading={isLoading}>
<p className="panel-tabs">
{
filterTabs.map((tab, i) => {
return (
<a key={`workgroup-tab-${i}`}
onClick={selectTab.bind(null, i)}
className={i === state.selectedTab ? 'is-active' : ''}>
{tab.label}
</a>
)
})
}
</p>
{ {
filterTabs.map((tab, i) => { workgroupsItems.length > 0 ?
return ( workgroupsItems :
<a key={`workgroup-tab-${i}`} <a className="panel-block has-text-centered is-block">
onClick={selectTab.bind(null, i)} <em>Aucun groupe dans cet catégorie pour l'instant.</em>
className={i === state.selectedTab ? 'is-active' : ''}> </a>
{tab.label}
</a>
)
})
} }
</p> </WithLoader>
{
workgroupsItems.length > 0 ?
workgroupsItems :
<a className="panel-block has-text-centered is-block">
<em>Aucun groupe dans cet catégorie pour l'instant.</em>
</a>
}
</nav> </nav>
) )
} }

View File

@ -1,14 +0,0 @@
import React from 'react';
export class Loader extends React.Component {
render() {
return (
<div className="loader-container">
<div className="lds-ripple">
<div></div>
<div></div>
</div>
</div>
)
}
}

View File

@ -1,7 +1,6 @@
import React, { useEffect } from 'react'; import React from 'react';
import { Page } from '../Page'; import { Page } from '../Page';
import { UserForm } from '../UserForm'; import { UserForm } from '../UserForm';
import { Loader } from '../Loader';
import { User } from '../../types/user'; import { User } from '../../types/user';
import { useUserProfileQuery } from '../../gql/queries/profile'; import { useUserProfileQuery } from '../../gql/queries/profile';
import { useUpdateUserProfileMutation } from '../../gql/mutations/profile'; import { useUpdateUserProfileMutation } from '../../gql/mutations/profile';
@ -27,11 +26,9 @@ export function ProfilePage() {
<div className="columns"> <div className="columns">
<div className="column is-6 is-offset-3"> <div className="column is-6 is-offset-3">
<h2 className="is-size-2 subtitle">Mon profil</h2> <h2 className="is-size-2 subtitle">Mon profil</h2>
<WithLoader loading={isLoading}> <WithLoader loading={isLoading || !userProfile}>
{ {
userProfile ? <UserForm onChange={onUserChange} user={userProfile} />
<UserForm onChange={onUserChange} user={userProfile} /> :
<Loader />
} }
</WithLoader> </WithLoader>
</div> </div>

View File

@ -9,12 +9,7 @@ export const WithLoader: FunctionComponent<WithLoaderProps> = ({ loading, childr
<Fragment> <Fragment>
{ {
loading ? loading ?
<div className="loader-container"> <div>Chargement</div> :
<div className="lds-ripple">
<div></div>
<div></div>
</div>
</div> :
children children
} }
</Fragment> </Fragment>

View File

@ -0,0 +1,22 @@
import React, { useEffect } from 'react';
import { Page } from '../Page';
import { WithLoader } from '../WithLoader';
export function WorkgroupPage() {
return (
<Page title="Groupe de travail">
<div className="container is-fluid">
<section className="section">
<div className="columns">
<div className="column is-6 is-offset-3">
<h2 className="is-size-2 subtitle">Groupe de travail</h2>
<WithLoader loading={false}>
</WithLoader>
</div>
</div>
</section>
</div>
</Page>
);
}

View File

@ -4,12 +4,11 @@ import { WebSocketLink } from "@apollo/client/link/ws";
import { RetryLink } from "@apollo/client/link/retry"; import { RetryLink } from "@apollo/client/link/retry";
import { SubscriptionClient } from "subscriptions-transport-ws"; import { SubscriptionClient } from "subscriptions-transport-ws";
const subscriptionClient = new SubscriptionClient(Config.subscriptionEndpoint, { const subscriptionClient = new SubscriptionClient(Config.subscriptionEndpoint, {
reconnect: true reconnect: true,
}); });
const link = new RetryLink().split( const link = new RetryLink({attempts: {max: 2}}).split(
(operation) => operation.operationName === 'subscription', (operation) => operation.operationName === 'subscription',
new WebSocketLink(subscriptionClient), new WebSocketLink(subscriptionClient),
new HttpLink({ uri: Config.graphQLEndpoint, credentials: 'include' }) new HttpLink({ uri: Config.graphQLEndpoint, credentials: 'include' })

View File

@ -12,5 +12,5 @@ query userProfile {
}`; }`;
export function useUserProfileQuery() { export function useUserProfileQuery() {
return useQuery(QUERY_USER_PROFILE, { fetchPolicy: "network-only" }); return useQuery(QUERY_USER_PROFILE);
} }