Skip to content

Commit d2ebd18

Browse files
authored
Merge pull request #573 from performant-software/feature/archnet1718-table-view
Add table view as option for Items list (archnet #1718)
2 parents d086699 + 90d8e1e commit d2ebd18

5 files changed

Lines changed: 86 additions & 10 deletions

File tree

packages/semantic-ui/src/components/DataTable.css

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
.data-table .ui.table .actions-cell {
2-
white-space: nowrap;
3-
width: 1px;
4-
}
5-
61
.data-table .empty-button {
72
display: inline;
83
margin-left: 5px;
@@ -38,6 +33,8 @@
3833
position: relative;
3934
}
4035

36+
.ui.table.data-table td.actions-cell,
4137
.data-table.ui.celled.table tr td.actions-cell {
4238
white-space: nowrap;
39+
width: 1px;
4340
}

packages/semantic-ui/src/components/DataTable.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,10 @@ DataTable.defaultProps = {
640640

641641
export default useColumnSelector(useList(DataTable));
642642

643+
export {
644+
DataTable as DataTableComponent
645+
};
646+
643647
export type {
644648
Props
645649
};

packages/semantic-ui/src/components/DataTableColumnSelector.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React, { Component, type ComponentType, type Element } from 'react';
55
import { Checkbox, Dropdown, Icon } from 'semantic-ui-react';
66
import _ from 'underscore';
77
import Draggable from './Draggable';
8+
import { Views } from './ItemsToggle';
89
import ListSessionUtils from '../utils/ListSession';
910
import type { Props as ListProps } from './List';
1011
import './DataTableColumnSelector.css';
@@ -49,7 +50,13 @@ type Props = ListProps & {
4950
/**
5051
* If <code>true</code>, columns can be shown/hidden by the user.
5152
*/
52-
configurable?: boolean
53+
configurable?: boolean,
54+
55+
/**
56+
* Used in multi-view environments to hide the column selector if a view is selected, and it is not the
57+
* table view.
58+
*/
59+
view?: number,
5360
};
5461

5562
type State = {
@@ -204,10 +211,12 @@ const useColumnSelector = (WrappedComponent: ComponentType<any>) => (
204211
return null;
205212
}
206213

214+
const isTableView = this.props.view === undefined || this.props.view === Views.table;
215+
207216
return (
208217
<>
209218
{ this.props.renderListHeader && this.props.renderListHeader() }
210-
{ this.props.configurable && (
219+
{ this.props.configurable && isTableView && (
211220
<Dropdown
212221
aria-label='Select Columns'
213222
basic

packages/semantic-ui/src/components/Items.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import i18n from '../i18n/i18n';
1616
import useList from './List';
1717
import useItemsToggle, { Views } from './ItemsToggle';
1818
import Draggable from './Draggable';
19+
import useColumnSelector from './DataTableColumnSelector';
20+
import { DataTableComponent } from './DataTable';
1921
import './Items.css';
2022

2123
import type { Props as ListProps } from './List';
@@ -214,6 +216,7 @@ class ItemsClass extends Component<Props, {}> {
214216
>
215217
{ this.renderList() }
216218
{ this.renderGrid() }
219+
{ this.renderTable() }
217220
{ this.renderEmptyList() }
218221
{ this.props.children }
219222
</div>
@@ -503,13 +506,31 @@ class ItemsClass extends Component<Props, {}> {
503506
</Item.Group>
504507
);
505508
}
509+
510+
/**
511+
* Renders the table view.
512+
*
513+
* @returns {null|*}
514+
*/
515+
renderTable() {
516+
if (this.props.view !== Views.table || !(this.props.items && this.props.items.length)) {
517+
return null;
518+
}
519+
520+
return (
521+
<DataTableComponent
522+
{...this.props}
523+
loading={false} /* prevent duplicate loading spinners */
524+
/>
525+
);
526+
}
506527
}
507528

508529
ItemsClass.defaultProps = {
509530
actions: []
510531
};
511532

512-
const Items = useItemsToggle(useList(ItemsClass));
533+
const Items = useItemsToggle(useColumnSelector(useList(ItemsClass)));
513534
export default Items;
514535

515536
export type {

packages/semantic-ui/src/components/ItemsToggle.js

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, { Component, type ComponentType } from 'react';
44
import { Button, Dropdown } from 'semantic-ui-react';
55
import _ from 'underscore';
66
import { SORT_ASCENDING } from './DataList';
7+
import ListSessionUtils from '../utils/ListSession';
78

89
type Sort = {
910
key: string,
@@ -14,10 +15,15 @@ type Sort = {
1415

1516
type Props = {
1617
basic?: boolean,
18+
columns?: Array<any>,
1719
defaultView?: number,
1820
hideToggle?: boolean,
1921
onSort?: (sortColumn: string, sortDirection?: ?string) => void,
2022
renderListHeader?: () => JSX.Element,
23+
session?: {
24+
key: string,
25+
storage: typeof sessionStorage
26+
},
2127
sort?: Array<Sort>,
2228
sortColor?: string,
2329
sortColumn?: string,
@@ -30,7 +36,8 @@ type State = {
3036

3137
const Views = {
3238
list: 0,
33-
grid: 1
39+
grid: 1,
40+
table: 2
3441
};
3542

3643
/**
@@ -60,8 +67,12 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
6067
constructor(props: any) {
6168
super(props);
6269

70+
// set view based on session storage if present
71+
const { key, storage } = props.session || {};
72+
const session = ListSessionUtils.restoreSession(key, storage) || {};
73+
6374
this.state = {
64-
view: props.defaultView || Views.list
75+
view: session.view || props.defaultView || Views.list
6576
};
6677
}
6778

@@ -105,6 +116,31 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
105116
this.props.onSort(sort.value, sortDirection);
106117
}
107118

119+
/**
120+
* Updates the session whenever the view state changes.
121+
*
122+
* @param prevProps
123+
* @param prevState
124+
*/
125+
componentDidUpdate(prevProps: Props, prevState: State) {
126+
if (prevState.view !== this.state.view) {
127+
this.setSession();
128+
}
129+
}
130+
131+
/**
132+
* Sets the view property on the session.
133+
*/
134+
setSession() {
135+
const { key, storage } = this.props.session || {};
136+
137+
if (!key) {
138+
return;
139+
}
140+
141+
ListSessionUtils.setSession(key, storage, { view: this.state.view });
142+
}
143+
108144
/**
109145
* Renders the ItemsToggle component.
110146
*
@@ -153,6 +189,15 @@ const useItemsToggle = (WrappedComponent: ComponentType<any>) => (
153189
icon='grid layout'
154190
onClick={() => this.setState({ view: Views.grid })}
155191
/>
192+
{ !_.isEmpty(this.props.columns) && (
193+
<Button
194+
active={this.state.view === Views.table}
195+
aria-label='Table View'
196+
basic={this.props.basic}
197+
icon='table'
198+
onClick={() => this.setState({ view: Views.table })}
199+
/>
200+
)}
156201
</>
157202
)}
158203
{ !_.isEmpty(this.props.sort) && this.props.onSort && (

0 commit comments

Comments
 (0)