-
Notifications
You must be signed in to change notification settings - Fork 6
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
ZEN - Multiple bugfixes #231
base: v2.x/staging
Are you sure you want to change the base?
Conversation
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
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.
{(showPasswordDialog && updatedConnection) && <Wizard initialization={false}/>} | ||
{!showPasswordDialog && <Wizard initialization={false}/>} | ||
{(showPasswordDialog && updatedConnection) && <Wizard initialization={isNewInstallation}/>} | ||
{!showPasswordDialog && <Wizard initialization={isNewInstallation}/>} |
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.
These two lines look like over-complication, what is the use of updatedConnection? Why we can't use showPasswordDialog only?
Also there is inconsistency, if you resume progress after click Save & Close it will show the dialog, but if you close the app and click resume after re-opening it will start with Connection tab.
And line 73 has unused values const [showLoginDialog, setShowLogin] = useState(false);
that are probably intended for the same purpose?
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.
The following behavior is intentional:
-
If we click "Save & Close" and then resume in the same session, a dialog prompts for the password. Since we do not store the password in the app, we only ask for it.
Additionally, because it is the same session, the user does not need to see the entire connection tab—just the password is required. -
If we restart the app (different session) and resume, the connection tab with all attributes is displayed before resuming.
This behavior originates from staging.
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.
Great catch @skurnevich regarding the updatedConnection
. This issue originates from staging and has been addressed in this PR now.
Thanks.
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.
Additionally, I have removed unused states and variables in the Home component that originated from staging.
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.
Ok thank you, sorry for me asking on things that are not part of this PR, but even if it is already in staging we still need to fix things that are not in a good shape.
So i do believe that we need to unify this different behavior for resuming the saved installation, because even if the app is reopened we sill know the host/port and user for that installation, so we just need to ask for password and validate the entire connection.
I can't see any reason to ask user for host or to change it, moreover if user gets to connection tab and changes the host for saved installation it will corrupt the entire installation as part of progress is done on a different machine.
So ok let's not have it as part of this PR as it does not belongs here, but i'll create an issue for fixing 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.
Sure @skurnevich Thank you for the detailed review on my PRs.
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.
We previously discussed these two different approaches for the resume. However, we can revisit and refine them further.
Thanks for creating the issue.
src/renderer/components/Home.tsx
Outdated
const handleClick = () => { | ||
let newInstallationArgs = installationSlice.getInitialState().installationArgs; | ||
if (id === "install") { | ||
dispatch(setIsNewerInstallation(true)); | ||
setIsNewInstallation(true); |
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.
Having setIsNewInstallation and setIsNewerInstallation looks like an algorithmic issue, what is the reason to have both?
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 added setIsNewerInstallation
as a Redux state to be used globally across other stages.
The isNewInstallation
is from v2.x/staging and it is not necessary.
I just updated the PR to rely solely on the Redux state.
Thanks!
@@ -17,7 +17,7 @@ import StepLabel from '@mui/material/StepLabel'; | |||
import Button from '@mui/material/Button'; | |||
import Typography from '@mui/material/Typography'; | |||
import { Link } from 'react-router-dom'; | |||
import { selectConnectionStatus } from '../stages/progress/progressSlice'; | |||
import { selectConnectionStatus, setConnectionStatus } from '../stages/progress/progressSlice'; |
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.
setConnectionStatus does not seem to be used here, and should not be set from this component
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.
Removed it.
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.
Additionally, I have removed unused states, functions and variables in the Stepper component that originated from staging.
@@ -29,25 +29,31 @@ import Warning from '@mui/icons-material/Warning'; | |||
import CheckCircle from '@mui/icons-material/CheckCircle'; | |||
import { TYPE_YAML, TYPE_OUTPUT, TYPE_JCL, INIT_STAGE_LABEL, REVIEW_INSTALL_STAGE_LABEL, UNPAX_STAGE_LABEL } from '../common/Utils'; | |||
import { getProgress, getCompleteProgress, mapAndSetSkipStatus, mapAndGetSkipStatus } from '../stages/progress/StageProgressStatus'; | |||
|
|||
import {initProgressStatus} from '../stages/progress/progressConst'; |
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.
So is this a set of defaults or replacement for the progress storage? Shouldn't defaults be part of the storage anyway?
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.
Removed initProgressStatus
// TODO: define props, stages, stage interfaces | ||
// TODO: One rule in the store to enable/disable button | ||
|
||
export default function HorizontalLinearStepper({stages, initialization}:{stages: any, initialization?:boolean}) { | ||
|
||
const connectionStatus = useSelector(selectConnectionStatus); | ||
const connectionStatus = useState(useAppSelector(selectConnectionStatus)); |
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.
Why the useSelector even appeared there over the useAppSelector? If it was by mistake i still can see it in the line 58 useSelector(selectConnectionStatus),
And again, any benefits of using useState here?
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.
Ideally, it should be useAppSelector
. This originated from staging, and I'm not sure how or when useSelector
was added. I've fixed it in this PR. Additionally, useState
is not necessary for connectionStatus
here since it is not responsible for updating any state. So removed it.
|
||
if(!isNewInstallation) { | ||
completeProgress = getCompleteProgress(); | ||
} |
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 suggest to get rid of initProgressStatus, but even if not the ternary operator can be used here instead of 'completeProgress' re-assigning
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.
Removed initProgressStatus
. And added: const completeProgress = getCompleteProgress();
getCompleteProgress()
takes care of it.
const keysArray = [progressStateKey, activeStateKey, planningStateKey, installationTypeKey, downloadUnpaxKey, datasetInstallationKey, apfAuthKey, securityKey, stcsKey, certificateKey, vsamKey, planningValidationDetailsKey, prevInstallationKey, skipStateKey, installationArgsKey]; | ||
keysArray.forEach(key => { | ||
if(localStorage.getItem(key) !== null) { | ||
localStorage.removeItem(key); |
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.
So all of above is happening just to reset the storage in case user click on New Zowe Installation when they have some Saved Installation? Can you share more details on how this works with the keys and ids?
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.
The code is designed to reset various progress-related states and storage entries when a user initiates a new Zowe installation, even if they have saved installation data. The setProgressObjects
function initializes all the necessary state objects to their default values, ensuring that the application starts fresh. The resetProgress
function clears the relevant keys from local storage to remove any saved data associated with the previous installation. This process ensures that the application doesn't carry over any outdated or conflicting data from a previous setup. By using unique IDs based on the host
and user
, the code manages and isolates storage and state for different user sessions.
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.
Ok, i still believe it is not correct, your idea is to split different sessions in the storage so user can continue with multiple instances installation is great and we should have it some eventually. But host
and user
combination is not enough to define a unique installation, for that we need to use unique session/instance id. Second, as of now it doesn't even work for me, when i save my session and then ask different user to start new one they still can see some values from my installation, and after that i can't return to my first installation as there is just one card for saved installation.
So in the current state i propose to keep multiple saved installations as a feature to be done in future, and just when user clicks on New Installation to show a warning popup that their previous progress will be deleted and after that actually delete all the contents of configuration storage
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, using just the host and username cannot fully distinguish between different installations, so this approach needs reworking. However, due to time constraints, we planned to proceed with this for the first release.
For future enhancements, we plan to support multiple saved installations.
In the meantime, I will implement a warning popup. Thanks again.
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.
@skurnevich Added the warning dialog for the new installation
@skurnevich For reference, please see the attached screenshot: |
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
Signed-off-by: Sakshi Bobade <[email protected]>
const keysArray = [progressStateKey, activeStateKey, planningStateKey, installationTypeKey, downloadUnpaxKey, datasetInstallationKey, apfAuthKey, securityKey, stcsKey, certificateKey, vsamKey, planningValidationDetailsKey, prevInstallationKey, skipStateKey, installationArgsKey]; | ||
keysArray.forEach(key => { | ||
if(localStorage.getItem(key) !== null) { | ||
localStorage.removeItem(key); |
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.
Ok, i still believe it is not correct, your idea is to split different sessions in the storage so user can continue with multiple instances installation is great and we should have it some eventually. But host
and user
combination is not enough to define a unique installation, for that we need to use unique session/instance id. Second, as of now it doesn't even work for me, when i save my session and then ask different user to start new one they still can see some values from my installation, and after that i can't return to my first installation as there is just one card for saved installation.
So in the current state i propose to keep multiple saved installations as a feature to be done in future, and just when user clicks on New Installation to show a warning popup that their previous progress will be deleted and after that actually delete all the contents of configuration storage
{(showPasswordDialog && updatedConnection) && <Wizard initialization={false}/>} | ||
{!showPasswordDialog && <Wizard initialization={false}/>} | ||
{(showPasswordDialog && updatedConnection) && <Wizard initialization={isNewInstallation}/>} | ||
{!showPasswordDialog && <Wizard initialization={isNewInstallation}/>} |
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.
Ok thank you, sorry for me asking on things that are not part of this PR, but even if it is already in staging we still need to fix things that are not in a good shape.
So i do believe that we need to unify this different behavior for resuming the saved installation, because even if the app is reopened we sill know the host/port and user for that installation, so we just need to ask for password and validate the entire connection.
I can't see any reason to ask user for host or to change it, moreover if user gets to connection tab and changes the host for saved installation it will corrupt the entire installation as part of progress is done on a different machine.
So ok let's not have it as part of this PR as it does not belongs here, but i'll create an issue for fixing that.
import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControl, TextField } from '@mui/material'; | ||
import { useState } from 'react'; | ||
|
||
const WarningDialog = ({onWarningDialogSubmit}: {onWarningDialogSubmit: any}) => { |
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 seems to be quite hardcoded again.
First it is better to have the WarningDialog.tsx in "common", no need to have separate structure for that.
Second we should have it as simple as possible, taking 3 properties "text", "onSubmit", "onCancel" and no logic inside, even visibility should be controlled in the parent component. In that case it could be reused in future in any other place. We actually can go even further and add 4th property to control dialog type, like error/warning/info etc.
import WarningDialog from './Dialogs/WarningDialog'; | ||
import HomeCardComponent from './HomeCardComponent'; | ||
import { ICard } from '../../types/interfaces'; | ||
import { ROUTES } from '../../Routes/RouteConstant'; |
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.
Similar with Routes, you have moved it out to a separate file structure Routes/RouteConstant.tsx which looks like an overkill to me, especially when there are just two links and routing is not actually needed, it is just a legacy leftover that should be cleaned up later. And definitely we do not need Routes outside of renderer.
It is fine to move constants that need to be shared between modules out to some distinct file, if there are not many, but in this case you can use something like generic constants.ts in the “renderer” or “src” folder.
Also cards constant still uses text "/wizard" on lines 46 and 53
dispatch(setIsNewInstallation(status)) | ||
setNewInstallationClick(false); | ||
setPreviousInstallation(!status); | ||
|
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.
Well, it does not clear previous information for me, it starts with a connection screen again, but all the data still there. I was going to recommend you to just drop the stores here, like every store has the deleteAll() function for that purpose, but when i tried that i realize it also has no effect until you close the app.
I believe we have some issues with the way we use storage, we duplicate it in memory and so just complicate things, creating multiple sources of data
@@ -10,126 +10,23 @@ | |||
|
|||
import { flatten, unflatten } from 'flat'; | |||
import { ProgressState, PlanningState, InstallationType, ActiveState, DatasetInstallationState, InitSubStepsState, CertInitSubStepsState, PlanningValidationDetails, SkipState, InstallationArgs, DownloadUnpaxState} from '../../../../types/stateInterfaces'; | |||
import { initProgressStatus, initInstallationTypeStatus, initDownloadUnpaxStatus, initActiveStatus, initPlanningStageStatus, initDatasetInstallationStatus, initApfAuthStatus, initSecurityInitStatus, initStcsInitStatus, initCertificateInitStatus, initVsamInitStatus, initPlanningValidationDetailsStatus, initStepSkipStatus, initInstallationArgsStatus } from './progressConst'; |
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.
Why we even have StageProgressStatus.ts, why don't we use storage/ProgressStore.ts for that?
Proposed changes
This PR addresses several issues:
Type of change
Please delete options that are not relevant.
PR Checklist
Please delete options that are not relevant.
Testing
Further comments