Visão geral: O usuário pode clicar em um AVpanel da lista e o panelviewer é chamado para exibir o svg do painel junto com os vários rótulos/módulos.
Em teoria, isso funciona perfeitamente. Ele carrega o painel e adiciona os rótulos dos módulos com as cores de texto/fundo. Abaixo está uma imagem do componente do painel com os rótulos. Abaixo dos rótulos, é onde os componentes do módulo são renderizados.
Imagem do componente do painel
O problema que tenho é quando se trata de adicionar os componentes do módulo ao componente do painel. Se os módulos forem todos HDMI, eles serão adicionados. Se forem todos Cat6, eles serão adicionados. Isso ocorre quando há dois tipos de módulos. Se for um módulo HDMI em shelf03modD, ele renderiza esse componente para todos os módulos. E o mesmo se for Cat6. O último da lista será renderizado para todos.
AVPanels.ts
Este arquivo é usado como catálogo/modelo para os painéis/módulos. É usado para criar e selecionar o imageComponent para o visualizador de painéis e módulos.
import dynamic from 'next/dynamic';
interface ModuleProps {
x?: number;
y?: number;
model?: React.ComponentType<ModuleProps>;
}
interface PanelComponentProps {
shelf01ModuleALabel?: string;
shelf01ModuleATextColor?: string;
shelf01ModuleABackgroundColor?: string;
shelf01ModuleAModel?: React.ComponentType<ModuleProps>;
}
export interface PanelTemplate {
imageComponent?: React.ComponentType<PanelComponentProps>;
}
export interface ModuleTemplate {
imageModuleComponent?: React.ComponentType<ModuleProps>;
}
export const genericPanels: PanelTemplate[] = [ {
imageComponent: dynamic(() => import('@/assets/svg/panels/1u/Generic1u4ModPanel').then(mod => mod.default as React.ComponentType<PanelComponentProps>)),
}]
export const avModules: ModuleTemplate[] = [{
imageModuleComponent: dynamic(() => import('@/assets/svg/modules/GenericHDMImodule').then(mod => mod.default as React.ComponentType<ModuleProps>)),
}]
PanelViewer.tsx
getModuleDetails obtém os adereços que os componentes devem usar.
const getModuleDetailsForShelf = (shelfPosition: string) => {
if (!genericPanel) return {};
const shelf = genericPanel.fibrePanelShelves.find(
(s) => s.shelfPosition === shelfPosition
);
if (!shelf || shelf.genericPanelModules.length === 0) return {};
return shelf.genericPanelModules.reduce((acc, module) => {
const shelfNum = shelfPosition.split("_")[1].padStart(2, "0");
const position = module.modulePosition;
const moduleTemplate = getModuleTemplateByModel(module.moduleModel);
const label = `shelf${shelfNum}Module${position}Label`;
const txtColor = `shelf${shelfNum}Module${position}TextColor`;
const bgColor = `shelf${shelfNum}Module${position}BackgroundColor`;
const model = `shelf${shelfNum}Module${position}Model`;
const textColor = module.moduleLabel.includes("HDMI")
? "green"
: module.moduleLabel.includes("Cat6")
? "black"
: "black";
const backgroundColor = module.moduleLabel.includes("HDMI")
? "blue"
: module.moduleLabel.includes("Cat6")
? "white"
: "transparent";
return {
...acc,
[label]: module.moduleLabel,
[txtColor]: textColor,
[bgColor]: backgroundColor,
[model]: moduleTemplate?.imageModuleComponent,
};
}, {});
};
const genericPanelTemplate = getPanelTemplateByModel(
genericPanel.genericPanelModel
);
const ImageComponent = fibrePanelTemplate?.imageComponent;
return (
<div className="h-full w-full overflow-y-auto p-4 ease-linear">
<div className="w-full">
{image === "show" && ImageComponent && (
<ImageComponent
{...getModuleDetailsForShelf("Shelf_01")}
{...getModuleDetailsForShelf("Shelf_02")}
{...getModuleDetailsForShelf("Shelf_03")}
/>
)}
GenericPanel.tsx
Este é o componente SVG do painel
"use client";
interface ModuleProps {
x: number;
y: number;
model?: React.ComponentType<ModuleProps>;
}
const ModuleRenderer = ({ x, y, model }: ModuleProps) => {
if (!model) {
return null;
}
const ModuleComponent = model;
return <ModuleComponent x={x} y={y} model={model} />;
};
interface GenericPanelProps {
shelf01ModuleALabel?: string;
shelf01ModuleATextColor?: string;
shelf01ModuleABackgroundColor?: string;
shelf01ModuleAModel?: React.ComponentType<ModuleProps>;
}
const Generic1u4ModPanel = ({
shelf01ModuleAModel,
}: GenericPanelProps) => {
return
//This contains the SVG code for the panel. Then in each each section for the modules contains this...
<g id="s1mAlabel" transform="translate(35.163 -14.93)">
<path
id="path84"
d="M0 66.642h80.514v11.311H0z"
className="st11"
fill={shelf01ModuleABackgroundColor}
/>
<text
id="text84"
x="40.257"
y="73.5"
className="st12"
fill={shelf01ModuleATextColor}
>
{shelf01ModuleALabel}
</text>
</g>
<g id="s1mA" transform="translate(35.163 -2.444)">
<ModuleRenderer model={shelf01ModuleAModel} x={0} y={30.26} />
</g>
MóduloHDMIGenérico.tsx
Cada módulo tem isso adicionado...
"use client";
interface ModuleProps {
x?: number;
y?: number;
}
const GenericHDMImodule = ({ x = 0, y = 0 }: ModuleProps) => {
return (
<g transform={`translate(${x} ${y})`} height={11.31} width={80.51}>
A dica é que o último componente do módulo na lista do array é renderizado para todos se houver 2 ou mais tipos de módulo em um painel. Eu tive o mesmo problema quando comecei com os rótulos. Resolvi isso atribuindo a cada rótulo sua própria propriedade (por exemplo, shelf01moduleAlabel, shelf01moduleBlabel). Mas isso não funciona para renderizar os componentes do módulo em si. Ele ainda usa o último da lista e o renderiza para todos os módulos, pois esses são componentes dinâmicos. Simplesmente não consigo descobrir como atribuir a cada posição uma chave exclusiva para que eles sejam renderizados.
Muito mais fácil com os modernos componentes da Web padrão