mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-23 08:56:29 +00:00
Add option to turn on and off automatic log scrolling (#1149)
* Add option to turn on and off log automatic scrolling * Use vueuse storage helper
This commit is contained in:
parent
c79d49c862
commit
efdad4a9fc
8 changed files with 66 additions and 9 deletions
5
web/components.d.ts
vendored
5
web/components.d.ts
vendored
|
@ -37,7 +37,10 @@ declare module '@vue/runtime-core' {
|
||||||
IGgTrash: typeof import('~icons/gg/trash')['default']
|
IGgTrash: typeof import('~icons/gg/trash')['default']
|
||||||
IIcBaselineDarkMode: typeof import('~icons/ic/baseline-dark-mode')['default']
|
IIcBaselineDarkMode: typeof import('~icons/ic/baseline-dark-mode')['default']
|
||||||
IIcBaselineDownload: typeof import('~icons/ic/baseline-download')['default']
|
IIcBaselineDownload: typeof import('~icons/ic/baseline-download')['default']
|
||||||
|
IIcBaselineDownloadForOffline: typeof import('~icons/ic/baseline-download-for-offline')['default']
|
||||||
IIcBaselineEdit: typeof import('~icons/ic/baseline-edit')['default']
|
IIcBaselineEdit: typeof import('~icons/ic/baseline-edit')['default']
|
||||||
|
IIcBaselineFileDownload: typeof import('~icons/ic/baseline-file-download')['default']
|
||||||
|
IIcBaselineFileDownloadOff: typeof import('~icons/ic/baseline-file-download-off')['default']
|
||||||
IIcBaselineHealing: typeof import('~icons/ic/baseline-healing')['default']
|
IIcBaselineHealing: typeof import('~icons/ic/baseline-healing')['default']
|
||||||
IIconoirArrowLeft: typeof import('~icons/iconoir/arrow-left')['default']
|
IIconoirArrowLeft: typeof import('~icons/iconoir/arrow-left')['default']
|
||||||
IIconParkOutlineAlarmClock: typeof import('~icons/icon-park-outline/alarm-clock')['default']
|
IIconParkOutlineAlarmClock: typeof import('~icons/icon-park-outline/alarm-clock')['default']
|
||||||
|
@ -50,10 +53,10 @@ declare module '@vue/runtime-core' {
|
||||||
IMdiFormatListBulleted: typeof import('~icons/mdi/format-list-bulleted')['default']
|
IMdiFormatListBulleted: typeof import('~icons/mdi/format-list-bulleted')['default']
|
||||||
IMdiGithub: typeof import('~icons/mdi/github')['default']
|
IMdiGithub: typeof import('~icons/mdi/github')['default']
|
||||||
IMdiLoading: typeof import('~icons/mdi/loading')['default']
|
IMdiLoading: typeof import('~icons/mdi/loading')['default']
|
||||||
|
IMdiSync: typeof import('~icons/mdi/sync')['default']
|
||||||
IMdiSourceBranch: typeof import('~icons/mdi/source-branch')['default']
|
IMdiSourceBranch: typeof import('~icons/mdi/source-branch')['default']
|
||||||
IMdisourceCommit: typeof import('~icons/mdi/source-commit')['default']
|
IMdisourceCommit: typeof import('~icons/mdi/source-commit')['default']
|
||||||
IMdiSourcePull: typeof import('~icons/mdi/source-pull')['default']
|
IMdiSourcePull: typeof import('~icons/mdi/source-pull')['default']
|
||||||
IMdiSync: typeof import('~icons/mdi/sync')['default']
|
|
||||||
IMdiTagOutline: typeof import('~icons/mdi/tag-outline')['default']
|
IMdiTagOutline: typeof import('~icons/mdi/tag-outline')['default']
|
||||||
InputField: typeof import('./src/components/form/InputField.vue')['default']
|
InputField: typeof import('./src/components/form/InputField.vue')['default']
|
||||||
IOcticonSkip24: typeof import('~icons/octicon/skip24')['default']
|
IOcticonSkip24: typeof import('~icons/octicon/skip24')['default']
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"@intlify/vite-plugin-vue-i18n": "^6.0.0",
|
"@intlify/vite-plugin-vue-i18n": "^6.0.0",
|
||||||
"@kyvg/vue3-notification": "^2.3.6",
|
"@kyvg/vue3-notification": "^2.3.6",
|
||||||
"@meforma/vue-toaster": "^1.3.0",
|
"@meforma/vue-toaster": "^1.3.0",
|
||||||
|
"@vueuse/core": "^9.1.1",
|
||||||
"ansi_up": "^5.1.0",
|
"ansi_up": "^5.1.0",
|
||||||
"dayjs": "^1.11.4",
|
"dayjs": "^1.11.4",
|
||||||
"floating-vue": "^2.0.0-beta.19",
|
"floating-vue": "^2.0.0-beta.19",
|
||||||
|
|
|
@ -190,7 +190,9 @@
|
||||||
"canceled": "This step has been canceled.",
|
"canceled": "This step has been canceled.",
|
||||||
"cancel_success": "Pipeline canceled",
|
"cancel_success": "Pipeline canceled",
|
||||||
"restart_success": "Pipeline restarted",
|
"restart_success": "Pipeline restarted",
|
||||||
"log_download": "Download"
|
"log_download": "Download",
|
||||||
|
"log_auto_scroll": "Automatically scroll down",
|
||||||
|
"log_auto_scroll_off": "Turn off automatic scrolling"
|
||||||
},
|
},
|
||||||
"protected": {
|
"protected": {
|
||||||
"awaits": "This pipeline is awaiting approval by some maintainer!",
|
"awaits": "This pipeline is awaiting approval by some maintainer!",
|
||||||
|
|
|
@ -165,7 +165,9 @@
|
||||||
"canceled": "Šis solis tika atcelts.",
|
"canceled": "Šis solis tika atcelts.",
|
||||||
"cancel_success": "Konvejerdarbs atcelts",
|
"cancel_success": "Konvejerdarbs atcelts",
|
||||||
"restart_success": "Konvejerdarbs pārstartēts",
|
"restart_success": "Konvejerdarbs pārstartēts",
|
||||||
"log_download": "Lejupielādēt"
|
"log_download": "Lejupielādēt",
|
||||||
|
"log_auto_scroll": "Automātiski ritināt",
|
||||||
|
"log_auto_scroll_off": "Atslēgt automātisko ritināšanu"
|
||||||
},
|
},
|
||||||
"protected": {
|
"protected": {
|
||||||
"awaits": "Šim konvejerdarbam ir nepieciešams apstiprinājums no atbildīgajām personām!",
|
"awaits": "Šim konvejerdarbam ir nepieciešams apstiprinājums no atbildīgajām personām!",
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
<i-mdi-chevron-right v-else-if="name === 'chevron-right'" class="h-6 w-6" />
|
<i-mdi-chevron-right v-else-if="name === 'chevron-right'" class="h-6 w-6" />
|
||||||
<i-carbon-close-outline v-else-if="name === 'close'" class="h-6 w-6" />
|
<i-carbon-close-outline v-else-if="name === 'close'" class="h-6 w-6" />
|
||||||
<i-ic-baseline-edit v-else-if="name === 'edit'" class="h-6 w-6" />
|
<i-ic-baseline-edit v-else-if="name === 'edit'" class="h-6 w-6" />
|
||||||
<i-ic-baseline-download v-else-if="name === 'download'" class="h-6 w-6" />
|
<i-ic-baseline-download-for-offline v-else-if="name === 'download'" class="h-6 w-6" />
|
||||||
<i-icon-park-outline-alarm-clock v-else-if="name === 'stopwatch'" class="h-6 w-6" />
|
<i-icon-park-outline-alarm-clock v-else-if="name === 'stopwatch'" class="h-6 w-6" />
|
||||||
|
<i-ic-baseline-file-download v-else-if="name === 'auto-scroll'" class="h-6 w-6" />
|
||||||
|
<i-ic-baseline-file-download-off v-else-if="name === 'auto-scroll-off'" class="h-6 w-6" />
|
||||||
<div v-else-if="name === 'blank'" class="h-6 w-6" />
|
<div v-else-if="name === 'blank'" class="h-6 w-6" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -84,7 +86,9 @@ export type IconNames =
|
||||||
| 'close'
|
| 'close'
|
||||||
| 'edit'
|
| 'edit'
|
||||||
| 'stopwatch'
|
| 'stopwatch'
|
||||||
| 'download';
|
| 'download'
|
||||||
|
| 'auto-scroll'
|
||||||
|
| 'auto-scroll-off';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Icon',
|
name: 'Icon',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="isBuildFeedOpen"
|
v-if="isBuildFeedOpen"
|
||||||
class="flex flex-col overflow-y-auto items-center bg-white dark:bg-dark-gray-800 dark:border-dark-500"
|
class="flex flex-col z-50 overflow-y-auto items-center bg-white dark:bg-dark-gray-800 dark:border-dark-500"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
v-for="build in sortedBuildFeed"
|
v-for="build in sortedBuildFeed"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
@mouseover="showActions = true"
|
@mouseover="showActions = true"
|
||||||
@mouseleave="showActions = false"
|
@mouseleave="showActions = false"
|
||||||
>
|
>
|
||||||
<div v-show="showActions" class="absolute top-0 right-0 z-50 mt-2 mr-4 hidden md:flex">
|
<div v-show="showActions" class="absolute top-0 right-0 z-40 mt-2 mr-4 hidden md:flex">
|
||||||
<Button
|
<Button
|
||||||
v-if="proc?.end_time !== undefined"
|
v-if="proc?.end_time !== undefined"
|
||||||
:is-loading="downloadInProgress"
|
:is-loading="downloadInProgress"
|
||||||
|
@ -21,6 +21,12 @@
|
||||||
start-icon="download"
|
start-icon="download"
|
||||||
@click="download"
|
@click="download"
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
v-if="proc?.end_time === undefined"
|
||||||
|
:title="autoScroll ? $t('repo.build.actions.log_auto_scroll_off') : $t('repo.build.actions.log_auto_scroll')"
|
||||||
|
:start-icon="autoScroll ? 'auto-scroll' : 'auto-scroll-off'"
|
||||||
|
@click="autoScroll = !autoScroll"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -57,6 +63,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '~/style/console.css';
|
import '~/style/console.css';
|
||||||
|
|
||||||
|
import { useStorage } from '@vueuse/core';
|
||||||
import AnsiUp from 'ansi_up';
|
import AnsiUp from 'ansi_up';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { computed, defineComponent, inject, nextTick, onMounted, PropType, Ref, ref, toRef, watch } from 'vue';
|
import { computed, defineComponent, inject, nextTick, onMounted, PropType, Ref, ref, toRef, watch } from 'vue';
|
||||||
|
@ -120,7 +127,7 @@ export default defineComponent({
|
||||||
// we do not have logs for skipped jobs
|
// we do not have logs for skipped jobs
|
||||||
repo?.value && build.value && proc.value && proc.value.state !== 'skipped' && proc.value.state !== 'killed',
|
repo?.value && build.value && proc.value && proc.value.state !== 'skipped' && proc.value.state !== 'killed',
|
||||||
);
|
);
|
||||||
const autoScroll = ref(true); // TODO: allow enable / disable
|
const autoScroll = useStorage('log-auto-scroll', false);
|
||||||
const showActions = ref(false);
|
const showActions = ref(false);
|
||||||
const downloadInProgress = ref(false);
|
const downloadInProgress = ref(false);
|
||||||
const ansiUp = ref(new AnsiUp());
|
const ansiUp = ref(new AnsiUp());
|
||||||
|
@ -284,7 +291,18 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { consoleElement, proc, log, loadedLogs, hasLogs, formatTime, showActions, download, downloadInProgress };
|
return {
|
||||||
|
consoleElement,
|
||||||
|
proc,
|
||||||
|
log,
|
||||||
|
loadedLogs,
|
||||||
|
hasLogs,
|
||||||
|
formatTime,
|
||||||
|
showActions,
|
||||||
|
download,
|
||||||
|
downloadInProgress,
|
||||||
|
autoScroll,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -479,6 +479,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
|
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
|
||||||
integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
|
integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
|
||||||
|
|
||||||
|
"@types/web-bluetooth@^0.0.15":
|
||||||
|
version "0.0.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.15.tgz#d60330046a6ed8a13b4a53df3813c44942ebdf72"
|
||||||
|
integrity sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA==
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@^5.33.0":
|
"@typescript-eslint/eslint-plugin@^5.33.0":
|
||||||
version "5.33.0"
|
version "5.33.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz#059798888720ec52ffa96c5f868e31a8f70fa3ec"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz#059798888720ec52ffa96c5f868e31a8f70fa3ec"
|
||||||
|
@ -709,6 +714,28 @@
|
||||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702"
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702"
|
||||||
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
|
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
|
||||||
|
|
||||||
|
"@vueuse/core@^9.1.1":
|
||||||
|
version "9.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-9.1.1.tgz#a5c09c33ccee58cfd53bc3ec2d5a0d304155529e"
|
||||||
|
integrity sha512-QfuaNWRDMQcCUwXylCyYhPC3ScS9Tiiz4J0chdwr3vOemBwRToSywq8MP+ZegKYFnbETzRY8G/5zC+ca30wrRQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/web-bluetooth" "^0.0.15"
|
||||||
|
"@vueuse/metadata" "9.1.1"
|
||||||
|
"@vueuse/shared" "9.1.1"
|
||||||
|
vue-demi "*"
|
||||||
|
|
||||||
|
"@vueuse/metadata@9.1.1":
|
||||||
|
version "9.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-9.1.1.tgz#b3fe4b97e62096f7566cd8eb107c503998b2c9a6"
|
||||||
|
integrity sha512-XZ2KtSW+85LLHB/IdGILPAtbIVHasPsAW7aqz3BRMzJdAQWRiM/FGa1OKBwLbXtUw/AmjKYFlZJo7eOFIBXRog==
|
||||||
|
|
||||||
|
"@vueuse/shared@9.1.1":
|
||||||
|
version "9.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-9.1.1.tgz#811f47629e281a19013ae6dcdf11ed3e1e91e023"
|
||||||
|
integrity sha512-c+IfcOYmHiHqoEa3ED1Tbpue5GHmoUmTp8PtO4YbczthtY155Rt6DmWhjxMLXBF1Bcidagxljmp/7xtAzEHXLw==
|
||||||
|
dependencies:
|
||||||
|
vue-demi "*"
|
||||||
|
|
||||||
"@windicss/config@1.8.7":
|
"@windicss/config@1.8.7":
|
||||||
version "1.8.7"
|
version "1.8.7"
|
||||||
resolved "https://registry.yarnpkg.com/@windicss/config/-/config-1.8.7.tgz#650bec3c6e3293306e4fe0c478253bd0085884aa"
|
resolved "https://registry.yarnpkg.com/@windicss/config/-/config-1.8.7.tgz#650bec3c6e3293306e4fe0c478253bd0085884aa"
|
||||||
|
|
Loading…
Reference in a new issue