mirror of
https://github.com/nextcloud/server.git
synced 2026-02-03 20:41:22 -05:00
Merge pull request #57791 from nextcloud/refactor/settings-navigation-vue
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Integration sqlite / changes (push) Waiting to run
Integration sqlite / integration-sqlite (master, 8.4, main, --tags ~@large files_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, capabilities_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, collaboration_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, comments_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, dav_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, federation_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, file_conversions) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, files_reminders) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, filesdrop_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, ldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_numerical_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, remoteapi_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, routing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, setup_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharees_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, theming_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, videoverification_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite-summary (push) Blocked by required conditions
Psalm static code analysis / static-code-analysis (push) Waiting to run
Psalm static code analysis / static-code-analysis-security (push) Waiting to run
Psalm static code analysis / static-code-analysis-ocp (push) Waiting to run
Psalm static code analysis / static-code-analysis-ncu (push) Waiting to run
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Integration sqlite / changes (push) Waiting to run
Integration sqlite / integration-sqlite (master, 8.4, main, --tags ~@large files_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, capabilities_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, collaboration_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, comments_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, dav_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, federation_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, file_conversions) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, files_reminders) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, filesdrop_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, ldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, openldap_numerical_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, remoteapi_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, routing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, setup_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharees_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, sharing_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, theming_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite (master, 8.4, main, videoverification_features) (push) Blocked by required conditions
Integration sqlite / integration-sqlite-summary (push) Blocked by required conditions
Psalm static code analysis / static-code-analysis (push) Waiting to run
Psalm static code analysis / static-code-analysis-security (push) Waiting to run
Psalm static code analysis / static-code-analysis-ocp (push) Waiting to run
Psalm static code analysis / static-code-analysis-ncu (push) Waiting to run
refactor(settings): use `NcAppNavigation` for the settings navigation
This commit is contained in:
commit
50cc3439af
17 changed files with 277 additions and 153 deletions
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
{"version":3,"sourceRoot":"","sources":["settings.scss","../../../core/css/variables.scss","../../../core/css/functions.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCEA;AAAA;AAAA;AAAA,GCFA;AAAA;AAAA;AAAA,GFWC,0BACC,WAKF,OACC,WAID,4BE0BC,2CFtBD,mBEsBC,kDFlBD,qBEkBC,yCFdD,0BEcC,wCFVD,oEEUC,2CFND,oCACC,oBACA,0BACA,+BACA,mBAGD,4BACC,oBACA,kCAGD,yBACC,WAIA,wCACC,kBACA,yDACC,gBAIA,mOACC,WAKH,uCACC,aAGD,sCACC,WAED,uDACC,WAKD,gBACC,WAIF,mBACC,aACA,aACA,iBACA,uEACA,gBAEA,4BACC,kBACA,SAEA,+BACC,mBAIA,qCACC,iBAKH,kCACC,sBACA,mBACA,gBAGD,mGACC,4BACA,0BACA,WAMF,oBACC,kBACA,wCACC,0BAIF,aACC,oBACA,4CACA,kFACA,8CACA,wCACA,2CACA,8CACA,6CACA,mBACA,yCAEA,sCAEC,oDAGD,+CAEC,6DACA,oDAGD,6BACC,qCACA,WACA,YAIF,6BACC,oBACA,kCAEA,mCACC,WAIA,oCACC,kBACA,oBACA,iBACA,2BACA,WACA,mBACA,QAEA,0CACC,mBACA,uBACA,gBAKD,gIACC,kBACA,qBACA,UACA,oBACA,YAKH,qCACC,kBACA,wBACA,MACA,SAEA,yCACC,qBAIF,4CACC,eAGD,4CACC,sBACA,WACA,YACA,YAMF,qBACC,aACA,sBACA,SACA,YAEA,uBACC,aAGD,uCACC,sBACA,cACA,yBAIF,gBACC,YAIA,2BACC,kCAGD,mBACC,YAIF,sCAEC,aAGD,eACC,WAGD,YACC,qBAIA,aACC,WACA,yBACA,YAGD,WACC,WACA,yBACA,YAMD,oBACC,sBAGD,iBACC,eAOD,oBACC,gBAGD,wBACC,yBAGD,oDACC,WACA,YACA,wCAOD,oBACC,UACA,cACA,gBACA,uBAGD,2BACC,UAKD,oCAEC,cAKD,wEAEC,aAIF,gBACC,kBACA,QACA,mBAEA,sBACC,YAGD,sBACC,iBAKF,WACC,WAEA,cACC,WACA,UACA,uBACA,4CACA,iBACA,mBAGD,cACC,4CACA,UACA,uBACA,iBACA,mBAKD,gBACC,0BACA,cACA,eACA,uBACA,gBAGD,wBACC,0BAEA,gCACC,kBAIF,sCACC,kBAGD,sDAEC,cACA,eACA,eAEA,0EACC,UACA,qBACA,uBACA,gBAIF,8BACC,eAGD,kCACC,wBACA,cAIF,2BACC,mBAMA,oBACC,mBACA,sBACA,WAGD,gCACC,0BAIA,gGACC,cAOH,SACC,gBAEA,0BACC,4CAID,YACC,oBACA,mBACA,uBACA,eACA,iBACA,gBACA,aAEA,uBACC,aACA,mBACA,uBACA,oCACA,qCACA,yDACA,sBACA,oCAKF,WACC,kBACA,kBACA,oCACA,gBAKF,KACC,mBACA,mBAGD,SACC,aAGD,mBACC,mBAGD,eACC,gBAIA,sBACC,aAGD,YACC,oBAGD,kBACC,0BAGD,yBACC,0BAGD,sBACC,0BAGD,oCACC,uBAIF,yCACC,uBAGD,wBACC,qBAGD,2BACC,wBAEA,gBACA,aACA,yBACA,sBAKD,WACC,kBACA,2BACA,WAGD,2DAGC,qBAIA,mCACC,qBACA,YACA,eAGD,+EAEC,YAIF,yBACC,mCACC,YACA,iBACA,cACA,iDAIF,eACC,WAGD,SACC,yBAGD,QACC,qBACA,YACA,WACA,2BAEA,gBACC,kBAIF,qBACC,sBACA,qBACA,YACA,iBAGD,kBACC,qBACA,gBAIA,aACC,sCACA,mCAGD,WACC,oCAGD,mBACC,sCACA,oBAMF,8CACC,yBACA,YAGD,wBACC,WACA,YACA,mBACA,kBACA,+DAGD,SACC,UAGD,eACC,oCACA,wBAGD,UACI,+CAGJ,2BACE,GACE,YAGJ,mCACE,GACE,WAKH,wBACC,qBACA,eACA,mCACA","file":"settings.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["settings.scss","../../../core/css/variables.scss","../../../core/css/functions.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCEA;AAAA;AAAA;AAAA,GCFA;AAAA;AAAA;AAAA,GFWC,0BACC,WAKF,OACC,WAGD,oCACC,oBACA,0BACA,+BACA,mBAGD,4BACC,oBACA,kCAGD,yBACC,WAIA,wCACC,kBACA,yDACC,gBAIA,mOACC,WAKH,uCACC,aAGD,sCACC,WAED,uDACC,WAKD,gBACC,WAIF,mBACC,aACA,aACA,iBACA,uEACA,gBAEA,4BACC,kBACA,SAEA,+BACC,mBAIA,qCACC,iBAKH,kCACC,sBACA,mBACA,gBAGD,mGACC,4BACA,0BACA,WAMF,oBACC,kBACA,wCACC,0BAIF,aACC,oBACA,4CACA,kFACA,8CACA,wCACA,2CACA,8CACA,6CACA,mBACA,yCAEA,sCAEC,oDAGD,+CAEC,6DACA,oDAGD,6BACC,qCACA,WACA,YAIF,6BACC,oBACA,kCAEA,mCACC,WAIA,oCACC,kBACA,oBACA,iBACA,2BACA,WACA,mBACA,QAEA,0CACC,mBACA,uBACA,gBAKD,gIACC,kBACA,qBACA,UACA,oBACA,YAKH,qCACC,kBACA,wBACA,MACA,SAEA,yCACC,qBAIF,4CACC,eAGD,4CACC,sBACA,WACA,YACA,YAMF,qBACC,aACA,sBACA,SACA,YAEA,uBACC,aAGD,uCACC,sBACA,cACA,yBAIF,gBACC,YAIA,2BACC,kCAGD,mBACC,YAIF,sCAEC,aAGD,eACC,WAGD,YACC,qBAIA,aACC,WACA,yBACA,YAGD,WACC,WACA,yBACA,YAMD,oBACC,sBAGD,iBACC,eAOD,oBACC,gBAGD,wBACC,yBAGD,oDACC,WACA,YACA,wCAOD,oBACC,UACA,cACA,gBACA,uBAGD,2BACC,UAIF,gBACC,kBACA,QACA,mBAEA,sBACC,YAGD,sBACC,iBAKF,WACC,WAEA,cACC,WACA,UACA,uBACA,4CACA,iBACA,mBAGD,cACC,4CACA,UACA,uBACA,iBACA,mBAKD,gBACC,0BACA,cACA,eACA,uBACA,gBAGD,wBACC,0BAEA,gCACC,kBAIF,sCACC,kBAGD,sDAEC,cACA,eACA,eAEA,0EACC,UACA,qBACA,uBACA,gBAIF,8BACC,eAGD,kCACC,wBACA,cAIF,2BACC,mBAKD,SACC,gBAEA,0BACC,4CAID,YACC,oBACA,mBACA,uBACA,eACA,iBACA,gBACA,aAEA,uBACC,aACA,mBACA,uBACA,oCACA,qCACA,yDACA,sBACA,oCAKF,WACC,kBACA,kBACA,oCACA,gBAKF,KACC,mBACA,mBAGD,SACC,aAGD,mBACC,mBAGD,eACC,gBAIA,sBACC,aAGD,YACC,oBAGD,kBACC,0BAGD,yBACC,0BAGD,sBACC,0BAGD,oCACC,uBAIF,yCACC,uBAGD,wBACC,qBAGD,2BACC,wBAEA,gBACA,aACA,yBACA,sBAKD,WACC,kBACA,2BACA,WAGD,2DAGC,qBAIA,mCACC,qBACA,YACA,eAGD,+EAEC,YAIF,yBACC,mCACC,YACA,iBACA,cACA,iDAIF,eACC,WAGD,SACC,yBAGD,QACC,qBACA,YACA,WACA,2BAEA,gBACC,kBAIF,qBACC,sBACA,qBACA,YACA,iBAGD,kBACC,qBACA,gBAIA,aACC,sCACA,mCAGD,WACC,oCAGD,mBACC,sCACA,oBAMF,8CACC,yBACA,YAGD,wBACC,WACA,YACA,mBACA,kBACA,+DAGD,SACC,UAGD,eACC,oCACA,wBAGD,UACI,+CAGJ,2BACE,GACE,YAGJ,mCACE,GACE,WAKH,wBACC,qBACA,eACA,mCACA","file":"settings.css"}
|
||||
|
|
@ -19,27 +19,6 @@ input {
|
|||
clear: both;
|
||||
}
|
||||
|
||||
/* icons for sidebar */
|
||||
.nav-icon-personal-settings {
|
||||
@include functions.icon-color('personal', 'settings', variables.$color-black);
|
||||
}
|
||||
|
||||
.nav-icon-security {
|
||||
@include functions.icon-color('toggle-filelist', 'settings', variables.$color-black);
|
||||
}
|
||||
|
||||
.nav-icon-clientsbox {
|
||||
@include functions.icon-color('change', 'settings', variables.$color-black);
|
||||
}
|
||||
|
||||
.nav-icon-federated-cloud {
|
||||
@include functions.icon-color('share', 'settings', variables.$color-black);
|
||||
}
|
||||
|
||||
.nav-icon-second-factor-backup-codes, .nav-icon-ssl-root-certificate {
|
||||
@include functions.icon-color('password', 'settings', variables.$color-black);
|
||||
}
|
||||
|
||||
#personal-settings-avatar-container {
|
||||
display: inline-grid;
|
||||
grid-template-columns: 1fr;
|
||||
|
|
@ -325,20 +304,6 @@ table.nostyle {
|
|||
}
|
||||
}
|
||||
|
||||
li.active {
|
||||
.delete,
|
||||
.rename {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.app-navigation-entry-utils {
|
||||
.delete,
|
||||
.rename {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#usersearchform {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
|
|
@ -424,26 +389,6 @@ span.usersLastLoginTooltip {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* SETTINGS NAVIGATION */
|
||||
#app-navigation {
|
||||
/* Navigation icons */
|
||||
img {
|
||||
margin-bottom: -3px;
|
||||
margin-inline-end: 6px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
li span.no-icon {
|
||||
padding-inline-start: 32px;
|
||||
}
|
||||
|
||||
ul li.active > span.utils {
|
||||
.delete, .rename {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SETTINGS SECTIONS */
|
||||
// to match with NcSettingsSection component
|
||||
.section {
|
||||
|
|
|
|||
|
|
@ -49,22 +49,10 @@ trait CommonSettingsTrait {
|
|||
/** @var IInitialState */
|
||||
private $initialState;
|
||||
|
||||
/**
|
||||
* @return array{forms: array{personal: array, admin: array}}
|
||||
*/
|
||||
private function getNavigationParameters(string $currentType, string $currentSection): array {
|
||||
return [
|
||||
'forms' => [
|
||||
'personal' => $this->formatPersonalSections($currentType, $currentSection),
|
||||
'admin' => $this->formatAdminSections($currentType, $currentSection),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IIconSection[][] $sections
|
||||
* @psalm-param 'admin'|'personal' $type
|
||||
* @return list<array{anchor: string, section-name: string, active: bool, icon: string}>
|
||||
* @return list<array{id: string, name: string, active: bool, icon: string}>
|
||||
*/
|
||||
protected function formatSections(array $sections, string $currentSection, string $type, string $currentType): array {
|
||||
$templateParameters = [];
|
||||
|
|
@ -89,8 +77,8 @@ trait CommonSettingsTrait {
|
|||
&& $type === $currentType;
|
||||
|
||||
$templateParameters[] = [
|
||||
'anchor' => $section->getID(),
|
||||
'section-name' => $section->getName(),
|
||||
'id' => $section->getID(),
|
||||
'name' => $section->getName(),
|
||||
'active' => $active,
|
||||
'icon' => $icon,
|
||||
];
|
||||
|
|
@ -99,11 +87,17 @@ trait CommonSettingsTrait {
|
|||
return $templateParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{id: string, name: string, active: bool, icon: string}>
|
||||
*/
|
||||
protected function formatPersonalSections(string $currentType, string $currentSection): array {
|
||||
$sections = $this->settingsManager->getPersonalSections();
|
||||
return $this->formatSections($sections, $currentSection, 'personal', $currentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{id: string, name: string, active: bool, icon: string}>
|
||||
*/
|
||||
protected function formatAdminSections(string $currentType, string $currentSection): array {
|
||||
$sections = $this->settingsManager->getAdminSections();
|
||||
return $this->formatSections($sections, $currentSection, 'admin', $currentType);
|
||||
|
|
@ -175,9 +169,13 @@ trait CommonSettingsTrait {
|
|||
$this->initialState->provideInitialState('declarative-settings-forms', $declarativeSettings);
|
||||
}
|
||||
|
||||
$this->initialState->provideInitialState('sections', [
|
||||
'personal' => $this->formatPersonalSections($type, $section),
|
||||
'admin' => $this->formatAdminSections($type, $section),
|
||||
]);
|
||||
|
||||
$settings = array_merge(...$settings);
|
||||
$templateParams = $this->formatSettings($settings, $declarativeSettings);
|
||||
$templateParams = array_merge($templateParams, $this->getNavigationParameters($type, $section));
|
||||
|
||||
$activeSection = $this->settingsManager->getSection($type, $section);
|
||||
if ($activeSection) {
|
||||
|
|
@ -186,6 +184,7 @@ trait CommonSettingsTrait {
|
|||
$templateParams['activeSectionType'] = $type;
|
||||
}
|
||||
|
||||
Util::addScript(Application::APP_ID, 'main', prepend: true);
|
||||
return new TemplateResponse('settings', 'settings/frame', $templateParams);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
apps/settings/src/components/SettingsNavigationItem.vue
Normal file
54
apps/settings/src/components/SettingsNavigationItem.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { computed } from 'vue'
|
||||
import NcAppNavigationItem from '@nextcloud/vue/components/NcAppNavigationItem'
|
||||
|
||||
export interface ISettingsSection {
|
||||
id: string
|
||||
name: string
|
||||
icon?: string
|
||||
active: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
section: ISettingsSection
|
||||
type: 'admin' | 'personal'
|
||||
}>()
|
||||
|
||||
const href = computed(() => generateUrl('/settings/{type}/{section}', {
|
||||
type: props.type === 'personal' ? 'user' : 'admin',
|
||||
section: props.section.id,
|
||||
}))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcAppNavigationItem
|
||||
:name="section.name"
|
||||
:active="section.active"
|
||||
:href="href">
|
||||
<template v-if="section.icon" #icon>
|
||||
<img
|
||||
:class="$style.settingsNavigationItem__icon"
|
||||
:src="section.icon"
|
||||
alt="">
|
||||
</template>
|
||||
</NcAppNavigationItem>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.settingsNavigationItem__icon {
|
||||
width: var(--default-font-size);
|
||||
height: var(--default-font-size);
|
||||
object-fit: contain;
|
||||
filter: var(--background-invert-if-dark);
|
||||
}
|
||||
|
||||
:global(.active) .settingsNavigationItem__icon {
|
||||
filter: var(--primary-invert-if-dark);
|
||||
}
|
||||
</style>
|
||||
13
apps/settings/src/main-settings.ts
Normal file
13
apps/settings/src/main-settings.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { getCSPNonce } from '@nextcloud/auth'
|
||||
import Vue from 'vue'
|
||||
import SettingsNavigation from './views/SettingsNavigation.vue'
|
||||
|
||||
__webpack_nonce__ = getCSPNonce()
|
||||
|
||||
const app = new Vue(SettingsNavigation)
|
||||
app.$mount('#app-navigation')
|
||||
51
apps/settings/src/views/SettingsNavigation.vue
Normal file
51
apps/settings/src/views/SettingsNavigation.vue
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ISettingsSection } from '../components/SettingsNavigationItem.vue'
|
||||
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import NcAppNavigation from '@nextcloud/vue/components/NcAppNavigation'
|
||||
import NcAppNavigationCaption from '@nextcloud/vue/components/NcAppNavigationCaption'
|
||||
import NcAppNavigationList from '@nextcloud/vue/components/NcAppNavigationList'
|
||||
import SettingsNavigationItem from '../components/SettingsNavigationItem.vue'
|
||||
|
||||
const {
|
||||
personal: personalSections,
|
||||
admin: adminSections,
|
||||
} = loadState<{ admin: ISettingsSection[], personal: ISettingsSection[] }>('settings', 'sections')
|
||||
const hasAdminSections = adminSections.length > 0
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcAppNavigation>
|
||||
<NcAppNavigationCaption
|
||||
heading-id="settings-personal_section_heading"
|
||||
is-heading
|
||||
:name="t('settings', 'Personal')" />
|
||||
<NcAppNavigationList aria-labelledby="settings-personal_section_heading">
|
||||
<SettingsNavigationItem
|
||||
v-for="section in personalSections"
|
||||
:key="'personal-section--' + section.id"
|
||||
:section="section"
|
||||
type="personal" />
|
||||
</NcAppNavigationList>
|
||||
|
||||
<template v-if="hasAdminSections">
|
||||
<NcAppNavigationCaption
|
||||
heading-id="settings-admin_section_heading"
|
||||
is-heading
|
||||
:name="t('settings', 'Administration')" />
|
||||
<NcAppNavigationList aria-labelledby="settings-admin_section_heading">
|
||||
<SettingsNavigationItem
|
||||
v-for="section in adminSections"
|
||||
:key="'admin-section--' + section.id"
|
||||
:section="section"
|
||||
type="admin" />
|
||||
</NcAppNavigationList>
|
||||
</template>
|
||||
</NcAppNavigation>
|
||||
</template>
|
||||
|
|
@ -7,61 +7,7 @@
|
|||
style('settings', 'settings');
|
||||
?>
|
||||
|
||||
<div id="app-navigation">
|
||||
<?php if (!empty($_['forms']['admin'])): ?>
|
||||
<div id="app-navigation-caption-personal" class="app-navigation-caption"><?php p($l->t('Personal')); ?></div>
|
||||
<?php endif; ?>
|
||||
<nav class="app-navigation-personal" aria-labelledby="app-navigation-caption-personal">
|
||||
<ul>
|
||||
<?php foreach ($_['forms']['personal'] as $form) {
|
||||
if (isset($form['anchor'])) {
|
||||
$anchor = \OCP\Server::get(\OCP\IURLGenerator::class)->linkToRoute('settings.PersonalSettings.index', ['section' => $form['anchor']]);
|
||||
$class = 'nav-icon-' . $form['anchor'];
|
||||
$sectionName = $form['section-name']; ?>
|
||||
<li <?php print_unescaped($form['active'] ? ' class="active"' : ''); ?> data-section-id="<?php print_unescaped($form['anchor']); ?>" data-section-type="personal">
|
||||
<a href="<?php p($anchor); ?>"<?php print_unescaped($form['active'] ? ' aria-current="page"' : ''); ?>>
|
||||
<?php if (!empty($form['icon'])) { ?>
|
||||
<img alt="" src="<?php print_unescaped($form['icon']); ?>">
|
||||
<span><?php p($form['section-name']); ?></span>
|
||||
<?php } else { ?>
|
||||
<span class="no-icon"><?php p($form['section-name']); ?></span>
|
||||
<?php } ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<?php if (!empty($_['forms']['admin'])): ?>
|
||||
<div id="app-navigation-caption-administration" class="app-navigation-caption"><?php p($l->t('Administration')); ?></div>
|
||||
<?php endif; ?>
|
||||
<nav class="app-navigation-administration" aria-labelledby="app-navigation-caption-administration">
|
||||
<ul>
|
||||
<?php foreach ($_['forms']['admin'] as $form) {
|
||||
if (isset($form['anchor'])) {
|
||||
$anchor = \OCP\Server::get(\OCP\IURLGenerator::class)->linkToRoute('settings.AdminSettings.index', ['section' => $form['anchor']]);
|
||||
$class = 'nav-icon-' . $form['anchor'];
|
||||
$sectionName = $form['section-name']; ?>
|
||||
<li <?php print_unescaped($form['active'] ? ' class="active"' : ''); ?> data-section-id="<?php print_unescaped($form['anchor']); ?>" data-section-type="admin">
|
||||
<a href="<?php p($anchor); ?>"<?php print_unescaped($form['active'] ? ' aria-current="page"' : ''); ?>>
|
||||
<?php if (!empty($form['icon'])) { ?>
|
||||
<img alt="" src="<?php print_unescaped($form['icon']); ?>">
|
||||
<span><?php p($form['section-name']); ?></span>
|
||||
<?php } else { ?>
|
||||
<span class="no-icon"><?php p($form['section-name']); ?></span>
|
||||
<?php } ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div id="app-navigation"></div>
|
||||
<main id="app-content" <?php if (!empty($_['activeSectionId'])) { ?> data-active-section-id="<?php print_unescaped($_['activeSectionId']) ?>" <?php } if (!empty($_['activeSectionType'])) { ?> data-active-section-type="<?php print_unescaped($_['activeSectionType']) ?>" <?php } ?>>
|
||||
<?php print_unescaped($_['content']); ?>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -122,12 +122,23 @@ class AdminSettingsControllerTest extends TestCase {
|
|||
->with($user, 'admin', 'test')
|
||||
->willReturn([]);
|
||||
|
||||
$idx = $this->adminSettingsController->index('test');
|
||||
$initialState = [];
|
||||
$this->initialState->expects(self::atLeastOnce())
|
||||
->method('provideInitialState')
|
||||
->willReturnCallback(function () use (&$initialState) {
|
||||
$initialState[] = func_get_args();
|
||||
});
|
||||
|
||||
$expected = new TemplateResponse('settings', 'settings/frame', [
|
||||
'forms' => ['personal' => [], 'admin' => []],
|
||||
'content' => ''
|
||||
]);
|
||||
$this->assertEquals($expected, $idx);
|
||||
$expected = new TemplateResponse(
|
||||
'settings',
|
||||
'settings/frame',
|
||||
[
|
||||
'content' => ''
|
||||
],
|
||||
);
|
||||
$this->assertEquals($expected, $this->adminSettingsController->index('test'));
|
||||
$this->assertEquals([
|
||||
['sections', ['admin' => [], 'personal' => []]],
|
||||
], $initialState);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ module.exports = {
|
|||
'public-nickname-handler': path.join(__dirname, 'apps/files_sharing/src', 'public-nickname-handler.ts'),
|
||||
},
|
||||
settings: {
|
||||
main: path.join(__dirname, 'apps/settings/src', 'main-settings.ts'),
|
||||
'vue-settings-admin-overview': path.join(__dirname, 'apps/settings/src', 'main-admin-overview.ts'),
|
||||
'vue-settings-admin-basic-settings': path.join(__dirname, 'apps/settings/src', 'main-admin-basic-settings.js'),
|
||||
'vue-settings-admin-ai': path.join(__dirname, 'apps/settings/src', 'main-admin-ai.js'),
|
||||
|
|
|
|||
|
|
@ -28,15 +28,18 @@ describe('Settings: Ensure only administrator can see the administration setting
|
|||
.click()
|
||||
cy.url().should('match', /\/settings\/user$/)
|
||||
|
||||
cy.get('#app-navigation').should('be.visible').within(() => {
|
||||
// I see the personal section is NOT shown
|
||||
cy.get('#app-navigation-caption-personal').should('not.exist')
|
||||
// I see the admin section is NOT shown
|
||||
cy.get('#app-navigation-caption-administration').should('not.exist')
|
||||
cy.findAllByRole('navigation')
|
||||
.filter('#app-navigation-vue')
|
||||
.as('appNavigation')
|
||||
.findByRole('list', { name: 'Personal' })
|
||||
.should('be.visible')
|
||||
.findByRole('link', { name: /Personal info/i })
|
||||
.should('be.visible')
|
||||
.and('have.attr', 'aria-current', 'page')
|
||||
|
||||
// I see that the "Personal info" entry in the settings panel is shown
|
||||
cy.get('[data-section-id="personal-info"]').should('exist').and('be.visible')
|
||||
})
|
||||
cy.get('@appNavigation')
|
||||
.findByRole('list', { name: 'Administration' })
|
||||
.should('not.exist')
|
||||
})
|
||||
|
||||
it('Admin users can see admin-level items on the Settings page', () => {
|
||||
|
|
@ -52,14 +55,19 @@ describe('Settings: Ensure only administrator can see the administration setting
|
|||
.click()
|
||||
cy.url().should('match', /\/settings\/user$/)
|
||||
|
||||
cy.get('#app-navigation').should('be.visible').within(() => {
|
||||
// I see the personal section is shown
|
||||
cy.get('#app-navigation-caption-personal').should('be.visible')
|
||||
// I see the admin section is shown
|
||||
cy.get('#app-navigation-caption-administration').should('be.visible')
|
||||
cy.findAllByRole('navigation')
|
||||
.filter('#app-navigation-vue')
|
||||
.as('appNavigation')
|
||||
.findByRole('list', { name: 'Personal' })
|
||||
.should('be.visible')
|
||||
.findByRole('link', { name: /Personal info/i })
|
||||
.should('be.visible')
|
||||
.and('have.attr', 'aria-current', 'page')
|
||||
|
||||
// I see that the "Personal info" entry in the settings panel is shown
|
||||
cy.get('[data-section-id="personal-info"]').should('exist').and('be.visible')
|
||||
})
|
||||
cy.get('@appNavigation')
|
||||
.findByRole('list', { name: 'Administration' })
|
||||
.should('be.visible')
|
||||
.findByRole('link', { name: /Overview/i })
|
||||
.should('be.visible')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
4
dist/core-common.js
vendored
4
dist/core-common.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-common.js.map
vendored
2
dist/core-common.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/settings-main.js
vendored
Normal file
2
dist/settings-main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
92
dist/settings-main.js.license
vendored
Normal file
92
dist/settings-main.js.license
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
SPDX-License-Identifier: MIT
|
||||
SPDX-License-Identifier: ISC
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
SPDX-License-Identifier: (MPL-2.0 OR Apache-2.0)
|
||||
SPDX-FileCopyrightText: escape-html developers
|
||||
SPDX-FileCopyrightText: Tobias Koppers @sokra
|
||||
SPDX-FileCopyrightText: Roman Shtylman <shtylman@gmail.com>
|
||||
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
||||
SPDX-FileCopyrightText: Guillaume Chau <guillaume.b.chau@gmail.com>
|
||||
SPDX-FileCopyrightText: GitHub Inc.
|
||||
SPDX-FileCopyrightText: Evan You
|
||||
SPDX-FileCopyrightText: Dr.-Ing. Mario Heiderich, Cure53 <mario@cure53.de> (https://cure53.de/)
|
||||
SPDX-FileCopyrightText: David Clark
|
||||
SPDX-FileCopyrightText: Christoph Wurst
|
||||
SPDX-FileCopyrightText: Anthony Fu <https://github.com/antfu>
|
||||
SPDX-FileCopyrightText: Anthony Fu <anthonyfu117@hotmail.com>
|
||||
|
||||
|
||||
This file is generated from multiple sources. Included packages:
|
||||
- @nextcloud/auth
|
||||
- version: 2.5.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/browser-storage
|
||||
- version: 0.5.0
|
||||
- license: GPL-3.0-or-later
|
||||
- semver
|
||||
- version: 7.7.2
|
||||
- license: ISC
|
||||
- @nextcloud/event-bus
|
||||
- version: 3.3.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/initial-state
|
||||
- version: 3.0.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/l10n
|
||||
- version: 3.4.1
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/logger
|
||||
- version: 3.0.3
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/router
|
||||
- version: 3.1.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/vue
|
||||
- version: 8.35.3
|
||||
- license: AGPL-3.0-or-later
|
||||
- @vueuse/core
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- @vueuse/shared
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- css-loader
|
||||
- version: 7.1.2
|
||||
- license: MIT
|
||||
- dompurify
|
||||
- version: 3.3.1
|
||||
- license: (MPL-2.0 OR Apache-2.0)
|
||||
- escape-html
|
||||
- version: 1.0.3
|
||||
- license: MIT
|
||||
- floating-vue
|
||||
- version: 1.0.0-beta.19
|
||||
- license: MIT
|
||||
- focus-trap
|
||||
- version: 7.8.0
|
||||
- license: MIT
|
||||
- process
|
||||
- version: 0.11.10
|
||||
- license: MIT
|
||||
- style-loader
|
||||
- version: 4.0.0
|
||||
- license: MIT
|
||||
- tabbable
|
||||
- version: 6.4.0
|
||||
- license: MIT
|
||||
- vue-demi
|
||||
- version: 0.14.10
|
||||
- license: MIT
|
||||
- vue-loader
|
||||
- version: 15.11.1
|
||||
- license: MIT
|
||||
- vue
|
||||
- version: 2.7.16
|
||||
- license: MIT
|
||||
- webpack
|
||||
- version: 5.104.1
|
||||
- license: MIT
|
||||
- nextcloud
|
||||
- version: 1.0.0
|
||||
- license: AGPL-3.0-or-later
|
||||
1
dist/settings-main.js.map
vendored
Normal file
1
dist/settings-main.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/settings-main.js.map.license
vendored
Symbolic link
1
dist/settings-main.js.map.license
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
settings-main.js.license
|
||||
Loading…
Reference in a new issue