From e623109668d90a78d95c9f23ab0f3f60a9143da9 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Wed, 13 Dec 2023 21:21:25 -0500 Subject: [PATCH] actually revert this until its NOT broken (#23557) --- tgui/docs/component-reference.md | 116 -------- tgui/packages/tgui/components/Table.js | 157 +---------- .../tgui/interfaces/AccountsUplinkTerminal.js | 221 +++++++++------ .../tgui/interfaces/MedicalRecords.js | 255 +++++++++++++----- .../tgui/interfaces/SecurityRecords.js | 186 +++++++++---- .../tgui/interfaces/common/RecordsTable.js | 55 ---- tgui/packages/tgui/public/tgui.bundle.css | 2 +- tgui/packages/tgui/public/tgui.bundle.js | 6 +- .../interfaces/AccountsUplinkTerminal.scss | 18 ++ .../styles/interfaces/MedicalRecords.scss | 18 ++ .../styles/interfaces/SecurityRecords.scss | 18 ++ .../interfaces/common/RecordsTable.scss | 29 -- tgui/packages/tgui/styles/main.scss | 1 - 13 files changed, 523 insertions(+), 559 deletions(-) delete mode 100644 tgui/packages/tgui/interfaces/common/RecordsTable.js delete mode 100644 tgui/packages/tgui/styles/interfaces/common/RecordsTable.scss diff --git a/tgui/docs/component-reference.md b/tgui/docs/component-reference.md index 4070b5d46c36..c892cb628be9 100644 --- a/tgui/docs/component-reference.md +++ b/tgui/docs/component-reference.md @@ -44,15 +44,12 @@ Make sure to add new items to this list if you document new components. - [`Table`](#table) - [`Table.Row`](#tablerow) - [`Table.Cell`](#tablecell) - - [`Table.Sortable`](#tablesortable) - [`Tabs`](#tabs) - [`Tabs.Tab`](#tabstab) - [`Tooltip`](#tooltip) - [`tgui/layouts`](#tguilayouts) - [`Window`](#window) - [`Window.Content`](#windowcontent) -- [`tgui/interfaces/common`](#tguiinterfacescommon) - - [`RecordsTable`](#recordstable) ## General Concepts @@ -847,103 +844,6 @@ A straight forward mapping to `` element. - `collapsing: boolean` - Collapses table cell to the smallest possible size, and stops any text inside from wrapping. -### `Table.Sortable` - -A managed sortable table. - -**Props:** - -- See inherited props: [Table](#table) -- `columns: Column[]` - A list of data fields to be - used. The order in which columns are specified is the order in which they - appear in the UI. -- `columnDefaults: UnnamedColumn` - Default values for all columns. - `columnDefaults.datum.children` can be used to specify the default children, - but will get overriden by children defined at each column. - `columnDefaults.datum.props` and `columnDefaults.header.props` can be used to - specify additional props for the datum and header respectively. -- `data: object[]` - The data to put into the table. -- `datumID: object => object` - A function which takes in a datum and returns - an id. -- `filter: object[] => object[]` - A function applied to the data before - sorting the table. The `createSearch` function can be applied here. -- `headerRowProps: object` - Props to apply to the header row. -- `datumRowProps: object | object => object` - Props to apply to the data - rows. If a function is specified instead, the data associated with that row - is passed into it. -- `...rest` - The rest of the props are applied on the table. -- `children: Component[]` - Not supported. Do not use. - -The column types is defined as such: - -```ts -interface UnnamedColumn { - // ? signifies optional - datum?: { - // Pass the children directly or pass a function which takes the value of - // the cell and returns the props. Setting this property overrides the - // default children. - children?: React.ReactNode | ((value: object) => React.ReactNode); - // Pass the additional props directly or pass a function which takes the - // value of the cell and returns the additional props. - props?: CellProps | ((value: object) => CellProps); - }; - header?: { - // Additional props for the header cell. - props?: HeaderProps; - }; -} - -// Inherits properties from UnnamedColumn -type Column = UnnamedColumn & { - id: string; - name: string; -}; -``` - -The following is an example of how to use `Table.Sortable`. - -```jsx -const data = [ - { 'account_number': 6224001, 'name': 'Command Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 3099002, 'name': 'Security Account', 'suspended': 'Active', 'money': 14000, }, - { 'account_number': 8652003, 'name': 'Science Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 8422004, 'name': 'Service Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 9853005, 'name': 'Supply Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 1866006, 'name': 'Engineering Account', 'suspended': 'Active', 'money': 7250, }, - { 'account_number': 3811007, 'name': 'Medical Account', 'suspended': 'Active', 'money': 7000, }, - { 'account_number': 3945008, 'name': 'Assistant Account', 'suspended': 'Active', 'money': 4500, }, -] - - datum.account_number} - - datumRowProps={(datum) => ({ - className: `AccountsUplinkTerminal__listRow--${datum.suspended}`, - })} - datumCellChildren={{ - name: (value) => <> {value}, - }} -/> -``` - -In the above example, the `columns` prop defines the fields in the data that -are used. `columns.id` is the key or the name of the property on the data, -while `columns.name` is what the user sees on the UI. `datumID` selects which -field in the data to use as the key for render caching. `datumID` can return -anything, but it must be unique. - -`datumRowProps` applies a class to a row if the account associated with that -row is suspended, and `datumCellChildren` prepends a wallet to the contents -of the `name` column. - ### `Tabs` Tabs make it easy to explore and switch between different views. @@ -1068,19 +968,3 @@ Can be scrollable. - `className: string` - Applies a CSS class to the element. - `scrollable: boolean` - Shows or hides the scrollbar. - `children: any` - Main content of your window. - -## `tgui/interfaces/common` - -## `RecordsTable` - -An extension to [`Table.Sortable`](#tablesortable) which provides a search -function and slots for buttons. - -**Props:** - -- See inherited props: [`Table.Sortable`](#tablesortable) -- `leftButtons: Component` - Optional buttons to add left of the search box. -- `rightButtons: Component` - Optional buttons to add right of the search box. -- `searchPlaceholder: string` - The default text in the search box. - -Use a ``(or `<>`) to specify multiple buttons. diff --git a/tgui/packages/tgui/components/Table.js b/tgui/packages/tgui/components/Table.js index 14228caa20f5..681a795ed42c 100644 --- a/tgui/packages/tgui/components/Table.js +++ b/tgui/packages/tgui/components/Table.js @@ -1,8 +1,5 @@ import { classes, pureComponentHooks } from 'common/react'; -import { computeBoxClassName, computeBoxProps } from './Box'; -import { Component } from 'inferno'; -import { Button } from './Button'; -import { Icon } from './Icon'; +import { Box, computeBoxClassName, computeBoxProps } from './Box'; export const Table = (props) => { const { className, collapsing, children, ...rest } = props; @@ -56,159 +53,7 @@ export const TableCell = (props) => { ); }; -const resolveFunctionalProp = (props, ...data) => - props ? (props instanceof Function ? props(...data) : props) : undefined; -class HoverableIcon extends Component { - constructor() { - super(); - this.state = { - hovering: false, - }; - this.handleMouseOver = (e) => { - this.setState({ hovering: true }); - }; - this.handleMouseOut = (e) => { - this.setState({ hovering: false }); - }; - } - - render() { - const { hoverIcon, name, ...rest } = this.props; - const { hovering } = this.state; - return ( - - ); - } -} - -class SortableTable extends Component { - constructor(props) { - super(); - this.state = { - // Allow null - sortId: props.sortId === undefined ? props.columns[0].id : props.sortId, - sortOrder: props.sortOrder ?? 1, - }; - } - - render() { - const { - className, - columnDefaults, - columns, - data, - datumID, - filter, - headerRowProps, - datumRowProps, - ...rest - } = this.props; - const { sortId, sortOrder } = this.state; - - const columnHeaders = columns.map( - ({ id, name, header: { props } = {} }) => { - const { - header: { props: defaultProps }, - } = columnDefaults; - return ( - - - - ); - } - ); - const dataRows = (filter ? filter(data) : data) - .sort((a, b) => { - if (sortId) { - const i = sortOrder ? 1 : -1; - return a[sortId].toString().localeCompare(b[sortId].toString()) * i; - } else { - return 0; - } - }) - .map((datum) => { - let cells = columns.map( - ({ id, name, datum: { props, children } = {} }) => { - const { - datum: { children: defaultChildren, props: defaultProps }, - } = columnDefaults; - return ( - - {resolveFunctionalProp(children, datum[id]) ?? - resolveFunctionalProp(defaultChildren, datum[id]) ?? - datum[id]} - - ); - } - ); - return ( - - {cells} - - ); - }); - return ( - - - {columnHeaders} - - {dataRows} -
- ); - } -} - TableCell.defaultHooks = pureComponentHooks; Table.Row = TableRow; Table.Cell = TableCell; -Table.Sortable = SortableTable; diff --git a/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js b/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js index b509baced50f..ecd2d7a397c9 100644 --- a/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js +++ b/tgui/packages/tgui/interfaces/AccountsUplinkTerminal.js @@ -1,7 +1,9 @@ +import { createSearch } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend, useLocalState } from '../backend'; import { Button, + Flex, Icon, Input, LabeledList, @@ -9,10 +11,11 @@ import { Table, Tabs, } from '../components'; +import { FlexItem } from '../components/Flex'; +import { TableCell } from '../components/Table'; import { Window } from '../layouts'; import { LoginInfo } from './common/LoginInfo'; import { LoginScreen } from './common/LoginScreen'; -import { RecordsTable } from './common/RecordsTable'; export const AccountsUplinkTerminal = (properties, context) => { const { act, data } = useBackend(context); @@ -39,7 +42,7 @@ export const AccountsUplinkTerminal = (properties, context) => { return ( - + {body} @@ -78,95 +81,159 @@ const AccountsUplinkTerminalContent = (props, context) => { } }; -const AccountsRecordList = (props, context) => { +const AccountsRecordList = (properties, context) => { const { act, data } = useBackend(context); const { accounts } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const [sortId, _setSortId] = useLocalState(context, 'sortId', 'owner_name'); + const [sortOrder, _setSortOrder] = useLocalState(context, 'sortOrder', true); return ( - ( - <> - {value} - - ), - }, - }, - { - id: 'account_number', - name: 'Account Number', - datum: { children: (value) => <>#{value} }, - }, - { id: 'suspended', name: 'Account Status' }, - { id: 'money', name: 'Account Balance' }, - ]} - data={accounts} - datumID={(datum) => datum.account_number} - leftButtons={ - + + ); +}; + +const AccountsActions = (properties, context) => { + const { act, data } = useBackend(context); + const { is_printing } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + return ( + + + + ); +}; + +const SortButton2 = (properties, context) => { + const [sortId2, setSortId2] = useLocalState(context, 'sortId2', 'name'); + const [sortOrder2, setSortOrder2] = useLocalState( + context, + 'sortOrder2', + true + ); + const { id, children } = properties; + return ( + + + + ); +}; + const MedicalRecordsNavigation = (_properties, context) => { const { act, data } = useBackend(context); const { screen, general } = data; diff --git a/tgui/packages/tgui/interfaces/SecurityRecords.js b/tgui/packages/tgui/interfaces/SecurityRecords.js index e49a3ff98706..b908f6d7ff36 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords.js +++ b/tgui/packages/tgui/interfaces/SecurityRecords.js @@ -1,13 +1,23 @@ -import { decodeHtmlEntities } from 'common/string'; +import { createSearch, decodeHtmlEntities } from 'common/string'; import { Fragment } from 'inferno'; -import { useBackend } from '../backend'; -import { Box, Button, Icon, LabeledList, Section, Tabs } from '../components'; +import { useBackend, useLocalState } from '../backend'; +import { + Box, + Button, + Flex, + Icon, + Input, + LabeledList, + Section, + Table, + Tabs, +} from '../components'; +import { FlexItem } from '../components/Flex'; import { Window } from '../layouts'; import { ComplexModal, modalOpen } from './common/ComplexModal'; import { LoginInfo } from './common/LoginInfo'; import { LoginScreen } from './common/LoginScreen'; import { TemporaryNotice } from './common/TemporaryNotice'; -import { RecordsTable } from './common/RecordsTable'; const statusStyles = { '*Execute*': 'execute', @@ -85,56 +95,128 @@ const SecurityRecordsNavigation = (properties, context) => { ); }; -const SecurityRecordsPageList = (props, context) => { +const SecurityRecordsPageList = (properties, context) => { const { act, data } = useBackend(context); - const { isPrinting, records } = data; + const { records } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const [sortId, _setSortId] = useLocalState(context, 'sortId', 'name'); + const [sortOrder, _setSortOrder] = useLocalState(context, 'sortOrder', true); return ( - ( - <> - {value} - - ), - }, - }, - { id: 'id', name: 'ID' }, - { id: 'rank', name: 'Assignment' }, - { id: 'fingerprint', name: 'Fingerprint' }, - { id: 'status', name: 'Criminal Status' }, - ]} - data={records} - datumID={(datum) => datum.id} - leftButtons={ - <> - + + ); +}; + +const SecurityRecordsActions = (properties, context) => { + const { act, data } = useBackend(context); + const { isPrinting } = data; + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + return ( + + +