Skip to content

Commit ce1bbf1

Browse files
authored
Merge pull request #2882 from appirio-tech/dev
Production release 2.4.10
2 parents 98fc4ea + c6a21a9 commit ce1bbf1

File tree

72 files changed

+10921
-8898
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+10921
-8898
lines changed

package-lock.json

+8,920-7,845
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@
7979
"webpack-merge": "^4.1.1"
8080
},
8181
"dependencies": {
82-
"appirio-tech-react-components": "git+https://github.com/appirio-tech/react-components.git#feature/filestack-v3",
82+
"appirio-tech-react-components": "git+https://github.com/appirio-tech/react-components.git#feature/connectv2",
8383
"axios": "^0.13.1",
84+
"brace": "^0.11.1",
8485
"classnames": "^2.2.3",
8586
"coffeescript": "^1.12.7",
8687
"draft-js": "^0.10.1",
@@ -100,6 +101,8 @@
100101
"history": "^1.17.0",
101102
"html5-uploader": "^0.1.1",
102103
"js-cookie": "^2.1.4",
104+
"jsoneditor": "^5.28.2",
105+
"jsoneditor-react": "^1.0.0",
103106
"linkify-it": "^2.0.3",
104107
"lodash": "^4.16.4",
105108
"mobile-detect": "^1.4.2",
@@ -119,7 +122,6 @@
119122
"react-dotdotdot": "^1.0.4",
120123
"react-gateway": "^3.0.0",
121124
"react-infinite-scroller": "^1.1.1",
122-
"react-json-view": "^1.19.1",
123125
"react-layout-pane": "^0.1.16",
124126
"react-modal": "^1.9.7",
125127
"react-redux": "^4.4.5",
@@ -128,7 +130,7 @@
128130
"react-s-alert": "^1.1.4",
129131
"react-scroll": "^1.7.6",
130132
"react-scroll-lock-component": "^1.1.2",
131-
"react-select": "^0.9.1",
133+
"react-select": "^2.4.0",
132134
"react-stickynode": "^1.2.1",
133135
"react-text-truncate": "^0.8.3",
134136
"react-transition-group": "^2.5.0",

src/api/projectMemberInvites.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ export function updateProjectMemberInvite(projectId, member) {
2323
*/
2424
export function createProjectMemberInvite(projectId, member) {
2525
const url = `${PROJECTS_API_URL}/v4/projects/${projectId}/members/invite/`
26-
return axios.post(url, { param: member})
26+
return axios({
27+
method: 'post',
28+
url,
29+
data: {
30+
param: member
31+
},
32+
validateStatus (status) {
33+
return (status >= 200 && status < 300) || status === 403
34+
},
35+
})
2736
.then(resp => {
2837
return resp.data.result.content
2938
})

src/api/projects.js

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function getProjectById(projectId) {
5656
_.forEach(res.attachments, a => {
5757
a.downloadUrl = `/projects/${projectId}/attachments/${a.id}`
5858
})
59+
if (!res.invites) res.invites = []
5960
return res
6061
})
6162
}

src/api/users.js

+35-30
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import _ from 'lodash'
22
import { axiosInstance as axios } from './requestInterceptor'
33
import { TC_API_URL, RESET_PASSWORD_URL } from '../config/constants'
4+
import querystring from 'querystring'
45

56
/**
67
* Get a user based on it's handle/username
7-
*
8+
*
89
* @param {String} handle user handle
9-
*
10+
*
1011
* @returns {Promise<Object>} user profile data
1112
*/
1213
export function getUserProfile(handle) {
@@ -18,15 +19,19 @@ export function getUserProfile(handle) {
1819

1920
/**
2021
* Update user profile
21-
*
22+
*
2223
* @param {String} handle user handle
2324
* @param {Object} updatedProfile updated user data
24-
*
25+
* @param {Object} [queryParams] optional query params
26+
*
2527
* @returns {Promise<Object>} user profile data
2628
*/
27-
export function updateUserProfile(handle, updatedProfile) {
28-
return axios.put(`${TC_API_URL}/v3/members/${handle}/`, {
29-
param: updatedProfile
29+
export function updateUserProfile(handle, updatedProfile, queryParams = {}) {
30+
let query = querystring.stringify(queryParams)
31+
query = query ? `?${query}` : ''
32+
33+
return axios.put(`${TC_API_URL}/v3/members/${handle}/${query}`, {
34+
param: updatedProfile
3035
})
3136
.then(resp => {
3237
return _.get(resp.data, 'result.content', {})
@@ -35,9 +40,9 @@ export function updateUserProfile(handle, updatedProfile) {
3540

3641
/**
3742
* Get member traits
38-
*
43+
*
3944
* @param {String} handle member handle
40-
*
45+
*
4146
* @returns {Promise<Array>} member traits
4247
*/
4348
export const getMemberTraits = (handle) => {
@@ -47,10 +52,10 @@ export const getMemberTraits = (handle) => {
4752

4853
/**
4954
* Update member traits
50-
*
55+
*
5156
* @param {String} handle member handle
5257
* @param {Array} updatedTraits list of updated traits
53-
*
58+
*
5459
* @returns {Promise<Array>} member traits
5560
*/
5661
export const updateMemberTraits = (handle, updatedTraits) => {
@@ -62,10 +67,10 @@ export const updateMemberTraits = (handle, updatedTraits) => {
6267

6368
/**
6469
* Create member traits
65-
*
70+
*
6671
* @param {String} handle member handle
6772
* @param {Array} traits list of traits to create
68-
*
73+
*
6974
* @returns {Promise<Array>} member traits
7075
*/
7176
export const createMemberTraits = (handle, traits) => {
@@ -77,12 +82,12 @@ export const createMemberTraits = (handle, traits) => {
7782

7883
/**
7984
* Update member photo
80-
*
85+
*
8186
* @param {String} handle member handle
8287
* @param {Object} data params to update photo
8388
* @param {String} data.contentType photo file content type
8489
* @param {String} data.token token provided by pre signed URL
85-
*
90+
*
8691
* @returns {Promise<String>} photo URL
8792
*/
8893
export const updateMemberPhoto = (handle, data) => {
@@ -94,26 +99,26 @@ export const updateMemberPhoto = (handle, data) => {
9499

95100
/**
96101
* Get pre-signed URL for member photo
97-
*
102+
*
98103
* @param {String} handle member handle
99104
* @param {File} file file to upload
100-
*
101-
* @returns {Promise<Object>} data of pre-signed URL
105+
*
106+
* @returns {Promise<Object>} data of pre-signed URL
102107
*/
103108
export const getPreSignedUrl = (handle, file) => {
104-
return axios.post(`${TC_API_URL}/v3/members/${handle}/photoUploadUrl`, {
105-
param: {
106-
contentType: file.type
107-
}
109+
return axios.post(`${TC_API_URL}/v3/members/${handle}/photoUploadUrl`, {
110+
param: {
111+
contentType: file.type
112+
}
108113
})
109114
.then(resp => _.get(resp.data, 'result.content', {}))
110115
}
111116

112117
/**
113118
* Check if email is available to be used for a user
114-
*
119+
*
115120
* @param {String} email email to validate
116-
*
121+
*
117122
* @returns {Promise<Object>} response body
118123
*/
119124
export const checkEmailValidity = (email) => {
@@ -123,24 +128,24 @@ export const checkEmailValidity = (email) => {
123128

124129
/**
125130
* Update user password
126-
*
131+
*
127132
* @param {Number} userId user id
128133
* @param {Object} credential user credentials old and new one
129-
*
134+
*
130135
* @returns {Promise<Object>} response body
131136
*/
132137
export const updatePassword = (userId, credential) => {
133-
return axios.patch(`${TC_API_URL}/v3/users/${userId}`, {
134-
param: { credential }
138+
return axios.patch(`${TC_API_URL}/v3/users/${userId}`, {
139+
param: { credential }
135140
})
136141
.then(resp => _.get(resp.data, 'result.content', {}))
137142
}
138143

139144
/**
140145
* Send reset password email to the user
141-
*
146+
*
142147
* @param {String} email user email
143-
*
148+
*
144149
* @returns {Promise<Object>} response body
145150
*/
146151
export const resetPassword = (email) => {

src/components/ActionCard/AddComment.jsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default class AddComment extends React.Component {
2525
}
2626

2727
render() {
28-
const { className, avatarUrl, authorName, placeholder, isAdding, hasError, allMembers } = this.props
28+
const { className, avatarUrl, authorName, placeholder, isAdding, hasError, allMembers, projectMembers } = this.props
2929

3030
return (
3131
<RichTextArea ref="richTextArea"
@@ -39,6 +39,7 @@ export default class AddComment extends React.Component {
3939
avatarUrl={avatarUrl}
4040
authorName={authorName}
4141
allMembers={allMembers}
42+
projectMembers={projectMembers}
4243
/>
4344
)
4445
}
@@ -54,5 +55,6 @@ AddComment.propTypes = {
5455
placeholder: PropTypes.string,
5556
hasError: PropTypes.bool,
5657
isAdding: PropTypes.bool,
57-
allMembers: PropTypes.object
58+
allMembers: PropTypes.object,
59+
projectMembers: PropTypes.object
5860
}

src/components/ActionCard/Comment.jsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Comment extends React.Component {
5858
}
5959

6060
render() {
61-
const {message, author, date, edited, children, noInfo, self, isSaving, hasError, readonly, allMembers, canDelete} = this.props
61+
const {message, author, date, edited, children, noInfo, self, isSaving, hasError, readonly, allMembers, canDelete, projectMembers} = this.props
6262
const messageAnchor = `comment-${message.id}`
6363
const messageLink = window.location.pathname.substr(0, window.location.pathname.indexOf('#')) + `#${messageAnchor}`
6464
const authorName = author ? (author.firstName + ' ' + author.lastName) : 'Connect user'
@@ -84,6 +84,7 @@ class Comment extends React.Component {
8484
authorName={authorName}
8585
cancelEdit={this.cancelEdit}
8686
allMembers={allMembers}
87+
projectMembers={projectMembers}
8788
editingTopic = {false}
8889
/>
8990
</div>
@@ -194,7 +195,7 @@ Comment.propTypes = {
194195
*/
195196
readonly: PropTypes.bool,
196197
allMembers: PropTypes.object.isRequired,
197-
198+
projectMembers: PropTypes.object,
198199
/**
199200
* If true only comment text is shown without additional info
200201
*/

src/components/Feed/Feed.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class Feed extends React.Component {
8686
id, user, currentUser, topicMessage, totalComments, hasMoreComments, onLoadMoreComments, isLoadingComments,
8787
allowComments, comments, children, onNewCommentChange, onAddNewComment, isAddingComment, onSaveMessageChange,
8888
onEditMessage, onSaveMessage, isSavingTopic, onDeleteMessage, onDeleteTopic, isDeletingTopic, error, allMembers,
89-
onEnterFullscreenClick, onExitFullscreenClick, isFullScreen, commentId
89+
onEnterFullscreenClick, onExitFullscreenClick, isFullScreen, commentId, projectMembers
9090
} = this.props
9191
const { editTopicMode, headerHeight } = this.state
9292
let authorName = user ? user.firstName : 'Unknown'
@@ -177,6 +177,7 @@ class Feed extends React.Component {
177177
onSaveMessage={onSaveMessage}
178178
onDeleteMessage={onDeleteMessage}
179179
allMembers={allMembers}
180+
projectMembers={projectMembers}
180181
isFullScreen={isFullScreen}
181182
headerHeight={headerHeight}
182183
commentId={commentId}

src/components/Feed/FeedComments.jsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class FeedComments extends React.Component {
179179
const {
180180
comments, currentUser, onLoadMoreComments, isLoadingComments, hasMoreComments, onAddNewComment,
181181
onNewCommentChange, error, avatarUrl, isAddingComment, allowComments, onSaveMessage, onDeleteMessage, allMembers,
182-
totalComments, isFullScreen, headerHeight
182+
totalComments, isFullScreen, headerHeight, projectMembers
183183
} = this.props
184184
const { isNewCommentMobileOpen, stickyRowNext, stickyRowPrev } = this.state
185185
let authorName = currentUser.firstName
@@ -319,6 +319,7 @@ class FeedComments extends React.Component {
319319
isSaving={item.isSavingComment}
320320
hasError={item.error}
321321
allMembers={allMembers}
322+
projectMembers={projectMembers}
322323
noInfo={item.noInfo}
323324
canDelete={idx !== 0}
324325
>
@@ -389,6 +390,7 @@ class FeedComments extends React.Component {
389390
isAdding={isAddingComment}
390391
hasError={error}
391392
allMembers={allMembers}
393+
projectMembers={projectMembers}
392394
/>
393395
</div>
394396
}

src/components/Feed/NewPost.jsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class NewPost extends React.Component {
1313
}
1414

1515
render() {
16-
const {currentUser, allMembers, titlePlaceholder, contentPlaceholder, isCreating, hasError, expandedTitlePlaceholder} = this.props
16+
const {currentUser, allMembers, titlePlaceholder, contentPlaceholder, isCreating, hasError, expandedTitlePlaceholder, projectMembers} = this.props
1717
let authorName = currentUser.firstName
1818
if (authorName && currentUser.lastName) {
1919
authorName += ' ' + currentUser.lastName
@@ -38,6 +38,7 @@ class NewPost extends React.Component {
3838
avatarUrl={currentUser.photoURL}
3939
authorName={authorName}
4040
allMembers={allMembers}
41+
projectMembers={projectMembers}
4142
/>
4243
)
4344
}
@@ -48,6 +49,7 @@ NewPost.propTypes = {
4849
expandedTitlePlaceholder: PropTypes.string,
4950
currentUser: PropTypes.object.isRequired,
5051
allMembers: PropTypes.object.isRequired,
52+
projectMembers: PropTypes.object,
5153
onPost: PropTypes.func.isRequired,
5254
onNewPostChange: PropTypes.func.isRequired,
5355
hasError: PropTypes.bool,

src/components/FileList/AddFilePermissions.jsx

+15-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import Modal from 'react-modal'
44
import { mapKeys, get } from 'lodash'
55

66
import UserAutoComplete from '../UserAutoComplete/UserAutoComplete'
7+
import LoadingIndicator from '../LoadingIndicator/LoadingIndicator'
78

89
import './AddFilePermissions.scss'
910
import XMarkIcon from '../../assets/icons/icon-x-mark.svg'
1011

11-
const AddFilePermission = ({ onCancel, onSubmit, onChange, selectedUsers, projectMembers, loggedInUser }) => {
12+
const AddFilePermission = ({ onCancel, onSubmit, onChange, selectedUsers, projectMembers, loggedInUser, isSharingAttachment }) => {
1213
selectedUsers = selectedUsers || ''
1314
const mapHandlesToUserIds = handles => {
1415
const projectMembersByHandle = mapKeys(projectMembers, value => value.handle)
@@ -28,10 +29,18 @@ const AddFilePermission = ({ onCancel, onSubmit, onChange, selectedUsers, projec
2829
<span onClick={onCancel}><XMarkIcon /></span>
2930
</div>
3031

32+
<div styleName="loading-indicator-wrapper">
33+
{ isSharingAttachment && <LoadingIndicator isSmall /> }
34+
</div>
35+
3136
{/* Share with all members */}
3237
<div className="dialog-body">
3338
<div styleName="btn-all-members">
34-
<button className="tc-btn tc-btn-primary tc-btn-md" onClick={() => onSubmit(null)}>All project members</button>
39+
<button
40+
className="tc-btn tc-btn-primary tc-btn-md"
41+
onClick={() => onSubmit(null)}
42+
disabled={isSharingAttachment}
43+
>All project members</button>
3544
</div>
3645
</div>
3746

@@ -41,10 +50,10 @@ const AddFilePermission = ({ onCancel, onSubmit, onChange, selectedUsers, projec
4150

4251
<UserAutoComplete projectMembers={projectMembers} selectedUsers={selectedUsers} onUpdate={onChange} loggedInUser={loggedInUser} />
4352

44-
<div>
53+
<div styleName="btn-selected-members">
4554
<button className="tc-btn tc-btn-primary tc-btn-md"
4655
onClick={() => onSubmit(mapHandlesToUserIds(selectedUsers.split(',')))}
47-
disabled={!selectedUsers || selectedUsers.length === 0 }
56+
disabled={!selectedUsers || selectedUsers.length === 0 || isSharingAttachment }
4857
>Share with selected members</button>
4958
</div>
5059
</div>
@@ -59,7 +68,8 @@ AddFilePermission.propTypes = {
5968
onChange: PropTypes.func.isRequired,
6069
selectedUsers: PropTypes.string,
6170
projectMembers: PropTypes.object,
62-
loggedInUser: PropTypes.object.isRequired
71+
loggedInUser: PropTypes.object.isRequired,
72+
isSharingAttachment: PropTypes.bool.isRequired,
6373
}
6474

6575
export default AddFilePermission

0 commit comments

Comments
 (0)