<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>Simulator Web UI</title>
+ <style>
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ #app {
+ height: fit-content;
+ width: 100%;
+ font-family: var(--font-family);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: flex;
+ flex-direction: row;
+ color: var(--color-text);
+ background-color: var(--color-bg);
+ }
+ </style>
</head>
<body>
<Container
v-show="$route.name !== 'charging-stations' && $route.name !== 'not-found'"
id="action-container"
+ class="action-container"
>
<router-view name="action" />
</Container>
import Container from '@/components/Container.vue'
</script>
-<style>
-#app {
- height: fit-content;
- width: 100%;
- font-family: Tahoma, 'Arial Narrow', Arial, Helvetica, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- display: flex;
- flex-direction: row;
- color: var(--color-text);
- background-color: var(--color-bg);
-}
-
-#action-container {
+<style scoped>
+.action-container {
min-width: max-content;
height: fit-content;
display: flex;
position: sticky;
- top: 0.008%;
+ top: 0;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
- margin-right: 0.2%;
- margin-left: 0.2%;
- padding: 0.4%;
+ margin-inline: var(--spacing-sm);
+ padding: var(--spacing-md);
border: solid 0.25px var(--color-border);
}
-
-body {
- margin: 0.008%;
- padding: 0.008%;
-}
</style>
--color-border-row: var(--ctp-surface0);
--color-accent: var(--ctp-lavender);
--color-shadow-inset: rgba(0, 0, 0, 0.1);
+
+ /* Spacing */
+ --spacing-xs: 0.125rem;
+ --spacing-sm: 0.25rem;
+ --spacing-md: 0.5rem;
+ --spacing-lg: 1rem;
+ --spacing-xl: 1.5rem;
+
+ /* Typography */
+ --font-family: Tahoma, 'Arial Narrow', Arial, Helvetica, sans-serif;
+ --font-size-sm: 0.875rem;
}
body {
--color-border-row: var(--sap-border);
--color-accent: var(--sap-brand);
--color-shadow-inset: rgba(34, 53, 72, 0.15);
+
+ /* Spacing */
+ --spacing-xs: 0.125rem;
+ --spacing-sm: 0.25rem;
+ --spacing-md: 0.5rem;
+ --spacing-lg: 1rem;
+ --spacing-xl: 1.5rem;
+
+ /* Typography */
+ --font-family: Tahoma, 'Arial Narrow', Arial, Helvetica, sans-serif;
+ --font-size-sm: 0.875rem;
}
body {
--color-border-row: var(--tn-bg-hover);
--color-accent: var(--tn-accent);
--color-shadow-inset: rgba(0, 0, 0, 0.4);
+
+ /* Spacing */
+ --spacing-xs: 0.125rem;
+ --spacing-sm: 0.25rem;
+ --spacing-md: 0.5rem;
+ --spacing-lg: 1rem;
+ --spacing-xl: 1.5rem;
+
+ /* Typography */
+ --font-family: Tahoma, 'Arial Narrow', Arial, Helvetica, sans-serif;
+ --font-size-sm: 0.875rem;
}
body {
</div>
</template>
-<style>
+<style scoped>
.container {
flex: auto;
}
<template>
- <h1 id="action">
+ <h1 class="action">
Add Charging Stations
</h1>
<p>Template:</p>
<input
id="number-of-stations"
v-model="state.numberOfStations"
+ class="number-of-stations"
min="1"
name="number-of-stations"
placeholder="number of stations"
type="number"
>
<p>Template options overrides:</p>
- <ul id="template-options">
+ <ul class="template-options">
<li>
Supervision url:
<input
id="supervision-url"
v-model.trim="state.supervisionUrl"
+ class="supervision-url"
name="supervision-url"
placeholder="wss://"
type="url"
}
</script>
-<style>
-#number-of-stations {
- width: 15%;
+<style scoped>
+.action {
+ min-width: max-content;
+ color: var(--color-text-strong);
+ background-color: var(--color-bg-caption);
+ padding: var(--spacing-lg);
+}
+
+.number-of-stations {
+ width: auto;
+ max-width: 6rem;
text-align: center;
}
-#supervision-url {
- width: 90%;
+.supervision-url {
+ width: 100%;
+ max-width: 40rem;
text-align: left;
}
-#template-options {
+.template-options {
list-style: circle inside;
text-align: left;
}
<template>
- <h1 id="action">
+ <h1 class="action">
Set Supervision Url
</h1>
<h2>{{ chargingStationId }}</h2>
<input
id="supervision-url"
v-model.trim="state.supervisionUrl"
+ class="supervision-url"
name="supervision-url"
placeholder="wss://"
type="url"
})
</script>
-<style>
-#supervision-url {
- width: 90%;
+<style scoped>
+.action {
+ min-width: max-content;
+ color: var(--color-text-strong);
+ background-color: var(--color-bg-caption);
+ padding: var(--spacing-lg);
+}
+
+.supervision-url {
+ width: 100%;
+ max-width: 40rem;
text-align: left;
}
</style>
<template>
- <h1 id="action">
+ <h1 class="action">
Start Transaction
</h1>
<h2>{{ chargingStationId }}</h2>
<input
id="idtag"
v-model.trim="state.idTag"
+ class="idtag"
name="idtag"
placeholder="RFID tag"
type="text"
}
</script>
-<style>
-#idtag {
+<style scoped>
+.action {
+ min-width: max-content;
+ color: var(--color-text-strong);
+ background-color: var(--color-bg-caption);
+ padding: var(--spacing-lg);
+}
+
+.idtag {
text-align: center;
}
</style>
</button>
</template>
-<style>
+<style scoped>
.button {
display: block;
- flex: auto;
width: 100%;
text-align: center;
- font: small-caption;
+ white-space: nowrap;
+ font-size: var(--font-size-sm);
+}
+
+.button:focus-visible {
+ outline: 2px solid var(--color-accent);
+ outline-offset: -2px;
}
</style>
}>()
</script>
-<style>
-@keyframes rotation {
+<style scoped>
+@keyframes spin {
from {
transform: rotate(0deg);
}
}
.spin {
- animation: rotation 2s linear infinite;
+ animation: spin 2s linear infinite;
}
</style>
}
</script>
-<style>
+<style scoped>
button.on {
color: var(--color-text);
background-color: var(--color-bg-active);
</Button>
</td>
<td class="cs-table__connectors-column">
- <table id="connectors-table">
- <thead id="connectors-table__head">
+ <table class="connectors-table">
+ <thead class="connectors-table__head">
<tr class="connectors-table__row">
<th
class="connectors-table__column"
</th>
</tr>
</thead>
- <tbody id="connectors-table__body">
+ <tbody class="connectors-table__body">
<CSConnector
v-for="entry in getConnectorEntries()"
:key="entry.evseId != null ? `${entry.evseId}-${entry.connectorId}` : entry.connectorId"
}
</script>
-<style>
-#connectors-table {
+<style scoped>
+.connectors-table {
width: 100%;
background-color: var(--color-bg-surface);
border-collapse: collapse;
empty-cells: show;
}
-.connectors-table__row {
- border: solid 0.25px var(--color-border-row);
+.connectors-table__head .connectors-table__row {
+ background-color: var(--color-bg-header);
}
-.connectors-table__row:nth-of-type(even) {
- background-color: var(--color-bg-hover);
+:deep(.connectors-table__row) {
+ border: solid 0.25px var(--color-border-row);
}
-#connectors-table__head .connectors-table__row {
- background-color: var(--color-bg-header);
+:deep(.connectors-table__row:nth-of-type(even)) {
+ background-color: var(--color-bg-hover);
}
-.connectors-table__column {
+:deep(.connectors-table__column) {
text-align: center;
vertical-align: middle;
padding: 0.25rem;
<template>
<div class="cs-table__wrapper">
- <table id="cs-table">
- <caption id="cs-table__caption">
+ <table class="cs-table">
+ <caption class="cs-table__caption">
Charging Stations
</caption>
<colgroup>
<col>
<col class="cs-table__col--connectors">
</colgroup>
- <thead id="cs-table__head">
+ <thead class="cs-table__head">
<tr class="cs-table__row">
<th
class="cs-table__column"
</th>
</tr>
</thead>
- <tbody id="cs-table__body">
+ <tbody class="cs-table__body">
<CSData
v-for="chargingStation in chargingStations"
:key="chargingStation.stationInfo.hashId"
const $emit = defineEmits(['need-refresh'])
</script>
-<style>
+<style scoped>
.cs-table__wrapper {
overflow-x: auto;
}
-#cs-table {
+.cs-table {
width: 100%;
min-width: 1280px;
background-color: var(--color-bg-surface);
empty-cells: show;
}
-#cs-table__caption {
+.cs-table__caption {
color: var(--color-text-strong);
background-color: var(--color-bg-caption);
font-size: 1.5rem;
padding: 0.5rem;
}
-.cs-table__row {
- border: solid 0.25px var(--color-border-row);
+.cs-table__head .cs-table__row {
+ background-color: var(--color-bg-header);
}
-.cs-table__row:nth-of-type(even) {
- background-color: var(--color-bg-hover);
+:deep(.cs-table__row) {
+ border: solid 0.25px var(--color-border-row);
}
-#cs-table__head .cs-table__row {
- background-color: var(--color-bg-header);
+:deep(.cs-table__row:nth-of-type(even)) {
+ background-color: var(--color-bg-hover);
}
-.cs-table__column {
+:deep(.cs-table__column) {
text-align: center;
vertical-align: middle;
padding: 0.25rem;
- overflow-wrap: anywhere;
+ overflow-wrap: break-word;
}
.cs-table__col--connectors {
width: 33%;
}
-.cs-table__connectors-column {
+:deep(.cs-table__connectors-column) {
vertical-align: top;
padding: 0;
}
<template>
- <Container id="charging-stations-container">
- <Container id="buttons-container">
+ <Container class="charging-stations-container">
+ <Container class="buttons-container">
<Container
v-show="Array.isArray(uiServerConfigurations) && uiServerConfigurations.length > 1"
id="ui-server-container"
+ class="ui-server-container"
>
<select
id="ui-server-selector"
v-model="state.uiServerIndex"
+ class="ui-server-selector"
@change="
() => {
if (
Add Charging Stations
</ToggleButton>
<ReloadButton
- id="reload-button"
+ class="reload-button"
:loading="state.gettingChargingStations"
@click="getChargingStations()"
/>
}
</script>
-<style>
-#charging-stations-container {
+<style scoped>
+.charging-stations-container {
height: fit-content;
width: 100%;
display: flex;
flex-direction: column;
}
-#ui-server-container {
+.ui-server-container {
display: flex;
+ flex: 3 1 0;
+ min-width: 0;
justify-content: center;
border: 1px solid var(--color-border-row);
}
-#ui-server-selector {
+.ui-server-selector {
width: 100%;
background-color: var(--color-bg-input);
color: var(--color-text);
- font: small-caption;
+ font-size: var(--font-size-sm);
text-align: center;
}
-#ui-server-selector:hover {
+.ui-server-selector:hover {
background-color: var(--color-bg-hover);
}
-#buttons-container {
+.ui-server-selector:focus-visible {
+ outline: 2px solid var(--color-accent);
+ outline-offset: -2px;
+}
+
+.buttons-container {
display: flex;
flex-direction: row;
+ gap: var(--spacing-xs);
position: sticky;
top: 0;
}
-#action-button {
- flex: none;
+.buttons-container > * {
+ flex: 1 1 0;
}
-#reload-button {
+.reload-button {
font-size: 1.5rem;
}
-#reload-button:active {
+.reload-button:active {
background-color: var(--color-primary);
}
-
-#action {
- min-width: max-content;
- color: var(--color-text-strong);
- background-color: var(--color-bg-caption);
- padding: 0.8%;
-}
</style>
<template>
- <Container id="not-found">
+ <Container class="not-found">
404 - Not found
</Container>
</template>
import Container from '@/components/Container.vue'
</script>
-<style>
-#not-found {
+<style scoped>
+.not-found {
display: flex;
justify-content: center;
align-items: center;