Author SHA1 Message Date
jakob.scheid 4b010d03ac feat(settings): toggle sidebar on small screens when section is selected
The settings view now hides the sidebar on small screens when a settings
section is selected.
2026-08-02 13:58:37 +02:00
jakob.scheid 813cc7c7fc feat(sidebar): allow left sidebar layout content to toggle sidebar 2026-08-02 13:57:11 +02:00
jakob.scheid a77bbec3fa refactor(sidebar): rename sidebar toggling function
Renamed the sidebar toggling function in the left sidebar layout to
toggleSidebar.
2026-08-02 13:56:25 +02:00
jakob.scheidandGitea 447207e5f0 Merge pull request 'Feat(sidebar): implement sidebar toggling' (#157) from feature/expandable-sidebar into main
Deploy on dev / Deploy on dev (push) Successful in 39s
Reviewed-on: #157
Reviewed-by: Jakob Gregory
2026-07-31 21:00:19 +02:00
jakob.scheidandGitea 0939379c0a feat(sidebar): decrease horizontal padding when sidebar is not expanded
Set the horizontal padding of the unexpanded sidebar to 1em.
2026-07-31 20:59:19 +02:00
jakob.scheidandGitea 48e979ac64 fix(sidebar): fix main content displaying
Do not show main content on small screens when the sidebar is expanded.
2026-07-31 20:59:19 +02:00
jakob.scheidandGitea 0a58944157 feat(sidebar): add sidebar expand button to left sidebar layout
Added a sidebar expand button to the left sidebar layout that is shown
on small screens when the sidebar is not expanded.
2026-07-31 20:59:19 +02:00
jakob.scheidandGitea 63d9e31d29 fix(sidebar): do not show sidebar expanding button on small screens when sidebar is not expanded 2026-07-31 20:59:19 +02:00
jakob.scheidandGitea e43784bff0 feat(sidebar): implement sidebar visibility toggling 2026-07-31 20:59:19 +02:00
jakob.scheidandGitea 5b1f2b57a7 feat(sidebar): add sidebar expand button
Added a button to expand the sidebar to the sidebar and reorganized
sidebar elements accordingly.
2026-07-31 20:59:19 +02:00
jakob.scheidandGitea c70e285026 feat(icons): add sidebar expanding icon 2026-07-31 20:59:19 +02:00
jakob.scheidandGitea 8f83efb16b Merge pull request 'Fix(settings): settings validator selection setting default values array handling' (#155) from fix/settings-validator-selection-default-values-array into main
Deploy on dev / Deploy on dev (push) Successful in 36s
Reviewed-on: #155
Reviewed-by: Jakob Gregory
2026-07-31 20:58:29 +02:00
jakob.scheid f41c5c407f test(settings): add settings validator test cases
Added test cases to the settings validator unit test to test the
selection setting default value array handling when allowMultiple is
true.
2026-07-30 10:45:58 +02:00
jakob.scheid 35bfedbd6b fix(settings): expect array default values for multiple choice selections 2026-07-30 10:43:47 +02:00
4 changed files with 84 additions and 12 deletions
@@ -557,6 +557,30 @@ describe('settingsValidator', () => {
{ name: 'maybe', i18n: 'selectSomething.options.maybe' }
] }],
[{ name: 'selectMultiple', type: 'selection', i18n: 'selectMultiple.title', default: ['1', '2', '3'], allowMultiple: true, options: [
{ name: '1', i18n: 'selectMultiple.options.1' },
{ name: '2', i18n: 'selectMultiple.options.2' },
{ name: '3', i18n: 'selectMultiple.options.3' }
] }],
[{ name: 'selectMultiple', type: 'selection', i18n: 'selectMultiple.title', default: ['2', '3'], allowMultiple: true, options: [
{ name: '1', i18n: 'selectMultiple.options.1' },
{ name: '2', i18n: 'selectMultiple.options.2' },
{ name: '3', i18n: 'selectMultiple.options.3' }
] }],
[{ name: 'selectMultiple', type: 'selection', i18n: 'selectMultiple.title', default: ['2'], allowMultiple: true, options: [
{ name: '1', i18n: 'selectMultiple.options.1' },
{ name: '2', i18n: 'selectMultiple.options.2' },
{ name: '3', i18n: 'selectMultiple.options.3' }
] }],
[{ name: 'selectMultiple', type: 'selection', i18n: 'selectMultiple.title', default: [], allowMultiple: true, options: [
{ name: '1', i18n: 'selectMultiple.options.1' },
{ name: '2', i18n: 'selectMultiple.options.2' },
{ name: '3', i18n: 'selectMultiple.options.3' }
] }],
[{ name: 'aSection', type: 'section', i18n: 'sections.aSection.title', content: [] }],
[{ name: 'aSection', type: 'section', i18n: 'sections.aSection.title', content: [
{ name: 'enableFeature42', type: 'bool', i18n: 'feature.42.enable', default: true }
@@ -616,6 +640,34 @@ describe('settingsValidator', () => {
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', default: 'a', options: true }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', default: 'a', options: [] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', default: ['a'], options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', default: ['a', 'b'], options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', allowMultiple: true, default: 'a', options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', allowMultiple: true, default: 'a', options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', allowMultiple: true, default: ['c'], options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', allowMultiple: true, default: [1], options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', allowMultiple: true, default: ['a', 1], options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
] }],
[{ name: 'selectSomething', type: 'selection', i18n: 'selectSomething.title', default: 'c', options: [
{ name: 'a', i18n: 'a' },
{ name: 'b', i18n: 'b' }
@@ -73,12 +73,27 @@ export const validateEntry = function validateEntry (entry, path) {
throw new Error(`[settings] "${path}.default" must be a string`);
}
if (entry.type === 'selection') {
if (typeof entry.default !== 'string') {
throw new Error(`[settings] "${path}.default" must be a string`);
};
if (!entry.options.map((option) => option.name).includes(entry.default)) {
throw new Error(`[settings] option "${path}.default" does not exist`);
};
if (entry.allowMultiple) {
if (!Array.isArray(entry.default)) {
throw new Error(`[settings] "${path}.default" must be an array`);
}
const allOptions = entry.options.map((option) => option.name);
entry.default.forEach((defaultValue, index) => {
if (typeof defaultValue !== 'string') {
throw new Error(`[settings] "${path}.default[${index}]" must be a string`);
}
if (!allOptions.includes(defaultValue)) {
throw new Error(`[settings] option "${path}.default[${index}]" does not exist`);
}
});
} else {
if (typeof entry.default !== 'string') {
throw new Error(`[settings] "${path}.default" must be a string`);
};
if (!entry.options.map((option) => option.name).includes(entry.default)) {
throw new Error(`[settings] option "${path}.default" does not exist`);
};
}
};
}
}
+6 -1
View File
@@ -61,6 +61,10 @@ onMounted(async () => {
});
settingsLoaded.value = true;
});
const toggleSidebarIfSmallScreen = function toggleSidebarIfSmallScreen (toggleSidebarFunction) {
if (matchMedia('(max-width: 48rem)').matches) toggleSidebarFunction();
};
</script>
<template>
@@ -71,13 +75,14 @@ onMounted(async () => {
</h1>
</header>
<LeftSidebarLayout class="layout">
<template #sidebar>
<template #sidebar="{ toggleSidebar }">
<ul class="sidebar-sections-list">
<li v-for="section in settings">
<RouterLink
:to="`/settings/${section.name}`"
class="button button-link link sidebar-section"
:class="{ active: activeSection === section.name }"
@click="toggleSidebarIfSmallScreen(toggleSidebar)"
>
{{ t(section.i18n) }}
</RouterLink>
+5 -5
View File
@@ -29,7 +29,7 @@ const props = defineProps({
const expanded = ref(props.expanded);
const toggleExpanded = function toggleExpanded () {
const toggleSidebar = function toggleSidebar () {
expanded.value = !expanded.value;
};
</script>
@@ -37,13 +37,13 @@ const toggleExpanded = function toggleExpanded () {
<template>
<div class="layout-container" :class="{ expanded }">
<div class="sidebar-expand-button-container">
<SidebarExpandButton class="sidebar-expand-button" @click="toggleExpanded" />
<SidebarExpandButton class="sidebar-expand-button" @click="toggleSidebar" />
</div>
<Sidebar @toggle-expanded="toggleExpanded" :expanded="expanded" class="sidebar">
<slot name="sidebar" />
<Sidebar @toggle-expanded="toggleSidebar" :expanded="expanded" class="sidebar">
<slot name="sidebar" :toggleSidebar="toggleSidebar" />
</Sidebar>
<main class="main-content">
<slot />
<slot :toggleSidebar="toggleSidebar" />
</main>
</div>
</template>