reposition some buttons
This commit is contained in:
parent
470b3e2336
commit
0639aeae6f
6 changed files with 120 additions and 21 deletions
57
elevators.js
57
elevators.js
|
@ -4,6 +4,7 @@ const internalData = {
|
||||||
};
|
};
|
||||||
let geolocationPermission = false;
|
let geolocationPermission = false;
|
||||||
let geolocation = [null, null];
|
let geolocation = [null, null];
|
||||||
|
const openStations = new Set();
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'capitalize', {
|
Object.defineProperty(String.prototype, 'capitalize', {
|
||||||
|
@ -229,7 +230,10 @@ function renderData() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#loadElevators').innerHTML = 'Daten aktualisieren';
|
document.querySelector('#updateInfo').classList.remove('hidden');
|
||||||
|
document.querySelector('#loadElevators').classList.remove('hidden');
|
||||||
|
document.querySelector('#filters').classList.remove('hidden');
|
||||||
|
document.querySelector('#initialLoad').classList.add('hidden');
|
||||||
const dateContainer = document.querySelector('#lastUpdated');
|
const dateContainer = document.querySelector('#lastUpdated');
|
||||||
dateContainer.innerHTML = dateTimeStyle.format(new Date(internalData.lastUpdate));
|
dateContainer.innerHTML = dateTimeStyle.format(new Date(internalData.lastUpdate));
|
||||||
|
|
||||||
|
@ -245,6 +249,8 @@ function renderData() {
|
||||||
let elevatorsTemplate = '';
|
let elevatorsTemplate = '';
|
||||||
let previewTemplate = '';
|
let previewTemplate = '';
|
||||||
|
|
||||||
|
let templateHasOsmButton = false;
|
||||||
|
|
||||||
for (const elevator of station.elevators) {
|
for (const elevator of station.elevators) {
|
||||||
let linesTemplate = '<div class="lineList">Linien: ';
|
let linesTemplate = '<div class="lineList">Linien: ';
|
||||||
for (const line of elevator.lines) {
|
for (const line of elevator.lines) {
|
||||||
|
@ -342,9 +348,14 @@ Auf Karte anzeigen
|
||||||
${osmTemplate ? `<div class="osm" data-nodeid="${elevator.osmNodeId}">
|
${osmTemplate ? `<div class="osm" data-nodeid="${elevator.osmNodeId}">
|
||||||
<h4>Daten von OpenStreetMap</h4>
|
<h4>Daten von OpenStreetMap</h4>
|
||||||
${osmTemplate}
|
${osmTemplate}
|
||||||
</div>` : ''}
|
</div>` : `<button class="loadOSM">
|
||||||
|
Zusätzliche Daten von OpenStreetMap abrufen
|
||||||
|
<span data-icon="load" class="size-s spinner hidden"></span>
|
||||||
|
</button>`}
|
||||||
</div>
|
</div>
|
||||||
</li>`;
|
</li>`;
|
||||||
|
|
||||||
|
templateHasOsmButton = templateHasOsmButton || !osmTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `<li class="station" id="station_${stationIndex}">
|
const template = `<li class="station" id="station_${stationIndex}">
|
||||||
|
@ -362,7 +373,7 @@ ${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<details>
|
<details data-stationid="${stationIndex}" ${openStations.has(stationIndex) ? 'open' : ''}>
|
||||||
<summary>
|
<summary>
|
||||||
Aufzüge anzeigen
|
Aufzüge anzeigen
|
||||||
</summary>
|
</summary>
|
||||||
|
@ -373,28 +384,52 @@ ${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.
|
||||||
</li>`;
|
</li>`;
|
||||||
listContainer.insertAdjacentHTML('beforeend', template);
|
listContainer.insertAdjacentHTML('beforeend', template);
|
||||||
|
|
||||||
// immediate invocation
|
if (templateHasOsmButton) {
|
||||||
// (function () {
|
//immediate invocation
|
||||||
// const stationId = stationIndex;
|
(function () {
|
||||||
// listContainer.querySelector(`#station_${stationIndex}`)
|
listContainer.querySelectorAll(`#station_${stationIndex} .loadOSM`).forEach(e => {
|
||||||
// .addEventListener('click', () => toggleElevatorList(stationId))
|
e.addEventListener('click', (ev) => {
|
||||||
// }());
|
ev.target.querySelector('.spinner').classList.remove('hidden');
|
||||||
|
loadOsmData().then(() => {
|
||||||
|
ev.target.classList.add('hidden');
|
||||||
|
renderData();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listContainer.querySelectorAll(`details`).forEach(e => {
|
||||||
|
e.addEventListener("toggle", (event) => {
|
||||||
|
const stationId = event.target.dataset['stationid'];
|
||||||
|
if (event.target.open) {
|
||||||
|
openStations.add(stationId);
|
||||||
|
} else {
|
||||||
|
openStations.delete(stationId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#loadElevators')
|
document.querySelector('#loadElevators')
|
||||||
.addEventListener('click', (e) => {
|
.addEventListener('click', (e) => {
|
||||||
|
e.target.querySelector('.spinner').classList.remove('hidden');
|
||||||
loadElevators().then(() => {
|
loadElevators().then(() => {
|
||||||
|
e.target.querySelector('.spinner').classList.add('hidden');
|
||||||
renderData();
|
renderData();
|
||||||
filterData();
|
filterData();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
document.querySelector('#loadOSM')
|
document.querySelector('#initialLoad')
|
||||||
.addEventListener('click', (e) => {
|
.addEventListener('click', (e) => {
|
||||||
loadOsmData().then(() => {
|
e.target.querySelector('.spinner').classList.remove('hidden');
|
||||||
|
loadElevators().then(() => {
|
||||||
|
e.target.classList.add('hidden');
|
||||||
renderData();
|
renderData();
|
||||||
|
filterData();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
15
index.html
15
index.html
|
@ -26,14 +26,16 @@
|
||||||
</nav>
|
</nav>
|
||||||
<main>
|
<main>
|
||||||
<h2>Station List</h2>
|
<h2>Station List</h2>
|
||||||
<div>
|
<div id="updateInfo" class="hidden">
|
||||||
<span>Last Updated: <b id="lastUpdated"></b></span>
|
<span>Last Updated: <b id="lastUpdated"></b></span>
|
||||||
<button id="loadElevators">Daten vom HVV abrufen</button>
|
<button id="loadElevators" class="hidden">
|
||||||
<button id="loadOSM">OSM Daten abrufen</button>
|
Daten aktualisieren
|
||||||
|
<span data-icon="load" class="size-s spinner hidden"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div class="filters">
|
<div class="hidden" id="filters">
|
||||||
<input placeholder="Station suchen" id="searchStation">
|
<input placeholder="Station suchen" id="searchStation">
|
||||||
<button id="stationsNearMe">
|
<button id="stationsNearMe">
|
||||||
<span data-icon="location-searching" class="size-m"></span>
|
<span data-icon="location-searching" class="size-m"></span>
|
||||||
|
@ -41,6 +43,11 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button id="initialLoad">
|
||||||
|
Daten vom HVV abrufen
|
||||||
|
<span data-icon="load" class="size-m spinner hidden"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<ul id="stationList">
|
<ul id="stationList">
|
||||||
</ul>
|
</ul>
|
||||||
</main>
|
</main>
|
||||||
|
|
1
md_icons/load.svg
Normal file
1
md_icons/load.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M202-279q-32-45-48.5-96T137-480q0-140 98-241.5T470-823h8l-49-49 67-66 178 178-178 178-67-66 49-49h-5q-87 0-148.5 63.5T263-480q0 29 7.5 56.5T293-370l-91 91ZM464-21 286-199l178-179 67 67-49 49h5q87 0 148.5-64T697-480q0-29-7.5-56.5T667-590l91-90q32 45 48.5 95.5T823-480q0 140-98 242T490-136h-8l49 48-67 67Z"/></svg>
|
After Width: | Height: | Size: 428 B |
33
style.css
33
style.css
|
@ -56,7 +56,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red {
|
.text-red {
|
||||||
|
@ -143,15 +143,23 @@ button:hover {
|
||||||
border-color: var(--station-border-hover);
|
border-color: var(--station-border-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.filters {
|
div#filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
justify-items: stretch;
|
justify-items: stretch;
|
||||||
}
|
}
|
||||||
div.filters button, div.filters input {
|
div#filters button, div#filters input {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button#initialLoad {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.loadOSM {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
ul#stationList {
|
ul#stationList {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -559,5 +567,24 @@ span[data-icon][data-icon=up-down] {
|
||||||
span[data-icon][data-icon=location-searching] {
|
span[data-icon][data-icon=location-searching] {
|
||||||
mask-image: url(/md_icons/location-searching.svg);
|
mask-image: url(/md_icons/location-searching.svg);
|
||||||
}
|
}
|
||||||
|
span[data-icon][data-icon=load] {
|
||||||
|
mask-image: url(/md_icons/load.svg);
|
||||||
|
}
|
||||||
|
span[data-icon].spinner {
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-direction: normal;
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-fill-mode: none;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: spinner;
|
||||||
|
animation-play-state: running;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinner {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=style.css.map */
|
/*# sourceMappingURL=style.css.map */
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAmBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAzBA;EA/BF;IAgCI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;AAcJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAGA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AAOV;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIF;EACE;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EAEA;;AAEA;EAPF;IAQI;;;AAIJ;EACE;EAEA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;AAMR;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EA1BF;IA2BI;;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EAKA;;AAJA;EATF;IAUI;;;AAMF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AACA;EARF;IASI;;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKE;EACE;;AAMR;EACE;EACA;EACA;EAEA;EACA;;AAEA;EACE;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;;;AAIJ;EACE;EACA;EAEA;;AAEA;EANF;IAOI;;;;AAYpB;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI;;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;EAMA;EACA;EACA;EACA;EACA;EACA;EACA;;AAVA;EACE;;AAWF;EAIE;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE","file":"style.css"}
|
{"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAmBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAzBA;EA/BF;IAgCI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;AAcJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAGA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AAOV;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIF;EACE;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EAEA;;AAEA;EAPF;IAQI;;;AAIJ;EACE;EAEA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;AAMR;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EA1BF;IA2BI;;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;EAKA;;AAJA;EATF;IAUI;;;AAMF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AACA;EARF;IASI;;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKE;EACE;;AAMR;EACE;EACA;EACA;EAEA;EACA;;AAEA;EACE;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;;;AAIJ;EACE;EACA;EAEA;;AAEA;EANF;IAOI;;;;AAYpB;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI;;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;EAMA;EACA;EACA;EACA;EACA;EACA;EACA;;AAVA;EACE;;AAWF;EAIE;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;IACE","file":"style.css"}
|
33
style.scss
33
style.scss
|
@ -61,7 +61,7 @@ $mediumBreakpoint: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red {
|
.text-red {
|
||||||
|
@ -161,7 +161,7 @@ button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.filters {
|
div#filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
justify-items: stretch;
|
justify-items: stretch;
|
||||||
|
@ -171,6 +171,14 @@ div.filters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button#initialLoad {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.loadOSM {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
ul#stationList {
|
ul#stationList {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -662,4 +670,25 @@ span[data-icon] {
|
||||||
&[data-icon="location-searching"] {
|
&[data-icon="location-searching"] {
|
||||||
mask-image: url(/md_icons/location-searching.svg);
|
mask-image: url(/md_icons/location-searching.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[data-icon="load"] {
|
||||||
|
mask-image: url(/md_icons/load.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.spinner {
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-direction: normal;
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-fill-mode: none;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: spinner;
|
||||||
|
animation-play-state: running;
|
||||||
|
animation-timing-function: linear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinner {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue