Merge branch 'next' into test-themes
This commit is contained in:
commit
684e12d2b9
|
|
@ -19,7 +19,9 @@
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
<div id="layout">
|
<div id="layout">
|
||||||
<Sidebar ref="sidebar" id = "mainnav" v-if="showNavigation" />
|
<Navigation ref="navigation" id="mainnav" v-if="showNavigation">
|
||||||
|
<Sidebar ref="sidebar" id = "mainnav" v-if="showNavigation" />
|
||||||
|
</Navigation>
|
||||||
|
|
||||||
<div id="content" initial-martial-complete="{{ hasLoaded }}">
|
<div id="content" initial-martial-complete="{{ hasLoaded }}">
|
||||||
<main title="Main content">
|
<main title="Main content">
|
||||||
|
|
@ -77,6 +79,7 @@
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import Sidebar from 'picocrank/vue/components/Sidebar.vue';
|
import Sidebar from 'picocrank/vue/components/Sidebar.vue';
|
||||||
|
import Navigation from 'picocrank/vue/components/Navigation.vue';
|
||||||
import Header from 'picocrank/vue/components/Header.vue';
|
import Header from 'picocrank/vue/components/Header.vue';
|
||||||
import { HugeiconsIcon } from '@hugeicons/vue'
|
import { HugeiconsIcon } from '@hugeicons/vue'
|
||||||
import { Menu01Icon } from '@hugeicons/core-free-icons'
|
import { Menu01Icon } from '@hugeicons/core-free-icons'
|
||||||
|
|
@ -91,6 +94,7 @@ const { t, locale } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const sidebar = ref(null);
|
const sidebar = ref(null);
|
||||||
|
const navigation = ref(null);
|
||||||
const username = ref('notset');
|
const username = ref('notset');
|
||||||
const isLoggedIn = ref(false);
|
const isLoggedIn = ref(false);
|
||||||
const serverConnection = ref(true);
|
const serverConnection = ref(true);
|
||||||
|
|
@ -181,7 +185,7 @@ function updateHeaderFromInit() {
|
||||||
showLoginLink.value = false
|
showLoginLink.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSidebar()
|
renderNavigation()
|
||||||
|
|
||||||
if (window.initResponse.loginRequired) {
|
if (window.initResponse.loginRequired) {
|
||||||
router.push('/login')
|
router.push('/login')
|
||||||
|
|
@ -189,19 +193,19 @@ function updateHeaderFromInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSidebar() {
|
function renderNavigation() {
|
||||||
if (!sidebar.value) {
|
if (!navigation.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootDashboards = window.initResponse?.rootDashboards || []
|
const rootDashboards = window.initResponse?.rootDashboards || []
|
||||||
|
|
||||||
if (typeof sidebar.value.clear === 'function') {
|
if (typeof navigation.value.clear === 'function') {
|
||||||
sidebar.value.clear()
|
navigation.value.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const rootDashboard of rootDashboards) {
|
for (const rootDashboard of rootDashboards) {
|
||||||
sidebar.value.addNavigationLink({
|
navigation.value.addNavigationLink({
|
||||||
id: rootDashboard,
|
id: rootDashboard,
|
||||||
name: rootDashboard,
|
name: rootDashboard,
|
||||||
title: rootDashboard,
|
title: rootDashboard,
|
||||||
|
|
@ -210,15 +214,15 @@ function renderSidebar() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebar.value.addSeparator()
|
navigation.value.addSeparator()
|
||||||
sidebar.value.addRouterLink('Entities', t('nav.entities'))
|
navigation.value.addRouterLink('Entities', t('nav.entities'))
|
||||||
|
|
||||||
if (showLogs.value) {
|
if (showLogs.value) {
|
||||||
sidebar.value.addRouterLink('Logs', t('nav.logs'))
|
navigation.value.addRouterLink('Logs', t('nav.logs'))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showDiagnostics.value) {
|
if (showDiagnostics.value) {
|
||||||
sidebar.value.addRouterLink('Diagnostics', t('nav.diagnostics'))
|
navigation.value.addRouterLink('Diagnostics', t('nav.diagnostics'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,9 +261,9 @@ function changeLanguage() {
|
||||||
languagePreference.value = selectedLanguage.value
|
languagePreference.value = selectedLanguage.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update sidebar with new translations
|
// Update navigation with new translations
|
||||||
if (sidebar.value) {
|
if (navigation.value) {
|
||||||
renderSidebar()
|
renderNavigation()
|
||||||
}
|
}
|
||||||
|
|
||||||
closeLanguageDialog()
|
closeLanguageDialog()
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<button @click="navigateToDirectory">
|
<button @click="navigateToDirectory">
|
||||||
{{ component.title }}
|
<span class="icon" v-html="unicodeIcon"></span>
|
||||||
|
<span class="title">{{ component.title }}</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
|
@ -16,6 +18,18 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getUnicodeIcon(icon) {
|
||||||
|
if (icon === '' || !icon) {
|
||||||
|
return '📁' // Default folder icon
|
||||||
|
} else {
|
||||||
|
return unescape(icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unicodeIcon = computed(() => {
|
||||||
|
return getUnicodeIcon(props.component.icon)
|
||||||
|
})
|
||||||
|
|
||||||
function navigateToDirectory() {
|
function navigateToDirectory() {
|
||||||
const params = { title: props.component.title }
|
const params = { title: props.component.title }
|
||||||
|
|
||||||
|
|
@ -34,9 +48,18 @@ function navigateToDirectory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.5em;
|
||||||
box-shadow: 0 0 .6em #aaa;
|
box-shadow: 0 0 .6em #aaa;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: .7em;
|
border-radius: .7em;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
font-size: .85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
|
|
@ -44,16 +67,30 @@ button:hover {
|
||||||
border-color: #999;
|
border-color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button .icon {
|
||||||
|
font-size: 3em;
|
||||||
|
flex-grow: 1;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button .title {
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
button {
|
button {
|
||||||
box-shadow: 0 0 .6em #000;
|
box-shadow: 0 0 .6em #000;
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
border-color: #000;
|
border-color: #000;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
border-color: #000;
|
border-color: #000;
|
||||||
|
box-shadow: 0 0 6px #444;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -263,10 +263,21 @@ func (h *OAuth2Handler) HandleOAuthCallback(w http.ResponseWriter, r *http.Reque
|
||||||
Timeout: clientSettings.Timeout,
|
Timeout: clientSettings.Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
userinfo := getUserInfo(h.cfg, userInfoClient, h.cfg.AuthOAuth2Providers[registeredState.providerName])
|
userinfo := getUserInfo(h.cfg, userInfoClient, providerConfig)
|
||||||
|
|
||||||
h.registeredStates[state].Username = userinfo.Username
|
h.registeredStates[state].Username = userinfo.Username
|
||||||
h.registeredStates[state].Usergroup = userinfo.Usergroup
|
|
||||||
|
usergroup := userinfo.Usergroup
|
||||||
|
if providerConfig != nil && providerConfig.AddToUsergroup != "" {
|
||||||
|
// Append configured usergroup name if addToUsergroup is set
|
||||||
|
if usergroup != "" {
|
||||||
|
usergroup = usergroup + " " + providerConfig.AddToUsergroup
|
||||||
|
} else {
|
||||||
|
usergroup = providerConfig.AddToUsergroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h.registeredStates[state].Usergroup = usergroup
|
||||||
|
|
||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ type OAuth2Provider struct {
|
||||||
InsecureSkipVerify bool `koanf:"insecureSkipVerify"`
|
InsecureSkipVerify bool `koanf:"insecureSkipVerify"`
|
||||||
CallbackTimeout int `koanf:"callbackTimeout"`
|
CallbackTimeout int `koanf:"callbackTimeout"`
|
||||||
CertBundlePath string `koanf:"certBundlePath"`
|
CertBundlePath string `koanf:"certBundlePath"`
|
||||||
|
AddToUsergroup string `koanf:"addToUsergroup"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NavigationLink struct {
|
type NavigationLink struct {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue