DashboardPage.tsx 5.34 KB
Newer Older
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
1
import * as React from 'react';
2 3
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
Maxym Borodenko's avatar
Maxym Borodenko committed
4 5
import { translate } from 'react-i18next';
import { parse } from 'query-string';
6

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
7
// Actions
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
8
import {loadMoreSubsets, applyFilters, createNewVersion} from 'subsets/actions/dashboard';
9

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
10 11
// Models
import FilteredPage from 'model/FilteredPage';
12
import Subset from 'model/subset/Subset';
Maxym Borodenko's avatar
Maxym Borodenko committed
13
import SubsetFilter from 'model/subset/SubsetFilter';
Matija Obreza's avatar
Matija Obreza committed
14
import {SortDirection, IPageRequest} from 'model/Page';
15
import ApiCall from 'model/ApiCall';
16

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
17
// UI
Maxym Borodenko's avatar
Maxym Borodenko committed
18
import SubsetFilters from './c/SubsetFilters';
Oleksii Savran's avatar
Oleksii Savran committed
19
import CreateNewButton from 'ui/common/buttons/CreateNewButton';
Maxym Borodenko's avatar
Maxym Borodenko committed
20
import ContentLayout from 'ui/layout/ContentLayout';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
21
import PageTitle from 'ui/common/PageTitle';
Oleksii Savran's avatar
Oleksii Savran committed
22 23 24 25 26
import { PageContents } from 'ui/layout/PageLayout';
import Loading from 'ui/common/Loading';
import PagedLoader from 'ui/common/PagedLoader';
import SubsetCard from 'subsets/ui/c/SubsetCard';
import PaginationComponent from 'ui/common/pagination';
Oleksii Savran's avatar
Oleksii Savran committed
27
import PrettyFilters from 'ui/common/filter/PrettyFilters';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
28 29

interface IDashboardPageProps extends React.ClassAttributes<any> {
30
  apiCall: ApiCall<FilteredPage<Subset>>;
31
  loadMoreSubsets: (page?: FilteredPage<Subset>) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
32
  createNewVersion: (uuid: string) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
33
  login: any;
Maxym Borodenko's avatar
Maxym Borodenko committed
34 35
  t: any;
  filterCode: string;
Matija Obreza's avatar
Matija Obreza committed
36
  applyFilters: (filters: string | SubsetFilter, page?: IPageRequest) => any;
Oleksii Savran's avatar
Oleksii Savran committed
37
  dataClassName: string;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
38 39 40 41 42 43 44 45 46 47 48
}

const sortOptions = {
  lastModifiedDate: {label: 'Latest edit', dir: 'DESC'},
  title: 'Title',
  wiewsCode: 'Publisher',
};

class DashboardPage extends React.Component<IDashboardPageProps> {

  protected static needs = [
Maxym Borodenko's avatar
Maxym Borodenko committed
49 50 51 52
    ({ search, params: { filterCode } }) => {
      const qs = parse(search || '');
      return applyFilters(filterCode || '', FilteredPage.fromQueryString(qs));
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
53 54 55 56 57 58 59
  ];

  constructor(props: IDashboardPageProps, context: any) {
    super(props, context);
  }

  public componentWillMount() {
60 61
    const {apiCall, applyFilters, filterCode} = this.props;
    const {data: paged} = apiCall || {data: undefined};
Maxym Borodenko's avatar
Maxym Borodenko committed
62 63 64 65 66 67 68 69
    if (filterCode) {
      if (!paged || paged.filterCode !== filterCode) {
        applyFilters(filterCode);
      }
    } else {
      applyFilters('');
    }
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
70

Maxym Borodenko's avatar
Maxym Borodenko committed
71
  public componentWillReceiveProps(nextProps) {
72 73
    const { filterCode: prevFilterCode } = this.props;
    const { filterCode, applyFilters, apiCall } = nextProps;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
74

75 76
    if (filterCode !== prevFilterCode) {
      if (apiCall && apiCall.data && !apiCall.loading && apiCall.data.filterCode !== filterCode) {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
77 78
        applyFilters(filterCode || '');
      }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
79 80 81
    }
  }

Maxym Borodenko's avatar
Maxym Borodenko committed
82
  protected myApplyFilters = (filters: SubsetFilter) => {
83 84
    const { apiCall, applyFilters } = this.props;
    const {data: paged} = apiCall || {data: undefined};
Maxym Borodenko's avatar
Maxym Borodenko committed
85 86 87 88 89 90 91 92
    if (paged) {
      applyFilters(filters, { page: 0, direction: paged.sort[0].direction, properties: [ paged.sort[0].property ] });
    } else {
      applyFilters(filters);
    }
  }

  protected onSortChange = (sortBy: string, dir: SortDirection) => {
93 94
    const { apiCall, applyFilters, filterCode } = this.props;
    const {data: paged} = apiCall || {data: undefined};
95
    applyFilters(filterCode || paged.filterCode || '', FilteredPage.reSort(paged, sortBy, dir));
Maxym Borodenko's avatar
Maxym Borodenko committed
96 97
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
98 99 100 101 102
  protected handleCreateNewVersion = (uuid) => {
    const {createNewVersion} = this.props;
    createNewVersion(uuid);
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
103
  public render() {
104 105
    const {apiCall, login: { authorities: userRoles }, loadMoreSubsets, t} = this.props;
    const {data: paged} = apiCall || {data: undefined};
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
106
    const renderSubset = (s: Subset, index: number) => {
Oleksii Savran's avatar
Oleksii Savran committed
107 108 109 110 111 112
      return (
        <SubsetCard
          key={ s.uuid }
          subset={ s }
          index={ index }
          isAdmin={ userRoles.findIndex((role) => role === 'ROLE_ADMINISTRATOR') !== -1 }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
113
          handleCreateNewVersion={ this.handleCreateNewVersion }
Oleksii Savran's avatar
Oleksii Savran committed
114 115 116 117
          dataClassName={ this.props.dataClassName }
          compact
        />
      );
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
118 119
    };

Oleksii Savran's avatar
Oleksii Savran committed
120

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
121
    return (
Maxym Borodenko's avatar
Maxym Borodenko committed
122 123 124
      <ContentLayout left={
        <SubsetFilters initialValues={ paged && paged.filter || {} } onSubmit={ this.myApplyFilters } t={ t }/>
      } customHeaderHeight>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
125
        <PageTitle title={ t('subsets.dashboard.p.browse.title') }/>
Oleksii Savran's avatar
Oleksii Savran committed
126 127
        <PaginationComponent
          pageObj={ paged }
Maxym Borodenko's avatar
Maxym Borodenko committed
128
          onSortChange={ this.onSortChange }
Oleksii Savran's avatar
Oleksii Savran committed
129 130
          displayName={ t('subsets.common.modelName') }
          sortOptions={ sortOptions }
Maxym Borodenko's avatar
Maxym Borodenko committed
131
        />
Oleksii Savran's avatar
Oleksii Savran committed
132 133 134 135 136
        <PrettyFilters
          prefix="subsets"
          filterObj={ paged && paged.filter || {} }
          onSubmit={ this.myApplyFilters }
        />
Oleksii Savran's avatar
Oleksii Savran committed
137 138 139 140 141 142 143 144 145
        <PageContents className="pt-1rem container-spacing-horizontal">
          { ! paged ? <Loading /> :
            <PagedLoader
              paged={ paged }
              loadMore={ loadMoreSubsets }
              roughItemHeight={ 80 }
              itemRenderer={ renderSubset } />
          }
        </PageContents>
Oleksii Savran's avatar
Oleksii Savran committed
146 147 148 149
        <CreateNewButton
          title="subsets.common.modelName"
          path="/dashboard/subsets/edit"
        />
Maxym Borodenko's avatar
Maxym Borodenko committed
150
      </ContentLayout>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
151 152 153 154 155
    );
  }
}

const mapStateToProps = (state, ownProps) => ({
156
  apiCall: state.subsets.dashboard.paged,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
157
  login: state.login,
Maxym Borodenko's avatar
Maxym Borodenko committed
158
  filterCode: ownProps.match.params.filterCode,
Oleksii Savran's avatar
Oleksii Savran committed
159
  dataClassName: Subset.clazz,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
160 161 162
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
163
  loadMoreSubsets,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
164
  createNewVersion,
Maxym Borodenko's avatar
Maxym Borodenko committed
165
  applyFilters,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
166 167
}, dispatch);

Maxym Borodenko's avatar
Maxym Borodenko committed
168
export default connect(mapStateToProps, mapDispatchToProps)((translate()(DashboardPage)));