Various improvements Cards, OmniSearch and Cards Listing (#2881)

This commit is contained in:
Sudheer Salavadi 2024-12-17 08:32:22 -05:00 committed by GitHub
parent c851bf0ad1
commit 592923b6d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 247 additions and 233 deletions

View file

@ -1,64 +1,67 @@
// Components/Dashboard/components/AddToDashboardButton.tsx
import React from 'react';
import {Grid2x2Check} from "lucide-react"
import {Button, Modal} from "antd";
import Select from "Shared/Select/Select";
import {Form} from "UI";
import {useStore} from "App/mstore";
import { Grid2x2Check } from 'lucide-react';
import { Button, Modal } from 'antd';
import Select from 'Shared/Select/Select';
import { Form } from 'UI';
import { useStore } from 'App/mstore';
interface Props {
metricId: string;
metricId: string;
}
function AddToDashboardButton({metricId}: Props) {
const {dashboardStore} = useStore();
const dashboardOptions = dashboardStore.dashboards.map((i: any) => ({
key: i.id,
label: i.name,
value: i.dashboardId,
}));
const [selectedId, setSelectedId] = React.useState(dashboardOptions[0]?.value);
export const showAddToDashboardModal = (metricId: string, dashboardStore: any) => {
const dashboardOptions = dashboardStore.dashboards.map((i: any) => ({
key: i.id,
label: i.name,
value: i.dashboardId,
}));
let selectedId = dashboardOptions[0]?.value;
const onSave = (close: any) => {
const dashboard = dashboardStore.getDashboard(selectedId)
if (dashboard) {
dashboardStore.addWidgetToDashboard(dashboard, [metricId]).then(close)
}
const onSave = (close: any) => {
const dashboard = dashboardStore.getDashboard(selectedId);
if (dashboard) {
dashboardStore.addWidgetToDashboard(dashboard, [metricId]).then(close);
}
};
const onClick = () => {
Modal.confirm({
title: 'Add to selected dashboard',
icon: null,
content: (
<Form.Field>
<Select
options={dashboardOptions}
defaultValue={dashboardOptions[0].value}
onChange={({value}: any) => setSelectedId(value.value)}
/>
</Form.Field>
),
cancelText: 'Cancel',
onOk: onSave,
okText: 'Add',
footer: (_, {OkBtn, CancelBtn}) => (
<>
<CancelBtn/>
<OkBtn/>
</>
),
})
}
Modal.confirm({
title: 'Add to selected dashboard',
icon: null,
content: (
<Form.Field>
<Select
options={dashboardOptions}
defaultValue={selectedId}
onChange={({ value }: any) => (selectedId = value.value)}
/>
</Form.Field>
),
cancelText: 'Cancel',
onOk: onSave,
okText: 'Add',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<CancelBtn />
<OkBtn />
</>
),
});
};
return (
<Button
type="default"
onClick={onClick}
icon={<Grid2x2Check size={18}/>}
>
Add to Dashboard
</Button>
);
}
const AddToDashboardButton = ({ metricId }: Props) => {
const { dashboardStore } = useStore();
export default AddToDashboardButton;
return (
<Button
type="default"
onClick={() => showAddToDashboardModal(metricId, dashboardStore)}
icon={<Grid2x2Check size={18} />}
>
Add to Dashboard
</Button>
);
};
export default AddToDashboardButton;

View file

@ -56,7 +56,7 @@ const FilterSeriesHeader = observer(
};
return (
<div
className={cn('px-4 h-12 flex items-center relative bg-white border-gray-lighter border-t border-l border-r rounded-t-xl', {
className={cn('px-4 ps-2 h-12 flex items-center relative bg-white border-gray-lighter border-t border-l border-r rounded-t-xl', {
hidden: props.hidden,
'rounded-b-xl': !props.expanded,
})}
@ -81,6 +81,8 @@ const FilterSeriesHeader = observer(
size="small"
disabled={!props.canDelete}
icon={<Trash size={14} />}
type='text'
className='btn-delete-series'
/>
<Button
onClick={props.toggleExpand}
@ -92,6 +94,8 @@ const FilterSeriesHeader = observer(
<ChevronDown size={16} />
)
}
type='text'
className='btn-toggle-series'
/>
</Space>
</div>

View file

@ -1,61 +1,68 @@
import React, { useState, useRef, useEffect } from 'react';
import { Icon } from 'UI';
import {Input, Tooltip} from 'antd';
import { Input, Tooltip } from 'antd';
interface Props {
name: string;
onUpdate: (name) => void;
onUpdate: (name: string) => void;
seriesIndex?: number;
}
function SeriesName(props: Props) {
const { seriesIndex = 1 } = props;
const [editing, setEditing] = useState(false)
const [name, setName] = useState(props.name)
const ref = useRef<any>(null)
const [editing, setEditing] = useState(false);
const [name, setName] = useState(props.name);
const ref = useRef<any>(null);
const write = ({ target: { value, name } }) => {
setName(value)
}
const write = ({ target: { value } }) => {
setName(value);
};
const onBlur = () => {
setEditing(false)
props.onUpdate(name)
}
setEditing(false);
props.onUpdate(name);
};
const onKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
setEditing(false);
props.onUpdate(name);
}
};
useEffect(() => {
if (editing) {
ref.current.focus()
ref.current.focus();
}
}, [editing])
}, [editing]);
useEffect(() => {
setName(props.name)
}, [props.name])
// const { name } = props;
setName(props.name);
}, [props.name]);
return (
<div className="flex items-center">
{ editing ? (
{editing ? (
<Input
ref={ ref }
ref={ref}
name="name"
value={name}
// readOnly={!editing}
onChange={write}
onBlur={onBlur}
onFocus={() => setEditing(true)}
className='bg-white'
onKeyDown={onKeyDown}
className="bg-white text-lg border-transparent rounded-lg font-medium ps-2"
/>
) : (
<div className="text-base h-8 flex items-center border-transparent">{name && name.trim() === '' ? 'Series ' + (seriesIndex + 1) : name }</div>
)}
<div className="ml-3 cursor-pointer " onClick={() => setEditing(true)}>
<Tooltip title='Rename' placement='bottom'>
<Icon name="pencil" size="14" />
<Tooltip title="Double click to rename.">
<div
className="text-lg font-medium h-8 flex items-center border-transparent p-2 hover:bg-teal/10 cursor-pointer rounded-lg input-rename-series"
onClick={() => setEditing(true)}
data-event='input-rename-series'
>
{name && name.trim() === '' ? 'Series ' + (seriesIndex + 1) : name}
</div>
</Tooltip>
</div>
)}
</div>
);
}

View file

@ -5,6 +5,7 @@ import { PlusOutlined } from '@ant-design/icons';
import AddCardSection from '../AddCardSection/AddCardSection';
import MetricsSearch from '../MetricsSearch';
import Select from 'Shared/Select';
import {Select as AntSelect} from 'antd';
import { useStore } from 'App/mstore';
import { observer, useObserver } from 'mobx-react-lite';
import { DROPDOWN_OPTIONS } from 'App/constants/card';
@ -44,9 +45,9 @@ function MetricViewHeader() {
<div className="border-y px-6 py-1 mt-2 flex items-center w-full justify-between">
<div className="items-center flex gap-4">
<Select
<AntSelect
options={[
{ label: 'All Types', value: 'all' },
{ label: 'All Card Types', value: 'all' },
...DROPDOWN_OPTIONS,
]}
name="type"
@ -54,8 +55,7 @@ function MetricViewHeader() {
onChange={({ value }) =>
metricStore.updateKey('filter', { ...filter, type: value.value })
}
plain={true}
isSearchable={true}
/>
<DashboardDropdown

View file

@ -517,7 +517,8 @@ function WidgetChart(props: Props) {
{renderChart()}
{props.isPreview && _metric.metricType === TIMESERIES ? (
<WidgetDatatable
defaultOpen={_metric.viewType === 'table'}
//defaultOpen={_metric.viewType === 'table'}
defaultOpen={true}
data={data}
enabledRows={enabledRows}
setEnabledRows={setEnabledRows}

View file

@ -125,6 +125,7 @@ function WidgetDatatable(props: Props) {
size={'small'}
type={'default'}
onClick={() => setShowTable(!showTable)}
className='btn-show-hide-table'
>
{showTable ? 'Hide Table' : 'Show Table'}
</Button>

View file

@ -43,7 +43,7 @@ function RangeGranularity({
return (
<Dropdown menu={menuProps} trigger={['click']}>
<Button type='text' variant='text' size='small'>
<Button type='text' variant='text' size='small' className='btn-granularity'>
<span>{selected}</span>
<DownOutlined />
</Button>

View file

@ -94,7 +94,7 @@ const FilterSection = observer(({ metric, excludeFilterKeys }: any) => {
if (!canAddSeries) return;
metric.addSeries();
}}
className="w-full cursor-pointer flex items-center py-2 justify-center gap-2"
className="w-full cursor-pointer flex items-center py-2 justify-center gap-2 font-medium hover:text-teal"
>
<PlusIcon size={16} />
Add Series

View file

@ -1,92 +1,80 @@
import React, { useState, useRef, useEffect } from 'react';
import { Icon, Tooltip } from 'UI';
import { Input } from 'antd';
import { Icon } from 'UI';
import { Input, Tooltip } from 'antd';
import cn from 'classnames';
interface Props {
name: string;
onUpdate: (name: any) => void;
onUpdate: (name: string) => void;
seriesIndex?: number;
canEdit?: boolean
canEdit?: boolean;
}
function WidgetName(props: Props) {
const { canEdit = true } = props;
const [editing, setEditing] = useState(false)
const [name, setName] = useState(props.name)
const ref = useRef<any>(null)
const [editing, setEditing] = useState(false);
const [name, setName] = useState(props.name);
const ref = useRef<any>(null);
const write = ({ target: { value } }) => {
setName(value)
}
setName(value);
};
const onBlur = (nameInput?: string) => {
setEditing(false)
const toUpdate = nameInput || name
props.onUpdate(toUpdate && toUpdate.trim() === '' ? 'New Widget' : toUpdate)
}
setEditing(false);
const toUpdate = nameInput || name;
props.onUpdate(toUpdate && toUpdate.trim() === '' ? 'New Widget' : toUpdate);
};
const onKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
onBlur(name);
}
if (e.key === 'Escape' || e.key === 'Esc') {
setEditing(false);
}
};
useEffect(() => {
if (editing) {
ref.current.focus()
ref.current.focus();
}
}, [editing])
}, [editing]);
useEffect(() => {
setName(props.name)
}, [props.name])
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.key === 'Enter') {
onBlur(name)
}
if (e.key === 'Escape' || e.key === 'Esc') {
setEditing(false)
}
}
document.addEventListener('keydown', handler, false)
return () => {
document.removeEventListener('keydown', handler, false)
}
}, [name])
setName(props.name);
}, [props.name]);
return (
<div className="flex items-center">
{ editing ? (
{editing ? (
<Input
ref={ ref }
ref={ref}
name="name"
value={name}
onChange={write}
onBlur={() => onBlur()}
onKeyDown={onKeyDown}
onFocus={() => setEditing(true)}
maxLength={80}
className="bg-white text-2xl ps-2 rounded-lg h-8"
/>
) : (
// @ts-ignore
<Tooltip delay={200} title="Double click to edit" disabled={!canEdit}>
<div
onDoubleClick={() => setEditing(true)}
className={
cn(
"text-2xl h-8 flex items-center border-transparent",
canEdit && 'cursor-pointer select-none border-b border-b-borderColor-transparent hover:border-dotted hover:border-gray-medium'
)
}
className={cn(
"text-2xl h-8 flex items-center p-2 rounded-lg",
canEdit && 'cursor-pointer select-none ps-2 hover:bg-teal/10'
)}
>
{ name }
{name}
</div>
</Tooltip>
)}
{ canEdit && <div className="ml-3 cursor-pointer" onClick={() => setEditing(true)}>
<Tooltip title='Rename' placement='bottom'>
<Icon name="pencil" size="16" />
</Tooltip>
</div> }
</div>
);
}
export default WidgetName;
export default WidgetName;

View file

@ -112,7 +112,7 @@ const SeriesTypeOptions = observer(({ metric }: { metric: any }) => {
},
}}
>
<Button type='text' variant='text' size='small'>
<Button type='text' variant='text' size='small' className='btn-aggregator'>
<Space>
{chartIcons[metric.metricOf]}
<div>{items[metric.metricOf] || 'Total Sessions'}</div>
@ -179,7 +179,7 @@ const WidgetViewTypeOptions = observer(({ metric }: { metric: any }) => {
}}
>
<Button type='text' variant='text' size='small'>
<Button type='text' variant='text' size='small' className='btn-visualization-type'>
<Space>
{chartIcons[metric.viewType]}
<div>{chartTypes[metric.viewType]}</div>

View file

@ -1,16 +1,18 @@
// Components/CardViewMenu.tsx
import { useHistory } from 'react-router';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import { Button, Dropdown, MenuProps, message, Modal } from 'antd';
import { BellIcon, EllipsisVertical, TrashIcon } from 'lucide-react';
import { Button, Dropdown, MenuProps, Modal } from 'antd';
import { BellIcon, EllipsisVertical, Grid2x2Plus, TrashIcon } from 'lucide-react';
import { toast } from 'react-toastify';
import React from 'react';
import { useModal } from 'Components/ModalContext';
import AlertFormModal from 'Components/Alerts/AlertFormModal/AlertFormModal';
import { showAddToDashboardModal } from 'Components/Dashboard/components/AddToDashboardButton';
const CardViewMenu = () => {
const history = useHistory();
const { alertsStore, metricStore } = useStore();
const { alertsStore, metricStore, dashboardStore } = useStore();
const widget = metricStore.instance;
const { openModal, closeModal } = useModal();
@ -18,13 +20,19 @@ const CardViewMenu = () => {
const seriesId = (widget.series[0] && widget.series[0].seriesId) || '';
alertsStore.init({ query: { left: seriesId } });
openModal(<AlertFormModal onClose={closeModal} />, {
// title: 'Set Alerts',
placement: 'right',
width: 620,
});
};
const items: MenuProps['items'] = [
{
key: 'add-to-dashboard',
label: 'Add to Dashboard',
icon: <Grid2x2Plus size={16} />,
disabled: !widget.exists(),
onClick: () => showAddToDashboardModal(widget.metricId, dashboardStore),
},
{
key: 'alert',
label: 'Set Alerts',
@ -35,7 +43,7 @@ const CardViewMenu = () => {
{
key: 'remove',
label: 'Delete',
icon: <TrashIcon size={16} />,
icon: <TrashIcon size={15} />,
disabled: !widget.exists(),
onClick: () => {
Modal.confirm({
@ -52,7 +60,7 @@ const CardViewMenu = () => {
onOk: () => {
metricStore
.delete(widget)
.then((r) => {
.then(() => {
history.goBack();
})
.catch(() => {
@ -64,41 +72,13 @@ const CardViewMenu = () => {
},
];
const onClick: MenuProps['onClick'] = ({ key }) => {
if (key === 'alert') {
message.info('Set Alerts');
} else if (key === 'remove') {
Modal.confirm({
title: 'Are you sure you want to remove this card?',
icon: null,
// content: 'Bla bla ...',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<CancelBtn />
<OkBtn />
</>
),
onOk: () => {
metricStore
.delete(widget)
.then((r) => {
history.goBack();
})
.catch(() => {
toast.error('Failed to remove card');
});
},
});
}
};
return (
<div className="flex items-center justify-between">
<Dropdown menu={{ items }}>
<Button icon={<EllipsisVertical size={16} />} />
<Button type='text' icon={<EllipsisVertical size={16} />} className='btn-card-options' />
</Dropdown>
</div>
);
};
export default observer(CardViewMenu);
export default observer(CardViewMenu);

View file

@ -3,7 +3,7 @@ import cn from 'classnames';
import WidgetName from 'Components/Dashboard/components/WidgetName';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import AddToDashboardButton from 'Components/Dashboard/components/AddToDashboardButton';
import { Button, Space, Tooltip } from 'antd';
import CardViewMenu from 'Components/Dashboard/components/WidgetView/CardViewMenu';
import { Link2 } from 'lucide-react'
@ -31,11 +31,11 @@ function WidgetViewHeader({ onClick, onSave }: Props) {
return (
<div
className={cn(
'flex justify-between items-center bg-white rounded px-4 py-2 border border-gray-lighter'
'flex justify-between items-center bg-white rounded-lg shadow-sm px-4 ps-2 py-2 border border-gray-lighter input-card-title'
)}
onClick={onClick}
>
<h1 className="mb-0 text-2xl mr-4 min-w-fit">
<h1 className="mb-0 text-2xl mr-4 min-w-fit ">
<WidgetName
name={widget.name}
onUpdate={(name) => metricStore.merge({ name })}
@ -43,20 +43,28 @@ function WidgetViewHeader({ onClick, onSave }: Props) {
/>
</h1>
<Space>
<AddToDashboardButton metricId={widget.metricId} />
<MetricTypeSelector />
<Tooltip title={tooltipText}>
<Button disabled={!widget.exists()} onClick={copyUrl} icon={<Link2 size={16} strokeWidth={1} />}></Button>
</Tooltip>
<Button
type="primary"
<Button
type={
metricStore.isSaving || (widget.exists() && !widget.hasChanged) ? 'text' : 'primary'
}
onClick={onSave}
loading={metricStore.isSaving}
disabled={metricStore.isSaving || (widget.exists() && !widget.hasChanged)}
className='font-medium btn-update-card'
>
{widget.exists() ? 'Update' : 'Create'}
</Button>
<MetricTypeSelector />
<Tooltip title={tooltipText}>
<Button type='text' className='btn-copy-card-url' disabled={!widget.exists()} onClick={copyUrl} icon={<Link2 size={16} strokeWidth={1}/> }></Button>
</Tooltip>
<CardViewMenu />
</Space>
</div>
);

View file

@ -90,7 +90,7 @@ function FunnelBarData({
bottom: 0,
background: isFocused
? 'rgba(204, 0, 0, 0.3)'
: 'repeating-linear-gradient(325deg, lightgray, lightgray 2px, #FFF1F0 2px, #FFF1F0 6px)',
: 'repeating-linear-gradient(325deg, lightgray, lightgray 1px, #FFF1F0 1px, #FFF1F0 6px)',
cursor: 'pointer',
}
const horizontalEmptyBarStyle = {
@ -102,7 +102,7 @@ function FunnelBarData({
left: 0,
background: isFocused
? 'rgba(204, 0, 0, 0.3)'
: 'repeating-linear-gradient(325deg, lightgray, lightgray 2px, #FFF1F0 2px, #FFF1F0 6px)',
: 'repeating-linear-gradient(325deg, lightgray, lightgray 1px, #FFF1F0 1px, #FFF1F0 6px)',
cursor: 'pointer',
}

View file

@ -1,10 +1,10 @@
import React from 'react';
import { Table } from 'antd';
import { Table, Tooltip } from 'antd';
import type { TableProps } from 'antd';
import Widget from 'App/mstore/types/widget';
import Funnel from 'App/mstore/types/funnel';
import { ItemMenu } from 'UI';
import { EllipsisVertical } from 'lucide-react';
import { EllipsisVertical, FileDown } from 'lucide-react';
import { exportAntCsv } from '../../../utils';
interface Props {
@ -101,30 +101,27 @@ export function TableExporter({
}) {
const onClick = () => exportAntCsv(tableColumns, tableData, filename);
return (
<Tooltip title='Export Data to CSV'>
<div
className={`absolute ${top ? top : 'top-0'} ${
right ? right : '-right-1'
}`}
>
<ItemMenu
items={[{ icon: 'pencil', text: 'Export', onClick }]}
items={[{ icon: 'download', text: 'Export to CSV', onClick }]}
bold
customTrigger={
<div
className={
'flex items-center justify-center bg-gray-lighter cursor-pointer hover:bg-gray-light'
}
style={{
height: 38,
width: 38,
boxShadow: '-2px 0px 3px 0px rgba(0, 0, 0, 0.05)',
}}
>
<div
className={
'flex items-center justify-center bg-gradient-to-r from-[#fafafa] to-neutral-200 cursor-pointer rounded-lg h-[38px] w-[38px] btn-export-table-data'
}
>
<EllipsisVertical size={16} />
</div>
}
/>
</div>
</Tooltip>
);
}

View file

@ -134,10 +134,10 @@ export function AutocompleteModal({
</>
</Loader>
<div className={'flex gap-2 items-center pt-2'}>
<Button type={'primary'} onClick={applyValues}>
<Button type={'primary'} onClick={applyValues} className='btn-apply-event-value'>
Apply
</Button>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={onClose} className='btn-cancel-event-value'>Cancel</Button>
</div>
</OutsideClickDetectingDiv>
);

View file

@ -91,7 +91,7 @@ function FilterItem(props: Props) {
<FilterOperator
options={filter.sourceOperatorOptions}
onChange={onSourceOperatorChange}
className="mx-2 flex-shrink-0"
className="mx-2 flex-shrink-0 btn-event-operator"
value={filter.sourceOperator}
isDisabled={filter.operatorDisabled || props.readonly}
/>
@ -105,7 +105,7 @@ function FilterItem(props: Props) {
<FilterOperator
options={filter.operatorOptions}
onChange={onOperatorChange}
className="mx-2 flex-shrink-0"
className="mx-2 flex-shrink-0 btn-sub-event-operator"
value={filter.operator}
isDisabled={filter.operatorDisabled || props.readonly}
/>
@ -157,6 +157,7 @@ function FilterItem(props: Props) {
type="text"
onClick={props.onRemoveFilter}
size="small"
className='btn-remove-step'
>
<CircleMinus size={14} />
</Button>

View file

@ -38,14 +38,15 @@ const EventsOrder = observer(
title="Select the operator to be applied between events."
placement="bottom"
>
<div className="text-neutral-500/90 text-sm">Events Order</div>
<div className="text-neutral-500/90 text-sm font-normal">Events Order</div>
</Tooltip>
<Dropdown
menu={{ items: menuItems, onClick }}
trigger={['click']}
placement="bottomRight"
className="bg-white border border-neutral-200 rounded-lg px-1 py-0.5 hover:border-teal"
className="bg-white border font-normal text-sm border-neutral-200 rounded-lg px-1 py-0.5 hover:border-teal btn-events-order"
data-event="btn-events-order"
>
<Button size={'small'}>{selected || 'Select'}</Button>
</Dropdown>

View file

@ -70,6 +70,7 @@ export const FilterList = observer((props: Props) => {
icon={<Filter size={16} strokeWidth={1} />}
type="default"
size={'small'}
className='btn-add-filter'
>
Add
</Button>
@ -214,6 +215,7 @@ export const EventsList = observer((props: Props) => {
icon={<Plus size={16} strokeWidth={1} />}
type="default"
size={'small'}
className='btn-add-event'
>
Add
</Button>
@ -228,27 +230,39 @@ export const EventsList = observer((props: Props) => {
actions.map((action, index) => <div key={index}>{action}</div>)}
</div>
</div>
<div className={'flex flex-col'}>
<div className={'flex flex-col '}>
{filters.map((filter: any, filterIndex: number) =>
filter.isEvent ? (
<div
className={cn(
'hover:bg-active-blue px-5 pe-3 gap-2 items-center flex',
{
'bg-[#f6f6f6]': hoveredItem.i === filterIndex,
}
)}
style={{
pointerEvents: 'unset',
paddingTop:
hoveredItem.i === filterIndex &&
hoveredItem.position === 'top'
hoveredItem.i === filterIndex && hoveredItem.position === 'top'
? '1.5rem'
: '0.5rem',
paddingBottom:
hoveredItem.i === filterIndex &&
hoveredItem.position === 'bottom'
hoveredItem.i === filterIndex && hoveredItem.position === 'bottom'
? '1.5rem'
: '0.5rem',
marginLeft: '-1.25rem',
width: 'calc(100% + 2.5rem)',
marginLeft: '-1rem',
width: 'calc(100% + 2rem)',
alignItems: 'start',
borderTop:
hoveredItem.i === filterIndex && hoveredItem.position === 'top'
? '1px dashed #888'
: undefined,
borderBottom:
hoveredItem.i === filterIndex && hoveredItem.position === 'bottom'
? '1px dashed #888'
: undefined,
}}
className={'hover:bg-active-blue px-5 gap-2 items-center flex'}
id={`${filter.key}-${filterIndex}`}
onDragOver={(e) => handleDragOverEv(e, filterIndex)}
onDrop={(e) => handleDrop(e)}
@ -257,16 +271,19 @@ export const EventsList = observer((props: Props) => {
{!!props.onFilterMove && eventsNum > 1 ? (
<div
className={
'p-2 cursor-grab text-neutral-500/90 hover:bg-gray-lighter px-1 pt-2 rounded-lg'
'p-2 cursor-grab text-neutral-500/90 hover:bg-white px-1 pt-2 rounded-lg'
}
draggable={!!props.onFilterMove}
onDragStart={(e) =>
handleDragStart(
e,
filterIndex,
`${filter.key}-${filterIndex}`
)
handleDragStart(e, filterIndex, `${filter.key}-${filterIndex}`)
}
onDragEnd={() => {
setHoveredItem({ i: null, position: null });
setDraggedItem(null);
}}
style={{
cursor: draggedInd !== null ? 'grabbing' : 'grab',
}}
>
<GripVertical size={16} />
</div>

View file

@ -1,3 +1,4 @@
import { backgroundClip } from 'html2canvas/dist/types/css/property-descriptors/background-clip';
import React from 'react';
import Select from 'Shared/Select';
@ -5,14 +6,18 @@ const dropdownStyles = {
control: (provided: any) => {
const obj = {
...provided,
border: 'solid thin #ddd !important',
border: 'solid thin #ddd',
boxShadow: 'none !important',
cursor: 'pointer',
height: '26px',
minHeight: '26px',
backgroundColor: 'white',
borderRadius: '.5rem',
'&:hover': {
borderColor: 'rgb(115 115 115 / 0.9)',
}
}
return obj;
},
valueContainer: (provided: any) => ({
@ -79,6 +84,7 @@ function FilterOperator(props: Props) {
isDisabled={isDisabled}
value={value ? options?.find((i: any) => i.value === value) : null}
onChange={({ value }: any) => onChange(null, { name: 'operator', value: value.value })}
className='btn-event-operator'
/>
</div>
);

View file

@ -62,7 +62,7 @@ function FilterSelection(props: Props) {
) : (
<div
className={cn(
'rounded-lg py-1 px-2 flex items-center gap-1 cursor-pointer bg-white border border-gray-light text-ellipsis hover:border-neutral-400',
'rounded-lg py-1 px-2 flex items-center gap-1 cursor-pointer bg-white border border-gray-light text-ellipsis hover:border-neutral-400 btn-select-event',
{ 'opacity-50 pointer-events-none': disabled }
)}
style={{
@ -70,8 +70,8 @@ function FilterSelection(props: Props) {
}}
onClick={() => setShowModal(true)}
>
<div className='text-xs text-neutral-500/90'>{getNewIcon(filter)}</div>
<div className={'text-neutral-500/90 flex gap-2'}>{`${filter.category}`}</div>
<div className='text-xs text-neutral-500/90 hover:border-neutral-400 '>{getNewIcon(filter)}</div>
<div className={'text-neutral-500/90 flex gap-2 hover:border-neutral-400 '}>{`${filter.category}`}</div>
<div
className="rounded-lg overflow-hidden whitespace-nowrap text-ellipsis mr-auto truncate "
style={{ textOverflow: 'ellipsis' }}

View file

@ -23,7 +23,7 @@ export default function SubFilterItem(props: Props) {
<FilterOperator
options={filter.operatorOptions}
onChange={onOperatorChange}
className="mx-2 flex-shrink-0"
className="mx-2 flex-shrink-0 btn-filter-operator"
value={filter.operator}
/>

View file

@ -197,7 +197,7 @@ function AndDateRange({
{comparison ? (
<div className={'flex items-center gap-0'}>
<Dropdown menu={menuProps} trigger={['click']} className={'px-2 py-1 gap-1'}>
<Button type='text' variant='text' className='flex items-center' size='small'>
<Button type='text' variant='text' className='flex items-center btn-compare-card-data' size='small'>
<span>{`Compare to ${comparisonValue || ''}`}</span>
{selectedValue && (
<Tooltip title='Reset'>
@ -220,7 +220,7 @@ function AndDateRange({
<Button
type="text"
size='small'
className="flex items-center"
className="flex items-center btn-card-period-range"
icon={useButtonStyle ? <Calendar size={16} /> : null}
>
{isCustomRange ? customRange : selectedValue?.label}

View file

@ -363,8 +363,8 @@ p {
135deg,
transparent,
transparent 2px,
#ccc 2px,
#ccc 4px
#ccc 1px,
#ccc 1px
);
}