-
Notifications
You must be signed in to change notification settings - Fork 195
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
fix(compass-connections, sidebar): move all connection related logic and state to compass-connections COMPASS-8067 #6059
fix(compass-connections, sidebar): move all connection related logic and state to compass-connections COMPASS-8067 #6059
Conversation
…and state to compass-connections
8408ac4
to
41e9d44
Compare
}; | ||
|
||
if (duplicate.favorite?.name) { | ||
const copyFormat = duplicate.favorite?.name.match(/(.*)\s\(([0-9])+\)/); // title (2) -> [title (2), title, 2] |
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 this missing anchors? Otherwise we match something like foo (2) bar
as well and lose everything after the closing parenthesis
const copyFormat = duplicate.favorite?.name.match(/(.*)\s\(([0-9])+\)/); // title (2) -> [title (2), title, 2] | |
const copyFormat = duplicate.favorite?.name.match(/^(.*)\s\(([0-9])+\)$/); // title (2) -> [title (2), title, 2] |
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.
Good catch! I'll fix this implementation and add a test (we can also probably reduce the complexity of the algorithm there by reducing to the highest number right away instead of looping over for every number 🤔)
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.
Updated in ade3ada, also fixed handling multi digit numbers
error: error as Error, | ||
// Autoconnect flow might fail before we can even load connection info | ||
// so connectionInfo might be undefiend at this point. In | ||
// single-conneciton mode this requires some special handling so that |
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.
// single-conneciton mode this requires some special handling so that | |
// single-connection mode this requires some special handling so that |
const isOIDC = isOIDCAuth(connectionInfo.connectionOptions.connectionString); | ||
return { | ||
title: `Connecting to ${connectionTitle}`, | ||
description: isOIDC ? 'Go to the browser to complete authentication' : '', |
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 text is now applied both to multiple and single connections flow now that we're sharing more UI code between the two
// connection info object to be passed around. For that purposes this hook will | ||
// either return an editing connection info or will create a new one as a | ||
// fallback if nothing is actively being edited | ||
function useActiveConnectionInfo( |
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 might be something that we want to just make part of the connection-form logic, it's convenient to have a default there and then we don't need to manually create new connection info in two different places all the time
); | ||
|
||
const onConnectClick = (connectionInfo: ConnectionInfo) => { | ||
void connect({ ...cloneDeep(connectionInfo) }, true).catch(() => { |
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.
Honestly not sure why this was shallow and deep cloning, if someone knows what's the reason for this, please tell
enableDebugUseCsfleSchemaMap, | ||
protectConnectionStringsForNewConnections, | ||
] | ||
const activeConnectionInfo = useActiveConnectionInfo(editingConnectionInfo); |
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.
"Active" is like this concept only applicable to single connection form: what is being edited is also what you are connecting to (not sure if it's worth a comment in the code taking into account that we're going to remove it)
export function showNonGenuineMongoDBWarningModal( | ||
connectionInfo?: ConnectionInfo | ||
) { | ||
return showConfirmation({ |
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.
Button names are slightly different because of this change, but I'm not sure if it matters much tbh, I didn't try to make the names exactly the same
const favoriteConnectionsRef = useRef(favoriteConnections); | ||
favoriteConnectionsRef.current = favoriteConnections; | ||
|
||
const nonFavoriteConnectionsRef = useRef(nonFavoriteConnections); | ||
nonFavoriteConnectionsRef.current = nonFavoriteConnections; | ||
|
||
const autoConnectInfoRef = useRef(autoConnectInfo); | ||
autoConnectInfoRef.current = autoConnectInfo; |
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.
Drive-by: in a lot of places we need to just access the current state of those, which without changing some of the methods here required subscribing to changes to those (invalidating dependencies of a lot of other hooks) even when we don't care about it and only want to read the current value
activeConnectionId?: string; | ||
activeConnectionInfo: ConnectionInfo; | ||
connectingConnectionId: string | null; | ||
connectingStatusText: string; | ||
connectionErrorMessage: string | null; | ||
oidcDeviceAuthVerificationUrl: string | null; | ||
oidcDeviceAuthUserCode: string | null; |
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.
Literally none of this state makes sense in multiple connections mode 🙃
// In multiple connections mode we don't allow to start another edit | ||
// when one is already in progress |
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'm not sure if this was an intentional decision, before this was not possible mostly because of the bugs in the state. Currently it should be technically possible to "open" multiple times while editing if you get a toast with an error for a different connection, but maybe it's still a good idea not to allow resetting the form while one is already opened
duplicate.favorite.name = `${name} (${copyNumber})`; | ||
const connectWithInflightCheck = useCallback( | ||
async (connectionInfo: ConnectionInfo) => { | ||
const inflightConnect = InFlightConnections.get(connectionInfo.id); |
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.
@himanshusinghs is this something that you had in mind?
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.
yea something similar. I was probably thinking of having that in ConnectionsManager itself but having it here must have its own reasons. Sorry, I am yet to go through the PR (for my own understanding of the change).
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.
My thinking is that this connect method is the main and only interface that other parts of UI should use to start a connection, so debounce should happen as high as possible. We are also planning to dissolve manager and repository in the connections redux store with the follow-up refactor, so this logic will end up in the store eventually anyway
/> | ||
{editingConnectionInfo && ( | ||
<ConnectionFormModal |
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.
Technically could've moved the form to compass-connections too already, but all the tests are also here and I'm trying to limit this already massive PR 😅
…ot grab number from the middle of the string; reduce algo complexity by doing just one pass over array
The goal of this patch is to fix various inconsistencies in connection logic caused by the logic being spread across two places in the application. The issue was highlighted by the autoconnection flow just not working as expected at all, but the fix was not possible to do in a clean way without refactoring the connection store as the store shape was just not accounting for multiple connection mode at all (it's honestly mostly luck that e2e tests were still passing, mostly because even in multiple connections mode we're still testing more or less a single connection flow at a time).
The main changes to the store that this patch introduces:
activeConnectionId
,connectingConnectionId
states: they don't make any sense in the multiple connection worldI want to note that it's not the final shape of this store, it's still not aligned with Compass architecture and using React reduxers here puts some restrictions on how separated the logic can be and the async nature of state updates spread around here.
For the reviewer:
connections-store.tsx
file is probably the main one to focus on, it changed a lot because very little of the old store was relevant and had to be adjusted for multiple connections to work, so it would probably be easier to just read through it as if it's a new file and not a diff.I'll try to leave comments in places that I think are most notable, but if something doesn't make sense, please ask for clarifications!