1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-31 10:07:22 +01:00

Add clear logs functionality (#1584)

* Add clear logs functionality

Other Changes:
- Add actions toolbar for actions pertaining to container logs
- Move Download button to actions toolbar, remove text and margin to match clear logs button
- Move search box below actions toolbar
- Turn off pointer events for scroll progress component so that Download button can be clicked
- Adjust spacing of container bar to accomodate the new actions toolbar

* Change actions toolbar into a floating menu

Other Changes:
- Move actions toolbar into its own component
- Move clear hotkey from LogEventSource to LogActionsToolbar, where the button is
- Move search back to where it was before
- Add tooltip component from buefy to annotate action buttons
- Add CSS variable for action toolbar background color, changes based on theme
This commit is contained in:
James Cote
2021-11-04 21:48:51 -04:00
committed by GitHub
parent d9e8cca867
commit 49b39fb3af
8 changed files with 130 additions and 37 deletions

View File

@@ -0,0 +1,92 @@
<template>
<div class="toolbar mr-0 is-vcentered is-hidden-mobile">
<div class="is-flex">
<b-tooltip type="is-dark" label="Clear">
<a @click="onClearClicked" class="button is-small is-light is-inverted" id="clear">
<span class="icon">
<icon name="bin"></icon>
</span>
</a>
</b-tooltip>
<div class="is-flex-grow-1"></div>
<b-tooltip type="is-dark" label="Download">
<a
class="button is-small is-light is-inverted"
id="download"
:href="`${base}/api/logs/download?id=${container.id}`"
download
>
<span class="icon">
<icon name="save"></icon>
</span>
</a>
</b-tooltip>
</div>
</div>
</template>
<script>
import config from "../store/config";
import hotkeys from "hotkeys-js";
import Icon from "./Icon";
export default {
props: {
onClearClicked: {
type: Function,
default: () => {},
},
container: {
type: Object,
},
},
name: "LogActionsToolbar",
components: {
Icon,
},
computed: {
base() {
return config.base;
},
},
mounted() {
hotkeys("shift+command+l, shift+ctrl+l", (event, handler) => {
this.onClearClicked();
event.preventDefault();
});
},
};
</script>
<style>
#download.button,
#clear.button {
.icon {
height: 80%;
}
&:hover {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
.toolbar {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 200px;
background-color: var(--action-toolbar-background-color);
border-radius: 8em;
margin-top: 0.5em;
& > div {
margin: 0 2em;
padding: 0.5em 0;
}
.button {
background-color: rgba(0, 0, 0, 0) !important;
}
}
</style>

View File

@@ -1,43 +1,32 @@
<template>
<scrollable-view :scrollable="scrollable" v-if="container">
<template v-slot:header v-if="showTitle">
<div class="mr-0 columns is-vcentered is-hidden-mobile">
<div class="column is-clipped">
<div class="mr-0 columns is-vcentered is-marginless is-hidden-mobile">
<div class="column is-clipped is-paddingless">
<container-title :container="container" @close="$emit('close')"></container-title>
</div>
<div class="column is-narrow">
<div class="column is-narrow is-paddingless">
<container-stat :stat="container.stat" :state="container.state"></container-stat>
</div>
<div class="column is-narrow">
<a
class="button is-small is-outlined"
id="download"
:href="`${base}/api/logs/download?id=${container.id}`"
download
>
<span class="icon">
<icon name="save"></icon>
</span>
Download
</a>
</div>
<div class="column is-narrow" v-if="closable">
<div class="column is-clipped is-paddingless"></div>
<div class="column is-narrow is-paddingless" v-if="closable">
<button class="delete is-medium" @click="$emit('close')"></button>
</div>
</div>
<log-actions-toolbar :container="container" :onClearClicked="onClearClicked"></log-actions-toolbar>
</template>
<template v-slot="{ setLoading }">
<log-viewer-with-source :id="id" @loading-more="setLoading($event)"></log-viewer-with-source>
<log-viewer-with-source ref="logViewer" :id="id" @loading-more="setLoading($event)"></log-viewer-with-source>
</template>
</scrollable-view>
</template>
<script>
import LogViewerWithSource from "./LogViewerWithSource";
import LogActionsToolbar from "./LogActionsToolbar";
import ScrollableView from "./ScrollableView";
import ContainerTitle from "./ContainerTitle";
import ContainerStat from "./ContainerStat";
import Icon from "./Icon";
import config from "../store/config";
import containerMixin from "./mixins/container";
@@ -63,14 +52,14 @@ export default {
name: "LogContainer",
components: {
LogViewerWithSource,
LogActionsToolbar,
ScrollableView,
ContainerTitle,
ContainerStat,
Icon,
},
computed: {
base() {
return config.base;
methods: {
onClearClicked() {
this.$refs.logViewer.clear();
},
},
};
@@ -88,16 +77,4 @@ button.delete {
opacity: 1;
}
}
#download.button {
.icon {
margin-right: 5px;
height: 80%;
}
&:hover {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
</style>

View File

@@ -70,6 +70,9 @@ export default {
this.messages.push(...this.buffer);
this.buffer = [];
},
clear() {
this.messages = [];
},
reset() {
if (this.es) {
this.es.close();

View File

@@ -1,5 +1,5 @@
<template>
<log-event-source :id="id" v-slot="eventSource" @loading-more="$emit('loading-more', $event)">
<log-event-source ref="logEventSource" :id="id" v-slot="eventSource" @loading-more="$emit('loading-more', $event)">
<log-viewer :messages="eventSource.messages"></log-viewer>
</log-event-source>
</template>
@@ -15,5 +15,10 @@ export default {
LogEventSource,
LogViewer,
},
methods: {
clear() {
this.$refs.logEventSource.clear();
},
},
};
</script>

View File

@@ -90,6 +90,7 @@ export default {
.scroll-progress {
display: inline-block;
position: relative;
pointer-events: none;
svg {
filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.2));

View File

@@ -83,6 +83,14 @@
d="M224 1536h608V384H192v1120q0 13 9.5 22.5t22.5 9.5zm1376-32V384H960v1152h608q13 0 22.5-9.5t9.5-22.5zm128-1216v1216q0 66-47 113t-113 47H224q-66 0-113-47t-47-113V288q0-66 47-113t113-47h1344q66 0 113 47t47 113z"
/>
</symbol>
<symbol id="icon-bin" viewBox="0 0 16 16">
<path
d="M2 5v10c0 0.55 0.45 1 1 1h9c0.55 0 1-0.45 1-1v-10h-11zM5 14h-1v-7h1v7zM7 14h-1v-7h1v7zM9 14h-1v-7h1v7zM11 14h-1v-7h1v7z"
></path>
<path
d="M13.25 2h-3.25v-1.25c0-0.412-0.338-0.75-0.75-0.75h-3.5c-0.412 0-0.75 0.338-0.75 0.75v1.25h-3.25c-0.413 0-0.75 0.337-0.75 0.75v1.25h13v-1.25c0-0.413-0.338-0.75-0.75-0.75zM9 2h-3v-0.987h3v0.987z"
></path>
</symbol>
</defs>
</svg>
<div id="app"></div>

View File

@@ -5,6 +5,7 @@ import Switch from "buefy/dist/esm/switch";
import Radio from "buefy/dist/esm/radio";
import Field from "buefy/dist/esm/field";
import Modal from "buefy/dist/esm/modal";
import Tooltip from "buefy/dist/esm/tooltip";
import Autocomplete from "buefy/dist/esm/autocomplete";
import store from "./store";
@@ -18,6 +19,7 @@ Vue.use(Switch);
Vue.use(Radio);
Vue.use(Field);
Vue.use(Modal);
Vue.use(Tooltip);
Vue.use(Autocomplete);
const routes = [

View File

@@ -1,7 +1,6 @@
@charset "utf-8";
@import "~bulma/sass/utilities/initial-variables.sass";
$body-background-color: var(--body-background-color);
$scheme-main: var(--scheme-main);
@@ -25,12 +24,16 @@ $panel-heading-color: var(--panel-heading-color);
$link: $turquoise;
$link-active: $grey-dark;
$dark-toolbar-color: rgba($black-bis, 0.7);
$light-toolbar-color: rgba($grey-darker, 0.7);
@import "~bulma";
@import "../node_modules/splitpanes/dist/splitpanes.css";
@import "~buefy/src/scss/utils/_all";
@import "~buefy/src/scss/components/_switch";
@import "~buefy/src/scss/components/_radio";
@import "~buefy/src/scss/components/_modal";
@import "~buefy/src/scss/components/_tooltip";
@import "~buefy/src/scss/components/_autocomplete";
html {
@@ -46,6 +49,7 @@ html {
--secondary-color: #{$yellow};
--body-background-color: #{$black-bis};
--action-toolbar-background-color: #{$dark-toolbar-color};
--menu-item-active-background-color: var(--primary-color);
--menu-item-color: hsl(0, 6%, 87%);
@@ -72,6 +76,7 @@ html {
--secondary-color: #d8f0ca;
--body-background-color: #{$white-bis};
--action-toolbar-background-color: #{$light-toolbar-color};
--body-color: #{$grey-darker};
--menu-item-color: #{$grey-dark};