mirror of
https://github.com/hanzoai/insights.git
synced 2026-10-30 16:15:31 +00:00
Every component in the library carried the upstream project's mascot in its identifier, its CSS class, its SCSS file and its path. The prefix carried no information -- a button is a button -- so it is gone: LemonButton is Button, LemonBanner is Banner, and the set they belong to lives in lib/elements. lib/ui was the obvious home and is not available: it already holds the headless primitives (ButtonPrimitive, TabsPrimitive, ListBox), and both layers define a Label. Folding a styled set into a primitive one is a redesign; keeping them apart keeps this a rename and nothing more. --lemon-button-height becomes --height, not --button-height. lib/ui sets a bare --button-height inline in ButtonPrimitives and reads it back in DropdownMenu and SelectPrimitive; custom properties inherit, so reusing that name would silently resize any primitive nested inside a styled button. Left alone because they are not ours to rename: LemonChiffon and lemonchiffon (W3C named colours, used as lookup keys), kylelemons (a Go dependency) and Plemons (a surname in the person-name generator). Words that merely contain the letters -- disableMonospaceOptimizations, MultipleMonths, ScheduleMonitorJobInputs -- are untouched; the codemod is case-sensitive so it never saw them. capture_request_dump.jsonl keeps the old class names too. Its inputs are gzipped captures of what a browser actually sent in 2023 and cannot be rewritten, so renaming only the expected output would have made the fixture contradict itself. Storybook titles moved with the files, so story ids still match the snapshot filenames they are compared against. Co-authored-by: Hanzo Dev <[email protected]>
87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import { useValues } from 'kea'
|
|
|
|
import { IconMinusSquare, IconPlusSquare } from '@hanzo/icons'
|
|
import { Button, Table } from '@hanzo/elements'
|
|
|
|
import { PropertyFilterType, PropertyOperator } from '~/types'
|
|
|
|
import { attributeBreakdownLogic } from './attributeBreakdownLogic'
|
|
|
|
export const AttributeBreakdowns = ({
|
|
attribute,
|
|
type,
|
|
addFilter,
|
|
id,
|
|
}: {
|
|
attribute: string
|
|
type: PropertyFilterType
|
|
addFilter: (key: string, value: string, operator?: PropertyOperator, type?: PropertyFilterType) => void
|
|
id: string
|
|
}): JSX.Element => {
|
|
const logic = attributeBreakdownLogic({ attribute, type, id })
|
|
const { attributeValues, logCount, breakdowns } = useValues(logic)
|
|
|
|
const dataSource = Object.entries(breakdowns)
|
|
.sort(([, c1], [, c2]) => c2 - c1)
|
|
.slice(0, 10)
|
|
.map(([value, count]) => ({
|
|
value,
|
|
count,
|
|
percentage: ((count / attributeValues.length) * 100).toFixed(0),
|
|
}))
|
|
|
|
return (
|
|
<div className="flex flex-col p-2 gap-y-2">
|
|
{attributeValues.length} of the {logCount} logs have the label {attribute}
|
|
<Table
|
|
className="w-fit"
|
|
hideScrollbar
|
|
dataSource={dataSource}
|
|
size="small"
|
|
columns={[
|
|
{
|
|
key: 'actions',
|
|
width: 0,
|
|
render: (_, record) => (
|
|
<div className="flex gap-x-0">
|
|
<Button
|
|
tooltip="Add as filter"
|
|
size="xsmall"
|
|
onClick={() => addFilter(attribute, record.value, PropertyOperator.Exact, type)}
|
|
>
|
|
<IconPlusSquare />
|
|
</Button>
|
|
<Button
|
|
tooltip="Exclude as filter"
|
|
size="xsmall"
|
|
onClick={() => addFilter(attribute, record.value, PropertyOperator.IsNot, type)}
|
|
>
|
|
<IconMinusSquare />
|
|
</Button>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
title: 'Count',
|
|
key: 'count',
|
|
dataIndex: 'count',
|
|
width: 0,
|
|
},
|
|
{
|
|
title: 'Percentage',
|
|
key: 'percentage',
|
|
dataIndex: 'percentage',
|
|
width: 0,
|
|
render: (value) => `${value}%`,
|
|
},
|
|
{
|
|
title: 'Value',
|
|
key: 'value',
|
|
dataIndex: 'value',
|
|
},
|
|
]}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|