MyDataPage.tsx 7.18 KB
Newer Older
1
2
import * as React from 'react';
import {connect} from 'react-redux';
3
import {bindActionCreators} from 'redux';
4
5
import * as update from 'immutability-helper';

Matija Obreza's avatar
Matija Obreza committed
6
import { Dataset } from 'model/dataset.model';
Matija Obreza's avatar
Matija Obreza committed
7
import {Descriptor, DescriptorList} from 'model/descriptor.model';
8
import {Page} from 'model/common.model';
Maxym Borodenko's avatar
Maxym Borodenko committed
9
import { parse } from 'query-string';
10

Matija Obreza's avatar
Matija Obreza committed
11
import { filterCodeToUrl } from 'actions/filterCode';
12
13
import {listMyDatasets} from 'actions/dataset';
import {listMyDescriptors} from 'actions/descriptors';
14
import {listMyDescriptorLists} from 'actions/descriptorList';
Maxym Borodenko's avatar
Maxym Borodenko committed
15
import {setPageTitle} from 'actions/pageTitle';
16
17

import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
Maxym Borodenko's avatar
Maxym Borodenko committed
18
import BackButton from 'ui/common/buttons/BackButton';
19
20
21
22
23
24
25
26
import MyDataTable from './c/MyDataTable';

interface IDataPublishedContainerProps extends React.ClassAttributes<any> {
  title: string;
  tab?: string;
  pageCurrent: number;
  pageSize: number;
  pageSort?: string;
Matija Obreza's avatar
Matija Obreza committed
27
  pageDir?: string;
Matija Obreza's avatar
Matija Obreza committed
28
29
  filterCode?: string;
  filter: any;
30
31
32
  datasets: Page<Dataset>;
  descriptors: Page<Descriptor>;
  descriptorLists: Page<DescriptorList>;
33
  preFilter?: object;
Matija Obreza's avatar
Matija Obreza committed
34
  basePath: string;
Matija Obreza's avatar
Matija Obreza committed
35
  filterCodeToUrl: any;
Matija Obreza's avatar
Matija Obreza committed
36
37
38
  listDescriptorLists: any;
  listDescriptors: any;
  listDatasets: any;
Maxym Borodenko's avatar
Maxym Borodenko committed
39
  setPageTitle: (title: string) => void;
40
41
}

Matija Obreza's avatar
Matija Obreza committed
42
class BaseMyDataPage<T> extends React.Component<T & IDataPublishedContainerProps & any, any> {
43
44
45

  // SSR only
  protected static needs = [
Maxym Borodenko's avatar
Maxym Borodenko committed
46
47
48
49
50
    ({ params: { tab }, search }) => {
      const pageCurrent = parse(search).p;
      const pageSize = parse(search).l;
      const pageSort = parse(search).s;
      const pageDir = parse(search).d;
Matija Obreza's avatar
Matija Obreza committed
51
      const filterCode = parse(search).filter;
52
      switch (tab) {
Matija Obreza's avatar
Matija Obreza committed
53
54
        case 'descriptors': return listMyDescriptors(pageCurrent, pageSize, pageSort, filterCode || {}, pageDir);
        case 'descriptorlists': return listMyDescriptorLists(pageCurrent, pageSize, pageSort, filterCode || {}, pageDir);
55
        case 'datasets':
Matija Obreza's avatar
Matija Obreza committed
56
        default: return listMyDatasets(pageCurrent, pageSize, pageSort, filterCode || {}, pageDir);
57
58
59
60
      }
    },
  ];

61
62
  constructor(props) {
    super(props);
Matija Obreza's avatar
Matija Obreza committed
63
    this.state = {tab: '', filterCode: props.filterCode};
64
65
66
67
68
69
70
  }

  public componentDidMount() {
    // noop
  }

  public componentWillMount() {
71
    const {tab, pageCurrent, pageSize, pageSort, pageDir} = this.props;
Matija Obreza's avatar
Matija Obreza committed
72
    // console.log(`willM ${filterCode}`, filters[filterCode]);
73

Matija Obreza's avatar
Matija Obreza committed
74
    this.loadData(null, tab, pageCurrent, pageSize, pageSort, pageDir);
75
76
77
78
79
80
81
  }

  public componentWillUnmount() {
    // noop
  }

  public componentWillReceiveProps(nextProps) {
Matija Obreza's avatar
Matija Obreza committed
82
83
    const {filterCodeToUrl} = this.props;
    const paged = this.getPaged(nextProps);
84

Matija Obreza's avatar
Matija Obreza committed
85
86
87
88
89
90
91
92
93
    if (paged) {
      filterCodeToUrl(paged.filterCode);
    }

    const {tab} = nextProps;
    if (tab !== this.state.tab) {
      const {pageCurrent, pageSize, pageSort, pageDir} = nextProps;
      this.loadData(null, tab, pageCurrent, pageSize, pageSort, pageDir);
    }
94
95
96
  }

  public componentWillUpdate(nextProps, nextState) {
Valeriy Panov's avatar
Valeriy Panov committed
97
    // noop
98
99
100
  }

  public componentDidUpdate() {
Valeriy Panov's avatar
Valeriy Panov committed
101
    // noop
102
103
  }

Matija Obreza's avatar
Matija Obreza committed
104
105
106
107
108
109
110
111
112
  protected getPaged(props) {
    switch (props.tab) {
      case 'descriptorlists': return props.descriptorLists;
      case 'descriptors': return props.descriptors;
      case 'datasets':
      default: return props.datasets;
    }
  }

113
  protected onPaginationChange = (page, results, sortBy, dir) => {
Maxym Borodenko's avatar
Maxym Borodenko committed
114
    const { history, location } = this.props;
Maxym Borodenko's avatar
Maxym Borodenko committed
115
116
117
118
119
120
121
122
    const params = new URLSearchParams(location.search);
    params.set('p', page);
    params.set('l', results);
    if (sortBy) {
      params.set('s', sortBy);
    } else {
      params.delete('s');
    }
Maxym Borodenko's avatar
Maxym Borodenko committed
123
    if (dir) {
Maxym Borodenko's avatar
Maxym Borodenko committed
124
125
126
      params.set('d', dir);
    } else {
      params.delete('d');
Maxym Borodenko's avatar
Maxym Borodenko committed
127
    }
128

Maxym Borodenko's avatar
Maxym Borodenko committed
129
130
    location.search = params.toString();
    history.push(location);
Matija Obreza's avatar
Matija Obreza committed
131
132
    const { tab } = this.props;
    this.loadData(null, tab, page, results, sortBy, dir);
133
134
  }

Matija Obreza's avatar
Matija Obreza committed
135
136
  protected onFilter = (newFilters) => {
    this.setState({...this.state, filter: newFilters});
137

Matija Obreza's avatar
Matija Obreza committed
138
139
140
    const {tab, pageCurrent, pageSize, pageSort, pageDir} = this.props;
    this.loadData(newFilters, tab, pageCurrent, pageSize, pageSort, pageDir);
  }
141

Matija Obreza's avatar
Matija Obreza committed
142
143
144
145
  protected loadData(filter, tab, page, size, sortBy, dir) {
    const {listDatasets, listDescriptors, listDescriptorLists, preFilter, filterCode} = this.props;
    const newFilters = filter && { ...preFilter, ...filter };
    // console.log(`Filters code=${filterCode}`, newFilters, preFilter);
146

Matija Obreza's avatar
Matija Obreza committed
147
148
    if (newFilters || this.state.tab !== tab || this.state.pageCurrent !== page || this.state.pageSize !== size || this.state.pageSort !== sortBy || this.state.pageDir !== dir) {
      // console.log('Reloading');
149
150
151
152
153
      this.setState(update(this.state, {
        tab: {$set: tab},
        pageCurrent: {$set: page},
        pageSize: {$set: size},
        pageSort: {$set: sortBy},
154
        pageDir: {$set: dir},
Matija Obreza's avatar
Matija Obreza committed
155
        filterCode: {$set: filterCode},
156
157
158
      }));

      switch (tab) {
Matija Obreza's avatar
Matija Obreza committed
159
160
        case 'descriptors': listDescriptors(page, size, sortBy, newFilters || filterCode, dir); break;
        case 'descriptorlists': listDescriptorLists(page, size, sortBy, newFilters || filterCode, dir); break;
161
        case 'datasets':
Matija Obreza's avatar
Matija Obreza committed
162
        default: listDatasets(page, size, sortBy, newFilters || filterCode, dir); break;
163
164
      }
    } else {
Valeriy Panov's avatar
Valeriy Panov committed
165
      // noop
166
167
168
169
    }
  }
}

Matija Obreza's avatar
Matija Obreza committed
170
class DP extends BaseMyDataPage<any> {
171
172
173

  constructor(props) {
    super(props);
Maxym Borodenko's avatar
Maxym Borodenko committed
174
175
    const { title, setPageTitle } = this.props;
    setPageTitle(title);
176
177
178
  }

  public render() {
Matija Obreza's avatar
Matija Obreza committed
179
    const {title, tab, basePath, filterCode, filter} = this.props;
180

Matija Obreza's avatar
Matija Obreza committed
181
    const paged = this.getPaged(this.props);
182
183
184

    return (
      <div>
Maxym Borodenko's avatar
Maxym Borodenko committed
185
        <ContentHeaderWithButton title={ title } buttons={ <BackButton defaultTarget="/dashboard" defaultBackText="BACK TO DASHBOARD" preferDefaultTarget="true" /> }/>
Matija Obreza's avatar
Matija Obreza committed
186
        <MyDataTable tab={ tab } basePath={ basePath } filterCode={ filterCode } filter={ filter } onFilter={ this.onFilter }
187
          paged={ paged } onPaginationChange={ this.onPaginationChange } />
188
189
190
191
192
193
      </div>
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
Maxym Borodenko's avatar
Maxym Borodenko committed
194
195
196
  title: ownProps.route.extraProps.title || 'Data', // route-configured
  basePath: ownProps.route.extraProps.basePath, // route-configured
  preFilter: ownProps.route.extraProps.filter || {}, // route-configured
Maxym Borodenko's avatar
Maxym Borodenko committed
197
198
199
200
201
  tab: ownProps.match.params.tab || 'datasets', // current tab, or ownProps.location.pathname
  pageCurrent: +parse(ownProps.location.search).p || 0, // current page
  pageSize: +parse(ownProps.location.search).l || 20, // page size
  pageSort: parse(ownProps.location.search).s, // page sort
  pageDir: parse(ownProps.location.search).d, // page sort direction
Matija Obreza's avatar
Matija Obreza committed
202
203
  filterCode: parse(ownProps.location.search).filter, // filter code
  filter: state.filterCode.filters && parse(ownProps.location.search).filter && state.filterCode.filters[parse(ownProps.location.search).filter] || null,
Matija Obreza's avatar
Matija Obreza committed
204
  datasets: state.datasets.paged,
205
  descriptors: state.descriptors.paged,
206
  descriptorLists: state.descriptorList.paged,
207
208
});

209
210
211
212
const mapDispatchToProps = (dispatch) => bindActionCreators({
  listDatasets: listMyDatasets,
  listDescriptors: listMyDescriptors,
  listDescriptorLists: listMyDescriptorLists,
Maxym Borodenko's avatar
Maxym Borodenko committed
213
  setPageTitle,
Matija Obreza's avatar
Matija Obreza committed
214
  filterCodeToUrl,
215
}, dispatch);
216
217
218
219
220
221

const MyDataPage = connect(
  mapStateToProps, mapDispatchToProps,
)(DP);

export {MyDataPage as default, BaseMyDataPage};