123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- <!--
- - @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 :name="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"
- data-admin-theming-settings>
- <div class="admin-theming">
- <NcNoteCard v-if="!isThemable"
- type="error"
- :show-alert="true">
- <p>{{ notThemableErrorMessage }}</p>
- </NcNoteCard>
- <!-- Name, web link, slogan... fields -->
- <TextField v-for="field in textFields"
- :key="field.name"
- :data-admin-theming-setting-field="field.name"
- :default-value="field.defaultValue"
- :display-name="field.displayName"
- :maxlength="field.maxlength"
- :name="field.name"
- :placeholder="field.placeholder"
- :type="field.type"
- :value.sync="field.value"
- @update:theming="$emit('update:theming')" />
- <!-- Primary color picker -->
- <ColorPickerField :name="colorPickerField.name"
- :default-value="colorPickerField.defaultValue"
- :display-name="colorPickerField.displayName"
- :value.sync="colorPickerField.value"
- data-admin-theming-setting-primary-color
- @update:theming="$emit('update:theming')" />
- <!-- Default background picker -->
- <FileInputField v-for="field in fileInputFields"
- :key="field.name"
- :aria-label="field.ariaLabel"
- :data-admin-theming-setting-file="field.name"
- :default-mime-value="field.defaultMimeValue"
- :display-name="field.displayName"
- :mime-name="field.mimeName"
- :mime-value.sync="field.mimeValue"
- :name="field.name"
- @update:theming="$emit('update:theming')" />
- <div class="admin-theming__preview" data-admin-theming-preview>
- <div class="admin-theming__preview-logo" data-admin-theming-preview-logo />
- </div>
- </div>
- </NcSettingsSection>
- <NcSettingsSection :name="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"
- data-admin-theming-setting-disable-user-theming
- @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>
- <AppMenuSection :default-apps.sync="defaultApps" />
- </section>
- </template>
- <script>
- import { loadState } from '@nextcloud/initial-state'
- import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
- import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
- 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'
- import AppMenuSection from './components/admin/AppMenuSection.vue'
- const {
- backgroundMime,
- canThemeIcons,
- color,
- docUrl,
- docUrlIcons,
- faviconMime,
- isThemable,
- legalNoticeUrl,
- logoheaderMime,
- logoMime,
- name,
- notThemableErrorMessage,
- privacyPolicyUrl,
- slogan,
- url,
- userThemingDisabled,
- defaultApps,
- } = 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: {
- AppMenuSection,
- CheckboxField,
- ColorPickerField,
- FileInputField,
- NcNoteCard,
- NcSettingsSection,
- TextField,
- },
- emits: [
- 'update:theming',
- ],
- textFields,
- data() {
- return {
- textFields,
- colorPickerField,
- fileInputFields,
- advancedTextFields,
- advancedFileInputFields,
- userThemingField,
- defaultApps,
- 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;
- /* This is basically https://github.com/nextcloud/server/blob/master/core/css/guest.css
- But without the user variables. That way the admin can preview the render as guest*/
- /* As guest, there is no user color color-background-plain */
- background-color: var(--color-primary-element-default);
- /* As guest, there is no user background (--image-background)
- 1. Empty background if defined
- 2. Else default background
- 3. Finally default gradient (should not happened, the background is always defined anyway) */
- background-image: var(--image-background-plain, var(--image-background-default));
- &-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>
|