Skip to content

Commit

Permalink
Merge pull request #205 from hql287/custom-invoice-id
Browse files Browse the repository at this point in the history
Allow user to set custom invoiceID
  • Loading branch information
hql287 authored Feb 4, 2018
2 parents 4f0392b + 32b6684 commit bd47b94
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 43 deletions.
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ function setInitialValues() {
amount: 0,
},
required_fields: {
invoiceID: false,
dueDate: false,
currency: false,
discount: false,
Expand Down
67 changes: 67 additions & 0 deletions app/components/form/InvoiceID.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Libraries
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

// Custom Components
import { Section } from '../shared/Section';

// Animation
import _withFadeInAnimation from '../shared/hoc/_withFadeInAnimation';

// Styles
import styled from 'styled-components';
const NoteContent = styled.textarea`
min-height: 36px;
border-radius: 4px;
padding: 10px;
display: block;
width: 100%;
border: 1px solid #f2f3f4;
color: #3a3e42;
font-size: 14px;
`;

// Component
export class InvoiceID extends PureComponent {
constructor(props) {
super(props);
this.state = { invoiceID: this.props.invoiceID };
this.handleInputChange = this.handleInputChange.bind(this);
}

componentWillReceiveProps(nextProps) {
if (nextProps.invoiceID === "") {
this.setState({ invoiceID: "" });
}
}

handleInputChange(event) {
this.setState({ invoiceID: event.target.value }, () => {
this.props.updateFieldData('invoiceID', this.state.invoiceID);
});
}

render() {
const { t } = this.props;
return (
<Section>
<label className="itemLabel">Invoice ID</label>
<input
name="invoiceID"
type="text"
onChange={this.handleInputChange}
value={this.state.invoiceID}
/>
</Section>
);
}
}

InvoiceID.propTypes = {
invoiceID: PropTypes.string.isRequired,
t: PropTypes.func.isRequired,
updateFieldData: PropTypes.func.isRequired,
};

// Export
export default _withFadeInAnimation(InvoiceID);
9 changes: 9 additions & 0 deletions app/components/form/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ class Settings extends PureComponent {
</Helper>

<AllSettings>
<Setting>
<Label>Invoice ID</Label>
<Switch
name="invoiceID"
checked={required_fields.invoiceID}
onChange={this.handleInputChange}
/>
</Setting>

<Setting>
<Label>{t('form:fields:dueDate:name')}</Label>
<Switch
Expand Down
70 changes: 70 additions & 0 deletions app/components/form/__tests__/InvoiceID.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Libs
import React from 'react';
import renderer from 'react-test-renderer';
import { mount } from 'enzyme';

// Component
import { InvoiceID } from '../InvoiceID.jsx';

// Mocks
const t = jest.fn();
const updateFieldData = jest.fn();
const invoiceID = "Invoice: 123-456-789"

describe('InvoiceID component', () => {
let wrapper;
beforeEach(() => {
wrapper = mount(
<InvoiceID
t={t}
invoiceID={invoiceID}
updateFieldData={updateFieldData}
/>
);
});

// PROPS & STATE
it('receives correct props', () => {
expect(wrapper.prop('invoiceID')).toEqual(invoiceID);
expect(wrapper.prop('updateFieldData')).toEqual(updateFieldData);
});

// RENDER
it('renders necessary element', () => {
expect(wrapper.find('label')).toHaveLength(1);
expect(wrapper.find('input')).toHaveLength(1);
});

// LIFE CYCLE EVENTS
// TODO
it('render when necessary', () => {});

// PRIVATE METHOD
it('handleInputChange correctly', () => {
const spy = jest.spyOn(InvoiceID.prototype, 'handleInputChange');
const wrap = mount(
<InvoiceID
t={t}
invoiceID={invoiceID}
updateFieldData={updateFieldData}
/>
);
const textInput = wrap.find('input');
textInput.simulate('change', { target: { value: 'Invoice: 987-654-321' } });
expect(spy).toHaveBeenCalled();
});

// SNAPSHOT
it('matches snapshot', () => {
const tree = renderer
.create(
<InvoiceID
t={t}
invoiceID={invoiceID}
updateFieldData={updateFieldData}
/>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
23 changes: 15 additions & 8 deletions app/components/form/__tests__/Settings.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const currentInvoice = {
settings: {
open: false,
required_fields: {
invoiceID: false,
dueDate: false,
currency: false,
discount: false,
Expand All @@ -34,6 +35,7 @@ const currentInvoice = {
tax: {},
currency: 'USD',
required_fields: {
invoiceID: false,
dueDate: false,
currency: false,
discount: false,
Expand Down Expand Up @@ -68,13 +70,12 @@ describe('Settings component', () => {
expect(wrapper.prop('toggleField')).toEqual(toggleField);
expect(wrapper.prop('toggleFormSettings')).toEqual(toggleFormSettings);
expect(wrapper.prop('updateSavedSettings')).toEqual(updateSavedSettings);
// expect(wrapper.prop('currentInvoice')).toEqual(currentInvoice);
});

// RENDER
it('renders necessary element', () => {
expect(wrapper.find('label')).toHaveLength(11);
expect(wrapper.find(Switch)).toHaveLength(5);
expect(wrapper.find('label')).toHaveLength(13);
expect(wrapper.find(Switch)).toHaveLength(6);
});

// LIFE CYCLE EVENTS
Expand All @@ -84,13 +85,19 @@ describe('Settings component', () => {
// PRIsettingsE METHOD
it('toggle field correctly', () => {
// Setup
const dueDate = wrapper.find(Switch).at(0);
const currency = wrapper.find(Switch).at(1);
const discount = wrapper.find(Switch).at(2);
const tax = wrapper.find(Switch).at(3);
const note = wrapper.find(Switch).at(4);
const invoiceID = wrapper.find(Switch).at(0);
const dueDate = wrapper.find(Switch).at(1);
const currency = wrapper.find(Switch).at(2);
const discount = wrapper.find(Switch).at(3);
const tax = wrapper.find(Switch).at(4);
const note = wrapper.find(Switch).at(5);

// Execute & Assert
invoiceID.find('input').simulate('change');
expect(toggleField).toHaveBeenCalled();
expect(toggleField).toHaveBeenCalledWith('invoiceID');
expect(toggleField).not.toHaveBeenCalledWith('something-else');

dueDate.find('input').simulate('change');
expect(toggleField).toHaveBeenCalled();
expect(toggleField).toHaveBeenCalledWith('dueDate');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`InvoiceID component matches snapshot 1`] = `
<div
className="Section__SectionStyle-dgSKSv cwfAAu"
>
<label
className="itemLabel"
>
Invoice ID
</label>
<input
name="invoiceID"
onChange={[Function]}
type="text"
value="Invoice: 123-456-789"
/>
</div>
`;
23 changes: 23 additions & 0 deletions app/components/form/__tests__/__snapshots__/Settings.spec.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,29 @@ exports[`Settings component matches snapshot 1`] = `
<div
className="Settings__AllSettings-hAEgKd cLFeXF"
>
<div
className="Settings__Setting-iSwZaF jiKDp"
>
<label
className="Settings__Label-bIhYmz iPSgUQ"
>
Invoice ID
</label>
<label
className="Switch__SwitchStyle-cIZUZy lcgmHp"
>
<input
checked={false}
className="Switch__Input-jIJATX kGoGgc"
name="invoiceID"
onChange={[Function]}
type="checkbox"
/>
<span
className="Switch__Slider-iwwTvI egztuK"
/>
</label>
</div>
<div
className="Settings__Setting-iSwZaF jiKDp"
>
Expand Down
12 changes: 6 additions & 6 deletions app/components/invoices/Invoice.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ class Invoice extends PureComponent {
</span>
);
}

case 'paid': {
return (
<span>
Expand All @@ -186,7 +185,6 @@ class Invoice extends PureComponent {
</span>
);
}

case 'refunded': {
return (
<span>
Expand Down Expand Up @@ -244,10 +242,12 @@ class Invoice extends PureComponent {
<Field>
<label>{t('invoices:fields:invoiceID')}</label>
<p>
{truncate(invoice._id, {
length: 8,
omission: '',
})}
{ invoice.invoiceID
? invoice.invoiceID
: truncate(invoice._id, {
length: 8,
omission: '', })
}
</p>
</Field>
<Field>
Expand Down
13 changes: 12 additions & 1 deletion app/components/settings/Invoice.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ class Invoice extends Component {
<label className="itemLabel">{t('settings:fields:requiredFields')}</label>
<Section>
<Row>
<Field>
<label className="itemLabel">Invoice ID</label>
<label className="switch">
<input
name="invoiceID"
type="checkbox"
checked={required_fields.invoiceID}
onChange={this.handleVisibilityChange}
/>
<span className="slider round" />
</label>
</Field>
<Field>
<label className="itemLabel">{t('form:fields:dueDate:name')}</label>
<label className="switch">
Expand All @@ -216,7 +228,6 @@ class Invoice extends Component {
<span className="slider round" />
</label>
</Field>

<Field>
<label className="itemLabel">{t('form:fields:discount:name')}</label>
<label className="switch">
Expand Down
9 changes: 9 additions & 0 deletions app/containers/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Discount from '../components/form/Discount';
import DueDate from '../components/form/DueDate';
import Tax from '../components/form/Tax';
import Note from '../components/form/Note';
import InvoiceID from '../components/form/InvoiceID';
import Settings from '../components/form/Settings';
import Button from '../components/shared/Button';
import _withFadeInAnimation from '../components/shared/hoc/_withFadeInAnimation';
Expand Down Expand Up @@ -50,6 +51,7 @@ class Form extends PureComponent {
discount,
tax,
note,
invoiceID,
settings,
savedSettings,
} = this.props.currentInvoice;
Expand Down Expand Up @@ -89,6 +91,13 @@ class Form extends PureComponent {
savedSettings={savedSettings.required_fields}
updateSavedSettings={updateSavedFormSettings}
/>
{required_fields.invoiceID && (
<InvoiceID
t={t}
invoiceID={invoiceID}
updateFieldData={updateFieldData}
/>
)}
<Recipient />
<ItemsList />
{required_fields.dueDate && (
Expand Down
Loading

0 comments on commit bd47b94

Please sign in to comment.