ui: event and user props lists

This commit is contained in:
nick-delirium 2025-01-31 17:01:38 +01:00
parent bb2f39517b
commit b465da5a15
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
6 changed files with 315 additions and 80 deletions

View file

@ -3,7 +3,6 @@ import { EventsList, FilterList } from 'Shared/Filters/FilterList';
import { Table, Dropdown } from 'antd';
import { MoreOutlined } from '@ant-design/icons';
import { numberWithCommas } from 'App/utils';
import { Pagination } from 'UI';
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
import ColumnsModal from 'Components/DataManagement/Activity/ColumnsModal';
import Event from './data/Event';
@ -15,6 +14,7 @@ import { Link } from 'react-router-dom';
import { dataManagement, withSiteId } from 'App/routes'
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import FullPagination from "Shared/FullPagination";
const limit = 100;
@ -280,26 +280,14 @@ function ActivityPage() {
pagination={false}
columns={shownCols}
/>
<div className="flex items-center justify-between px-4 py-3 shadow-sm w-full bg-white rounded-lg mt-2">
<div>
{'Showing '}
<span className="font-medium">{(page - 1) * limit + 1}</span>
{' to '}
<span className="font-medium">
{(page - 1) * limit + list.length}
</span>
{' of '}
<span className="font-medium">{numberWithCommas(total)}</span>
{' events.'}
</div>
<Pagination
page={page}
total={total}
onPageChange={onPageChange}
limit={limit}
debounceRequest={500}
/>
</div>
<FullPagination
page={page}
limit={limit}
total={total}
listLen={list.length}
onPageChange={onPageChange}
entity={'events'}
/>
</div>
</div>
</div>

View file

@ -0,0 +1,151 @@
import React from 'react';
import FullPagination from 'Shared/FullPagination';
import { Input, Table } from 'antd';
import Tabs from 'Shared/Tabs';
import { list } from "../Activity/Page";
function PropertiesPage() {
const [query, setQuery] = React.useState('');
const [activeView, setActiveView] = React.useState('properties');
const views = [
{
key: 'user-props',
label: <div className={'text-lg font-medium'}>User Properties</div>,
},
{
key: 'events-props',
label: <div className={'text-lg font-medium'}>Event Properties</div>,
},
];
return (
<div
className="flex flex-col gap-4 rounded-lg border bg-white mx-auto"
style={{ maxWidth: 1360 }}
>
<div className={'flex items-center justify-between border-b px-4 pt-2 '}>
<Tabs items={views} onChange={setActiveView} activeKey={activeView} />
<Input.Search
size={'small'}
placeholder={'Name, email, ID'}
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
</div>
{activeView === 'user-props' ? <UserPropsList /> : <EventPropsList />}
</div>
);
}
function UserPropsList() {
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.name.localeCompare(b.name),
},
{
title: 'Display Name',
dataIndex: 'displayName',
key: 'displayName',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.displayName.localeCompare(b.displayName),
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.description.localeCompare(b.description),
},
{
title: 'Example Value',
dataIndex: 'exampleValue',
key: 'exampleValue',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.exampleValue.localeCompare(b.exampleValue),
},
{
title: '# of Queries',
dataIndex: 'monthQuery',
key: 'monthQuery',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.monthQuery.localeCompare(b.monthQuery),
},
];
const page = 1;
const total = 100;
const onPageChange = (page: number) => {};
const limit = 10;
return (
<div>
<Table columns={columns} dataSource={list} pagination={false} />
<FullPagination
page={page}
limit={limit}
total={total}
listLen={list.length}
onPageChange={onPageChange}
entity={'events'}
/>
</div>
);
}
function EventPropsList() {
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.name.localeCompare(b.name),
},
{
title: 'Display Name',
dataIndex: 'displayName',
key: 'displayName',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.displayName.localeCompare(b.displayName),
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.description.localeCompare(b.description),
},
{
title: 'Example Value',
dataIndex: 'exampleValue',
key: 'exampleValue',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.exampleValue.localeCompare(b.exampleValue),
},
{
title: '# of Events',
dataIndex: 'totalVolume',
key: 'totalVolume',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.totalVolume.localeCompare(b.totalVolume),
},
];
const page = 1;
const total = 100;
const onPageChange = (page: number) => {};
const limit = 10;
return (
<div>
<Table columns={columns} dataSource={list} pagination={false} />
<FullPagination
page={page}
limit={limit}
total={total}
listLen={list.length}
onPageChange={onPageChange}
entity={'events'}
/>
</div>
);
}

View file

@ -0,0 +1,19 @@
import React from 'react';
import Event from 'Components/DataManagement/Activity/data/Event'
function UserProperty() {
const testEv = new Event({
name: '$broswerthing',
displayName: 'Browser Thing',
description: 'The browser the user is using',
customFields: {
exampleValue: 'Chrome',
type: 'String',
}
})
return (
<div className="border rounded-lg flex flex-col gap-4 w-full mx-auto" style={{ maxWidth: 1360 }}>
</div>
)
}

View file

@ -1,56 +1,52 @@
import React from 'react';
import { numberWithCommas } from 'App/utils';
import FilterSelection from "Shared/Filters/FilterSelection/FilterSelection";
import FilterSelection from 'Shared/Filters/FilterSelection/FilterSelection';
import User from './data/User';
import { Pagination } from 'UI';
import { Segmented, Input, Table, Button, Dropdown, Tabs, TabsProps } from 'antd';
import { Input, Table, Button, Dropdown } from 'antd';
import { MoreOutlined } from '@ant-design/icons';
import { useHistory } from 'react-router-dom';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import { withSiteId, dataManagement } from "App/routes";
import { Filter, Album } from "lucide-react";
import { list } from '../Activity/Page'
import { withSiteId, dataManagement } from 'App/routes';
import { Filter, Album } from 'lucide-react';
import { list } from '../Activity/Page';
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
import ColumnsModal from 'Components/DataManagement/Activity/ColumnsModal';
const customTabBar: TabsProps['renderTabBar'] = (props, DefaultTabBar) => (
<DefaultTabBar {...props} className="!mb-0" />
);
import FullPagination from 'Shared/FullPagination';
import Tabs from 'Shared/Tabs'
function ListPage() {
const { projectsStore } = useStore();
const siteId = projectsStore.activeSiteId;
const history = useHistory();
const toUser = (id: string) => history.push(withSiteId(dataManagement.userPage(id), siteId));
const toUser = (id: string) =>
history.push(withSiteId(dataManagement.userPage(id), siteId));
const [view, setView] = React.useState('users');
const views = [
{
key: 'users',
label: <div className={'text-lg font-medium'}>Users</div>,
content: <div>placeholder</div>,
},
{
key: 'events',
label: <div className={'text-lg font-medium'}>Events</div>,
content: <div>placeholder</div>,
},
];
return (
<div className="flex flex-col gap-4 rounded-lg border bg-white mx-auto" style={{ maxWidth: 1360 }}>
<div className={'flex items-center justify-between border-b p-4 pt-2 '}>
<div
className="flex flex-col gap-4 rounded-lg border bg-white mx-auto"
style={{ maxWidth: 1360 }}
>
<div className={'flex items-center justify-between border-b px-4 pt-2 '}>
<Tabs
type={'line'}
defaultActiveKey={'users'}
activeKey={view}
style={{ borderBottom: 'none' }}
onChange={(key) => setView(key)}
items={views}
renderTabBar={customTabBar}
/>
<div className="flex items-center gap-2">
<Button type={'text'} icon={<Album size={14} />}>Docs</Button>
<Button type={'text'} icon={<Album size={14} />}>
Docs
</Button>
<Input.Search size={'small'} placeholder={'Name, email, ID'} />
</div>
</div>
@ -90,14 +86,30 @@ function EventsList() {
sorter: (a, b) => a.monthVolume.localeCompare(b.monthVolume),
},
{
title: '30 Day Query',
title: '30 Day Queries',
dataIndex: 'monthQuery',
key: 'monthQuery',
showSorterTooltip: { target: 'full-header' },
sorter: (a, b) => a.monthQuery.localeCompare(b.monthQuery),
},
]
return <Table columns={columns} dataSource={list} pagination={false} />;
];
const page = 1;
const total = 100;
const onPageChange = (page: number) => {};
const limit = 10;
return (
<div>
<Table columns={columns} dataSource={list} pagination={false} />
<FullPagination
page={page}
limit={limit}
total={total}
listLen={list.length}
onPageChange={onPageChange}
entity={'events'}
/>
</div>
);
}
function UsersList({ toUser }: { toUser: (id: string) => void }) {
@ -147,8 +159,8 @@ function UsersList({ toUser }: { toUser: (id: string) => void }) {
email: 'sad;jsadk',
},
updatedAt: Date.now(),
})
]
}),
];
const dropdownItems = [
{
@ -211,8 +223,8 @@ function UsersList({ toUser }: { toUser: (id: string) => void }) {
const list = [];
const onAddFilter = () => console.log('add filter');
const excludeFilterKeys = []
const excludeCategory = []
const excludeFilterKeys = [];
const excludeCategory = [];
const shownCols = columns.map((col) => ({
...col,
@ -229,8 +241,8 @@ function UsersList({ toUser }: { toUser: (id: string) => void }) {
setEditCols(false);
};
return (
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2 px-4">
<div className="flex flex-col">
<div className="flex items-center gap-2 px-4 pb-2">
{/* 1.23 -- <span>Show by</span>*/}
{/*<Segmented*/}
{/* size={'small'}*/}
@ -252,7 +264,7 @@ function UsersList({ toUser }: { toUser: (id: string) => void }) {
icon={<Filter size={16} strokeWidth={1} />}
type="default"
size={'small'}
className='btn-add-filter'
className="btn-add-filter"
>
Filters
</Button>
@ -269,36 +281,24 @@ function UsersList({ toUser }: { toUser: (id: string) => void }) {
/>
</OutsideClickDetectingDiv>
) : null}
<Table
onRow={(record) => ({
onClick: () => toUser(record.userId),
})}
pagination={false}
rowClassName={'cursor-pointer'}
dataSource={testUsers}
columns={shownCols}
/>
</div>
<div className="flex items-center justify-between px-4 py-3 shadow-sm w-full bg-white rounded-lg mt-2">
<div>
{'Showing '}
<span className="font-medium">{(page - 1) * limit + 1}</span>
{' to '}
<span className="font-medium">
{(page - 1) * limit + list.length}
</span>
{' of '}
<span className="font-medium">{numberWithCommas(total)}</span>
{' users.'}
</div>
<Pagination
page={page}
total={total}
onPageChange={onPageChange}
limit={limit}
debounceRequest={500}
<Table
onRow={(record) => ({
onClick: () => toUser(record.userId),
})}
pagination={false}
rowClassName={'cursor-pointer'}
dataSource={testUsers}
columns={shownCols}
/>
</div>
<FullPagination
page={page}
limit={limit}
total={total}
listLen={list.length}
onPageChange={onPageChange}
entity={'users'}
/>
</div>
);
}

View file

@ -0,0 +1,42 @@
import React from 'react';
import { Pagination } from 'UI';
import { numberWithCommas } from 'App/utils';
function FullPagination({
page,
limit,
total,
listLen,
onPageChange,
entity,
}: {
page: number;
limit: number;
total: number;
listLen: number;
onPageChange: (page: number) => void;
entity?: string;
}) {
return (
<div className="flex items-center justify-between px-4 py-3 shadow-sm w-full bg-white rounded-lg mt-2">
<div>
{'Showing '}
<span className="font-medium">{(page - 1) * limit + 1}</span>
{' to '}
<span className="font-medium">{(page - 1) * limit + listLen}</span>
{' of '}
<span className="font-medium">{numberWithCommas(total)}</span>
{entity ? ` ${entity}.` : '.'}
</div>
<Pagination
page={page}
total={total}
onPageChange={onPageChange}
limit={limit}
debounceRequest={500}
/>
</div>
);
}
export default FullPagination;

View file

@ -0,0 +1,35 @@
import React from 'react';
import { Tabs, TabsProps } from 'antd';
const customTabBar: TabsProps['renderTabBar'] = (props, DefaultTabBar) => (
<DefaultTabBar {...props} className="!mb-0" />
);
function CustomizedTabs({
items,
onChange,
activeKey,
}: {
items: { key: string; label: React.ReactNode }[];
onChange: (key: string) => void;
activeKey: string;
}) {
const customItems = items.map((i) => ({
...i,
content: <div>placeholder</div>,
}));
return (
<Tabs
type={'line'}
defaultActiveKey={items[0].key}
activeKey={activeKey}
style={{ borderBottom: 'none' }}
onChange={onChange}
items={customItems}
renderTabBar={customTabBar}
/>
);
}
export default CustomizedTabs;