diff --git a/apps/profile/lib/Listener/ProfilePickerReferenceListener.php b/apps/profile/lib/Listener/ProfilePickerReferenceListener.php index 242f89b1e7e..124d10e035c 100644 --- a/apps/profile/lib/Listener/ProfilePickerReferenceListener.php +++ b/apps/profile/lib/Listener/ProfilePickerReferenceListener.php @@ -12,17 +12,36 @@ use OCA\Profile\AppInfo\Application; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\IAppConfig; +use OCP\Profile\IProfileManager; use OCP\Util; /** * @template-implements IEventListener */ class ProfilePickerReferenceListener implements IEventListener { + + public function __construct( + private IAppConfig $appConfig, + private IProfileManager $profileManager, + ) { + } + public function handle(Event $event): void { if (!$event instanceof RenderReferenceEvent) { return; } - Util::addScript(Application::APP_ID, 'reference'); + $profileEnabledGlobally = $this->profileManager->isProfileEnabled(); + + $profilePickerEnabled = filter_var( + $this->appConfig->getValueString('settings', 'profile_picker_enabled', '1'), + FILTER_VALIDATE_BOOLEAN, + FILTER_NULL_ON_FAILURE, + ); + + if ($profileEnabledGlobally && $profilePickerEnabled) { + Util::addScript(Application::APP_ID, 'reference'); + } } } diff --git a/apps/profile/lib/Reference/ProfilePickerReferenceProvider.php b/apps/profile/lib/Reference/ProfilePickerReferenceProvider.php index e5c4daa5097..9b748a42d6d 100644 --- a/apps/profile/lib/Reference/ProfilePickerReferenceProvider.php +++ b/apps/profile/lib/Reference/ProfilePickerReferenceProvider.php @@ -15,6 +15,7 @@ use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; use OCP\Collaboration\Reference\IReference; use OCP\Collaboration\Reference\Reference; +use OCP\IAppConfig; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUserManager; @@ -22,6 +23,7 @@ use OCP\Profile\IProfileManager; class ProfilePickerReferenceProvider extends ADiscoverableReferenceProvider { public const RICH_OBJECT_TYPE = 'profile_widget'; + private bool $enabled; public function __construct( private IL10N $l10n, @@ -29,8 +31,16 @@ class ProfilePickerReferenceProvider extends ADiscoverableReferenceProvider { private IUserManager $userManager, private IAccountManager $accountManager, private IProfileManager $profileManager, + private IAppConfig $appConfig, private ?string $userId, ) { + $profileEnabledGlobally = $this->profileManager->isProfileEnabled(); + $profilePickerEnabled = filter_var( + $this->appConfig->getValueString('settings', 'profile_picker_enabled', '1'), + FILTER_VALIDATE_BOOLEAN, + FILTER_NULL_ON_FAILURE, + ); + $this->enabled = $profileEnabledGlobally && $profilePickerEnabled; } /** @@ -65,6 +75,9 @@ class ProfilePickerReferenceProvider extends ADiscoverableReferenceProvider { * @inheritDoc */ public function matchReference(string $referenceText): bool { + if (!$this->enabled) { + return false; + } return $this->getObjectId($referenceText) !== null; } diff --git a/apps/settings/lib/Settings/Admin/Server.php b/apps/settings/lib/Settings/Admin/Server.php index 02a6cd2736b..32328da5b1a 100644 --- a/apps/settings/lib/Settings/Admin/Server.php +++ b/apps/settings/lib/Settings/Admin/Server.php @@ -53,6 +53,7 @@ class Server implements IDelegatedSettings { // Profile page $this->initialStateService->provideInitialState('profileEnabledGlobally', $this->profileManager->isProfileEnabled()); $this->initialStateService->provideInitialState('profileEnabledByDefault', $this->isProfileEnabledByDefault($this->config)); + $this->initialStateService->provideInitialState('profilePickerEnabled', $this->isProfilePickerEnabled($this->config)); // Basic settings $this->initialStateService->provideInitialState('restrictSystemTagsCreationToAdmin', $this->appConfig->getValueBool('systemtags', 'restrict_creation_to_admin', false)); diff --git a/apps/settings/src/components/BasicSettings/ProfileSettings.vue b/apps/settings/src/components/BasicSettings/ProfileSettings.vue index 084155309d5..55d116cbe95 100644 --- a/apps/settings/src/components/BasicSettings/ProfileSettings.vue +++ b/apps/settings/src/components/BasicSettings/ProfileSettings.vue @@ -11,9 +11,9 @@ {{ t('settings', 'Profile') }} -

+ {{ t('settings', 'Enable or disable profile by default for new accounts.') }} -

+ {{ t('settings', 'Enable') }} + + + {{ t('settings', 'Enable the profile picker') }} + + + + {{ t('settings', 'Enable or disable the profile picker in the Smart Picker and the profile link previews.') }} + @@ -28,22 +39,26 @@ import { showError } from '@nextcloud/dialogs' import { loadState } from '@nextcloud/initial-state' import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch' +import NcNoteCard from '@nextcloud/vue/components/NcNoteCard' import logger from '../../logger.ts' -import { saveProfileDefault } from '../../service/ProfileService.js' +import { saveProfileDefault, saveProfilePicker } from '../../service/ProfileService.js' import { validateBoolean } from '../../utils/validate.js' const profileEnabledByDefault = loadState('settings', 'profileEnabledByDefault', true) +const profilePickerEnabled = loadState('settings', 'profilePickerEnabled', true) export default { name: 'ProfileSettings', components: { NcCheckboxRadioSwitch, + NcNoteCard, }, data() { return { initialProfileEnabledByDefault: profileEnabledByDefault, + initialProfilePickerEnabled: profilePickerEnabled, } }, @@ -59,6 +74,7 @@ export default { const responseData = await saveProfileDefault(isEnabled) this.handleResponse({ isEnabled, + key: 'initialProfileEnabledByDefault', status: responseData.ocs?.meta?.status, }) } catch (e) { @@ -69,9 +85,31 @@ export default { } }, - handleResponse({ isEnabled, status, errorMessage, error }) { + async onProfilePickerChange(isEnabled) { + if (validateBoolean(isEnabled)) { + await this.updateProfilePicker(isEnabled) + } + }, + + async updateProfilePicker(isEnabled) { + try { + const responseData = await saveProfilePicker(isEnabled) + this.handleResponse({ + isEnabled, + key: 'initialProfilePickerEnabled', + status: responseData.ocs?.meta?.status, + }) + } catch (e) { + this.handleResponse({ + errorMessage: t('settings', 'Unable to update profile picker setting'), + error: e, + }) + } + }, + + handleResponse({ isEnabled, key, status, errorMessage, error }) { if (status === 'ok') { - this.initialProfileEnabledByDefault = isEnabled + this[key] = isEnabled } else { showError(errorMessage) logger.error(errorMessage, error) @@ -80,3 +118,9 @@ export default { }, } + + diff --git a/apps/settings/src/service/ProfileService.js b/apps/settings/src/service/ProfileService.js index 1e0f4d46bbe..1490915c49b 100644 --- a/apps/settings/src/service/ProfileService.js +++ b/apps/settings/src/service/ProfileService.js @@ -52,3 +52,27 @@ export async function saveProfileDefault(isEnabled) { return res.data } + +/** + * Save profile picker default + * + * @param {boolean} isEnabled the default + * @return {object} + */ +export async function saveProfilePicker(isEnabled) { + // Convert to string for compatibility + isEnabled = isEnabled ? '1' : '0' + + const url = generateOcsUrl('/apps/provisioning_api/api/v1/config/apps/{appId}/{key}', { + appId: 'settings', + key: 'profile_picker_enabled', + }) + + await confirmPassword() + + const res = await axios.post(url, { + value: isEnabled, + }) + + return res.data +} diff --git a/core/shipped.json b/core/shipped.json index 54ba1d29227..0ea8051cadd 100644 --- a/core/shipped.json +++ b/core/shipped.json @@ -48,7 +48,6 @@ "twofactor_totp", "updatenotification", "user_ldap", - "user_picker", "user_status", "viewer", "weather_status", diff --git a/lib/private/Profile/TProfileHelper.php b/lib/private/Profile/TProfileHelper.php index ad24d82445c..77a6ea5dd32 100644 --- a/lib/private/Profile/TProfileHelper.php +++ b/lib/private/Profile/TProfileHelper.php @@ -19,4 +19,12 @@ trait TProfileHelper { FILTER_NULL_ON_FAILURE, ); } + + protected function isProfilePickerEnabled(IConfig $config): ?bool { + return filter_var( + $config->getAppValue('settings', 'profile_picker_enabled', '1'), + FILTER_VALIDATE_BOOLEAN, + FILTER_NULL_ON_FAILURE, + ); + } }