Merge pull request #46592 from nextcloud/feat/first-day-of-week-user-setting

feat: let users configure their first day of week
This commit is contained in:
Richard Steinmetz 2024-07-23 09:03:19 +02:00 committed by GitHub
commit ee6f857889
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 162 additions and 8 deletions

View file

@ -39,6 +39,7 @@ abstract class AUserData extends OCSController {
public const USER_FIELD_DISPLAYNAME = 'display';
public const USER_FIELD_LANGUAGE = 'language';
public const USER_FIELD_LOCALE = 'locale';
public const USER_FIELD_FIRST_DAY_OF_WEEK = 'first_day_of_week';
public const USER_FIELD_PASSWORD = 'password';
public const USER_FIELD_QUOTA = 'quota';
public const USER_FIELD_MANAGER = 'manager';

View file

@ -913,6 +913,7 @@ class UsersController extends AUserData {
$this->groupManager->isAdmin($currentLoggedInUser->getUID())
) {
$permittedFields[] = self::USER_FIELD_LOCALE;
$permittedFields[] = self::USER_FIELD_FIRST_DAY_OF_WEEK;
}
$permittedFields[] = IAccountManager::PROPERTY_PHONE;
@ -965,6 +966,7 @@ class UsersController extends AUserData {
$permittedFields[] = self::USER_FIELD_PASSWORD;
$permittedFields[] = self::USER_FIELD_LANGUAGE;
$permittedFields[] = self::USER_FIELD_LOCALE;
$permittedFields[] = self::USER_FIELD_FIRST_DAY_OF_WEEK;
$permittedFields[] = IAccountManager::PROPERTY_PHONE;
$permittedFields[] = IAccountManager::PROPERTY_ADDRESS;
$permittedFields[] = IAccountManager::PROPERTY_WEBSITE;
@ -1056,6 +1058,17 @@ class UsersController extends AUserData {
}
$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
break;
case self::USER_FIELD_FIRST_DAY_OF_WEEK:
$intValue = (int)$value;
if ($intValue < -1 || $intValue > 6) {
throw new OCSException($this->l10n->t('Invalid first day of week'), 102);
}
if ($intValue === -1) {
$this->config->deleteUserValue($targetUser->getUID(), 'core', AUserData::USER_FIELD_FIRST_DAY_OF_WEEK);
} else {
$this->config->setUserValue($targetUser->getUID(), 'core', AUserData::USER_FIELD_FIRST_DAY_OF_WEEK, $value);
}
break;
case self::USER_FIELD_NOTIFICATION_EMAIL:
$success = false;
if ($value === '' || filter_var($value, FILTER_VALIDATE_EMAIL)) {

View file

@ -11,6 +11,7 @@ namespace OCA\Settings\Settings\Personal;
use OC\Profile\ProfileManager;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\Provisioning_API\Controller\AUserData;
use OCP\Accounts\IAccount;
use OCP\Accounts\IAccountManager;
use OCP\Accounts\IAccountProperty;
@ -141,6 +142,7 @@ class PersonalInfo implements ISettings {
'headline' => $this->getProperty($account, IAccountManager::PROPERTY_HEADLINE),
'biography' => $this->getProperty($account, IAccountManager::PROPERTY_BIOGRAPHY),
'birthdate' => $this->getProperty($account, IAccountManager::PROPERTY_BIRTHDATE),
'firstDayOfWeek' => $this->config->getUserValue($uid, 'core', AUserData::USER_FIELD_FIRST_DAY_OF_WEEK),
];
$accountParameters = [

View file

@ -0,0 +1,126 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<section class="fdow-section">
<HeaderBar :input-id="inputId"
:readable="propertyReadable" />
<NcSelect :aria-label-listbox="t('settings', 'Days to use as the first day of week')"
class="fdow-section__day-select"
:clearable="false"
:input-id="inputId"
label="label"
label-outside
:options="dayOptions"
:value="valueOption"
@option:selected="updateFirstDayOfWeek" />
</section>
</template>
<script lang="ts">
import HeaderBar from './shared/HeaderBar.vue'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import {
ACCOUNT_SETTING_PROPERTY_ENUM,
ACCOUNT_SETTING_PROPERTY_READABLE_ENUM,
} from '../../constants/AccountPropertyConstants'
import { getDayNames, getFirstDay } from '@nextcloud/l10n'
import { savePrimaryAccountProperty } from '../../service/PersonalInfo/PersonalInfoService'
import { handleError } from '../../utils/handlers.ts'
import { loadState } from '@nextcloud/initial-state'
interface DayOption {
value: number,
label: string,
}
const { firstDayOfWeek } = loadState<{firstDayOfWeek?: string}>(
'settings',
'personalInfoParameters',
{},
)
export default {
name: 'FirstDayOfWeekSection',
components: {
HeaderBar,
NcSelect,
},
data() {
let firstDay = -1
if (firstDayOfWeek) {
firstDay = parseInt(firstDayOfWeek)
}
return {
firstDay,
}
},
computed: {
inputId(): string {
return 'account-property-fdow'
},
propertyReadable(): string {
return ACCOUNT_SETTING_PROPERTY_READABLE_ENUM.FIRST_DAY_OF_WEEK
},
dayOptions(): DayOption[] {
const options = [{
value: -1,
label: t('settings', 'Derived from your locale ({weekDayName})', {
weekDayName: getDayNames()[getFirstDay()],
}),
}]
for (const [index, dayName] of getDayNames().entries()) {
options.push({ value: index, label: dayName })
}
return options
},
valueOption(): DayOption | undefined {
return this.dayOptions.find((option) => option.value === this.firstDay)
},
},
methods: {
async updateFirstDayOfWeek(option: DayOption): Promise<void> {
try {
const responseData = await savePrimaryAccountProperty(
ACCOUNT_SETTING_PROPERTY_ENUM.FIRST_DAY_OF_WEEK,
option.value.toString(),
)
this.handleResponse({
value: option.value,
status: responseData.ocs?.meta?.status,
})
window.location.reload()
} catch (e) {
this.handleResponse({
errorMessage: t('settings', 'Unable to update first day of week'),
error: e,
})
}
},
handleResponse({ value, status, errorMessage, error }): void {
if (status === 'ok') {
this.firstDay = value
} else {
this.$emit('update:value', this.firstDay)
handleError(error, errorMessage)
}
},
},
}
</script>
<style lang="scss" scoped>
.fdow-section {
padding: 10px;
&__day-select {
width: 100%;
margin-top: 6px; // align with other inputs
}
}
</style>

View file

@ -130,7 +130,7 @@ export default {
}
&.setting-property {
height: 44px;
height: 34px;
}
label {

View file

@ -99,12 +99,14 @@ export const PROPERTY_READABLE_KEYS_ENUM = Object.freeze({
export const ACCOUNT_SETTING_PROPERTY_ENUM = Object.freeze({
LANGUAGE: 'language',
LOCALE: 'locale',
FIRST_DAY_OF_WEEK: 'first_day_of_week',
})
/** Enum of account setting properties to human readable setting properties */
export const ACCOUNT_SETTING_PROPERTY_READABLE_ENUM = Object.freeze({
LANGUAGE: t('settings', 'Language'),
LOCALE: t('settings', 'Locale'),
FIRST_DAY_OF_WEEK: t('settings', 'First day of week'),
})
/** Enum of scopes */

View file

@ -26,6 +26,7 @@ import HeadlineSection from './components/PersonalInfo/HeadlineSection.vue'
import BiographySection from './components/PersonalInfo/BiographySection.vue'
import ProfileVisibilitySection from './components/PersonalInfo/ProfileVisibilitySection/ProfileVisibilitySection.vue'
import BirthdaySection from './components/PersonalInfo/BirthdaySection.vue'
import FirstDayOfWeekSection from './components/PersonalInfo/FirstDayOfWeekSection.vue'
__webpack_nonce__ = btoa(getRequestToken())
@ -49,6 +50,7 @@ const FediverseView = Vue.extend(FediverseSection)
const LanguageView = Vue.extend(LanguageSection)
const LocaleView = Vue.extend(LocaleSection)
const BirthdayView = Vue.extend(BirthdaySection)
const FirstDayOfWeekView = Vue.extend(FirstDayOfWeekSection)
new AvatarView().$mount('#vue-avatar-section')
new DetailsView().$mount('#vue-details-section')
@ -61,6 +63,7 @@ new TwitterView().$mount('#vue-twitter-section')
new FediverseView().$mount('#vue-fediverse-section')
new LanguageView().$mount('#vue-language-section')
new LocaleView().$mount('#vue-locale-section')
new FirstDayOfWeekView().$mount('#vue-fdow-section')
new BirthdayView().$mount('#vue-birthday-section')
if (profileEnabledGlobally) {

View file

@ -61,6 +61,9 @@ script('settings', [
<div class="personal-settings-setting-box personal-settings-locale-box">
<div id="vue-locale-section"></div>
</div>
<div class="personal-settings-setting-box">
<div id="vue-fdow-section"></div>
</div>
<div class="personal-settings-setting-box">
<div id="vue-website-section"></div>
</div>

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

File diff suppressed because one or more lines are too long

View file

@ -12,6 +12,7 @@ use OC\Authentication\Token\IProvider;
use OC\CapabilitiesManager;
use OC\Files\FilenameValidator;
use OC\Share\Share;
use OCA\Provisioning_API\Controller\AUserData;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\Authentication\Exceptions\ExpiredTokenException;
@ -133,6 +134,9 @@ class JSConfigHelper {
$capabilities = $this->capabilitiesManager->getCapabilities(false, true);
$userFirstDay = $this->config->getUserValue($uid, 'core', AUserData::USER_FIELD_FIRST_DAY_OF_WEEK, null);
$firstDay = (int)($userFirstDay ?? $this->l->l('firstday', null));
$config = [
/** @deprecated 30.0.0 - use files capabilities instead */
'blacklist_files_regex' => FileInfo::BLACKLIST_FILES_REGEX,
@ -220,7 +224,7 @@ class JSConfigHelper {
$this->l->t('Nov.'),
$this->l->t('Dec.')
]),
"firstDay" => json_encode($this->l->l('firstday', null)),
"firstDay" => json_encode($firstDay),
"_oc_config" => json_encode($config),
"oc_appconfig" => json_encode([
'core' => [