This commit is contained in:
dank074 2021-10-21 14:30:36 -05:00
parent 3ca58c81a4
commit 700a890b1d
13 changed files with 202 additions and 27 deletions

View File

@ -4,7 +4,9 @@ import { GetSessionDataManager } from '../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
import { useModToolsContext } from '../../context/ModToolsContext'; import { useModToolsContext } from '../../context/ModToolsContext';
import { ModToolsTicketsViewProps } from './ModToolsTicketsView.types'; import { ModToolsTicketsViewProps } from './ModToolsTicketsView.types';
import { ModToolsMyIssuesTabView } from './my-issues/ModToolsMyIssuesTabView';
import { ModToolsOpenIssuesTabView } from './open-issues/ModToolsOpenIssuesTabView'; import { ModToolsOpenIssuesTabView } from './open-issues/ModToolsOpenIssuesTabView';
import { ModToolsPickedIssuesTabView } from './picked-issues/ModToolsPickedIssuesTabView';
const TABS: string[] = [ const TABS: string[] = [
'Open Issues', 'Open Issues',
@ -45,9 +47,11 @@ export const ModToolsTicketsView: FC<ModToolsTicketsViewProps> = props =>
switch(currentTab) switch(currentTab)
{ {
case 0: return <ModToolsOpenIssuesTabView openIssues={openIssues}/>; case 0: return <ModToolsOpenIssuesTabView openIssues={openIssues}/>;
case 1: return <ModToolsMyIssuesTabView myIssues={myIssues} />;
case 2: return <ModToolsPickedIssuesTabView pickedIssues={pickedIssues}/>;
default: return null; default: return null;
} }
}, [currentTab, openIssues]); }, [currentTab, myIssues, openIssues, pickedIssues]);
return ( return (
<NitroCardView className="nitro-mod-tools-tickets" simple={ false }> <NitroCardView className="nitro-mod-tools-tickets" simple={ false }>

View File

@ -0,0 +1,53 @@
import { FC } from 'react';
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
import { ModToolsMyIssuesTabViewProps } from './ModToolsMyIssuesTabView.types';
export const ModToolsMyIssuesTabView: FC<ModToolsMyIssuesTabViewProps> = props =>
{
const { myIssues = null } = props;
const RowRenderer: ListRowRenderer = (props: ListRowProps) =>
{
const item = myIssues[props.index];
return (
<div key={props.key} style={props.style} className="row issue-entry justify-content-start">
<div className="col-auto text-center">{item.categoryId}</div>
<div className="col justify-content-start username"><span className="fw-bold cursor-pointer">{item.reportedUserName}</span></div>
<div className="col-sm-2 justify-content-start"><span className="text-break text-wrap h-100">{item.getOpenTime(new Date().getTime())}</span></div>
<div className="col-sm-2">
<button className="btn btn-sm btn-primary">View Issue</button>
</div>
</div>
);
};
return (
<>
<div className="row align-items-start w-100">
<div className="col-auto text-center fw-bold">Type</div>
<div className="col fw-bold">Room/Player</div>
<div className="col-sm-2 fw-bold">Opened</div>
<div className="col-sm-2"></div>
</div>
<div className="row w-100 h-100 issues">
<AutoSizer defaultWidth={400} defaultHeight={200}>
{({ height, width }) =>
{
return (
<List
width={width}
height={height}
rowCount={myIssues.length}
rowHeight={25}
className={'issues-container'}
rowRenderer={RowRenderer}
/>
)
}
}
</AutoSizer>
</div>
</>
);
}

View File

@ -0,0 +1,6 @@
import { IssueMessageData } from '@nitrots/nitro-renderer';
export interface ModToolsMyIssuesTabViewProps
{
myIssues: IssueMessageData[];
}

View File

@ -1,11 +1,53 @@
import { FC } from 'react'; import { FC } from 'react';
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
import { ModToolsOpenIssuesTabViewProps } from './ModToolsOpenIssuesTabView.types'; import { ModToolsOpenIssuesTabViewProps } from './ModToolsOpenIssuesTabView.types';
export const ModToolsOpenIssuesTabView: FC<ModToolsOpenIssuesTabViewProps> = props => export const ModToolsOpenIssuesTabView: FC<ModToolsOpenIssuesTabViewProps> = props =>
{ {
const { openIssues = null } = props; const { openIssues = null } = props;
const RowRenderer: ListRowRenderer = (props: ListRowProps) =>
{
const item = openIssues[props.index];
return ( return (
<div>{openIssues.length}</div> <div key={props.key} style={props.style} className="row issue-entry justify-content-start">
<div className="col-auto text-center">{item.categoryId}</div>
<div className="col justify-content-start username"><span className="fw-bold cursor-pointer">{item.reportedUserName}</span></div>
<div className="col-sm-2 justify-content-start"><span className="text-break text-wrap h-100">{item.getOpenTime(new Date().getTime())}</span></div>
<div className="col-sm-2">
<button className="btn btn-sm btn-primary">Pick Issue</button>
</div>
</div>
);
};
return (
<>
<div className="row align-items-start w-100">
<div className="col-auto text-center fw-bold">Type</div>
<div className="col fw-bold">Room/Player</div>
<div className="col-sm-2 fw-bold">Opened</div>
<div className="col-sm-2"></div>
</div>
<div className="row w-100 h-100 issues">
<AutoSizer defaultWidth={400} defaultHeight={200}>
{({ height, width }) =>
{
return (
<List
width={width}
height={height}
rowCount={openIssues.length}
rowHeight={25}
className={'issues-container'}
rowRenderer={RowRenderer}
/>
)
}
}
</AutoSizer>
</div>
</>
); );
} }

View File

@ -0,0 +1,53 @@
import { FC } from 'react';
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
import { ModToolsPickedIssuesTabViewProps } from './ModToolsPickedIssuesTabView.types';
export const ModToolsPickedIssuesTabView: FC<ModToolsPickedIssuesTabViewProps> = props =>
{
const { pickedIssues = null } = props;
const RowRenderer: ListRowRenderer = (props: ListRowProps) =>
{
const item = pickedIssues[props.index];
return (
<div key={props.key} style={props.style} className="row issue-entry justify-content-start">
<div className="col-auto text-center">{item.categoryId}</div>
<div className="col justify-content-start username"><span className="fw-bold cursor-pointer">{item.reportedUserName}</span></div>
<div className="col-sm-2 justify-content-start"><span className="text-break text-wrap h-100">{item.getOpenTime(new Date().getTime())}</span></div>
<div className="col-sm-2">
{item.pickerUserName}
</div>
</div>
);
};
return (
<>
<div className="row align-items-start w-100">
<div className="col-auto text-center fw-bold">Type</div>
<div className="col fw-bold">Room/Player</div>
<div className="col-sm-2 fw-bold">Opened</div>
<div className="col-sm-2 fw-bold">Picker</div>
</div>
<div className="row w-100 h-100 issues">
<AutoSizer defaultWidth={400} defaultHeight={200}>
{({ height, width }) =>
{
return (
<List
width={width}
height={height}
rowCount={pickedIssues.length}
rowHeight={25}
className={'issues-container'}
rowRenderer={RowRenderer}
/>
)
}
}
</AutoSizer>
</div>
</>
);
}

View File

@ -0,0 +1,6 @@
import { IssueMessageData } from '@nitrots/nitro-renderer';
export interface ModToolsPickedIssuesTabViewProps
{
pickedIssues: IssueMessageData[];
}

View File

@ -103,7 +103,7 @@ export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
return ( return (
<> <>
<NitroCardView className="nitro-mod-tools-user" simple={true}> <NitroCardView className="nitro-mod-tools-user" simple={true}>
<NitroCardHeaderView headerText={ LocalizeText('modtools.userinfo.title', [ 'username' ], [ userInfo.userName ]) } onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={ LocalizeText('modtools.userinfo.title', [ 'username' ], [ userInfo.userName ]) } onCloseClick={ () => onCloseClick() } />
<NitroCardContentView className="text-black"> <NitroCardContentView className="text-black">
<NitroLayoutGrid> <NitroLayoutGrid>
<NitroLayoutGridColumn size={ 8 }> <NitroLayoutGridColumn size={ 8 }>
@ -143,11 +143,11 @@ export const ModToolsUserView: FC<ModToolsUserViewProps> = props =>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
{ sendMessageVisible && { sendMessageVisible &&
<ModToolsSendUserMessageView user={ { userId: userId, username: userInfo.userName } } onCloseClick={ event => setSendMessageVisible(false) } /> } <ModToolsSendUserMessageView user={ { userId: userId, username: userInfo.userName } } onCloseClick={ () => setSendMessageVisible(false) } /> }
{ modActionVisible && { modActionVisible &&
<ModToolsUserModActionView user={ { userId: userId, username: userInfo.userName } } onCloseClick={ event => setModActionVisible(false) } /> } <ModToolsUserModActionView user={ { userId: userId, username: userInfo.userName } } onCloseClick={ () => setModActionVisible(false) } /> }
{ roomVisitsVisible && { roomVisitsVisible &&
<ModToolsUserRoomVisitsView userId={ userId } onCloseClick={ event => setRoomVisitsVisible(false) } /> } <ModToolsUserRoomVisitsView userId={ userId } onCloseClick={ () => setRoomVisitsVisible(false) } /> }
</> </>
); );
} }

View File

@ -49,13 +49,20 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
return values; return values;
}, [cfhCategories]); }, [cfhCategories]);
const sendDefaultSanction = useCallback(() =>
{
SendMessageHook(new DefaultSanctionMessageComposer(user.userId, selectedTopic, message));
onCloseClick();
}, [message, onCloseClick, selectedTopic, user.userId]);
const sendSanction = useCallback(() => const sendSanction = useCallback(() =>
{ {
if(selectedTopic === -1) if( (selectedTopic === -1) || (selectedAction === -1) )
{ {
dispatchUiEvent(new NotificationAlertEvent(['You must select a CFH topic'], null, null, null, 'Error', null)); dispatchUiEvent(new NotificationAlertEvent(['You must select a CFH topic and Sanction'], null, null, null, 'Error', null));
return; return;
} }
if(!settings || !settings.cfhPermission) if(!settings || !settings.cfhPermission)
{ {
dispatchUiEvent(new NotificationAlertEvent(['You do not have permission to do this'], null, null, null, 'Error', null)); dispatchUiEvent(new NotificationAlertEvent(['You do not have permission to do this'], null, null, null, 'Error', null));
@ -71,15 +78,14 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
return; return;
} }
const messageOrDefault = message.trim().length === 0 ? LocalizeText('help.cfh.topic.' + category.id) : message; if(!sanction)
if(!sanction) // send default sanction
{ {
SendMessageHook(new DefaultSanctionMessageComposer(user.userId, category.id, messageOrDefault)); dispatchUiEvent(new NotificationAlertEvent(['You must select a sanction'], null, null, null, 'Error', null));
onCloseClick(null);
return; return;
} }
const messageOrDefault = message.trim().length === 0 ? LocalizeText('help.cfh.topic.' + category.id) : message;
switch(sanction.actionType) switch(sanction.actionType)
{ {
case ModActionDefinition.ALERT: case ModActionDefinition.ALERT:
@ -147,12 +153,12 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
break; break;
} }
onCloseClick(null); onCloseClick();
}, [message, onCloseClick, selectedAction, selectedTopic, settings, topics, user.userId]); }, [message, onCloseClick, selectedAction, selectedTopic, settings, topics, user.userId]);
return ( return (
<NitroCardView className="nitro-mod-tools-user-action" simple={true}> <NitroCardView className="nitro-mod-tools-user-action" simple={true}>
<NitroCardHeaderView headerText={'Mod Action: ' + (user ? user.username : '')} onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={'Mod Action: ' + (user ? user.username : '')} onCloseClick={ () => onCloseClick() } />
<NitroCardContentView className="text-black"> <NitroCardContentView className="text-black">
{ user && { user &&
<> <>
@ -182,7 +188,10 @@ export const ModToolsUserModActionView: FC<ModToolsUserModActionViewProps> = pro
</div> </div>
<div className="form-group mb-2"> <div className="form-group mb-2">
<button type="button" className="btn btn-primary" onClick={ () => sendSanction()}>Sanction</button> <div className="d-flex justify-content-between">
<button type="button" className="btn btn-danger w-100 me-2" onClick={ () => sendSanction()}>Sanction</button>
<button className="btn btn-success w-100" onClick={ () => sendDefaultSanction()}>Default Sanction</button>
</div>
</div> </div>
</> </>
} }

View File

@ -1,8 +1,7 @@
import { MouseEvent } from 'react';
import { ISelectedUser } from '../../../utils/ISelectedUser'; import { ISelectedUser } from '../../../utils/ISelectedUser';
export interface ModToolsUserModActionViewProps export interface ModToolsUserModActionViewProps
{ {
user: ISelectedUser; user: ISelectedUser;
onCloseClick: (event: MouseEvent) => void; onCloseClick: () => void;
} }

View File

@ -42,7 +42,7 @@ export const ModToolsUserRoomVisitsView: FC<ModToolsUserRoomVisitsViewProps> = p
return ( return (
<NitroCardView className="nitro-mod-tools-user-visits" simple={true}> <NitroCardView className="nitro-mod-tools-user-visits" simple={true}>
<NitroCardHeaderView headerText={'User Visits'} onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={'User Visits'} onCloseClick={ () => onCloseClick() } />
<NitroCardContentView className="text-black"> <NitroCardContentView className="text-black">
{roomVisitData && {roomVisitData &&
<div className="row h-100 w-100 user-visits"> <div className="row h-100 w-100 user-visits">

View File

@ -1,7 +1,6 @@
import { MouseEvent } from 'react';
export interface ModToolsUserRoomVisitsViewProps export interface ModToolsUserRoomVisitsViewProps
{ {
userId: number; userId: number;
onCloseClick: (event: MouseEvent) => void; onCloseClick: () => void;
} }

View File

@ -1,8 +1,7 @@
import { MouseEvent } from 'react';
import { ISelectedUser } from '../../../utils/ISelectedUser'; import { ISelectedUser } from '../../../utils/ISelectedUser';
export interface ModToolsSendUserMessageViewProps export interface ModToolsSendUserMessageViewProps
{ {
user: ISelectedUser; user: ISelectedUser;
onCloseClick: (event: MouseEvent) => void; onCloseClick: () => void;
} }

View File

@ -1,6 +1,7 @@
import { ModMessageMessageComposer } from '@nitrots/nitro-renderer'; import { ModMessageMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { SendMessageHook } from '../../../../../hooks'; import { NotificationAlertEvent } from '../../../../../events';
import { dispatchUiEvent, SendMessageHook } from '../../../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
import { ModToolsSendUserMessageViewProps } from './ModToolsSendUserMessage.types'; import { ModToolsSendUserMessageViewProps } from './ModToolsSendUserMessage.types';
@ -12,16 +13,20 @@ export const ModToolsSendUserMessageView: FC<ModToolsSendUserMessageViewProps> =
const sendMessage = useCallback(() => const sendMessage = useCallback(() =>
{ {
if(message.trim().length === 0) return; if(message.trim().length === 0)
{
dispatchUiEvent(new NotificationAlertEvent(['Please write a message to user.'], null, null, null, 'Error', null));
return;
}
SendMessageHook(new ModMessageMessageComposer(user.userId, message, -999)); SendMessageHook(new ModMessageMessageComposer(user.userId, message, -999));
onCloseClick(null); onCloseClick();
}, [message, onCloseClick, user.userId]); }, [message, onCloseClick, user.userId]);
return ( return (
<NitroCardView className="nitro-mod-tools-user-message" simple={true}> <NitroCardView className="nitro-mod-tools-user-message" simple={true}>
<NitroCardHeaderView headerText={'Send Message'} onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={'Send Message'} onCloseClick={ () => onCloseClick() } />
<NitroCardContentView className="text-black"> <NitroCardContentView className="text-black">
{user && <> {user && <>
<div>Message To: {user.username}</div> <div>Message To: {user.username}</div>