[Update] Symbol alignement behavior + filtered Symbollist in ContainerForm.tsx
This commit is contained in:
parent
bf4f69a95f
commit
a476017d99
8 changed files with 148 additions and 32 deletions
|
@ -5,7 +5,8 @@ import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||||
import {
|
import {
|
||||||
SHOW_BORROWER_DIMENSIONS,
|
SHOW_BORROWER_DIMENSIONS,
|
||||||
SHOW_CHILDREN_DIMENSIONS,
|
SHOW_CHILDREN_DIMENSIONS,
|
||||||
SHOW_SELF_DIMENSIONS, SHOW_SELF_MARGINS_DIMENSIONS
|
SHOW_SELF_DIMENSIONS,
|
||||||
|
SHOW_SELF_MARGINS_DIMENSIONS
|
||||||
} from '../../utils/default';
|
} from '../../utils/default';
|
||||||
import {
|
import {
|
||||||
ApplyWidthMargin,
|
ApplyWidthMargin,
|
||||||
|
@ -27,8 +28,12 @@ import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector';
|
||||||
import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes';
|
import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes';
|
||||||
import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes';
|
import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes';
|
||||||
import { Category } from '../Category/Category';
|
import { Category } from '../Category/Category';
|
||||||
|
import { Orientation } from '../../Enums/Orientation';
|
||||||
|
import { FindContainerById } from '../../utils/itertools';
|
||||||
|
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||||
|
|
||||||
interface IContainerFormProps {
|
interface IContainerFormProps {
|
||||||
|
containers: Map<string, IContainerModel>
|
||||||
properties: IContainerProperties
|
properties: IContainerProperties
|
||||||
symbols: Map<string, ISymbolModel>
|
symbols: Map<string, ISymbolModel>
|
||||||
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
|
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
|
||||||
|
@ -36,6 +41,8 @@ interface IContainerFormProps {
|
||||||
|
|
||||||
export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
const categoryHeight = 'h-11';
|
const categoryHeight = 'h-11';
|
||||||
|
const parent = FindContainerById(props.containers, props.properties.parentId);
|
||||||
|
const isVertical = parent?.properties.orientation === Orientation.Vertical;
|
||||||
return (
|
return (
|
||||||
<div className='grid grid-cols-1 gap-y-4 items-center'>
|
<div className='grid grid-cols-1 gap-y-4 items-center'>
|
||||||
<TextInputGroup
|
<TextInputGroup
|
||||||
|
@ -185,8 +192,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
type='number'
|
type='number'
|
||||||
min={props.properties.minWidth}
|
min={props.properties.minWidth}
|
||||||
max={props.properties.maxWidth}
|
max={props.properties.maxWidth}
|
||||||
value={(RemoveWidthMargin(props.properties.width, props.properties.margin.left, props.properties.margin.right)).toString()}
|
value={(RemoveWidthMargin(props.properties.width,
|
||||||
onChange={(value) => { props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right)); }}
|
props.properties.margin.left,
|
||||||
|
props.properties.margin.right)).toString()}
|
||||||
|
onChange={(value) => {
|
||||||
|
props.onChange('width', ApplyWidthMargin(Number(value),
|
||||||
|
props.properties.margin.left,
|
||||||
|
props.properties.margin.right));
|
||||||
|
}}
|
||||||
isDisabled={props.properties.isFlex}/>
|
isDisabled={props.properties.isFlex}/>
|
||||||
<TextInputGroup
|
<TextInputGroup
|
||||||
id={`${props.properties.id}-maxWidth`}
|
id={`${props.properties.id}-maxWidth`}
|
||||||
|
@ -218,8 +231,14 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
type='number'
|
type='number'
|
||||||
min={props.properties.minHeight}
|
min={props.properties.minHeight}
|
||||||
max={props.properties.maxHeight}
|
max={props.properties.maxHeight}
|
||||||
value={(RemoveWidthMargin(props.properties.height, props.properties.margin.top, props.properties.margin.bottom)).toString()}
|
value={(RemoveWidthMargin(props.properties.height,
|
||||||
onChange={(value) => { props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom)); }}
|
props.properties.margin.top,
|
||||||
|
props.properties.margin.bottom)).toString()}
|
||||||
|
onChange={(value) => {
|
||||||
|
props.onChange('height', ApplyWidthMargin(Number(value),
|
||||||
|
props.properties.margin.top,
|
||||||
|
props.properties.margin.bottom));
|
||||||
|
}}
|
||||||
isDisabled={props.properties.isFlex}
|
isDisabled={props.properties.isFlex}
|
||||||
/>
|
/>
|
||||||
<TextInputGroup
|
<TextInputGroup
|
||||||
|
@ -332,7 +351,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
labelText={Text({ textId: '@ContainerAlignWithSymbol' })}
|
labelText={Text({ textId: '@ContainerAlignWithSymbol' })}
|
||||||
labelClassName=''
|
labelClassName=''
|
||||||
inputClassName=''
|
inputClassName=''
|
||||||
inputs={[...props.symbols.values()].map(symbol => ({
|
inputs={[...props.symbols.values()].filter(symbol => (symbol.isVertical === isVertical)).map(symbol => ({
|
||||||
key: symbol.id,
|
key: symbol.id,
|
||||||
text: symbol.id,
|
text: symbol.id,
|
||||||
value: symbol.id
|
value: symbol.id
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PropertyType } from '../../Enums/PropertyType';
|
import { type PropertyType } from '../../Enums/PropertyType';
|
||||||
import { IContainerProperties } from '../../Interfaces/IContainerProperties';
|
import { type IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||||
import { ContainerForm } from './ContainerForm';
|
import { ContainerForm } from './ContainerForm';
|
||||||
|
import { type IContainerModel } from '../../Interfaces/IContainerModel';
|
||||||
|
|
||||||
interface IPropertiesProps {
|
interface IPropertiesProps {
|
||||||
|
containers: Map<string, IContainerModel>
|
||||||
properties?: IContainerProperties
|
properties?: IContainerProperties
|
||||||
symbols: Map<string, ISymbolModel>
|
symbols: Map<string, ISymbolModel>
|
||||||
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
|
onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
|
||||||
|
@ -18,6 +20,7 @@ export function ContainerProperties(props: IPropertiesProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className='h-full p-3 bg-slate-200 overflow-y-auto'>
|
<div className='h-full p-3 bg-slate-200 overflow-y-auto'>
|
||||||
<ContainerForm
|
<ContainerForm
|
||||||
|
containers={props.containers}
|
||||||
properties={props.properties}
|
properties={props.properties}
|
||||||
symbols={props.symbols}
|
symbols={props.symbols}
|
||||||
onChange={props.onChange} />
|
onChange={props.onChange} />
|
||||||
|
|
|
@ -7,8 +7,8 @@ export function ApplySymbol(containers: Map<string, IContainerModel>,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
symbol: ISymbolModel): IContainerModel {
|
symbol: ISymbolModel): IContainerModel {
|
||||||
if (symbol.isVertical) {
|
if (symbol.isVertical) {
|
||||||
container.properties.y = TransformY(symbol.offset + symbol.height / 2,
|
container.properties.y = TransformY(symbol.offset,
|
||||||
symbol.height,
|
symbol.height * 2,
|
||||||
symbol.config.PositionReference);
|
symbol.config.PositionReference);
|
||||||
container.properties.y = RestoreY(container.properties.y,
|
container.properties.y = RestoreY(container.properties.y,
|
||||||
container.properties.height,
|
container.properties.height,
|
||||||
|
@ -21,7 +21,7 @@ export function ApplySymbol(containers: Map<string, IContainerModel>,
|
||||||
container.properties.y = y;
|
container.properties.y = y;
|
||||||
return container;
|
return container;
|
||||||
} else {
|
} else {
|
||||||
container.properties.x = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference);
|
container.properties.x = TransformX(symbol.offset, symbol.width * 2, symbol.config.PositionReference);
|
||||||
container.properties.x = RestoreX(container.properties.x,
|
container.properties.x = RestoreX(container.properties.x,
|
||||||
container.properties.width,
|
container.properties.width,
|
||||||
container.properties.positionReference);
|
container.properties.positionReference);
|
||||||
|
|
|
@ -169,6 +169,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
|
||||||
{props.selectedExtendedSidebar === ExtendedSidebar.Property &&
|
{props.selectedExtendedSidebar === ExtendedSidebar.Property &&
|
||||||
<div className='flex flex-1 flex-col w-64 border-r-2 border-slate-400'>
|
<div className='flex flex-1 flex-col w-64 border-r-2 border-slate-400'>
|
||||||
<ContainerProperties
|
<ContainerProperties
|
||||||
|
containers ={props.containers}
|
||||||
properties={props.selectedContainer?.properties}
|
properties={props.selectedContainer?.properties}
|
||||||
symbols={props.symbols}
|
symbols={props.symbols}
|
||||||
onChange={props.onPropertyChange}
|
onChange={props.onPropertyChange}
|
||||||
|
@ -231,8 +232,10 @@ function ElementsListRow(
|
||||||
: 'bg-slate-300/60 hover:bg-slate-400 hover:shadow-slate-400';
|
: 'bg-slate-300/60 hover:bg-slate-400 hover:shadow-slate-400';
|
||||||
|
|
||||||
return <button type="button"
|
return <button type="button"
|
||||||
className={`transition-all border-blue-500 hover:shadow-lg elements-sidebar-row whitespace-pre
|
className={`transition-all border-blue-500
|
||||||
text-left text-sm font-medium flex items-center align-middle group ${container.properties.type} ${buttonSelectedClass}`}
|
hover:shadow-lg elements-sidebar-row whitespace-pre
|
||||||
|
text-left text-sm font-medium flex items-center align-middle group
|
||||||
|
${container.properties.type} ${buttonSelectedClass}`}
|
||||||
id={key}
|
id={key}
|
||||||
key={key}
|
key={key}
|
||||||
style={style}
|
style={style}
|
||||||
|
|
|
@ -185,7 +185,7 @@ function AddHorizontalSymbolDimension(symbol: ISymbolModel,
|
||||||
scale: number,
|
scale: number,
|
||||||
depth: number
|
depth: number
|
||||||
): void {
|
): void {
|
||||||
const width = symbol.offset + (symbol.width / 2);
|
const width = TransformX(symbol.offset, symbol.width * 2, symbol.config.PositionReference);
|
||||||
if (width != null && width > 0) {
|
if (width != null && width > 0) {
|
||||||
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
|
const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`;
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ function AddVerticalSymbolDimension(symbol: ISymbolModel,
|
||||||
scale: number,
|
scale: number,
|
||||||
depth: number
|
depth: number
|
||||||
): void {
|
): void {
|
||||||
const height = symbol.offset + (symbol.height / 2);
|
const height = TransformY(symbol.offset, symbol.height * 2, symbol.config.PositionReference);
|
||||||
if (height != null && height > 0) {
|
if (height != null && height > 0) {
|
||||||
const id = `dim-x-margin-left${symbol.height.toFixed(0)}-${symbol.id}`;
|
const id = `dim-x-margin-left${symbol.height.toFixed(0)}-${symbol.id}`;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ import * as React from 'react';
|
||||||
import { SYMBOL_MARGIN } from '../../../../utils/default';
|
import { SYMBOL_MARGIN } from '../../../../utils/default';
|
||||||
import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel';
|
import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel';
|
||||||
import { Selector } from '../Selector/Selector';
|
import { Selector } from '../Selector/Selector';
|
||||||
|
import { TransformX, TransformY } from '../../../../utils/svg';
|
||||||
|
import { PositionReference } from '../../../../Enums/PositionReference';
|
||||||
|
|
||||||
interface ISelectorSymbolProps {
|
interface ISelectorSymbolProps {
|
||||||
symbols: Map<string, ISymbolModel>
|
symbols: Map<string, ISymbolModel>
|
||||||
|
@ -19,20 +21,44 @@ export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
const scale = (props.scale ?? 1);
|
const scale = (props.scale ?? 1);
|
||||||
const [width, height] = [
|
|
||||||
props.selected.width / scale,
|
|
||||||
props.selected.height / scale
|
|
||||||
];
|
|
||||||
|
|
||||||
let x, y: number;
|
let x, y: number;
|
||||||
|
|
||||||
|
const scaledHeight = props.selected.height / scale;
|
||||||
|
const scaledWidth = props.selected.width / scale;
|
||||||
|
|
||||||
if (props.selected.isVertical) {
|
if (props.selected.isVertical) {
|
||||||
x = -SYMBOL_MARGIN / scale - width;
|
x = (-SYMBOL_MARGIN - props.selected.width) / scale;
|
||||||
y = (props.selected.offset + props.selected.height / 2) - (props.selected.height / scale / 2);
|
y = TransformY(props.selected.offset, props.selected.height * 2, props.selected.config.PositionReference);
|
||||||
|
|
||||||
|
switch (props.selected.config.PositionReference) {
|
||||||
|
case PositionReference.CenterLeft:
|
||||||
|
case PositionReference.CenterCenter:
|
||||||
|
case PositionReference.CenterRight:
|
||||||
|
y -= scaledHeight / 2;
|
||||||
|
break;
|
||||||
|
case PositionReference.BottomLeft:
|
||||||
|
case PositionReference.BottomCenter:
|
||||||
|
case PositionReference.BottomRight:
|
||||||
|
y -= scaledHeight;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
[x, y] = [
|
x = TransformX(props.selected.offset, props.selected.width * 2, props.selected.config.PositionReference);
|
||||||
(props.selected.offset + props.selected.width / 2) - (props.selected.width / scale / 2),
|
|
||||||
-SYMBOL_MARGIN / scale - height];
|
switch (props.selected.config.PositionReference) {
|
||||||
|
case PositionReference.TopCenter:
|
||||||
|
case PositionReference.CenterCenter:
|
||||||
|
case PositionReference.BottomCenter:
|
||||||
|
x -= scaledWidth / 2;
|
||||||
|
break;
|
||||||
|
case PositionReference.TopRight:
|
||||||
|
case PositionReference.CenterRight:
|
||||||
|
case PositionReference.BottomRight:
|
||||||
|
x -= scaledWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
y = (-SYMBOL_MARGIN - props.selected.height) / scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -40,8 +66,8 @@ export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element {
|
||||||
text={props.selected.displayedText}
|
text={props.selected.displayedText}
|
||||||
x={x}
|
x={x}
|
||||||
y={y}
|
y={y}
|
||||||
width={width}
|
width={scaledWidth}
|
||||||
height={height}
|
height={scaledHeight}
|
||||||
scale={scale}
|
scale={scale}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { Interweave } from 'interweave';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
import { type ISymbolModel } from '../../../Interfaces/ISymbolModel';
|
||||||
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../utils/default';
|
import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../utils/default';
|
||||||
|
import { TransformX, TransformY } from '../../../utils/svg';
|
||||||
|
import { PositionReference } from '../../../Enums/PositionReference';
|
||||||
|
|
||||||
interface ISymbolProps {
|
interface ISymbolProps {
|
||||||
model: ISymbolModel
|
model: ISymbolModel
|
||||||
|
@ -38,9 +40,36 @@ export function Symbol(props: ISymbolProps): JSX.Element {
|
||||||
}
|
}
|
||||||
if (props.model.isVertical) {
|
if (props.model.isVertical) {
|
||||||
x = (-SYMBOL_MARGIN - props.model.width) / props.scale;
|
x = (-SYMBOL_MARGIN - props.model.width) / props.scale;
|
||||||
y = (props.model.offset + props.model.height / 2) - (props.model.height / props.scale / 2);
|
y = TransformY(props.model.offset, props.model.height * 2, props.model.config.PositionReference);
|
||||||
|
|
||||||
|
switch (props.model.config.PositionReference) {
|
||||||
|
case PositionReference.CenterLeft:
|
||||||
|
case PositionReference.CenterCenter:
|
||||||
|
case PositionReference.CenterRight:
|
||||||
|
y -= props.model.height / props.scale / 2;
|
||||||
|
break;
|
||||||
|
case PositionReference.BottomLeft:
|
||||||
|
case PositionReference.BottomCenter:
|
||||||
|
case PositionReference.BottomRight:
|
||||||
|
y -= props.model.height / props.scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x = (props.model.offset + props.model.width / 2) - (props.model.width / props.scale / 2);
|
x = TransformX(props.model.offset, props.model.width * 2, props.model.config.PositionReference);
|
||||||
|
|
||||||
|
switch (props.model.config.PositionReference) {
|
||||||
|
case PositionReference.TopCenter:
|
||||||
|
case PositionReference.CenterCenter:
|
||||||
|
case PositionReference.BottomCenter:
|
||||||
|
x -= props.model.width / props.scale / 2;
|
||||||
|
break;
|
||||||
|
case PositionReference.TopRight:
|
||||||
|
case PositionReference.CenterRight:
|
||||||
|
case PositionReference.BottomRight:
|
||||||
|
x -= props.model.width / props.scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
y = (-SYMBOL_MARGIN - props.model.height) / props.scale;
|
y = (-SYMBOL_MARGIN - props.model.height) / props.scale;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -286,7 +286,7 @@ const GetSVGLayoutConfiguration = () => {
|
||||||
Svg: null,
|
Svg: null,
|
||||||
Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg'
|
Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg'
|
||||||
},
|
},
|
||||||
Name: 'Poteau structure',
|
Name: 'Poteau CenterCenter',
|
||||||
PositionReference: 1,
|
PositionReference: 1,
|
||||||
AssociatedContainer: {
|
AssociatedContainer: {
|
||||||
Type: 'Montant'
|
Type: 'Montant'
|
||||||
|
@ -297,13 +297,49 @@ const GetSVGLayoutConfiguration = () => {
|
||||||
Height: 32,
|
Height: 32,
|
||||||
Image: {
|
Image: {
|
||||||
Base64Image: null,
|
Base64Image: null,
|
||||||
Name: 'Arrow',
|
Name: 'ArrowTopLeft',
|
||||||
Svg: null,
|
Svg: null,
|
||||||
Url: './images/arrow-down.svg'
|
Url: './images/arrow-down.svg'
|
||||||
},
|
},
|
||||||
Name: 'Arrow',
|
Name: 'ArrowTopLeft',
|
||||||
PositionReference: 0
|
PositionReference: 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Width: 32,
|
||||||
|
Height: 32,
|
||||||
|
Image: {
|
||||||
|
Base64Image: null,
|
||||||
|
Name: 'ArrowTopRight',
|
||||||
|
Svg: null,
|
||||||
|
Url: './images/arrow-down.svg'
|
||||||
|
},
|
||||||
|
Name: 'ArrowTopRight',
|
||||||
|
PositionReference: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Width: 32,
|
||||||
|
Height: 32,
|
||||||
|
Image: {
|
||||||
|
Base64Image: null,
|
||||||
|
Name: 'ArrowCenterRight',
|
||||||
|
Svg: null,
|
||||||
|
Url: './images/arrow-down.svg'
|
||||||
|
},
|
||||||
|
Name: 'ArrowCenterRight',
|
||||||
|
PositionReference: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Width: 32,
|
||||||
|
Height: 32,
|
||||||
|
Image: {
|
||||||
|
Base64Image: null,
|
||||||
|
Name: 'ArrowBottomRight',
|
||||||
|
Svg: null,
|
||||||
|
Url: './images/arrow-down.svg'
|
||||||
|
},
|
||||||
|
Name: 'ArrowBottomRight',
|
||||||
|
PositionReference: 8
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Width: 32,
|
Width: 32,
|
||||||
Height: 32,
|
Height: 32,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue