choose which stack operations show the full compose log
This commit is contained in:
6 files changed
+249
-20
No files matched your search
@@ -7,6 +7,11 @@ import {
|
||||
parseTimestamp,
|
||||
type DateTimeFormatters
|
||||
} from '$lib/utils/date-format';
|
||||
import {
|
||||
DEFAULT_STACK_LOG_OPERATIONS,
|
||||
sanitizeStackLogOperations,
|
||||
type StackLogOperation
|
||||
} from '$lib/utils/stack-log-operations';
|
||||
|
||||
export type TimeFormat = '12h' | '24h';
|
||||
export type DateFormat = 'MM/DD/YYYY' | 'DD/MM/YYYY' | 'YYYY-MM-DD' | 'DD.MM.YYYY';
|
||||
@@ -59,6 +64,7 @@ export interface AppSettings {
|
||||
// Scanner Advanced settings (#1219). Empty values = use auto-detection.
|
||||
defaultScannerNetworkMode: string; // '' | 'host' | 'bridge' | 'none' | <custom-network>
|
||||
defaultScannerDns: string[]; // ['1.1.1.1', '8.8.8.8']; empty = inherit
|
||||
stackLogOperations: StackLogOperation[]; // stack ops that show the log popover (#1558)
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: AppSettings = {
|
||||
@@ -102,6 +108,7 @@ const DEFAULT_SETTINGS: AppSettings = {
|
||||
protectScannerImages: true,
|
||||
defaultScannerNetworkMode: '',
|
||||
defaultScannerDns: [],
|
||||
stackLogOperations: DEFAULT_STACK_LOG_OPERATIONS,
|
||||
defaultComposeTemplate: `version: "3.8"
|
||||
|
||||
services:
|
||||
@@ -195,7 +202,8 @@ function createSettingsStore() {
|
||||
showWhatsNew: settings.showWhatsNew ?? DEFAULT_SETTINGS.showWhatsNew,
|
||||
protectScannerImages: settings.protectScannerImages ?? DEFAULT_SETTINGS.protectScannerImages,
|
||||
defaultScannerNetworkMode: settings.defaultScannerNetworkMode ?? DEFAULT_SETTINGS.defaultScannerNetworkMode,
|
||||
defaultScannerDns: Array.isArray(settings.defaultScannerDns) ? settings.defaultScannerDns : DEFAULT_SETTINGS.defaultScannerDns
|
||||
defaultScannerDns: Array.isArray(settings.defaultScannerDns) ? settings.defaultScannerDns : DEFAULT_SETTINGS.defaultScannerDns,
|
||||
stackLogOperations: sanitizeStackLogOperations(settings.stackLogOperations)
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
@@ -257,7 +265,8 @@ function createSettingsStore() {
|
||||
showWhatsNew: updatedSettings.showWhatsNew ?? DEFAULT_SETTINGS.showWhatsNew,
|
||||
protectScannerImages: updatedSettings.protectScannerImages ?? DEFAULT_SETTINGS.protectScannerImages,
|
||||
defaultScannerNetworkMode: updatedSettings.defaultScannerNetworkMode ?? DEFAULT_SETTINGS.defaultScannerNetworkMode,
|
||||
defaultScannerDns: Array.isArray(updatedSettings.defaultScannerDns) ? updatedSettings.defaultScannerDns : DEFAULT_SETTINGS.defaultScannerDns
|
||||
defaultScannerDns: Array.isArray(updatedSettings.defaultScannerDns) ? updatedSettings.defaultScannerDns : DEFAULT_SETTINGS.defaultScannerDns,
|
||||
stackLogOperations: sanitizeStackLogOperations(updatedSettings.stackLogOperations)
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -291,6 +300,13 @@ function createSettingsStore() {
|
||||
return newSettings;
|
||||
});
|
||||
},
|
||||
setStackLogOperations: (value: StackLogOperation[]) => {
|
||||
const clean = sanitizeStackLogOperations(value);
|
||||
update((current) => {
|
||||
saveSettings({ stackLogOperations: clean });
|
||||
return { ...current, stackLogOperations: clean };
|
||||
});
|
||||
},
|
||||
setShowStoppedContainers: (value: boolean) => {
|
||||
update((current) => {
|
||||
const newSettings = { ...current, showStoppedContainers: value };
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Which stack operations show the full compose-log popover (#1558).
|
||||
*
|
||||
* Some users find the log popover on every start/stop noisy and just want the
|
||||
* buttons + a toast. This setting lists the operations for which the popover IS
|
||||
* shown; operations not in the list run "quiet" (toast only), and their log is
|
||||
* opened automatically only if the operation FAILS, so errors are never hidden.
|
||||
*
|
||||
* Stored as a JSON array of operation keys in the settings KV. Pure + shared so
|
||||
* the default, the key set, and the "should show?" decision are one source of
|
||||
* truth for the server, the store, and the stacks page.
|
||||
*/
|
||||
// Only operations that actually stream a compose log are listed. Remove is deliberately
|
||||
// absent: it never opens the log popover (plain toast + error dialog), so a checkbox for it
|
||||
// would control nothing.
|
||||
export type StackLogOperation = 'start' | 'stop' | 'restart' | 'deploy' | 'down';
|
||||
|
||||
/** All operations, in display order, with a human label for the settings list. */
|
||||
export const STACK_LOG_OPERATIONS: { key: StackLogOperation; label: string }[] = [
|
||||
{ key: 'start', label: 'Start' },
|
||||
{ key: 'stop', label: 'Stop' },
|
||||
{ key: 'restart', label: 'Restart / recreate' },
|
||||
{ key: 'deploy', label: 'Deploy / redeploy' },
|
||||
{ key: 'down', label: 'Down' }
|
||||
];
|
||||
|
||||
const ALL_KEYS = STACK_LOG_OPERATIONS.map((o) => o.key);
|
||||
|
||||
/**
|
||||
* Default: show the log for everything EXCEPT the simple start/stop, matching the
|
||||
* 1.0.47 behavior for the heavier operations while giving start/stop the quiet
|
||||
* treatment the request asked for.
|
||||
*/
|
||||
export const DEFAULT_STACK_LOG_OPERATIONS: StackLogOperation[] = ['restart', 'deploy', 'down'];
|
||||
|
||||
/** Keep only valid, de-duplicated operation keys (defends the KV value + API body). */
|
||||
export function sanitizeStackLogOperations(value: unknown): StackLogOperation[] {
|
||||
if (!Array.isArray(value)) return [...DEFAULT_STACK_LOG_OPERATIONS];
|
||||
const seen = new Set<StackLogOperation>();
|
||||
for (const v of value) {
|
||||
if (typeof v === 'string' && (ALL_KEYS as string[]).includes(v)) seen.add(v as StackLogOperation);
|
||||
}
|
||||
return ALL_KEYS.filter((k) => seen.has(k)); // canonical order
|
||||
}
|
||||
|
||||
/** Whether the log popover should be shown for this operation. */
|
||||
export function shouldShowStackLog(ops: StackLogOperation[], op: StackLogOperation): boolean {
|
||||
return ops.includes(op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the stored KV value (a JSON array string) into the operation list. The
|
||||
* unset-vs-empty distinction is load-bearing: a null/absent value means the user never
|
||||
* touched the setting -> use the default; a stored "[]" means the user turned every op
|
||||
* off -> honor it as "log nothing" (NOT the default). Malformed JSON falls back to the
|
||||
* default rather than throwing.
|
||||
*/
|
||||
export function parseStackLogOperationsStorage(raw: string | null | undefined): StackLogOperation[] {
|
||||
if (raw == null) return [...DEFAULT_STACK_LOG_OPERATIONS];
|
||||
try {
|
||||
return sanitizeStackLogOperations(JSON.parse(raw));
|
||||
} catch {
|
||||
return [...DEFAULT_STACK_LOG_OPERATIONS];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user