Merged PR 186: Implement filterlists

This commit is contained in:
Eric Nguyen 2022-09-19 08:46:41 +00:00
parent 1091257281
commit 4b874dfff4
6 changed files with 55 additions and 5 deletions

View file

@ -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' : ''}`}>

View file

@ -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>

View file

@ -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}

View file

@ -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>

View file

@ -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 {

View file

@ -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: {