Connection status/error messages

This commit is contained in:
Leo Vasanko
2023-11-07 18:01:34 +00:00
parent 54d6ea6332
commit d5e1304c0d
10 changed files with 124 additions and 75 deletions

View File

@@ -129,8 +129,8 @@
</td>
</tr>
</template>
<tr class="summary">
<td colspan="3" class="right">{{props.documents.length}} items shown:</td>
<tr class="summary" v-if="props.documents.length > 1">
<td colspan="3" class="right">{{props.documents.length}} items</td>
<td class="size right">{{ formatSize(props.documents.reduce((a, b) => a + b.size, 0)) }}</td>
<td class="menu"></td>
</tr>
@@ -140,7 +140,7 @@
</template>
<script setup lang="ts">
import { ref, computed, watchEffect, onBeforeUpdate } from 'vue'
import { ref, computed, watchEffect } from 'vue'
import { useDocumentStore } from '@/stores/documents'
import type { Document } from '@/repositories/Document'
import FileRenameInput from './FileRenameInput.vue'
@@ -510,4 +510,7 @@ tbody .selection input {
.loc {
color: #888;
}
.summary {
color: #888;
}
</style>

View File

@@ -1,6 +1,10 @@
<template>
<nav class="headermain">
<div class="buttons">
<template v-if="documentStore.error">
<div class="error-message" @click="documentStore.error = ''">{{ documentStore.error }}</div>
<div class="smallgap"></div>
</template>
<UploadButton />
<SvgButton
name="create-folder"
@@ -23,17 +27,6 @@
<SvgButton name="cog" @click="settingsMenu" />
</div>
</nav>
<context-menu v-model:show="showMenu">
<context-menu-item label="Simple item" @click="onMenuClick(1)" />
<context-menu-sperator /><!--use this to add sperator-->
<context-menu-group label="Menu with child">
<context-menu-item label="Item1" @click="onMenuClick(2)" />
<context-menu-item label="Item2" @click="onMenuClick(3)" />
<context-menu-group label="Child with v-for 50">
<context-menu-item v-for="index of 50" :key="index" :label="'Item3-'+index" @click="onLoopMenuClick(index)" />
</context-menu-group>
</context-menu-group>
</context-menu>
</template>
<script setup lang="ts">
@@ -64,12 +57,16 @@ const toggleSearchInput = () => {
const settingsMenu = (e: Event) => {
// show the context menu
const items = []
if (documentStore.user.isLoggedIn) {
items.push({ label: `Logout ${documentStore.user.username ?? ''}`, onClick: () => documentStore.logout() })
} else {
items.push({ label: 'Login', onClick: () => documentStore.loginDialog() })
}
ContextMenu.showContextMenu({
// @ts-ignore
x: e.target.getBoundingClientRect().right, y: e.target.getBoundingClientRect().bottom,
items: [
{ label: "Logout", onClick: () => { documentStore.logout() } },
]
items,
})
}

View File

@@ -1,5 +1,5 @@
<template>
<ModalDialog v-if="store.user.isOpenLoginModal" title="Authentication required">
<ModalDialog v-if="store.user.isOpenLoginModal" title="Authentication required" @blur="store.user.isOpenLoginModal = false">
<form @submit.prevent="login">
<div class="login-container">
<label for="username">Username:</label>
@@ -7,6 +7,8 @@
id="username"
name="username"
autocomplete="username"
spellcheck="false"
autocorrect="off"
required
v-model="loginForm.username"
/>
@@ -16,12 +18,14 @@
name="password"
type="password"
autocomplete="current-password"
spellcheck="false"
autocorrect="off"
required
v-model="loginForm.password"
/>
</div>
<h3 v-if="loginForm.error.length > 0" class="error-text">
{{ loginForm.error }}
<h3 class="error-text">
{{ loginForm.error || '\u00A0' }}
</h3>
<div class="dialog-buttons">
<div class="spacer"></div>
@@ -33,21 +37,13 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { loginUser, logoutUser } from '@/repositories/User'
import { loginUser } from '@/repositories/User'
import type { ISimpleError } from '@/repositories/Client'
import { useDocumentStore } from '@/stores/documents'
const confirmLoading = ref<boolean>(false)
const store = useDocumentStore()
const logout = async () => {
try {
await logoutUser()
} finally {
location.reload()
}
}
const loginForm = reactive({
username: '',
password: '',
@@ -59,13 +55,10 @@ const login = async () => {
loginForm.error = ''
confirmLoading.value = true
const msg = await loginUser(loginForm.username, loginForm.password)
console.log('Logged in', msg)
store.login(msg.username, !!msg.privileged)
store.login(msg.data.username, !!msg.data.privileged)
} catch (error) {
const httpError = error as ISimpleError
if (httpError.name) {
loginForm.error = httpError.message
}
loginForm.error = httpError.message || '🛑 Unknown error'
} finally {
confirmLoading.value = false
}
@@ -87,18 +80,22 @@ const login = async () => {
align-items: center;
}
.button-login {
color: #fff;
background: var(--soft-color);
cursor: pointer;
font-weight: bold;
border: 0;
border-radius: .5rem;
padding: .5rem;
padding: .5rem 2rem;
margin-left: auto;
background-color: var(--accent-color);
color: var(--primary-color);
transition: all var(--transition-time) linear;
}
.ant-btn-primary:not(:disabled):hover {
background-color: var(--blue-color);
.button-login:hover, .button-login:focus {
background: var(--accent-color);
box-shadow: 0 0 .3rem #000;
}
.error-text {
color: var(--red-color);
height: 1em;
}
</style>

View File

@@ -23,15 +23,18 @@ const props = withDefaults(
title: ''
}
)
onMounted(() => {
const show = () => {
dialog.value!.showModal()
}
defineExpose({ show })
onMounted(() => {
show()
})
</script>
<style>
/* Style for the background */
body:has(dialog[open])::before {
dialog::backdrop {
content: '';
display: block;
position: fixed;
@@ -40,7 +43,7 @@ body:has(dialog[open])::before {
width: 100%;
height: 100%;
background: #0008;
backdrop-filter: blur(0.2em);
backdrop-filter: blur(0.4em);
z-index: 1000;
}
@@ -50,6 +53,7 @@ dialog[open] {
color: black;
display: block;
border: none;
font-size: 1.2rem;
border-radius: 0.5rem;
box-shadow: 0.2rem 0.2rem 1rem #000;
padding: 1rem;
@@ -58,11 +62,13 @@ dialog[open] {
left: 0;
z-index: 1001;
}
input {
font: inherit;
}
dialog[open] > h1 {
background: var(--accent-color);
color: black;
font-size: 1rem;
background: var(--soft-color);
color: #fff;
font-size: 1.2rem;
margin: -1rem -1rem 0 -1rem;
padding: 0.5rem 1rem 0.5rem 1rem;
}