[MIRROR] request manager refactor (#28818)

* request manager refactor (#84584)

* request manager refactor

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-07-13 15:00:01 +05:30
committed by GitHub
co-authored by Ben10Omintrix
parent 5741e1893d
commit 429e64fadb
2 changed files with 105 additions and 86 deletions
+4 -6
View File
@@ -243,12 +243,10 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
return TRUE
/datum/request_manager/ui_data(mob/user)
. = list(
"requests" = list()
)
var/list/data = list()
for (var/ckey in requests)
for (var/datum/request/request as anything in requests[ckey])
var/list/data = list(
data["requests"] += list(list(
"id" = request.id,
"req_type" = request.req_type,
"owner" = request.owner ? "[REF(request.owner)]" : null,
@@ -258,8 +256,8 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
"additional_info" = request.additional_information,
"timestamp" = request.timestamp,
"timestamp_str" = gameTimestamp(wtime = request.timestamp)
)
.["requests"] += list(data)
))
return data
#undef REQUEST_PRAYER
#undef REQUEST_CENTCOM
@@ -3,37 +3,65 @@
* @copyright 2021 bobbahbrown (https://github.com/bobbahbrown)
* @license MIT
*/
import { decodeHtmlEntities } from 'common/string';
import { createSearch, decodeHtmlEntities } from 'common/string';
import { useState } from 'react';
import { useBackend, useLocalState } from '../backend';
import { Button, Input, Popper, Section, Table } from '../components';
import { useBackend } from '../backend';
import { Button, Input, Popper, Section, Stack, Table } from '../components';
import { Window } from '../layouts';
type Data = {
requests: Request[];
};
type Request = {
id: string;
req_type: string;
owner: string;
owner_ckey: string;
owner_name: string;
message: string;
additional_info: string;
timestamp: number;
timestamp_str: string;
};
const displayTypeMap = {
request_prayer: 'PRAYER',
request_centcom: 'CENTCOM',
request_syndicate: 'SYNDICATE',
request_nuke: 'NUKE CODE',
request_fax: 'FAX',
request_internet_sound: 'INTERNET SOUND',
};
export const RequestManager = (props) => {
const { act, data } = useBackend();
const { requests } = data;
const [filteredTypes, _] = useLocalState(
'filteredTypes',
const { act, data } = useBackend<Data>();
const { requests = [] } = data;
const [filteredTypes, setFilteredTypes] = useState(
Object.fromEntries(
Object.entries(displayTypeMap).map(([type, _]) => [type, true]),
),
);
const [searchText, setSearchText] = useState('');
const updateFilter = (type) => {
const newFilter = { ...filteredTypes };
newFilter[type] = !newFilter[type];
setFilteredTypes(newFilter);
};
// Handle filtering
let displayedRequests = requests.filter(
(request) => filteredTypes[request.req_type],
);
if (searchText) {
const filterText = searchText.toLowerCase();
displayedRequests = displayedRequests.filter(
(request) =>
decodeHtmlEntities(request.message)
.toLowerCase()
.includes(filterText) ||
request.owner_name.toLowerCase().includes(filterText),
);
const search = createSearch(
searchText,
(requests: Request) =>
requests.owner_name + decodeHtmlEntities(requests.message),
);
if (searchText.length > 0) {
displayedRequests = displayedRequests.filter((request) => search(request));
}
return (
@@ -42,15 +70,22 @@ export const RequestManager = (props) => {
<Section
title="Requests"
buttons={
<>
<Input
value={searchText}
onChange={(_, value) => setSearchText(value)}
placeholder={'Search...'}
mr={1}
/>
<FilterPanel />
</>
<Stack>
<Stack.Item>
<Input
value={searchText}
onInput={(_, value) => setSearchText(value)}
placeholder={'Search...'}
mr={1}
/>
</Stack.Item>
<Stack.Item>
<FilterPanel
typesList={filteredTypes}
updateFilter={updateFilter}
/>
</Stack.Item>
</Stack>
}
>
{displayedRequests.map((request) => (
@@ -79,15 +114,6 @@ export const RequestManager = (props) => {
);
};
const displayTypeMap = {
request_prayer: 'PRAYER',
request_centcom: 'CENTCOM',
request_syndicate: 'SYNDICATE',
request_nuke: 'NUKE CODE',
request_fax: 'FAX',
request_internet_sound: 'INTERNET SOUND',
};
const RequestType = (props) => {
const { requestType } = props;
@@ -99,7 +125,7 @@ const RequestType = (props) => {
};
const RequestControls = (props) => {
const { act, _ } = useBackend();
const { act } = useBackend<Data>();
const { request } = props;
return (
@@ -131,52 +157,47 @@ const RequestControls = (props) => {
const FilterPanel = (props) => {
const [filterVisible, setFilterVisible] = useState(false);
const [filteredTypes, setFilteredTypes] = useLocalState(
'filteredTypes',
Object.fromEntries(
Object.entries(displayTypeMap).map(([type, _]) => [type, true]),
),
);
const { typesList, updateFilter } = props;
return (
<Popper
placement="bottom-end"
content={
<div
className="RequestManager__filterPanel"
style={{
display: filterVisible ? 'block' : 'none',
}}
>
<Table width="0">
{Object.keys(displayTypeMap).map((type) => {
return (
<Table.Row className="candystripe" key={type}>
<Table.Cell collapsing>
<RequestType requestType={type} />
</Table.Cell>
<Table.Cell collapsing>
<Button.Checkbox
checked={filteredTypes[type]}
onClick={() => {
filteredTypes[type] = !filteredTypes[type];
setFilteredTypes(filteredTypes);
}}
my={0.25}
/>
</Table.Cell>
</Table.Row>
);
})}
</Table>
</div>
}
>
<div>
<Button icon="cog" onClick={() => setFilterVisible(!filterVisible)}>
Type Filter
</Button>
</div>
</Popper>
<div>
{' '}
<Button icon="cog" onClick={() => setFilterVisible(!filterVisible)}>
Type Filter
</Button>
<Popper
isOpen={filterVisible}
placement="bottom-end"
content={
<div
className="RequestManager__filterPanel"
style={{
display: 'block',
}}
>
<Table width="0">
{Object.keys(displayTypeMap).map((type) => {
return (
<Table.Row className="candystripe" key={type}>
<Table.Cell collapsing>
<RequestType requestType={type} />
</Table.Cell>
<Table.Cell collapsing>
<Button.Checkbox
checked={typesList[type]}
onClick={() => {
updateFilter(type);
}}
my={0.25}
/>
</Table.Cell>
</Table.Row>
);
})}
</Table>
</div>
}
/>
</div>
);
};