BrowsePage.tsx 5.93 KB
Newer Older
1
2
3
import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
Matija Obreza's avatar
Matija Obreza committed
4
import { withStyles } from '@material-ui/core/styles';
Maxym Borodenko's avatar
Maxym Borodenko committed
5
import { parse } from 'query-string';
6

Matija Obreza's avatar
Matija Obreza committed
7
8
import { listVocabularies, promiseListVocabularies, createVocabulary } from 'vocabulary/actions/public';
import { autoUpdateVocabularies } from 'vocabulary/actions/admin';
9
10
import { Page, Pagination } from 'model/common.model';

Matija Obreza's avatar
Matija Obreza committed
11
import PagedLoader from 'ui/common/PagedLoader';
12
import Authorize from 'ui/common/authorized/Authorize';
Valeriy Panov's avatar
Valeriy Panov committed
13
import Loading from 'ui/common/Loading';
14
import PaginationComponent from 'ui/common/pagination';
15
16
17
import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
import VocabularyCard from './c/VocabularyCard';

Matija Obreza's avatar
Matija Obreza committed
18
19
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
20
import PageLayout from 'ui/layout/PageLayout';
21
22
import Vocabulary from 'model/vocabulary/Vocabulary';
import VocabularyFilter from 'model/vocabulary/VocabularyFilter';
Valeriy Panov's avatar
Valeriy Panov committed
23

24
25
26
27
28
29
30
const styles = (theme) => ({
    root: {
        backgroundColor: '#E8E5E0',
    },
    card: {
        margin: '20px',
    },
Valeriy Panov's avatar
Valeriy Panov committed
31
32
33
    updateButton: {
        marginRight: '1rem',
    },
34
35
36
});

interface IBrowsePageProps extends React.ClassAttributes<any> {
37
    pagination?: Pagination<VocabularyFilter>;
38
    paged?: Page<Vocabulary>;
Matija Obreza's avatar
Matija Obreza committed
39
40
    listVocabularies: () => void;
    promiseListVocabularies: () => Promise<Page<Vocabulary>>;
41
42
43
    createVocabulary: any;
}

44
class BrowsePage extends React.Component<IBrowsePageProps & any, any> {
45
46

    protected static needs = [
Maxym Borodenko's avatar
Maxym Borodenko committed
47
        ({ search }) => listVocabularies(parse(search).p, parse(search).l, parse(search).s, {}, parse(search).d),
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    ];

    public componentWillMount() {
        const {pagination, paged, listVocabularies} = this.props;

        if (!paged) {
            listVocabularies(pagination.page, pagination.size, pagination.sort, pagination.filter, pagination.dir);
        }
    }

    public componentWillReceiveProps(nextProps) {
        const {listVocabularies, pagination: oldPagination} = this.props;
        const {pagination} = nextProps;

        if (!oldPagination.equals(pagination)) {
            listVocabularies(pagination.page, pagination.size, pagination.sort, pagination.filter, pagination.dir);
        }
    }

    protected onPaginationChange = (page, results, sortBy, dir) => {
Maxym Borodenko's avatar
Maxym Borodenko committed
68
        const { history, location } = this.props;
Maxym Borodenko's avatar
Maxym Borodenko committed
69
70
71
72
73
74
75
76
        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
77
        if (dir) {
Maxym Borodenko's avatar
Maxym Borodenko committed
78
79
80
            params.set('d', dir);
        } else {
            params.delete('d');
Maxym Borodenko's avatar
Maxym Borodenko committed
81
        }
82

Maxym Borodenko's avatar
Maxym Borodenko committed
83
84
        location.search = params.toString();
        history.push(location);
85
86
    }

Matija Obreza's avatar
Matija Obreza committed
87
88
89
    protected autoUpdateVocabularies = () => {
        const {autoUpdateVocabularies, pagination} = this.props;
        autoUpdateVocabularies()
Matija Obreza's avatar
Matija Obreza committed
90
91
92
93
          .then(() => {
            console.log('Vocabularies are updated');
            listVocabularies(pagination.page, pagination.size, pagination.sort, pagination.filter, pagination.dir);
          });
Valeriy Panov's avatar
Valeriy Panov committed
94
95
    }

96
    public render() {
Matija Obreza's avatar
Matija Obreza committed
97
        const {classes, paged, createVocabulary, pagination, promiseListVocabularies} = this.props;
98

99
        const stillLoading: boolean = (!(paged && paged.content));
Valeriy Panov's avatar
Valeriy Panov committed
100

Matija Obreza's avatar
Matija Obreza committed
101
102
103
104
105
106
107
108
        const loadVocabularyPage = (page: number, pageSize: number) => promiseListVocabularies(page, pageSize, pagination.sort, pagination.filter, pagination.dir);

        const renderVocabulary = (vocabulary: Vocabulary) => (
          <Grid key={ vocabulary.uuid } item xs={ 12 }>
              <VocabularyCard className={ classes.card } vocabulary={ vocabulary } textRows={ 3 } />
          </Grid>
        );

Valeriy Panov's avatar
Valeriy Panov committed
109
        return (
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
110
          <PageLayout>
111
            <Authorize role="ROLE_ADMINISTRATOR">
Valeriy Panov's avatar
Valeriy Panov committed
112
113
114
115
              <ContentHeaderWithButton
                  title="What do you want to do?"
                  buttons={
                      <div>
Matija Obreza's avatar
Matija Obreza committed
116
                          <Button className={ classes.updateButton } variant="raised" onClick={ this.autoUpdateVocabularies }>
Valeriy Panov's avatar
Valeriy Panov committed
117
118
                              Update vocabularies
                          </Button>
Matija Obreza's avatar
Matija Obreza committed
119
                          <Button variant="raised" onClick={ createVocabulary }>
Valeriy Panov's avatar
Valeriy Panov committed
120
121
122
123
124
                              Create vocabulary
                          </Button>
                      </div>
                  }
              />
125
126
            </Authorize>
            <Grid container spacing={ 0 }>
127
128
129
                <Grid item xs={ 12 }>
                    <PaginationComponent pageObj={ paged }
                                         onChange={ this.onPaginationChange }
Matija Obreza's avatar
Matija Obreza committed
130
                                         displayName="label.vocabulary"
Matija Obreza's avatar
Matija Obreza committed
131
                                         infinite
Valeriy Panov's avatar
Valeriy Panov committed
132
                                         sortOptions={ Vocabulary.SORT_OPTIONS }
133
134
                    />
                </Grid>
135
                { stillLoading ? <Loading /> :
Matija Obreza's avatar
Matija Obreza committed
136
137
138
139
140
                  <PagedLoader
                    paged={ paged }
                    loadPage={ loadVocabularyPage }
                    colSpan={ 3 }
                    itemRenderer={ renderVocabulary } />
141
                }
142
            </Grid>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
143
          </PageLayout>
144
145
146
147
148
        );
    }
}

const mapStateToProps = (state, ownProps) => ({
149
    pagination: new Pagination<VocabularyFilter>({
Maxym Borodenko's avatar
Maxym Borodenko committed
150
151
152
153
        page: +parse(ownProps.location.search).p || 0, // current page
        size: +parse(ownProps.location.search).l || 20, // page size
        sort: parse(ownProps.location.search).s, // page sorts
        dir: parse(ownProps.location.search).d, // page sort directions
154
    }),
155
    paged: state.vocabulary.public.paged,
156
157
158
159
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
    listVocabularies,
Matija Obreza's avatar
Matija Obreza committed
160
    promiseListVocabularies,
161
    createVocabulary,
Matija Obreza's avatar
Matija Obreza committed
162
    autoUpdateVocabularies,
163
164
165
166
167
}, dispatch);

const styled = withStyles(styles)(BrowsePage);

export default connect(mapStateToProps, mapDispatchToProps)(styled);