@ant-design/icons#FlagOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#FlagOutlined.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: commandPaletteLogic.ts From posthog-foss with MIT License | 4 votes |
commandPaletteLogic = kea<
commandPaletteLogicType<
Command,
CommandFlow,
CommandRegistrations,
CommandResult,
CommandResultDisplayable,
RegExpCommandPairs
>
>({
path: ['lib', 'components', 'CommandPalette', 'commandPaletteLogic'],
connect: {
actions: [personalAPIKeysLogic, ['createKey']],
values: [teamLogic, ['currentTeam'], userLogic, ['user']],
logic: [preflightLogic], // used in afterMount, which does not auto-connect
},
actions: {
hidePalette: true,
showPalette: true,
togglePalette: true,
setInput: (input: string) => ({ input }),
onArrowUp: true,
onArrowDown: (maxIndex: number) => ({ maxIndex }),
onMouseEnterResult: (index: number) => ({ index }),
onMouseLeaveResult: true,
executeResult: (result: CommandResult) => ({ result }),
activateFlow: (flow: CommandFlow | null) => ({ flow }),
backFlow: true,
registerCommand: (command: Command) => ({ command }),
deregisterCommand: (commandKey: string) => ({ commandKey }),
setCustomCommand: (commandKey: string) => ({ commandKey }),
deregisterScope: (scope: string) => ({ scope }),
},
reducers: {
isPaletteShown: [
false,
{
hidePalette: () => false,
showPalette: () => true,
togglePalette: (previousState) => !previousState,
},
],
keyboardResultIndex: [
0,
{
setInput: () => 0,
executeResult: () => 0,
activateFlow: () => 0,
backFlow: () => 0,
onArrowUp: (previousIndex) => (previousIndex > 0 ? previousIndex - 1 : 0),
onArrowDown: (previousIndex, { maxIndex }) => (previousIndex < maxIndex ? previousIndex + 1 : maxIndex),
},
],
hoverResultIndex: [
null as number | null,
{
activateFlow: () => null,
backFlow: () => null,
onMouseEnterResult: (_, { index }) => index,
onMouseLeaveResult: () => null,
onArrowUp: () => null,
onArrowDown: () => null,
},
],
input: [
'',
{
setInput: (_, { input }) => input,
activateFlow: () => '',
backFlow: () => '',
executeResult: () => '',
},
],
activeFlow: [
null as CommandFlow | null,
{
activateFlow: (currentFlow, { flow }) =>
flow ? { ...flow, scope: flow.scope ?? currentFlow?.scope, previousFlow: currentFlow } : null,
backFlow: (currentFlow) => currentFlow?.previousFlow ?? null,
},
],
rawCommandRegistrations: [
{} as CommandRegistrations,
{
registerCommand: (commands, { command }) => {
return { ...commands, [command.key]: command }
},
deregisterCommand: (commands, { commandKey }) => {
const { [commandKey]: _, ...cleanedCommands } = commands // eslint-disable-line
return cleanedCommands
},
},
],
},
listeners: ({ actions, values }) => ({
showPalette: () => {
posthog.capture('palette shown', { isMobile: isMobile() })
},
togglePalette: () => {
if (values.isPaletteShown) {
posthog.capture('palette shown', { isMobile: isMobile() })
}
},
executeResult: ({ result }: { result: CommandResult }) => {
if (result.executor === true) {
actions.activateFlow(null)
actions.hidePalette()
} else {
const possibleFlow = result.executor?.() || null
actions.activateFlow(possibleFlow)
if (!possibleFlow) {
actions.hidePalette()
}
}
// Capture command execution, without useless data
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { icon, index, ...cleanedResult }: Record<string, any> = result
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { resolver, ...cleanedCommand } = cleanedResult.source
cleanedResult.source = cleanedCommand
cleanedResult.isMobile = isMobile()
posthog.capture('palette command executed', cleanedResult)
},
deregisterScope: ({ scope }) => {
for (const command of Object.values(values.commandRegistrations)) {
if (command.scope === scope) {
actions.deregisterCommand(command.key)
}
}
},
setInput: async ({ input }, breakpoint) => {
await breakpoint(300)
if (input.length > 8) {
const response = await api.get('api/person/?key_identifier=' + encodeURIComponent(input))
const person = response.results[0]
if (person) {
actions.registerCommand({
key: `person-${person.distinct_ids[0]}`,
resolver: [
{
icon: UserOutlined,
display: `View person ${input}`,
executor: () => {
const { push } = router.actions
push(urls.person(person.distinct_ids[0]))
},
},
],
scope: GLOBAL_COMMAND_SCOPE,
})
}
}
},
}),
selectors: {
isSqueak: [
(selectors) => [selectors.input],
(input: string) => {
return input.trim().toLowerCase() === 'squeak'
},
],
activeResultIndex: [
(selectors) => [selectors.keyboardResultIndex, selectors.hoverResultIndex],
(keyboardResultIndex: number, hoverResultIndex: number | null) => {
return hoverResultIndex ?? keyboardResultIndex
},
],
commandRegistrations: [
(selectors) => [
selectors.rawCommandRegistrations,
dashboardsModel.selectors.nameSortedDashboards,
teamLogic.selectors.currentTeam,
],
(rawCommandRegistrations: CommandRegistrations, dashboards: DashboardType[]): CommandRegistrations => ({
...rawCommandRegistrations,
custom_dashboards: {
key: 'custom_dashboards',
resolver: dashboards.map((dashboard: DashboardType) => ({
key: `dashboard_${dashboard.id}`,
icon: LineChartOutlined,
display: `Go to Dashboard: ${dashboard.name}`,
executor: () => {
const { push } = router.actions
push(urls.dashboard(dashboard.id))
},
})),
scope: GLOBAL_COMMAND_SCOPE,
},
}),
],
regexpCommandPairs: [
(selectors) => [selectors.commandRegistrations],
(commandRegistrations: CommandRegistrations) => {
const array: RegExpCommandPairs = []
for (const command of Object.values(commandRegistrations)) {
if (command.prefixes) {
array.push([new RegExp(`^\\s*(${command.prefixes.join('|')})(?:\\s+(.*)|$)`, 'i'), command])
} else {
array.push([null, command])
}
}
return array
},
],
commandSearchResults: [
(selectors) => [
selectors.isPaletteShown,
selectors.regexpCommandPairs,
selectors.input,
selectors.activeFlow,
selectors.isSqueak,
],
(
isPaletteShown: boolean,
regexpCommandPairs: RegExpCommandPairs,
argument: string,
activeFlow: CommandFlow | null,
isSqueak: boolean
) => {
if (!isPaletteShown || isSqueak) {
return []
}
if (activeFlow) {
return resolveCommand(activeFlow, argument)
}
let directResults: CommandResult[] = []
let prefixedResults: CommandResult[] = []
for (const [regexp, command] of regexpCommandPairs) {
if (regexp) {
const match = argument.match(regexp)
if (match && match[1]) {
prefixedResults = [...prefixedResults, ...resolveCommand(command, match[2], match[1])]
}
}
directResults = [...directResults, ...resolveCommand(command, argument)]
}
const allResults = directResults.concat(prefixedResults)
let fusableResults: CommandResult[] = []
let guaranteedResults: CommandResult[] = []
for (const result of allResults) {
if (result.guarantee) {
guaranteedResults.push(result)
} else {
fusableResults.push(result)
}
}
fusableResults = uniqueBy(fusableResults, (result) => result.display)
guaranteedResults = uniqueBy(guaranteedResults, (result) => result.display)
const fusedResults = argument
? new Fuse(fusableResults, {
keys: ['display', 'synonyms'],
})
.search(argument)
.slice(0, RESULTS_MAX)
.map((result) => result.item)
: sample(fusableResults, RESULTS_MAX - guaranteedResults.length)
return guaranteedResults.concat(fusedResults)
},
],
commandSearchResultsGrouped: [
(selectors) => [selectors.commandSearchResults, selectors.activeFlow],
(commandSearchResults: CommandResult[], activeFlow: CommandFlow | null) => {
const resultsGrouped: {
[scope: string]: CommandResult[]
} = {}
if (activeFlow) {
resultsGrouped[activeFlow.scope ?? '?'] = []
}
for (const result of commandSearchResults) {
const scope: string = result.source.scope ?? '?'
if (!(scope in resultsGrouped)) {
resultsGrouped[scope] = []
} // Ensure there's an array to push to
resultsGrouped[scope].push({ ...result })
}
let rollingGroupIndex = 0
let rollingResultIndex = 0
const resultsGroupedInOrder: [string, CommandResultDisplayable[]][] = []
for (const [group, results] of Object.entries(resultsGrouped)) {
resultsGroupedInOrder.push([group, []])
for (const result of results) {
resultsGroupedInOrder[rollingGroupIndex][1].push({ ...result, index: rollingResultIndex++ })
}
rollingGroupIndex++
}
return resultsGroupedInOrder
},
],
},
events: ({ actions }) => ({
afterMount: () => {
const { push } = router.actions
const goTo: Command = {
key: 'go-to',
scope: GLOBAL_COMMAND_SCOPE,
prefixes: ['open', 'visit'],
resolver: [
{
icon: FundOutlined,
display: 'Go to Dashboards',
executor: () => {
push(urls.dashboards())
},
},
{
icon: RiseOutlined,
display: 'Go to Insights',
executor: () => {
push(urls.savedInsights())
},
},
{
icon: RiseOutlined,
display: 'Go to Trends',
executor: () => {
// TODO: Don't reset insight on change
push(urls.insightNew({ insight: InsightType.TRENDS }))
},
},
{
icon: FunnelPlotOutlined,
display: 'Go to Funnels',
executor: () => {
// TODO: Don't reset insight on change
push(urls.insightNew({ insight: InsightType.FUNNELS }))
},
},
{
icon: GatewayOutlined,
display: 'Go to Retention',
executor: () => {
// TODO: Don't reset insight on change
push(urls.insightNew({ insight: InsightType.RETENTION }))
},
},
{
icon: InteractionOutlined,
display: 'Go to Paths',
executor: () => {
// TODO: Don't reset insight on change
push(urls.insightNew({ insight: InsightType.PATHS }))
},
},
{
icon: ContainerOutlined,
display: 'Go to Events',
executor: () => {
push(urls.events())
},
},
{
icon: AimOutlined,
display: 'Go to Actions',
executor: () => {
push(urls.actions())
},
},
{
icon: UserOutlined,
display: 'Go to Persons',
synonyms: ['people'],
executor: () => {
push(urls.persons())
},
},
{
icon: UsergroupAddOutlined,
display: 'Go to Cohorts',
executor: () => {
push(urls.cohorts())
},
},
{
icon: FlagOutlined,
display: 'Go to Feature Flags',
synonyms: ['feature flags', 'a/b tests'],
executor: () => {
push(urls.featureFlags())
},
},
{
icon: MessageOutlined,
display: 'Go to Annotations',
executor: () => {
push(urls.annotations())
},
},
{
icon: TeamOutlined,
display: 'Go to Team members',
synonyms: ['organization', 'members', 'invites', 'teammates'],
executor: () => {
push(urls.organizationSettings())
},
},
{
icon: ProjectOutlined,
display: 'Go to Project settings',
executor: () => {
push(urls.projectSettings())
},
},
{
icon: SmileOutlined,
display: 'Go to My settings',
synonyms: ['account'],
executor: () => {
push(urls.mySettings())
},
},
{
icon: ApiOutlined,
display: 'Go to Plugins',
synonyms: ['integrations'],
executor: () => {
push(urls.plugins())
},
},
{
icon: DatabaseOutlined,
display: 'Go to System status page',
synonyms: ['redis', 'celery', 'django', 'postgres', 'backend', 'service', 'online'],
executor: () => {
push(urls.systemStatus())
},
},
{
icon: PlusOutlined,
display: 'Create action',
executor: () => {
push(urls.createAction())
},
},
{
icon: LogoutOutlined,
display: 'Log out',
executor: () => {
userLogic.actions.logout()
},
},
],
}
const debugClickhouseQueries: Command = {
key: 'debug-clickhouse-queries',
scope: GLOBAL_COMMAND_SCOPE,
resolver:
userLogic.values.user?.is_staff ||
userLogic.values.user?.is_impersonated ||
preflightLogic.values.preflight?.is_debug ||
preflightLogic.values.preflight?.instance_preferences?.debug_queries
? {
icon: PlusOutlined,
display: 'Debug queries (ClickHouse)',
executor: () => {
debugCHQueries()
},
}
: [],
}
const calculator: Command = {
key: 'calculator',
scope: GLOBAL_COMMAND_SCOPE,
resolver: (argument) => {
// don't try evaluating if there's no argument or if it's a plain number already
if (!argument || !isNaN(+argument)) {
return null
}
try {
const result = +Parser.evaluate(argument)
return isNaN(result)
? null
: {
icon: CalculatorOutlined,
display: `= ${result}`,
guarantee: true,
executor: () => {
copyToClipboard(result.toString(), 'calculation result')
},
}
} catch {
return null
}
},
}
const openUrls: Command = {
key: 'open-urls',
scope: GLOBAL_COMMAND_SCOPE,
prefixes: ['open', 'visit'],
resolver: (argument) => {
const results: CommandResultTemplate[] = (teamLogic.values.currentTeam?.app_urls ?? []).map(
(url: string) => ({
icon: LinkOutlined,
display: `Open ${url}`,
synonyms: [`Visit ${url}`],
executor: () => {
open(url)
},
})
)
if (argument && isURL(argument)) {
results.push({
icon: LinkOutlined,
display: `Open ${argument}`,
synonyms: [`Visit ${argument}`],
executor: () => {
open(argument)
},
})
}
results.push({
icon: LinkOutlined,
display: 'Open PostHog Docs',
synonyms: ['technical documentation'],
executor: () => {
open('https://posthog.com/docs')
},
})
return results
},
}
const createPersonalApiKey: Command = {
key: 'create-personal-api-key',
scope: GLOBAL_COMMAND_SCOPE,
resolver: {
icon: KeyOutlined,
display: 'Create Personal API Key',
executor: () => ({
instruction: 'Give your key a label',
icon: TagOutlined,
scope: 'Creating Personal API Key',
resolver: (argument) => {
if (argument?.length) {
return {
icon: KeyOutlined,
display: `Create Key "${argument}"`,
executor: () => {
personalAPIKeysLogic.actions.createKey(argument)
push(urls.mySettings(), {}, 'personal-api-keys')
},
}
}
return null
},
}),
},
}
const createDashboard: Command = {
key: 'create-dashboard',
scope: GLOBAL_COMMAND_SCOPE,
resolver: {
icon: FundOutlined,
display: 'Create Dashboard',
executor: () => ({
instruction: 'Name your new dashboard',
icon: TagOutlined,
scope: 'Creating Dashboard',
resolver: (argument) => {
if (argument?.length) {
return {
icon: FundOutlined,
display: `Create Dashboard "${argument}"`,
executor: () => {
dashboardsModel.actions.addDashboard({ name: argument, show: true })
},
}
}
return null
},
}),
},
}
const shareFeedback: Command = {
key: 'share-feedback',
scope: GLOBAL_COMMAND_SCOPE,
resolver: {
icon: CommentOutlined,
display: 'Share Feedback',
synonyms: ['send opinion', 'ask question', 'message posthog', 'github issue'],
executor: () => ({
scope: 'Sharing Feedback',
resolver: [
{
display: 'Send Message Directly to PostHog',
icon: CommentOutlined,
executor: () => ({
instruction: "What's on your mind?",
icon: CommentOutlined,
resolver: (argument) => ({
icon: SendOutlined,
display: 'Send',
executor: !argument?.length
? undefined
: () => {
posthog.capture('palette feedback', { message: argument })
return {
resolver: {
icon: CheckOutlined,
display: 'Message Sent!',
executor: true,
},
}
},
}),
}),
},
{
icon: VideoCameraOutlined,
display: 'Schedule Quick Call',
executor: () => {
open('https://calendly.com/posthog-feedback')
},
},
{
icon: ExclamationCircleOutlined,
display: 'Create GitHub Issue',
executor: () => {
open('https://github.com/PostHog/posthog/issues/new/choose')
},
},
],
}),
},
}
actions.registerCommand(goTo)
actions.registerCommand(openUrls)
actions.registerCommand(debugClickhouseQueries)
actions.registerCommand(calculator)
actions.registerCommand(createPersonalApiKey)
actions.registerCommand(createDashboard)
actions.registerCommand(shareFeedback)
},
beforeUnmount: () => {
actions.deregisterCommand('go-to')
actions.deregisterCommand('open-urls')
actions.deregisterCommand('debug-clickhouse-queries')
actions.deregisterCommand('calculator')
actions.deregisterCommand('create-personal-api-key')
actions.deregisterCommand('create-dashboard')
actions.deregisterCommand('share-feedback')
},
}),
})
Example #2
Source File: FunnelStepTable.tsx From posthog-foss with MIT License | 4 votes |
export function FunnelStepTable(): JSX.Element | null {
const { insightProps, isViewedOnDashboard } = useValues(insightLogic)
const logic = funnelLogic(insightProps)
const {
stepsWithCount,
flattenedSteps,
steps,
visibleStepsWithConversionMetrics,
hiddenLegendKeys,
barGraphLayout,
flattenedStepsByBreakdown,
flattenedBreakdowns,
aggregationTargetLabel,
isModalActive,
filters,
} = useValues(logic)
const { openPersonsModalForStep, toggleVisibilityByBreakdown, setHiddenById } = useActions(logic)
const { cohorts } = useValues(cohortsModel)
const showLabels = false // #7653 - replaces (visibleStepsWithConversionMetrics?.[0]?.nested_breakdown?.length ?? 0) < 6
const isOnlySeries = flattenedBreakdowns.length === 1
function getColumns(): ColumnsType<FlattenedFunnelStep> | ColumnsType<FlattenedFunnelStepByBreakdown> {
if (barGraphLayout === FunnelLayout.vertical) {
const _columns: ColumnsType<FlattenedFunnelStepByBreakdown> = []
if (!isViewedOnDashboard) {
_columns.push({
render: function RenderCheckbox({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
const checked = !!flattenedBreakdowns?.every(
(b) =>
!hiddenLegendKeys[
getVisibilityIndex(visibleStepsWithConversionMetrics?.[0], b.breakdown_value)
]
)
const color = getSeriesColor(breakdown?.breakdownIndex, isOnlySeries)
return renderGraphAndHeader(
rowIndex,
0,
<PHCheckbox
color={color}
checked={
!hiddenLegendKeys[
getVisibilityIndex(
visibleStepsWithConversionMetrics?.[0],
breakdown.breakdown_value
)
]
} // assume visible status from first step's visibility
onChange={() => toggleVisibilityByBreakdown(breakdown.breakdown_value)}
/>,
<PHCheckbox
color={isOnlySeries ? 'var(--primary)' : undefined}
checked={checked}
indeterminate={flattenedBreakdowns?.some(
(b) =>
!hiddenLegendKeys[
getVisibilityIndex(
visibleStepsWithConversionMetrics?.[0],
b.breakdown_value
)
]
)}
onChange={() => {
// either toggle all data on or off
setHiddenById(
Object.fromEntries(
visibleStepsWithConversionMetrics.flatMap((s) =>
flattenedBreakdowns.map((b) => [
getVisibilityIndex(s, b.breakdown_value),
checked,
])
)
)
)
}}
/>,
showLabels,
undefined,
isViewedOnDashboard
)
},
fixed: 'left',
width: 20,
align: 'center',
})
_columns.push({
render: function RenderLabel({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
const color = getSeriesColor(breakdown?.breakdownIndex, isOnlySeries)
return renderGraphAndHeader(
rowIndex,
1,
<InsightLabel
seriesColor={color}
fallbackName={formatBreakdownLabel(
cohorts,
isOnlySeries ? `Unique ${aggregationTargetLabel.plural}` : breakdown.breakdown_value
)}
hasMultipleSeries={steps.length > 1}
breakdownValue={breakdown.breakdown_value}
hideBreakdown={false}
iconSize={IconSize.Small}
iconStyle={{ marginRight: 12 }}
allowWrap
hideIcon
pillMaxWidth={165}
/>,
renderColumnTitle('Breakdown'),
showLabels,
undefined,
isViewedOnDashboard
)
},
fixed: 'left',
width: 150,
className: 'funnel-table-cell breakdown-label-column',
})
_columns.push({
render: function RenderCompletionRate({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
return renderGraphAndHeader(
rowIndex,
2,
<span>{formatDisplayPercentage(breakdown?.conversionRates?.total ?? 0)}%</span>,
renderSubColumnTitle('Rate'),
showLabels,
undefined,
isViewedOnDashboard
)
},
fixed: 'left',
width: 120,
align: 'right',
className: 'funnel-table-cell dividing-column',
})
}
// Add columns per step
visibleStepsWithConversionMetrics.forEach((step, stepIndex) => {
_columns.push({
render: function RenderCompleted({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
const breakdownStep = breakdown.steps?.[step.order]
return renderGraphAndHeader(
rowIndex,
step.order === 0 ? 3 : (stepIndex - 1) * 5 + 5,
breakdownStep?.count != undefined ? (
<ValueInspectorButton
onClick={() => openPersonsModalForStep({ step: breakdownStep, converted: true })}
disabled={!isModalActive}
>
{breakdown.steps?.[step.order].count}
</ValueInspectorButton>
) : (
EmptyValue
),
renderSubColumnTitle(
<>
<UserOutlined
title={`Unique ${aggregationTargetLabel.plural} ${
filters.aggregation_group_type_index != undefined ? 'that' : 'who'
} completed this step`}
/>{' '}
Completed
</>
),
showLabels,
step,
isViewedOnDashboard
)
},
width: 80,
align: 'right',
})
_columns.push({
render: function RenderConversion({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
return renderGraphAndHeader(
rowIndex,
step.order === 0 ? 4 : (stepIndex - 1) * 5 + 6,
breakdown.steps?.[step.order]?.conversionRates.fromBasisStep != undefined ? (
<>
{getSignificanceFromBreakdownStep(breakdown, step.order)?.fromBasisStep ? (
<Tooltip title="Significantly different from other breakdown values">
<span className="table-text-highlight">
<FlagOutlined style={{ marginRight: 2 }} />{' '}
{formatDisplayPercentage(
breakdown.steps?.[step.order]?.conversionRates.fromBasisStep
)}
%
</span>
</Tooltip>
) : (
<span>
{formatDisplayPercentage(
breakdown.steps?.[step.order]?.conversionRates.fromBasisStep
)}
%
</span>
)}
</>
) : (
EmptyValue
),
renderSubColumnTitle('Rate'),
showLabels,
step,
isViewedOnDashboard
)
},
width: 80,
align: 'right',
className: step.order === 0 ? 'funnel-table-cell dividing-column' : undefined,
})
if (step.order !== 0) {
_columns.push({
render: function RenderDropoff({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
const breakdownStep = breakdown.steps?.[step.order]
return renderGraphAndHeader(
rowIndex,
(stepIndex - 1) * 5 + 7,
breakdownStep?.droppedOffFromPrevious != undefined ? (
<ValueInspectorButton
onClick={() =>
openPersonsModalForStep({
step: breakdownStep,
converted: false,
})
}
disabled={!isModalActive}
>
{breakdown.steps?.[step.order]?.droppedOffFromPrevious}
</ValueInspectorButton>
) : (
EmptyValue
),
renderSubColumnTitle(
<>
<UserDeleteOutlined
title={`Unique ${aggregationTargetLabel.plural} who dropped off on this step`}
/>{' '}
Dropped
</>
),
showLabels,
step,
isViewedOnDashboard
)
},
width: 80,
align: 'right',
})
_columns.push({
render: function RenderDropoffRate({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
return renderGraphAndHeader(
rowIndex,
(stepIndex - 1) * 5 + 8,
breakdown.steps?.[step.order]?.conversionRates.fromPrevious != undefined ? (
<>
{!getSignificanceFromBreakdownStep(breakdown, step.order)?.fromBasisStep &&
getSignificanceFromBreakdownStep(breakdown, step.order)?.fromPrevious ? (
<Tooltip title="Significantly different from other breakdown values">
<span className="table-text-highlight">
<FlagOutlined style={{ marginRight: 2 }} />{' '}
{formatDisplayPercentage(
1 - breakdown.steps?.[step.order]?.conversionRates.fromPrevious
)}
%
</span>
</Tooltip>
) : (
<span>
{formatDisplayPercentage(
1 - breakdown.steps?.[step.order]?.conversionRates.fromPrevious
)}
%
</span>
)}
</>
) : (
EmptyValue
),
renderSubColumnTitle('Rate'),
showLabels,
step,
isViewedOnDashboard
)
},
width: 80,
align: 'right',
})
_columns.push({
render: function RenderAverageTime({}, breakdown: FlattenedFunnelStepByBreakdown, rowIndex) {
return renderGraphAndHeader(
rowIndex,
(stepIndex - 1) * 5 + 9,
breakdown.steps?.[step.order]?.average_conversion_time != undefined ? (
<span>
{colonDelimitedDuration(
breakdown.steps?.[step.order]?.average_conversion_time,
3
)}
</span>
) : (
EmptyValue
),
renderSubColumnTitle('Avg. time'),
showLabels,
step,
isViewedOnDashboard
)
},
width: 80,
align: 'right',
className: 'funnel-table-cell dividing-column',
})
}
})
return _columns
}
// If steps are horizontal, render table with flattened steps
const _columns: ColumnsType<FlattenedFunnelStep> = []
_columns.push({
title: '',
render: function RenderSeriesGlyph({}, step: FlattenedFunnelStep): JSX.Element | null {
if (step.breakdownIndex === undefined) {
// Not a breakdown value; show a step-order glyph
return <SeriesGlyph variant="funnel-step-glyph">{humanizeOrder(step.order)}</SeriesGlyph>
}
return null
},
fixed: 'left',
width: 20,
align: 'center',
})
if (!!steps[0]?.breakdown) {
_columns.push({
title: '',
render: function RenderCheckbox({}, step: FlattenedFunnelStep): JSX.Element | null {
const color = getSeriesColor(step?.breakdownIndex, flattenedBreakdowns.length === 1)
// Breakdown parent
if (step.breakdownIndex === undefined && (step.nestedRowKeys ?? []).length > 0) {
return (
<PHCheckbox
checked={!!step.nestedRowKeys?.every((rowKey) => !hiddenLegendKeys[rowKey])}
indeterminate={step.nestedRowKeys?.some((rowKey) => !hiddenLegendKeys[rowKey])}
onChange={() => {
// either toggle all data on or off
const currentState = !!step.nestedRowKeys?.every(
(rowKey) => !hiddenLegendKeys[rowKey]
)
setHiddenById(
Object.fromEntries(
step.nestedRowKeys?.map((rowKey) => [rowKey, currentState]) ?? []
)
)
}}
/>
)
}
// Breakdown child
return (
<PHCheckbox
color={color}
checked={!hiddenLegendKeys[step.rowKey]}
onChange={() => {
setHiddenById({
[getVisibilityIndex(step, step.breakdown_value)]: !hiddenLegendKeys[step.rowKey],
})
}}
/>
)
},
fixed: 'left',
width: 20,
align: 'center',
})
}
_columns.push({
title: 'Step',
render: function RenderLabel({}, step: FlattenedFunnelStep): JSX.Element {
const color = getStepColor(step, !!step.breakdown)
return (
<InsightLabel
seriesColor={color}
fallbackName={
!step.isBreakdownParent && isBreakdownChildType(step.breakdown)
? formatBreakdownLabel(cohorts, step.breakdown)
: step.name
}
action={
!step.isBreakdownParent && isBreakdownChildType(step.breakdown)
? undefined
: getActionFilterFromFunnelStep(step)
}
hasMultipleSeries={step.isBreakdownParent && steps.length > 1}
breakdownValue={
step.breakdown === ''
? 'None'
: isBreakdownChildType(step.breakdown)
? step.breakdown_value
: undefined
}
pillMaxWidth={165}
hideBreakdown={step.isBreakdownParent}
iconSize={IconSize.Small}
iconStyle={{ marginRight: 12 }}
hideIcon
allowWrap
showEventName={step.isBreakdownParent}
/>
)
},
fixed: 'left',
width: 120,
})
_columns.push({
title: 'Completed',
render: function RenderCompleted({}, step: FlattenedFunnelStep): JSX.Element {
return (
<ValueInspectorButton
onClick={() => openPersonsModalForStep({ step, converted: true })}
disabled={!isModalActive}
>
{step.count}
</ValueInspectorButton>
)
},
width: 80,
align: 'center',
})
_columns.push({
title: 'Conversion',
render: function RenderConversion({}, step: FlattenedFunnelStep): JSX.Element | null {
return step.order === 0 ? (
EmptyValue
) : (
<span>{formatDisplayPercentage(step.conversionRates.total)}%</span>
)
},
width: 80,
align: 'center',
})
_columns.push({
title: 'Dropped off',
render: function RenderDropoff({}, step: FlattenedFunnelStep): JSX.Element | null {
return step.order === 0 ? (
EmptyValue
) : (
<ValueInspectorButton
onClick={() => openPersonsModalForStep({ step, converted: false })}
disabled={!isModalActive}
>
{step.droppedOffFromPrevious}
</ValueInspectorButton>
)
},
width: 80,
align: 'center',
})
_columns.push({
title: 'From previous step',
render: function RenderDropoffFromPrevious({}, step: FlattenedFunnelStep): JSX.Element | null {
return step.order === 0 ? (
EmptyValue
) : (
<span>{formatDisplayPercentage(1 - step.conversionRates.fromPrevious)}%</span>
)
},
width: 80,
align: 'center',
})
_columns.push({
title: 'Average time',
render: function RenderAverageTime({}, step: FlattenedFunnelStep): JSX.Element {
return step.average_conversion_time ? (
<span>{humanFriendlyDuration(step.average_conversion_time, 2)}</span>
) : (
EmptyValue
)
},
width: 100,
align: 'center',
})
return _columns
}
// If the bars are vertical, use table as legend #5733
const columns = getColumns()
const tableData: TableProps<any /* TODO: Type this */> =
barGraphLayout === FunnelLayout.vertical
? {
dataSource: flattenedStepsByBreakdown.slice(
0,
isViewedOnDashboard ? 2 : flattenedStepsByBreakdown.length
),
columns,
showHeader: false,
rowClassName: (record, index) => {
return clsx(
`funnel-steps-table-row-${index}`,
index === 2 && 'funnel-table-cell',
record.significant && 'table-cell-highlight'
)
},
}
: {
dataSource: flattenedSteps,
columns,
}
return stepsWithCount.length > 1 ? (
<Table
{...tableData}
scroll={isViewedOnDashboard ? undefined : { x: 'max-content' }}
size="small"
rowKey="rowKey"
pagination={{ pageSize: 100, hideOnSinglePage: true }}
style={{ height: '100%' }}
data-attr={barGraphLayout === FunnelLayout.vertical ? 'funnel-bar-graph' : 'funnel-steps-table'}
className="funnel-steps-table"
/>
) : null
}
Example #3
Source File: Icon.tsx From html2sketch with MIT License | 4 votes |
IconSymbol: FC = () => {
return (
<Row>
{/*<CaretUpOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
{/*/>*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
{/*/>*/}
{/*<StepBackwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
{/*<StepForwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
<StepForwardOutlined />
<ShrinkOutlined />
<ArrowsAltOutlined />
<DownOutlined />
<UpOutlined />
<LeftOutlined />
<RightOutlined />
<CaretUpOutlined />
<CaretDownOutlined />
<CaretLeftOutlined />
<CaretRightOutlined />
<VerticalAlignTopOutlined />
<RollbackOutlined />
<FastBackwardOutlined />
<FastForwardOutlined />
<DoubleRightOutlined />
<DoubleLeftOutlined />
<VerticalLeftOutlined />
<VerticalRightOutlined />
<VerticalAlignMiddleOutlined />
<VerticalAlignBottomOutlined />
<ForwardOutlined />
<BackwardOutlined />
<EnterOutlined />
<RetweetOutlined />
<SwapOutlined />
<SwapLeftOutlined />
<SwapRightOutlined />
<ArrowUpOutlined />
<ArrowDownOutlined />
<ArrowLeftOutlined />
<ArrowRightOutlined />
<LoginOutlined />
<LogoutOutlined />
<MenuFoldOutlined />
<MenuUnfoldOutlined />
<BorderBottomOutlined />
<BorderHorizontalOutlined />
<BorderInnerOutlined />
<BorderOuterOutlined />
<BorderLeftOutlined />
<BorderRightOutlined />
<BorderTopOutlined />
<BorderVerticleOutlined />
<PicCenterOutlined />
<PicLeftOutlined />
<PicRightOutlined />
<RadiusBottomleftOutlined />
<RadiusBottomrightOutlined />
<RadiusUpleftOutlined />
<RadiusUprightOutlined />
<FullscreenOutlined />
<FullscreenExitOutlined />
<QuestionOutlined />
<PauseOutlined />
<MinusOutlined />
<PauseCircleOutlined />
<InfoOutlined />
<CloseOutlined />
<ExclamationOutlined />
<CheckOutlined />
<WarningOutlined />
<IssuesCloseOutlined />
<StopOutlined />
<EditOutlined />
<CopyOutlined />
<ScissorOutlined />
<DeleteOutlined />
<SnippetsOutlined />
<DiffOutlined />
<HighlightOutlined />
<AlignCenterOutlined />
<AlignLeftOutlined />
<AlignRightOutlined />
<BgColorsOutlined />
<BoldOutlined />
<ItalicOutlined />
<UnderlineOutlined />
<StrikethroughOutlined />
<RedoOutlined />
<UndoOutlined />
<ZoomInOutlined />
<ZoomOutOutlined />
<FontColorsOutlined />
<FontSizeOutlined />
<LineHeightOutlined />
<SortAscendingOutlined />
<SortDescendingOutlined />
<DragOutlined />
<OrderedListOutlined />
<UnorderedListOutlined />
<RadiusSettingOutlined />
<ColumnWidthOutlined />
<ColumnHeightOutlined />
<AreaChartOutlined />
<PieChartOutlined />
<BarChartOutlined />
<DotChartOutlined />
<LineChartOutlined />
<RadarChartOutlined />
<HeatMapOutlined />
<FallOutlined />
<RiseOutlined />
<StockOutlined />
<BoxPlotOutlined />
<FundOutlined />
<SlidersOutlined />
<AndroidOutlined />
<AppleOutlined />
<WindowsOutlined />
<IeOutlined />
<ChromeOutlined />
<GithubOutlined />
<AliwangwangOutlined />
<DingdingOutlined />
<WeiboSquareOutlined />
<WeiboCircleOutlined />
<TaobaoCircleOutlined />
<Html5Outlined />
<WeiboOutlined />
<TwitterOutlined />
<WechatOutlined />
<AlipayCircleOutlined />
<TaobaoOutlined />
<SkypeOutlined />
<FacebookOutlined />
<CodepenOutlined />
<CodeSandboxOutlined />
<AmazonOutlined />
<GoogleOutlined />
<AlipayOutlined />
<AntDesignOutlined />
<AntCloudOutlined />
<ZhihuOutlined />
<SlackOutlined />
<SlackSquareOutlined />
<BehanceSquareOutlined />
<DribbbleOutlined />
<DribbbleSquareOutlined />
<InstagramOutlined />
<YuqueOutlined />
<AlibabaOutlined />
<YahooOutlined />
<RedditOutlined />
<SketchOutlined />
<AccountBookOutlined />
<AlertOutlined />
<ApartmentOutlined />
<ApiOutlined />
<QqOutlined />
<MediumWorkmarkOutlined />
<GitlabOutlined />
<MediumOutlined />
<GooglePlusOutlined />
<AppstoreAddOutlined />
<AppstoreOutlined />
<AudioOutlined />
<AudioMutedOutlined />
<AuditOutlined />
<BankOutlined />
<BarcodeOutlined />
<BarsOutlined />
<BellOutlined />
<BlockOutlined />
<BookOutlined />
<BorderOutlined />
<BranchesOutlined />
<BuildOutlined />
<BulbOutlined />
<CalculatorOutlined />
<CalendarOutlined />
<CameraOutlined />
<CarOutlined />
<CarryOutOutlined />
<CiCircleOutlined />
<CiOutlined />
<CloudOutlined />
<ClearOutlined />
<ClusterOutlined />
<CodeOutlined />
<CoffeeOutlined />
<CompassOutlined />
<CompressOutlined />
<ContactsOutlined />
<ContainerOutlined />
<ControlOutlined />
<CopyrightCircleOutlined />
<CopyrightOutlined />
<CreditCardOutlined />
<CrownOutlined />
<CustomerServiceOutlined />
<DashboardOutlined />
<DatabaseOutlined />
<DeleteColumnOutlined />
<DeleteRowOutlined />
<DisconnectOutlined />
<DislikeOutlined />
<DollarCircleOutlined />
<DollarOutlined />
<DownloadOutlined />
<EllipsisOutlined />
<EnvironmentOutlined />
<EuroCircleOutlined />
<EuroOutlined />
<ExceptionOutlined />
<ExpandAltOutlined />
<ExpandOutlined />
<ExperimentOutlined />
<ExportOutlined />
<EyeOutlined />
<FieldBinaryOutlined />
<FieldNumberOutlined />
<FieldStringOutlined />
<DesktopOutlined />
<DingtalkOutlined />
<FileAddOutlined />
<FileDoneOutlined />
<FileExcelOutlined />
<FileExclamationOutlined />
<FileOutlined />
<FileImageOutlined />
<FileJpgOutlined />
<FileMarkdownOutlined />
<FilePdfOutlined />
<FilePptOutlined />
<FileProtectOutlined />
<FileSearchOutlined />
<FileSyncOutlined />
<FileTextOutlined />
<FileUnknownOutlined />
<FileWordOutlined />
<FilterOutlined />
<FireOutlined />
<FlagOutlined />
<FolderAddOutlined />
<FolderOutlined />
<FolderOpenOutlined />
<ForkOutlined />
<FormatPainterOutlined />
<FrownOutlined />
<FunctionOutlined />
<FunnelPlotOutlined />
<GatewayOutlined />
<GifOutlined />
<GiftOutlined />
<GlobalOutlined />
<GoldOutlined />
<GroupOutlined />
<HddOutlined />
<HeartOutlined />
<HistoryOutlined />
<HomeOutlined />
<HourglassOutlined />
<IdcardOutlined />
<ImportOutlined />
<InboxOutlined />
<InsertRowAboveOutlined />
<InsertRowBelowOutlined />
<InsertRowLeftOutlined />
<InsertRowRightOutlined />
<InsuranceOutlined />
<InteractionOutlined />
<KeyOutlined />
<LaptopOutlined />
<LayoutOutlined />
<LikeOutlined />
<LineOutlined />
<LinkOutlined />
<Loading3QuartersOutlined />
<LoadingOutlined />
<LockOutlined />
<MailOutlined />
<ManOutlined />
<MedicineBoxOutlined />
<MehOutlined />
<MenuOutlined />
<MergeCellsOutlined />
<MessageOutlined />
<MobileOutlined />
<MoneyCollectOutlined />
<MonitorOutlined />
<MoreOutlined />
<NodeCollapseOutlined />
<NodeExpandOutlined />
<NodeIndexOutlined />
<NotificationOutlined />
<NumberOutlined />
<PaperClipOutlined />
<PartitionOutlined />
<PayCircleOutlined />
<PercentageOutlined />
<PhoneOutlined />
<PictureOutlined />
<PoundCircleOutlined />
<PoundOutlined />
<PoweroffOutlined />
<PrinterOutlined />
<ProfileOutlined />
<ProjectOutlined />
<PropertySafetyOutlined />
<PullRequestOutlined />
<PushpinOutlined />
<QrcodeOutlined />
<ReadOutlined />
<ReconciliationOutlined />
<RedEnvelopeOutlined />
<ReloadOutlined />
<RestOutlined />
<RobotOutlined />
<RocketOutlined />
<SafetyCertificateOutlined />
<SafetyOutlined />
<ScanOutlined />
<ScheduleOutlined />
<SearchOutlined />
<SecurityScanOutlined />
<SelectOutlined />
<SendOutlined />
<SettingOutlined />
<ShakeOutlined />
<ShareAltOutlined />
<ShopOutlined />
<ShoppingCartOutlined />
<ShoppingOutlined />
<SisternodeOutlined />
<SkinOutlined />
<SmileOutlined />
<SolutionOutlined />
<SoundOutlined />
<SplitCellsOutlined />
<StarOutlined />
<SubnodeOutlined />
<SyncOutlined />
<TableOutlined />
<TabletOutlined />
<TagOutlined />
<TagsOutlined />
<TeamOutlined />
<ThunderboltOutlined />
<ToTopOutlined />
<ToolOutlined />
<TrademarkCircleOutlined />
<TrademarkOutlined />
<TransactionOutlined />
<TrophyOutlined />
<UngroupOutlined />
<UnlockOutlined />
<UploadOutlined />
<UsbOutlined />
<UserAddOutlined />
<UserDeleteOutlined />
<UserOutlined />
<UserSwitchOutlined />
<UsergroupAddOutlined />
<UsergroupDeleteOutlined />
<VideoCameraOutlined />
<WalletOutlined />
<WifiOutlined />
<BorderlessTableOutlined />
<WomanOutlined />
<BehanceOutlined />
<DropboxOutlined />
<DeploymentUnitOutlined />
<UpCircleOutlined />
<DownCircleOutlined />
<LeftCircleOutlined />
<RightCircleOutlined />
<UpSquareOutlined />
<DownSquareOutlined />
<LeftSquareOutlined />
<RightSquareOutlined />
<PlayCircleOutlined />
<QuestionCircleOutlined />
<PlusCircleOutlined />
<PlusSquareOutlined />
<MinusSquareOutlined />
<MinusCircleOutlined />
<InfoCircleOutlined />
<ExclamationCircleOutlined />
<CloseCircleOutlined />
<CloseSquareOutlined />
<CheckCircleOutlined />
<CheckSquareOutlined />
<ClockCircleOutlined />
<FormOutlined />
<DashOutlined />
<SmallDashOutlined />
<YoutubeOutlined />
<CodepenCircleOutlined />
<AliyunOutlined />
<PlusOutlined />
<LinkedinOutlined />
<AimOutlined />
<BugOutlined />
<CloudDownloadOutlined />
<CloudServerOutlined />
<CloudSyncOutlined />
<CloudUploadOutlined />
<CommentOutlined />
<ConsoleSqlOutlined />
<EyeInvisibleOutlined />
<FileGifOutlined />
<DeliveredProcedureOutlined />
<FieldTimeOutlined />
<FileZipOutlined />
<FolderViewOutlined />
<FundProjectionScreenOutlined />
<FundViewOutlined />
<MacCommandOutlined />
<PlaySquareOutlined />
<OneToOneOutlined />
<RotateLeftOutlined />
<RotateRightOutlined />
<SaveOutlined />
<SwitcherOutlined />
<TranslationOutlined />
<VerifiedOutlined />
<VideoCameraAddOutlined />
<WhatsAppOutlined />
{/*</Col>*/}
</Row>
);
}