Launcher: UI rework
Fixed help modal header margins for title and close button. Help menu titles now have same padding from both sides. Scroll fixed in chrome. Problem in Safari.
Change-Id: I2987ea93379e385125e81ec37b9f0bb61a6d7797
diff --git a/core/installer/values-tmpl/dodo-app.cue b/core/installer/values-tmpl/dodo-app.cue
index ddd3b17..fbbd8ad 100644
--- a/core/installer/values-tmpl/dodo-app.cue
+++ b/core/installer/values-tmpl/dodo-app.cue
@@ -172,8 +172,7 @@
help: [{
title: "How to use"
- contents: """
- Clone: git clone ssh://\(_domain):\(input.sshPort)/app <button onClick='copyToClipboard(this, "git clone ssh://\(_domain):\(input.sshPort)/app")'><svg width='24px' height='24px' viewBox='-2.4 -2.4 28.80 28.80' fill='none' xmlns='http://www.w3.org/2000/svg'><g id='SVGRepo_bgCarrier' stroke-width='0'></g><g id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'></g><g id='SVGRepo_iconCarrier'> <path fill-rule='evenodd' clip-rule='evenodd' d='M19.5 16.5L19.5 4.5L18.75 3.75H9L8.25 4.5L8.25 7.5L5.25 7.5L4.5 8.25V20.25L5.25 21H15L15.75 20.25V17.25H18.75L19.5 16.5ZM15.75 15.75L15.75 8.25L15 7.5L9.75 7.5V5.25L18 5.25V15.75H15.75ZM6 9L14.25 9L14.25 19.5L6 19.5L6 9Z' fill='#080341'></path> </g></svg></button>
- Server public key: \(input.ssKeys.public)
+ "contents": """
+ Clone: git clone ssh://\(_domain):\(input.sshPort)/app <div onClick='copyToClipboard(this, "git clone ssh://\(_domain):\(input.sshPort)/app")' style='display: inline-block; cursor: pointer;'> <svg width='26px' height='26px' viewBox='-0 -0 28.80 28.80' fill='#7f9f7f' xmlns='http://www.w3.org/2000/svg' style='outline: none;'> <g id='SVGRepo_bgCarrier' stroke-width='0'></g> <g id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'></g> <g id='SVGRepo_iconCarrier'> <path fill-rule='evenodd' clip-rule='evenodd' d='M19.5 16.5L19.5 4.5L18.75 3.75H9L8.25 4.5L8.25 7.5L5.25 7.5L4.5 8.25V20.25L5.25 21H15L15.75 20.25V17.25H18.75L19.5 16.5ZM15.75 15.75L15.75 8.25L15 7.5L9.75 7.5V5.25L18 5.25V15.75H15.75ZM6 9L14.25 9L14.25 19.5L6 19.5L6 9Z' fill='#7f9f7f'></path> </g> </svg> </div> Server public key: \(input.ssKeys.public)
"""
}]
diff --git a/core/installer/values-tmpl/headscale.cue b/core/installer/values-tmpl/headscale.cue
index ec06383..5071b4a 100644
--- a/core/installer/values-tmpl/headscale.cue
+++ b/core/installer/values-tmpl/headscale.cue
@@ -5,7 +5,7 @@
name: "headscale"
namespace: "app-headscale"
-icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 48 48'><circle cx='24' cy='24' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='10' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='10' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='10' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='38' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='38' r='4.5' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='2' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='24' r='2' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='2' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='2' fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round'/></svg>"
+icon: "<svg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 48 48'><circle cx='24' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='10' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='38' r='4.5' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='38' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='24' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='10' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/><circle cx='38' cy='24' r='2' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'/></svg>"
images: {
headscale: {
diff --git a/core/installer/welcome/launcher-tmpl/launcher.html b/core/installer/welcome/launcher-tmpl/launcher.html
index 91562f5..6d404ad 100644
--- a/core/installer/welcome/launcher-tmpl/launcher.html
+++ b/core/installer/welcome/launcher-tmpl/launcher.html
@@ -5,13 +5,14 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dodo: Launcher</title>
<link rel="stylesheet" type="text/css" href="/static/pico.2.0.6.min.css">
- <link rel="stylesheet" type="text/css" href="/static/launcher.css?v=0.0.2">
+ <link rel="stylesheet" type="text/css" href="/static/launcher.css?v=0.0.13">
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/hack-font/3.3.0/web/hack.min.css">
</head>
<body class="container-fluid">
<div id="left-panel">
<div class="user-circle">
<div class="circle">
- <p>{{ GetUserInitials .LoggedInUsername }}</p>
+ <p id="user-initial">{{ GetUserInitials .LoggedInUsername }}</p>
<div class="tooltip-user" id="tooltip-user">
<p>{{ .LoggedInUsername }}</p>
<a href="{{ .LogoutURL }}" role="button" id="logout-button">Log Out</a>
@@ -19,28 +20,26 @@
</div>
</div>
<hr class="separator">
- <div class="app-list">
+ <div class="app-list scrollbar-custom">
{{range .AllAppsInfo}}
- <div class="app-icon-tooltip" data-app-id="{{ .Id }}" data-app-url="{{ .URL }}">
- <div class="icon">
- {{.Icon}}
- </div>
- <div class="tooltip">
- <p>{{ .Name }}</p>
- {{ if .DisplayURL }}
- <p>{{ .DisplayURL }}</p>
- {{ end }}
- {{ if .Help }}
- <button class="help-button" id="help-button-{{ CleanAppName .Id }}">Help</button>
- {{ end }}
- </div>
- </div>
+ <div class="app-icon" data-app-id="{{ .Id }}" data-app-url="{{ .URL }}" {{ if not .URL }}data-modal-id="modal-{{ CleanAppName .Id }}"{{ end }}>
+ {{.Icon}}
+ </div>
+ <div class="tooltip">
+ <p>{{ .Name }}</p>
+ {{ if .DisplayURL }}
+ <p>{{ .DisplayURL }}</p>
+ {{ end }}
+ {{ if .Help }}
+ <button class="help-button" id="help-button-{{ CleanAppName .Id }}">Help</button>
+ {{ end }}
+ </div>
<dialog class="app-help-modal" id="modal-{{ CleanAppName .Id }}" close>
<article class="modal-article">
<header>
<h4>{{ .Name }}</h4>
<button class="close-button" id="close-help-{{ CleanAppName .Id }}">
- <svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" viewBox="0 0 32 32"><path fill="black" d="M16 2C8.2 2 2 8.2 2 16s6.2 14 14 14s14-6.2 14-14S23.8 2 16 2m5.4 21L16 17.6L10.6 23L9 21.4l5.4-5.4L9 10.6L10.6 9l5.4 5.4L21.4 9l1.6 1.6l-5.4 5.4l5.4 5.4z"/></svg>
+ <svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" viewBox="0 0 32 32"><path fill="#d4888d" d="M16 2C8.2 2 2 8.2 2 16s6.2 14 14 14s14-6.2 14-14S23.8 2 16 2m5.4 21L16 17.6L10.6 23L9 21.4l5.4-5.4L9 10.6L10.6 9l5.4 5.4L21.4 9l1.6 1.6l-5.4 5.4l5.4 5.4z"/></svg>
</button>
</header>
<div class="app-help-modal-article">
@@ -81,6 +80,6 @@
{{ template "help-content-template" (dict "Help" $h.Children "First" false) }}
{{ end }}
{{ end }}
- <script src="/static/launcher.js?v=0.0.3"></script>
+ <script src="/static/launcher.js?v=0.0.13"></script>
</body>
</html>
diff --git a/core/installer/welcome/static/launcher.css b/core/installer/welcome/static/launcher.css
index bc716c8..d6038f9 100644
--- a/core/installer/welcome/static/launcher.css
+++ b/core/installer/welcome/static/launcher.css
@@ -3,23 +3,32 @@
--pico-color: unset;
}
+:root {
+ --bg: #d6d6d6;
+ --bodyBg: #3a3a3a;
+ --text: #3a3a3a;
+ --formText: #d6d6d6;
+ --button: #7f9f7f;
+ --logo: #d4888d;
+ --fontSize: 14px;
+}
+
body {
margin: 0;
padding: 0;
- font-family: Arial, sans-serif;
+ font-family: Hack, monospace;
display: flex;
height: 100vh;
- padding-left: 10px !important;
- padding-right: 10px !important;
- background-color: black;
+ padding-left: 5px !important;
+ padding-right: 5px !important;
+ background-color: var(--bodyBg);
+ overflow-x: hidden;
+ overflow-y: hidden;
}
#left-panel {
width: 80px;
- background-color: #f0f0f0;
- border-radius: 10px;
- border-width: 1px;
- border-color: black;
+ background-color: var(--bg);
display: flex;
flex-direction: column;
align-items: center;
@@ -31,15 +40,50 @@
display: flex;
flex-direction: column;
align-items: center;
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding-top: 3px;
+ width: 95% !important;
+ /* scrollbar-width: thin;
+ scrollbar-color: var(--bodyBg) var(--bg); */
}
+.scrollbar-custom {
+ scrollbar-width: thin;
+ scrollbar-color: var(--bodyBg) var(--bg);
+}
+
+/* .app-list:hover::-webkit-scrollbar {
+ width: 6px;
+ scrollbar-color: var(--bodyBg) var(--bg);
+} */
+
+.scrollbar-custom::-webkit-scrollbar {
+ width: 6px;
+}
+
+.scrollbar-custom::-webkit-scrollbar-track {
+ background-color: var(--bg) !important;
+}
+
+.scrollbar-custom::-webkit-scrollbar-thumb {
+ background-color: var(--bodyBg) !important;
+ border-radius: 4px !important;
+}
+
+.scrollbar-custom::-webkit-scrollbar-thumb:hover {
+ background-color: var(--bodyBg);
+}
+
+/* .layout-scrollbar::-webkit-scrollbar-thumb:active {
+ background-color: var(--bodyBg);
+} */
+
#right-panel {
flex: 1;
- background-color: #f0f0f0;
- margin: 5px;
+ background-color: none !important;
+ margin: 5px 0 5px 5px;
padding: 2px;
- border-radius: 10px;
- border-color: black;
}
.appFrame {
@@ -49,30 +93,28 @@
border: 0;
}
-.app-icon-tooltip {
- position: relative;
- display: inline-block;
- align-items: flex-start;
+.app-icon {
+ /* position: relative; */
+ /* display: inline-block; */
+ display: flex;
+ flex-direction: column;
+ align-items: center;
justify-content: center;
- cursor: initial;
+ /* cursor: initial; */
width: 80px !important;
height: 50px !important;
margin-bottom: 10px !important;
cursor: pointer !important;
- --pico-background-color: unset !important;
- --pico-color: unset !important;
+ /* --pico-background-color: unset !important;
+ --pico-color: unset !important; */
}
.tooltip {
position: absolute;
width: 200px;
- border-radius: 0 10px 10px 0;
- top: 70%;
- left: 98%;
+ left: 90px;
transform: translateY(-50%);
- background-color: black;
- color: white;
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
+ background-color: var(--bodyBg);
padding: 5px;
z-index: 1;
display: flex;
@@ -88,56 +130,45 @@
margin-top: 5px !important;
padding: 0 !important;
border: 0 !important;
- margin-bottom: 5px !important;
+ margin-bottom: 1px !important;
width: 100% !important;
- color: white !important;
+ background-color: var(--button) !important;
+ color: var(--bodyBg) !important;
+ border-radius: 0 !important;
cursor: pointer !important;
font-size: 16px !important;
}
-.icon {
- display: flex;
- justify-content: center;
- align-items: center !important;
-}
-
.tooltip p {
- color: white;
+ color: var(--formText);
margin: 0;
cursor: auto;
+ font-size: var(--fontSize);
}
-.app-icon-tooltip:hover {
+.app-icon:hover {
transform: scale(1.15);
}
-.app-icon-tooltip .background-glow {
- position: absolute;
- top: 0;
- left: 4px;
- right: 4px;
- bottom: 0;
- background: rgba(0, 0, 0, 0);
- pointer-events: none;
- border-radius: 5px;
- box-shadow: 0px 0px 7px 7px black;
-}
-
.modal-left {
- width: 30%;
overflow-y: auto;
float: left;
margin-left: 0px;
+ padding-right: 10px;
background-color: #fbfcfc;
border-radius: 2px;
}
.modal-right {
- /* flex: 1; */
- width: 70%;
+ flex: 1;
+ /* width: 70%; */
overflow-y: auto;
float: right;
margin-left: 2px;
+ color: var(--bg);
+ padding-left: 10px;
+ padding-right: 10px;
+ font-size: 16px !important;
}
.app-help-modal {
@@ -173,6 +204,12 @@
align-items: center;
position: relative;
margin-bottom: 2px !important;
+ background-color: var(--bodyBg) !important;
+}
+
+header h4 {
+ color: var(--formText) !important;
+ padding-left: 10px;
}
.close-button {
@@ -185,7 +222,7 @@
height: 1.5em;
position: absolute;
top: 11px;
- right: 5px;
+ right: 28px;
}
.modal-article {
@@ -194,6 +231,8 @@
min-height: 90% !important;
max-height: 90% !important;
overflow: hidden;
+ padding-left: 5px !important;
+ padding-right: 5px !important;
}
.help-content {
@@ -204,19 +243,21 @@
width: 50px;
height: 50px;
border-radius: 50%;
- background-color: #ccc;
+ background-color: var(--bodyBg);
display: flex;
justify-content: center;
align-items: center;
+ margin-top: 2px;
}
-.circle p {
+#user-initial {
font-size: 24px;
text-align: center;
line-height: 50px;
margin: 0;
position: relative;
display: inline-block;
+ color: var(--logo);
}
.user-circle {
@@ -232,7 +273,7 @@
margin-top: 2px !important;
margin-bottom: 4px !important;
border-width: 2px !important;
- border-color: black !important;
+ border-color: var(--bodyBg) !important;
width: 100% !important;
}
@@ -245,7 +286,7 @@
.modal-left ul li {
list-style: none !important;
- padding-inline-start: 19px !important;
+ padding-inline-start: 10px !important;
margin-bottom: 0px;
font-size: 16px !important;
}
@@ -254,19 +295,17 @@
--pico-text-decoration: none;
cursor: pointer;
}
-
.modal-left ul li a[aria-current] {
color: var(--pico-primary);
}
.tooltip-user {
position: absolute;
- top: 54px;
- left: 90px;
+ top: 45px;
+ left: 85.5px;
transform: translateY(-50%);
width: 234px;
- background-color: black;
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
+ background-color: var(--bodyBg);
padding: 5px;
z-index: 1;
display: flex;
@@ -274,7 +313,6 @@
align-items: center;
visibility: hidden;
opacity: 0;
- border-radius: 0 0 10px 0;
cursor: auto;
}
@@ -284,9 +322,11 @@
border: 0 !important;
margin-bottom: 5px !important;
width: 100% !important;
- color: white !important;
cursor: pointer !important;
font-size: 19px !important;
+ border-radius: 0;
+ background-color: var(--button);
+ color: var(--text) !important;
}
.tooltip-user p {
@@ -294,4 +334,5 @@
margin: 0;
cursor: auto;
font-size: 19px;
+ color: var(--logo);
}
diff --git a/core/installer/welcome/static/launcher.js b/core/installer/welcome/static/launcher.js
index cbd35fd..ed54a70 100644
--- a/core/installer/welcome/static/launcher.js
+++ b/core/installer/welcome/static/launcher.js
@@ -1,74 +1,92 @@
+function showTooltip(obj) {
+ obj.style.visibility = 'visible';
+ obj.style.opacity = '1';
+}
+function hideTooltip(obj) {
+ obj.style.visibility = 'hidden';
+ obj.style.opacity = '0';
+}
+
document.addEventListener("DOMContentLoaded", function () {
document.getElementById('appFrame-default').contentDocument.write("Welcome to the dodo: application launcher, think of it as your desktop environment. You can launch applications from left-hand side dock. You should setup VPN clients on your devices, so you can install applications from Application Manager and access your private network. Instructions on how to do that can be viewed by clicking <b>Help</b> button after hovering over <b>Headscale</b> icon in the dock.");
-
- function showTooltip(obj) {
- obj.style.visibility = 'visible';
- obj.style.opacity = '1';
- }
- function hideTooltip(obj) {
- obj.style.visibility = 'hidden';
- obj.style.opacity = '0';
- }
-
+ document.getElementById('appFrame-default').style.backgroundColor = '#d6d6d6';
+ const icons = document.querySelectorAll(".app-icon");
const circle = document.querySelector(".user-circle");
const tooltipUser = document.querySelector("#tooltip-user");
- [
- ['mouseenter', () => showTooltip(tooltipUser)],
- ['mouseleave', () => hideTooltip(tooltipUser)],
- ].forEach(([event, listener]) => {
- circle.addEventListener(event, listener);
+ const initial = document.getElementById('user-initial');
+
+ circle.addEventListener('mouseenter', () => {
+ icons.forEach(icon => {
+ const tooltip = icon.nextElementSibling;
+ hideTooltip(tooltip);
+ });
+ showTooltip(tooltipUser);
+ initial.style.color = "#7f9f7f";
});
- const iframes = {};
- const rightPanel = document.getElementById('right-panel');
+ circle.addEventListener('mouseleave', () => {
+ hideTooltip(tooltipUser);
+ initial.style.color = "#d4888d";
+ });
- function showIframe(appId) {
- document.querySelectorAll('.appFrame').forEach(iframe => {
- iframe.style.display = iframe.id === `appFrame-${appId}` ? 'block' : 'none';
- });
- }
+ let hideTimeout;
+ let activeTooltip;
- function createIframe(appId, appUrl) {
- const iframe = document.createElement('iframe');
- iframe.id = `appFrame-${appId}`;
- iframe.className = 'appFrame';
- iframe.src = appUrl;
- iframe.style.display = 'none';
- rightPanel.appendChild(iframe);
- iframes[appId] = iframe;
- }
-
- const icons = document.querySelectorAll(".app-icon-tooltip");
icons.forEach(function (icon) {
icon.addEventListener("click", function (event) {
event.stopPropagation();
const appUrl = this.getAttribute("data-app-url");
const appId = this.getAttribute("data-app-id");
- if (!appUrl) {
- const modalId = `modal-${this.querySelector('.help-button').id.replace('help-button-', '')}`;
+ const modalId = this.getAttribute("data-modal-id");
+
+ if (!appUrl && modalId) {
openModal(document.getElementById(modalId));
} else {
if (!iframes[appId]) createIframe(appId, appUrl);
showIframe(appId);
- }
- document.querySelectorAll(".app-icon-tooltip .background-glow").forEach((e) => e.remove());
- const glow = document.createElement('div');
- glow.classList.add("background-glow");
- glow.setAttribute("style", "transform: none; transform-origin: 50% 50% 0px;")
- this.appendChild(glow);
+ document.querySelectorAll(".app-icon").forEach((icon) => {
+ icon.style.color = "var(--bodyBg)";
+ });
+ this.style.color = "var(--button)";
+ };
});
- const tooltip = icon.querySelector('.tooltip');
- tooltip.addEventListener("click", function (event) {
- event.stopPropagation();
- });
+
+ const tooltip = icon.nextElementSibling;
[
- ['mouseenter', () => showTooltip(tooltip)],
- ['mouseleave', () => hideTooltip(tooltip)],
- ['focus', () => showTooltip(tooltip)],
- ['blur', () => hideTooltip(tooltip)],
+ ['mouseenter', () => {
+ clearTimeout(hideTimeout);
+ if (activeTooltip && activeTooltip !== tooltip) {
+ hideTooltip(activeTooltip);
+ };
+ const rect = icon.getBoundingClientRect();
+ tooltip.style.top = `${rect.top + 26}px`;
+ showTooltip(tooltip);
+ activeTooltip = tooltip;
+ }],
+ ['mouseleave', () => {
+ hideTimeout = setTimeout(() => {
+ hideTooltip(tooltip);
+ if (activeTooltip === tooltip) {
+ activeTooltip = null;
+ };
+ }, 200);
+ }],
].forEach(([event, listener]) => {
icon.addEventListener(event, listener);
});
+
+ tooltip.addEventListener('mouseenter', () => {
+ clearTimeout(hideTimeout);
+ });
+
+ tooltip.addEventListener('mouseleave', () => {
+ hideTimeout = setTimeout(() => {
+ hideTooltip(tooltip);
+ if (activeTooltip === tooltip) {
+ activeTooltip = null;
+ };
+ }, 200);
+ });
});
let visibleModal = undefined;
@@ -77,6 +95,7 @@
modal.setAttribute("open", true);
visibleModal = modal;
};
+
const closeModal = function (modal) {
modal.removeAttribute("open");
modal.setAttribute("close", true);
@@ -84,6 +103,7 @@
};
const helpButtons = document.querySelectorAll('.help-button');
+
helpButtons.forEach(function (button) {
button.addEventListener('click', function (event) {
event.stopPropagation();
@@ -101,19 +121,33 @@
});
const modalHelpButtons = document.querySelectorAll('.title-menu');
+
modalHelpButtons.forEach(function (button) {
button.addEventListener('click', function (event) {
event.stopPropagation();
const helpTitle = button.getAttribute('id');
const helpTitleId = helpTitle.substring('title-'.length);
const helpContentId = 'help-content-' + helpTitleId;
- const allContentElements = document.querySelectorAll('.help-content');
+ let clDiv = document.getElementById(helpContentId).parentNode;
+ const allContentElements = clDiv.querySelectorAll('.help-content');
+
allContentElements.forEach(function (contentElement) {
contentElement.style.display = "none";
});
- modalHelpButtons.forEach(function (button) {
+
+ let currentHelpTitle = button;
+ while (currentHelpTitle && !currentHelpTitle.classList.contains('modal-left')) {
+ currentHelpTitle = currentHelpTitle.parentNode;
+ if (currentHelpTitle === document.body) {
+ currentHelpTitle = null;
+ break;
+ }
+ }
+
+ currentHelpTitle.querySelectorAll('.title-menu').forEach(function (button) {
button.removeAttribute("aria-current");
});
+
document.getElementById(helpContentId).style.display = 'block';
button.setAttribute("aria-current", "page");
});
@@ -126,13 +160,32 @@
});
document.addEventListener("click", (event) => {
- if (visibleModal === null) return;
+ if (visibleModal === null || visibleModal === undefined) return;
const modalContent = visibleModal.querySelector("article");
const closeButton = visibleModal.querySelector(".close-button");
if (!modalContent.contains(event.target) || closeButton.contains(event.target)) {
closeModal(visibleModal);
}
});
+
+ const iframes = {};
+ const rightPanel = document.getElementById('right-panel');
+
+ function showIframe(appId) {
+ document.querySelectorAll('.appFrame').forEach(iframe => {
+ iframe.style.display = iframe.id === `appFrame-${appId}` ? 'block' : 'none';
+ });
+ };
+
+ function createIframe(appId, appUrl) {
+ const iframe = document.createElement('iframe');
+ iframe.id = `appFrame-${appId}`;
+ iframe.className = 'appFrame';
+ iframe.src = appUrl;
+ iframe.style.display = 'none';
+ rightPanel.appendChild(iframe);
+ iframes[appId] = iframe;
+ };
});
function copyToClipboard(elem, text) {
@@ -140,7 +193,7 @@
elem.setAttribute("data-tooltip", "Copied");
elem.setAttribute("data-placement", "bottom");
setTimeout(() => {
- elem.removeAttribute("data-tooltip");
- elem.removeAttribute("data-placement");
+ elem.removeAttribute("data-tooltip");
+ elem.removeAttribute("data-placement");
}, 500);
-}
+};