diff --git a/dashboard/src/models/BrandingModel.js b/dashboard/src/models/BrandingModel.js index c29700daf..396812028 100644 --- a/dashboard/src/models/BrandingModel.js +++ b/dashboard/src/models/BrandingModel.js @@ -11,7 +11,6 @@ const KEYS = { }; function notifyChange(key, value) { - console.log('notifying for ', key, value, changeHandlers) const listener = changeHandlers[key] || []; listener.forEach(h => h(value)); } diff --git a/dashboard/src/style.css b/dashboard/src/style.css index 3885aac66..acde0357e 100644 --- a/dashboard/src/style.css +++ b/dashboard/src/style.css @@ -251,3 +251,16 @@ fieldset > * { transform: translateX(20px); opacity: 0; } + +.slide-up-enter-active, +.slide-up-leave-active { + transition: all 0.15s ease-in-out; +} +.slide-up-enter-from { + opacity: 0; + transform: translateY(30px); +} +.slide-up-leave-to { + opacity: 0; + transform: translateY(-30px); +} diff --git a/dashboard/src/views/BrandingView.vue b/dashboard/src/views/BrandingView.vue index 84980a900..fa64a7f39 100644 --- a/dashboard/src/views/BrandingView.vue +++ b/dashboard/src/views/BrandingView.vue @@ -4,6 +4,7 @@ import { ref, onMounted } from 'vue'; import { Button, FormGroup, TextInput } from 'pankow'; import { API_ORIGIN } from '../constants.js'; 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'; @@ -11,49 +12,95 @@ import DashboardModel from '../models/DashboardModel.js'; const brandingModel = BrandingModel.create(); const dashboardModel = DashboardModel.create(); -let newBackground = null; -let newAvatar = null; - -const busy = ref(false); 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 backgroundError = ref(''); -async function onSubmit() { - busy.value = true; - backgroundError.value = ''; - let [error] = await brandingModel.setName(name.value); - if (error) return console.error(error); +// Cloudron name +const editingName = ref(false); +const editName = ref(''); +const editNameBusy = ref(false); - [error] = await brandingModel.setFooter(footer.value); - if (error) return console.error(error); - - if (newBackground) { - const [error] = await brandingModel.setBackground(newBackground); - if (error) { - backgroundError.value = error.body ? error.body.message : 'Internal error'; - busy.value = false; - return; - } - } - - if (newAvatar) { - const [error] = await brandingModel.setAvatar(newAvatar); - if (error) return console.error(error); - } - - busy.value = 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 = ''; +} + + +// Avatar +const avatarBusy = ref(false); +const avatarNew = ref(null); + function onAvatarChanged(file) { - newAvatar = file; + avatarNew.value = file; } +async function onAvatarSubmit() { + if (!avatarNew.value) return; + + avatarBusy.value = true; + const [error] = await brandingModel.setAvatar(avatarNew.value); + if (error) return console.error(error); + avatarNew.value = null; + avatarBusy.value = false; +} + + +// Background +const backgroundBusy = ref(false); +const backgroundNew = ref(null); + function onBackgroundChanged(file) { - newBackground = file; + backgroundNew.value = file; +} + +async function onBackgroundSubmit() { + if (!backgroundNew.value) return; + + backgroundBusy.value = true; + const [error] = await brandingModel.setBackground(backgroundNew.value); + if (error) return console.error(error); + backgroundNew.value = null; + backgroundBusy.value = false; +} + + +// 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 = ''; } onMounted(async () => { @@ -71,35 +118,61 @@ onMounted(async () => {