([]);
+
+ const styles = useStyles({ height });
+
+ useEffect(() => {
+ const selectedProcessEvents = (selectedProcess?.events || []).map((processEvent, idx) => ({
+ id: `${processEvent?.event.action}-${idx + 1}` || `event-${idx + 1}`,
+ name: `${processEvent?.event.action}-${idx + 1}` || `event-${idx + 1}`,
+ content: (
+
+
+
+
+ ),
+ }));
+
+ setProcessEventsTabs(selectedProcessEvents);
+ setSelectedDetailTab(selectedProcessEvents?.[0]?.id || '');
+ }, [selectedProcess]);
+
+ const handleAnimationEnd = () => {
+ if (!isDetailMounted) {
+ setIsDetailOpen(false);
+ }
+ };
+
+ const renderSelectedProcessEvents = () => {
+ if (selectedProcess) {
+ return (
+
+
+
+
+
+
+
+
+ {processEventsTabs.map((tab, idx) => (
+ setSelectedDetailTab(tab.id)}
+ isSelected={tab.id === selectedDetailTab}
+ >
+ {tab.name}
+
+ ))}
+
+
+ {processEventsTabs.find((tab) => tab.id === selectedDetailTab)?.content}
+
+ );
+ }
+ };
+
+ return (
+
+ {renderSelectedProcessEvents()}
+
+
+
+
+
+ {/* Add session detail */}
+
+
+
+
+
+
+ {/* Add server detail */}
+
+
+
+
+
+
+ {/* Add alert detail conditionally */}
+
+ );
+};
diff --git a/x-pack/plugins/session_view/public/components/SessionViewDetailPanel/styles.ts b/x-pack/plugins/session_view/public/components/SessionViewDetailPanel/styles.ts
new file mode 100644
index 00000000000000..bb9959cffc0a5b
--- /dev/null
+++ b/x-pack/plugins/session_view/public/components/SessionViewDetailPanel/styles.ts
@@ -0,0 +1,64 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { useMemo } from 'react';
+import { keyframes, CSSObject } from '@emotion/react';
+
+interface StylesDeps {
+ height: number | undefined;
+}
+
+export const useStyles = ({ height = 500 }: StylesDeps) => {
+ const cached = useMemo(() => {
+ const slideIn = keyframes({
+ to: {
+ right: '0',
+ },
+ });
+
+ const slideOut = keyframes({
+ from: {
+ right: '0',
+ },
+ to: {
+ right: '-100%',
+ },
+ });
+
+ const detailPanel: CSSObject = {
+ width: '424px',
+ height: `${height}px`,
+ overflowY: 'auto',
+ position: 'absolute',
+ top: '8px',
+ right: '-100%',
+ };
+
+ const detailPanelIn: Array = [
+ slideIn.styles,
+ {
+ ...detailPanel,
+ animation: `${slideIn.name} 200ms ease forwards`,
+ },
+ ];
+
+ const detailPanelOut: Array = [
+ slideOut.styles,
+ {
+ ...detailPanel,
+ animation: `${slideOut.name} 150ms ease`,
+ },
+ ];
+
+ return {
+ detailPanelIn,
+ detailPanelOut,
+ };
+ }, [height]);
+
+ return cached;
+};
diff --git a/x-pack/plugins/session_view/public/hooks/use_process_tree.ts b/x-pack/plugins/session_view/public/hooks/use_process_tree.ts
index 4414f4728d8657..75e39f17078cdd 100644
--- a/x-pack/plugins/session_view/public/hooks/use_process_tree.ts
+++ b/x-pack/plugins/session_view/public/hooks/use_process_tree.ts
@@ -47,7 +47,7 @@ interface ProcessFields {
exit_code?: number;
}
-interface ProcessSelf extends ProcessFields {
+export interface ProcessSelf extends ProcessFields {
parent: ProcessFields;
session: ProcessFields;
entry: ProcessFields;
@@ -165,6 +165,7 @@ class ProcessImpl implements Process {
);
if (execsForks.length === 0) {
+ // eslint-disable-next-line no-debugger
debugger;
}
@@ -183,7 +184,7 @@ class ProcessImpl implements Process {
isUserEntered() {
const event = this.getDetails();
- const { interactive, pgid, parent } = event.process;
+ const { interactive, pgid, parent } = event?.process || {};
return interactive && pgid !== parent.pgid;
}
@@ -298,7 +299,7 @@ export const useProcessTree = ({
if (process.searchMatched || process.isUserEntered()) {
let { parent } = process;
- while (parent) {
+ while (parent && parent.id !== parent.parent?.id) {
parent.autoExpand = true;
parent = parent.parent;
}