This is an automated email from the ASF dual-hosted git repository.

zqr10159 pushed a commit to branch 2.0.0
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/2.0.0 by this push:
     new d58a839f4b Wire service overview dashboard action
d58a839f4b is described below

commit d58a839f4b3cdd1c5fc9abb2b7ceb7b6e5a5b4da
Author: Logic <[email protected]>
AuthorDate: Mon Jun 8 09:18:08 2026 +0800

    Wire service overview dashboard action
---
 .../app/dashboard/dashboard-draft-workspace.tsx    |  55 +++
 web-next/app/dashboard/page.test.ts                |  10 +
 web-next/lib/i18n-runtime-messages.ts              | 444 ++++++++++++++++++++-
 3 files changed, 507 insertions(+), 2 deletions(-)

diff --git a/web-next/app/dashboard/dashboard-draft-workspace.tsx 
b/web-next/app/dashboard/dashboard-draft-workspace.tsx
index 70b945d7d8..7ece164bbb 100644
--- a/web-next/app/dashboard/dashboard-draft-workspace.tsx
+++ b/web-next/app/dashboard/dashboard-draft-workspace.tsx
@@ -31,6 +31,7 @@ import {
   buildSignalDashboardRuntimeSyncCrosshair,
   buildSignalDashboardRuntimeSyncTooltip,
   buildSignalDashboardVariableOptions,
+  buildSignalServiceOverviewDashboard,
   createSignalDashboardPanelDraftsFromFilterSelection,
   createSignalDashboardPanelDraftFromRuntimeBreakout,
   createSignalDashboardPanelDraftFromRuntimeEvidence,
@@ -774,6 +775,7 @@ export default function DashboardDraftWorkspace({
   const [dashboardDescriptionDraft, setDashboardDescriptionDraft] = 
useState('');
   const [savingPreviewLayout, setSavingPreviewLayout] = useState(false);
   const [savingVariables, setSavingVariables] = useState(false);
+  const [savingServiceOverview, setSavingServiceOverview] = useState(false);
   const [variableNameDraft, setVariableNameDraft] = useState('service.name');
   const [variableTypeDraft, setVariableTypeDraft] = 
useState<SignalDashboardVariableType>('textbox');
   const [variableValueDraft, setVariableValueDraft] = useState('');
@@ -794,6 +796,21 @@ export default function DashboardDraftWorkspace({
     () => readDashboardVariableUrlOverrides(initialContext),
     [initialContext]
   );
+  const serviceOverviewContext = useMemo(() => {
+    const serviceName = firstParamValue(initialContext.serviceName)?.trim() || 
'';
+    if (!serviceName) return null;
+    return {
+      serviceName,
+      serviceNamespace: 
firstParamValue(initialContext.serviceNamespace)?.trim() || undefined,
+      environment: firstParamValue(initialContext.environment)?.trim() || 
undefined,
+      entityId: firstParamValue(initialContext.entityId)?.trim() || undefined,
+      entityType: firstParamValue(initialContext.entityType)?.trim() || 
undefined,
+      entityName: firstParamValue(initialContext.entityName)?.trim() || 
undefined,
+      source: firstParamValue(initialContext.source)?.trim() || undefined,
+      collector: firstParamValue(initialContext.collector)?.trim() || 
undefined,
+      template: firstParamValue(initialContext.template)?.trim() || undefined
+    };
+  }, [initialContext]);
   const defaultDashboardTitle = t('dashboard.composition.default-title');
   const defaultDashboardDescription = 
t('dashboard.composition.default-description');
   const runtimeTableLabels = useMemo(() => ({
@@ -1111,6 +1128,29 @@ export default function DashboardDraftWorkspace({
     }
   };
 
+  const saveServiceOverviewDashboard = async () => {
+    if (!serviceOverviewContext) return;
+    setSavingServiceOverview(true);
+    setCompositionState('saving');
+    try {
+      const dashboard = buildSignalServiceOverviewDashboard({
+        ...serviceOverviewContext,
+        ...dashboardTimeRange
+      });
+      const saved = await saveSignalDashboard(dashboard);
+      setDashboardKeyDraft(saved.dashboardKey);
+      setDashboardTitleDraft(saved.title);
+      setDashboardDescriptionDraft(saved.description || 
defaultDashboardDescription);
+      replaceDashboardDeepLink(saved.dashboardKey);
+      setDashboards(current => [saved, ...current.filter(item => 
item.dashboardKey !== saved.dashboardKey)]);
+      setCompositionState('saved');
+    } catch {
+      setCompositionState('error');
+    } finally {
+      setSavingServiceOverview(false);
+    }
+  };
+
   const replaceSelectedDashboardVariables = (variables: 
SignalDashboardVariable[]) => {
     if (!selectedDashboard) return;
     setDashboards(current => current.map(dashboard =>
@@ -1924,6 +1964,8 @@ export default function DashboardDraftWorkspace({
             clip
             
data-dashboard-composition-preview-owner="hertzbeat-ui-panel-surface"
             
data-dashboard-composition-preview-key={selectedDashboard?.dashboardKey || 
normalizeSignalDashboardKey(dashboardKeyDraft || dashboardTitleDraft)}
+            data-dashboard-service-overview-context={serviceOverviewContext ? 
'ready' : 'missing'}
+            
data-dashboard-service-overview-service={serviceOverviewContext?.serviceName || 
''}
             data-dashboard-composition-preview-panels={previewPanels.length}
             data-dashboard-composition-time-range-mode={dashboardTimeRangeMode}
             
data-dashboard-composition-time-range-start={dashboardTimeRange.start}
@@ -1981,6 +2023,19 @@ export default function DashboardDraftWorkspace({
                 <Save size={13} />
                 {t('dashboard.composition.action.save-preview-layout')}
               </HzButton>
+              <HzButton
+                type="button"
+                size="sm"
+                intent="secondary"
+                disabled={!serviceOverviewContext || savingServiceOverview}
+                onClick={() => void saveServiceOverviewDashboard()}
+                data-dashboard-service-overview-action="save"
+                
data-dashboard-service-overview-action-state={serviceOverviewContext ? 'ready' 
: 'missing'}
+                
data-dashboard-service-overview-action-service={serviceOverviewContext?.serviceName
 || ''}
+              >
+                <LayoutDashboard size={13} />
+                {t('dashboard.composition.action.save-service-overview')}
+              </HzButton>
             </div>
             <div
               className="grid gap-2 border-b border-[#252b35] bg-[#080b10] 
px-4 py-3"
diff --git a/web-next/app/dashboard/page.test.ts 
b/web-next/app/dashboard/page.test.ts
index c238435ade..d3fb0bc637 100644
--- a/web-next/app/dashboard/page.test.ts
+++ b/web-next/app/dashboard/page.test.ts
@@ -126,6 +126,16 @@ describe('dashboard panel draft workspace route', () => {
     expect(workspaceSource).toContain('loadSignalDashboards');
     expect(workspaceSource).toContain('saveSignalDashboard');
     expect(workspaceSource).toContain('deleteSignalDashboard');
+    expect(workspaceSource).toContain('buildSignalServiceOverviewDashboard');
+    expect(workspaceSource).toContain('const serviceOverviewContext = 
useMemo(');
+    expect(workspaceSource).toContain('const serviceName = 
firstParamValue(initialContext.serviceName)?.trim()');
+    expect(workspaceSource).toContain('const saveServiceOverviewDashboard = 
async () =>');
+    expect(workspaceSource).toContain('buildSignalServiceOverviewDashboard({');
+    
expect(workspaceSource).toContain('data-dashboard-service-overview-context');
+    
expect(workspaceSource).toContain('data-dashboard-service-overview-service');
+    
expect(workspaceSource).toContain('data-dashboard-service-overview-action="save"');
+    
expect(workspaceSource).toContain('data-dashboard-service-overview-action-state');
+    
expect(workspaceSource).toContain('dashboard.composition.action.save-service-overview');
     expect(workspaceSource).toContain('normalizeSignalDashboardKey');
     expect(workspaceSource).toContain('buildDashboardVariableDeepLinkHref');
     expect(workspaceSource).toContain('buildDashboardTimeRangeDeepLinkHref');
diff --git a/web-next/lib/i18n-runtime-messages.ts 
b/web-next/lib/i18n-runtime-messages.ts
index d9947ed0c3..b78346557c 100644
--- a/web-next/lib/i18n-runtime-messages.ts
+++ b/web-next/lib/i18n-runtime-messages.ts
@@ -1843,16 +1843,162 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'dashboard.quick-entry.dashboards.copy': 'Open saved visualization 
boards.',
     'dashboard.add-panel.title': 'Dashboard panel draft',
     'dashboard.add-panel.description': 'Prepare a {{signal}} panel for 
{{title}} from the current explorer context.',
+    'dashboard.add-panel.saved-description': 'Review saved panel drafts from 
logs, traces, and metrics before placing them on a dashboard.',
     'dashboard.add-panel.signal.logs': 'Logs',
     'dashboard.add-panel.signal.traces': 'Traces',
     'dashboard.add-panel.signal.metrics': 'Metrics',
+    'dashboard.add-panel.signal.alerts': 'Alerts',
     'dashboard.add-panel.action.save-draft': 'Save draft',
     'dashboard.add-panel.action.open-explorer': 'Open source explorer',
+    'dashboard.add-panel.action.duplicate-draft': 'Duplicate draft',
+    'dashboard.add-panel.action.delete-draft': 'Delete draft',
+    'dashboard.add-panel.duplicate-title-suffix': 'Copy',
     'dashboard.add-panel.saved-title': 'Saved panel drafts',
+    'dashboard.add-panel.sync.local-cache': 'Local cache',
+    'dashboard.add-panel.sync.server-loading': 'Syncing drafts',
+    'dashboard.add-panel.sync.server-backed': 'Server backed',
+    'dashboard.add-panel.sync.server-unavailable': 'Local fallback',
+    'dashboard.add-panel.sync.saving': 'Saving',
+    'dashboard.add-panel.sync.saved': 'Saved',
+    'dashboard.add-panel.sync.failed': 'Sync failed',
     'dashboard.add-panel.query.label': 'Source query',
     'dashboard.add-panel.query.meta': 'Explorer query context',
     'dashboard.add-panel.expression.label': 'Panel expression',
     'dashboard.add-panel.expression.meta': 'Dashboard expression',
+    'dashboard.panel-drafts.title': 'Dashboard panel drafts',
+    'dashboard.panel-drafts.action.overview': 'Open overview',
+    'dashboard.panel-drafts.metric.total': 'Total drafts',
+    'dashboard.panel-drafts.column.panel': 'Panel',
+    'dashboard.panel-drafts.column.signal': 'Signal',
+    'dashboard.panel-drafts.column.visualization': 'Visualization',
+    'dashboard.panel-drafts.column.route': 'Source route',
+    'dashboard.panel-drafts.column.updated': 'Updated',
+    'dashboard.panel-drafts.column.actions': 'Actions',
+    'dashboard.panel-drafts.status.loading': 'Loading panel drafts from 
/api/signal/dashboard-panel-draft.',
+    'dashboard.panel-drafts.status.ready': 'Panel drafts loaded from 
/api/signal/dashboard-panel-draft.',
+    'dashboard.panel-drafts.status.empty': 'No panel drafts yet. Use Add to 
dashboard from Logs, Traces, or Metrics explorers.',
+    'dashboard.panel-drafts.status.error': 'Panel draft API is unavailable. 
Explorer draft handoffs remain saved when the backend returns.',
+    'dashboard.panel-drafts.status-label.loading': 'Loading',
+    'dashboard.panel-drafts.status-label.ready': 'Ready',
+    'dashboard.panel-drafts.status-label.empty': 'Empty',
+    'dashboard.panel-drafts.status-label.partial': 'Partial',
+    'dashboard.panel-drafts.status-label.error': 'Unavailable',
+    'dashboard.panel-drafts.empty-title.loading': 'Loading saved panel drafts',
+    'dashboard.panel-drafts.empty-title.empty': 'No saved panel drafts',
+    'dashboard.panel-drafts.empty-title.error': 'Panel draft sync unavailable',
+    'dashboard.panel-drafts.empty-title.ready': 'Saved panel drafts ready',
+    'dashboard.saved-views.title': 'Saved query views',
+    'dashboard.saved-views.metric.total': 'Saved views',
+    'dashboard.saved-views.column.view': 'View',
+    'dashboard.saved-views.column.signal': 'Signal',
+    'dashboard.saved-views.column.route': 'Source route',
+    'dashboard.saved-views.column.created': 'Created',
+    'dashboard.saved-views.column.actions': 'Actions',
+    'dashboard.saved-views.field.label': 'Name',
+    'dashboard.saved-views.field.description': 'Description',
+    'dashboard.saved-views.status.loading': 'Loading saved query views from 
/api/signal/saved-view.',
+    'dashboard.saved-views.status.ready': 'Saved query views loaded from 
/api/signal/saved-view. Add one as a dashboard panel draft.',
+    'dashboard.saved-views.status.partial': 'Saved query views loaded 
partially. Unavailable signals: {signals}. Available views can still be added 
as dashboard panel drafts.',
+    'dashboard.saved-views.status.empty': 'No saved query views yet. Save 
views from Logs, Traces, or Metrics explorers.',
+    'dashboard.saved-views.status.error': 'Saved view API is unavailable. 
Panel drafts remain reviewable while the backend returns.',
+    'dashboard.saved-views.empty-title.loading': 'Loading saved query views',
+    'dashboard.saved-views.empty-title.empty': 'No saved query views',
+    'dashboard.saved-views.empty-title.error': 'Saved view sync unavailable',
+    'dashboard.saved-views.empty-title.ready': 'Saved query views ready',
+    'dashboard.saved-views.action.add-panel': 'Add panel',
+    'dashboard.saved-views.action.update': 'Update view',
+    'dashboard.saved-views.action.delete': 'Delete view',
+    'dashboard.composition.default-title': 'Signals overview',
+    'dashboard.composition.default-description': 'Dashboard composed from 
logs, traces, and metrics panel drafts.',
+    'dashboard.composition.action.save-layout': 'Save layout',
+    'dashboard.composition.action.save-preview-layout': 'Save preview layout',
+    'dashboard.composition.action.save-service-overview': 'Service overview',
+    'dashboard.composition.action.save-variables': 'Save variables',
+    'dashboard.composition.action.add-variable': 'Add variable',
+    'dashboard.composition.action.delete-variable': 'Delete',
+    'dashboard.composition.action.select-dashboard': 'Use dashboard',
+    'dashboard.composition.action.delete-dashboard': 'Delete',
+    'dashboard.composition.action.edit-panel': 'Edit panel',
+    'dashboard.composition.metric.dashboards': 'Dashboards',
+    'dashboard.composition.saved-title': 'Saved dashboards',
+    'dashboard.composition.target-title': 'Target dashboard',
+    'dashboard.composition.field.key': 'Dashboard key',
+    'dashboard.composition.field.title': 'Title',
+    'dashboard.composition.field.description': 'Description',
+    'dashboard.composition.preview-title': 'Dashboard layout preview',
+    'dashboard.composition.preview-copy': 'Saved widgets are shown in their 
persisted layout without inventing chart data.',
+    'dashboard.composition.preview-empty-copy': 'Select or save a dashboard 
composition to preview its panel layout.',
+    'dashboard.composition.preview-empty-title': 'No dashboard layout 
selected',
+    'dashboard.composition.preview-no-panels-copy': 'This dashboard 
composition has no saved widgets yet.',
+    'dashboard.composition.layout.move-left': 'Left',
+    'dashboard.composition.layout.move-right': 'Right',
+    'dashboard.composition.layout.move-up': 'Up',
+    'dashboard.composition.layout.move-down': 'Down',
+    'dashboard.composition.layout.wider': 'Wider',
+    'dashboard.composition.layout.narrower': 'Narrower',
+    'dashboard.composition.layout.taller': 'Taller',
+    'dashboard.composition.layout.shorter': 'Shorter',
+    'dashboard.composition.variables-title': 'Dashboard variables',
+    'dashboard.composition.variables-copy': 'Persist dashboard inputs for 
$variable references in saved panel queries.',
+    'dashboard.composition.variables-empty-copy': 'Select or save a dashboard 
before editing variables.',
+    'dashboard.composition.variables-empty-title': 'No dashboard variables',
+    'dashboard.composition.variable.field.name': 'Name',
+    'dashboard.composition.variable.field.type': 'Type',
+    'dashboard.composition.variable.field.value': 'Value',
+    'dashboard.composition.variable.field.description': 'Description',
+    'dashboard.composition.variable.field.options': 'Options',
+    'dashboard.composition.variable.type.custom': 'Custom',
+    'dashboard.composition.variable.type.textbox': 'Textbox',
+    'dashboard.composition.variable.type.query': 'Query',
+    'dashboard.composition.variable.type.dynamic': 'Dynamic',
+    'dashboard.composition.variable.description-empty': 'No description',
+    'dashboard.composition.variable.option-source.static': 'static',
+    'dashboard.composition.variable.option-source.runtime': 'runtime',
+    'dashboard.composition.filter-toolbar.title': 'Dashboard filters',
+    'dashboard.composition.filter-toolbar.variables': 'Variables',
+    'dashboard.composition.filter-toolbar.any': 'any',
+    'dashboard.composition.filter-toolbar.search': 'Search',
+    'dashboard.composition.filter-toolbar.add-panel-draft': 'Add panels',
+    'dashboard.composition.filter-toolbar.panel-title-prefix': 'Filter panel',
+    'dashboard.composition.time-range.start': 'Start',
+    'dashboard.composition.time-range.end': 'End',
+    'dashboard.composition.time-range.preset': 'Preset',
+    'dashboard.composition.time-range.refresh': 'Refresh',
+    'dashboard.composition.time-range.live': 'Live',
+    'dashboard.composition.widget-count': 'Widgets',
+    'dashboard.runtime.table.time': 'Time',
+    'dashboard.runtime.table.service': 'Service',
+    'dashboard.runtime.table.status': 'Status',
+    'dashboard.runtime.table.message': 'Message',
+    'dashboard.runtime.table.trace': 'Trace',
+    'dashboard.runtime.table.span': 'Span',
+    'dashboard.runtime.table.duration': 'Duration',
+    'dashboard.runtime.sync': 'Sync',
+    'dashboard.runtime.sync.idle': 'idle',
+    'dashboard.runtime.sync.pin': 'Pinned',
+    'dashboard.runtime.sync.clear-pin': 'Clear',
+    'dashboard.runtime.sync.open-source': 'Open',
+    'dashboard.runtime.sync.open-related': 'Related',
+    'dashboard.runtime.sync.add-panel-draft': 'Add panel',
+    'dashboard.runtime.sync.evidence-panel-title-prefix': 'Evidence panel',
+    'dashboard.runtime.sync.breakout-panel-draft': 'Breakout',
+    'dashboard.runtime.sync.breakout-panel-title-prefix': 'Breakout panel',
+    'dashboard.runtime.sync.apply-filter': 'Filter',
+    'dashboard.runtime.sync.add-filter': 'Add filter',
+    'dashboard.runtime.sync.tooltip': 'Synchronized evidence',
+    'dashboard.composition.empty-title': 'No saved dashboards',
+    'dashboard.composition.status.loading': 'Loading saved dashboard 
compositions from /api/signal/dashboard.',
+    'dashboard.composition.status.ready': 'Saved dashboard compositions loaded 
from /api/signal/dashboard.',
+    'dashboard.composition.status.empty': 'No dashboard composition has been 
saved yet. Save Layout to persist the current panel draft grid.',
+    'dashboard.composition.status.saving': 'Saving dashboard layout to 
/api/signal/dashboard.',
+    'dashboard.composition.status.saved': 'Dashboard layout saved to 
/api/signal/dashboard.',
+    'dashboard.composition.status.error': 'Dashboard composition API is 
unavailable. Panel drafts remain reviewable while the backend returns.',
+    'dashboard.composition.status-label.loading': 'Loading',
+    'dashboard.composition.status-label.ready': 'Ready',
+    'dashboard.composition.status-label.empty': 'Empty',
+    'dashboard.composition.status-label.saving': 'Saving',
+    'dashboard.composition.status-label.saved': 'Saved',
+    'dashboard.composition.status-label.error': 'Unavailable',
     'dashboard.owner.unassigned': 'Unassigned',
     'dashboard.severity.critical': 'Critical',
     'dashboard.severity.warning': 'Warning',
@@ -2461,8 +2607,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'trace.manage.saved-view.rename-label': 'Saved view name',
     'trace.manage.saved-view.rename-save': 'Save name',
     'trace.manage.saved-view.rename-cancel': 'Cancel rename',
+    'trace.manage.saved-view.persistence.local': 'Saved in this browser',
+    'trace.manage.saved-view.persistence.server': 'Shared on server',
     'trace.manage.saved-view.current-label': 'Current route view',
     'trace.manage.saved-view.empty': 'No local views',
+    'trace.manage.dashboard-panel-draft.add-current': 'Add to dashboard',
+    'trace.manage.dashboard-panel-draft.update-current': 'Update dashboard 
panel',
+    'trace.manage.dashboard-panel-draft.return-dashboard': 'Return to 
dashboard',
+    'trace.manage.dashboard-panel-draft.saving': 'Saving dashboard draft',
+    'trace.manage.dashboard-panel-draft.saved': 'Dashboard draft saved',
+    'trace.manage.dashboard-panel-draft.failed': 'Dashboard draft unavailable',
+    'trace.manage.dashboard-panel-draft.update-saving': 'Updating dashboard 
panel',
+    'trace.manage.dashboard-panel-draft.update-saved': 'Dashboard panel 
updated',
+    'trace.manage.dashboard-panel-draft.update-failed': 'Dashboard panel 
update unavailable',
     'trace.manage.saved-view.description.empty': 'Empty trace explorer route',
     'trace.manage.saved-view.field.view': 'view',
     'trace.manage.saved-view.field.service': 'service',
@@ -2583,6 +2740,31 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'trace.manage.drawer.attributes.empty.copy': 'No attributes are available 
for the selected span.',
     'trace.manage.drawer.attributes.group-action': 'Group',
     'trace.manage.drawer.attributes.group-action.aria': 'Group traces by 
{{name}}',
+    'trace.manage.drawer.related-logs.title': 'Related logs',
+    'trace.manage.drawer.related-logs.aria': 'Related logs for the selected 
trace span',
+    'trace.manage.drawer.related-logs.loading.title': 'Loading related logs',
+    'trace.manage.drawer.related-logs.loading.copy': 'Reading log records 
correlated by trace and span context.',
+    'trace.manage.drawer.related-logs.error.title': 'Related logs unavailable',
+    'trace.manage.drawer.related-logs.error.meta': 'log query error',
+    'trace.manage.drawer.related-logs.empty.title': 'No related logs',
+    'trace.manage.drawer.related-logs.empty.copy': 'No log records matched 
this trace context yet.',
+    'trace.manage.drawer.related-logs.action': 'Open logs',
+    'trace.manage.drawer.related-metrics.title': 'Related metrics',
+    'trace.manage.drawer.related-metrics.aria': 'Related metrics for the 
selected trace span',
+    'trace.manage.drawer.related-metrics.loading.title': 'Loading related 
metrics',
+    'trace.manage.drawer.related-metrics.loading.copy': 'Discovering metric 
candidates from the selected span resource context.',
+    'trace.manage.drawer.related-metrics.error.title': 'Related metrics 
unavailable',
+    'trace.manage.drawer.related-metrics.error.meta': 'discovery error',
+    'trace.manage.drawer.related-metrics.empty.title': 'No related metrics',
+    'trace.manage.drawer.related-metrics.empty.copy': 'No metric candidates 
matched this span resource context yet.',
+    'trace.manage.drawer.related-metrics.candidate.meta': 'resource candidate',
+    'trace.manage.drawer.related-metrics.action': 'Open metric',
+    'otlp.metrics.related-candidate.title': 'Related metric source',
+    'otlp.metrics.related-candidate.source': 'Candidate source',
+    'otlp.metrics.related-candidate.meta': 'backend related metric candidate',
+    'otlp.metrics.related-candidate.matched-labels': 'Matched labels',
+    'otlp.metrics.related-candidate.labels-meta': 'labels used to correlate 
this metric',
+    'otlp.metrics.related-candidate.resource-meta': 'resource match from 
related metrics discovery',
     'trace.manage.drawer.kicker': 'Trace detail',
     'trace.manage.drawer.title-fallback': 'Trace waterfall',
     'trace.manage.drawer.action.logs': 'View logs',
@@ -2938,8 +3120,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'otlp.metrics.saved-view.rename-label': 'Saved view name',
     'otlp.metrics.saved-view.rename-save': 'Save name',
     'otlp.metrics.saved-view.rename-cancel': 'Cancel rename',
+    'otlp.metrics.saved-view.persistence.local': 'Saved in this browser',
+    'otlp.metrics.saved-view.persistence.server': 'Shared on server',
     'otlp.metrics.saved-view.current-label': 'Current route view',
     'otlp.metrics.saved-view.empty': 'No local views',
+    'otlp.metrics.dashboard-panel-draft.add-current': 'Add to dashboard',
+    'otlp.metrics.dashboard-panel-draft.update-current': 'Update dashboard 
panel',
+    'otlp.metrics.dashboard-panel-draft.return-dashboard': 'Return to 
dashboard',
+    'otlp.metrics.dashboard-panel-draft.saving': 'Saving dashboard draft',
+    'otlp.metrics.dashboard-panel-draft.saved': 'Dashboard draft saved',
+    'otlp.metrics.dashboard-panel-draft.failed': 'Dashboard draft unavailable',
+    'otlp.metrics.dashboard-panel-draft.update-saving': 'Updating dashboard 
panel',
+    'otlp.metrics.dashboard-panel-draft.update-saved': 'Dashboard panel 
updated',
+    'otlp.metrics.dashboard-panel-draft.update-failed': 'Dashboard panel 
update unavailable',
     'otlp.metrics.saved-view.description.empty': 'Empty metrics explorer 
route',
     'otlp.metrics.saved-view.field.query': 'query',
     'otlp.metrics.saved-view.field.filter': 'filter',
@@ -3503,7 +3696,7 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.rule.evidence.return': 'Return to troubleshooting context',
     'alert.rule.evidence.fallback-target': 'troubleshooting context',
     'alert.rule.evidence.group.title': 'Grouping context from {{signal}}',
-    'alert.rule.evidence.group.copy': 'New grouping rules converge by stable 
labels from the current entity, service, namespace, and environment; trace 
detail stays as evidence context only.',
+    'alert.rule.evidence.group.copy': 'New grouping rules converge by stable 
signal, service, environment, source, and alert-query labels; trace detail 
stays as evidence context only.',
     'alert.rule.evidence.group.draft-name': '{{signal}} {{target}} group',
     'alert.rule.evidence.silence.title': 'Silence context from {{signal}}',
     'alert.rule.evidence.silence.copy': 'New silence rules match the current 
entity, service, environment, and trace labels so unrelated alerts are not 
muted.',
@@ -3522,6 +3715,8 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.group.delete.confirm.single': 'Delete the selected grouping rule. 
This cannot be undone.',
     'alert.group.delete.confirm.batch': 'Delete {{count}} grouping rules. This 
cannot be undone.',
     'alert.group.evidence.labels': 'Grouping labels',
+    'alert.group.preview.title': 'Recommended group-by labels',
+    'alert.group.preview.copy': 'Use these stable label keys to group related 
signal alerts while keeping high-cardinality trace and span IDs out of 
notification grouping.',
     'alert.group.pagination.summary': 'Page {{page}} / {{totalPages}} · 
{{from}}-{{to}} / {{total}}',
     'alert.group.pagination.page-size': 'Page size',
     'alert.group.pagination.page': 'Page',
@@ -3845,8 +4040,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'log.manage.saved-view.rename-label': 'Saved view name',
     'log.manage.saved-view.rename-save': 'Save name',
     'log.manage.saved-view.rename-cancel': 'Cancel rename',
+    'log.manage.saved-view.persistence.local': 'Saved in this browser',
+    'log.manage.saved-view.persistence.server': 'Shared on server',
     'log.manage.saved-view.current-label': 'Current route view',
     'log.manage.saved-view.empty': 'No local views',
+    'log.manage.dashboard-panel-draft.add-current': 'Add to dashboard',
+    'log.manage.dashboard-panel-draft.update-current': 'Update dashboard 
panel',
+    'log.manage.dashboard-panel-draft.return-dashboard': 'Return to dashboard',
+    'log.manage.dashboard-panel-draft.saving': 'Saving dashboard draft',
+    'log.manage.dashboard-panel-draft.saved': 'Dashboard draft saved',
+    'log.manage.dashboard-panel-draft.failed': 'Dashboard draft unavailable',
+    'log.manage.dashboard-panel-draft.update-saving': 'Updating dashboard 
panel',
+    'log.manage.dashboard-panel-draft.update-saved': 'Dashboard panel updated',
+    'log.manage.dashboard-panel-draft.update-failed': 'Dashboard panel update 
unavailable',
     'log.manage.saved-view.description.empty': 'Empty logs explorer route',
     'log.manage.saved-view.field.view': 'view',
     'log.manage.saved-view.field.search': 'search',
@@ -4271,6 +4477,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.notice.receiver.people.placeholder': 'Select a receiver',
     'alert.notice.receiver.type': 'Receiver type',
     'alert.notice.receiver.type.placeholder': 'Select a notice type',
+    'alert.notice.receiver.test-preview.title': 'Signal alert test context',
+    'alert.notice.receiver.test-preview.copy': 'The test message validates 
this receiver configuration. The labels below are the alert context that 
notification policies should match.',
+    'alert.notice.receiver.test-preview.payload.title': 'Sample alert payload 
preview',
+    'alert.notice.receiver.test-preview.payload.copy': 'Preview only. The 
receiver test still validates the receiver configuration through the backend.',
+    'alert.notice.receiver.test-preview.payload.status': 'Status',
+    'alert.notice.receiver.test-preview.payload.status.firing': 'Firing 
sample',
+    'alert.notice.receiver.test-preview.payload.rule': 'Rule',
+    'alert.notice.receiver.test-preview.payload.signal': 'Signal',
+    'alert.notice.receiver.test-preview.payload.scope': 'Scope',
+    'alert.notice.receiver.test-preview.payload.query': 'Query',
+    'alert.notice.receiver.test-preview.payload.severity': 'Severity',
+    'alert.notice.receiver.test-preview.payload.severity.sample': 'warning',
+    'alert.notice.receiver.test-preview.payload.message': '{{rule}} is firing 
for {{signal}} in {{scope}}.',
     'alert.notice.rule.receivers.empty': 'No receivers yet. Create a receiver 
first.',
     'alert.notice.send-test': 'Send Alert Test Msg',
     'alert.notice.send-test.notify.failed': 'Send Alert Test Failed!',
@@ -4310,6 +4529,7 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.notice.rule.priority.placeholder': 'Select Priorities',
     'alert.notice.rule.tag': 'Label Match',
     'alert.notice.rule.tag.placeholder': 'Select Labels',
+    'alert.notice.rule.labels.prefill': 'Matched alert labels',
     'alert.notice.rule.label.value.placeholder': 'Label value',
     'alert.notice.rule.time': 'Notification Time',
     'alert.notice.rule.time-end': 'End time',
@@ -6084,16 +6304,162 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'dashboard.quick-entry.dashboards.copy': '打开已保存的可视化看板。',
     'dashboard.add-panel.title': '仪表盘面板草稿',
     'dashboard.add-panel.description': '从当前 Explorer 上下文为 {{title}} 准备 
{{signal}} 面板。',
+    'dashboard.add-panel.saved-description': '将日志、链路和指标里的已保存面板草稿放入仪表盘前先统一检查。',
     'dashboard.add-panel.signal.logs': '日志',
     'dashboard.add-panel.signal.traces': '链路',
     'dashboard.add-panel.signal.metrics': '指标',
+    'dashboard.add-panel.signal.alerts': '告警',
     'dashboard.add-panel.action.save-draft': '保存草稿',
     'dashboard.add-panel.action.open-explorer': '打开来源 Explorer',
+    'dashboard.add-panel.action.duplicate-draft': '复制草稿',
+    'dashboard.add-panel.action.delete-draft': '删除草稿',
+    'dashboard.add-panel.duplicate-title-suffix': '副本',
     'dashboard.add-panel.saved-title': '已保存面板草稿',
+    'dashboard.add-panel.sync.local-cache': '本地缓存',
+    'dashboard.add-panel.sync.server-loading': '正在同步草稿',
+    'dashboard.add-panel.sync.server-backed': '服务端保存',
+    'dashboard.add-panel.sync.server-unavailable': '本地兜底',
+    'dashboard.add-panel.sync.saving': '正在保存',
+    'dashboard.add-panel.sync.saved': '已保存',
+    'dashboard.add-panel.sync.failed': '同步失败',
     'dashboard.add-panel.query.label': '来源查询',
     'dashboard.add-panel.query.meta': 'Explorer 查询上下文',
     'dashboard.add-panel.expression.label': '面板表达式',
     'dashboard.add-panel.expression.meta': '仪表盘表达式',
+    'dashboard.panel-drafts.title': '仪表盘面板草稿',
+    'dashboard.panel-drafts.action.overview': '打开概览',
+    'dashboard.panel-drafts.metric.total': '草稿总数',
+    'dashboard.panel-drafts.column.panel': '面板',
+    'dashboard.panel-drafts.column.signal': '信号',
+    'dashboard.panel-drafts.column.visualization': '可视化',
+    'dashboard.panel-drafts.column.route': '来源路由',
+    'dashboard.panel-drafts.column.updated': '更新时间',
+    'dashboard.panel-drafts.column.actions': '操作',
+    'dashboard.panel-drafts.status.loading': '正在从 
/api/signal/dashboard-panel-draft 加载面板草稿。',
+    'dashboard.panel-drafts.status.ready': '面板草稿已从 
/api/signal/dashboard-panel-draft 加载。',
+    'dashboard.panel-drafts.status.empty': '暂无面板草稿。请从日志、链路或指标 Explorer 
使用添加到仪表盘。',
+    'dashboard.panel-drafts.status.error': '面板草稿 API 暂不可用。后端恢复后 Explorer 
草稿跳转会继续保留。',
+    'dashboard.panel-drafts.status-label.loading': '加载中',
+    'dashboard.panel-drafts.status-label.ready': '就绪',
+    'dashboard.panel-drafts.status-label.empty': '为空',
+    'dashboard.panel-drafts.status-label.partial': '部分可用',
+    'dashboard.panel-drafts.status-label.error': '不可用',
+    'dashboard.panel-drafts.empty-title.loading': '正在加载已保存面板草稿',
+    'dashboard.panel-drafts.empty-title.empty': '暂无已保存面板草稿',
+    'dashboard.panel-drafts.empty-title.error': '面板草稿同步不可用',
+    'dashboard.panel-drafts.empty-title.ready': '已保存面板草稿就绪',
+    'dashboard.saved-views.title': '已保存查询视图',
+    'dashboard.saved-views.metric.total': '已保存视图',
+    'dashboard.saved-views.column.view': '视图',
+    'dashboard.saved-views.column.signal': '信号',
+    'dashboard.saved-views.column.route': '来源路由',
+    'dashboard.saved-views.column.created': '创建时间',
+    'dashboard.saved-views.column.actions': '操作',
+    'dashboard.saved-views.field.label': '名称',
+    'dashboard.saved-views.field.description': '描述',
+    'dashboard.saved-views.status.loading': '正在从 /api/signal/saved-view 
加载已保存查询视图。',
+    'dashboard.saved-views.status.ready': '已从 /api/signal/saved-view 
加载查询视图,可添加为仪表盘面板草稿。',
+    'dashboard.saved-views.status.partial': 
'已部分加载查询视图。不可用信号:{signals}。可用视图仍可添加为仪表盘面板草稿。',
+    'dashboard.saved-views.status.empty': '暂无已保存查询视图。请从日志、链路或指标 Explorer 
保存视图。',
+    'dashboard.saved-views.status.error': '已保存视图 API 暂不可用。后端恢复前仍可继续检查面板草稿。',
+    'dashboard.saved-views.empty-title.loading': '正在加载已保存查询视图',
+    'dashboard.saved-views.empty-title.empty': '暂无已保存查询视图',
+    'dashboard.saved-views.empty-title.error': '已保存视图同步不可用',
+    'dashboard.saved-views.empty-title.ready': '已保存查询视图就绪',
+    'dashboard.saved-views.action.add-panel': '添加面板',
+    'dashboard.saved-views.action.update': '更新视图',
+    'dashboard.saved-views.action.delete': '删除视图',
+    'dashboard.composition.default-title': '信号总览',
+    'dashboard.composition.default-description': '由日志、链路和指标面板草稿编排出的仪表盘。',
+    'dashboard.composition.action.save-layout': '保存布局',
+    'dashboard.composition.action.save-preview-layout': '保存预览布局',
+    'dashboard.composition.action.save-service-overview': '服务概览',
+    'dashboard.composition.action.save-variables': '保存变量',
+    'dashboard.composition.action.add-variable': '添加变量',
+    'dashboard.composition.action.delete-variable': '删除',
+    'dashboard.composition.action.select-dashboard': '使用此仪表盘',
+    'dashboard.composition.action.delete-dashboard': '删除',
+    'dashboard.composition.action.edit-panel': '编辑面板',
+    'dashboard.composition.metric.dashboards': '仪表盘',
+    'dashboard.composition.saved-title': '已保存仪表盘',
+    'dashboard.composition.target-title': '目标仪表盘',
+    'dashboard.composition.field.key': '仪表盘标识',
+    'dashboard.composition.field.title': '标题',
+    'dashboard.composition.field.description': '描述',
+    'dashboard.composition.preview-title': '仪表盘布局预览',
+    'dashboard.composition.preview-copy': '按已保存布局展示组件,不伪造图表数据。',
+    'dashboard.composition.preview-empty-copy': '选择或保存一个仪表盘编排后即可预览面板布局。',
+    'dashboard.composition.preview-empty-title': '尚未选择仪表盘布局',
+    'dashboard.composition.preview-no-panels-copy': '此仪表盘编排还没有已保存组件。',
+    'dashboard.composition.layout.move-left': '左移',
+    'dashboard.composition.layout.move-right': '右移',
+    'dashboard.composition.layout.move-up': '上移',
+    'dashboard.composition.layout.move-down': '下移',
+    'dashboard.composition.layout.wider': '加宽',
+    'dashboard.composition.layout.narrower': '变窄',
+    'dashboard.composition.layout.taller': '增高',
+    'dashboard.composition.layout.shorter': '变矮',
+    'dashboard.composition.variables-title': '仪表盘变量',
+    'dashboard.composition.variables-copy': '持久化仪表盘输入,供已保存面板查询里的 $variable 
引用使用。',
+    'dashboard.composition.variables-empty-copy': '选择或保存一个仪表盘后即可编辑变量。',
+    'dashboard.composition.variables-empty-title': '暂无仪表盘变量',
+    'dashboard.composition.variable.field.name': '名称',
+    'dashboard.composition.variable.field.type': '类型',
+    'dashboard.composition.variable.field.value': '值',
+    'dashboard.composition.variable.field.description': '描述',
+    'dashboard.composition.variable.field.options': '选项',
+    'dashboard.composition.variable.type.custom': '自定义',
+    'dashboard.composition.variable.type.textbox': '文本框',
+    'dashboard.composition.variable.type.query': '查询',
+    'dashboard.composition.variable.type.dynamic': '动态',
+    'dashboard.composition.variable.description-empty': '暂无描述',
+    'dashboard.composition.variable.option-source.static': '静态',
+    'dashboard.composition.variable.option-source.runtime': '运行时',
+    'dashboard.composition.filter-toolbar.title': '仪表盘筛选',
+    'dashboard.composition.filter-toolbar.variables': '变量',
+    'dashboard.composition.filter-toolbar.any': '任意',
+    'dashboard.composition.filter-toolbar.search': '搜索',
+    'dashboard.composition.filter-toolbar.add-panel-draft': '添加面板',
+    'dashboard.composition.filter-toolbar.panel-title-prefix': '筛选面板',
+    'dashboard.composition.time-range.start': '开始时间',
+    'dashboard.composition.time-range.end': '结束时间',
+    'dashboard.composition.time-range.preset': '预设范围',
+    'dashboard.composition.time-range.refresh': '刷新间隔',
+    'dashboard.composition.time-range.live': '实时',
+    'dashboard.composition.widget-count': '组件',
+    'dashboard.runtime.table.time': '时间',
+    'dashboard.runtime.table.service': '服务',
+    'dashboard.runtime.table.status': '状态',
+    'dashboard.runtime.table.message': '消息',
+    'dashboard.runtime.table.trace': '链路',
+    'dashboard.runtime.table.span': 'Span',
+    'dashboard.runtime.table.duration': '耗时',
+    'dashboard.runtime.sync': '同步',
+    'dashboard.runtime.sync.idle': '空闲',
+    'dashboard.runtime.sync.pin': '固定',
+    'dashboard.runtime.sync.clear-pin': '清除',
+    'dashboard.runtime.sync.open-source': '打开',
+    'dashboard.runtime.sync.open-related': '相关',
+    'dashboard.runtime.sync.add-panel-draft': '添加面板',
+    'dashboard.runtime.sync.evidence-panel-title-prefix': '证据面板',
+    'dashboard.runtime.sync.breakout-panel-draft': '拆分',
+    'dashboard.runtime.sync.breakout-panel-title-prefix': '拆分面板',
+    'dashboard.runtime.sync.apply-filter': '过滤',
+    'dashboard.runtime.sync.add-filter': '新增过滤',
+    'dashboard.runtime.sync.tooltip': '同步证据',
+    'dashboard.composition.empty-title': '暂无已保存仪表盘',
+    'dashboard.composition.status.loading': '正在从 /api/signal/dashboard 
加载已保存仪表盘编排。',
+    'dashboard.composition.status.ready': '已从 /api/signal/dashboard 加载仪表盘编排。',
+    'dashboard.composition.status.empty': '暂无已保存的仪表盘编排。点击保存布局即可持久化当前面板草稿网格。',
+    'dashboard.composition.status.saving': '正在将仪表盘布局保存到 
/api/signal/dashboard。',
+    'dashboard.composition.status.saved': '仪表盘布局已保存到 /api/signal/dashboard。',
+    'dashboard.composition.status.error': '仪表盘编排 API 暂不可用。后端恢复前仍可查看面板草稿。',
+    'dashboard.composition.status-label.loading': '加载中',
+    'dashboard.composition.status-label.ready': '就绪',
+    'dashboard.composition.status-label.empty': '为空',
+    'dashboard.composition.status-label.saving': '保存中',
+    'dashboard.composition.status-label.saved': '已保存',
+    'dashboard.composition.status-label.error': '不可用',
     'dashboard.owner.unassigned': '未分配',
     'dashboard.severity.critical': '严重',
     'dashboard.severity.warning': '警告',
@@ -6696,8 +7062,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'trace.manage.saved-view.rename-label': '已存视图名称',
     'trace.manage.saved-view.rename-save': '保存名称',
     'trace.manage.saved-view.rename-cancel': '取消重命名',
+    'trace.manage.saved-view.persistence.local': '保存在当前浏览器',
+    'trace.manage.saved-view.persistence.server': '服务器共享保存',
     'trace.manage.saved-view.current-label': '当前路由视图',
     'trace.manage.saved-view.empty': '暂无本地视图',
+    'trace.manage.dashboard-panel-draft.add-current': '添加到仪表盘',
+    'trace.manage.dashboard-panel-draft.update-current': '更新仪表盘面板',
+    'trace.manage.dashboard-panel-draft.return-dashboard': '返回仪表盘',
+    'trace.manage.dashboard-panel-draft.saving': '正在保存仪表盘草稿',
+    'trace.manage.dashboard-panel-draft.saved': '仪表盘草稿已保存',
+    'trace.manage.dashboard-panel-draft.failed': '仪表盘草稿暂不可用',
+    'trace.manage.dashboard-panel-draft.update-saving': '正在更新仪表盘面板',
+    'trace.manage.dashboard-panel-draft.update-saved': '仪表盘面板已更新',
+    'trace.manage.dashboard-panel-draft.update-failed': '仪表盘面板更新暂不可用',
     'trace.manage.saved-view.description.empty': '空链路工作台路由',
     'trace.manage.saved-view.field.view': '视图',
     'trace.manage.saved-view.field.service': '服务',
@@ -6818,6 +7195,31 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'trace.manage.drawer.attributes.empty.copy': '当前选中跨度没有可用属性。',
     'trace.manage.drawer.attributes.group-action': '分组',
     'trace.manage.drawer.attributes.group-action.aria': '按 {{name}} 对链路分组',
+    'trace.manage.drawer.related-logs.title': '相关日志',
+    'trace.manage.drawer.related-logs.aria': '当前选中跨度的相关日志',
+    'trace.manage.drawer.related-logs.loading.title': '正在加载相关日志',
+    'trace.manage.drawer.related-logs.loading.copy': '正在按链路和跨度上下文读取关联日志记录。',
+    'trace.manage.drawer.related-logs.error.title': '相关日志暂不可用',
+    'trace.manage.drawer.related-logs.error.meta': '日志查询异常',
+    'trace.manage.drawer.related-logs.empty.title': '暂无相关日志',
+    'trace.manage.drawer.related-logs.empty.copy': '当前链路上下文暂未匹配到日志记录。',
+    'trace.manage.drawer.related-logs.action': '打开日志',
+    'trace.manage.drawer.related-metrics.title': '相关指标',
+    'trace.manage.drawer.related-metrics.aria': '当前选中跨度的相关指标',
+    'trace.manage.drawer.related-metrics.loading.title': '正在加载相关指标',
+    'trace.manage.drawer.related-metrics.loading.copy': '正在根据当前跨度资源上下文发现指标候选。',
+    'trace.manage.drawer.related-metrics.error.title': '相关指标暂不可用',
+    'trace.manage.drawer.related-metrics.error.meta': '发现异常',
+    'trace.manage.drawer.related-metrics.empty.title': '暂无相关指标',
+    'trace.manage.drawer.related-metrics.empty.copy': '当前跨度资源上下文暂未匹配到指标候选。',
+    'trace.manage.drawer.related-metrics.candidate.meta': '资源候选',
+    'trace.manage.drawer.related-metrics.action': '打开指标',
+    'otlp.metrics.related-candidate.title': '相关指标来源',
+    'otlp.metrics.related-candidate.source': '候选来源',
+    'otlp.metrics.related-candidate.meta': '后端相关指标候选',
+    'otlp.metrics.related-candidate.matched-labels': '匹配标签',
+    'otlp.metrics.related-candidate.labels-meta': '用于关联该指标的标签',
+    'otlp.metrics.related-candidate.resource-meta': '相关指标发现返回的资源匹配',
     'trace.manage.drawer.kicker': '链路详情',
     'trace.manage.drawer.title-fallback': '链路瀑布',
     'trace.manage.drawer.action.logs': '查看日志',
@@ -7173,8 +7575,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'otlp.metrics.saved-view.rename-label': '已存视图名称',
     'otlp.metrics.saved-view.rename-save': '保存名称',
     'otlp.metrics.saved-view.rename-cancel': '取消重命名',
+    'otlp.metrics.saved-view.persistence.local': '保存在当前浏览器',
+    'otlp.metrics.saved-view.persistence.server': '服务器共享保存',
     'otlp.metrics.saved-view.current-label': '当前路由视图',
     'otlp.metrics.saved-view.empty': '暂无本地视图',
+    'otlp.metrics.dashboard-panel-draft.add-current': '添加到仪表盘',
+    'otlp.metrics.dashboard-panel-draft.update-current': '更新仪表盘面板',
+    'otlp.metrics.dashboard-panel-draft.return-dashboard': '返回仪表盘',
+    'otlp.metrics.dashboard-panel-draft.saving': '正在保存仪表盘草稿',
+    'otlp.metrics.dashboard-panel-draft.saved': '仪表盘草稿已保存',
+    'otlp.metrics.dashboard-panel-draft.failed': '仪表盘草稿暂不可用',
+    'otlp.metrics.dashboard-panel-draft.update-saving': '正在更新仪表盘面板',
+    'otlp.metrics.dashboard-panel-draft.update-saved': '仪表盘面板已更新',
+    'otlp.metrics.dashboard-panel-draft.update-failed': '仪表盘面板更新暂不可用',
     'otlp.metrics.saved-view.description.empty': '空指标工作台路由',
     'otlp.metrics.saved-view.field.query': '查询',
     'otlp.metrics.saved-view.field.filter': '过滤',
@@ -7738,7 +8151,7 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.rule.evidence.return': '返回排障上下文',
     'alert.rule.evidence.fallback-target': '排障上下文',
     'alert.rule.evidence.group.title': '来自{{signal}}的分组上下文',
-    'alert.rule.evidence.group.copy': 
'新建分组时会按当前实体、服务、命名空间和环境等稳定标签键收敛,链路明细只作为证据上下文保留。',
+    'alert.rule.evidence.group.copy': 
'新建分组时会按当前信号、服务、环境、来源和告警查询等稳定标签键收敛,链路明细只作为证据上下文保留。',
     'alert.rule.evidence.group.draft-name': '{{signal}} {{target}} 分组',
     'alert.rule.evidence.silence.title': '来自{{signal}}的静默上下文',
     'alert.rule.evidence.silence.copy': 
'新建静默时会按当前实体、服务、环境和链路标签做匹配,避免把无关告警一起静默。',
@@ -7757,6 +8170,8 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.group.delete.confirm.single': '将删除选中的分组策略,删除后不可恢复。',
     'alert.group.delete.confirm.batch': '将删除 {{count}} 条分组策略,删除后不可恢复。',
     'alert.group.evidence.labels': '分组标签',
+    'alert.group.preview.title': '推荐分组标签',
+    'alert.group.preview.copy': '使用这些稳定标签键对相关信号告警分组,同时避免把高基数 trace/span ID 
放进通知分组。',
     'alert.group.pagination.summary': '第 {{page}} / {{totalPages}} 页 · 
{{from}}-{{to}} / {{total}}',
     'alert.group.pagination.page-size': '每页条数',
     'alert.group.pagination.page': '页码',
@@ -8080,8 +8495,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'log.manage.saved-view.rename-label': '已存视图名称',
     'log.manage.saved-view.rename-save': '保存名称',
     'log.manage.saved-view.rename-cancel': '取消重命名',
+    'log.manage.saved-view.persistence.local': '保存在当前浏览器',
+    'log.manage.saved-view.persistence.server': '服务器共享保存',
     'log.manage.saved-view.current-label': '当前路由视图',
     'log.manage.saved-view.empty': '暂无本地视图',
+    'log.manage.dashboard-panel-draft.add-current': '添加到仪表盘',
+    'log.manage.dashboard-panel-draft.update-current': '更新仪表盘面板',
+    'log.manage.dashboard-panel-draft.return-dashboard': '返回仪表盘',
+    'log.manage.dashboard-panel-draft.saving': '正在保存仪表盘草稿',
+    'log.manage.dashboard-panel-draft.saved': '仪表盘草稿已保存',
+    'log.manage.dashboard-panel-draft.failed': '仪表盘草稿暂不可用',
+    'log.manage.dashboard-panel-draft.update-saving': '正在更新仪表盘面板',
+    'log.manage.dashboard-panel-draft.update-saved': '仪表盘面板已更新',
+    'log.manage.dashboard-panel-draft.update-failed': '仪表盘面板更新暂不可用',
     'log.manage.saved-view.description.empty': '空日志工作台路由',
     'log.manage.saved-view.field.view': '视图',
     'log.manage.saved-view.field.search': '检索',
@@ -8506,6 +8932,19 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.notice.receiver.people.placeholder': '选择接收对象',
     'alert.notice.receiver.type': '接收人类型',
     'alert.notice.receiver.type.placeholder': '选择通知方式',
+    'alert.notice.receiver.test-preview.title': '当前告警测试上下文',
+    'alert.notice.receiver.test-preview.copy': 
'测试消息用于验证当前接收对象配置。下面的标签是通知策略应匹配的告警上下文。',
+    'alert.notice.receiver.test-preview.payload.title': '告警样例载荷预览',
+    'alert.notice.receiver.test-preview.payload.copy': 
'此处仅用于预览。接收对象测试仍由后端验证当前接收对象配置。',
+    'alert.notice.receiver.test-preview.payload.status': '状态',
+    'alert.notice.receiver.test-preview.payload.status.firing': '触发样例',
+    'alert.notice.receiver.test-preview.payload.rule': '规则',
+    'alert.notice.receiver.test-preview.payload.signal': '信号',
+    'alert.notice.receiver.test-preview.payload.scope': '范围',
+    'alert.notice.receiver.test-preview.payload.query': '查询',
+    'alert.notice.receiver.test-preview.payload.severity': '级别',
+    'alert.notice.receiver.test-preview.payload.severity.sample': 'warning',
+    'alert.notice.receiver.test-preview.payload.message': '{{rule}} 正在 
{{signal}} 的 {{scope}} 范围内触发。',
     'alert.notice.rule.receivers.empty': '暂无接收对象,请先新增接收对象',
     'alert.notice.send-test': '发送告警测试',
     'alert.notice.send-test.notify.failed': '触发告警测试失败!',
@@ -8545,6 +8984,7 @@ export const SUPPLEMENTAL_MESSAGES: 
Partial<Record<LocaleCode, Messages>> = {
     'alert.notice.rule.priority.placeholder': '选择级别',
     'alert.notice.rule.tag': '标签匹配',
     'alert.notice.rule.tag.placeholder': '选择标签',
+    'alert.notice.rule.labels.prefill': '当前告警标签',
     'alert.notice.rule.label.value.placeholder': '标签值',
     'alert.notice.rule.time': '通知时段',
     'alert.notice.rule.time-end': '结束时间',


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to