-
+
+
+
+
@@ -106,6 +121,13 @@ const getStyles = (theme: GrafanaTheme2) => ({
borderBottom: 'none',
borderTopLeftRadius: theme.shape.radius.default,
}),
+ searchRow: css({
+ display: 'flex',
+ marginBottom: theme.spacing(1),
+ }),
+ closeButton: css({
+ marginLeft: theme.spacing(1),
+ }),
customFieldMargin: css({
marginBottom: theme.spacing(1),
}),
diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx
index 9e2ca410700..10fb8788a03 100644
--- a/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx
+++ b/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx
@@ -1000,7 +1000,7 @@ describe('DashboardScene', () => {
scene.setState({ isDirty: true });
locationService.push('/d/adsdas');
- await scene.deleteDashboard();
+ await scene.onDashboardDelete();
expect(scene.state.isDirty).toBe(false);
});
diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx
index 13f1069c653..3378af54647 100644
--- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx
+++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx
@@ -34,7 +34,6 @@ import store from 'app/core/store';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
-import { deleteDashboard } from 'app/features/manage-dashboards/state/actions';
import { getClosestScopesFacade, ScopesFacade } from 'app/features/scopes';
import { VariablesChanged } from 'app/features/variables/types';
import { DashboardDTO, DashboardMeta, KioskMode, SaveDashboardResponseDTO } from 'app/types';
@@ -891,8 +890,7 @@ export class DashboardScene extends SceneObjectBase
{
this._initialSaveModel = saveModel;
}
- public async deleteDashboard() {
- await deleteDashboard(this.state.uid!, true);
+ public async onDashboardDelete() {
// Need to mark it non dirty to navigate away without unsaved changes warning
this.setState({ isDirty: false });
locationService.replace('/');
diff --git a/public/app/features/dashboard-scene/settings/DeleteDashboardButton.tsx b/public/app/features/dashboard-scene/settings/DeleteDashboardButton.tsx
index aca70195cf1..19494d5663d 100644
--- a/public/app/features/dashboard-scene/settings/DeleteDashboardButton.tsx
+++ b/public/app/features/dashboard-scene/settings/DeleteDashboardButton.tsx
@@ -2,17 +2,56 @@ import { useAsyncFn, useToggle } from 'react-use';
import { selectors } from '@grafana/e2e-selectors';
import { config, reportInteraction } from '@grafana/runtime';
-import { Button, ConfirmModal, Modal } from '@grafana/ui';
-import { Trans } from 'app/core/internationalization';
+import { Button, ConfirmModal, Modal, Space, Text } from '@grafana/ui';
+import { t, Trans } from 'app/core/internationalization';
+import { useDeleteItemsMutation } from '../../browse-dashboards/api/browseDashboardsAPI';
import { DashboardScene } from '../scene/DashboardScene';
interface ButtonProps {
dashboard: DashboardScene;
}
+interface ProvisionedDeleteModalProps {
+ dashboardId: string | undefined;
+ onClose: () => void;
+}
+
+interface DeleteModalProps {
+ dashboardTitle: string;
+ onConfirm: () => void;
+ onClose: () => void;
+}
+
export function DeleteDashboardButton({ dashboard }: ButtonProps) {
const [showModal, toggleModal] = useToggle(false);
+ const [deleteItems] = useDeleteItemsMutation();
+
+ const [, onConfirm] = useAsyncFn(async () => {
+ reportInteraction('grafana_manage_dashboards_delete_clicked', {
+ item_counts: {
+ dashboard: 1,
+ },
+ source: 'dashboard_scene_settings',
+ restore_enabled: config.featureToggles.dashboardRestoreUI,
+ });
+ toggleModal();
+ if (dashboard.state.uid) {
+ await deleteItems({
+ selectedItems: {
+ dashboard: {
+ [dashboard.state.uid]: true,
+ },
+ folder: {},
+ },
+ });
+ }
+ await dashboard.onDashboardDelete();
+ }, [dashboard, toggleModal]);
+
+ if (dashboard.state.meta.provisioned && showModal) {
+ return ;
+ }
return (
<>
@@ -24,52 +63,48 @@ export function DeleteDashboardButton({ dashboard }: ButtonProps) {
Delete dashboard
- {showModal && }
+ {showModal && (
+
+ )}
>
);
}
-interface ModalProps {
- dashboard: DashboardScene;
- onClose: () => void;
-}
-
-function DeleteDashboardModal({ dashboard, onClose }: ModalProps) {
- const [, onConfirm] = useAsyncFn(async () => {
- reportInteraction('grafana_manage_dashboards_delete_clicked', {
- item_counts: {
- dashboard: 1,
- },
- source: 'dashboard_scene_settings',
- restore_enabled: config.featureToggles.dashboardRestoreUI,
- });
- onClose();
- await dashboard.deleteDashboard();
- }, [dashboard, onClose]);
-
- if (dashboard.state.meta.provisioned) {
- return ;
- }
-
+export function DeleteDashboardModal({ dashboardTitle, onConfirm, onClose }: DeleteModalProps) {
return (
- Do you want to delete this dashboard?
- {dashboard.state.title}
+ {config.featureToggles.dashboardRestore && (
+ <>
+
+
+ This action will mark the dashboard for deletion in 30 days. Your organization administrator can
+ restore it anytime before the 30 days expire.
+
+
+
+ >
+ )}
+
+ Do you want to delete this dashboard?
+
+ {dashboardTitle}
+
>
}
onConfirm={onConfirm}
onDismiss={onClose}
- title="Delete"
+ title={t('dashboard-settings.delete-modal.title', 'Delete')}
icon="trash-alt"
- confirmText="Delete"
+ confirmText={t('dashboard-settings.delete-modal.delete-button', 'Delete')}
+ confirmationText={t('dashboard-settings.delete-modal.confirmation-text', 'Delete')}
/>
);
}
-function ProvisionedDeleteModal({ dashboard, onClose }: ModalProps) {
+function ProvisionedDeleteModal({ dashboardId, onClose }: ProvisionedDeleteModalProps) {
return (
@@ -90,7 +125,7 @@ function ProvisionedDeleteModal({ dashboard, onClose }: ModalProps) {
for more information about provisioning.
- File path: {dashboard.state.meta.provisionedExternalId}
+ File path: {dashboardId}
diff --git a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx
index fd265a3c0b6..d82f4fd56a0 100644
--- a/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx
+++ b/public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx
@@ -3,12 +3,13 @@ import { connect, ConnectedProps } from 'react-redux';
import useAsyncFn from 'react-use/lib/useAsyncFn';
import { locationService, config, reportInteraction } from '@grafana/runtime';
-import { Modal, ConfirmModal, Button, Text, Space, TextLink } from '@grafana/ui';
+import { Modal, Button, Text, Space, TextLink } from '@grafana/ui';
import { DashboardModel } from 'app/features/dashboard/state';
import { cleanUpDashboardAndVariables } from 'app/features/dashboard/state/actions';
import { Trans, t } from '../../../../core/internationalization';
import { useDeleteItemsMutation } from '../../../browse-dashboards/api/browseDashboardsAPI';
+import { DeleteDashboardModal as DeleteModal } from '../../../dashboard-scene/settings/DeleteDashboardButton';
type DeleteDashboardModalProps = {
hideModal(): void;
@@ -52,29 +53,7 @@ const DeleteDashboardModalUnconnected = ({ hideModal, cleanUpDashboardAndVariabl
return ;
}
- return (
-
-
-
- Do you want to delete this dashboard?
-
-
-
- {dashboard.title}
-
- >
- }
- onConfirm={onConfirm}
- onDismiss={hideModal}
- title={t('dashboard-settings.dashboard-delete-modal.title', 'Delete')}
- icon="trash-alt"
- confirmText={t('dashboard-settings.dashboard-delete-modal.delete-button', 'Delete')}
- confirmationText={t('dashboard-settings.dashboard-delete-modal.confirmation-text', 'Delete')}
- />
- );
+ return ;
};
const ProvisionedDeleteModal = ({ hideModal, provisionedId }: { hideModal(): void; provisionedId: string }) => (
diff --git a/public/app/features/dashboard/index.ts b/public/app/features/dashboard/index.ts
deleted file mode 100644
index 12c86883b58..00000000000
--- a/public/app/features/dashboard/index.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// Services
-import './services/DashboardLoaderSrv';
-import './services/DashboardSrv';
-// Components
-import './components/DashExportModal';
-import './components/DashNav';
-import './components/DashboardSettings';
diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx
index f2d0a4d9be2..29399e29552 100644
--- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx
+++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx
@@ -67,7 +67,6 @@ export const getStyles = (theme: GrafanaTheme2) => {
summaryItem: css`
label: summaryItem;
display: inline;
- margin-left: 0.7em;
padding-right: 0.5rem;
border-right: 1px solid ${autoColor(theme, '#ddd')};
&:last-child {
@@ -90,10 +89,11 @@ export const getStyles = (theme: GrafanaTheme2) => {
export type AccordianKeyValuesProps = {
className?: string | TNil;
data: TraceKeyValuePair[];
+ logName?: string;
highContrast?: boolean;
interactive?: boolean;
isOpen: boolean;
- label: string;
+ label: string | React.ReactNode;
linksGetter?: ((pairs: TraceKeyValuePair[], index: number) => TraceLink[]) | TNil;
onToggle?: null | (() => void);
};
@@ -127,6 +127,7 @@ export function KeyValuesSummary({ data = null }: KeyValuesSummaryProps) {
export default function AccordianKeyValues({
className = null,
data,
+ logName,
highContrast = false,
interactive = true,
isOpen,
@@ -134,11 +135,12 @@ export default function AccordianKeyValues({
linksGetter,
onToggle = null,
}: AccordianKeyValuesProps) {
- const isEmpty = !Array.isArray(data) || !data.length;
+ const isEmpty = (!Array.isArray(data) || !data.length) && !logName;
const styles = useStyles2(getStyles);
const iconCls = cx(alignIcon, { [styles.emptyIcon]: isEmpty });
let arrow: React.ReactNode | null = null;
let headerProps: {} | null = null;
+ const tableFields = logName ? [{ key: 'event name', value: logName }, ...data] : data;
if (interactive) {
arrow = isOpen ? (
@@ -152,6 +154,8 @@ export default function AccordianKeyValues({
};
}
+ const showDataSummaryFields = data.length > 0 && !isOpen;
+
return (
{label}
- {isOpen || ':'}
+ {showDataSummaryFields && ':'}
- {!isOpen && }
+ {showDataSummaryFields && (
+
+
+
+ )}
- {isOpen &&
}
+ {isOpen &&
}
);
}
diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.test.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.test.tsx
index 8e5db8dcebd..f69f3c8808f 100644
--- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.test.tsx
+++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.test.tsx
@@ -30,6 +30,7 @@ const logs = [
{ key: 'message', value: 'oh the next log message' },
{ key: 'more', value: 'stuff' },
],
+ name: 'foo event name',
},
];
@@ -72,4 +73,47 @@ describe('AccordianLogs tests', () => {
expect(screen.getByText(/^something$/)).toBeInTheDocument();
expect(screen.getByText(/^else$/)).toBeInTheDocument();
});
+
+ it('shows log entries and long event name when expanded', () => {
+ const longNameLog = {
+ timestamp: 20,
+ name: 'This is a very very very very very very very long name',
+ fields: [{ key: 'foo', value: 'test' }],
+ };
+
+ setup({
+ isOpen: true,
+ logs: [longNameLog],
+ openedItems: new Set([longNameLog]),
+ } as AccordianLogsProps);
+
+ expect(
+ screen.getByRole('switch', {
+ name: '15μs (This is a very very ...)',
+ })
+ ).toBeInTheDocument();
+
+ expect(screen.getByRole('table')).toBeInTheDocument();
+ expect(screen.queryAllByRole('cell')).toHaveLength(6);
+ expect(screen.getByText(/^event name$/)).toBeInTheDocument();
+ expect(screen.getByText(/This is a very very very very very very very long name/)).toBeInTheDocument();
+ });
+
+ it('renders event name and duration when events list is closed', () => {
+ setup({ isOpen: true, openedItems: new Set() } as AccordianLogsProps);
+ expect(
+ screen.getByRole('switch', {
+ name: '15μs (foo event name) : message = oh the next log message more = stuff',
+ })
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole('switch', { name: '5μs: message = oh the log message something = else' })
+ ).toBeInTheDocument();
+ });
+
+ it('renders event name and duration when events list is open', () => {
+ setup({ isOpen: true, openedItems: new Set(logs) } as AccordianLogsProps);
+ expect(screen.getByRole('switch', { name: '15μs (foo event name)' })).toBeInTheDocument();
+ expect(screen.getByRole('switch', { name: '5μs' })).toBeInTheDocument();
+ });
});
diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx
index 9e8cefccd8c..6ecfec0f80d 100644
--- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx
+++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx
@@ -59,6 +59,9 @@ const getStyles = (theme: GrafanaTheme2) => {
AccordianKeyValuesItem: css({
marginBottom: theme.spacing(0.5),
}),
+ parenthesis: css({
+ color: `${autoColor(theme, '#777')}`,
+ }),
};
};
@@ -108,22 +111,35 @@ export default function AccordianLogs({
{isOpen && (
- {_sortBy(logs, 'timestamp').map((log, i) => (
-
onItemToggle(log) : null}
- />
- ))}
+ {_sortBy(logs, 'timestamp').map((log, i) => {
+ const formattedDuration = formatDuration(log.timestamp - timestamp);
+ const truncateLogNameInSummary = log.name && log.name.length > 20;
+ const formattedLogName = log.name && truncateLogNameInSummary ? log.name.slice(0, 20) + '...' : log.name;
+ const label = formattedLogName ? (
+
+ {formattedDuration} ({formattedLogName})
+
+ ) : (
+ formattedDuration
+ );
+ return (
+ onItemToggle(log) : null}
+ />
+ );
+ })}
- Log timestamps are relative to the start time of the full trace.
+ Event timestamps are relative to the start time of the full trace.
)}
diff --git a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx
index 005d3af52ea..92b0731d467 100644
--- a/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx
+++ b/public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/KeyValuesTable.tsx
@@ -48,7 +48,7 @@ export const getStyles = (theme: GrafanaTheme2) => {
row: css`
label: row;
& > td {
- padding: 0rem 0.5rem;
+ padding: 0.5rem 0.5rem;
height: 30px;
}
&:nth-child(2n) > td {
@@ -63,6 +63,7 @@ export const getStyles = (theme: GrafanaTheme2) => {
color: ${autoColor(theme, '#888')};
white-space: pre;
width: 125px;
+ vertical-align: top;
`,
copyColumn: css`
label: copyColumn;
diff --git a/public/app/features/explore/TraceView/components/types/trace.ts b/public/app/features/explore/TraceView/components/types/trace.ts
index 0507287b987..bee45e059b4 100644
--- a/public/app/features/explore/TraceView/components/types/trace.ts
+++ b/public/app/features/explore/TraceView/components/types/trace.ts
@@ -31,6 +31,7 @@ export type TraceLink = {
export type TraceLog = {
timestamp: number;
fields: TraceKeyValuePair[];
+ name?: string;
};
export type TraceProcess = {
diff --git a/public/app/features/explore/TraceView/components/utils/filter-spans.test.ts b/public/app/features/explore/TraceView/components/utils/filter-spans.test.ts
index 1cf04d8424a..4bae04a74a2 100644
--- a/public/app/features/explore/TraceView/components/utils/filter-spans.test.ts
+++ b/public/app/features/explore/TraceView/components/utils/filter-spans.test.ts
@@ -55,6 +55,7 @@ describe('filterSpans', () => {
],
logs: [
{
+ name: 'logName0',
fields: [
{
key: 'logFieldKey0',
@@ -316,6 +317,10 @@ describe('filterSpans', () => {
).toEqual(new Set([spanID0]));
});
+ it('it should return logs have a name which matches the filter', () => {
+ expect(filterSpans({ ...defaultFilters, query: 'logName0' }, spans)).toEqual(new Set([spanID0]));
+ });
+
it('should return no spans when logs is null', () => {
const nullSpan = { ...span0, logs: null };
expect(
diff --git a/public/app/features/explore/TraceView/components/utils/filter-spans.tsx b/public/app/features/explore/TraceView/components/utils/filter-spans.tsx
index 942a13a476b..9f6d908d52e 100644
--- a/public/app/features/explore/TraceView/components/utils/filter-spans.tsx
+++ b/public/app/features/explore/TraceView/components/utils/filter-spans.tsx
@@ -90,7 +90,8 @@ export function getQueryMatches(query: string, spans: TraceSpan[] | TNil) {
(span.instrumentationLibraryName && isTextInQuery(queryParts, span.instrumentationLibraryName)) ||
(span.instrumentationLibraryVersion && isTextInQuery(queryParts, span.instrumentationLibraryVersion)) ||
(span.traceState && isTextInQuery(queryParts, span.traceState)) ||
- (span.logs !== null && span.logs.some((log) => isTextInKeyValues(log.fields))) ||
+ (span.logs !== null &&
+ span.logs.some((log) => (log.name && isTextInQuery(queryParts, log.name)) || isTextInKeyValues(log.fields))) ||
isTextInKeyValues(span.process.tags) ||
queryParts.some((queryPart) => queryPart === span.spanID);
diff --git a/public/app/features/manage-dashboards/state/actions.ts b/public/app/features/manage-dashboards/state/actions.ts
index a3c6df8cd87..f87b4a80b56 100644
--- a/public/app/features/manage-dashboards/state/actions.ts
+++ b/public/app/features/manage-dashboards/state/actions.ts
@@ -3,7 +3,6 @@ import { getBackendSrv, getDataSourceSrv, isFetchError } from '@grafana/runtime'
import { notifyApp } from 'app/core/actions';
import { createErrorNotification } from 'app/core/copy/appNotification';
import { browseDashboardsAPI, ImportInputs } from 'app/features/browse-dashboards/api/browseDashboardsAPI';
-import { getDashboardAPI } from 'app/features/dashboard/api/dashboard_api';
import { FolderInfo, PermissionLevelString, SearchQueryType, ThunkResult } from 'app/types';
import {
@@ -281,39 +280,6 @@ export async function moveFolders(folderUIDs: string[], toFolder: FolderInfo) {
return result;
}
-function createTask(fn: (...args: any[]) => Promise, ignoreRejections: boolean, ...args: any[]) {
- return async (result: any) => {
- try {
- const res = await fn(...args);
- return Array.prototype.concat(result, [res]);
- } catch (err) {
- if (ignoreRejections) {
- return result;
- }
-
- throw err;
- }
- };
-}
-
-export function deleteFoldersAndDashboards(folderUids: string[], dashboardUids: string[]) {
- const tasks = [];
-
- for (const folderUid of folderUids) {
- tasks.push(createTask(deleteFolder, true, folderUid, true));
- }
-
- for (const dashboardUid of dashboardUids) {
- tasks.push(createTask(deleteDashboard, true, dashboardUid, true));
- }
-
- return executeInOrder(tasks);
-}
-
-function deleteFolder(uid: string, showSuccessAlert: boolean) {
- return getBackendSrv().delete(`/api/folders/${uid}?forceDeleteRules=false`, undefined, { showSuccessAlert });
-}
-
export function createFolder(payload: any) {
return getBackendSrv().post('/api/folders', payload);
}
@@ -346,13 +312,3 @@ export function getFolderByUid(uid: string): Promise<{ uid: string; title: strin
export function getFolderById(id: number): Promise<{ id: number; title: string }> {
return getBackendSrv().get(`/api/folders/id/${id}`);
}
-
-export function deleteDashboard(uid: string, showSuccessAlert: boolean) {
- return getDashboardAPI().deleteDashboard(uid, showSuccessAlert);
-}
-
-function executeInOrder(tasks: any[]): Promise {
- return tasks.reduce((acc, task) => {
- return Promise.resolve(acc).then(task);
- }, []);
-}
diff --git a/public/app/features/plugins/all.ts b/public/app/features/plugins/all.ts
deleted file mode 100644
index fe460be0708..00000000000
--- a/public/app/features/plugins/all.ts
+++ /dev/null
@@ -1 +0,0 @@
-import './datasource_srv';
diff --git a/public/app/plugins/datasource/jaeger/_importedDependencies/types/trace.ts b/public/app/plugins/datasource/jaeger/_importedDependencies/types/trace.ts
index 0507287b987..bee45e059b4 100644
--- a/public/app/plugins/datasource/jaeger/_importedDependencies/types/trace.ts
+++ b/public/app/plugins/datasource/jaeger/_importedDependencies/types/trace.ts
@@ -31,6 +31,7 @@ export type TraceLink = {
export type TraceLog = {
timestamp: number;
fields: TraceKeyValuePair[];
+ name?: string;
};
export type TraceProcess = {
diff --git a/public/app/plugins/datasource/jaeger/types.ts b/public/app/plugins/datasource/jaeger/types.ts
index fe6778957f6..3fc5f8de320 100644
--- a/public/app/plugins/datasource/jaeger/types.ts
+++ b/public/app/plugins/datasource/jaeger/types.ts
@@ -14,6 +14,7 @@ export type TraceLink = {
export type TraceLog = {
timestamp: number;
fields: TraceKeyValuePair[];
+ name?: string;
};
export type TraceProcess = {
diff --git a/public/app/plugins/datasource/tempo/resultTransformer.ts b/public/app/plugins/datasource/tempo/resultTransformer.ts
index 592b043307b..b41458590d1 100644
--- a/public/app/plugins/datasource/tempo/resultTransformer.ts
+++ b/public/app/plugins/datasource/tempo/resultTransformer.ts
@@ -132,7 +132,7 @@ function getLogs(span: collectorTypes.opentelemetryProto.trace.v1.Span) {
fields.push({ key: attribute.key, value: getAttributeValue(attribute.value) });
}
}
- logs.push({ fields, timestamp: event.timeUnixNano / 1000000 });
+ logs.push({ fields, timestamp: event.timeUnixNano / 1000000, name: event.name });
}
}
@@ -364,7 +364,7 @@ function getOTLPEvents(logs: TraceLog[]): collectorTypes.opentelemetryProto.trac
timeUnixNano: log.timestamp * 1000000,
attributes: [],
droppedAttributesCount: 0,
- name: '',
+ name: log.name || '',
};
for (const field of log.fields) {
event.attributes!.push({
diff --git a/public/app/plugins/datasource/tempo/test/testResponse.ts b/public/app/plugins/datasource/tempo/test/testResponse.ts
index 493cb97501a..765e55cf08c 100644
--- a/public/app/plugins/datasource/tempo/test/testResponse.ts
+++ b/public/app/plugins/datasource/tempo/test/testResponse.ts
@@ -1920,7 +1920,7 @@ export const otlpDataFrameFromResponse = new MutableDataFrame({
name: 'logs',
type: FieldType.other,
config: {},
- values: [[]],
+ values: [[{ name: 'DNSDone', fields: [{ key: 'addr', value: '172.18.0.6' }] }]],
},
{
name: 'references',
@@ -2138,7 +2138,20 @@ export const otlpDataFrameToResponse = new MutableDataFrame({
name: 'logs',
type: FieldType.other,
config: {},
- values: [[]],
+ values: [
+ [
+ {
+ fields: [
+ {
+ key: 'addr',
+ value: '172.18.0.6',
+ },
+ ],
+ timestamp: 1627471657255.809,
+ name: 'DNSDone',
+ },
+ ],
+ ],
state: {
displayName: 'logs',
},
@@ -2240,6 +2253,14 @@ export const otlpResponse = {
{ key: 'http.url', value: { stringValue: '/' } },
{ key: 'component', value: { stringValue: 'net/http' } },
],
+ events: [
+ {
+ name: 'DNSDone',
+ attributes: [{ key: 'addr', value: { stringValue: '172.18.0.6' } }],
+ droppedAttributesCount: 0,
+ timeUnixNano: 1627471657255809000,
+ },
+ ],
links: [
{
spanId: 'spanId',
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index ba9a51a6a84..1fe44ea4c33 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -607,12 +607,13 @@
"title": "Annotations"
},
"dashboard-delete-button": "Delete dashboard",
- "dashboard-delete-modal": {
+ "delete-modal": {
"confirmation-text": "Delete",
"delete-button": "Delete",
- "text": "Do you want to delete this dashboard?",
"title": "Delete"
},
+ "delete-modal-restore-dashboards-text": "This action will mark the dashboard for deletion in 30 days. Your organization administrator can restore it anytime before the 30 days expire.",
+ "delete-modal-text": "Do you want to delete this dashboard?",
"general": {
"auto-refresh-description": "Define the auto refresh intervals that should be available in the auto refresh list. Use the format '5s' for seconds, '1m' for minutes, '1h' for hours, and '1d' for days (e.g.: '5s,10s,30s,1m,5m,15m,30m,1h,2h,1d').",
"auto-refresh-label": "Auto refresh",
diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json
index 28726d4ec22..c8e15f1d979 100644
--- a/public/locales/pseudo-LOCALE/grafana.json
+++ b/public/locales/pseudo-LOCALE/grafana.json
@@ -607,12 +607,13 @@
"title": "Åʼnʼnőŧäŧįőʼnş"
},
"dashboard-delete-button": "Đęľęŧę đäşĥþőäřđ",
- "dashboard-delete-modal": {
+ "delete-modal": {
"confirmation-text": "Đęľęŧę",
"delete-button": "Đęľęŧę",
- "text": "Đő yőū ŵäʼnŧ ŧő đęľęŧę ŧĥįş đäşĥþőäřđ?",
"title": "Đęľęŧę"
},
+ "delete-modal-restore-dashboards-text": "Ŧĥįş äčŧįőʼn ŵįľľ mäřĸ ŧĥę đäşĥþőäřđ ƒőř đęľęŧįőʼn įʼn 30 đäyş. Ÿőūř őřģäʼnįžäŧįőʼn äđmįʼnįşŧřäŧőř čäʼn řęşŧőřę įŧ äʼnyŧįmę þęƒőřę ŧĥę 30 đäyş ęχpįřę.",
+ "delete-modal-text": "Đő yőū ŵäʼnŧ ŧő đęľęŧę ŧĥįş đäşĥþőäřđ?",
"general": {
"auto-refresh-description": "Đęƒįʼnę ŧĥę äūŧő řęƒřęşĥ įʼnŧęřväľş ŧĥäŧ şĥőūľđ þę äväįľäþľę įʼn ŧĥę äūŧő řęƒřęşĥ ľįşŧ. Ůşę ŧĥę ƒőřmäŧ '5ş' ƒőř şęčőʼnđş, '1m' ƒőř mįʼnūŧęş, '1ĥ' ƒőř ĥőūřş, äʼnđ '1đ' ƒőř đäyş (ę.ģ.: '5ş,10ş,30ş,1m,5m,15m,30m,1ĥ,2ĥ,1đ').",
"auto-refresh-label": "Åūŧő řęƒřęşĥ",
diff --git a/yarn.lock b/yarn.lock
index 146a96ce487..a6743b4c8f6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3933,8 +3933,8 @@ __metadata:
linkType: soft
"@grafana/scenes@npm:^5.11.1":
- version: 5.11.1
- resolution: "@grafana/scenes@npm:5.11.1"
+ version: 5.11.2
+ resolution: "@grafana/scenes@npm:5.11.2"
dependencies:
"@floating-ui/react": "npm:0.26.16"
"@grafana/e2e-selectors": "npm:^11.0.0"
@@ -3951,7 +3951,7 @@ __metadata:
"@grafana/ui": ">=10.4"
react: ^18.0.0
react-dom: ^18.0.0
- checksum: 10/15ec8bee9aa2aa8f5c64ed9fcaf4bd7c835162e0e63814556e7561e62462d5485f098131e411893e54ae3247692b348c8773a9459c30e45e936c5b0ef1a9d789
+ checksum: 10/1f6cded27acac813b1f039fa656efa476bcb2a444217c78c707441698d8d2dc053745fadcbad2dbe94a252d2613f1b32ac120fb11d887bb14f08a0bbea4c423b
languageName: node
linkType: hard