Skip to content

Commit

Permalink
feat: some enhancments to the search bar (#1057)
Browse files Browse the repository at this point in the history
Co-authored-by: Test <[email protected]>
  • Loading branch information
shahargl and talboren authored Apr 7, 2024
1 parent e10bc34 commit d791925
Show file tree
Hide file tree
Showing 16 changed files with 505 additions and 67 deletions.
1 change: 1 addition & 0 deletions keep-ui/app/alerts/ColumnSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function ColumnSelection({
closePopover();
};


return (
<Popover as={Fragment}>
{({ close }) => (
Expand Down
123 changes: 123 additions & 0 deletions keep-ui/app/alerts/ThemeSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React, { useState, Fragment, useRef, FormEvent } from 'react';
import { Popover } from '@headlessui/react';
import { Button, Tab, TabGroup, TabList, TabPanels, TabPanel } from "@tremor/react";
import { IoColorPaletteOutline } from 'react-icons/io5';
import { FloatingArrow, arrow, offset, useFloating } from "@floating-ui/react";

const predefinedThemes = {
Transparent: {
critical: 'bg-white',
high: 'bg-white',
warning: 'bg-white',
low: 'bg-white',
info: 'bg-white'
},
Keep: {
critical: 'bg-orange-400', // Highest opacity for critical
high: 'bg-orange-300',
warning: 'bg-orange-200',
low: 'bg-orange-100',
info: 'bg-orange-50' // Lowest opacity for info
},
Basic: {
critical: 'bg-red-200',
high: 'bg-orange-200',
warning: 'bg-yellow-200',
low: 'bg-green-200',
info: 'bg-blue-200'
}
};

const themeKeyMapping = {
0: 'Transparent',
1: 'Keep',
2: 'Basic'
};
type ThemeName = keyof typeof predefinedThemes;

export const ThemeSelection = ({ onThemeChange }: { onThemeChange: (theme: any) => void }) => {
const arrowRef = useRef(null);
const [selectedTab, setSelectedTab] = useState<ThemeName>('Transparent');

const { refs, floatingStyles, context } = useFloating({
strategy: "fixed",
placement: "bottom-end",
middleware: [offset({ mainAxis: 10 }), arrow({ element: arrowRef })],
});

const handleThemeChange = (event: any) => {
const themeIndex = event as 0 | 1 | 2;
handleApplyTheme(themeIndex as 0 | 1 | 2);
};




const handleApplyTheme = (themeKey: keyof typeof themeKeyMapping) => {
const themeName = themeKeyMapping[themeKey];
setSelectedTab(themeName as ThemeName);
};



const onApplyTheme = (close: () => void) => {
// themeName is now assured to be a key of predefinedThemes
const themeName: ThemeName = selectedTab;
const newTheme = predefinedThemes[themeName]; // This should now be error-free
onThemeChange(newTheme);
setSelectedTab('Transparent'); // Assuming 'Transparent' is a valid key
close(); // Close the popover
};

return (
<Popover as={Fragment}>
{({ close }) => (
<>
<Popover.Button
as={Button}
variant="light"
color="gray"
icon={IoColorPaletteOutline}
ref={refs.setReference}
className="ml-2"
/>
<Popover.Overlay className="fixed inset-0 bg-black opacity-30 z-20" />
<Popover.Panel
className="bg-white z-30 p-4 rounded-sm"
ref={refs.setFloating}
style={{ ...floatingStyles, minWidth: '250px' }} // Adjust width here
>
<FloatingArrow
className="fill-white [&>path:last-of-type]:stroke-white"
ref={arrowRef}
context={context}
/>
<span className="text-gray-400 text-sm">Set theme colors</span>
<TabGroup onChange={handleThemeChange}>
<TabList color="orange">
<Tab>Transparent</Tab>
<Tab>Keep</Tab>
<Tab>Basic</Tab>
</TabList>
<TabPanels>
{Object.keys(predefinedThemes).map(themeName => (
<TabPanel key={themeName}>
{Object.entries(predefinedThemes[themeName as keyof typeof predefinedThemes]).map(([severity, color]) => (
<div key={severity} className="flex justify-between items-center my-2">
<span>{severity.charAt(0).toUpperCase() + severity.slice(1).toLowerCase()}</span>
<div className={`w-6 h-6 rounded-full border border-gray-400 ${color}`}></div>
</div>
))}
</TabPanel>
))}
</TabPanels>
</TabGroup>
<Button className="mt-5" color="orange" onClick={() => onApplyTheme(close)}>
Apply theme
</Button>
</Popover.Panel>
</>
)}
</Popover>
);
};
12 changes: 11 additions & 1 deletion keep-ui/app/alerts/TitleAndFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ import { DateRangePicker, DateRangePickerValue, Title } from "@tremor/react";
import { AlertDto } from "./models";
import ColumnSelection from "./ColumnSelection";
import { LastRecieved } from "./LastReceived";
import { ThemeSelection } from './ThemeSelection';

type Theme = {
[key: string]: string;
};

type TableHeaderProps = {
presetName: string;
alerts: AlertDto[];
table: Table<AlertDto>;
onThemeChange: (newTheme: Theme) => void;
};

export const TitleAndFilters = ({
presetName,
alerts,
table,
onThemeChange,
}: TableHeaderProps) => {
const onDateRangePickerChange = ({
from: start,
Expand Down Expand Up @@ -46,7 +53,10 @@ export const TitleAndFilters = ({
onValueChange={onDateRangePickerChange}
enableYearNavigation
/>
<ColumnSelection table={table} presetName={presetName} />
<div style={{ display: 'flex', alignItems: 'center' }}>
<ColumnSelection table={table} presetName={presetName} />
<ThemeSelection onThemeChange={onThemeChange} />
</div>
<LastRecieved />
</div>
</div>
Expand Down
40 changes: 40 additions & 0 deletions keep-ui/app/alerts/ViewAlertModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { AlertDto } from "./models"; // Adjust the import path as needed
import Modal from "@/components/ui/Modal"; // Ensure this path matches your project structure
import { Button } from "@tremor/react";
import { toast } from "react-toastify";

interface ViewAlertModalProps {
alert: AlertDto | null | undefined;
handleClose: () => void;
}

export const ViewAlertModal: React.FC<ViewAlertModalProps> = ({ alert, handleClose }) => {
const isOpen = !!alert;

const handleCopy = async () => {
if (alert) {
try {
await navigator.clipboard.writeText(JSON.stringify(alert, null, 2));
toast.success("Alert copied to clipboard!");
} catch (err) {
toast.error("Failed to copy alert.");
}
}
};

return (
<Modal onClose={handleClose} isOpen={isOpen} className="overflow-visible max-w-fit">
<div className="flex justify-between items-center">
<h2 className="text-lg font-semibold">Alert Details</h2>
<Button onClick={handleCopy} color="orange">
Copy to Clipboard
</Button>
</div>
{alert && (
<pre className="p-2 bg-gray-100 rounded mt-2 overflow-auto">
{JSON.stringify(alert, null, 2)}
</pre>
)}
</Modal>
);
};
23 changes: 23 additions & 0 deletions keep-ui/app/alerts/alert-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TrashIcon,
UserPlusIcon,
PlayIcon,
EyeIcon
} from "@heroicons/react/24/outline";
import { IoNotificationsOffOutline } from "react-icons/io5";

Expand All @@ -28,6 +29,7 @@ interface Props {
setRunWorkflowModalAlert?: (alert: AlertDto) => void;
setDismissModalAlert?: (alert: AlertDto) => void;
presetName: string;
setViewAlertModal?: (alert: AlertDto) => void;
}

export default function AlertMenu({
Expand All @@ -37,6 +39,7 @@ export default function AlertMenu({
setRunWorkflowModalAlert,
setDismissModalAlert,
presetName,
setViewAlertModal,
}: Props) {
const router = useRouter();

Expand Down Expand Up @@ -282,6 +285,26 @@ export default function AlertMenu({
)}
</Menu.Item>
)}
{/*View the alert */}
<Menu.Item>
{({ active }) => (
<button
onClick={() => {
setViewAlertModal?.(alert);
handleCloseMenu();
}}
className={`${
active ? "bg-slate-200" : "text-gray-900"
} group flex w-full items-center rounded-md px-2 py-2 text-xs`}
>
<EyeIcon
className="mr-2 h-4 w-4"
aria-hidden="true"
/>
View Alert
</button>
)}
</Menu.Item>
</div>
{provider?.methods && provider?.methods?.length > 0 && (
<div className="px-1 py-1">
Expand Down
4 changes: 2 additions & 2 deletions keep-ui/app/alerts/alert-severity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ export default function AlertSeverity({ severity }: Props) {
color = "orange";
severityText = Severity.High.toString();
break;
case "medium":
case "warning":
color = "yellow";
icon = ArrowRightIcon;
severityText = Severity.Medium.toString();
severityText = Severity.Warning.toString();
break;
case "low":
icon = ArrowDownRightIcon;
Expand Down
Loading

0 comments on commit d791925

Please sign in to comment.