Skip to content

Commit

Permalink
Merge pull request #9 from psmb/newui
Browse files Browse the repository at this point in the history
TASK: migrate newsletter view to new UI
  • Loading branch information
dimaip authored Aug 26, 2017
2 parents 41535a5 + d69f656 commit 545f533
Show file tree
Hide file tree
Showing 12 changed files with 950 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules

6 changes: 5 additions & 1 deletion Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ Neos:
fusion:
autoInclude:
Psmb.Newsletter: true

Ui:
resources:
javascript:
'Psmb.Newsletter:NewsletterView':
resource: resource://Psmb.Newsletter/Public/JavaScript/NewsletterView/Plugin.js
#Psmb:
# Newsletter:
# globalSettings:
Expand Down
14 changes: 14 additions & 0 deletions Resources/Private/NewsletterView/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{yml,yaml}]
indent_size = 2

[*.{md}]
indent_size = 2
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions Resources/Private/NewsletterView/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6.3.0
15 changes: 15 additions & 0 deletions Resources/Private/NewsletterView/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"description": "NewsletterView",
"license": "MIT",
"private": true,
"scripts": {
"build": "neos-react-scripts build",
"watch": "neos-react-scripts watch"
},
"devDependencies": {
"@neos-project/neos-ui-extensibility": "@dev"
},
"neos": {
"buildTargetDirectory": "../../Public/JavaScript/NewsletterView"
}
}
26 changes: 26 additions & 0 deletions Resources/Private/NewsletterView/src/ConfirmationDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, {PropTypes} from 'react';
import {Button, Dialog} from '@neos-project/react-ui-components';

const ConfirmationDialog = ({isOpen, translate, close, send}) => {
return (
<Dialog
isOpen={isOpen}
title={translate('Psmb.Newsletter:Main:js.testConfirmationTitle')}
onRequestClose={close}
actions={[
<Button onClick={close} style="clean">{translate('Neos.Neos:Main:cancel')}</Button>,
<Button onClick={send} style="brand">{translate('Psmb.Newsletter:Main:js.send')}</Button>
]}
>
<div style={{padding: '16px'}}>{translate('Psmb.Newsletter:Main:js.confirmationDescription')}</div>
</Dialog>
);
};
ConfirmationDialog.propTypes = {
isOpen: PropTypes.bool,
translate: PropTypes.func.isRequired,
close: PropTypes.func.isRequired,
send: PropTypes.func.isRequired
};

export default ConfirmationDialog;
134 changes: 134 additions & 0 deletions Resources/Private/NewsletterView/src/NewsletterView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, {PropTypes, Component} from 'react';
import {SelectBox, Button} from '@neos-project/react-ui-components';
import {connect} from 'react-redux';
import {selectors} from '@neos-project/neos-ui-redux-store';
import {neos} from '@neos-project/neos-ui-decorators';
import {$get} from 'plow-js';
import TestConfirmationDialog from './TestConfirmationDialog';
import ConfirmationDialog from './ConfirmationDialog';

const fetchSubscriptions = nodeType => fetch(`/newsletter/getSubscriptions?nodeType=${nodeType}`, {
credentials: 'include'
}).then(response => response.json());

const sendNewsletter = (focusedNodeContextPath, subscription, isTest, email) => {
const sendEndpointUrl = isTest ? '/newsletter/testSend' : '/newsletter/send';
const csrfToken = document.getElementById('appContainer').dataset.csrfToken;
const data = new URLSearchParams();
data.set('node', focusedNodeContextPath.replace(/user-.+\;/, 'live;'));
data.set('subscription', subscription);
data.set('__csrfToken', csrfToken);
if (isTest && email) {
data.set('email', email);
}
return fetch(sendEndpointUrl, {
credentials: 'include',
method: 'POST',
body: data
})
.then(response => response.json());
};

@neos(globalRegistry => ({
i18nRegistry: globalRegistry.get('i18n')
}))
@connect(state => ({
focusedNodeContextPath: selectors.CR.Nodes.focusedNodePathSelector(state),
getNodeByContextPath: selectors.CR.Nodes.nodeByContextPath(state)
}))
export default class NewsletterView extends Component {

static propTypes = {
focusedNodeContextPath: PropTypes.string,
getNodeByContextPath: PropTypes.func.isRequired
};

constructor(props) {
super(props);
this.state = {
subscriptions: [],
selectedSubscription: null,
confirmationDialogIsOpen: false,
testConfirmationDialogIsOpen: false,
isError: null,
isSent: null
};
this.selectSubscription = this.selectSubscription.bind(this);
this.sendNewsletter = this.sendNewsletter.bind(this);
this.sendTestNewsletter = this.sendTestNewsletter.bind(this);
this.toggleConfirmationDialog = this.toggleConfirmationDialog.bind(this);
this.toggleTestConfirmationDialog = this.toggleTestConfirmationDialog.bind(this);
}

componentDidMount() {
const node = this.props.getNodeByContextPath(this.props.focusedNodeContextPath);
const nodeType = $get('nodeType', node);
if (nodeType) {
fetchSubscriptions(nodeType).then(json => this.setState({subscriptions: json}));
}
}

toggleConfirmationDialog(isOpen) {
this.setState({confirmationDialogIsOpen: isOpen})
}

toggleTestConfirmationDialog(isOpen) {
this.setState({testConfirmationDialogIsOpen: isOpen})
}

selectSubscription(value) {
this.setState({selectedSubscription: value});
}

sendNewsletter() {
const isTest = false;
sendNewsletter(this.props.focusedNodeContextPath, this.state.selectedSubscription, isTest)
.then(json => {
console.log('asdf', json);
return json.status === 'success' ? this.setState({isSent: true}) : this.setState({isError: true});
})
.catch(() => this.setState({isError: true}));
this.toggleConfirmationDialog(false);
}

sendTestNewsletter(email) {
const isTest = true;
sendNewsletter(this.props.focusedNodeContextPath, this.state.selectedSubscription, isTest, email)
.then(json => {
console.log('asdf1', json);
return json.status === 'success' ? this.setState({isSent: true}) : this.setState({isError: true})
})
.catch(() => this.setState({isError: true}));
this.toggleTestConfirmationDialog(false);
}

render() {
return (
<div>
<SelectBox
value={this.state.selectedSubscription}
options={this.state.subscriptions}
onValueChange={this.selectSubscription}
/>
<Button disabled={!this.state.selectedSubscription} style="brand" onClick={() => this.toggleConfirmationDialog(true)}>{this.props.i18nRegistry.translate('Psmb.Newsletter:Main:js.send')}</Button>
<Button disabled={!this.state.selectedSubscription} style="clean" onClick={() => this.toggleTestConfirmationDialog(true)}>{this.props.i18nRegistry.translate('Psmb.Newsletter:Main:js.test')}</Button>

{this.state.isError ? <div style={{marginTop: '16px', color: 'red'}}>{this.props.i18nRegistry.translate('Psmb.Newsletter:Main:js.error')}</div> : ''}
{this.state.isSent ? <div style={{marginTop: '16px', color: 'green'}}>{this.props.i18nRegistry.translate('Psmb.Newsletter:Main:js.sent')}</div> : ''}

<TestConfirmationDialog
isOpen={this.state.testConfirmationDialogIsOpen}
translate={this.props.i18nRegistry.translate.bind(this.props.i18nRegistry)}
close={() => this.toggleTestConfirmationDialog(false)}
send={this.sendTestNewsletter}
/>
<ConfirmationDialog
isOpen={this.state.confirmationDialogIsOpen}
translate={this.props.i18nRegistry.translate.bind(this.props.i18nRegistry)}
close={() => this.toggleConfirmationDialog(false)}
send={this.sendNewsletter}
/>
</div>
);
}
}
42 changes: 42 additions & 0 deletions Resources/Private/NewsletterView/src/TestConfirmationDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, {PropTypes, Component} from 'react';
import {SelectBox, Button, Dialog, TextInput} from '@neos-project/react-ui-components';

export default class TestConfirmationDialog extends Component {

static propTypes = {
isOpen: PropTypes.bool,
translate: PropTypes.func.isRequired,
close: PropTypes.func.isRequired,
send: PropTypes.func.isRequired
};

constructor(props) {
super(props);
this.state = {
email: ''
};
}

render() {
const {isOpen, translate, close, send} = this.props;
return (
<Dialog
isOpen={isOpen}
title={translate('Psmb.Newsletter:Main:js.testConfirmationTitle')}
onRequestClose={close}
actions={[
<Button onClick={close} style="clean">{translate('Neos.Neos:Main:cancel')}</Button>,
<Button disabled={!this.state.email.includes('@')} onClick={() => send(this.state.email)} style="brand">{translate('Psmb.Newsletter:Main:js.send')}</Button>
]}
>
<div style={{padding: '16px'}}>
{translate('Psmb.Newsletter:Main:js.testEmailLabel')}
<TextInput
onChange={email => this.setState({email})}
value={this.state.email}
/>
</div>
</Dialog>
);
}
}
1 change: 1 addition & 0 deletions Resources/Private/NewsletterView/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('./manifest');
10 changes: 10 additions & 0 deletions Resources/Private/NewsletterView/src/manifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import manifest from '@neos-project/neos-ui-extensibility';
import NewsletterView from './NewsletterView';

manifest('Psmb.Newsletter:NewsletterView', {}, globalRegistry => {
const viewsRegistry = globalRegistry.get('inspector').get('views');

viewsRegistry.add('Psmb.Newsletter/Views/NewsletterView', {
component: NewsletterView
});
});
Loading

0 comments on commit 545f533

Please sign in to comment.