From 71b144248f3430f5044da75d0e7c6b7370f0bf6e Mon Sep 17 00:00:00 2001 From: Tal Date: Sun, 24 Nov 2024 17:48:32 +0200 Subject: [PATCH] feat: make providers page easier to navigate (#2610) --- .../components/providers-categories/index.ts | 1 + .../providers-categories.tsx | 53 +++ .../providers-filter-by-label.tsx | 4 +- .../providers-search/providers-search.tsx | 1 + .../filter-context/filter-context.tsx | 7 +- .../(keep)/providers/filter-context/types.ts | 4 +- keep-ui/app/(keep)/providers/layout.tsx | 6 +- keep-ui/app/(keep)/providers/page.client.tsx | 26 +- .../app/(keep)/providers/provider-tile.tsx | 14 +- .../app/(keep)/providers/providers-tiles.tsx | 7 +- keep-ui/app/(keep)/providers/providers.tsx | 20 +- keep-ui/app/(signin)/layout.tsx | 4 +- keep-ui/public/icons/salesforce-icon.png | Bin 0 -> 56517 bytes keep-ui/public/icons/zendesk-icon.png | Bin 0 -> 38135 bytes keep/api/models/provider.py | 6 +- keep/providers/aks_provider/aks_provider.py | 1 + .../appdynamics_provider.py | 19 +- .../auth0_provider/auth0_provider.py | 8 +- .../axiom_provider/axiom_provider.py | 2 + .../azuremonitoring_provider.py | 1 + keep/providers/base/base_provider.py | 21 + .../bigquery_provider/bigquery_provider.py | 2 + .../centreon_provider/centreon_provider.py | 397 +++++++++--------- .../checkmk_provider/checkmk_provider.py | 174 ++++---- .../cilium_provider/cilium_provider.py | 1 + .../clickhouse_provider.py | 37 +- .../cloudwatch_provider.py | 3 +- .../coralogix_provider/coralogix_provider.py | 2 +- .../datadog_provider/datadog_provider.py | 1 + .../discord_provider/discord_provider.py | 1 + .../dynatrace_provider/dynatrace_provider.py | 2 + .../elastic_provider/elastic_provider.py | 2 + .../gcpmonitoring_provider.py | 2 +- .../github_provider/github_provider.py | 1 + .../gitlab_provider/gitlab_provider.py | 40 +- .../gitlabpipelines_provider.py | 8 +- keep/providers/gke_provider/gke_provider.py | 9 +- .../google_chat_provider.py | 17 +- .../grafana_incident_provider.py | 63 +-- .../grafana_oncall_provider.py | 2 + .../grafana_provider/grafana_provider.py | 1 + .../graylog_provider/graylog_provider.py | 35 +- .../ilert_provider/ilert_provider.py | 1 + .../incidentio_provider.py | 120 ++++-- .../incidentmanager_provider.py | 2 + keep/providers/jira_provider/jira_provider.py | 19 +- .../jiraonprem_provider.py | 26 +- .../kafka_provider/kafka_provider.py | 11 +- .../kibana_provider/kibana_provider.py | 1 + .../kubernetes_provider.py | 111 +++-- .../linear_provider/linear_provider.py | 1 + .../linearb_provider/linearb_provider.py | 1 + .../mailchimp_provider/mailchimp_provider.py | 36 +- .../mailgun_provider/mailgun_provider.py | 1 + .../mattermost_provider.py | 3 +- .../microsoft-planner-provider.py | 2 + .../mongodb_provider/mongodb_provider.py | 9 +- .../mysql_provider/mysql_provider.py | 1 + .../netdata_provider/netdata_provider.py | 1 + .../newrelic_provider/newrelic_provider.py | 1 + keep/providers/ntfy_provider/ntfy_provider.py | 1 + .../openai_provider/openai_provider.py | 1 + .../openobserve_provider.py | 2 +- .../openshift_provider/openshift_provider.py | 36 +- .../opsgenie_provider/opsgenie_provider.py | 1 + .../pagerduty_provider/pagerduty_provider.py | 2 +- .../pagertree_provider/pagertree_provider.py | 201 +++++---- .../parseable_provider/parseable_provider.py | 1 + .../pingdom_provider/pingdom_provider.py | 2 +- .../postgres_provider/postgres_provider.py | 13 +- .../prometheus_provider.py | 1 + keep/providers/providers_factory.py | 15 +- .../pushover_provider/pushover_provider.py | 1 + .../quickchart_provider.py | 1 + .../redmine_provider/redmine_provider.py | 56 ++- .../resend_provider/resend_provider.py | 2 + .../rollbar_provider/rollbar_provider.py | 2 +- .../providers/salesforce_provider/__init__.py | 0 .../salesforce_provider.py | 36 ++ .../sendgrid_provider/sendgrid_provider.py | 1 + .../sentry_provider/sentry_provider.py | 2 +- .../servicenow_provider.py | 1 + .../signalfx_provider/signalfx_provider.py | 2 + .../signl4_provider/signl4_provider.py | 37 +- .../site24x7_provider/site24x7_provider.py | 2 +- .../slack_provider/slack_provider.py | 1 + keep/providers/smtp_provider/smtp_provider.py | 1 + .../snowflake_provider/snowflake_provider.py | 1 + .../splunk_provider/splunk_provider.py | 2 +- .../squadcast_provider/squadcast_provider.py | 4 +- keep/providers/ssh_provider/ssh_provider.py | 1 + .../statuscake_provider.py | 26 +- .../sumologic_provider/sumologic_provider.py | 2 +- .../teams_provider/teams_provider.py | 4 +- .../telegram_provider/telegram_provider.py | 1 + .../trello_provider/trello_provider.py | 9 +- .../twilio_provider/twilio_provider.py | 9 +- .../uptimekuma_provider.py | 1 + .../victoriametrics_provider.py | 2 +- .../webhook_provider/webhook_provider.py | 1 + .../zabbix_provider/zabbix_provider.py | 1 + keep/providers/zendesk_provider/__init__.py | 0 .../zendesk_provider/zendesk_provider.py | 36 ++ .../zenduty_provider/zenduty_provider.py | 17 +- .../test_pushing_prometheus_alerts.py | 6 +- 105 files changed, 1215 insertions(+), 681 deletions(-) create mode 100644 keep-ui/app/(keep)/providers/components/providers-categories/index.ts create mode 100644 keep-ui/app/(keep)/providers/components/providers-categories/providers-categories.tsx create mode 100644 keep-ui/public/icons/salesforce-icon.png create mode 100644 keep-ui/public/icons/zendesk-icon.png create mode 100644 keep/providers/salesforce_provider/__init__.py create mode 100644 keep/providers/salesforce_provider/salesforce_provider.py create mode 100644 keep/providers/zendesk_provider/__init__.py create mode 100644 keep/providers/zendesk_provider/zendesk_provider.py diff --git a/keep-ui/app/(keep)/providers/components/providers-categories/index.ts b/keep-ui/app/(keep)/providers/components/providers-categories/index.ts new file mode 100644 index 000000000..79942cca9 --- /dev/null +++ b/keep-ui/app/(keep)/providers/components/providers-categories/index.ts @@ -0,0 +1 @@ +export { ProvidersCategories } from "./providers-categories"; diff --git a/keep-ui/app/(keep)/providers/components/providers-categories/providers-categories.tsx b/keep-ui/app/(keep)/providers/components/providers-categories/providers-categories.tsx new file mode 100644 index 000000000..bb657e440 --- /dev/null +++ b/keep-ui/app/(keep)/providers/components/providers-categories/providers-categories.tsx @@ -0,0 +1,53 @@ +import { TProviderCategory } from "@/app/(keep)/providers/providers"; +import { Badge } from "@tremor/react"; +import { useFilterContext } from "../../filter-context"; + +export const ProvidersCategories = () => { + const { providersSelectedCategories, setProvidersSelectedCategories } = + useFilterContext(); + + const categories: TProviderCategory[] = [ + "Monitoring", + "Incident Management", + "Cloud Infrastructure", + "Ticketing", + "Developer Tools", + "Database", + "Identity and Access Management", + "Security", + "Collaboration", + "CRM", + "Queues", + "Coming Soon", + "Others", + ]; + + const toggleCategory = (category: TProviderCategory) => { + setProvidersSelectedCategories((prev) => + prev.includes(category) + ? prev.filter((c) => c !== category) + : [...prev, category] + ); + }; + + return ( +
+ {categories.map((category) => ( + toggleCategory(category)} + > + {category} + + ))} +
+ ); +}; diff --git a/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx b/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx index 09f696c8e..669c966f1 100644 --- a/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx +++ b/keep-ui/app/(keep)/providers/components/providers-filter-by-label/providers-filter-by-label.tsx @@ -18,8 +18,8 @@ export const ProvidersFilterByLabel: FC = (props) => { {options.map(([value, label]) => ( diff --git a/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx b/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx index 5d4965038..604f24bd5 100644 --- a/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx +++ b/keep-ui/app/(keep)/providers/components/providers-search/providers-search.tsx @@ -16,6 +16,7 @@ export const ProvidersSearch: FC = () => { id="search-providers" icon={MagnifyingGlassIcon} placeholder="Filter providers..." + className="w-full" value={providersSearchString} onChange={handleChange} /> diff --git a/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx b/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx index 1e2866721..e61f91dba 100644 --- a/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx +++ b/keep-ui/app/(keep)/providers/filter-context/filter-context.tsx @@ -2,7 +2,7 @@ import { createContext, useState, FC, PropsWithChildren } from "react"; import { IFilterContext } from "./types"; import { useSearchParams } from "next/navigation"; import { PROVIDER_LABELS_KEYS } from "./constants"; -import type { TProviderLabels } from "../providers"; +import type { TProviderCategory, TProviderLabels } from "../providers"; export const FilterContext = createContext(null); @@ -12,6 +12,9 @@ export const FilerContextProvider: FC = ({ children }) => { const [providersSearchString, setProvidersSearchString] = useState(""); + const [providersSelectedCategories, setProvidersSelectedCategories] = + useState([]); + const [providersSelectedTags, setProvidersSelectedTags] = useState< TProviderLabels[] >(() => { @@ -26,8 +29,10 @@ export const FilerContextProvider: FC = ({ children }) => { const contextValue: IFilterContext = { providersSearchString, providersSelectedTags, + providersSelectedCategories, setProvidersSelectedTags, setProvidersSearchString, + setProvidersSelectedCategories, }; return ( diff --git a/keep-ui/app/(keep)/providers/filter-context/types.ts b/keep-ui/app/(keep)/providers/filter-context/types.ts index c56f163b6..aeb6f0d5c 100644 --- a/keep-ui/app/(keep)/providers/filter-context/types.ts +++ b/keep-ui/app/(keep)/providers/filter-context/types.ts @@ -1,9 +1,11 @@ import { Dispatch, SetStateAction } from "react"; -import { TProviderLabels } from "../providers"; +import { TProviderCategory, TProviderLabels } from "../providers"; export interface IFilterContext { providersSearchString: string; providersSelectedTags: TProviderLabels[]; + providersSelectedCategories: TProviderCategory[]; setProvidersSearchString: Dispatch>; setProvidersSelectedTags: Dispatch>; + setProvidersSelectedCategories: Dispatch>; } diff --git a/keep-ui/app/(keep)/providers/layout.tsx b/keep-ui/app/(keep)/providers/layout.tsx index 83d2cc7fc..0c229eef2 100644 --- a/keep-ui/app/(keep)/providers/layout.tsx +++ b/keep-ui/app/(keep)/providers/layout.tsx @@ -3,16 +3,18 @@ import { PropsWithChildren } from "react"; import { ProvidersFilterByLabel } from "./components/providers-filter-by-label"; import { ProvidersSearch } from "./components/providers-search"; import { FilerContextProvider } from "./filter-context"; +import { ProvidersCategories } from "./components/providers-categories"; export default function ProvidersLayout({ children }: PropsWithChildren) { return (
-
-
+
+
+
{children}
diff --git a/keep-ui/app/(keep)/providers/page.client.tsx b/keep-ui/app/(keep)/providers/page.client.tsx index fd49f8ff9..b4e4131ad 100644 --- a/keep-ui/app/(keep)/providers/page.client.tsx +++ b/keep-ui/app/(keep)/providers/page.client.tsx @@ -110,7 +110,11 @@ export default function ProvidersPage({ session, isLocalhost, } = useFetchProviders(); - const { providersSearchString, providersSelectedTags } = useFilterContext(); + const { + providersSearchString, + providersSelectedTags, + providersSelectedCategories, + } = useFilterContext(); const apiUrl = useApiUrl(); const router = useRouter(); useEffect(() => { @@ -147,6 +151,21 @@ export default function ProvidersPage({ ); }; + const searchCategories = (provider: Provider) => { + if (providersSelectedCategories.includes("Coming Soon")) { + if (provider.coming_soon) { + return true; + } + } + + return ( + providersSelectedCategories.length === 0 || + provider.categories.some((category) => + providersSelectedCategories.includes(category) + ) + ); + }; + const searchTags = (provider: Provider) => { return ( providersSelectedTags.length === 0 || @@ -171,7 +190,10 @@ export default function ProvidersPage({ )} searchProviders(provider) && searchTags(provider) + (provider) => + searchProviders(provider) && + searchTags(provider) && + searchCategories(provider) )} isLocalhost={isLocalhost} /> diff --git a/keep-ui/app/(keep)/providers/provider-tile.tsx b/keep-ui/app/(keep)/providers/provider-tile.tsx index 34949538f..2e4ef9c95 100644 --- a/keep-ui/app/(keep)/providers/provider-tile.tsx +++ b/keep-ui/app/(keep)/providers/provider-tile.tsx @@ -159,16 +159,17 @@ export default function ProviderTile({ provider, onClick }: Props) { /> ); }; - return (