mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
make UI for table filters nicer
This commit is contained in:
parent
5d9252d1ff
commit
f0a3ddbf2e
@ -906,9 +906,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
||||
headerbuttons.push({
|
||||
title: "",
|
||||
buttonStyle: ButtonStyleType.ICON,
|
||||
className: props.showRefreshButton
|
||||
? "p-1 px-1 pr-0 pl-0 py-0 mt-1"
|
||||
: "py-0 pr-0 pl-1 mt-1",
|
||||
className: "py-0 pr-0 pl-1 mt-1",
|
||||
onClick: () => {
|
||||
setQuery({});
|
||||
setShowFilterModal(true);
|
||||
|
@ -14,7 +14,7 @@ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
||||
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
||||
import API from "../../../Utils/API";
|
||||
import MoreMenuSection from "../MoreMenu/MoreMenuSection";
|
||||
import Button, { ButtonStyleType } from "../Button/Button";
|
||||
import { ButtonStyleType } from "../Button/Button";
|
||||
import IconProp from "../../../Types/Icon/IconProp";
|
||||
import { BarLoader } from "react-spinners";
|
||||
import ConfirmModal from "../Modal/ConfirmModal";
|
||||
@ -22,9 +22,10 @@ import ModelFormModal from "../ModelFormModal/ModelFormModal";
|
||||
import { FormType } from "../Forms/ModelForm";
|
||||
import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
|
||||
import { PromiseVoidFunction } from "../../../Types/FunctionTypes";
|
||||
import { GetReactElementFunction } from "../../Types/FunctionTypes";
|
||||
import { GetReactElementArrayFunction } from "../../Types/FunctionTypes";
|
||||
import ProjectUtil from "../../Utils/Project";
|
||||
import User from "../../Utils/User";
|
||||
import Icon, { SizeProp, ThickProp } from "../Icon/Icon";
|
||||
|
||||
export interface ComponentProps {
|
||||
tableId: string;
|
||||
@ -122,21 +123,28 @@ const TableViewElement: FunctionComponent<ComponentProps> = (
|
||||
(item: TableView): ReactElement => {
|
||||
return (
|
||||
<div className="flex">
|
||||
<Button
|
||||
icon={IconProp.Edit}
|
||||
buttonStyle={ButtonStyleType.ICON_LIGHT}
|
||||
onClick={() => {
|
||||
setTableViewToEdit(item);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
icon={IconProp.Trash}
|
||||
buttonStyle={ButtonStyleType.ICON_LIGHT}
|
||||
onClick={() => {
|
||||
setTableViewToDelete(item);
|
||||
}}
|
||||
/>
|
||||
<div className="h-4 w-4 mr-2">
|
||||
<Icon
|
||||
icon={IconProp.Edit}
|
||||
className="text-gray-400 hover:text-gray-600"
|
||||
size={SizeProp.Regular}
|
||||
thick={ThickProp.Thick}
|
||||
onClick={() => {
|
||||
setTableViewToEdit(item);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="h-4 w-4">
|
||||
<Icon
|
||||
className="text-gray-400 hover:text-gray-600"
|
||||
icon={IconProp.Trash}
|
||||
size={SizeProp.Regular}
|
||||
thick={ThickProp.Thick}
|
||||
onClick={() => {
|
||||
setTableViewToDelete(item);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -150,6 +158,8 @@ const TableViewElement: FunctionComponent<ComponentProps> = (
|
||||
key={index}
|
||||
rightElement={getRightElementForTableViewMenuItem(item)}
|
||||
text={item.name || ""}
|
||||
className="text-gray-600 hover:text-gray-800"
|
||||
icon={IconProp.Window}
|
||||
onClick={() => {
|
||||
props.onViewChange && props.onViewChange(item);
|
||||
setCurrentlySelectedView(item);
|
||||
@ -159,42 +169,36 @@ const TableViewElement: FunctionComponent<ComponentProps> = (
|
||||
});
|
||||
};
|
||||
|
||||
const getMenuContents: GetReactElementFunction = (): ReactElement => {
|
||||
if (isLoading) {
|
||||
return <BarLoader />;
|
||||
}
|
||||
const getMenuContents: GetReactElementArrayFunction =
|
||||
(): Array<ReactElement> => {
|
||||
if (isLoading) {
|
||||
return [<BarLoader />];
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{allTableViews.length > 0 ? (
|
||||
const elements: Array<ReactElement> = [];
|
||||
|
||||
if (allTableViews.length > 0) {
|
||||
elements.push(
|
||||
<MoreMenuSection title="Saved Views">
|
||||
{getViewItems()}
|
||||
</MoreMenuSection>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{currentlySelectedView ? (
|
||||
<MoreMenuItem
|
||||
text="Deselect View"
|
||||
onClick={() => {
|
||||
setCurrentlySelectedView(null);
|
||||
props.onViewChange && props.onViewChange(null);
|
||||
}}
|
||||
></MoreMenuItem>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</MoreMenuSection>,
|
||||
);
|
||||
}
|
||||
|
||||
elements.push(
|
||||
<MoreMenuItem
|
||||
text="Save View"
|
||||
text="Save as New View"
|
||||
className="bg-gray-50 hover:bg-gray-100 text-gray-700 hover:text-gray-900 font-medium -mt-2"
|
||||
icon={IconProp.Add}
|
||||
iconClassName=""
|
||||
onClick={() => {
|
||||
setShowCreateNewViewModel(true);
|
||||
}}
|
||||
></MoreMenuItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
></MoreMenuItem>,
|
||||
);
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
@ -311,7 +315,38 @@ const TableViewElement: FunctionComponent<ComponentProps> = (
|
||||
);
|
||||
}
|
||||
|
||||
return <MoreMenu>{getMenuContents()}</MoreMenu>;
|
||||
type GetElementToBeShownInsteadOfButtonFunction = () => ReactElement | undefined;
|
||||
|
||||
const getElementToBeShownInsteadOfButton: GetElementToBeShownInsteadOfButtonFunction = (): ReactElement | undefined => {
|
||||
if (!currentlySelectedView) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ml-2 mt-1 cursor-pointer font-semibold flex rounded-full border-2 border-gray-600 text-gray-600 text-xs p-1 pl-2 pr-2">
|
||||
{currentlySelectedView.name}
|
||||
<div className="h-4 w-4 rounded-full bg-gray-500 text-white hover:bg-gray-800 ml-3 -mr-1 p-1">
|
||||
<Icon
|
||||
icon={IconProp.Close}
|
||||
size={SizeProp.Regular}
|
||||
thick={ThickProp.Thick}
|
||||
onClick={() => {
|
||||
setCurrentlySelectedView(null);
|
||||
props.onViewChange && props.onViewChange(null);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<MoreMenu
|
||||
elementToBeShownInsteadOfButton={getElementToBeShownInsteadOfButton()}
|
||||
>
|
||||
{getMenuContents()}
|
||||
</MoreMenu>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableViewElement;
|
||||
|
@ -9,7 +9,8 @@ import IconProp from "../../../Types/Icon/IconProp";
|
||||
import useComponentOutsideClick from "../../Types/UseComponentOutsideClick";
|
||||
|
||||
export interface ComponentProps {
|
||||
children: Array<ReactElement> | ReactElement;
|
||||
children: Array<ReactElement>;
|
||||
elementToBeShownInsteadOfButton?: ReactElement | undefined;
|
||||
}
|
||||
|
||||
const MoreMenu: FunctionComponent<ComponentProps> = (
|
||||
@ -26,15 +27,27 @@ const MoreMenu: FunctionComponent<ComponentProps> = (
|
||||
|
||||
return (
|
||||
<div className="relative inline-block text-left">
|
||||
<div>
|
||||
<Button
|
||||
icon={IconProp.More}
|
||||
buttonStyle={ButtonStyleType.ICON}
|
||||
{!props.elementToBeShownInsteadOfButton && (
|
||||
<div>
|
||||
<Button
|
||||
icon={IconProp.More}
|
||||
buttonStyle={ButtonStyleType.ICON}
|
||||
onClick={() => {
|
||||
setIsComponentVisible(!isDropdownVisible);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.elementToBeShownInsteadOfButton && (
|
||||
<div
|
||||
onClick={() => {
|
||||
setIsComponentVisible(!isDropdownVisible);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
>
|
||||
{props.elementToBeShownInsteadOfButton}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isComponentVisible && (
|
||||
<div
|
||||
@ -44,7 +57,21 @@ const MoreMenu: FunctionComponent<ComponentProps> = (
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="menu-button"
|
||||
>
|
||||
{props.children}
|
||||
{props.children.map((child: ReactElement, index: number) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
if (isComponentVisible) {
|
||||
setIsComponentVisible(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{child}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -7,6 +7,8 @@ export interface ComponentProps {
|
||||
text: string;
|
||||
onClick: () => void;
|
||||
rightElement?: Array<ReactElement> | ReactElement | undefined;
|
||||
className?: string | undefined;
|
||||
iconClassName?: string | undefined;
|
||||
}
|
||||
|
||||
const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
||||
@ -14,7 +16,7 @@ const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
||||
): ReactElement => {
|
||||
return (
|
||||
<a
|
||||
className="cursor-pointer group flex items-center px-4 py-2 text-sm text-gray-700 hover:text-gray-900 hover:bg-gray-50"
|
||||
className={`cursor-pointer group flex items-center px-4 py-2 text-sm text-gray-600 hover:text-gray-700 hover:bg-gray-50 ${props.className}`}
|
||||
role="menuitem"
|
||||
onClick={() => {
|
||||
props.onClick();
|
||||
@ -23,10 +25,10 @@ const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
||||
{props.icon && (
|
||||
<Icon
|
||||
icon={props.icon}
|
||||
className="mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500"
|
||||
className={`mr-3 h-5 w-5 text-gray-400 text-gray-700 hover:text-gray-900 ${props.iconClassName}`}
|
||||
/>
|
||||
)}
|
||||
<div className="flex justify-between">
|
||||
<div className="flex w-full justify-between">
|
||||
<div>{props.text}</div>
|
||||
<div>{props.rightElement}</div>
|
||||
</div>
|
||||
|
@ -10,8 +10,8 @@ const MoreMenuSection: FunctionComponent<ComponentProps> = (
|
||||
): ReactElement => {
|
||||
return (
|
||||
<div>
|
||||
<div className="text-gray-400 text-sm font-medium">
|
||||
{props.title.toLocaleUpperCase()}
|
||||
<div className="text-gray-400 text-xs font-medium pt-2 pl-3 pr-3 pb-2">
|
||||
{props.title.toUpperCase()}
|
||||
</div>
|
||||
{props.children}
|
||||
<MoreMenuDivider />
|
||||
|
@ -2,4 +2,6 @@ import { ReactElement } from "react";
|
||||
|
||||
export type GetReactElementFunction = () => ReactElement;
|
||||
|
||||
export type GetReactElementArrayFunction = () => Array<ReactElement>;
|
||||
|
||||
export type GetReactElementOrStringFunction = () => ReactElement | string;
|
||||
|
@ -60,7 +60,7 @@ const MonitorsTable: FunctionComponent<ComponentProps> = (
|
||||
modelType={Monitor}
|
||||
name="Monitors"
|
||||
id="Monitors-table"
|
||||
// saveFilterProps={props.saveFilterProps}
|
||||
saveFilterProps={props.saveFilterProps}
|
||||
bulkActions={{
|
||||
buttons: [
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user