feat: Enhance BlockEditor with data handling and UI improvements
- Added a type switch for selecting between "design" and "data" modes in BlockEditor. - Implemented DataDetailedDropdown component for improved data selection. - Introduced DeviceIcon and ParametersIcon for better visual representation in dropdowns. - Updated styles for BlockEditor and related components to improve layout and usability. - Refactored background color and opacity handling in BlockEditor. - Removed unnecessary loading page and scene components from MainScene.
This commit is contained in:
48
app/package-lock.json
generated
48
app/package-lock.json
generated
@@ -2031,7 +2031,7 @@
|
|||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/trace-mapping": "0.3.9"
|
"@jridgewell/trace-mapping": "0.3.9"
|
||||||
},
|
},
|
||||||
@@ -2043,7 +2043,7 @@
|
|||||||
"version": "0.3.9",
|
"version": "0.3.9",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.0.3",
|
"@jridgewell/resolve-uri": "^3.0.3",
|
||||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||||
@@ -4242,26 +4242,6 @@
|
|||||||
"url": "https://github.com/sponsors/gregberge"
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@testing-library/dom": {
|
|
||||||
"version": "10.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
|
||||||
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.10.4",
|
|
||||||
"@babel/runtime": "^7.12.5",
|
|
||||||
"@types/aria-query": "^5.0.1",
|
|
||||||
"aria-query": "5.3.0",
|
|
||||||
"dom-accessibility-api": "^0.5.9",
|
|
||||||
"lz-string": "^1.5.0",
|
|
||||||
"picocolors": "1.1.1",
|
|
||||||
"pretty-format": "^27.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@testing-library/jest-dom": {
|
"node_modules/@testing-library/jest-dom": {
|
||||||
"version": "5.17.0",
|
"version": "5.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
|
||||||
@@ -4373,25 +4353,25 @@
|
|||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
||||||
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node12": {
|
"node_modules/@tsconfig/node12": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node14": {
|
"node_modules/@tsconfig/node14": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node16": {
|
"node_modules/@tsconfig/node16": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@turf/along": {
|
"node_modules/@turf/along": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
@@ -9233,7 +9213,7 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
@@ -10249,7 +10229,7 @@
|
|||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
}
|
}
|
||||||
@@ -15652,7 +15632,7 @@
|
|||||||
"version": "1.3.6",
|
"version": "1.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/makeerror": {
|
"node_modules/makeerror": {
|
||||||
"version": "1.0.12",
|
"version": "1.0.12",
|
||||||
@@ -21308,7 +21288,7 @@
|
|||||||
"version": "10.9.2",
|
"version": "10.9.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cspotcode/source-map-support": "^0.8.0",
|
"@cspotcode/source-map-support": "^0.8.0",
|
||||||
"@tsconfig/node10": "^1.0.7",
|
"@tsconfig/node10": "^1.0.7",
|
||||||
@@ -21351,7 +21331,7 @@
|
|||||||
"version": "8.3.4",
|
"version": "8.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.11.0"
|
"acorn": "^8.11.0"
|
||||||
},
|
},
|
||||||
@@ -21363,7 +21343,7 @@
|
|||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
@@ -21859,7 +21839,7 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/v8-to-istanbul": {
|
"node_modules/v8-to-istanbul": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
@@ -22952,7 +22932,7 @@
|
|||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { RefObject } from "react";
|
import { useState, type RefObject } from "react";
|
||||||
import { Block } from "../../../../types/exportedTypes";
|
import { Block } from "../../../../types/exportedTypes";
|
||||||
import { getAlphaFromRgba, rgbaToHex } from "../../functions/helpers/colorHandlers";
|
import { getAlphaFromRgba, rgbaToHex } from "../../functions/helpers/colorHandlers";
|
||||||
import { getCurrentBlockStyleValue } from "../../functions/helpers/getCurrentBlockStyleValue";
|
import { getCurrentBlockStyleValue } from "../../functions/helpers/getCurrentBlockStyleValue";
|
||||||
@@ -8,6 +8,9 @@ import { handleBlurAmountChange } from "../../functions/helpers/handleBlurAmount
|
|||||||
import InputRange from "../../../ui/inputs/InputRange";
|
import InputRange from "../../../ui/inputs/InputRange";
|
||||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||||
import { DeleteIcon } from "../../../icons/ContextMenuIcons";
|
import { DeleteIcon } from "../../../icons/ContextMenuIcons";
|
||||||
|
import InputWithDropDown from "../../../ui/inputs/InputWithDropDown";
|
||||||
|
import { AddIcon, DeviceIcon, EyeDroperIcon, ParametersIcon } from "../../../icons/ExportCommonIcons";
|
||||||
|
import DataDetailedDropdown from "../../../ui/inputs/DataDetailedDropdown";
|
||||||
|
|
||||||
interface BlockEditorProps {
|
interface BlockEditorProps {
|
||||||
blockEditorRef: RefObject<HTMLDivElement>;
|
blockEditorRef: RefObject<HTMLDivElement>;
|
||||||
@@ -30,14 +33,35 @@ const BlockEditor: React.FC<BlockEditorProps> = ({
|
|||||||
updateBlockPositionType,
|
updateBlockPositionType,
|
||||||
updateBlockZIndex,
|
updateBlockZIndex,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
|
const [selectType, setSelectType] = useState("data")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={blockEditorRef} className="panel block-editor-panel">
|
<div ref={blockEditorRef} className="panel block-editor-panel">
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<h4>Block Style</h4>
|
<h4>Block Style</h4>
|
||||||
<div className="delete icon">
|
{/* <div className="delete icon">
|
||||||
<DeleteIcon />
|
<DeleteIcon />
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="type-switch">
|
||||||
|
<div
|
||||||
|
className={`type ${selectType === "design" ? "active" : ""}`}
|
||||||
|
onClick={() => setSelectType("design")}>
|
||||||
|
Design
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`type ${selectType === "data" ? "active" : ""}`}
|
||||||
|
onClick={() => setSelectType("data")}>
|
||||||
|
Data
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{selectType === "design" && (
|
||||||
|
<>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="form-label">Position Type: </label>
|
<label className="form-label">Position Type: </label>
|
||||||
<select
|
<select
|
||||||
@@ -251,6 +275,142 @@ const BlockEditor: React.FC<BlockEditorProps> = ({
|
|||||||
className="form-input"
|
className="form-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{selectType === "data" && (
|
||||||
|
<div className="data-details">
|
||||||
|
|
||||||
|
<div className="data-wrapper">
|
||||||
|
<InputWithDropDown
|
||||||
|
label="Title"
|
||||||
|
value={`title`}
|
||||||
|
placeholder={"Label 1"}
|
||||||
|
min={0.1}
|
||||||
|
step={0.1}
|
||||||
|
max={2}
|
||||||
|
onChange={() => { }}
|
||||||
|
/>
|
||||||
|
<div className="data">
|
||||||
|
<DataDetailedDropdown
|
||||||
|
title="Data Source"
|
||||||
|
placeholder="Select assets"
|
||||||
|
sections={[
|
||||||
|
{
|
||||||
|
title: "Global",
|
||||||
|
items: [
|
||||||
|
{ id: "global", label: "Global", icon: <DeviceIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Assets",
|
||||||
|
items: [
|
||||||
|
{ id: "cmm-001", label: "CMM-001", icon: <DeviceIcon /> },
|
||||||
|
{ id: "cnc-1", label: "CNC-Lathe-0001", icon: <DeviceIcon /> },
|
||||||
|
{ id: "cnc-2", label: "CNC-drilling-tapping-3Axis", icon: <DeviceIcon /> },
|
||||||
|
{ id: "cnc-3", label: "CNC_0001", icon: <DeviceIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
value={null}
|
||||||
|
onChange={() => { }}
|
||||||
|
dropDownHeader={"RT-Data"}
|
||||||
|
eyedroper={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="data">
|
||||||
|
<DataDetailedDropdown
|
||||||
|
title="Value"
|
||||||
|
placeholder="Select Value"
|
||||||
|
sections={[
|
||||||
|
{
|
||||||
|
title: "Selected Assets name",
|
||||||
|
items: [
|
||||||
|
{ id: "ambientTemp", label: "ambientTemp", icon: <ParametersIcon /> },
|
||||||
|
{ id: "measurementDeviation", label: "measurementDeviation", icon: <ParametersIcon /> },
|
||||||
|
{ id: "powerConsumption", label: "powerConsumption", icon: <ParametersIcon /> },
|
||||||
|
{ id: "probeX", label: "probePositionX", icon: <ParametersIcon /> },
|
||||||
|
{ id: "probeY", label: "probePositionY", icon: <ParametersIcon /> },
|
||||||
|
{ id: "probeZ", label: "probePositionZ", icon: <ParametersIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
value={null}
|
||||||
|
onChange={() => { }}
|
||||||
|
dropDownHeader={"RT-Data-Value"}
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="data-mapping">
|
||||||
|
<div className="heading">Data Mapping</div>
|
||||||
|
|
||||||
|
<div className="type-switch">
|
||||||
|
<div
|
||||||
|
className={`type active`}
|
||||||
|
onClick={() => setSelectType("design")}
|
||||||
|
>
|
||||||
|
Single Machine
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`type`}
|
||||||
|
onClick={() => setSelectType("data")}
|
||||||
|
>
|
||||||
|
Multiple Machine
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="fields-wrapper">
|
||||||
|
<div className="datas">
|
||||||
|
<div className="datas__label">Data Source</div>
|
||||||
|
<div className="datas__class">
|
||||||
|
<RegularDropDown
|
||||||
|
header={"Select value"}
|
||||||
|
options={["1h", "2h", "12h"]}
|
||||||
|
onSelect={() => { }}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="datas">
|
||||||
|
<div className="datas__label">Input 1</div>
|
||||||
|
<div className="datas__class">
|
||||||
|
<RegularDropDown
|
||||||
|
header={"Select value"}
|
||||||
|
options={["1h", "2h", "12h"]}
|
||||||
|
onSelect={() => { }}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="datas">
|
||||||
|
<div className="datas__label">Input 2</div>
|
||||||
|
<div className="datas__class">
|
||||||
|
<RegularDropDown
|
||||||
|
header={"Select value"}
|
||||||
|
options={["1h", "2h", "12h"]}
|
||||||
|
onSelect={() => { }}
|
||||||
|
search={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="add-field">
|
||||||
|
<div className="icon"><AddIcon /></div>
|
||||||
|
<div className="label">Add Field</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1748,3 +1748,29 @@ export const PerformanceStatsIcon = () => {
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DeviceIcon = () => {
|
||||||
|
return (
|
||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.4 1.125H5.38395C4.97753 1.125 4.64972 1.125 4.38427 1.14668C4.11095 1.16902 3.87088 1.2162 3.64877 1.32937C3.29597 1.50913 3.00913 1.79597 2.82937 2.14877C2.7162 2.37088 2.66902 2.61095 2.64668 2.88427C2.625 3.14972 2.625 3.47753 2.625 3.88395V3.9V8.1V8.11605C2.625 8.52245 2.625 8.8503 2.64668 9.11575C2.66902 9.38905 2.7162 9.6291 2.82937 9.85125C3.00913 10.2041 3.29597 10.4908 3.64877 10.6706C3.87088 10.7838 4.11095 10.831 4.38427 10.8533C4.64972 10.875 4.97753 10.875 5.38395 10.875H5.4H6.6H6.61605C7.0225 10.875 7.3503 10.875 7.61575 10.8533C7.88905 10.831 8.1291 10.7838 8.35125 10.6706C8.70405 10.4908 8.99085 10.2041 9.17065 9.85125C9.2838 9.6291 9.331 9.38905 9.3533 9.11575C9.375 8.8503 9.375 8.5225 9.375 8.11605V8.1V3.9V3.88394C9.375 3.47753 9.375 3.14972 9.3533 2.88427C9.331 2.61095 9.2838 2.37088 9.17065 2.14877C8.99085 1.79597 8.70405 1.50913 8.35125 1.32937C8.1291 1.2162 7.88905 1.16902 7.61575 1.14668C7.3503 1.125 7.0225 1.125 6.61605 1.125H6.6H5.4ZM3.98926 1.99762C4.08802 1.9473 4.2184 1.91274 4.44534 1.89419C4.67666 1.87529 4.97378 1.875 5.4 1.875H6.6C7.02625 1.875 7.32335 1.87529 7.55465 1.89419C7.7816 1.91274 7.912 1.9473 8.01075 1.99762C8.2224 2.10548 8.3945 2.27758 8.5024 2.48926C8.5527 2.58802 8.58725 2.71841 8.6058 2.94534C8.6247 3.17666 8.625 3.47378 8.625 3.9V8.1C8.625 8.52625 8.6247 8.82335 8.6058 9.05465C8.58725 9.2816 8.5527 9.412 8.5024 9.51075C8.3945 9.7224 8.2224 9.8945 8.01075 10.0024C7.912 10.0527 7.7816 10.0872 7.55465 10.1058C7.32335 10.1247 7.02625 10.125 6.6 10.125H5.4C4.97378 10.125 4.67666 10.1247 4.44534 10.1058C4.2184 10.0872 4.08802 10.0527 3.98926 10.0024C3.77758 9.8945 3.60548 9.7224 3.49762 9.51075C3.4473 9.412 3.41274 9.2816 3.39419 9.05465C3.37529 8.82335 3.375 8.52625 3.375 8.1V3.9C3.375 3.47378 3.37529 3.17666 3.39419 2.94534C3.41274 2.71841 3.4473 2.58802 3.49762 2.48926C3.60548 2.27758 3.77758 2.10548 3.98926 1.99762ZM5 8.625C4.7929 8.625 4.625 8.7929 4.625 9C4.625 9.2071 4.7929 9.375 5 9.375H7C7.2071 9.375 7.375 9.2071 7.375 9C7.375 8.7929 7.2071 8.625 7 8.625H5Z" fill="#CCACFF" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ParametersIcon = () => {
|
||||||
|
return (
|
||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_6422_4175)">
|
||||||
|
<path d="M10.5 4.875V3C10.4998 2.80116 10.4207 2.61052 10.2801 2.46992C10.1395 2.32932 9.94884 2.25023 9.75 2.25H8.625V3H9.75V4.875C9.75072 5.08872 9.79738 5.29978 9.88681 5.49388C9.97625 5.68799 10.1064 5.86059 10.2684 6C10.1064 6.13941 9.97625 6.31201 9.88681 6.50612C9.79738 6.70022 9.75072 6.91128 9.75 7.125V9H8.625V9.75H9.75C9.94884 9.74977 10.1395 9.67068 10.2801 9.53008C10.4207 9.38948 10.4998 9.19884 10.5 9V7.125C10.5002 6.92616 10.5793 6.73552 10.7199 6.59492C10.8605 6.45432 11.0512 6.37523 11.25 6.375V5.625C11.0512 5.62477 10.8605 5.54568 10.7199 5.40508C10.5793 5.26447 10.5002 5.07384 10.5 4.875Z" fill="#B7B7C6" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.375 3.375L6.05362 4.5H6.80362L7.125 3.375H7.875L7.55362 4.5H8.25V5.25H7.3395L6.91088 6.75H7.875V7.5H6.69638L6.375 8.625H5.625L5.94638 7.5H5.19638L4.875 8.625H4.125L4.44638 7.5H3.75V6.75H4.66087L5.0895 5.25H4.125V4.5H5.30362L5.625 3.375H6.375ZM6.5895 5.25H5.8395L5.41087 6.75H6.16088L6.5895 5.25Z" fill="#B7B7C6" />
|
||||||
|
<path d="M2.25 4.875V3H3.375V2.25H2.25C2.05116 2.25023 1.86052 2.32932 1.71992 2.46992C1.57932 2.61052 1.50023 2.80116 1.5 3V4.875C1.49977 5.07384 1.42068 5.26447 1.28008 5.40508C1.13948 5.54568 0.948842 5.62477 0.75 5.625V6.375C0.948842 6.37523 1.13948 6.45432 1.28008 6.59492C1.42068 6.73552 1.49977 6.92616 1.5 7.125V9C1.50023 9.19884 1.57932 9.38948 1.71992 9.53008C1.86052 9.67068 2.05116 9.74977 2.25 9.75H3.375V9H2.25V7.125C2.24928 6.91128 2.20262 6.70022 2.11319 6.50612C2.02375 6.31201 1.89363 6.13941 1.73164 6C1.89363 5.86059 2.02375 5.68799 2.11319 5.49388C2.20262 5.29978 2.24928 5.08872 2.25 4.875Z" fill="#B7B7C6" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_6422_4175">
|
||||||
|
<rect width="12" height="12" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ function MainScene() {
|
|||||||
{!selectedUser && (
|
{!selectedUser && (
|
||||||
<>
|
<>
|
||||||
<KeyPressListener />
|
<KeyPressListener />
|
||||||
{!createNewWindow && loadingProgress > 0 && <LoadingPage progress={loadingProgress} />}
|
{/* {!createNewWindow && loadingProgress > 0 && <LoadingPage progress={loadingProgress} />} */}
|
||||||
{!isPlaying && (
|
{!isPlaying && (
|
||||||
<>
|
<>
|
||||||
{!toggleView && !isComparing && <ModuleToggle />}
|
{!toggleView && !isComparing && <ModuleToggle />}
|
||||||
@@ -254,7 +254,7 @@ function MainScene() {
|
|||||||
}
|
}
|
||||||
onDragOver={(event) => event.preventDefault()}
|
onDragOver={(event) => event.preventDefault()}
|
||||||
>
|
>
|
||||||
<Scene layout="Main Layout" />
|
{/* <Scene layout="Main Layout" /> */}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
110
app/src/components/ui/inputs/DataDetailedDropdown.tsx
Normal file
110
app/src/components/ui/inputs/DataDetailedDropdown.tsx
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import React, { useState, useMemo } from "react";
|
||||||
|
import { EyeDroperIcon, SearchIcon } from "../../icons/ExportCommonIcons";
|
||||||
|
|
||||||
|
export type DropdownItem = {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
icon?: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DataDetailedDropdownProps = {
|
||||||
|
title: string;
|
||||||
|
placeholder?: string;
|
||||||
|
sections: {
|
||||||
|
title?: string;
|
||||||
|
items: DropdownItem[];
|
||||||
|
}[];
|
||||||
|
value?: DropdownItem | null;
|
||||||
|
onChange?: (item: DropdownItem) => void;
|
||||||
|
dropDownHeader?: string;
|
||||||
|
eyedroper?: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
const DataDetailedDropdown: React.FC<DataDetailedDropdownProps> = ({
|
||||||
|
title,
|
||||||
|
placeholder = "Select value",
|
||||||
|
sections,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
dropDownHeader,
|
||||||
|
eyedroper
|
||||||
|
}) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
|
const filteredSections = useMemo(() => {
|
||||||
|
if (!search) return sections;
|
||||||
|
|
||||||
|
return sections
|
||||||
|
.map((section) => ({
|
||||||
|
...section,
|
||||||
|
items: section.items.filter((item) =>
|
||||||
|
item.label.toLowerCase().includes(search.toLowerCase())
|
||||||
|
),
|
||||||
|
}))
|
||||||
|
.filter((section) => section.items.length > 0);
|
||||||
|
}, [search, sections]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="data-detailed-dropdown">
|
||||||
|
<div className="title">{title}</div>
|
||||||
|
<div className="input-container">
|
||||||
|
<div className="input-wrapper">
|
||||||
|
<div
|
||||||
|
className="input"
|
||||||
|
onClick={() => setOpen((v) => !v)}
|
||||||
|
>
|
||||||
|
{value?.label || placeholder}
|
||||||
|
<div className="icon">▾</div>
|
||||||
|
</div>
|
||||||
|
{open && (
|
||||||
|
<div className="dropdown-panel">
|
||||||
|
<div className="heading">{dropDownHeader}</div>
|
||||||
|
<div className="search">
|
||||||
|
<div className="icon">
|
||||||
|
<SearchIcon />
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
placeholder="Search Assets"
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{filteredSections.map((section, index) => (
|
||||||
|
<div key={index} className="data-section">
|
||||||
|
{section.title && (
|
||||||
|
<div className="data-header">
|
||||||
|
<div className="data-section-title">{section.title}</div>
|
||||||
|
<div className="data-section-count">
|
||||||
|
{section.items.length}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{section.items.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className="item"
|
||||||
|
onClick={() => {
|
||||||
|
onChange?.(item);
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.icon && <span className="icon">{item.icon}</span>}
|
||||||
|
<span>{item.label}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{eyedroper && <div className="icon"><EyeDroperIcon isActive={false} /></div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataDetailedDropdown;
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
* > {
|
*> {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0 0 10px 0;
|
// margin: 0 0 10px 0;
|
||||||
border-bottom: 1px solid gray;
|
border-bottom: 1px solid gray;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
|
||||||
@@ -312,12 +312,121 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.block-editor-panel {
|
&.block-editor-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 11px;
|
||||||
min-width: 280px;
|
min-width: 280px;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 70vh;
|
||||||
|
padding: 20px 8px;
|
||||||
// h4 {
|
// h4 {
|
||||||
// color: #4caf50;
|
// color: #4caf50;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
.type-switch {
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
|
||||||
|
.type {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px 0;
|
||||||
|
border-radius: 19px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: var(--background-color-button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.data-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
|
||||||
|
.value-field-container {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.label,
|
||||||
|
.input.default {
|
||||||
|
width: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.data {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 9px;
|
||||||
|
|
||||||
|
.datas_label,
|
||||||
|
.regularDropdown-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-mapping {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 9px;
|
||||||
|
background: var(--background-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
box-shadow: var(--box-shadow-medium);
|
||||||
|
padding: 15px 12px;
|
||||||
|
border-radius: 25px;
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type-switch {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fields-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
.datas {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
padding: 6px 12px;
|
||||||
|
|
||||||
|
.datas__label,
|
||||||
|
.datas__class {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-field {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
stroke: #CCACFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #CCACFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.element-editor-panel {
|
&.element-editor-panel {
|
||||||
@@ -534,3 +643,133 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// DataDetailedDropdown
|
||||||
|
.data-detailed-dropdown {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.title,
|
||||||
|
.input-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
.input-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-wrapper {
|
||||||
|
|
||||||
|
outline: 1px solid var(--input-border-color);
|
||||||
|
outline-offset: -1px;
|
||||||
|
border: none;
|
||||||
|
background: var(--background-color-input);
|
||||||
|
color: var(--input-text-color);
|
||||||
|
|
||||||
|
border-radius: 100px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
min-width: 200px;
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
outline-offset: -1px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
background: var(--background-color);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.search {
|
||||||
|
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
outline-offset: -1px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--background-color);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 4px 9px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
height: 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
padding-left: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-section {
|
||||||
|
.data-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.data-section-count{
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
padding: 8px 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
span {
|
||||||
|
color: #CCACFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user