diff --git a/src/pages/workspace/utils/web_scraping/web_page_content_tracker_revision.tsx b/src/pages/workspace/utils/web_scraping/web_page_content_tracker_revision.tsx
index 9617c60..bbb8df5 100644
--- a/src/pages/workspace/utils/web_scraping/web_page_content_tracker_revision.tsx
+++ b/src/pages/workspace/utils/web_scraping/web_page_content_tracker_revision.tsx
@@ -1,26 +1,60 @@
-import { EuiCodeBlock } from '@elastic/eui';
+import { EuiCodeBlock, EuiMarkdownFormat } from '@elastic/eui';
import type { WebPageContentRevision } from './web_page_data_revision';
+import type { WebPageTrackerHistoryMode } from './web_page_tracker_history';
export interface WebPageContentTrackerRevisionProps {
revision: WebPageContentRevision;
- showDiff?: boolean;
+ mode: WebPageTrackerHistoryMode;
}
-export function WebPageContentTrackerRevision({ revision, showDiff }: WebPageContentTrackerRevisionProps) {
+function containHTMLTags(data: string) {
+ try {
+ const doc = new DOMParser().parseFromString(data, 'text/html');
+ return Array.from(doc.body.childNodes).some((node) => node.nodeType === Node.ELEMENT_NODE);
+ } catch {
+ return false;
+ }
+}
+
+export function WebPageContentTrackerRevision({ revision, mode }: WebPageContentTrackerRevisionProps) {
let dataToRender;
+ let codeBlockType = null;
try {
dataToRender = JSON.parse(revision.data) as string | object;
- if (typeof dataToRender !== 'string') {
+ if (typeof dataToRender === 'object' && dataToRender) {
dataToRender = JSON.stringify(dataToRender, null, 2);
+ codeBlockType = 'json';
+ } else if (typeof dataToRender !== 'string') {
+ dataToRender = JSON.stringify(dataToRender, null, 2);
+ } else if (containHTMLTags(dataToRender)) {
+ codeBlockType = 'html';
}
} catch {
dataToRender = revision.data;
}
- return (
-
- {dataToRender}
-
- );
+ if (mode === 'source' || (mode === 'default' && codeBlockType)) {
+ return (
+
+ {dataToRender}
+
+ );
+ }
+
+ if (mode === 'diff' && dataToRender.startsWith('@@')) {
+ return (
+
+ {dataToRender}
+
+ );
+ }
+
+ return {dataToRender};
}
diff --git a/src/pages/workspace/utils/web_scraping/web_page_content_trackers.tsx b/src/pages/workspace/utils/web_scraping/web_page_content_trackers.tsx
index 438d191..ca1e039 100644
--- a/src/pages/workspace/utils/web_scraping/web_page_content_trackers.tsx
+++ b/src/pages/workspace/utils/web_scraping/web_page_content_trackers.tsx
@@ -154,8 +154,8 @@ export default function WebPageContentTrackers() {
} else {
itemIdToExpandedRowMapValues[tracker.name] = (
- {(revision, showDiff) => (
-
+ {(revision, mode) => (
+
)}
);
diff --git a/src/pages/workspace/utils/web_scraping/web_page_tracker_history.tsx b/src/pages/workspace/utils/web_scraping/web_page_tracker_history.tsx
index f13c02d..c4b6ea8 100644
--- a/src/pages/workspace/utils/web_scraping/web_page_tracker_history.tsx
+++ b/src/pages/workspace/utils/web_scraping/web_page_tracker_history.tsx
@@ -3,6 +3,7 @@ import type { ReactNode } from 'react';
import {
EuiButton,
+ EuiButtonGroup,
EuiConfirmModal,
EuiEmptyPrompt,
EuiFlexGroup,
@@ -10,7 +11,6 @@ import {
EuiIcon,
EuiPanel,
EuiSelect,
- EuiSwitch,
} from '@elastic/eui';
import { css } from '@emotion/react';
import axios from 'axios';
@@ -25,20 +25,35 @@ import { useWorkspaceContext } from '../../hooks';
export interface WebPageTrackerHistoryProps {
tracker: WebPageTracker;
kind: 'content' | 'resources';
- children: (revision: WebPageDataRevision, showDiff: boolean) => ReactNode;
+ children: (revision: WebPageDataRevision, mode: WebPageTrackerHistoryMode) => ReactNode;
}
+export type WebPageTrackerHistoryMode = 'default' | 'diff' | 'source';
+
export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTrackerHistoryProps) {
const { uiState, addToast } = useWorkspaceContext();
- const [showDiff, setShowDiff] = useState(true);
const [revisions, setRevisions] = useState>({
status: 'pending',
state: null,
});
const [revisionIndex, setRevisionIndex] = useState(null);
+
+ const modes = [
+ { id: 'default' as const, label: 'Default', isDisabled: revisions.status !== 'succeeded' },
+ { id: 'diff' as const, label: 'Diff', isDisabled: revisionIndex === 0 || revisions.status !== 'succeeded' },
+ ...(kind === 'content'
+ ? [{ id: 'source' as const, label: 'Source', isDisabled: revisions.status !== 'succeeded' }]
+ : []),
+ ];
+ const [mode, setMode] = useState('default');
+
const fetchHistory = useCallback(
- ({ refresh }: { refresh: boolean } = { refresh: false }) => {
+ (
+ { refresh, forceMode }: { refresh: boolean; forceMode?: WebPageTrackerHistoryMode } = {
+ refresh: false,
+ },
+ ) => {
setRevisions((currentRevisions) =>
currentRevisions.status === 'succeeded'
? { status: 'pending', state: currentRevisions.data }
@@ -47,7 +62,7 @@ export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTracke
axios
.post(
getApiUrl(`/api/utils/web_scraping/${kind}/${encodeURIComponent(tracker.id)}/history`),
- { refresh, calculateDiff: showDiff },
+ { refresh, calculateDiff: (forceMode ?? mode) === 'diff' },
getApiRequestConfig(),
)
.then(
@@ -58,6 +73,12 @@ export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTracke
if (refresh || revisionIndex === null || revisionIndex >= response.data.length) {
setRevisionIndex(response.data.length > 0 ? response.data.length - 1 : null);
}
+
+ if (response.data.length < 2) {
+ setMode('default');
+ } else if (forceMode && forceMode !== mode) {
+ setMode(forceMode);
+ }
},
(err: Error) => {
setRevisions((currentRevisions) => ({
@@ -69,7 +90,7 @@ export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTracke
},
);
},
- [getApiUrl, revisionIndex, showDiff],
+ [getApiUrl, revisionIndex, mode],
);
useEffect(() => {
@@ -78,7 +99,7 @@ export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTracke
}
fetchHistory();
- }, [uiState, tracker, showDiff]);
+ }, [uiState, tracker]);
const onRevisionChange = useCallback(
(revisionId: string) => {
@@ -163,7 +184,7 @@ export function WebPageTrackerHistory({ kind, tracker, children }: WebPageTracke
/>
);
} else if (revisionIndex !== null) {
- history = children(revisions.data[revisionIndex], showDiff);
+ history = children(revisions.data[revisionIndex], mode);
} else {
const updateButton = (
- setShowDiff(e.target.checked)}
+ onChange={(id) => {
+ const newMode = id as WebPageTrackerHistoryMode;
+ setMode(newMode);
+
+ const shouldFetch = (mode === 'diff' && id !== 'diff') || (mode !== 'diff' && id === 'diff');
+ if (shouldFetch) {
+ fetchHistory({ forceMode: newMode, refresh: false });
+ }
+ }}
/>