Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: fix slopes editor form validation #5581

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions front/src/applications/editor/components/EditorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,7 @@ function EditorForm<T extends Omit<EditorEntity, 'objType'> & { objType: string
}}
onChange={(event) => {
setFormData({ ...data.properties, ...event.formData });
if (onChange) {
onChange({ ...data, properties: { ...data.properties, ...event.formData } });
}
onChange?.({ ...data, properties: { ...data.properties, ...event.formData } });
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import {
} from 'common/IntervalsDataViz/data';
import { LinearMetadataItem } from 'common/IntervalsDataViz/types';
import { LinearMetadataDataviz } from 'common/IntervalsDataViz/dataviz';
import { useModal } from '../../../../common/BootstrapSNCF/ModalSNCF';
import { useModal } from 'common/BootstrapSNCF/ModalSNCF';
import { tooltipPosition, notEmpty } from 'common/IntervalsDataViz/utils';
import HelpModal from './HelpModal';
import { tooltipPosition, notEmpty } from '../../../../common/IntervalsDataViz/utils';

import { LinearMetadataTooltip } from './tooltip';
import { FormBeginEndWidget } from './FormBeginEndWidget';
Expand Down Expand Up @@ -66,12 +66,19 @@ export const FormComponent: React.FC<FieldProps> = (props) => {
return 0;
}, [formContext]);

// Remove the 'valueField' required field because it is required by the backend. However,
// the segment with missing values is filtered in 'customOnChange' before being sent to the backend,
// and then re-added by 'fixLinearMetadataItems'.
const requiredFilter = (requireds: string[]) =>
requireds.filter((r) => ['end', 'begin'].includes(r));

// Compute the JSON schema of the linear metadata item
const jsonSchema = useMemo(
() =>
getFieldJsonSchema(
schema,
registry.rootSchema,
requiredFilter,
distance
? {
begin: {
Expand Down Expand Up @@ -108,6 +115,7 @@ export const FormComponent: React.FC<FieldProps> = (props) => {

const customOnChange = useCallback(
(newData: Array<LinearMetadataItem>) => {
// Remove item without value, it will be recreated by the fixLinearMetadataItems function
onChange(newData.filter((e) => (valueField ? !isNil(e[valueField]) : true)));
},
[onChange, valueField]
Expand Down Expand Up @@ -337,7 +345,7 @@ export const FormComponent: React.FC<FieldProps> = (props) => {
noHtml5Validate
tagName="div"
schema={
(getFieldJsonSchema(schema, registry.rootSchema, {
(getFieldJsonSchema(schema, registry.rootSchema, requiredFilter, {
begin: {
minimum: 0,
maximum: fnMax([selectedData.begin, selectedData.end - SEGMENT_MIN_SIZE]),
Expand All @@ -363,43 +371,41 @@ export const FormComponent: React.FC<FieldProps> = (props) => {
}}
formData={selectedData}
onChange={(e) => {
if (e.errors.length === 0) {
const newItem = e.formData;
const oldItem = data[selected];
let newData = [...data];
// we keep the old value for begin and end
// they will be change in the resize function if needed
newData[selected] = {
...oldItem,
...omit(newItem, ['begin', 'end']),
};
const newItem = e.formData;
const oldItem = data[selected];
let newData = [...data];
// we keep the old value for begin and end
// they will be change in the resize function if needed
newData[selected] = {
...oldItem,
...omit(newItem, ['begin', 'end']),
};

// Check if there is a resize
try {
if (newItem.begin !== oldItem.begin) {
const resizeBegin = resizeSegment(
[...newData],
selected,
newItem.begin - oldItem.begin,
'begin'
);
newData = resizeBegin.result;
}
if (oldItem.end !== newItem.end) {
const resizeEnd = resizeSegment(
[...newData],
selected,
newItem.end - oldItem.end,
'end'
);
newData = resizeEnd.result;
}
customOnChange(newData);
} catch (error) {
// TODO: Should we display the resize error ?
} finally {
setSelectedData(newItem);
// Check if there is a resize
try {
if (newItem.begin !== oldItem.begin) {
const resizeBegin = resizeSegment(
[...newData],
selected,
newItem.begin - oldItem.begin,
'begin'
);
newData = resizeBegin.result;
}
if (oldItem.end !== newItem.end) {
const resizeEnd = resizeSegment(
[...newData],
selected,
newItem.end - oldItem.end,
'end'
);
newData = resizeEnd.result;
}
customOnChange(newData);
} catch (error) {
// TODO: Should we display the resize error ?
} finally {
setSelectedData(newItem);
}
}}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { JSONSchema7 } from 'json-schema';
import { LinearMetadataItem } from 'common/IntervalsDataViz/types';
import { isNil } from 'lodash';

interface LinearMetadataTooltipProps<T> {
item: LinearMetadataItem<T>;
Expand Down Expand Up @@ -38,7 +39,7 @@ export const LinearMetadataTooltip = <T extends Record<string, unknown>>({
<span className="mr-3">
{((schema.properties || {})[k] as JSONSchema7 | undefined)?.title || k}
</span>
{`${item[k] || '-'}`}
{isNil(item[k]) ? '-' : `${item[k]}`}
</div>
))}
</div>
Expand Down
2 changes: 2 additions & 0 deletions front/src/applications/editor/tools/trackEdition/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export function getNewLine(points: [number, number][]): TrackSectionEntity {
properties: {
id: NEW_ENTITY_ID,
length: 0,
slopes: [],
curves: [],
},
};
}
Expand Down
29 changes: 19 additions & 10 deletions front/src/common/IntervalsDataViz/IntervalItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,27 @@ const IntervalItem = <T extends { [key: string]: string | number }>({
valueText = `${interval[field]}`;
}
}

const hasNoData =
!!field &&
(segment === undefined || segment[field] === undefined || segment[field] === emptyValue);
const hasData =
!!field &&
segment !== undefined &&
segment[field] !== undefined &&
segment[field] !== emptyValue;
const fieldValue = !!field && segment !== undefined && segment[field];
const isDataZero = fieldValue === 0;

return (
<div
className={cx(
'item',
highlighted.includes(segment.index) && 'highlighted',
field &&
segment !== undefined &&
segment[field] !== undefined &&
segment[field] !== emptyValue &&
'with-data',
field &&
(segment === undefined ||
segment[field] === undefined ||
segment[field] === emptyValue) &&
'no-data',
{
'with-data': hasData,
'no-data': hasNoData,
},
!field && isNilObject(segment, ['begin', 'end', 'index']) && 'no-data'
)}
style={{
Expand Down Expand Up @@ -147,6 +153,9 @@ const IntervalItem = <T extends { [key: string]: string | number }>({
<span className="value" style={{ height: '100%' }} />
)}

{hasNoData && <div className="no-data-line" style={computeStyleForDataValue(0, min, max)} />}
{isDataZero && <div className="zero-line" style={computeStyleForDataValue(0, min, max)} />}

{/* Create a div for the resize */}
{data[segment.index] && segment.end === data[segment.index].end && (
<div
Expand Down
5 changes: 5 additions & 0 deletions front/src/common/IntervalsDataViz/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ export function entityDoUpdate<T extends EditorEntity>(entity: T, sourceLine: Li
export function getFieldJsonSchema(
fieldSchema: JSONSchema7,
rootSchema: JSONSchema7,
requiredFilter?: (required: string[]) => string[],
enhancement: { [key: string]: JSONSchema7Definition } = {}
): JSONSchema7 {
let result = { ...fieldSchema };
Expand All @@ -698,6 +699,10 @@ export function getFieldJsonSchema(
...result,
items: {
...itemsSchema,
required:
requiredFilter && itemsSchema.required && isArray(itemsSchema.required)
? requiredFilter(itemsSchema.required)
: itemsSchema.required,
properties: {
begin: {
...(itemsSchema.properties?.begin as JSONSchema7),
Expand Down
6 changes: 1 addition & 5 deletions front/src/common/IntervalsDataViz/dataviz.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { head, isNil, last, maxBy, minBy } from 'lodash';
import cx from 'classnames';

import { AdditionalDataItem } from 'common/IntervalsEditor/types';
import { preventDefault, computeStyleForDataValue, getPositionFromMouseEvent } from './utils';
import { preventDefault, getPositionFromMouseEvent } from './utils';
import {
cropForDatavizViewbox,
cropOperationPointsForDatavizViewbox,
Expand Down Expand Up @@ -366,10 +366,6 @@ export const LinearMetadataDataviz = <T extends { [key: string]: any }>({
(viewBox === null || viewBox[1] === last(data)?.end) && 'end-visible'
)}
>
{/* Display the 0 axis if it's necessary */}
{min < 0 && max > 0 && (
<div className="axis-zero" style={computeStyleForDataValue(0, min, max)} />
)}
{/* Display the Y axis if there is one */}
{field && min !== max && !options.fullHeightItem && (
<SimpleScale className="scale-y" begin={min} end={max} />
Expand Down
42 changes: 22 additions & 20 deletions front/src/common/IntervalsDataViz/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,24 @@ $resize-width: 3px;
flex-direction: row;
align-items: flex-end;
justify-content: flex-end;
position: relative;

&.no-data {
background-color: mixw($color, 0.9);
background-image: repeating-linear-gradient(
45deg,
$color-nodata,
$color-nodata 1px,
transparent 2px,
transparent 10px
);

&.highlighted {
background-color: $color-highlight;
}
.zero-line {
position: absolute !important;
width: 100%;
right: 0;
left: 0;
z-index: 1;
border-bottom: 1px solid $color;
}

.no-data-line {
position: absolute !important;
width: 100%;
right: 0;
left: 0;
z-index: 1;
border-bottom: 1px dashed var(--coolgray9);
}

&.with-data {
Expand All @@ -178,6 +182,10 @@ $resize-width: 3px;
div.value {
background-color: $color-highlight;
}

.zero-line {
border-bottom-color: $color-highlight;
}
}

div.value {
Expand Down Expand Up @@ -269,13 +277,6 @@ $resize-width: 3px;
}
}

.axis-zero {
position: absolute !important;
width: 100%;
border-bottom: 1px solid red;
z-index: 1;
}

.scale {
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -312,6 +313,7 @@ $resize-width: 3px;
align-items: center;
width: 100%;
height: 100%;
padding-right: 2px;
div {
position: relative;
top: 0;
Expand Down
3 changes: 3 additions & 0 deletions front/src/types/editor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { JSONSchema7 } from 'json-schema';
import { Feature, GeoJsonProperties, Geometry, Point, LineString, MultiLineString } from 'geojson';
import { Direction, DirectionalTrackRange, ObjectType } from 'common/api/osrdEditoastApi';
import { LinearMetadataItem } from 'common/IntervalsDataViz/types';
import { NullGeometry } from './geospatial';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -22,6 +23,8 @@ export interface TrackSectionEntity
LineString,
{
length: number;
slopes: LinearMetadataItem<{ gradient: number }>[];
curves: LinearMetadataItem<{ radius: number }>[];
extensions?: {
sncf?: {
line_code?: number;
Expand Down