mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 09:13:19 -04:00
fix(settings): Use status states from NcInputField instead of custom handling
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de> Co-authored-by: Pytal <24800714+Pytal@users.noreply.github.com> Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
fe58d8aae9
commit
3e09295fa1
12 changed files with 420 additions and 406 deletions
|
|
@ -99,7 +99,7 @@ export default {
|
|||
flex-direction: column;
|
||||
margin: 10px 32px 10px 0;
|
||||
gap: 16px 0;
|
||||
color: var(--color-text-lighter);
|
||||
color: var(--color-text-maxcontrast);
|
||||
|
||||
&__groups,
|
||||
&__quota {
|
||||
|
|
@ -117,7 +117,7 @@ export default {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
&::v-deep .material-design-icon {
|
||||
&:deep(.material-design-icon) {
|
||||
align-self: flex-start;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,63 +23,69 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="email">
|
||||
<input :id="inputIdWithDefault"
|
||||
<NcInputField :id="inputIdWithDefault"
|
||||
ref="email"
|
||||
type="email"
|
||||
autocomplete="email"
|
||||
:aria-label="inputPlaceholder"
|
||||
:placeholder="inputPlaceholder"
|
||||
:value="email"
|
||||
:aria-describedby="helperText ? `${inputIdWithDefault}-helper-text` : undefined"
|
||||
autocapitalize="none"
|
||||
autocomplete="email"
|
||||
:error="hasError || !!helperText"
|
||||
:helper-text="helperText || undefined"
|
||||
:label="inputPlaceholder"
|
||||
:placeholder="inputPlaceholder"
|
||||
spellcheck="false"
|
||||
@input="onEmailChange">
|
||||
:success="isSuccess"
|
||||
type="email"
|
||||
:value.sync="emailAddress" />
|
||||
|
||||
<div class="email__actions-container">
|
||||
<transition name="fade">
|
||||
<Check v-if="showCheckmarkIcon" :size="20" />
|
||||
<AlertOctagon v-else-if="showErrorIcon" :size="20" />
|
||||
</transition>
|
||||
|
||||
<template v-if="!primary">
|
||||
<FederationControl :readable="propertyReadable"
|
||||
:additional="true"
|
||||
:additional-value="email"
|
||||
:disabled="federationDisabled"
|
||||
:handle-additional-scope-change="saveAdditionalEmailScope"
|
||||
:scope.sync="localScope"
|
||||
@update:scope="onScopeChange" />
|
||||
</template>
|
||||
|
||||
<NcActions class="email__actions"
|
||||
:aria-label="t('settings', 'Email options')"
|
||||
:force-menu="true">
|
||||
<NcActionButton :aria-label="deleteEmailLabel"
|
||||
:close-after-click="true"
|
||||
:disabled="deleteDisabled"
|
||||
icon="icon-delete"
|
||||
@click.stop.prevent="deleteEmail">
|
||||
{{ deleteEmailLabel }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!primary || !isNotificationEmail"
|
||||
:aria-label="setNotificationMailLabel"
|
||||
:close-after-click="true"
|
||||
:disabled="setNotificationMailDisabled"
|
||||
icon="icon-favorite"
|
||||
@click.stop.prevent="setNotificationMail">
|
||||
{{ setNotificationMailLabel }}
|
||||
</NcActionButton>
|
||||
<div class="email__actions">
|
||||
<NcActions :aria-label="actionsLabel" @close="showFederationSettings = false">
|
||||
<template v-if="showFederationSettings">
|
||||
<NcActionButton @click="showFederationSettings = false">
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper :path="mdiArrowLeft" />
|
||||
</template>
|
||||
{{ t('settings', 'Back') }}
|
||||
</NcActionButton>
|
||||
<FederationControlActions :readable="propertyReadable"
|
||||
:additional="true"
|
||||
:additional-value="email"
|
||||
:disabled="federationDisabled"
|
||||
:handle-additional-scope-change="saveAdditionalEmailScope"
|
||||
:scope.sync="localScope"
|
||||
@update:scope="onScopeChange" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<NcActionButton v-if="!federationDisabled && !primary"
|
||||
@click="showFederationSettings = true">
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper :path="mdiLock" />
|
||||
</template>
|
||||
{{ t('settings', 'Change scope level of {property}', { property: propertyReadable.toLocaleLowerCase() }) }}
|
||||
</NcActionButton>
|
||||
<NcActionCaption v-if="!isConfirmedAddress"
|
||||
:name="t('settings', 'This address is not confirmed')" />
|
||||
<NcActionButton close-after-click
|
||||
:disabled="deleteDisabled"
|
||||
@click="deleteEmail">
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper :path="mdiTrashCan" />
|
||||
</template>
|
||||
{{ deleteEmailLabel }}
|
||||
</NcActionButton>
|
||||
<NcActionButton v-if="!primary || !isNotificationEmail"
|
||||
close-after-click
|
||||
:disabled="!isConfirmedAddress"
|
||||
@click="setNotificationMail">
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper v-if="isNotificationEmail" :path="mdiStar" />
|
||||
<NcIconSvgWrapper v-else :path="mdiStarOutline" />
|
||||
</template>
|
||||
{{ setNotificationMailLabel }}
|
||||
</NcActionButton>
|
||||
</template>
|
||||
</NcActions>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p v-if="helperText"
|
||||
:id="`${inputIdWithDefault}-helper-text`"
|
||||
class="email__helper-text-message email__helper-text-message--error">
|
||||
<AlertCircle class="email__helper-text-message__icon" :size="18" />
|
||||
{{ helperText }}
|
||||
</p>
|
||||
|
||||
<em v-if="isNotificationEmail">
|
||||
{{ t('settings', 'Primary email for password reset and notifications') }}
|
||||
</em>
|
||||
|
|
@ -89,12 +95,13 @@
|
|||
<script>
|
||||
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import AlertCircle from 'vue-material-design-icons/AlertCircleOutline.vue'
|
||||
import AlertOctagon from 'vue-material-design-icons/AlertOctagon.vue'
|
||||
import Check from 'vue-material-design-icons/Check.vue'
|
||||
import NcActionCaption from '@nextcloud/vue/dist/Components/NcActionCaption.js'
|
||||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
|
||||
import debounce from 'debounce'
|
||||
|
||||
import FederationControl from '../shared/FederationControl.vue'
|
||||
import { mdiArrowLeft, mdiLock, mdiStar, mdiStarOutline, mdiTrashCan } from '@mdi/js'
|
||||
import FederationControlActions from '../shared/FederationControlActions.vue'
|
||||
import { handleError } from '../../../utils/handlers.js'
|
||||
|
||||
import { ACCOUNT_PROPERTY_READABLE_ENUM, VERIFICATION_ENUM } from '../../../constants/AccountPropertyConstants.js'
|
||||
|
|
@ -114,10 +121,10 @@ export default {
|
|||
components: {
|
||||
NcActions,
|
||||
NcActionButton,
|
||||
AlertCircle,
|
||||
AlertOctagon,
|
||||
Check,
|
||||
FederationControl,
|
||||
NcActionCaption,
|
||||
NcIconSvgWrapper,
|
||||
NcInputField,
|
||||
FederationControlActions,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
@ -152,19 +159,38 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
mdiArrowLeft,
|
||||
mdiLock,
|
||||
mdiStar,
|
||||
mdiStarOutline,
|
||||
mdiTrashCan,
|
||||
saveAdditionalEmailScope,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
propertyReadable: ACCOUNT_PROPERTY_READABLE_ENUM.EMAIL,
|
||||
initialEmail: this.email,
|
||||
localScope: this.scope,
|
||||
saveAdditionalEmailScope,
|
||||
hasError: false,
|
||||
helperText: null,
|
||||
showCheckmarkIcon: false,
|
||||
showErrorIcon: false,
|
||||
initialEmail: this.email,
|
||||
isSuccess: false,
|
||||
localScope: this.scope,
|
||||
propertyReadable: ACCOUNT_PROPERTY_READABLE_ENUM.EMAIL,
|
||||
showFederationSettings: false,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
actionsLabel() {
|
||||
if (this.primary) {
|
||||
return t('settings', 'Email options')
|
||||
} else {
|
||||
return t('settings', 'Options for additional email address {index}', { index: this.index + 1 })
|
||||
}
|
||||
},
|
||||
|
||||
deleteDisabled() {
|
||||
if (this.primary) {
|
||||
// Disable for empty primary email as there is nothing to delete
|
||||
|
|
@ -183,15 +209,13 @@ export default {
|
|||
return t('settings', 'Delete email')
|
||||
},
|
||||
|
||||
setNotificationMailDisabled() {
|
||||
return !this.primary && this.localVerificationState !== VERIFICATION_ENUM.VERIFIED
|
||||
isConfirmedAddress() {
|
||||
return this.primary || this.localVerificationState === VERIFICATION_ENUM.VERIFIED
|
||||
},
|
||||
|
||||
setNotificationMailLabel() {
|
||||
setNotificationMailLabel() {
|
||||
if (this.isNotificationEmail) {
|
||||
return t('settings', 'Unset as primary email')
|
||||
} else if (!this.primary && this.localVerificationState !== VERIFICATION_ENUM.VERIFIED) {
|
||||
return t('settings', 'This address is not confirmed')
|
||||
}
|
||||
return t('settings', 'Set as primary email')
|
||||
},
|
||||
|
|
@ -213,25 +237,30 @@ export default {
|
|||
return (this.email && this.email === this.activeNotificationEmail)
|
||||
|| (this.primary && this.activeNotificationEmail === '')
|
||||
},
|
||||
|
||||
emailAddress: {
|
||||
get() {
|
||||
return this.email
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:email', value)
|
||||
this.debounceEmailChange(value.trim())
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.primary && this.initialEmail === '') {
|
||||
// $nextTick is needed here, otherwise it may not always work https://stackoverflow.com/questions/51922767/autofocus-input-on-mount-vue-ios/63485725#63485725
|
||||
// $nextTick is needed here, otherwise it may not always work
|
||||
// https://stackoverflow.com/questions/51922767/autofocus-input-on-mount-vue-ios/63485725#63485725
|
||||
this.$nextTick(() => this.$refs.email?.focus())
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onEmailChange(e) {
|
||||
this.$emit('update:email', e.target.value)
|
||||
this.debounceEmailChange(e.target.value.trim())
|
||||
},
|
||||
|
||||
debounceEmailChange: debounce(async function(email) {
|
||||
this.helperText = null
|
||||
if (this.$refs.email?.validationMessage) {
|
||||
this.helperText = this.$refs.email.validationMessage
|
||||
this.helperText = this.$refs.email?.$refs.input?.validationMessage || null
|
||||
if (this.helperText !== null) {
|
||||
return
|
||||
}
|
||||
if (validateEmail(email) || email === '') {
|
||||
|
|
@ -356,12 +385,12 @@ export default {
|
|||
} else if (notificationEmail !== undefined) {
|
||||
this.$emit('update:notification-email', notificationEmail)
|
||||
}
|
||||
this.showCheckmarkIcon = true
|
||||
setTimeout(() => { this.showCheckmarkIcon = false }, 2000)
|
||||
this.isSuccess = true
|
||||
setTimeout(() => { this.isSuccess = false }, 2000)
|
||||
} else {
|
||||
handleError(error, errorMessage)
|
||||
this.showErrorIcon = true
|
||||
setTimeout(() => { this.showErrorIcon = false }, 2000)
|
||||
this.hasError = true
|
||||
setTimeout(() => { this.hasError = false }, 2000)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -374,66 +403,16 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.email {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.email__actions-container {
|
||||
grid-area: 1 / 1;
|
||||
justify-self: flex-end;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: start;
|
||||
gap: 4px;
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
gap: 0 2px;
|
||||
margin-right: 5px;
|
||||
|
||||
.email__actions {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
|
||||
&::v-deep button {
|
||||
height: 30px !important;
|
||||
min-height: 30px !important;
|
||||
width: 30px !important;
|
||||
min-width: 30px !important;
|
||||
}
|
||||
}
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
&__helper-text-message {
|
||||
padding: 4px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__icon {
|
||||
margin-right: 8px;
|
||||
align-self: start;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
&--error {
|
||||
color: var(--color-error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-enter-active {
|
||||
transition: opacity 200ms ease-out;
|
||||
}
|
||||
|
||||
.fade-leave-active {
|
||||
transition: opacity 300ms ease-out;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -199,10 +199,6 @@ export default {
|
|||
section {
|
||||
padding: 10px 10px;
|
||||
|
||||
&::v-deep button:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.additional-emails-label {
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
|
|
|
|||
|
|
@ -22,23 +22,15 @@
|
|||
|
||||
<template>
|
||||
<div class="language">
|
||||
<select :id="inputId" @change="onLanguageChange">
|
||||
<option v-for="commonLanguage in commonLanguages"
|
||||
:key="commonLanguage.code"
|
||||
:selected="language.code === commonLanguage.code"
|
||||
:value="commonLanguage.code">
|
||||
{{ commonLanguage.name }}
|
||||
</option>
|
||||
<option disabled>
|
||||
──────────
|
||||
</option>
|
||||
<option v-for="otherLanguage in otherLanguages"
|
||||
:key="otherLanguage.code"
|
||||
:selected="language.code === otherLanguage.code"
|
||||
:value="otherLanguage.code">
|
||||
{{ otherLanguage.name }}
|
||||
</option>
|
||||
</select>
|
||||
<NcSelect :aria-label-listbox="t('settings', 'Languages')"
|
||||
class="language__select"
|
||||
:clearable="false"
|
||||
:input-id="inputId"
|
||||
label="name"
|
||||
label-outside
|
||||
:options="allLanguages"
|
||||
:value="language"
|
||||
@option:selected="onLanguageChange" />
|
||||
|
||||
<a href="https://www.transifex.com/nextcloud/nextcloud/"
|
||||
target="_blank"
|
||||
|
|
@ -54,9 +46,15 @@ import { savePrimaryAccountProperty } from '../../../service/PersonalInfo/Person
|
|||
import { validateLanguage } from '../../../utils/validate.js'
|
||||
import { handleError } from '../../../utils/handlers.js'
|
||||
|
||||
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
|
||||
|
||||
export default {
|
||||
name: 'Language',
|
||||
|
||||
components: {
|
||||
NcSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
inputId: {
|
||||
type: String,
|
||||
|
|
@ -83,17 +81,18 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* All available languages, sorted like: current, common, other
|
||||
*/
|
||||
allLanguages() {
|
||||
return Object.freeze(
|
||||
[...this.commonLanguages, ...this.otherLanguages]
|
||||
.reduce((acc, { code, name }) => ({ ...acc, [code]: name }), {}),
|
||||
)
|
||||
const common = this.commonLanguages.filter(l => l.code !== this.language.code)
|
||||
const other = this.otherLanguages.filter(l => l.code !== this.language.code)
|
||||
return [this.language, ...common, ...other]
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async onLanguageChange(e) {
|
||||
const language = this.constructLanguage(e.target.value)
|
||||
async onLanguageChange(language) {
|
||||
this.$emit('update:language', language)
|
||||
|
||||
if (validateLanguage(language)) {
|
||||
|
|
@ -108,7 +107,7 @@ export default {
|
|||
language,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
this.reloadPage()
|
||||
window.location.reload()
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update language'),
|
||||
|
|
@ -117,13 +116,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
constructLanguage(languageCode) {
|
||||
return {
|
||||
code: languageCode,
|
||||
name: this.allLanguages[languageCode],
|
||||
}
|
||||
},
|
||||
|
||||
handleResponse({ language, status, errorMessage, error }) {
|
||||
if (status === 'ok') {
|
||||
// Ensure that local state reflects server state
|
||||
|
|
@ -132,10 +124,6 @@ export default {
|
|||
handleError(error, errorMessage)
|
||||
}
|
||||
},
|
||||
|
||||
reloadPage() {
|
||||
location.reload()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -144,12 +132,11 @@ export default {
|
|||
.language {
|
||||
display: grid;
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
#{&}__select {
|
||||
margin-top: 6px; // align with other inputs
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-main-text);
|
||||
text-decoration: none;
|
||||
width: max-content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,11 @@
|
|||
<HeaderBar :input-id="inputId"
|
||||
:readable="propertyReadable" />
|
||||
|
||||
<template v-if="isEditable">
|
||||
<Language :input-id="inputId"
|
||||
:common-languages="commonLanguages"
|
||||
:other-languages="otherLanguages"
|
||||
:language.sync="language" />
|
||||
</template>
|
||||
<Language v-if="isEditable"
|
||||
:input-id="inputId"
|
||||
:common-languages="commonLanguages"
|
||||
:other-languages="otherLanguages"
|
||||
:language.sync="language" />
|
||||
|
||||
<span v-else>
|
||||
{{ t('settings', 'No language set') }}
|
||||
|
|
@ -56,11 +55,17 @@ export default {
|
|||
HeaderBar,
|
||||
},
|
||||
|
||||
data() {
|
||||
setup() {
|
||||
// Non reactive instance properties
|
||||
return {
|
||||
propertyReadable: ACCOUNT_SETTING_PROPERTY_READABLE_ENUM.LANGUAGE,
|
||||
commonLanguages,
|
||||
otherLanguages,
|
||||
propertyReadable: ACCOUNT_SETTING_PROPERTY_READABLE_ENUM.LANGUAGE,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
language: activeLanguage,
|
||||
}
|
||||
},
|
||||
|
|
@ -80,9 +85,5 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
section {
|
||||
padding: 10px 10px;
|
||||
|
||||
&::v-deep button:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -22,26 +22,18 @@
|
|||
|
||||
<template>
|
||||
<div class="locale">
|
||||
<select :id="inputId" @change="onLocaleChange">
|
||||
<option v-for="currentLocale in localesForLanguage"
|
||||
:key="currentLocale.code"
|
||||
:selected="locale.code === currentLocale.code"
|
||||
:value="currentLocale.code">
|
||||
{{ currentLocale.name }}
|
||||
</option>
|
||||
<option disabled>
|
||||
──────────
|
||||
</option>
|
||||
<option v-for="currentLocale in otherLocales"
|
||||
:key="currentLocale.code"
|
||||
:selected="locale.code === currentLocale.code"
|
||||
:value="currentLocale.code">
|
||||
{{ currentLocale.name }}
|
||||
</option>
|
||||
</select>
|
||||
<NcSelect :aria-label-listbox="t('settings', 'Locales')"
|
||||
class="locale__select"
|
||||
:clearable="false"
|
||||
:input-id="inputId"
|
||||
label="name"
|
||||
label-outside
|
||||
:options="allLocales"
|
||||
:value="locale"
|
||||
@option:selected="updateLocale" />
|
||||
|
||||
<div class="example">
|
||||
<Web :size="20" />
|
||||
<MapClock :size="20" />
|
||||
<div class="example__text">
|
||||
<p>
|
||||
<span>{{ example.date }}</span>
|
||||
|
|
@ -57,18 +49,19 @@
|
|||
|
||||
<script>
|
||||
import moment from '@nextcloud/moment'
|
||||
import Web from 'vue-material-design-icons/Web.vue'
|
||||
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
|
||||
import MapClock from 'vue-material-design-icons/MapClock.vue'
|
||||
|
||||
import { ACCOUNT_SETTING_PROPERTY_ENUM } from '../../../constants/AccountPropertyConstants.js'
|
||||
import { savePrimaryAccountProperty } from '../../../service/PersonalInfo/PersonalInfoService.js'
|
||||
import { validateLocale } from '../../../utils/validate.js'
|
||||
import { handleError } from '../../../utils/handlers.js'
|
||||
|
||||
export default {
|
||||
name: 'Locale',
|
||||
|
||||
components: {
|
||||
Web,
|
||||
MapClock,
|
||||
NcSelect,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
@ -93,6 +86,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
initialLocale: this.locale,
|
||||
intervalId: 0,
|
||||
example: {
|
||||
date: moment().format('L'),
|
||||
time: moment().format('LTS'),
|
||||
|
|
@ -102,28 +96,25 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* All available locale, sorted like: current, common, other
|
||||
*/
|
||||
allLocales() {
|
||||
return Object.freeze(
|
||||
[...this.localesForLanguage, ...this.otherLocales]
|
||||
.reduce((acc, { code, name }) => ({ ...acc, [code]: name }), {}),
|
||||
)
|
||||
const common = this.localesForLanguage.filter(l => l.code !== this.locale.code)
|
||||
const other = this.otherLocales.filter(l => l.code !== this.locale.code)
|
||||
return [this.locale, ...common, ...other]
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
setInterval(this.refreshExample, 1000)
|
||||
mounted() {
|
||||
this.intervalId = window.setInterval(this.refreshExample, 1000)
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
window.clearInterval(this.intervalId)
|
||||
},
|
||||
|
||||
methods: {
|
||||
async onLocaleChange(e) {
|
||||
const locale = this.constructLocale(e.target.value)
|
||||
this.$emit('update:locale', locale)
|
||||
|
||||
if (validateLocale(locale)) {
|
||||
await this.updateLocale(locale)
|
||||
}
|
||||
},
|
||||
|
||||
async updateLocale(locale) {
|
||||
try {
|
||||
const responseData = await savePrimaryAccountProperty(ACCOUNT_SETTING_PROPERTY_ENUM.LOCALE, locale.code)
|
||||
|
|
@ -131,7 +122,7 @@ export default {
|
|||
locale,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
this.reloadPage()
|
||||
window.location.reload()
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update locale'),
|
||||
|
|
@ -140,13 +131,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
constructLocale(localeCode) {
|
||||
return {
|
||||
code: localeCode,
|
||||
name: this.allLocales[localeCode],
|
||||
}
|
||||
},
|
||||
|
||||
handleResponse({ locale, status, errorMessage, error }) {
|
||||
if (status === 'ok') {
|
||||
this.initialLocale = locale
|
||||
|
|
@ -163,10 +147,6 @@ export default {
|
|||
firstDayOfWeek: window.dayNames[window.firstDay],
|
||||
}
|
||||
},
|
||||
|
||||
reloadPage() {
|
||||
location.reload()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -175,8 +155,8 @@ export default {
|
|||
.locale {
|
||||
display: grid;
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
#{&}__select {
|
||||
margin-top: 6px; // align with other inputs
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,9 +164,9 @@ export default {
|
|||
margin: 10px 0;
|
||||
display: flex;
|
||||
gap: 0 10px;
|
||||
color: var(--color-text-lighter);
|
||||
color: var(--color-text-maxcontrast);
|
||||
|
||||
&::v-deep .material-design-icon {
|
||||
&:deep(.material-design-icon) {
|
||||
align-self: flex-start;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,11 @@
|
|||
<HeaderBar :input-id="inputId"
|
||||
:readable="propertyReadable" />
|
||||
|
||||
<template v-if="isEditable">
|
||||
<Locale :input-id="inputId"
|
||||
:locales-for-language="localesForLanguage"
|
||||
:other-locales="otherLocales"
|
||||
:locale.sync="locale" />
|
||||
</template>
|
||||
<Locale v-if="isEditable"
|
||||
:input-id="inputId"
|
||||
:locales-for-language="localesForLanguage"
|
||||
:other-locales="otherLocales"
|
||||
:locale.sync="locale" />
|
||||
|
||||
<span v-else>
|
||||
{{ t('settings', 'No locale set') }}
|
||||
|
|
@ -80,9 +79,5 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
section {
|
||||
padding: 10px 10px;
|
||||
|
||||
&::v-deep button:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
:checked.sync="isProfileEnabled"
|
||||
:loading="loading"
|
||||
@update:checked="saveEnableProfile">
|
||||
{{ t('settings', 'Enable Profile') }}
|
||||
{{ t('settings', 'Enable profile') }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -33,40 +33,31 @@
|
|||
:id="inputId"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
:error="hasError || !!helperText"
|
||||
:helper-text="helperText"
|
||||
label-outside
|
||||
:placeholder="placeholder"
|
||||
rows="8"
|
||||
spellcheck="false"
|
||||
:success="isSuccess"
|
||||
:value.sync="inputValue" />
|
||||
<NcInputField v-else
|
||||
:id="inputId"
|
||||
ref="input"
|
||||
:aria-describedby="helperText ? `${name}-helper-text` : undefined"
|
||||
autocapitalize="none"
|
||||
:autocomplete="autocomplete"
|
||||
:error="hasError || !!helperText"
|
||||
:helper-text="helperText"
|
||||
label-outside
|
||||
:placeholder="placeholder"
|
||||
spellcheck="false"
|
||||
:success="isSuccess"
|
||||
:type="type"
|
||||
:value.sync="inputValue" />
|
||||
|
||||
<div class="property__actions-container">
|
||||
<Transition name="fade">
|
||||
<Check v-if="showCheckmarkIcon" :size="20" />
|
||||
<AlertOctagon v-else-if="showErrorIcon" :size="20" />
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
<span v-else>
|
||||
{{ value || t('settings', 'No {property} set', { property: readable.toLocaleLowerCase() }) }}
|
||||
</span>
|
||||
|
||||
<p v-if="helperText"
|
||||
:id="`${name}-helper-text`"
|
||||
class="property__helper-text-message property__helper-text-message--error">
|
||||
<AlertCircle class="property__helper-text-message__icon" :size="18" />
|
||||
{{ helperText }}
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
|
@ -74,9 +65,6 @@
|
|||
import debounce from 'debounce'
|
||||
import NcInputField from '@nextcloud/vue/dist/Components/NcInputField.js'
|
||||
import NcTextArea from '@nextcloud/vue/dist/Components/NcTextArea.js'
|
||||
import AlertCircle from 'vue-material-design-icons/AlertCircleOutline.vue'
|
||||
import AlertOctagon from 'vue-material-design-icons/AlertOctagon.vue'
|
||||
import Check from 'vue-material-design-icons/Check.vue'
|
||||
|
||||
import HeaderBar from './HeaderBar.vue'
|
||||
|
||||
|
|
@ -87,9 +75,6 @@ export default {
|
|||
name: 'AccountPropertySection',
|
||||
|
||||
components: {
|
||||
AlertCircle,
|
||||
AlertOctagon,
|
||||
Check,
|
||||
HeaderBar,
|
||||
NcInputField,
|
||||
NcTextArea,
|
||||
|
|
@ -147,9 +132,9 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
initialValue: this.value,
|
||||
helperText: null,
|
||||
showCheckmarkIcon: false,
|
||||
showErrorIcon: false,
|
||||
helperText: '',
|
||||
isSuccess: false,
|
||||
hasError: false,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -170,12 +155,13 @@ export default {
|
|||
|
||||
debouncePropertyChange() {
|
||||
return debounce(async function(value) {
|
||||
this.helperText = null
|
||||
if (this.$refs.input && this.$refs.input.validationMessage) {
|
||||
this.helperText = this.$refs.input.validationMessage
|
||||
this.helperText = this.$refs.input?.$refs.input?.validationMessage || ''
|
||||
if (this.helperText !== '') {
|
||||
return
|
||||
}
|
||||
if (this.onValidate && !this.onValidate(value)) {
|
||||
this.hasError = this.onValidate && !this.onValidate(value)
|
||||
if (this.hasError) {
|
||||
this.helperText = t('settings', 'Invalid value')
|
||||
return
|
||||
}
|
||||
await this.updateProperty(value)
|
||||
|
|
@ -208,13 +194,13 @@ export default {
|
|||
if (this.onSave) {
|
||||
this.onSave(value)
|
||||
}
|
||||
this.showCheckmarkIcon = true
|
||||
setTimeout(() => { this.showCheckmarkIcon = false }, 2000)
|
||||
this.isSuccess = true
|
||||
setTimeout(() => { this.isSuccess = false }, 2000)
|
||||
} else {
|
||||
this.$emit('update:value', this.initialValue)
|
||||
handleError(error, errorMessage)
|
||||
this.showErrorIcon = true
|
||||
setTimeout(() => { this.showErrorIcon = false }, 2000)
|
||||
this.hasError = true
|
||||
setTimeout(() => { this.hasError = false }, 2000)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -226,25 +212,15 @@ section {
|
|||
padding: 10px 10px;
|
||||
|
||||
.property {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: start;
|
||||
gap: 4px;
|
||||
|
||||
.property__actions-container {
|
||||
grid-area: 1 / 1;
|
||||
margin-top: 6px;
|
||||
justify-self: flex-end;
|
||||
align-self: flex-end;
|
||||
height: 30px;
|
||||
|
||||
display: flex;
|
||||
gap: 0 2px;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
- @copyright 2021, Christopher Ng <chrng8@gmail.com>
|
||||
-
|
||||
- @author Christopher Ng <chrng8@gmail.com>
|
||||
- @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
|
|
@ -25,51 +26,37 @@
|
|||
class="federation-actions"
|
||||
:class="{ 'federation-actions--additional': additional }"
|
||||
:aria-label="ariaLabel"
|
||||
:default-icon="scopeIcon"
|
||||
:disabled="disabled">
|
||||
<NcActionButton v-for="federationScope in federationScopes"
|
||||
:key="federationScope.name"
|
||||
:close-after-click="true"
|
||||
:disabled="!supportedScopes.includes(federationScope.name)"
|
||||
:icon="federationScope.iconClass"
|
||||
:name="federationScope.displayName"
|
||||
type="radio"
|
||||
:value="federationScope.name"
|
||||
:model-value="scope"
|
||||
@update:modelValue="changeScope">
|
||||
{{ supportedScopes.includes(federationScope.name) ? federationScope.tooltip : federationScope.tooltipDisabled }}
|
||||
</NcActionButton>
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper :path="scopeIcon" />
|
||||
</template>
|
||||
<FederationControlActions :additional="additional"
|
||||
:additional-value="additionalValue"
|
||||
:handle-additional-scope-change="handleAdditionalScopeChange"
|
||||
:readable="readable"
|
||||
:scope="scope"
|
||||
@update:scope="onUpdateScope" />
|
||||
</NcActions>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
|
||||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
import {
|
||||
ACCOUNT_PROPERTY_READABLE_ENUM,
|
||||
ACCOUNT_SETTING_PROPERTY_READABLE_ENUM,
|
||||
PROFILE_READABLE_ENUM,
|
||||
PROPERTY_READABLE_KEYS_ENUM,
|
||||
PROPERTY_READABLE_SUPPORTED_SCOPES_ENUM,
|
||||
SCOPE_ENUM, SCOPE_PROPERTY_ENUM,
|
||||
UNPUBLISHED_READABLE_PROPERTIES,
|
||||
SCOPE_PROPERTY_ENUM,
|
||||
} from '../../../constants/AccountPropertyConstants.js'
|
||||
import { savePrimaryAccountPropertyScope } from '../../../service/PersonalInfo/PersonalInfoService.js'
|
||||
import { handleError } from '../../../utils/handlers.js'
|
||||
|
||||
const {
|
||||
federationEnabled,
|
||||
lookupServerUploadEnabled,
|
||||
} = loadState('settings', 'accountParameters', {})
|
||||
import FederationControlActions from './FederationControlActions.vue'
|
||||
|
||||
export default {
|
||||
name: 'FederationControl',
|
||||
|
||||
components: {
|
||||
NcActions,
|
||||
NcActionButton,
|
||||
NcIconSvgWrapper,
|
||||
FederationControlActions,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
@ -103,7 +90,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
readableLowerCase: this.readable.toLocaleLowerCase(),
|
||||
initialScope: this.scope,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -117,84 +103,16 @@ export default {
|
|||
},
|
||||
|
||||
scopeIcon() {
|
||||
return SCOPE_PROPERTY_ENUM[this.scope].iconClass
|
||||
},
|
||||
|
||||
federationScopes() {
|
||||
return Object.values(SCOPE_PROPERTY_ENUM)
|
||||
},
|
||||
|
||||
supportedScopes() {
|
||||
const scopes = PROPERTY_READABLE_SUPPORTED_SCOPES_ENUM[this.readable]
|
||||
|
||||
if (UNPUBLISHED_READABLE_PROPERTIES.includes(this.readable)) {
|
||||
return scopes
|
||||
}
|
||||
|
||||
if (federationEnabled) {
|
||||
scopes.push(SCOPE_ENUM.FEDERATED)
|
||||
}
|
||||
|
||||
if (lookupServerUploadEnabled) {
|
||||
scopes.push(SCOPE_ENUM.PUBLISHED)
|
||||
}
|
||||
|
||||
return scopes
|
||||
return SCOPE_PROPERTY_ENUM[this.scope].icon
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async changeScope(scope) {
|
||||
onUpdateScope(scope) {
|
||||
this.$emit('update:scope', scope)
|
||||
|
||||
if (!this.additional) {
|
||||
await this.updatePrimaryScope(scope)
|
||||
} else {
|
||||
await this.updateAdditionalScope(scope)
|
||||
}
|
||||
|
||||
// TODO: provide focus method from NcActions
|
||||
this.$refs.federationActions.$refs.menuButton.$el.focus()
|
||||
},
|
||||
|
||||
async updatePrimaryScope(scope) {
|
||||
try {
|
||||
const responseData = await savePrimaryAccountPropertyScope(PROPERTY_READABLE_KEYS_ENUM[this.readable], scope)
|
||||
this.handleResponse({
|
||||
scope,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update federation scope of the primary {property}', { property: this.readableLowerCase }),
|
||||
error: e,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
async updateAdditionalScope(scope) {
|
||||
try {
|
||||
const responseData = await this.handleAdditionalScopeChange(this.additionalValue, scope)
|
||||
this.handleResponse({
|
||||
scope,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update federation scope of additional {property}', { property: this.readableLowerCase }),
|
||||
error: e,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
handleResponse({ scope, status, errorMessage, error }) {
|
||||
if (status === 'ok') {
|
||||
this.initialScope = scope
|
||||
} else {
|
||||
this.$emit('update:scope', this.initialScope)
|
||||
handleError(error, errorMessage)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
<!--
|
||||
- @copyright 2021, Christopher Ng <chrng8@gmail.com>
|
||||
-
|
||||
- @author Christopher Ng <chrng8@gmail.com>
|
||||
- @author Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<Fragment>
|
||||
<NcActionButton v-for="federationScope in federationScopes"
|
||||
:key="federationScope.name"
|
||||
:close-after-click="true"
|
||||
:disabled="!supportedScopes.includes(federationScope.name)"
|
||||
:name="federationScope.displayName"
|
||||
type="radio"
|
||||
:value="federationScope.name"
|
||||
:model-value="scope"
|
||||
@update:modelValue="changeScope">
|
||||
<template #icon>
|
||||
<NcIconSvgWrapper :path="federationScope.icon" />
|
||||
</template>
|
||||
{{ supportedScopes.includes(federationScope.name) ? federationScope.tooltip : federationScope.tooltipDisabled }}
|
||||
</NcActionButton>
|
||||
</Fragment>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
|
||||
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
|
||||
import { loadState } from '@nextcloud/initial-state'
|
||||
import { Fragment } from 'vue-frag'
|
||||
|
||||
import {
|
||||
ACCOUNT_PROPERTY_READABLE_ENUM,
|
||||
ACCOUNT_SETTING_PROPERTY_READABLE_ENUM,
|
||||
PROFILE_READABLE_ENUM,
|
||||
PROPERTY_READABLE_KEYS_ENUM,
|
||||
PROPERTY_READABLE_SUPPORTED_SCOPES_ENUM,
|
||||
SCOPE_ENUM, SCOPE_PROPERTY_ENUM,
|
||||
UNPUBLISHED_READABLE_PROPERTIES,
|
||||
} from '../../../constants/AccountPropertyConstants.js'
|
||||
import { savePrimaryAccountPropertyScope } from '../../../service/PersonalInfo/PersonalInfoService.js'
|
||||
import { handleError } from '../../../utils/handlers.js'
|
||||
|
||||
const {
|
||||
federationEnabled,
|
||||
lookupServerUploadEnabled,
|
||||
} = loadState('settings', 'accountParameters', {})
|
||||
|
||||
export default {
|
||||
name: 'FederationControlActions',
|
||||
|
||||
components: {
|
||||
Fragment,
|
||||
NcActionButton,
|
||||
NcIconSvgWrapper,
|
||||
},
|
||||
|
||||
props: {
|
||||
readable: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: (value) => Object.values(ACCOUNT_PROPERTY_READABLE_ENUM).includes(value) || Object.values(ACCOUNT_SETTING_PROPERTY_READABLE_ENUM).includes(value) || value === PROFILE_READABLE_ENUM.PROFILE_VISIBILITY,
|
||||
},
|
||||
additional: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
additionalValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
handleAdditionalScopeChange: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
scope: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
readableLowerCase: this.readable.toLocaleLowerCase(),
|
||||
initialScope: this.scope,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
federationScopes() {
|
||||
return Object.values(SCOPE_PROPERTY_ENUM)
|
||||
},
|
||||
|
||||
supportedScopes() {
|
||||
const scopes = PROPERTY_READABLE_SUPPORTED_SCOPES_ENUM[this.readable]
|
||||
|
||||
if (UNPUBLISHED_READABLE_PROPERTIES.includes(this.readable)) {
|
||||
return scopes
|
||||
}
|
||||
|
||||
if (federationEnabled) {
|
||||
scopes.push(SCOPE_ENUM.FEDERATED)
|
||||
}
|
||||
|
||||
if (lookupServerUploadEnabled) {
|
||||
scopes.push(SCOPE_ENUM.PUBLISHED)
|
||||
}
|
||||
|
||||
return scopes
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
async changeScope(scope) {
|
||||
this.$emit('update:scope', scope)
|
||||
|
||||
if (!this.additional) {
|
||||
await this.updatePrimaryScope(scope)
|
||||
} else {
|
||||
await this.updateAdditionalScope(scope)
|
||||
}
|
||||
},
|
||||
|
||||
async updatePrimaryScope(scope) {
|
||||
try {
|
||||
const responseData = await savePrimaryAccountPropertyScope(PROPERTY_READABLE_KEYS_ENUM[this.readable], scope)
|
||||
this.handleResponse({
|
||||
scope,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update federation scope of the primary {property}', { property: this.readableLowerCase }),
|
||||
error: e,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
async updateAdditionalScope(scope) {
|
||||
try {
|
||||
const responseData = await this.handleAdditionalScopeChange(this.additionalValue, scope)
|
||||
this.handleResponse({
|
||||
scope,
|
||||
status: responseData.ocs?.meta?.status,
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleResponse({
|
||||
errorMessage: t('settings', 'Unable to update federation scope of additional {property}', { property: this.readableLowerCase }),
|
||||
error: e,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
handleResponse({ scope, status, errorMessage, error }) {
|
||||
if (status === 'ok') {
|
||||
this.initialScope = scope
|
||||
} else {
|
||||
this.$emit('update:scope', this.initialScope)
|
||||
handleError(error, errorMessage)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
* SYNC to be kept in sync with `lib/public/Accounts/IAccountManager.php`
|
||||
*/
|
||||
|
||||
import { mdiAccountGroup, mdiCellphone, mdiLock, mdiWeb } from '@mdi/js'
|
||||
import { translate as t } from '@nextcloud/l10n'
|
||||
|
||||
/** Enum of account properties */
|
||||
|
|
@ -167,28 +168,28 @@ export const SCOPE_PROPERTY_ENUM = Object.freeze({
|
|||
displayName: t('settings', 'Private'),
|
||||
tooltip: t('settings', 'Only visible to people matched via phone number integration through Talk on mobile'),
|
||||
tooltipDisabled: t('settings', 'Not available as this property is required for core functionality including file sharing and calendar invitations'),
|
||||
iconClass: 'icon-phone',
|
||||
icon: mdiCellphone,
|
||||
},
|
||||
[SCOPE_ENUM.LOCAL]: {
|
||||
name: SCOPE_ENUM.LOCAL,
|
||||
displayName: t('settings', 'Local'),
|
||||
tooltip: t('settings', 'Only visible to people on this instance and guests'),
|
||||
// tooltipDisabled is not required here as this scope is supported by all account properties
|
||||
iconClass: 'icon-password',
|
||||
icon: mdiLock,
|
||||
},
|
||||
[SCOPE_ENUM.FEDERATED]: {
|
||||
name: SCOPE_ENUM.FEDERATED,
|
||||
displayName: t('settings', 'Federated'),
|
||||
tooltip: t('settings', 'Only synchronize to trusted servers'),
|
||||
tooltipDisabled: t('settings', 'Not available as federation has been disabled for your account, contact your system administration if you have any questions'),
|
||||
iconClass: 'icon-contacts-dark',
|
||||
icon: mdiAccountGroup,
|
||||
},
|
||||
[SCOPE_ENUM.PUBLISHED]: {
|
||||
name: SCOPE_ENUM.PUBLISHED,
|
||||
displayName: t('settings', 'Published'),
|
||||
tooltip: t('settings', 'Synchronize to trusted servers and the global and public address book'),
|
||||
tooltipDisabled: t('settings', 'Not available as publishing account specific data to the lookup server is not allowed, contact your system administration if you have any questions'),
|
||||
iconClass: 'icon-link',
|
||||
icon: mdiWeb,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue