Merged PR 186: Implement filterlists
This commit is contained in:
parent
1091257281
commit
4b874dfff4
6 changed files with 55 additions and 5 deletions
|
@ -4,7 +4,7 @@ import { ICategory } from '../../Interfaces/ICategory';
|
||||||
import { TruncateString } from '../../utils/stringtools';
|
import { TruncateString } from '../../utils/stringtools';
|
||||||
|
|
||||||
interface ICategoryProps {
|
interface ICategoryProps {
|
||||||
children: JSX.Element | JSX.Element[]
|
children: JSX.Element[]
|
||||||
category: ICategory
|
category: ICategory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ export function Category(props: ICategoryProps): JSX.Element {
|
||||||
title={categoryDisplayedText}
|
title={categoryDisplayedText}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className='flex flex-row group cursor-pointer h-16'
|
className={'flex flex-row group h-16 cursor-pointer'}
|
||||||
onClick={() => setIsOpen(!isOpen)}
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
>
|
>
|
||||||
<span className={`transition-all flex-1 h-full justify-center sidebar-component-left ${isOpen ? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600' : ''}`}>
|
<span className={`transition-all flex-1 h-full justify-center sidebar-component-left ${isOpen ? 'rounded-b-none bg-slate-400/80 group-hover:bg-blue-600' : ''}`}>
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
import { EyeIcon, EyeOffIcon } from '@heroicons/react/outline';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
||||||
import { ICategory } from '../../Interfaces/ICategory';
|
import { ICategory } from '../../Interfaces/ICategory';
|
||||||
|
import { IContainerModel } from '../../Interfaces/IContainerModel';
|
||||||
import { TruncateString } from '../../utils/stringtools';
|
import { TruncateString } from '../../utils/stringtools';
|
||||||
import { Category } from '../Category/Category';
|
import { Category } from '../Category/Category';
|
||||||
|
|
||||||
interface ISidebarProps {
|
interface ISidebarProps {
|
||||||
|
selectedContainer: IContainerModel | undefined
|
||||||
componentOptions: IAvailableContainer[]
|
componentOptions: IAvailableContainer[]
|
||||||
categories: ICategory[]
|
categories: ICategory[]
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
|
@ -21,6 +24,8 @@ interface SidebarCategory {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Sidebar(props: ISidebarProps): JSX.Element {
|
export function Sidebar(props: ISidebarProps): JSX.Element {
|
||||||
|
const [hideDisabled, setHideDisabled] = React.useState<boolean>(false);
|
||||||
|
|
||||||
const rootElements: Array<JSX.Element | undefined> = [];
|
const rootElements: Array<JSX.Element | undefined> = [];
|
||||||
const categories = new Map<string, SidebarCategory>(props.categories.map(category => [
|
const categories = new Map<string, SidebarCategory>(props.categories.map(category => [
|
||||||
category.Type,
|
category.Type,
|
||||||
|
@ -41,12 +46,25 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
|
||||||
</Category>);
|
</Category>);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectedContainer = props.selectedContainer;
|
||||||
|
const config = props.componentOptions.find(option => option.Type === selectedContainer?.properties.type);
|
||||||
// build the components
|
// build the components
|
||||||
props.componentOptions.forEach(componentOption => {
|
props.componentOptions.forEach(componentOption => {
|
||||||
if (componentOption.IsHidden === true) {
|
if (componentOption.IsHidden === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let disabled = false;
|
||||||
|
if (config?.Whitelist !== undefined) {
|
||||||
|
disabled = config.Whitelist?.find(type => type === componentOption.Type) === undefined;
|
||||||
|
} else if (config?.Blacklist !== undefined) {
|
||||||
|
disabled = config.Blacklist?.find(type => type === componentOption.Type) !== undefined ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled && hideDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const componentButton = (<button
|
const componentButton = (<button
|
||||||
key={componentOption.Type}
|
key={componentOption.Type}
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -56,9 +74,11 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
|
||||||
onClick={() => props.buttonOnClick(componentOption.Type)}
|
onClick={() => props.buttonOnClick(componentOption.Type)}
|
||||||
draggable={true}
|
draggable={true}
|
||||||
onDragStart={(event) => HandleDragStart(event)}
|
onDragStart={(event) => HandleDragStart(event)}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
|
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
|
||||||
</button>);
|
</button>);
|
||||||
|
|
||||||
if (componentOption.Category === null || componentOption.Category === undefined) {
|
if (componentOption.Category === null || componentOption.Category === undefined) {
|
||||||
rootElements.push(componentButton);
|
rootElements.push(componentButton);
|
||||||
return;
|
return;
|
||||||
|
@ -69,6 +89,7 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
|
||||||
console.error(`[Category] Category does not exists in configuration.Categories: ${componentOption.Category}`);
|
console.error(`[Category] Category does not exists in configuration.Categories: ${componentOption.Category}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
category.children.push(componentButton);
|
category.children.push(componentButton);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -77,10 +98,22 @@ export function Sidebar(props: ISidebarProps): JSX.Element {
|
||||||
<div className={`fixed z-10 bg-slate-200
|
<div className={`fixed z-10 bg-slate-200
|
||||||
text-gray-700 transition-all h-full w-64
|
text-gray-700 transition-all h-full w-64
|
||||||
overflow-y-auto ${isOpenClasses}`}>
|
overflow-y-auto ${isOpenClasses}`}>
|
||||||
<div className='bg-slate-100 sidebar-title'>
|
<div className='bg-slate-100 sidebar-title flex place-content-between'>
|
||||||
Components
|
Components
|
||||||
|
<button
|
||||||
|
onClick={() => { setHideDisabled(!hideDisabled); }}
|
||||||
|
className='h-6'
|
||||||
|
aria-label='Hide disabled component'
|
||||||
|
title='Hide disabled component'
|
||||||
|
>
|
||||||
|
{
|
||||||
|
hideDisabled
|
||||||
|
? <EyeOffIcon className='heroicon'></EyeOffIcon>
|
||||||
|
: <EyeIcon className='heroicon'></EyeIcon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid grid-cols-1 md:grid-cols-1 gap-2
|
<div className='transition-all grid grid-cols-1 md:grid-cols-1 gap-2
|
||||||
m-2 md:text-xs font-bold'>
|
m-2 md:text-xs font-bold'>
|
||||||
{rootElements}
|
{rootElements}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -84,6 +84,7 @@ export function UI(props: IUIProps): JSX.Element {
|
||||||
} }/>
|
} }/>
|
||||||
|
|
||||||
<Sidebar
|
<Sidebar
|
||||||
|
selectedContainer={props.selectedContainer}
|
||||||
componentOptions={props.availableContainers}
|
componentOptions={props.availableContainers}
|
||||||
categories={props.categories}
|
categories={props.categories}
|
||||||
isOpen={isSidebarOpen}
|
isOpen={isSidebarOpen}
|
||||||
|
|
|
@ -118,6 +118,18 @@ export interface IAvailableContainer {
|
||||||
*/
|
*/
|
||||||
IsHidden?: boolean
|
IsHidden?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable a list of available container to be added inside
|
||||||
|
*/
|
||||||
|
Blacklist?: string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cannot be used with blacklist. Whitelist will be prioritized.
|
||||||
|
* To disable the whitelist, Whitelist must be undefined.
|
||||||
|
* Only allow a set of available container to be added inside
|
||||||
|
*/
|
||||||
|
Whitelist?: string[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (optional)
|
* (optional)
|
||||||
* Style of the <rect>
|
* Style of the <rect>
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-component {
|
.sidebar-component {
|
||||||
@apply transition-all px-2 py-6 text-sm rounded-lg bg-slate-300/80 hover:bg-blue-500 hover:text-slate-50
|
@apply transition-all px-2 py-6 text-sm rounded-lg
|
||||||
|
bg-slate-300/80 hover:bg-blue-500 hover:text-slate-50
|
||||||
|
disabled:bg-slate-400 disabled:text-slate-500
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-component-left {
|
.sidebar-component-left {
|
||||||
|
|
|
@ -65,6 +65,7 @@ const GetSVGLayoutConfiguration = () => {
|
||||||
{
|
{
|
||||||
Type: 'Chassis',
|
Type: 'Chassis',
|
||||||
DisplayedText: 'Chassis?',
|
DisplayedText: 'Chassis?',
|
||||||
|
Whitelist: ["Trou"],
|
||||||
MaxWidth: 500,
|
MaxWidth: 500,
|
||||||
MinWidth: 200,
|
MinWidth: 200,
|
||||||
Width: 200,
|
Width: 200,
|
||||||
|
@ -81,6 +82,7 @@ const GetSVGLayoutConfiguration = () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: 'Trou',
|
Type: 'Trou',
|
||||||
|
Blacklist: ["Chassis"],
|
||||||
DefaultX: 0,
|
DefaultX: 0,
|
||||||
DefaultY: 0,
|
DefaultY: 0,
|
||||||
Margin: {
|
Margin: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue