Skip to content

Commit 3964b3d

Browse files
authored
Merge pull request #2740 from appirio-tech/hotfix/horizontal-layout-for-questions
[Hotfix] [PROD] - horizontal layout for questions
2 parents 8ccc88b + 4e79794 commit 3964b3d

File tree

6 files changed

+151
-18
lines changed

6 files changed

+151
-18
lines changed

src/projects/detail/components/FileListContainer.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class FileListContainer extends Component {
4242
canManageAttachments,
4343
removeAttachment,
4444
updateAttachment,
45+
additionalClass,
4546
} = this.props
4647

4748
files.forEach(file => {
@@ -55,7 +56,7 @@ class FileListContainer extends Component {
5556
})
5657

5758
return (
58-
<div>
59+
<div className={additionalClass}>
5960
<FileList files={files} onDelete={removeAttachment} onSave={updateAttachment} canModify={canManageAttachments}/>
6061
<AddFiles successHandler={this.processUploadedFiles} storePath={attachmentsStorePath} category={category} />
6162
</div>
@@ -77,6 +78,11 @@ FileListContainer.propTypes = {
7778
addAttachment: PropTypes.func.isRequired,
7879
updateAttachment: PropTypes.func.isRequired,
7980
removeAttachment: PropTypes.func.isRequired,
81+
additionalClass: PropTypes.string
82+
}
83+
84+
FileListContainer.defaultProps = {
85+
additionalClass: '',
8086
}
8187

8288
export default connect(mapStateToProps, mapDispatchToProps)(FileListContainer)

src/projects/detail/components/SpecQuestionList/SpecQuestionList.jsx

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,66 @@
11
import React from 'react'
22
import PropTypes from 'prop-types'
33
import cn from 'classnames'
4+
import _ from 'lodash'
45
require('./SpecQuestionList.scss')
56

6-
const SpecQuestionList = ({ children }) => {
7+
const SpecQuestionList = ({ children, layout, additionalClass }) => {
8+
const directionClass = _.get(layout, 'direction', '')
9+
710
return (
8-
<div className="spec-question-list">
11+
<div className={'spec-question-list ' + directionClass + ' ' + additionalClass}>
912
{ children }
1013
</div>
1114
)
1215
}
1316

1417
SpecQuestionList.propTypes = {
15-
children: PropTypes.any.isRequired
18+
children: PropTypes.any.isRequired,
19+
/**
20+
* Layout of questions
21+
*/
22+
layout: PropTypes.object,
23+
24+
/**
25+
* additional class
26+
*/
27+
additionalClass: PropTypes.string
28+
}
29+
30+
SpecQuestionList.defaultProps = {
31+
additionalClass: ''
1632
}
1733

18-
const SpecQuestionListItem = ({icon, title, description, children, required, hideDescription}) => (
19-
<div className="spec-question-list-item">
34+
const SpecQuestionListItem = ({icon, title, type, additionalClass, description, children, required, hideDescription}) => {
35+
let shouldShowTitle = true
36+
let shouldShowRequire = false
37+
if (additionalClass.includes('spacing-gray-input') && (type === 'textinput')) {
38+
shouldShowTitle = false
39+
shouldShowRequire = true
40+
}
41+
return (<div className={'spec-question-list-item ' + additionalClass }>
2042
{icon && <div className="icon-col">{icon}</div>}
2143
<div className="content-col">
22-
<h5>{title}{required ? <span>*</span> : null}</h5>
44+
{shouldShowTitle && (<h5>{title}{required ? <span>*</span> : null}</h5>)}
2345
{children && <div className="child-component">{children}</div>}
2446
{!hideDescription && <p className={cn({bigger: !icon})}>{description}</p>}
47+
{shouldShowRequire &&
48+
<div className="require-desc">{required ? 'Required' : 'Optional'}</div>}
2549
</div>
26-
</div>
27-
)
50+
</div>)
51+
}
2852

2953
SpecQuestionListItem.propTypes = {
3054
icon: PropTypes.any,
3155
title: PropTypes.any.isRequired,
3256
description: PropTypes.any,
33-
children: PropTypes.any
57+
children: PropTypes.any,
58+
type: PropTypes.string,
59+
additionalClass: PropTypes.string
60+
}
61+
62+
SpecQuestionListItem.defaultProps = {
63+
additionalClass: '',
3464
}
3565

3666
SpecQuestionList.Item = SpecQuestionListItem

src/projects/detail/components/SpecQuestionList/SpecQuestionList.scss

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
:global {
44
.spec-question-list {
5+
&.horizontal {
6+
display: flex;
7+
flex-direction: row;
8+
}
9+
&.horizontal.codes .spec-question-list-item {
10+
margin-right: 10px;
11+
}
512
}
613

714
.spec-question-list-item {
@@ -12,6 +19,56 @@
1219
margin-top: 9 * $base-unit;
1320
}
1421

22+
.require-desc {
23+
@include roboto;
24+
font-size: 12px;
25+
line-height: 20px;
26+
color: #808080;
27+
font-style: italic;
28+
}
29+
30+
.spacing-gray-input {
31+
width: 100px;
32+
33+
input {
34+
background-color: #fafafb;
35+
border: none;
36+
border-bottom: 1px solid #959596;
37+
color: #404041;
38+
margin: 0;
39+
40+
@include placeholder {
41+
@include roboto;
42+
color: $tc-gray-30;
43+
text-transform: none;
44+
font-style: italic;
45+
font-size: $base-unit*3;
46+
line-height: $base-unit*4;
47+
}
48+
&:focus {
49+
background: $tc-dark-blue-10 !important;
50+
border: none;
51+
border-bottom: 1px solid $tc-dark-blue-70;
52+
box-shadow: none;
53+
color: $tc-gray-80;
54+
}
55+
&:hover {
56+
border: none;
57+
border-bottom: 1px solid $tc-dark-blue-70;
58+
box-shadow: none;
59+
}
60+
&:disabled {
61+
background: $tc-gray-neutral-light;
62+
border-bottom: 1px solid $tc-gray-40;
63+
color: $tc-gray-30;
64+
}
65+
&.error{
66+
border: 1px solid $tc-red-70!important;
67+
background: $tc-gray-neutral-light!important;
68+
}
69+
}
70+
}
71+
1572
.icon-col {
1673
padding-top: 3px;
1774
padding-right: 10px;

src/projects/detail/components/SpecQuestions.jsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const getIcon = icon => {
3030
}
3131

3232
// { isRequired, represents the overall questions section's compulsion, is also available}
33-
const SpecQuestions = ({questions, project, dirtyProject, resetFeatures, showFeaturesDialog, showHidden }) => {
33+
const SpecQuestions = ({questions, layout, additionalClass, project, dirtyProject, resetFeatures, showFeaturesDialog, showHidden }) => {
3434

3535
const renderQ = (q, index) => {
3636
// let child = null
@@ -71,6 +71,9 @@ const SpecQuestions = ({questions, project, dirtyProject, resetFeatures, showFea
7171
})
7272
}
7373

74+
let additionalItemClass = ''
75+
const spacing = _.get(q, 'spacing', '')
76+
7477
let ChildElem = ''
7578
switch (q.type) {
7679
case 'see-attached-textbox':
@@ -83,7 +86,11 @@ const SpecQuestions = ({questions, project, dirtyProject, resetFeatures, showFea
8386
break
8487
case 'textinput':
8588
ChildElem = TCFormFields.TextInput
86-
elemProps.wrapperClass = 'row'
89+
elemProps.wrapperClass = 'row ' + spacing
90+
if (spacing.includes('spacing-gray-input')) {
91+
elemProps.placeholder = q.title
92+
}
93+
additionalItemClass = spacing
8794
// child = <TCFormFields.TextInput name={q.fieldName} label={q.label} value={value} wrapperClass="row" />
8895
break
8996
case 'numberinput':
@@ -167,8 +174,10 @@ const SpecQuestions = ({questions, project, dirtyProject, resetFeatures, showFea
167174
}
168175
return (
169176
<SpecQuestionList.Item
177+
additionalClass = {additionalItemClass}
170178
key={index}
171179
title={q.title}
180+
type={q.type}
172181
icon={getIcon(q.icon)}
173182
description={q.description}
174183
required={q.required || (q.validations && q.validations.indexOf('isRequired') !== -1)}
@@ -180,7 +189,7 @@ const SpecQuestions = ({questions, project, dirtyProject, resetFeatures, showFea
180189
}
181190

182191
return (
183-
<SpecQuestionList>
192+
<SpecQuestionList layout={layout} additionalClass={additionalClass}>
184193
{questions.filter((question) => showHidden || !question.hidden).map(renderQ)}
185194
</SpecQuestionList>
186195
)
@@ -212,6 +221,19 @@ SpecQuestions.propTypes = {
212221
* If true, then `hidden` property of questions will be ignored and hidden questions will be rendered
213222
*/
214223
showHidden: PropTypes.bool,
224+
/**
225+
* Layout of questions
226+
*/
227+
layout: PropTypes.object,
228+
229+
/**
230+
* additional class
231+
*/
232+
additionalClass: PropTypes.string
233+
}
234+
235+
SpecQuestions.defaultProps = {
236+
additionalClass: '',
215237
}
216238

217239
export default SpecQuestions

src/projects/detail/components/SpecScreens.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class SpecScreens extends Component {
5858
const { screens } = this.state
5959
const { appDefinition } = (this.props.dirtyProject || this.props.project).details
6060
const numberScreensSelected = parseInt(_.last(_.get(appDefinition, 'numberScreens', '0').split('-')))
61+
const { additionalClass } = this.props
6162

6263
const renderCurrentScreen = (screen, index) => {
6364
return (
@@ -87,7 +88,7 @@ class SpecScreens extends Component {
8788
}
8889

8990
return (
90-
<div>
91+
<div className={additionalClass}>
9192
{screens.map(renderCurrentScreen)}
9293
{/*renderNewScreen(screens.length + 1)*/}
9394
<div className="edit-screen-footer">
@@ -122,6 +123,11 @@ SpecScreens.propTypes = {
122123
questions: PropTypes.arrayOf(PropTypes.object).isRequired,
123124
project: PropTypes.object.isRequired,
124125
dirtyProject: PropTypes.object.isRequired,
126+
additionalClass: PropTypes.string
127+
}
128+
129+
SpecScreens.defaultProps = {
130+
additionalClass: '',
125131
}
126132

127133
export default hoc(SpecScreens)

src/projects/detail/components/SpecSection.jsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ const SpecSection = props => {
117117

118118
const renderChild = props => {
119119
const {type} = props
120+
121+
let additionalClass = ''
122+
const spacing = _.get(props.layout, 'spacing', '')
123+
124+
if (spacing) {
125+
additionalClass += spacing
126+
}
127+
120128
switch(type) {
121129
case 'tabs': {
122130
const tabs = _.get(props, 'tabs')
@@ -126,17 +134,19 @@ const SpecSection = props => {
126134
</Tab>
127135
)
128136
return (
129-
<Tabs defaultActiveKey={1}>
137+
<Tabs additionalClass={additionalClass} defaultActiveKey={1}>
130138
{tabs.map(renderTab)}
131139
</Tabs>
132140
)
133141
}
134142
case 'questions':
135143
return (
136144
<SpecQuestions
145+
additionalClass={additionalClass}
137146
showFeaturesDialog={showFeaturesDialog}
138147
resetFeatures={resetFeatures}
139148
questions={props.questions}
149+
layout={props.layout}
140150
project={project}
141151
dirtyProject={dirtyProject}
142152
isRequired={props.required}
@@ -145,7 +155,7 @@ const SpecSection = props => {
145155
)
146156
case 'notes':
147157
return (
148-
<div>
158+
<div className={additionalClass}>
149159
<div className="textarea-title">
150160
{props.description}
151161
</div>
@@ -170,6 +180,7 @@ const SpecSection = props => {
170180
category = 'product' === category ? `${category}#${projectLatest.id}` : category
171181
return (
172182
<FileListContainer
183+
additionalClass={additionalClass}
173184
project={projectLatest}
174185
files={files}
175186
category={category}
@@ -185,6 +196,7 @@ const SpecSection = props => {
185196
const screens = _.get(project, props.fieldName, [])
186197
return (
187198
<SpecScreens
199+
additionalClass={additionalClass}
188200
name={props.fieldName}
189201
screens={screens}
190202
questions={props.questions}
@@ -199,7 +211,7 @@ const SpecSection = props => {
199211
const refCode = _.get(project, refCodeFieldName, '')
200212
const queryParamRefCode = qs.parse(window.location.search).refCode
201213
return (
202-
<div className="project-name-section">
214+
<div className={'project-name-section ' + additionalClass}>
203215
<div className="editable-project-name">
204216
<TCFormFields.TextInput
205217
name="name"
@@ -241,7 +253,7 @@ const SpecSection = props => {
241253
const costCentreFieldName = 'details.costCentre'
242254
const costCentre = _.get(project, costCentreFieldName, '')
243255
return (
244-
<div className="project-name-section">
256+
<div className={'project-name-section ' + additionalClass}>
245257
<div className="editable-project-name">
246258
<TCFormFields.TextInput
247259
name="name"

0 commit comments

Comments
 (0)