Création/mise à jour basique d'un DAD #15
|
@ -3,6 +3,7 @@ import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
|
|||
import { HomePage } from './HomePage/HomePage';
|
||||
import { ProfilePage } from './ProfilePage/ProfilePage';
|
||||
import { WorkgroupPage } from './WorkgroupPage/WorkgroupPage';
|
||||
import { DecisionSupportFilePage } from './DecisionSupportFilePage/DecisionSupportFilePage';
|
||||
|
||||
export class App extends React.Component {
|
||||
render() {
|
||||
|
@ -12,6 +13,7 @@ export class App extends React.Component {
|
|||
<Route path="/" exact component={HomePage} />
|
||||
<Route path="/profile" exact component={ProfilePage} />
|
||||
<Route path="/workgroups/:id" exact component={WorkgroupPage} />
|
||||
<Route path="/decisions/:id" exact component={DecisionSupportFilePage} />
|
||||
<Route component={() => <Redirect to="/" />} />
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { DecisionSupportFile } from '../../types/decision';
|
||||
|
||||
export interface AppendixPanelProps {
|
||||
dsf: DecisionSupportFile,
|
||||
};
|
||||
|
||||
export const AppendixPanel: FunctionComponent<AppendixPanelProps> = ({ dsf }) => {
|
||||
return (
|
||||
<nav className="panel">
|
||||
<p className="panel-heading">
|
||||
Annexes
|
||||
</p>
|
||||
<div className="panel-block">
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { DecisionSupportFile } from '../../types/decision';
|
||||
|
||||
export interface ClarificationSectionProps {
|
||||
dsf: DecisionSupportFile,
|
||||
};
|
||||
|
||||
export const ClarificationSection: FunctionComponent<ClarificationSectionProps> = ({ dsf }) => {
|
||||
return (
|
||||
<section>
|
||||
<div className="box">
|
||||
<div className="field">
|
||||
<label className="label">Intitulé du dossier</label>
|
||||
<div className="control">
|
||||
<input className="input" type="text" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="label">Quelle décision devons nous prendre ?</label>
|
||||
<div className="control">
|
||||
<textarea className="textarea" placeholder="Décrire globalement les tenants et aboutissants de la décision à prendre." rows={10}></textarea>
|
||||
</div>
|
||||
<p className="help is-info"><i className="fa fa-info-circle"></i> Ne pas essayer de rentrer trop dans les détails ici. Préférer l'utilisation des annexes et y faire référence.</p>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="label">Pourquoi devons nous prendre cette décision ?</label>
|
||||
<div className="control">
|
||||
<textarea className="textarea" placeholder="Décrire pourquoi il est important de prendre cette décision." rows={10}></textarea>
|
||||
</div>
|
||||
<p className="help is-info"><i className="fa fa-info-circle"></i> Penser à indiquer si des obligations légales pèsent sur cette prise de décision.</p>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="label">Portée de la décision</label>
|
||||
<div className="control">
|
||||
<div className="select">
|
||||
<select>
|
||||
<option></option>
|
||||
<option>Individuelle</option>
|
||||
<option>Groupe identifié</option>
|
||||
<option>Collective</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="label">Nature de la décision</label>
|
||||
<div className="control">
|
||||
<div className="select">
|
||||
<select>
|
||||
<option></option>
|
||||
<option>Opérationnelle</option>
|
||||
<option>Tactique</option>
|
||||
<option>Stratégique</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="label">Existe t'il une échéance particulière pour cette décision ?</label>
|
||||
<div className="control">
|
||||
<input className="input" type="date" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { Page } from '../Page';
|
||||
import { ClarificationSection } from './ClarificationSection';
|
||||
import { OptionsSection } from './OptionsSection';
|
||||
import { MetadataPanel } from './MetadataPanel';
|
||||
import { AppendixPanel } from './AppendixPanel';
|
||||
|
||||
export interface DecisionSupportFilePageProps {
|
||||
|
||||
};
|
||||
|
||||
export const DecisionSupportFilePage: FunctionComponent<DecisionSupportFilePageProps> = () => {
|
||||
const [ state, setState ] = useState({ dsf: null });
|
||||
const isNew = true;
|
||||
const isClosed = false;
|
||||
return (
|
||||
<Page title="Dossier d'Aide à la Décision">
|
||||
<div className="container is-fluid">
|
||||
<section className="mt-5">
|
||||
<div className="level">
|
||||
<div className="level-left">
|
||||
{
|
||||
isNew ?
|
||||
<div className="level-item">
|
||||
<div>
|
||||
<h2 className="is-size-3 title is-spaced">Nouveau</h2>
|
||||
<h3 className="is-size-5 subtitle">Dossier d'Aide à la Décision</h3>
|
||||
</div>
|
||||
</div> :
|
||||
<div className="level-item">
|
||||
<div>
|
||||
<h2 className="is-size-3 title is-spaced">{state.dsf.title}</h2>
|
||||
<h3 className="is-size-5 subtitle">Dossier d'Aide à la Décision <span className="is-italic">{ isClosed ? '(clos)' : null }</span></h3>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="columns mt-3">
|
||||
<div className="column is-9">
|
||||
<div className="tabs is-medium is-toggle has-background-white">
|
||||
<ul>
|
||||
<li className="is-active">
|
||||
<a>
|
||||
<span className="icon is-small"><i className="fas fa-pen" aria-hidden="true"></i></span>
|
||||
<span>Clarifier la décision</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>
|
||||
<span className="icon is-small"><i className="fas fa-search" aria-hidden="true"></i></span>
|
||||
<span>Explorer les options</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>
|
||||
<span className="icon is-small"><i className="fas fa-person-booth" aria-hidden="true"></i></span>
|
||||
<span>Prendre la décision</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ClarificationSection dsf={state.dsf} />
|
||||
</div>
|
||||
<div className="column is-3">
|
||||
<MetadataPanel dsf={state.dsf} />
|
||||
<AppendixPanel dsf={state.dsf} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { DecisionSupportFile } from '../../types/decision';
|
||||
|
||||
export interface MetadataPanelProps {
|
||||
dsf: DecisionSupportFile,
|
||||
};
|
||||
|
||||
export const MetadataPanel: FunctionComponent<MetadataPanelProps> = ({ dsf }) => {
|
||||
return (
|
||||
<nav className="panel">
|
||||
<p className="panel-heading">
|
||||
Métadonnées
|
||||
</p>
|
||||
<div className="panel-block">
|
||||
<div style={{width:'100%'}}>
|
||||
<div className="field">
|
||||
<div className="label">Groupe de travail</div>
|
||||
<div className="control is-expanded">
|
||||
<div className="select is-fullwidth">
|
||||
<select>
|
||||
<option></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="label">Statut</div>
|
||||
<div className="control is-expanded">
|
||||
<div className="select is-fullwidth">
|
||||
<select>
|
||||
<option>En préparation</option>
|
||||
<option>Prêt à voter</option>
|
||||
<option>Voté</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="label">Créé le</div>
|
||||
<div className="control">
|
||||
<p>--</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="field">
|
||||
<div className="label">Dernière modification</div>
|
||||
<div className="control">
|
||||
<p>--</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { DecisionSupportFile } from '../../types/decision';
|
||||
|
||||
export interface OptionsSectionProps {
|
||||
dsf: DecisionSupportFile,
|
||||
};
|
||||
|
||||
export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf }) => {
|
||||
return (
|
||||
<section>
|
||||
<h4 id="options-section" className="is-size-4 title is-spaced"><a href="#options-section">Explorer les options</a></h4>
|
||||
<div className="box">
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
|
@ -31,7 +31,7 @@ export function DecisionSupportFilePanel() {
|
|||
return (
|
||||
<ItemPanel
|
||||
className='is-link'
|
||||
title="Dossiers d'Aide à la Décision"
|
||||
title="D.A.D."
|
||||
newItemUrl="/decisions/new"
|
||||
items={decisions}
|
||||
tabs={tabs}
|
||||
|
|
|
@ -78,7 +78,7 @@ export const ItemPanel: FunctionComponent<ItemPanelProps> = (props) => {
|
|||
|
||||
return (
|
||||
<nav className={`panel ${className}`}>
|
||||
<div className="level panel-heading mb-0">
|
||||
<div className="level is-mobile panel-heading mb-0">
|
||||
<div className="level-left">
|
||||
<p className="level-item">{title}</p>
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,7 @@ export function Navbar() {
|
|||
};
|
||||
|
||||
return (
|
||||
<nav className="navbar" role="navigation" aria-label="main navigation">
|
||||
<nav className="navbar is-fixed-top" role="navigation" aria-label="main navigation">
|
||||
<div className="container is-fluid">
|
||||
<div className="navbar-brand">
|
||||
<Link className="navbar-item" to="/">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { gql, useQuery, useMutation } from '@apollo/client';
|
||||
|
||||
const MUTATION_UPDATE_USER_PROFILE = gql`
|
||||
export const MUTATION_UPDATE_USER_PROFILE = gql`
|
||||
mutation updateUserProfile($changes: ProfileChanges!) {
|
||||
updateProfile(changes: $changes) {
|
||||
id,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { gql, useQuery, useMutation } from '@apollo/client';
|
||||
import { QUERY_WORKGROUP } from '../queries/workgroups';
|
||||
|
||||
const MUTATION_UPDATE_WORKGROUP = gql`
|
||||
export const MUTATION_UPDATE_WORKGROUP = gql`
|
||||
mutation updateWorkgroup($workgroupId: ID!, $changes: WorkgroupChanges!) {
|
||||
updateWorkgroup(workgroupId: $workgroupId, changes: $changes) {
|
||||
id,
|
||||
|
@ -19,7 +20,7 @@ export function useUpdateWorkgroupMutation() {
|
|||
return useMutation(MUTATION_UPDATE_WORKGROUP);
|
||||
}
|
||||
|
||||
const MUTATION_CREATE_WORKGROUP = gql`
|
||||
export const MUTATION_CREATE_WORKGROUP = gql`
|
||||
mutation createWorkgroup($changes: WorkgroupChanges!) {
|
||||
createWorkgroup(changes: $changes) {
|
||||
id,
|
||||
|
@ -35,10 +36,12 @@ mutation createWorkgroup($changes: WorkgroupChanges!) {
|
|||
}`;
|
||||
|
||||
export function useCreateWorkgroupMutation() {
|
||||
return useMutation(MUTATION_CREATE_WORKGROUP);
|
||||
return useMutation(MUTATION_CREATE_WORKGROUP, {
|
||||
refetchQueries: [{query: QUERY_WORKGROUP}],
|
||||
});
|
||||
}
|
||||
|
||||
const MUTATION_JOIN_WORKGROUP = gql`
|
||||
export const MUTATION_JOIN_WORKGROUP = gql`
|
||||
mutation joinWorkgroup($workgroupId: ID!) {
|
||||
joinWorkgroup(workgroupId: $workgroupId) {
|
||||
id,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { DecisionSupportFile } from '../../types/decision';
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useGraphQLData } from './helper';
|
||||
|
||||
const QUERY_DECISIONS = gql`
|
||||
export const QUERY_DECISIONS = gql`
|
||||
query decisions($filter: DecisionFilter) {
|
||||
decisions(filter: $filter) {
|
||||
id,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { User } from '../../types/user';
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useGraphQLData } from './helper';
|
||||
|
||||
const QUERY_USER_PROFILE = gql`
|
||||
export const QUERY_USER_PROFILE = gql`
|
||||
query userProfile {
|
||||
userProfile {
|
||||
id,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { gql, useQuery } from '@apollo/client';
|
|||
import { Workgroup } from '../../types/workgroup';
|
||||
import { useGraphQLData } from './helper';
|
||||
|
||||
const QUERY_WORKGROUP = gql`
|
||||
export const QUERY_WORKGROUP = gql`
|
||||
query workgroups($filter: WorkgroupsFilter) {
|
||||
workgroups(filter: $filter) {
|
||||
id,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="has-navbar-fixed-top">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
html, body {
|
||||
height: 100%;
|
||||
background-color: #f7f7f7;
|
||||
background-color: #ffffff;
|
||||
// Generated with https://www.svgbackgrounds.com/
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='351' height='292.5' viewBox='0 0 1080 900'%3E%3Cg fill-opacity='0.04'%3E%3Cpolygon fill='%23444' points='90 150 0 300 180 300'/%3E%3Cpolygon points='90 150 180 0 0 0'/%3E%3Cpolygon fill='%23AAA' points='270 150 360 0 180 0'/%3E%3Cpolygon fill='%23DDD' points='450 150 360 300 540 300'/%3E%3Cpolygon fill='%23999' points='450 150 540 0 360 0'/%3E%3Cpolygon points='630 150 540 300 720 300'/%3E%3Cpolygon fill='%23DDD' points='630 150 720 0 540 0'/%3E%3Cpolygon fill='%23444' points='810 150 720 300 900 300'/%3E%3Cpolygon fill='%23FFF' points='810 150 900 0 720 0'/%3E%3Cpolygon fill='%23DDD' points='990 150 900 300 1080 300'/%3E%3Cpolygon fill='%23444' points='990 150 1080 0 900 0'/%3E%3Cpolygon fill='%23DDD' points='90 450 0 600 180 600'/%3E%3Cpolygon points='90 450 180 300 0 300'/%3E%3Cpolygon fill='%23666' points='270 450 180 600 360 600'/%3E%3Cpolygon fill='%23AAA' points='270 450 360 300 180 300'/%3E%3Cpolygon fill='%23DDD' points='450 450 360 600 540 600'/%3E%3Cpolygon fill='%23999' points='450 450 540 300 360 300'/%3E%3Cpolygon fill='%23999' points='630 450 540 600 720 600'/%3E%3Cpolygon fill='%23FFF' points='630 450 720 300 540 300'/%3E%3Cpolygon points='810 450 720 600 900 600'/%3E%3Cpolygon fill='%23DDD' points='810 450 900 300 720 300'/%3E%3Cpolygon fill='%23AAA' points='990 450 900 600 1080 600'/%3E%3Cpolygon fill='%23444' points='990 450 1080 300 900 300'/%3E%3Cpolygon fill='%23222' points='90 750 0 900 180 900'/%3E%3Cpolygon points='270 750 180 900 360 900'/%3E%3Cpolygon fill='%23DDD' points='270 750 360 600 180 600'/%3E%3Cpolygon points='450 750 540 600 360 600'/%3E%3Cpolygon points='630 750 540 900 720 900'/%3E%3Cpolygon fill='%23444' points='630 750 720 600 540 600'/%3E%3Cpolygon fill='%23AAA' points='810 750 720 900 900 900'/%3E%3Cpolygon fill='%23666' points='810 750 900 600 720 600'/%3E%3Cpolygon fill='%23999' points='990 750 900 900 1080 900'/%3E%3Cpolygon fill='%23999' points='180 0 90 150 270 150'/%3E%3Cpolygon fill='%23444' points='360 0 270 150 450 150'/%3E%3Cpolygon fill='%23FFF' points='540 0 450 150 630 150'/%3E%3Cpolygon points='900 0 810 150 990 150'/%3E%3Cpolygon fill='%23222' points='0 300 -90 450 90 450'/%3E%3Cpolygon fill='%23FFF' points='0 300 90 150 -90 150'/%3E%3Cpolygon fill='%23FFF' points='180 300 90 450 270 450'/%3E%3Cpolygon fill='%23666' points='180 300 270 150 90 150'/%3E%3Cpolygon fill='%23222' points='360 300 270 450 450 450'/%3E%3Cpolygon fill='%23FFF' points='360 300 450 150 270 150'/%3E%3Cpolygon fill='%23444' points='540 300 450 450 630 450'/%3E%3Cpolygon fill='%23222' points='540 300 630 150 450 150'/%3E%3Cpolygon fill='%23AAA' points='720 300 630 450 810 450'/%3E%3Cpolygon fill='%23666' points='720 300 810 150 630 150'/%3E%3Cpolygon fill='%23FFF' points='900 300 810 450 990 450'/%3E%3Cpolygon fill='%23999' points='900 300 990 150 810 150'/%3E%3Cpolygon points='0 600 -90 750 90 750'/%3E%3Cpolygon fill='%23666' points='0 600 90 450 -90 450'/%3E%3Cpolygon fill='%23AAA' points='180 600 90 750 270 750'/%3E%3Cpolygon fill='%23444' points='180 600 270 450 90 450'/%3E%3Cpolygon fill='%23444' points='360 600 270 750 450 750'/%3E%3Cpolygon fill='%23999' points='360 600 450 450 270 450'/%3E%3Cpolygon fill='%23666' points='540 600 630 450 450 450'/%3E%3Cpolygon fill='%23222' points='720 600 630 750 810 750'/%3E%3Cpolygon fill='%23FFF' points='900 600 810 750 990 750'/%3E%3Cpolygon fill='%23222' points='900 600 990 450 810 450'/%3E%3Cpolygon fill='%23DDD' points='0 900 90 750 -90 750'/%3E%3Cpolygon fill='%23444' points='180 900 270 750 90 750'/%3E%3Cpolygon fill='%23FFF' points='360 900 450 750 270 750'/%3E%3Cpolygon fill='%23AAA' points='540 900 630 750 450 750'/%3E%3Cpolygon fill='%23FFF' points='720 900 810 750 630 750'/%3E%3Cpolygon fill='%23222' points='900 900 990 750 810 750'/%3E%3Cpolygon fill='%23222' points='1080 300 990 450 1170 450'/%3E%3Cpolygon fill='%23FFF' points='1080 300 1170 150 990 150'/%3E%3Cpolygon points='1080 600 990 750 1170 750'/%3E%3Cpolygon fill='%23666' points='1080 600 1170 450 990 450'/%3E%3Cpolygon fill='%23DDD' points='1080 900 1170 750 990 750'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.is-fullheight {
|
||||
|
@ -18,4 +20,8 @@ html, body {
|
|||
#app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background-color: #ffffff;
|
||||
}
|
Loading…
Reference in New Issue