From acc3dc1de15c471a775e290656bbe93c9c445d1c Mon Sep 17 00:00:00 2001 From: Johan Girod Date: Tue, 26 May 2020 14:18:27 +0200 Subject: [PATCH] =?UTF-8?q?:art:=20affiche=20l'explication=20des=20r=C3=A8?= =?UTF-8?q?gles=20=C3=A0=20l'int=C3=A9rieur=20du=20studio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../source/sites/publi.codes/App.tsx | 2 +- .../source/sites/publi.codes/Studio.tsx | 149 ++++++++---------- 2 files changed, 67 insertions(+), 84 deletions(-) diff --git a/mon-entreprise/source/sites/publi.codes/App.tsx b/mon-entreprise/source/sites/publi.codes/App.tsx index 3dfc6f0c5..bc37752b2 100644 --- a/mon-entreprise/source/sites/publi.codes/App.tsx +++ b/mon-entreprise/source/sites/publi.codes/App.tsx @@ -24,7 +24,7 @@ const RouterSwitch = () => { <> - + diff --git a/mon-entreprise/source/sites/publi.codes/Studio.tsx b/mon-entreprise/source/sites/publi.codes/Studio.tsx index f34b203fd..6d3e4ce4d 100644 --- a/mon-entreprise/source/sites/publi.codes/Studio.tsx +++ b/mon-entreprise/source/sites/publi.codes/Studio.tsx @@ -1,19 +1,19 @@ // import { ControlledEditor } from '@monaco-editor/react' -import Engine from 'publicodes' -import { formatValue } from 'publicodes' -import yaml from 'yaml' -import { last } from 'ramda' +import Engine, { Documentation, getDocumentationSiteMap } from 'publicodes' +import { invertObj, last } from 'ramda' import React, { useCallback, useEffect, useMemo, useState } from 'react' import emoji from 'react-easy-emoji' import MonacoEditor from 'react-monaco-editor' -import { useLocation } from 'react-router-dom' +import { useHistory, useLocation } from 'react-router-dom' import styled from 'styled-components' +import yaml from 'yaml' const EXAMPLE_CODE = ` # Bienvenue dans le bac à sable du langage publicode ! # Pour en savoir plus sur le langage, consultez le tutoriel : # => https://publi.codes +prix: prix . carottes: 2€/kg prix . champignons: 5€/kg prix . avocat: 2€/avocat @@ -47,7 +47,7 @@ function useDebounce(value: T, delay: number) { return debouncedValue } export default function Studio() { - const search = useLocation().search + const { search, pathname } = useLocation() const initialValue = useMemo(() => { const code = new URLSearchParams(search ?? '').get('code') return code ? code : EXAMPLE_CODE @@ -64,15 +64,13 @@ export default function Studio() { } }, [debouncedEditorValue]) + const history = useHistory() useEffect(() => { - history.replaceState( - null, - '', - `${window.location.pathname}?code=${encodeURIComponent( - debouncedEditorValue - )}` - ) - }, [debouncedEditorValue]) + history.replace({ + pathname, + search: `?code=${encodeURIComponent(debouncedEditorValue)}` + }) + }, [debouncedEditorValue, history]) const handleShare = useCallback(() => { navigator.clipboard.writeText(window.location.href) @@ -116,52 +114,61 @@ type ResultsProps = { } export const Results = ({ targets, onClickShare, rules }: ResultsProps) => { - const [rule, setCurrentTarget] = useState() - const currentTarget = rule ?? (last(targets) as string) const engine = useMemo(() => new Engine(rules), [rules]) + const documentationPath = '/studio' + const pathToRule = useMemo( + () => getDocumentationSiteMap({ engine, documentationPath }), + [engine, documentationPath] + ) + const ruleToPaths = useMemo(() => invertObj(pathToRule), [pathToRule]) + const { search, pathname } = useLocation() + const currentTarget = pathToRule[pathname] ?? (last(targets) as string) + const history = useHistory() + const setCurrentTarget = useCallback( + target => history.replace({ pathname: ruleToPaths[target], search }), + [ruleToPaths, history, search] + ) + // EN ATTENDANT d'AVOIR une meilleure gestion d'erreur, on va mocker // console.warn const warnings: string[] = [] const originalWarn = console.warn console.warn = (warning: string) => warnings.push(warning) - const evaluation = engine.evaluate(currentTarget) - console.warn = originalWarn return ( <>
-

- -

- -
-
+ + Aller à{' '} + +
-
@@ -178,39 +185,13 @@ export const Results = ({ targets, onClickShare, rules }: ResultsProps) => { {nl2br(warning)}
))} - {evaluation ? ( -
-

Résultats

- {evaluation.isApplicable === false ? ( - <>{emoji('❌')} Cette règle n'est pas applicable - ) : ( - <> -

- {formatValue(evaluation)} -

-
- {'temporalValue' in evaluation && - evaluation.temporalValue && - evaluation.temporalValue - .filter(({ value }) => value !== false) - .map(({ start: du, end: au, value }) => ( - - - Du {du} au {au} :{' '} - - - {formatValue({ - nodeValue: value, - unit: evaluation.unit - })} - {' '} -
-
- ))} - - )} -
- ) : null} + + + ) } @@ -249,11 +230,11 @@ const Layout = styled.div` ` class ErrorBoundary extends React.Component { - state: { error: false | string } = { error: false } + state: { error: false | { message: string; name: string } } = { error: false } - static getDerivedStateFromError(error) { + static getDerivedStateFromError(error: Error) { console.error(error) - return { error: error.message } + return { error: { message: error.message, name: error.name } } } render() { if (this.state.error) { @@ -265,7 +246,9 @@ class ErrorBoundary extends React.Component { border-radius: 5px; `} > - {nl2br(this.state.error)} + {this.state.error.name} +
+ {nl2br(this.state.error.message)} ) }