+
+ {map(queries, (query) => (
+
+ ))}
+ {map(staging, (value) => (
+
+ {value as string}
+
+ ))}
+
+ {optionsData && (
+
+ )}
+ {queries && queries.length > 0 && (
+ } type="text" onClick={clearQueries} />
+ )}
+
+ );
+}
+
+export default SearchFilter;
diff --git a/frontend/src/container/ListOfDashboard/SearchFilter/styles.ts b/frontend/src/container/ListOfDashboard/SearchFilter/styles.ts
new file mode 100644
index 0000000000..dc03219e1e
--- /dev/null
+++ b/frontend/src/container/ListOfDashboard/SearchFilter/styles.ts
@@ -0,0 +1,30 @@
+import { grey } from '@ant-design/colors';
+import { Tag } from 'antd';
+import styled from 'styled-components';
+
+export const SearchContainer = styled.div<{
+ isDarkMode: boolean;
+}>`
+ background: ${({ isDarkMode }): string => (isDarkMode ? '#000' : '#fff')};
+ width: 100%;
+ display: flex;
+ align-items: center;
+ gap: 0.2rem;
+ padding: 0.2rem 0;
+ margin: 1rem 0;
+ border: 1px solid #ccc5;
+`;
+export const QueryChipContainer = styled.span`
+ display: flex;
+ align-items: center;
+ margin-right: 0.5rem;
+ &:hover {
+ & > * {
+ background: ${grey.primary}44;
+ }
+ }
+`;
+
+export const QueryChipItem = styled(Tag)`
+ margin-right: 0.1rem;
+`;
diff --git a/frontend/src/container/ListOfDashboard/SearchFilter/types.ts b/frontend/src/container/ListOfDashboard/SearchFilter/types.ts
new file mode 100644
index 0000000000..a9e8a7e8b9
--- /dev/null
+++ b/frontend/src/container/ListOfDashboard/SearchFilter/types.ts
@@ -0,0 +1,18 @@
+export type TOperator = '=' | '!=';
+
+export type TCategory = 'title' | 'description' | 'tags';
+export interface IQueryStructure {
+ category: string;
+ id: string;
+ operator: TOperator;
+ value: string | string[];
+}
+
+interface IOptions {
+ name: string;
+ value?: string;
+}
+export interface IOptionsData {
+ mode: undefined | 'tags' | 'multiple';
+ options: IOptions[] | [];
+}
diff --git a/frontend/src/container/ListOfDashboard/SearchFilter/utils.ts b/frontend/src/container/ListOfDashboard/SearchFilter/utils.ts
new file mode 100644
index 0000000000..5f9b37cc3e
--- /dev/null
+++ b/frontend/src/container/ListOfDashboard/SearchFilter/utils.ts
@@ -0,0 +1,152 @@
+/* eslint-disable no-param-reassign */
+/* eslint-disable no-restricted-syntax */
+/* eslint-disable sonarjs/cognitive-complexity */
+import { decode, encode } from 'js-base64';
+import { flattenDeep, map, uniqWith } from 'lodash-es';
+import { Dashboard } from 'types/api/dashboard/getAll';
+
+import { IOptionsData, IQueryStructure, TCategory, TOperator } from './types';
+
+export const convertQueriesToURLQuery = (
+ queries: IQueryStructure[],
+): string => {
+ if (!queries || !queries.length) {
+ return '';
+ }
+
+ return encode(JSON.stringify(queries));
+};
+
+export const convertURLQueryStringToQuery = (
+ queryString: string,
+): IQueryStructure[] => {
+ return JSON.parse(decode(queryString));
+};
+
+export const resolveOperator = (
+ result: unknown,
+ operator: TOperator,
+): boolean => {
+ if (operator === '!=') {
+ return !result;
+ }
+ if (operator === '=') {
+ return !!result;
+ }
+ return !!result;
+};
+export const executeSearchQueries = (
+ queries: IQueryStructure[] = [],
+ searchData: Dashboard[] = [],
+): Dashboard[] => {
+ if (!searchData.length || !queries.length) {
+ return searchData;
+ }
+
+ queries.forEach((query: IQueryStructure) => {
+ const { operator } = query;
+ let { value } = query;
+ const categoryLowercase: TCategory = `${query.category}`.toLowerCase() as
+ | 'title'
+ | 'description';
+ value = flattenDeep([value]);
+
+ searchData = searchData.filter(({ data: searchPayload }: Dashboard) => {
+ try {
+ const searchSpace =
+ flattenDeep([searchPayload[categoryLowercase]]).filter(Boolean) || null;
+ if (!searchSpace || !searchSpace.length)
+ return resolveOperator(false, operator);
+
+ for (const searchSpaceItem of searchSpace) {
+ if (searchSpaceItem)
+ for (const queryValue of value) {
+ if (searchSpaceItem.match(queryValue)) {
+ return resolveOperator(true, operator);
+ }
+ }
+ }
+ } catch (error) {
+ console.error(error);
+ }
+ return resolveOperator(false, operator);
+ });
+ });
+ return searchData;
+};
+
+export const OptionsSchemas = {
+ attribute: {
+ mode: undefined,
+ options: [
+ {
+ name: 'Title',
+ },
+ {
+ name: 'Description',
+ },
+ {
+ name: 'Tags',
+ },
+ ],
+ },
+ operator: {
+ mode: undefined,
+ options: [
+ {
+ value: '=',
+ name: 'Equal',
+ },
+ {
+ name: 'Not Equal',
+ value: '!=',
+ },
+ ],
+ },
+};
+
+export function OptionsValueResolution(
+ category: TCategory,
+ searchData: Dashboard[],
+): Record