diff --git a/package.json b/package.json index 2489d825..b80b273b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,10 @@ "skillsInstallation": false, "workspaceScheduling": false, "remoteSsh": false, - "linearIntegration": false + "linearIntegration": false, + "logs": false, + "checks": false, + "browser": false }, "env": { "dev": { diff --git a/src-tauri/src/commands/checks.rs b/src-tauri/src/commands/checks.rs index f666cee9..83921276 100644 --- a/src-tauri/src/commands/checks.rs +++ b/src-tauri/src/commands/checks.rs @@ -1,5 +1,7 @@ use crate::core::checks_logs::{LogBucket, LogQuery, LogRecordView, SqlResult}; use crate::core::{JobResult, RunSummary, SetupScriptStatus, WorkflowInfo}; +use crate::AppState; +use tauri::State; #[tauri::command] pub async fn list_workflows(repo_path: String) -> Result, String> { @@ -10,12 +12,17 @@ pub async fn list_workflows(repo_path: String) -> Result, Stri #[tauri::command] pub async fn run_workflow_job( + state: State<'_, AppState>, repo_path: String, filename: String, job_id: String, workspace_id: i64, workspace_path: String, ) -> Result { + crate::commands::feature_preview::require( + &state, + crate::core::feature_preview::PreviewFeature::Checks, + )?; tauri::async_runtime::spawn_blocking(move || { crate::core::run_workflow_job_sync( &repo_path, @@ -31,11 +38,16 @@ pub async fn run_workflow_job( #[tauri::command] pub async fn run_workflow( + state: State<'_, AppState>, repo_path: String, filename: String, workspace_id: i64, workspace_path: String, ) -> Result, String> { + crate::commands::feature_preview::require( + &state, + crate::core::feature_preview::PreviewFeature::Checks, + )?; tauri::async_runtime::spawn_blocking(move || { crate::core::run_workflow_sync(&repo_path, &filename, workspace_id, &workspace_path) }) diff --git a/src-tauri/src/core/feature_preview.rs b/src-tauri/src/core/feature_preview.rs index a7ecfcd7..78582a18 100644 --- a/src-tauri/src/core/feature_preview.rs +++ b/src-tauri/src/core/feature_preview.rs @@ -11,6 +11,9 @@ pub enum PreviewFeature { WorkspaceScheduling, RemoteSsh, LinearIntegration, + Logs, + Checks, + Browser, } impl PreviewFeature { @@ -20,6 +23,9 @@ impl PreviewFeature { Self::WorkspaceScheduling => "workspaceScheduling", Self::RemoteSsh => "remoteSsh", Self::LinearIntegration => "linearIntegration", + Self::Logs => "logs", + Self::Checks => "checks", + Self::Browser => "browser", } } @@ -98,6 +104,9 @@ mod tests { assert!(!package_json_default(PreviewFeature::WorkspaceScheduling)); assert!(!package_json_default(PreviewFeature::RemoteSsh)); assert!(!package_json_default(PreviewFeature::LinearIntegration)); + assert!(!package_json_default(PreviewFeature::Logs)); + assert!(!package_json_default(PreviewFeature::Checks)); + assert!(!package_json_default(PreviewFeature::Browser)); } #[test] diff --git a/src/components/LogsTimeseriesChart.tsx b/src/components/LogsTimeseriesChart.tsx index 12f13e4f..ca3bb01c 100644 --- a/src/components/LogsTimeseriesChart.tsx +++ b/src/components/LogsTimeseriesChart.tsx @@ -62,7 +62,7 @@ export function LogsTimeseriesChart({ const index = new Map(timeline.map((t, i) => [t, i])); const series = SERIES.map(({ severity, label, color }) => { - const data = new Array(timeline.length).fill(0); + const data = Array.from({ length: timeline.length }).fill(0); for (const bucket of buckets) { if (bucket.severity_text !== severity) continue; const at = index.get(Date.parse(bucket.bucket)); diff --git a/src/components/ShowWorkspace.tsx b/src/components/ShowWorkspace.tsx index 3a172d87..6adf0232 100644 --- a/src/components/ShowWorkspace.tsx +++ b/src/components/ShowWorkspace.tsx @@ -240,6 +240,9 @@ export const ShowWorkspace = ({ const { addToast } = useToast(); const workspaceScheduling = usePreviewFeature("workspaceScheduling"); const linearIntegration = usePreviewFeature("linearIntegration"); + const logsEnabled = usePreviewFeature("logs"); + const checksEnabled = usePreviewFeature("checks"); + const browserEnabled = usePreviewFeature("browser"); const { fontSize } = useTerminalSettingsStore(); const { data: remoteInfo } = useGitRemoteInfo(effectiveRepoPath || undefined); @@ -326,6 +329,21 @@ export const ShowWorkspace = ({ const [scrollToCommitId, setScrollToCommitId] = useState(null); const [showFileBrowserInCode, setShowFileBrowserInCode] = useState(false); + useEffect(() => { + if ( + (!logsEnabled && activeTab === "logs") || + (!checksEnabled && activeTab === "checks") + ) { + setActiveTab("overview"); + } + }, [activeTab, checksEnabled, logsEnabled]); + + useEffect(() => { + if (!browserEnabled && reviewSubView === "browser") { + setReviewSubView("diff"); + } + }, [browserEnabled, reviewSubView]); + // `treq send --browser ` opens the Browser view directly, // instead of showing an attachment preview like image/text sends do. const treqSendAssets = useTreqSendStore((s) => s.assets); @@ -1294,14 +1312,16 @@ export const ShowWorkspace = ({ )} - - - Checks - - {!workspace && ( + {checksEnabled && ( + + + Checks + + )} + {!workspace && logsEnabled && ( - {activeTab === "changes" && ( + {activeTab === "changes" && browserEnabled && (