From f032e83e71c88babc34db9adbf3bc4dbab103c86 Mon Sep 17 00:00:00 2001 From: William Petit Date: Mon, 12 Oct 2020 14:56:22 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Affichage=20des=20dossiers=20associ=C3=A9s?= =?UTF-8?q?=20dans=20la=20page=20groupe=20de=20travail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DecisionSupportFilePanel.tsx | 2 +- .../DashboardPage/WorkgroupsPanel.tsx | 2 +- .../components/DecisionSupportFileLink.tsx | 2 +- .../{DashboardPage => }/ItemPanel.tsx | 2 +- .../DecisionSupportFilePanel.tsx | 48 +++++++++++++++++++ .../WorkgroupPage/WorkgroupPage.tsx | 9 ++-- internal/graph/query.graphql | 1 + internal/model/dsf_repository.go | 4 ++ 8 files changed, 62 insertions(+), 8 deletions(-) rename client/src/components/{DashboardPage => }/ItemPanel.tsx (98%) create mode 100644 client/src/components/WorkgroupPage/DecisionSupportFilePanel.tsx diff --git a/client/src/components/DashboardPage/DecisionSupportFilePanel.tsx b/client/src/components/DashboardPage/DecisionSupportFilePanel.tsx index 208c7d7..56ba4fa 100644 --- a/client/src/components/DashboardPage/DecisionSupportFilePanel.tsx +++ b/client/src/components/DashboardPage/DecisionSupportFilePanel.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { DecisionSupportFile, DecisionSupportFileStatus } from '../../types/decision'; -import { ItemPanel, TabDefinition, Item } from './ItemPanel'; +import { ItemPanel, TabDefinition, Item } from '../ItemPanel'; import { useUserProfile } from '../../gql/queries/profile'; import { inWorkgroup } from '../../types/workgroup'; import { useDecisionSupportFiles } from '../../gql/queries/dsf'; diff --git a/client/src/components/DashboardPage/WorkgroupsPanel.tsx b/client/src/components/DashboardPage/WorkgroupsPanel.tsx index 5bb9684..dc9fa4f 100644 --- a/client/src/components/DashboardPage/WorkgroupsPanel.tsx +++ b/client/src/components/DashboardPage/WorkgroupsPanel.tsx @@ -2,7 +2,7 @@ import React, { } from 'react'; import { Workgroup, inWorkgroup } from '../../types/workgroup'; import { useWorkgroups } from '../../gql/queries/workgroups'; import { useUserProfile } from '../../gql/queries/profile'; -import { ItemPanel, Item } from './ItemPanel'; +import { ItemPanel, Item } from '../ItemPanel'; export function WorkgroupsPanel() { const { workgroups } = useWorkgroups(); diff --git a/client/src/components/DecisionSupportFileLink.tsx b/client/src/components/DecisionSupportFileLink.tsx index 542c94a..0f512e0 100644 --- a/client/src/components/DecisionSupportFileLink.tsx +++ b/client/src/components/DecisionSupportFileLink.tsx @@ -4,7 +4,7 @@ import { useWorkgroups } from "../gql/queries/workgroups"; import { useDecisionSupportFiles } from "../gql/queries/dsf"; export interface DecisioSupportFileLinkProps { - decisionSupportFileId: number + decisionSupportFileId: number|string } export const DecisionSupportFileLink: FunctionComponent = ({ decisionSupportFileId }) => { diff --git a/client/src/components/DashboardPage/ItemPanel.tsx b/client/src/components/ItemPanel.tsx similarity index 98% rename from client/src/components/DashboardPage/ItemPanel.tsx rename to client/src/components/ItemPanel.tsx index 84211af..14be08f 100644 --- a/client/src/components/DashboardPage/ItemPanel.tsx +++ b/client/src/components/ItemPanel.tsx @@ -1,6 +1,6 @@ import React, { FunctionComponent, useState, useEffect } from "react"; import { Link } from "react-router-dom"; -import { WithLoader } from "../WithLoader"; +import { WithLoader } from "./WithLoader"; export interface Item { id: string diff --git a/client/src/components/WorkgroupPage/DecisionSupportFilePanel.tsx b/client/src/components/WorkgroupPage/DecisionSupportFilePanel.tsx new file mode 100644 index 0000000..1dffea8 --- /dev/null +++ b/client/src/components/WorkgroupPage/DecisionSupportFilePanel.tsx @@ -0,0 +1,48 @@ +import React, { FunctionComponent } from 'react'; +import { Link } from 'react-router-dom'; +import { useDecisionSupportFiles } from '../../gql/queries/dsf'; +import { DecisionSupportFile } from '../../types/decision'; +import { User } from '../../types/user'; +import { DecisionSupportFileLink } from '../DecisionSupportFileLink'; +import { WorkgroupLink } from '../WorkgroupLink'; + +export interface DecisionSupportFilePanelProps { + workgroupId: string +} + +export const DecisionSupportFilePanel: FunctionComponent = ({ workgroupId }) => { + const { decisionSupportFiles } = useDecisionSupportFiles({ + variables: { + filter: { + workgroups: [workgroupId], + } + } + }) + + return ( + + ); +} \ No newline at end of file diff --git a/client/src/components/WorkgroupPage/WorkgroupPage.tsx b/client/src/components/WorkgroupPage/WorkgroupPage.tsx index b9f74b3..530f452 100644 --- a/client/src/components/WorkgroupPage/WorkgroupPage.tsx +++ b/client/src/components/WorkgroupPage/WorkgroupPage.tsx @@ -1,18 +1,18 @@ import React, { useEffect, useState, Fragment } from 'react'; import { Page } from '../Page'; -import { WithLoader } from '../WithLoader'; import { useParams } from 'react-router'; -import { useWorkgroupsQuery, useWorkgroups } from '../../gql/queries/workgroups'; -import { useUserProfileQuery, useUserProfile } from '../../gql/queries/profile'; +import { useWorkgroups } from '../../gql/queries/workgroups'; +import { useUserProfile } from '../../gql/queries/profile'; import { MembersPanel } from './MembersPanel'; import { User } from '../../types/user'; import { InfoPanel } from './InfoPanel'; import { Workgroup } from '../../types/workgroup'; import { useJoinWorkgroupMutation, useLeaveWorkgroupMutation, useCloseWorkgroupMutation } from '../../gql/mutations/workgroups'; import { TimelinePanel } from './TimelinePanel'; +import { DecisionSupportFilePanel } from './DecisionSupportFilePanel'; export function WorkgroupPage() { - const { id } = useParams(); + const { id } = useParams(); const { workgroups } = useWorkgroups({ variables:{ filter: { @@ -140,6 +140,7 @@ export function WorkgroupPage() {
+
diff --git a/internal/graph/query.graphql b/internal/graph/query.graphql index 0599fe8..aea05aa 100644 --- a/internal/graph/query.graphql +++ b/internal/graph/query.graphql @@ -46,6 +46,7 @@ type DecisionSupportFile { input DecisionSupportFileFilter { ids: [ID] + workgroups: [ID] } input AuthorizationObject { diff --git a/internal/model/dsf_repository.go b/internal/model/dsf_repository.go index 4660713..6106429 100644 --- a/internal/model/dsf_repository.go +++ b/internal/model/dsf_repository.go @@ -108,6 +108,10 @@ func (r *DSFRepository) Search(ctx context.Context, filter *DecisionSupportFileF if filter.Ids != nil { query = query.Where("id in (?)", filter.Ids) } + + if filter.Workgroups != nil { + query = query.Where("workgroup_id in (?)", filter.Workgroups) + } } dsfs := make([]*DecisionSupportFile, 0) From 5649cd2aad20e0b0119f29ef85c732eb3b42fe58 Mon Sep 17 00:00:00 2001 From: William Petit Date: Mon, 12 Oct 2020 15:58:19 +0200 Subject: [PATCH 2/2] Gestion des liens profonds sur les tabs dans la page DAD --- client/src/components/App.tsx | 2 +- .../ClarificationSection.tsx | 158 +++++++++--------- .../DecisionReportSection.tsx | 22 ++- .../DecisionSupportFilePage.tsx | 67 +++----- .../OptionsSection.tsx | 4 +- client/src/components/RoutedTabs.tsx | 79 +++++++++ 6 files changed, 192 insertions(+), 140 deletions(-) create mode 100644 client/src/components/RoutedTabs.tsx diff --git a/client/src/components/App.tsx b/client/src/components/App.tsx index fe5eaea..5c06542 100644 --- a/client/src/components/App.tsx +++ b/client/src/components/App.tsx @@ -45,7 +45,7 @@ export const App: FunctionComponent = () => { - + } /> diff --git a/client/src/components/DecisionSupportFilePage/ClarificationSection.tsx b/client/src/components/DecisionSupportFilePage/ClarificationSection.tsx index 21c1c0a..37e5785 100644 --- a/client/src/components/DecisionSupportFilePage/ClarificationSection.tsx +++ b/client/src/components/DecisionSupportFilePage/ClarificationSection.tsx @@ -49,90 +49,88 @@ export const ClarificationSection: FunctionComponent return (
-
-
- -
- +
+ +
+ +
+
+
+ +
+ +
+

Ne pas essayer de rentrer trop dans les détails ici. Préférer l'utilisation des annexes et y faire référence.

+
+
+ +
+ +
+

Penser à indiquer si des obligations légales pèsent sur cette prise de décision.

+
+
+ +
+
+
-
- -
- -
-

Ne pas essayer de rentrer trop dans les détails ici. Préférer l'utilisation des annexes et y faire référence.

-
-
- -
- -
-

Penser à indiquer si des obligations légales pèsent sur cette prise de décision.

-
-
- -
-
- -
+
+
+ +
+
+
-
- -
-
- -
-
-
- -
-
- -
-
- -
+
+ +
+
+ +
+
+
diff --git a/client/src/components/DecisionSupportFilePage/DecisionReportSection.tsx b/client/src/components/DecisionSupportFilePage/DecisionReportSection.tsx index 315bb48..c26ca37 100644 --- a/client/src/components/DecisionSupportFilePage/DecisionReportSection.tsx +++ b/client/src/components/DecisionSupportFilePage/DecisionReportSection.tsx @@ -32,19 +32,17 @@ export const DecisionReportSection: FunctionComponent -
-
- -
- -
-

Penser à indiquer le résultat du vote et les éléments de contexte liés à la prise de décision.

+
+ +
+
+

Penser à indiquer le résultat du vote et les éléments de contexte liés à la prise de décision.

); diff --git a/client/src/components/DecisionSupportFilePage/DecisionSupportFilePage.tsx b/client/src/components/DecisionSupportFilePage/DecisionSupportFilePage.tsx index 979da13..a4c6962 100644 --- a/client/src/components/DecisionSupportFilePage/DecisionSupportFilePage.tsx +++ b/client/src/components/DecisionSupportFilePage/DecisionSupportFilePage.tsx @@ -11,6 +11,7 @@ import { OptionsSection } from './OptionsSection'; import { useIsAuthorized } from '../../gql/queries/authorization'; import { TimelinePanel } from './TimelinePanel'; import { DecisionReportSection } from './DecisionReportSection'; +import { RoutedTabs } from '../RoutedTabs'; export interface DecisionSupportFilePageProps { @@ -30,10 +31,8 @@ export const DecisionSupportFilePage: FunctionComponent ({ ...state, dsf: { ...state.dsf, ...dsf }})) }, [ decisionSupportFiles ]); - const selectTab = (tabIndex: number) => { - setState(state => ({ ...state, selectedTabIndex: tabIndex })); - }; + const tabs = [ + { + name: "Clarifier la proposition", + icon: "fas fa-pen", + route: '/info', + render: () => () + }, + { + name: "Explorer les options", + icon: "fas fa-search", + route: '/options', + render: () => () + }, + { + name: "Prendre la décision", + icon: "fas fa-person-booth", + route: '/vote', + render: () => () + } + ]; const updateDSF = (dsf: DecisionSupportFile) => { setState(state => { @@ -130,46 +146,9 @@ export const DecisionSupportFilePage: FunctionComponent
-
- +
+
- { - state.selectedTabIndex === 0 ? - : - null - } - { - state.selectedTabIndex === 1 ? - : - null - } - { - state.selectedTabIndex === 2 ? - : - null - }
diff --git a/client/src/components/DecisionSupportFilePage/OptionsSection.tsx b/client/src/components/DecisionSupportFilePage/OptionsSection.tsx index d44e5e1..f82832c 100644 --- a/client/src/components/DecisionSupportFilePage/OptionsSection.tsx +++ b/client/src/components/DecisionSupportFilePage/OptionsSection.tsx @@ -75,8 +75,7 @@ export const OptionsSection: FunctionComponent = ({ dsf, up return (
-

Explorer les options

-
+

Explorer les options

@@ -154,7 +153,6 @@ export const OptionsSection: FunctionComponent = ({ dsf, up
-
); }; \ No newline at end of file diff --git a/client/src/components/RoutedTabs.tsx b/client/src/components/RoutedTabs.tsx new file mode 100644 index 0000000..8c3407c --- /dev/null +++ b/client/src/components/RoutedTabs.tsx @@ -0,0 +1,79 @@ +import React, { FunctionComponent, ReactNode, useEffect, useState } from 'react'; +import { useHistory, useLocation, useRouteMatch } from 'react-router'; +import { Link } from 'react-router-dom'; + +export interface Tab { + route: string + name: string + icon ?: string + render: (tab: Tab) => ReactNode +} + +export interface RoutedTabsProps { + tabs: Tab[] + baseRoute?: string + defaultTabIndex?: number +} + + + +export const RoutedTabs: FunctionComponent = ({ tabs, baseRoute, defaultTabIndex }) => { + const history = useHistory(); + const location = useLocation(); + + const tabRoute = (route: string): string => { + return `${baseRoute}${route}`; + }; + + const [ selectedTabIndex, setSelectedTabIndex ] = useState(defaultTabIndex || 0); + const expectedTab = tabs[selectedTabIndex]; + const expectedTabRoute = tabRoute(expectedTab.route); + + let matchExpectedTabRoute = useRouteMatch(expectedTabRoute); + + useEffect(() => { + if (matchExpectedTabRoute) return; + + const newTabIndex = tabs.findIndex(t => location.pathname === tabRoute(t.route)); + + if (newTabIndex !== -1) { + selectTab(newTabIndex); + return; + } + + history.push(expectedTabRoute); + }, [matchExpectedTabRoute]); + + const selectTab = (tabIndex: number) => { + setSelectedTabIndex(tabIndex); + const newTab = tabs[tabIndex]; + history.push(tabRoute(newTab.route)); + }; + + return ( + +
+ +
+ { expectedTab.render(expectedTab) } +
+ ); +} \ No newline at end of file