170 lines
6.5 KiB
Vue
170 lines
6.5 KiB
Vue
<script setup>
|
|
|
|
import { ref, onMounted, inject, useTemplateRef } from 'vue';
|
|
import { Button, FormGroup, TextInput } from '@cloudron/pankow';
|
|
import { API_ORIGIN } from '../constants.js';
|
|
import ApplinkDialog from '../components/ApplinkDialog.vue';
|
|
import Section from '../components/Section.vue';
|
|
import SettingsItem from '../components/SettingsItem.vue';
|
|
import ImagePicker from '../components/ImagePicker.vue';
|
|
import BrandingModel from '../models/BrandingModel.js';
|
|
import DashboardModel from '../models/DashboardModel.js';
|
|
|
|
const brandingModel = BrandingModel.create();
|
|
const dashboardModel = DashboardModel.create();
|
|
|
|
const name = ref('');
|
|
const footer = ref('');
|
|
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');
|
|
|
|
// Cloudron name
|
|
const editingName = ref(false);
|
|
const editName = ref('');
|
|
const editNameBusy = ref(false);
|
|
|
|
function onChangeName(currentName) {
|
|
editNameBusy.value = false;
|
|
editingName.value = true;
|
|
editName.value = currentName;
|
|
}
|
|
|
|
async function onChangeNameSubmit() {
|
|
editNameBusy.value = true;
|
|
|
|
const [error] = await brandingModel.setName(editName.value);
|
|
if (error) return console.error(error);
|
|
|
|
name.value = editName.value;
|
|
editingName.value = false;
|
|
editNameBusy.value = false;
|
|
editName.value = '';
|
|
}
|
|
|
|
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 editingFooter = ref(false);
|
|
const editFooter = ref('');
|
|
const editFooterBusy = ref(false);
|
|
|
|
function onChangeFooter(currentFooter) {
|
|
editFooterBusy.value = false;
|
|
editingFooter.value = true;
|
|
editFooter.value = currentFooter;
|
|
}
|
|
|
|
async function onChangeFooterSubmit() {
|
|
editFooterBusy.value = true;
|
|
|
|
const [error] = await brandingModel.setFooter(editFooter.value);
|
|
if (error) return console.error(error);
|
|
|
|
footer.value = editFooter.value;
|
|
editingFooter.value = false;
|
|
editFooterBusy.value = false;
|
|
editFooter.value = '';
|
|
}
|
|
|
|
const applinkDialog = useTemplateRef('applinkDialog');
|
|
|
|
function onAddDashboardLink() {
|
|
applinkDialog.value.open();
|
|
}
|
|
|
|
function onApplinkAdded() {
|
|
window.location.href = '#/apps';
|
|
}
|
|
|
|
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>
|
|
<div class="content">
|
|
<ApplinkDialog ref="applinkDialog" @success="onApplinkAdded"/>
|
|
|
|
<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 :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 :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>
|
|
<FormGroup>
|
|
<label>{{ $t('branding.cloudronName') }}</label>
|
|
<div>{{ name }}</div>
|
|
</FormGroup>
|
|
<Transition name="slide-up" mode="out-in">
|
|
<div v-if="editingName" style="display: flex; position: relative; align-items: center; gap: 6px">
|
|
<TextInput v-model="editName" @keydown.enter="onChangeNameSubmit()" :disabled="editNameBusy"/>
|
|
<Button tool @click="onChangeNameSubmit()" :disabled="editNameBusy" :loading="editNameBusy">{{ $t('main.dialog.save') }}</Button>
|
|
<Button tool plain secondary @click="editingName = false" :disabled="editNameBusy">{{ $t('main.dialog.cancel') }}</Button>
|
|
</div>
|
|
<div v-else style="display: flex; position: relative; align-items: center">
|
|
<Button tool plain @click="onChangeName(name)" :disabled="!features.branding">{{ $t('main.dialog.edit') }}</Button>
|
|
</div>
|
|
</Transition>
|
|
</SettingsItem>
|
|
|
|
<SettingsItem>
|
|
<FormGroup>
|
|
<label>{{ $t('branding.footer.title') }}</label>
|
|
<div>{{ $t('branding.footer.description') }} <sup><a href="https://docs.cloudron.io/branding/#footer" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></div>
|
|
</FormGroup>
|
|
<Transition name="slide-up" mode="out-in">
|
|
<div v-if="editingFooter" style="display: flex; position: relative; align-items: center; gap: 6px; flex-grow: 1; justify-content: right;">
|
|
<textarea v-model="editFooter" @keydown.enter="onChangeFooterSubmit()" :disabled="editFooterBusy" style="flex-grow: 1; height: 120px;"></textarea>
|
|
<Button tool @click="onChangeFooterSubmit()" :disabled="editFooterBusy" :loading="editFooterBusy">{{ $t('main.dialog.save') }}</Button>
|
|
<Button tool plain secondary @click="editingFooter = false" :disabled="editFooterBusy">{{ $t('main.dialog.cancel') }}</Button>
|
|
</div>
|
|
<div v-else style="display: flex; position: relative; align-items: center">
|
|
<Button tool plain @click="onChangeFooter(footer)" :disabled="!features.branding">{{ $t('main.dialog.edit') }}</Button>
|
|
</div>
|
|
</Transition>
|
|
</SettingsItem>
|
|
|
|
<SettingsItem>
|
|
<FormGroup>
|
|
<label>Dashboard Links</label>
|
|
<div>Links to other domains and services can be added to the dashboard</div>
|
|
</FormGroup>
|
|
<div style="display: flex; position: relative; align-items: center">
|
|
<Button tool plain @click="onAddDashboardLink()" :disabled="!features.branding">Add Link</Button>
|
|
</div>
|
|
</SettingsItem>
|
|
</Section>
|
|
</div>
|
|
</template>
|