feat: enhance Design component with improved styling and functionality for element customization
feat: update LogList and LoggerContext to manage log visibility and selected tab state refactor: clean up DraggableWidget by removing unnecessary console logs refactor: remove debug logs from TotalCardComponent style: improve sidebar styles for better layout and appearance
This commit is contained in:
parent
49d6b242d4
commit
640505a7f7
|
@ -1,324 +1,146 @@
|
||||||
import { useState, useEffect, useRef } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { ArrowIcon } from "../../../../icons/ExportCommonIcons";
|
||||||
|
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
|
||||||
|
import InputRange from "../../../../ui/inputs/InputRange";
|
||||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||||
import ChartComponent from "../../../sidebarLeft/visualization/widgets/ChartComponent";
|
import ChartComponent from "../../../sidebarLeft/visualization/widgets/ChartComponent";
|
||||||
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
|
|
||||||
import { WalletIcon } from "../../../../icons/3dChartIcons";
|
|
||||||
import SimpleCard from "../../../../../modules/visualization/widgets/floating/cards/SimpleCard";
|
|
||||||
|
|
||||||
interface Widget {
|
const defaultStyle = {
|
||||||
id: string;
|
theme: "Glass",
|
||||||
type?: string;
|
elementColor: "#ffffff",
|
||||||
panel: "top" | "bottom" | "left" | "right";
|
blurEffect: 10,
|
||||||
title?: string;
|
opacity: 10,
|
||||||
header?: string;
|
selectedElement: "Glass",
|
||||||
fontFamily?: string;
|
};
|
||||||
fontSize?: string;
|
|
||||||
fontWeight?: string;
|
|
||||||
className?: string;
|
|
||||||
data?: {
|
|
||||||
labels: string[];
|
|
||||||
datasets: {
|
|
||||||
data: number[];
|
|
||||||
backgroundColor: string;
|
|
||||||
borderColor: string;
|
|
||||||
borderWidth: number;
|
|
||||||
}[];
|
|
||||||
};
|
|
||||||
value?: string;
|
|
||||||
per?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChartElement {
|
const defaultChartData = {
|
||||||
tagName: string;
|
duration: "1h",
|
||||||
className: string;
|
measurements: {},
|
||||||
textContent: string;
|
datasets: [
|
||||||
selector: string;
|
{
|
||||||
}
|
data: [65, 59, 80, 81, 56, 55, 40],
|
||||||
|
backgroundColor: "#6f42c1",
|
||||||
|
borderColor: "#b392f0",
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||||
|
};
|
||||||
|
|
||||||
const Design = () => {
|
const Design = () => {
|
||||||
const [selectedFont, setSelectedFont] = useState("drop down");
|
const { selectedChartId } = useWidgetStore();
|
||||||
const [selectedSize, setSelectedSize] = useState("drop down");
|
const [styles, setStyles] = useState<Record<string, typeof defaultStyle>>({});
|
||||||
const [selectedWeight, setSelectedWeight] = useState("drop down");
|
|
||||||
const [elementColor, setElementColor] = useState("#6f42c1");
|
|
||||||
const [showColorPicker, setShowColorPicker] = useState(false);
|
|
||||||
const [chartElements, setChartElements] = useState<ChartElement[]>([]);
|
|
||||||
const [selectedElementToStyle, setSelectedElementToStyle] = useState<
|
|
||||||
string | null
|
|
||||||
>(null);
|
|
||||||
const [nameInput, setNameInput] = useState("");
|
|
||||||
const chartRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
const { selectedChartId, setSelectedChartId, widgets, setWidgets } =
|
const currentStyle = selectedChartId
|
||||||
useWidgetStore();
|
? styles[selectedChartId.id] || defaultStyle
|
||||||
|
: defaultStyle;
|
||||||
|
|
||||||
// Initialize name input and extract elements when selectedChartId changes
|
const updateStyle = (updates: Partial<typeof defaultStyle>) => {
|
||||||
useEffect(() => {
|
|
||||||
setNameInput(selectedChartId?.header ? selectedChartId?.title : "");
|
|
||||||
|
|
||||||
if (!chartRef.current) return;
|
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
const chartContainer = chartRef.current;
|
|
||||||
if (!chartContainer) return;
|
|
||||||
|
|
||||||
const elements = Array.from(chartContainer.querySelectorAll("*"))
|
|
||||||
.filter((el) => {
|
|
||||||
const tagName = el.tagName.toLowerCase();
|
|
||||||
return !["script", "style", "meta", "link", "head"].includes(tagName);
|
|
||||||
})
|
|
||||||
.map((el, index) => {
|
|
||||||
const tagName = el.tagName.toLowerCase();
|
|
||||||
const className =
|
|
||||||
typeof el.className === "string" ? el.className : "";
|
|
||||||
const textContent = el.textContent?.trim() ?? "";
|
|
||||||
|
|
||||||
let selector = tagName;
|
|
||||||
|
|
||||||
if (className && typeof className === "string") {
|
|
||||||
const classList = className
|
|
||||||
.split(/\s+/)
|
|
||||||
.filter((c) => c.length > 0);
|
|
||||||
if (classList.length > 0) {
|
|
||||||
selector += "." + classList.join(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!className || className.trim() === "") {
|
|
||||||
const parent = el.parentElement;
|
|
||||||
if (parent) {
|
|
||||||
const siblings = Array.from(parent.children).filter(
|
|
||||||
(child) => child.tagName.toLowerCase() === tagName
|
|
||||||
);
|
|
||||||
const position = siblings.indexOf(el) + 1;
|
|
||||||
selector += `:nth-of-type(${position})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
tagName,
|
|
||||||
className,
|
|
||||||
textContent,
|
|
||||||
selector,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
setChartElements(elements);
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, [selectedChartId]);
|
|
||||||
|
|
||||||
const applyStyles = () => {
|
|
||||||
if (!selectedElementToStyle || !chartRef.current) return;
|
|
||||||
|
|
||||||
const element = chartRef.current.querySelector(selectedElementToStyle);
|
|
||||||
if (!element) return;
|
|
||||||
|
|
||||||
const elementToStyle = element as HTMLElement;
|
|
||||||
|
|
||||||
if (selectedFont !== "drop down") {
|
|
||||||
elementToStyle.style.fontFamily = selectedFont;
|
|
||||||
}
|
|
||||||
if (selectedSize !== "drop down") {
|
|
||||||
elementToStyle.style.fontSize = selectedSize;
|
|
||||||
}
|
|
||||||
if (selectedWeight !== "drop down") {
|
|
||||||
elementToStyle.style.fontWeight = selectedWeight.toLowerCase();
|
|
||||||
}
|
|
||||||
if (elementColor) {
|
|
||||||
elementToStyle.style.color = elementColor;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
applyStyles();
|
|
||||||
}, [
|
|
||||||
selectedFont,
|
|
||||||
selectedSize,
|
|
||||||
selectedWeight,
|
|
||||||
elementColor,
|
|
||||||
selectedElementToStyle,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleUpdateWidget = (updatedProperties: Partial<Widget>) => {
|
|
||||||
if (!selectedChartId) return;
|
if (!selectedChartId) return;
|
||||||
|
setStyles((prev) => ({
|
||||||
const updatedChartId = {
|
...prev,
|
||||||
...selectedChartId,
|
[selectedChartId.id]: { ...currentStyle, ...updates },
|
||||||
...updatedProperties,
|
}));
|
||||||
};
|
|
||||||
setSelectedChartId(updatedChartId);
|
|
||||||
|
|
||||||
const updatedWidgets = widgets.map((widget) =>
|
|
||||||
widget.id === selectedChartId.id
|
|
||||||
? { ...widget, ...updatedProperties }
|
|
||||||
: widget
|
|
||||||
);
|
|
||||||
setWidgets(updatedWidgets);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
useEffect(() => {
|
||||||
const newName = e.target.value;
|
console.log("Styles", styles);
|
||||||
setNameInput(newName);
|
}, [styles]);
|
||||||
|
|
||||||
if (selectedChartId?.title) {
|
|
||||||
handleUpdateWidget({ title: newName });
|
|
||||||
} else if (selectedChartId?.header) {
|
|
||||||
handleUpdateWidget({ header: newName });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultChartData = {
|
|
||||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
data: [65, 59, 80, 81, 56, 55, 40],
|
|
||||||
backgroundColor: "#6f42c1",
|
|
||||||
borderColor: "#b392f0",
|
|
||||||
borderWidth: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const elementOptions = chartElements.map((el) => {
|
|
||||||
let displayName = el.tagName;
|
|
||||||
if (el.className) displayName += `.${el.className}`;
|
|
||||||
if (el.textContent)
|
|
||||||
displayName += ` (${el.textContent.substring(0, 20)}${
|
|
||||||
el.textContent.length > 20 ? "..." : ""
|
|
||||||
})`;
|
|
||||||
return {
|
|
||||||
display: displayName,
|
|
||||||
value: el.selector,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="design">
|
<div className="design">
|
||||||
<div className="selectedWidget">
|
<div className="appearance-container">
|
||||||
{selectedChartId?.title ? selectedChartId?.header : "Widget 1"}
|
<div className="header-container">
|
||||||
|
<div className="head">Appearance</div>
|
||||||
|
<div className="icon">
|
||||||
|
<ArrowIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appearance-style">
|
||||||
|
<div className="theme-wrapper">
|
||||||
|
<div className="key">Theme</div>
|
||||||
|
<div className="value">
|
||||||
|
<RegularDropDown
|
||||||
|
header={currentStyle.theme}
|
||||||
|
options={["Glass", "Fill", "Transparent"]}
|
||||||
|
onSelect={(theme) => updateStyle({ theme })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{currentStyle.theme === "Glass" && (
|
||||||
|
<div className="blurEffect-wrapper">
|
||||||
|
<InputRange
|
||||||
|
label="Blur Effects"
|
||||||
|
disabled={false}
|
||||||
|
value={currentStyle.blurEffect}
|
||||||
|
min={0}
|
||||||
|
max={50}
|
||||||
|
onChange={(blurEffect) => updateStyle({ blurEffect })}
|
||||||
|
onPointerUp={() => {}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentStyle.theme !== "Fill" && (
|
||||||
|
<div className="opacity-wrapper">
|
||||||
|
<InputRange
|
||||||
|
label="Opacity"
|
||||||
|
disabled={false}
|
||||||
|
value={currentStyle.opacity}
|
||||||
|
min={0}
|
||||||
|
max={50}
|
||||||
|
onChange={(opacity) => updateStyle({ opacity })}
|
||||||
|
onPointerUp={() => {}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="color-wrapper">
|
||||||
|
<div className="key">Color</div>
|
||||||
|
<div className="value">
|
||||||
|
<input
|
||||||
|
type="color"
|
||||||
|
value={currentStyle.elementColor}
|
||||||
|
onChange={(e) => updateStyle({ elementColor: e.target.value })}
|
||||||
|
/>
|
||||||
|
<span style={{ marginLeft: "10px" }}>
|
||||||
|
{currentStyle.elementColor}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="reviewChart" ref={chartRef}>
|
<div className="element-container">
|
||||||
{selectedChartId?.title ? (
|
<div className="display-element">
|
||||||
<ChartComponent
|
<ChartComponent
|
||||||
type={selectedChartId.type ?? "bar"}
|
type={selectedChartId?.type ?? "bar"}
|
||||||
title={selectedChartId.title}
|
title={selectedChartId?.title ?? "Chart"}
|
||||||
data={selectedChartId.data ?? defaultChartData}
|
data={{
|
||||||
/>
|
labels: selectedChartId?.data?.labels ?? defaultChartData.labels,
|
||||||
) : (
|
datasets: selectedChartId?.data?.datasets?.length
|
||||||
<SimpleCard
|
? selectedChartId.data.datasets
|
||||||
header={selectedChartId?.header ?? ""}
|
: defaultChartData.datasets,
|
||||||
icon={WalletIcon}
|
|
||||||
value={selectedChartId?.value ?? ""}
|
|
||||||
per={selectedChartId?.per ?? ""}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="optionsContainer">
|
|
||||||
<div className="option">
|
|
||||||
<span>Element to Style</span>
|
|
||||||
<RegularDropDown
|
|
||||||
header={selectedElementToStyle ?? "Select Element"}
|
|
||||||
options={
|
|
||||||
elementOptions.length > 0
|
|
||||||
? elementOptions.map((opt) => opt.display)
|
|
||||||
: ["No elements found"]
|
|
||||||
}
|
|
||||||
onSelect={(value) => {
|
|
||||||
const selected = elementOptions.find(
|
|
||||||
(opt) => opt.display === value
|
|
||||||
);
|
|
||||||
setSelectedElementToStyle(selected?.value ?? null);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="option">
|
<div className="name-wrapper">
|
||||||
<span>Name</span>
|
<div className="key">Name</div>
|
||||||
<input
|
<input className="value" type="text" />
|
||||||
type="text"
|
|
||||||
value={nameInput}
|
|
||||||
onChange={handleNameChange}
|
|
||||||
placeholder="Enter name"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedChartId?.title && (
|
<div className="element-wrapper">
|
||||||
<div className="option">
|
<div className="key">Element</div>
|
||||||
<span>Chart Type</span>
|
<div className="value">
|
||||||
<RegularDropDown
|
<RegularDropDown
|
||||||
header={selectedChartId?.type ?? "Select Type"}
|
header={currentStyle.selectedElement}
|
||||||
options={["bar", "line", "pie", "doughnut", "radar", "polarArea"]}
|
options={["Glass", "Fill", "Transparent"]}
|
||||||
onSelect={(value) => {
|
onSelect={(selectedElement) => updateStyle({ selectedElement })}
|
||||||
handleUpdateWidget({ type: value });
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="option">
|
|
||||||
<span>Font Family</span>
|
|
||||||
<RegularDropDown
|
|
||||||
header={selectedChartId?.fontFamily ?? "Select Font"}
|
|
||||||
options={["Arial", "Roboto", "Sans-serif"]}
|
|
||||||
onSelect={(value) => setSelectedFont(value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="option">
|
|
||||||
<span>Size</span>
|
|
||||||
<RegularDropDown
|
|
||||||
header={selectedChartId?.fontSize ?? "Select Size"}
|
|
||||||
options={["12px", "14px", "16px", "18px"]}
|
|
||||||
onSelect={(value) => setSelectedSize(value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="option">
|
|
||||||
<span>Weight</span>
|
|
||||||
<RegularDropDown
|
|
||||||
header={selectedChartId?.fontWeight ?? "Select Weight"}
|
|
||||||
options={["Light", "Regular", "Bold"]}
|
|
||||||
onSelect={(value) => setSelectedWeight(value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="option">
|
|
||||||
<button
|
|
||||||
className="header"
|
|
||||||
onClick={() => setShowColorPicker((prev) => !prev)}
|
|
||||||
>
|
|
||||||
<span>Element Color</span>
|
|
||||||
<div className="icon">▾</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{showColorPicker && (
|
|
||||||
<div className="colorDisplayer">
|
|
||||||
<input
|
|
||||||
type="color"
|
|
||||||
value={elementColor}
|
|
||||||
onChange={(e) => {
|
|
||||||
setElementColor(e.target.value);
|
|
||||||
if (selectedChartId?.data) {
|
|
||||||
handleUpdateWidget({
|
|
||||||
data: {
|
|
||||||
...selectedChartId.data,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
...selectedChartId.data.datasets[0],
|
|
||||||
backgroundColor: e.target.value,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<span style={{ marginLeft: "10px" }}>{elementColor}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,10 +5,14 @@ import { useLogger } from "./LoggerContext";
|
||||||
import { GetLogIcon } from "../../footer/getLogIcons";
|
import { GetLogIcon } from "../../footer/getLogIcons";
|
||||||
|
|
||||||
const LogList: React.FC = () => {
|
const LogList: React.FC = () => {
|
||||||
const { logs, clear, setIsLogListVisible } = useLogger();
|
const {
|
||||||
const [selectedTab, setSelectedTab] = useState<
|
logs,
|
||||||
"all" | "info" | "warning" | "error" | "log" | "success"
|
clear,
|
||||||
>("all");
|
setIsLogListVisible,
|
||||||
|
isLogListVisible,
|
||||||
|
selectedTab,
|
||||||
|
setSelectedTab,
|
||||||
|
} = useLogger();
|
||||||
|
|
||||||
const formatTimestamp = (date: Date) => new Date(date).toLocaleTimeString();
|
const formatTimestamp = (date: Date) => new Date(date).toLocaleTimeString();
|
||||||
|
|
||||||
|
@ -18,18 +22,17 @@ const LogList: React.FC = () => {
|
||||||
: [...logs].filter((log) => log.type === selectedTab).reverse();
|
: [...logs].filter((log) => log.type === selectedTab).reverse();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (logs.length > 0) {
|
if (isLogListVisible && logs.length > 0) {
|
||||||
const lastLog = logs[logs.length - 1];
|
const lastLog = logs[logs.length - 1];
|
||||||
const validTypes = ["all", "info", "warning", "error"];
|
const validTypes = ["all", "info", "warning", "error"];
|
||||||
|
|
||||||
if (validTypes.includes(lastLog.type)) {
|
if (validTypes.includes(lastLog.type)) {
|
||||||
console.log("lastLog.type: ", lastLog.type);
|
|
||||||
setSelectedTab(lastLog.type);
|
setSelectedTab(lastLog.type);
|
||||||
} else {
|
} else {
|
||||||
setSelectedTab("all");
|
setSelectedTab("all");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [logs]);
|
}, [isLogListVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
// LoggerProvider.tsx
|
// LoggerProvider.tsx
|
||||||
import React, { createContext, useContext, useState, useCallback, useMemo, useEffect } from "react";
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
useEffect,
|
||||||
|
} from "react";
|
||||||
import { MathUtils } from "three";
|
import { MathUtils } from "three";
|
||||||
|
|
||||||
export type LogType = "log" | "info" | "warning" | "error" | "success";
|
export type LogType = "log" | "info" | "warning" | "error" | "success";
|
||||||
|
@ -16,6 +23,8 @@ interface LoggerContextValue {
|
||||||
setLogs: React.Dispatch<React.SetStateAction<LogEntry[]>>;
|
setLogs: React.Dispatch<React.SetStateAction<LogEntry[]>>;
|
||||||
isLogListVisible: boolean;
|
isLogListVisible: boolean;
|
||||||
setIsLogListVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsLogListVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
selectedTab: LogType | "all";
|
||||||
|
setSelectedTab: React.Dispatch<React.SetStateAction<LogType | "all">>;
|
||||||
log: (message: string) => void;
|
log: (message: string) => void;
|
||||||
info: (message: string) => void;
|
info: (message: string) => void;
|
||||||
warn: (message: string) => void;
|
warn: (message: string) => void;
|
||||||
|
@ -31,19 +40,17 @@ export const LoggerProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const [logs, setLogs] = useState<LogEntry[]>([]);
|
const [logs, setLogs] = useState<LogEntry[]>([]);
|
||||||
const [isLogListVisible, setIsLogListVisible] = useState<boolean>(false);
|
const [isLogListVisible, setIsLogListVisible] = useState<boolean>(false);
|
||||||
|
const [selectedTab, setSelectedTab] = useState<LogType | "all">("all");
|
||||||
|
|
||||||
const addLog = useCallback(
|
const addLog = useCallback((type: LogType, message: string) => {
|
||||||
(type: LogType, message: string) => {
|
const newLog: LogEntry = {
|
||||||
const newLog: LogEntry = {
|
id: MathUtils.generateUUID(),
|
||||||
id: MathUtils.generateUUID(),
|
type,
|
||||||
type,
|
message,
|
||||||
message,
|
timestamp: new Date(),
|
||||||
timestamp: new Date(),
|
};
|
||||||
};
|
setLogs((prevLogs) => [...prevLogs, newLog]);
|
||||||
setLogs((prevLogs) => [...prevLogs, newLog]);
|
}, []);
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const loggerMethods: LoggerContextValue = useMemo(
|
const loggerMethods: LoggerContextValue = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -51,17 +58,33 @@ export const LoggerProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
setLogs,
|
setLogs,
|
||||||
isLogListVisible,
|
isLogListVisible,
|
||||||
setIsLogListVisible,
|
setIsLogListVisible,
|
||||||
|
selectedTab,
|
||||||
|
setSelectedTab,
|
||||||
log: (message: string) => addLog("log", message),
|
log: (message: string) => addLog("log", message),
|
||||||
info: (message: string) => addLog("info", message),
|
info: (message: string) => addLog("info", message),
|
||||||
warn: (message: string) => addLog("warning", message),
|
warn: (message: string) => addLog("warning", message),
|
||||||
error: (message: string) => addLog("error", message),
|
error: (message: string) => addLog("error", message),
|
||||||
success: (message: string) => addLog("success", message),
|
success: (message: string) => addLog("success", message),
|
||||||
clear: () => setLogs([]),
|
clear: () => {
|
||||||
|
if (selectedTab !== "all") {
|
||||||
|
setLogs((prevLogs) =>
|
||||||
|
prevLogs.filter((log) => log.type !== selectedTab)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setLogs([]);
|
||||||
|
}
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
[logs, setLogs, isLogListVisible, setIsLogListVisible, addLog]
|
[
|
||||||
|
logs,
|
||||||
|
setLogs,
|
||||||
|
isLogListVisible,
|
||||||
|
setIsLogListVisible,
|
||||||
|
selectedTab,
|
||||||
|
setSelectedTab,
|
||||||
|
addLog,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Attach logger globally to window object
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(window as any).echo = {
|
(window as any).echo = {
|
||||||
log: loggerMethods.log,
|
log: loggerMethods.log,
|
||||||
|
|
|
@ -98,8 +98,6 @@ export const DraggableWidget = ({
|
||||||
|
|
||||||
const deleteSelectedChart = async () => {
|
const deleteSelectedChart = async () => {
|
||||||
try {
|
try {
|
||||||
console.log("delete");
|
|
||||||
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
let deleteWidget = {
|
let deleteWidget = {
|
||||||
|
@ -111,7 +109,6 @@ export const DraggableWidget = ({
|
||||||
if (visualizationSocket) {
|
if (visualizationSocket) {
|
||||||
setSelectedChartId(null);
|
setSelectedChartId(null);
|
||||||
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget);
|
visualizationSocket.emit("v2:viz-widget:delete", deleteWidget);
|
||||||
console.log("delete widget", selectedChartId);
|
|
||||||
}
|
}
|
||||||
const updatedWidgets = selectedZone.widgets.filter(
|
const updatedWidgets = selectedZone.widgets.filter(
|
||||||
(w: Widget) => w.id !== widget.id
|
(w: Widget) => w.id !== widget.id
|
||||||
|
@ -313,7 +310,6 @@ export const DraggableWidget = ({
|
||||||
ref={chartWidget}
|
ref={chartWidget}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedChartId(widget);
|
setSelectedChartId(widget);
|
||||||
console.log("click");
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Kebab Icon */}
|
{/* Kebab Icon */}
|
||||||
|
|
|
@ -12,12 +12,11 @@ import {
|
||||||
} from "../../../../../components/icons/3dChartIcons";
|
} from "../../../../../components/icons/3dChartIcons";
|
||||||
|
|
||||||
const TotalCardComponent = ({ object }: any) => {
|
const TotalCardComponent = ({ object }: any) => {
|
||||||
console.log('object: ', object);
|
|
||||||
const [progress, setProgress] = useState<any>(0);
|
const [progress, setProgress] = useState<any>(0);
|
||||||
const [measurements, setmeasurements] = useState<any>({});
|
const [measurements, setmeasurements] = useState<any>({});
|
||||||
const [duration, setDuration] = useState("1h");
|
const [duration, setDuration] = useState("1h");
|
||||||
const [name, setName] = useState(object.header ? object.header : "");
|
const [name, setName] = useState(object.header ? object.header : "");
|
||||||
console.log('name: ', name);
|
|
||||||
const email = localStorage.getItem("email") || "";
|
const email = localStorage.getItem("email") || "";
|
||||||
const organization = email?.split("@")[1]?.split(".")[0];
|
const organization = email?.split("@")[1]?.split(".")[0];
|
||||||
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
const { header, flotingDuration, flotingMeasurements } = useChartStore();
|
||||||
|
|
|
@ -829,22 +829,115 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
padding: 0;
|
|
||||||
font-size: var(--font-weight-regular);
|
font-size: var(--font-weight-regular);
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
.reviewChart {
|
.appearance-container,
|
||||||
width: 100%;
|
.element-container {
|
||||||
|
|
||||||
.floating {
|
background: var(--background-color);
|
||||||
width: 100%;
|
backdrop-filter: blur(20px);
|
||||||
|
border-radius: 15px;
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
padding: 0;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appearance-style {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
|
||||||
|
.regularDropdown-container {
|
||||||
|
.dropdown-options {
|
||||||
|
width: 130%;
|
||||||
|
left: -15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-header {
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-wrapper,
|
||||||
|
.opacity-wrapper,
|
||||||
|
.blurEffect-wrapper,
|
||||||
|
.theme-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.input-range-container {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.input-container {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-wrapper {
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-wrapper {
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
.value {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 34px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.selectedWidget {
|
|
||||||
padding: 6px 12px;
|
|
||||||
border-top: 1px solid var(--border-color);
|
.element-container {
|
||||||
border-bottom: 1px solid var(--border-color);
|
padding: 8px;
|
||||||
|
|
||||||
|
.display-element {
|
||||||
|
width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
background: var(--background-color);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border-radius: 5px;
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-wrapper,
|
||||||
|
.element-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.value {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue