Skip to content

Commit c4fe775

Browse files
authored
Merge pull request #3811 from vigneshTheDev/feature/link-attachments
final fixes for challenge 30119190-links as attachments
2 parents dfe536c + da6230b commit c4fe775

File tree

7 files changed

+82
-50
lines changed

7 files changed

+82
-50
lines changed

src/api/projectAttachments.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { axiosInstance as axios } from './requestInterceptor'
2-
import { PROJECTS_API_URL, FILE_PICKER_SUBMISSION_CONTAINER_NAME } from '../config/constants'
2+
import { PROJECTS_API_URL, FILE_PICKER_SUBMISSION_CONTAINER_NAME, ATTACHMENT_TYPE_FILE } from '../config/constants'
33

4-
export function addProjectAttachment(projectId, fileData) {
4+
export function addProjectAttachment(projectId, attachment) {
55

6-
if (fileData.type === 'file') {
6+
if (attachment.type === ATTACHMENT_TYPE_FILE) {
77
// add s3 bucket prop
8-
fileData.s3Bucket = FILE_PICKER_SUBMISSION_CONTAINER_NAME
8+
attachment.s3Bucket = FILE_PICKER_SUBMISSION_CONTAINER_NAME
99
}
1010

1111
// The api takes only arrays
12-
if (!fileData.tags) {
13-
fileData.tags = []
12+
if (!attachment.tags) {
13+
attachment.tags = []
1414
}
1515

16-
return axios.post(`${PROJECTS_API_URL}/v5/projects/${projectId}/attachments`, fileData)
16+
return axios.post(`${PROJECTS_API_URL}/v5/projects/${projectId}/attachments`, attachment)
1717
.then( resp => {
1818
resp.data.downloadUrl = `/projects/${projectId}/attachments/${resp.data.id}`
1919
return resp.data

src/components/Modal/Modal.scss

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
border-radius: $corner-radius;
88
position: relative;
99
padding: $base-unit*2 0;
10-
10+
1111
.btn-close {
1212
position: absolute;
1313
display: block;
@@ -16,14 +16,14 @@
1616
top: $base-unit*3;
1717
right: $base-unit*3;
1818
}
19-
19+
2020
.modal-title {
2121
@include roboto-bold;
2222
font-size: $tc-label-lg;
2323
padding: $base-unit*2 $base-unit*4 0 $base-unit*4;
2424
line-height: $base-unit*4;
2525
text-align: center;
26-
26+
2727
&.title-muted {
2828
@include roboto-medium;
2929
color: $tc-gray-50;
@@ -32,18 +32,23 @@
3232
padding-top: $base-unit;
3333
padding-bottom: $base-unit;
3434
}
35-
35+
3636
&.danger {
3737
color: $tc-red;
3838
}
3939
}
40-
40+
4141
.modal-body {
4242
@include roboto;
4343
font-size: $tc-label-md;
4444
line-height: $base-unit * 4;
4545
margin: $base-unit*2 $base-unit*4;
46-
46+
47+
// Fix alignment issue of selected items in react select inside modal
48+
.has-react-select input {
49+
height: auto
50+
}
51+
4752
input {
4853
display: block;
4954
height: 38px;
@@ -55,67 +60,67 @@
5560
@include placeholder {
5661
text-transform: none;
5762
}
58-
63+
5964
&[disabled] {
6065
color: $tc-gray-20;
6166
background: $tc-white;
6267
}
63-
68+
6469
&:hover {
6570
border-color: $tc-gray-40;
6671
background: $tc-gray-neutral-light;
6772
}
68-
73+
6974
&:focus {
7075
background: $tc-white !important;
7176
border-color: $tc-dark-blue !important;
7277
}
73-
78+
7479
&.error {
7580
border-left: 3px solid $tc-red-70 !important;
7681
background: $tc-gray-neutral-light !important;
77-
82+
7883
&:focus {
7984
background: $tc-white !important;
8085
border-color: $tc-dark-blue !important;
8186
}
8287
}
8388
}
84-
89+
8590
.modal-inline-form {
8691
display: flex;
8792
margin-bottom: $base-unit*2;
88-
93+
8994
button {
9095
margin-left: $base-unit;
9196
}
92-
97+
9398
.input-icon-group {
9499
position: relative;
95100
flex-grow: 1;
96101
display: flex;
97102
border: 1px solid $tc-gray-20;
98103
box-shadow: inset 0px 0px 2px 0px rgba($tc-gray-30, 0.2);
99-
104+
100105
input {
101106
flex-grow: 1;
102107
display: inline-block;
103108
border: none;
104109
box-shadow: none;
105110
}
106-
111+
107112
.input-icon {
108113
height: 30px;
109114
margin: 4px;
110-
115+
111116
&:empty {
112117
width: 36px;
113118
background-size: 30px 30px;
114119
background-color: $tc-gray-20;
115120
background-position: center;
116121
border-radius: 34px;
117122
}
118-
123+
119124
img {
120125
width: 30px;
121126
height: 30px;
@@ -124,33 +129,32 @@
124129
}
125130
}
126131
}
127-
132+
128133
.message {
129134
text-align: center;
130135
margin-bottom: $base-unit*4;
131136
color: $tc-black;
132137
}
133-
138+
134139
.button-area {
135140
button:not(:last-child) {
136141
margin-right: 2 * $base-unit;
137142
}
138-
143+
139144
.btn-cancel {
140145
border: 1px solid $tc-dark-blue;
141146
box-shadow: 0px 0px 3px 0px $tc-dark-blue-30;
142147
}
143148
}
144149
}
145-
150+
146151
.form-group {
147152
margin-top: 20px;
148153
margin-bottom: 15px;
149154
}
150-
155+
151156
.center-buttons {
152157
text-align: center;
153158
}
154159
}
155160
}
156-

src/components/TagSelect/TagSelect.jsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,69 @@ import React from 'react'
22
import ReactSelect from '../Select/Select'
33
import FormsySelect from '../Select/FormsySelect'
44
import PropTypes from 'prop-types'
5+
import _ from 'lodash'
56

67
/**
78
* TagSelect renders the tag selection component for attachment options dialog
89
*/
910
export const TagSelect = ({ selectedTags, onUpdate, useFormsySelect, name }) => {
1011
const noOptionsMessage = evt => {
11-
if (evt.inputValue === '') {
12+
const inputValue = evt.inputValue && evt.inputValue.trim()
13+
if (inputValue === '') {
1214
return 'Start typing to create a new tag'
13-
} else if (selectedTags && selectedTags.includes(evt.inputValue)) {
15+
} else if (selectedTags && selectedTags.includes(inputValue)) {
1416
return 'Tag already selected'
1517
}
1618
}
1719

20+
const isValidNewOption = inputValue => {
21+
return inputValue && !!inputValue.trim()
22+
}
23+
24+
const getNewOptionData = (inputValue, label) => {
25+
return {
26+
label,
27+
value: inputValue.trim()
28+
}
29+
}
30+
31+
const onInputChange = (value) => {
32+
// prevent preceding spaces
33+
return _.trimStart(value)
34+
}
35+
1836
return (
19-
<div>
37+
<div className="has-react-select">
2038
{
2139
useFormsySelect ?
2240
<FormsySelect
2341
isMulti
42+
heightAuto
2443
name={name}
2544
setValueOnly
2645
closeMenuOnSelect
2746
createOption
2847
showDropdownIndicator={false}
2948
placeholder="Add tags"
49+
onInputChange={onInputChange}
3050
noOptionsMessage={noOptionsMessage}
51+
isValidNewOption={isValidNewOption}
52+
getNewOptionData={getNewOptionData}
3153
/> :
3254
<ReactSelect
3355
isMulti
56+
heightAuto
3457
name={name}
3558
closeMenuOnSelect
3659
createOption
3760
showDropdownIndicator={false}
3861
placeholder="Add tags"
3962
value={(selectedTags || []).map(t => ({ value: t, label: t }))}
4063
onChange={tags => onUpdate(tags.map(t => t.value))}
64+
onInputChange={onInputChange}
4165
noOptionsMessage={noOptionsMessage}
66+
isValidNewOption={isValidNewOption}
67+
getNewOptionData={getNewOptionData}
4268
/>
4369
}
4470

src/components/UserAutoComplete/UserAutoComplete.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const UserAutoComplete = ({
1717
onUpdate,
1818
loggedInUser
1919
}) => (
20-
<div styleName="user-select-wrapper" className="user-select-wrapper">
20+
<div styleName="user-select-wrapper" className="user-select-wrapper has-react-select">
2121
<Select
2222
isMulti
2323
closeMenuOnSelect

src/config/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,11 @@ export const SCOPE_CHANGE_REQ_STATUS_REJECTED = 'rejected'
560560
export const SCOPE_CHANGE_REQ_STATUS_ACTIVATED = 'activated'
561561
export const SCOPE_CHANGE_REQ_STATUS_CANCELED = 'canceled'
562562

563+
/*
564+
* Project Attachment types
565+
*/
566+
export const ATTACHMENT_TYPE_FILE = 'file'
567+
export const ATTACHMENT_TYPE_LINK = 'link'
563568

564569
export const PHASE_STATUS_DRAFT = 'draft'
565570
export const PHASE_STATUS_IN_REVIEW = 'in_review'

src/projects/detail/components/FileListContainer.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import AddFiles from '../../../components/FileList/AddFiles'
77
import { getProjectRoleForCurrentUser } from '../../../helpers/projectHelper'
88
import { uploadProjectAttachments, discardAttachments, changeAttachmentPermission } from '../../actions/projectAttachment'
99
import AddFilePermission from '../../../components/FileList/AddFilePermissions'
10+
import { ATTACHMENT_TYPE_FILE } from '../../../config/constants'
1011

1112
class FileListContainer extends Component {
1213
constructor(props) {
@@ -25,7 +26,7 @@ class FileListContainer extends Component {
2526
category,
2627
size: f.size,
2728
path: f.key,
28-
type: 'file',
29+
type: ATTACHMENT_TYPE_FILE,
2930
contentType: f.mimetype || 'application/unknown'
3031
}
3132
attachments.push(attachment)

0 commit comments

Comments
 (0)