forked from meshery/meshery
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request meshery#8733 from aabidsofi19/notification-center
Notification Center
- Loading branch information
Showing
38 changed files
with
2,830 additions
and
1,273 deletions.
There are no files selected for viewing
171 changes: 171 additions & 0 deletions
171
docs/pages/project/contributing/contributing-ui-notification-center.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
--- | ||
layout: page | ||
title: Contributing to Meshery UI - Notification Center | ||
permalink: project/contributing/contributing-ui-notification-center | ||
description: How to contribute to the Notification Center in Meshery's web-based UI. | ||
language: en | ||
type: project | ||
category: contributing | ||
--- | ||
|
||
<div class="prereqs"><p><strong style="font-size: 20px;">Prerequisite Reading</strong></p> | ||
<ol><li><a ahref="contributing-ui">Contributing to Meshery UI</a></li></ol> | ||
</div> | ||
|
||
## <a name="contributing-ui-notification-center">Contributing to Meshery UI - Notification Center</a> | ||
|
||
<video class="videoTest" style="width:min(100%,750px)" height="auto" autoplay muted loop> | ||
<source src="https://github.com/meshery/meshery/assets/65964225/345672de-3f61-4be0-b3c8-0e7480cc496c" type="video/mp4"> | ||
Your browser does not support the video tag | ||
</video> | ||
|
||
The `NotificationCenter` component of Meshery UI Switching to Graphql subscriptions and implementing robust filtering. Events are persisted in Meshery Server and state management on client is done using Redux Toolkit and RTK. | ||
|
||
#### User-facing Features | ||
|
||
- Robust filtering support inspired by GitHub's notification filtering style. | ||
- Search is also included. | ||
- Proper hierarchial presentation of error details, including probable cause and suggested remeditation. | ||
- Suport for notification status (notifications can be marked as read and unread) | ||
- *Future: Notifications can be acknowledged or resolved.* | ||
- Event-based notification via Graphql subscription (provided by Meshery Server and any upstream components or externally managed systems, like Kubernetes) | ||
- Infinite scroll for pagination. | ||
|
||
#### State Management and Internal Details | ||
|
||
- The State on client is managed using `Redux Tooltik` and `Rtk-query` | ||
- Update and Delete operations are optimistically handled. | ||
- Network Request are cached and are invalidated when new events come or events are deleted/updated. | ||
- Due to need for infinite scroll and optimistic update the events are stored globally in Redux. | ||
|
||
### Notification Severities and Colors | ||
|
||
Notification severities and colors are defined in the constants file, `ui/components/NotificationCenter/constants.js`. | ||
|
||
### Notification Filtering and Searching | ||
|
||
**Table of Contents** | ||
|
||
- [Usage](#usage) | ||
- [Props](#props) | ||
- [Examples](#examples) | ||
|
||
The Notfication Center includes a resusable component, `TypingFilter`, for sophisticated filtering and searching of notifications based on their attributes. It adheres to the GitHub-style syntax for filtering, offering a straight-forward and adaptable way to filter and search notification details. The `TypingFilter` component is a customizable React component that enables real-time filtering and selection based on user input. | ||
|
||
The state for filtering is managed by a state machine created using a reducer. `TypingFilter` supports multiple filters, suggestions and completions. | ||
|
||
### Usage | ||
|
||
The `TypingFilter` component is designed to provide an interactive filtering experience in your application. Here's how you can use it: | ||
|
||
```javascript | ||
import React from 'react'; | ||
import TypingFilter from './path-to-TypingFilter'; | ||
|
||
function MyComponent() { | ||
// Define a filter schema that describes the available filter options. | ||
const filterSchema = { | ||
// Define your filter categories here | ||
// Example: | ||
SEVERITY: { | ||
value: "severity", | ||
description: "Filter by severity", | ||
values: ["Low", "Medium", "High"], | ||
multiple : true // default | ||
}, | ||
// Add more filter categories as needed | ||
}; | ||
|
||
// Define a callback function to handle filter changes. | ||
const handleFilterChange = (filteredData) => { | ||
// Implement your logic to react to the filtered data. | ||
// This function will be called when the user applies a filter. ( on presing enter in input) | ||
console.log("Filtered data:", filteredData); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<TypingFilter | ||
filterSchema={filterSchema} | ||
handleFilter={handleFilterChange} | ||
/> | ||
{/* Your other components */} | ||
</div> | ||
); | ||
} | ||
|
||
export default MyComponent; | ||
``` | ||
|
||
### Props | ||
|
||
The `TypingFilter` component accepts the following props: | ||
|
||
- `filterSchema` (object, required): An object that defines available filter options. Each property of this object represents a filter category with the following properties: | ||
- `value` (string, required): The filter name used for filtering within the category. | ||
- `description` (string, required): Description of the filter category. | ||
- `type` (string, optional): The data type of the filter (e.g., "string", "number"). | ||
- `values` (array, optional): Possible values for the filter. | ||
|
||
- `handleFilter` (function, required): A callback function that is called when the user applies a filter. This function receives the filtered data as an argument. | ||
|
||
|
||
## Finite State Machine (FSM) for `TypingFilter` Component | ||
|
||
This section provides an overview of the Finite State Machine (FSM) implementation used to manage the state of the `TypingFilter` component. The FSM is responsible for handling user interactions, such as selecting filters, entering values, and clearing the filter, within the component. The FSM implementation within the `TypingFilter` component ensures that user interactions are correctly processed and managed, resulting in a smooth and intuitive filtering experience. | ||
|
||
**Table of Contents** | ||
|
||
- [Overview](#overview) | ||
- [State Definitions](#state-definitions) | ||
- [Reducers](#reducers) | ||
- [State Transitions](#state-transitions) | ||
- [Initial State Handling](#initial-state-handling) | ||
|
||
### State Definitions | ||
|
||
The FSM code defines three sets of constants to represent important elements within the state management: | ||
|
||
#### 1. `FILTERING_STATE` | ||
|
||
Defines the possible states that the `TypingFilter` component can be in. These states include: | ||
- `IDLE`: Represents the initial state when the component is not actively filtering. | ||
- `SELECTING_FILTER`: Indicates that the user is selecting a filter. | ||
- `SELECTING_VALUE`: Indicates that the user is entering a filter value. | ||
|
||
#### 2. `FILTER_EVENTS` | ||
|
||
Represents the events that trigger state transitions within the FSM. Some of the events include: | ||
- `START`: Initiates the filtering process. | ||
- `SELECT`: Indicates the selection of a filter. | ||
- `INPUT_CHANGE`: Represents a change in the filter input. | ||
- `CLEAR`: Clears the filter. | ||
- `EXIT`: Exits the filtering process. | ||
|
||
#### 3. `Delimiter` | ||
|
||
Defines delimiters used to separate filter and value entries within the component. Delimiters include: | ||
- `FILTER`: Separates multiple filters. | ||
- `FILTER_VALUE`: Separates filters from their corresponding values. | ||
|
||
### Reducers | ||
|
||
The FSM implementation includes two key reducer functions: | ||
|
||
#### 1. `commonReducer` | ||
|
||
This common reducer function handles events that are common across all states. It includes logic to handle "CLEAR" and "EXIT" events, which reset the component's state and clear any entered values. | ||
|
||
#### 2. `filterSelectionReducer` | ||
|
||
The `filterSelectionReducer` is a specific reducer used to manage transitions between "SELECTING_FILTER" and "SELECTING_VALUE" states. It handles events related to selecting filters and entering values. The logic ensures that delimiters are appropriately added or removed when the user interacts with the filter. | ||
|
||
### State Transitions | ||
|
||
State transitions are managed based on user actions and the current state of the component. For example, when the user selects a filter, the state transitions from "SELECTING_FILTER" to "SELECTING_VALUE." When the user inputs values or clears the filter, the state transitions are managed accordingly. | ||
|
||
### Initial State Handling | ||
|
||
The FSM implementation includes handling for the initial state, where it listens for the "START" event to transition from "IDLE" to "SELECTING_FILTER." This ensures that the filtering process is initiated when the user interacts with the component. | ||
|
||
{% include suggested-reading.html %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from "react"; | ||
|
||
const AlertIcon = ({ height, width, fill, style = {} }) => { | ||
return ( | ||
<svg | ||
style={style} | ||
height={height} | ||
width={width} | ||
fill="#fff" | ||
viewBox="0 0 20 20" | ||
> | ||
<path d="M11.6042 11.6667H9.89591V7.49999H11.6042V11.6667ZM11.6042 15H9.89591V13.3333H11.6042V15ZM1.35425 17.5H20.1459L10.7501 1.66666L1.35425 17.5Z" fill={fill} /> | ||
|
||
</svg> | ||
); | ||
}; | ||
|
||
export default AlertIcon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
import React from "react"; | ||
const ArchiveIcon = ({ height, width, fill, innerFill = "#fff", style = {} }) => { | ||
return ( | ||
<svg | ||
style={style} | ||
height={height} | ||
width={width} | ||
fill={fill} | ||
viewBox="0 0 20 20" | ||
> | ||
<g clip-path="url(#clip0_19418_1412)"> | ||
<path d="M17.1167 4.35833L15.9583 2.95833C15.7333 2.675 15.3917 2.5 15 2.5H5C4.60833 2.5 4.26667 2.675 4.03333 2.95833L2.88333 4.35833C2.64167 4.64167 2.5 5.01667 2.5 5.41667V15.8333C2.5 16.75 3.25 17.5 4.16667 17.5H15.8333C16.75 17.5 17.5 16.75 17.5 15.8333V5.41667C17.5 5.01667 17.3583 4.64167 17.1167 4.35833ZM10 14.5833L5.41667 10H8.33333V8.33333H11.6667V10H14.5833L10 14.5833ZM4.26667 4.16667L4.94167 3.33333H14.9417L15.725 4.16667H4.26667Z" fill={fill} /> | ||
</g> | ||
<defs> | ||
<clipPath id="clip0_19418_1412"> | ||
<rect width="20" height="20" fill={innerFill} /> | ||
</clipPath> | ||
</defs> | ||
</svg> | ||
); | ||
}; | ||
|
||
export default ArchiveIcon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,4 @@ const ClearIcon = (props) => { | |
) | ||
}; | ||
|
||
export default ClearIcon; | ||
export default ClearIcon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React from "react"; | ||
|
||
const ContentFilterIcon = (props) => { | ||
return ( | ||
<svg | ||
id="content-filter-icon-svg" | ||
version="1.1" | ||
viewBox="0 0 24 24" | ||
xmlns="http://www.w3.org/2000/svg" | ||
width={props.width ? props.width : "24px"} | ||
height={props.height ? props.height : "24px"} | ||
onClick={props.onClick} | ||
className={props.className} | ||
color={props.color ? props.color : "unset"} | ||
fontSize={props.fontSize ? props.fontSize : "unset"} | ||
style={{ ...props.style }} | ||
fill={props.fill ? props.fill : "currentColor"} | ||
> | ||
|
||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 18H14V16H10V18ZM3 6V8H21V6H3ZM6 13H18V11H6V13Z" fill={props.fill}/> | ||
</svg> | ||
); | ||
}; | ||
|
||
export default ContentFilterIcon; | ||
|
Oops, something went wrong.