Repository: meshery/meshery
Pull request #14345: Fix: Enhance Formatters
Author: login: FaheemOnHub
Labels: name: component/ui
description: User Interface
name: component/server
Created: 2025-04-09T09:38:20Z | Merged: 2025-04-22T12:52:53Z



- This PR fixes #14315 

**[Signed commits](https://github.com/meshery/meshery/blob/master/CONTRIBUTING.md#signing-off-on-commits-developer-certificate-of-origin)**
- [x] Yes, I signed my commits.

<!--
Thank you for contributing to Meshery! 

Contributing Conventions:

1. Include descriptive PR titles with [<component-name>] prepended.
2. Build and test your changes before submitting a PR. 
3. Sign your commits.
4. Include before and after screenshots/terminal output.

By following the community's contribution conventions upfront, the review process will 
be accelerated and your PR merged more quickly.
-->


Linked issue #14315: [UI] Improve Formatters and Resolve Notification Center Bugs
### Scope of Work
This issue focuses on enhancing the formatters' functionality, improving UI/UX consistency, and fixing bugs in the notification center. Below is the refined and detailed breakdown of tasks:
### Expected Behavior
1. Embedded Design Links:
Ensure the "View Design" link is embedded within the saved design name as design-name[link].

2. Error Formatter Improvements:
Place error code references inside an ellipse for better readability and compactness.
Remove redundant "Doc link" sections, as error code references will be included in the ellipse.

4. Button Placement:
Relocate "Download" and "View" buttons into the ellipse for a cleaner UI design.
<img width="326" alt="Image" src="https://github.com/user-attachments/assets/a3a394bb-8956-4062-9a08-f076d6fcb50d" />

5. Spacing Adjustments:
Fix spacing issues between concatenated words like LongDescription and SuggestedRemediation.

6.Documentation Links:
Add doc links to all formatters that explain specific keywords or functionalities (e.g., clarifying terms such as "registrant meshery imported 11 models, 1627 components, 2 relationships").

7.Connection Registration Enhancements:
Convert connection-name into a clickable chip that deep-links to its filtered view in the connection table (e.g., "Registration for Kubernetes context kubernetes-admin@kubernetes started").

8.Formatter Cleanup:
Remove unnecessary sections like "kind" from all formatters to streamline their appearance.

9.Event Count Fix:
Correct the number of events displayed inside the notification center chips to ensure accurate counts.

10.Checkbox Improvement:
Replace the single checkbox with a double checkbox labeled "Select All" for better functionality.

Additional Requirements
Ensure all formatters include documentation links for user guidance.

Maintain consistency across all UI elements, including chips, ellipses, and buttons.

Validate deep-link functionality for connection chips during implementation.


---

### Contributor [Guides](https://docs.meshery.io/project/contributing) and [Handbook](https://layer5.io/community/handbook)

- 🎨 Wireframes and [designs for Meshery UI](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9)
- 🖥 [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui)
- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://meshery.io/community#community-forums) and [Community Slack](https://slack.meshery.io)

Linked issue comments: user: login: github-actions[bot]
created_at: 2025-04-06T16:00:12Z
body: 

This issue has been labeled with 'component/ui'. 🧰 Here are docs on [Contributing to Meshery UI](https://docs.meshery.io/project/contributing/contributing-ui). 🎨 Here is the [Meshery UI Figma File](https://www.figma.com/file/SMP3zxOjZztdOLtgN4dS2W/Meshery-UI?node-id=4%3A0) File. Lastly, here are docs on [Contributing to Meshery's End-to-End Tests](https://docs.meshery.io/project/contributing/contributing-ui-tests).

---

 > &nbsp; &#9; &nbsp; &#9;  &nbsp; &#9;  &nbsp; &#9; Be sure to [join the community](https://slack.meshery.io), if you haven't yet and please leave a :star: [star on the project](../stargazers) :smile: 
author_association: CONTRIBUTOR

Diff:
diff --git a/server/handlers/connections_handlers.go b/server/handlers/connections_handlers.go
index 3bd3814759e5..f49aaf5469f1 100644
--- a/server/handlers/connections_handlers.go
+++ b/server/handlers/connections_handlers.go
@@ -383,7 +383,11 @@ func (h *Handler) UpdateConnectionStatus(w http.ResponseWriter, req *http.Reques
 			}
 
 			event := eventBuilder.WithSeverity(events.Informational).
-				WithDescription(fmt.Sprintf("Processing status update to \"%s\" for connection %s", status, k8scontext.Name)).Build()
+				WithDescription(fmt.Sprintf("Processing status update to \"%s\" for connection %s", status, k8scontext.Name)).
+				WithMetadata(map[string]interface{}{
+					"connectionName": k8scontext.Name,
+				}).
+				Build()
 			_ = provider.PersistEvent(event)
 			go h.config.EventBroadcaster.Publish(userID, event)
 
diff --git a/server/handlers/meshery_pattern_handler.go b/server/handlers/meshery_pattern_handler.go
index ff946378a312..0b82fd09e0c5 100644
--- a/server/handlers/meshery_pattern_handler.go
+++ b/server/handlers/meshery_pattern_handler.go
@@ -170,8 +170,16 @@ func (h *Handler) handlePatternPOST(
 	} else {
 		eventBuilder = eventBuilder.WithAction(models.Create)
 	}
-
-	event := eventBuilder.WithDescription(fmt.Sprintf("Saved design '%s'", requestPayload.DesignFile.Name)).Build()
+	metadata := map[string]interface{}{
+		"design": map[string]interface{}{
+            "name": requestPayload.DesignFile.Name,
+            "id":   requestPayload.DesignFile.Id.String(),
+        },
+		"doclink": "https://docs.meshery.io/concepts/logical/designs",
+	}
+	event := eventBuilder.
+        WithMetadata(metadata).
+        Build()
 	_ = provider.PersistEvent(event)
 
 	_, _ = rw.Write(savedDesignByt)
diff --git a/server/handlers/policy_relationship_handler.go b/server/handlers/policy_relationship_handler.go
index 8aae2840309a..743b56fdd714 100644
--- a/server/handlers/policy_relationship_handler.go
+++ b/server/handlers/policy_relationship_handler.go
@@ -393,6 +393,7 @@ func (h *Handler) EvaluateRelationshipPolicy(
 			WithMetadata(map[string]interface{}{
 				"trace":        evaluationResponse.Trace,
 				"evaluated_at": *evaluationResponse.Timestamp,
+				"modelName": evaluationResponse.Trace.ComponentsUpdated[0].Model.DisplayName,
 			}).WithSeverity(events.Informational).Build()
 		_ = provider.PersistEvent(event)
 
diff --git a/server/helpers/common_registry_logs.go b/server/helpers/common_registry_logs.go
index 0e7d916f9315..d52d106cc2a1 100644
--- a/server/helpers/common_registry_logs.go
+++ b/server/helpers/common_registry_logs.go
@@ -185,8 +185,7 @@ func FailedEventCompute(hostname string, mesheryInstanceID gofrs.UUID, provider
 		errorEventBuilder.WithSeverity(events.Error).WithDescription(failedMsg)
 		errorEvent := errorEventBuilder.Build()
 		errorEventBuilder.WithMetadata(map[string]interface{}{
-			"LongDescription":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
-			"SuggestedRemediation": fmt.Sprintf("Open Meshery Error Reference with error code %s", "https://docs.meshery.io/reference/error-codes"),
+			"Long_Description":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
 			"DownloadLink":         filePath,
 			"ViewLink":             filePath,
 		})
diff --git a/server/models/seed_models_logs.go b/server/models/seed_models_logs.go
index aeeef7106cb5..e79322e3045e 100644
--- a/server/models/seed_models_logs.go
+++ b/server/models/seed_models_logs.go
@@ -177,7 +177,7 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %d %s,", value, label)
 			}
 		}
 		appendIfNonZero(host.Summary.Models, "models")
@@ -185,9 +185,12 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		appendIfNonZero(host.Summary.Relationships, "relationships")
 		appendIfNonZero(host.Summary.Policies, "policies")
 
+		successMessage = strings.TrimSuffix(successMessage, ",") + "."
+
 		log.Info(successMessage)
 		eventBuilder.WithMetadata(map[string]interface{}{
 			"kind": host.Kind,
+			"doclink": "https://docs.meshery.io/concepts/logical#logical-concepts",
 		})
 		eventBuilder.WithSeverity(events.Informational).WithDescription(successMessage)
 		successEvent := eventBuilder.Build()
diff --git a/ui/components/DesignLifeCycle/common.js b/ui/components/DesignLifeCycle/common.js
index 398ee8843d07..495b500097e4 100644
--- a/ui/components/DesignLifeCycle/common.js
+++ b/ui/components/DesignLifeCycle/common.js
@@ -1,5 +1,5 @@
 import React from 'react';
-import { Box, Checkbox, CircularProgress, Stack, Typography } from '@layer5/sistent';
+import { Box, Checkbox, CircularProgress, Stack, styled, Typography } from '@layer5/sistent';
 import PatternIcon from '@/assets/icons/Pattern';
 import { processDesign } from '@/utils/utils';
 import { CustomTooltip } from '@layer5/sistent';
@@ -11,10 +11,19 @@ export const DEPLOYMENT_TYPE = {
   UNDEPLOY: 'undeploy',
 };
 
-export const ComponentIcon = ({ iconSrc }) => {
+const ModelName = styled(Typography)(() => ({
+  fontSize: '10px',
+  fontWeight: 'bold',
+  textTransform: 'uppercase',
+}));
+export const ComponentIcon = ({ iconSrc, label }) => {
+  const [imgError, setImgError] = React.useState(false);
   if (!iconSrc) {
     return <PatternIcon fill="#fff" height="1.5rem" width="1.5rem" />;
   }
+  if (imgError) {
+    return <ModelName title={label}>{label}</ModelName>;
+  }
 
   return (
     <div style={{ height: '1.5rem', width: '1.5rem' }}>
@@ -25,6 +34,7 @@ export const ComponentIcon = ({ iconSrc }) => {
           width: '100%',
           objectFit: 'contain',
         }}
+        onError={() => setImgError(true)}
       />
     </div>
   );
diff --git a/ui/components/NotificationCenter/constants.js b/ui/components/NotificationCenter/constants.js
index 9c9851f910ff..d53b7be2d83c 100644
--- a/ui/components/NotificationCenter/constants.js
+++ b/ui/components/NotificationCenter/constants.js
@@ -74,4 +74,8 @@ export const EVENT_TYPE = {
     category: 'relationship',
     action: 'evaluation',
   },
+  REGISTRANT_SUMMARY: {
+    category: 'entity',
+    action: 'get_summary',
+  },
 };
diff --git a/ui/components/NotificationCenter/formatters/RegistrantSummaryFormatter.js b/ui/components/NotificationCenter/formatters/RegistrantSummaryFormatter.js
new file mode 100644
index 000000000000..a86d1ab3d09a
--- /dev/null
+++ b/ui/components/NotificationCenter/formatters/RegistrantSummaryFormatter.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import { TitleLink } from './common';
+import { Box, Typography } from '@layer5/sistent';
+
+export const RegistrantSummaryFormatter = ({ event }) => {
+  const docLink = 'https://docs.meshery.io/concepts/logical#logical-concepts';
+
+  return (
+    <Box>
+      <Typography>{event.description}</Typography>
+      <TitleLink href={docLink} target="_blank" rel="noopener noreferrer">
+        Understanding Models, Components, and Relationships
+      </TitleLink>
+    </Box>
+  );
+};
diff --git a/ui/components/NotificationCenter/formatters/relationship_evaluation.js b/ui/components/NotificationCenter/formatters/relationship_evaluation.js
index fffa93649ce7..0e49235b3fd3 100644
--- a/ui/components/NotificationCenter/formatters/relationship_evaluation.js
+++ b/ui/components/NotificationCenter/formatters/relationship_evaluation.js
@@ -1,5 +1,5 @@
 import React, { memo, useState } from 'react';
-import { Box, Typography, styled, Chip, CustomTooltip, Collapse } from '@layer5/sistent';
+import { Box, Typography, styled, CustomTooltip, Collapse } from '@layer5/sistent';
 import { ComponentIcon } from '@/components/DesignLifeCycle/common';
 import { InfoIcon } from '@layer5/sistent'; // Assuming MUI icons are available
 import ExpandLessIcon from '@/assets/icons/ExpandLessIcon';
@@ -42,11 +42,6 @@ const ItemRow = styled(Box)(({ theme }) => ({
   },
 }));
 
-const ModelBadge = styled(Chip)(() => ({
-  fontSize: '12px',
-  height: '24px',
-}));
-
 const EmptyState = styled(Box)(({ theme }) => ({
   display: 'flex',
   justifyContent: 'center',
@@ -107,7 +102,10 @@ const ComponentItem = ({ component }) => (
           title={`Model: ${component.model.name}  Version: ${component?.model?.version}`}
         >
           <div>
-            <ModelBadge size="small" label={component.model.name} variant="outlined" />
+            <ComponentIcon
+              iconSrc={`/static/img/${component.model.name}.svg`}
+              label={component.model.name}
+            />
           </div>
         </CustomTooltip>
       </Box>
@@ -116,38 +114,43 @@ const ComponentItem = ({ component }) => (
 );
 
 // Relationship Trace Item
-const RelationshipItem = ({ relationship }) => (
-  <>
-    {relationship.selectors.map((selector, index) => (
-      <ItemRow key={index}>
-        <Box
-          flex={1}
-          display={'flex'}
-          justifyItems={'space-between'}
-          justifyContent={'space-between'}
-          width={'100%'}
-          alignItems={'center'}
-        >
-          <Typography variant="body2">
-            <span style={{ fontWeight: 500 }}>
-              {relationship.kind}-{relationship.subType}-{relationship.type}
-            </span>{' '}
-            relationship from <strong>{selector?.allow?.from?.[0]?.kind || 'Unknown'}</strong> to{' '}
-            <strong>{selector?.allow?.to?.[0]?.kind || 'Unknown'}</strong>
-          </Typography>
-
-          <CustomTooltip
-            title={`Model: ${relationship.model.name} Version: ${relationship?.model?.version}`}
+const RelationshipItem = ({ relationship }) => {
+  return (
+    <>
+      {relationship.selectors.map((selector, index) => (
+        <ItemRow key={index}>
+          <Box
+            flex={1}
+            display={'flex'}
+            justifyItems={'space-between'}
+            justifyContent={'space-between'}
+            width={'100%'}
+            alignItems={'center'}
           >
-            <div>
-              <ModelBadge size="small" label={relationship.model.name} variant="outlined" />
-            </div>
-          </CustomTooltip>
-        </Box>
-      </ItemRow>
-    ))}
-  </>
-);
+            <Typography variant="body2">
+              <span style={{ fontWeight: 500 }}>
+                {relationship.kind}-{relationship.subType}-{relationship.type}
+              </span>{' '}
+              relationship from <strong>{selector?.allow?.from?.[0]?.kind || 'Unknown'}</strong> to{' '}
+              <strong>{selector?.allow?.to?.[0]?.kind || 'Unknown'}</strong>
+            </Typography>
+
+            <CustomTooltip
+              title={`Model: ${relationship.model.name} Version: ${relationship?.model?.version}`}
+            >
+              <div>
+                <ComponentIcon
+                  iconSrc={`/static/img/${relationship.model.name}.svg`}
+                  label={relationship.model.name}
+                />
+              </div>
+            </CustomTooltip>
+          </Box>
+        </ItemRow>
+      ))}
+    </>
+  );
+};
 
 // Component Trace List
 export const ComponentsTrace = ({ components, title }) => (
@@ -208,12 +211,12 @@ export const RelationshipEvaluationTraceFormatter = memo(function RelationshipTr
           <RelationshipsTrace
             title="Relationships Added"
             type="added"
-            relationships={trace.relationshipsAdded | []}
+            relationships={trace.relationshipsAdded || []}
           />
           <RelationshipsTrace
             title="Relationships Updated"
             type="updated"
-            relationships={trace.relationshipsUpdated | []}
+            relationships={trace.relationshipsUpdated || []}
           />
           <RelationshipsTrace
             title="Relationships Removed"
diff --git a/ui/components/NotificationCenter/index.js b/ui/components/NotificationCenter/index.js
index a23005143d18..ab4d94e11df9 100644
--- a/ui/components/NotificationCenter/index.js
+++ b/ui/components/NotificationCenter/index.js
@@ -129,7 +129,6 @@ const NavbarNotificationIcon = () => {
   const { data, error, isLoading } = useGetEventsSummaryQuery({
     status: STATUS.UNREAD,
   });
-
   if (error || (!data && !isLoading)) {
     console.log(
       '[NavbarNotificationIcon] Error fetching notification summary for NotificationIconCount',
@@ -337,8 +336,11 @@ const BulkActions = () => {
         padding: '0.15rem',
       }}
     >
-      <Box>
+      <Box sx={{ display: 'flex', alignItems: 'center' }}>
         <Checkbox checked={areAllEventsChecked} color="primary" onChange={handleCheckboxChange} />
+        <Typography variant="body2">
+          {areAllEventsChecked ? `Selected ${checkedEvents.length} notifications` : 'Select All'}
+        </Typography>
       </Box>
       <Collapse in={checkedEvents.length > 0}>
         <Box sx={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
@@ -399,11 +401,13 @@ const EventsView = ({ handleLoadNextPage, isFetching, hasMore }) => {
 
   return (
     <>
-      {events.map((event, idx) => (
-        <div key={event.id + idx}>
-          <Notification eventData={event} event_id={event.id} />
-        </div>
-      ))}
+      {events.map((event, idx) => {
+        return (
+          <div key={event.id + idx}>
+            <Notification eventData={event} event_id={event.id} />
+          </div>
+        );
+      })}
 
       {events.length === 0 && <EmptyState />}
 
diff --git a/ui/components/NotificationCenter/metadata.js b/ui/components/NotificationCenter/metadata.js
index 3a872dd01104..a0acb67d4ed8 100644
--- a/ui/components/NotificationCenter/metadata.js
+++ b/ui/components/NotificationCenter/metadata.js
@@ -9,8 +9,9 @@ import { ErrorMetadataFormatter } from './formatters/error';
 import { DryRunResponse } from './formatters/pattern_dryrun';
 import { ModelImportMessages, ModelImportedSection } from './formatters/model_registration';
 import { RelationshipEvaluationEventFormatter } from './formatters/relationship_evaluation';
-import { useTheme } from '@layer5/sistent';
+import { useTheme, DownloadIcon, InfoIcon } from '@layer5/sistent';
 import _ from 'lodash';
+import { ChipWrapper } from '../connections/styles';
 
 export const PropertyFormatters = {
   //trace can be very large, so we need to convert it to a file
@@ -24,42 +25,74 @@ export const PropertyFormatters = {
       />
     );
   },
+  design: (value) => {
+    const theme = useTheme();
+    const { name, id } = value;
+
+    return (
+      <TitleLink
+        href={'/extension/meshmap?mode=design&design=' + encodeURIComponent(id)}
+        style={{
+          color: theme.palette.text.default,
+          fontWeight: 'normal',
+          textDecoration: 'none',
+        }}
+        target="_self"
+      >
+        Saved design {name}
+      </TitleLink>
+    );
+  },
+  connectionName: (value) => {
+    return (
+      <ChipWrapper
+        label={value}
+        clickable
+        component="a"
+        href={`/management/connections?tab=connections&searchText=${value}`}
+        target="_self"
+      />
+    );
+  },
   error: (value) => <ErrorMetadataFormatter metadata={value} event={event} />,
   dryRunResponse: (value) => <DryRunResponse response={value} />,
   ModelImportMessage: (value) => value && <ModelImportMessages message={value} />,
   ModelDetails: (value) => value && <ModelImportedSection modelDetails={value} />,
 };
 
-const PropertyLinkFormatters = {
-  doc: (value) => (
-    <TitleLink href={value} style={{ textAlign: 'end', color: 'inherit' }}>
-      Doc
-    </TitleLink>
-  ),
-  DownloadLink: (value) => (
-    <TitleLink
-      href={'/api/system/fileDownload?file=' + encodeURIComponent(value)}
-      style={{ textAlign: 'end', color: 'inherit' }}
-    >
-      Download File
-    </TitleLink>
-  ),
-  ViewLink: (value) => (
-    <TitleLink
-      href={'/api/system/fileView?file=' + encodeURIComponent(value)}
-      style={{ textAlign: 'end', color: 'inherit' }}
-    >
-      View File
-    </TitleLink>
-  ),
+export const LinkFormatters = {
+  doclink: (value) => {
+    return (
+      <TitleLink href={value} style={{ textAlign: 'end', color: 'inherit' }}>
+        Doc
+      </TitleLink>
+    );
+  },
+};
+export const PropertyLinkFormatters = {
+  doc: (value) => ({
+    label: 'Doc',
+    href: value,
+  }),
+  DownloadLink: (value) => ({
+    label: 'Download File',
+    href: '/api/system/fileDownload?file=' + encodeURIComponent(value),
+    icon: DownloadIcon,
+  }),
+  ViewLink: (value) => ({
+    label: 'Get Logs',
+    href: '/api/system/fileView?file=' + encodeURIComponent(value),
+    icon: InfoIcon,
+  }),
 };
 
-const linkOrder = ['doc', 'DownloadLink', 'ViewLink'];
+const linkOrder = ['doclink'];
 
 const EventTypeFormatters = {
   [eventDetailFormatterKey(EVENT_TYPE.DEPLOY_DESIGN)]: DeploymentSummaryFormatter,
   [eventDetailFormatterKey(EVENT_TYPE.UNDEPLOY_DESIGN)]: DeploymentSummaryFormatter,
   [eventDetailFormatterKey(EVENT_TYPE.EVALUATE_DESIGN)]: RelationshipEvaluationEventFormatter,
+  // [eventDetailFormatterKey(EVENT_TYPE.REGISTRANT_SUMMARY)]: RegistrantSummaryFormatter,
 };
 
 export const FormattedMetadata = ({ event }) => {
@@ -74,15 +107,16 @@ export const FormattedMetadata = ({ event }) => {
   }
 
   const metadata = {
-    ..._.omit(event.metadata, linkOrder),
+    ..._.omit(event.metadata, [...linkOrder, 'kind', 'ViewLink', 'DownloadLink']),
     ShortDescription:
       event.metadata.error || !canTruncateDescription(event.description || '')
         ? null
         : event.description,
   };
-
   const order = [
+    'doclink',
     'ShortDescription',
+    'connectionName',
     'LongDescription',
     'Summary',
     'SuggestedRemediation',
@@ -103,13 +137,12 @@ export const FormattedMetadata = ({ event }) => {
         fontWeight: 'normal',
         color: theme.palette.text.default,
       }}
+      event={event}
     />
   );
 };
 
 export const FormattedLinkMetadata = ({ event }) => {
   const filteredMetadata = _.pick(event.metadata, linkOrder);
-  return (
-    <FormatStructuredData propertyFormatters={PropertyLinkFormatters} data={filteredMetadata} />
-  );
+  return <FormatStructuredData propertyFormatters={LinkFormatters} data={filteredMetadata} />;
 };
diff --git a/ui/components/NotificationCenter/notification.js b/ui/components/NotificationCenter/notification.js
index ebd7b210876b..b0df1098d953 100644
--- a/ui/components/NotificationCenter/notification.js
+++ b/ui/components/NotificationCenter/notification.js
@@ -36,6 +36,7 @@ import LinkedInIcon from '../../assets/icons/LinkedInIcon';
 import TwitterIcon from '../../assets/icons/TwitterIcon';
 import ShareIcon from '../../assets/icons/ShareIcon';
 import DeleteIcon from '../../assets/icons/DeleteIcon';
+import ErrorIcon from '@/assets/icons/ErrorIcon';
 import {
   useUpdateStatusMutation,
   useDeleteEventMutation,
@@ -50,8 +51,9 @@ import { useGetUserByIdQuery } from '../../rtk-query/user';
 import { FacebookShareButton, LinkedinShareButton, TwitterShareButton } from 'react-share';
 import ReadIcon from '../../assets/icons/ReadIcon';
 import UnreadIcon from '../../assets/icons/UnreadIcon';
-import { FormattedLinkMetadata, FormattedMetadata } from './metadata';
+import { FormattedLinkMetadata, FormattedMetadata, PropertyLinkFormatters } from './metadata';
 import { truncate } from 'lodash';
+import { MESHERY_DOCS_URL } from '@/constants/endpoints';
 
 export const eventPreventDefault = (e) => {
   e.preventDefault();
@@ -109,6 +111,10 @@ const BasicMenu = ({ event }) => {
     setIsSocialShareOpen((prev) => !prev);
   };
   const theme = useTheme();
+  const links = Object.entries(event.metadata || {})
+    .map(([key, value]) => PropertyLinkFormatters[key]?.(value))
+    .filter(Boolean);
+  const errorCodes = getErrorCodesFromEvent(event);
   return (
     <div className="mui-fixed" onClick={(e) => e.stopPropagation()}>
       <IconButton
@@ -153,7 +159,45 @@ const BasicMenu = ({ event }) => {
               </SocialListItem>
             </Collapse>
           </OptionList>
-
+          {errorCodes?.length > 0 && (
+            <OptionList>
+              <ListButton
+                component="a"
+                href={`${MESHERY_DOCS_URL}/reference/error-codes#${errorCodes[0]}`}
+                target="_blank"
+                rel="noopener noreferrer"
+                onClick={(e) => e.stopPropagation()}
+              >
+                <ErrorIcon {...iconMedium} fill={theme.palette.icon.secondary} />
+                <Typography variant="body1" sx={{ marginLeft: '0.5rem' }}>
+                  Error Docs
+                </Typography>
+              </ListButton>
+            </OptionList>
+          )}
+          <OptionList>
+            {links.map((link, index) => {
+              const IconComponent = link.icon;
+              return (
+                <OptionListItem key={index} sx={{ width: '100%' }}>
+                  <ListButton
+                    component="a"
+                    href={link.href}
+                    target="_blank"
+                    rel="noopener noreferrer"
+                    onClick={(e) => e.stopPropagation()}
+                  >
+                    {IconComponent && (
+                      <IconComponent {...iconMedium} fill={theme.palette.icon.secondary} />
+                    )}
+                    <Typography variant="body1" sx={{ marginLeft: '0.5rem' }}>
+                      {link.label}
+                    </Typography>
+                  </ListButton>
+                </OptionListItem>
+              );
+            })}
+          </OptionList>
           <DeleteEvent event={event} />
           <ChangeStatus event={event} />
         </MenuPaper>
diff --git a/ui/components/connections/ConnectionTable.js b/ui/components/connections/ConnectionTable.js
index 350a73cbbdaf..86098f9d29bc 100644
--- a/ui/components/connections/ConnectionTable.js
+++ b/ui/components/connections/ConnectionTable.js
@@ -1,4 +1,5 @@
 import React, { useEffect, useRef, useState } from 'react';
+import { useRouter } from 'next/router';
 import {
   CustomTooltip,
   CustomColumnVisibilityControl,
@@ -98,6 +99,7 @@ const ConnectionTable = ({
   selectedConnectionId,
   updateUrlWithConnectionId,
 }) => {
+  const router = useRouter();
   const organization = useLegacySelector((state) => state.get('organization'));
   const ping = useKubernetesHook();
   const { width } = useWindowDimensions();
@@ -122,6 +124,11 @@ const ConnectionTable = ({
   const open = Boolean(anchorEl);
   const modalRef = useRef(null);
 
+  useEffect(() => {
+    if (router.query.searchText) {
+      setSearch(router.query.searchText);
+    }
+  }, [router.query.searchText]);
   const filters = {
     status: {
       name: 'Status',


Reviews:
user: login: gemini-code-assist[bot]
body: Hello @FaheemOnHub, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

## Summary of Changes
This pull request focuses on enhancing the formatters in the notification center and improving event logging throughout the Meshery server. It addresses issue #14315. The changes include adding metadata to events for better context, improving the display of registrant summaries in the UI, and adding links to relevant documentation within notifications. It also includes a fix to allow the connection table to be filtered based on a search parameter.

### Highlights
* **Event Metadata Enhancement**: Metadata is added to connection status update events and Meshery design save events, providing more context for these events in the notification center.
* **Registrant Summary Formatting**: A new formatter, `RegistrantSummaryFormatter`, is introduced to display registrant summaries in the notification center, including a link to relevant documentation.
* **Dependency Update**: The `go.mod` file is updated to include the `dustin/go-humanize` package, which is used to format large numbers with commas for better readability.
* **Connection Table Search**: The connection table now supports filtering based on a search parameter passed in the URL.

### Changelog
<details>
<summary>Click here to see the changelog</summary>

* **go.mod**
  * Added `github.com/dustin/go-humanize` dependency for number formatting.
* **server/handlers/connections_handlers.go**
  * Added metadata to the event published when a connection status is updated.
* **server/handlers/meshery_pattern_handler.go**
  * Added metadata to the event published when a Meshery design is saved.
* **server/helpers/common_registry_logs.go**
  * Renamed `LongDescription` to `Long_Description` in the metadata for failed registry events.
* **server/models/seed_models_logs.go**
  * Imported `github.com/dustin/go-humanize` for formatting numbers.
  * Formatted the numbers of models, components, relationships, and policies in the registry log messages using `humanize.Comma`.
* **ui/components/NotificationCenter/constants.js**
  * Added a new event type `REGISTRANT_SUMMARY` for registrant summary events.
* **ui/components/NotificationCenter/formatters/RegistrantSummaryFormatter.js**
  * Created a new formatter component to display registrant summary events with a link to documentation.
* **ui/components/NotificationCenter/formatters/common.js**
  * Removed the underline from the `TitleLink` component.
* **ui/components/NotificationCenter/index.js**
  * Added a console log for debugging purposes.
  * Added a label to the bulk actions checkbox to indicate the number of selected notifications.
  * Added a console log for debugging purposes in the `EventsView` component.
* **ui/components/NotificationCenter/metadata.js**
  * Added `Chip` import from `@mui/material`.
  * Added `RegistrantSummaryFormatter` import.
  * Added a formatter for `designId` to create a link to the saved design in MeshMap.
  * Added a formatter for `connectionName` to create a clickable chip that navigates to the connections page with the connection name as a search parameter.
  * Modified `PropertyLinkFormatters` to return objects with `label` and `href` properties.
  * Added `REGISTRANT_SUMMARY` to `EventTypeFormatters`.
  * Removed `kind` and `ViewLink` from the metadata that is omitted.
  * Added `connectionName` to the order of metadata properties.
  * Added `event` to the `FormattedMetadata` component.
  * Added console logs for debugging purposes.
* **ui/components/NotificationCenter/notification.js**
  * Added `ErrorIcon` import.
  * Added `PropertyLinkFormatters` import.
  * Added logic to display links from metadata in the notification menu.
  * Added logic to display a link to the error code documentation if the event has error codes.
* **ui/components/connections/ConnectionTable.js**
  * Added `useRouter` import.
  * Added logic to set the search term based on the `searchText` query parameter in the URL.

</details>


<details>

<summary><b>Using Gemini Code Assist</b></summary>
<br>

The full guide for Gemini Code Assist can be found on our [documentation page](https://developers.google.com/gemini-code-assist/docs/review-github-code), here are some quick tips.

<b>Invoking Gemini</b>

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either `/gemini <command>` or `@gemini-code-assist <command>`. Below is a summary of the supported commands.

Feature | Command | Description
--- | --- | ---
Code Review | `/gemini review` | Performs a code review for the current pull request in its current state.
Pull Request Summary | `/gemini summary` | Provides a summary of the current pull request in its current state.
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments.
Help | `/gemini help` | Displays a list of available commands.

<b>Customization</b>

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a `.gemini/` folder in the base of the repository. Detailed instructions can be found [here](https://developers.google.com/gemini-code-assist/docs/customize-gemini-behavior-github).

<b>Limitations & Feedback</b>

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments to provide feedback.

</details>

<b>You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the [Gemini Code Assist IDE Extension](https://cloud.google.com/products/gemini/code-assist).</b>


[^1]: Review the [Privacy Notices](https://policies.google.com/privacy), [Generative AI Prohibited Use Policy](https://policies.google.com/terms/generative-ai/use-policy), [Terms of Service](https://policies.google.com/terms), and learn how to configure Gemini Code Assist in GitHub [here](https://developers.google.com/gemini-code-assist/docs/review-github-code). Gemini can make mistakes, so double check it and [use code with caution](https://support.google.com/legal/answer/13505487).

---

> A log message appears,
> With metadata so clear,
> Events now defined,
> Context intertwined,
> A notification's cheer.


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T09:38:33Z
user: login: gemini-code-assist[bot]
body: ## Code Review
The pull request enhances the formatters and adds metadata to events, improving the overall user experience and providing more context for debugging. The changes are well-structured and easy to follow.

### Summary of Findings
* **Event Metadata**: The changes introduce metadata to events, which is a good practice for providing additional context. However, ensure that all relevant events are updated with appropriate metadata to maintain consistency.
* **Human-Readable Numbers**: The use of `humanize.Comma` enhances the readability of large numbers in log messages. This is a good addition for improving the user experience.
* **Console Logs**: The code includes `console.log` statements, which should be removed before merging to avoid unnecessary logging in production.
* **Link Formatting**: The formatting of links in the notification center has been updated. Ensure that the new formatting is consistent and user-friendly.

### Merge Readiness
The code changes are generally well-done, but there are a few suggestions for improvement. I would recommend addressing these before merging. I am unable to directly approve this pull request, and recommend that others review and approve this code before merging.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T09:39:01Z
user: login: amitamrutiya
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T16:24:25Z
user: login: FaheemOnHub
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T21:59:55Z
user: login: FaheemOnHub
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T22:01:38Z
user: login: FaheemOnHub
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T22:03:06Z
user: login: miacycle
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-15T22:37:56Z
user: login: amitamrutiya
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:17:30Z
user: login: FaheemOnHub
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-20T12:16:58Z
user: login: FaheemOnHub
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-20T12:45:02Z
user: login: amitamrutiya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T07:51:19Z
user: login: amitamrutiya
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-21T07:51:36Z

Review comments:
diff_hunk: @@ -21,6 +20,7 @@ require (
 	github.com/docker/cli v27.5.1+incompatible
 	github.com/docker/docker v27.5.1+incompatible
 	github.com/docker/go-connections v0.5.0
+	github.com/dustin/go-humanize v1.0.1
path: go.mod
user: login: amitamrutiya
body: why this change?
created_at: 2025-04-09T16:17:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -170,8 +170,12 @@ func (h *Handler) handlePatternPOST(
 	} else {
 		eventBuilder = eventBuilder.WithAction(models.Create)
 	}
-
-	event := eventBuilder.WithDescription(fmt.Sprintf("Saved design '%s'", requestPayload.DesignFile.Name)).Build()
+	metadata := map[string]interface{}{
+		"designId": fmt.Sprintf("%s+%s", requestPayload.DesignFile.Name, requestPayload.DesignFile.Id),
+	}
path: server/handlers/meshery_pattern_handler.go
user: login: amitamrutiya
body: pass this separately like designId and designName don't add in one string.
created_at: 2025-04-09T16:18:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -185,8 +185,7 @@ func FailedEventCompute(hostname string, mesheryInstanceID gofrs.UUID, provider
 		errorEventBuilder.WithSeverity(events.Error).WithDescription(failedMsg)
 		errorEvent := errorEventBuilder.Build()
 		errorEventBuilder.WithMetadata(map[string]interface{}{
-			"LongDescription":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
-			"SuggestedRemediation": fmt.Sprintf("Open Meshery Error Reference with error code %s", "https://docs.meshery.io/reference/error-codes"),
+			"Long_Description":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
path: server/helpers/common_registry_logs.go
user: login: amitamrutiya
body: why this changes LongDescription -> Long_Description
created_at: 2025-04-09T16:19:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -177,14 +178,16 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %s %s,", humanize.Comma(value), label)
path: server/models/seed_models_logs.go
user: login: amitamrutiya
body: why you add this package. try to use existing functionality.
created_at: 2025-04-09T16:20:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -177,14 +178,16 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %s %s,", humanize.Comma(value), label)
 			}
 		}
 		appendIfNonZero(host.Summary.Models, "models")
 		appendIfNonZero(host.Summary.Components, "components")
 		appendIfNonZero(host.Summary.Relationships, "relationships")
 		appendIfNonZero(host.Summary.Policies, "policies")
 
+		successMessage = strings.TrimSuffix(successMessage, ",") + "."
path: server/models/seed_models_logs.go
user: login: amitamrutiya
body: What is usecase of this one.
created_at: 2025-04-09T16:21:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,7 +15,7 @@ export const TitleLink = ({ href, children, ...props }) => {
       <Typography
         variant="h5"
         style={{
-          textDecorationLine: 'underline',
+          // textDecorationLine: 'underline',
path: ui/components/NotificationCenter/formatters/common.js
user: login: amitamrutiya
body: remove this comment
created_at: 2025-04-09T16:21:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -132,7 +132,7 @@ const NavbarNotificationIcon = () => {
   const { data, error, isLoading } = useGetEventsSummaryQuery({
     status: STATUS.UNREAD,
   });
-
+  console.log('here', data);
path: ui/components/NotificationCenter/index.js
user: login: amitamrutiya
body: ```suggestion
  console.log('here', data);
```
created_at: 2025-04-09T16:21:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -402,11 +405,14 @@ const EventsView = ({ handleLoadNextPage, isFetching, hasMore }) => {
 
   return (
     <>
-      {events.map((event, idx) => (
-        <div key={event.id + idx}>
-          <Notification eventData={event} event_id={event.id} />
-        </div>
-      ))}
+      {events.map((event, idx) => {
+        console.log('Notification Event:', { event, idx });
path: ui/components/NotificationCenter/index.js
user: login: amitamrutiya
body: ```suggestion
        console.log('Notification Event:', { event, idx });
```
created_at: 2025-04-09T16:22:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,42 +26,74 @@ export const PropertyFormatters = {
       />
     );
   },
+  designId: (value) => {
+    const theme = useTheme();
+    // console.log('Here is the value', value);
path: ui/components/NotificationCenter/metadata.js
user: login: amitamrutiya
body: ```suggestion
    // console.log('Here is the value', value);
```
created_at: 2025-04-09T16:22:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -74,15 +108,16 @@ export const FormattedMetadata = ({ event }) => {
   }
 
   const metadata = {
-    ..._.omit(event.metadata, linkOrder),
+    ..._.omit(event.metadata, [...linkOrder, 'kind', 'ViewLink']),
     ShortDescription:
       event.metadata.error || !canTruncateDescription(event.description || '')
         ? null
         : event.description,
   };
-
+  console.log(metadata);
path: ui/components/NotificationCenter/metadata.js
user: login: amitamrutiya
body: ```suggestion
  console.log(metadata);
```
created_at: 2025-04-09T16:22:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -94,6 +129,7 @@ export const FormattedMetadata = ({ event }) => {
   const orderedMetadata = hasImportedModelName
     ? reorderObjectProperties({ ...metadata, ShortDescription: null }, order) // Exclude ShortDescription
     : reorderObjectProperties(metadata, order);
+  console.log(orderedMetadata);
path: ui/components/NotificationCenter/metadata.js
user: login: amitamrutiya
body: ```suggestion
  console.log(orderedMetadata);
```
created_at: 2025-04-09T16:22:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -153,7 +158,39 @@ const BasicMenu = ({ event }) => {
               </SocialListItem>
             </Collapse>
           </OptionList>
-
+          {errorCodes?.length > 0 && (
+            <OptionList>
+              <ListButton
+                component="a"
+                href={`https://docs.meshery.io/reference/error-codes#${errorCodes[0]}`}
path: ui/components/NotificationCenter/notification.js
user: login: amitamrutiya
body: uses docs url from endpoints.js file
created_at: 2025-04-09T16:24:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -185,8 +185,7 @@ func FailedEventCompute(hostname string, mesheryInstanceID gofrs.UUID, provider
 		errorEventBuilder.WithSeverity(events.Error).WithDescription(failedMsg)
 		errorEvent := errorEventBuilder.Build()
 		errorEventBuilder.WithMetadata(map[string]interface{}{
-			"LongDescription":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
-			"SuggestedRemediation": fmt.Sprintf("Open Meshery Error Reference with error code %s", "https://docs.meshery.io/reference/error-codes"),
+			"Long_Description":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
path: server/helpers/common_registry_logs.go
user: login: FaheemOnHub
body: as we need space between Title , so on frontent there was already code which demands this :
<img width="428" alt="Screenshot 2025-04-16 at 3 22 32 AM" src="https://github.com/user-attachments/assets/8f68072d-cb86-424f-b867-570fa90cb524" />

Long_Description - > Long Description
created_at: 2025-04-15T21:59:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -177,14 +178,16 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %s %s,", humanize.Comma(value), label)
path: server/models/seed_models_logs.go
user: login: FaheemOnHub
body: humanize function will formats large numbers with commas for better readability.
ex:
1000 becomes "1,000".
1000000 becomes "1,000,000".
created_at: 2025-04-15T22:01:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -177,14 +178,16 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %s %s,", humanize.Comma(value), label)
 			}
 		}
 		appendIfNonZero(host.Summary.Models, "models")
 		appendIfNonZero(host.Summary.Components, "components")
 		appendIfNonZero(host.Summary.Relationships, "relationships")
 		appendIfNonZero(host.Summary.Policies, "policies")
 
+		successMessage = strings.TrimSuffix(successMessage, ",") + "."
path: server/models/seed_models_logs.go
user: login: FaheemOnHub
body: removes the last trailing comma
"For registrant X imported 1,000 models, 500 components."
created_at: 2025-04-15T22:03:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -170,8 +170,13 @@ func (h *Handler) handlePatternPOST(
 	} else {
 		eventBuilder = eventBuilder.WithAction(models.Create)
 	}
-
-	event := eventBuilder.WithDescription(fmt.Sprintf("Saved design '%s'", requestPayload.DesignFile.Name)).Build()
+	metadata := map[string]interface{}{
+		"designId": fmt.Sprintf("%s+%s", requestPayload.DesignFile.Name, requestPayload.DesignFile.Id),
+		"doclink": "https://docs.meshery.io/concepts/logical/designs",
path: server/handlers/meshery_pattern_handler.go
user: login: miacycle
body: Links to docs! yay! 🎈 
created_at: 2025-04-15T22:37:47Z
author_association: MEMBER
diff_hunk: @@ -21,6 +20,7 @@ require (
 	github.com/docker/cli v27.5.1+incompatible
 	github.com/docker/docker v27.5.1+incompatible
 	github.com/docker/go-connections v0.5.0
+	github.com/dustin/go-humanize v1.0.1
path: go.mod
user: login: amitamrutiya
body: why this is still used? please don't resolve if you haven't fixed. it
created_at: 2025-04-16T06:12:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -185,8 +185,7 @@ func FailedEventCompute(hostname string, mesheryInstanceID gofrs.UUID, provider
 		errorEventBuilder.WithSeverity(events.Error).WithDescription(failedMsg)
 		errorEvent := errorEventBuilder.Build()
 		errorEventBuilder.WithMetadata(map[string]interface{}{
-			"LongDescription":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
-			"SuggestedRemediation": fmt.Sprintf("Open Meshery Error Reference with error code %s", "https://docs.meshery.io/reference/error-codes"),
+			"Long_Description":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
path: server/helpers/common_registry_logs.go
user: login: amitamrutiya
body: you can still separate LongDescription from Long Description. I guess we already have some functions defined for that.
created_at: 2025-04-16T06:14:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -170,8 +170,13 @@ func (h *Handler) handlePatternPOST(
 	} else {
 		eventBuilder = eventBuilder.WithAction(models.Create)
 	}
-
-	event := eventBuilder.WithDescription(fmt.Sprintf("Saved design '%s'", requestPayload.DesignFile.Name)).Build()
+	metadata := map[string]interface{}{
+		"designId": fmt.Sprintf("%s+%s", requestPayload.DesignFile.Name, requestPayload.DesignFile.Id),
+		"doclink": "https://docs.meshery.io/concepts/logical/designs",
path: server/handlers/meshery_pattern_handler.go
user: login: amitamrutiya
body: pass separately design id and design name. don't merge it into designId.
created_at: 2025-04-16T06:14:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -177,14 +178,16 @@ func RegistryLog(log logger.Handler, handlerConfig *HandlerConfig, regManager *m
 		successMessage := fmt.Sprintf("For registrant %s imported", host.Kind)
 		appendIfNonZero := func(value int64, label string) {
 			if value != 0 {
-				successMessage += fmt.Sprintf(" %d %s", value, label)
+				successMessage += fmt.Sprintf(" %s %s,", humanize.Comma(value), label)
path: server/models/seed_models_logs.go
user: login: amitamrutiya
body: do that operation in client side
created_at: 2025-04-16T06:15:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,7 +15,7 @@ export const TitleLink = ({ href, children, ...props }) => {
       <Typography
         variant="h5"
         style={{
-          textDecorationLine: 'underline',
+          // textDecorationLine: 'underline',
path: ui/components/NotificationCenter/formatters/common.js
user: login: amitamrutiya
body: ?
created_at: 2025-04-16T06:16:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -122,6 +124,11 @@ const ConnectionTable = ({
   const open = Boolean(anchorEl);
   const modalRef = useRef(null);
 
+  useEffect(() => {
+    if (router.query.searchText) {
+      setSearch(router.query.searchText);
+    }
+  }, [router.query.searchText]);
path: ui/components/connections/ConnectionTable.js
user: login: amitamrutiya
body: I don't think you need this. Use existing already implemented routing in connection table. If it based on Id that search with id.
created_at: 2025-04-16T06:17:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -122,6 +124,11 @@ const ConnectionTable = ({
   const open = Boolean(anchorEl);
   const modalRef = useRef(null);
 
+  useEffect(() => {
+    if (router.query.searchText) {
+      setSearch(router.query.searchText);
+    }
+  }, [router.query.searchText]);
path: ui/components/connections/ConnectionTable.js
user: login: FaheemOnHub
body: I tried using connectionId but the api does not supports search based on connection ID
created_at: 2025-04-20T12:16:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -21,6 +20,7 @@ require (
 	github.com/docker/cli v27.5.1+incompatible
 	github.com/docker/docker v27.5.1+incompatible
 	github.com/docker/go-connections v0.5.0
+	github.com/dustin/go-humanize v1.0.1
path: go.mod
user: login: FaheemOnHub
body: removed
created_at: 2025-04-20T12:45:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -185,8 +185,7 @@ func FailedEventCompute(hostname string, mesheryInstanceID gofrs.UUID, provider
 		errorEventBuilder.WithSeverity(events.Error).WithDescription(failedMsg)
 		errorEvent := errorEventBuilder.Build()
 		errorEventBuilder.WithMetadata(map[string]interface{}{
-			"LongDescription":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
-			"SuggestedRemediation": fmt.Sprintf("Open Meshery Error Reference with error code %s", "https://docs.meshery.io/reference/error-codes"),
+			"Long_Description":      fmt.Sprintf("One or more entities failed to register. The import process for registrant, %s, encountered the following issue: %s.", hostname, failedMsg),
path: server/helpers/common_registry_logs.go
user: login: amitamrutiya
body: ?
created_at: 2025-04-21T07:51:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -161,6 +161,25 @@ func writeLogsToFiles(regLog *RegistrationFailureLog) error {
 	return nil
 }
 
+func formatWithCommas(value int64) string {
+    if value < 1000 {
+        return fmt.Sprintf("%d", value)
+    }
+
+    numStr := fmt.Sprintf("%d", value)
+    n := len(numStr)
+
+    var result strings.Builder
+    for i, digit := range numStr {
+        if (n-i)%3 == 0 && i != 0 {
+            result.WriteRune(',')
+        }
+        result.WriteRune(digit)
+    }
+
+    return result.String()
+}
+
path: server/models/seed_models_logs.go
user: login: amitamrutiya
body: no need of this
created_at: 2025-04-21T07:51:36Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-09T09:41:38Z
body: <!-- meshmap-snapshot: do not delete/edit this line -->
[<img src="https://raw.githubusercontent.com/layer5labs/meshery-extensions-packages/master/action-assets/2025@4/dea82811-74ba-474f-b9e4-426e7401707ey1j9OQU=.png">](https://raw.githubusercontent.com/layer5labs/meshery-extensions-packages/master/action-assets/2025@4/dea82811-74ba-474f-b9e4-426e7401707ey1j9OQU=.png) _[View in catalog](https://cloud.layer5.io/catalog/content/design/5f2f55ac-f303-459e-ac8c-aa867f3c9994), [Edit in playground](https://playground.meshery.io/extension/meshmap?mode=design&design=5f2f55ac-f303-459e-ac8c-aa867f3c9994) or learn how to [interpret Meshery Designs](https://cloud.layer5.io/academy/learning-paths/mastering-meshery/introduction-to-meshery?chapter=interpreting-meshery-designs)_
author_association: CONTRIBUTOR
user: login: amitamrutiya
created_at: 2025-04-10T04:00:32Z
body: @FaheemOnHub we now have a routing setup for the connection table so do routing changes based on that. 
author_association: CONTRIBUTOR
user: login: FaheemOnHub
created_at: 2025-04-15T22:07:59Z
body: also fixes #14379 
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-04-21T08:00:06Z
body: ## [Codecov](https://app.codecov.io/gh/meshery/meshery/pull/14345?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) Report
Attention: Patch coverage is `0%` with `35 lines` in your changes missing coverage. Please review.
> Please [upload](https://docs.codecov.com/docs/codecov-uploader) report for BASE (`master@ef843a9`). [Learn more](https://docs.codecov.io/docs/error-reference?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#section-missing-base-commit) about missing BASE report.
> Report is 31 commits behind head on master.

| [Files with missing lines](https://app.codecov.io/gh/meshery/meshery/pull/14345?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) | Patch % | Lines |
|---|---|---|
| [server/models/seed\_models\_logs.go](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&filepath=server%2Fmodels%2Fseed_models_logs.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#diff-c2VydmVyL21vZGVscy9zZWVkX21vZGVsc19sb2dzLmdv) | 0.00% | [18 Missing :warning: ](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) |
| [server/handlers/meshery\_pattern\_handler.go](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&filepath=server%2Fhandlers%2Fmeshery_pattern_handler.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#diff-c2VydmVyL2hhbmRsZXJzL21lc2hlcnlfcGF0dGVybl9oYW5kbGVyLmdv) | 0.00% | [10 Missing :warning: ](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) |
| [server/handlers/connections\_handlers.go](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&filepath=server%2Fhandlers%2Fconnections_handlers.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#diff-c2VydmVyL2hhbmRsZXJzL2Nvbm5lY3Rpb25zX2hhbmRsZXJzLmdv) | 0.00% | [5 Missing :warning: ](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) |
| [server/handlers/policy\_relationship\_handler.go](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&filepath=server%2Fhandlers%2Fpolicy_relationship_handler.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#diff-c2VydmVyL2hhbmRsZXJzL3BvbGljeV9yZWxhdGlvbnNoaXBfaGFuZGxlci5nbw==) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) |
| [server/helpers/common\_registry\_logs.go](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&filepath=server%2Fhelpers%2Fcommon_registry_logs.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#diff-c2VydmVyL2hlbHBlcnMvY29tbW9uX3JlZ2lzdHJ5X2xvZ3MuZ28=) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/meshery/meshery/pull/14345?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##             master   #14345   +/-   ##
=========================================
  Coverage          ?    4.93%           
=========================================
  Files             ?      300           
  Lines             ?    57933           
  Branches          ?        0           
=========================================
  Hits              ?     2860           
  Misses            ?    54722           
  Partials          ?      351           
```

| [Flag](https://app.codecov.io/gh/meshery/meshery/pull/14345/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) | Coverage Δ | |
|---|---|---|
| [unittests](https://app.codecov.io/gh/meshery/meshery/pull/14345/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery) | `4.93% <0.00%> (?)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/meshery/meshery/pull/14345?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meshery).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-04-22T12:28:36Z
body:         
  **Commit SHA:** `b0ae7a84f273cd4cded879b187f1c217a048af0d`  

  ### END-TO-END TESTS

- Testing started at: April 22nd 2025, 12:18:49 pm

**📦 Test Result Summary**

- ✅ 45 passed
- ❌ 2 failed
- ⚠️ 16 flaked
- ⏩ 0 skipped

⌛ _Duration: 9 minutes and 24 seconds_

**Overall Result**: 👎 Some tests failed.



<details>
    <summary>[Show/Hide] Test Result Details</summary>
    <div markdown="1">

| Test | Browser | Test Case | Tags | Result |
| :---: | :---: | :--- | :---: | :---: |
| 1 | chromium-meshery-provider | Configure Existing Istio adapter through Mesh Adapter URL from Management page | unstable | ⚠️ |
| 2 | chromium-meshery-provider | Transition to disconnected state and then back to connected state | unstable | ⚠️ |
| 3 | chromium-meshery-provider | Transition to ignored state and then back to connected state | unstable | ⚠️ |
| 4 | chromium-meshery-provider | Transition to not found state and then back to connected state | unstable | ⚠️ |
| 5 | chromium-meshery-provider | Delete Kubernetes cluster connections | unstable | ⚠️ |
| 6 | chromium-meshery-provider | Add performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 7 | chromium-meshery-provider | Ping Istio Adapter | unstable | ⚠️ |
| 8 | chromium-meshery-provider | Connect to Meshery Istio Adapter and configure it |  | ❌ |
| 9 | chromium-local-provider | Add a cluster connection by uploading kubeconfig file | unstable | ⚠️ |
| 10 | chromium-local-provider | Transition to disconnected state and then back to connected state | unstable | ⚠️ |
| 11 | chromium-local-provider | Transition to ignored state and then back to connected state | unstable | ⚠️ |
| 12 | chromium-local-provider | Transition to not found state and then back to connected state | unstable | ⚠️ |
| 13 | chromium-local-provider | Delete Kubernetes cluster connections | unstable | ⚠️ |
| 14 | chromium-meshery-provider | View detailed result of a performance profile (Graph Visualiser) with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 15 | chromium-local-provider | Configure Existing Istio adapter through Mesh Adapter URL from Management page | unstable | ⚠️ |
| 16 | chromium-meshery-provider | Edit the configuration of a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 17 | chromium-local-provider | Add performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 18 | chromium-local-provider | Connect to Meshery Istio Adapter and configure it |  | ❌ |
| 19 | chromium-local-provider | Ping Istio Adapter | unstable | ⚠️ |
| 20 | chromium-meshery-provider | Compare test of a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 21 | chromium-local-provider | View detailed result of a performance profile (Graph Visualiser) with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 22 | chromium-meshery-provider | Delete a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 23 | chromium-local-provider | Edit the configuration of a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 24 | chromium-local-provider | Compare test of a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |
| 25 | chromium-local-provider | Delete a performance profile with load generator &quot;fortio&quot; and service mesh &quot;None&quot; | unstable | ⚠️ |

</div>
</details>


<!-- To see the full report, please visit our CI/CD pipeline with reporter. -->
  
author_association: CONTRIBUTOR