Skip to content

Commit b9e3001

Browse files
final fixes for challenge 30119190-links as attachments
1 parent dfe536c commit b9e3001

File tree

7 files changed

+72
-50
lines changed

7 files changed

+72
-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: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,27 @@ import PropTypes from 'prop-types'
88
*/
99
export const TagSelect = ({ selectedTags, onUpdate, useFormsySelect, name }) => {
1010
const noOptionsMessage = evt => {
11-
if (evt.inputValue === '') {
11+
const inputValue = evt.inputValue && evt.inputValue.trim()
12+
if (inputValue === '') {
1213
return 'Start typing to create a new tag'
13-
} else if (selectedTags && selectedTags.includes(evt.inputValue)) {
14+
} else if (selectedTags && selectedTags.includes(inputValue)) {
1415
return 'Tag already selected'
1516
}
1617
}
1718

19+
const isValidNewOption = inputValue => {
20+
return inputValue && !!inputValue.trim()
21+
}
22+
23+
const getNewOptionData = (inputValue, label) => {
24+
return {
25+
label,
26+
value: inputValue.trim()
27+
}
28+
}
29+
1830
return (
19-
<div>
31+
<div className="has-react-select">
2032
{
2133
useFormsySelect ?
2234
<FormsySelect
@@ -28,6 +40,8 @@ export const TagSelect = ({ selectedTags, onUpdate, useFormsySelect, name }) =>
2840
showDropdownIndicator={false}
2941
placeholder="Add tags"
3042
noOptionsMessage={noOptionsMessage}
43+
isValidNewOption={isValidNewOption}
44+
getNewOptionData={getNewOptionData}
3145
/> :
3246
<ReactSelect
3347
isMulti
@@ -39,6 +53,8 @@ export const TagSelect = ({ selectedTags, onUpdate, useFormsySelect, name }) =>
3953
value={(selectedTags || []).map(t => ({ value: t, label: t }))}
4054
onChange={tags => onUpdate(tags.map(t => t.value))}
4155
noOptionsMessage={noOptionsMessage}
56+
isValidNewOption={isValidNewOption}
57+
getNewOptionData={getNewOptionData}
4258
/>
4359
}
4460

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)

src/projects/detail/containers/AssetsInfoContainer.jsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import {
2626
PROJECT_ASSETS_SHARED_WITH_ALL_MEMBERS,
2727
PROJECT_ASSETS_SHARED_WITH_ADMIN,
2828
EVENT_TYPE,
29+
ATTACHMENT_TYPE_LINK,
30+
ATTACHMENT_TYPE_FILE,
2931
} from '../../../config/constants'
3032
import AddLink from '../../../components/AssetsLibrary/AddLink'
3133
import PERMISSIONS from '../../../config/permissions'
@@ -58,9 +60,8 @@ class AssetsInfoContainer extends React.Component {
5860
}
5961
}
6062
this.onAddNewLink = this.onAddNewLink.bind(this)
61-
this.onDeleteLink = this.onDeleteLink.bind(this)
6263
this.onEditLink = this.onEditLink.bind(this)
63-
this.onEditAttachment = this.onEditAttachment.bind(this)
64+
this.onEditFileAttachment = this.onEditFileAttachment.bind(this)
6465
this.onAddFile = this.onAddFile.bind(this)
6566
this.onUploadAttachment = this.onUploadAttachment.bind(this)
6667
this.removeAttachment = this.removeAttachment.bind(this)
@@ -192,16 +193,11 @@ class AssetsInfoContainer extends React.Component {
192193
addProjectAttachment(project.id, {
193194
title: link.title,
194195
tags: link.tags,
195-
type: 'link',
196+
type: ATTACHMENT_TYPE_LINK,
196197
path: link.address
197198
})
198199
}
199200

200-
onDeleteLink(id) {
201-
const { project, removeProjectAttachment } = this.props
202-
removeProjectAttachment(project.id, id)
203-
}
204-
205201
onEditLink(id, title, address, tags) {
206202
const { project, updateProjectAttachment } = this.props
207203

@@ -212,7 +208,7 @@ class AssetsInfoContainer extends React.Component {
212208
})
213209
}
214210

215-
onEditAttachment(originalAttachment, title, allowedUsers, tags) {
211+
onEditFileAttachment(originalAttachment, title, allowedUsers, tags) {
216212
const { project, updateProjectAttachment, phases, updateProductAttachment } = this.props
217213
const updatedAttachment = {
218214
title,
@@ -501,7 +497,7 @@ class AssetsInfoContainer extends React.Component {
501497
const { project, isSuperUser, phases, feeds,
502498
isManageUser, phasesTopics, canAccessPrivatePosts } = this.props
503499

504-
let attachments = _.filter(project.attachments, a => a.type === 'file')
500+
let attachments = _.filter(project.attachments, a => a.type === ATTACHMENT_TYPE_FILE)
505501
// merges the product attachments to show in the links menu
506502
if (phases && phases.length > 0) {
507503
phases.forEach(phase => {
@@ -555,7 +551,7 @@ class AssetsInfoContainer extends React.Component {
555551
const privateTopicLinks = topicLinks.filter(link => link.tag === PROJECT_FEED_TYPE_MESSAGES)
556552
const phaseLinks = this.extractLinksFromPosts(phaseFeeds)
557553

558-
let links = _.filter(project.attachments, a => a.type === 'link')
554+
let links = _.filter(project.attachments, a => a.type === ATTACHMENT_TYPE_LINK)
559555
links = links.concat(publicTopicLinks)
560556
if (canAccessPrivatePosts) {
561557
links = links.concat(privateTopicLinks)
@@ -763,7 +759,7 @@ class AssetsInfoContainer extends React.Component {
763759
category,
764760
size: f.size,
765761
path: f.key,
766-
type: 'file',
762+
type: ATTACHMENT_TYPE_FILE,
767763
contentType: f.mimetype || 'application/unknown'
768764
}
769765
attachments.push(attachment)
@@ -862,7 +858,7 @@ class AssetsInfoContainer extends React.Component {
862858
links={attachments}
863859
title="Files"
864860
onDelete={this.removeAttachment}
865-
onEdit={this.onEditAttachment}
861+
onEdit={this.onEditFileAttachment}
866862
onAddAttachment={addProjectAttachment}
867863
onUploadAttachment={this.onUploadAttachment}
868864
isSharingAttachment={isSharingAttachment}
@@ -898,7 +894,7 @@ class AssetsInfoContainer extends React.Component {
898894
assetsMembers={assetsMembers}
899895
canDelete={canManageLinks}
900896
canEdit={canManageLinks}
901-
onDelete={this.onDeleteLink}
897+
onDelete={this.removeAttachment}
902898
onEdit={this.onEditLink}
903899
formatModifyDate={formatModifyDate}
904900
formatFolderTitle={formatFolderTitle}

0 commit comments

Comments
 (0)