change(ui): projects revamp - progress avatar of samplerate, scroll etc.,
This commit is contained in:
parent
1b1287515b
commit
40ff41f97d
6 changed files with 80 additions and 74 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { NoContent } from 'UI';
|
||||
import CustomFieldForm from './CustomFieldForm';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
|
@ -8,6 +7,7 @@ import { observer } from 'mobx-react-lite';
|
|||
import { List, Space, Typography, Button, Tooltip } from 'antd';
|
||||
import { PencilIcon, PlusIcon, Tags } from 'lucide-react';
|
||||
import usePageTitle from '@/hooks/usePageTitle';
|
||||
import { Empty } from '.store/antd-virtual-7db13b4af6/package';
|
||||
|
||||
const CustomFields = () => {
|
||||
usePageTitle('Metadata - OpenReplay Preferences');
|
||||
|
|
@ -59,36 +59,26 @@ const CustomFields = () => {
|
|||
</Typography.Text>
|
||||
</Space>
|
||||
|
||||
|
||||
<NoContent
|
||||
title={
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<AnimatedSVG name={ICONS.NO_METADATA} size={60} />
|
||||
<div className="text-center my-4">None added yet</div>
|
||||
</div>
|
||||
}
|
||||
size="small"
|
||||
show={fields.length === 0}
|
||||
>
|
||||
<List
|
||||
loading={loading}
|
||||
dataSource={fields}
|
||||
renderItem={(field: any) => (
|
||||
<List.Item
|
||||
// disabled={deletingItem !== null && deletingItem === field.index}
|
||||
onClick={() => handleInit(field)}
|
||||
className="cursor-pointer group hover:bg-active-blue !px-4"
|
||||
actions={[
|
||||
<Button className="opacity-0 group-hover:!opacity-100" icon={<PencilIcon size={14} />} />
|
||||
]}
|
||||
>
|
||||
<List.Item.Meta
|
||||
title={field.key}
|
||||
avatar={<Tags size={20} />}
|
||||
/>
|
||||
</List.Item>
|
||||
)} />
|
||||
</NoContent>
|
||||
<List
|
||||
locale={{
|
||||
emptyText: <Empty description="None added yet" image={<AnimatedSVG name={ICONS.NO_METADATA} size={60} />} />
|
||||
}}
|
||||
loading={loading}
|
||||
dataSource={fields}
|
||||
renderItem={(field: any) => (
|
||||
<List.Item
|
||||
onClick={() => handleInit(field)}
|
||||
className="cursor-pointer group hover:bg-active-blue !px-4"
|
||||
actions={[
|
||||
<Button className="opacity-0 group-hover:!opacity-100" icon={<PencilIcon size={14} />} />
|
||||
]}
|
||||
>
|
||||
<List.Item.Meta
|
||||
title={field.key}
|
||||
avatar={<Tags size={20} />}
|
||||
/>
|
||||
</List.Item>
|
||||
)} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Avatar, Input, Menu, List, Typography } from 'antd';
|
||||
import { Avatar, Input, Menu, Progress } from 'antd';
|
||||
import { useStore } from '@/mstore';
|
||||
import Project from '@/mstore/types/project';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
|
@ -21,30 +21,65 @@ function ProjectList() {
|
|||
|
||||
return (
|
||||
<div className="h-full flex flex-col gap-4">
|
||||
<div className="p-4">
|
||||
<div className="px-4 mt-4">
|
||||
<Input.Search
|
||||
placeholder="Search"
|
||||
onSearch={onSearch}
|
||||
onClear={() => setSearch('')}
|
||||
allowClear
|
||||
// className="m-4"
|
||||
/>
|
||||
</div>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={[config.pid + '']}
|
||||
className="h-full w-full ml-0 pl-0 !bg-white !border-r-0"
|
||||
items={list.filter((item: Project) => item.name.toLowerCase().includes(search.toLowerCase())).map((project) => ({
|
||||
key: project.id,
|
||||
label: project.name,
|
||||
onClick: () => onProjectClick(project),
|
||||
icon: <Avatar className="bg-tealx-light"
|
||||
icon={project.platform === 'web' ? <AppWindowMac size={18} color="teal" /> :
|
||||
<Smartphone size={18} color="teal" />} />
|
||||
})) as any}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
height: 'calc(100vh - 250px)'
|
||||
}}
|
||||
className="overflow-y-auto"
|
||||
>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={[config.pid + '']}
|
||||
className="w-full ml-0 pl-0 !bg-white !border-r-0"
|
||||
items={list.filter((item: Project) => item.name.toLowerCase().includes(search.toLowerCase())).map((project) => ({
|
||||
key: project.id,
|
||||
label: project.name,
|
||||
onClick: () => onProjectClick(project),
|
||||
icon: <ProjectIconWithProgress platform={project.platform} progress={project.sampleRate} />
|
||||
})) as any}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(ProjectList);
|
||||
|
||||
|
||||
const ProjectIconWithProgress: React.FC<{
|
||||
platform: string; progress: number
|
||||
}> = ({ platform, progress }) => {
|
||||
return (
|
||||
<div className="relative flex items-center justify-center mr-2 leading-none">
|
||||
<Progress
|
||||
type="circle"
|
||||
percent={progress}
|
||||
size={28}
|
||||
format={() => ''}
|
||||
strokeWidth={4}
|
||||
strokeColor="#23959a"
|
||||
/>
|
||||
<div className="absolute">
|
||||
<Avatar
|
||||
className="bg-tealx-light"
|
||||
size={26}
|
||||
icon={
|
||||
platform === 'web' ? (
|
||||
<AppWindowMac size={16} color="teal" />
|
||||
) : (
|
||||
<Smartphone size={16} color="teal" />
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { useStore } from '@/mstore';
|
||||
import { List, Button, Typography, Space } from 'antd';
|
||||
import { List, Button, Typography, Space, Empty } from 'antd';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { PencilIcon, ScanSearch } from 'lucide-react';
|
||||
import { useModal } from 'Components/ModalContext';
|
||||
import TagForm from 'Components/Client/Projects/TagForm';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
|
||||
function ProjectTags() {
|
||||
const { tagWatchStore, projectsStore } = useStore();
|
||||
|
|
@ -36,6 +37,9 @@ function ProjectTags() {
|
|||
</ul>
|
||||
</Space>
|
||||
<List
|
||||
locale={{
|
||||
emptyText: <Empty description="No tags found" image={<AnimatedSVG name={ICONS.NO_METADATA} size={60} />} />
|
||||
}}
|
||||
loading={tagWatchStore.isLoading}
|
||||
dataSource={list}
|
||||
renderItem={(item) => (
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ function Projects() {
|
|||
]}
|
||||
>
|
||||
<Layout>
|
||||
<Layout.Sider width={300} trigger={null} className="!bg-white border-r">
|
||||
<Layout.Sider width={300} trigger={null}
|
||||
className="!bg-white border-r">
|
||||
<ProjectList />
|
||||
</Layout.Sider>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@ import * as routes from 'App/routes';
|
|||
import {
|
||||
CLIENT_DEFAULT_TAB,
|
||||
CLIENT_TABS,
|
||||
bookmarks,
|
||||
client,
|
||||
fflags,
|
||||
notes,
|
||||
sessions,
|
||||
withSiteId
|
||||
} from 'App/routes';
|
||||
import { MODULES } from 'Components/Client/Modules';
|
||||
|
|
@ -33,13 +29,6 @@ import { useStore } from 'App/mstore';
|
|||
|
||||
const { Text } = Typography;
|
||||
|
||||
const TabToUrlMap = {
|
||||
all: sessions() as '/sessions',
|
||||
bookmark: bookmarks() as '/bookmarks',
|
||||
notes: notes() as '/notes',
|
||||
flags: fflags() as '/feature-flags'
|
||||
};
|
||||
|
||||
interface Props extends RouteComponentProps {
|
||||
siteId?: string;
|
||||
isCollapsed?: boolean;
|
||||
|
|
@ -135,16 +124,6 @@ function SideMenu(props: Props) {
|
|||
});
|
||||
}, [isAdmin, isEnterprise, isPreferencesActive, modules, spotOnly, siteId]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const currentLocation = location.pathname;
|
||||
// const tab = Object.keys(TabToUrlMap).find((tab: keyof typeof TabToUrlMap) =>
|
||||
// currentLocation.includes(TabToUrlMap[tab])
|
||||
// );
|
||||
// if (tab && tab !== searchStore.activeTab && siteId) {
|
||||
// searchStore.setActiveTab({ type: tab });
|
||||
// }
|
||||
}, [location.pathname]);
|
||||
|
||||
const menuRoutes: any = {
|
||||
[MENU.EXIT]: () =>
|
||||
props.history.push(withSiteId(routes.sessions(), siteId)),
|
||||
|
|
@ -164,7 +143,6 @@ function SideMenu(props: Props) {
|
|||
[PREFERENCES_MENU.SESSION_LISTING]: () =>
|
||||
client(CLIENT_TABS.SESSIONS_LISTING),
|
||||
[PREFERENCES_MENU.INTEGRATIONS]: () => client(CLIENT_TABS.INTEGRATIONS),
|
||||
[PREFERENCES_MENU.METADATA]: () => client(CLIENT_TABS.CUSTOM_FIELDS),
|
||||
[PREFERENCES_MENU.WEBHOOKS]: () => client(CLIENT_TABS.WEBHOOKS),
|
||||
[PREFERENCES_MENU.PROJECTS]: () => client(CLIENT_TABS.SITES),
|
||||
[PREFERENCES_MENU.ROLES_ACCESS]: () => client(CLIENT_TABS.MANAGE_ROLES),
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ export const enum PREFERENCES_MENU {
|
|||
ACCOUNT = 'account',
|
||||
SESSION_LISTING = 'session-listing',
|
||||
INTEGRATIONS = 'integrations',
|
||||
METADATA = 'metadata',
|
||||
WEBHOOKS = 'webhooks',
|
||||
MODULES = 'modules',
|
||||
PROJECTS = 'projects',
|
||||
|
|
@ -131,7 +130,6 @@ export const preferences: Category[] = [
|
|||
{ label: 'Account', key: PREFERENCES_MENU.ACCOUNT, icon: 'person' },
|
||||
{ label: 'Sessions Listing', key: PREFERENCES_MENU.SESSION_LISTING, icon: 'card-list' },
|
||||
{ label: 'Integrations', key: PREFERENCES_MENU.INTEGRATIONS, icon: 'plug' },
|
||||
{ label: 'Metadata', key: PREFERENCES_MENU.METADATA, icon: 'tags' },
|
||||
{ label: 'Webhooks', key: PREFERENCES_MENU.WEBHOOKS, icon: 'link-45deg' },
|
||||
{ label: 'Modules', key: PREFERENCES_MENU.MODULES, icon: 'puzzle' },
|
||||
{ label: 'Projects', key: PREFERENCES_MENU.PROJECTS, icon: 'folder2' },
|
||||
|
|
@ -159,4 +157,4 @@ export const spotOnlyCats = [
|
|||
MENU.PREFERENCES,
|
||||
MENU.SUPPORT,
|
||||
MENU.SPOTS,
|
||||
]
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue