Skip to content

Commit

Permalink
front: create power restriction grid modal
Browse files Browse the repository at this point in the history
  • Loading branch information
SharglutDev committed Oct 25, 2023
1 parent 8a557c5 commit bf4e61b
Show file tree
Hide file tree
Showing 17 changed files with 428 additions and 103 deletions.
1 change: 1 addition & 0 deletions front/public/locales/en/rollingstock.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"add": "Add",
"addNewRollingStock": "New rolling stock",
"addNewTractionMode": "Add a new traction mode",
"basePowerClass": "Power class",
Expand Down
1 change: 1 addition & 0 deletions front/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"reset-north": "Reset camera",
"save": "Save",
"search": "Search",
"selected": "already selected",
"settings": "Settings",
"sort": "Sort",
"train(s)": "train(s)",
Expand Down
1 change: 1 addition & 0 deletions front/public/locales/fr/rollingstock.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"add": "Ajouter",
"addNewRollingStock": "Nouveau matériel roulant",
"addNewTractionMode": "Ajouter un nouveau mode de traction",
"basePowerClass": "Classe de puissance",
Expand Down
1 change: 1 addition & 0 deletions front/public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"reset-north": "Réinitialiser la caméra",
"save": "Sauvegarder",
"search": "Rechercher",
"selected": "déjà sélectionné",
"settings": "Paramètres",
"sort": "Tri",
"train(s)": "train(s)",
Expand Down
8 changes: 7 additions & 1 deletion front/src/common/BootstrapSNCF/SelectImprovedSNCF.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.d-flex .select-improved {
flex-grow:4
flex-grow: 4;
}

.add-border-top {
border-top: var(--coolgray3) solid 1px;
border-top-right-radius: 0.4375rem;
border-top-left-radius: 0.4375rem;
}
62 changes: 36 additions & 26 deletions front/src/common/BootstrapSNCF/SelectImprovedSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface SelectProps<T> {
dataTestId?: string;
isOpened?: boolean;
setSelectVisibility?: (arg: boolean) => void;
noTogglingHeader?: boolean;
}

function SelectImproved<T extends string | SelectOptionObject>({
Expand All @@ -37,6 +38,7 @@ function SelectImproved<T extends string | SelectOptionObject>({
blockMenu = false,
isOpened = false,
setSelectVisibility,
noTogglingHeader = false,
}: SelectProps<T>) {
const [isOpen, setIsOpen] = useState(isOpened);
const [selectedItem, setSelectedItem] = useState<T | undefined>(value);
Expand Down Expand Up @@ -127,36 +129,44 @@ function SelectImproved<T extends string | SelectOptionObject>({
)}
<div className={`select-improved ${isOpen ? 'active' : ''}`}>
<div className="select-control">
<div
className={`input-group ${sm ? 'input-group-sm' : ''}`}
tabIndex={0}
role="button"
onClick={() => setIsOpen(!isOpen)}
>
<p
className={`form-control is-placeholder d-flex align-items-center ${
bgWhite ? 'bg-white' : ''
}`}
style={sm ? { minHeight: '1.813rem' } : undefined}
{!noTogglingHeader && (
<div
className={`input-group ${sm ? 'input-group-sm' : ''}`}
tabIndex={0}
role="button"
onClick={() => setIsOpen(!isOpen)}
>
{renderSelectedItem()}
</p>
<div className="input-group-append input-group-last">
<button
className="btn btn-primary btn-only-icon"
<p
className={`form-control is-placeholder d-flex align-items-center ${
bgWhite ? 'bg-white' : ''
}`}
style={sm ? { minHeight: '1.813rem' } : undefined}
type="button"
aria-expanded="false"
aria-controls="selecttoggle"
>
<i
className={`${isOpen ? 'icons-arrow-up' : 'icons-arrow-down'} icons-size-x75`}
aria-hidden="true"
/>
</button>
{renderSelectedItem()}
</p>
<div className="input-group-append input-group-last">
<button
className="btn btn-primary btn-only-icon"
style={sm ? { minHeight: '1.813rem' } : undefined}
type="button"
aria-expanded="false"
aria-controls="selecttoggle"
>
<i
className={`${isOpen ? 'icons-arrow-up' : 'icons-arrow-down'} icons-size-x75`}
aria-hidden="true"
/>
</button>
</div>
</div>
</div>
<div className={cx('select-menu', { 'position-relative': blockMenu })} id="-selecttoggle">
)}
<div
id="-selecttoggle"
className={cx('select-menu', {
'add-border-top': noTogglingHeader,
'position-relative': blockMenu,
})}
>
<div className="d-flex flex-column">
{withSearch && (
<div className="form-control-container w-100 has-left-icon mb-3">
Expand Down
40 changes: 26 additions & 14 deletions front/src/common/Grid.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,39 @@

.grid-item {
width: 77px;
max-width: 77px;
padding: 10px 7px;
border-bottom: solid 1px gray;
list-style-type: none;
cursor: pointer;
padding-inline: 11px 7px;
padding-block: 10px;
border: none;
border-bottom: solid 1px var(--coolgray11);
// This font allows items to be perfectly aligned as each letters have the same width
font-family: monospace;
color: var(--coolgray11);
background-color: transparent;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
white-space: nowrap;

&:hover {
&.filtered {
opacity: 0.2;
}

&:hover,
&:focus {
background-color: var(--primary);
color: var(--white);
// to remove browser style on focus
outline: none;
}

.grid-name {
// This font allows items to be perfectly aligned as each letters have the same width
font-family: monospace;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.present:focus,
&.present:hover {
background-color: transparent;
}

.filtered {
opacity: 0.2;
span.present {
opacity: 0.7;
color: var(--green);
}
}
}
55 changes: 37 additions & 18 deletions front/src/common/Grid.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
import React from 'react';
import cx from 'classnames';
import './Grid.scss';
import { useTranslation } from 'react-i18next';

type GridProps = {
data: string[];
gridData: string[];
filter?: string;
extraClass?: string;
updateData: (data: string) => void;
selectorData?: (string | null)[];
};

function isFiltered(item: string, filter: string): boolean {
return filter !== '' && !item.toLocaleLowerCase().includes(filter.toLocaleLowerCase());
}

const Grid = ({ data, filter, extraClass, updateData }: GridProps) => (
<div className={`grid-list ${extraClass}`}>
{data.map((item, i) => (
<button
key={i}
type="button"
title={item}
className={cx('grid-item', {
filtered: filter && isFiltered(item, filter),
})}
onClick={() => updateData(item)}
>
{item}
</button>
))}
</div>
);
function isInSelector(data: (string | null)[], item: string) {
return data.includes(item);
}

const Grid = ({ gridData, filter, extraClass, updateData, selectorData }: GridProps) => {
const { t } = useTranslation('translation');
return (
<div className={`grid-list ${extraClass}`}>
{gridData.map((item, i) => (
<button
key={i}
type="button"
disabled={selectorData && isInSelector(selectorData, item)}
title={`${item} ${
selectorData && isInSelector(selectorData, item) ? t('common.selected') : ''
}`}
className={cx('grid-item', {
filtered: filter && isFiltered(item, filter),
present: selectorData && isInSelector(selectorData, item),
})}
onClick={() => updateData(item)}
>
<span
className={cx({
present: selectorData && isInSelector(selectorData, item),
})}
>
{item}
</span>
</button>
))}
</div>
);
};

export default Grid;
9 changes: 8 additions & 1 deletion front/src/common/SelectorSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@ export default function SelectorSNCF<
}}
key={`selector-${title}-${index}`}
>
<div className={`${mainClass}-item-name pt-1 pl-3`}>
<div
className={`${mainClass}-item-name pt-1 pl-3`}
title={
!isNull(item)
? t(getTranslationKey(translationList, String(item)))
: t('unspecified')
}
>
{!isNull(item)
? t(getTranslationKey(translationList, String(item)))
: t('unspecified')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import cx from 'classnames';
import { useTranslation } from 'react-i18next';
import { RiAddFill } from 'react-icons/ri';
import { compact } from 'lodash';
import { useModal } from 'common/BootstrapSNCF/ModalSNCF';
import PowerRestrictionGridModal from './PowerRestrictionGridModal';

export default function AddRollingstockParam({
listName,
Expand All @@ -22,8 +24,11 @@ export default function AddRollingstockParam({
}) {
const COMFORT_LEVELS_KEY: keyof RollingStockSelectorParams = 'comfortLevels';
const TRACTION_MODES_KEY: keyof RollingStockSelectorParams = 'tractionModes';
const POWER_RESTRICTIONS_KEY: keyof RollingStockSelectorParams = 'powerRestrictions';

const { t } = useTranslation('rollingstock');
const { openModal } = useModal();

const [isSelectVisible, setIsSelectVisible] = useState(false);
const isTractionModes = listName === TRACTION_MODES_KEY;

Expand All @@ -45,7 +50,7 @@ export default function AddRollingstockParam({
};
});

return (
return listName !== POWER_RESTRICTIONS_KEY ? (
<div>
<button
type="button"
Expand All @@ -72,9 +77,27 @@ export default function AddRollingstockParam({
bgWhite
isOpened
setSelectVisibility={setIsSelectVisible}
noTogglingHeader
/>
</div>
)}
</div>
) : (
<button
type="button"
className="rollingstock-selector-buttons mb-2"
onClick={() =>
openModal(
<PowerRestrictionGridModal
powerRestrictionsList={allOptionsList as string[]}
updatePowerRestrictions={updateDisplayedLists}
currentPowerRestrictions={displayedLists.powerRestrictions}
/>,
'lg'
)
}
>
<RiAddFill />
</button>
);
}
Loading

0 comments on commit bf4e61b

Please sign in to comment.