BrowsePage.tsx 7.93 KB
Newer Older
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
1
2
import * as React from 'react';
import { connect } from 'react-redux';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
3
import { compose } from 'redux';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
4
5
import { WithTranslation, withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
6

7
// Service
Maksym Tishchenko's avatar
Maksym Tishchenko committed
8
import { CooperatorService, UISecurity as P } from '@gringlobal-ce/client/service';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
9
// Action
Maksym Tishchenko's avatar
Maksym Tishchenko committed
10
import { receiveCooperatorSuccessAction, listCooperatorsAction, loadMoreCooperatorsAction } from 'cooperator/action/public';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
11
// Model
Maksym Tishchenko's avatar
Maksym Tishchenko committed
12
import { Cooperator } from '@gringlobal-ce/client/model/gringlobal';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
13
// Ui
14
15
16
import ContentHeader from '@gringlobal-ce/client/ui/common/heading/ContentHeader';
import Table, { TextAlign } from '@gringlobal-ce/client/ui/common/table/Table';
import AddNewButton from '@gringlobal-ce/client/ui/common/button/AddNewButton';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
17
import withBrowsePageBase, { WithBrowsePage } from 'ui/common/withBrowsePageBase';
18
import { CooperatorOwnedTableConfiguration as TableConfiguration } from '@gringlobal-ce/client/ui/common/table/TableConfiguration';
Matija Obreza's avatar
Matija Obreza committed
19
import Filters from './c/Filters';
20
21
22
import Geography from '@gringlobal-ce/client/model/gringlobal/Geography';
import PageTitle from '@gringlobal-ce/client/ui/common/PageTitle';
import Site from '@gringlobal-ce/client/model/gringlobal/Site';
23
import { CodeValueDisplay } from 'common/CodeValue';
Matija Obreza's avatar
Matija Obreza committed
24
import FiltersButton from 'accession/ui/c/FiltersButton';
25
import CooperatorForm from 'cooperator/ui/c/CooperatorForm';
Maksym Tishchenko's avatar
Maksym Tishchenko committed
26
27
import { showSnackbar } from '@gringlobal-ce/client/action/snackbar';
import SimilarCooperatorsDialog from 'cooperator/ui/c/SimilarCooperatorsDialog';
28
import { GeographyLink } from 'ui/common/Links';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
29

30
31
export const CooperatorTableDefaultConfig = {
  defaultColumns: [
Matija Obreza's avatar
Matija Obreza committed
32
    'name',
33
34
35
36
37
    'title',
    'lastName',
    'firstName',
    'organization',
    'job',
Matija Obreza's avatar
Matija Obreza committed
38
    'geography',
39
    'faoInstituteNumber',
40
  ],
Matija Obreza's avatar
Matija Obreza committed
41
42
43
44
  defaultColumnSettings: {
    name: { readonly: true },
    title: { align: TextAlign.right },
  },
45
46
47
  ignoredColumns: [
    'id',
    '_class',
48
    'webCooperator',
49
  ],
50
51
  columnRenderers: {
    name: ({ row: cooperator }: { row: Cooperator }): JSX.Element => (
Matija Obreza's avatar
Matija Obreza committed
52
      <Link to={ `/cooperator/${cooperator.id}` }>
Matija Obreza's avatar
Matija Obreza committed
53
54
55
56
57
58
        { (cooperator.firstName || cooperator.lastName) && (
          <>{ cooperator.title } { cooperator.firstName } { cooperator.lastName }</>
        ) }
        { ! (cooperator.firstName || cooperator.lastName) && (
          <>{ cooperator.organization }</>
        ) }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
59
60
61
62
63
64
        { ! ((cooperator.firstName || cooperator.lastName) && cooperator.organization) &&
          <>{ cooperator.email }</>
        }
        { ! ((cooperator.firstName || cooperator.lastName) && cooperator.organization && cooperator.email) &&
          <>{ cooperator.id }</>
        }
Oleksii Savran's avatar
Oleksii Savran committed
65
66
      </Link>
    ),
67
68
    geography: ({ value: geography }: { value: Geography }): JSX.Element => <GeographyLink geography={ geography } />,
    currentGeography: ({ value: geography }: { value: Geography }): JSX.Element => <GeographyLink geography={ geography } />,
69
70
71
72
73
    site: ({ value: site }: { value: Site }): JSX.Element => site && <>{ site.siteShortName }</>,
    statusCode: ({ value: statusCode }: { value: string }) => <CodeValueDisplay codeGroup={ Cooperator.CodeGroup.statusCode } value={ statusCode } />,
    categoryCode: ({ value: categoryCode }: { value: string }) => <CodeValueDisplay codeGroup={ Cooperator.CodeGroup.categoryCode } value={ categoryCode } />,
    disciplineCode: ({ value: disciplineCode }: { value: string }) => <CodeValueDisplay codeGroup={ Cooperator.CodeGroup.disciplineCode } value={ disciplineCode } />,
    title: ({ value: title }: { value: string }) => <CodeValueDisplay codeGroup={ Cooperator.CodeGroup.title } value={ title } />,
74
75
  },
};
Oleksii Savran's avatar
Oleksii Savran committed
76

77
78
const CooperatorTableConfig = new TableConfiguration(CooperatorTableDefaultConfig);

Maksym Tishchenko's avatar
Maksym Tishchenko committed
79
class CooperatorBrowsePage extends React.Component<PropsFromRedux & WithTranslation & WithBrowsePage> {
80
81
  public state = {
    cooperatorDialogIsOpen: false,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
82
83
84
    similar: null,
    unsaved: null,
    error: null
85
  };
86
87
88
89

  protected static needs = [
    ({}) => listCooperatorsAction(),
  ];
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
90

91
92
  public constructor(props) {
    super(props);
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
93
94
  }

Maksym Tishchenko's avatar
Maksym Tishchenko committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  private handleSubmit = () => {
    const { unsaved } = this.state;
    console.log('Saving unsaved cooperator from Similarity Dialog', unsaved);
    this.createCooperator(unsaved);
  }

  private createCooperator = (formData: Cooperator) => {
    const { receiveCooperatorSuccessAction } = this.props;
    this.resetError();
    CooperatorService.createCooperator(formData).then((cooperator) => {
      receiveCooperatorSuccessAction(cooperator);
      this.closeSimilarDialog();
      this.closeCooperatorDialog();
    }).catch((e) => {
      this.closeSimilarDialog();
      this.setState({ error: e.data && e.data.error || e.toString() });
    })
112
113
  };

Maksym Tishchenko's avatar
Maksym Tishchenko committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  private resetError = () => {
    return this.setState({ error: null });
  }

  private checkSimilarCooperators = (formData: Cooperator) => {
    const { showSnackbar, t } = this.props;
    showSnackbar(t('cooperator.public.p.details.lookingForSimilar'));
    CooperatorService.getSimilarCooperatorForUnsaved(formData).then((similar) => {
      if (similar && similar.length > 0) {
        this.setState({ similar, unsaved: formData });
      } else {
        this.createCooperator(formData);
      }
    }).catch((e) => {
      showSnackbar(JSON.stringify(e));
      console.log(e);
    })
  }

133
134
135
136
137
138
139
140
  private openCooperatorDialog = () => {
    this.setState({ cooperatorDialogIsOpen: true });
  };

  private closeCooperatorDialog = () => {
    this.setState({ cooperatorDialogIsOpen: false });
  };

Maksym Tishchenko's avatar
Maksym Tishchenko committed
141
142
143
144
  private closeSimilarDialog = () => {
    this.setState({ similar: null, unsaved: null });
  };

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
145
  public render() {
Matija Obreza's avatar
Matija Obreza committed
146
    const { data, t, onSortChange, applyFilter, loadMore } = this.props;
Maksym Tishchenko's avatar
Maksym Tishchenko committed
147
    const { cooperatorDialogIsOpen, similar, unsaved, error } = this.state;
148
    const columns = CooperatorTableConfig.getColumns( data && data.content ? data.content[0] : null);
149

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
150
151
    return (
      <>
Matija Obreza's avatar
Matija Obreza committed
152
153
154
155
156
157
158
159
        <PageTitle title={ data && data.totalElements ? t('cooperator.browse.title', { count: data.totalElements }) : t('cooperator.public.p.browse.title') }/>
        <ContentHeader title={ data && data.totalElements ? t('cooperator.browse.title', { count: data.totalElements }) : t('cooperator.public.p.browse.title') }>
          <FiltersButton>
            <Filters
              onSubmit={ applyFilter }
              filter={ data && data.filter }
            />
          </FiltersButton>
Matija Obreza's avatar
Matija Obreza committed
160
        </ContentHeader>
161
        <Table
162
          tableKey="cooperator-browse-list"
163
          type={ 'Cooperator' }
164
          columns={ columns }
165
          data={ data && data.content }
166
          tableConfig={ CooperatorTableConfig }
Oleksii Savran's avatar
Oleksii Savran committed
167
168
169
170
          total={ data && data.content && data.totalElements }
          loadMore={ loadMore }
          sort={ data && data.sort }
          onSortChange={ onSortChange }
171
        />
172
173

        <P.HasAccess action={ P.CooperatorData } permission={ P.create }>
174
175
176
177
          <AddNewButton action={ this.openCooperatorDialog } />
          <CooperatorForm
            isOpen={ cooperatorDialogIsOpen }
            onClose={ this.closeCooperatorDialog }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
178
179
            onSubmit={ this.checkSimilarCooperators }
            formId="cooperator-form"
180
            title={ t('cooperator.public.p.edit.title') }
Maksym Tishchenko's avatar
Maksym Tishchenko committed
181
            size="lg"
182
            sectioned
Maksym Tishchenko's avatar
Maksym Tishchenko committed
183
184
185
186
187
188
189
190
191
            error={ error }
            resetError={ this.resetError }
          />
          <SimilarCooperatorsDialog
            unsaved={ unsaved }
            similar={ similar }
            onClose={ this.closeSimilarDialog }
            onSave={ this.handleSubmit }
            size="lg"
192
          />
193
        </P.HasAccess>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
194
195
196
197
198
199
200
      </>
    );
  }

}


201
const mapStateToProps = (state) => ({
Oleksii Savran's avatar
Oleksii Savran committed
202
  loadableData: state.cooperator.public.cooperators,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
203
204
});

Maksym Tishchenko's avatar
Maksym Tishchenko committed
205
const mapDispatch = {
Oleksii Savran's avatar
Oleksii Savran committed
206
207
  listAction: listCooperatorsAction,
  loadMoreData: loadMoreCooperatorsAction,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
208
209
  receiveCooperatorSuccessAction,
  showSnackbar,
Maksym Tishchenko's avatar
Maksym Tishchenko committed
210
}
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
211

Maksym Tishchenko's avatar
Maksym Tishchenko committed
212
type PropsFromRedux = ReturnType<typeof mapStateToProps> & typeof mapDispatch;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
213
214

export default compose(
Maksym Tishchenko's avatar
Maksym Tishchenko committed
215
  connect(mapStateToProps, mapDispatch),
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
216
  withTranslation(),
Oleksii Savran's avatar
Oleksii Savran committed
217
)(withBrowsePageBase(CooperatorBrowsePage));