diff --git a/src/lib/GlobalCssProperties.json b/src/lib/GlobalCssProperties.json index 9f5b3a2f..700a2414 100644 --- a/src/lib/GlobalCssProperties.json +++ b/src/lib/GlobalCssProperties.json @@ -95,7 +95,7 @@ 0.39901960784, 0.43823529411 ], - "--engine-ui-underline-color": ["display-p3", 1, 1, 1], + "--engine-ui-underline-color": ["display-p3", 0, 0, 0], "--engine-ui-error-underline-color": [ "display-p3", 0.82745098039, @@ -104,15 +104,21 @@ ], "--engine-ui-input-text-placeholder-color": [ "display-p3", - 0.8, - 0.8, - 0.8 + 0.5, + 0.5, + 0.5 ], "--engine-ui-scrollbar-thumb-background-color": [ "display-p3", - 0.5608, - 0.498, - 0.4353 + 0.3, + 0.3, + 0.3 + ], + "--engine-ui-scrollbar-thumb-hover-background-color": [ + "display-p3", + 0.1, + 0.1, + 0.1 ], "--engine-ui-scrollbar-thumb-color": [ "display-p3", @@ -120,14 +126,9 @@ 0.6941, 0.6706 ], - "--engine-ui-text-color": ["display-p3", 1, 1, 1], - "--engine-ui-background-color": [ - "display-p3", - 0.2862745098, - 0.34901960784, - 0.38823529411 - ], - "--engine-ui-button-color": [ + "--engine-ui-text-color": ["display-p3", 0, 0, 0], + "--engine-ui-background-color": ["display-p3", 0.95, 0.95, 0.95], + "--engine-ui-checkbox-color": [ "display-p3", 0.2862745098, 0.34901960784, @@ -136,7 +137,13 @@ "--settings-danger-button-color": ["srgb", 0.498, 0.0902, 0.0549], "--settings-safe-button-color": ["srgb", 0.3255, 0.498, 0.2667], "--dropdown-button-color": ["srgb", 1, 1, 1], - "--dropdown-text-color": ["srgb", 0, 0, 0] + "--dropdown-text-color": ["srgb", 0, 0, 0], + "--modal-background-color": [ + "display-p3", + 0.22745098039, + 0.27450980392, + 0.30588235294 + ] }, "fontSize": { "--sidebar-fontsize": [1, "rem"], @@ -256,9 +263,9 @@ ], "--engine-ui-input-text-placeholder-color": [ "display-p3", - 0.7333, - 0.7333, - 0.7333 + 0.5, + 0.5, + 0.5 ], "--engine-ui-scrollbar-thumb-background-color": [ "display-p3", @@ -266,6 +273,12 @@ 0.95, 0.95 ], + "--engine-ui-scrollbar-thumb-hover-background-color": [ + "display-p3", + 0.6, + 0.6, + 0.6 + ], "--engine-ui-scrollbar-thumb-color": ["display-p3", 0, 0, 0], "--engine-ui-background-color": [ "display-p3", @@ -273,13 +286,19 @@ 0.09666666666, 0.12019607843 ], - "--engine-ui-button-color": [ + "--engine-ui-checkbox-color": [ "display-p3", 0.08490196078, 0.09666666666, 0.12019607843 ], - "--engine-ui-text-color": ["display-p3", 1, 1, 1] + "--engine-ui-text-color": ["display-p3", 1, 1, 1], + "--modal-background-color": [ + "display-p3", + 0.0156862745, + 0.02352941176, + 0.03529411764 + ] } }, { diff --git a/src/lib/classes/engine/Engine.ts b/src/lib/classes/engine/Engine.ts new file mode 100644 index 00000000..c0328d8f --- /dev/null +++ b/src/lib/classes/engine/Engine.ts @@ -0,0 +1,113 @@ +import { + comparePortRange, + validateEndPort, + validateIP, + validateName, + validateStartPort, +} from "./Validation"; + +/** + * A Reveaal, JEcdar andd API engine definition + * It stores the IP and port of an engine + * */ +export class Engine { + /** + * The #name of the Engine + * */ + #name: string = ""; + get name(): string { + return this.#name; + } + set name(setName: string) { + if (validateName(setName)) this.#name = setName; + else throw new Error("Engine must have a name"); + } + /** + * The IP #address of the engine + * */ + #address: string = ""; + get address(): string { + return this.#address; + } + set address(ipAdress: string) { + if (validateIP(ipAdress)) this.#address = ipAdress; + else throw new Error(ipAdress + " Is an invalid IP address"); + } + /** + * The starting number of the portrange + * */ + #portRangeStart: number = 0; + get portRangeStart(): number { + return this.#portRangeStart; + } + set portRangeStart(portStart: number) { + if (validateStartPort(portStart)) this.#portRangeStart = portStart; + else throw new Error("Invalid start port"); + } + + /** + * The last number of the portrange + * */ + #portRangeEnd: number = 0; + get portRangeEnd(): number { + return this.#portRangeEnd; + } + set portRangeEnd(portEnd: number) { + if ( + comparePortRange(this.#portRangeStart, portEnd) && + validateEndPort(portEnd) + ) + this.#portRangeEnd = portEnd; + else throw new Error("Invalid end port"); + } + + /** + * Unique identifier + * */ + #id: number = 0; + get id(): number { + return this.#id; + } + set id(inputId: number) { + if (inputId >= 0) this.#id = inputId; + else throw new Error("Invalid id"); + } + + hasBeenChanged: boolean = false; + + #useBundle: boolean = false; + get useBundle(): boolean { + return this.#useBundle; + } + set useBundle(useBundle: boolean) { + this.#useBundle = useBundle; + if (useBundle) this.address = "127.0.0.1"; + } + + constructor( + name: string, + address: string, + portRangeStart: number, + portRangeEnd: number, + id: number, + useBundle: boolean, + ) { + this.name = name; + if (!useBundle) this.address = address; + this.portRangeStart = portRangeStart; + this.portRangeEnd = portRangeEnd; + this.id = id; + this.#useBundle = useBundle; + } + + toJSON() { + return { + name: this.#name, + address: this.#address, + portRangeStart: this.#portRangeStart, + portRangeEnd: this.#portRangeEnd, + id: this.#id, + useBundle: this.#useBundle, + }; + } +} diff --git a/src/lib/classes/engine/EngineStorage.ts b/src/lib/classes/engine/EngineStorage.ts new file mode 100644 index 00000000..c5dc2d99 --- /dev/null +++ b/src/lib/classes/engine/EngineStorage.ts @@ -0,0 +1,163 @@ +import type IEngineStorageObject from "$lib/interfaces/IEngineStorageObject"; +import { Engine } from "./Engine"; +/** + * Engine storage definition. + * Stores an array of Engine instances, and can create, delete or search the array + * */ +class EngineStorage { + /** + * Array of engines defined + * */ + engineArray: Array = []; + + /** + * variable used to give unique id to engines + * */ + #engineId: number = 0; + + get engineId(): number { + this.engineId = ++this.#engineId; //auto inc + return this.#engineId; + } + set engineId(id: number) { + if (id >= 0) this.#engineId = id; + else throw new Error("Invalid engineId"); + } + + /** + * Array of engines defined + * */ + #defaultEngine: Engine | undefined; + get defaultEngine(): Engine | undefined { + return this.#defaultEngine; + } + set defaultEngine(engine: Engine | undefined) { + let index = -1; + + index = this.engineArray.findIndex( + (arrayEngine: Engine | undefined) => { + return arrayEngine?.id === engine?.id; + }, + ); + if (engine === undefined || index > -1) this.#defaultEngine = engine; + else throw new Error("Failed to set default engine"); + } + + constructor() { + this.engineArray = new Array(); + this.engineId = 0; + this.defaultEngine = undefined; + } + + /** + * Create an Engine and pushes it to engineArray + */ + createEngine( + name: string, + address: string, + portRangeStart: number, + portRangeEnd: number, + useBundle: boolean, + ) { + const newEngine = new Engine( + name, + address, + portRangeStart, + portRangeEnd, + this.engineId, + useBundle, + ); + this.engineArray[this.engineId - 1] = newEngine; + + return newEngine; + } + + /** + * Deletes the engine with the given id + */ + deleteEngine(id: number) { + //check for results + if (this.engineArray[id]) { + //Check if the default engine is being removed + if (this.defaultEngine?.id === id) this.defaultEngine = undefined; + + this.engineArray[id] = undefined; + } else { + throw new Error("Engine Id does not exist"); + } + } + /** + * Get engines based on id or name + */ + getEngine(identifier: number | string): Engine { + let returnEngine: undefined | Engine; + + //Find engine based on id + if (typeof identifier === "number") { + returnEngine = this.engineArray[identifier]; + } + //Find engine based on name + else { + returnEngine = this.engineArray.find( + (engine: Engine | undefined) => { + return engine?.name === identifier; + }, + ); + } + if (returnEngine !== undefined) return returnEngine; + else throw new Error("Could not find engine"); + } + + /** + * Returns all engines in the store in the form of an array + */ + getEngineArray(): Array { + const filtered: Engine[] = this.engineArray.filter( + (element) => element !== undefined, + ) as Engine[]; + return filtered; + } + + /** + * Coonvert the EngineStorage to a JSON string + */ + serialize(): string { + return JSON.stringify(this); + } + + toJSON() { + return { + engineArray: this.engineArray, + engineId: this.#engineId, + defaultEngine: this.defaultEngine, + }; + } + + /** + * Reads fields and engines from JSON string, and applies them in the store + */ + deSerialize(json: string) { + const parsedJSON: IEngineStorageObject = JSON.parse( + json, + ) as IEngineStorageObject; + this.engineArray = []; + this.engineId = parsedJSON.engineId; + this.defaultEngine = parsedJSON.defaultEngine; + + //run Engine constructer to validate input. + parsedJSON.engineArray.forEach((engine) => { + this.engineArray.push( + new Engine( + engine.name, + engine.address, + engine.portRangeStart, + engine.portRangeEnd, + engine.id, + engine.useBundle, + ), + ); + }); + } +} +const engineStorage = new EngineStorage(); +export default engineStorage; diff --git a/src/lib/classes/engine/Validation.ts b/src/lib/classes/engine/Validation.ts new file mode 100644 index 00000000..96ce6bbe --- /dev/null +++ b/src/lib/classes/engine/Validation.ts @@ -0,0 +1,24 @@ +export function validateName(name: string | undefined): boolean { + if (name != "" && name !== undefined) return true; + return false; +} + +// const regexTest: RegExp = new RegExp( +// "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", // Will test for any valid IP address +// ); + +export function validateIP(ipAddress: string): boolean { + return URL.canParse("https://" + ipAddress) || URL.canParse(ipAddress); //regexTest.test(ipAdress); +} + +export function validateStartPort(port: number): boolean { + return 0 <= port && port <= 65353; +} + +export function validateEndPort(port: number): boolean { + return 0 <= port && port <= 65353; +} + +export function comparePortRange(start: number, end: number): boolean { + return start <= end; +} diff --git a/src/lib/classes/styling/ZodSchemas/CSSVariables.ts b/src/lib/classes/styling/ZodSchemas/CSSVariables.ts index 6d1a4ebc..26dac905 100644 --- a/src/lib/classes/styling/ZodSchemas/CSSVariables.ts +++ b/src/lib/classes/styling/ZodSchemas/CSSVariables.ts @@ -38,14 +38,16 @@ export const ColorVariables = z "--engine-ui-error-underline-color": ColorAttribute, "--engine-ui-input-text-placeholder-color": ColorAttribute, "--engine-ui-scrollbar-thumb-background-color": ColorAttribute, + "--engine-ui-scrollbar-thumb-hover-background-color": ColorAttribute, "--engine-ui-scrollbar-thumb-color": ColorAttribute, "--engine-ui-text-color": ColorAttribute, "--engine-ui-background-color": ColorAttribute, - "--engine-ui-button-color": ColorAttribute, + "--engine-ui-checkbox-color": ColorAttribute, "--settings-danger-button-color": ColorAttribute, "--settings-safe-button-color": ColorAttribute, "--dropdown-button-color": ColorAttribute, "--dropdown-text-color": ColorAttribute, + "--modal-background-color": ColorAttribute, }) .strict(); diff --git a/src/lib/components/engineUI/EngineDTO.ts b/src/lib/components/engineUI/EngineDTO.ts new file mode 100644 index 00000000..323de139 --- /dev/null +++ b/src/lib/components/engineUI/EngineDTO.ts @@ -0,0 +1,6 @@ +import type { Engine } from "$lib/classes/engine/Engine"; + +/** + * A data transfer object for the Engine class + */ +export type EngineDTO = Omit, "toJSON">; diff --git a/src/lib/components/engineUI/EnginePanel.svelte b/src/lib/components/engineUI/EnginePanel.svelte new file mode 100644 index 00000000..c8315277 --- /dev/null +++ b/src/lib/components/engineUI/EnginePanel.svelte @@ -0,0 +1,62 @@ + + +

Engines

+
+ {#each $tempEngines as engine, index} + {#if engine.address != "-1"} + + {/if} + {/each} +
+ + diff --git a/src/lib/components/engineUI/EngineSeperate.svelte b/src/lib/components/engineUI/EngineSeperate.svelte new file mode 100644 index 00000000..4724e3cc --- /dev/null +++ b/src/lib/components/engineUI/EngineSeperate.svelte @@ -0,0 +1,423 @@ + + + +
+
+

+ {#if currentEngine.name !== ""} + Are you sure you wish to delete the engine: + {currentEngine.name} + {:else} + Are you sure you wish to delete this engine? + {/if} +

+
+ + { + showDeleteDialog = false; + }} + size={24} + id="delete-button" + color={"var(--engine-ui-text-color)"} + /> +
+
+
+
+ +
+

Name:

+
+ +
+
+ { + showDeleteDialog = true; + }} + color={"var(--engine-ui-text-color)"} + /> +
+

IP Address:

+
+ +
+
+ +
+

Port range:

+
+ +

-

+ +
+
+ + diff --git a/src/lib/components/engineUI/EngineUI.svelte b/src/lib/components/engineUI/EngineUI.svelte new file mode 100644 index 00000000..39254bf1 --- /dev/null +++ b/src/lib/components/engineUI/EngineUI.svelte @@ -0,0 +1,296 @@ + + + +
+
+ +
+
+ + + +
+
+
+ + + + + + + + + + diff --git a/src/lib/components/engineUI/showEngineUI.ts b/src/lib/components/engineUI/showEngineUI.ts new file mode 100644 index 00000000..6f5eafc8 --- /dev/null +++ b/src/lib/components/engineUI/showEngineUI.ts @@ -0,0 +1,3 @@ +import { writable } from "svelte/store"; + +export const showEngineUI = writable(false); diff --git a/src/lib/components/modal/Modal.svelte b/src/lib/components/modal/Modal.svelte index c17c7b1d..50eb5caa 100644 --- a/src/lib/components/modal/Modal.svelte +++ b/src/lib/components/modal/Modal.svelte @@ -59,6 +59,7 @@ dialog { color: var(--text-color); background-color: var(--background-color); + overflow-y: hidden; } dialog::backdrop { background-color: var(--modal-background-color); diff --git a/src/lib/components/overlayMenu/elements/Button.svelte b/src/lib/components/overlayMenu/elements/Button.svelte index 9f12e148..c89e47b3 100644 --- a/src/lib/components/overlayMenu/elements/Button.svelte +++ b/src/lib/components/overlayMenu/elements/Button.svelte @@ -9,12 +9,12 @@ export let backgroundColor: string = "var(--dropdown-button-color)"; - export let buttonColor: string = "var(--dropdown-text-color))"; + export let checkBoxColor: string = "var(--dropdown-text-color))";