diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.module.css b/grafana-plugin/src/components/SourceCode/SourceCode.module.css index 7cac30a8..beabde1e 100644 --- a/grafana-plugin/src/components/SourceCode/SourceCode.module.css +++ b/grafana-plugin/src/components/SourceCode/SourceCode.module.css @@ -1,5 +1,6 @@ .root { position: relative; + width: 100%; } .scroller { diff --git a/grafana-plugin/src/components/SourceCode/SourceCode.tsx b/grafana-plugin/src/components/SourceCode/SourceCode.tsx index 3484b82e..1689212c 100644 --- a/grafana-plugin/src/components/SourceCode/SourceCode.tsx +++ b/grafana-plugin/src/components/SourceCode/SourceCode.tsx @@ -12,23 +12,26 @@ const cx = cn.bind(styles); interface SourceCodeProps { noMaxHeight?: boolean; + showCopyToClipboard?: boolean; } const SourceCode: FC = (props) => { - const { children, noMaxHeight = false } = props; + const { children, noMaxHeight = false, showCopyToClipboard = true } = props; return (
- { - openNotification('Copied!'); - }} - > - - + {showCopyToClipboard && ( + { + openNotification('Copied!'); + }} + > + + + )}
 
     const { alertReceiveChannelStore } = store;
 
-    const { isMobile } = store;
-
     const { alerts } = store.alertGroupStore;
 
     const incident = alerts.get(id);
@@ -174,17 +177,15 @@ class IncidentPage extends React.Component
       );
     }
 
-    const integration = store.alertReceiveChannelStore.getIntegration(incident.alert_receive_channel);
-
     return (
       <>
         
{this.renderHeader()}
- {this.renderIncident(incident)} - {this.renderGroupedIncidents()} - {this.renderAttachedIncidents()} + + +
{this.renderTimeline()}
@@ -335,112 +336,6 @@ class IncidentPage extends React.Component this.setState({ showAttachIncidentForm: true }); }; - renderIncident = (incident: Alert) => { - let datetimeReference; - - if (incident.last_alert_at || incident.created_at) { - const m = moment(incident.last_alert_at || incident.created_at); - datetimeReference = `(${m.fromNow()}, ${m.toString()})`; - } - - return ( -
- - - {incident.inside_organization_number - ? `#${incident.inside_organization_number} ${incident.render_for_web.title}` - : incident.render_for_web.title} - - {datetimeReference} - -
- {incident.render_for_web.image_url && } -
- ); - }; - - renderGroupedIncidents() { - const { - store, - query: { id }, - } = this.props; - - const incident = store.alertGroupStore.alerts.get(id); - - const alerts = incident.alerts; - if (!alerts) { - return null; - } - - const latestAlert = alerts[alerts.length - 1]; - const latestAlertMoment = moment(latestAlert.created_at); - - return ( - - {incident.alerts_count} Grouped Alerts - - (latest {latestAlertMoment.fromNow()}, {latestAlertMoment.toString()}) - - - } - contentClassName={cx('incidents-content')} - > - {alerts.map(this.renderIncident)} - - ); - } - - renderAttachedIncidents = () => { - const { - store, - query: { id }, - } = this.props; - - const incident = store.alertGroupStore.alerts.get(id); - - if (!incident.dependent_alert_groups.length) { - return null; - } - - const alerts = incident.dependent_alert_groups; - - return ( - {incident.dependent_alert_groups.length} Attached Incidents} - contentClassName={cx('incidents-content')} - > - {alerts.map((incident) => { - return ( - - - #{incident.inside_organization_number} {incident.render_for_web.title} - - {/* */} - - - - - ); - })} - - ); - }; - getUnattachClickHandler = (pk: Alert['pk']) => { const { store } = this.props; @@ -614,6 +509,192 @@ class IncidentPage extends React.Component store.alertGroupStore.doIncidentAction(alert.pk, AlertAction.unSilence, false); }; }; + + getIncidentDatetimeReference = (incident: Alert | GroupedAlert): string => { + let datetimeReference; + if ((incident as Alert).last_alert_at || incident.created_at) { + const m = moment((incident as Alert).last_alert_at || incident.created_at); + datetimeReference = `(${m.fromNow()}, ${m.toString()})`; + } + + return datetimeReference; + }; +} + +function Incident({ incident, datetimeReference }: { incident: Alert; datetimeReference: string }) { + return ( +
+ + + {incident.inside_organization_number + ? `#${incident.inside_organization_number} ${incident.render_for_web.title}` + : incident.render_for_web.title} + + {datetimeReference} + +
+ {incident.render_for_web.image_url && } +
+ ); +} + +function GroupedIncidentsList({ + id, + getIncidentDatetimeReference, +}: { + id: string; + getIncidentDatetimeReference: (incident: GroupedAlert) => string; +}) { + const store = useStore(); + const incident = store.alertGroupStore.alerts.get(id); + + const alerts = incident.alerts; + if (!alerts) { + return null; + } + + const latestAlert = alerts[alerts.length - 1]; + const latestAlertMoment = moment(latestAlert.created_at); + + return ( + + {incident.alerts_count} Grouped Alerts + + (latest {latestAlertMoment.fromNow()}, {latestAlertMoment.toString()}) + + + } + contentClassName={cx('incidents-content')} + > + {alerts.map((alert) => ( + + ))} + + ); +} + +function GroupedIncident({ incident, datetimeReference }: { incident: GroupedAlert; datetimeReference: string }) { + const store = useStore(); + const [incidentRawResponse, setIncidentRawResponse] = useState<{ id: string; raw_request_data: any }>(undefined); + const [isModalOpen, setIsModalOpen] = useState(false); + const payloadJSON = isModalOpen ? JSON.stringify(incidentRawResponse.raw_request_data, null, 4) : undefined; + + return ( + <> + {isModalOpen && ( + setIsModalOpen(false)} closeOnEscape isOpen={isModalOpen} title="Alert Payload"> +
+ + + {incident.render_for_web.title} - {datetimeReference} + + +
+ + {payloadJSON} + + { + openNotification('Copied!'); + }} + > + + + + +
+ )} + +
+
+
+ + + {incident.render_for_web.title} + + {datetimeReference} + +
+
+ + + openIncidentResponse(incident)} /> + + +
+
+
+ {incident.render_for_web.image_url && } +
+ + ); + + async function openIncidentResponse(incident: GroupedAlert) { + const currentIncidentRawResponse = await store.alertGroupStore.getPayloadForIncident(incident.id); + setIncidentRawResponse(currentIncidentRawResponse); + setIsModalOpen(true); + } +} + +function AttachedIncidentsList({ + id, + getUnattachClickHandler, +}: { + id: string; + getUnattachClickHandler(pk: string): void; +}) { + const store = useStore(); + const incident = store.alertGroupStore.alerts.get(id); + + if (!incident.dependent_alert_groups.length) { + return null; + } + + const alerts = incident.dependent_alert_groups; + + return ( + {incident.dependent_alert_groups.length} Attached Incidents} + contentClassName={cx('incidents-content')} + > + {alerts.map((incident) => { + return ( + + + #{incident.inside_organization_number} {incident.render_for_web.title} + + {/* */} + + + + + ); + })} + + ); } export default withMobXProviderContext(IncidentPage); diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx index 18d718af..e2839858 100644 --- a/grafana-plugin/src/pages/incidents/Incidents.tsx +++ b/grafana-plugin/src/pages/incidents/Incidents.tsx @@ -103,7 +103,6 @@ class Incidents extends React.Component renderIncidentFilters() { const { query } = this.props; - const { filters } = this.state; return (