aboutsummaryrefslogtreecommitdiffstats
path: root/apps/theming/src/AdminTheming.vue
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2022-10-01 03:04:39 +0000
committerChristopher Ng <chrng8@gmail.com>2022-10-28 00:18:47 +0000
commit4a2bbc7af9249364ba2455f627522450262cad75 (patch)
treeb0fd373e0aad0f18c35d2272c565b20bdab630a9 /apps/theming/src/AdminTheming.vue
parentd007088cf5d89e29065991e0cbe2c890dfa13d96 (diff)
downloadnextcloud-server-4a2bbc7af9249364ba2455f627522450262cad75.tar.gz
nextcloud-server-4a2bbc7af9249364ba2455f627522450262cad75.zip
Rewrite admin theming in Vue
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'apps/theming/src/AdminTheming.vue')
-rw-r--r--apps/theming/src/AdminTheming.vue303
1 files changed, 303 insertions, 0 deletions
diff --git a/apps/theming/src/AdminTheming.vue b/apps/theming/src/AdminTheming.vue
new file mode 100644
index 00000000000..1d9f5b69512
--- /dev/null
+++ b/apps/theming/src/AdminTheming.vue
@@ -0,0 +1,303 @@
+<!--
+ - @copyright 2022 Christopher Ng <chrng8@gmail.com>
+ -
+ - @author Christopher Ng <chrng8@gmail.com>
+ -
+ - @license AGPL-3.0-or-later
+ -
+ - 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>
+ <section>
+ <NcSettingsSection :title="t('theming', 'Theming')"
+ :description="t('theming', 'Theming makes it possible to easily customize the look and feel of your instance and supported clients. This will be visible for all users.')"
+ :doc-url="docUrl">
+ <div class="admin-theming">
+ <NcNoteCard v-if="!isThemable"
+ type="error"
+ :show-alert="true">
+ <p>{{ notThemableErrorMessage }}</p>
+ </NcNoteCard>
+ <TextField v-for="field in textFields"
+ :key="field.name"
+ :name="field.name"
+ :value.sync="field.value"
+ :default-value="field.defaultValue"
+ :type="field.type"
+ :display-name="field.displayName"
+ :placeholder="field.placeholder"
+ :maxlength="field.maxlength"
+ @update:theming="$emit('update:theming')" />
+ <ColorPickerField :name="colorPickerField.name"
+ :value.sync="colorPickerField.value"
+ :default-value="colorPickerField.defaultValue"
+ :display-name="colorPickerField.displayName"
+ @update:theming="$emit('update:theming')" />
+ <FileInputField v-for="field in fileInputFields"
+ :key="field.name"
+ :name="field.name"
+ :mime-name="field.mimeName"
+ :mime-value.sync="field.mimeValue"
+ :default-mime-value="field.defaultMimeValue"
+ :display-name="field.displayName"
+ :aria-label="field.ariaLabel"
+ @update:theming="$emit('update:theming')" />
+ <div class="admin-theming__preview">
+ <div class="admin-theming__preview-logo" />
+ </div>
+ </div>
+ </NcSettingsSection>
+ <NcSettingsSection :title="t('theming', 'Advanced options')">
+ <div class="admin-theming-advanced">
+ <TextField v-for="field in advancedTextFields"
+ :key="field.name"
+ :name="field.name"
+ :value.sync="field.value"
+ :default-value="field.defaultValue"
+ :type="field.type"
+ :display-name="field.displayName"
+ :placeholder="field.placeholder"
+ :maxlength="field.maxlength"
+ @update:theming="$emit('update:theming')" />
+ <FileInputField v-for="field in advancedFileInputFields"
+ :key="field.name"
+ :name="field.name"
+ :mime-name="field.mimeName"
+ :mime-value.sync="field.mimeValue"
+ :default-mime-value="field.defaultMimeValue"
+ :display-name="field.displayName"
+ :aria-label="field.ariaLabel"
+ @update:theming="$emit('update:theming')" />
+ <CheckboxField :name="userThemingField.name"
+ :value="userThemingField.value"
+ :default-value="userThemingField.defaultValue"
+ :display-name="userThemingField.displayName"
+ :label="userThemingField.label"
+ :description="userThemingField.description"
+ @update:theming="$emit('update:theming')" />
+ <a v-if="!canThemeIcons"
+ :href="docUrlIcons"
+ rel="noreferrer noopener">
+ <em>{{ t('theming', 'Install the ImageMagick PHP extension with support for SVG images to automatically generate favicons based on the uploaded logo and color.') }}</em>
+ </a>
+ </div>
+ </NcSettingsSection>
+ </section>
+</template>
+
+<script>
+import { loadState } from '@nextcloud/initial-state'
+
+import {
+ NcNoteCard,
+ NcSettingsSection,
+} from '@nextcloud/vue'
+import CheckboxField from './components/admin/CheckboxField.vue'
+import ColorPickerField from './components/admin/ColorPickerField.vue'
+import FileInputField from './components/admin/FileInputField.vue'
+import TextField from './components/admin/TextField.vue'
+
+const {
+ backgroundMime,
+ canThemeIcons,
+ color,
+ docUrl,
+ docUrlIcons,
+ faviconMime,
+ isThemable,
+ legalNoticeUrl,
+ logoheaderMime,
+ logoMime,
+ name,
+ notThemableErrorMessage,
+ privacyPolicyUrl,
+ slogan,
+ url,
+ userThemingDisabled,
+} = loadState('theming', 'adminThemingParameters')
+
+const textFields = [
+ {
+ name: 'name',
+ value: name,
+ defaultValue: 'Nextcloud',
+ type: 'text',
+ displayName: t('theming', 'Name'),
+ placeholder: t('theming', 'Name'),
+ maxlength: 250,
+ },
+ {
+ name: 'url',
+ value: url,
+ defaultValue: 'https://nextcloud.com',
+ type: 'url',
+ displayName: t('theming', 'Web link'),
+ placeholder: 'https://…',
+ maxlength: 500,
+ },
+ {
+ name: 'slogan',
+ value: slogan,
+ defaultValue: t('theming', 'a safe home for all your data'),
+ type: 'text',
+ displayName: t('theming', 'Slogan'),
+ placeholder: t('theming', 'Slogan'),
+ maxlength: 500,
+ },
+]
+
+const colorPickerField = {
+ name: 'color',
+ value: color,
+ defaultValue: '#0082c9',
+ displayName: t('theming', 'Color'),
+}
+
+const fileInputFields = [
+ {
+ name: 'logo',
+ mimeName: 'logoMime',
+ mimeValue: logoMime,
+ defaultMimeValue: '',
+ displayName: t('theming', 'Logo'),
+ ariaLabel: t('theming', 'Upload new logo'),
+ },
+ {
+ name: 'background',
+ mimeName: 'backgroundMime',
+ mimeValue: backgroundMime,
+ defaultMimeValue: '',
+ displayName: t('theming', 'Background and login image'),
+ ariaLabel: t('theming', 'Upload new background and login image'),
+ },
+]
+
+const advancedTextFields = [
+ {
+ name: 'imprintUrl',
+ value: legalNoticeUrl,
+ defaultValue: '',
+ type: 'url',
+ displayName: t('theming', 'Legal notice link'),
+ placeholder: 'https://…',
+ maxlength: 500,
+ },
+ {
+ name: 'privacyUrl',
+ value: privacyPolicyUrl,
+ defaultValue: '',
+ type: 'url',
+ displayName: t('theming', 'Privacy policy link'),
+ placeholder: 'https://…',
+ maxlength: 500,
+ },
+]
+
+const advancedFileInputFields = [
+ {
+ name: 'logoheader',
+ mimeName: 'logoheaderMime',
+ mimeValue: logoheaderMime,
+ defaultMimeValue: '',
+ displayName: t('theming', 'Header logo'),
+ ariaLabel: t('theming', 'Upload new header logo'),
+ },
+ {
+ name: 'favicon',
+ mimeName: 'faviconMime',
+ mimeValue: faviconMime,
+ defaultMimeValue: '',
+ displayName: t('theming', 'Favicon'),
+ ariaLabel: t('theming', 'Upload new favicon'),
+ },
+]
+
+const userThemingField = {
+ name: 'disable-user-theming',
+ value: userThemingDisabled,
+ defaultValue: false,
+ displayName: t('theming', 'User settings'),
+ label: t('theming', 'Disable user theming'),
+ description: t('theming', 'Although you can select and customize your instance, users can change their background and colors. If you want to enforce your customization, you can toggle this on.'),
+}
+
+export default {
+ name: 'AdminTheming',
+
+ components: {
+ CheckboxField,
+ ColorPickerField,
+ FileInputField,
+ NcNoteCard,
+ NcSettingsSection,
+ TextField,
+ },
+
+ emits: [
+ 'update:theming',
+ ],
+
+ data() {
+ return {
+ textFields,
+ colorPickerField,
+ fileInputFields,
+ advancedTextFields,
+ advancedFileInputFields,
+ userThemingField,
+
+ canThemeIcons,
+ docUrl,
+ docUrlIcons,
+ isThemable,
+ notThemableErrorMessage,
+ }
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+.admin-theming,
+.admin-theming-advanced {
+ display: flex;
+ flex-direction: column;
+ gap: 8px 0;
+}
+
+.admin-theming {
+ &__preview {
+ width: 230px;
+ height: 140px;
+ background-size: cover;
+ background-position: center;
+ text-align: center;
+ margin-top: 10px;
+ background-color: var(--color-primary-default);
+ background-image: var(--image-background-default, var(--image-background-plain, url('../../../core/img/app-background.jpg'), linear-gradient(40deg, #0082c9 0%, #30b6ff 100%)));
+
+ &-logo {
+ width: 20%;
+ height: 20%;
+ margin-top: 20px;
+ display: inline-block;
+ background-size: contain;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-image: var(--image-logo, url('../../../core/img/logo/logo.svg'));
+ }
+ }
+}
+</style>