-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove connections list module #8991
Conversation
[ PUBLICIZE_CONNECTION_CREATE ]: ( state, { ID, siteId } ) => ( { ...state, [ ID ]: { | ||
...state[ ID ], sites: [ ...state[ ID ].sites, siteId.toString() ] | ||
[ PUBLICIZE_CONNECTION_CREATE ]: ( state, { connection: { keyring_connection_ID: ID, site_ID } } ) => ( { ...state, [ ID ]: { | ||
...state[ ID ], sites: [ ...state[ ID ].sites, site_ID.toString() ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is site_ID not always a fixed type?
This is also probably on the edge of readability for a one-liner. 👍 Thanks for the tests through, made what the reducer is doing pretty clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I should test what happens if we mix strings and integers here, not sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think we should be very wary about destructuring more than a single level deep, as it becomes very difficult to read, especially with aliasing. Speaking of, naming should be id
, not ID
, per camelCasing guidelines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is site_ID not always a fixed type?
The /me/keyring-connections
endpoint returns the site IDs as an array of strings. While user_ID
gets treated with an absint()
before being returned, site IDs do not.
Also see #9068 (comment)
onDisconnectionSuccess: function() { | ||
this.setState( { isDisconnecting: false } ); | ||
this.props.connections.off( 'destroy:error', this.onDisconnectionError ); | ||
|
||
notices.success( this.translate( 'The %(service)s account was successfully disconnected.', { | ||
this.props.successNotice( this.props.translate( 'The %(service)s account was successfully disconnected.', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's are appropriate redux action types to associate this with, adding these to notice middleware may make sense: https://github.com/Automattic/wp-calypso/blob/master/client/state/notices/middleware.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll do that when porting update/delete actions over to redux. So far only Create is full redux.
@@ -79,6 +63,7 @@ class SharingServicesGroup extends Component { | |||
|
|||
export default connect( | |||
( state, { type } ) => ( { | |||
initialized: !! getSelectedSiteId( state ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this relate to services being initialized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no site is selected, connecting services is moot. We can probably remove that, I assume it's from a time when we couldn't rely on having a selected site available?
var connectionsList = require( 'lib/connections-list' )(), | ||
sites = require( 'lib/sites-list' )(); | ||
import connectionsList from 'lib/connections-list'; | ||
import sites from 'lib/sites-list'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we perhaps either connect this or update the functions to take in a site object instead of a siteId?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we connect modules that are not react components?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can create a component that renders nothing like we do for QueryComponents or if it doesn't make sense we can update the interfaces to pass in a site.
0be2ea2
to
c7b2545
Compare
|
||
componentWillReceiveProps: function( nextProps ) { | ||
this.onClose = this.onClose.bind( this ); | ||
this.onSelectedAccountChanged = this.onSelectedAccountChanged.bind( this ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional, but we can also do in the function def:
onSelectedAccountChanged = () => {
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably should have been many separate pull requests. My attentiveness wanes after the 20th file 😄
} ); | ||
} | ||
|
||
export default AccountDialogAccount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: You could include the default export on the same line as the class declaration itself:
export default class AccountDialogAccount extends Component {
Or is there a preference toward exporting bottom-of-file?
{ action: 'connect', label: this.translate( 'Connect' ), isPrimary: true } | ||
]; | ||
if ( this.isSelectedAccountConflicting() ) { | ||
this.props.warningNotice( this.props.translate( 'The connection marked {{icon/}} will be replaced with your selection.', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I correct in understanding that this will change the conflict notice from being inline to being a global notice? Does that work well with the dialog being shown? Perhaps also worth a design review.
Ref: 3513-gh-calypso-pre-oss
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, does including this in render
run the risk of many notices being shown if renders occur unexpectedly?
const classes = classNames( 'account-dialog', { | ||
'single-account': 1 === this.props.accounts.length | ||
} ), | ||
buttons = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be more readable if this were a separate const
declaration, not comma-separated, especially since both of these variables are multi-line. What do you think?
]; | ||
if ( this.isSelectedAccountConflicting() ) { | ||
this.props.warningNotice( this.props.translate( 'The connection marked {{icon/}} will be replaced with your selection.', { | ||
components: { icon: <span className="noticon noticon-warning" /> }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it'd be considered in-scope, but noticons are deprecated in favor of <Gridicon />
and should ideally be updated.
isSavingSitewide: false | ||
}; | ||
|
||
this.toggleSitewideConnection = this.toggleSitewideConnection.bind( this ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel particularly strongly either way, but curious how you feel about class instance property initializers to simplify binding at the time of declaring the function?
toggleSitewideConnection = ( event ) => {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gwwar had mentioned that to me as well. I like it, especially since it lets us avoid having to write out the constructor.
import ServiceTip from './service-tip'; | ||
import SocialLogo from 'components/social-logo'; | ||
|
||
const SharingService = React.createClass( { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason you chose not to Component
-ify this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still uses a mixin to monitor connections-list
, I'm planning on doing it once all actions have moved over to using Redux
siteUserConnections: getSiteUserConnectionsForService( | ||
state, getSelectedSiteId( state ), getCurrentUserId( state ), service.ID | ||
), | ||
user: getCurrentUser( state ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're only using user.ID
, maybe better to pass userId: getCurrentUserId( state )
?
} | ||
}, | ||
|
||
addConnection: function( service = this.props.service, keyringConnectionId, externalUserId = false ) { | ||
const _this = this, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be unnecessary since the popupMonitor
event handler uses an arrow function (this
still refers to the component instance).
@@ -49,7 +48,10 @@ const EditorSharingAccordion = React.createClass( { | |||
const targeted = connections.filter( ( connection ) => { | |||
return ! includes( skipped, connection.keyring_connection_ID ); | |||
} ); | |||
const targetedServices = serviceConnections.getServicesFromConnections( targeted ); | |||
const targetedServices = uniq( targeted.map( ( connection ) => ( { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe plain uniq
is not what you want here:
https://lodash.com/docs/4.16.4#uniq
Instead, uniqBy
is the one that lets you specify an iteratee:
[ PUBLICIZE_CONNECTION_CREATE ]: ( state, { ID, siteId } ) => ( { ...state, [ ID ]: { | ||
...state[ ID ], sites: [ ...state[ ID ].sites, siteId.toString() ] | ||
[ PUBLICIZE_CONNECTION_CREATE ]: ( state, { connection: { keyring_connection_ID: ID, site_ID } } ) => ( { ...state, [ ID ]: { | ||
...state[ ID ], sites: [ ...state[ ID ].sites, site_ID.toString() ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think we should be very wary about destructuring more than a single level deep, as it becomes very difficult to read, especially with aliasing. Speaking of, naming should be id
, not ID
, per camelCasing guidelines.
efb050d
to
7a3ece6
Compare
* Update keyring reducer to use correct format. Turns out that publicize connection objects don’t actually look like I thought the look like. * Use full connection object when deleting a connection. Allows the keyring reducer to remove a connection based on the `keyring_connection_ID`. * Return all connections for a specified service. There may be more than one connection per service in the case of publicize services. * Introduce `getSiteUserConnectionsForService` Avoids having to filter the selector in the component that uses it. * Introduce `getAvailableExternalConnections` A selector for available external accounts for a service. * Simplify filtering of selector. * Extract action object to make it reusable * Handle update events for connections. * Update API to accept a connection object Simplifies its usage in components and allows us to pass its label to error messages. * Make keyring reducer easier to read. See #8991 (comment) * Introduce a selector for connections that can be removed by the current user. See https://github.com/Automattic/wp-calypso/pull/8991/files#r85749283 * Add missing function docs for new action creator. * Avoid using variable name previously defined in outer scope. Fixes an ESLint warning. * Remove unnecessary fallback value. `filter` always returns a new array. Props @gwwar. See #9068 (comment) * Limit variable destruction to one level deep. See #9068 (comment) * Move selector for external accounts to sharing directory. It’s a better place for the selector since it accesses both parts of sharing, `keyring` and `publicize`. It also returns more of a custom structure than either keyring or publicize connections. See #9068 (comment), #9068 (comment) * Remove unused reference to `additional_external_users`. See fddcca0. * Remove unused parts of test state. See fddcca0. * Simplify how removable connections are being retrieved. Checks capabilities based on the current user rather than the selected site. Props @gwwar. See https://github.com/Automattic/wp-calypso/pull/9068/files#r86043229.
7a3ece6
to
733fdb0
Compare
Avoids having to define a constructor in 2/3 cases. Props @gwwar. See #8991 (comment), #8991 (comment)
ada491a
to
ea75de9
Compare
ea75de9
to
e851afc
Compare
e851afc
to
5fca738
Compare
Avoids having to define a constructor in 2/3 cases. Props @gwwar. See #8991 (comment), #8991 (comment)
5fca738
to
bd3eb43
Compare
Allows for easier handling of Eventbrite connections since it doesn’t use Publicize.
Avoids regression with previous bahavior. See #8991 (comment) 1
f2fbe8d
to
949e357
Compare
} | ||
} else { | ||
// If an account wasn't selected from the dialog or the user cancels | ||
// the connection, the dialog should simply close | ||
this.props.connections.emit( 'create:error', { cancel: true } ); | ||
this.props.warningNotice( this.props.translate( 'The connection could not be made because no account was selected.', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ℹ️ This string is probably long enough that it doesn't need a context. Are you sure you don't want to use a translator comment instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use a context here. A translator comment is better suited ( i.e 'comment': 'Warning notice that appears If an account wasn't selected in the publicize/sharing dialog'
)
Means we can tick off a bunch of items in #8726? 🎉 |
Oh, good point! I checked off two items that were fixed by this PR |
Whoa, nice to see that in! |
Moves Publicize connections to be based on Redux.
This includes creating, updating, and deleting connections. This will also modernize the existing components and probably restructure them in a more modular fashion.
See #5046.