refactor Appearance into two components - Applinks and Branding
This commit is contained in:
37
dashboard/src/components/Applinks.vue
Normal file
37
dashboard/src/components/Applinks.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<script setup>
|
||||
|
||||
import { inject, useTemplateRef } from 'vue';
|
||||
import { Button, FormGroup } from '@cloudron/pankow';
|
||||
import ApplinkDialog from './ApplinkDialog.vue';
|
||||
import Section from './Section.vue';
|
||||
import SettingsItem from './SettingsItem.vue';
|
||||
|
||||
const features = inject('features');
|
||||
|
||||
const applinkDialog = useTemplateRef('applinkDialog');
|
||||
|
||||
function onAddExternalLink() {
|
||||
applinkDialog.value.open();
|
||||
}
|
||||
|
||||
function onApplinkAdded() {
|
||||
window.location.href = '#/apps';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ApplinkDialog ref="applinkDialog" @success="onApplinkAdded"/>
|
||||
|
||||
<Section :title="$t('dashboard.title')">
|
||||
<SettingsItem>
|
||||
<FormGroup>
|
||||
<label>{{ $t('externallinks.label') }}</label>
|
||||
<div>{{ $t('externallinks.description') }}</div>
|
||||
</FormGroup>
|
||||
<div style="display: flex; position: relative; align-items: center">
|
||||
<Button tool plain @click="onAddExternalLink()" :disabled="!features.branding">{{ $t('main.action.add') }}</Button>
|
||||
</div>
|
||||
</SettingsItem>
|
||||
</Section>
|
||||
</template>
|
||||
97
dashboard/src/components/Branding.vue
Normal file
97
dashboard/src/components/Branding.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<script setup>
|
||||
|
||||
import { ref, onMounted, inject } from 'vue';
|
||||
import { API_ORIGIN } from '../constants.js';
|
||||
import Section from './Section.vue';
|
||||
import SettingsItem from './SettingsItem.vue';
|
||||
import EditableField from './EditableField.vue';
|
||||
import ImagePicker from './ImagePicker.vue';
|
||||
import BrandingModel from '../models/BrandingModel.js';
|
||||
import DashboardModel from '../models/DashboardModel.js';
|
||||
|
||||
const brandingModel = BrandingModel.create();
|
||||
const dashboardModel = DashboardModel.create();
|
||||
|
||||
const avatarUrl = ref(`${API_ORIGIN}/api/v1/cloudron/avatar?${String(Math.random()).slice(2)}`);
|
||||
const backgroundUrl = ref(`${API_ORIGIN}/api/v1/cloudron/background?${String(Math.random()).slice(2)}`);
|
||||
|
||||
const features = inject('features');
|
||||
|
||||
const name = ref('');
|
||||
const savingName = ref(false);
|
||||
|
||||
async function onNameSave(newName) {
|
||||
savingName.value = true;
|
||||
|
||||
const [error] = await brandingModel.setName(newName);
|
||||
savingName.value = false;
|
||||
if (error) return console.error(error);
|
||||
|
||||
name.value = newName;
|
||||
}
|
||||
|
||||
async function onAvatarSubmit(file) {
|
||||
const [error] = await brandingModel.setAvatar(file);
|
||||
if (error) return console.error(error);
|
||||
}
|
||||
|
||||
async function onBackgroundSubmit(file) {
|
||||
const [error] = await brandingModel.setBackground(file);
|
||||
if (error) return console.error(error);
|
||||
}
|
||||
|
||||
async function onBackgroundUnset() {
|
||||
const [error] = await brandingModel.unsetBackground();
|
||||
if (error) return console.error(error);
|
||||
backgroundUrl.value = '';
|
||||
}
|
||||
|
||||
// Footer
|
||||
const footer = ref('');
|
||||
const savingFooter = ref(false);
|
||||
|
||||
async function onFooterSave(newFooter) {
|
||||
savingFooter.value = true;
|
||||
|
||||
const [error] = await brandingModel.setFooter(newFooter);
|
||||
savingFooter.value = false;
|
||||
if (error) return console.error(error);
|
||||
|
||||
footer.value = newFooter;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
let [error, result] = await dashboardModel.config();
|
||||
if (error) return console.error(error);
|
||||
name.value = result.cloudronName;
|
||||
|
||||
[error, result] = await brandingModel.getFooter();
|
||||
if (error) return console.error(error);
|
||||
footer.value = result;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Section :title="$t('branding.title')" :title-badge="!features.branding ? 'Upgrade' : ''">
|
||||
<div style="display: flex; justify-content: space-around; margin-bottom: 20px;">
|
||||
<div style="display: flex; flex-direction: column; align-content: stretch; align-items: center;">
|
||||
<label>{{ $t('branding.logo') }}</label>
|
||||
<ImagePicker mode="editable" :src="avatarUrl" :save-handler="onAvatarSubmit" :size="512" display-height="128px" :disabled="!features.branding"/>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-direction: column; align-content: stretch; align-items: center;">
|
||||
<label>{{ $t('branding.backgroundImage') }}</label>
|
||||
<ImagePicker mode="editable" :src="backgroundUrl" :save-handler="onBackgroundSubmit" :unset-handler="onBackgroundUnset" :disabled="!features.branding" fallback-src="/img/background-image-placeholder.svg" display-height="128px" :max-size="1280"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SettingsItem>
|
||||
<EditableField :label="$t('branding.cloudronName')" :saving="savingName" :value="name" :disabled="!features.branding" @save="onNameSave"/>
|
||||
</SettingsItem>
|
||||
|
||||
<SettingsItem>
|
||||
<EditableField :label="$t('branding.footer.title')" helpUrl="https://docs.cloudron.io/branding/#footer" multiline markdown :saving="savingFooter" :value="footer" :disabled="!features.branding" @save="onFooterSave"/>
|
||||
</SettingsItem>
|
||||
</Section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user