mirror of
https://github.com/nextcloud/server.git
synced 2026-04-20 22:00:39 -04:00
Merge pull request #54570 from nextcloud/artonge/feat/add_preset_selection_in_settings
This commit is contained in:
commit
896fb2fcb5
39 changed files with 679 additions and 34 deletions
File diff suppressed because one or more lines are too long
|
|
@ -29,6 +29,7 @@
|
|||
<settings>
|
||||
<admin>OCA\Settings\Settings\Admin\Mail</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Overview</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Presets</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\ArtificialIntelligence</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Server</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Sharing</admin>
|
||||
|
|
@ -39,6 +40,7 @@
|
|||
<admin-section>OCA\Settings\Sections\Admin\Delegation</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Groupware</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Overview</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Presets</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\ArtificialIntelligence</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Security</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Server</admin-section>
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ return array(
|
|||
'OCA\\Settings\\Sections\\Admin\\Delegation' => $baseDir . '/../lib/Sections/Admin/Delegation.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Groupware' => $baseDir . '/../lib/Sections/Admin/Groupware.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Overview' => $baseDir . '/../lib/Sections/Admin/Overview.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Presets' => $baseDir . '/../lib/Sections/Admin/Presets.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Security' => $baseDir . '/../lib/Sections/Admin/Security.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Server' => $baseDir . '/../lib/Sections/Admin/Server.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Sharing' => $baseDir . '/../lib/Sections/Admin/Sharing.php',
|
||||
|
|
@ -71,6 +72,7 @@ return array(
|
|||
'OCA\\Settings\\Settings\\Admin\\Mail' => $baseDir . '/../lib/Settings/Admin/Mail.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\MailProvider' => $baseDir . '/../lib/Settings/Admin/MailProvider.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Overview' => $baseDir . '/../lib/Settings/Admin/Overview.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Presets' => $baseDir . '/../lib/Settings/Admin/Presets.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Security' => $baseDir . '/../lib/Settings/Admin/Security.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Server' => $baseDir . '/../lib/Settings/Admin/Server.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Sharing' => $baseDir . '/../lib/Settings/Admin/Sharing.php',
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ class ComposerStaticInitSettings
|
|||
'OCA\\Settings\\Sections\\Admin\\Delegation' => __DIR__ . '/..' . '/../lib/Sections/Admin/Delegation.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Groupware' => __DIR__ . '/..' . '/../lib/Sections/Admin/Groupware.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Overview' => __DIR__ . '/..' . '/../lib/Sections/Admin/Overview.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Presets' => __DIR__ . '/..' . '/../lib/Sections/Admin/Presets.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Security' => __DIR__ . '/..' . '/../lib/Sections/Admin/Security.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Server' => __DIR__ . '/..' . '/../lib/Sections/Admin/Server.php',
|
||||
'OCA\\Settings\\Sections\\Admin\\Sharing' => __DIR__ . '/..' . '/../lib/Sections/Admin/Sharing.php',
|
||||
|
|
@ -86,6 +87,7 @@ class ComposerStaticInitSettings
|
|||
'OCA\\Settings\\Settings\\Admin\\Mail' => __DIR__ . '/..' . '/../lib/Settings/Admin/Mail.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\MailProvider' => __DIR__ . '/..' . '/../lib/Settings/Admin/MailProvider.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Overview' => __DIR__ . '/..' . '/../lib/Settings/Admin/Overview.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Presets' => __DIR__ . '/..' . '/../lib/Settings/Admin/Presets.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Security' => __DIR__ . '/..' . '/../lib/Settings/Admin/Security.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Server' => __DIR__ . '/..' . '/../lib/Settings/Admin/Server.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Sharing' => __DIR__ . '/..' . '/../lib/Settings/Admin/Sharing.php',
|
||||
|
|
|
|||
1
apps/settings/img/library_add_check.svg
Normal file
1
apps/settings/img/library_add_check.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368\"><path d="m508-398 226-226-56-58-170 170-86-84-56 56 142 142ZM320-240q-33 0-56.5-23.5T240-320v-480q0-33 23.5-56.5T320-880h480q33 0 56.5 23.5T880-800v480q0 33-23.5 56.5T800-240H320Zm0-80h480v-480H320v480ZM160-80q-33 0-56.5-23.5T80-160v-560h80v560h560v80H160Zm160-720v480-480Z"/></svg>
|
||||
|
After Width: | Height: | Size: 390 B |
38
apps/settings/lib/Sections/Admin/Presets.php
Normal file
38
apps/settings/lib/Sections/Admin/Presets.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Settings\Sections\Admin;
|
||||
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Settings\IIconSection;
|
||||
|
||||
class Presets implements IIconSection {
|
||||
|
||||
public function __construct(
|
||||
private IL10N $l,
|
||||
private IURLGenerator $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getIcon(): string {
|
||||
return $this->urlGenerator->imagePath('settings', 'library_add_check.svg');
|
||||
}
|
||||
|
||||
public function getID(): string {
|
||||
return 'presets';
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->l->t('Settings presets');
|
||||
}
|
||||
|
||||
public function getPriority(): int {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
54
apps/settings/lib/Settings/Admin/Presets.php
Normal file
54
apps/settings/lib/Settings/Admin/Presets.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Settings\Settings\Admin;
|
||||
|
||||
use OC\Config\PresetManager;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Services\IInitialState;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\ServerVersion;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class Presets implements ISettings {
|
||||
public function __construct(
|
||||
private ServerVersion $serverVersion,
|
||||
private IConfig $config,
|
||||
private IL10N $l,
|
||||
private readonly PresetManager $presetManager,
|
||||
private IInitialState $initialState,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getForm() {
|
||||
$presets = $this->presetManager->retrieveLexiconPreset();
|
||||
$selectedPreset = $this->presetManager->getLexiconPreset();
|
||||
$presetsApps = $this->presetManager->retrieveLexiconPresetApps();
|
||||
|
||||
$this->initialState->provideInitialState('settings-selected-preset', $selectedPreset->name);
|
||||
$this->initialState->provideInitialState('settings-presets', $presets);
|
||||
$this->initialState->provideInitialState('settings-presets-apps', $presetsApps);
|
||||
|
||||
return new TemplateResponse('settings', 'settings/admin/presets', [], '');
|
||||
}
|
||||
|
||||
public function getSection() {
|
||||
return 'presets';
|
||||
}
|
||||
|
||||
public function getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->l->t('Settings presets');
|
||||
}
|
||||
|
||||
public function getAuthorizedAppConfig(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
|
||||
|
||||
import type { PresetAppConfig, PresetAppConfigs, PresetAppsStates, PresetIds } from './models.ts'
|
||||
|
||||
const applicationsStates = loadState('settings', 'settings-presets-apps', {}) as PresetAppsStates
|
||||
|
||||
const props = defineProps({
|
||||
presets: {
|
||||
type: Object as () => PresetAppConfigs,
|
||||
required: true,
|
||||
},
|
||||
selectedPreset: {
|
||||
type: String as () => PresetIds,
|
||||
default: 'NONE',
|
||||
},
|
||||
})
|
||||
|
||||
const appsConfigPresets = Object.entries(props.presets)
|
||||
.map(([appId, presets]) => [appId, presets.filter(configPreset => configPreset.config === 'app')])
|
||||
.filter(([, presets]) => presets.length > 0) as [string, PresetAppConfig[]][]
|
||||
const userConfigPresets = Object.entries(props.presets)
|
||||
.map(([appId, presets]) => [appId, presets.filter(configPreset => configPreset.config === 'user')])
|
||||
.filter(([, presets]) => presets.length > 0) as [string, PresetAppConfig[]][]
|
||||
|
||||
const hasApplicationsPreset = computed(() => applicationsStates[props.selectedPreset].enabled.length > 0 || applicationsStates[props.selectedPreset].disabled.length > 0)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="presets">
|
||||
<h3 class="presets__title">
|
||||
{{ t('settings', 'Default config values') }}
|
||||
</h3>
|
||||
|
||||
<div v-if="appsConfigPresets.length > 0" class="presets__config-list">
|
||||
<h4 class="presets__config-list__subtitle">
|
||||
{{ t('settings', 'Applications config') }}
|
||||
</h4>
|
||||
<template v-for="[appId, appConfigPresets] in appsConfigPresets">
|
||||
<div v-for="configPreset in appConfigPresets"
|
||||
:key="appId + '-' + configPreset.entry.key"
|
||||
class="presets__config-list__item">
|
||||
<span>
|
||||
<div>{{ configPreset.entry.definition }}</div>
|
||||
<code class="presets__config-list__item__key">{{ configPreset.entry.key }}</code>
|
||||
</span>
|
||||
<span>
|
||||
<NcCheckboxRadioSwitch v-if="configPreset.entry.type === 'BOOL'"
|
||||
:model-value="configPreset.defaults[selectedPreset] === '1'"
|
||||
:disabled="true" />
|
||||
<code v-else>{{ configPreset.defaults[selectedPreset] }}</code>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="userConfigPresets.length > 0" class="presets__config-list">
|
||||
<h4 class="presets__config-list__subtitle">
|
||||
{{ t('settings', 'User config') }}
|
||||
</h4>
|
||||
<template v-for="[appId, userPresets] in userConfigPresets">
|
||||
<div v-for="configPreset in userPresets"
|
||||
:key="appId + '-' + configPreset.entry.key"
|
||||
class="presets__config-list__item">
|
||||
<span>
|
||||
<div>{{ configPreset.entry.definition }}</div>
|
||||
<code class="presets__config-list__item__key">{{ configPreset.entry.key }}</code>
|
||||
</span>
|
||||
<span>
|
||||
<NcCheckboxRadioSwitch v-if="configPreset.entry.type === 'BOOL'"
|
||||
:model-value="configPreset.defaults[selectedPreset] === '1'"
|
||||
:disabled="true" />
|
||||
<code v-else>{{ configPreset.defaults[selectedPreset] }}</code>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<template v-if="hasApplicationsPreset">
|
||||
<h3 class="presets__title">
|
||||
{{ t('settings', 'Bundled applications') }}
|
||||
</h3>
|
||||
|
||||
<div class="presets__app-list">
|
||||
<div class="presets__app-list__enabled">
|
||||
<h4 class="presets__app-list__title">
|
||||
{{ t('settings', 'Enabled applications') }}
|
||||
</h4>
|
||||
<ul>
|
||||
<li v-for="applicationId in applicationsStates[selectedPreset].enabled"
|
||||
:key="applicationId">
|
||||
{{ applicationId }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="presets__app-list__disabled">
|
||||
<h4 class="presets__app-list__title">
|
||||
{{ t('settings', 'Disabled applications') }}
|
||||
</h4>
|
||||
<ul>
|
||||
<li v-for="applicationId in applicationsStates[selectedPreset].disabled"
|
||||
:key="applicationId">
|
||||
{{ applicationId }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.presets {
|
||||
margin-top: 16px;
|
||||
|
||||
&__title {
|
||||
font-size: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&__config-list {
|
||||
margin-top: 8px;
|
||||
width: 55%;
|
||||
|
||||
&__subtitle {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 2px 0;
|
||||
|
||||
&__key {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-maxcontrast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__app-list {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
|
||||
&__title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import Domain from 'vue-material-design-icons/Domain.vue'
|
||||
import CloudCircleOutline from 'vue-material-design-icons/CloudCircleOutline.vue'
|
||||
import SchoolOutline from 'vue-material-design-icons/SchoolOutline.vue'
|
||||
import Crowd from 'vue-material-design-icons/Crowd.vue'
|
||||
import AccountGroupOutline from 'vue-material-design-icons/AccountGroupOutline.vue'
|
||||
import AccountOutline from 'vue-material-design-icons/AccountOutline.vue'
|
||||
import MinusCircleOutline from 'vue-material-design-icons/MinusCircleOutline.vue'
|
||||
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
|
||||
|
||||
import { type PresetAppConfigs, type PresetIds } from './models.ts'
|
||||
|
||||
const PresetNames = {
|
||||
LARGE: t('settings', 'Large organization'),
|
||||
MEDIUM: t('settings', 'Big organization'),
|
||||
SMALL: t('settings', 'Small organization'),
|
||||
SHARED: t('settings', 'Hosting company'),
|
||||
UNIVERSITY: t('settings', 'University'),
|
||||
SCHOOL: t('settings', 'School'),
|
||||
CLUB: t('settings', 'Club or association'),
|
||||
FAMILY: t('settings', 'Family'),
|
||||
PRIVATE: t('settings', 'Personal use'),
|
||||
NONE: t('settings', 'Default'),
|
||||
}
|
||||
|
||||
const PresetsIcons = {
|
||||
LARGE: Domain,
|
||||
MEDIUM: Domain,
|
||||
SMALL: Domain,
|
||||
SHARED: CloudCircleOutline,
|
||||
UNIVERSITY: SchoolOutline,
|
||||
SCHOOL: SchoolOutline,
|
||||
CLUB: AccountGroupOutline,
|
||||
FAMILY: Crowd,
|
||||
PRIVATE: AccountOutline,
|
||||
NONE: MinusCircleOutline,
|
||||
}
|
||||
|
||||
defineProps({
|
||||
presets: {
|
||||
type: Object as () => PresetAppConfigs,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
type: String as () => PresetIds,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'input', option: string): void
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form class="presets-form">
|
||||
<label v-for="(presetName, presetId) in PresetNames"
|
||||
:key="presetId"
|
||||
class="presets-form__option">
|
||||
|
||||
<components :is="PresetsIcons[presetId]" :size="32" />
|
||||
|
||||
<NcCheckboxRadioSwitch type="radio"
|
||||
:model-value="value"
|
||||
:value="presetId"
|
||||
name="preset"
|
||||
@update:modelValue="emit('input', presetId)" />
|
||||
|
||||
<span class="presets-form__option__name">{{ presetName }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.presets-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
margin-top: 32px;
|
||||
|
||||
&__option {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
width: 250px;
|
||||
min-height: 100px;
|
||||
padding: 16px;
|
||||
border-radius: var(--border-radius-large);
|
||||
background-color: var(--color-background-dark);
|
||||
font-size: 20px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-darker);
|
||||
}
|
||||
|
||||
&:has(input[type=radio]:checked) {
|
||||
border: 2px solid var(--color-main-text);
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
&__name {
|
||||
flex-basis: 250px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
&__name, .material-design-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
31
apps/settings/src/components/SettingsPresets/models.ts
Normal file
31
apps/settings/src/components/SettingsPresets/models.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
type PresetAppConfigEntry = {
|
||||
key: string
|
||||
type: 'ARRAY' | 'BOOL' | 'FLOAT' | 'INT' | 'MIXED' | 'STRING'
|
||||
definition: string
|
||||
note: string
|
||||
lazy: boolean
|
||||
deprecated: boolean
|
||||
}
|
||||
|
||||
export type PresetIds = 'LARGE' | 'MEDIUM' | 'SMALL' | 'SHARED' | 'UNIVERSITY' | 'SCHOOL' | 'CLUB' | 'FAMILY' | 'PRIVATE' | 'NONE'
|
||||
|
||||
export type PresetAppConfig = {
|
||||
config: 'app' | 'user'
|
||||
entry: PresetAppConfigEntry
|
||||
defaults: Record<PresetIds, string>
|
||||
value?: unknown
|
||||
}
|
||||
|
||||
export type PresetAppConfigs = Record<string, PresetAppConfig[]>
|
||||
|
||||
type PresetAppsState = {
|
||||
enabled: string[]
|
||||
disabled: string[]
|
||||
}
|
||||
|
||||
export type PresetAppsStates = Record<PresetIds, PresetAppsState>
|
||||
19
apps/settings/src/main-admin-settings-presets.ts
Normal file
19
apps/settings/src/main-admin-settings-presets.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
|
||||
import SettingsPresets from './views/SettingsPresets.vue'
|
||||
import { getCSPNonce } from '@nextcloud/auth'
|
||||
|
||||
// CSP config for webpack dynamic chunk loading
|
||||
// eslint-disable-next-line camelcase
|
||||
__webpack_nonce__ = getCSPNonce()
|
||||
|
||||
export default new Vue({
|
||||
render: h => h(SettingsPresets),
|
||||
el: '#settings-presets',
|
||||
name: 'SettingsPresets',
|
||||
})
|
||||
68
apps/settings/src/views/SettingsPresets.vue
Normal file
68
apps/settings/src/views/SettingsPresets.vue
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<!--
|
||||
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import axios from '@nextcloud/axios'
|
||||
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
|
||||
import NcButton from '@nextcloud/vue/components/NcButton'
|
||||
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
|
||||
import PresetsSelectionForm from '../components/SettingsPresets/PresetsSelectionForm.vue'
|
||||
import PresetVisualisation from '../components/SettingsPresets/PresetVisualisation.vue'
|
||||
import type { PresetAppConfigs, PresetIds } from '../components/SettingsPresets/models'
|
||||
import logger from '../logger'
|
||||
|
||||
const presets = loadState('settings', 'settings-presets', {}) as PresetAppConfigs
|
||||
const currentPreset = ref(loadState('settings', 'settings-selected-preset', 'NONE') as PresetIds)
|
||||
const selectedPreset = ref(currentPreset.value)
|
||||
const savingPreset = ref(false)
|
||||
|
||||
async function saveSelectedPreset() {
|
||||
try {
|
||||
savingPreset.value = true
|
||||
await axios.post(generateUrl('/settings/preset/current'), {
|
||||
presetName: selectedPreset.value,
|
||||
})
|
||||
currentPreset.value = selectedPreset.value
|
||||
} catch (error) {
|
||||
showError(t('settings', 'Failed to save selected preset.'))
|
||||
logger.error('Error saving selected preset:', { error })
|
||||
selectedPreset.value = currentPreset.value
|
||||
} finally {
|
||||
savingPreset.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NcSettingsSection :name="t('settings', 'Settings presets')"
|
||||
:description="t('settings', 'Select a configuration preset for easy setup.')">
|
||||
<PresetsSelectionForm v-model="selectedPreset" :presets="presets" />
|
||||
|
||||
<PresetVisualisation :presets="presets" :selected-preset="selectedPreset" />
|
||||
|
||||
<NcButton class="save-button"
|
||||
variant="primary"
|
||||
:disabled="selectedPreset === currentPreset || savingPreset"
|
||||
@click="saveSelectedPreset()">
|
||||
{{ t('settings', 'Apply') }}
|
||||
|
||||
<template v-if="savingPreset" #icon>
|
||||
<NcLoadingIcon />
|
||||
</template>
|
||||
</NcButton>
|
||||
</NcSettingsSection>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.save-button {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
12
apps/settings/templates/settings/admin/presets.php
Normal file
12
apps/settings/templates/settings/admin/presets.php
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
\OCP\Util::addScript('settings', 'vue-settings-admin-settings-presets');
|
||||
|
||||
?>
|
||||
|
||||
<div id="settings-presets">
|
||||
</div>
|
||||
|
|
@ -53,7 +53,7 @@ class ConfigLexicon implements ILexicon {
|
|||
Preset::FAMILY, Preset::PRIVATE => true,
|
||||
default => false,
|
||||
},
|
||||
definition: 'Allow users to set custom share link tokens',
|
||||
definition: 'Allow users to customize share URL',
|
||||
lazy: true,
|
||||
note: 'Shares with guessable tokens may be accessed easily. Shares with custom tokens will continue to be accessible after this setting has been disabled.',
|
||||
),
|
||||
|
|
@ -65,7 +65,7 @@ class ConfigLexicon implements ILexicon {
|
|||
Preset::SCHOOL, Preset::UNIVERSITY, Preset::SHARED, Preset::SMALL, Preset::MEDIUM, Preset::LARGE => true,
|
||||
default => false,
|
||||
},
|
||||
definition: 'Enforce password protection when sharing document'
|
||||
definition: 'Enforce password protection for shared documents'
|
||||
),
|
||||
new Entry(
|
||||
key: self::SHARE_LINK_EXPIRE_DATE_DEFAULT,
|
||||
|
|
@ -74,7 +74,7 @@ class ConfigLexicon implements ILexicon {
|
|||
Preset::SHARED, Preset::SMALL, Preset::MEDIUM, Preset::LARGE => true,
|
||||
default => false,
|
||||
},
|
||||
definition: 'Set default expiration date for shares via link or mail'
|
||||
definition: 'Default expiration date for shares via link or mail'
|
||||
),
|
||||
new Entry(
|
||||
key: self::SHARE_LINK_EXPIRE_DATE_ENFORCED,
|
||||
|
|
|
|||
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
4
dist/core-unified-search.js
vendored
4
dist/core-unified-search.js
vendored
File diff suppressed because one or more lines are too long
2
dist/core-unified-search.js.map
vendored
2
dist/core-unified-search.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/federatedfilesharing-external.js
vendored
4
dist/federatedfilesharing-external.js
vendored
File diff suppressed because one or more lines are too long
2
dist/federatedfilesharing-external.js.map
vendored
2
dist/federatedfilesharing-external.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/settings-users-3239.js
vendored
4
dist/settings-users-3239.js
vendored
File diff suppressed because one or more lines are too long
2
dist/settings-users-3239.js.map
vendored
2
dist/settings-users-3239.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/settings-vue-settings-admin-security.js
vendored
4
dist/settings-vue-settings-admin-security.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
dist/settings-vue-settings-admin-settings-presets.js
vendored
Normal file
2
dist/settings-vue-settings-admin-settings-presets.js
vendored
Normal file
File diff suppressed because one or more lines are too long
133
dist/settings-vue-settings-admin-settings-presets.js.license
vendored
Normal file
133
dist/settings-vue-settings-admin-settings-presets.js.license
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
SPDX-License-Identifier: MIT
|
||||
SPDX-License-Identifier: ISC
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
SPDX-License-Identifier: (MPL-2.0 OR Apache-2.0)
|
||||
SPDX-FileCopyrightText: inherits developers
|
||||
SPDX-FileCopyrightText: escape-html developers
|
||||
SPDX-FileCopyrightText: Varun A P
|
||||
SPDX-FileCopyrightText: Tobias Koppers @sokra
|
||||
SPDX-FileCopyrightText: T. Jameson Little <t.jameson.little@gmail.com>
|
||||
SPDX-FileCopyrightText: Roman Shtylman <shtylman@gmail.com>
|
||||
SPDX-FileCopyrightText: Rob Cresswell <robcresswell@pm.me>
|
||||
SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
|
||||
SPDX-FileCopyrightText: Matt Zabriskie
|
||||
SPDX-FileCopyrightText: Joyent
|
||||
SPDX-FileCopyrightText: Guillaume Chau <guillaume.b.chau@gmail.com>
|
||||
SPDX-FileCopyrightText: GitHub Inc.
|
||||
SPDX-FileCopyrightText: Feross Aboukhadijeh
|
||||
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: @nextcloud/dialogs developers
|
||||
|
||||
|
||||
This file is generated from multiple sources. Included packages:
|
||||
- @nextcloud/auth
|
||||
- version: 2.5.2
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/axios
|
||||
- version: 2.5.1
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/browser-storage
|
||||
- version: 0.4.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/dialogs
|
||||
- version: 6.3.1
|
||||
- license: AGPL-3.0-or-later
|
||||
- semver
|
||||
- version: 7.7.2
|
||||
- license: ISC
|
||||
- @nextcloud/event-bus
|
||||
- version: 3.3.2
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/initial-state
|
||||
- version: 3.0.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/l10n
|
||||
- version: 3.4.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/logger
|
||||
- version: 3.0.2
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/router
|
||||
- version: 3.0.1
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/initial-state
|
||||
- version: 2.2.0
|
||||
- license: GPL-3.0-or-later
|
||||
- @nextcloud/vue
|
||||
- version: 8.29.1
|
||||
- license: AGPL-3.0-or-later
|
||||
- @vueuse/core
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- @vueuse/shared
|
||||
- version: 11.3.0
|
||||
- license: MIT
|
||||
- axios
|
||||
- version: 1.11.0
|
||||
- license: MIT
|
||||
- base64-js
|
||||
- version: 1.5.1
|
||||
- license: MIT
|
||||
- css-loader
|
||||
- version: 7.1.2
|
||||
- license: MIT
|
||||
- dompurify
|
||||
- version: 3.2.6
|
||||
- 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.6.5
|
||||
- license: MIT
|
||||
- ieee754
|
||||
- version: 1.2.1
|
||||
- license: BSD-3-Clause
|
||||
- buffer
|
||||
- version: 6.0.3
|
||||
- license: MIT
|
||||
- inherits
|
||||
- version: 2.0.3
|
||||
- license: ISC
|
||||
- util
|
||||
- version: 0.10.4
|
||||
- license: MIT
|
||||
- path
|
||||
- version: 0.12.7
|
||||
- license: MIT
|
||||
- process
|
||||
- version: 0.11.10
|
||||
- license: MIT
|
||||
- style-loader
|
||||
- version: 4.0.0
|
||||
- license: MIT
|
||||
- tabbable
|
||||
- version: 6.2.0
|
||||
- license: MIT
|
||||
- toastify-js
|
||||
- version: 1.12.0
|
||||
- license: MIT
|
||||
- vue-loader
|
||||
- version: 15.11.1
|
||||
- license: MIT
|
||||
- vue-material-design-icons
|
||||
- version: 5.3.1
|
||||
- license: MIT
|
||||
- vue
|
||||
- version: 2.7.16
|
||||
- license: MIT
|
||||
- webpack
|
||||
- version: 5.101.3
|
||||
- license: MIT
|
||||
- nextcloud
|
||||
- version: 1.0.0
|
||||
- license: AGPL-3.0-or-later
|
||||
1
dist/settings-vue-settings-admin-settings-presets.js.map
vendored
Normal file
1
dist/settings-vue-settings-admin-settings-presets.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/settings-vue-settings-admin-settings-presets.js.map.license
vendored
Symbolic link
1
dist/settings-vue-settings-admin-settings-presets.js.map.license
vendored
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
settings-vue-settings-admin-settings-presets.js.license
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
dist/systemtags-admin.js
vendored
4
dist/systemtags-admin.js
vendored
File diff suppressed because one or more lines are too long
2
dist/systemtags-admin.js.map
vendored
2
dist/systemtags-admin.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/twofactor_backupcodes-settings.js
vendored
4
dist/twofactor_backupcodes-settings.js
vendored
File diff suppressed because one or more lines are too long
2
dist/twofactor_backupcodes-settings.js.map
vendored
2
dist/twofactor_backupcodes-settings.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/user_status-menu.js
vendored
4
dist/user_status-menu.js
vendored
File diff suppressed because one or more lines are too long
2
dist/user_status-menu.js.map
vendored
2
dist/user_status-menu.js.map
vendored
File diff suppressed because one or more lines are too long
|
|
@ -87,6 +87,7 @@ module.exports = {
|
|||
'vue-settings-admin-ai': path.join(__dirname, 'apps/settings/src', 'main-admin-ai.js'),
|
||||
'vue-settings-admin-delegation': path.join(__dirname, 'apps/settings/src', 'main-admin-delegation.js'),
|
||||
'vue-settings-admin-security': path.join(__dirname, 'apps/settings/src', 'main-admin-security.js'),
|
||||
'vue-settings-admin-settings-presets': path.join(__dirname, 'apps/settings/src', 'main-admin-settings-presets.js'),
|
||||
'vue-settings-admin-sharing': path.join(__dirname, 'apps/settings/src', 'admin-settings-sharing.ts'),
|
||||
'vue-settings-apps-users-management': path.join(__dirname, 'apps/settings/src', 'main-apps-users-management.ts'),
|
||||
'vue-settings-nextcloud-pdf': path.join(__dirname, 'apps/settings/src', 'main-nextcloud-pdf.js'),
|
||||
|
|
|
|||
Loading…
Reference in a new issue