change(ui): make components|

This commit is contained in:
sylenien 2022-12-01 11:47:47 +01:00 committed by Delirium
parent 7c12c6683e
commit 3d760b4ed0
6 changed files with 259 additions and 0 deletions

View file

@ -0,0 +1,137 @@
import React from 'react'
import { Loader, Pagination, Tooltip } from 'UI';
import { connect } from 'react-redux';
import SessionItem from 'Shared/SessionItem';
import { addFilterByKeyAndValue, updateCurrentPage, applyFilter } from 'Duck/liveSearch';
import { List } from 'immutable';
import { FilterKey } from 'App/types/filter/filterType';
import Select from 'Shared/Select';
import SortOrderButton from 'Shared/SortOrderButton';
import { KEYS } from 'Types/filter/customFilter';
import { capitalize } from 'App/utils';
import { useStore } from 'App/mstore'
import { observer } from 'mobx-react-lite'
import cn from 'classnames'
import Session from 'App/mstore/types/session';
const PER_PAGE = 10;
interface OwnProps {}
interface ConnectProps {
loading: boolean;
metaListLoading: boolean;
list: List<any>;
filter: any;
currentPage: number;
metaList: any;
sort: any;
total: number;
addFilterByKeyAndValue: (key: FilterKey, value: string) => void;
updateCurrentPage: (page: number) => void;
applyFilter: (filter: any) => void;
onAdd: () => void;
}
type Props = OwnProps & ConnectProps;
function AssistSessionsModal(props: Props) {
const { assistTabStore } = useStore();
const { loading, list, metaList = [], filter, currentPage, total, onAdd } = props;
const onUserClick = () => false;
const { filters } = filter;
const hasUserFilter = filters.map((i: any) => i.key).includes(KEYS.USERID);
const sortOptions = metaList
.map((i: any) => ({
label: capitalize(i),
value: i,
}))
.toJS();
React.useEffect(() => {
props.applyFilter({ ...filter });
}, []);
const onSortChange = ({ value }: any) => {
props.applyFilter({ sort: value.value });
};
const onSessionAdd = (session: Session) => {
assistTabStore.addSession(session);
onAdd()
}
return (
<div className="bg-gray-lightest box-shadow h-screen p-4" style={{ width: '840px' }}>
<div className="flex items-center my-2">
<div className="flex items-center">
<span className="mr-2 color-gray-medium">Sort By</span>
<Tooltip
title="No metadata available to sort"
disabled={sortOptions.length > 0}
>
<div className={cn("flex items-center", { 'disabled': sortOptions.length === 0 })} >
<Select
plain
right
options={sortOptions}
onChange={onSortChange}
value={sortOptions.find((i: any) => i.value === filter.sort) || sortOptions[0]}
/>
<div className="mx-2" />
<SortOrderButton onChange={(state: any) => props.applyFilter({ order: state })} sortOrder={filter.order} />
</div>
</Tooltip>
</div>
</div>
<Loader loading={loading}>
<>
{list.map((session) => (
<React.Fragment key={session.sessionID}>
<div className="rounded bg-white mb-2 overflow-hidden border">
<SessionItem
key={session.sessionId}
session={session}
live
hasUserFilter={hasUserFilter}
onUserClick={onUserClick}
metaList={metaList}
onClick={() => onSessionAdd(session)}
/>
</div>
</React.Fragment>
))}
</>
</Loader>
{total > PER_PAGE && (
<div className="w-full flex items-center justify-center py-6">
<Pagination
page={currentPage}
totalPages={Math.ceil(total / PER_PAGE)}
onPageChange={(page: any) => props.updateCurrentPage(page)}
limit={PER_PAGE}
/>
</div>
)}
</div>
)
}
export default connect(
(state: any) => ({
list: state.getIn(['liveSearch', 'list']),
loading: state.getIn(['liveSearch', 'fetchList', 'loading']),
metaListLoading: state.getIn(['customFields', 'fetchRequest', 'loading']),
filter: state.getIn(['liveSearch', 'instance']),
total: state.getIn(['liveSearch', 'total']),
currentPage: state.getIn(['liveSearch', 'currentPage']),
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
sort: state.getIn(['liveSearch', 'sort']),
}),
{
applyFilter,
addFilterByKeyAndValue,
updateCurrentPage,
}
)(AssistSessionsModal);

View file

@ -0,0 +1 @@
export { default } from './AssistSessionsModal'

View file

@ -0,0 +1,75 @@
import React from 'react';
import cn from 'classnames';
import { useModal } from 'App/components/Modal';
import { Icon } from 'UI';
import AssistSessionsModal from '../AssistSessionsModal';
import { useStore } from 'App/mstore'
import Session from 'App/mstore/types/session'
import { observer } from 'mobx-react-lite'
interface ITab {
onClick?: () => void;
onDoubleClick?: () => void;
classNames?: string;
children: React.ReactNode;
}
const Tab = (props: ITab) => (
<div
onDoubleClick={props.onDoubleClick}
onClick={props.onClick}
className={cn('p-1 rounded flex items-center justify-center cursor-pointer', props.classNames)}
>
{props.children}
</div>
);
const InactiveTab = (props: Omit<ITab, 'children' | 'onDoubleClick'>) => (
<Tab onClick={props.onClick} classNames="hover:bg-gray-bg bg-gray-light">
<Icon name="plus" size="22" color="white" />
</Tab>
);
const ActiveTab = (props: Omit<ITab, 'children'>) => (
<Tab onDoubleClick={props.onDoubleClick} classNames="hover:bg-teal bg-borderColor-primary">
<Icon name="play-fill-new" size="22" color="white" />
</Tab>
);
const CurrentTab = () => (
<Tab classNames="bg-teal color-white">
<span style={{ fontSize: '0.65rem' }}>PLAYING</span>
</Tab>
);
function AssistTabs({ session }: { session: Session }) {
const { showModal, hideModal } = useModal();
const { assistTabStore } = useStore()
const placeholder = new Array(4 - assistTabStore.sessions.length).fill(0)
React.useEffect(() => {
if (assistTabStore.sessions.length === 0) {
assistTabStore.addSession(session)
assistTabStore.setActiveSession(session.sessionId)
}
}, [])
const showAssistList = () => showModal(<AssistSessionsModal onAdd={hideModal} />, { right: true });
return (
<div className="grid grid-cols-2 w-28 h-full" style={{ gap: '4px' }}>
{assistTabStore.sessions.map(session => (
<React.Fragment key={session.sessionId}>
{assistTabStore.isActive(session.sessionId)
? <CurrentTab /> : <ActiveTab />}
</React.Fragment>
)
)}
{placeholder.map((_, i) => (
<React.Fragment key={i}>
<InactiveTab onClick={showAssistList} />
</React.Fragment>
))}
</div>
);
}
export default observer(AssistTabs);

View file

@ -3,6 +3,7 @@ import cn from 'classnames';
import { connect } from 'react-redux';
import { STORAGE_TYPES, selectStorageType } from 'Player';
import LiveTag from 'Shared/LiveTag';
import AssistSessionsTabs from './AssistSessionsTabs';
import { Icon, Tooltip } from 'UI';
import {
@ -95,6 +96,7 @@ function Controls(props: any) {
skipInterval,
disabledRedux,
showStorageRedux,
session,
// showStackRedux,
} = props;
@ -259,6 +261,10 @@ function Controls(props: any) {
)}
</div>
<div>
<AssistSessionsTabs session={session} />
</div>
<div className="flex items-center h-full">
<ControlButton
disabled={disabled && !inspectorMode}
@ -368,6 +374,7 @@ export default connect(
bottomBlock: state.getIn(['components', 'player', 'bottomBlock']),
showStorageRedux: !state.getIn(['components', 'player', 'hiddenHints', 'storage']),
showStackRedux: !state.getIn(['components', 'player', 'hiddenHints', 'stack']),
session: state.getIn(['sessions', 'current']),
closedLive:
!!state.getIn(['sessions', 'errors']) || !state.getIn(['sessions', 'current', 'live']),
skipInterval: state.getIn(['components', 'player', 'skipInterval']),

View file

@ -0,0 +1,36 @@
import { makeAutoObservable } from "mobx"
import Session from './types/session';
type TabSessions = [Session?,Session?,Session?,Session?]
export default class AssistTabStore {
sessions: TabSessions = []
activeSession: Session = null
constructor() {
makeAutoObservable(this)
}
isActive(sessionId: string): boolean {
return this.activeSession.sessionId === sessionId
}
setSessions(sessions: TabSessions) {
this.sessions = sessions
}
addSession(session: Session) {
if (this.sessions.length < 4) {
this.sessions.push(session)
}
}
setActiveSession(sessionId: string) {
this.activeSession = this.sessions.find(session => session.sessionId === sessionId)
}
reset() {
this.sessions = []
this.activeSession = null
}
}

View file

@ -24,6 +24,7 @@ import SessionStore from './sessionStore';
import NotesStore from './notesStore';
import BugReportStore from './bugReportStore'
import RecordingsStore from './recordingsStore'
import AssistTabStore from './assistTabStore';
export class RootStore {
dashboardStore: DashboardStore;
@ -39,6 +40,7 @@ export class RootStore {
notesStore: NotesStore;
bugReportStore: BugReportStore;
recordingsStore: RecordingsStore;
assistTabStore: AssistTabStore;
constructor() {
this.dashboardStore = new DashboardStore();
@ -54,6 +56,7 @@ export class RootStore {
this.notesStore = new NotesStore();
this.bugReportStore = new BugReportStore();
this.recordingsStore = new RecordingsStore();
this.assistTabStore = new AssistTabStore();
}
initClient() {