Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions web/src/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,13 @@
"light": "Light",
"dark": "Dark",
"auto": "Auto"
},
"pipeline_logs": {
"pipeline_logs": "Pipeline logs",
"collapse_groups": {
"collapse": "Collapse log groups by default",
"desc": "When opening a finished step, collapse all command groups to show only the outline."
}
}
},
"secrets": {
Expand Down
9 changes: 6 additions & 3 deletions web/src/components/repo/pipeline/PipelineLog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ import useApiClient from '~/compositions/useApiClient';
import useConfig from '~/compositions/useConfig';
import { requiredInject } from '~/compositions/useInjectProvide';
import useNotifications from '~/compositions/useNotifications';
import useUserConfig from '~/compositions/useUserConfig';
import type { Pipeline, PipelineConfig, PipelineStep, PipelineWorkflow } from '~/lib/api/types';
import { debounce } from '~/lib/utils';

Expand Down Expand Up @@ -209,6 +210,7 @@ defineEmits<{

const notifications = useNotifications();
const i18n = useI18n();
const { userConfig } = useUserConfig();
const pipeline = toRef(props, 'pipeline');
const stepId = toRef(props, 'stepId');
const repo = requiredInject('repo');
Expand Down Expand Up @@ -572,11 +574,12 @@ const expandLogGroupWithPageHash = (hash: string) => {
}
};

// When user click on a step, if the step has already finished running, show user the
// only the outline by collapse all log groups
// When a user opens a step that has already finished running, collapse all log
// groups by default so they see only the command outline. This is opt-out via
// the "collapse log groups by default" user preference.
watch(loadedLogs, async (isLoaded, wasLoaded) => {
// Only trigger when transitioning from unloaded to loaded state
if (isLoaded && !wasLoaded) {
if (isLoaded && !wasLoaded && userConfig.value.collapseLogGroupsByDefault) {
const isFinished = step.value && !['running', 'pending', 'started'].includes(step.value.state);
if (isFinished) {
// Wait for groupedLogs computed property to update
Expand Down
15 changes: 11 additions & 4 deletions web/src/compositions/useUserConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ import { computed } from 'vue';
interface UserConfig {
isPipelineFeedOpen: boolean;
redirectUrl: string;
collapseLogGroupsByDefault: boolean;
}

const config = useStorage<UserConfig>('woodpecker:user-config', {
isPipelineFeedOpen: false,
redirectUrl: '',
});
const config = useStorage<UserConfig>(
'woodpecker:user-config',
{
isPipelineFeedOpen: false,
redirectUrl: '',
collapseLogGroupsByDefault: true,
},
undefined,
{ mergeDefaults: true },
);

export default () => ({
setUserConfig<T extends keyof UserConfig>(key: T, value: UserConfig[T]): void {
Expand Down
20 changes: 20 additions & 0 deletions web/src/views/user/UserGeneral.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
]"
/>
</InputField>

<InputField :label="$t('user.settings.general.pipeline_logs.pipeline_logs')">
<Checkbox
v-model="collapseLogGroupsByDefault"
:label="$t('user.settings.general.pipeline_logs.collapse_groups.collapse')"
:description="$t('user.settings.general.pipeline_logs.collapse_groups.desc')"
/>
</InputField>
</Settings>
</template>

Expand All @@ -38,15 +46,27 @@ import { SUPPORTED_LOCALES } from 'virtual:vue-i18n-supported-locales';
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';

import Checkbox from '~/components/form/Checkbox.vue';
import InputField from '~/components/form/InputField.vue';
import SelectField from '~/components/form/SelectField.vue';
import Settings from '~/components/layout/Settings.vue';
import { setI18nLanguage } from '~/compositions/useI18n';
import { useTheme } from '~/compositions/useTheme';
import useUserConfig from '~/compositions/useUserConfig';
import { useWPTitle } from '~/compositions/useWPTitle';

const { locale, t } = useI18n();
const { storeTheme } = useTheme();
const { userConfig, setUserConfig } = useUserConfig();

const collapseLogGroupsByDefault = computed<boolean>({
get() {
return userConfig.value.collapseLogGroupsByDefault;
},
set(value) {
setUserConfig('collapseLogGroupsByDefault', value);
},
});

const localeOptions = computed(() =>
SUPPORTED_LOCALES.map((supportedLocale) => ({
Expand Down