Passage en lecture seule du DAD lorsqu'il appartient à un groupe différent #21
|
@ -7,7 +7,7 @@ export interface ClarificationSectionProps extends DecisionSupportFileUpdaterPro
|
||||||
|
|
||||||
const ClarificationSectionName = 'clarification';
|
const ClarificationSectionName = 'clarification';
|
||||||
|
|
||||||
export const ClarificationSection: FunctionComponent<ClarificationSectionProps> = ({ dsf, updateDSF }) => {
|
export const ClarificationSection: FunctionComponent<ClarificationSectionProps> = ({ dsf, updateDSF, readOnly }) => {
|
||||||
const [ state, setState ] = useState({
|
const [ state, setState ] = useState({
|
||||||
changed: false,
|
changed: false,
|
||||||
section: {
|
section: {
|
||||||
|
@ -51,15 +51,16 @@ export const ClarificationSection: FunctionComponent<ClarificationSectionProps>
|
||||||
<section>
|
<section>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label">Intitulé du dossier</label>
|
<label className="label is-medium">Intitulé du dossier</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<input className="input" type="text" value={dsf.title} onChange={onTitleChange} />
|
<input className="input is-medium" type="text" readOnly={readOnly} value={dsf.title} onChange={onTitleChange} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label">Quelle décision devons nous prendre ?</label>
|
<label className="label is-medium">Quelle décision devons nous prendre ?</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<textarea className="textarea"
|
<textarea className="textarea is-medium"
|
||||||
|
readOnly={readOnly}
|
||||||
value={state.section.objectives}
|
value={state.section.objectives}
|
||||||
onChange={onSectionAttrChange.bind(null, 'objectives')}
|
onChange={onSectionAttrChange.bind(null, 'objectives')}
|
||||||
placeholder="Décrire globalement les tenants et aboutissants de la décision à prendre."
|
placeholder="Décrire globalement les tenants et aboutissants de la décision à prendre."
|
||||||
|
@ -69,9 +70,10 @@ export const ClarificationSection: FunctionComponent<ClarificationSectionProps>
|
||||||
<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>
|
<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>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label">Pourquoi devons nous prendre cette décision ?</label>
|
<label className="label is-medium">Pourquoi devons nous prendre cette décision ?</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<textarea className="textarea"
|
<textarea className="textarea is-medium"
|
||||||
|
readOnly={readOnly}
|
||||||
value={state.section.motivations}
|
value={state.section.motivations}
|
||||||
onChange={onSectionAttrChange.bind(null, 'motivations')}
|
onChange={onSectionAttrChange.bind(null, 'motivations')}
|
||||||
placeholder="Décrire pourquoi il est important de prendre cette décision."
|
placeholder="Décrire pourquoi il est important de prendre cette décision."
|
||||||
|
@ -81,10 +83,11 @@ export const ClarificationSection: FunctionComponent<ClarificationSectionProps>
|
||||||
<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>
|
<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>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label">Portée de la décision</label>
|
<label className="label is-medium">Portée de la décision</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<div className="select">
|
<div className="select is-medium">
|
||||||
<select
|
<select
|
||||||
|
disabled={readOnly}
|
||||||
onChange={onSectionAttrChange.bind(null, 'scope')}
|
onChange={onSectionAttrChange.bind(null, 'scope')}
|
||||||
value={state.section.scope}>
|
value={state.section.scope}>
|
||||||
<option></option>
|
<option></option>
|
||||||
|
@ -96,10 +99,12 @@ export const ClarificationSection: FunctionComponent<ClarificationSectionProps>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<label className="label">Nature de la décision</label>
|
<label className="label is-medium">Nature de la décision</label>
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<div className="select">
|
<div className="select is-medium">
|
||||||
<select onChange={onSectionAttrChange.bind(null, 'nature')}
|
<select
|
||||||
|
disabled={readOnly}
|
||||||
|
onChange={onSectionAttrChange.bind(null, 'nature')}
|
||||||
value={state.section.nature}>
|
value={state.section.nature}>
|
||||||
<option></option>
|
<option></option>
|
||||||
<option value="operational">Opérationnelle</option>
|
<option value="operational">Opérationnelle</option>
|
||||||
|
@ -114,16 +119,19 @@ export const ClarificationSection: FunctionComponent<ClarificationSectionProps>
|
||||||
<div className="column">
|
<div className="column">
|
||||||
<label className="checkbox">
|
<label className="checkbox">
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
className="is-medium"
|
||||||
|
disabled={readOnly}
|
||||||
onChange={onSectionAttrChange.bind(null, 'hasDeadline')}
|
onChange={onSectionAttrChange.bind(null, 'hasDeadline')}
|
||||||
checked={state.section.hasDeadline} />
|
checked={state.section.hasDeadline} />
|
||||||
<span className="ml-1">Existe t'il une échéance particulière pour cette décision ?</span>
|
<span className="ml-1 has-text-weight-bold is-size-5">Existe t'il une échéance particulière pour cette décision ?</span>
|
||||||
</label>
|
</label>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<div className="control">
|
<div className="control">
|
||||||
<input disabled={!state.section.hasDeadline}
|
<input disabled={!state.section.hasDeadline}
|
||||||
|
readOnly={readOnly}
|
||||||
value={state.section.deadline ? asDate(state.section.deadline).toISOString().substr(0, 10) : ''}
|
value={state.section.deadline ? asDate(state.section.deadline).toISOString().substr(0, 10) : ''}
|
||||||
onChange={onDeadlineChange}
|
onChange={onDeadlineChange}
|
||||||
type="date" className="input" />
|
type="date" className="input is-medium" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { DecisionSupportFile, newDecisionSupportFile, DecisionSupportFileStatus
|
||||||
import { useParams, useHistory } from 'react-router';
|
import { useParams, useHistory } from 'react-router';
|
||||||
import { useDecisionSupportFiles } from '../../gql/queries/dsf';
|
import { useDecisionSupportFiles } from '../../gql/queries/dsf';
|
||||||
import { useCreateDecisionSupportFileMutation, useUpdateDecisionSupportFileMutation } from '../../gql/mutations/dsf';
|
import { useCreateDecisionSupportFileMutation, useUpdateDecisionSupportFileMutation } from '../../gql/mutations/dsf';
|
||||||
import { useDebounce } from '../../hooks/useDebounce';
|
|
||||||
import { OptionsSection } from './OptionsSection';
|
import { OptionsSection } from './OptionsSection';
|
||||||
|
import { useIsAuthorized } from '../../gql/queries/authorization';
|
||||||
|
|
||||||
export interface DecisionSupportFilePageProps {
|
export interface DecisionSupportFilePageProps {
|
||||||
|
|
||||||
|
@ -31,6 +31,16 @@ export const DecisionSupportFilePage: FunctionComponent<DecisionSupportFilePageP
|
||||||
selectedTabIndex: 0,
|
selectedTabIndex: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const { isAuthorized } = useIsAuthorized({
|
||||||
|
variables: {
|
||||||
|
action: 'update',
|
||||||
|
object: {
|
||||||
|
decisionSupportFileId: state.dsf.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, id === 'new');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const dsf = decisionSupportFiles.length > 0 && decisionSupportFiles[0].id === id ? decisionSupportFiles[0] : {};
|
const dsf = decisionSupportFiles.length > 0 && decisionSupportFiles[0].id === id ? decisionSupportFiles[0] : {};
|
||||||
setState(state => ({ ...state, dsf: { ...state.dsf, ...dsf }}))
|
setState(state => ({ ...state, dsf: { ...state.dsf, ...dsf }}))
|
||||||
|
@ -96,7 +106,7 @@ export const DecisionSupportFilePage: FunctionComponent<DecisionSupportFilePageP
|
||||||
</div> :
|
</div> :
|
||||||
<div className="level-item">
|
<div className="level-item">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="is-size-3 title is-spaced">{state.dsf.title}</h2>
|
<h2 className="is-size-3 title is-spaced">{state.dsf.title} <span className={`ml-3 tag is-warning is-medium ${ isAuthorized ? 'is-hidden' : ''}`}>Lecture seule</span></h2>
|
||||||
<h3 className="is-size-5 subtitle">Dossier d'Aide à la Décision <span className="is-italic">{ isClosed ? '(clos)' : null }</span></h3>
|
<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>
|
||||||
|
@ -141,17 +151,17 @@ export const DecisionSupportFilePage: FunctionComponent<DecisionSupportFilePageP
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
state.selectedTabIndex === 0 ?
|
state.selectedTabIndex === 0 ?
|
||||||
<ClarificationSection dsf={state.dsf} updateDSF={updateDSF} /> :
|
<ClarificationSection readOnly={!isAuthorized} dsf={state.dsf} updateDSF={updateDSF} /> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
state.selectedTabIndex === 1 ?
|
state.selectedTabIndex === 1 ?
|
||||||
<OptionsSection dsf={state.dsf} updateDSF={updateDSF} /> :
|
<OptionsSection readOnly={!isAuthorized} dsf={state.dsf} updateDSF={updateDSF} /> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="column is-3">
|
<div className="column is-3">
|
||||||
<MetadataPanel dsf={state.dsf} updateDSF={updateDSF} />
|
<MetadataPanel readOnly={!isAuthorized} dsf={state.dsf} updateDSF={updateDSF} />
|
||||||
<AppendixPanel dsf={state.dsf} />
|
<AppendixPanel dsf={state.dsf} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,4 +3,5 @@ import { DecisionSupportFile } from "../../types/decision";
|
||||||
export interface DecisionSupportFileUpdaterProps {
|
export interface DecisionSupportFileUpdaterProps {
|
||||||
dsf: DecisionSupportFile
|
dsf: DecisionSupportFile
|
||||||
updateDSF: (dsf: DecisionSupportFile) => void
|
updateDSF: (dsf: DecisionSupportFile) => void
|
||||||
|
readOnly: boolean
|
||||||
}
|
}
|
|
@ -5,10 +5,11 @@ import { useUserProfile } from '../../gql/queries/profile';
|
||||||
import { inWorkgroup } from '../../types/workgroup';
|
import { inWorkgroup } from '../../types/workgroup';
|
||||||
import { DecisionSupportFileUpdaterProps } from './DecisionSupportFileUpdaterProps';
|
import { DecisionSupportFileUpdaterProps } from './DecisionSupportFileUpdaterProps';
|
||||||
import { asDate } from '../../util/date';
|
import { asDate } from '../../util/date';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export interface MetadataPanelProps extends DecisionSupportFileUpdaterProps {};
|
export interface MetadataPanelProps extends DecisionSupportFileUpdaterProps {};
|
||||||
|
|
||||||
export const MetadataPanel: FunctionComponent<MetadataPanelProps> = ({ dsf, updateDSF }) => {
|
export const MetadataPanel: FunctionComponent<MetadataPanelProps> = ({ dsf, updateDSF, readOnly }) => {
|
||||||
const { user } = useUserProfile();
|
const { user } = useUserProfile();
|
||||||
const { workgroups } = useWorkgroups();
|
const { workgroups } = useWorkgroups();
|
||||||
|
|
||||||
|
@ -39,26 +40,36 @@ export const MetadataPanel: FunctionComponent<MetadataPanelProps> = ({ dsf, upda
|
||||||
<div style={{width:'100%'}}>
|
<div style={{width:'100%'}}>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<div className="label">Groupe de travail</div>
|
<div className="label">Groupe de travail</div>
|
||||||
<div className="control is-expanded">
|
{
|
||||||
<div className="select is-fullwidth">
|
readOnly && dsf.workgroup !== null ?
|
||||||
<select onChange={onWorkgroupChanged} value={dsf.workgroup ? dsf.workgroup.id : ''}>
|
<Link to={`/workgroups/${dsf.workgroup.id}`}>{dsf.workgroup.name}</Link> :
|
||||||
<option></option>
|
<div className="control is-expanded">
|
||||||
{
|
<div className="select is-fullwidth">
|
||||||
userOpenedWorkgroups.map(wg => {
|
<select
|
||||||
return (
|
disabled={readOnly}
|
||||||
<option key={`wg-${wg.id}`} value={wg.id}>{wg.name}</option>
|
onChange={onWorkgroupChanged}
|
||||||
);
|
value={dsf.workgroup ? dsf.workgroup.id : ''}>
|
||||||
})
|
<option></option>
|
||||||
}
|
{
|
||||||
</select>
|
userOpenedWorkgroups.map(wg => {
|
||||||
|
return (
|
||||||
|
<option key={`wg-${wg.id}`} value={wg.id}>{wg.name}</option>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className="field">
|
<div className="field">
|
||||||
<div className="label">Statut</div>
|
<div className="label">Statut</div>
|
||||||
<div className="control is-expanded">
|
<div className="control is-expanded">
|
||||||
<div className="select is-fullwidth">
|
<div className="select is-fullwidth">
|
||||||
<select onChange={onStatusChanged} value={dsf.status}>
|
<select
|
||||||
|
disabled={readOnly}
|
||||||
|
onChange={onStatusChanged}
|
||||||
|
value={dsf.status}>
|
||||||
<option value="draft">Brouillon</option>
|
<option value="draft">Brouillon</option>
|
||||||
<option value="ready">Prêt à voter</option>
|
<option value="ready">Prêt à voter</option>
|
||||||
<option value="voted">Voté</option>
|
<option value="voted">Voté</option>
|
||||||
|
|
|
@ -6,7 +6,7 @@ export interface OptionsSectionProps extends DecisionSupportFileUpdaterProps {};
|
||||||
|
|
||||||
const OptionsSectionName = 'options';
|
const OptionsSectionName = 'options';
|
||||||
|
|
||||||
export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, updateDSF }) => {
|
export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, updateDSF, readOnly }) => {
|
||||||
interface OptionsSectionState {
|
interface OptionsSectionState {
|
||||||
changed: boolean
|
changed: boolean
|
||||||
section: OptionsSection
|
section: OptionsSection
|
||||||
|
@ -94,6 +94,7 @@ export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, up
|
||||||
<tr key={`option-${o.id}`}>
|
<tr key={`option-${o.id}`}>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
|
disabled={readOnly}
|
||||||
onClick={onRemoveOptionClick.bind(null, index)}
|
onClick={onRemoveOptionClick.bind(null, index)}
|
||||||
className="button is-danger is-small is-outlined">
|
className="button is-danger is-small is-outlined">
|
||||||
🗑️
|
🗑️
|
||||||
|
@ -101,6 +102,7 @@ export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, up
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<textarea className="textarea"
|
<textarea className="textarea"
|
||||||
|
readOnly={readOnly}
|
||||||
value={o.label}
|
value={o.label}
|
||||||
onChange={onOptionChange.bind(null, index, 'label')}
|
onChange={onOptionChange.bind(null, index, 'label')}
|
||||||
placeholder="Décrire cette décision."
|
placeholder="Décrire cette décision."
|
||||||
|
@ -110,6 +112,7 @@ export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, up
|
||||||
<td>
|
<td>
|
||||||
<textarea className="textarea is-success"
|
<textarea className="textarea is-success"
|
||||||
value={o.pros}
|
value={o.pros}
|
||||||
|
readOnly={readOnly}
|
||||||
onChange={onOptionChange.bind(null, index, 'pros')}
|
onChange={onOptionChange.bind(null, index, 'pros')}
|
||||||
placeholder="Décrire les avantages de cette décision."
|
placeholder="Décrire les avantages de cette décision."
|
||||||
rows={10}>
|
rows={10}>
|
||||||
|
@ -118,6 +121,7 @@ export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, up
|
||||||
<td>
|
<td>
|
||||||
<textarea className="textarea is-danger"
|
<textarea className="textarea is-danger"
|
||||||
value={o.cons}
|
value={o.cons}
|
||||||
|
readOnly={readOnly}
|
||||||
onChange={onOptionChange.bind(null, index, 'cons')}
|
onChange={onOptionChange.bind(null, index, 'cons')}
|
||||||
placeholder="Décrire les désavantages de cette décision."
|
placeholder="Décrire les désavantages de cette décision."
|
||||||
rows={10}>
|
rows={10}>
|
||||||
|
@ -139,9 +143,12 @@ export const OptionsSection: FunctionComponent<OptionsSectionProps> = ({ dsf, up
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan={5}>
|
<td colSpan={5}>
|
||||||
<a className="button is-primary is-pulled-right" onClick={onAddOptionClick}>
|
<button
|
||||||
|
disabled={readOnly}
|
||||||
|
className="button is-primary is-pulled-right"
|
||||||
|
onClick={onAddOptionClick}>
|
||||||
Ajouter
|
Ajouter
|
||||||
</a>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|
Loading…
Reference in New Issue