EditPage.tsx 6.7 KB
Newer Older
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
1
2
3
4
import * as React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { translate } from 'react-i18next';
Oleksii Savran's avatar
Oleksii Savran committed
5
import { withStyles } from '@material-ui/core';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
6
7

// actions
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
8
9
import { createGlobalArticle, loadArticle, updateArticle } from 'cms/actions/admin';
import { showSnackbar } from 'actions/snackbar';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
10
11
// model
import Article from 'model/cms/Article';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
12
13
// service
import CmsService from 'service/genesys/CmsService';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
14
15
16
17
// utilities
import { log } from 'utilities/debug';
// ui
import { PageContents } from 'ui/layout/PageLayout';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
18
import PageTitle from 'ui/common/PageTitle';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
19
20
import Grid from '@material-ui/core/Grid';
import ArticleForm from './c/ArticleForm';
Oleksii Savran's avatar
Oleksii Savran committed
21
22
import ContentHeaderWithButton from 'ui/common/heading/ContentHeaderWithButton';
import ActionButton from 'ui/common/buttons/ActionButton';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
23
import ArticleSection from 'cms/ui/c/ArticleSection';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
24
import ButtonBar from 'ui/common/buttons/ButtonBar';
Oleksii Savran's avatar
Oleksii Savran committed
25
26
27
28
29

const styles = () => ({
  article: {
    maxWidth: '100%',
  },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  alertWarning: {
    fontSize: 16,
    backgroundColor: '#fcf8e3',
    color: '#8a6d3b',
    border: '1px solid #faebcc',
    marginBottom: '1rem',
    padding: '.5rem',
  },
  /*tslint:disable*/
  customSubHeader: {
    justifyContent: 'space-between' as 'space-between',
    '& > div': {
      width: 'auto !important' as 'auto !important',
    },
  },
  /*tslint:enable*/
Oleksii Savran's avatar
Oleksii Savran committed
46
});
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
47
48
49
50
51
52
53
54
55
56
57
58
59

interface IArticleEditPageProps extends React.ClassAttributes<any> {
  t: any;
  i18n: any;
  classes: any;
  loading: any;
  slug?: string;
  targetId?: number;
  className?: string;
  article: Article;
  loadArticle: (lang: string, slug, targetId?: number, className?: string) => void;
  createGlobalArticle: (article: Article) => void;
  updateArticle: (article: Article) => void;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
60
  showSnackbar: any;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
61
62
63
64
65
66
67
68
}

class ArticleEditPage extends React.Component<IArticleEditPageProps, any> {

  protected static needs = [
    ({ params, state }) => loadArticle(state.applicationConfig.lang, params.slug, params.targetId, params.className),
  ];

Oleksii Savran's avatar
Oleksii Savran committed
69
70
  private constructor(props, context) {
    super(props, context);
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
71
72
73
74
    this.state = {
      isEdit: true,
      fetchResults: {},
    };
Oleksii Savran's avatar
Oleksii Savran committed
75
  }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

  private onSave = (article: any) => {
    const { slug, createGlobalArticle, updateArticle } = this.props;
    if (slug) {
      updateArticle(article);
    } else {
      createGlobalArticle(article);
    }
  }

  public componentWillMount() {
    const { article, loadArticle, slug, i18n, targetId, className } = this.props;

    if (slug && (!article || article.slug !== slug || (targetId && article.targetId !== targetId && article.classPk && article.classPk.className !== className))) {
      loadArticle(i18n.language, slug, targetId, className);
    }
  }

  public componentWillReceiveProps(nextProps) {
    const {article, loadArticle, slug, i18n, targetId, className, loading }  = nextProps;

    if (slug && !loading && (!article || article.slug !== slug)) {
      loadArticle(i18n.language, slug, targetId, className);
    }
  }

  public render() {
Oleksii Savran's avatar
Oleksii Savran committed
103
    const { slug, t, classes } = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
104
    const { isEdit, fetchResults } = this.state;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
105
106
107
108
109
110
111
112
113
114
115
116
    let { article } = this.props;

    if (!article && !slug) {
      article = new Article();
    }

    if (!article) {
      log('No institute.');
      return null;
    }

    return (
Oleksii Savran's avatar
Oleksii Savran committed
117
      <div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
118
        <PageTitle title={ article.title }/>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        <ContentHeaderWithButton title={ article.title } classes={ { subHeader: classes.customSubHeader } } buttons={
          <ButtonBar>
            <ActionButton
              title={ isEdit ? t('common:action.view') : t('common:action.edit') }
              action={ () => this.setState({ isEdit: !isEdit }) }
            />
            <ActionButton
              title={ t('cms.admin.p.edit.transifex.fetch') }
              action={ this.fetchAllTranslations }
            />
            <ActionButton
              title={ t('cms.admin.p.edit.transifex.post') }
              action={ this.postToTransifex }
            />
            <ActionButton
              title={ t('cms.admin.p.edit.transifex.delete') }
              action={ this.deleteFromTransifex }
            />
          </ButtonBar>
Oleksii Savran's avatar
Oleksii Savran committed
138
139
        }/>
        <PageContents className="pt-1rem pb-1rem">
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
140
141
142
143
144
          { fetchResults && Object.keys(fetchResults).length > 0 &&
            <div className={ classes.alertWarning }>
              { Object.keys(fetchResults).map((lang) => <div key={ lang }>{ t('cms.admin.p.edit.transifex.fetchResult', {lang, result: fetchResults[lang]}) }</div>) }
            </div>
          }
Oleksii Savran's avatar
Oleksii Savran committed
145
146
147
148
149
150
151
152
153
          <Grid item xs={ 12 }>
            { isEdit ? (
              <ArticleForm
                showIsTemplate={ !slug }
                initialValues={ article }
                onSubmit={ this.onSave }
                t={ t }
              />
            ) : (
Oleksii Savran's avatar
Oleksii Savran committed
154
              <ArticleSection body={ article.body } className={ classes.article }/>
Oleksii Savran's avatar
Oleksii Savran committed
155
156
157
158
            ) }
          </Grid>
        </PageContents>
      </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
159
160
161
    );
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  private fetchAllTranslations = () => {
    const { article, showSnackbar } = this.props;
    this.setState({ fetchResults: {} });

    if (!article || !article.slug) {
      return this.setState({ fetchResults: { en: 'Article is undefined' } });
    }

    showSnackbar('cms.admin.p.edit.transifex.fetchStarted');
    CmsService.fetchAllFromTransifex(article.slug, article.classPk ? article.classPk.shortName : null, article.targetId, article.template)
      .then((fetchResults) => this.setState({ fetchResults }));
  }

  private postToTransifex = () => {
    const { article, showSnackbar } = this.props;

    showSnackbar('cms.admin.p.edit.transifex.postStarted');
    CmsService.postToTransifex(article.classPk.shortName, article.slug, article.targetId)
      .then(() => showSnackbar('cms.admin.p.edit.transifex.postSucceeded'))
      .catch(() => showSnackbar('cms.admin.p.edit.transifex.postFailed'));
  }

  private deleteFromTransifex = () => {
    const { article, showSnackbar } = this.props;

    showSnackbar('cms.admin.p.edit.transifex.deleteStarted');
    CmsService.deleteFromTransifex(article.classPk.shortName, article.slug)
      .then(() => showSnackbar('cms.admin.p.edit.transifex.deleteSucceeded'))
      .catch(() => showSnackbar('cms.admin.p.edit.transifex.deleteFailed'));
  }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
193
194
195
196
197
198
199
200
201
202
203
204
205
206
}

const mapStateToProps = (state, ownProps) => ({
  slug: ownProps.match.params.slug,
  targetId:  ownProps.match.params.targetId,
  className: ownProps.match.params.className,
  loading: state.cms.admin.loading,
  article: state.cms.admin.articles[ownProps.match.params.slug],
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
  loadArticle,
  updateArticle,
  createGlobalArticle,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
207
  showSnackbar,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
208
209
}, dispatch);

Oleksii Savran's avatar
Oleksii Savran committed
210
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(translate()(ArticleEditPage)));