diff --git a/UnicadoGUI/Frontend/src/lib/components/TabComponent.svelte b/UnicadoGUI/Frontend/src/lib/components/TabComponent.svelte new file mode 100644 index 0000000000000000000000000000000000000000..6d5b8d95596314295df4dcefd37eb5b042cfad64 --- /dev/null +++ b/UnicadoGUI/Frontend/src/lib/components/TabComponent.svelte @@ -0,0 +1,221 @@ +<script lang="ts"> + import { Input, Styles, Tooltip } from "@sveltestrap/sveltestrap"; + import { onMount } from "svelte"; + import { + SettingsSwitch, + SettingsSelector, + SettingsTextfield, + SettingsNumberfield, + SettingsLabel, + } from "$lib/settings/SettingsUi"; + import { + isNumber, + calcStepSize, + formatLabel, + } from "$lib/utilities/utilities"; + + export let data; + + type dictionary = { + [key: string]: any; + }; + + let modalModule: dictionary = { + name: "", + response: {}, + html: [], + }; + + onMount(async () => { + console.log(data); + generateHTML(data); + modalModule.html = [...modalModule.html]; + }); + + function generateHTML(json: dictionary) { + Object.entries(json).forEach(([key, value]) => { + if (value == null) { + return; + } + if (value.hasOwnProperty("value")) { + if ( + value["@description"] && + value["@description"].toLowerCase().includes("switch") + ) { + value.value = value.value === "true" || value.value === "1"; //transform string input to boolean for easier binding + modalModule.html.push( + new SettingsSwitch(key, value["@description"], value), + ); + } else if ( + value["@description"] && + value["@description"].toLowerCase().includes("selector") + ) { + let options = []; + for (let i = 0; i < 5; i++) { + if (value["@description"].includes("mode_" + i)) { + options.push("mode_" + i); + } + } + modalModule.html.push( + new SettingsSelector( + key, + value["@description"], + value, + options, + ), + ); + } else if (isNumber(value.value)) { + value.value = parseFloat(value.value); + let numberField = new SettingsNumberfield( + key, + value["@description"], + value, + ); + if ( + value.hasOwnProperty("lower_boundary") && + isNumber(value["lower_boundary"]) + ) { + numberField.setMin(value["lower_boundary"]); + } + if ( + value.hasOwnProperty("upper_boundary") && + isNumber(value["upper_boundary"]) + ) { + numberField.setMax(value["upper_boundary"]); + } + if (value.hasOwnProperty("@unit")) { + numberField.setUnit(value["@unit"]); + } //spaeter entweder unit oder Unit in XML + if (value.hasOwnProperty("@Unit")) { + numberField.setUnit(value["@Unit"]); + } + if (value.hasOwnProperty("unit")) { + numberField.setUnit(value["unit"]); + } + if (value.hasOwnProperty("Unit")) { + numberField.setUnit(value["Unit"]); + } + modalModule.html.push(numberField); + } else { + modalModule.html.push( + new SettingsTextfield( + key, + value["@description"], + value, + key, + ), + ); + } + } else if (typeof value === "object") { + modalModule.html.push(new SettingsLabel(key)); + generateHTML(json[key]); + } else { + return; + } + }); + } + + let modalChanged: boolean = false; + function checkModalChanged() { + modalChanged = true; + modalChanged = modalChanged; + } + + function validateNumber(index: number) { + console.log("validateNumber"); + if (modalModule.html[index].bind.value < modalModule.html[index].min) { + modalModule.html[index].bind.value = modalModule.html[index].min; + } else if ( + modalModule.html[index].bind.value > modalModule.html[index].max + ) { + modalModule.html[index].bind.value = modalModule.html[index].max; + } + } +</script> + +{#each modalModule.html as element, index} + {#if element.type == "switch"} + <Input + id="uiElement{index}" + type="switch" + label={formatLabel(element.label)} + bind:checked={element.bind.value} + on:change={() => checkModalChanged()} + /> + <Tooltip target="uiElement{index}" placement="left"> + {element.description} + </Tooltip> + {:else if element.type == "label"} + <h3>{formatLabel(element.label)}</h3> + {:else if element.type == "selector"} + <h6>{formatLabel(element.label)}</h6> + <Input + id="uiElement{index}" + type="select" + bind:value={element.bind.value} + on:change={() => checkModalChanged()} + > + {#each element.options as option} + <option>{option}</option> + {/each} + </Input> + <Tooltip target="uiElement{index}" placement="left"> + {element.description} + </Tooltip> + {:else if element.type == "textfield"} + <h7>{formatLabel(element.label)}</h7> + <Input + id="uiElement{index}" + type="text" + bind:value={element.bind.value} + on:change={() => checkModalChanged()} + /> + <Tooltip target="uiElement{index}" placement="left"> + {element.description} + </Tooltip> + {:else if element.type == "numberfield"} + {#if element.unit != "1" && element.unit != "-" && element.unit != "count"} + <h7>{formatLabel(element.label)} (in {element.unit})</h7> + {:else} + <h7>{formatLabel(element.label)}</h7> + {/if} + {#if element.max != Number.POSITIVE_INFINITY && element.min != Number.NEGATIVE_INFINITY} + <Input + type="range" + min={element.min} + max={element.max} + step="0.01" + bind:value={element.bind.value} + placeholder="range placeholder" + on:change={() => checkModalChanged()} + /> + <Input + id="uiElement{index}" + type="number" + min={element.min} + max={element.max} + step="0.01" + bind:value={element.bind.value} + on:change={() => checkModalChanged()} + on:blur={() => validateNumber(index)} + /> + {:else} + <Input + id="uiElement{index}" + type="number" + min={element.min} + max={element.max} + step={calcStepSize(element.bind.value)} + bind:value={element.bind.value} + on:change={() => checkModalChanged()} + on:blur={() => validateNumber(index)} + /> + {/if} + + <Tooltip target="uiElement{index}" placement="left"> + {element.description} + </Tooltip> + {/if} +{/each} + +<Styles /> diff --git a/UnicadoGUI/Frontend/src/lib/settings/SettingsUi.ts b/UnicadoGUI/Frontend/src/lib/settings/SettingsUi.ts new file mode 100644 index 0000000000000000000000000000000000000000..e2d87279780ef9bb8c7d2991c3974b62f3950fe3 --- /dev/null +++ b/UnicadoGUI/Frontend/src/lib/settings/SettingsUi.ts @@ -0,0 +1,94 @@ +//Interface for Ui-elements in module settings and it's implementations +export interface SettingsUi { + type: string; + label: string; + description: string; + bind: string; +} + +export class SettingsSwitch implements SettingsUi { + readonly type = "switch"; + label: string; + description: string; + bind: string; + + constructor(label: string, description: string, bind: string) { + this.bind = bind; + this.label = label; + this.description = description; + } +} + +export class SettingsSelector implements SettingsUi { + readonly type = "selector"; + label: string; + description: string; + bind: string; + options: string[]; + + constructor( + label: string, + description: string, + bind: string, + options: string[], + ) { + this.bind = bind; + this.label = label; + this.description = description; + this.options = options; + } +} + +export class SettingsTextfield implements SettingsUi { + readonly type = "textfield"; + label: string; + description: string; + bind: string; + input: string; + + constructor( + label: string, + description: string, + bind: string, + input: string, + ) { + this.bind = bind; + this.label = label; + this.description = description; + this.input = input; + } +} + +export class SettingsNumberfield implements SettingsUi { + readonly type = "numberfield"; + label: string; + description: string; + bind: string; + unit: string = "-"; + max: number = Number.POSITIVE_INFINITY; + min: number = Number.NEGATIVE_INFINITY; + + constructor(label: string, description: string, bind: string) { + this.bind = bind; + this.label = label; + this.description = description; + } + setMax(max: number) { + this.max = max; + } + setMin(min: number) { + this.min = min; + } + setUnit(unit: string) { + this.unit = unit; + } +} + +export class SettingsLabel { + readonly type = "label"; + label: string; + + constructor(label: string) { + this.label = label; + } +} diff --git a/UnicadoGUI/Frontend/src/lib/utilities/utilities.ts b/UnicadoGUI/Frontend/src/lib/utilities/utilities.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba33364b778c88b35f60ce831b4100de61695c88 --- /dev/null +++ b/UnicadoGUI/Frontend/src/lib/utilities/utilities.ts @@ -0,0 +1,19 @@ +export function isNumber(n: string) { + return !isNaN(parseFloat(n)) && isFinite(parseFloat(n)); +} + + +//Calculate Stepsize of number inputs from current value +export function calcStepSize(value: number) { + const numberString = value.toString(); + if (!numberString.includes(".")) { + return 1; + } else { + const decimalPart = numberString.split(".")[1]; + return Math.pow(10, -decimalPart.length); + } +} +//Replacing underscores to space +export function formatLabel(label: string) { + return label.replaceAll("_", " "); +} \ No newline at end of file diff --git a/UnicadoGUI/Frontend/src/routes/settings/+page.svelte b/UnicadoGUI/Frontend/src/routes/settings/+page.svelte index a2cf8d48047ac3c79ab13bfc2038159e3783b186..084adf5af1f5f9a2119d4c8be5b826255841263b 100644 --- a/UnicadoGUI/Frontend/src/routes/settings/+page.svelte +++ b/UnicadoGUI/Frontend/src/routes/settings/+page.svelte @@ -1,592 +1,44 @@ <script lang="ts"> - //Testpage to show possible look of a settingspage + import { Styles } from "@sveltestrap/sveltestrap"; + import { onMount } from "svelte"; + import { settingData, loadTabData } from "../../stores/settings"; + import TabComponent from "$lib/components/TabComponent.svelte"; - import { - Button, - ButtonGroup, - Form, - FormGroup, - Icon, - Input, - Styles, - TabContent, - TabPane, - Tooltip - } from "@sveltestrap/sveltestrap"; - import {onMount} from "svelte"; - let changed = false; - - class EnergyCarrier{ - constructor(value : string, id :number) { - this.value = value; - this.id = id; - } - } - class Propulsor{ - constructor(powertrain : string,type : string,position : string ,energycarrier: EnergyCarrier[],thrust_share: string) { - this.powertrain = powertrain; - this.type = type; - this.position = position; - this.energycarrier = energycarrier; - this.thrust_share = thrust_share; - } - } - //Energy Carriers - let kerosin = new EnergyCarrier("kerosin",1); - let liquid_hydrogen = new EnergyCarrier("liquid_hydrogen",2); - let battery = new EnergyCarrier("battery",3); - let saf = new EnergyCarrier("saf",4); - - - let propulsors : Propulsor[]= []; - let energycarriers : EnergyCarrier[]=[]; - - let max_load_factor= 2; - let min_load_factor= -1; - let maneuver_load_factor= 1.1; - let passenger_nr= 150; - let mass_per_passenger=80; - let luggage_mass_per_passenger=17; - let additional_cargo_mass= 500; - let cargo_density =165; - let thrust_share = 1; - let thickness = 0.003; - let maximum_structrual_payload_mass = 30000; - let takeoff_distance = 2122; - let landing_field_length = 2387; - let requirements ={ - general:{ - type: String, - model: String, - }, - mission_files: { - design_mission_file: String, - study_mission_file: String, - requirements_mission_file: String, - }, - design_specification:{ - configuration: { - configuration_type: String, - fuselage_type: String, - mounting: String, - empennage_type: String, - undercarriage_definition:{ - main_gear_mounting: String, - undercarriage_retractability: String, - }, - - - - }, - - - } - } + let selectedTab = Object.keys($settingData)[0]; onMount(async () => { - await getModuleConf(); - }) - - async function getModuleConf() { - try { - const res = await fetch(`http://127.0.0.1:8000/projects/aircraft_exchange_file/`); - const data = await res.json(); - modalModule.name = 'exchange_file'; - modalModule.response = JSON.parse(data); - modalModule.html = []; - generateHTML(modalModule.response); - } catch (error) { - console.error(error); - modalModule.name = "no"; - modalModule.response = {}; - modalModule.html = []; - modalModule.html.push(new SettingsLabel("No config found!")); - } - } - -/** - * TODO: make it more modula, as now 2 files have a lot same code -*/ -type dictionary = { - [key: string]: any - } - /* Dictionary with information of the module - * including the json response and the settings elements it needs to implement in the dom - */ - let modalModule: dictionary = { - name: '', - response: {}, - html: [] - } - - //check if string is a number - function isNumber(n:string){ - return!isNaN(parseFloat(n))&&isFinite(parseFloat(n)) - } - - //Interface for Ui-elements in module settings and it's implementations - interface SettingsUi { - type: string; - label: string; - description: string; - bind: string; - } - - class SettingsSwitch implements SettingsUi { - readonly type = "switch"; - label: string; - description: string; - bind: string; - - constructor(label: string, description: string, bind: string) { - this.bind = bind; - this.label = label; - this.description = description; - } - } - - class SettingsSelector implements SettingsUi { - readonly type = "selector"; - label: string; - description: string; - bind: string; - options: string[]; - - constructor(label: string, description: string, bind: string, options: string[]) { - this.bind = bind; - this.label = label; - this.description = description; - this.options = options; - } - } - - class SettingsTextfield implements SettingsUi { - readonly type = "textfield"; - label: string; - description: string; - bind: string; - input: string; - - constructor(label: string, description: string, bind: string, input: string) { - this.bind = bind; - this.label = label; - this.description = description; - this.input = input; - } - } - - class SettingsNumberfield implements SettingsUi { - readonly type = "numberfield"; - label: string; - description: string; - bind: string; - unit: string = '-'; - max: number = Number.POSITIVE_INFINITY; - min: number = Number.NEGATIVE_INFINITY; - - constructor(label: string, description: string, bind: string) { - this.bind = bind; - this.label = label; - this.description = description; - } - setMax(max:number){ - this.max=max; - } - setMin(min:number){ - this.min=min; - } - setUnit(unit:string){ - this.unit=unit; - } - } - - class SettingsLabel { - readonly type = "label"; - label: string; - - constructor(label: string) { - this.label = label; - } - } - /*Parse json response to matching SettingsUi-Elements - * to portray it later in the DOM - * recursive Function - * */ - function generateHTML(json: dictionary) { - Object.entries(json).forEach(([key, value]) => { - if (value == null) { - return - } - if (value.hasOwnProperty("value")) { - if (value["@description"] && value["@description"].toLowerCase().includes("switch")) { - value.value = (value.value === 'true' || value.value === "1") //transform string input to boolean for easier binding - modalModule.html.push(new SettingsSwitch(key, value["@description"], value)) - } else if (value["@description"] && value["@description"].toLowerCase().includes("selector")) { - let options = []; - for (let i = 0; i < 5; i++) { - if (value["@description"].includes("mode_" + i)) { - options.push("mode_" + i) - } - } - modalModule.html.push(new SettingsSelector(key, value["@description"], value, options)) - }else if(isNumber(value.value)){ - value.value=parseFloat(value.value); - let numberField = new SettingsNumberfield(key, value["@description"], value) - if(value.hasOwnProperty('lower_boundary')&&isNumber(value['lower_boundary'])){numberField.setMin(value['lower_boundary'])} - if(value.hasOwnProperty('upper_boundary')&&isNumber(value['upper_boundary'])){numberField.setMax(value['upper_boundary'])} - if(value.hasOwnProperty("@unit")){numberField.setUnit(value["@unit"])}//spaeter entweder unit oder Unit in XML - if(value.hasOwnProperty("@Unit")){numberField.setUnit(value["@Unit"])} - if(value.hasOwnProperty("unit")){numberField.setUnit(value["unit"])} - if(value.hasOwnProperty("Unit")){numberField.setUnit(value["Unit"])} - modalModule.html.push(numberField); - } else { - modalModule.html.push(new SettingsTextfield(key, value["@description"], value, key)) - } - } else if (typeof value === "object") { - modalModule.html.push(new SettingsLabel(key)) - generateHTML(json[key]) - } else { - return; - } - }) - } - - //Replacing underscores to space - function formatLabel(label: string) { - return label.replaceAll("_", " ") - } - //check if the settings modal of a module changed - function checkModalChanged() { - modalChanged = true; - modalChanged = modalChanged; - } - - let modalChanged: boolean = false; - - //check if number is in boundry - function validateNumber(index:number){ - console.log("validateNumber") - if(modalModule.html[index].bind.value<modalModule.html[index].min){ - modalModule.html[index].bind.value=modalModule.html[index].min; - }else if(modalModule.html[index].bind.value>modalModule.html[index].max){ - modalModule.html[index].bind.value=modalModule.html[index].max; - } - } - - //Calculate Stepsize of number inputs from current value - function calcStepSize(value:number){ - const numberString = value.toString() - if (!numberString.includes('.')) { - return 1; - } else { - const decimalPart = numberString.split('.')[1]; - return Math.pow(10, -decimalPart.length); - } + const res = await fetch( + `http://127.0.0.1:8000/projects/aircraft_exchange_file/`, + ); + const data = await res.json(); + await loadTabData(data); + selectedTab = Object.keys($settingData)[0]; + console.log(Object.keys($settingData)); + }); + + function selectTab(tab: string) { + selectedTab = tab; } </script> -{#each modalModule.html as element, index} -{#if element.type == "switch"} - <Input id="uiElement{index}" type="switch" label="{formatLabel(element.label)}" - bind:checked={element.bind.value} on:change={()=>checkModalChanged()}/> - <Tooltip target="uiElement{index}" placement="left"> - {element.description} - </Tooltip> -{:else if element.type == "label"} - <h3>{formatLabel(element.label)}</h3> -{:else if element.type == "selector"} - <h6>{formatLabel(element.label)}</h6> - <Input id="uiElement{index}" type="select" bind:value={element.bind.value} - on:change={()=>checkModalChanged()}> - {#each element.options as option} - <option>{option}</option> - {/each} - </Input> - <Tooltip target="uiElement{index}" placement="left"> - {element.description} - </Tooltip> -{:else if element.type == "textfield"} - <h7>{formatLabel(element.label)}</h7> - <Input id="uiElement{index}" type="text" bind:value={element.bind.value} - on:change={()=>checkModalChanged()}/> - <Tooltip target="uiElement{index}" placement="left"> - {element.description} - </Tooltip> -{:else if element.type == "numberfield"} - {#if element.unit != "1" && element.unit != "-" && element.unit != "count"} - <h7>{formatLabel(element.label)} (in {element.unit})</h7> - {:else} - <h7>{formatLabel(element.label)}</h7> - {/if} - {#if element.max != Number.POSITIVE_INFINITY && element.min != Number.NEGATIVE_INFINITY} - <Input type="range" min={element.min} max={element.max} step=0.01 bind:value={element.bind.value} - placeholder="range placeholder" on:change={()=>checkModalChanged()}/> - <Input id="uiElement{index}" type="number" min={element.min} max={element.max} step=0.01 - bind:value={element.bind.value} on:change={()=>checkModalChanged()} on:blur={()=>validateNumber(index)}/> - {:else} - <Input id="uiElement{index}" type="number" min={element.min} max={element.max} step={calcStepSize(element.bind.value)} - bind:value={element.bind.value} on:change={()=>checkModalChanged()} on:blur={()=>validateNumber(index)}/> - {/if} - - <Tooltip target="uiElement{index}" placement="left"> - {element.description} - </Tooltip> -{/if} -{/each} -<!-- - -<h1>Aircraftmodelsettings</h1> -<ButtonGroup style="margin-bottom: 20px"> - <Button color="dark" outline ><Icon name="bootstrap-reboot"/> Reset </Button> - {#if changed} - <Button color="danger" outline active><Icon name="cloud-upload" /> Save </Button> - {:else} - <Button color="dark" outline ><Icon name="cloud-upload" /> Save </Button> +<div class="tabs"> + {#each Object.keys($settingData) as tab} + <button + on:click={() => selectTab(tab)} + class:selected={selectedTab === tab} + > + {tab} + </button> + {/each} +</div> + +<div class="tab-content"> + <!--TODO: fix the type error, even it doesnt break anything--> + {#if $settingData[selectedTab]} + {#key selectedTab} + <TabComponent data={$settingData[selectedTab]} /> + {/key} {/if} - <Button color="dark" outline ><Icon name="cloud-download" /> Load </Button> -</ButtonGroup> - -<TabContent vertical pills> - <TabPane tabId="general" tab="General" active> - <Form> - <h5>General aircraft information</h5> - <FormGroup floating label="Aircraft type"> - <Input placeholder="Enter a value"/> - </FormGroup> - <FormGroup floating label="Model - Version"> - <Input placeholder="Enter a value"/> - </FormGroup> - - <h5>Name of xml files which are located in the missionData directory and contain the flight phase data</h5> - <FormGroup floating label="Name of the study mission xml"> - <Input placeholder="Enter a value"/> - </FormGroup> - <FormGroup floating label="Name of the requirements mission xml"> - <Input placeholder="Enter a value"/> - </FormGroup> - </Form> - </TabPane> - <TabPane tabId="design_specification" tab="Design Specification"> - <Form> - <h5>Configuration information</h5> - <FormGroup floating label="Aircraft configuration"> - <Input type="select" placeholder="Enter a value"> - <option value="tube_and_wing">tube and wing</option> - <option value="blended_wing_body">blended wing body</option> - </Input> - </FormGroup> - <FormGroup floating label="Design description of the fuselage"> - <Input type="select" placeholder="Enter a value"> - <option value="single_aisle">single aisle</option> - <option value="weight_body">weight body</option> - </Input> - </FormGroup> - <FormGroup floating label="Definitions for wing design"> - <Input type="select" placeholder="Enter a value"> - <option value="low">low</option> - <option value="mid">mid</option> - <option value="high">high</option> - </Input> - </FormGroup> - - - <h5>Design description of the undercarriage</h5> - <FormGroup floating label="Mounting position of the main landing gear"> - <Input type="select" placeholder="Enter a value"> - <option value="wing_mounted">wing mounted</option> - <option value="fuselage_mounted">fuselage mounted</option> - </Input> - </FormGroup> - <FormGroup floating label="Retractability of landing gear"> - <Input type="select" placeholder="Enter a value"> - <option value="retractable">retractable</option> - <option value="non_retractable">non retractable</option> - </Input> - </FormGroup> - - <h5> Design Load information</h5> - <FormGroup floating label="maximum load factor"> - <Input type="number" min={0} max={4} step={0.1} bind:value={max_load_factor} placeholder="number placeholder"/> - <Input type="range" min={0} max={4} step={0.1} bind:value={max_load_factor} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="minimum load factor"> - <Input type="number" min={-2} max={0} step={0.1} bind:value={min_load_factor} placeholder="number placeholder"/> - <Input type="range" min={-2} max={0} step={0.1} bind:value={min_load_factor} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="standard maneuver load factor for e.g. flare"> - <Input type="number" min={0} max={2} step={0.1} bind:value={maneuver_load_factor} placeholder="number placeholder"/> - <Input type="range" min={0} max={2} step={0.1} bind:value={maneuver_load_factor} placeholder="range placeholder"/> - </FormGroup> - - <h5> Passenger definition</h5> - <FormGroup floating label="Number of passengers"> - <Input type="number" min={0} step={1} bind:value={passenger_nr} placeholder="number placeholder"/> - </FormGroup> - <FormGroup floating label="Design mass of a single passenger WITHOUT luggage in kg"> - <Input type="number" min={50} max={200} step={1} bind:value={mass_per_passenger} placeholder="number placeholder"/> - <Input type="range" min={50} max={200} step={1} bind:value={mass_per_passenger} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="Design mass of a the luggage for a single passenger in kg"> - <Input type="number" min={0} max={25} step={1} bind:value={luggage_mass_per_passenger} placeholder="number placeholder"/> - <Input type="range" min={0} max={25} step={1} bind:value={luggage_mass_per_passenger} placeholder="range placeholder"/> - </FormGroup> - <h6>passenger class distro with bar and 5 classes</h6> - - <h5>Cargo definition</h5> - <FormGroup floating label="Mass of cargo which does not belong to passengers in kg"> - <Input type="number" min={0} max={1000} step={1} bind:value={additional_cargo_mass} placeholder="number placeholder"/> - <Input type="range" min={0} max={1000} step={1} bind:value={additional_cargo_mass} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="Density of cargo which does not belong to passengers in kg/m^3"> - <Input type="number" min={150} max={200} step={1} bind:value={cargo_density} placeholder="number placeholder"/> - <Input type="range" min={150} max={200} step={1} bind:value={cargo_density} placeholder="range placeholder"/> - </FormGroup> - </Form> - </TabPane> - <TabPane tabId="requirements" tab="Requirements"> - <Form> - - </Form> - </TabPane> - <TabPane tabId="assessment_scenario" tab="Assessment Scenario"> - <Form> - - </Form> - </TabPane> -</TabContent> -<Form> - <h2>Requirements and Specifications</h2> - - - - <h5>Design specification</h5> - - - <h5>Energy carriers information</h5> - <FormGroup floating label="ID of Energy type: kerosene / liquid_hydrogen / battery / saf (for multifuel engine create new ID)"> - <Input type="number" placeholder="number placeholder"/> - </FormGroup> - - <h5>Propulsion information?</h5> - <FormGroup floating label="Way the power is generated from the source"> - <Input type="select" placeholder="Enter a value"> - <option value="turbo">turbo</option> - <option value="electric">electric</option> - <option value="fuel_cell">fuel_cell</option> - </Input> - </FormGroup> - <FormGroup floating label="Type of main thrust generator"> - <Input type="select" placeholder="Enter a value"> - <option value="fan">fan</option> - <option value="prop">prop</option> - </Input> - </FormGroup> - <FormGroup floating label="position on component"> - <Input type="select" placeholder="Enter a value"> - <option value="wing">wing</option> - <option value="fuselage">fuselage</option> - <option value="empennage">empennage</option> - </Input> - </FormGroup> - <FormGroup floating label="x-position (aircraft coordinate system)"> - <Input type="select" placeholder="Enter a value"> - <option value="front">front</option> - <option value="back">back</option> - </Input> - </FormGroup> - <FormGroup floating label="y-position (aircraft coordinate system)"> - <Input type="select" placeholder="Enter a value"> - <option value="left">left</option> - <option value="right">right</option> - </Input> - </FormGroup> - <FormGroup floating label="z-position (aircraft coordinate system)"> - <Input type="select" placeholder="Enter a value"> - <option value="over">over</option> - <option value="mid">mid</option> - <option value="under">under</option> - <option value="in">in</option> - </Input> - </FormGroup> - <FormGroup floating label="see energy carrier specification node"> - <Input type="number" min={0} max={5} step={1} bind:value={energycarriers} placeholder="number placeholder"/> - <Input type="range" min={0} max={5} step={1} bind:value={energycarriers} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="Share of this thrust in relation to required aircraft thrust"> - <Input type="number" min={0} max={1} step={0.1} bind:value={thrust_share} placeholder="number placeholder"/> - <Input type="range" min={0} max={1} step={0.1} bind:value={thrust_share} placeholder="range placeholder"/> - </FormGroup> - - <h5>Systems information</h5> - <FormGroup floating label="Way the power is generated from the source"> - <Input type="select" placeholder="Enter a value"> - <option value="propulsor">propulsor</option> - <option value="turbo">turbo</option> - <option value="electric">electric</option> - <option value="fuel_cell">fuel_cell</option> - </Input> - </FormGroup> - <p>dieser bereich ist verwirrend, unterkategorien?</p> - - <h5>Skinning Information</h5> - <FormGroup floating label="Material of skinning"> - <Input placeholder="Enter a value"/> - </FormGroup> - <FormGroup floating label="Thickness of skinning"> - <Input type="number" min={0.0001} max={0.1} step={0.0001} bind:value={thickness} placeholder="number placeholder"/> - <Input type="range" min={0.0001} max={0.1} step={0.0001} bind:value={thickness} placeholder="range placeholder"/> - </FormGroup> - - <h5>Technology</h5> - <Input type="switch" label="Switch if variable camber is used" /> - - <h5>Energy tanks information?</h5> - <p>energiecarrier wieder, machmal bei auswahl zahlen manchmal direkt wörter</p> - <FormGroup floating label="Component where the tank is located"> - <Input type="select" placeholder="Enter a value"> - <option value="fusalage">fusalage</option> - <option value="wing">wing</option> - <option value="horizontal_stabilizer">horizontal_stabilizer</option> - </Input> - </FormGroup> - <FormGroup floating label="Position of tank in location"> - <Input type="select" placeholder="Enter a value"> - <option value="tailcone">tailcone</option> - <option value="rear">rear</option> - <option value="front">front</option> - <option value="top">top</option> - <option value="bottom">bottom</option> - <option value="center">center</option> - <option value="inner_left">inner_left</option> - <option value="outer_left">outer_left</option> - <option value="inner_right">inner_right</option> - <option value="outer_right">outer_right</option> - <option value="total">total</option> - </Input> - </FormGroup> - - <h5>Aircraft design requirements</h5> - <h6>TLAR</h6> - <FormGroup floating label="Maximum structual payload mass which can be carried by the aircraft (e.g. for short trips) in kg"> - <Input type="number" min={100} max={150000} step={100} bind:value={maximum_structrual_payload_mass} placeholder="number placeholder"/> - <Input type="range" min={100} max={150000} step={100} bind:value={maximum_structrual_payload_mass} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="Design takeoff distance (Balanced Field Length) at Sea Level with maximum takeoff mass (MTOM) and (ISA + deltaISA)-Conditions in m"> - <Input type="number" min={600} max={5000} step={1} bind:value={takeoff_distance} placeholder="number placeholder"/> - <Input type="range" min={600} max={5000} step={1} bind:value={takeoff_distance} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="Needed runway length at Sea Level with maximum landing mass (MLM) and (ISA + deltaISA)-Conditions (Safety-Landing Distance according to FAR 121.195: landing_field_required/0.6) in m"> - <Input type="number" min={600} max={5000} step={1} bind:value={landing_field_length} placeholder="number placeholder"/> - <Input type="range" min={600} max={5000} step={1} bind:value={landing_field_length} placeholder="range placeholder"/> - </FormGroup> - <FormGroup floating label="ICAO reference code - code_number 1-4 (field length) + code_letter A-F (wing span limits) + faa ADG code number I-VI (wing span limits + tail height limits) + Aircraft Approach Category letter A-D"> - <Input placeholder="Enter a value"/> - </FormGroup> - <p>mit check dass code stimmt?</p> - - -</Form> ---> - +</div> -<Styles/> \ No newline at end of file +<Styles /> diff --git a/UnicadoGUI/Frontend/src/stores/settings.js b/UnicadoGUI/Frontend/src/stores/settings.js new file mode 100644 index 0000000000000000000000000000000000000000..fd01e7c53764ac83938da680396a6499a8c5f914 --- /dev/null +++ b/UnicadoGUI/Frontend/src/stores/settings.js @@ -0,0 +1,30 @@ +import { writable } from 'svelte/store'; + +// Define the type for the entire settings data object +/** + * @typedef {Object<string, string>} SettingsData + */ + +export const settingData = writable({}); + + +/** + * Load XML data into the tab store dynamically. + * @param {string} data - The XML data as a string. + * @returns {Promise<void>} + */ +async function loadTabData(data) { + const parsedXML = JSON.parse(data); + const root = parsedXML.aircraft_exchange_file; + + /** @type {SettingsData} */ + const tabs = {}; + + for (const [key, value] of Object.entries(root)) { + tabs[key] = value; + } + + settingData.set(tabs); +} + +export { loadTabData }; \ No newline at end of file