refactor: consolidate OC.Settings

1. Remove unused legacy parts (no code match in the whole github
organization).
2. Consolidate `OC.Settings` in `core/src/OC` for consistency.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Ferdinand Thiessen 2026-01-06 00:23:55 +01:00
parent 0fa396d0b8
commit 805805767f
No known key found for this signature in database
GPG key ID: 7E849AE05218500F
14 changed files with 36 additions and 288 deletions

View file

@ -239,75 +239,6 @@ select {
}
}
.federation-menu {
position: relative;
cursor: pointer;
width: var(--default-clickable-area);
height: var(--default-clickable-area);
padding: calc(2 * var(--default-grid-baseline));
margin: 0;
background: none;
border: none;
&:hover,
&:focus {
background-color: var(--color-background-hover);
border-radius: var(--border-radius-element);
.icon-federation-menu {
opacity: 0.8;
}
}
.icon-federation-menu {
padding-inline-start: 16px;
background-size: 16px;
background-position: left center;
opacity: .3;
cursor: inherit;
.icon-triangle-s {
display: inline-block;
vertical-align: middle;
cursor: inherit;
}
}
.federationScopeMenu {
top: var(--default-clickable-area);
&.popovermenu {
.menuitem {
// override h3 heading font size
font-size: 12.8px;
line-height: 1.6em;
.menuitem-text-detail {
opacity: .75;
}
&.active {
box-shadow: inset 2px 0 var(--color-primary-element);
.menuitem-text {
font-weight: bold;
}
}
&.disabled {
opacity: .5;
cursor: default;
* {
cursor: default;
}
}
}
}
}
}
.clientsbox img {
height: 60px;
}

View file

@ -1,91 +0,0 @@
(function() {
var template = Handlebars.template, templates = OC.Settings.Templates = OC.Settings.Templates || {};
templates['federationscopemenu'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return ((stack1 = lookupProperty(helpers,"unless").call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,"hidden") : depth0),{"name":"unless","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":2},"end":{"line":25,"column":13}}})) != null ? stack1 : "");
},"2":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return " <li>\n"
+ ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"disabled") : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.program(6, data, 0),"data":data,"loc":{"start":{"line":5,"column":3},"end":{"line":9,"column":10}}})) != null ? stack1 : "")
+ ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"iconClass") : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.program(10, data, 0),"data":data,"loc":{"start":{"line":10,"column":4},"end":{"line":14,"column":11}}})) != null ? stack1 : "")
+ " <p>\n <strong class=\"menuitem-text\">"
+ alias4(((helper = (helper = lookupProperty(helpers,"displayName") || (depth0 != null ? lookupProperty(depth0,"displayName") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"displayName","hash":{},"data":data,"loc":{"start":{"line":16,"column":35},"end":{"line":16,"column":50}}}) : helper)))
+ "</strong><br>\n <span class=\"menuitem-text-detail\">"
+ alias4(((helper = (helper = lookupProperty(helpers,"tooltip") || (depth0 != null ? lookupProperty(depth0,"tooltip") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tooltip","hash":{},"data":data,"loc":{"start":{"line":17,"column":40},"end":{"line":17,"column":51}}}) : helper)))
+ "</span>\n </p>\n"
+ ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"disabled") : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.program(14, data, 0),"data":data,"loc":{"start":{"line":19,"column":3},"end":{"line":23,"column":10}}})) != null ? stack1 : "")
+ " </li>\n";
},"3":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return " <div class=\"menuitem action action-"
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":6,"column":38},"end":{"line":6,"column":46}}}) : helper)))
+ " permanent "
+ ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"active") : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":6,"column":57},"end":{"line":6,"column":84}}})) != null ? stack1 : "")
+ " disabled\" data-action=\""
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":6,"column":108},"end":{"line":6,"column":116}}}) : helper)))
+ "\">\n";
},"4":function(container,depth0,helpers,partials,data) {
return "active";
},"6":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return " <a href=\"#\" class=\"menuitem action action-"
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":8,"column":45},"end":{"line":8,"column":53}}}) : helper)))
+ " permanent "
+ ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"active") : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":8,"column":64},"end":{"line":8,"column":91}}})) != null ? stack1 : "")
+ "\" data-action=\""
+ alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":8,"column":106},"end":{"line":8,"column":114}}}) : helper)))
+ "\">\n";
},"8":function(container,depth0,helpers,partials,data) {
var helper, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return " <span class=\"icon "
+ container.escapeExpression(((helper = (helper = lookupProperty(helpers,"iconClass") || (depth0 != null ? lookupProperty(depth0,"iconClass") : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"iconClass","hash":{},"data":data,"loc":{"start":{"line":11,"column":23},"end":{"line":11,"column":36}}}) : helper)))
+ "\"></span>\n";
},"10":function(container,depth0,helpers,partials,data) {
return " <span class=\"no-icon\"></span>\n";
},"12":function(container,depth0,helpers,partials,data) {
return " </div>\n";
},"14":function(container,depth0,helpers,partials,data) {
return " </a>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return "<ul>\n"
+ ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,"items") : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":1},"end":{"line":26,"column":10}}})) != null ? stack1 : "")
+ "</ul>\n";
},"useData":true});
})();

View file

@ -1,27 +0,0 @@
<ul>
{{#each items}}
{{#unless hidden}}
<li>
{{#if disabled}}
<div class="menuitem action action-{{name}} permanent {{#if active}}active{{/if}} disabled" data-action="{{name}}">
{{else}}
<a href="#" class="menuitem action action-{{name}} permanent {{#if active}}active{{/if}}" data-action="{{name}}">
{{/if}}
{{#if iconClass}}
<span class="icon {{iconClass}}"></span>
{{else}}
<span class="no-icon"></span>
{{/if}}
<p>
<strong class="menuitem-text">{{displayName}}</strong><br>
<span class="menuitem-text-detail">{{tooltip}}</span>
</p>
{{#if disabled}}
</div>
{{else}}
</a>
{{/if}}
</li>
{{/unless}}
{{/each}}
</ul>

View file

@ -1,60 +0,0 @@
/* global OC */
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
(function() {
'use strict'
let errorNotification
/**
* Model for storing and saving user settings
*
* @class UserSettings
*/
const UserSettings = OC.Backbone.Model.extend({
url: OC.generateUrl('/settings/users/{id}/settings', { id: OC.currentUser }),
isNew: function() {
return false // Force PUT on .save()
},
parse: function(data) {
if (_.isUndefined(data)) {
return null
}
if (errorNotification) {
errorNotification.hide()
}
if (data.status && data.status === 'error') {
errorNotification = OC.Notification.show(data.data.message, { type: 'error' })
}
if (_.isUndefined(data.data)) {
return null
}
data = data.data
const ignored = [
'userId',
'message',
]
_.each(ignored, function(ign) {
if (!_.isUndefined(data[ign])) {
delete data[ign]
}
})
return data
},
})
OC.Settings = OC.Settings || {}
OC.Settings.UserSettings = UserSettings
})()

View file

@ -1,10 +0,0 @@
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import rebuildNavigation from './service/rebuild-navigation.js'
window.OC.Settings = window.OC.Settings || {}
window.OC.Settings.Apps = window.OC.Settings.Apps || {
rebuildNavigation,
}

View file

@ -10,9 +10,5 @@ __webpack_nonce__ = getCSPNonce()
Vue.prototype.t = t
// Not used here but required for legacy templates
window.OC = window.OC || {}
window.OC.Settings = window.OC.Settings || {}
const View = Vue.extend(ArtificialIntelligence)
new View().$mount('#ai-settings')

View file

@ -13,10 +13,6 @@ __webpack_nonce__ = getCSPNonce()
Vue.prototype.t = t
// Not used here but required for legacy templates
window.OC = window.OC || {}
window.OC.Settings = window.OC.Settings || {}
store.replaceState(loadState('settings', 'mandatory2FAState'))
const View = Vue.extend(AdminTwoFactor)

View file

@ -4,9 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
script('settings', [
'vue-settings-admin-ai',
]);
\OCP\Util::addScript('settings', 'vue-settings-admin-ai');
?>
<div id="ai-settings">

View file

@ -7,9 +7,7 @@
/** @var \OCP\IL10N $l */
/** @var array $_ */
script('settings', [
'vue-settings-admin-basic-settings',
]);
\OCP\Util::addScript('settings', 'vue-settings-admin-basic-settings');
?>
<div id="vue-admin-background-job"></div>

View file

@ -5,9 +5,7 @@
*/
style('settings', 'settings');
\OCP\Util::addScript('settings', 'settings', 'core');
\OCP\Util::addScript('settings', 'legacy-admin');
?>
<div id="app-navigation">

View file

@ -8,11 +8,7 @@
/** @var \OCP\IL10N $l */
/** @var array $_ */
script('settings', [
'usersettings',
'templates',
'vue-settings-personal-info',
]);
\OCP\Util::addScript('settings', 'vue-settings-personal-info');
?>
<?php if (!$_['isFairUseOfFreePushService']) : ?>
<div class="section">

View file

@ -51,7 +51,6 @@ module.exports = {
'public-nickname-handler': path.join(__dirname, 'apps/files_sharing/src', 'public-nickname-handler.ts'),
},
settings: {
apps: path.join(__dirname, 'apps/settings/src', 'apps.js'),
'legacy-admin': path.join(__dirname, 'apps/settings/src', 'admin.js'),
'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'),

View file

@ -69,6 +69,7 @@ import { getRequestToken } from './requesttoken.ts'
import {
linkToRemoteBase,
} from './routing.js'
import Settings from './settings.js'
import { theme } from './theme.js'
import Util from './util.js'
import webroot from './webroot.js'
@ -198,6 +199,10 @@ export default {
*/
PasswordConfirmation,
Plugins,
/**
* @deprecated 25.0.0 Use Vue based (`@nextcloud/vue`) settings components instead
*/
Settings,
theme,
Util,
debug,

View file

@ -3,9 +3,18 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
OC.Settings = OC.Settings || {}
OC.Settings = _.extend(OC.Settings, {
import axios from '@nextcloud/axios'
import { emit } from '@nextcloud/event-bus'
import { generateOcsUrl } from '@nextcloud/router'
import $ from 'jquery'
import _ from 'underscore'
import logger from '../logger.js'
/**
* @deprecated 25.0.0 Use Vue based (`@nextcloud/vue`) settings components instead
*/
export default {
_cachedGroups: null,
escapeHTML: function(text) {
@ -17,6 +26,16 @@ OC.Settings = _.extend(OC.Settings, {
.split('\'').join('&#039;')
},
async rebuildNavigation() {
const { data } = await axios.get(generateOcsUrl('core/navigation', 2) + '/apps?format=json')
if (data.ocs.meta.statuscode !== 200) {
return
}
emit('nextcloud:app-menu.refresh', { apps: data.ocs.data })
window.dispatchEvent(new Event('resize'))
},
/**
* Setup selection box for group selection.
*
@ -35,7 +54,7 @@ OC.Settings = _.extend(OC.Settings, {
if ($elements.length > 0) {
// Let's load the data and THEN init our select
$.ajax({
url: OC.linkToOCS('cloud/groups', 2) + 'details',
url: generateOcsUrl('cloud/groups/details'),
dataType: 'json',
success: function(data) {
const results = []
@ -50,7 +69,7 @@ OC.Settings = _.extend(OC.Settings, {
// note: settings are saved through a "change" event registered
// on all input fields
$elements.select2(_.extend({
placeholder: t('settings', 'Groups'),
placeholder: t('core', 'Groups'),
allowClear: true,
multiple: true,
toggleSelect: true,
@ -94,15 +113,15 @@ OC.Settings = _.extend(OC.Settings, {
},
}, extraOptions || {}))
} else {
OC.Notification.show(t('settings', 'Group list is empty'), { type: 'error' })
console.log(data)
OC.Notification.show(t('core', 'Group list is empty'), { type: 'error' })
logger.debug(data)
}
},
error: function(data) {
OC.Notification.show(t('settings', 'Unable to retrieve the group list'), { type: 'error' })
console.log(data)
OC.Notification.show(t('core', 'Unable to retrieve the group list'), { type: 'error' })
logger.debug(data)
},
})
}
},
})
}