Skip to content

Commit 0104c7f

Browse files
authored
Merge pull request #4299 from CDharmateja/project-defaults-billing-account
Billing account field in project defaults
2 parents 2d04a30 + 4cd987e commit 0104c7f

File tree

5 files changed

+132
-5
lines changed

5 files changed

+132
-5
lines changed

src/api/billingAccounts.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { axiosInstance as axios } from './requestInterceptor'
2+
import { TC_API_URL } from '../config/constants'
3+
4+
/**
5+
* Get billing accounts based on project id
6+
*
7+
* @param {String} projectId Id of the project
8+
*
9+
* @returns {Promise<Object>} Billing accounts data
10+
*/
11+
export function fetchBillingAccounts(projectId) {
12+
return axios.get(`${TC_API_URL}/v5/projects/${projectId}/billingAccounts`)
13+
}
14+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React from 'react'
2+
import {HOC as hoc} from 'formsy-react'
3+
4+
import Select from '../../../../components/Select/Select'
5+
import {fetchBillingAccounts} from '../../../../api/billingAccounts'
6+
import {SALESFORCE_PROJECT_LEAD_LINK} from '../../../../config/constants'
7+
8+
import styles from './styles.module.scss'
9+
10+
class BillingAccountField extends React.Component {
11+
constructor (props) {
12+
super(props)
13+
14+
this.state = {
15+
billingAccounts: [],
16+
selectedBillingAccount: this.props.billingAccountId
17+
}
18+
19+
this.handleChange = this.handleChange.bind(this)
20+
this.mapOpts = this.mapOpts.bind(this)
21+
}
22+
23+
componentDidMount() {
24+
fetchBillingAccounts(this.props.projectId)
25+
.then(({data: billingAccounts}) => this.setState({billingAccounts}))
26+
.then(() => {
27+
if (this.props.billingAccountId) {
28+
this.setState(state => {
29+
const existentBillingAccount = _.find(state.billingAccounts, {
30+
tcBillingAccountId: this.props.billingAccountId
31+
})
32+
if (!existentBillingAccount) {
33+
const billingAccountObj = {
34+
name: '<Assigned Account>',
35+
tcBillingAccountId: this.props.billingAccountId
36+
}
37+
return {
38+
billingAccounts: [...state.billingAccounts, billingAccountObj],
39+
selectedBillingAccount: this.mapOpts(billingAccountObj)
40+
}
41+
} else {
42+
return {
43+
selectedBillingAccount: this.mapOpts(existentBillingAccount)
44+
}
45+
}
46+
})
47+
}
48+
})
49+
.catch(console.error)
50+
}
51+
52+
handleChange(value) {
53+
this.setState({selectedBillingAccount: value})
54+
this.props.setValue(value.value)
55+
}
56+
57+
mapOpts(opt) {
58+
return {
59+
label: `${opt.name} (${opt.tcBillingAccountId})`,
60+
value: opt.tcBillingAccountId
61+
}
62+
}
63+
64+
render() {
65+
return (
66+
<div className={styles.container}>
67+
<div className={styles.fieldName}>Choose a Billing Account</div>
68+
<Select
69+
placeholder={
70+
this.state.billingAccounts.length > 0
71+
? 'Select billing account'
72+
: 'No Billing Account Available'
73+
}
74+
onChange={this.handleChange}
75+
value={this.state.selectedBillingAccount}
76+
options={this.state.billingAccounts.map(this.mapOpts)}
77+
isDisabled={this.state.billingAccounts.length === 0}
78+
/>
79+
<a
80+
className={styles.manageBillingAccountLink}
81+
href={`${SALESFORCE_PROJECT_LEAD_LINK}${this.props.projectId}`}
82+
target="_blank"
83+
rel="noopener noreferrer"
84+
>
85+
Manage the billing account in Salesforce
86+
</a>
87+
</div>
88+
)
89+
}
90+
}
91+
92+
export default hoc(BillingAccountField)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import '~tc-ui/src/styles/tc-includes';
2+
3+
.container {
4+
.fieldName {
5+
margin-bottom: 10px;
6+
}
7+
.manageBillingAccountLink {
8+
display: block;
9+
color: $tc-dark-blue-110;
10+
margin-top: 10px;
11+
&:hover {
12+
color: inherit;
13+
}
14+
}
15+
}

src/projects/detail/components/EditProjectDefaultsForm/EditProjectDefaultsForm.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const Formsy = FormsyForm.Formsy
66
import { updateProject } from '../../../actions/project'
77
import NDAField from '../NDAField'
88
import GroupsField from '../GroupsField'
9+
import BillingAccountField from '../BillingAccountField'
910

1011
import './EditProjectDefaultsForm.scss'
1112

@@ -40,7 +41,7 @@ class EditProjectDefaultsForm extends React.Component {
4041
}, {})
4142
const project = _.assign({}, this.state.project, reqProjectState)
4243
this.setState({project})
43-
const isProjectEqual = _.isEqual(this.state.project, this.props.project)
44+
const isProjectEqual = _.isEqual(project, this.props.project)
4445
if (!isProjectEqual && !this.state.enableButton) {
4546
this.setState({enableButton: true})
4647
} else if (isProjectEqual && this.state.enableButton !== false) {
@@ -80,6 +81,11 @@ class EditProjectDefaultsForm extends React.Component {
8081
name="groups"
8182
value={this.state.project.groups}
8283
/>
84+
<BillingAccountField
85+
name="billingAccountId"
86+
projectId={this.state.project.id}
87+
billingAccountId={this.state.project.billingAccountId}
88+
/>
8389
</div>
8490
<div className="section-footer section-footer-spec">
8591
<button
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.container {
2-
margin: 10px 0;
2+
margin: 10px 0 20px 0;
3+
.fieldName {
4+
margin-bottom: 10px;
5+
}
36
}
4-
.fieldName {
5-
margin-bottom: 10px;
6-
}

0 commit comments

Comments
 (0)