mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-10-15 21:21:30 +08:00

* feat: funnels list page basic UI * feat: get funnels list data from mock API, and handle data, loading and empty states * feat: implement funnel rename * chore: move useFunnels to hooks/TracesFunnels * feat: create traces funnels details basic page + funnel -> details redirection * fix: properly display created at in funnels list item + preventDefault * chore: add tab bar to trace funnel details page * chore: traces funnel details page overall skeleton * chore: traces funnel details results skeleton * fix: hide step count for add button only * feat: funnel details page steps and configuration (#7424) * chore: add a new tab for traces funnels * feat: funnels list page basic UI * feat: get funnels list data from mock API, and handle data, loading and empty states * feat: implement funnel rename * refactor: overall improvements * feat: implement sorting in traces funnels list page * feat: add sort column key and order to url params * chore: move useFunnels to hooks/TracesFunnels * feat: implement traces funnels search and refactor search and sort by extracting to custom hooks * chore: overall improvements to rename trace funnel modal * chore: make the rename input auto-focusable * feat: handle create funnel modal * feat: delete funnel modal and functionality * fix: fix the layout shift in funnel item caused by getContainer={false} * chore: overall improvements and use live api in traces funnels * feat: create traces funnels details basic page + funnel -> details redirection * fix: funnels traces light mode UI * fix: properly display created at in funnels list item + preventDefault * refactor: extract FunnelItemPopover into a separate component * chore: hide funnel tab from traces explorer * chore: add check to display trace funnels tab only in dev environment * chore: improve funnels modals light mode * chore: overall improvements * fix: properly pass funnel details link * chore: address PR review changes * chore: add tab bar to trace funnel details page * feat: funnel step UI with service, span, and where filters * feat: build radio button component * refactor: use the SignozRadioButton in funnel results -> step transitions radio buttons * feat: inter step config (i.e. latency type) UI * chore: improve steps header styles by removing divider width * feat: funnel steps title, description, popover UI + pass data from API * chore: update FilterSelect component to conditionally add url params and accept on change * fix: fix funnel step where clause and update the state variables for filters * chore: add support for isMultiple and fix the type in FilterSelect * feat: centralize the steps state management in StepsContent * fix: move steps state up + pass steps count from state * feat: implement auto save for updating the steps whenever any step changes * feat: implement auto save for validating steps if service name or span names change * feat: impelement funnel step removal * feat: implement add details modal for funnel steps * fix: fix the overflowing time range picker * feat: funnel details empty state * feat: add support for saving funnel description * chore: overall improvements * fix: fix the light mode styles * fix: fix the failing build + broken search UI * refactor: remove the reference of useLocation from traceFunnel item in TraceModulePage constant * fix: fix the issue of update steps getting triggered on initial render if we have filters * fix: fix the edge case of stale state causing filters to be re-added after removing * feat: funnel details page results (#7451) * feat: funnel metrics table component * feat: funnel metrics and steps transition metrics components UI * feat: funnel table component * feat: slowest traces and traces with error components * fix: overall light theme fixes * fix: fix the warning * chore: add empty and loading states to FunnelMetricsTable * feat: get overall funnel metrics from the API * fix: fix the empty state of funnel metrics table * feat: get data for slowest traces and traces with errors * fix: link trace id to trace details page * fix: get data for funnel step transition metrics and refactor the existing data fetching logic * refactor: add funnel context + overall refactoring and optimizations * refactor: move steps states to funnel context + handle empty and run funnel disabled states * feat: handle run funnel * fix: improve empty state * chore: rename isValidateStepsMutationLoading -> isValidateStepsLoading * chore: improve query key * fix: display loading state if funnel results are fetching * refactor: move steps validation fetching and states to the context API * fix: display loading state in funnel results while steps validation is fetching * fix: call validate steps API only on changing the service name or span name of any step * refactor: move validateStepsQuery key out of useEffect and update the dependencies * chore: centralize hasIncompleteSteps and run validate only if steps have service and spans * fix: handle all empty fields state + overall improvements * fix: handle long where query tags * feat: build the funnel result graph component * feat: build the funnel result graph component * feat: handle loading, error, empty states in funnel graph * fix: don't display change percentage if % is 0 * refactor: overall improvements * feat: get funnel steps graph data from API + move logic to custom hook * fix: improve empty and error states * fix: handle funnel graph legends width using css * fix: redirect to trace funnels list page on clicking delete from funnel details * fix: update the query cache while updating steps * fix: implement debounced search for funnel list search * fix: refetch steps graph data query on clicking run funnel / sync button * fix: improve the step footer spacing * chore: add gap between divider to inter-step-config * fix: handle loading state while fetching * feat: add span to funnel flow (from trace details page) (#7477) * chore: display add to funnel icon on hovering any span in trace details page * chore: add className to funnel item actions popover * feat: add funnels tab to trace details v2 tab bar * feat: add span to funnel flow * chore: hide actions popover button from funnel item in span -> funnel flows * chore: improve the funnel details UI in add span to funnel modal * fix: display empty state + don't redirect to funnels list on delete success + overall improvements * chore: add null check * fix: display add to funnel button based on feature flag * fix: display funnels tab in trace details based on feature flag * fix: remove maxTagCount * feat: change ms to ns * chore: address review comments * chore: remove feature flag and display trace funnels only in dev envirnoment * fix: handle restoring steps if updating funnel steps fail * refactor: update the get and delete funnel endpoints to adjust to the BE changes (#7697) * refactor: address review comments * fix: handle nested funnel response structure to fix missing funnel_id… (#7740) * fix: handle nested funnel response structure to fix missing funnel_id in updates Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: remove console.og Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * chore: revert explicitly passing funnelId to updateFunnelSteps --------- Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> Co-authored-by: ahmadshaheer <ashaheerki@gmail.com> * chore: fix api endpoint Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> * refactor: incorporate the recent funnel details API changes (#7760) * chore: trace funnels feedback changes (#7772) * chore: change the copy from x traces to valid traces found / not found * chore: add open funnel button in add span to funnel modal * feat: display buttons for adding step details and funnel description + copy to clipboard * feat: highlight funnel graph column based on selected (total / error span) from the legend items * chore: trace funnel changes (#7780) * refactor: handle funnels list search on frontend * refactor: use funnel steps update API for adding / updating step title and description * feat: allow selecting user's typed option in trace funnel service and span name dropdowns * chore: properly render the -> between steps in funnel results * fix: sync funnel step name with add details modal text fields --------- Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com> Co-authored-by: Yunus M <myounis.ar@live.com> Co-authored-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
208 lines
6.1 KiB
TypeScript
208 lines
6.1 KiB
TypeScript
import './FunnelStep.styles.scss';
|
|
|
|
import { Button, Divider, Dropdown, Form, Space, Switch, Tooltip } from 'antd';
|
|
import { MenuProps } from 'antd/lib';
|
|
import { FilterSelect } from 'components/CeleryOverview/CeleryOverviewConfigOptions/CeleryOverviewConfigOptions';
|
|
import { QueryParams } from 'constants/query';
|
|
import { initialQueriesMap } from 'constants/queryBuilder';
|
|
import QueryBuilderSearchV2 from 'container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2';
|
|
import { ChevronDown, GripVertical, HardHat, PencilLine } from 'lucide-react';
|
|
import { LatencyPointers } from 'pages/TracesFunnelDetails/constants';
|
|
import { useFunnelContext } from 'pages/TracesFunnels/FunnelContext';
|
|
import { useMemo, useState } from 'react';
|
|
import { FunnelStepData } from 'types/api/traceFunnels';
|
|
import { DataSource } from 'types/common/queryBuilder';
|
|
|
|
import FunnelStepPopover from './FunnelStepPopover';
|
|
|
|
interface FunnelStepProps {
|
|
stepData: FunnelStepData;
|
|
index: number;
|
|
stepsCount: number;
|
|
}
|
|
|
|
function FunnelStep({
|
|
stepData,
|
|
index,
|
|
stepsCount,
|
|
}: FunnelStepProps): JSX.Element {
|
|
const {
|
|
handleStepChange: onStepChange,
|
|
handleStepRemoval: onStepRemove,
|
|
} = useFunnelContext();
|
|
const [form] = Form.useForm();
|
|
const currentQuery = initialQueriesMap[DataSource.TRACES];
|
|
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
|
|
const [isAddDetailsModalOpen, setIsAddDetailsModalOpen] = useState<boolean>(
|
|
false,
|
|
);
|
|
|
|
const latencyPointerItems: MenuProps['items'] = LatencyPointers.map(
|
|
(option) => ({
|
|
key: option.value,
|
|
label: option.key,
|
|
style:
|
|
option.value === stepData.latency_pointer
|
|
? { backgroundColor: 'var(--bg-slate-100)' }
|
|
: {},
|
|
}),
|
|
);
|
|
|
|
const updatedCurrentQuery = useMemo(
|
|
() => ({
|
|
...currentQuery,
|
|
builder: {
|
|
...currentQuery.builder,
|
|
queryData: [
|
|
{
|
|
...currentQuery.builder.queryData[0],
|
|
dataSource: DataSource.TRACES,
|
|
filters: stepData.filters ?? {
|
|
op: 'AND',
|
|
items: [],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
[stepData.filters, currentQuery],
|
|
);
|
|
|
|
const query = updatedCurrentQuery?.builder?.queryData[0] || null;
|
|
|
|
return (
|
|
<div className="funnel-step">
|
|
<Form form={form}>
|
|
<div className="funnel-step__header">
|
|
<div className="funnel-step-details">
|
|
{stepData.name ? (
|
|
<div className="funnel-step-details__title">{stepData.name}</div>
|
|
) : (
|
|
<div className="funnel-step-details__title">Step {index + 1}</div>
|
|
)}
|
|
{!!stepData.description && (
|
|
<div className="funnel-step-details__description">
|
|
{stepData.description}
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="funnel-step-actions">
|
|
<Tooltip title="Add details to step">
|
|
<Button
|
|
type="text"
|
|
className="funnel-item__action-btn"
|
|
icon={<PencilLine size={14} />}
|
|
onClick={(): void => setIsAddDetailsModalOpen(true)}
|
|
/>
|
|
</Tooltip>
|
|
|
|
<Divider type="vertical" />
|
|
<FunnelStepPopover
|
|
isPopoverOpen={isPopoverOpen}
|
|
setIsPopoverOpen={setIsPopoverOpen}
|
|
onStepRemove={(): void => onStepRemove(index)}
|
|
stepsCount={stepsCount}
|
|
isAddDetailsModalOpen={isAddDetailsModalOpen}
|
|
setIsAddDetailsModalOpen={setIsAddDetailsModalOpen}
|
|
stepData={{
|
|
step_order: stepData.step_order,
|
|
name: stepData.name,
|
|
description: stepData.description,
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="funnel-step__content">
|
|
<div className="drag-icon">
|
|
<GripVertical size={14} color="var(--bg-slate-200)" />
|
|
</div>
|
|
<div className="filters">
|
|
<div className="filters__service-and-span">
|
|
<div className="service">
|
|
<Form.Item name={['steps', stepData.id, 'service_name']}>
|
|
<FilterSelect
|
|
placeholder="Select Service"
|
|
queryParam={QueryParams.service}
|
|
filterType="serviceName"
|
|
shouldSetQueryParams={false}
|
|
values={stepData.service_name}
|
|
isMultiple={false}
|
|
onChange={(v): void => {
|
|
onStepChange(index, { service_name: (v ?? '') as string });
|
|
}}
|
|
/>
|
|
</Form.Item>
|
|
</div>
|
|
<div className="span">
|
|
<Form.Item name={['steps', stepData.id, 'span_name']}>
|
|
<FilterSelect
|
|
placeholder="Select Span name"
|
|
queryParam={QueryParams.spanName}
|
|
filterType="name"
|
|
shouldSetQueryParams={false}
|
|
values={stepData.span_name}
|
|
isMultiple={false}
|
|
onChange={(v): void =>
|
|
onStepChange(index, { span_name: (v ?? '') as string })
|
|
}
|
|
/>
|
|
</Form.Item>
|
|
</div>
|
|
</div>
|
|
<div className="filters__where-filter">
|
|
<div className="label">Where</div>
|
|
<Form.Item name={['steps', stepData.id, 'filters']}>
|
|
<QueryBuilderSearchV2
|
|
query={query}
|
|
onChange={(query): void => onStepChange(index, { filters: query })}
|
|
hasPopupContainer={false}
|
|
placeholder="Search for filters..."
|
|
suffixIcon={<HardHat size={12} color="var(--bg-vanilla-400)" />}
|
|
rootClassName="traces-funnel-where-filter"
|
|
/>
|
|
</Form.Item>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="funnel-step__footer">
|
|
<div className="error">
|
|
<Switch
|
|
className="error__switch"
|
|
size="small"
|
|
checked={stepData.has_errors}
|
|
onChange={(): void =>
|
|
onStepChange(index, { has_errors: !stepData.has_errors })
|
|
}
|
|
/>
|
|
<div className="error__label">Errors</div>
|
|
</div>
|
|
<div className="latency-pointer">
|
|
<div className="latency-pointer__label">Latency pointer</div>
|
|
<Dropdown
|
|
menu={{
|
|
items: latencyPointerItems,
|
|
onClick: ({ key }): void =>
|
|
onStepChange(index, {
|
|
latency_pointer: key as FunnelStepData['latency_pointer'],
|
|
}),
|
|
}}
|
|
trigger={['click']}
|
|
>
|
|
<Space>
|
|
{
|
|
LatencyPointers.find(
|
|
(option) => option.value === stepData.latency_pointer,
|
|
)?.key
|
|
}
|
|
<ChevronDown size={14} color="var(--bg-vanilla-400)" />
|
|
</Space>
|
|
</Dropdown>
|
|
</div>
|
|
</div>
|
|
</Form>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default FunnelStep;
|