Skip to content

Commit 9eab852

Browse files
committed
front: Change display when description is too long
Signed-off-by: theocrsb <[email protected]>
1 parent 3ad5d84 commit 9eab852

File tree

2 files changed

+96
-8
lines changed

2 files changed

+96
-8
lines changed

front/src/applications/operationalStudies/components/Scenario/ScenarioDescription.tsx

+53-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { Blocked, ChevronLeft, Pencil } from '@osrd-project/ui-icons';
1+
import { useEffect, useRef, useState } from 'react';
2+
3+
import { Blocked, ChevronLeft, Pencil, X } from '@osrd-project/ui-icons';
24
import { useTranslation } from 'react-i18next';
35

46
import type { InfraWithState, ScenarioResponse } from 'common/api/osrdEditoastApi';
57
import { useModal } from 'common/BootstrapSNCF/ModalSNCF';
68
import AddAndEditScenarioModal from 'modules/scenario/components/AddOrEditScenarioModal';
9+
import useOutsideClick from 'utils/hooks/useOutsideClick';
710

811
import InfraLoadingState from './InfraLoadingState';
912

@@ -22,6 +25,34 @@ const ScenarioDescription = ({
2225
}: ScenarioDescriptionProps) => {
2326
const { t } = useTranslation('operationalStudies/scenario');
2427
const { openModal } = useModal();
28+
const [isOpenedDescription, setIsOpenedDescription] = useState<boolean>(false);
29+
const expandedDescriptionRef = useRef<HTMLDivElement | null>(null);
30+
const collapsedDescriptionRef = useRef<HTMLDivElement | null>(null);
31+
const [isTooLongDescription, setIsTooLongDescription] = useState<boolean>(false);
32+
33+
const toggleDescription = () => {
34+
setIsOpenedDescription(!isOpenedDescription);
35+
};
36+
37+
const checkIfDescriptionIsTooLong = () => {
38+
if (collapsedDescriptionRef.current)
39+
setIsTooLongDescription(
40+
collapsedDescriptionRef.current.scrollHeight > collapsedDescriptionRef.current.clientHeight
41+
);
42+
};
43+
44+
useOutsideClick(expandedDescriptionRef, () => setIsOpenedDescription(false));
45+
46+
useEffect(() => {
47+
checkIfDescriptionIsTooLong();
48+
window.addEventListener('resize', checkIfDescriptionIsTooLong);
49+
50+
return () => {
51+
window.removeEventListener('resize', checkIfDescriptionIsTooLong);
52+
};
53+
}, []);
54+
55+
useEffect(checkIfDescriptionIsTooLong, [scenario.description]);
2556

2657
return (
2758
<div>
@@ -30,10 +61,29 @@ const ScenarioDescription = ({
3061
{scenario.name}
3162
</span>
3263
</div>
33-
3464
<div className="scenario-description">
3565
{scenario.description && (
36-
<div className="scenario-details-description">{scenario.description}</div>
66+
<div ref={collapsedDescriptionRef} className="scenario-details-description not-opened">
67+
{scenario.description}
68+
{isTooLongDescription && (
69+
<span role="button" onClick={toggleDescription} tabIndex={0}>
70+
(plus)
71+
</span>
72+
)}
73+
</div>
74+
)}
75+
{isOpenedDescription && (
76+
<div ref={expandedDescriptionRef} className="scenario-details-description opened">
77+
{scenario.description}
78+
<span
79+
onClick={toggleDescription}
80+
role="button"
81+
tabIndex={0}
82+
className="displayed-description"
83+
>
84+
<X />
85+
</span>
86+
</div>
3787
)}
3888
<div className="flex justify-end">
3989
<button

front/src/styles/scss/applications/operationalStudies/_scenario.scss

+43-5
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
min-width: 24.5rem;
120120
max-width: 29.5rem;
121121
padding: 0.875rem 1.5rem 0 1.5rem;
122-
box-shadow: inset -1px 0 var(--black5);
122+
box-shadow: inset -0.0625rem 0 var(--black5);
123123

124124
.scenario-sidemenu :first-child:hover {
125125
.update-scenario {
@@ -141,9 +141,9 @@
141141

142142
.scenario-description {
143143
position: relative;
144-
text-wrap: wrap;
145144

146145
.scenario-details-description {
146+
position: relative;
147147
color: var(--grey50);
148148
font-size: 0.875rem;
149149
font-weight: 400;
@@ -152,6 +152,44 @@
152152
word-break: break-all;
153153
}
154154

155+
.not-opened {
156+
overflow: hidden;
157+
max-height: 3.75rem;
158+
max-width: 100%;
159+
span {
160+
padding-inline: 0.2188rem;
161+
position: absolute;
162+
bottom: 0;
163+
right: 0;
164+
background: rgba(222, 221, 214, 1);
165+
color: var(--grey80);
166+
}
167+
}
168+
169+
.opened {
170+
position: absolute;
171+
top: 0;
172+
left: -0.5rem;
173+
background-color: var(--white100);
174+
color: var(--grey80);
175+
padding: 3.375rem 3.5rem 3.125rem 3.5rem;
176+
font-size: 1rem;
177+
font-weight: 400;
178+
line-height: 1.5rem;
179+
z-index: 3;
180+
border-radius: 0.375rem;
181+
box-shadow:
182+
0rem 0.375rem 1.3125rem -0.3125rem rgba(255, 171, 88, 0.31),
183+
0rem 1rem 1.875rem -0.3125rem rgba(0, 0, 0, 0.19),
184+
0rem 0.1875rem 0.3125rem -0.125rem rgba(0, 0, 0, 0.16);
185+
width: calc(100% + 7.5rem);
186+
.displayed-description {
187+
position: absolute;
188+
top: 1rem - 0.3125rem;
189+
right: 1rem;
190+
}
191+
}
192+
155193
.scenario-collapse-button {
156194
position: absolute;
157195
padding-bottom: 0.188rem;
@@ -163,8 +201,8 @@
163201
border-radius: 0.313rem 0 0 0.313rem;
164202
top: 0;
165203
transform: translateX(1.5rem);
166-
box-shadow: 0 0px 0 1px var(--black10);
167-
clip-path: inset(-1px 0 -1px -1px);
204+
box-shadow: 0 0 0 0.0625rem var(--black10);
205+
clip-path: inset(-0.0625rem 0 -0.0625rem -0.0625rem);
168206
}
169207

170208
.update-scenario {
@@ -391,7 +429,7 @@
391429
.invalid-trains {
392430
display: flex;
393431
background: var(--warning5);
394-
box-shadow: inset 0px 1px var(--white100);
432+
box-shadow: inset 0 0.0625rem var(--white100);
395433
height: 3rem;
396434
font-size: 1rem;
397435
font-weight: 600;

0 commit comments

Comments
 (0)