WIP ⚙️ implémentation du retour en arrière (brut visuellement)
Reste : corriger le fix dans reducers Bonus : brouillons d'icônespull/6/head
parent
d0da37db5c
commit
092947a145
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 744.09448819 1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="finsvg.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="295.97165"
|
||||
inkscape:cy="571.35343"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0;fill-rule:nonzero;stroke:#000000;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4136"
|
||||
width="557.06598"
|
||||
height="344.28571"
|
||||
x="90"
|
||||
y="308.07648" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:8.3871851;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 155.20364,307.27204 352.90158,145.51919 578.15741,304.87571"
|
||||
id="path4140"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:8.3871851;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path4148"
|
||||
cx="352.90158"
|
||||
cy="145.51918"
|
||||
r="23.963387" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="162.85715"
|
||||
y="569.50507"
|
||||
id="text4150"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4152"
|
||||
x="162.85715"
|
||||
y="569.50507"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:250px;font-family:msbm10;-inkscape-font-specification:msbm10">FIN</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 744.09448819 1052.3622047"
|
||||
id="svg4166"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="icônes-CDD.svg">
|
||||
<defs
|
||||
id="defs4168" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="222.37121"
|
||||
inkscape:cy="329.39132"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1021"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4171">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:10.3946209;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4714"
|
||||
width="575.48065"
|
||||
height="176.74823"
|
||||
x="21.464886"
|
||||
y="86.84523" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 205.67544,154.64744 210.26673,0"
|
||||
id="path4716"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 153.54319,183.32017 263.26786,0"
|
||||
id="path4718"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:87.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="520.22858"
|
||||
y="183.63103"
|
||||
id="text4724"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4726"
|
||||
x="520.22858"
|
||||
y="183.63103"
|
||||
style="font-size:50px">€</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="478.81232"
|
||||
y="163.42796"
|
||||
id="text4728"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4730"
|
||||
x="478.81232"
|
||||
y="163.42796" /></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 474.7717,244.24018 c 31.31473,-20.20306 59.599,-38.3858 53.53809,-17.1726 -6.06092,21.21321 35.35534,6.06092 35.35534,6.06092"
|
||||
id="path4732"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 130.30968,528.09304 c 32.32488,-19.1929 61.6783,-24.56623 178.797,-28.28428 63.63961,-2.0203 88.38835,-12.6269 88.38835,-12.6269"
|
||||
id="path4755"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc" />
|
||||
<g
|
||||
transform="matrix(1.7389448,0,0,1.7389448,237.04228,351.03091)"
|
||||
id="g4">
|
||||
<path
|
||||
style="fill:#000000"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 74.97,45.051 c 3.928,0.775 6.896,2.735 7.001,4.52 C 83.465,33.237 72.374,18.072 55.869,14.811 39.362,11.55 23.337,21.357 18.508,37.032 c 0.775,-1.612 4.267,-2.294 8.193,-1.519 4.228,0.835 7.351,3.041 6.979,4.927 0.373,-1.886 4.364,-2.686 8.915,-1.787 4.552,0.9 7.939,3.157 7.567,5.043 0.373,-1.886 4.364,-2.685 8.914,-1.787 4.554,0.899 7.939,3.158 7.568,5.043 0.371,-1.885 4.099,-2.737 8.326,-1.901 z"
|
||||
id="path6" />
|
||||
<polygon
|
||||
style="fill:#000000"
|
||||
points="51.331,41.31 42.67,85.143 41.402,86.638 40.799,84.773 49.459,40.94 "
|
||||
id="polygon8" />
|
||||
</g>
|
||||
<g
|
||||
id="g4790"
|
||||
transform="translate(-10,5)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4771"
|
||||
d="m 222.23356,482.63617 108.08632,-8.08122 36.36549,-29.29443"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4773"
|
||||
d="m 250,480.93363 -5.1978,19.39847"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4773-3"
|
||||
d="m 296.73836,478.27687 4.38042,19.59923"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 5.4314649,517.38856 C 19.894644,500.38015 53.55256,494.39958 72.243237,494.78475 c 18.690678,0.38517 31.590923,16.1695 46.221523,16.86681 14.63061,0.69731 27.35758,-14.60867 39.46566,-14.03158 7.12056,0.33938 17.61353,4.41922 22.0853,6.84295 8.75475,4.74514 -12.68938,5.64463 -37.17939,18.28112 -13.21823,6.82042 -91.943091,84.09988 -91.943091,84.09988"
|
||||
id="path4795"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssssc" />
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="729.33014"
|
||||
y="709.92047"
|
||||
id="text5346"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5348"
|
||||
x="729.33014"
|
||||
y="709.92047">https://thenounproject.com/search/?q=job+search&i=873829</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 383.92066,784.656 -12.41,-12.41 c 13.289,-18.911 8.731,-45.014 -10.18,-58.303 -18.911,-13.289 -45.014,-8.731 -58.303,10.18 -13.289,18.911 -8.731,45.014 10.18,58.303 14.437,10.145 33.686,10.145 48.123,0 l 12.41,12.41 c 2.011,2.009 5.269,2.009 7.28,0 l 2.89,-2.89 c 2.016,-2.007 2.023,-5.267 0.017,-7.283 -0.003,-0.003 -0.005,-0.005 -0.007,-0.007 z m -69.11,-14 c -12.407,-12.407 -12.407,-32.523 0,-44.93 12.407,-12.407 32.523,-12.407 44.93,0 12.407,12.407 12.407,32.522 0,44.929 -12.416,12.386 -32.514,12.386 -44.93,10e-4 z"
|
||||
id="path4" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 355.21066,737.696 -8.92,0 0,-2.51 c 0,-2.066 -1.674,-3.74 -3.74,-3.74 l 0,0 -10.12,0 c -2.066,0 -3.74,1.674 -3.74,3.74 l 0,0 0,2.51 -9.34,0 c -1.613,0 -2.92,1.307 -2.92,2.92 l 0,0 0,19.67 c 0,1.613 1.307,2.92 2.92,2.92 l 0,0 35.86,0 c 1.613,0 2.92,-1.307 2.92,-2.92 l 0,-19.67 c 0,-1.613 -1.307,-2.92 -2.92,-2.92 z m -23.1,-2.51 c 0,-0.166 0.134,-0.3 0.3,-0.3 l 10.14,0 c 0.166,0 0.3,0.134 0.3,0.3 l 0,2.51 -10.74,0 0,-2.51 z"
|
||||
id="path6-6" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="753.57379"
|
||||
y="172.51933"
|
||||
id="text5358"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5360"
|
||||
x="753.57379"
|
||||
y="172.51933"
|
||||
style="font-size:25px">+ FUSÉE ?</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="370.72598"
|
||||
y="719.01184"
|
||||
id="text5364"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5366"
|
||||
x="370.72598"
|
||||
y="719.01184"
|
||||
style="font-size:62.5px">+</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="591.9494"
|
||||
y="895.78857"
|
||||
id="text4715"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4717"
|
||||
x="591.9494"
|
||||
y="895.78857">https://thenounproject.com/search/?q=lesson&i=118285</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 64.058704,916.78877 c -0.599,0 -1.087,-0.486 -1.087,-1.086 l 0,-19.682 c 0,-0.148 -0.121,-0.271 -0.271,-0.271 l -3.141,0 c -0.133,0 -0.246,0.096 -0.269,0.229 l -3.318,19.902 c -0.087,0.527 -0.538,0.908 -1.072,0.908 l -4.187,0 c -0.314,0 -0.613,-0.137 -0.82,-0.375 -0.207,-0.238 -0.3,-0.553 -0.256,-0.865 l 3.491,-24.449 0.003,-12.611 c 0,-0.149 -0.121,-0.272 -0.271,-0.272 l -0.788,0 c -0.15,0 -0.272,0.123 -0.272,0.272 l 0,9.164 c 0,0.598 -0.487,1.086 -1.087,1.086 l -4.186,0 c -0.6,0 -1.087,-0.488 -1.087,-1.086 l 0,-10.523 c 0,-4.467 3.633,-8.101 8.1,-8.101 l 6.332,0 c 0.15,0 0.272,-0.122 0.272,-0.272 l 0,-0.91 c 0,-0.133 -0.097,-0.246 -0.228,-0.268 -3.931,-0.646 -6.783,-4.004 -6.783,-7.982 0,-3.978 2.853,-7.336 6.783,-7.983 0.131,-0.021 0.228,-0.135 0.228,-0.268 l 0,-5.775 c 0,-0.599 0.487,-1.087 1.087,-1.087 l 53.864996,0 c 0.6,0 1.087,0.488 1.087,1.087 l 0,28.055 c 0,0.599 -0.487,1.087 -1.087,1.087 l -35.688996,0 c -0.045,0 -0.09,0.011 -0.129,0.033 l -2.398,1.3 c -0.158,0.086 -0.338,0.131 -0.518,0.131 l -6.758,0 c -0.15,0 -0.271,0.122 -0.271,0.272 l 0,39.254 c 0,0.6 -0.488,1.086 -1.088,1.086 l -4.187,0 z m 0,-23.213 c 0.6,0 1.087,0.488 1.087,1.088 l 0,19.68 c 0,0.15 0.122,0.271 0.272,0.271 l 1.469,0 c 0.15,0 0.272,-0.121 0.272,-0.271 l 0,-39.255 c 0,-0.599 0.487,-1.086 1.086,-1.086 l 7.772,0 c 0.045,0 0.089,-0.012 0.129,-0.033 l 5.469,-2.787 c 0.111,-0.06 0.166,-0.188 0.133,-0.311 l -1.07,-2.217 c -0.021,-0.08 -0.079,-0.146 -0.155,-0.179 -0.034,-0.015 -0.07,-0.021 -0.106,-0.021 -0.045,0 -0.089,0.011 -0.13,0.033 l -4.767,2.583 c -0.158,0.087 -0.337,0.132 -0.519,0.132 l -21.46,0 c -3.268,0 -5.926,2.659 -5.926,5.927 l 0,9.163 c 0,0.15 0.121,0.271 0.271,0.271 l 1.469,0 c 0.149,0 0.271,-0.121 0.271,-0.271 l 0,-9.163 c 0,-0.6 0.488,-1.087 1.087,-1.087 l 3.506,0 c 0.6,0 1.087,0.487 1.087,1.087 l 0,14.026 c 0,0.051 -0.003,0.104 -0.01,0.152 l -3.283,22.996 c -0.012,0.078 0.012,0.158 0.063,0.217 0.051,0.061 0.126,0.094 0.205,0.094 l 1.468,0 c 0.133,0 0.246,-0.096 0.269,-0.227 l 3.319,-19.904 c 0.088,-0.525 0.538,-0.908 1.072,-0.908 l 5.65,0 z m 31.653,-33.949 c -0.047,0 -0.094,0.013 -0.136,0.036 l -12.146,7.014 c -0.131,0.074 -0.175,0.241 -0.1,0.371 l 1.298,2.222 c 0.036,0.062 0.096,0.108 0.165,0.127 0.023,0.006 0.047,0.009 0.07,0.009 0.047,0 0.095,-0.012 0.137,-0.036 l 12.207,-6.881 c 0.13,-0.075 0.174,-0.241 0.1,-0.371 l -1.359,-2.354 c -0.036,-0.062 -0.096,-0.108 -0.165,-0.127 -0.024,-0.007 -0.047,-0.01 -0.071,-0.01 z m -34.478,-5.956 c -3.268,0 -5.926,2.658 -5.926,5.926 0,3.267 2.658,5.926 5.926,5.926 3.268,0 5.926,-2.659 5.926,-5.926 0,-3.268 -2.658,-5.926 -5.926,-5.926 z"
|
||||
id="path4-3" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
|
@ -2,8 +2,8 @@
|
|||
// The state keeps track of which of them have been submitted
|
||||
// The user can also come back to one of his answers and edit it
|
||||
export const STEP_ACTION = 'STEP_ACTION'
|
||||
export function stepAction(name, newState) {
|
||||
return {type: STEP_ACTION, name, newState}
|
||||
export function stepAction(name, step) {
|
||||
return {type: STEP_ACTION, name, step}
|
||||
}
|
||||
|
||||
export const START_CONVERSATION = 'START_CONVERSATION'
|
||||
|
|
|
@ -14,7 +14,8 @@ let situationSelector = formValueSelector('conversation')
|
|||
@connect(
|
||||
state => ({
|
||||
situation: variableName => situationSelector(state, variableName),
|
||||
steps: state.submittedSteps.concat(state.steps),
|
||||
foldedSteps: state.foldedSteps,
|
||||
unfoldedSteps: state.unfoldedSteps,
|
||||
themeColours: state.themeColours,
|
||||
analysedSituation: state.analysedSituation,
|
||||
}),
|
||||
|
@ -28,12 +29,22 @@ export default class CDD extends Component {
|
|||
this.props.startConversation()
|
||||
}
|
||||
render() {
|
||||
let {steps, situation} = this.props
|
||||
let {foldedSteps, unfoldedSteps, situation} = this.props
|
||||
|
||||
let conversation = steps.map(step => (
|
||||
<step.component key={step.name} {...step} step={step} answer={situation(step.name)}/>
|
||||
let conversation = foldedSteps.map(step => <step.component
|
||||
key={step.name}
|
||||
{...step}
|
||||
step={step}
|
||||
answer={situation(step.name)} />
|
||||
).concat(unfoldedSteps.map(step => <step.component
|
||||
key={step.name}
|
||||
{...step}
|
||||
step={step}
|
||||
unfolded={true}
|
||||
answer={situation(step.name)} />
|
||||
))
|
||||
|
||||
|
||||
return (
|
||||
<div id="sim">
|
||||
<PageTypeIcon type="simulation" />
|
||||
|
|
|
@ -19,7 +19,7 @@ export var FormDecorator = formType => RenderField =>
|
|||
themeColours: state.themeColours
|
||||
}),
|
||||
dispatch => ({
|
||||
stepAction: (name, newState) => dispatch(stepAction(name, newState)),
|
||||
stepAction: (name, step) => dispatch(stepAction(name, step)),
|
||||
setFormValue: (field, value) => dispatch(change('conversation', field, value)),
|
||||
pointOutObjectives: objectives => dispatch({type: POINT_OUT_OBJECTIVES, objectives})
|
||||
})
|
||||
|
@ -33,11 +33,13 @@ export var FormDecorator = formType => RenderField =>
|
|||
stepAction,
|
||||
themeColours,
|
||||
setFormValue,
|
||||
pointOutObjectives
|
||||
pointOutObjectives,
|
||||
/* Une étape déjà répondue est marquée 'folded'. Dans ce dernier cas, un résumé
|
||||
de la réponse est affiché */
|
||||
unfolded
|
||||
} = this.props,
|
||||
{
|
||||
name,
|
||||
visible,
|
||||
possibleChoice, // should be found in the question set theoritically, but it is used for a single choice question -> the question itself is dynamic and cannot be input as code,
|
||||
// formerly in conversation-steps
|
||||
valueType,
|
||||
|
@ -48,20 +50,10 @@ export var FormDecorator = formType => RenderField =>
|
|||
helpText,
|
||||
suggestions,
|
||||
subquestion,
|
||||
objectives
|
||||
objectives,
|
||||
} = this.props.step
|
||||
|
||||
this.step = this.props.step
|
||||
|
||||
/* La saisie peut être cachée car ce n'est pas encore son tour,
|
||||
ou parce qu'elle a déjà été remplie. Dans ce dernier cas, un résumé
|
||||
de la réponse est affiché */
|
||||
let stepState = this.step.state,
|
||||
completed = stepState && stepState != 'editing',
|
||||
unfolded = !completed
|
||||
|
||||
if (!visible) return null
|
||||
|
||||
/* Nos propriétés personnalisées à envoyer au RenderField.
|
||||
Elles sont regroupées dans un objet précis pour pouvoir être enlevées des
|
||||
props passées à ce dernier, car React 15.2 n'aime pas les attributes inconnus
|
||||
|
@ -73,7 +65,7 @@ export var FormDecorator = formType => RenderField =>
|
|||
optionsURL, /* Select component's data source */
|
||||
possibleChoice, /* RhetoricalQuestion component's only choice :'-( */
|
||||
//TODO hack, enables redux-form/CHANGE to update the form state before the traverse functions are run
|
||||
submit: () => setTimeout(() => stepAction(name, 'filled'), 1),
|
||||
submit: () => setTimeout(() => stepAction('fold', name), 1),
|
||||
setFormValue: value => setFormValue(name, value),
|
||||
valueType,
|
||||
suggestions,
|
||||
|
@ -85,7 +77,7 @@ export var FormDecorator = formType => RenderField =>
|
|||
|
||||
return (
|
||||
<div
|
||||
className={classNames({step: unfolded, fact: completed}, formType)}
|
||||
className={classNames({step: unfolded}, formType)}
|
||||
onMouseOver={() => pointOutObjectives(objectives)}
|
||||
onMouseOut={() => pointOutObjectives([])}>
|
||||
{this.state.helpVisible && this.renderHelpBox(helpText)}
|
||||
|
@ -142,9 +134,8 @@ export var FormDecorator = formType => RenderField =>
|
|||
<span>
|
||||
<span className="title">{this.props.step.title}</span>
|
||||
<span className="answer">{answer}
|
||||
<span className="edit">
|
||||
<span className="edit" onClick={() => stepAction('unfold', name)}>
|
||||
<i
|
||||
onClick={() => stepAction(name, 'editing')}
|
||||
className="fa fa-pencil-square-o"
|
||||
aria-hidden="true">
|
||||
</i>
|
||||
|
|
|
@ -11,7 +11,6 @@ export let constructStepMeta = ({titre, question, subquestion, dottedName, name}
|
|||
lightBackground={true}
|
||||
/>,
|
||||
title: titre || name,
|
||||
dependencyOfVariables: ['chai pas'],
|
||||
subquestion,
|
||||
|
||||
// Legacy properties :
|
||||
|
|
|
@ -128,7 +128,7 @@ let collectNodeMissingVariables = target => (root, source=root, results=[]) => {
|
|||
}
|
||||
|
||||
|
||||
export let collectMissingVariables = (groupMethod='groupByMissingVariable', analysedSituation) =>
|
||||
export let collectMissingVariables = (groupMethod='groupByMissingVariable') => analysedSituation =>
|
||||
R.pipe(
|
||||
R.unless(R.is(Array), R.of),
|
||||
R.chain( v =>
|
||||
|
|
|
@ -43,6 +43,143 @@ function pointedOutObjectives(state=[], {type, objectives}) {
|
|||
}
|
||||
}
|
||||
|
||||
let handleSteps = (state, action) => {
|
||||
|
||||
let returnObject = {
|
||||
...state,
|
||||
analysedSituation: analyse(state)
|
||||
}
|
||||
if (action.type == START_CONVERSATION) {
|
||||
return {
|
||||
...returnObject,
|
||||
unfoldedSteps: buildNextSteps(returnObject.analysedSituation)
|
||||
}
|
||||
}
|
||||
if (action.type == STEP_ACTION && action.name == 'fold') {
|
||||
return {
|
||||
...returnObject,
|
||||
foldedSteps: [...state.foldedSteps, R.head(state.unfoldedSteps)],
|
||||
unfoldedSteps: buildNextSteps(returnObject.analysedSituation)
|
||||
}
|
||||
}
|
||||
if (action.type == STEP_ACTION && action.name == 'unfold') {
|
||||
let stepFinder = R.propEq('name', action.step),
|
||||
foldedSteps = R.pipe(
|
||||
R.splitWhen(stepFinder),
|
||||
R.head
|
||||
)(state.foldedSteps)
|
||||
console.log('foldedSteps', foldedSteps)
|
||||
return {
|
||||
...returnObject,
|
||||
foldedSteps,
|
||||
unfoldedSteps: [R.find(stepFinder)(state.foldedSteps)]
|
||||
}
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
let analyse = R.pipe(
|
||||
situationGate,
|
||||
// une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables')
|
||||
analyseSituation
|
||||
)
|
||||
|
||||
let missingVariables
|
||||
|
||||
let buildNextSteps = R.pipe(
|
||||
/*
|
||||
on collecte les variables manquantes : celles qui sont nécessaires pour
|
||||
remplir les objectifs de la simulation (calculer des cotisations) mais qui n'ont pas
|
||||
encore été renseignées
|
||||
|
||||
TODO perf : peut-on le faire en même temps que l'on traverse l'AST ?
|
||||
Oui sûrement, cette liste se complète en remontant l'arbre. En fait, on le fait déjà pour nodeValue,
|
||||
et quand nodeValue vaut null, c'est qu'il y a des missingVariables ! Il suffit donc de remplacer les
|
||||
null par un tableau, et d'ailleurs utiliser des fonction d'aide pour mutualiser ces tests.
|
||||
|
||||
missingVariables: {variable: [objectives]}
|
||||
*/
|
||||
R.path(['formule', 'explanation', 'explanation']),
|
||||
analysedSituation => {
|
||||
//TODO temporary fix
|
||||
missingVariables = collectMissingVariables('groupByMissingVariable')(analysedSituation)
|
||||
return missingVariables
|
||||
},
|
||||
R.keys,
|
||||
/*
|
||||
Certaines variables manquantes peuvent être factorisées dans des groupes.
|
||||
Par exemple, au lieu de :
|
||||
|
||||
q1: "Pensez vous porlonger le CDD en CDI",
|
||||
r1: Oui | Non
|
||||
q2: "Pensez-vous qu'une rupture pour faute grave est susceptible d'arriver"
|
||||
r2: Oui | Non
|
||||
|
||||
on préfère :
|
||||
|
||||
q: "Pensez-vous être confronté à l'un de ces événements ?"
|
||||
r: Prolongation du CDD en CDI | Rupture pour faute grave
|
||||
*/
|
||||
R.groupBy(parentName),
|
||||
// on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes
|
||||
R.pipe(
|
||||
R.mapObjIndexed((variables, group) =>
|
||||
R.pipe(
|
||||
findGroup,
|
||||
R.cond([
|
||||
// Pas de groupe trouvé : ce sont des variables individuelles
|
||||
[R.isNil, () => variables.map(dottedName => {
|
||||
let rule = findRuleByDottedName(dottedName)
|
||||
return Object.assign(constructStepMeta(rule),
|
||||
rule.format == 'nombre positif' ||
|
||||
rule.format == 'période' ?
|
||||
{
|
||||
component: Input,
|
||||
valueType: rule.format == 'nombre positif' ? euro : months,
|
||||
attributes: {
|
||||
inputMode: 'numeric',
|
||||
placeholder: 'votre réponse'
|
||||
},
|
||||
suggestions: rule.suggestions
|
||||
} : {
|
||||
component: Question,
|
||||
choices: [
|
||||
{value: 'non', label: 'Non'},
|
||||
{value: 'oui', label: 'Oui'}
|
||||
]
|
||||
},
|
||||
{
|
||||
objectives: missingVariables[dottedName]
|
||||
}
|
||||
)})],
|
||||
[R.T, group => do {
|
||||
let possibilities = group['une possibilité']
|
||||
Object.assign(
|
||||
constructStepMeta(group),
|
||||
{
|
||||
component: Question,
|
||||
choices:
|
||||
possibilities.concat(
|
||||
group['langue au chat possible'] === 'oui' ?
|
||||
[{value: '_', label: 'Aucun'}] : []
|
||||
)
|
||||
},
|
||||
{
|
||||
objectives: R.pipe(
|
||||
R.chain(v => missingVariables[group.dottedName + ' . ' + v]),
|
||||
R.uniq()
|
||||
)(possibilities)
|
||||
}
|
||||
)}]
|
||||
])
|
||||
)(group)
|
||||
),
|
||||
R.values,
|
||||
R.unnest
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
export default reduceReducers(
|
||||
combineReducers({
|
||||
// this is handled by redux-form, pas touche !
|
||||
|
@ -50,9 +187,9 @@ export default reduceReducers(
|
|||
|
||||
/* Have forms been filled or ignored ?
|
||||
false means the user is reconsidering its previous input */
|
||||
steps: (steps=[]) => steps,
|
||||
foldedSteps: (steps=[]) => steps,
|
||||
unfoldedSteps: (steps=[]) => steps,
|
||||
|
||||
submittedSteps: (steps=[]) => steps,
|
||||
|
||||
analysedSituation: (state = []) => state,
|
||||
|
||||
|
@ -63,132 +200,5 @@ export default reduceReducers(
|
|||
pointedOutObjectives
|
||||
}),
|
||||
// cross-cutting concerns because here `state` is the whole state tree
|
||||
(state, action) => {
|
||||
if (action.type == STEP_ACTION || action.type == START_CONVERSATION) {
|
||||
|
||||
// pour débugguer :
|
||||
window.situationGate = situationGate(state)
|
||||
|
||||
let newlySubmittedSteps =
|
||||
action.newState == 'filled'
|
||||
? [{
|
||||
...state.steps.find(s => s.name === action.name),
|
||||
state: 'filled'
|
||||
}]
|
||||
: []
|
||||
|
||||
|
||||
// on calcule la prochaine étape, à ajouter sur la pile
|
||||
let
|
||||
// une liste des objectifs de la simulation (des 'rules' aussi nommées 'variables')
|
||||
analysedSituation = analyseSituation(
|
||||
situationGate(state)
|
||||
),
|
||||
|
||||
// y = console.log('analysedSituation',analysedSituation),
|
||||
|
||||
/*
|
||||
on collecte les variables manquantes : celles qui sont nécessaires pour
|
||||
remplir les objectifs de la simulation (calculer des cotisations) mais qui n'ont pas
|
||||
encore été renseignées
|
||||
|
||||
TODO perf : peut-on le faire en même temps que l'on traverse l'AST ?
|
||||
Oui sûrement, cette liste se complète en remontant l'arbre. En fait, on le fait déjà pour nodeValue,
|
||||
et quand nodeValue vaut null, c'est qu'il y a des missingVariables ! Il suffit donc de remplacer les
|
||||
null par un tableau, et d'ailleurs utiliser des fonction d'aide pour mutualiser ces tests.
|
||||
|
||||
missingVariables: {variable: [objectives]}
|
||||
*/
|
||||
|
||||
missingVariables = collectMissingVariables('groupByMissingVariable', R.path(['formule', 'explanation', 'explanation'])(analysedSituation)),
|
||||
// yy = console.log('missingVariables',missingVariables),
|
||||
|
||||
missingVariablesList = R.keys(missingVariables),
|
||||
/*
|
||||
Certaines variables manquantes peuvent être factorisées dans des groupes.
|
||||
Par exemple, au lieu de :
|
||||
|
||||
q1: "Pensez vous porlonger le CDD en CDI",
|
||||
r1: Oui | Non
|
||||
q2: "Pensez-vous qu'une rupture pour faute grave est susceptible d'arriver"
|
||||
r2: Oui | Non
|
||||
|
||||
on préfère :
|
||||
|
||||
q: "Pensez-vous être confronté à l'un de ces événements ?"
|
||||
r: Prolongation du CDD en CDI | Rupture pour faute grave
|
||||
*/
|
||||
groups = R.groupBy(
|
||||
parentName
|
||||
)(missingVariablesList),
|
||||
|
||||
// on va maintenant construire la liste des composants React qui afficheront les questions à l'utilisateur pour que l'on obtienne les variables manquantes
|
||||
steps = R.pipe(
|
||||
R.mapObjIndexed((variables, group) =>
|
||||
R.pipe(
|
||||
findGroup,
|
||||
R.cond([
|
||||
// Pas de groupe trouvé : ce sont des variables individuelles
|
||||
[R.isNil, () => variables.map(dottedName => {
|
||||
let rule = findRuleByDottedName(dottedName)
|
||||
return Object.assign(constructStepMeta(rule),
|
||||
rule.format == 'nombre positif' ||
|
||||
rule.format == 'période' ?
|
||||
{
|
||||
component: Input,
|
||||
valueType: rule.format == 'nombre positif' ? euro : months,
|
||||
attributes: {
|
||||
inputMode: 'numeric',
|
||||
placeholder: 'votre réponse'
|
||||
},
|
||||
suggestions: rule.suggestions
|
||||
} : {
|
||||
component: Question,
|
||||
choices: [
|
||||
{value: 'non', label: 'Non'},
|
||||
{value: 'oui', label: 'Oui'}
|
||||
]
|
||||
},
|
||||
{
|
||||
objectives: missingVariables[dottedName]
|
||||
}
|
||||
)})],
|
||||
[R.T, group => do {
|
||||
let possibilities = group['une possibilité']
|
||||
Object.assign(
|
||||
constructStepMeta(group),
|
||||
{
|
||||
component: Question,
|
||||
choices:
|
||||
possibilities.concat(
|
||||
group['langue au chat possible'] === 'oui' ?
|
||||
[{value: '_', label: 'Aucun'}] : []
|
||||
)
|
||||
},
|
||||
{
|
||||
objectives: R.pipe(
|
||||
R.chain(v => missingVariables[group.dottedName + ' . ' + v]),
|
||||
R.uniq()
|
||||
)(possibilities)
|
||||
}
|
||||
)}]
|
||||
])
|
||||
)(group)
|
||||
),
|
||||
R.values,
|
||||
R.unnest
|
||||
)(groups)
|
||||
|
||||
return {
|
||||
...state,
|
||||
steps,
|
||||
submittedSteps: state.submittedSteps.concat(newlySubmittedSteps),
|
||||
analysedSituation
|
||||
}
|
||||
|
||||
} else {
|
||||
return state
|
||||
}
|
||||
|
||||
}
|
||||
handleSteps
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue