From 89ae3ddac2331f629789cfdcccd22f7f758c36bf Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 01/47] feat(assets): :bento: new logo proposal

---
 public/favicon-large-outline.svg | 147 ------------------------------
 public/favicon-small-outline.svg | 152 -------------------------------
 public/favicon.svg               | 136 +--------------------------
 src/assets/images/logo.svg       |  16 +---
 4 files changed, 2 insertions(+), 449 deletions(-)
 delete mode 100644 public/favicon-large-outline.svg
 delete mode 100644 public/favicon-small-outline.svg

diff --git a/public/favicon-large-outline.svg b/public/favicon-large-outline.svg
deleted file mode 100644
index 0d0aa17..0000000
--- a/public/favicon-large-outline.svg
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   width="92.201767mm"
-   height="92.201752mm"
-   viewBox="0 0 92.201767 92.201752"
-   version="1.1"
-   id="svg936"
-   sodipodi:docname="favicon-large-outline.svg"
-   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <sodipodi:namedview
-     id="namedview36"
-     pagecolor="#ffffff"
-     bordercolor="#111111"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="1"
-     inkscape:document-units="mm"
-     showgrid="false"
-     inkscape:snap-bbox="true"
-     inkscape:bbox-paths="true"
-     inkscape:bbox-nodes="true"
-     inkscape:snap-bbox-edge-midpoints="true"
-     inkscape:snap-bbox-midpoints="true"
-     inkscape:snap-page="true"
-     inkscape:zoom="1.8116734"
-     inkscape:cx="-49.677827"
-     inkscape:cy="206.71496"
-     inkscape:window-width="2560"
-     inkscape:window-height="1376"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg936"
-     inkscape:snap-global="true" />
-  <defs
-     id="defs933">
-    <inkscape:path-effect
-       down_right_point="52.288009,77.780807"
-       down_left_point="20.068929,110.34112"
-       up_right_point="52.288009,52.530593"
-       up_left_point="20.068929,20.346231"
-       effect="perspective-envelope"
-       id="path-effect4940"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="15.803945,123.84352"
-       down_left_point="-17.47761,113.54459"
-       up_right_point="15.803945,12.392374"
-       up_left_point="-17.47761,10.76222"
-       effect="perspective-envelope"
-       id="path-effect4938"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="-21.180257,109.09997"
-       down_left_point="-48.863556,81.317737"
-       up_right_point="-21.180257,20.975556"
-       up_left_point="-48.863556,49.182794"
-       effect="perspective-envelope"
-       id="path-effect4936"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       effect="bounding_box"
-       id="path-effect4915"
-       is_visible="true"
-       lpeversion="1"
-       linkedpath=""
-       visualbounds="false" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath1979">
-      <path
-         id="path1981"
-         style="fill:#000000;stroke:#000000;stroke-width:2.64583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-         d="m -17.562228,-22.854671 c 8.855019,-8.85502 4.008778,-8.4357 26.245047,-30.671974 22.236282,-22.236279 26.885662,-23.232311 32.974431,-29.321072 6.088769,-6.088768 4.904512,-14.698424 -0.387149,-19.990073 -5.291651,-5.29166 -13.901309,-6.47592 -19.990081,-0.38715 -6.088758,6.088764 -7.084779,10.738152 -29.3210584,32.974432 -22.2362696,22.236269 -21.8169606,17.390012 -30.6719906,26.245048 -8.85504,8.855035 -4.44845,17.027382 -0.162511,21.313309 4.285951,4.285922 12.45828,8.692515 21.313312,-0.16252 z" />
-    </clipPath>
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath1979-1">
-      <path
-         id="path1981-9"
-         style="fill:#000000;stroke:#000000;stroke-width:2.64583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-         d="m -17.562228,-22.854671 c 8.855019,-8.85502 4.008778,-8.4357 26.245047,-30.671974 22.236282,-22.236279 26.885662,-23.232311 32.974431,-29.321072 6.088769,-6.088768 4.904512,-14.698424 -0.387149,-19.990073 -5.291651,-5.29166 -13.901309,-6.47592 -19.990081,-0.38715 -6.088758,6.088764 -7.084779,10.738152 -29.3210584,32.974432 -22.2362696,22.236269 -21.8169606,17.390012 -30.6719906,26.245048 -8.85504,8.855035 -4.44845,17.027382 -0.162511,21.313309 4.285951,4.285922 12.45828,8.692515 21.313312,-0.16252 z" />
-    </clipPath>
-  </defs>
-  <ellipse
-     style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;paint-order:normal"
-     id="path7070"
-     cx="46.100883"
-     cy="46.100876"
-     rx="37.684639"
-     ry="37.684635" />
-  <g
-     id="layer1-6"
-     transform="matrix(1.0290845,0,0,1.0290845,45.119552,110.44056)" />
-  <path
-     style="color:#000000;fill:#ffffff;stroke-width:1.00227;-inkscape-stroke:none"
-     d="M 73.061296,0.01833152 C 68.066071,-0.19603056 62.941066,1.4606521 58.941342,5.4603766 52.622261,11.77946 52.47912,15.115396 33.326535,34.267979 23.779232,43.815284 19.43186,47.241205 16.460111,49.343228 c -2.971749,2.102022 -5.646239,3.569253 -9.9307533,7.853771 -5.0514705,5.051467 -7.14514773,11.453025 -6.37384839,16.811613 0.77129935,5.358586 3.62874789,9.2 6.23290339,11.804147 2.6041461,2.604129 6.4455653,5.461606 11.8041483,6.232904 5.358583,0.771298 11.762104,-1.322382 16.81357,-6.373849 4.284508,-4.284508 5.749789,-6.959006 7.851813,-9.930754 C 44.95997,72.769314 48.385888,68.421943 57.933193,58.874636 77.085779,39.722052 80.421713,39.578906 86.740795,33.259831 94.740243,25.260384 93.36511,12.760038 86.404094,5.7990363 82.923593,2.3185286 78.05652,0.23269361 73.061296,0.01833152 Z M 72.804853,13.78005 c 1.25119,0.128846 2.459473,0.873838 3.601929,2.016298 2.284916,2.28491 2.975946,4.826929 0.336703,7.466171 -4.319609,4.319602 -9.107517,5.916682 -28.807603,25.616764 -9.879018,9.879022 -14.048124,15.061075 -16.619771,18.696752 -2.571647,3.635678 -2.855767,4.646944 -6.307291,8.098467 -2.684577,2.68458 -3.720599,2.534092 -4.801918,2.378449 -1.081321,-0.155642 -2.680979,-1.097311 -3.821178,-2.237503 -1.14018,-1.140175 -2.079905,-2.739858 -2.235545,-3.821177 -0.155643,-1.081319 -0.30809,-2.115383 2.376491,-4.799962 3.451526,-3.451529 4.462785,-3.737602 8.098467,-6.309248 3.635682,-2.571646 8.819689,-6.740751 18.698709,-16.61977 19.700086,-19.700086 21.295214,-24.488006 25.614806,-28.807604 1.319624,-1.319622 2.615011,-1.806484 3.866201,-1.677637 z"
-     id="path1981-3" />
-  <g
-     id="g1820"
-     clip-path="url(#clipPath1979)"
-     transform="matrix(0.87164945,0,0,0.87164945,45.269682,100.59753)">
-    <path
-       id="rect1503"
-       style="fill:#84cc16;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-       transform="rotate(-45)"
-       d="m -13.114324,-75.221169 h 39.049752 v 63.372471 h -39.049752 z"
-       sodipodi:nodetypes="ccccc" />
-    <path
-       id="rect1503-3"
-       style="fill:#65a30d;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-       transform="rotate(-45)"
-       d="m 25.935436,-75.221169 h 39.049752 v 63.372471 H 25.935436 Z" />
-    <path
-       id="rect1503-3-6"
-       style="fill:#4d7c0f;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-       transform="rotate(-45)"
-       d="m 64.985191,-75.221169 h 39.049749 v 63.372471 H 64.985191 Z" />
-  </g>
-  <g
-     aria-label="Sno"
-     transform="rotate(-45)"
-     id="text10247-6-9"
-     style="font-size:64.5726px;line-height:1.25;letter-spacing:0px;stroke-width:1.87397" />
-</svg>
diff --git a/public/favicon-small-outline.svg b/public/favicon-small-outline.svg
deleted file mode 100644
index 0dd8d8e..0000000
--- a/public/favicon-small-outline.svg
+++ /dev/null
@@ -1,152 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   width="92.201767mm"
-   height="92.201752mm"
-   viewBox="0 0 92.201767 92.201752"
-   version="1.1"
-   id="svg936"
-   sodipodi:docname="favicon-small-outline.svg"
-   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <sodipodi:namedview
-     id="namedview36"
-     pagecolor="#ffffff"
-     bordercolor="#111111"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="1"
-     inkscape:document-units="mm"
-     showgrid="false"
-     inkscape:snap-bbox="true"
-     inkscape:bbox-paths="true"
-     inkscape:bbox-nodes="true"
-     inkscape:snap-bbox-edge-midpoints="true"
-     inkscape:snap-bbox-midpoints="true"
-     inkscape:snap-page="true"
-     inkscape:zoom="1.8116734"
-     inkscape:cx="-49.677827"
-     inkscape:cy="206.71496"
-     inkscape:window-width="2560"
-     inkscape:window-height="1376"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg936"
-     inkscape:snap-global="true" />
-  <defs
-     id="defs933">
-    <inkscape:path-effect
-       down_right_point="52.288009,77.780807"
-       down_left_point="20.068929,110.34112"
-       up_right_point="52.288009,52.530593"
-       up_left_point="20.068929,20.346231"
-       effect="perspective-envelope"
-       id="path-effect4940"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="15.803945,123.84352"
-       down_left_point="-17.47761,113.54459"
-       up_right_point="15.803945,12.392374"
-       up_left_point="-17.47761,10.76222"
-       effect="perspective-envelope"
-       id="path-effect4938"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="-21.180257,109.09997"
-       down_left_point="-48.863556,81.317737"
-       up_right_point="-21.180257,20.975556"
-       up_left_point="-48.863556,49.182794"
-       effect="perspective-envelope"
-       id="path-effect4936"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       effect="bounding_box"
-       id="path-effect4915"
-       is_visible="true"
-       lpeversion="1"
-       linkedpath=""
-       visualbounds="false" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath1979">
-      <path
-         id="path1981"
-         style="fill:#000000;stroke:#000000;stroke-width:2.64583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-         d="m -17.562228,-22.854671 c 8.855019,-8.85502 4.008778,-8.4357 26.245047,-30.671974 22.236282,-22.236279 26.885662,-23.232311 32.974431,-29.321072 6.088769,-6.088768 4.904512,-14.698424 -0.387149,-19.990073 -5.291651,-5.29166 -13.901309,-6.47592 -19.990081,-0.38715 -6.088758,6.088764 -7.084779,10.738152 -29.3210584,32.974432 -22.2362696,22.236269 -21.8169606,17.390012 -30.6719906,26.245048 -8.85504,8.855035 -4.44845,17.027382 -0.162511,21.313309 4.285951,4.285922 12.45828,8.692515 21.313312,-0.16252 z" />
-    </clipPath>
-  </defs>
-  <ellipse
-     style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;paint-order:normal"
-     id="path7070"
-     cx="46.100883"
-     cy="46.100876"
-     rx="37.684639"
-     ry="37.684635" />
-  <g
-     id="layer1-6"
-     transform="matrix(1.0290845,0,0,1.0290845,45.119552,110.44056)">
-    <g
-       id="path1981-3">
-      <path
-         style="color:#000000;fill:#ff00ff;stroke-width:10.6629;-inkscape-stroke:none"
-         d="m -15.185712,-27.945904 c 7.7184726,-7.718473 3.494249,-7.352973 22.876481,-26.735209 19.382243,-19.38224 23.434872,-20.250431 28.742145,-25.557696 5.307272,-5.307272 4.275015,-12.811874 -0.337459,-17.424336 -4.612464,-4.612475 -12.117068,-5.644735 -17.424343,-0.33746 -5.307262,5.307268 -6.175443,9.359905 -25.5576841,28.742146 -19.3822319,19.382232 -19.0167419,15.157994 -26.7352239,22.876482 -7.718491,7.718486 -3.877489,14.841908 -0.141652,18.577734 3.735846,3.735821 10.859252,7.576826 18.577736,-0.141661 z"
-         id="path9363" />
-      <path
-         style="color:#000000;fill:#ffffff;stroke-width:1.01124;-inkscape-stroke:none"
-         d="m 28.104252,-107.30019 c -4.578875,-0.20576 -9.278685,1.32109 -12.984165,5.02657 -6.1293874,6.129394 -6.4526034,9.671981 -25.843903,29.06328 -9.673541,9.673541 -14.162354,13.223011 -17.242436,15.401663 -3.080083,2.17865 -5.574151,3.512166 -9.794414,7.732432 -4.805201,4.805197 -6.64145,10.604789 -5.939062,15.484616 0.702388,4.879828 3.349676,8.478963 5.796855,10.926136 2.447173,2.447155 6.046312,5.094467 10.926135,5.796855 4.879824,0.702386 10.67942,-1.133864 15.484615,-5.939062 4.2202586,-4.220258 5.5537806,-6.714334 7.7324334,-9.794414 2.178653,-3.08008 5.7281207,-7.568893 15.4016636,-17.242436 19.391302,-19.3913 22.935861,-19.714518 29.065255,-25.843903 7.410959,-7.410959 6.105792,-18.797991 -0.341689,-25.245447 -3.223732,-3.22374 -7.682411,-5.16054 -12.261288,-5.36629 z m -0.195532,10.493587 c 1.723406,0.140529 3.392445,1.057898 4.833017,2.498474 2.88115,2.881142 3.662598,6.672988 0.339713,9.995873 -4.60445,4.604444 -9.25639,6.03504 -29.0652552,25.843902 -9.9265311,9.926533 -14.0419888,15.054351 -16.5788098,18.640792 -2.53682,3.586442 -2.968346,4.811095 -6.55331,8.396059 -3.000038,3.000039 -4.706525,3.122384 -6.324202,2.88954 -1.617678,-0.232843 -3.50828,-1.416681 -4.838943,-2.747334 -1.330645,-1.330642 -2.51449,-3.221266 -2.747333,-4.838943 -0.232845,-1.617676 -0.108526,-3.322188 2.891515,-6.322226 3.584968,-3.584971 4.809613,-4.018467 8.396059,-6.555286 3.586444,-2.536819 8.712284,-6.652278 18.6388157,-16.57881 19.8088643,-19.808863 21.2414423,-24.460814 25.8458783,-29.065256 1.661444,-1.661443 3.439449,-2.297314 5.162855,-2.156785 z"
-         id="path9365" />
-    </g>
-  </g>
-  <g
-     id="layer1"
-     transform="matrix(1.0290845,0,0,1.0290845,45.119554,110.44056)"
-     style="display:inline">
-    <g
-       id="g1820"
-       clip-path="url(#clipPath1979)"
-       transform="matrix(0.87164945,0,0,0.87164945,0.12239456,-8.0246424)">
-      <path
-         id="rect1503"
-         style="fill:#84cc16;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m -13.114324,-75.221169 h 39.049752 v 63.372471 h -39.049752 z"
-         sodipodi:nodetypes="ccccc" />
-      <path
-         id="rect1503-3"
-         style="fill:#65a30d;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m 25.935436,-75.221169 h 39.049752 v 63.372471 H 25.935436 Z" />
-      <path
-         id="rect1503-3-6"
-         style="fill:#4d7c0f;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m 64.985191,-75.221169 h 39.049749 v 63.372471 H 64.985191 Z" />
-    </g>
-  </g>
-  <g
-     aria-label="Sno"
-     transform="rotate(-45)"
-     id="text10247-6-9"
-     style="font-size:64.5726px;line-height:1.25;letter-spacing:0px;stroke-width:1.87397" />
-</svg>
diff --git a/public/favicon.svg b/public/favicon.svg
index aa5e238..5f35e22 100644
--- a/public/favicon.svg
+++ b/public/favicon.svg
@@ -1,135 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   width="92.201767mm"
-   height="92.201752mm"
-   viewBox="0 0 92.201767 92.201752"
-   version="1.1"
-   id="svg936"
-   sodipodi:docname="favicon.svg"
-   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <sodipodi:namedview
-     id="namedview36"
-     pagecolor="#ffffff"
-     bordercolor="#111111"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="1"
-     inkscape:document-units="mm"
-     showgrid="false"
-     inkscape:snap-bbox="true"
-     inkscape:bbox-paths="true"
-     inkscape:bbox-nodes="true"
-     inkscape:snap-bbox-edge-midpoints="true"
-     inkscape:snap-bbox-midpoints="true"
-     inkscape:snap-page="true"
-     inkscape:zoom="1.8116734"
-     inkscape:cx="-49.677827"
-     inkscape:cy="206.71496"
-     inkscape:window-width="2560"
-     inkscape:window-height="1376"
-     inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg936"
-     inkscape:snap-global="true" />
-  <defs
-     id="defs933">
-    <inkscape:path-effect
-       down_right_point="52.288009,77.780807"
-       down_left_point="20.068929,110.34112"
-       up_right_point="52.288009,52.530593"
-       up_left_point="20.068929,20.346231"
-       effect="perspective-envelope"
-       id="path-effect4940"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="15.803945,123.84352"
-       down_left_point="-17.47761,113.54459"
-       up_right_point="15.803945,12.392374"
-       up_left_point="-17.47761,10.76222"
-       effect="perspective-envelope"
-       id="path-effect4938"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       down_right_point="-21.180257,109.09997"
-       down_left_point="-48.863556,81.317737"
-       up_right_point="-21.180257,20.975556"
-       up_left_point="-48.863556,49.182794"
-       effect="perspective-envelope"
-       id="path-effect4936"
-       is_visible="true"
-       lpeversion="1"
-       deform_type="perspective"
-       horizontal_mirror="false"
-       vertical_mirror="false"
-       overflow_perspective="false" />
-    <inkscape:path-effect
-       effect="bounding_box"
-       id="path-effect4915"
-       is_visible="true"
-       lpeversion="1"
-       linkedpath=""
-       visualbounds="false" />
-    <clipPath
-       clipPathUnits="userSpaceOnUse"
-       id="clipPath1979">
-      <path
-         id="path1981"
-         style="fill:#000000;stroke:#000000;stroke-width:2.64583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-         d="m -17.562228,-22.854671 c 8.855019,-8.85502 4.008778,-8.4357 26.245047,-30.671974 22.236282,-22.236279 26.885662,-23.232311 32.974431,-29.321072 6.088769,-6.088768 4.904512,-14.698424 -0.387149,-19.990073 -5.291651,-5.29166 -13.901309,-6.47592 -19.990081,-0.38715 -6.088758,6.088764 -7.084779,10.738152 -29.3210584,32.974432 -22.2362696,22.236269 -21.8169606,17.390012 -30.6719906,26.245048 -8.85504,8.855035 -4.44845,17.027382 -0.162511,21.313309 4.285951,4.285922 12.45828,8.692515 21.313312,-0.16252 z" />
-    </clipPath>
-  </defs>
-  <ellipse
-     style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;paint-order:normal"
-     id="path7070"
-     cx="46.100883"
-     cy="46.100876"
-     rx="37.684639"
-     ry="37.684635" />
-  <g
-     id="layer1"
-     transform="matrix(1.0290845,0,0,1.0290845,45.119554,110.44056)">
-    <g
-       id="g1820"
-       clip-path="url(#clipPath1979)">
-      <path
-         id="rect1503"
-         style="fill:#84cc16;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m -13.114324,-75.221169 h 39.049752 v 63.372471 h -39.049752 z"
-         sodipodi:nodetypes="ccccc" />
-      <path
-         id="rect1503-3"
-         style="fill:#65a30d;fill-opacity:1;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m 25.935436,-75.221169 h 39.049752 v 63.372471 H 25.935436 Z" />
-      <path
-         id="rect1503-3-6"
-         style="fill:#4d7c0f;stroke-width:4.24737;stroke-linecap:round;stroke-linejoin:round"
-         transform="rotate(-45)"
-         d="m 64.985191,-75.221169 h 39.049749 v 63.372471 H 64.985191 Z" />
-    </g>
-  </g>
-  <g
-     aria-label="Sno"
-     transform="rotate(-45)"
-     id="text10247-6-9"
-     style="font-size:64.5726px;line-height:1.25;letter-spacing:0px;stroke-width:1.87397" />
-</svg>
+<svg width="348.48" height="348.48" viewBox="0 0 92.2 92.2" xmlns="http://www.w3.org/2000/svg"><defs><clipPath clipPathUnits="userSpaceOnUse" id="b"><path d="M-17.56-22.85c8.85-8.86 4-8.44 26.24-30.68 22.24-22.23 26.89-23.23 32.98-29.32 6.09-6.09 4.9-14.7-.39-19.99-5.3-5.29-13.9-6.47-19.99-.38-6.09 6.08-7.08 10.73-29.32 32.97-22.24 22.24-21.82 17.39-30.67 26.24-8.86 8.86-4.45 17.03-.17 21.32 4.29 4.28 12.46 8.69 21.32-.16z" stroke="#000" stroke-width="2.65"/></clipPath><filter id="a" x="-.32" y="-.32" width="1.64" height="1.64" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="5" result="fbSourceGraphic"/><feGaussianBlur stdDeviation=".01" in="SourceGraphic" result="result1"/><feComposite in2="result1" operator="arithmetic" in="fbSourceGraphic" k2=".5" k3=".5" result="result2"/><feBlend in2="fbSourceGraphic" result="fbSourceGraphic"/><feColorMatrix result="fbSourceGraphicAlpha" in="fbSourceGraphic" values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"/><feGaussianBlur stdDeviation="5" result="fbSourceGraphic" in="fbSourceGraphic"/><feGaussianBlur stdDeviation=".01" in="fbSourceGraphic" result="result1"/><feComposite in2="result1" operator="arithmetic" in="fbSourceGraphic" k2=".5" k3=".5" result="result2"/><feBlend in2="fbSourceGraphic" result="result3"/></filter></defs><circle cx="46.1" cy="46.1" transform="translate(3.03 3.03) scale(.9342)" r="37.68" fill="#fbbf24" filter="url(#a)"/><circle cx="46.1" cy="46.1" r="35.21" fill="#fff"/><g clip-path="url(#b)" transform="translate(45.14 110.4) scale(1.02872)"><path d="m-62.46-43.92 27.61-27.61 44.81 44.8L-17.64.9z" fill="#84cc16"/><path d="m-34.85-71.53 27.62-27.61 44.8 44.8-27.6 27.62Z" fill="#65a30d"/><path d="m-7.23-99.14 27.6-27.6 44.81 44.8-27.6 27.6Z" fill="#4d7c0f"/></g></svg>
\ No newline at end of file
diff --git a/src/assets/images/logo.svg b/src/assets/images/logo.svg
index 6268dc1..718b2ad 100644
--- a/src/assets/images/logo.svg
+++ b/src/assets/images/logo.svg
@@ -1,15 +1 @@
-<svg width="512" height="295" xmlns="http://www.w3.org/2000/svg">
-    <g aria-label="SNO" style="line-height:1.25" font-size="10.583" letter-spacing="-2.117" word-spacing="0"
-        stroke-width=".265" font-family="Essays1743" writing-mode="vertical-lr">
-        <path
-            d="M29.84 91.32l.275-8.499q.914-1.005 1.92-1.005 1.005 0 2.832.914 2.377 1.37 3.382 4.295 1.097 2.834 2.01 5.85 1.006 3.016 3.748 5.118 2.741 2.01 7.128 2.01 5.027 0 6.855-1.005 1.919-1.005 2.559-2.285 1.645-2.742 1.645-6.397 0-3.747-3.199-8.409-1.645-2.376-3.93-3.564-2.285-1.188-5.575-2.102-3.29-1.005-4.935-1.92-1.645-.913-3.839-1.644-2.102-.731-3.564-1.554-1.462-.822-2.467-2.467-3.565-5.575-3.565-10.602 0-5.118 1.554-9.23 1.554-4.205 3.381-5.941 1.92-1.828 5.027-3.016 3.199-1.28 5.666-1.28 2.56 0 7.038 1.006 4.57.914 6.214 1.188 1.645.183 2.468.365 2.376.549 3.564 2.56 0 6.031-.274 8.407-.183 2.285-1.28 7.952-.913.182-1.187.182-3.29 0-4.296-6.489-.457-2.558-1.645-5.3-1.097-2.742-3.016-3.93-3.381-2.102-5.575-2.102-2.193 0-3.747 1.28-4.478 3.655-4.478 9.687 0 4.204 2.102 8.225.914 1.828 2.376 2.742 1.554.823 3.93 1.462 2.467.64 4.021 1.463 1.645.73 4.57 1.462 2.924.731 5.026 1.736 2.102 1.006 3.473 3.108 3.382 5.026 3.382 10.144t-1.92 10.145q-1.827 4.935-4.02 7.129-2.103 2.193-5.667 3.747-3.473 1.462-6.854 1.462-3.382 0-9.597-1.462l-1.553-.457q-.64-.183-1.188-.275-.549-.182-1.189-.457-.548-.365-.914-.457-.365-.182-1.188-.73-.73-.549-1.188-.732-.365-.274-1.645-1.097L30.39 99.09q-.548-5.21-.548-7.768zM24.22 119.945l-4.387.274q-3.198 0-3.838-1.919-.183-.548-.183-.823 0-2.102 3.838-3.838 4.387-1.097 7.495-1.097 3.198 0 9.87 1.828l21.02 25.225 6.215 8.042 7.586 10.236 1.645-40.03q-1.645 0-3.747.548-2.102.549-3.108.549-.914 0-1.736-.823-.823-.822-.823-1.553l.823-3.2q0-.456-.274-1.005 5.666-.365 8.773-.365 3.108 0 11.79.548 1.097 0 1.097 1.828 0 1.737-1.92 3.656-.913.822-1.827.822l-3.656-.274q-.457 9.048-.457 17.09l.457 21.478q0 7.037-.457 14.714-.091.091-.64 1.005-.457.914-.822 1.371-1.097 1.371-2.468 1.554h-.366q-2.01 0-4.295-3.107l-37.197-45.24q.823 9.87.823 14.989 0 5.026-.549 12.43-.548 7.402-.548 12.885v2.56q.366 1.096 2.01 1.096h.915q2.102 0 2.102 2.102 0 .64-.549 2.01-.457 1.372-.548 2.103-3.199.091-7.951.457-4.753.274-8.043.274h-2.742q-.091-.731-.64-2.102-.548-1.37-.548-2.01 0-.64.64-1.646.731-1.005 3.199-1.005l4.57.366q1.096 0 1.645-.549-.366-9.596-.366-16.816l.366-33.907q-.457-.73-2.194-.73zM54.745 187.685q8.043 0 13.983 2.925 5.94 2.833 10.693 9.596 4.753 6.763 4.753 15.446 0 4.843-1.097 10.235-1.005 5.393-2.193 8.134-1.188 2.65-2.194 4.205-1.005 1.553-3.107 4.386l-2.925 4.296q-6.306 9.505-18.918 9.505-8.134 0-14.075-3.016-10.875-5.575-14.897-10.602-4.02-4.752-5.026-10.967-.914-6.215-.914-10.327 0-10.693 6.123-18.736 6.124-8.134 12.978-11.607 6.946-3.473 16.45-3.473zm-20.563 33.541l-.274 6.032q0 5.85 2.285 10.054 2.376 4.204 4.843 6.306 2.468 2.01 6.215 3.29 3.839 1.28 7.037 1.28 3.199 0 7.038-2.103 3.93-2.193 5.94-5.21 2.102-3.106 4.661-9.504 2.56-6.489 2.56-12.43 0-2.833-.732-7.037-.64-4.204-2.102-7.311-1.462-3.199-4.752-6.032-5.667-4.935-11.15-4.935-8.226 0-13.8 6.58-2.56 2.925-4.113 5.575-1.554 2.56-2.377 5.21-.73 2.65-.914 4.478-.182 1.736-.365 5.757z"
-            style="-inkscape-font-specification:Essays1743;text-orientation:upright" />
-    </g>
-    <g aria-label="Board" style="line-height:1.25;-inkscape-font-specification:Essays1743" font-size="20.496"
-        font-family="Essays1743" stroke-width=".321">
-        <path
-            d="M134.463 207.027l4.78-72.216q-2.302-2.3-3.718-2.3-1.239 0-4.779 1.238-3.54 1.24-6.726 1.24-3.009 0-6.018-.709-1.77-1.947-1.77-5.487t3.363-6.548q12.213-3.186 20.532-3.186 8.496 0 16.815 1.062 8.496 1.062 15.399 1.77 6.903.53 10.266 1.062 3.54.53 8.496 1.77 5.133 1.238 9.204 3.716 4.247 2.301 8.318 5.841t5.664 7.788q2.124 6.018 2.124 14.16 0 10.266-7.788 18.054-1.062 1.062-1.947 2.124t-3.009 1.947q-1.946.708-3.185 1.239-1.24.53-5.487 1.947-4.248 1.416-7.434 2.655 4.779 3.363 9.735 5.133 5.133 1.593 8.318 3.186 3.363 1.416 6.018 5.31 4.956 6.726 4.956 15.93 0 1.946-.53 7.964-.532 5.841-1.24 9.381-.53 3.363-2.832 7.788-2.3 4.248-6.372 7.257-9.203 6.903-21.947 6.903l-21.24-1.062q-3.363 0-5.133.177l-22.302 1.593q-8.142 0-20-1.593-2.301-2.832-2.301-6.195 0-6.018 5.31-10.443 1.592-.708 3.716-.708 2.301 0 6.195 1.416 3.894 1.24 5.841 1.24 2.124 0 3.894-1.948v-3.186q0-8.142-1.593-14.867-1.593-6.903-1.593-10.443zm28.32-72.747q-1.416 16.107-1.416 22.833 0 6.549 1.416 18.939 2.832 2.3 5.133 2.3 3.894 0 8.142-2.3 4.248-2.301 6.018-3.186 7.788-3.54 9.912-8.496 2.478-4.956 2.478-9.912t-2.301-9.38q-2.124-4.426-5.133-6.55-3.01-2.3-7.965-4.07-4.78-1.77-8.142-1.77-3.186 0-8.142 1.592zm8.496 104.43q10.797 0 16.46-7.789 5.842-7.965 5.842-16.46 0-8.673-4.071-14.514-4.071-6.018-11.505-6.903l-6.195-1.062q-4.956-.708-7.08-.708-6.195 0-6.372 4.779-1.593 21.593-1.593 25.664v4.78q.177 5.31 4.425 8.85 4.425 3.362 10.089 3.362zM266.858 251.453l-5.664-.177q-2.301.177-5.841.177-10.089 0-18.585-7.61-9.204-9.028-11.328-18.232-1.77-6.903-1.77-13.098 0-6.371 2.301-14.336 2.301-8.142 5.133-13.275 2.832-5.133 8.673-9.558 9.912-7.788 22.833-7.788h2.478q4.602.177 6.372.354 5.31.885 11.505 7.08 6.195 6.195 9.026 12.39 3.54 7.61 3.54 24.78 0 7.256-2.832 16.814-2.831 9.381-7.61 14.337-4.602 4.779-11.86 7.257-3.185.885-6.371.885zm-6.372-11.682l5.31.531q5.31 0 9.027-4.425 1.593-1.77 4.248-9.027 2.655-7.257 2.655-13.275 0-17.7-7.611-27.611-4.248-5.133-7.788-5.841-3.363-.708-6.903-.708-3.54 0-7.965 2.832-4.248 2.832-7.611 11.682-3.186 8.85-3.186 14.69 0 18.94 8.673 27.081 3.009 2.832 11.15 4.071zM361.02 251.63l-3.54.177q-3.185.354-5.31.354-1.946 0-3.893-.885-1.947-1.062-2.655-1.77-.708-.708-1.416-1.77t-1.416-1.593q-.531-.708-1.062-1.77-1.239-2.124-2.655-2.124h-.708q-2.301 0-5.31 2.655-2.832 2.655-3.894 3.363-1.062.531-2.478 1.416-4.425 3.363-10.62 3.363-6.195 0-10.266-2.655-4.07-2.655-5.487-8.319-1.416-5.84-1.416-9.735 0-10.443 10.09-19.116 6.194-4.955 16.106-9.026 1.77-.708 5.841-.885 4.248-.354 6.018-1.947 1.947-1.593 2.655-4.78.708-3.185.708-5.31 0-2.123-.354-4.07t-.531-3.363q-.177-1.416-.354-2.124-.177-.708-.531-1.77-.708-1.77-2.301-2.832-1.593-1.24-3.009-1.24-1.239 0-5.664 1.063-4.248.885-6.372 3.717-2.124 2.655-2.124 8.142v3.363q-.177 3.186-3.009 5.31-2.655 1.947-5.31 1.947-9.38 0-9.38-9.027 0-1.593.176-2.301 1.77-10.266 6.903-14.691 5.31-4.425 10.09-5.664 4.778-1.239 12.743-1.593l3.717-.177q5.664 0 10.266 3.186 6.549 4.425 7.965 12.036 1.416 7.61 1.416 19.647v4.602l.177 7.787.177 3.894-.177 7.257q0 3.363.53 7.965v2.301q0 1.947 2.125 1.947 2.124 0 4.956-3.717 2.832-3.894 4.779-3.894.177 0 1.416.531 1.416.531 1.416 2.655l-.531 4.248-.177 3.54q0 1.947-.354 2.832-.177.708-.354 1.593t-.531 1.593q-.177.531-.708 1.24-2.301 3.716-4.071 4.07-1.77.354-2.301.354zm-18.938-30.975l-.177-1.77q-.354-4.956-4.071-7.08-1.416-.707-5.133.354-3.54.885-8.496 3.894-8.673 5.664-8.673 10.62 0 9.912 5.664 12.39.708.354 1.416.354t2.478-.885q1.77-1.062 2.478-1.239l2.478-1.062q4.956-1.947 7.257-4.602 4.779-5.487 4.779-10.974zM404.562 222.78l-.177 9.911q.531 1.416 3.186 2.832t2.655 5.487q0 3.894-1.77 5.841-3.894 1.062-13.806 2.655-9.912 1.593-14.514 2.655-1.77-.708-2.832-3.54-1.062-2.832-.177-4.602 1.062-1.947 4.071-3.363 3.01-1.593 4.071-3.54.354-5.133.354-13.275l-.177-17.876q0-7.257.177-11.86-1.062-2.3-5.664-4.601-4.425-2.478-4.425-5.487.885-1.24 2.478-4.071 1.77-3.01 2.301-3.54l1.593-2.478q1.24-1.593 2.124-2.124l2.301-1.416q3.54-2.124 6.55-2.124 3.008 0 5.84 1.593 2.478 2.3 3.01 2.832.53.354 1.592.708 1.24.177 3.363 1.239 1.77-1.062 5.133-4.248 3.54-3.186 7.965-3.186h.708q8.85.708 12.036 13.098.53 1.947.53 4.248 0 2.3-3.008 6.726-3.01 4.248-6.726 4.248h-.885q-2.301-.531-3.717-4.602-1.239-4.071-3.363-4.602-5.84 3.894-10.797 7.788-.177 8.496-.177 16.991zM492.353 169.503q-.177-4.956-.177-21.417 0-16.638.708-18.762 0-.53-.708-.53-.53 0-3.54 1.061-3.009 1.062-4.602 1.062-1.947 0-1.947-3.186t3.01-7.61q3.008-4.425 6.017-6.372.885-.708 3.717-.708t6.372 1.77q3.717 1.77 3.717 3.894 0 .354-.354 1.062 1.593 37.17 1.593 106.021v7.257q0 1.24 2.832 4.248 3.009 2.832 3.009 3.894v.885q0 7.08-3.54 8.673-.354.177-1.416.177l-5.84-.53h-.709q-2.655 0-6.195-4.249-3.54-4.425-4.956-4.425-1.239 0-3.54 1.77-2.3 1.593-10.089 4.602-7.787 3.01-11.858 3.01-4.071 0-5.841-.355-3.54-.53-7.434-6.018l-2.832-4.07q-9.558-11.506-9.558-25.489v-2.124q.53-15.752 4.779-24.425 4.248-8.673 7.788-12.744 3.54-4.248 9.38-8.142 6.019-4.071 12.036-4.248h.708q3.363 0 12.036 3.009 1.24.354 3.363 2.478 2.301 2.124 3.01 2.124.884 0 1.061-1.593zm-13.452 7.434q-.708-.177-2.124-.177-1.239 0-5.84 2.3-4.425 2.125-8.673 7.258-4.071 5.133-6.372 9.38-2.301 4.249-3.01 9.382-.53 5.132-.53 6.548 0 6.372 3.186 11.505 3.186 4.956 6.549 7.434 3.54 2.301 8.495 4.248 4.956 1.77 6.726 1.77 1.947 0 3.186-.354 1.24-.354 1.77-.708.708-.354 1.24-.708.707-.53 1.061-.708.531-.354 1.062-.885.531-.708.708-.885.354-.354.885-1.239.531-.885.708-1.062.177-.177.708-1.239.708-1.062.885-1.239 6.372-10.266 6.372-24.248 0-9.204-4.779-16.992t-12.213-9.381z" />
-    </g>
-    <path
-        d="M43.711 294.848c-2.301-.19-4.738-.586-5.415-.878-4.272-1.843-6.758-2.692-9.22-3.147-7.742-1.43-17.456-9.892-19.387-16.886-.252-.914-1.331-3.18-2.398-5.034-2.015-3.504-2.6-5.446-3.39-11.248-.259-1.895-.841-4.886-1.296-6.646-.54-2.097-.719-4.016-.516-5.566.17-1.301.313-8.791.317-16.645.006-12.46.132-14.823.984-18.557.538-2.353 1.188-5.718 1.446-7.478.257-1.76.754-5.083 1.103-7.385.4-2.635.484-4.914.224-6.154-1.083-5.18-1.004-7.958.345-12.14.72-2.231 1.502-6.097 1.738-8.59.236-2.494.669-4.982.962-5.53.294-.55.534-3.5.534-6.558 0-5.204-.619-9.724-2.213-16.166-.368-1.49-.812-4.148-.985-5.908-.174-1.76-.658-4.75-1.077-6.646-.553-2.506-.802-7.008-.91-16.493-.08-7.175-.396-14.375-.7-16-.304-1.624-.653-3.95-.776-5.169-.123-1.218-.377-2.88-.563-3.692-.187-.812-.391-2.363-.455-3.446-.064-1.083-.374-3.853-.69-6.154C.82 72.685.368 65.4.228 58.27c-.037-1.895.217-7.544.565-12.554.662-9.508 2.121-16.507 4-19.176.485-.69 1.037-1.753 1.226-2.362C6.818 21.6 17.657 9.732 20.3 8.54a36.794 36.794 0 002.734-1.39c4.219-2.444 9.406-4.511 12.062-4.806 1.624-.18 5.169-.81 7.877-1.398C47.133.04 49.079-.098 55.527.052c7.094.164 7.82.27 10.338 1.5 1.49.728 3.345 1.326 4.125 1.329 1.953.006 6.496 2.654 9.217 5.373 1.246 1.244 3.78 3.148 5.634 4.23 6.031 3.52 11.598 10.034 12.34 14.438.593 3.522 1.75 10.467 2.147 12.887.244 1.489.583 4.369.754 6.4.17 2.03.623 4.818 1.005 6.194.387 1.39.673 4.454.645 6.892-.027 2.415.023 4.612.111 4.883.089.27-.103 1.932-.426 3.692-.323 1.76-.83 6.298-1.127 10.085-.297 3.786-.614 7.004-.705 7.152-.092.147.05 2.06.315 4.251.43 3.555.37 4.294-.558 6.879-2.455 6.83-2.9 9.295-2.854 15.803.038 5.215-.135 6.83-1.012 9.433-1.176 3.493-1.283 5.135-.577 8.854.324 1.709.312 2.969-.037 3.883-.688 1.803-.839 4.4-1.161 19.994-.16 7.676-.079 13.977.19 15.015.256.985.587 4.559.737 7.944.274 6.2.695 9.508 1.786 14.03.327 1.354.658 6.255.736 10.89.13 7.732.246 8.693 1.413 11.609 1.072 2.68 1.276 3.985 1.3 8.31.017 2.821.21 6.223.429 7.558.22 1.336.22 4.019.002 5.962-.218 1.944-.528 5.608-.689 8.144-.16 2.535-.741 6.388-1.29 8.561-.548 2.173-1.089 5.6-1.201 7.615-.243 4.332-1.985 12.349-3.223 14.83-1.078 2.16-4.839 5.433-11.985 10.426-6.257 4.373-8.465 5.544-15.302 8.115-4.78 1.798-5.122 1.854-11.815 1.917-3.791.035-8.776-.091-11.077-.282zm13.652-5.65c1.02-.386 3.628-.801 5.794-.923 4.783-.267 8.36-1.77 13.047-5.484 1.76-1.394 3.975-3.058 4.923-3.696 3.323-2.241 6.008-5.224 7.698-8.554 2.06-4.057 3.607-9.917 3.617-13.694.004-1.527.553-4.876 1.22-7.44 1.169-4.5 1.205-5.133 1.036-17.9-.159-12.038-.274-13.549-1.27-16.683-.603-1.895-1.16-4.886-1.236-6.646-.534-12.302-.884-16.768-1.465-18.708-.867-2.893-1.35-7.995-1.294-13.671.029-2.996-.226-5.362-.743-6.883-.529-1.559-.703-3.245-.531-5.141.14-1.553.05-3.74-.203-4.863-.29-1.293-.278-3.056.034-4.818.497-2.802 1.024-12.575 1.266-23.454.09-4.096.459-7.175 1.198-10.04.9-3.484 1.018-4.91.754-9.107-.24-3.795-.118-5.853.514-8.669 1.872-8.34 2.058-10.145 1.335-12.91-.674-2.575-.604-4.244.377-8.998.28-1.353.637-3.458.795-4.676.158-1.219.839-3.632 1.513-5.363 1.574-4.04 1.468-7.336-.928-28.853-.666-5.982-2.316-10.837-5.015-14.758-1.115-1.618-2.691-4.152-3.503-5.632-1.037-1.888-2.43-3.401-4.677-5.08a316.735 316.735 0 01-5.416-4.142c-2.823-2.23-6.105-3.88-8.615-4.33-1.083-.195-2.634-.643-3.446-.995-3.533-1.53-4.872-1.718-12.8-1.795-7.388-.072-8.716.04-11.323.96-1.625.572-3.307 1.046-3.738 1.052-.43.007-2.572.899-4.759 1.982-2.186 1.083-4.22 1.969-4.518 1.969-1.16 0-6.685 2.527-7.813 3.574-.653.606-1.929 2.254-2.834 3.661s-2.168 2.9-2.807 3.319c-1.487.974-2.934 3.624-4.184 7.661-.545 1.76-1.458 4.698-2.029 6.53-.969 3.105-1.096 7.651-.283 10.106.116.35-.117 3.739-.517 7.532-.477 4.522-.578 7.565-.291 8.838.24 1.068.47 4.806.513 8.308.042 3.501.287 7.101.545 8 .258.898.469 2.828.469 4.287 0 1.46.205 3.455.456 4.434 1.144 4.466 1.747 10.829 1.777 18.765.026 7.115.195 9.087.965 11.323.571 1.659.96 4.235 1.004 6.647.039 2.166.267 4.713.507 5.661.24.948.452 3.385.47 5.415.036 3.853 1.499 20.922 1.993 23.247.309 1.457-1.464 13.842-2.381 16.63-.338 1.027-.595 5.605-.636 11.323-.08 11.164-.73 17.875-2.262 23.385-.602 2.166-1.128 4.935-1.167 6.154-.04 1.218-.25 3.434-.465 4.923-.216 1.49-.352 5.81-.301 9.6.05 3.79.067 9.913.036 13.604-.092 11.125 1.79 18.94 5.946 24.676.793 1.095 1.442 2.349 1.442 2.786 0 1.29 3.835 7.503 6.004 9.727 2.83 2.902 7.054 4.675 12.211 5.126 2.302.202 5.182.741 6.4 1.2 6.076 2.285 13.783 2.943 17.59 1.501z" />
-</svg>
\ No newline at end of file
+<svg width="443.635" height="324.769" viewBox="0 0 117.378 85.929" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><radialGradient xlink:href="#a" id="d" cx="52.857" cy="-111.757" fx="52.857" fy="-111.757" r="2.204" gradientTransform="matrix(1 0 0 .6874 0 -34.934)" gradientUnits="userSpaceOnUse" spreadMethod="pad"/><radialGradient xlink:href="#b" id="g" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.47963 0 0 1.50836 -55.407 -3.594)" cx="106.633" cy="87.421" fx="106.633" fy="87.421" r="1.46"/><linearGradient id="a"><stop style="stop-color:#f59e0b;stop-opacity:1" offset="0"/><stop style="stop-color:#f59e0b;stop-opacity:1" offset=".725"/><stop style="stop-color:#f59e0b;stop-opacity:.05882353" offset="1"/></linearGradient><linearGradient id="b"><stop style="stop-color:#fbbf24;stop-opacity:1" offset="0"/><stop style="stop-color:#fbbf24;stop-opacity:1" offset=".29"/><stop style="stop-color:#fbbf24;stop-opacity:0" offset="1"/></linearGradient><clipPath clipPathUnits="userSpaceOnUse" id="e"><path style="font-size:26.8628px;line-height:1.25;font-family:Moreganic;-inkscape-font-specification:Moreganic;fill:#000;stroke-width:.271687" class="powerclip" d="M50.225 74.7H155.52v34.507H50.225Zm94.793 1.099A9.463 9.463 0 0 0 143.2 76c-.814.117-1.696.55-1.815 1.455-.36 1.595.138 3.229.206 4.834a815.79 815.79 0 0 0 1.904 13.765c.369 1.528 2.261 2.208 3.639 1.625 1.627-.523 3.099-1.458 4.49-2.432 1.562-1.152 2.467-2.994 2.673-4.9.42-2.882.142-5.914-.98-8.612-1.112-2.304-2.955-4.355-5.314-5.412-.947-.376-1.967-.538-2.986-.525zm-9.489 1.851a4.745 4.745 0 0 0-1.302.187c-1.37.478-2.892.617-4.138 1.388-.85.666-1.155 1.79-.909 2.822l.21 2.206c1.213-.382 2.551-.277 3.668-.962.141-.37-.27-1.026.505-.874 1.103-.352 2.605-.547 3.408.536.636.773.44 1.96-.35 2.551-.739.512-.502 1.52-.73 2.291-.169 1.07-.334 2.14-.506 3.208.62-.308.839.168.975.69.726 2.1 1.685 4.03 2.338 6.132.255.68 1.053 1.097 1.717.692.794-.432 1.966-.407 2.436-1.28.284-.925-.511-1.746-.756-2.598-.8-1.892-1.683-3.758-2.432-5.665.441-1.03 1.434-1.783 1.732-2.909.565-1.987.308-4.309-.948-5.988-1.257-1.365-3.046-2.434-4.918-2.427zm-11.864 2.422c-.053 0-.107.005-.162.012-.97.281-1.973.415-2.955.62-1.231.452-1.097 1.977-1.367 3.021-.748 3.967-1.155 7.99-1.603 11.998-.045 1.37-.27 2.757-.128 4.12.317 1.087 1.677.944 2.57.914.773.07 1.326-.68 1.182-1.412.178-1.298.169-2.632.474-3.907.34-.384 1.052-.23 1.553-.402.926-.252 1.924-.319 2.842-.473l3.25-2.536c-1.423-3.495-2.49-7.128-4.07-10.558-.242-.706-.793-1.408-1.586-1.397zm21.778.138c.427 4.177 1.13 8.328 1.597 12.503.562-.266 1.103-.547 1.57-.967 1.016-.732 1.7-1.921 1.571-3.2.144-1.79-.007-3.681-1.028-5.218-.691-1.498-1.995-2.73-3.626-3.112zm-34.497 2.534c-.321.005-.642.04-.957.11-.995-.093-.395.65-.183 1.19l1.335 3.047c1.089.21 1.142 1.518 1.437 2.367.69 2.461.177 5.1-.787 7.411-.362.637-1.3.724-1.719.092-.897-1.098-1.483-2.488-1.444-3.926.187-.73-.488-.632-.999-.696-1.026-.264-2.112.115-2.78.928-.465.36-.085 1.02-.079 1.523.076.462.186.924.329 1.379a3.205 3.205 0 0 0-.182-.351c-.547-1.1-1.673-1.698-2.827-1.962-.208-.264-.85-.43-1.368-.612-.823-.283-1.645-.573-2.469-.853-.495.373-1.012.73-1.595.952-.223-1.331-.424-2.692-.638-4.008.493-.125.63-.797.902-1.195.396-.747.314-1.615.318-2.43-.716.032-1.43.073-2.13.248-1.02.253-2.14.602-2.842 1.42-.458.835.043 1.813.046 2.702.09.769.185 1.536.284 2.303a5.802 5.802 0 0 0-.123-.289c-.316-1.793-1.562-3.406-3.316-3.981-.623-.26-1.299-.322-1.96-.422l-.042.565-.256 3.342c.688.054 1.189.561 1.302 1.232.682 1.746.65 3.691.025 5.447-.328.857-.52 2.148-1.655 2.234-1.093-.16-1.55-1.384-1.968-2.27-.21-.663-.14-1.373-.212-2.058-1.23.039-2.721-.345-3.66.707-.614.422-.177 1.22-.136 1.828.568 2.937 3.116 5.663 6.24 5.657 2.064.136 3.902-1.316 4.73-3.13 1.05-1.847 1.45-3.967 1.417-6.071.246 1.668.518 3.332.822 4.991.212.959.149 2.099.84 2.865.85.684 2.025.18 3.006.198 2.15-.196 4.38-.746 6.085-2.13 1.132-1.096 1.93-2.848 1.539-4.412.735 1.968 2.097 3.73 4.029 4.594 1.76.792 4.042.52 5.327-1.007 1.297-1.515 1.924-3.499 2.333-5.42.324-2.034.273-4.129-.04-6.157-.505-1.224-.631-2.619-1.476-3.694-1.01-1.405-2.767-2.284-4.503-2.258zm11.807 3.93c-.242 1.426-.462 2.856-.683 4.285.727-.1 1.429-.336 2.123-.57l-.881-2.275-.559-1.44zm-52.65 4.893a.857.857 0 0 0-.31.056c-.824.365-1.737.52-2.568.82-.796.723-.336 1.94-.312 2.87l.046.364c-.472-1.457-1.728-2.656-3.285-2.824-.918-.126-1.858-.057-2.76.143-2.019.408-3.988 2.073-4.087 4.232.111 1.965 1.852 3.404 3.554 4.106.76.32 1.62.712 2.05 1.448.369.57-.497 1.382-1.037 1.425-.192.32.26.58.036.987-.218.632-.162 1.305-.149 1.961 2.045-.017 4.369-.803 5.256-2.804.624-1.225.275-2.709-.628-3.696-1.18-1.534-3.317-1.771-4.633-3.118-.503-.342-.459-1.191.181-1.336.67-.21 1.628.018 1.768.803.568.931 1.708.348 2.503.12.503-.107 1.182-.4 1.301-.906.338 2.603.72 5.2 1.062 7.803.145.661.18 1.355.423 1.985.79.57 1.83.18 2.711.074 1.023-.215.781-1.443.666-2.196-.168-1.36-.353-2.717-.521-4.076 1.244 1.603 2.45 3.276 3.968 4.63 1.243.644 2.722.201 4.001-.116.735-.079 1.467-.613 1.38-1.424-.08-1.836-.445-3.65-.464-5.493-.004-.773-.904-.838-1.451-.594-.966.289-1.976.348-2.978.331.041.56.168 1.279.158 1.74-1.948-2.137-3.362-4.6-5.068-6.915-.21-.235-.505-.398-.813-.4zm29.097 5.53-.273.005c-.527.05-1.038.2-1.564.256.07.7.167 1.398.292 2.09.462-.012.95-.141 1.39-.305.711-.31 1.857-.521 1.973-1.428-.39-.553-1.16-.62-1.818-.617z"/></clipPath><clipPath clipPathUnits="userSpaceOnUse" id="f"><path style="font-size:26.8628px;line-height:1.25;font-family:Moreganic;-inkscape-font-specification:Moreganic;display:inline;stroke-width:.271687" class="powerclip" d="M85.473 84.662h46.146V108.2H85.473Zm38.208-4.591c-.06 0-.119.004-.178.013-.97.281-1.973.415-2.955.62-1.231.452-1.097 1.977-1.367 3.021-.748 3.967-1.155 7.99-1.603 11.997-.045 1.37-.27 2.758-.128 4.121.317 1.087 1.677.944 2.57.914.773.07 1.326-.68 1.182-1.412.178-1.298.169-2.633.474-3.907.34-.384 1.052-.23 1.553-.402.845-.194 1.704-.357 2.57-.404.63 1.501 1.192 3.05 1.94 4.49.46.743 1.443.276 2.148.325.713-.131 1.938-.03 1.974-1.028-.232-.967-.83-1.83-1.117-2.794-1.206-3.256-2.616-6.436-3.696-9.74-.709-1.776-1.304-3.627-2.27-5.28-.274-.303-.681-.531-1.097-.534zm-12.735 2.673c-.321.005-.642.04-.957.11-1.354.325-2.434 1.263-3.619 1.94l2.274 3.834c.664-.836 1.688-1.766 2.84-1.42.831.472.834 1.589 1.132 2.397.636 2.42.117 4.998-.825 7.264-.362.637-1.3.724-1.719.092-.764-.952-1.327-2.115-1.438-3.345-1.36-.174-2.72-.345-4.08-.517.068 1.064.25 2.137.578 3.156a3.82 3.82 0 0 0-2.753-2.312c-.812-.034-.076-.438.145-.752 1.16-1.25 1.515-3.248.557-4.717-1.247-2.094-3.841-3.023-6.192-2.746l-.207.012c-1.532.113-3.195.469-4.348 1.543-.582.828-.017 1.88-.022 2.795.396 3.348.868 6.684 1.483 9.998.197.963.167 2.063.774 2.879.796.78 2.01.271 2.984.282 2.153-.186 4.38-.72 6.108-2.076 1.204-1.124 2.046-2.924 1.583-4.575.405 1.129 1 2.182 1.832 3.07 1.549 1.84 4.464 2.764 6.606 1.42 1.84-1.212 2.549-3.454 3.125-5.466.518-2.254.45-4.613.127-6.888-.51-1.232-.636-2.637-1.485-3.72-1.01-1.405-2.767-2.284-4.503-2.258zm11.807 3.93c-.242 1.426-.462 2.856-.683 4.285.727-.1 1.429-.336 2.123-.57l-.881-2.275-.558-1.44zm-26.413 2.66v-.001c-.11.002-.219.007-.328.01.213 1.164.364 2.338.566 3.504-.106.88.667.18 1.053-.008.646-.535 1.733-1.088 1.602-2.072-.266-1.292-1.813-1.424-2.893-1.433zm2.98 7.75c-.662-.008-1.3.203-1.956.272.07.553.103 1.111.222 1.657-.09.602.42.439.824.323.915-.331 2.13-.513 2.614-1.463-.05-.628-.924-.685-1.42-.772a2.882 2.882 0 0 0-.285-.017z"/></clipPath><filter style="color-interpolation-filters:sRGB" id="c" x="-.061" y="-.087" width="1.122" height="1.174"><feGaussianBlur stdDeviation="5" result="fbSourceGraphic"/><feGaussianBlur stdDeviation=".01" in="SourceGraphic" result="result1"/><feComposite in2="result1" operator="arithmetic" in="fbSourceGraphic" k2=".5" k3=".5" result="result2"/><feBlend in2="fbSourceGraphic" result="fbSourceGraphic"/><feColorMatrix result="fbSourceGraphicAlpha" in="fbSourceGraphic" values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"/><feGaussianBlur stdDeviation="5" result="fbSourceGraphic" in="fbSourceGraphic"/><feGaussianBlur stdDeviation=".01" in="fbSourceGraphic" result="result1"/><feComposite in2="result1" operator="arithmetic" in="fbSourceGraphic" k2=".5" k3=".5" result="result2"/><feBlend in2="fbSourceGraphic" result="result3"/></filter></defs><g style="display:inline"><path style="color:#000;fill:#fbbf24;fill-opacity:1;stroke-width:3.77953;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;filter:url(#c)" d="M384.352 140.064c-10.04-.009-16.21 3.262-19.975 7.344-3.766 4.083-5.204 8.847-6.37 11.348-.609 1.308-.647 3.094-.849 4.738-.225-.147-.472-.323-.693-.465a67.442 67.442 0 0 0-2.85-1.728c-.913-.523-1.8-1-2.658-1.424a39.628 39.628 0 0 0-2.51-1.137 34.805 34.805 0 0 0-2.435-.9 34.966 34.966 0 0 0-2.4-.688c-.799-.2-1.594-.372-2.407-.523a53.613 53.613 0 0 0-2.473-.399h-.008c-.547-.075-1.373-.148-2.523-.28a77.382 77.382 0 0 1-4.148-.583 57.606 57.606 0 0 1-2.415-.465 45.526 45.526 0 0 1-2.48-.605c-.15-.041-.326-.101-.48-.149-.082-.539-.404-1.393-1.05-1.92-1.039-.848-2.343-.792-3.911-.84-.03-.028-.026-.029-.059-.06a8.415 8.415 0 0 0-1.95-1.357 11.138 11.138 0 0 0-2.103-.805 19.837 19.837 0 0 0-2.133-.451c-1.43-.232-2.875-.37-4.326-.62a24.07 24.07 0 0 1-2.185-.472 17.579 17.579 0 0 1-1.86-.635c-.073-.075-.128-.17-.222-.265a18.757 18.757 0 0 0-2.967-2.398 17.715 17.715 0 0 0-2.258-1.241 15.361 15.361 0 0 0-2.724-.953 13.641 13.641 0 0 0-3.124-.39 12.764 12.764 0 0 0-3.426.465 13.27 13.27 0 0 0-1.763.634c-.061.027-.058.033-.111.058-.808-.25-7.166-2.274-13.346-2.294-1.84-.006-3.62.16-5.227.738-1.605.578-3.12 1.686-3.816 3.41-.64 1.584-.28 3.262.39 4.531.672 1.27 1.623 2.32 2.563 3.309.94.988 1.885 1.911 2.555 2.709.563.67.817 1.182.914 1.467-.04.054-.098.147-.303.326-.481.42-1.31.957-2.154 1.476-.844.52-1.689.995-2.43 1.647-.37.326-.786.674-1.04 1.46-.256.788.154 2.044.745 2.555 2.632 2.276 6.143 2.917 8.977 3.145 1.735.14 2.21.04 3.137-.016.014.193.052.813.052.813a1.89 1.89 0 0 0 .213.717s.289.466.613.775c.327.31.797.668 1.47 1.041.67.373 1.54.765 2.7 1.158.582.197 1.24.391 1.973.584.256.068.535.122.805.184.53 1.306 1.512 2.399 2.996 2.496a1.89 1.89 0 0 0 .133 0c1.1-.006 2.148-.142 3.189-.268.13.143.143.19.354.385.256.238.572.494.96.746.387.251.838.5 1.387.76a1.89 1.89 0 0 0 .008 0 18.22 18.22 0 0 0 1.535.65c.495.18.962.32 1.403.436.889.234 1.692.366 2.406.457.713.091 1.332.142 1.89.229a8.27 8.27 0 0 1 1.594.39c.235.085.421.177.576.268.153.089.27.177.377.271.217.19.388.407.59.71.202.3.426.694.776 1.152.174.228.38.469.634.7.258.237.562.453.9.635a1.89 1.89 0 0 0 0 .008c.352.189.706.315 1.042.407.344.094.68.15 1.004.191.23.029.44.022.664.037.04.107-.01.175.045.287.41.848 1.676 1.633 2.738 1.573 1.125-.065 2.209-.01 3.293.052.275.231.535.446.863.739 1.593 1.423 3.635 3.328 5.862 5.365a253.838 253.838 0 0 0 3.455 3.115 135.723 135.723 0 0 0 3.572 3.049 75.388 75.388 0 0 0 3.537 2.754c.322.234.55.368.818.539.15 1.625 1.113 3.093 2.776 3.426.08.212.124.36.236.605a44.444 44.444 0 0 0 1.729 3.358 73.531 73.531 0 0 0 1.955 3.226 156.74 156.74 0 0 0 2 3.057c1.312 1.96 2.545 3.76 3.455 5.277.042.07.08.159.119.229-.724 1.347-.855 2.967.2 4.177.347.402.716.79 1.077 1.182.054.976.178 2.012.367 3.107a57.8 57.8 0 0 0 .739 3.53c.291 1.215.619 2.462.96 3.705.685 2.485 1.429 4.965 2.051 7.16.312 1.097.592 2.122.82 3.035.229.912.403 1.714.503 2.34.236 1.478.414 2.715.547 3.764.097.771.156 1.364.207 1.957-.115.492-.241.984-.26 1.498-.017.461.189 1.005.347 1.529-.01.192-.018.396-.023.441-.069.602-.195 1.105-.308 1.907-.058.401-.102.858-.125 1.394a21.04 21.04 0 0 0 .006 1.92c0 .022.007.037.008.059-.148-.1-.104-.09-.258-.192-3.681-2.425-9.026-5.496-14.284-5.08-3.908.31-8.941 1.414-13.664 3.729-4.722 2.314-9.18 5.886-11.494 11.154-2.405 5.477-2.196 13.734-1.468 21.488.692 7.376 1.953 13.722 2.634 16.69-.06.1-.135.181-.191.289a5.533 5.533 0 0 0-.436 1.092 5.305 5.305 0 0 0-.17 1.003 1.89 1.89 0 0 0 0 .008c-.047.612-.002 1.064 0 1.374.002.153-.002.278-.015.384-.007.059-.024.12-.037.176-.17.256-1.74 2.615-3.41 5.604-.88 1.573-1.739 3.244-2.37 4.783-.63 1.539-1.23 2.784-.834 4.488.033.141.134.372.178.524-15.867 2.475-61.426 9.673-78.056 10.888-10.324.755-19.19 4.141-25.504 10.106-6.316 5.964-9.967 14.483-9.996 25.01-.03 10.724 5.157 22.172 13.501 30.222 8.345 8.05 20.08 12.684 32.747 9.147 20.189-5.639 53.95-12.25 97.226-18.057 38.436-5.157 172.61-13.68 201.504-14.365 14.719-.35 28.814-6.152 38.393-16.83 9.578-10.679 14.514-26.229 11.072-45.532-3.962-22.217-17.134-33.496-30.47-38.52-13.338-5.022-26.599-4.153-32.306-2.538-21.732 6.148-44.263 11.423-67.646 16.83.229-.304.467-.6.672-.922.337-.53.642-1.092.892-1.684.25-.589.444-1.204.561-1.853.118-.65.158-1.331.09-2.016a12.062 12.062 0 0 0-.518-2.478 12.985 12.985 0 0 0-.922-2.194 15.364 15.364 0 0 0-1.21-1.904 19.55 19.55 0 0 0-1.368-1.639c-.18-.194-.295-.283-.457-.435.25-1.489-.12-3.042-1.476-3.861a1.89 1.89 0 0 0-.118-.067c-1.13-.577-2.287-.997-3.433-1.41a34.182 34.182 0 0 1-.479-1.557c-.212-.729-.462-1.54-.879-2.369a7.515 7.515 0 0 0-.767-1.234 6.506 6.506 0 0 0-1.115-1.13 5.639 5.639 0 0 0-1.344-.788 5.51 5.51 0 0 0-1.27-.356v.008c-.64-.097-1.013-.082-1.27-.088a5.224 5.224 0 0 1-.132-.834c-.142-1.58-.35-3.466-.613-5.558-.263-2.093-.584-4.39-.967-6.77-.066-.41-.138-.8-.2-1.166v-.015a.151.151 0 0 0-.007-.037c-.001-.016.005-.016-.006-.11a1.89 1.89 0 0 0-.045-.052l.021.008a163.885 163.885 0 0 0-1.091-5.92 115.28 115.28 0 0 0-1.58-6.666c.03-.145.111-.297.126-.436.047-.431.03-.848-.023-1.256a1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 8.329 8.329 0 0 0-.266-1.224 13.075 13.075 0 0 0-.435-1.233 23.63 23.63 0 0 0-1.248-2.584A43.034 43.034 0 0 0 439.43 232c-.587-.9-1.211-1.8-1.846-2.672a73.146 73.146 0 0 0-1.904-2.502c-.314-.393-.6-.717-.887-1.057.004-.503.015-1.01.008-1.511-.03-1.623-1.233-2.747-2.695-3.249-.156-.604-.282-1.161-.524-1.912a33.928 33.928 0 0 0-.738-2.068c-.28-.708-.592-1.43-.945-2.133-.166-.33-.376-.637-.56-.959.612-.044 1.22-.076 1.874-.17a14.38 14.38 0 0 0 1.455-.281c.492-.124.983-.283 1.469-.486.484-.203.965-.45 1.432-.768a7.397 7.397 0 0 0 1.306-1.13 6.236 6.236 0 0 0 1.033-1.557 7.29 7.29 0 0 0 .532-1.631c.11-.535.16-1.061.177-1.567v-.013a11.29 11.29 0 0 0-.044-1.448 14.825 14.825 0 0 0-.399-2.289c-.023-.094-.021-.095-.043-.168.203-.377.426-.78.752-1.574a16.24 16.24 0 0 0 .768-2.316c.103-.425.189-.867.244-1.323.055-.457.076-.926.052-1.402a1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002c-.034-.604-.176-1.159-.37-1.705a11.296 11.296 0 0 0-.731-1.61 18.75 18.75 0 0 0-.967-1.572 25.44 25.44 0 0 0-1.115-1.505 24.187 24.187 0 0 0-2.332-2.561c-.38-.356-.744-.669-1.108-.932-.365-.264-.693-.502-1.27-.672.3.088.16.082-.02-.066a1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 1.89 1.89 0 0 0 0-.002 9.84 9.84 0 0 1-.762-.717c-.617-.636-1.395-1.531-2.221-2.488-.826-.957-1.704-1.978-2.563-2.908-.429-.465-.85-.91-1.27-1.315a13.467 13.467 0 0 0-1.253-1.084 8.86 8.86 0 0 0-1.404-.857 1.89 1.89 0 0 0-.006 0c-.487-.24-.99-.443-1.5-.62-1.022-.352-2.075-.602-3.108-.812-.575-.116-1.093-.206-1.638-.302v-.229l-.03.229-.045-.008a1.89 1.89 0 0 0-.015-.325l.088.088a45.68 45.68 0 0 0-.272-4.45v-.009c-.668-5.988-2.94-13.115-7.789-18.912-4.849-5.798-12.36-10.16-22.912-10.379h-.008a40.45 40.45 0 0 0-.973-.014z" transform="translate(-46 -30.696) scale(.26458)"/><path style="fill:#d97706;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M80.812 122.984c-.325-1.354-1.471-7.506-.371-10.011 1.1-2.506 4.292-3.487 6.237-3.64 1.148-.092 2.528.644 3.466 1.262.65.43 1.089.802 1.089.802l8.642-.72 10.656 2.695 5.725 4.107-.315 5.52-16.47 4.508-10.906 1.457z" transform="translate(-41.955 -71.433)"/><g style="display:inline"><path style="display:inline;fill:#fff;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M83.071 87.768c-3.828.596-16.674 2.63-21.278 2.967-5.288.387-8.914 3.45-8.93 8.795-.014 5.345 5.268 11.7 11.602 9.931 5.383-1.503 14.327-3.252 25.793-4.79 10.249-1.376 45.664-3.623 53.37-3.805 7.54-.18 14.384-5.95 12.607-15.914-2.04-11.443-13.29-11.23-15.982-10.468-14.813 4.19-30.335 6.919-50.09 12.31" transform="translate(-46 -30.696)"/><g aria-label="SnoBoard" style="font-size:26.8628px;line-height:1.25;font-family:'Lohit Tamil Classical';-inkscape-font-specification:'Lohit Tamil Classical';display:inline;stroke-width:.271687"><path style="display:inline;fill:#84cc16;stroke-width:.559859;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1.11972,2.23943" d="M87.703 119.898a4.26 4.26 0 0 0-.996-.042 5.531 5.531 0 0 0-1.646.393l-1.589.606a1.658 1.658 0 0 0-.522.387l-.413.501c-.803.997-1.376 2.06-1.723 3.193a15.383 15.383 0 0 0-.6 3.443c-.074.96.005 1.896.236 2.812.248.901.676 1.761 1.287 2.582.914 1.193 2.095 1.903 3.553 2.124.063.009.124.013.185.02l2.318-.428a4.84 4.84 0 0 0 1.48-1.196 12.808 12.808 0 0 0 1.47-2.185c.428-.788.752-1.64.97-2.555a3.52 3.52 0 0 0 .11-.56l.108-.51c.053-.426.107-.843.16-1.252.052-.426.086-.852.1-1.278a1.435 1.435 0 0 0-.093-.638 2.07 2.07 0 0 1-.123-.687c-.048-.816-.238-1.551-.57-2.204-.332-.668-.87-1.242-1.61-1.72a5.003 5.003 0 0 0-1.49-.669 4.665 4.665 0 0 0-.602-.137zm-9.115.507a2.395 2.395 0 0 0-.342-.023 8.257 8.257 0 0 0-.946.047 7.39 7.39 0 0 1-.88.044c-.32-.002-.534.062-.645.192-.11.13-.155.336-.133.62.022.264.044.6.067 1.008.024.407.038.833.043 1.276l.014 1.278.012 1.012a70.97 70.97 0 0 1-.117 2.05l-.09 2.047a3.246 3.246 0 0 0-.022.425c.001.142-.006.284-.023.425a2.92 2.92 0 0 1-.285-.48 2.91 2.91 0 0 0-.283-.479l-.336-.424a6.962 6.962 0 0 1-.31-.476 24.401 24.401 0 0 1-.949-1.68c-.315-.625-.628-1.256-.941-1.894-.294-.637-.586-1.262-.878-1.877-.29-.63-.562-1.207-.815-1.73a1.297 1.297 0 0 0-.268-.402c-.124-.149-.308-.183-.552-.103-.26.064-.528.12-.804.166-.275.03-.558.068-.848.116a1.89 1.89 0 0 1-.536.05c-.186-.026-.32.065-.402.271a1.858 1.858 0 0 0-.147.462l-.045.482c-.042.743-.076 1.51-.1 2.303a109.99 109.99 0 0 0 0 2.298c.005.37-.007.901-.032 1.591l-.028 2.07c-.008.705-.018 1.361-.028 1.966.007.606.02 1.01.039 1.211.018.152.02.287.005.404a.596.596 0 0 0 .028.304.48.48 0 0 0 .254.16c.119.039.321.064.61.075l.766.029c.446.017.722-.024.825-.123.12-.098.186-.36.199-.787.012-.41.024-.88.036-1.41l.033-1.666.034-1.642c.011-.548.023-1.028.036-1.439l-.003-.282c-.002-.137.014-.231.048-.283.035.017.089.076.16.179.07.085.14.187.212.307.071.12.134.24.188.36.071.103.116.171.134.206.179.326.386.706.62 1.138.235.433.47.876.706 1.329.255.437.51.866.766 1.289.257.423.496.796.717 1.116.165.214.286.392.36.535.093.125.194.234.305.325.11.074.248.14.414.198.166.04.415.093.749.157.167.04.371.056.613.047l.788-.027c.282-.026.556-.053.821-.08.285-.044.533-.08.744-.11.115-.014.22-.083.314-.206a.797.797 0 0 0 .17-.373c.09-.593.13-1.26.122-2 .01-.757.041-1.443.093-2.056a55.53 55.53 0 0 0 .155-1.735c.07-.688.13-1.394.18-2.119.05-.725.08-1.432.092-2.12a12.742 12.742 0 0 0-.078-1.792l-.012-1.086c-.042-.252-.121-.429-.239-.532-.073-.064-.192-.108-.355-.132zm8.632 2.45c.156.025.298.069.427.131.203.078.39.215.557.411.169.196.273.386.312.57.194.765.305 1.541.332 2.328a7.02 7.02 0 0 1-.252 2.311 12.46 12.46 0 0 1-.673 1.799 13.199 13.199 0 0 1-.888 1.657c-.321.54-.807.835-1.455.885-.358.04-.68-.058-.968-.294a2.848 2.848 0 0 1-.835-1.118 10.76 10.76 0 0 1-.462-1.252 3.53 3.53 0 0 1-.145-1.148c.03-.422.061-.771.093-1.048.08-.683.196-1.335.347-1.956.152-.638.339-1.27.562-1.895.086-.247.26-.472.525-.675.283-.22.594-.393.933-.518.36-.125.72-.194 1.083-.204.182-.014.351-.008.507.016zm-24.558-1.52a7.228 7.228 0 0 0-2.1-.02 4.506 4.506 0 0 0-1.309.346 5.25 5.25 0 0 0-1.152.698 4.229 4.229 0 0 0-.899.962 3.13 3.13 0 0 0-.476 1.164c-.064.42-.016.857.143 1.309.48 1.311 1.464 2.376 2.973 3.2.144.077.26.173.352.29.108.103.236.213.38.33.438.365.714.711.827 1.039.113.314.152.622.12.923-.034.248-.168.462-.402.641a1.34 1.34 0 0 1-.728.282c-.465.031-.821-.008-1.07-.115-.249-.107-.436-.31-.563-.607a1.822 1.822 0 0 1-.081-.251.444.444 0 0 0-.082-.252c-.036-.051-.133-.084-.29-.098a3.451 3.451 0 0 0-.549-.043 5.812 5.812 0 0 0-.672-.005 4.663 4.663 0 0 1-.617-.043c-.238-.027-.382-.016-.433.034a.693.693 0 0 1-.176.094c-.05.024-.084.087-.1.188.001.1.011.183.029.246.143.77.532 1.447 1.17 2.032.644.577 1.57.957 2.79 1.138.25.033.51.042.778.025.27-.004.532-.029.786-.073.6-.073 1.122-.228 1.563-.465a3.922 3.922 0 0 0 1.083-.827c.298-.326.521-.675.669-1.046.147-.372.22-.718.216-1.04-.006-.521-.193-1.104-.56-1.744-.346-.638-.943-1.237-1.785-1.796a9.855 9.855 0 0 1-.916-.675c-.276-.244-.56-.486-.853-.727a2.128 2.128 0 0 1-.491-.515l-.329-.614a.949.949 0 0 1-.14-.481 2.23 2.23 0 0 1 .102-.49c.07-.158.158-.297.264-.418.124-.135.266-.232.428-.29.413-.149.84-.154 1.28-.015.46.126.815.37 1.06.73a.698.698 0 0 1 .144.411c.02.145.078.283.172.412a.634.634 0 0 0 .17.114.653.653 0 0 0 .253.053l.762-.083c.341-.05.589-.092.741-.123.287-.05.497-.096.631-.14.135-.059.211-.122.23-.19.038-.082.037-.19-.003-.324a20.25 20.25 0 0 1-.151-.54 3.308 3.308 0 0 0-1.228-1.858c-.48-.376-1.136-.627-1.96-.752z" transform="matrix(.98054 -.14748 .14328 .95264 -62.103 -43.725)"/><path style="display:inline;fill:#65a30d;stroke-width:.8684;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1.7368,3.47359" d="M139.678 109.707a8.624 8.624 0 0 0-2.341.083c-.088.009-.24.056-.455.141-.215.085-.352.183-.411.294a4.09 4.09 0 0 0-.41.735c-.083.218-.173.564-.271 1.035a29.6 29.6 0 0 0-.154 1.244c-.076.68-.167 1.443-.27 2.293a128.056 128.056 0 0 0-.374 4.442c-.036.297-.07.572-.103.826-.03.234-.055.477-.07.73l-.039.634a308.561 308.561 0 0 1-.313 3.865 304.13 304.13 0 0 0-.313 3.863c-.022.358.063.673.254.945.207.293.429.501.665.625.236.125.485.196.746.215.261.04.526.027.794-.04.268-.045.536-.101.807-.169a12.58 12.58 0 0 0 1.535-.565 51.101 51.101 0 0 0 1.563-.703 9.394 9.394 0 0 0 2.499-1.647c.75-.696 1.358-1.611 1.821-2.746a18.304 18.304 0 0 0 1.41-6.865c.048-1.413-.13-2.677-.535-3.789a10.826 10.826 0 0 0-1.695-3.039c-.875-1.114-1.886-1.828-3.03-2.146a7.32 7.32 0 0 0-1.31-.261zm-9.788.955a5.184 5.184 0 0 0-1.36.039l-1.818.33c-.589.088-1.175.206-1.76.353-.405.086-.791.329-1.16.729-.349.376-.543.766-.585 1.167l-.3 2.414a96.783 96.783 0 0 0-.222 2.375c-.12 1.679-.23 3.347-.33 5.004a475.602 475.602 0 0 1-.28 5.003c-.02.34-.05.68-.088 1.019-.02.34-.032.679-.036 1.018l-.047.779c-.01.18-.002.32.026.419.026.12.099.19.217.209.135.039.331.057.589.056l.778-.004c.33-.002.6.006.809.025.439-.003.675-.268.707-.796.005-.366.019-.741.043-1.127.04-.386.074-.793.1-1.22.03-.507.05-.984.06-1.43.028-.447.064-.884.107-1.312.022-.365.054-.731.093-1.098l.12-1.1.96-.046c.324-.036.649-.062.973-.079l.109-.005c.146-.028.232.03.26.172l.086.365c.07.346.11.591.119.734.009.144.034.338.073.583.122.983.273 1.947.452 2.891.18.947.305 1.918.373 2.911.023.228.093.435.21.621.117.208.336.259.657.153.341-.106.692-.202 1.053-.287a6.289 6.289 0 0 0 1.065-.292c.37-.15.502-.457.397-.92-.246-1.26-.482-2.505-.71-3.737-.226-1.227-.46-2.461-.702-3.701-.076-.288-.08-.538-.01-.75.087-.213.24-.43.46-.65v-.001c.3-.31.6-.61.902-.902.32-.292.596-.625.828-.998.293-.42.525-.92.694-1.502.19-.605.304-1.204.34-1.798a6.244 6.244 0 0 0-.067-1.733c-.1-.56-.273-1.016-.519-1.37-.611-.88-1.334-1.555-2.166-2.025a3.797 3.797 0 0 0-1.5-.486zm9.337 2.561c.13.017.278.065.446.144a5.03 5.03 0 0 1 1.76 1.337c.495.565.854 1.295 1.075 2.189.316.846.488 1.67.513 2.473.043.803-.055 1.657-.295 2.561-.119.441-.23.892-.331 1.353a4.41 4.41 0 0 1-.465 1.29 4.021 4.021 0 0 1-.632.902 5.421 5.421 0 0 1-.78.675c-.266.203-.55.395-.85.577l-.838.476-.107.003-.714.277c-.235.07-.472.162-.709.275l.055-.896.135-1.348c.046-.47.091-.92.135-1.349.044-.428.072-.738.084-.93l.376-4.432c.144-1.5.28-3.001.407-4.501.05-.537.16-.865.327-.986a.531.531 0 0 1 .408-.09zm-21.758-1.289a.919.919 0 0 0-.273.012l-1.249.19c-.402.042-.802.063-1.199.063-.342.015-.616.114-.824.298-.188.162-.355.424-.502.784-.336.866-.68 1.72-1.031 2.562a56.794 56.794 0 0 0-.945 2.564c-.505 1.427-.99 2.837-1.455 4.23-.463 1.389-.925 2.781-1.386 4.178l-.23.846c-.11.403-.229.825-.357 1.267-.11.421-.22.832-.33 1.233-.091.4-.15.68-.177.84-.04.1-.04.23.002.389.042.14.104.229.186.269.18.099.371.168.573.207.204.02.407.05.61.089.188.02.376.03.566.029a.717.717 0 0 0 .5-.123c.127-.081.205-.233.236-.456a3.92 3.92 0 0 1 .196-.639c.022-.081.077-.274.166-.579.107-.325.214-.661.323-1.008.127-.367.235-.704.323-1.01.09-.327.156-.532.196-.614a3.2 3.2 0 0 1 .303-.648.947.947 0 0 1 .312-.345.84.84 0 0 1 .404-.104c.18-.026.393-.044.643-.05.287-.01.566-.03.837-.058.273-.05.51-.078.71-.084a7.63 7.63 0 0 1 .685-.053l.715-.022c.221-.007.397-.002.525.014.13-.004.22.024.272.085.07.06.12.174.147.34.028.146.062.354.1.625l.14.937c.072.334.135.678.188 1.034.073.334.136.68.19 1.036.073.335.129.64.169.913.032.084.073.178.123.283.052.084.096.126.134.125l1.332.058c.459-.002.912-.025 1.358-.069a.44.44 0 0 0 .3-.162c.084-.107.085-.289.004-.544a21.538 21.538 0 0 1-.332-1.693 54.928 54.928 0 0 1-.258-1.942c-.067-.466-.143-.962-.225-1.49a45.05 45.05 0 0 0-.277-1.58 58.03 58.03 0 0 0-.24-1.701c-.08-.545-.162-1.089-.243-1.632-.089-.711-.17-1.41-.24-2.1a35.35 35.35 0 0 0-.27-2.09l-.325-2.045a22.417 22.417 0 0 0-.411-1.996.801.801 0 0 0-.333-.497.607.607 0 0 0-.356-.166zm11.156 2.228c.195.023.39.064.585.122.592.19 1.03.541 1.313 1.053.302.511.367 1.128.193 1.848-.12.445-.337.814-.65 1.106-.313.292-.641.564-.986.815a4.158 4.158 0 0 1-1.506.628c-.507.076-1.004.18-1.492.315-.144.05-.25.057-.32.021-.048-.057-.076-.177-.083-.358l.03-2.215c.008-.728.018-1.466.029-2.213a1.09 1.09 0 0 0 .02-.335l.018-.304c.006-.102.028-.174.066-.218.038-.044.12-.073.243-.085.514-.01 1.032-.06 1.557-.151.33-.058.657-.068.983-.029zm-24.264-.761a3.691 3.691 0 0 0-.999.01c-.55.08-1.113.265-1.687.554l-1.645.796c-.2.114-.386.274-.556.478l-.455.605a13.492 13.492 0 0 0-1.988 3.795 21.702 21.702 0 0 0-.882 4.018 11.362 11.362 0 0 0 .006 3.238 8.446 8.446 0 0 0 1.079 2.92c.818 1.33 1.945 2.09 3.391 2.267.84.09 1.603-.059 2.286-.45a6.014 6.014 0 0 0 1.851-1.621 17.894 17.894 0 0 0 1.66-2.617c.497-.939.894-1.946 1.19-3.02.072-.24.123-.459.155-.657l.152-.598c.089-.497.176-.985.263-1.463.088-.498.157-.995.207-1.49a1.822 1.822 0 0 0-.042-.735 2.62 2.62 0 0 1-.068-.792c.019-.944-.113-1.787-.395-2.526-.28-.756-.775-1.39-1.483-1.902a4.066 4.066 0 0 0-1.445-.687 3.835 3.835 0 0 0-.595-.123zm11.082 2.983c.03.1.052.192.065.273.013.082.026.173.038.275l.387 2.637c.13.861.26 1.745.389 2.65.015.062-.018.147-.099.255-.08.108-.148.174-.205.197l-1.054.237c-.348.059-.704.117-1.067.175l-.431.021a.604.604 0 0 0-.27.013c-.306.056-.394-.093-.266-.447.361-.958.714-1.909 1.058-2.851.363-.947.728-1.907 1.095-2.88a.893.893 0 0 1 .152-.26c.078-.088.147-.187.208-.295zm-25-1.291c-.06-.007-.121-.012-.182-.017-.27-.02-.54-.033-.81-.037a6.639 6.639 0 0 0-.856-.006c-.463.034-.898.09-1.306.166a5.95 5.95 0 0 0-1.222.373 3.766 3.766 0 0 0-.372.16 1.497 1.497 0 0 0-.346.18.93.93 0 0 0-.403.739c-.092.955-.19 1.997-.293 3.128-.102 1.113-.2 2.155-.292 3.123-.031.226-.063.605-.095 1.136l-.099 1.618-.092 1.52c-.011.466-.021.772-.03.917-.006.37-.028.732-.067 1.086-.038.355-.06.717-.066 1.087.002.257-.005.498-.019.724-.013.225 0 .426.04.602a.723.723 0 0 0 .232.408c.112.111.288.174.528.188.29.029.636.041 1.036.037.4.012.802.016 1.207.012.407-.005.8-.025 1.177-.062.377-.02.693-.05.948-.085a9.995 9.995 0 0 0 1.47-.343 14.937 14.937 0 0 0 1.476-.524 4.823 4.823 0 0 0 1.597-1.172 6.505 6.505 0 0 0 1.102-1.638c.263-.538.382-1.064.355-1.575a3.474 3.474 0 0 0-.455-1.515 2.088 2.088 0 0 0-.89-.872c-.365-.2-.74-.382-1.123-.546a20.629 20.629 0 0 0-.518-.222c-.089-.062-.085-.129.012-.202.14-.142.336-.313.59-.514a8.36 8.36 0 0 0 .652-.52c1.344-1.208 1.847-2.554 1.496-4.02a2.402 2.402 0 0 0-.121-.346 1.79 1.79 0 0 0-.15-.368c-.443-.822-1.027-1.447-1.75-1.879-.671-.401-1.46-.648-2.362-.741zm13.19 1.766c.154.02.294.062.418.127.199.079.374.226.528.444a1.4 1.4 0 0 1 .267.641c.133.877.18 1.772.144 2.684a9.761 9.761 0 0 1-.444 2.695c-.23.726-.505 1.434-.824 2.123a18.755 18.755 0 0 1-1.029 1.97c-.368.644-.88 1.013-1.536 1.106a1.032 1.032 0 0 1-.948-.287c-.336-.312-.585-.729-.747-1.25a12.498 12.498 0 0 1-.361-1.425 4.538 4.538 0 0 1-.052-1.32c.065-.49.125-.897.18-1.22.136-.795.305-1.557.508-2.284.204-.748.444-1.49.718-2.227.107-.291.3-.562.583-.812a3.98 3.98 0 0 1 .98-.655 3.47 3.47 0 0 1 1.106-.3 1.9 1.9 0 0 1 .508-.01zm-15.12.781c.419.044.827.121 1.225.233.534.133.991.399 1.37.797.15.237.254.486.311.748.06.228.073.468.04.721-.016.251-.114.5-.295.747-.18.246-.413.479-.7.698a8.908 8.908 0 0 1-.908.61c-.3.184-.615.344-.945.481-.33.136-.629.238-.898.304a1.2 1.2 0 0 1-.212-.012.528.528 0 0 1-.153-.088.457.457 0 0 1-.07-.167 1.023 1.023 0 0 1-.012-.219l.133-2.185a46.98 46.98 0 0 0 .134-2.209c-.004-.211.039-.345.13-.403.092-.057.235-.087.43-.09.141.008.281.02.42.034zm1.138 8.371a3.815 3.815 0 0 1 .86.182c.18.06.35.136.51.229.178.092.319.204.422.333a.83.83 0 0 1 .225.419c.069.383-.092.749-.484 1.097-.37.33-.843.569-1.417.719-.388.11-.764.211-1.13.304-.362.076-.74.119-1.131.13-.248.005-.422-.039-.522-.134-.081-.112-.116-.274-.103-.487.028-.164.038-.32.029-.467l.028-.466.187-1.771c.476.01.948-.011 1.415-.065a4.456 4.456 0 0 1 1.111-.023z" transform="matrix(.98662 -.09823 .2135 .93955 -62.103 -43.725)"/></g></g><path style="fill:#f59e0b;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M76.934 38.324s-4.857-1.505-5.53.163c-.421 1.043 1.647 2.076 1.753 2.985.075.637-1.97 1.252-1.563 1.604 1.107.958 3.348.704 3.348.704" transform="translate(-46 -30.696)"/><path style="fill:#f59e0b;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m85.874 82.018-1.298 1.46s-1.903 2.871-1.728 3.626c.175.754 2.053 5.524 4.596 4.814 2.542-.71 3.3-2.314 3.08-3.33-.22-1.016-.476-2.079-.38-2.5.097-.423 1.356-.646 1.356-.646l1.377-1.86" transform="translate(-46 -30.696)"/><path style="display:inline;fill:#fcd34d;fill-opacity:1;stroke:none;stroke-width:3.77953;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M396.877 163.404s12.431 10.877 15.292 11.736c2.86.858 7.996 1.03 10.659 3.03 2.662 2.002 7.221 8.461 8.691 8.894 1.47.432 6.4 6.017 6.541 8.844.14 2.828-1.955 6.34-1.955 6.34s1.763 4.956-.625 7.576c-2.388 2.619-6.513 2.059-9.604 2.54 3.646 3.606 5.086 11.923 5.086 11.923 3.445 3.463 11.583 14.128 9.998 17.153 2.464 8.951 3.983 20.223 4.544 26.445.377 4.181 2.273 1.436 4.727 3.37 2.453 1.936 1.936 5.638 3.783 7.514 2.189 2.223 7.667 5.56 8.247 11.468.394 4.002-4.026 7.843-6.917 9.905l-2.615.573c-.334-1.283-1.304-4.702-2.159-6.565-1.026-2.236-12.366-7.903-12.366-7.903s-5.345-2.831-13.222-5.2c-1.986.889-12.334 9.801-19.588 12.303-.29 3.255-46.231 29.728-59.566 29.58-2.75-3.862-4.98-6.84-9.756-8.62-4.776-1.781-9.822-1.733-16.415 1.2.642-1.948-.819-2.93 1.976-5.675 6.569-6.45 25.492-23.165 30.643-21.946 4.15-5.93 14.515-11.597 17.998-14.986-5.975-2.76-10.802-3.14-11.111-10.396-.24-5.597 1.501-2.676-.41-14.625-.91-5.693-6.432-19.901-5.305-25.118-.624-4.227-9.443-13.457-12.064-21.971-8.02-4.58-20.612-18.124-22.862-18.892-2.249-.768-5.042-.062-6.62-.91-1.578-.847-1.404-2.879-4.106-3.851-2.703-.972-4.774-.253-8.668-2.092-3.895-1.84-.786-2.46-7.8-3.88-7.015-1.418-7.924-3.161-7.924-3.161s-1.905-17.544 6.42-22.627c8.327-5.083 15.721 2.471 16.203 3.232 6.617 2.785 12.557.572 15.629 5.706 6.202 2.957 15.075 3.548 16.816 3.788 6.545.901 11.462 2.602 20.022 8.556 17.767-2.495 20.417-3.258 38.383-3.258z" transform="translate(-46 -30.696) scale(.26458)"/><path style="display:inline;fill:none;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M105.007 43.234s3.29 2.878 4.046 3.105c.757.227 2.116.273 2.82.802.705.53 1.91 2.239 2.3 2.353.389.114 1.693 1.592 1.73 2.34.038.748-.517 1.677-.517 1.677s.467 1.312-.165 2.005c-.632.693-1.724.545-2.541.672.964.954 1.345 3.155 1.345 3.155.912.916 3.065 3.738 2.646 4.538.652 2.368 1.053 5.35 1.202 6.997.1 1.106.601.38 1.25.892.65.512.513 1.491 1.001 1.988.58.588 2.03 1.47 2.183 3.034.104 1.059-1.066 2.075-1.83 2.62l-.692.152c-.089-.34-.345-1.244-.572-1.737-.271-.591-3.271-2.09-3.271-2.09s-1.415-.75-3.499-1.377c-.525.236-3.263 2.594-5.182 3.256-.077.86-12.233 7.865-15.76 7.826-.728-1.022-1.318-1.81-2.582-2.28-1.264-.472-2.599-.46-4.343.317.17-.516-.217-.775.523-1.502 1.738-1.706 6.745-6.129 8.107-5.806 1.099-1.57 3.84-3.069 4.762-3.966-1.58-.73-2.858-.83-2.94-2.75-.063-1.48.398-.708-.108-3.87-.24-1.506-1.702-5.265-1.404-6.645-.165-1.119-2.498-3.561-3.192-5.814-2.121-1.211-5.453-4.795-6.048-4.998-.595-.203-1.334-.016-1.752-.24-.418-.225-.371-.762-1.086-1.02-.715-.257-1.263-.067-2.294-.553-1.03-.487-.208-.651-2.063-1.027-1.856-.375-2.097-.836-2.097-.836s-.504-4.642 1.699-5.987c2.203-1.345 4.16.654 4.287.855 1.75.737 3.322.152 4.135 1.51 1.64.782 3.988.939 4.449 1.002 1.732.239 3.033.689 5.297 2.264 4.701-.66 5.403-.862 10.156-.862z" transform="translate(-46 -30.696)"/><path style="display:inline;fill:none;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M97.968 72.205s2.212-2.051 2.83-4.042c.616-1.992 2.042-5.257 2.498-6.476-.164-1.04 2.433-5.093 4.673-5.87 1.347-.467 3.891-.542 4.71.371m-.236 18.172c1.157-1.12 5.43-3.482 4.958-7.072" transform="translate(-46 -30.696)"/><path style="display:inline;fill:#f59e0b;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M109.568 47.608s3.015.625 2.243 2.372c-.197.446-1.299.62-1.862 1.038a74.83 74.83 0 0 1-3.571 2.455" transform="translate(-46 -30.696)"/><path style="display:inline;fill:#f59e0b;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M95.08 48.855c.119.41-.11 2.637 1.81 2.937.424.067-.395 1.218.064 1.516.46.298.171 1.446.427 1.539 1.582.573 1.949 3.34 2.849 3.263.334-.028 1.571-1.608 2.398-2.222.67-.498 2.176-1.058 3.076-1.41.82-.32.457-1.673 1.38-1.559.874.109 1.877-2.372 1.878-2.648-.791-.296-1.064.359-1.838.219-.285-.052-.905-.417-1.348-.654" transform="translate(-46 -30.696)"/><path style="display:inline;fill:#d97706;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M95.08 48.855s-.288-3.004-.23-4.737c.026-.755.118-1.454.326-1.902.688-1.476 1.438-4.763 6.764-4.653 5.327.11 7.305 4.302 7.64 7.307.334 3.004-.618 5.401-.618 5.401" transform="translate(-46 -30.696)"/><path style="fill:url(#d);stroke-width:.571755;stroke-linecap:round;stroke-linejoin:round" transform="matrix(-.23112 .97293 -.99585 .09096 -46 -30.696)" d="M55.06-111.757a2.204 1.515 0 0 1-2.203 1.516 2.204 1.515 0 0 1-2.204-1.516 2.204 1.515 0 0 1 2.204-1.515 2.204 1.515 0 0 1 2.204 1.515z"/><path style="display:inline;fill:#334155;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M95.077 47.885s.664.699 1.408 1.173l9.572.007c1.434.05 3.253-1.066 3.253-1.066l.34-2s-1.82 1.117-3.254 1.068l-10.1.05c-.744-.473-1.408-1.172-1.408-1.172z" transform="translate(-46 -30.696)"/><path style="display:inline;fill:#334155;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M96.676 46.344c.312-.172 4.13.443 5.106.495.978.052 3.429-.41 4.192-.358.763.052.535 3.014.148 3.147-.387.132-2.27 1.844-2.982 1.466-.713-.378-1.399-1.345-2.23-1.345-.83 0-.776 1.059-1.55 1.059s-3.108-1.083-3.06-1.42c.049-.338-.34-2.65.376-3.044z" transform="translate(-46 -30.696)"/><path style="fill:#94a3b8;fill-opacity:1;stroke:none;stroke-linecap:round;stroke-linejoin:round" d="M98.418 46.662h2.099l-1.588 3.646h-2.098z" transform="translate(-46 -30.696)"/><path style="display:inline;fill:none;fill-opacity:1;stroke:#000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M96.676 46.344c.312-.172 4.13.443 5.106.495.978.052 3.429-.41 4.192-.358.763.052.535 3.014.148 3.147-.387.132-2.27 1.844-2.982 1.466-.713-.378-1.399-1.345-2.23-1.345-.83 0-.776 1.059-1.55 1.059s-3.108-1.083-3.06-1.42c.049-.338-.34-2.65.376-3.044z" transform="translate(-46 -30.696)"/><path style="color:#000;display:inline;fill:#000;stroke-linecap:round;-inkscape-stroke:none" d="M91.336 77.27c.074-.92.016.56-.385-.625-.4-1.185-.575-2.52-.73-2.321-.153.198-.454 1.172-.118 2.486.336 1.315.285-.245.235.38.33.136.737.086.998.08zm.391-.913c-.372-.686-.677-1.188-.508-1.16.181.031.704.317 1.222.94-.34.176-.603.197-.714.22z" transform="translate(-46 -30.696)"/><path style="color:#000;fill:#000;stroke-linecap:round;-inkscape-stroke:none" d="M104.37 79.484c1.092.424 2.26.468 3.23.682.969.214 1.492.5 1.51.385.018-.115-.535-.537-1.379-.85-.843-.315-1.632-.395-2.76-.832-.034.313-.092.465-.6.615z" transform="translate(-46 -30.696)"/><path style="color:#000;display:inline;fill:#000;stroke-linecap:round;-inkscape-stroke:none" d="M119.527 79.689a.5.5 0 0 0-.126-.698c-1.545-.91-3.546-1.22-3.597-1.108-.05.114 1.692.67 3.16 2.031.202.188.405.001.563-.225z" transform="translate(-46 -30.696)"/><path style="color:#000;fill:#000;stroke-linecap:round;-inkscape-stroke:none" d="M97.045 52.816a.5.5 0 0 0-.182.983s.741.34 1.608.457c.867.118 1.824.031 2.492-.053.274-.034 1.338-.373 1.31-.489-.026-.115-1.029.156-2.15.172-1.123.016-1.871-.243-2.803-.944-.678-.51-.275-.126-.275-.126zm3.019 2.787c.769-.124 1.477-.142 1.475-.229 0-.087-.529-.14-1.477-.236-.947-.096-1.327-.034-1.982-.478-.655-.443-.315.539-.235.804.079.264.63.78.726.855.85-.443.724-.592 1.493-.716zm-3.06-4.298a.5.5 0 1 0-.229.974s1.274-.177 1.802-.075c.863.075 1.812.41 1.821.239.01-.172-1.619-.755-2.457-.94a26.365 26.365 0 0 1-.937-.198zm10.49.815c-.4.407-1.186.37-2.356.322-1.17-.048-2.29.287-3.277.398-.986.111-1.574.01-1.553.125.02.114.68.335 1.58.359.9.024 1.672-.155 2.88-.106 1.209.05 1.692.477 2.605.18.262-.085.272-.37.188-.632-.085-.264.331-1.055-.067-.647zm-14.365 6.144a.5.5 0 0 0-.05.707c.603.696 1.258 1.373 2.385 1.918 1.126.544 2.2 1.355 2.167 1.106-.034-.25-.518-1.147-1.69-1.828-1.174-.681-1.88-1.388-2.138-1.945-.117-.25-.465-.14-.674.042zm14.748-2.356c-.056-.271-.15-.543-.398-.431-.841.378-1.982.568-3.004 1.29-1.022.722-2.042 1.17-2.042 1.275 0 .104 1.234-.153 1.843-.5.609-.346.791-.109.688.019-.105.128 2.97-1.383 2.913-1.653zm13.264 18.641a.5.5 0 0 0-.168-.69c-1.598-.814-3.614-1.002-3.657-.886-.044.116 1.429.7 3.138 1.743a.5.5 0 0 0 .687-.167zm-25.799-7.767c-.233.15-.38.895-.228 1.127.236.31.409 1.434.421 1.105.006-.165.453-.581.88-.453 1.066.32 2.043-.27 2.09-.315.089-.086-2.666.24-2.879-1.24-.039-.272-.053-.375-.284-.224zm20.066-13.616c.115.253-.199 1.555-.352 1.288-.024-.393-.083.421-1.334.446-.311.006-1.565-.228-1.952-.223-1.166.016-2.073.057-2.012-.003.119-.116.827-.413 1.788-.548.494-.07 1.168 0 1.626-.043 1.35-.128 1.752-.807 1.911-1.076.175-.295.21-.092.325.16zm-1.276-3.442c-.144-.236-.906-.392-.712-.195.327.33.059 1.252-.602 1.952-.61.645-1.212.621-1.224.692-.016.092.784.26 1.894-.464.535-.348.382-.376.834-.844.23-.24.31-.259.407-.18.25.202-.597-.96-.597-.96zM93.439 75.841c.251.116 1.37-.655.965-.261-.495.482-.95 1.988-2.801 3.418-.99.764-2.175 1.347-2.327 1.335-.153-.012 1.043-.91 1.984-1.888.94-.978 1.32-1.69 1.066-1.556.116-.25.862-1.164 1.113-1.048zm20.591-16.989a.5.5 0 0 1 .512.491c.018.922-.015 1.863-.486 3.022-.47 1.16-2.675 3.673-2.817 3.466-.143-.207 1.566-2.39 1.98-3.682.414-1.291.31-2.212.298-2.839-.006-.275.237-.452.513-.458zm-6.118 18.512c.079.265-.026.569-.292.646-.885.26-3.1.605-4.342.456-1.242-.15-4.032.864-3.87.672.163-.191 2.503-1.597 3.858-1.537 1.356.06 3.628-.328 4.19-.607.255-.126.378.105.456.37zm-31.01-32.061a.5.5 0 0 0 .466.535c1.794-.011 3.67-.772 3.656-.895-.015-.123-1.796.293-3.754-.122-.27-.058-.349.207-.368.482zm6.518 2.653c.023-.276.26-.433.536-.409 1.771.282 3.517 1.27 3.484 1.389-.033.12-1.73-.561-3.729-.447-.276.016-.313-.257-.29-.533zm6.42 5.002a.5.5 0 0 0 .4.585c1.783.197 3.188 2.257 3.187 2.133 0-.084-.363-1.2-1.315-2.122-.458-.444-1.277-.708-1.834-1.044-.284-.172-.388.177-.439.448zM84.548 40.91c.294.474.525 1.034 1.041 1.739.517.704 1.616 1.514 2.482 1.938.865.424 3.06 1.94 3.086 1.79.027-.148-1.988-1.808-3.354-2.846-3.458-2.628-.457-2.985-3.127-3.037-.318.298.781.446-.128.416z" transform="translate(-46 -30.696)"/><path style="display:inline;fill:none;stroke:#94a3b8;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" d="M55.975 99.831a5.61 5.61 0 0 0 2.658 3.009 5.609 5.609 0 0 0 3.993.428c.975-.263 1.865-.791 2.638-1.442.773-.65 1.435-1.423 2.05-2.224 1.23-1.604 2.308-3.36 3.865-4.648 2.268-1.875 5.319-2.547 8.26-2.594 2.943-.048 5.862.465 8.796.678 3.604.26 7.396.024 10.53-1.774 1.078-.617 2.048-1.403 3.074-2.103 1.025-.7 2.132-1.326 3.348-1.575a6.506 6.506 0 0 1 3.124.154c1.009.296 1.938.81 2.834 1.359 1.469.9 2.872 1.903 4.231 2.96 1.296 1.009 2.562 2.072 4 2.864 1.44.79 3.09 1.3 4.72 1.095 1.83-.23 3.441-1.332 4.778-2.605 2.355-2.244 4.065-5.062 5.948-7.715.935-1.316 1.935-2.616 3.223-3.59 1.292-.977 2.87-1.599 4.489-1.655 2.049-.07 4.115.802 5.48 2.333a7.041 7.041 0 0 1 1.671 5.716" transform="translate(-46 -30.696)" clip-path="url(#e)"/><path style="display:inline;fill:none;fill-opacity:1;stroke:#334155;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M91.173 102.501c6.021-2.01 6.76-7.397 11.07-10.587 1.271-.93 2.797-1.607 4.371-1.549.877.032 1.735.29 2.529.664.794.374 1.529.861 2.243 1.37 2.411 1.722 4.657 3.743 7.37 4.932 2.237.98 4.744 1.351 7.163 1.013" transform="translate(-46 -30.696)" clip-path="url(#f)"/><path style="display:inline;fill:url(#g);fill-opacity:1;stroke-width:2.44399;stroke-linecap:round;stroke-linejoin:round" d="M104.532 128.268a2.16 2.203 0 0 1-2.161 2.203 2.16 2.203 0 0 1-2.161-2.203 2.16 2.203 0 0 1 2.16-2.203 2.16 2.203 0 0 1 2.162 2.203z" transform="translate(-41.955 -71.433)"/><path style="display:inline;fill:#f59e0b;stroke-width:2.07148;stroke-linecap:round;stroke-linejoin:round" d="M103.67 128.268a1.3 1.3 0 0 1-1.3 1.3 1.3 1.3 0 0 1-1.299-1.3 1.3 1.3 0 0 1 1.3-1.3 1.3 1.3 0 0 1 1.3 1.3z" transform="translate(-41.955 -71.433)"/><path style="fill:#000;stroke:#000;stroke-width:.264583px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" d="m123.691 118.334-1.31 3.227 1.037-.163-.91 2.745 2.623-3.88-1.401.372 2.428-2.82" transform="translate(-41.955 -71.433)"/><path style="display:inline;fill:#000;stroke:#000;stroke-width:.264583px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" d="m62.56 149.44 1.31-3.228-1.037.163.91-2.745-2.622 3.88 1.4-.371-2.428 2.82" transform="translate(-41.955 -71.433)"/></g></svg>
\ No newline at end of file
-- 
GitLab


From 43d1c892b8df744a09f8eeba0d33c527ef1a0727 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 02/47] feat(router): :sparkles: pass initial table columns &
 filters from url to props

---
 src/router/index.ts         | 13 +++++++++++++
 src/views/DataTableView.vue | 13 +++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/src/router/index.ts b/src/router/index.ts
index c503d32..4d72227 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -34,6 +34,19 @@ const router = createRouter({
       path: '/data',
       name: 'data-table',
       component: () => import('@/views/DataTableView.vue'),
+      props: (to) => ({
+        initialColumns: Array.isArray(to.query.columns)
+          ? to.query.columns.map((column) => column?.split(',')).flat()
+          : to.query.columns && to.query.columns.split(','),
+        initialFilters: Object.entries(to.query).reduce(
+          (initialFilters, [key, value]) => {
+            return key === 'columns' || !value
+              ? initialFilters
+              : { ...initialFilters, [key]: value }
+          },
+          {}
+        )
+      }),
       meta: {
         title: 'Data table'
       }
diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 2c9b8d2..0f5c503 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -92,6 +92,16 @@ interface ColumnGroupModel {
   columns: ColumnModel[]
 }
 
+/**
+ * Component props.
+ */
+const props = defineProps<{
+  /** The columns of the table to display initially. */
+  initialColumns?: string[]
+  /** The filters to apply on the table initially. */
+  initialFilters?: Record<string, any>
+}>()
+
 /**
  * Reactive urql GraphQL query object, updated with query state & response
  */
@@ -99,6 +109,9 @@ const gqlQuery = useQuery({
   query: tableEntriesQuery
 })
 
+/**
+ * Data to display in the table.
+ */
 const tableEntries = computed(() =>
   gqlQuery.data.value?.tableEntries.map((entry) => ({
     ...entry,
-- 
GitLab


From 031ac3fbdccc0fec4c9e324106e447c1a9f31aa2 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 03/47] feat(router): :sparkles: allow table aray filter in url

---
 src/router/index.ts         | 27 ++++++++++++++++++++-------
 src/typings/typeUtils.ts    | 18 +++++++++++++++++-
 src/views/DataTableView.vue |  4 ++--
 3 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/src/router/index.ts b/src/router/index.ts
index 4d72227..1bb7d1d 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -10,6 +10,7 @@ import HomeView from '@/views/HomeView.vue'
  * Other 3rd-party imports
  */
 import { useTitle } from '@vueuse/core'
+import { isNonNullish } from '@/typings/typeUtils'
 
 declare module 'vue-router' {
   interface RouteMeta {
@@ -35,15 +36,27 @@ const router = createRouter({
       name: 'data-table',
       component: () => import('@/views/DataTableView.vue'),
       props: (to) => ({
-        initialColumns: Array.isArray(to.query.columns)
-          ? to.query.columns.map((column) => column?.split(',')).flat()
-          : to.query.columns && to.query.columns.split(','),
+        initialColumnIds: Array.isArray(to.query.columns)
+          ? to.query.columns
+              .filter(isNonNullish)
+              .map((column) => column?.split(','))
+              .flat()
+          : to.query.columns?.split(','),
         initialFilters: Object.entries(to.query).reduce(
-          (initialFilters, [key, value]) => {
-            return key === 'columns' || !value
+          (initialFilters, [key, value]) =>
+            key === 'columns' || !value
               ? initialFilters
-              : { ...initialFilters, [key]: value }
-          },
+              : {
+                  ...initialFilters,
+                  [key]: Array.isArray(value)
+                    ? value
+                        .filter(isNonNullish)
+                        .map((filter) => filter?.split(','))
+                        .flat()
+                    : value.includes(',')
+                    ? value.split(',')
+                    : value
+                },
           {}
         )
       }),
diff --git a/src/typings/typeUtils.ts b/src/typings/typeUtils.ts
index 717ecb3..e520db7 100644
--- a/src/typings/typeUtils.ts
+++ b/src/typings/typeUtils.ts
@@ -34,7 +34,23 @@ export type DeepDefined<T> = T extends object
   : T
 
 /**
- * Checks if a value is defined, narrowing by excluding `undefined` if yes.
+ * Checks if a value is truthy (`!= false`), narrowing it.
+ * @param value The value to check.
+ */
+// export const isTruthy = <T>(
+//   value: T
+// ): value is Exclude<T, false | 0 | '' | null | undefined> =>
+//   !!value
+
+/**
+ * Checks if a value is not nullish (`!= null`), narrowing it.
+ * @param value The value to check.
+ */
+export const isNonNullish = <T>(value: T): value is NonNullable<T> =>
+  typeof value != null
+
+/**
+ * Checks if a value is defined, narrowing it.
  * @param value The value to check.
  */
 export const isDefined = <T>(value: T): value is Exclude<T, undefined> =>
diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 0f5c503..66081e4 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -97,9 +97,9 @@ interface ColumnGroupModel {
  */
 const props = defineProps<{
   /** The columns of the table to display initially. */
-  initialColumns?: string[]
+  initialColumnIds?: string[]
   /** The filters to apply on the table initially. */
-  initialFilters?: Record<string, any>
+  initialFilters?: Record<string, string | string[]>
 }>()
 
 /**
-- 
GitLab


From cb176ad765e1deb6428d57a072e68eddb9caaa97 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 04/47] feat(table-view): :sparkles: actually use initial
 column & filters from props

Closes #83
---
 src/views/DataTableView.vue | 77 +++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 66081e4..a7275f5 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -375,27 +375,42 @@ const columns = columnGroups.reduce<ColumnModel[]>(
 )
 
 /**
- * Columns to display at startup
+ * List of all column IDs.
  */
-const defaultColumnIds = [
-  'entryId',
-  'modificationId',
-  'modificationName',
-  'modificationPosition',
-  'modificationResult',
-  'targetId',
-  'targetName',
-  'targetType',
-  'guideId',
-  'guideName',
-  'guideType',
-  'guideChromosomeName',
-  'guideStart',
-  'guideEnd',
-  'guideLength',
-  'speciesName',
-  'speciesId'
-]
+const columnIds = columns.map((column) => column.id)
+
+/**
+ * Columns IDs to display initially (from props), filtered by keeping only those
+ * actually existing.
+ */
+const filteredInitialColumnsIds = props.initialColumnIds?.filter((columnId) =>
+  columnIds?.includes(columnId)
+)
+
+/**
+ * Columns IDs to display initially, with default value if none provided.
+ */
+const initialColumnIdsWithDefaults = filteredInitialColumnsIds
+  ? ['entryId', ...filteredInitialColumnsIds]
+  : [
+      'entryId',
+      'modificationId',
+      'modificationName',
+      'modificationPosition',
+      'modificationResult',
+      'targetId',
+      'targetName',
+      'targetType',
+      'guideId',
+      'guideName',
+      'guideType',
+      'guideChromosomeName',
+      'guideStart',
+      'guideEnd',
+      'guideLength',
+      'speciesName',
+      'speciesId'
+    ]
 
 /**
  * Columns selected by user with the MultiSelect
@@ -403,7 +418,7 @@ const defaultColumnIds = [
  * because MultiSelect v-model puts new selection at the end of the array
  */
 const selectedColumns = ref<ColumnModel[]>(
-  columns.filter((col) => defaultColumnIds.includes(col.id))
+  columns.filter((col) => initialColumnIdsWithDefaults.includes(col.id))
 )
 
 /**
@@ -437,22 +452,28 @@ const sortedSelectedColumnGroups = computed<ColumnGroupModel[]>(() =>
  * Reactive column filters object
  */
 const filters = ref<DataTableFilterMeta>(
-  columns.reduce(
-    (filters, column) => ({
+  columns.reduce((filters, column) => {
+    const thisColumnFilter = props.initialFilters?.[column.id]
+    return {
       ...filters,
       [column.field]: {
-        value: null,
+        value: thisColumnFilter
+          ? Array.isArray(thisColumnFilter)
+            ? thisColumnFilter.filter((filterValue) =>
+                column.filter?.options?.includes(filterValue)
+              )
+            : thisColumnFilter
+          : null,
         matchMode: column.filter?.matchMode
           ? column.filter?.matchMode
           : primeVueFilterMatchMode.CONTAINS
       }
-    }),
-    {}
-  )
+    }
+  }, {})
 )
 // Also set the global filter
 filters.value.global = {
-  value: null,
+  value: props.initialFilters?.global ? props.initialFilters.global : null,
   matchMode: primeVueFilterMatchMode.CONTAINS
 }
 </script>
-- 
GitLab


From 18a2b7a16cadb3229dffba9b2398da33f1557ac0 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 05/47] refactor(table-view): :recycle: enforce consistency
 between column's groupId & actual group id

---
 src/views/DataTableView.vue | 78 +++++++++++++------------------------
 1 file changed, 28 insertions(+), 50 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index a7275f5..4ee15ec 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -144,7 +144,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'entryId',
         field: 'id',
         title: 'Data entry ID',
-        groupId: 'entryId',
         single: true
       }
     ]
@@ -157,7 +156,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'modificationId',
         field: 'modification.id',
         title: 'ID',
-        groupId: 'modification',
         link: {
           routeName: 'modificationDetails',
           queryIdField: 'modification.id',
@@ -167,20 +165,17 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'modificationName',
         field: 'modification.name',
-        title: 'Name',
-        groupId: 'modification'
+        title: 'Name'
       },
       {
         id: 'modificationPosition',
         field: 'modification.position',
-        title: 'Position',
-        groupId: 'modification'
+        title: 'Position'
       },
       {
         id: 'modificationResult',
         field: 'modification.result',
         title: 'Result',
-        groupId: 'modification',
         filter: {
           matchMode: primeVueFilterMatchMode.IN,
           options: ['Am', 'Um', 'Cm', 'Gm', 'Ψ']
@@ -190,7 +185,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'modificationType',
         field: 'modification.type',
         title: 'Type',
-        groupId: 'modification',
         filter: {
           matchMode: primeVueFilterMatchMode.IN,
           options: Object.values(ModifType)
@@ -206,7 +200,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'guideId',
         field: 'guide.id',
         title: 'ID',
-        groupId: 'guide',
         link: {
           routeName: 'guideDetails',
           queryIdField: 'guide.id',
@@ -216,62 +209,52 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'guideName',
         field: 'guide.name',
-        title: 'Name',
-        groupId: 'guide'
+        title: 'Name'
       },
       {
         id: 'guideType',
         field: 'guide.type',
-        title: 'Type',
-        groupId: 'guide'
+        title: 'Type'
       },
       {
         id: 'guideSubtype',
         field: 'guide.subtype',
-        title: 'Subtype',
-        groupId: 'guide'
+        title: 'Subtype'
       },
       {
         id: 'guideChromosomeId',
         field: 'guide.parentConnection.node.id',
-        title: 'Chromosome ID',
-        groupId: 'guide'
+        title: 'Chromosome ID'
       },
       {
         id: 'guideChromosomeName',
         field: 'guide.parentConnection.node.name',
-        title: 'Chromosome name',
-        groupId: 'guide'
+        title: 'Chromosome name'
       },
       {
         id: 'guideStart',
         field: 'guide.parentConnection.start',
-        title: 'Start',
-        groupId: 'guide'
+        title: 'Start'
       },
       {
         id: 'guideEnd',
         field: 'guide.parentConnection.end',
-        title: 'End',
-        groupId: 'guide'
+        title: 'End'
       },
       {
         id: 'guideStrand',
         field: 'guide.parentConnection.strand',
-        title: 'Strand',
-        groupId: 'guide'
+        title: 'Strand'
       },
       {
         id: 'guideLength',
         field: 'guide.length',
-        title: 'Length',
-        groupId: 'guide'
+        title: 'Length'
       },
       {
         id: 'guideSequence',
         field: 'guide.seq',
-        title: 'Sequence',
-        groupId: 'guide'
+        title: 'Sequence'
       }
     ]
   },
@@ -283,7 +266,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'targetId',
         field: 'modification.target.id',
         title: 'ID',
-        groupId: 'target',
         link: {
           routeName: 'targetDetails',
           queryIdField: 'modification.target.id',
@@ -293,50 +275,42 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'targetName',
         field: 'modification.target.name',
-        title: 'Name',
-        groupId: 'target'
+        title: 'Name'
       },
       {
         id: 'targetLength',
         field: 'modification.target.length',
-        title: 'Length',
-        groupId: 'target'
+        title: 'Length'
       },
       {
         id: 'targetType',
         field: 'modification.target.type',
-        title: 'Type',
-        groupId: 'target'
+        title: 'Type'
       },
       {
         id: 'targetChromosomeId',
         field: 'modification.target.parentConnection.node.id',
-        title: 'Chromosome ID',
-        groupId: 'target'
+        title: 'Chromosome ID'
       },
       {
         id: 'targetChromosomeName',
         field: 'modification.target.parentConnection.node.name',
-        title: 'Chromosome Name',
-        groupId: 'target'
+        title: 'Chromosome Name'
       },
       {
         id: 'targetStart',
         field: 'modification.target.parentConnection.start',
-        title: 'Start',
-        groupId: 'target'
+        title: 'Start'
       },
       {
         id: 'targetEnd',
         field: 'modification.target.parentConnection.end',
-        title: 'End',
-        groupId: 'target'
+        title: 'End'
       },
       {
         id: 'targetStrand',
         field: 'modification.target.parentConnection.strand',
-        title: 'Strand',
-        groupId: 'target'
+        title: 'Strand'
       }
     ]
   },
@@ -348,7 +322,6 @@ const columnGroups: ColumnGroupModel[] = [
         id: 'speciesName',
         field: 'modification.target.genome.species.name',
         title: 'Species Name',
-        groupId: 'misc',
         link: {
           routeName: 'statistics',
           queryIdField: 'modification.target.genome.species.id',
@@ -358,12 +331,17 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'speciesId',
         field: 'modification.target.genome.species.id',
-        title: 'Species ID',
-        groupId: 'misc'
+        title: 'Species ID'
       }
     ]
   }
-]
+].map((group) => ({
+  ...group,
+  columns: group.columns.map((column) => ({
+    ...column,
+    groupId: group.id
+  }))
+}))
 
 /**
  * Array of the columns (not structured in groups),
-- 
GitLab


From 3fcfac6991d530a7ccc735b5d3450ad84beb897e Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 06/47] feat(table-view): :sparkles: make row ID column
 optional & not frozen

& rename it
---
 src/views/DataTableView.vue | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 4ee15ec..048e83e 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -137,13 +137,13 @@ const tableEntries = computed(() =>
  */
 const columnGroups: ColumnGroupModel[] = [
   {
-    title: 'Data entry ID',
-    id: 'entryId',
+    title: 'Data row ID',
+    id: 'rowId',
     columns: [
       {
-        id: 'entryId',
+        id: 'rowId',
         field: 'id',
-        title: 'Data entry ID',
+        title: 'Data row ID',
         single: true
       }
     ]
@@ -368,10 +368,10 @@ const filteredInitialColumnsIds = props.initialColumnIds?.filter((columnId) =>
 /**
  * Columns IDs to display initially, with default value if none provided.
  */
-const initialColumnIdsWithDefaults = filteredInitialColumnsIds
-  ? ['entryId', ...filteredInitialColumnsIds]
+const initialColumnIdsWithDefaults = filteredInitialColumnsIds?.length
+  ? filteredInitialColumnsIds
   : [
-      'entryId',
+      'rowId',
       'modificationId',
       'modificationName',
       'modificationPosition',
@@ -503,20 +503,16 @@ filters.value.global = {
               placeholder="Select Columns"
               display="chip"
               :max-selected-labels="3"
-              :option-disabled="(column) => column.id === 'entryId'"
               scroll-height="50vh"
             >
               <template #value>
                 <Chip
                   v-for="column in sortedSelectedColumns.slice(0, 3)"
                   :key="column.id"
-                  :class="[{ 'opacity-60': column.id === 'entryId' }, 'mr-1']"
-                  :removable="column.id === 'entryId' ? false : true"
+                  class="mr-1"
+                  removable
                   :label="`${
-                    column.single ||
-                    columnGroups.find(
-                      (columnGroup) => columnGroup.id === column.groupId
-                    )?.id === 'misc'
+                    column.single || column.groupId === 'misc'
                       ? ''
                       : columnGroups.find(
                           (columnGroup) => columnGroup.id === column.groupId
@@ -558,13 +554,11 @@ filters.value.global = {
               :key="columnGroup.id"
               :header="columnGroup.title"
               :colspan="columnGroup.columns.length"
-              :sortable="columnGroup.id === 'entryId'"
+              :sortable="columnGroup.id === 'rowId'"
               :field="columnGroup.id"
               :rowspan="columnGroup.columns[0]?.single ? 2 : 1"
-              :frozen="columnGroup.id === 'entryId'"
               :class="[
                 {
-                  'frozen-column': columnGroup.id === 'entryId',
                   'column-headers': columnGroup.columns[0]?.single
                 },
                 !columnGroup.columns[0]?.single &&
@@ -647,12 +641,7 @@ filters.value.global = {
           </Row>
         </ColumnGroup>
 
-        <Column
-          v-for="(column, index) in sortedSelectedColumns"
-          :key="index"
-          :frozen="column.id === 'entryId'"
-          :class="column.id === 'entryId' ? 'frozen-column' : ''"
-        >
+        <Column v-for="(column, index) in sortedSelectedColumns" :key="index">
           <template #body="{ data }">
             <!-- Only display something if cell content is defined -->
             <template v-if="!!_get(data, column.field)">
-- 
GitLab


From 7ddf8104910c4f448bda8af0ccc51cbd85d648da Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 07/47] feat(table-view): :sparkles: dedup table entries based
 on column selection

---
 src/views/DataTableView.vue | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 048e83e..d2ee560 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -20,7 +20,7 @@ import IconFa6SolidArrowUpRightFromSquare from '~icons/fa6-solid/arrow-up-right-
 /**
  * Other 3rd-party imports
  */
-import { get as _get } from 'lodash-es'
+import { get as _get, uniqBy as _uniqBy } from 'lodash-es'
 import { FilterMatchMode as primeVueFilterMatchMode } from 'primevue/api'
 import { useQuery } from '@urql/vue'
 /**
@@ -454,6 +454,21 @@ filters.value.global = {
   value: props.initialFilters?.global ? props.initialFilters.global : null,
   matchMode: primeVueFilterMatchMode.CONTAINS
 }
+
+/**
+ * Deduped table entries, by the values in the currently selected columns.
+ */
+const dedupedTableEntries = computed(() =>
+  _uniqBy(tableEntries.value, (entry) =>
+    sortedSelectedColumns.value
+      .map((column) => _get(entry, column.field))
+      .join('')
+  ).filter((entry) =>
+    sortedSelectedColumns.value
+      .map((column) => _get(entry, column.field))
+      .join('')
+  )
+)
 </script>
 
 <template>
@@ -467,7 +482,7 @@ filters.value.global = {
           'modification.target.name',
           'modification.target.species.name'
         ]"
-        :value="tableEntries"
+        :value="dedupedTableEntries"
         paginator
         :rows="10"
         :rows-per-page-options="[5, 10, 20, 50]"
@@ -479,6 +494,7 @@ filters.value.global = {
         scroll-height="flex"
         reorderable-columns
         column-resize-mode="expand"
+        size="small"
         :pt="{
           table: {
             style: {
-- 
GitLab


From ed3195479a7ebeb8b53aa16539aa5fcee0b60be8 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 08/47] feat(table-view): :sparkles: move link from id to name
 (modif, guide, target)

& remove link icon
---
 src/views/DataTableView.vue | 42 +++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index d2ee560..69c25bd 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -16,7 +16,6 @@ import ColumnGroup from 'primevue/columngroup'
 import Row from 'primevue/row'
 import InputText from 'primevue/inputtext'
 import DataTable from 'primevue/datatable'
-import IconFa6SolidArrowUpRightFromSquare from '~icons/fa6-solid/arrow-up-right-from-square'
 /**
  * Other 3rd-party imports
  */
@@ -155,18 +154,18 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'modificationId',
         field: 'modification.id',
-        title: 'ID',
+        title: 'ID'
+      },
+      {
+        id: 'modificationName',
+        field: 'modification.name',
+        title: 'Name',
         link: {
           routeName: 'modificationDetails',
           queryIdField: 'modification.id',
           color: 'sky'
         }
       },
-      {
-        id: 'modificationName',
-        field: 'modification.name',
-        title: 'Name'
-      },
       {
         id: 'modificationPosition',
         field: 'modification.position',
@@ -199,18 +198,18 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'guideId',
         field: 'guide.id',
-        title: 'ID',
+        title: 'ID'
+      },
+      {
+        id: 'guideName',
+        field: 'guide.name',
+        title: 'Name',
         link: {
           routeName: 'guideDetails',
           queryIdField: 'guide.id',
           color: 'lime'
         }
       },
-      {
-        id: 'guideName',
-        field: 'guide.name',
-        title: 'Name'
-      },
       {
         id: 'guideType',
         field: 'guide.type',
@@ -265,18 +264,18 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'targetId',
         field: 'modification.target.id',
-        title: 'ID',
+        title: 'ID'
+      },
+      {
+        id: 'targetName',
+        field: 'modification.target.name',
+        title: 'Name',
         link: {
           routeName: 'targetDetails',
           queryIdField: 'modification.target.id',
           color: 'amber'
         }
       },
-      {
-        id: 'targetName',
-        field: 'modification.target.name',
-        title: 'Name'
-      },
       {
         id: 'targetLength',
         field: 'modification.target.length',
@@ -484,7 +483,7 @@ const dedupedTableEntries = computed(() =>
         ]"
         :value="dedupedTableEntries"
         paginator
-        :rows="10"
+        :rows="20"
         :rows-per-page-options="[5, 10, 20, 50]"
         sort-mode="multiple"
         removable-sort
@@ -675,9 +674,6 @@ const dedupedTableEntries = computed(() =>
                 }"
               >
                 {{ _get(data, column.field) }}
-                <sup>
-                  <icon-fa6-solid-arrow-up-right-from-square class="inline" />
-                </sup>
               </RouterLink>
               <Tag
                 v-else-if="column.id === 'modificationResult'"
-- 
GitLab


From 85d6306de73400bf787c670cb7e0694297a0a128 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 09/47] feat(table-view): :sparkles: remove some fields from
 default columns

---
 src/views/DataTableView.vue | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 69c25bd..f7294e5 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -370,23 +370,17 @@ const filteredInitialColumnsIds = props.initialColumnIds?.filter((columnId) =>
 const initialColumnIdsWithDefaults = filteredInitialColumnsIds?.length
   ? filteredInitialColumnsIds
   : [
-      'rowId',
-      'modificationId',
       'modificationName',
       'modificationPosition',
       'modificationResult',
-      'targetId',
       'targetName',
       'targetType',
-      'guideId',
       'guideName',
       'guideType',
       'guideChromosomeName',
       'guideStart',
       'guideEnd',
-      'guideLength',
-      'speciesName',
-      'speciesId'
+      'speciesName'
     ]
 
 /**
-- 
GitLab


From 6572632a6b5b093f32c2defe474ab93df7767468 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 10/47] feat(table-view): :sparkles: move target between modif
 & guide

---
 src/views/DataTableView.vue | 116 ++++++++++++++++++------------------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index f7294e5..aa64b3c 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -191,6 +191,62 @@ const columnGroups: ColumnGroupModel[] = [
       }
     ]
   },
+  {
+    title: 'Target',
+    id: 'target',
+    columns: [
+      {
+        id: 'targetId',
+        field: 'modification.target.id',
+        title: 'ID'
+      },
+      {
+        id: 'targetName',
+        field: 'modification.target.name',
+        title: 'Name',
+        link: {
+          routeName: 'targetDetails',
+          queryIdField: 'modification.target.id',
+          color: 'amber'
+        }
+      },
+      {
+        id: 'targetLength',
+        field: 'modification.target.length',
+        title: 'Length'
+      },
+      {
+        id: 'targetType',
+        field: 'modification.target.type',
+        title: 'Type'
+      },
+      {
+        id: 'targetChromosomeId',
+        field: 'modification.target.parentConnection.node.id',
+        title: 'Chromosome ID'
+      },
+      {
+        id: 'targetChromosomeName',
+        field: 'modification.target.parentConnection.node.name',
+        title: 'Chromosome Name'
+      },
+      {
+        id: 'targetStart',
+        field: 'modification.target.parentConnection.start',
+        title: 'Start'
+      },
+      {
+        id: 'targetEnd',
+        field: 'modification.target.parentConnection.end',
+        title: 'End'
+      },
+      {
+        id: 'targetStrand',
+        field: 'modification.target.parentConnection.strand',
+        title: 'Strand'
+      }
+    ]
+  },
   {
     title: 'Guide',
     id: 'guide',
@@ -223,12 +279,12 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'guideChromosomeId',
         field: 'guide.parentConnection.node.id',
-        title: 'Chromosome ID'
+        title: 'Chr. ID'
       },
       {
         id: 'guideChromosomeName',
         field: 'guide.parentConnection.node.name',
-        title: 'Chromosome name'
+        title: 'Chromosome'
       },
       {
         id: 'guideStart',
@@ -257,62 +313,6 @@ const columnGroups: ColumnGroupModel[] = [
       }
     ]
   },
-  {
-    title: 'Target',
-    id: 'target',
-    columns: [
-      {
-        id: 'targetId',
-        field: 'modification.target.id',
-        title: 'ID'
-      },
-      {
-        id: 'targetName',
-        field: 'modification.target.name',
-        title: 'Name',
-        link: {
-          routeName: 'targetDetails',
-          queryIdField: 'modification.target.id',
-          color: 'amber'
-        }
-      },
-      {
-        id: 'targetLength',
-        field: 'modification.target.length',
-        title: 'Length'
-      },
-      {
-        id: 'targetType',
-        field: 'modification.target.type',
-        title: 'Type'
-      },
-      {
-        id: 'targetChromosomeId',
-        field: 'modification.target.parentConnection.node.id',
-        title: 'Chromosome ID'
-      },
-      {
-        id: 'targetChromosomeName',
-        field: 'modification.target.parentConnection.node.name',
-        title: 'Chromosome Name'
-      },
-      {
-        id: 'targetStart',
-        field: 'modification.target.parentConnection.start',
-        title: 'Start'
-      },
-      {
-        id: 'targetEnd',
-        field: 'modification.target.parentConnection.end',
-        title: 'End'
-      },
-      {
-        id: 'targetStrand',
-        field: 'modification.target.parentConnection.strand',
-        title: 'Strand'
-      }
-    ]
-  },
   {
     title: 'Miscellaneous',
     id: 'misc',
-- 
GitLab


From 8dc81aebc92dc12e924660695de5013322108ee9 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 11/47] feat(table-view): :sparkles: remove sort icon when not
 sorted

---
 src/views/DataTableView.vue | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index aa64b3c..11edeb9 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -16,6 +16,8 @@ import ColumnGroup from 'primevue/columngroup'
 import Row from 'primevue/row'
 import InputText from 'primevue/inputtext'
 import DataTable from 'primevue/datatable'
+import IconFa6SolidArrowDownShortWide from '~icons/fa6-solid/arrow-down-short-wide'
+import IconFa6SolidArrowUpShortWide from '~icons/fa6-solid/arrow-up-short-wide'
 /**
  * Other 3rd-party imports
  */
@@ -610,20 +612,16 @@ const dedupedTableEntries = computed(() =>
                 columnFilter: { style: { marginLeft: '.5ch' } }
               }"
             >
-              <!-- <template #filter>
-                <MultiSelect
-                  v-if="column.filter?.matchMode === primeVueFilterMatchMode.IN"
-                  v-model="filters[column.field].value"
-                  :options="column.filter?.options"
-                  placeholder="Chose"
-                ></MultiSelect>
-                <InputText
-                  v-else
-                  v-model="filters[column.field].value"
-                  type="text"
-                  placeholder="Type"
+              <template #sorticon="{ sortOrder }">
+                <icon-fa6-solid-arrow-up-short-wide
+                  v-if="sortOrder === 1"
+                  class="p-icon p-sortable-column-icon"
                 />
-              </template> -->
+                <icon-fa6-solid-arrow-down-short-wide
+                  v-else-if="sortOrder === -1"
+                  class="p-icon p-sortable-column-icon"
+                />
+              </template>
               <template #filter="{ filterModel, filterCallback }">
                 <MultiSelect
                   v-if="column.filter?.matchMode === primeVueFilterMatchMode.IN"
-- 
GitLab


From f59efb081013710cbf4535117059b4b1bd8c3da3 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 12/47] feat(table-view): :sparkles: scroll to table top when
 changing page

---
 src/views/DataTableView.vue | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 11edeb9..596d730 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -464,6 +464,16 @@ const dedupedTableEntries = computed(() =>
       .join('')
   )
 )
+
+/**
+ * Function to call to scroll to the top of the table.
+ */
+const scrollToTableTop = () =>
+  setTimeout(() => {
+    document
+      .getElementById('data-table')
+      ?.scrollTo({ top: 0, behavior: 'smooth' })
+  }, 10)
 </script>
 
 <template>
@@ -491,6 +501,9 @@ const dedupedTableEntries = computed(() =>
         column-resize-mode="expand"
         size="small"
         :pt="{
+          wrapper: {
+            id: 'data-table'
+          },
           table: {
             style: {
               borderCollapse: 'separate'
@@ -502,6 +515,7 @@ const dedupedTableEntries = computed(() =>
             }
           }
         }"
+        @page="scrollToTableTop"
       >
         <template #header>
           <div class="flex justify-between">
-- 
GitLab


From 3d536d3aa2518928ef3aeb1f1ca16728a5abb2b0 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 13/47] feat(utils): :sparkles: add formatted guide subtype
 options

---
 src/utils/textFormatting.ts | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/utils/textFormatting.ts b/src/utils/textFormatting.ts
index 421c2ab..8083781 100644
--- a/src/utils/textFormatting.ts
+++ b/src/utils/textFormatting.ts
@@ -43,8 +43,14 @@ export const formatGuideSubtype = (guideSubtype?: GuideType) => {
     case GuideType.Haca:
       return 'H/ACA box'
 
+    case GuideType.Other:
+      return 'Other'
+
+    case GuideType.ScaRna:
+      return 'scaRNA'
+
     default:
-      return 'UNKNOWN_TYPE'
+      return 'Unknown Type'
   }
 }
 
-- 
GitLab


From dc8d533048fd147c825ebfa554d44595a1c83c0a Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 14/47] refactor: :recycle: use v-bind shorthand (:) everywhere

---
 src/layouts/MainLayout.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 7e92a41..d163680 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -69,10 +69,10 @@ const menuItems: CustomMenuItem[] = [
           <RouterLink
             v-if="item.routerDest"
             :to="item.routerDest"
-            v-bind="props.action"
+            :="props.action"
           >
-            <component :is="item.iconComponent || ''" v-bind="props.icon" />
-            <span v-bind="props.label">{{ item.label }}</span>
+            <component :is="item.iconComponent || ''" :="props.icon" />
+            <span :="props.label">{{ item.label }}</span>
           </RouterLink>
         </template>
       </Menubar>
-- 
GitLab


From 1e1756f7c3a02dc1ba53a3e2bac45584f9a4e401 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 15/47] refactor(layouts): :fire: remove useless icon name

---
 src/layouts/MainLayout.vue | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index d163680..be6875d 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -29,25 +29,21 @@ interface CustomMenuItem extends MenuItem {
 const menuItems: CustomMenuItem[] = [
   {
     label: 'Data Table',
-    icon: 'icon-fas-table',
     iconComponent: IconFa6SolidTable,
     routerDest: { name: 'data-table' }
   },
   {
     label: 'API',
-    icon: 'icon-fas-database',
     iconComponent: IconFa6SolidDatabase,
     routerDest: { name: 'api' }
   },
   {
     label: 'Help',
-    icon: 'icon-fas-circle-question',
     iconComponent: IconFa6SolidCircleQuestion,
     routerDest: { name: 'about' }
   },
   {
     label: 'Contact',
-    icon: 'icon-fas-address-card',
     iconComponent: IconFa6SolidAddressCard,
     routerDest: { name: 'contact' }
   }
-- 
GitLab


From 60432cfad07dd21982da10a84954728db45e0128 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 16/47] feat(assets): :bento: add custom icons for guide &
 modification

---
 src/assets/icons/guide.svg          |  6 ++++++
 src/assets/icons/list-check-all.svg | 18 ++++++++++++++++++
 src/assets/icons/modification.svg   | 11 +++++++++++
 vite.config.ts                      |  6 +++++-
 4 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 src/assets/icons/guide.svg
 create mode 100644 src/assets/icons/list-check-all.svg
 create mode 100644 src/assets/icons/modification.svg

diff --git a/src/assets/icons/guide.svg b/src/assets/icons/guide.svg
new file mode 100644
index 0000000..37926f8
--- /dev/null
+++ b/src/assets/icons/guide.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
+   <path
+      style="fill:currentColor"
+      d="M414.05 9.959c-53.716 0-97.949 44.232-97.948 97.95a32.003 32.003 0 0 0 0 .034c.003 2.659.142 5.31.36 7.954l-38.91 38.91c-19.775-8.134-40.998-12.444-62.544-12.45a32.003 32.003 0 0 0-.01 0c-90.529.001-164.602 74.076-164.602 164.604a32.003 32.003 0 0 0 .002.156c.099 20 3.915 39.717 11.045 58.256l-52.07 52.07a32 32 0 0 0 0 45.254 32 32 0 0 0 45.254 0l67.906-67.906a32.003 32.003 0 0 0 5.147-38.52 100.593 100.593 0 0 1-13.28-49.402c.05-55.893 44.686-100.506 100.59-100.512a100.593 100.593 0 0 1 52.287 14.672 32.003 32.003 0 0 0 39.268-4.707l66.953-66.95a32.003 32.003 0 0 0 8.03-31.802c-.94-3.14-1.419-6.4-1.424-9.677.008-19.121 14.824-33.934 33.947-33.934 19.128 0 33.95 14.82 33.949 33.95 0 19.114-14.801 33.924-33.91 33.945a33.983 33.983 0 0 1-4.979-.385 32.003 32.003 0 0 0-27.45 9.008l-72.01 72.01a32.003 32.003 0 0 0-5.674 37.56 100.602 100.602 0 0 1 11.627 46.922c-.005 55.905-44.618 100.54-100.512 100.59a100.593 100.593 0 0 1-49.405-13.28 32.003 32.003 0 0 0-38.519 5.147L79.18 447.414a32 32 0 0 0 0 45.254 32 32 0 0 0 45.256 0l32.152-32.152c18.538 7.13 38.255 10.948 58.254 11.046a32.003 32.003 0 0 0 .156 0c90.528.001 164.603-74.073 164.604-164.601a32.003 32.003 0 0 0 0-.002 32.003 32.003 0 0 0 0-.002 32.003 32.003 0 0 0 0-.002 32.003 32.003 0 0 0 0-.002 32.003 32.003 0 0 0 0-.002c-.005-18.633-3.244-37.049-9.385-54.52l46.72-46.722c52.395-1.563 95.064-45.058 95.063-97.8 0-53.718-44.232-97.95-97.95-97.95Z"
+   />
+</svg>
\ No newline at end of file
diff --git a/src/assets/icons/list-check-all.svg b/src/assets/icons/list-check-all.svg
new file mode 100644
index 0000000..d63af41
--- /dev/null
+++ b/src/assets/icons/list-check-all.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
+    <g>
+        <path fill="currentColor"
+            d="M152.1 38.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7l -40.1 -40c-9.3-9.4-9.3-24.6 0-34s24.6-9.4 33.9 0l22.1 22.1l55.1-61.2c8.9-9.9 24-10.7 33.9-1.8z" />
+        <path fill="currentColor"
+            d="M152.1 198.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7l -40.1 -40c-9.3-9.4-9.3-24.6 0-34s24.6-9.4 33.9 0l22.1 22.1l55.1-61.2c8.9-9.9 24-10.7 33.9-1.8z" />
+        <path fill="currentColor"
+            d="M152.1 358.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7l -40.1 -40c-9.3-9.4-9.3-24.6 0-34s24.6-9.4 33.9 0l22.1 22.1l55.1-61.2c8.9-9.9 24-10.7 33.9-1.8z" />
+    </g>
+    <g>
+        <path fill="currentColor"
+            d="M224 96c0-17.7 14.3-32 32-32h224c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32z" />
+        <path fill="currentColor"
+            d="M224 256c0-17.7 14.3-32 32-32h224c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32z" />
+        <path fill="currentColor"
+            d="M224 416c0-17.7 14.3-32 32-32h224c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32z" />
+    </g>
+</svg>
\ No newline at end of file
diff --git a/src/assets/icons/modification.svg b/src/assets/icons/modification.svg
new file mode 100644
index 0000000..cb196bf
--- /dev/null
+++ b/src/assets/icons/modification.svg
@@ -0,0 +1,11 @@
+<svg width="1em" height="1em" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
+
+    <path
+        style="fill:currentColor"
+        d="M56.8 267.5q-17.2-.7-27-8.2-9.9-7.6-13-22.3l-5-24.2 5.9 2H.5l-1.3-6q8.4-6.2 17.5-6.2 6.6 0 10.6 3.7 4.1 3.5 5.4 10.2l2.8 15.4q1.6 9.3 4.4 15 2.8 5.4 7.2 8 4.3 2.5 10.6 3.1h11q4-.3 7-1 3-.8 5.7-2.5 1.4-1.4 3-4.8 1.5-3.4 3-8.2 1.3-4.8 2.3-9.6l3-15.4q1.2-6.7 5.1-10.2 4-3.7 10-3.7 9.2 0 17.5 6.2l-1.2 6h-17.2l5.9-2-5 24q-3.2 14.8-13.2 22.3-10 7.6-27.3 8.4zm-16.3 28.2-.9-4.4q2.8-1.7 6-3.2 3.3-1.7 7.9-3.4l.1 11zm25.7 0 .4-9.9 19.3 2.8-.1 7.1zm-14.5 0v-92h21.2v92zm8.5-82-19.3-2.8.1-7.1h19.6zm10.8 1.1-.2-11h12.7l.9 4.4-6.7 3.5q-3 1.6-6.7 3.1zm60 100.9-5.4-6.5q4.2-3.7 6.7-7.7 2.7-4 2.8-7.7l-7.4-6q.9-5.2 3.8-8.7 3-3.6 7.3-5.9 6.3 2.3 9.3 6.6 3.1 4.2 3.1 9.2 0 5-2.7 10.1-2.6 5.2-7.2 9.5t-10.4 7.1z"
+        transform="translate(1.7 -441.4) scale(2.2456)" />
+    <path
+        style="fill:currentColor"
+        d="m272 272.7-53.4-81.9.3-11.7h17l51.2 80-1.4 9.3zm-68.5-1.7-.9-4.4q3.1-2 6.6-3.5 3.7-1.7 7.3-3.1l.1 11zm18.9 0 .4-9.9L242 264l-.2 7.1zm-7.9 0v-92H236l-9.8 12.8 3.7 30.5V271zm8.4-82-18.2-2.8.2-7.1h18.4zm49 83.7 9.3-8L277 229v-50h15.3l-.6 92zm10.7-83.7-19.3-2.8.2-7.1H283zm7.1 1.1-.1-11h13.1l.9 4.4q-3.1 1.9-6.6 3.5-3.5 1.6-7.3 3.1zm27 80.9v-62.3L330 202l7 6.7V271zm41.5 0v-40.4q0-7-2.5-10.4-2.5-3.4-6.8-3.3-3 .2-6.7 1.9-3.7 1.5-7.4 3.9-3.8 2.2-7.2 4.9l-1.4-4.5q6.2-5.5 12.2-9.6 6.1-4.4 11.6-7.2 5.4-3 9.6-3.9 2.7.1 6 1.3 3.1 1 6.2 3.2 3 2 4.9 5.3.7 1.1 1.1 3 .4 2 .6 5.4l.1 9V271zm41.7 0v-40.4q0-7-2.5-10.4-2.5-3.4-6.9-3.3-3 .2-6.7 1.9-3.6 1.5-7.4 3.9-3.8 2.2-7.1 4.9l-1.4-4.5q6.1-5.5 12.1-9.6 6.2-4.4 11.6-7.2 5.5-3 9.7-3.9 2.6.1 5.9 1.3 3.2 1 6.3 3.2 3 2 4.8 5.3.7 1.1 1.2 3 .4 2 .5 5.4.2 3.3.2 9V271zm-93.7-57.4-1-6.7q5.5-2.1 12-3.4 6.5-1.2 12.8-1.5l.6 7.8-9.1 5.6zm.7 57.4-.4-4.7q3.5-2.1 8-3.6 4.6-1.7 8-2.6l-1.4 11zm20 0 2.4-12.7q4.2.9 8.4 2.4 4.3 1.4 7.7 3.5l-.6 6.8zm24.2 0-.4-4.7q3.5-2.1 8-3.6 4.6-1.7 8-2.6l-1.5 11zm17.5 0 2.4-12.7q4.2.9 8.5 2.4 4.5 1.4 7.8 3.5l-.5 6.8zm24.2 0-.5-4.7q3.5-2.1 8-3.6 4.6-1.7 8.1-2.6l-1.5 11zm18 0 2.4-12.7q4 .9 9 2.4 5.1 1.4 8.5 3.5l-.6 6.8z"
+        transform="translate(-455 -114) scale(2.2456)" />
+</svg>
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index f1a9f90..14d1664 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -4,6 +4,7 @@ import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import { visualizer } from 'rollup-plugin-visualizer'
 import Icons from 'unplugin-icons/vite'
+import { FileSystemIconLoader } from 'unplugin-icons/loaders'
 
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -12,7 +13,10 @@ export default defineConfig({
     Icons({
       autoInstall: true,
       scale: 1,
-      compiler: 'vue3'
+      compiler: 'vue3',
+      customCollections: {
+        snoboard: FileSystemIconLoader('src/assets/icons')
+      }
     }),
     visualizer({
       template: 'raw-data',
-- 
GitLab


From 83888efc9ab751701be62e9199a46fbc1f0f3e78 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 17/47] feat(table-view): :sparkles: use options (multiselect)
 for guide subtype filter

---
 src/views/DataTableView.vue | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 596d730..82d4552 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -31,7 +31,7 @@ import type {
   DataTableFilterMeta,
   DataTableFilterMetaData
 } from 'primevue/datatable'
-import { ModifType } from '@/gql/codegen/graphql'
+import { GuideType, ModifType } from '@/gql/codegen/graphql'
 /**
  * Utils imports
  */
@@ -276,7 +276,11 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'guideSubtype',
         field: 'guide.subtype',
-        title: 'Subtype'
+        title: 'Subtype',
+        filter: {
+          matchMode: primeVueFilterMatchMode.IN,
+          options: Object.values(GuideType)
+        }
       },
       {
         id: 'guideChromosomeId',
@@ -644,11 +648,14 @@ const scrollToTableTop = () =>
                   placeholder="Chose"
                   @change="filterCallback()"
                 >
-                  <template
-                    v-if="column.id === 'modificationType'"
-                    #option="{ option }"
-                  >
-                    <FormattedModificationType :type-code="option" />
+                  <template #option="{ option }">
+                    <FormattedModificationType
+                      v-if="column.id === 'modificationType'"
+                      :type-code="option"
+                    />
+                    <span v-else-if="column.id === 'guideSubtype'">
+                      {{ formatGuideSubtype(option) }}
+                    </span>
                   </template>
                 </MultiSelect>
                 <InputText
-- 
GitLab


From 36628fcc277218b77311485062eef2c932462ff3 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 18/47] feat(table-view): :sparkles: prettify multiselect's
 value for 'IN' filters

---
 src/views/DataTableView.vue | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 82d4552..d00a909 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -657,6 +657,31 @@ const scrollToTableTop = () =>
                       {{ formatGuideSubtype(option) }}
                     </span>
                   </template>
+
+                  <template #value="{ value: selection }">
+                    <template v-if="selection">
+                      <template
+                        v-for="(selected, selIndex) in column.filter?.options
+                          ?.filter((option) => selection.includes(option))
+                          .slice(0, 3)"
+                        :key="selIndex"
+                      >
+                        <FormattedModificationType
+                          v-if="column.id === 'modificationType'"
+                          :type-code="selected"
+                        />
+                        <span v-else-if="column.id === 'guideSubtype'">
+                          {{ formatGuideSubtype(selected) }}
+                        </span>
+                        <span v-else>{{ selected }}</span>
+                        <span v-if="selIndex !== selection.length - 1">, </span>
+                      </template>
+
+                      <span v-if="selection.length > 3">
+                        +{{ selection.length - 3 }}...
+                      </span>
+                    </template>
+                  </template>
                 </MultiSelect>
                 <InputText
                   v-else
-- 
GitLab


From 32a0f1c58a62a70f28d4aa1f126f5fe6d28130b0 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 19/47] fix(table-view): :bug: error when passing 'IN' filter
 through url

when a single value was passed with url to 'IN' filters, being a string instead of an array it resulted in an error
---
 src/views/DataTableView.vue | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index d00a909..801b663 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -436,7 +436,9 @@ const filters = ref<DataTableFilterMeta>(
       [column.field]: {
         value: thisColumnFilter
           ? Array.isArray(thisColumnFilter)
-            ? thisColumnFilter.filter((filterValue) =>
+            ? thisColumnFilter
+            : column.filter?.matchMode === primeVueFilterMatchMode.IN
+            ? [thisColumnFilter].filter((filterValue) =>
                 column.filter?.options?.includes(filterValue)
               )
             : thisColumnFilter
-- 
GitLab


From 86b384287e6beffb3516cfc8732727b172fc1e39 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:37 +0200
Subject: [PATCH 20/47] feat(home-view): :sparkles: rework landing page
 navigation

use a menubar with quick links instead of buttons
---
 src/views/HomeView.vue | 394 +++++++++++++++++++++++++++++++++++------
 1 file changed, 338 insertions(+), 56 deletions(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 9ff1e67..ee10c33 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -2,21 +2,34 @@
 /**
  * Vue imports
  */
-import { computed, ref } from 'vue'
+import { computed } from 'vue'
 /**
  * Components imports
  */
 import Image from 'primevue/image'
-import Button from 'primevue/button'
+import Menubar from 'primevue/menubar'
 import SearchBar from '@/components/SearchBar.vue'
-import BaseRadioFieldset from '@/components/BaseRadioFieldset.vue'
+import FormattedModificationType from '@/components/FormattedModificationType.vue'
 import IconFa6SolidMagnifyingGlass from '~icons/fa6-solid/magnifying-glass'
 import IconFa6SolidCircleXmark from '~icons/fa6-solid/circle-xmark'
 import IconFa6SolidArrowRight from '~icons/fa6-solid/arrow-right'
+import IconFa6SolidChevronDown from '~icons/fa6-solid/chevron-down'
+import IconFa6SolidChevronRight from '~icons/fa6-solid/chevron-right'
+import IconFa6SolidSliders from '~icons/fa6-solid/sliders'
+import IconFa6SolidTable from '~icons/fa6-solid/table'
+import IconFa6SolidDatabase from '~icons/fa6-solid/database'
+import IconFa6SolidPaw from '~icons/fa6-solid/paw'
+import IconFa6SolidBullseye from '~icons/fa6-solid/bullseye'
+import IconSnoboardGuide from '~icons/snoboard/guide'
+import IconSnoboardModification from '~icons/snoboard/modification'
 /**
  * Other 3rd-party imports
  */
 import { useQuery } from '@urql/vue'
+/**
+ * Types imports.
+ */
+import type { MenuItem } from 'primevue/menuitem'
 /**
  * Utils imports
  */
@@ -26,6 +39,51 @@ import { speciesListQuery } from '@/gql/queries'
  * Assets imports
  */
 import logoUrl from '@/assets/images/logo.svg'
+import { GuideType, ModifType } from '@/gql/codegen/graphql'
+import { formatGuideSubtype } from '@/utils/textFormatting'
+import { isInEnum } from '@/typings/typeUtils'
+import tailwindDefaultColors from 'tailwindcss/colors'
+
+/**
+ * Useful columns to show to list guides in the table.
+ */
+const LIST_GUIDES_TABLE_COLUMNS = [
+  'guideId',
+  'guideName',
+  'guideType',
+  'guideSubtype',
+  'guideChromosomeName',
+  'guideLength',
+  'speciesName',
+  'speciesId'
+]
+
+/**
+ * Useful columns to show to list modifications in the table.
+ */
+const LIST_MODIFICATIONS_TABLE_COLUMNS = [
+  'modificationId',
+  'modificationName',
+  'modificationPosition',
+  'modificationResult',
+  'modificationType',
+  'targetName',
+  'speciesName',
+  'speciesId'
+]
+
+/**
+ * Useful columns to show to list modifications in the table.
+ */
+const LIST_TARGETS_TABLE_COLUMNS = [
+  'targetId',
+  'targetName',
+  'targetLength',
+  'targetType',
+  'targetChromosomeName',
+  'speciesName',
+  'speciesId'
+]
 
 /**
  * Reactive urql GraphQL query object, updated with query state & response
@@ -38,12 +96,196 @@ const gqlQuery = useQuery({
  * The list of all the species present in the database,
  * reactively updated when fetched
  */
-const speciesList = computed(() => gqlQuery.data.value?.manySpecies)
+const speciesList = computed(() =>
+  gqlQuery.data.value?.manySpecies.map((species) => ({
+    ...species,
+    name: formatSpeciesName(species.name)
+  }))
+)
 
 /**
- *  The currently selected species
+ * Menu items.
  */
-const selectedSpeciesId = ref<number>()
+const menuItems: MenuItem[] = [
+  {
+    label: 'Guides',
+    items: [
+      {
+        label: 'All guides',
+        route: {
+          name: 'data-table',
+          query: {
+            columns: LIST_GUIDES_TABLE_COLUMNS
+          }
+        },
+        iconComponent: IconFa6SolidTable
+      },
+      ...Object.values(GuideType)
+        .filter((guideType) => guideType !== GuideType.Other)
+        .map((guideType) => ({
+          label: formatGuideSubtype(guideType),
+          indent: 1,
+          route: {
+            name: 'data-table',
+            query: {
+              columns: LIST_GUIDES_TABLE_COLUMNS,
+              guideSubtype: guideType
+            }
+          }
+        })),
+      {
+        label: 'Advanced guide selection',
+        route: {
+          // name: 'data-selection',
+          // query: {
+          //   type: 'guide'
+          // }
+        },
+        iconComponent: IconFa6SolidSliders
+      }
+    ]
+  },
+  {
+    label: 'Modifications',
+    items: [
+      {
+        label: 'All modifications',
+        route: {
+          name: 'data-table',
+          query: {
+            columns: LIST_MODIFICATIONS_TABLE_COLUMNS
+          }
+        },
+        iconComponent: IconFa6SolidTable
+      },
+      ...Object.values(ModifType)
+        .filter((modificationType) => modificationType !== ModifType.Other)
+        .map((modificationType) => ({
+          label: modificationType,
+          indent: 1,
+          route: {
+            name: 'data-table',
+            query: {
+              columns: LIST_MODIFICATIONS_TABLE_COLUMNS,
+              modificationType: modificationType
+            }
+          }
+        })),
+      {
+        label: 'Advanced modification selection',
+        route: {
+          // name: 'data-selection',
+          // query: {
+          //   type: 'modification'
+          // }
+        },
+        iconComponent: IconFa6SolidSliders
+      }
+    ]
+  },
+  {
+    label: 'Targets',
+    items: [
+      {
+        label: 'All targets',
+        route: {
+          name: 'data-table',
+          query: {
+            columns: LIST_TARGETS_TABLE_COLUMNS
+          }
+        },
+        iconComponent: IconFa6SolidTable
+      },
+      // ...Object.values(ModifType)
+      //   .filter((modificationType) => modificationType !== ModifType.Other)
+      //   .map((modificationType) => ({
+      //     label: modificationType,
+      //     indent: 1,
+      //     route: {
+      //       name: 'data-table',
+      //       query: {
+      //         columns: LIST_TARGETS_TABLE_COLUMNS,
+      //         guideSubtype: modificationType
+      //       }
+      //     }
+      //   })),
+      {
+        label: 'Advanced target selection',
+        route: {
+          // name: 'data-selection',
+          // query: {
+          //   type: 'target'
+          // }
+        },
+        iconComponent: IconFa6SolidSliders
+      }
+    ]
+  },
+  {
+    label: 'spacer',
+    separator: true
+  },
+  {
+    label: 'Conservation',
+    items: [
+      {
+        label: 'Modifications',
+        route: {
+          // name: 'conservation',
+          // query: {
+          //   type: 'modification'
+          // }
+        },
+        iconComponent: IconSnoboardModification
+      },
+      {
+        label: 'Guides',
+        route: {
+          // name: 'conservation',
+          // query: {
+          //   type: 'modification'
+          // }
+        },
+        iconComponent: IconSnoboardGuide
+      },
+      {
+        label: 'Targets',
+        route: {
+          // name: 'conservation',
+          // query: {
+          //   type: 'modification'
+          // }
+        },
+        iconComponent: IconFa6SolidBullseye
+      }
+    ]
+  },
+  {
+    label: 'Statistics',
+    items: [
+      {
+        label: 'Database-wide',
+        route: {
+          name: 'statistics'
+        },
+        iconComponent: IconFa6SolidDatabase
+      },
+      {
+        label: 'By organism',
+        items: speciesList.value?.map((species) => ({
+          label: species.name,
+          route: {
+            name: 'statistics',
+            query: {
+              id: species.id
+            }
+          }
+        })),
+        iconComponent: IconFa6SolidPaw
+      }
+    ]
+  }
+]
 </script>
 
 <template>
@@ -54,7 +296,7 @@ const selectedSpeciesId = ref<number>()
       :src="logoUrl"
     />
 
-    <SearchBar disabled class="mx-auto mb-8 max-w-xl 2xl:mb-16">
+    <SearchBar disabled class="mx-auto mb-16 max-w-xl 2xl:mb-16">
       <template #icon="{ className }">
         <icon-fa6-solid-magnifying-glass :class="className" />
       </template>
@@ -80,55 +322,95 @@ const selectedSpeciesId = ref<number>()
       </template>
     </SearchBar>
 
-    <div class="grid grid-rows-3 gap-8 sm:grid-cols-3 sm:grid-rows-none">
-      <form class="relative rounded-lg border-2 border-solid p-2 pl-0 pt-4">
-        <BaseRadioFieldset
-          v-if="speciesList"
-          class="mb-2 max-h-[35vh] overflow-auto"
-          legend="Species"
-          :values="speciesList"
-          data-field-path="id"
-          label-field-path="name"
-          @change="(speciesId: number) => (selectedSpeciesId = speciesId)"
-        >
-          <template #item-label="{ currentValue }">
-            <span class="italic">
-              {{ formatSpeciesName(currentValue.name) }}
-            </span>
-          </template>
-        </BaseRadioFieldset>
-        <!-- <Button
-          type="reset"
-          size="small"
-          @click="selectedSpeciesId = undefined"
-        >
-          Clear
-        </Button> -->
-      </form>
-
-      <div class="grid grid-rows-[1fr_min-content_1fr] items-center">
-        <h3>Select a species to browse its particular data...</h3>
-        <RouterLink
-          :class="[!selectedSpeciesId && 'pointer-events-none', 'my-4']"
-          :to="{ name: 'statistics', query: { id: selectedSpeciesId || 0 } }"
-        >
-          <Button
-            class="inline-flex h-48 w-48 justify-center"
-            :disabled="selectedSpeciesId === undefined"
-          >
-            Select a species to inspect its statistics
-          </Button>
-        </RouterLink>
-        <h3>...or leave it clear to browse all</h3>
-      </div>
-
-      <div class="flex items-center justify-center">
-        <RouterLink :to="{ name: 'data-table' }">
-          <Button class="inline-flex h-48 w-48 justify-center"
-            >Browse all data</Button
-          >
-        </RouterLink>
-      </div>
+    <div class="flex justify-center">
+      <Menubar
+        :model="menuItems"
+        :pt="{
+          submenu: {
+            style: {
+              minWidth: 'max-content'
+            }
+          },
+          separator: {
+            style: {
+              margin: '0 1rem',
+              border: `solid ${tailwindDefaultColors['slate'][300]} 1px`,
+              height: '3rem',
+              borderRadius: '999999px'
+            }
+          }
+        }"
+      >
+        <template #item="{ item, props, hasSubmenu, root }">
+          <span :class="[{ 'font-normal': item.indent }]">
+            <RouterLink
+              v-if="item.route && !hasSubmenu"
+              :to="item.route"
+              custom
+              #="{ href, navigate }"
+            >
+              <a :href="href" :="props.action" @click="navigate">
+                <component
+                  :is="item.iconComponent || ''"
+                  v-if="item.iconComponent"
+                  :="props.icon"
+                />
+                <span
+                  v-if="item.indent"
+                  class="mr-2"
+                  :style="{ paddingLeft: `${item.indent}rem` }"
+                >
+                  &rarr;
+                </span>
+                <FormattedModificationType
+                  v-if="
+                    typeof item.label === 'string' &&
+                    isInEnum(item.label, ModifType)
+                  "
+                  :type-code="item.label"
+                />
+                <span v-else>{{ item.label }}</span>
+              </a>
+            </RouterLink>
+            <a
+              v-else
+              :href="item.url"
+              :target="item.target"
+              :="props.action"
+              class="flex"
+            >
+              <component
+                :is="item.iconComponent || ''"
+                v-if="item.iconComponent"
+                :="props.icon"
+              />
+              <span
+                v-if="item.indent"
+                class="mr-2"
+                :style="{ paddingLeft: `${item.indent}rem` }"
+              >
+                &rarr;
+              </span>
+              <FormattedModificationType
+                v-if="
+                  typeof item.label === 'string' &&
+                  isInEnum(item.label, ModifType)
+                "
+                :type-code="item.label"
+              />
+              <span v-else>{{ item.label }}</span>
+              <icon-fa6-solid-chevron-down
+                v-if="hasSubmenu && root"
+                :="props.submenuicon"
+              />
+              <icon-fa6-solid-chevron-right
+                v-else-if="hasSubmenu"
+                :="props.submenuicon"
+              />
+            </a>
+          </span>
+        </template>
+      </Menubar>
     </div>
   </main>
 </template>
-- 
GitLab


From cbbb4a64a4fcfdd66c0baddb881db84935762f50 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:43:38 +0200
Subject: [PATCH 21/47] feat(table-view): :sparkles: allow for asynchronous
 filter options fetching

---
 src/views/DataTableView.vue | 151 ++++++++++++++++++++++++++----------
 1 file changed, 109 insertions(+), 42 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 801b663..2f5f6d0 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { ref, computed } from 'vue'
+import { ref, computed, watchEffect } from 'vue'
 /**
  * Components imports
  */
@@ -27,10 +27,7 @@ import { useQuery } from '@urql/vue'
 /**
  * Types imports
  */
-import type {
-  DataTableFilterMeta,
-  DataTableFilterMetaData
-} from 'primevue/datatable'
+import type { DataTableFilterMetaData } from 'primevue/datatable'
 import { GuideType, ModifType } from '@/gql/codegen/graphql'
 /**
  * Utils imports
@@ -75,8 +72,6 @@ interface ColumnModel {
   groupId?: string
   /** Wether the column is the only one in its group */
   single?: boolean
-  /** The filter type to apply to the column */
-  filter?: ColumnFilterModel
   /** If the column should be represented as a link, the link representation */
   link?: ColumnLinkModel
 }
@@ -176,20 +171,12 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'modificationResult',
         field: 'modification.result',
-        title: 'Result',
-        filter: {
-          matchMode: primeVueFilterMatchMode.IN,
-          options: ['Am', 'Um', 'Cm', 'Gm', 'Ψ']
-        }
+        title: 'Result'
       },
       {
         id: 'modificationType',
         field: 'modification.type',
-        title: 'Type',
-        filter: {
-          matchMode: primeVueFilterMatchMode.IN,
-          options: Object.values(ModifType)
-        }
+        title: 'Type'
       }
     ]
   },
@@ -276,11 +263,7 @@ const columnGroups: ColumnGroupModel[] = [
       {
         id: 'guideSubtype',
         field: 'guide.subtype',
-        title: 'Subtype',
-        filter: {
-          matchMode: primeVueFilterMatchMode.IN,
-          options: Object.values(GuideType)
-        }
+        title: 'Subtype'
       },
       {
         id: 'guideChromosomeId',
@@ -425,27 +408,62 @@ const sortedSelectedColumnGroups = computed<ColumnGroupModel[]>(() =>
     }))
 )
 
+/**
+ * Filter for fields with specific filtering strategy, i.e. different from
+ * `CONTAINS`.
+ * @description Needs to be reactive as some `filter.options` are fetched from
+ * the API (e.g. the species names list).\
+ * Then, only this `option` field may actually change (so not every dependence
+ * of this object needs to be reactive, only those depending on `options`).
+ */
+const specificFilterConfigs = computed<{
+  [columnId: string]: { columnField: string; filter: ColumnFilterModel }
+}>(() => ({
+  modificationResult: {
+    columnField:
+      columns.find((column) => column.id == 'modificationResult')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: ['Am', 'Um', 'Cm', 'Gm', 'Ψ']
+    }
+  },
+  modificationType: {
+    columnField:
+      columns.find((column) => column.id == 'modificationType')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: Object.values(ModifType)
+    }
+  },
+  guideSubtype: {
+    columnField:
+      columns.find((column) => column.id == 'guideSubtype')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: Object.values(GuideType)
+    }
+  },
+
 /**
  * Reactive column filters object
  */
-const filters = ref<DataTableFilterMeta>(
+const filters = ref<{ [columnField: string]: DataTableFilterMetaData }>(
   columns.reduce((filters, column) => {
-    const thisColumnFilter = props.initialFilters?.[column.id]
+    const columnInitialFilter = props.initialFilters?.[column.id]
     return {
       ...filters,
       [column.field]: {
-        value: thisColumnFilter
-          ? Array.isArray(thisColumnFilter)
-            ? thisColumnFilter
-            : column.filter?.matchMode === primeVueFilterMatchMode.IN
-            ? [thisColumnFilter].filter((filterValue) =>
-                column.filter?.options?.includes(filterValue)
-              )
-            : thisColumnFilter
-          : null,
-        matchMode: column.filter?.matchMode
-          ? column.filter?.matchMode
-          : primeVueFilterMatchMode.CONTAINS
+        matchMode:
+          specificFilterConfigs.value[column.id]?.filter.matchMode ||
+          primeVueFilterMatchMode.CONTAINS,
+        value: !columnInitialFilter
+          ? null
+          : specificFilterConfigs.value[column.id]?.filter.matchMode !==
+            primeVueFilterMatchMode.IN
+          ? columnInitialFilter
+          : Array.isArray(columnInitialFilter)
+          ? columnInitialFilter
+          : [columnInitialFilter]
       }
     }
   }, {})
@@ -456,6 +474,50 @@ filters.value.global = {
   matchMode: primeVueFilterMatchMode.CONTAINS
 }
 
+/**
+ * Watcher to filter filter with specific configs values when options are
+ * fetched.
+ */
+watchEffect(() => {
+  Object.values(specificFilterConfigs.value).forEach((specificFilterConfig) => {
+    // Don't modify filter value if not of type `IN` or if options are not ready
+    // (fetched) yet (as an array)
+    const specificFilterOptions = specificFilterConfig.filter.options
+    if (
+      specificFilterConfig.filter.matchMode !== primeVueFilterMatchMode.IN ||
+      !(Array.isArray(specificFilterOptions) && specificFilterOptions.length)
+    ) {
+      return
+    }
+
+    // Get the actual filter matching the currently processed config
+    const correspondingFilter = filters.value[specificFilterConfig.columnField]
+    if (
+      !(correspondingFilter?.value && Array.isArray(correspondingFilter.value))
+    )
+      return
+
+    // Get type of the options (i.e. type of the value of the column the filter
+    // applies to)
+    const filterOptionType = typeof specificFilterOptions[0]
+    // Cast current filter value to options' type
+    const castCorrespondingFilterValue =
+      filterOptionType === 'number'
+        ? correspondingFilter.value.map((filterValue) =>
+            parseFloat(filterValue)
+          )
+        : filterOptionType === 'boolean'
+        ? correspondingFilter.value.map((filterValue) => filterValue === 'true')
+        : correspondingFilter.value
+
+    // Keep only value available in options
+    correspondingFilter.value = castCorrespondingFilterValue.filter(
+      (correspondingFilterValue) =>
+        specificFilterConfig.filter.options?.includes(correspondingFilterValue)
+    )
+  })
+})
+
 /**
  * Deduped table entries, by the values in the currently selected columns.
  */
@@ -644,9 +706,12 @@ const scrollToTableTop = () =>
               </template>
               <template #filter="{ filterModel, filterCallback }">
                 <MultiSelect
-                  v-if="column.filter?.matchMode === primeVueFilterMatchMode.IN"
+                  v-if="
+                    specificFilterConfigs[column.id]?.filter.matchMode ===
+                    primeVueFilterMatchMode.IN
+                  "
                   v-model="filterModel.value"
-                  :options="column.filter?.options"
+                  :options="specificFilterConfigs[column.id]?.filter?.options"
                   placeholder="Chose"
                   @change="filterCallback()"
                 >
@@ -663,7 +728,9 @@ const scrollToTableTop = () =>
                   <template #value="{ value: selection }">
                     <template v-if="selection">
                       <template
-                        v-for="(selected, selIndex) in column.filter?.options
+                        v-for="(selected, selIndex) in specificFilterConfigs[
+                          column.id
+                        ]?.filter?.options
                           ?.filter((option) => selection.includes(option))
                           .slice(0, 3)"
                         :key="selIndex"
@@ -729,9 +796,9 @@ const scrollToTableTop = () =>
                 v-else-if="column.id === 'modificationType'"
                 :type-code="data.modification.type"
               />
-              <span v-else-if="column.id === 'guideSubtype'">{{
-                formatGuideSubtype(data.guide.subtype)
-              }}</span>
+              <span v-else-if="column.id === 'guideSubtype'">
+                {{ formatGuideSubtype(data.guide.subtype) }}
+              </span>
               <span v-else>{{ _get(data, column.field) }}</span>
             </template>
           </template>
-- 
GitLab


From 16c110482cc50ab39764967b56a8c7f53ab2d847 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:23 +0200
Subject: [PATCH 22/47] feat(table-view): :sparkles: add filter options for
 species ID, name & target name

use `IN` matchMode
---
 src/gql/codegen/gql.ts      |  9 +++-
 src/gql/codegen/graphql.ts  | 15 +++++-
 src/gql/queries.ts          | 98 +++++++++++++++++++++++++++++++++++++
 src/views/DataTableView.vue | 55 +++++++++++++++++++--
 4 files changed, 170 insertions(+), 7 deletions(-)

diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index d4cb035..ebfc5dd 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -14,7 +14,8 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  */
 const documents = {
     "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n": types.SpeciesListQueryDocument,
-    "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
+    "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
+    "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
     "\n  query speciesByIdQuery($id: Int) {\n    manySpecies(where: { id: $id }) {\n      id\n      name\n      shortname\n      genomes {\n        sequences(where: { featureType: Chromosome }) {\n          id\n          name\n          altnames\n          description\n          length\n          featureType\n          featuresConnection(where: { node: { featureType: Guide } }) {\n            totalCount\n          }\n        }\n      }\n    }\n\n    modifications(where: { target: { genome: { species: { id: $id } } } }) {\n      id\n      name\n      result\n      type\n      guidesAggregate {\n        count\n      }\n    }\n\n    targets(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      modificationsAggregate {\n        count\n      }\n    }\n\n    guides(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      subtype\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          node {\n            id\n          }\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n    }\n  }\n": types.SpeciesByIdQueryDocument,
     "\n  query modificationByIdQuery($id: ID) {\n    modifications(where: { id: $id }) {\n      id\n      name\n      type\n      result\n      position\n      target {\n        id\n        name\n        type\n        genome {\n          species {\n            id\n            name\n          }\n        }\n      }\n      # chebi_id\n      # so_id\n    }\n\n    guides(where: { modifications_SOME: { id: $id } }) {\n      id\n      name\n      type\n    }\n\n    interactions(where: { modification: { id: $id } }) {\n      duplexes {\n        primaryStrandsConnection: strandsConnection(\n          where: { edge: { primary: true } }\n        ) {\n          edges {\n            start\n            end\n            primary\n            node {\n              seq\n              parentConnection {\n                edges {\n                  start\n                  end\n                }\n              }\n            }\n          }\n        }\n        secondaryStrandsConnection: strandsConnection(\n          where: { edge: { primary: false } }\n        ) {\n          edges {\n            start\n            end\n            primary\n            node {\n              seq\n              parentConnection {\n                edges {\n                  start\n                  end\n                }\n              }\n            }\n          }\n        }\n        index\n      }\n      guide {\n        id\n        name\n        subtype\n        type\n      }\n      target {\n        id\n        name\n        type\n      }\n    }\n  }\n": types.ModificationByIdQueryDocument,
     "\n  query guideByIdQuery($id: ID) {\n    guides(where: { id: $id }) {\n      id\n      name\n      altnames\n      description\n      length\n      subtype\n      type\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          strand\n          node {\n            id\n            name\n            length\n            featureType\n          }\n        }\n      }\n      seq\n      genome {\n        species {\n          id\n          name\n        }\n      }\n      featuresConnection(where: { NOT: { node: { type: DuplexFragment } } }) {\n        edges {\n          start\n          end\n          node {\n            id\n            type\n          }\n        }\n      }\n      modifications {\n        id\n        name\n        target {\n          id\n          name\n          type\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n      interactions {\n        duplexes {\n          primaryStrandsConnection: strandsConnection(\n            where: { edge: { primary: true } }\n          ) {\n            edges {\n              start\n              end\n              primary\n              node {\n                seq\n                parentConnection {\n                  edges {\n                    start\n                    end\n                  }\n                }\n              }\n            }\n          }\n          secondaryStrandsConnection: strandsConnection(\n            where: { edge: { primary: false } }\n          ) {\n            edges {\n              start\n              end\n              primary\n              node {\n                seq\n                parentConnection {\n                  edges {\n                    start\n                    end\n                  }\n                }\n              }\n            }\n          }\n          index\n        }\n        modification {\n          id\n          name\n          position\n          result\n          type\n        }\n        target {\n          id\n          name\n          type\n        }\n      }\n      cluster {\n        id\n      }\n      clusterAggregate {\n        count\n      }\n      isoform {\n        guides {\n          id\n          name\n        }\n        guidesAggregate {\n          count\n        }\n      }\n      isoformAggregate {\n        count\n      }\n      chebi_id\n      so_id\n    }\n\n    targets(where: { modifications_SOME: { guides_SOME: { id: $id } } }) {\n      id\n      name\n      type\n    }\n  }\n": types.GuideByIdQueryDocument,
@@ -43,7 +44,11 @@ export function graphql(source: "\n  query speciesListQuery {\n    manySpecies {
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n  }\n"): (typeof documents)["\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n  }\n"];
+export function graphql(source: "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
+/**
+ * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
+ */
+export function graphql(source: "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index 5b137ac..d0ea57a 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6088,10 +6088,20 @@ export type SpeciesListQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
 export type SpeciesListQueryQuery = { __typename?: 'Query', manySpecies: Array<{ __typename?: 'Species', id: number, name: string, shortname: string }> };
 
+export type GuideSelectionQueryQueryVariables = Exact<{
+  guideSubtypes?: InputMaybe<Array<GuideType> | GuideType>;
+  targetNames?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>> | InputMaybe<Scalars['String']['input']>>;
+  modificationTypes?: InputMaybe<Array<InputMaybe<ModifType>> | InputMaybe<ModifType>>;
+  speciesIds?: InputMaybe<Array<Scalars['Int']['input']> | Scalars['Int']['input']>;
+}>;
+
+
+export type GuideSelectionQueryQuery = { __typename?: 'Query', guides: Array<{ __typename?: 'Guide', subtype: GuideType }>, targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+
 export type TableEntriesQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
 
-export type TableEntriesQueryQuery = { __typename?: 'Query', tableEntries: Array<{ __typename?: 'TableEntry', id: string, modification?: { __typename?: 'Modification', id: string, name: string, position: number, result: string, type?: ModifType | null, target: { __typename?: 'Target', id: string, name?: string | null, type: SequenceType, length: number, genome?: { __typename?: 'Genome', species?: { __typename?: 'Species', id: number, name: string } | null } | null, parentConnection: { __typename?: 'TargetParentConnection', edges: Array<{ __typename?: 'TargetParentRelationship', start: number, end: number, strand?: Strand | null, node: { __typename?: 'Chromosome', id: string, name?: string | null } | { __typename?: 'FeatureSequence', id: string, name?: string | null } | { __typename?: 'Guide', id: string, name?: string | null } | { __typename?: 'Target', id: string, name?: string | null } }> } } } | null, guide?: { __typename?: 'Guide', id: string, name?: string | null, type: SequenceType, subtype: GuideType, length: number, seq?: string | null, parentConnection: { __typename?: 'GuideParentConnection', edges: Array<{ __typename?: 'GuideParentRelationship', start: number, end: number, strand?: Strand | null, node: { __typename?: 'Chromosome', id: string, name?: string | null, length: number } | { __typename?: 'FeatureSequence', id: string, name?: string | null, length: number } | { __typename?: 'Guide', id: string, name?: string | null, length: number } | { __typename?: 'Target', id: string, name?: string | null, length: number } }> } } | null }> };
+export type TableEntriesQueryQuery = { __typename?: 'Query', tableEntries: Array<{ __typename?: 'TableEntry', id: string, modification?: { __typename?: 'Modification', id: string, name: string, position: number, result: string, type?: ModifType | null, target: { __typename?: 'Target', id: string, name?: string | null, type: SequenceType, length: number, genome?: { __typename?: 'Genome', species?: { __typename?: 'Species', id: number, name: string } | null } | null, parentConnection: { __typename?: 'TargetParentConnection', edges: Array<{ __typename?: 'TargetParentRelationship', start: number, end: number, strand?: Strand | null, node: { __typename?: 'Chromosome', id: string, name?: string | null } | { __typename?: 'FeatureSequence', id: string, name?: string | null } | { __typename?: 'Guide', id: string, name?: string | null } | { __typename?: 'Target', id: string, name?: string | null } }> } } } | null, guide?: { __typename?: 'Guide', id: string, name?: string | null, type: SequenceType, subtype: GuideType, length: number, seq?: string | null, parentConnection: { __typename?: 'GuideParentConnection', edges: Array<{ __typename?: 'GuideParentRelationship', start: number, end: number, strand?: Strand | null, node: { __typename?: 'Chromosome', id: string, name?: string | null, length: number } | { __typename?: 'FeatureSequence', id: string, name?: string | null, length: number } | { __typename?: 'Guide', id: string, name?: string | null, length: number } | { __typename?: 'Target', id: string, name?: string | null, length: number } }> } } | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }> };
 
 export type SpeciesByIdQueryQueryVariables = Exact<{
   id?: InputMaybe<Scalars['Int']['input']>;
@@ -6130,7 +6140,8 @@ export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __
 
 
 export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
-export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
+export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
+export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
 export const SpeciesByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sequences"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Guide"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<SpeciesByIdQueryQuery, SpeciesByIdQueryQueryVariables>;
 export const ModificationByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"interactions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modification"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duplexes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"primaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":true}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","alias":{"kind":"Name","value":"secondaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":false}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationByIdQueryQuery, ModificationByIdQueryQueryVariables>;
 export const GuideByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"NOT"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type"},"value":{"kind":"EnumValue","value":"DuplexFragment"}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"interactions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duplexes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"primaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":true}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","alias":{"kind":"Name","value":"secondaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":false}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"cluster"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"clusterAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isoform"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"isoformAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}},{"kind":"Field","name":{"kind":"Name","value":"chebi_id"}},{"kind":"Field","name":{"kind":"Name","value":"so_id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]} as unknown as DocumentNode<GuideByIdQueryQuery, GuideByIdQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index 0a5b804..6152d6b 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -16,6 +16,93 @@ export const speciesListQuery = graphql(/* GraphQL */ `
   }
 `)
 
+/**
+ * Get available data in the base matching given filters for guide selection.
+ */
+export const guideSelectionQuery = graphql(/* GraphQL */ `
+  query guideSelectionQuery(
+    $guideSubtypes: [GuideType!]
+    $targetNames: [String]
+    $modificationTypes: [ModifType]
+    $speciesIds: [Int!]
+  ) {
+    guides(
+      where: {
+        modifications_SOME: {
+          target: { name_IN: $targetNames }
+          type_IN: $modificationTypes
+        }
+        genome: { species: { id_IN: $speciesIds } }
+      }
+    ) {
+      subtype
+    }
+
+    targetsBase: targets {
+      name
+    }
+
+    targets(
+      where: {
+        modifications_SOME: {
+          guides_SOME: { subtype_IN: $guideSubtypes }
+          type_IN: $modificationTypes
+        }
+        genome: { species: { id_IN: $speciesIds } }
+      }
+    ) {
+      name
+    }
+
+    modifications(
+      where: {
+        target: {
+          name_IN: $targetNames
+          genome: { species: { id_IN: $speciesIds } }
+        }
+        guides_SOME: { subtype_IN: $guideSubtypes }
+      }
+    ) {
+      type
+    }
+
+    genomesBase: genomes {
+      species {
+        name
+        id
+      }
+    }
+
+    genomes(
+      where: {
+        AND: [
+          {
+            sequencesConnection_SOME: {
+              node: {
+                _on: {
+                  Target: {
+                    name_IN: $targetNames
+                    modifications_SOME: { type_IN: $modificationTypes }
+                  }
+                }
+              }
+            }
+          }
+          {
+            sequencesConnection_SOME: {
+              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }
+            }
+          }
+        ]
+      }
+    ) {
+      species {
+        id
+      }
+    }
+  }
+`)
+
 /**
  * Get the entries for data table display
  */
@@ -74,6 +161,17 @@ export const tableEntriesQuery = graphql(/* GraphQL */ `
         }
       }
     }
+
+    targets {
+      name
+    }
+
+    genomes {
+      species {
+        name
+        id
+      }
+    }
   }
 `)
 
diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 2f5f6d0..623841d 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -21,7 +21,7 @@ import IconFa6SolidArrowUpShortWide from '~icons/fa6-solid/arrow-up-short-wide'
 /**
  * Other 3rd-party imports
  */
-import { get as _get, uniqBy as _uniqBy } from 'lodash-es'
+import { get as _get, uniqBy as _uniqBy, uniq as _uniq } from 'lodash-es'
 import { FilterMatchMode as primeVueFilterMatchMode } from 'primevue/api'
 import { useQuery } from '@urql/vue'
 /**
@@ -34,7 +34,7 @@ import { GuideType, ModifType } from '@/gql/codegen/graphql'
  */
 import { getModificationColor } from '@/utils/colors'
 import { tableEntriesQuery } from '@/gql/queries'
-import { formatGuideSubtype } from '@/utils/textFormatting'
+import { formatGuideSubtype, formatSpeciesName } from '@/utils/textFormatting'
 
 /**
  * Representation of a column filter
@@ -127,6 +127,21 @@ const tableEntries = computed(() =>
   }))
 )
 
+/**
+ * All target names existing in the database.
+ */
+const allTargetNames = computed(() =>
+  _uniq(gqlQuery.data.value?.targets.map((target) => target.name))
+)
+
+/**
+ * All species (name & ID) existing in the database.
+ */
+const allSpecies = computed(() => ({
+  names: gqlQuery.data.value?.genomes.map((genome) => genome.species?.name),
+  ids: gqlQuery.data.value?.genomes.map((genome) => genome.species?.id)
+}))
+
 /**
  * Structure in which to represent the data in the table, columns will be
  * in the same order in the table
@@ -435,6 +450,14 @@ const specificFilterConfigs = computed<{
       options: Object.values(ModifType)
     }
   },
+  targetName: {
+    columnField:
+      columns.find((column) => column.id == 'targetName')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: allTargetNames.value
+    }
+  },
   guideSubtype: {
     columnField:
       columns.find((column) => column.id == 'guideSubtype')?.field || '',
@@ -443,6 +466,23 @@ const specificFilterConfigs = computed<{
       options: Object.values(GuideType)
     }
   },
+  speciesName: {
+    columnField:
+      columns.find((column) => column.id == 'speciesName')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: allSpecies.value.names
+    }
+  },
+  speciesId: {
+    columnField:
+      columns.find((column) => column.id == 'speciesId')?.field || '',
+    filter: {
+      matchMode: primeVueFilterMatchMode.IN,
+      options: allSpecies.value.ids
+    }
+  }
+}))
 
 /**
  * Reactive column filters object
@@ -723,6 +763,9 @@ const scrollToTableTop = () =>
                     <span v-else-if="column.id === 'guideSubtype'">
                       {{ formatGuideSubtype(option) }}
                     </span>
+                    <span v-if="column.id === 'speciesName'">
+                      {{ formatSpeciesName(option) }}
+                    </span>
                   </template>
 
                   <template #value="{ value: selection }">
@@ -742,6 +785,9 @@ const scrollToTableTop = () =>
                         <span v-else-if="column.id === 'guideSubtype'">
                           {{ formatGuideSubtype(selected) }}
                         </span>
+                        <span v-if="column.id === 'speciesName'">
+                          {{ formatSpeciesName(selected) }}
+                        </span>
                         <span v-else>{{ selected }}</span>
                         <span v-if="selIndex !== selection.length - 1">, </span>
                       </template>
@@ -780,7 +826,10 @@ const scrollToTableTop = () =>
                   }
                 }"
               >
-                {{ _get(data, column.field) }}
+                <span v-if="column.id === 'speciesName'">
+                  {{ formatSpeciesName(_get(data, column.field)) }}
+                </span>
+                <span v-else>{{ _get(data, column.field) }}</span>
               </RouterLink>
               <Tag
                 v-else-if="column.id === 'modificationResult'"
-- 
GitLab


From 41b49b7da4cea90f2b51718280b67badf38b484a Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:23 +0200
Subject: [PATCH 23/47] feat(advanced-selection): :sparkles: add actual view &
 route for advanced data selection

---
 src/components/GuideSelectionForm.vue        |   9 +
 src/components/ModificationSelectionForm.vue |   9 +
 src/components/TargetSelectionForm.vue       |   9 +
 src/router/index.ts                          |  29 +++
 src/utils/constant.ts                        |   5 +
 src/views/HomeView.vue                       |  24 +--
 src/views/SelectionView.vue                  | 191 +++++++++++++++++++
 7 files changed, 264 insertions(+), 12 deletions(-)
 create mode 100644 src/components/GuideSelectionForm.vue
 create mode 100644 src/components/ModificationSelectionForm.vue
 create mode 100644 src/components/TargetSelectionForm.vue
 create mode 100644 src/utils/constant.ts
 create mode 100644 src/views/SelectionView.vue

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
new file mode 100644
index 0000000..2841e18
--- /dev/null
+++ b/src/components/GuideSelectionForm.vue
@@ -0,0 +1,9 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <div
+    class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
+  >
+  </div>
+</template>
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
new file mode 100644
index 0000000..2841e18
--- /dev/null
+++ b/src/components/ModificationSelectionForm.vue
@@ -0,0 +1,9 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <div
+    class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
+  >
+  </div>
+</template>
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
new file mode 100644
index 0000000..2841e18
--- /dev/null
+++ b/src/components/TargetSelectionForm.vue
@@ -0,0 +1,9 @@
+<script setup lang="ts">
+</script>
+
+<template>
+  <div
+    class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
+  >
+  </div>
+</template>
diff --git a/src/router/index.ts b/src/router/index.ts
index 1bb7d1d..11f7199 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -11,6 +11,14 @@ import HomeView from '@/views/HomeView.vue'
  */
 import { useTitle } from '@vueuse/core'
 import { isNonNullish } from '@/typings/typeUtils'
+/**
+ * Types imports
+ */
+import type { SelectionFormModesType } from '@/views/SelectionView.vue'
+/**
+ * Utils imports
+ */
+import { SELECTION_FORM_MODES } from '@/utils/constant'
 
 declare module 'vue-router' {
   interface RouteMeta {
@@ -31,6 +39,27 @@ const router = createRouter({
         title: 'Home'
       }
     },
+    {
+      path: '/select',
+      name: 'data-selection',
+      component: () => import('@/views/SelectionView.vue'),
+      props: (to) => ({
+        mode: to.query.mode
+      }),
+      beforeEnter: (to) => {
+        if (
+          typeof to.query.mode !== 'string' ||
+          !SELECTION_FORM_MODES.includes(
+            to.query.mode as SelectionFormModesType
+          )
+        ) {
+          router.replace({ name: 'lost' })
+        }
+      },
+      meta: {
+        title: 'Advanced selection'
+      }
+    },
     {
       path: '/data',
       name: 'data-table',
diff --git a/src/utils/constant.ts b/src/utils/constant.ts
new file mode 100644
index 0000000..0608ef8
--- /dev/null
+++ b/src/utils/constant.ts
@@ -0,0 +1,5 @@
+/**
+ * The different modes available for advanced selection form on the selection
+ * page.
+ */
+export const SELECTION_FORM_MODES = ['modification', 'guide', 'target'] as const
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index ee10c33..f964640 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -136,10 +136,10 @@ const menuItems: MenuItem[] = [
       {
         label: 'Advanced guide selection',
         route: {
-          // name: 'data-selection',
-          // query: {
-          //   type: 'guide'
-          // }
+          name: 'data-selection',
+          query: {
+            mode: 'guide'
+          }
         },
         iconComponent: IconFa6SolidSliders
       }
@@ -174,10 +174,10 @@ const menuItems: MenuItem[] = [
       {
         label: 'Advanced modification selection',
         route: {
-          // name: 'data-selection',
-          // query: {
-          //   type: 'modification'
-          // }
+          name: 'data-selection',
+          query: {
+            mode: 'modification'
+          }
         },
         iconComponent: IconFa6SolidSliders
       }
@@ -212,10 +212,10 @@ const menuItems: MenuItem[] = [
       {
         label: 'Advanced target selection',
         route: {
-          // name: 'data-selection',
-          // query: {
-          //   type: 'target'
-          // }
+          name: 'data-selection',
+          query: {
+            mode: 'target'
+          }
         },
         iconComponent: IconFa6SolidSliders
       }
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
new file mode 100644
index 0000000..672dd87
--- /dev/null
+++ b/src/views/SelectionView.vue
@@ -0,0 +1,191 @@
+<script setup lang="ts">
+/**
+ * Vue imports
+ */
+import { computed, ref } from 'vue'
+import { useRouter } from 'vue-router'
+/**
+ * Components imports
+ */
+import MainLayout from '@/layouts/MainLayout.vue'
+import ModificationSelectionForm from '@/components/ModificationSelectionForm.vue'
+import GuideSelectionForm from '@/components/GuideSelectionForm.vue'
+import TargetSelectionForm from '@/components/TargetSelectionForm.vue'
+import TabView, { type TabViewChangeEvent } from 'primevue/tabview'
+import TabPanel from 'primevue/tabpanel'
+import Card from 'primevue/card'
+import Button from 'primevue/button'
+import IconFa6SolidTable from '~icons/fa6-solid/table'
+/**
+ * Other 3rd-party imports
+ */
+import { useTitle } from '@vueuse/core'
+import { capitalize as _capitalize } from 'lodash-es'
+/**
+ * Utils imports
+ */
+import { SELECTION_FORM_MODES } from '@/utils/constant'
+
+/**
+ * Type of data to select.
+ */
+export type SelectionFormModesType = (typeof SELECTION_FORM_MODES)[number]
+enum TabEnum {
+  Modification = 0,
+  Guide,
+  Target
+}
+
+/**
+ * A selection option.
+ */
+export interface SelectionOptionModel {
+  /** Label of the option. */
+  label: string
+  /** Value of the option. */
+  value: string
+  /** Optional disabling state of the option. */
+  isDisabled?: boolean
+}
+
+/**
+ * Component props.
+ */
+const props = defineProps<{
+  mode: SelectionFormModesType
+}>()
+
+/**
+ * Vue Router instance reactive object.
+ */
+const router = useRouter()
+
+/**
+ * The index of the tab currently selected, reactively updated when changed.
+ */
+const activeTabIndex = ref<TabEnum>(
+  SELECTION_FORM_MODES.findIndex((mode) => mode === props.mode)
+)
+
+/**
+ * Title of the page, reactively updated when data is fetched.
+ */
+const pageTitle = computed(
+  () =>
+    `${_capitalize(
+      SELECTION_FORM_MODES[activeTabIndex.value]
+    )} • Selection | SnoBoard`
+)
+// Bind actual page title to computed one
+useTitle(pageTitle)
+
+/**
+ * Callback to change the URL when switching tab.
+ * @param e The event emitted when changing tab.
+ */
+const updateUrlQuery = (e: TabViewChangeEvent) => {
+  const newMode = SELECTION_FORM_MODES[e.index]
+  if (newMode) {
+    router.replace({ name: 'data-selection', query: { mode: newMode } })
+  }
+}
+
+const activeTabTableColumns = computed(() => {
+  switch (activeTabIndex.value) {
+    case TabEnum.Modification:
+      return [
+        'modificationId',
+        'modificationName',
+        'modificationPosition',
+        'modificationResult',
+        'modificationType',
+        'targetName',
+        'speciesName',
+        'speciesId'
+      ]
+    case TabEnum.Guide:
+      return [
+        'guideId',
+        'guideName',
+        'guideType',
+        'guideSubtype',
+        'guideChromosomeName',
+        'guideLength',
+        'speciesName',
+        'speciesId'
+      ]
+    case TabEnum.Target:
+      return [
+        'targetId',
+        'targetName',
+        'targetLength',
+        'targetType',
+        'targetChromosomeName',
+        'speciesName',
+        'speciesId'
+      ]
+    default:
+      return []
+  }
+})
+</script>
+
+<template>
+  <MainLayout>
+    <h1 class="mb-8 text-center text-3xl">Advanced selection</h1>
+
+    <Card
+      class="mx-16 !rounded-2xl border-2 !shadow-none"
+      :pt="{
+        footer: {
+          style: {
+            display: 'flex',
+            justifyContent: 'center'
+          }
+        }
+      }"
+    >
+      <template #content>
+        <TabView
+          v-model:active-index="activeTabIndex"
+          :pt="{
+            nav: {
+              style: {
+                justifyContent: 'center',
+                marginBottom: '2rem',
+                fontSize: '1.25em'
+              }
+            }
+          }"
+          @tab-change="updateUrlQuery"
+        >
+          <TabPanel header="Modification">
+            <ModificationSelectionForm />
+          </TabPanel>
+          <TabPanel header="Guide">
+            <GuideSelectionForm />
+          </TabPanel>
+          <TabPanel header="Target">
+            <TargetSelectionForm />
+          </TabPanel>
+        </TabView>
+      </template>
+
+      <template #footer>
+        <RouterLink
+          :to="{
+            name: 'data-table',
+            query: {
+              columns: activeTabTableColumns
+            }
+          }"
+        >
+          <Button>
+            <icon-fa6-solid-table />
+            <span class="ml-2">View in table</span>
+          </Button>
+        </RouterLink>
+      </template>
+    </Card>
+  </MainLayout>
+</template>
-- 
GitLab


From c8a0d0917ad73d58f0ead204de0493c8def7d01b Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:23 +0200
Subject: [PATCH 24/47] feat(advanced-selection): :sparkles: add actual guide
 selection form

---
 src/components/GuideSelectionForm.vue | 345 ++++++++++++++++++++++++++
 src/views/SelectionView.vue           |  45 +++-
 2 files changed, 383 insertions(+), 7 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index 2841e18..a76c2fc 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -1,9 +1,354 @@
 <script setup lang="ts">
+/**
+ * Vue imports
+ */
+import { computed, ref, toRef } from 'vue'
+/**
+ * Component imports
+ */
+import FormattedModificationType from './FormattedModificationType.vue'
+import Chip from 'primevue/chip'
+import SelectButton from 'primevue/selectbutton'
+import MultiSelect from 'primevue/multiselect'
+import { GuideType, ModifType } from '@/gql/codegen/graphql'
+import { formatGuideSubtype, formatSpeciesName } from '@/utils/textFormatting'
+/**
+ * Other 3rd-party imports
+ */
+import { useQuery } from '@urql/vue'
+import {
+  uniqWith as _uniqWith,
+  isEqual as _isEqual,
+  remove as _remove
+} from 'lodash-es'
+/**
+ * Utils imports
+ */
+import { guideSelectionQuery } from '@/gql/queries'
+/**
+ * Types imports
+ */
+import type { SelectionOptionModel } from '@/views/SelectionView.vue'
+
+/**
+ * A selection.
+ */
+export interface GuideSelectionModel {
+  /** Currently selected guide subtypes. */
+  guideSubtypes: GuideType[]
+  /** Currently selected target names. */
+  targetNames: string[]
+  /** Currently selected modification types. */
+  modificationTypes: ModifType[]
+  /** Currently selected species IDs.*/
+  speciesIds: number[]
+}
+
+/**
+ * Available options for guide subtype selection, independently of other fields'
+ * selection.
+ */
+const GUIDE_SUBTYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
+  GuideType
+).map((guideSubtype) => ({
+  label: formatGuideSubtype(guideSubtype),
+  value: guideSubtype
+}))
+
+/**
+ * Available options for modification type selection, independently of other
+ * fields' selection.
+ */
+const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
+  ModifType
+).map((modifType) => ({
+  label: modifType,
+  value: modifType
+}))
+
+/**
+ * Component props
+ */
+defineProps<{
+  /** The current selection. */
+  modelValue?: GuideSelectionModel
+}>()
+
+/**
+ * Component events.
+ */
+defineEmits<{
+  /** Event used to update the `v-model` value. */
+  'update:modelValue': [modelValue: GuideSelectionModel]
+}>()
+
+/**
+ * Current selection of parameters/filters for the guides to pick.
+ */
+const selection = ref<GuideSelectionModel>({
+  guideSubtypes: [],
+  targetNames: [],
+  modificationTypes: [],
+  speciesIds: []
+})
+
+/**
+ * Reactive urql GraphQL query object, updated with query state & response.
+ */
+const gqlQuery = useQuery({
+  query: guideSelectionQuery,
+  variables: toRef(() => ({
+    guideSubtypes: selection.value.guideSubtypes?.length
+      ? selection.value.guideSubtypes
+      : undefined,
+    targetNames: selection.value.targetNames?.length
+      ? selection.value.targetNames
+      : undefined,
+    modificationTypes: selection.value.modificationTypes?.length
+      ? selection.value.modificationTypes
+      : undefined,
+    speciesIds: selection.value.speciesIds?.length
+      ? selection.value.speciesIds
+      : undefined
+  }))
+})
+
+/**
+ * Available guide subtypes, filtered based on other fields' selection (only guide
+ * types which exists with selected options are present).
+ */
+const guideSubtypesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.guides, _isEqual).map((guide) => guide.subtype)
+)
+
+/**
+ * Available options for guide subtype selection, with a `isDisabled` field on
+ * absence in `guideSubtypesFiltered`.
+ */
+const guideSubtypeOptionsWithDisabling = computed(() =>
+  GUIDE_SUBTYPE_OPTIONS_BASE.map((guideSubtypeOption) => ({
+    ...guideSubtypeOption,
+    isDisabled: !guideSubtypesFiltered.value.some(
+      (guideSubtypeFiltered) =>
+        guideSubtypeFiltered === guideSubtypeOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for target name selection, independently of other fields'
+ * selection.
+ */
+const targetNameOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
+    label: target.name,
+    value: target.name
+  }))
+)
+
+/**
+ * Available target names, filtered based on other fields' selection (only
+ * target names which exists with selected options are present).
+ */
+const targetNamesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targets, _isEqual).map((target) => target.name)
+)
+
+/**
+ * Available options for target name selection, with a `isDisabled` field on
+ * absence in `targetNamesFiltered`.
+ */
+const targetNameOptionsWithDisabling = computed(() =>
+  targetNameOptionsBase.value.map((targetNameOption) => ({
+    ...targetNameOption,
+    isDisabled: !targetNamesFiltered.value.some(
+      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
+    )
+  }))
+)
+
+/**
+ * Available modification types, filtered based on other fields' selection (only
+ * modification types which exists with selected options are present).
+ */
+const modificationTypesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.modifications, _isEqual).map(
+    (modification) => modification.type
+  )
+)
+
+/**
+ * Available options for modification type selection, with a `isDisabled` field
+ * on absence in `modificationTypesFiltered`.
+ */
+const modificationTypeOptionsWithDisabling = computed(() =>
+  MODIFICATION_TYPE_OPTIONS_BASE.map((modificationTypeOption) => ({
+    ...modificationTypeOption,
+    isDisabled: !modificationTypesFiltered.value.some(
+      (modificationTypeFiltered) =>
+        modificationTypeFiltered === modificationTypeOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for species ID selection, independently of other fields'
+ * selection.
+ */
+const speciesIdOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomesBase, _isEqual).map((genome) => ({
+    label: genome.species?.name,
+    value: genome.species?.id
+  }))
+)
+
+/**
+ * Available species IDs, filtered based on other fields' selection (only
+ * species IDs which exists with selected options are present).
+ */
+const speciesIdsFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomes, _isEqual).map(
+    (genome) => genome.species?.id
+  )
+)
+
+/**
+ * Available options for species ID selection, with a `isDisabled` field on
+ * absence in `speciesIdsFiltered`.
+ */
+const speciesIdOptionsWithDisabling = computed(() =>
+  speciesIdOptionsBase.value.map((speciesIdOption) => ({
+    ...speciesIdOption,
+    isDisabled: !speciesIdsFiltered.value.some(
+      (speciesIdFiltered) => speciesIdFiltered === speciesIdOption.value
+    )
+  }))
+)
 </script>
 
 <template>
   <div
     class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
   >
+    <h3 class="text-lg font-bold">Guide subtype</h3>
+    <SelectButton
+      v-model="selection.guideSubtypes"
+      :options="guideSubtypeOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      @update:model-value="(selectedGuideSubtypes: GuideType[]) => $emit('update:modelValue', {...selection, guideSubtypes:selectedGuideSubtypes })"
+    />
+
+    <h3 class="text-lg font-bold">Targets</h3>
+    <MultiSelect
+      v-model="selection.targetNames"
+      :options="targetNameOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select targets..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+    >
+      <template #value>
+        <Chip
+          v-for="targetName in selection.targetNames.slice(0, 3)"
+          :key="targetName"
+          class="mr-1"
+          :label="targetName"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              targetNames: _remove(
+                selection.targetNames,
+                (currTargetName) => currTargetName === targetName
+              )
+            })
+          "
+        />
+        <template v-if="selection.targetNames.length > 3">
+          +{{ selection.targetNames.length - 3 }} others...
+        </template>
+      </template>
+    </MultiSelect>
+
+    <h3 class="text-lg font-bold">Modifications</h3>
+    <SelectButton
+      v-model="selection.modificationTypes"
+      :options="modificationTypeOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+    >
+      <template #option="{ option }">
+        <FormattedModificationType
+          :type-code="option.label"
+          class="font-medium"
+        />
+      </template>
+    </SelectButton>
+
+    <h3 class="text-lg font-bold">Species</h3>
+    <MultiSelect
+      v-model="selection.speciesIds"
+      :options="speciesIdOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select species..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+    >
+      <template #value>
+        <Chip
+          v-for="speciesId in selection.speciesIds.slice(0, 3)"
+          :key="speciesId"
+          class="mr-1"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              speciesIds: _remove(
+                selection.speciesIds,
+                (currSpeciesId) => currSpeciesId === speciesId
+              )
+            })
+          "
+        >
+          <em class="my-1.5">
+            {{
+              formatSpeciesName(
+                speciesIdOptionsBase.find(
+                  (speciesIdOption) => speciesIdOption.value === speciesId
+                )?.label || ''
+              )
+            }}
+          </em>
+        </Chip>
+        <template v-if="selection.speciesIds.length > 3">
+          +{{ selection.speciesIds.length - 3 }} others...
+        </template>
+      </template>
+      <template #option="{ option }">
+        <em>
+          {{ formatSpeciesName(option.label) }}
+        </em>
+      </template>
+    </MultiSelect>
   </div>
 </template>
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 672dd87..46baaa8 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -67,14 +67,16 @@ const activeTabIndex = ref<TabEnum>(
   SELECTION_FORM_MODES.findIndex((mode) => mode === props.mode)
 )
 
+/**
+ * The mode corresponding to the tab currently selected.
+ */
+const activeMode = computed(() => SELECTION_FORM_MODES[activeTabIndex.value])
+
 /**
  * Title of the page, reactively updated when data is fetched.
  */
 const pageTitle = computed(
-  () =>
-    `${_capitalize(
-      SELECTION_FORM_MODES[activeTabIndex.value]
-    )} • Selection | SnoBoard`
+  () => `${_capitalize(activeMode.value)} • Selection | SnoBoard`
 )
 // Bind actual page title to computed one
 useTitle(pageTitle)
@@ -90,7 +92,35 @@ const updateUrlQuery = (e: TabViewChangeEvent) => {
   }
 }
 
-const activeTabTableColumns = computed(() => {
+/**
+ * The current selection.
+ */
+const selection = ref<{
+  modification?: undefined
+  guide?: GuideSelectionModel
+  target?: undefined
+}>({
+  modification: undefined,
+  guide: undefined,
+  target: undefined
+})
+
+/**
+ * The filter to apply to the table when navigating to it, derived from current
+ * selection.
+ */
+const tableFilters = computed(() => ({
+  guideSubtype: selection.value[activeMode.value]?.guideSubtypes,
+  targetName: selection.value[activeMode.value]?.targetNames,
+  modificationType: selection.value[activeMode.value]?.modificationTypes,
+  speciesId: selection.value[activeMode.value]?.speciesIds
+}))
+
+/**
+ * The columns to display in the table when navigating to it, based on the
+ * active tab (i.e. form mode).
+ */
+const activeModeTableColumns = computed(() => {
   switch (activeTabIndex.value) {
     case TabEnum.Modification:
       return [
@@ -163,7 +193,7 @@ const activeTabTableColumns = computed(() => {
             <ModificationSelectionForm />
           </TabPanel>
           <TabPanel header="Guide">
-            <GuideSelectionForm />
+            <GuideSelectionForm v-model="selection.guide" />
           </TabPanel>
           <TabPanel header="Target">
             <TargetSelectionForm />
@@ -176,7 +206,8 @@ const activeTabTableColumns = computed(() => {
           :to="{
             name: 'data-table',
             query: {
-              columns: activeTabTableColumns
+              columns: activeModeTableColumns,
+              ...tableFilters
             }
           }"
         >
-- 
GitLab


From 391873a3470bc5dd61a16b95b280147438cb800c Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:24 +0200
Subject: [PATCH 25/47] fix(table-view): :adhesive_bandage: if instead of
 else-if caused unwanted else execution

---
 src/views/DataTableView.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 623841d..5b60dca 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -785,7 +785,7 @@ const scrollToTableTop = () =>
                         <span v-else-if="column.id === 'guideSubtype'">
                           {{ formatGuideSubtype(selected) }}
                         </span>
-                        <span v-if="column.id === 'speciesName'">
+                        <span v-else-if="column.id === 'speciesName'">
                           {{ formatSpeciesName(selected) }}
                         </span>
                         <span v-else>{{ selected }}</span>
-- 
GitLab


From b039c8dc6fbe78926d513661cda9e1fc70c411ba Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:24 +0200
Subject: [PATCH 26/47] fix(home-view): :adhesive_bandage: non-reactive object
 causing no updates

---
 src/views/HomeView.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index f964640..109f6db 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -106,7 +106,7 @@ const speciesList = computed(() =>
 /**
  * Menu items.
  */
-const menuItems: MenuItem[] = [
+const menuItems = computed<MenuItem[]>(() => [
   {
     label: 'Guides',
     items: [
@@ -285,7 +285,7 @@ const menuItems: MenuItem[] = [
       }
     ]
   }
-]
+])
 </script>
 
 <template>
-- 
GitLab


From 5824905e50614d57166a6b91e55b810f87ab7e96 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:24 +0200
Subject: [PATCH 27/47] feat(advanced-selection): :sparkles: add actual
 modification selection

---
 src/components/GuideSelectionForm.vue        |   4 +-
 src/components/ModificationSelectionForm.vue | 294 +++++++++++++++++++
 src/gql/codegen/gql.ts                       |   5 +
 src/gql/codegen/graphql.ts                   |  10 +
 src/gql/queries.ts                           |  61 ++++
 src/views/SelectionView.vue                  |  17 +-
 6 files changed, 384 insertions(+), 7 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index a76c2fc..19449c2 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -230,7 +230,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
   <div
     class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
   >
-    <h3 class="text-lg font-bold">Guide subtype</h3>
+    <h3 class="text-lg font-bold">Guide subtypes</h3>
     <SelectButton
       v-model="selection.guideSubtypes"
       :options="guideSubtypeOptionsWithDisabling"
@@ -280,7 +280,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       </template>
     </MultiSelect>
 
-    <h3 class="text-lg font-bold">Modifications</h3>
+    <h3 class="text-lg font-bold">Guided modification types</h3>
     <SelectButton
       v-model="selection.modificationTypes"
       :options="modificationTypeOptionsWithDisabling"
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index 2841e18..b3674bf 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -1,9 +1,303 @@
 <script setup lang="ts">
+/**
+ * Vue imports
+ */
+import { computed, ref, toRef } from 'vue'
+/**
+ * Component imports
+ */
+import FormattedModificationType from './FormattedModificationType.vue'
+import Chip from 'primevue/chip'
+import SelectButton from 'primevue/selectbutton'
+import MultiSelect from 'primevue/multiselect'
+import { ModifType } from '@/gql/codegen/graphql'
+import { formatSpeciesName } from '@/utils/textFormatting'
+/**
+ * Other 3rd-party imports
+ */
+import { useQuery } from '@urql/vue'
+import {
+  uniqWith as _uniqWith,
+  isEqual as _isEqual,
+  remove as _remove
+} from 'lodash-es'
+/**
+ * Utils imports
+ */
+import { modificationSelectionQuery } from '@/gql/queries'
+/**
+ * Types imports
+ */
+import type { SelectionOptionModel } from '@/views/SelectionView.vue'
+
+/**
+ * A selection.
+ */
+export interface ModificationSelectionModel {
+  /** Currently selected modification types. */
+  modificationTypes: ModifType[]
+  /** Currently selected target names. */
+  targetNames: string[]
+  /** Currently selected species IDs.*/
+  speciesIds: number[]
+}
+
+/**
+ * Available options for modification type selection, independently of other
+ * fields' selection.
+ */
+const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
+  ModifType
+).map((modifType) => ({
+  label: modifType,
+  value: modifType
+}))
+
+/**
+ * Component props
+ */
+defineProps<{
+  /** The current selection. */
+  modelValue?: ModificationSelectionModel
+}>()
+
+/**
+ * Component events.
+ */
+defineEmits<{
+  /** Event used to update the `v-model` value. */
+  'update:modelValue': [modelValue: ModificationSelectionModel]
+}>()
+
+/**
+ * Current selection of parameters/filters for the modifications to pick.
+ */
+const selection = ref<ModificationSelectionModel>({
+  modificationTypes: [],
+  targetNames: [],
+  speciesIds: []
+})
+
+/**
+ * Reactive urql GraphQL query object, updated with query state & response.
+ */
+const gqlQuery = useQuery({
+  query: modificationSelectionQuery,
+  variables: toRef(() => ({
+    targetNames: selection.value.targetNames?.length
+      ? selection.value.targetNames
+      : undefined,
+    modificationTypes: selection.value.modificationTypes?.length
+      ? selection.value.modificationTypes
+      : undefined,
+    speciesIds: selection.value.speciesIds?.length
+      ? selection.value.speciesIds
+      : undefined
+  }))
+})
+
+/**
+ * Available modification types, filtered based on other fields' selection (only
+ * modification types which exists with selected options are present).
+ */
+const modificationTypesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.modifications, _isEqual).map(
+    (modification) => modification.type
+  )
+)
+
+/**
+ * Available options for modification type selection, with a `isDisabled` field
+ * on absence in `modificationTypesFiltered`.
+ */
+const modificationTypeOptionsWithDisabling = computed(() =>
+  MODIFICATION_TYPE_OPTIONS_BASE.map((modificationTypeOption) => ({
+    ...modificationTypeOption,
+    isDisabled: !modificationTypesFiltered.value.some(
+      (modificationTypeFiltered) =>
+        modificationTypeFiltered === modificationTypeOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for target name selection, independently of other fields'
+ * selection.
+ */
+const targetNameOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
+    label: target.name,
+    value: target.name
+  }))
+)
+
+/**
+ * Available target names, filtered based on other fields' selection (only
+ * target names which exists with selected options are present).
+ */
+const targetNamesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targets, _isEqual).map((target) => target.name)
+)
+
+/**
+ * Available options for target name selection, with a `isDisabled` field on
+ * absence in `targetNamesFiltered`.
+ */
+const targetNameOptionsWithDisabling = computed(() =>
+  targetNameOptionsBase.value.map((targetNameOption) => ({
+    ...targetNameOption,
+    isDisabled: !targetNamesFiltered.value.some(
+      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for species ID selection, independently of other fields'
+ * selection.
+ */
+const speciesIdOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomesBase, _isEqual).map((genome) => ({
+    label: genome.species?.name,
+    value: genome.species?.id
+  }))
+)
+
+/**
+ * Available species IDs, filtered based on other fields' selection (only
+ * species IDs which exists with selected options are present).
+ */
+const speciesIdsFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomes, _isEqual).map(
+    (genome) => genome.species?.id
+  )
+)
+
+/**
+ * Available options for species ID selection, with a `isDisabled` field on
+ * absence in `speciesIdsFiltered`.
+ */
+const speciesIdOptionsWithDisabling = computed(() =>
+  speciesIdOptionsBase.value.map((speciesIdOption) => ({
+    ...speciesIdOption,
+    isDisabled: !speciesIdsFiltered.value.some(
+      (speciesIdFiltered) => speciesIdFiltered === speciesIdOption.value
+    )
+  }))
+)
 </script>
 
 <template>
   <div
     class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
   >
+    <h3 class="text-lg font-bold">Modification types</h3>
+    <SelectButton
+      v-model="selection.modificationTypes"
+      :options="modificationTypeOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+    >
+      <template #option="{ option }">
+        <FormattedModificationType
+          :type-code="option.label"
+          class="font-medium"
+        />
+      </template>
+    </SelectButton>
+
+    <h3 class="text-lg font-bold">Targets</h3>
+    <MultiSelect
+      v-model="selection.targetNames"
+      :options="targetNameOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select targets..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+    >
+      <template #value>
+        <Chip
+          v-for="targetName in selection.targetNames.slice(0, 3)"
+          :key="targetName"
+          class="mr-1"
+          :label="targetName"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              targetNames: _remove(
+                selection.targetNames,
+                (currTargetName) => currTargetName === targetName
+              )
+            })
+          "
+        />
+        <template v-if="selection.targetNames.length > 3">
+          +{{ selection.targetNames.length - 3 }} others...
+        </template>
+      </template>
+    </MultiSelect>
+
+    <h3 class="text-lg font-bold">Species</h3>
+    <MultiSelect
+      v-model="selection.speciesIds"
+      :options="speciesIdOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select species..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+    >
+      <template #value>
+        <Chip
+          v-for="speciesId in selection.speciesIds.slice(0, 3)"
+          :key="speciesId"
+          class="mr-1"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              speciesIds: _remove(
+                selection.speciesIds,
+                (currSpeciesId) => currSpeciesId === speciesId
+              )
+            })
+          "
+        >
+          <em class="my-1.5">
+            {{
+              formatSpeciesName(
+                speciesIdOptionsBase.find(
+                  (speciesIdOption) => speciesIdOption.value === speciesId
+                )?.label || ''
+              )
+            }}
+          </em>
+        </Chip>
+        <template v-if="selection.speciesIds.length > 3">
+          +{{ selection.speciesIds.length - 3 }} others...
+        </template>
+      </template>
+      <template #option="{ option }">
+        <em>
+          {{ formatSpeciesName(option.label) }}
+        </em>
+      </template>
+    </MultiSelect>
   </div>
 </template>
diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index ebfc5dd..d404b1a 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -14,6 +14,7 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  */
 const documents = {
     "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n": types.SpeciesListQueryDocument,
+    "\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationSelectionQueryDocument,
     "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
     "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
     "\n  query speciesByIdQuery($id: Int) {\n    manySpecies(where: { id: $id }) {\n      id\n      name\n      shortname\n      genomes {\n        sequences(where: { featureType: Chromosome }) {\n          id\n          name\n          altnames\n          description\n          length\n          featureType\n          featuresConnection(where: { node: { featureType: Guide } }) {\n            totalCount\n          }\n        }\n      }\n    }\n\n    modifications(where: { target: { genome: { species: { id: $id } } } }) {\n      id\n      name\n      result\n      type\n      guidesAggregate {\n        count\n      }\n    }\n\n    targets(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      modificationsAggregate {\n        count\n      }\n    }\n\n    guides(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      subtype\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          node {\n            id\n          }\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n    }\n  }\n": types.SpeciesByIdQueryDocument,
@@ -41,6 +42,10 @@ export function graphql(source: string): unknown;
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
 export function graphql(source: "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n"): (typeof documents)["\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n"];
+/**
+ * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
+ */
+export function graphql(source: "\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index d0ea57a..5498cff 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6088,6 +6088,15 @@ export type SpeciesListQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
 export type SpeciesListQueryQuery = { __typename?: 'Query', manySpecies: Array<{ __typename?: 'Species', id: number, name: string, shortname: string }> };
 
+export type ModificationSelectionQueryQueryVariables = Exact<{
+  modificationTypes?: InputMaybe<Array<InputMaybe<ModifType>> | InputMaybe<ModifType>>;
+  targetNames?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>> | InputMaybe<Scalars['String']['input']>>;
+  speciesIds?: InputMaybe<Array<Scalars['Int']['input']> | Scalars['Int']['input']>;
+}>;
+
+
+export type ModificationSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+
 export type GuideSelectionQueryQueryVariables = Exact<{
   guideSubtypes?: InputMaybe<Array<GuideType> | GuideType>;
   targetNames?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>> | InputMaybe<Scalars['String']['input']>>;
@@ -6140,6 +6149,7 @@ export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __
 
 
 export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
+export const ModificationSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationSelectionQueryQuery, ModificationSelectionQueryQueryVariables>;
 export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
 export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
 export const SpeciesByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sequences"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Guide"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<SpeciesByIdQueryQuery, SpeciesByIdQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index 6152d6b..2caa17b 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -16,6 +16,67 @@ export const speciesListQuery = graphql(/* GraphQL */ `
   }
 `)
 
+/**
+ * Get available data in the base matching given filters for guide selection.
+ */
+export const modificationSelectionQuery = graphql(/* GraphQL */ `
+  query modificationSelectionQuery(
+    $modificationTypes: [ModifType]
+    $targetNames: [String]
+    $speciesIds: [Int!]
+  ) {
+    targetsBase: targets {
+      name
+    }
+
+    targets(
+      where: {
+        modifications_SOME: { type_IN: $modificationTypes }
+        genome: { species: { id_IN: $speciesIds } }
+      }
+    ) {
+      name
+    }
+
+    modifications(
+      where: {
+        target: {
+          name_IN: $targetNames
+          genome: { species: { id_IN: $speciesIds } }
+        }
+      }
+    ) {
+      type
+    }
+
+    genomesBase: genomes {
+      species {
+        name
+        id
+      }
+    }
+
+    genomes(
+      where: {
+        sequencesConnection_SOME: {
+          node: {
+            _on: {
+              Target: {
+                name_IN: $targetNames
+                modifications_SOME: { type_IN: $modificationTypes }
+              }
+            }
+          }
+        }
+      }
+    ) {
+      species {
+        id
+      }
+    }
+  }
+`)
+
 /**
  * Get available data in the base matching given filters for guide selection.
  */
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 46baaa8..638c2a5 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -8,8 +8,12 @@ import { useRouter } from 'vue-router'
  * Components imports
  */
 import MainLayout from '@/layouts/MainLayout.vue'
-import ModificationSelectionForm from '@/components/ModificationSelectionForm.vue'
-import GuideSelectionForm from '@/components/GuideSelectionForm.vue'
+import ModificationSelectionForm, {
+  type ModificationSelectionModel
+} from '@/components/ModificationSelectionForm.vue'
+import GuideSelectionForm, {
+  type GuideSelectionModel
+} from '@/components/GuideSelectionForm.vue'
 import TargetSelectionForm from '@/components/TargetSelectionForm.vue'
 import TabView, { type TabViewChangeEvent } from 'primevue/tabview'
 import TabPanel from 'primevue/tabpanel'
@@ -96,7 +100,7 @@ const updateUrlQuery = (e: TabViewChangeEvent) => {
  * The current selection.
  */
 const selection = ref<{
-  modification?: undefined
+  modification?: ModificationSelectionModel
   guide?: GuideSelectionModel
   target?: undefined
 }>({
@@ -110,7 +114,10 @@ const selection = ref<{
  * selection.
  */
 const tableFilters = computed(() => ({
-  guideSubtype: selection.value[activeMode.value]?.guideSubtypes,
+  guideSubtype:
+    activeMode.value === 'guide'
+      ? selection.value[activeMode.value]?.guideSubtypes
+      : undefined,
   targetName: selection.value[activeMode.value]?.targetNames,
   modificationType: selection.value[activeMode.value]?.modificationTypes,
   speciesId: selection.value[activeMode.value]?.speciesIds
@@ -190,7 +197,7 @@ const activeModeTableColumns = computed(() => {
           @tab-change="updateUrlQuery"
         >
           <TabPanel header="Modification">
-            <ModificationSelectionForm />
+            <ModificationSelectionForm v-model="selection.modification" />
           </TabPanel>
           <TabPanel header="Guide">
             <GuideSelectionForm v-model="selection.guide" />
-- 
GitLab


From d337a2f524fa61bf4a6e494478f54843fdbcef27 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:24 +0200
Subject: [PATCH 28/47] feat(advanced-selection): :sparkles: add actual target
 selection form

---
 src/components/GuideSelectionForm.vue        |   2 +-
 src/components/ModificationSelectionForm.vue |   6 +-
 src/components/TargetSelectionForm.vue       | 294 +++++++++++++++++++
 src/gql/codegen/gql.ts                       |   4 +-
 src/gql/codegen/graphql.ts                   |   6 +-
 src/gql/queries.ts                           |   7 +-
 src/views/SelectionView.vue                  |   8 +-
 7 files changed, 312 insertions(+), 15 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index 19449c2..920a423 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -31,7 +31,7 @@ import { guideSelectionQuery } from '@/gql/queries'
 import type { SelectionOptionModel } from '@/views/SelectionView.vue'
 
 /**
- * A selection.
+ * A guide selection.
  */
 export interface GuideSelectionModel {
   /** Currently selected guide subtypes. */
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index b3674bf..c4aadb4 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -24,14 +24,14 @@ import {
 /**
  * Utils imports
  */
-import { modificationSelectionQuery } from '@/gql/queries'
+import { modificationAndTargetSelectionQuery } from '@/gql/queries'
 /**
  * Types imports
  */
 import type { SelectionOptionModel } from '@/views/SelectionView.vue'
 
 /**
- * A selection.
+ * A modification selection.
  */
 export interface ModificationSelectionModel {
   /** Currently selected modification types. */
@@ -82,7 +82,7 @@ const selection = ref<ModificationSelectionModel>({
  * Reactive urql GraphQL query object, updated with query state & response.
  */
 const gqlQuery = useQuery({
-  query: modificationSelectionQuery,
+  query: modificationAndTargetSelectionQuery,
   variables: toRef(() => ({
     targetNames: selection.value.targetNames?.length
       ? selection.value.targetNames
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
index 2841e18..1075bd0 100644
--- a/src/components/TargetSelectionForm.vue
+++ b/src/components/TargetSelectionForm.vue
@@ -1,9 +1,303 @@
 <script setup lang="ts">
+/**
+ * Vue imports
+ */
+import { computed, ref, toRef } from 'vue'
+/**
+ * Component imports
+ */
+import FormattedModificationType from './FormattedModificationType.vue'
+import Chip from 'primevue/chip'
+import SelectButton from 'primevue/selectbutton'
+import MultiSelect from 'primevue/multiselect'
+import { ModifType } from '@/gql/codegen/graphql'
+import { formatSpeciesName } from '@/utils/textFormatting'
+/**
+ * Other 3rd-party imports
+ */
+import { useQuery } from '@urql/vue'
+import {
+  uniqWith as _uniqWith,
+  isEqual as _isEqual,
+  remove as _remove
+} from 'lodash-es'
+/**
+ * Utils imports
+ */
+import { modificationAndTargetSelectionQuery } from '@/gql/queries'
+/**
+ * Types imports
+ */
+import type { SelectionOptionModel } from '@/views/SelectionView.vue'
+
+/**
+ * A selection.
+ */
+export interface TargetSelectionModel {
+  /** Currently selected target names. */
+  targetNames: string[]
+  /** Currently selected modification types. */
+  modificationTypes: ModifType[]
+  /** Currently selected species IDs.*/
+  speciesIds: number[]
+}
+
+/**
+ * Available options for modification type selection, independently of other
+ * fields' selection.
+ */
+const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
+  ModifType
+).map((modifType) => ({
+  label: modifType,
+  value: modifType
+}))
+
+/**
+ * Component props
+ */
+defineProps<{
+  /** The current selection. */
+  modelValue?: TargetSelectionModel
+}>()
+
+/**
+ * Component events.
+ */
+defineEmits<{
+  /** Event used to update the `v-model` value. */
+  'update:modelValue': [modelValue: TargetSelectionModel]
+}>()
+
+/**
+ * Current selection of parameters/filters for the modifications to pick.
+ */
+const selection = ref<TargetSelectionModel>({
+  modificationTypes: [],
+  targetNames: [],
+  speciesIds: []
+})
+
+/**
+ * Reactive urql GraphQL query object, updated with query state & response.
+ */
+const gqlQuery = useQuery({
+  query: modificationAndTargetSelectionQuery,
+  variables: toRef(() => ({
+    targetNames: selection.value.targetNames?.length
+      ? selection.value.targetNames
+      : undefined,
+    modificationTypes: selection.value.modificationTypes?.length
+      ? selection.value.modificationTypes
+      : undefined,
+    speciesIds: selection.value.speciesIds?.length
+      ? selection.value.speciesIds
+      : undefined
+  }))
+})
+
+/**
+ * Available modification types, filtered based on other fields' selection (only
+ * modification types which exists with selected options are present).
+ */
+const modificationTypesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.modifications, _isEqual).map(
+    (modification) => modification.type
+  )
+)
+
+/**
+ * Available options for modification type selection, with a `isDisabled` field
+ * on absence in `modificationTypesFiltered`.
+ */
+const modificationTypeOptionsWithDisabling = computed(() =>
+  MODIFICATION_TYPE_OPTIONS_BASE.map((modificationTypeOption) => ({
+    ...modificationTypeOption,
+    isDisabled: !modificationTypesFiltered.value.some(
+      (modificationTypeFiltered) =>
+        modificationTypeFiltered === modificationTypeOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for target name selection, independently of other fields'
+ * selection.
+ */
+const targetNameOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
+    label: target.name,
+    value: target.name
+  }))
+)
+
+/**
+ * Available target names, filtered based on other fields' selection (only
+ * target names which exists with selected options are present).
+ */
+const targetNamesFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.targets, _isEqual).map((target) => target.name)
+)
+
+/**
+ * Available options for target name selection, with a `isDisabled` field on
+ * absence in `targetNamesFiltered`.
+ */
+const targetNameOptionsWithDisabling = computed(() =>
+  targetNameOptionsBase.value.map((targetNameOption) => ({
+    ...targetNameOption,
+    isDisabled: !targetNamesFiltered.value.some(
+      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
+    )
+  }))
+)
+
+/**
+ * Available options for species ID selection, independently of other fields'
+ * selection.
+ */
+const speciesIdOptionsBase = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomesBase, _isEqual).map((genome) => ({
+    label: genome.species?.name,
+    value: genome.species?.id
+  }))
+)
+
+/**
+ * Available species IDs, filtered based on other fields' selection (only
+ * species IDs which exists with selected options are present).
+ */
+const speciesIdsFiltered = computed(() =>
+  _uniqWith(gqlQuery.data.value?.genomes, _isEqual).map(
+    (genome) => genome.species?.id
+  )
+)
+
+/**
+ * Available options for species ID selection, with a `isDisabled` field on
+ * absence in `speciesIdsFiltered`.
+ */
+const speciesIdOptionsWithDisabling = computed(() =>
+  speciesIdOptionsBase.value.map((speciesIdOption) => ({
+    ...speciesIdOption,
+    isDisabled: !speciesIdsFiltered.value.some(
+      (speciesIdFiltered) => speciesIdFiltered === speciesIdOption.value
+    )
+  }))
+)
 </script>
 
 <template>
   <div
     class="grid grid-cols-[max-content_1fr] grid-rows-4 items-center gap-x-16 gap-y-8"
   >
+    <h3 class="text-lg font-bold">Targets</h3>
+    <MultiSelect
+      v-model="selection.targetNames"
+      :options="targetNameOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select targets..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+    >
+      <template #value>
+        <Chip
+          v-for="targetName in selection.targetNames.slice(0, 3)"
+          :key="targetName"
+          class="mr-1"
+          :label="targetName"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              targetNames: _remove(
+                selection.targetNames,
+                (currTargetName) => currTargetName === targetName
+              )
+            })
+          "
+        />
+        <template v-if="selection.targetNames.length > 3">
+          +{{ selection.targetNames.length - 3 }} others...
+        </template>
+      </template>
+    </MultiSelect>
+
+    <h3 class="text-lg font-bold">Modification types</h3>
+    <SelectButton
+      v-model="selection.modificationTypes"
+      :options="modificationTypeOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+    >
+      <template #option="{ option }">
+        <FormattedModificationType
+          :type-code="option.label"
+          class="font-medium"
+        />
+      </template>
+    </SelectButton>
+
+    <h3 class="text-lg font-bold">Species</h3>
+    <MultiSelect
+      v-model="selection.speciesIds"
+      :options="speciesIdOptionsWithDisabling"
+      option-label="label"
+      option-value="value"
+      option-disabled="isDisabled"
+      multiple
+      class="mr-auto"
+      placeholder="Select species..."
+      :max-selected-labels="3"
+      display="chip"
+      filter
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+    >
+      <template #value>
+        <Chip
+          v-for="speciesId in selection.speciesIds.slice(0, 3)"
+          :key="speciesId"
+          class="mr-1"
+          removable
+          @remove.stop="
+            $emit('update:modelValue', {
+              ...selection,
+              speciesIds: _remove(
+                selection.speciesIds,
+                (currSpeciesId) => currSpeciesId === speciesId
+              )
+            })
+          "
+        >
+          <em class="my-1.5">
+            {{
+              formatSpeciesName(
+                speciesIdOptionsBase.find(
+                  (speciesIdOption) => speciesIdOption.value === speciesId
+                )?.label || ''
+              )
+            }}
+          </em>
+        </Chip>
+        <template v-if="selection.speciesIds.length > 3">
+          +{{ selection.speciesIds.length - 3 }} others...
+        </template>
+      </template>
+      <template #option="{ option }">
+        <em>
+          {{ formatSpeciesName(option.label) }}
+        </em>
+      </template>
+    </MultiSelect>
   </div>
 </template>
diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index d404b1a..b63d780 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -14,7 +14,7 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  */
 const documents = {
     "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n": types.SpeciesListQueryDocument,
-    "\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationSelectionQueryDocument,
+    "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
     "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
     "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
     "\n  query speciesByIdQuery($id: Int) {\n    manySpecies(where: { id: $id }) {\n      id\n      name\n      shortname\n      genomes {\n        sequences(where: { featureType: Chromosome }) {\n          id\n          name\n          altnames\n          description\n          length\n          featureType\n          featuresConnection(where: { node: { featureType: Guide } }) {\n            totalCount\n          }\n        }\n      }\n    }\n\n    modifications(where: { target: { genome: { species: { id: $id } } } }) {\n      id\n      name\n      result\n      type\n      guidesAggregate {\n        count\n      }\n    }\n\n    targets(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      modificationsAggregate {\n        count\n      }\n    }\n\n    guides(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      subtype\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          node {\n            id\n          }\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n    }\n  }\n": types.SpeciesByIdQueryDocument,
@@ -45,7 +45,7 @@ export function graphql(source: "\n  query speciesListQuery {\n    manySpecies {
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
+export function graphql(source: "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index 5498cff..b2a4a4d 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6088,14 +6088,14 @@ export type SpeciesListQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
 export type SpeciesListQueryQuery = { __typename?: 'Query', manySpecies: Array<{ __typename?: 'Species', id: number, name: string, shortname: string }> };
 
-export type ModificationSelectionQueryQueryVariables = Exact<{
+export type ModificationAndTargetSelectionQueryQueryVariables = Exact<{
   modificationTypes?: InputMaybe<Array<InputMaybe<ModifType>> | InputMaybe<ModifType>>;
   targetNames?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>> | InputMaybe<Scalars['String']['input']>>;
   speciesIds?: InputMaybe<Array<Scalars['Int']['input']> | Scalars['Int']['input']>;
 }>;
 
 
-export type ModificationSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+export type ModificationAndTargetSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
 
 export type GuideSelectionQueryQueryVariables = Exact<{
   guideSubtypes?: InputMaybe<Array<GuideType> | GuideType>;
@@ -6149,7 +6149,7 @@ export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __
 
 
 export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
-export const ModificationSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationSelectionQueryQuery, ModificationSelectionQueryQueryVariables>;
+export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
 export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
 export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
 export const SpeciesByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sequences"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Guide"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<SpeciesByIdQueryQuery, SpeciesByIdQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index 2caa17b..dde6173 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -17,10 +17,11 @@ export const speciesListQuery = graphql(/* GraphQL */ `
 `)
 
 /**
- * Get available data in the base matching given filters for guide selection.
+ * Get available data in the base matching given filters for modification and
+ * target selection.
  */
-export const modificationSelectionQuery = graphql(/* GraphQL */ `
-  query modificationSelectionQuery(
+export const modificationAndTargetSelectionQuery = graphql(/* GraphQL */ `
+  query modificationAndTargetSelectionQuery(
     $modificationTypes: [ModifType]
     $targetNames: [String]
     $speciesIds: [Int!]
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 638c2a5..afb37d1 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -14,7 +14,9 @@ import ModificationSelectionForm, {
 import GuideSelectionForm, {
   type GuideSelectionModel
 } from '@/components/GuideSelectionForm.vue'
-import TargetSelectionForm from '@/components/TargetSelectionForm.vue'
+import TargetSelectionForm, {
+  type TargetSelectionModel
+} from '@/components/TargetSelectionForm.vue'
 import TabView, { type TabViewChangeEvent } from 'primevue/tabview'
 import TabPanel from 'primevue/tabpanel'
 import Card from 'primevue/card'
@@ -102,7 +104,7 @@ const updateUrlQuery = (e: TabViewChangeEvent) => {
 const selection = ref<{
   modification?: ModificationSelectionModel
   guide?: GuideSelectionModel
-  target?: undefined
+  target?: TargetSelectionModel
 }>({
   modification: undefined,
   guide: undefined,
@@ -203,7 +205,7 @@ const activeModeTableColumns = computed(() => {
             <GuideSelectionForm v-model="selection.guide" />
           </TabPanel>
           <TabPanel header="Target">
-            <TargetSelectionForm />
+            <TargetSelectionForm v-model="selection.target" />
           </TabPanel>
         </TabView>
       </template>
-- 
GitLab


From 0149d875f382914cde365bcfbeb0f89b8fa6cfc4 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 11:44:24 +0200
Subject: [PATCH 29/47] feat(advanced-selection): :sparkles: group targets by
 their types in MultiSelect

---
 src/components/GuideSelectionForm.vue        | 68 +++++++++++++++++---
 src/components/ModificationSelectionForm.vue | 68 +++++++++++++++++---
 src/components/TargetSelectionForm.vue       | 68 +++++++++++++++++---
 src/gql/codegen/gql.ts                       |  8 +--
 src/gql/codegen/graphql.ts                   |  8 +--
 src/gql/queries.ts                           |  2 +
 6 files changed, 184 insertions(+), 38 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index 920a423..98a4199 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -142,7 +142,8 @@ const guideSubtypeOptionsWithDisabling = computed(() =>
 const targetNameOptionsBase = computed(() =>
   _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
     label: target.name,
-    value: target.name
+    value: target.name,
+    groupLabel: target.type
   }))
 )
 
@@ -156,15 +157,60 @@ const targetNamesFiltered = computed(() =>
 
 /**
  * Available options for target name selection, with a `isDisabled` field on
- * absence in `targetNamesFiltered`.
+ * absence in `targetNamesFiltered`, and grouped.
  */
-const targetNameOptionsWithDisabling = computed(() =>
-  targetNameOptionsBase.value.map((targetNameOption) => ({
-    ...targetNameOption,
-    isDisabled: !targetNamesFiltered.value.some(
-      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
-    )
-  }))
+const targetNameOptionsWithDisablingGroups = computed(() =>
+  targetNameOptionsBase.value.reduce(
+    (targetNameOptionsWithDisablingGroups: any[], targetNameOption) => {
+      const targetNameOptionGroupIndex =
+        targetNameOptionsWithDisablingGroups.findIndex(
+          (group) => group.label === targetNameOption.groupLabel
+        )
+      return targetNameOptionGroupIndex !== -1
+        ? [
+            ...targetNameOptionsWithDisablingGroups.slice(
+              0,
+              targetNameOptionGroupIndex
+            ),
+            {
+              ...targetNameOptionsWithDisablingGroups[
+                targetNameOptionGroupIndex
+              ],
+              children: [
+                ...targetNameOptionsWithDisablingGroups[
+                  targetNameOptionGroupIndex
+                ].children,
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            },
+            ...targetNameOptionsWithDisablingGroups.slice(
+              targetNameOptionGroupIndex + 1
+            )
+          ]
+        : [
+            ...targetNameOptionsWithDisablingGroups,
+            {
+              label: targetNameOption.groupLabel,
+              children: [
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            }
+          ]
+    },
+    []
+  )
 )
 
 /**
@@ -245,10 +291,12 @@ const speciesIdOptionsWithDisabling = computed(() =>
     <h3 class="text-lg font-bold">Targets</h3>
     <MultiSelect
       v-model="selection.targetNames"
-      :options="targetNameOptionsWithDisabling"
+      :options="targetNameOptionsWithDisablingGroups"
       option-label="label"
       option-value="value"
       option-disabled="isDisabled"
+      option-group-label="label"
+      option-group-children="children"
       multiple
       class="mr-auto"
       placeholder="Select targets..."
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index c4aadb4..82feb11 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -127,7 +127,8 @@ const modificationTypeOptionsWithDisabling = computed(() =>
 const targetNameOptionsBase = computed(() =>
   _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
     label: target.name,
-    value: target.name
+    value: target.name,
+    groupLabel: target.type
   }))
 )
 
@@ -141,15 +142,60 @@ const targetNamesFiltered = computed(() =>
 
 /**
  * Available options for target name selection, with a `isDisabled` field on
- * absence in `targetNamesFiltered`.
+ * absence in `targetNamesFiltered`, and grouped.
  */
-const targetNameOptionsWithDisabling = computed(() =>
-  targetNameOptionsBase.value.map((targetNameOption) => ({
-    ...targetNameOption,
-    isDisabled: !targetNamesFiltered.value.some(
-      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
-    )
-  }))
+const targetNameOptionsWithDisablingGroups = computed(() =>
+  targetNameOptionsBase.value.reduce(
+    (targetNameOptionsWithDisablingGroups: any[], targetNameOption) => {
+      const targetNameOptionGroupIndex =
+        targetNameOptionsWithDisablingGroups.findIndex(
+          (group) => group.label === targetNameOption.groupLabel
+        )
+      return targetNameOptionGroupIndex !== -1
+        ? [
+            ...targetNameOptionsWithDisablingGroups.slice(
+              0,
+              targetNameOptionGroupIndex
+            ),
+            {
+              ...targetNameOptionsWithDisablingGroups[
+                targetNameOptionGroupIndex
+              ],
+              children: [
+                ...targetNameOptionsWithDisablingGroups[
+                  targetNameOptionGroupIndex
+                ].children,
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            },
+            ...targetNameOptionsWithDisablingGroups.slice(
+              targetNameOptionGroupIndex + 1
+            )
+          ]
+        : [
+            ...targetNameOptionsWithDisablingGroups,
+            {
+              label: targetNameOption.groupLabel,
+              children: [
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            }
+          ]
+    },
+    []
+  )
 )
 
 /**
@@ -213,10 +259,12 @@ const speciesIdOptionsWithDisabling = computed(() =>
     <h3 class="text-lg font-bold">Targets</h3>
     <MultiSelect
       v-model="selection.targetNames"
-      :options="targetNameOptionsWithDisabling"
+      :options="targetNameOptionsWithDisablingGroups"
       option-label="label"
       option-value="value"
       option-disabled="isDisabled"
+      option-group-label="label"
+      option-group-children="children"
       multiple
       class="mr-auto"
       placeholder="Select targets..."
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
index 1075bd0..e2430c9 100644
--- a/src/components/TargetSelectionForm.vue
+++ b/src/components/TargetSelectionForm.vue
@@ -127,7 +127,8 @@ const modificationTypeOptionsWithDisabling = computed(() =>
 const targetNameOptionsBase = computed(() =>
   _uniqWith(gqlQuery.data.value?.targetsBase, _isEqual).map((target) => ({
     label: target.name,
-    value: target.name
+    value: target.name,
+    groupLabel: target.type
   }))
 )
 
@@ -141,15 +142,60 @@ const targetNamesFiltered = computed(() =>
 
 /**
  * Available options for target name selection, with a `isDisabled` field on
- * absence in `targetNamesFiltered`.
+ * absence in `targetNamesFiltered`, and grouped.
  */
-const targetNameOptionsWithDisabling = computed(() =>
-  targetNameOptionsBase.value.map((targetNameOption) => ({
-    ...targetNameOption,
-    isDisabled: !targetNamesFiltered.value.some(
-      (targetNameFiltered) => targetNameFiltered === targetNameOption.value
-    )
-  }))
+const targetNameOptionsWithDisablingGroups = computed(() =>
+  targetNameOptionsBase.value.reduce(
+    (targetNameOptionsWithDisablingGroups: any[], targetNameOption) => {
+      const targetNameOptionGroupIndex =
+        targetNameOptionsWithDisablingGroups.findIndex(
+          (group) => group.label === targetNameOption.groupLabel
+        )
+      return targetNameOptionGroupIndex !== -1
+        ? [
+            ...targetNameOptionsWithDisablingGroups.slice(
+              0,
+              targetNameOptionGroupIndex
+            ),
+            {
+              ...targetNameOptionsWithDisablingGroups[
+                targetNameOptionGroupIndex
+              ],
+              children: [
+                ...targetNameOptionsWithDisablingGroups[
+                  targetNameOptionGroupIndex
+                ].children,
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            },
+            ...targetNameOptionsWithDisablingGroups.slice(
+              targetNameOptionGroupIndex + 1
+            )
+          ]
+        : [
+            ...targetNameOptionsWithDisablingGroups,
+            {
+              label: targetNameOption.groupLabel,
+              children: [
+                {
+                  ...targetNameOption,
+                  isDisabled: !targetNamesFiltered.value.some(
+                    (targetNameFiltered) =>
+                      targetNameFiltered === targetNameOption.value
+                  )
+                }
+              ]
+            }
+          ]
+    },
+    []
+  )
 )
 
 /**
@@ -194,10 +240,12 @@ const speciesIdOptionsWithDisabling = computed(() =>
     <h3 class="text-lg font-bold">Targets</h3>
     <MultiSelect
       v-model="selection.targetNames"
-      :options="targetNameOptionsWithDisabling"
+      :options="targetNameOptionsWithDisablingGroups"
       option-label="label"
       option-value="value"
       option-disabled="isDisabled"
+      option-group-label="label"
+      option-group-children="children"
       multiple
       class="mr-auto"
       placeholder="Select targets..."
diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index b63d780..cec05a3 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -14,8 +14,8 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  */
 const documents = {
     "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n": types.SpeciesListQueryDocument,
-    "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
-    "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
+    "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
+    "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
     "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
     "\n  query speciesByIdQuery($id: Int) {\n    manySpecies(where: { id: $id }) {\n      id\n      name\n      shortname\n      genomes {\n        sequences(where: { featureType: Chromosome }) {\n          id\n          name\n          altnames\n          description\n          length\n          featureType\n          featuresConnection(where: { node: { featureType: Guide } }) {\n            totalCount\n          }\n        }\n      }\n    }\n\n    modifications(where: { target: { genome: { species: { id: $id } } } }) {\n      id\n      name\n      result\n      type\n      guidesAggregate {\n        count\n      }\n    }\n\n    targets(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      modificationsAggregate {\n        count\n      }\n    }\n\n    guides(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      subtype\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          node {\n            id\n          }\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n    }\n  }\n": types.SpeciesByIdQueryDocument,
     "\n  query modificationByIdQuery($id: ID) {\n    modifications(where: { id: $id }) {\n      id\n      name\n      type\n      result\n      position\n      target {\n        id\n        name\n        type\n        genome {\n          species {\n            id\n            name\n          }\n        }\n      }\n      # chebi_id\n      # so_id\n    }\n\n    guides(where: { modifications_SOME: { id: $id } }) {\n      id\n      name\n      type\n    }\n\n    interactions(where: { modification: { id: $id } }) {\n      duplexes {\n        primaryStrandsConnection: strandsConnection(\n          where: { edge: { primary: true } }\n        ) {\n          edges {\n            start\n            end\n            primary\n            node {\n              seq\n              parentConnection {\n                edges {\n                  start\n                  end\n                }\n              }\n            }\n          }\n        }\n        secondaryStrandsConnection: strandsConnection(\n          where: { edge: { primary: false } }\n        ) {\n          edges {\n            start\n            end\n            primary\n            node {\n              seq\n              parentConnection {\n                edges {\n                  start\n                  end\n                }\n              }\n            }\n          }\n        }\n        index\n      }\n      guide {\n        id\n        name\n        subtype\n        type\n      }\n      target {\n        id\n        name\n        type\n      }\n    }\n  }\n": types.ModificationByIdQueryDocument,
@@ -45,11 +45,11 @@ export function graphql(source: "\n  query speciesListQuery {\n    manySpecies {
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
+export function graphql(source: "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
+export function graphql(source: "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index b2a4a4d..969c50a 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6095,7 +6095,7 @@ export type ModificationAndTargetSelectionQueryQueryVariables = Exact<{
 }>;
 
 
-export type ModificationAndTargetSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+export type ModificationAndTargetSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null, type: SequenceType }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
 
 export type GuideSelectionQueryQueryVariables = Exact<{
   guideSubtypes?: InputMaybe<Array<GuideType> | GuideType>;
@@ -6105,7 +6105,7 @@ export type GuideSelectionQueryQueryVariables = Exact<{
 }>;
 
 
-export type GuideSelectionQueryQuery = { __typename?: 'Query', guides: Array<{ __typename?: 'Guide', subtype: GuideType }>, targetsBase: Array<{ __typename?: 'Target', name?: string | null }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+export type GuideSelectionQueryQuery = { __typename?: 'Query', guides: Array<{ __typename?: 'Guide', subtype: GuideType }>, targetsBase: Array<{ __typename?: 'Target', name?: string | null, type: SequenceType }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
 
 export type TableEntriesQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
@@ -6149,8 +6149,8 @@ export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __
 
 
 export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
-export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
-export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
+export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
+export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
 export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
 export const SpeciesByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sequences"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Guide"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<SpeciesByIdQueryQuery, SpeciesByIdQueryQueryVariables>;
 export const ModificationByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"interactions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modification"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duplexes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"primaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":true}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","alias":{"kind":"Name","value":"secondaryStrandsConnection"},"name":{"kind":"Name","value":"strandsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"edge"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"primary"},"value":{"kind":"BooleanValue","value":false}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"primary"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationByIdQueryQuery, ModificationByIdQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index dde6173..a4d94c3 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -28,6 +28,7 @@ export const modificationAndTargetSelectionQuery = graphql(/* GraphQL */ `
   ) {
     targetsBase: targets {
       name
+      type
     }
 
     targets(
@@ -102,6 +103,7 @@ export const guideSelectionQuery = graphql(/* GraphQL */ `
 
     targetsBase: targets {
       name
+      type
     }
 
     targets(
-- 
GitLab


From ec3c308b1b064f1115d272008623e82b02fc5ed3 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 15:44:42 +0200
Subject: [PATCH 30/47] feat(advanced-selection): :lipstick: lighter &
 consistent with other pages style

---
 src/views/SelectionView.vue | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index afb37d1..09602e5 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -31,6 +31,7 @@ import { capitalize as _capitalize } from 'lodash-es'
  * Utils imports
  */
 import { SELECTION_FORM_MODES } from '@/utils/constant'
+import { getColorWithOptionalShade } from '@/utils/colors'
 
 /**
  * Type of data to select.
@@ -171,10 +172,12 @@ const activeModeTableColumns = computed(() => {
 
 <template>
   <MainLayout>
-    <h1 class="mb-8 text-center text-3xl">Advanced selection</h1>
+    <h1 class="text-center text-3xl font-semibold text-slate-700">
+      Advanced selection
+    </h1>
 
     <Card
-      class="mx-16 !rounded-2xl border-2 !shadow-none"
+      class="mx-16 !rounded-2xl border-none !shadow-none"
       :pt="{
         footer: {
           style: {
@@ -192,7 +195,16 @@ const activeModeTableColumns = computed(() => {
               style: {
                 justifyContent: 'center',
                 marginBottom: '2rem',
-                fontSize: '1.25em'
+                fontSize: '1.25em',
+                background: `linear-gradient(white 0 0) padding-box,
+                linear-gradient(90deg,
+                  ${getColorWithOptionalShade('slate', '300')}00 10%,
+                  ${getColorWithOptionalShade('slate', '300')}   15%,
+                  ${getColorWithOptionalShade('slate', '300')}   85%,
+                  ${getColorWithOptionalShade('slate', '300')}00 90%)
+                border-box`,
+                borderStyle: 'dashed',
+                borderColor: 'white'
               }
             }
           }"
-- 
GitLab


From c404781dbb6fb4429fc9f3d4909d78dfd1f2c73e Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 15:46:47 +0200
Subject: [PATCH 31/47] feat(home-view): :sparkles: truncate species list menu
 to 3 entries and add link to table for more

---
 src/gql/codegen/gql.ts     |  4 +--
 src/gql/codegen/graphql.ts |  4 +--
 src/gql/queries.ts         |  5 ++-
 src/views/HomeView.vue     | 62 +++++++++++++++++++++++++++-----------
 4 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index cec05a3..036e6fd 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -13,7 +13,7 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  * Therefore it is highly recommended to use the babel or swc plugin for production.
  */
 const documents = {
-    "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n": types.SpeciesListQueryDocument,
+    "\n  query speciesListQuery {\n    manySpecies(options: { limit: 3 }) {\n      id\n      name\n      shortname\n    }\n    manySpeciesAggregate {\n      count\n    }\n  }\n": types.SpeciesListQueryDocument,
     "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
     "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
     "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
@@ -41,7 +41,7 @@ export function graphql(source: string): unknown;
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n"): (typeof documents)["\n  query speciesListQuery {\n    manySpecies {\n      id\n      name\n      shortname\n    }\n  }\n"];
+export function graphql(source: "\n  query speciesListQuery {\n    manySpecies(options: { limit: 3 }) {\n      id\n      name\n      shortname\n    }\n    manySpeciesAggregate {\n      count\n    }\n  }\n"): (typeof documents)["\n  query speciesListQuery {\n    manySpecies(options: { limit: 3 }) {\n      id\n      name\n      shortname\n    }\n    manySpeciesAggregate {\n      count\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index 969c50a..1bafe8e 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6086,7 +6086,7 @@ export type TargetsConnection = {
 export type SpeciesListQueryQueryVariables = Exact<{ [key: string]: never; }>;
 
 
-export type SpeciesListQueryQuery = { __typename?: 'Query', manySpecies: Array<{ __typename?: 'Species', id: number, name: string, shortname: string }> };
+export type SpeciesListQueryQuery = { __typename?: 'Query', manySpecies: Array<{ __typename?: 'Species', id: number, name: string, shortname: string }>, manySpeciesAggregate: { __typename?: 'SpeciesAggregateSelection', count: number } };
 
 export type ModificationAndTargetSelectionQueryQueryVariables = Exact<{
   modificationTypes?: InputMaybe<Array<InputMaybe<ModifType>> | InputMaybe<ModifType>>;
@@ -6148,7 +6148,7 @@ export type ClusterByIdQueryQueryVariables = Exact<{
 export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __typename?: 'Cluster', id: string, guides: Array<{ __typename?: 'Guide', id: string, name?: string | null, type: SequenceType, subtype: GuideType, modificationsAggregate?: { __typename?: 'GuideModificationModificationsAggregationSelection', count: number } | null, parentConnection: { __typename?: 'GuideParentConnection', edges: Array<{ __typename?: 'GuideParentRelationship', start: number, end: number }> } }>, guidesAggregate?: { __typename?: 'ClusterGuideGuidesAggregationSelection', count: number } | null, referenceGuide: Array<{ __typename?: 'Guide', parent?: { __typename?: 'Chromosome', id: string, name?: string | null } | { __typename?: 'FeatureSequence', id: string, name?: string | null } | { __typename?: 'Guide', id: string, name?: string | null } | { __typename?: 'Target', id: string, name?: string | null } | null, genome?: { __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null } | null }> }> };
 
 
-export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
+export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"options"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"3"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}},{"kind":"Field","name":{"kind":"Name","value":"manySpeciesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
 export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
 export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
 export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index a4d94c3..ec90461 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -8,11 +8,14 @@ import { graphql } from './codegen'
  */
 export const speciesListQuery = graphql(/* GraphQL */ `
   query speciesListQuery {
-    manySpecies {
+    manySpecies(options: { limit: 3 }) {
       id
       name
       shortname
     }
+    manySpeciesAggregate {
+      count
+    }
   }
 `)
 
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 109f6db..906f4fa 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -41,7 +41,7 @@ import { speciesListQuery } from '@/gql/queries'
 import logoUrl from '@/assets/images/logo.svg'
 import { GuideType, ModifType } from '@/gql/codegen/graphql'
 import { formatGuideSubtype } from '@/utils/textFormatting'
-import { isInEnum } from '@/typings/typeUtils'
+import { isDefined, isInEnum } from '@/typings/typeUtils'
 import tailwindDefaultColors from 'tailwindcss/colors'
 
 /**
@@ -86,15 +86,20 @@ const LIST_TARGETS_TABLE_COLUMNS = [
 ]
 
 /**
- * Reactive urql GraphQL query object, updated with query state & response
+ * Useful columns to show to list modifications in the table.
+ */
+const LIST_SPECIES_TABLE_COLUMNS = ['speciesName', 'speciesId']
+
+/**
+ * Reactive urql GraphQL query object, updated with query state & response.
  */
 const gqlQuery = useQuery({
   query: speciesListQuery
 })
 
 /**
- * The list of all the species present in the database,
- * reactively updated when fetched
+ * The list of all the species present in the database,  reactively updated when
+ * fetched.
  */
 const speciesList = computed(() =>
   gqlQuery.data.value?.manySpecies.map((species) => ({
@@ -103,6 +108,14 @@ const speciesList = computed(() =>
   }))
 )
 
+/**
+ * The number of all the species present in the database, reactively updated
+ * when fetched.
+ */
+const speciesCount = computed(
+  () => gqlQuery.data.value?.manySpeciesAggregate.count
+)
+
 /**
  * Menu items.
  */
@@ -196,16 +209,16 @@ const menuItems = computed<MenuItem[]>(() => [
         },
         iconComponent: IconFa6SolidTable
       },
-      // ...Object.values(ModifType)
-      //   .filter((modificationType) => modificationType !== ModifType.Other)
-      //   .map((modificationType) => ({
-      //     label: modificationType,
+      // ...Object.values(UnitType)
+      //   .filter((unitType) => unitType !== UnitType.Other)
+      //   .map((unitType) => ({
+      //     label: unitType,
       //     indent: 1,
       //     route: {
       //       name: 'data-table',
       //       query: {
       //         columns: LIST_TARGETS_TABLE_COLUMNS,
-      //         guideSubtype: modificationType
+      //         unitType: unitType
       //       }
       //     }
       //   })),
@@ -272,15 +285,30 @@ const menuItems = computed<MenuItem[]>(() => [
       },
       {
         label: 'By organism',
-        items: speciesList.value?.map((species) => ({
-          label: species.name,
-          route: {
-            name: 'statistics',
-            query: {
-              id: species.id
+        items: [
+          ...(speciesList.value?.map((species) => ({
+            label: species.name,
+            route: {
+              name: 'statistics',
+              query: {
+                id: species.id
+              }
+            },
+            metadata: {
+              type: 'species'
             }
-          }
-        })),
+          })) || []),
+          speciesCount.value && speciesCount.value > 3
+            ? {
+                label: `+${speciesCount.value - 3} more...`,
+                route: {
+                  name: 'data-table',
+                  query: { columns: LIST_SPECIES_TABLE_COLUMNS }
+                },
+                iconComponent: IconFa6SolidTable
+              }
+            : undefined
+        ].filter(isDefined),
         iconComponent: IconFa6SolidPaw
       }
     ]
-- 
GitLab


From dfcf1b40c0a3224d9bae6dd7721f48cde3b2d89a Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 15:48:06 +0200
Subject: [PATCH 32/47] feat(home-view): :speech_balloon: move modifications
 menu before guides one

---
 src/views/HomeView.vue | 44 +++++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 906f4fa..fac2f26 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -121,37 +121,37 @@ const speciesCount = computed(
  */
 const menuItems = computed<MenuItem[]>(() => [
   {
-    label: 'Guides',
+    label: 'Modifications',
     items: [
       {
-        label: 'All guides',
+        label: 'All modifications',
         route: {
           name: 'data-table',
           query: {
-            columns: LIST_GUIDES_TABLE_COLUMNS
+            columns: LIST_MODIFICATIONS_TABLE_COLUMNS
           }
         },
         iconComponent: IconFa6SolidTable
       },
-      ...Object.values(GuideType)
-        .filter((guideType) => guideType !== GuideType.Other)
-        .map((guideType) => ({
-          label: formatGuideSubtype(guideType),
+      ...Object.values(ModifType)
+        .filter((modificationType) => modificationType !== ModifType.Other)
+        .map((modificationType) => ({
+          label: modificationType,
           indent: 1,
           route: {
             name: 'data-table',
             query: {
-              columns: LIST_GUIDES_TABLE_COLUMNS,
-              guideSubtype: guideType
+              columns: LIST_MODIFICATIONS_TABLE_COLUMNS,
+              modificationType: modificationType
             }
           }
         })),
       {
-        label: 'Advanced guide selection',
+        label: 'Advanced modification selection',
         route: {
           name: 'data-selection',
           query: {
-            mode: 'guide'
+            mode: 'modification'
           }
         },
         iconComponent: IconFa6SolidSliders
@@ -159,37 +159,37 @@ const menuItems = computed<MenuItem[]>(() => [
     ]
   },
   {
-    label: 'Modifications',
+    label: 'Guides',
     items: [
       {
-        label: 'All modifications',
+        label: 'All guides',
         route: {
           name: 'data-table',
           query: {
-            columns: LIST_MODIFICATIONS_TABLE_COLUMNS
+            columns: LIST_GUIDES_TABLE_COLUMNS
           }
         },
         iconComponent: IconFa6SolidTable
       },
-      ...Object.values(ModifType)
-        .filter((modificationType) => modificationType !== ModifType.Other)
-        .map((modificationType) => ({
-          label: modificationType,
+      ...Object.values(GuideType)
+        .filter((guideType) => guideType !== GuideType.Other)
+        .map((guideType) => ({
+          label: formatGuideSubtype(guideType),
           indent: 1,
           route: {
             name: 'data-table',
             query: {
-              columns: LIST_MODIFICATIONS_TABLE_COLUMNS,
-              modificationType: modificationType
+              columns: LIST_GUIDES_TABLE_COLUMNS,
+              guideSubtype: guideType
             }
           }
         })),
       {
-        label: 'Advanced modification selection',
+        label: 'Advanced guide selection',
         route: {
           name: 'data-selection',
           query: {
-            mode: 'modification'
+            mode: 'guide'
           }
         },
         iconComponent: IconFa6SolidSliders
-- 
GitLab


From 7956c886dc3a5187330919ac59dc46a18a7c7011 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 15:48:51 +0200
Subject: [PATCH 33/47] fix(home-view): :adhesive_bandage: species names in
 italic in menu

---
 src/views/HomeView.vue | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index fac2f26..5962450 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -397,7 +397,12 @@ const menuItems = computed<MenuItem[]>(() => [
                   "
                   :type-code="item.label"
                 />
-                <span v-else>{{ item.label }}</span>
+                <span
+                  v-else
+                  :class="{ italic: item.metadata?.type === 'species' }"
+                >
+                  {{ item.label }}
+                </span>
               </a>
             </RouterLink>
             <a
@@ -426,7 +431,11 @@ const menuItems = computed<MenuItem[]>(() => [
                 "
                 :type-code="item.label"
               />
-              <span v-else>{{ item.label }}</span>
+              <span
+                v-else
+                :class="{ italic: item.metadata?.type === 'species' }"
+                >{{ item.label }}</span
+              >
               <icon-fa6-solid-chevron-down
                 v-if="hasSubmenu && root"
                 :="props.submenuicon"
-- 
GitLab


From 9fb0c20856547a6e467be5ad25f8a03fe5835f57 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Mon, 10 Jun 2024 17:34:32 +0200
Subject: [PATCH 34/47] fix(table-view): :bug: filtering hidden columns causing
 some lines not being displayed

as deduplication is occuring before filtering, some lines where removed because similar ones were already displayed with current column selection, but with filtering the selected ones are removed were the removed ones would match
---
 src/views/DataTableView.vue | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 5b60dca..05730ff 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -559,14 +559,32 @@ watchEffect(() => {
 })
 
 /**
- * Deduped table entries, by the values in the currently selected columns.
+ * Columns used for deduplication, i.e. selected ones & filtered ones.
+ */
+const deduplicationColumnFields = computed(() => [
+  ...sortedSelectedColumns.value.map((column) => column.field),
+  ...Object.entries(filters.value).reduce(
+    (filteredColumnFields: string[], [currFilterField, currFilter]) =>
+      currFilter.value
+        ? [...filteredColumnFields, currFilterField]
+        : filteredColumnFields,
+    []
+  )
+])
+
+/**
+ * Deduped table entries, by the values in the currently selected & filtered
+ * columns.
  */
 const dedupedTableEntries = computed(() =>
   _uniqBy(tableEntries.value, (entry) =>
-    sortedSelectedColumns.value
-      .map((column) => _get(entry, column.field))
+    // Concat the entry values in the selected & the filtered columns to form a
+    // "hash" used to dedup the entries
+    deduplicationColumnFields.value
+      .map((columnField) => _get(entry, columnField))
       .join('')
   ).filter((entry) =>
+    // Remove entries for which there is no data in any of the selected column
     sortedSelectedColumns.value
       .map((column) => _get(entry, column.field))
       .join('')
-- 
GitLab


From 789bd457a7a0f461747e19a908747169d519e48a Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 12 Jun 2024 10:48:59 +0200
Subject: [PATCH 35/47] fix(advanced-selection): :bug: removing from chip in
 multiselects not working

---
 src/components/GuideSelectionForm.vue        | 21 ++++++++------------
 src/components/ModificationSelectionForm.vue | 21 ++++++++------------
 src/components/TargetSelectionForm.vue       | 21 ++++++++------------
 3 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index 98a4199..0a6264a 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -16,11 +16,7 @@ import { formatGuideSubtype, formatSpeciesName } from '@/utils/textFormatting'
  * Other 3rd-party imports
  */
 import { useQuery } from '@urql/vue'
-import {
-  uniqWith as _uniqWith,
-  isEqual as _isEqual,
-  remove as _remove
-} from 'lodash-es'
+import { uniqWith as _uniqWith, isEqual as _isEqual } from 'lodash-es'
 /**
  * Utils imports
  */
@@ -315,10 +311,10 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              targetNames: _remove(
-                selection.targetNames,
-                (currTargetName) => currTargetName === targetName
-              )
+              targetNames: (selection.targetNames =
+                selection.targetNames.filter(
+                  (currTargetName) => currTargetName !== targetName
+                ))
             })
           "
         />
@@ -371,10 +367,9 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              speciesIds: _remove(
-                selection.speciesIds,
-                (currSpeciesId) => currSpeciesId === speciesId
-              )
+              speciesIds: (selection.speciesIds = selection.speciesIds.filter(
+                (currSpeciesId) => currSpeciesId !== speciesId
+              ))
             })
           "
         >
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index 82feb11..1d6adbc 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -16,11 +16,7 @@ import { formatSpeciesName } from '@/utils/textFormatting'
  * Other 3rd-party imports
  */
 import { useQuery } from '@urql/vue'
-import {
-  uniqWith as _uniqWith,
-  isEqual as _isEqual,
-  remove as _remove
-} from 'lodash-es'
+import { uniqWith as _uniqWith, isEqual as _isEqual } from 'lodash-es'
 /**
  * Utils imports
  */
@@ -283,10 +279,10 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              targetNames: _remove(
-                selection.targetNames,
-                (currTargetName) => currTargetName === targetName
-              )
+              targetNames: (selection.targetNames =
+                selection.targetNames.filter(
+                  (currTargetName) => currTargetName !== targetName
+                ))
             })
           "
         />
@@ -320,10 +316,9 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              speciesIds: _remove(
-                selection.speciesIds,
-                (currSpeciesId) => currSpeciesId === speciesId
-              )
+              speciesIds: (selection.speciesIds = selection.speciesIds.filter(
+                (currSpeciesId) => currSpeciesId !== speciesId
+              ))
             })
           "
         >
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
index e2430c9..446c94d 100644
--- a/src/components/TargetSelectionForm.vue
+++ b/src/components/TargetSelectionForm.vue
@@ -16,11 +16,7 @@ import { formatSpeciesName } from '@/utils/textFormatting'
  * Other 3rd-party imports
  */
 import { useQuery } from '@urql/vue'
-import {
-  uniqWith as _uniqWith,
-  isEqual as _isEqual,
-  remove as _remove
-} from 'lodash-es'
+import { uniqWith as _uniqWith, isEqual as _isEqual } from 'lodash-es'
 /**
  * Utils imports
  */
@@ -264,10 +260,10 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              targetNames: _remove(
-                selection.targetNames,
-                (currTargetName) => currTargetName === targetName
-              )
+              targetNames: (selection.targetNames =
+                selection.targetNames.filter(
+                  (currTargetName) => currTargetName !== targetName
+                ))
             })
           "
         />
@@ -320,10 +316,9 @@ const speciesIdOptionsWithDisabling = computed(() =>
           @remove.stop="
             $emit('update:modelValue', {
               ...selection,
-              speciesIds: _remove(
-                selection.speciesIds,
-                (currSpeciesId) => currSpeciesId === speciesId
-              )
+              speciesIds: (selection.speciesIds = selection.speciesIds.filter(
+                (currSpeciesId) => currSpeciesId !== speciesId
+              ))
             })
           "
         >
-- 
GitLab


From b4cf27f6eef3cd86c8e0704adcf67023fe667fac Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 12 Jun 2024 15:09:12 +0200
Subject: [PATCH 36/47] feat(router): :sparkles: add scroll behavior to handle
 anchors & saved positions

---
 src/router/index.ts | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/router/index.ts b/src/router/index.ts
index 11f7199..e19e909 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -214,7 +214,23 @@ const router = createRouter({
         to.query && console.warn(`Route query :`, to.query)
       }
     }
-  ]
+  ],
+  scrollBehavior: (to, _from, savedPosition) =>
+    // Scroll to anchor if present (smoothly), if not to saved position, and if
+    // none to top
+    to.hash
+      ? new Promise((resolve) => {
+          setTimeout(() => {
+            resolve({
+              el: to.hash,
+              top: 20,
+              behavior: 'smooth'
+            })
+          }, 500)
+        })
+      : savedPosition
+      ? { ...savedPosition }
+      : { top: 0 }
 })
 
 router.afterEach((to) => {
-- 
GitLab


From 2f8a2a90a79cdc79be1247b7d74eea4d0ae3fe9c Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 12 Jun 2024 15:10:04 +0200
Subject: [PATCH 37/47] feat: :sparkles: add anchors to detail views panels

---
 src/views/GuideView.vue        | 2 ++
 src/views/ModificationView.vue | 1 +
 src/views/TargetView.vue       | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/src/views/GuideView.vue b/src/views/GuideView.vue
index 1ffdf26..eea319d 100644
--- a/src/views/GuideView.vue
+++ b/src/views/GuideView.vue
@@ -696,6 +696,7 @@ const ontologyLinks = computed(() => ({
     </Panel>
 
     <Panel
+      id="sequence-panel"
       toggleable
       class="mx-auto mb-16 max-w-7xl break-words 2xl:max-w-[100rem]"
       :pt="{
@@ -760,6 +761,7 @@ const ontologyLinks = computed(() => ({
     </Panel>
 
     <Panel
+      id="graphics-panel"
       toggleable
       class="mx-auto mb-16 max-w-7xl break-words 2xl:max-w-[100rem]"
       :pt="{
diff --git a/src/views/ModificationView.vue b/src/views/ModificationView.vue
index 17bbad9..41397e1 100644
--- a/src/views/ModificationView.vue
+++ b/src/views/ModificationView.vue
@@ -356,6 +356,7 @@ const linkedGuidesFieldName = computed(
     </Panel>
 
     <Panel
+      id="graphics-panel"
       toggleable
       class="mx-auto mb-16 max-w-7xl break-words 2xl:max-w-[100rem]"
       :pt="{
diff --git a/src/views/TargetView.vue b/src/views/TargetView.vue
index 16c6adb..3d1d5a8 100644
--- a/src/views/TargetView.vue
+++ b/src/views/TargetView.vue
@@ -626,6 +626,7 @@ const ontologyLinks = computed(() => ({
     </Panel>
 
     <Panel
+      id="sequence-panel"
       toggleable
       class="mx-auto mb-16 max-w-7xl break-words 2xl:max-w-[100rem]"
       :pt="{
@@ -671,6 +672,7 @@ const ontologyLinks = computed(() => ({
     </Panel>
 
     <Panel
+      id="graphics-panel"
       toggleable
       class="mx-auto mb-16 max-w-7xl break-words 2xl:max-w-[100rem]"
       :pt="{
-- 
GitLab


From cef91b4a5e61d8f3b321c62bc86154f1c061939d Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 12 Jun 2024 15:27:32 +0200
Subject: [PATCH 38/47] refactor(router): :recycle: rename routes

---
 src/layouts/MainLayout.vue  |  2 +-
 src/router/index.ts         |  4 ++--
 src/views/DataTableView.vue |  6 ++----
 src/views/HomeView.vue      | 20 ++++++++++----------
 src/views/SelectionView.vue |  4 ++--
 5 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index be6875d..e1a386c 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -30,7 +30,7 @@ const menuItems: CustomMenuItem[] = [
   {
     label: 'Data Table',
     iconComponent: IconFa6SolidTable,
-    routerDest: { name: 'data-table' }
+    routerDest: { name: 'table' }
   },
   {
     label: 'API',
diff --git a/src/router/index.ts b/src/router/index.ts
index e19e909..9adc6c0 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -41,7 +41,7 @@ const router = createRouter({
     },
     {
       path: '/select',
-      name: 'data-selection',
+      name: 'selection',
       component: () => import('@/views/SelectionView.vue'),
       props: (to) => ({
         mode: to.query.mode
@@ -62,7 +62,7 @@ const router = createRouter({
     },
     {
       path: '/data',
-      name: 'data-table',
+      name: 'table',
       component: () => import('@/views/DataTableView.vue'),
       props: (to) => ({
         initialColumnIds: Array.isArray(to.query.columns)
diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 05730ff..99380c5 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -596,9 +596,7 @@ const dedupedTableEntries = computed(() =>
  */
 const scrollToTableTop = () =>
   setTimeout(() => {
-    document
-      .getElementById('data-table')
-      ?.scrollTo({ top: 0, behavior: 'smooth' })
+    document.getElementById('table')?.scrollTo({ top: 0, behavior: 'smooth' })
   }, 10)
 </script>
 
@@ -628,7 +626,7 @@ const scrollToTableTop = () =>
         size="small"
         :pt="{
           wrapper: {
-            id: 'data-table'
+            id: 'table'
           },
           table: {
             style: {
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 5962450..972fe86 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -126,7 +126,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'All modifications',
         route: {
-          name: 'data-table',
+          name: 'table',
           query: {
             columns: LIST_MODIFICATIONS_TABLE_COLUMNS
           }
@@ -139,7 +139,7 @@ const menuItems = computed<MenuItem[]>(() => [
           label: modificationType,
           indent: 1,
           route: {
-            name: 'data-table',
+            name: 'table',
             query: {
               columns: LIST_MODIFICATIONS_TABLE_COLUMNS,
               modificationType: modificationType
@@ -149,7 +149,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'Advanced modification selection',
         route: {
-          name: 'data-selection',
+          name: 'selection',
           query: {
             mode: 'modification'
           }
@@ -164,7 +164,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'All guides',
         route: {
-          name: 'data-table',
+          name: 'table',
           query: {
             columns: LIST_GUIDES_TABLE_COLUMNS
           }
@@ -177,7 +177,7 @@ const menuItems = computed<MenuItem[]>(() => [
           label: formatGuideSubtype(guideType),
           indent: 1,
           route: {
-            name: 'data-table',
+            name: 'table',
             query: {
               columns: LIST_GUIDES_TABLE_COLUMNS,
               guideSubtype: guideType
@@ -187,7 +187,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'Advanced guide selection',
         route: {
-          name: 'data-selection',
+          name: 'selection',
           query: {
             mode: 'guide'
           }
@@ -202,7 +202,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'All targets',
         route: {
-          name: 'data-table',
+          name: 'table',
           query: {
             columns: LIST_TARGETS_TABLE_COLUMNS
           }
@@ -215,7 +215,7 @@ const menuItems = computed<MenuItem[]>(() => [
       //     label: unitType,
       //     indent: 1,
       //     route: {
-      //       name: 'data-table',
+      //       name: 'table',
       //       query: {
       //         columns: LIST_TARGETS_TABLE_COLUMNS,
       //         unitType: unitType
@@ -225,7 +225,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'Advanced target selection',
         route: {
-          name: 'data-selection',
+          name: 'selection',
           query: {
             mode: 'target'
           }
@@ -302,7 +302,7 @@ const menuItems = computed<MenuItem[]>(() => [
             ? {
                 label: `+${speciesCount.value - 3} more...`,
                 route: {
-                  name: 'data-table',
+                  name: 'table',
                   query: { columns: LIST_SPECIES_TABLE_COLUMNS }
                 },
                 iconComponent: IconFa6SolidTable
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 09602e5..7f009ef 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -95,7 +95,7 @@ useTitle(pageTitle)
 const updateUrlQuery = (e: TabViewChangeEvent) => {
   const newMode = SELECTION_FORM_MODES[e.index]
   if (newMode) {
-    router.replace({ name: 'data-selection', query: { mode: newMode } })
+    router.replace({ name: 'selection', query: { mode: newMode } })
   }
 }
 
@@ -225,7 +225,7 @@ const activeModeTableColumns = computed(() => {
       <template #footer>
         <RouterLink
           :to="{
-            name: 'data-table',
+            name: 'table',
             query: {
               columns: activeModeTableColumns,
               ...tableFilters
-- 
GitLab


From a7798ec25cb13964a9a598e04564d8809143965a Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 12 Jun 2024 16:41:43 +0200
Subject: [PATCH 39/47] fix(router): :bug: wrap useTitle bindings in onMounted
 hook

This allows to correctly overwrite the default value set in router (i.e. set it after having set the default)
---
 src/router/index.ts            | 4 +---
 src/views/ClusterView.vue      | 4 ++--
 src/views/GuideView.vue        | 4 ++--
 src/views/ModificationView.vue | 4 ++--
 src/views/SelectionView.vue    | 4 ++--
 src/views/StatisticsView.vue   | 4 ++--
 src/views/TargetView.vue       | 4 ++--
 7 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/src/router/index.ts b/src/router/index.ts
index 9adc6c0..fb96c20 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -26,8 +26,6 @@ declare module 'vue-router' {
   }
 }
 
-const title = useTitle()
-
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
   routes: [
@@ -234,7 +232,7 @@ const router = createRouter({
 })
 
 router.afterEach((to) => {
-  title.value = (to.meta.title ? `${to.meta.title} | ` : '') + 'SnoBoard'
+  useTitle((to.meta.title ? `${to.meta.title} | ` : '') + 'SnoBoard')
   console.info('Title changed.')
 })
 
diff --git a/src/views/ClusterView.vue b/src/views/ClusterView.vue
index 8acdd31..6365a52 100644
--- a/src/views/ClusterView.vue
+++ b/src/views/ClusterView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, toRef } from 'vue'
+import { computed, onMounted, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -74,7 +74,7 @@ const pageTitle = computed(() =>
     : 'Cluster | SnoBoard'
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * Species name, formatted for display
diff --git a/src/views/GuideView.vue b/src/views/GuideView.vue
index eea319d..51e9928 100644
--- a/src/views/GuideView.vue
+++ b/src/views/GuideView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, toRef } from 'vue'
+import { computed, onMounted, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -127,7 +127,7 @@ const pageTitle = computed(() =>
   guide.value ? `${guide.value.name} • Guide | SnoBoard` : 'Guide | SnoBoard'
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * The list of the interaction, formatted for display. If some mandatory fields
diff --git a/src/views/ModificationView.vue b/src/views/ModificationView.vue
index 41397e1..7887ca7 100644
--- a/src/views/ModificationView.vue
+++ b/src/views/ModificationView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, toRef } from 'vue'
+import { computed, onMounted, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -79,7 +79,7 @@ const pageTitle = computed(() =>
     : 'Modification | SnoBoard'
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * The list of the interaction, formatted for display. If some mandatory fields
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 7f009ef..de2652c 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, ref } from 'vue'
+import { computed, onMounted, ref } from 'vue'
 import { useRouter } from 'vue-router'
 /**
  * Components imports
@@ -86,7 +86,7 @@ const pageTitle = computed(
   () => `${_capitalize(activeMode.value)} • Selection | SnoBoard`
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * Callback to change the URL when switching tab.
diff --git a/src/views/StatisticsView.vue b/src/views/StatisticsView.vue
index e35b28b..1cf70fe 100644
--- a/src/views/StatisticsView.vue
+++ b/src/views/StatisticsView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { ref, computed, toRef } from 'vue'
+import { ref, computed, toRef, onMounted } from 'vue'
 /**
  * Components imports
  */
@@ -93,7 +93,7 @@ const pageTitle = computed(() =>
     : 'Guide | SnoBoard'
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * The field selected for displaying the list of its entries (targets, guides
diff --git a/src/views/TargetView.vue b/src/views/TargetView.vue
index 3d1d5a8..086b030 100644
--- a/src/views/TargetView.vue
+++ b/src/views/TargetView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, toRef } from 'vue'
+import { computed, onMounted, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -188,7 +188,7 @@ const pageTitle = computed(() =>
     : 'Target | SnoBoard'
 )
 // Bind actual page title to computed one
-useTitle(pageTitle)
+onMounted(() => useTitle(pageTitle))
 
 /**
  * The list of the interaction, formatted for display. If some mandatory fields
-- 
GitLab


From b2614d92bef575271aabd993c4fd915d48d1b0a8 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Thu, 13 Jun 2024 10:30:40 +0200
Subject: [PATCH 40/47] refactor(advanced-selection): :recycle: change name of
 the v-modelof the selection forms

---
 src/components/GuideSelectionForm.vue        | 18 +++++++++---------
 src/components/ModificationSelectionForm.vue | 16 ++++++++--------
 src/components/TargetSelectionForm.vue       | 16 ++++++++--------
 src/views/SelectionView.vue                  | 10 +++++++---
 4 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/src/components/GuideSelectionForm.vue b/src/components/GuideSelectionForm.vue
index 0a6264a..6aca482 100644
--- a/src/components/GuideSelectionForm.vue
+++ b/src/components/GuideSelectionForm.vue
@@ -67,15 +67,15 @@ const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
  */
 defineProps<{
   /** The current selection. */
-  modelValue?: GuideSelectionModel
+  selectionModel?: GuideSelectionModel
 }>()
 
 /**
  * Component events.
  */
 defineEmits<{
-  /** Event used to update the `v-model` value. */
-  'update:modelValue': [modelValue: GuideSelectionModel]
+  /** Event used to update the `v-model:selectionModel` value. */
+  'update:selectionModel': [selectionModel: GuideSelectionModel]
 }>()
 
 /**
@@ -281,7 +281,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       option-disabled="isDisabled"
       multiple
       class="mr-auto"
-      @update:model-value="(selectedGuideSubtypes: GuideType[]) => $emit('update:modelValue', {...selection, guideSubtypes:selectedGuideSubtypes })"
+      @update:model-value="(selectedGuideSubtypes: GuideType[]) => $emit('update:selectionModel', {...selection, guideSubtypes:selectedGuideSubtypes })"
     />
 
     <h3 class="text-lg font-bold">Targets</h3>
@@ -299,7 +299,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:selectionModel', {...selection, targetNames:selectedTargetNames })"
     >
       <template #value>
         <Chip
@@ -309,7 +309,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           :label="targetName"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               targetNames: (selection.targetNames =
                 selection.targetNames.filter(
@@ -333,7 +333,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       option-disabled="isDisabled"
       multiple
       class="mr-auto"
-      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:selectionModel', {...selection, modificationTypes:selectedModificationTypes })"
     >
       <template #option="{ option }">
         <FormattedModificationType
@@ -356,7 +356,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:selectionModel', {...selection, speciesIds:selectedSpeciesIds })"
     >
       <template #value>
         <Chip
@@ -365,7 +365,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           class="mr-1"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               speciesIds: (selection.speciesIds = selection.speciesIds.filter(
                 (currSpeciesId) => currSpeciesId !== speciesId
diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index 1d6adbc..2189a3e 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -54,15 +54,15 @@ const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
  */
 defineProps<{
   /** The current selection. */
-  modelValue?: ModificationSelectionModel
+  selectionModel?: ModificationSelectionModel
 }>()
 
 /**
  * Component events.
  */
 defineEmits<{
-  /** Event used to update the `v-model` value. */
-  'update:modelValue': [modelValue: ModificationSelectionModel]
+  /** Event used to update the `v-model:selectionModel` value. */
+  'update:selectionModel': [selectionModel: ModificationSelectionModel]
 }>()
 
 /**
@@ -242,7 +242,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       option-disabled="isDisabled"
       multiple
       class="mr-auto"
-      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:selectionModel', {...selection, modificationTypes:selectedModificationTypes })"
     >
       <template #option="{ option }">
         <FormattedModificationType
@@ -267,7 +267,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:selectionModel', {...selection, targetNames:selectedTargetNames })"
     >
       <template #value>
         <Chip
@@ -277,7 +277,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           :label="targetName"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               targetNames: (selection.targetNames =
                 selection.targetNames.filter(
@@ -305,7 +305,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:selectionModel', {...selection, speciesIds:selectedSpeciesIds })"
     >
       <template #value>
         <Chip
@@ -314,7 +314,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           class="mr-1"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               speciesIds: (selection.speciesIds = selection.speciesIds.filter(
                 (currSpeciesId) => currSpeciesId !== speciesId
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
index 446c94d..7079191 100644
--- a/src/components/TargetSelectionForm.vue
+++ b/src/components/TargetSelectionForm.vue
@@ -54,15 +54,15 @@ const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
  */
 defineProps<{
   /** The current selection. */
-  modelValue?: TargetSelectionModel
+  selectionModel?: TargetSelectionModel
 }>()
 
 /**
  * Component events.
  */
 defineEmits<{
-  /** Event used to update the `v-model` value. */
-  'update:modelValue': [modelValue: TargetSelectionModel]
+  /** Event used to update the `v-model:selectionModel` value. */
+  'update:selectionModel': [selectionModel: TargetSelectionModel]
 }>()
 
 /**
@@ -248,7 +248,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedTargetNames: string[]) => $emit('update:modelValue', {...selection, targetNames:selectedTargetNames })"
+      @update:model-value="(selectedTargetNames: string[]) => $emit('update:selectionModel', {...selection, targetNames:selectedTargetNames })"
     >
       <template #value>
         <Chip
@@ -258,7 +258,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           :label="targetName"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               targetNames: (selection.targetNames =
                 selection.targetNames.filter(
@@ -282,7 +282,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       option-disabled="isDisabled"
       multiple
       class="mr-auto"
-      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:modelValue', {...selection, modificationTypes:selectedModificationTypes })"
+      @update:model-value="(selectedModificationTypes: ModifType[]) => $emit('update:selectionModel', {...selection, modificationTypes:selectedModificationTypes })"
     >
       <template #option="{ option }">
         <FormattedModificationType
@@ -305,7 +305,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
       :max-selected-labels="3"
       display="chip"
       filter
-      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:modelValue', {...selection, speciesIds:selectedSpeciesIds })"
+      @update:model-value="(selectedSpeciesIds: number[]) => $emit('update:selectionModel', {...selection, speciesIds:selectedSpeciesIds })"
     >
       <template #value>
         <Chip
@@ -314,7 +314,7 @@ const speciesIdOptionsWithDisabling = computed(() =>
           class="mr-1"
           removable
           @remove.stop="
-            $emit('update:modelValue', {
+            $emit('update:selectionModel', {
               ...selection,
               speciesIds: (selection.speciesIds = selection.speciesIds.filter(
                 (currSpeciesId) => currSpeciesId !== speciesId
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index de2652c..b625d58 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -211,13 +211,17 @@ const activeModeTableColumns = computed(() => {
           @tab-change="updateUrlQuery"
         >
           <TabPanel header="Modification">
-            <ModificationSelectionForm v-model="selection.modification" />
+            <ModificationSelectionForm
+              v-model:selection-model="selection.modification"
+            />
           </TabPanel>
           <TabPanel header="Guide">
-            <GuideSelectionForm v-model="selection.guide" />
+            <GuideSelectionForm v-model:selection-model="selection.guide" />
           </TabPanel>
           <TabPanel header="Target">
-            <TargetSelectionForm v-model="selection.target" />
+            <TargetSelectionForm
+              v-model:selection-model="selection.target"
+            />
           </TabPanel>
         </TabView>
       </template>
-- 
GitLab


From 8691f304770d17be8ad82ad32091ae21903cabfa Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Thu, 13 Jun 2024 10:34:31 +0200
Subject: [PATCH 41/47] feat(advanced-selection): :sparkles: add a v-model for
 unique target id when available

---
 src/components/ModificationSelectionForm.vue | 29 ++++++-
 src/components/TargetSelectionForm.vue       | 29 ++++++-
 src/gql/codegen/gql.ts                       |  4 +-
 src/gql/codegen/graphql.ts                   |  4 +-
 src/gql/queries.ts                           |  1 +
 src/views/SelectionView.vue                  | 84 ++++++++++----------
 src/views/StatisticsView.vue                 |  2 +-
 7 files changed, 104 insertions(+), 49 deletions(-)

diff --git a/src/components/ModificationSelectionForm.vue b/src/components/ModificationSelectionForm.vue
index 2189a3e..a87d53f 100644
--- a/src/components/ModificationSelectionForm.vue
+++ b/src/components/ModificationSelectionForm.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, ref, toRef } from 'vue'
+import { computed, ref, toRef, watchEffect } from 'vue'
 /**
  * Component imports
  */
@@ -55,14 +55,20 @@ const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
 defineProps<{
   /** The current selection. */
   selectionModel?: ModificationSelectionModel
+  /** The ID of the target which matches the selection if it is unique (i.e. a
+   * single target name & a single species is selected), `undefined` otherwise.
+   */
+  onlyTargetId?: string
 }>()
 
 /**
  * Component events.
  */
-defineEmits<{
+const emit = defineEmits<{
   /** Event used to update the `v-model:selectionModel` value. */
   'update:selectionModel': [selectionModel: ModificationSelectionModel]
+  /** Event used to update the `v-model:onlyTargetId` value. */
+  'update:onlyTargetId': [onlyTargetId: string | undefined]
 }>()
 
 /**
@@ -227,6 +233,25 @@ const speciesIdOptionsWithDisabling = computed(() =>
     )
   }))
 )
+
+/**
+ * Watcher to update the `v-model:onlyTargetId` value.
+ */
+watchEffect(() => {
+  if (
+    selection.value.speciesIds.length === 1 &&
+    selection.value.targetNames.length === 1
+  ) {
+    const onlyTargetId = gqlQuery.data.value?.targets.find(
+      (target) => target.name === selection.value.targetNames[0]
+    )?.id
+    if (onlyTargetId) {
+      emit('update:onlyTargetId', onlyTargetId)
+      return
+    }
+  }
+  emit('update:onlyTargetId', undefined)
+})
 </script>
 
 <template>
diff --git a/src/components/TargetSelectionForm.vue b/src/components/TargetSelectionForm.vue
index 7079191..9c4925c 100644
--- a/src/components/TargetSelectionForm.vue
+++ b/src/components/TargetSelectionForm.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, ref, toRef } from 'vue'
+import { computed, ref, toRef, watchEffect } from 'vue'
 /**
  * Component imports
  */
@@ -55,14 +55,20 @@ const MODIFICATION_TYPE_OPTIONS_BASE: SelectionOptionModel[] = Object.values(
 defineProps<{
   /** The current selection. */
   selectionModel?: TargetSelectionModel
+  /** The ID of the target which matches the selection if it is unique (i.e. a
+   * single target name & a single species is selected), `undefined` otherwise.
+   */
+  onlyTargetId?: string
 }>()
 
 /**
  * Component events.
  */
-defineEmits<{
+const emit = defineEmits<{
   /** Event used to update the `v-model:selectionModel` value. */
   'update:selectionModel': [selectionModel: TargetSelectionModel]
+  /** Event used to update the `v-model:onlyTargetId` value. */
+  'update:onlyTargetId': [onlyTargetId: string | undefined]
 }>()
 
 /**
@@ -227,6 +233,25 @@ const speciesIdOptionsWithDisabling = computed(() =>
     )
   }))
 )
+
+/**
+ * Watcher to update the `v-model:onlyTargetId` value.
+ */
+watchEffect(() => {
+  if (
+    selection.value.speciesIds.length === 1 &&
+    selection.value.targetNames.length === 1
+  ) {
+    const onlyTargetId = gqlQuery.data.value?.targets.find(
+      (target) => target.name === selection.value.targetNames[0]
+    )?.id
+    if (onlyTargetId) {
+      emit('update:onlyTargetId', onlyTargetId)
+      return
+    }
+  }
+  emit('update:onlyTargetId', undefined)
+})
 </script>
 
 <template>
diff --git a/src/gql/codegen/gql.ts b/src/gql/codegen/gql.ts
index 036e6fd..a1fc805 100644
--- a/src/gql/codegen/gql.ts
+++ b/src/gql/codegen/gql.ts
@@ -14,7 +14,7 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
  */
 const documents = {
     "\n  query speciesListQuery {\n    manySpecies(options: { limit: 3 }) {\n      id\n      name\n      shortname\n    }\n    manySpeciesAggregate {\n      count\n    }\n  }\n": types.SpeciesListQueryDocument,
-    "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
+    "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n      id\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.ModificationAndTargetSelectionQueryDocument,
     "\n  query guideSelectionQuery(\n    $guideSubtypes: [GuideType!]\n    $targetNames: [String]\n    $modificationTypes: [ModifType]\n    $speciesIds: [Int!]\n  ) {\n    guides(\n      where: {\n        modifications_SOME: {\n          target: { name_IN: $targetNames }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      subtype\n    }\n\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: {\n          guides_SOME: { subtype_IN: $guideSubtypes }\n          type_IN: $modificationTypes\n        }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n        guides_SOME: { subtype_IN: $guideSubtypes }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        AND: [\n          {\n            sequencesConnection_SOME: {\n              node: {\n                _on: {\n                  Target: {\n                    name_IN: $targetNames\n                    modifications_SOME: { type_IN: $modificationTypes }\n                  }\n                }\n              }\n            }\n          }\n          {\n            sequencesConnection_SOME: {\n              node: { _on: { Guide: { subtype_IN: $guideSubtypes } } }\n            }\n          }\n        ]\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n": types.GuideSelectionQueryDocument,
     "\n  query tableEntriesQuery {\n    tableEntries {\n      id\n      modification {\n        id\n        name\n        position\n        result\n        type\n        target {\n          id\n          name\n          type\n          length\n          genome {\n            species {\n              id\n              name\n            }\n          }\n          parentConnection(where: { node: { featureType: Chromosome } }) {\n            edges {\n              start\n              end\n              strand\n              node {\n                id\n                name\n              }\n            }\n          }\n        }\n      }\n      guide {\n        id\n        name\n        type\n        subtype\n        length\n        seq\n        parentConnection(where: { node: { featureType: Chromosome } }) {\n          edges {\n            start\n            end\n            strand\n            node {\n              id\n              name\n              length\n            }\n          }\n        }\n      }\n    }\n\n    targets {\n      name\n    }\n\n    genomes {\n      species {\n        name\n        id\n      }\n    }\n  }\n": types.TableEntriesQueryDocument,
     "\n  query speciesByIdQuery($id: Int) {\n    manySpecies(where: { id: $id }) {\n      id\n      name\n      shortname\n      genomes {\n        sequences(where: { featureType: Chromosome }) {\n          id\n          name\n          altnames\n          description\n          length\n          featureType\n          featuresConnection(where: { node: { featureType: Guide } }) {\n            totalCount\n          }\n        }\n      }\n    }\n\n    modifications(where: { target: { genome: { species: { id: $id } } } }) {\n      id\n      name\n      result\n      type\n      guidesAggregate {\n        count\n      }\n    }\n\n    targets(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      modificationsAggregate {\n        count\n      }\n    }\n\n    guides(where: { genome: { species: { id: $id } } }) {\n      id\n      name\n      type\n      subtype\n      parentConnection(where: { node: { featureType: Chromosome } }) {\n        edges {\n          start\n          end\n          node {\n            id\n          }\n        }\n      }\n      modificationsAggregate {\n        count\n      }\n    }\n  }\n": types.SpeciesByIdQueryDocument,
@@ -45,7 +45,7 @@ export function graphql(source: "\n  query speciesListQuery {\n    manySpecies(o
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
-export function graphql(source: "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
+export function graphql(source: "\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n      id\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"): (typeof documents)["\n  query modificationAndTargetSelectionQuery(\n    $modificationTypes: [ModifType]\n    $targetNames: [String]\n    $speciesIds: [Int!]\n  ) {\n    targetsBase: targets {\n      name\n      type\n    }\n\n    targets(\n      where: {\n        modifications_SOME: { type_IN: $modificationTypes }\n        genome: { species: { id_IN: $speciesIds } }\n      }\n    ) {\n      name\n      id\n    }\n\n    modifications(\n      where: {\n        target: {\n          name_IN: $targetNames\n          genome: { species: { id_IN: $speciesIds } }\n        }\n      }\n    ) {\n      type\n    }\n\n    genomesBase: genomes {\n      species {\n        name\n        id\n      }\n    }\n\n    genomes(\n      where: {\n        sequencesConnection_SOME: {\n          node: {\n            _on: {\n              Target: {\n                name_IN: $targetNames\n                modifications_SOME: { type_IN: $modificationTypes }\n              }\n            }\n          }\n        }\n      }\n    ) {\n      species {\n        id\n      }\n    }\n  }\n"];
 /**
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
  */
diff --git a/src/gql/codegen/graphql.ts b/src/gql/codegen/graphql.ts
index 1bafe8e..7705b35 100644
--- a/src/gql/codegen/graphql.ts
+++ b/src/gql/codegen/graphql.ts
@@ -6095,7 +6095,7 @@ export type ModificationAndTargetSelectionQueryQueryVariables = Exact<{
 }>;
 
 
-export type ModificationAndTargetSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null, type: SequenceType }>, targets: Array<{ __typename?: 'Target', name?: string | null }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
+export type ModificationAndTargetSelectionQueryQuery = { __typename?: 'Query', targetsBase: Array<{ __typename?: 'Target', name?: string | null, type: SequenceType }>, targets: Array<{ __typename?: 'Target', name?: string | null, id: string }>, modifications: Array<{ __typename?: 'Modification', type?: ModifType | null }>, genomesBase: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', name: string, id: number } | null }>, genomes: Array<{ __typename?: 'Genome', species?: { __typename?: 'Species', id: number } | null }> };
 
 export type GuideSelectionQueryQueryVariables = Exact<{
   guideSubtypes?: InputMaybe<Array<GuideType> | GuideType>;
@@ -6149,7 +6149,7 @@ export type ClusterByIdQueryQuery = { __typename?: 'Query', clusters: Array<{ __
 
 
 export const SpeciesListQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesListQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"options"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"3"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}}]}},{"kind":"Field","name":{"kind":"Name","value":"manySpeciesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]} as unknown as DocumentNode<SpeciesListQueryQuery, SpeciesListQueryQueryVariables>;
-export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
+export const ModificationAndTargetSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"modificationAndTargetSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<ModificationAndTargetSelectionQueryQuery, ModificationAndTargetSelectionQueryQueryVariables>;
 export const GuideSelectionQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"guideSelectionQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GuideType"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ModifType"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"subtype"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"targetsBase"},"name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"speciesIds"}}}]}}]}}]}},{"kind":"ObjectField","name":{"kind":"Name","value":"guides_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}}]}},{"kind":"Field","alias":{"kind":"Name","value":"genomesBase"},"name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"AND"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetNames"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"modifications_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"type_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"modificationTypes"}}}]}}]}}]}}]}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"sequencesConnection_SOME"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"_on"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"Guide"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"subtype_IN"},"value":{"kind":"Variable","name":{"kind":"Name","value":"guideSubtypes"}}}]}}]}}]}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<GuideSelectionQueryQuery, GuideSelectionQueryQueryVariables>;
 export const TableEntriesQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tableEntriesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tableEntries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"target"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"genome"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guide"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"seq"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"strand"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"length"}}]}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"species"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode<TableEntriesQueryQuery, TableEntriesQueryQueryVariables>;
 export const SpeciesByIdQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"speciesByIdQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"manySpecies"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"shortname"}},{"kind":"Field","name":{"kind":"Name","value":"genomes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sequences"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"altnames"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"featureType"}},{"kind":"Field","name":{"kind":"Name","value":"featuresConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Guide"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modifications"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"target"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"result"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"guidesAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"targets"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"guides"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"genome"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"species"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"subtype"}},{"kind":"Field","name":{"kind":"Name","value":"parentConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"node"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"featureType"},"value":{"kind":"EnumValue","value":"Chromosome"}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"start"}},{"kind":"Field","name":{"kind":"Name","value":"end"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"modificationsAggregate"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]}}]} as unknown as DocumentNode<SpeciesByIdQueryQuery, SpeciesByIdQueryQueryVariables>;
diff --git a/src/gql/queries.ts b/src/gql/queries.ts
index ec90461..bfdbd8f 100644
--- a/src/gql/queries.ts
+++ b/src/gql/queries.ts
@@ -41,6 +41,7 @@ export const modificationAndTargetSelectionQuery = graphql(/* GraphQL */ `
       }
     ) {
       name
+      id
     }
 
     modifications(
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index b625d58..1051ebb 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -55,6 +55,42 @@ export interface SelectionOptionModel {
   isDisabled?: boolean
 }
 
+/**
+ * The columns to display in the table when navigating to it, depending on the
+ * active tab (i.e. form mode).
+ */
+const TABLE_COLUMNS_BY_MODE = {
+  modification: [
+    'modificationId',
+    'modificationName',
+    'modificationPosition',
+    'modificationResult',
+    'modificationType',
+    'targetName',
+    'speciesName',
+    'speciesId'
+  ],
+  guide: [
+    'guideId',
+    'guideName',
+    'guideType',
+    'guideSubtype',
+    'guideChromosomeName',
+    'guideLength',
+    'speciesName',
+    'speciesId'
+  ],
+  target: [
+    'targetId',
+    'targetName',
+    'targetLength',
+    'targetType',
+    'targetChromosomeName',
+    'speciesName',
+    'speciesId'
+  ]
+}
+
 /**
  * Component props.
  */
@@ -127,46 +163,12 @@ const tableFilters = computed(() => ({
 }))
 
 /**
- * The columns to display in the table when navigating to it, based on the
- * active tab (i.e. form mode).
+ * The ID of the target which matches the selection if it is unique (i.e. a
+ * single target name & a single species is selected), `undefined` otherwise.
  */
-const activeModeTableColumns = computed(() => {
-  switch (activeTabIndex.value) {
-    case TabEnum.Modification:
-      return [
-        'modificationId',
-        'modificationName',
-        'modificationPosition',
-        'modificationResult',
-        'modificationType',
-        'targetName',
-        'speciesName',
-        'speciesId'
-      ]
-    case TabEnum.Guide:
-      return [
-        'guideId',
-        'guideName',
-        'guideType',
-        'guideSubtype',
-        'guideChromosomeName',
-        'guideLength',
-        'speciesName',
-        'speciesId'
-      ]
-    case TabEnum.Target:
-      return [
-        'targetId',
-        'targetName',
-        'targetLength',
-        'targetType',
-        'targetChromosomeName',
-        'speciesName',
-        'speciesId'
-      ]
-    default:
-      return []
-  }
+const onlyTargetId = ref<{ modification?: string; target?: string }>({
+  modification: undefined,
+  target: undefined
 })
 </script>
 
@@ -213,6 +215,7 @@ const activeModeTableColumns = computed(() => {
           <TabPanel header="Modification">
             <ModificationSelectionForm
               v-model:selection-model="selection.modification"
+              v-model:only-target-id="onlyTargetId.modification"
             />
           </TabPanel>
           <TabPanel header="Guide">
@@ -221,6 +224,7 @@ const activeModeTableColumns = computed(() => {
           <TabPanel header="Target">
             <TargetSelectionForm
               v-model:selection-model="selection.target"
+              v-model:only-target-id="onlyTargetId.target"
             />
           </TabPanel>
         </TabView>
@@ -231,7 +235,7 @@ const activeModeTableColumns = computed(() => {
           :to="{
             name: 'table',
             query: {
-              columns: activeModeTableColumns,
+              columns: TABLE_COLUMNS_BY_MODE[activeMode],
               ...tableFilters
             }
           }"
diff --git a/src/views/StatisticsView.vue b/src/views/StatisticsView.vue
index 1cf70fe..2bac916 100644
--- a/src/views/StatisticsView.vue
+++ b/src/views/StatisticsView.vue
@@ -140,7 +140,7 @@ const colorByField: { [k: string]: TailwindDefaultColorNameModel } = {
 // }))
 
 /**
- * For each field, a `LinkListItemModel` of the uniq entries of that field
+ * For each field, a `LinkListItemModel` of the unique entries of that field
  */
 const itemsByField = computed<{
   [k: string]: LinkListItemModel<ModifType | SequenceType | ''>[] | undefined
-- 
GitLab


From 7c88b8fa7740205029c85c56fa1886f59fb225fa Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Fri, 14 Jun 2024 08:50:49 +0200
Subject: [PATCH 42/47] feat(detail-views): :sparkles: add a prop to define
 initially selected tab of the "Graphics" panel

---
 src/views/GuideView.vue        | 18 ++++++++++++++++--
 src/views/ModificationView.vue | 20 +++++++++++++++++---
 src/views/TargetView.vue       | 21 ++++++++++++++++++---
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/views/GuideView.vue b/src/views/GuideView.vue
index 51e9928..4fdfb7f 100644
--- a/src/views/GuideView.vue
+++ b/src/views/GuideView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, onMounted, toRef } from 'vue'
+import { computed, onMounted, ref, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -58,6 +58,13 @@ import { guideByIdQuery } from '@/gql/queries'
 import { isDefined, isInEnum } from '@/typings/typeUtils'
 import { getBoxColor, getModificationColor } from '@/utils/colors'
 
+/**
+ * Enum to represent the tabs in the 'Graphics' panel.
+ */
+enum GraphicsTabEnum {
+  interaction = 0
+}
+
 /**
  * Utility constant to get the icon component corresponding to each strand value.
  */
@@ -98,6 +105,8 @@ const GUIDE_LEGEND_ITEMS: LegendItemModel[] = [
 const props = defineProps<{
   /** The ID of the guide to display. */
   guideId: string
+  /** The tab to display initially in the 'Graphics' panel */
+  initialGraphicsPanelTab: keyof typeof GraphicsTabEnum
 }>()
 
 /**
@@ -409,6 +418,11 @@ const ontologyLinks = computed(() => ({
   SO: `http://www.sequenceontology.org/browser/current_release/term/SO:${ontologyIdsCleaned.value.SO}`,
   ChEBI: `https://www.ebi.ac.uk/chebi/searchId.do?chebiId=${ontologyIdsCleaned.value.ChEBI}`
 }))
+
+/**
+ * The selected tab in the 'Graphics' panel.
+ */
+const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
 </script>
 
 <template>
@@ -774,7 +788,7 @@ const ontologyLinks = computed(() => ({
         <span :class="scope.class">Graphics</span>
       </template>
 
-      <TabView>
+      <TabView v-model:active-index="selectedGraphicsTab">
         <TabPanel header="Local interaction">
           <!-- v-if is to ensure we can access and map `guide.interactions` -->
           <InteractionBoard
diff --git a/src/views/ModificationView.vue b/src/views/ModificationView.vue
index 7887ca7..611984b 100644
--- a/src/views/ModificationView.vue
+++ b/src/views/ModificationView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, onMounted, toRef } from 'vue'
+import { computed, onMounted, ref, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -35,12 +35,21 @@ import { getModificationColor } from '@/utils/colors'
 import { modificationByIdQuery } from '@/gql/queries'
 import { isDefined } from '@/typings/typeUtils'
 
+/**
+ * Enum to represent the tabs in the 'Graphics' panel.
+ */
+enum GraphicsTabEnum {
+  interaction = 0
+}
+
 /**
  * Component props
  */
 const props = defineProps<{
-  // The ID of the guide to display
+  /** The ID of the guide to display */
   modificationId: string
+  /** The tab to display initially in the 'Graphics' panel */
+  initialGraphicsPanelTab: keyof typeof GraphicsTabEnum
 }>()
 
 /**
@@ -197,6 +206,11 @@ const linkedGuidesFieldName = computed(
 //   SO: `http://www.sequenceontology.org/browser/current_release/term/SO:${referenceIdsCleaned.value.SO}`,
 //   ChEBI: `https://www.ebi.ac.uk/chebi/searchId.do?chebiId=${referenceIdsCleaned.value.ChEBI}`
 // }))
+
+/**
+ * The selected tab in the 'Graphics' panel.
+ */
+const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
 </script>
 
 <template>
@@ -369,7 +383,7 @@ const linkedGuidesFieldName = computed(
         <span :class="scope.class">Graphics</span>
       </template>
 
-      <TabView>
+      <TabView v-model:active-index="selectedGraphicsTab">
         <TabPanel header="Local interaction">
           <!-- v-if is to ensure we can access and map `modification.interactions` -->
           <InteractionBoard
diff --git a/src/views/TargetView.vue b/src/views/TargetView.vue
index 086b030..fb9379c 100644
--- a/src/views/TargetView.vue
+++ b/src/views/TargetView.vue
@@ -2,7 +2,7 @@
 /**
  * Vue imports
  */
-import { computed, onMounted, toRef } from 'vue'
+import { computed, onMounted, ref, toRef } from 'vue'
 /**
  * Components imports
  */
@@ -50,6 +50,14 @@ import { isDefined, isInEnum } from '@/typings/typeUtils'
 import { getModificationColor } from '@/utils/colors'
 import type { LegendItemModel } from '@/components/BaseLegendButtonOverlay.vue'
 
+/**
+ * Enum to represent the tabs in the 'Graphics' panel.
+ */
+enum GraphicsTabEnum {
+  interaction = 0,
+  '2d-struct'
+}
+
 /**
  * Utility constant to get the icon component corresponding to each strand value
  */
@@ -86,8 +94,10 @@ const TARGET_LEGEND_ITEMS: LegendItemModel[] = [
  * Component props
  */
 const props = defineProps<{
-  // The ID of the target to display
+  /** The ID of the target to display */
   targetId: string
+  /** The tab to display initially in the 'Graphics' panel */
+  initialGraphicsPanelTab: keyof typeof GraphicsTabEnum
 }>()
 
 /**
@@ -386,6 +396,11 @@ const ontologyLinks = computed(() => ({
   SO: `http://www.sequenceontology.org/browser/current_release/term/SO:${ontologyIdsCleaned.value.SO}`,
   ChEBI: `https://www.ebi.ac.uk/chebi/searchId.do?chebiId=${ontologyIdsCleaned.value.ChEBI}`
 }))
+
+/**
+ * The selected tab in the 'Graphics' panel.
+ */
+const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
 </script>
 
 <template>
@@ -685,7 +700,7 @@ const ontologyLinks = computed(() => ({
         <span :class="scope.class">Graphics</span>
       </template>
 
-      <TabView :lazy="true">
+      <TabView v-model:active-index="selectedGraphicsTab" :lazy="true">
         <TabPanel header="Local interaction">
           <!-- v-if is to ensure we can access and map `target.interactions` -->
           <InteractionBoard
-- 
GitLab


From 28aec0b7f15f39a4bff7278438ed7385ad9661dc Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Fri, 14 Jun 2024 08:52:16 +0200
Subject: [PATCH 43/47] feat(router): :sparkles: pass initial graphic tab prop
 to detail views from url query string

---
 src/router/index.ts | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/router/index.ts b/src/router/index.ts
index fb96c20..c54e570 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -119,7 +119,10 @@ const router = createRouter({
           path: 'guide',
           name: 'guideDetails',
           component: () => import('@/views/GuideView.vue'),
-          props: (to) => ({ guideId: to.query.id }),
+          props: (to) => ({
+            guideId: to.query.id,
+            initialGraphicsPanelTab: to.query.graphicsTab
+          }),
           beforeEnter: (to) => {
             if (typeof to.query.id !== 'string') {
               router.replace({ name: 'lost' })
@@ -130,7 +133,10 @@ const router = createRouter({
           path: 'modification',
           name: 'modificationDetails',
           component: () => import('@/views/ModificationView.vue'),
-          props: (to) => ({ modificationId: to.query.id }),
+          props: (to) => ({
+            modificationId: to.query.id,
+            initialGraphicsPanelTab: to.query.graphicsTab
+          }),
           beforeEnter: (to) => {
             if (typeof to.query.id !== 'string') {
               router.replace({ name: 'lost' })
@@ -141,7 +147,10 @@ const router = createRouter({
           path: 'target',
           name: 'targetDetails',
           component: () => import('@/views/TargetView.vue'),
-          props: (to) => ({ targetId: to.query.id }),
+          props: (to) => ({
+            targetId: to.query.id,
+            initialGraphicsPanelTab: to.query.graphicsTab
+          }),
           beforeEnter: (to) => {
             if (typeof to.query.id !== 'string') {
               router.replace({ name: 'lost' })
-- 
GitLab


From 141ac2ed4483c5384a709eed3276f6b6362ce1b6 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Fri, 14 Jun 2024 09:10:10 +0200
Subject: [PATCH 44/47] feat(advanced-selection): :sparkles: add links to
 target sequence & structure when applicable

---
 src/assets/icons/sequence.svg |   5 ++
 src/views/ClusterView.vue     |   2 +-
 src/views/SelectionView.vue   | 124 +++++++++++++++++++++++++++++-----
 3 files changed, 113 insertions(+), 18 deletions(-)
 create mode 100644 src/assets/icons/sequence.svg

diff --git a/src/assets/icons/sequence.svg b/src/assets/icons/sequence.svg
new file mode 100644
index 0000000..d978a2b
--- /dev/null
+++ b/src/assets/icons/sequence.svg
@@ -0,0 +1,5 @@
+<svg width="1em" height="1em" viewBox="0 0 512 512">
+   <path
+      style="fill:currentColor"
+      d="M60.95 93.45c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm118.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zM60.95 224c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm118.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zM60.95 354.55c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm118.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm68.02 0c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32z" />
+</svg>
\ No newline at end of file
diff --git a/src/views/ClusterView.vue b/src/views/ClusterView.vue
index 6365a52..88fe974 100644
--- a/src/views/ClusterView.vue
+++ b/src/views/ClusterView.vue
@@ -39,7 +39,7 @@ import { clusterByIdQuery } from '@/gql/queries'
  * Component props
  */
 const props = defineProps<{
-  // The ID of the cluster to display
+  /** The ID of the cluster to display */
   clusterId: string
 }>()
 
diff --git a/src/views/SelectionView.vue b/src/views/SelectionView.vue
index 1051ebb..c0015b0 100644
--- a/src/views/SelectionView.vue
+++ b/src/views/SelectionView.vue
@@ -22,6 +22,9 @@ import TabPanel from 'primevue/tabpanel'
 import Card from 'primevue/card'
 import Button from 'primevue/button'
 import IconFa6SolidTable from '~icons/fa6-solid/table'
+import IconFa6SolidBullseye from '~icons/fa6-solid/bullseye'
+import IconFa6SolidCircleNodes from '~icons/fa6-solid/circle-nodes'
+import IconSnoboardSequence from '~icons/snoboard/sequence'
 /**
  * Other 3rd-party imports
  */
@@ -165,11 +168,24 @@ const tableFilters = computed(() => ({
 /**
  * The ID of the target which matches the selection if it is unique (i.e. a
  * single target name & a single species is selected), `undefined` otherwise.
+ * One target ID is used for each mode able to provide one.
  */
-const onlyTargetId = ref<{ modification?: string; target?: string }>({
+const onlyTargetIdByMode = ref<{ modification?: string; target?: string }>({
   modification: undefined,
   target: undefined
 })
+
+/**
+ * The `onlyTargetId` (see `onlyTargetIdByMode`) corresponding to the active
+ * mode.
+ */
+const onlyTargetIdActiveMode = computed(() =>
+  activeMode.value === 'modification'
+    ? onlyTargetIdByMode.value.modification
+    : activeMode.value === 'target'
+    ? onlyTargetIdByMode.value.target
+    : undefined
+)
 </script>
 
 <template>
@@ -215,7 +231,7 @@ const onlyTargetId = ref<{ modification?: string; target?: string }>({
           <TabPanel header="Modification">
             <ModificationSelectionForm
               v-model:selection-model="selection.modification"
-              v-model:only-target-id="onlyTargetId.modification"
+              v-model:only-target-id="onlyTargetIdByMode.modification"
             />
           </TabPanel>
           <TabPanel header="Guide">
@@ -224,27 +240,101 @@ const onlyTargetId = ref<{ modification?: string; target?: string }>({
           <TabPanel header="Target">
             <TargetSelectionForm
               v-model:selection-model="selection.target"
-              v-model:only-target-id="onlyTargetId.target"
+              v-model:only-target-id="onlyTargetIdByMode.target"
             />
           </TabPanel>
         </TabView>
       </template>
 
       <template #footer>
-        <RouterLink
-          :to="{
-            name: 'table',
-            query: {
-              columns: TABLE_COLUMNS_BY_MODE[activeMode],
-              ...tableFilters
-            }
-          }"
-        >
-          <Button>
-            <icon-fa6-solid-table />
-            <span class="ml-2">View in table</span>
-          </Button>
-        </RouterLink>
+        <div class="flex gap-4">
+          <RouterLink
+            :to="{
+              name: 'table',
+              query: {
+                columns: TABLE_COLUMNS_BY_MODE[activeMode],
+                ...tableFilters
+              }
+            }"
+          >
+            <Button>
+              <icon-fa6-solid-table />
+              <span class="ml-2">View in table</span>
+            </Button>
+          </RouterLink>
+
+          <div
+            v-if="activeMode === 'target'"
+            v-tooltip.top="
+              !onlyTargetIdByMode.target && {
+                value: 'Select a unique target/species pair',
+                pt: {
+                  text: {
+                    style: {
+                      textAlign: 'center',
+                      fontStyle: 'italic'
+                    }
+                  }
+                }
+              }
+            "
+          >
+            <RouterLink
+              :to="{
+                name: 'targetDetails',
+                query: {
+                  id: onlyTargetIdByMode.target
+                },
+                hash: '#sequence-panel'
+              }"
+              :class="{ 'pointer-events-none': !onlyTargetIdByMode.target }"
+            >
+              <Button :disabled="!onlyTargetIdByMode.target">
+                <icon-snoboard-sequence />
+                <span class="ml-2">View sequence</span>
+              </Button>
+            </RouterLink>
+          </div>
+
+          <div
+            v-if="activeMode === 'target' || activeMode === 'modification'"
+            v-tooltip.top="
+              !onlyTargetIdActiveMode && {
+                value: 'Select a unique target/species pair',
+                pt: {
+                  text: {
+                    style: {
+                      textAlign: 'center',
+                      fontStyle: 'italic'
+                    }
+                  }
+                }
+              }
+            "
+          >
+            <RouterLink
+              :to="{
+                name: 'targetDetails',
+                query: {
+                  id: onlyTargetIdActiveMode,
+                  graphicsTab: '2d-struct'
+                },
+                hash: '#graphics-panel'
+              }"
+              :class="{ 'pointer-events-none': !onlyTargetIdActiveMode }"
+            >
+              <Button :disabled="!onlyTargetIdActiveMode">
+                <icon-fa6-solid-bullseye v-if="activeMode === 'modification'" />
+                <icon-fa6-solid-circle-nodes v-else />
+                <span class="ml-2">
+                  View
+                  {{ activeMode === 'modification' ? 'on target' : '' }}
+                  structure
+                </span>
+              </Button>
+            </RouterLink>
+          </div>
+        </div>
       </template>
     </Card>
   </MainLayout>
-- 
GitLab


From e42ec3e71622573155f97401bbd481152a35d9ee Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Fri, 14 Jun 2024 15:09:05 +0200
Subject: [PATCH 45/47] fix(home-view): :adhesive_bandage: disable links not
 implemented in menubar

---
 src/views/HomeView.vue | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 972fe86..c937187 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -249,7 +249,8 @@ const menuItems = computed<MenuItem[]>(() => [
           //   type: 'modification'
           // }
         },
-        iconComponent: IconSnoboardModification
+        iconComponent: IconSnoboardModification,
+        disabled: true
       },
       {
         label: 'Guides',
@@ -259,7 +260,8 @@ const menuItems = computed<MenuItem[]>(() => [
           //   type: 'modification'
           // }
         },
-        iconComponent: IconSnoboardGuide
+        iconComponent: IconSnoboardGuide,
+        disabled: true
       },
       {
         label: 'Targets',
@@ -269,7 +271,8 @@ const menuItems = computed<MenuItem[]>(() => [
           //   type: 'modification'
           // }
         },
-        iconComponent: IconFa6SolidBullseye
+        iconComponent: IconFa6SolidBullseye,
+        disabled: true
       }
     ]
   },
@@ -281,7 +284,8 @@ const menuItems = computed<MenuItem[]>(() => [
         route: {
           name: 'statistics'
         },
-        iconComponent: IconFa6SolidDatabase
+        iconComponent: IconFa6SolidDatabase,
+        disabled: true
       },
       {
         label: 'By organism',
-- 
GitLab


From d5b59ed07b58de94c12ca40edc49083f716f4bda Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Fri, 14 Jun 2024 15:42:45 +0200
Subject: [PATCH 46/47] refactor(router): :truck: rename "Statistics" view &
 route to "Species"

---
 src/router/index.ts                               | 6 +++---
 src/views/ClusterView.vue                         | 2 +-
 src/views/DataTableView.vue                       | 2 +-
 src/views/GuideView.vue                           | 2 +-
 src/views/HomeView.vue                            | 2 +-
 src/views/ModificationView.vue                    | 2 +-
 src/views/{StatisticsView.vue => SpeciesView.vue} | 0
 src/views/TargetView.vue                          | 2 +-
 8 files changed, 9 insertions(+), 9 deletions(-)
 rename src/views/{StatisticsView.vue => SpeciesView.vue} (100%)

diff --git a/src/router/index.ts b/src/router/index.ts
index c54e570..babb99a 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -92,9 +92,9 @@ const router = createRouter({
       }
     },
     {
-      path: '/statistics',
-      name: 'statistics',
-      component: () => import('@/views/StatisticsView.vue'),
+      path: '/species',
+      name: 'species',
+      component: () => import('@/views/SpeciesView.vue'),
       props: (to) => ({
         speciesId:
           Array.isArray(to.query.id) || !to.query.id
diff --git a/src/views/ClusterView.vue b/src/views/ClusterView.vue
index 88fe974..0ee57ab 100644
--- a/src/views/ClusterView.vue
+++ b/src/views/ClusterView.vue
@@ -194,7 +194,7 @@ const linkListGuides = computed<LinkListItemModel[]>(
           <RouterLink
             v-if="cluster?.genome?.species?.name"
             :to="{
-              name: 'statistics',
+              name: 'species',
               query: { id: cluster.genome.species.id }
             }"
             class="text-lg font-bold italic text-slate-700 underline transition-all duration-300 ease-in-out hover:text-indigo-600"
diff --git a/src/views/DataTableView.vue b/src/views/DataTableView.vue
index 99380c5..dd65298 100644
--- a/src/views/DataTableView.vue
+++ b/src/views/DataTableView.vue
@@ -326,7 +326,7 @@ const columnGroups: ColumnGroupModel[] = [
         field: 'modification.target.genome.species.name',
         title: 'Species Name',
         link: {
-          routeName: 'statistics',
+          routeName: 'species',
           queryIdField: 'modification.target.genome.species.id',
           color: 'indigo'
         }
diff --git a/src/views/GuideView.vue b/src/views/GuideView.vue
index 4fdfb7f..5f5f1b4 100644
--- a/src/views/GuideView.vue
+++ b/src/views/GuideView.vue
@@ -493,7 +493,7 @@ const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
           <RouterLink
             v-if="guide?.genome?.species?.name"
             :to="{
-              name: 'statistics',
+              name: 'species',
               query: { id: guide.genome.species.id }
             }"
             class="text-lg font-bold italic text-slate-700 underline transition-all duration-300 ease-in-out hover:text-indigo-600"
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index c937187..1750356 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -293,7 +293,7 @@ const menuItems = computed<MenuItem[]>(() => [
           ...(speciesList.value?.map((species) => ({
             label: species.name,
             route: {
-              name: 'statistics',
+              name: 'species',
               query: {
                 id: species.id
               }
diff --git a/src/views/ModificationView.vue b/src/views/ModificationView.vue
index 611984b..6463a82 100644
--- a/src/views/ModificationView.vue
+++ b/src/views/ModificationView.vue
@@ -280,7 +280,7 @@ const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
           <RouterLink
             v-if="modification?.target.genome?.species?.name"
             :to="{
-              name: 'statistics',
+              name: 'species',
               query: { id: modification?.target.genome?.species?.id }
             }"
             class="text-lg font-bold italic text-slate-700 underline transition-all duration-300 ease-in-out hover:text-indigo-600"
diff --git a/src/views/StatisticsView.vue b/src/views/SpeciesView.vue
similarity index 100%
rename from src/views/StatisticsView.vue
rename to src/views/SpeciesView.vue
diff --git a/src/views/TargetView.vue b/src/views/TargetView.vue
index fb9379c..10d11f3 100644
--- a/src/views/TargetView.vue
+++ b/src/views/TargetView.vue
@@ -480,7 +480,7 @@ const selectedGraphicsTab = ref(GraphicsTabEnum[props.initialGraphicsPanelTab])
           <RouterLink
             v-if="target?.genome?.species?.name"
             :to="{
-              name: 'statistics',
+              name: 'species',
               query: { id: target.genome?.species?.id }
             }"
             class="text-lg font-bold italic text-slate-700 underline transition-all duration-300 ease-in-out hover:text-indigo-600"
-- 
GitLab


From 7ffde852367ccf57310ba9dd5fa2fda4bb530e62 Mon Sep 17 00:00:00 2001
From: Julien Touchais <5978-julien.touchais@users.noreply.forgemia.inra.fr>
Date: Wed, 19 Jun 2024 10:53:08 +0200
Subject: [PATCH 47/47] fix(home-view): :adhesive_bandage: non-existing route

---
 src/views/HomeView.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 1750356..6ea7ca1 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -282,7 +282,7 @@ const menuItems = computed<MenuItem[]>(() => [
       {
         label: 'Database-wide',
         route: {
-          name: 'statistics'
+          // name: 'statistics'
         },
         iconComponent: IconFa6SolidDatabase,
         disabled: true
-- 
GitLab