mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-26 23:21:41 +01:00
Merge remote-tracking branch 'origin/master' into jump-to-context
This commit is contained in:
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
with:
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
|
||||
|
||||
2
.github/workflows/dev.yml
vendored
2
.github/workflows/dev.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2.7.0
|
||||
uses: docker/build-push-action@v2.8.0
|
||||
with:
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,6 +3,5 @@ dist
|
||||
node_modules
|
||||
.cache
|
||||
static
|
||||
a_main-packr.go
|
||||
dozzle
|
||||
gin-bin
|
||||
coverage
|
||||
|
||||
51
assets/components.d.ts
vendored
51
assets/components.d.ts
vendored
@@ -2,37 +2,28 @@
|
||||
// We suggest you to commit this file into source control
|
||||
// Read more: https://github.com/vuejs/vue-next/pull/3399
|
||||
|
||||
declare module 'vue' {
|
||||
declare module "vue" {
|
||||
export interface GlobalComponents {
|
||||
CarbonCaretDown: typeof import('~icons/carbon/caret-down')['default']
|
||||
CilColumns: typeof import('~icons/cil/columns')['default']
|
||||
CilFindInPage: typeof import('~icons/cil/find-in-page')['default']
|
||||
ContainerStat: typeof import('./components/ContainerStat.vue')['default']
|
||||
ContainerTitle: typeof import('./components/ContainerTitle.vue')['default']
|
||||
FuzzySearchModal: typeof import('./components/FuzzySearchModal.vue')['default']
|
||||
InfiniteLoader: typeof import('./components/InfiniteLoader.vue')['default']
|
||||
LogActionsToolbar: typeof import('./components/LogActionsToolbar.vue')['default']
|
||||
LogContainer: typeof import('./components/LogContainer.vue')['default']
|
||||
LogEventSource: typeof import('./components/LogEventSource.vue')['default']
|
||||
LogViewer: typeof import('./components/LogViewer.vue')['default']
|
||||
LogViewerWithSource: typeof import('./components/LogViewerWithSource.vue')['default']
|
||||
MdiDotsVertical: typeof import('~icons/mdi/dots-vertical')['default']
|
||||
MdiLightChevronDoubleDown: typeof import('~icons/mdi-light/chevron-double-down')['default']
|
||||
MdiLightChevronLeft: typeof import('~icons/mdi-light/chevron-left')['default']
|
||||
MdiLightChevronRight: typeof import('~icons/mdi-light/chevron-right')['default']
|
||||
MdiLightCog: typeof import('~icons/mdi-light/cog')['default']
|
||||
MdiLightMagnify: typeof import('~icons/mdi-light/magnify')['default']
|
||||
MobileMenu: typeof import('./components/MobileMenu.vue')['default']
|
||||
OcticonContainer24: typeof import('~icons/octicon/container24')['default']
|
||||
OcticonDownload24: typeof import('~icons/octicon/download24')['default']
|
||||
OcticonTrash24: typeof import('~icons/octicon/trash24')['default']
|
||||
PastTime: typeof import('./components/PastTime.vue')['default']
|
||||
RelativeTime: typeof import('./components/RelativeTime.vue')['default']
|
||||
ScrollableView: typeof import('./components/ScrollableView.vue')['default']
|
||||
ScrollProgress: typeof import('./components/ScrollProgress.vue')['default']
|
||||
Search: typeof import('./components/Search.vue')['default']
|
||||
SideMenu: typeof import('./components/SideMenu.vue')['default']
|
||||
CarbonCaretDown: typeof import("~icons/carbon/caret-down")["default"];
|
||||
CilColumns: typeof import("~icons/cil/columns")["default"];
|
||||
CilFindInPage: typeof import("~icons/cil/find-in-page")["default"];
|
||||
ContainerStat: typeof import("./components/ContainerStat.vue")["default"];
|
||||
ContainerTitle: typeof import("./components/ContainerTitle.vue")["default"];
|
||||
FuzzySearchModal: typeof import("./components/FuzzySearchModal.vue")["default"];
|
||||
InfiniteLoader: typeof import("./components/InfiniteLoader.vue")["default"];
|
||||
LogActionsToolbar: typeof import("./components/LogActionsToolbar.vue")["default"];
|
||||
LogContainer: typeof import("./components/LogContainer.vue")["default"];
|
||||
LogEventSource: typeof import("./components/LogEventSource.vue")["default"];
|
||||
LogViewer: typeof import("./components/LogViewer.vue")["default"];
|
||||
LogViewerWithSource: typeof import("./components/LogViewerWithSource.vue")["default"];
|
||||
MobileMenu: typeof import("./components/MobileMenu.vue")["default"];
|
||||
PastTime: typeof import("./components/PastTime.vue")["default"];
|
||||
RelativeTime: typeof import("./components/RelativeTime.vue")["default"];
|
||||
ScrollableView: typeof import("./components/ScrollableView.vue")["default"];
|
||||
ScrollProgress: typeof import("./components/ScrollProgress.vue")["default"];
|
||||
Search: typeof import("./components/Search.vue")["default"];
|
||||
SideMenu: typeof import("./components/SideMenu.vue")["default"];
|
||||
}
|
||||
}
|
||||
|
||||
export { }
|
||||
export {};
|
||||
|
||||
@@ -8,8 +8,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Container } from "@/types/Container";
|
||||
import { PropType } from "vue";
|
||||
defineProps({
|
||||
container: Object,
|
||||
container: {
|
||||
type: Object as PropType<Container>,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,38 +2,23 @@
|
||||
<time :datetime="date.toISOString()">{{ text }}</time>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { useIntervalFn } from "@vueuse/core";
|
||||
import formatDistance from "date-fns/formatDistance";
|
||||
import { PropType, ref } from "vue";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
date: {
|
||||
required: true,
|
||||
type: Date,
|
||||
},
|
||||
const props = defineProps({
|
||||
date: {
|
||||
required: true,
|
||||
type: Object as PropType<Date>,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
text: "" as string,
|
||||
interval: null,
|
||||
};
|
||||
},
|
||||
name: "PastTime",
|
||||
mounted() {
|
||||
this.updateFromNow();
|
||||
this.interval = setInterval(() => this.updateFromNow(), 30000);
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.interval);
|
||||
},
|
||||
methods: {
|
||||
updateFromNow() {
|
||||
this.text = formatDistance(this.date, new Date(), {
|
||||
addSuffix: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const text = ref<string>();
|
||||
function updateFromNow() {
|
||||
text.value = formatDistance(props.date, new Date(), {
|
||||
addSuffix: true,
|
||||
});
|
||||
}
|
||||
useIntervalFn(updateFromNow, 30_000, { immediateCallback: true });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -3,46 +3,42 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { formatRelative } from "date-fns";
|
||||
import { hourStyle } from "@/composables/settings";
|
||||
import enGB from "date-fns/locale/en-GB";
|
||||
import enUS from "date-fns/locale/en-US";
|
||||
|
||||
const use24Hr =
|
||||
new Intl.DateTimeFormat(undefined, {
|
||||
hour: "numeric",
|
||||
})
|
||||
.formatToParts(new Date(2020, 0, 1, 13))
|
||||
.find((part) => part.type === "hour").value.length === 2;
|
||||
.find((part) => part.type === "hour")?.value.length === 2;
|
||||
|
||||
const auto = use24Hr ? enGB : enUS;
|
||||
const styles = { auto, 12: enUS, 24: enGB };
|
||||
|
||||
export default {
|
||||
props: {
|
||||
date: {
|
||||
required: true,
|
||||
type: Date,
|
||||
},
|
||||
},
|
||||
name: "RelativeTime",
|
||||
components: {},
|
||||
computed: {
|
||||
locale() {
|
||||
const locale = styles[hourStyle.value];
|
||||
const oldFormatter = locale.formatRelative;
|
||||
return {
|
||||
...locale,
|
||||
formatRelative(token) {
|
||||
return oldFormatter(token) + "p";
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
relativeTime(date, locale) {
|
||||
return formatRelative(date, new Date(), { locale });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { formatRelative } from "date-fns";
|
||||
import { hourStyle } from "@/composables/settings";
|
||||
import enGB from "date-fns/locale/en-GB";
|
||||
import enUS from "date-fns/locale/en-US";
|
||||
import { computed, PropType } from "vue";
|
||||
defineProps({
|
||||
date: {
|
||||
required: true,
|
||||
type: Object as PropType<Date>,
|
||||
},
|
||||
});
|
||||
|
||||
const locale = computed(() => {
|
||||
const locale = styles[hourStyle.value];
|
||||
const oldFormatter = locale.formatRelative as (d: Date | number) => string;
|
||||
return {
|
||||
...locale,
|
||||
formatRelative(date: Date | number) {
|
||||
return oldFormatter(date) + "p";
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
function relativeTime(date: Date, locale: Locale) {
|
||||
return formatRelative(date, new Date(), { locale });
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="scroll-progress" ref="root">
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" :class="{ indeterminate }">
|
||||
<circle r="44" cx="50" cy="50" :style="{ '--progress': scrollProgress }" />
|
||||
<circle r="44" cx="50" cy="50" />
|
||||
</svg>
|
||||
<div class="is-overlay columns is-vcentered is-centered has-text-weight-light">
|
||||
<template v-if="indeterminate">
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useContainerStore } from "@/stores/container";
|
||||
import throttle from "lodash.throttle";
|
||||
import { useScroll } from "@vueuse/core";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { onMounted, onUnmounted, ref, watchPostEffect } from "vue";
|
||||
import { onMounted, ref, watch, watchPostEffect } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
indeterminate: {
|
||||
@@ -36,15 +36,28 @@ const props = defineProps({
|
||||
|
||||
const scrollProgress = ref(0);
|
||||
const animation = ref({ cancel: () => {} });
|
||||
const parentElement = ref<Node>(document);
|
||||
const root = ref<HTMLElement>();
|
||||
const store = useContainerStore();
|
||||
const { activeContainers } = storeToRefs(store);
|
||||
const onScrollThrottled = throttle(onScroll, 150);
|
||||
const scrollElement = ref<HTMLElement | Document>((root.value?.closest("[data-scrolling]") as HTMLElement) ?? document);
|
||||
const { y: scrollY } = useScroll(scrollElement, { throttle: 100 });
|
||||
|
||||
function onScroll() {
|
||||
const parent = parentElement.value == document ? document.documentElement : (parentElement.value as HTMLElement);
|
||||
scrollProgress.value = parent.scrollTop / (parent.scrollHeight - parent.clientHeight);
|
||||
onMounted(() => {
|
||||
watch(
|
||||
activeContainers,
|
||||
() => {
|
||||
scrollElement.value = (root.value?.closest("[data-scrolling]") as HTMLElement) ?? document;
|
||||
},
|
||||
{ immediate: true, flush: "post" }
|
||||
);
|
||||
});
|
||||
|
||||
watchPostEffect(() => {
|
||||
const parent =
|
||||
scrollElement.value === document
|
||||
? (scrollElement.value as Document).documentElement
|
||||
: (scrollElement.value as HTMLElement);
|
||||
scrollProgress.value = scrollY.value / (parent.scrollHeight - parent.clientHeight);
|
||||
animation.value.cancel();
|
||||
if (props.autoHide && root.value) {
|
||||
animation.value = root.value.animate(
|
||||
@@ -57,29 +70,6 @@ function onScroll() {
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function attachEvents() {
|
||||
parentElement.value = root.value?.closest("[data-scrolling]") || document;
|
||||
parentElement.value.addEventListener("scroll", onScrollThrottled);
|
||||
}
|
||||
|
||||
function detachEvents() {
|
||||
parentElement.value.removeEventListener("scroll", onScrollThrottled);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
attachEvents();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
detachEvents();
|
||||
});
|
||||
|
||||
watchPostEffect(() => {
|
||||
activeContainers.value.length;
|
||||
detachEvents();
|
||||
attachEvents();
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -105,7 +95,7 @@ watchPostEffect(() => {
|
||||
transform: rotate(-90deg);
|
||||
transform-origin: 50% 50%;
|
||||
stroke: var(--primary-color);
|
||||
stroke-dashoffset: calc(276.32px - var(--progress) * 276.32px);
|
||||
stroke-dashoffset: calc(276.32px - v-bind(scrollProgress) * 276.32px);
|
||||
stroke-dasharray: 276.32px 276.32px;
|
||||
stroke-linecap: round;
|
||||
stroke-width: 3;
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
<header v-if="$slots.header">
|
||||
<slot name="header"></slot>
|
||||
</header>
|
||||
<main ref="content" :data-scrolling="scrollable ? true : undefined">
|
||||
<main :data-scrolling="scrollable ? true : undefined">
|
||||
<div class="is-scrollbar-progress is-hidden-mobile">
|
||||
<scroll-progress v-show="paused" :indeterminate="loading" :auto-hide="!loading"></scroll-progress>
|
||||
</div>
|
||||
<slot :setLoading="setLoading"></slot>
|
||||
<div ref="scrollableContent">
|
||||
<slot :setLoading="setLoading"></slot>
|
||||
</div>
|
||||
|
||||
<div ref="scrollObserver" class="is-scroll-observer"></div>
|
||||
</main>
|
||||
|
||||
@@ -41,7 +44,7 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const { content } = this.$refs;
|
||||
const { scrollableContent } = this.$refs;
|
||||
this.mutationObserver = new MutationObserver((e) => {
|
||||
if (!this.paused) {
|
||||
this.scrollToBottom("instant");
|
||||
@@ -54,7 +57,7 @@ export default {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.mutationObserver.observe(content, { childList: true, subtree: true });
|
||||
this.mutationObserver.observe(scrollableContent, { childList: true, subtree: true });
|
||||
|
||||
this.intersectionObserver = new IntersectionObserver(
|
||||
(entries) => (this.paused = entries[0].intersectionRatio == 0),
|
||||
|
||||
30
package.json
30
package.json
@@ -22,32 +22,31 @@
|
||||
"postinstall": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify-json/carbon": "^1.0.13",
|
||||
"@iconify-json/carbon": "^1.0.14",
|
||||
"@iconify-json/cil": "^1.0.1",
|
||||
"@iconify-json/mdi": "^1.0.12",
|
||||
"@iconify-json/mdi-light": "^1.0.1",
|
||||
"@iconify-json/octicon": "^1.0.7",
|
||||
"@oruga-ui/oruga-next": "^0.5.2",
|
||||
"@oruga-ui/theme-bulma": "^0.1.5",
|
||||
"@vitejs/plugin-vue": "^2.0.1",
|
||||
"@vue/compiler-sfc": "^3.2.26",
|
||||
"@vueuse/core": "^7.5.3",
|
||||
"@oruga-ui/theme-bulma": "^0.2.1",
|
||||
"@vitejs/plugin-vue": "^2.1.0",
|
||||
"@vue/compiler-sfc": "^3.2.29",
|
||||
"@vueuse/core": "^7.5.4",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"bulma": "^0.9.3",
|
||||
"date-fns": "^2.28.0",
|
||||
"fuzzysort": "^1.1.4",
|
||||
"hotkeys-js": "^3.8.7",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"pinia": "^2.0.9",
|
||||
"sass": "^1.48.0",
|
||||
"sass": "^1.49.0",
|
||||
"semver": "^7.3.5",
|
||||
"splitpanes": "^3.0.6",
|
||||
"typescript": "^4.5.4",
|
||||
"unplugin-auto-import": "^0.5.10",
|
||||
"typescript": "^4.5.5",
|
||||
"unplugin-auto-import": "^0.5.11",
|
||||
"unplugin-icons": "^0.13.0",
|
||||
"unplugin-vue-components": "^0.17.11",
|
||||
"vite": "^2.7.12",
|
||||
"unplugin-vue-components": "^0.17.14",
|
||||
"vite": "^2.7.13",
|
||||
"vue": "^3.2.26",
|
||||
"vue-router": "^4.0.12"
|
||||
},
|
||||
@@ -55,19 +54,20 @@
|
||||
"@pinia/testing": "^0.0.9",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/lodash.throttle": "^4.1.6",
|
||||
"@types/node": "^17.0.10",
|
||||
"@types/semver": "^7.3.9",
|
||||
"@vue/test-utils": "^2.0.0-rc.18",
|
||||
"c8": "^7.11.0",
|
||||
"eventsourcemock": "^2.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"jsdom": "^19.0.0",
|
||||
"lint-staged": "^12.1.7",
|
||||
"lint-staged": "^12.3.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"release-it": "^14.12.1",
|
||||
"release-it": "^14.12.3",
|
||||
"ts-node": "^10.4.0",
|
||||
"vitest": "^0.1.13"
|
||||
"vitest": "^0.2.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,vue,css}": [
|
||||
|
||||
506
pnpm-lock.yaml
generated
506
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user