add toolbar and statusbar
This commit is contained in:
@@ -1,17 +1,42 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import AppMenubar from './components/AppMenubar.vue'
|
import AppMenubar from './components/AppMenubar.vue'
|
||||||
|
import AppToolbar from './components/AppToolbar.vue'
|
||||||
|
import AppStatusbar from './components/AppStatusbar.vue'
|
||||||
import RequirementsView from './views/RequirementsView.vue'
|
import RequirementsView from './views/RequirementsView.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<AppMenubar />
|
<AppMenubar />
|
||||||
<RequirementsView />
|
<AppToolbar />
|
||||||
|
<main class="app-main">
|
||||||
|
<RequirementsView />
|
||||||
|
</main>
|
||||||
|
<AppStatusbar />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#app {
|
* {
|
||||||
min-height: 100vh;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-main {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
85
kwa-ui/src/components/AppStatusbar.vue
Normal file
85
kwa-ui/src/components/AppStatusbar.vue
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
import { useRequirementsStore } from '../stores/requirements'
|
||||||
|
|
||||||
|
const requirementsStore = useRequirementsStore()
|
||||||
|
const { requirements, selectedRequirement, stats } = storeToRefs(requirementsStore)
|
||||||
|
|
||||||
|
const statusMessage = computed(() => {
|
||||||
|
if (!selectedRequirement.value) {
|
||||||
|
return 'No requirement selected'
|
||||||
|
}
|
||||||
|
return `${selectedRequirement.value.reference} - ${selectedRequirement.value.title}`
|
||||||
|
})
|
||||||
|
|
||||||
|
const detailsMessage = computed(() => {
|
||||||
|
return `Total: ${stats.value.total} | Approved: ${stats.value.approvedCount} | Blocked: ${stats.value.blockedCount}`
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<footer class="app-statusbar">
|
||||||
|
<div class="status-section">
|
||||||
|
<i :class="`pi ${selectedRequirement ? 'pi-check-circle text-success' : 'pi-info-circle text-info'}`" />
|
||||||
|
<span class="status-text">{{ statusMessage }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="status-divider" />
|
||||||
|
|
||||||
|
<div class="status-section">
|
||||||
|
<span class="status-details">{{ detailsMessage }}</span>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-statusbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 2rem;
|
||||||
|
padding: 0 1rem;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-top: 1px solid rgba(96, 117, 156, 0.16);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #6c7b97;
|
||||||
|
gap: 1rem;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-details {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-divider {
|
||||||
|
width: 1px;
|
||||||
|
height: 1rem;
|
||||||
|
background: rgba(96, 117, 156, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.pi) {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.pi.text-success) {
|
||||||
|
color: #22c55e;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.pi.text-info) {
|
||||||
|
color: #3b82f6;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
136
kwa-ui/src/components/AppToolbar.vue
Normal file
136
kwa-ui/src/components/AppToolbar.vue
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import Toolbar from 'primevue/toolbar'
|
||||||
|
import Button from 'primevue/button'
|
||||||
|
import Divider from 'primevue/divider'
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
new: []
|
||||||
|
open: []
|
||||||
|
save: []
|
||||||
|
undo: []
|
||||||
|
redo: []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const handleNew = () => emit('new')
|
||||||
|
const handleOpen = () => emit('open')
|
||||||
|
const handleSave = () => emit('save')
|
||||||
|
const handleUndo = () => emit('undo')
|
||||||
|
const handleRedo = () => emit('redo')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Toolbar class="app-toolbar">
|
||||||
|
<template #start>
|
||||||
|
<div class="toolbar-section">
|
||||||
|
<Button
|
||||||
|
icon="pi pi-file"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleNew"
|
||||||
|
v-tooltip="'New'"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon="pi pi-folder-open"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleOpen"
|
||||||
|
v-tooltip="'Open'"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon="pi pi-save"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleSave"
|
||||||
|
v-tooltip="'Save'"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Divider layout="vertical" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
icon="pi pi-undo"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleUndo"
|
||||||
|
v-tooltip="'Undo'"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon="pi pi-redo"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleRedo"
|
||||||
|
v-tooltip="'Redo'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #end>
|
||||||
|
<div class="toolbar-section">
|
||||||
|
<Button
|
||||||
|
icon="pi pi-bell"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="() => console.log('Notifications')"
|
||||||
|
v-tooltip="'Notifications'"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon="pi pi-user"
|
||||||
|
rounded
|
||||||
|
text
|
||||||
|
severity="secondary"
|
||||||
|
@click="() => console.log('Profile')"
|
||||||
|
v-tooltip="'Profile'"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Toolbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-toolbar {
|
||||||
|
border-bottom: 1px solid rgba(96, 117, 156, 0.16);
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.p-toolbar) {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.p-toolbar-group-start),
|
||||||
|
:deep(.p-toolbar-group-end) {
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.p-button.p-button-rounded) {
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.p-divider-vertical) {
|
||||||
|
height: 1.5rem;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
background: rgba(96, 117, 156, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.p-tooltip) {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -88,6 +88,7 @@ const treeData = computed(() => buildTreeData())
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.requirements-view {
|
.requirements-view {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
|
min-height: 100%;
|
||||||
background:
|
background:
|
||||||
radial-gradient(circle at top left, rgba(78, 107, 255, 0.18), transparent 34%),
|
radial-gradient(circle at top left, rgba(78, 107, 255, 0.18), transparent 34%),
|
||||||
radial-gradient(circle at top right, rgba(21, 184, 164, 0.14), transparent 28%),
|
radial-gradient(circle at top right, rgba(21, 184, 164, 0.14), transparent 28%),
|
||||||
@@ -165,3 +166,4 @@ const treeData = computed(() => buildTreeData())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user