Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: let users configure their first day of week #46592

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/provisioning_api/lib/Controller/AUserData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
13 changes: 13 additions & 0 deletions apps/provisioning_api/lib/Controller/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,7 @@ public function editUser(string $userId, string $key, string $value): DataRespon
$this->groupManager->isAdmin($currentLoggedInUser->getUID())
) {
$permittedFields[] = self::USER_FIELD_LOCALE;
$permittedFields[] = self::USER_FIELD_FIRST_DAY_OF_WEEK;
}

$permittedFields[] = IAccountManager::PROPERTY_PHONE;
Expand Down Expand Up @@ -965,6 +966,7 @@ public function editUser(string $userId, string $key, string $value): DataRespon
$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;
Expand Down Expand Up @@ -1056,6 +1058,17 @@ public function editUser(string $userId, string $key, string $value): DataRespon
}
$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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number 102?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like the other properties. For some reason they all return 102 in case of invalid values 🤷‍♂️

}
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)) {
Expand Down
2 changes: 2 additions & 0 deletions apps/settings/lib/Settings/Personal/PersonalInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

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;
Expand Down Expand Up @@ -141,6 +142,7 @@ public function getForm(): TemplateResponse {
'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 = [
Expand Down
126 changes: 126 additions & 0 deletions apps/settings/src/components/PersonalInfo/FirstDayOfWeekSection.vue
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export default {
}

&.setting-property {
height: 44px;
height: 34px;
}

label {
Expand Down
2 changes: 2 additions & 0 deletions apps/settings/src/constants/AccountPropertyConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
3 changes: 3 additions & 0 deletions apps/settings/src/main-personal-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand All @@ -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')
Expand All @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions apps/settings/templates/settings/personal/personal.info.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
<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>
Expand Down
4 changes: 2 additions & 2 deletions dist/settings-vue-settings-admin-basic-settings.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-admin-basic-settings.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-personal-info.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-personal-info.js.map

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion lib/private/Template/JSConfigHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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;
Expand Down Expand Up @@ -133,6 +134,9 @@ public function getConfig(): string {

$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,
Expand Down Expand Up @@ -220,7 +224,7 @@ public function getConfig(): string {
$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' => [
Expand Down
Loading