Skip to content
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

[UI] Volume Batch Creation #2981

Merged
merged 19 commits into from
Dec 27, 2020
Merged

Conversation

ChengYanJin
Copy link
Contributor

Component: ui, volumes

Context:
We want to be able to batch create volume from UI.

Summary:
Note that:
For RawBlockDevice, the recommended path only happens with '/dev/vda', we will see later if
For SparseLoopDevice, the size of the batch volume are the same as the default one.

Acceptance criteria:

  1. The Default Volume Creation Form
    image

  2. Volume type RawBlockDevice batch creation
    image

  3. Volume type SparseLoopDevice batch creation. (From big HD screen)
    image


Closes: #2964

@bert-e
Copy link
Contributor

bert-e commented Dec 14, 2020

Hello chengyanjin,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Status report is not available.

@bert-e
Copy link
Contributor

bert-e commented Dec 14, 2020

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

export const linuxDrivesNamingIncrement = (string, increment) => {
if (string.match(/^\/dev\/vd[a-z]/)) {
while (increment--) {
var lastChar = string.slice(-1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not yet sure about your styleguide conventions but I would always prefer usage of let or const for variable definitions, using const here will reflect clearly that this variable doesn't change elsewhere and will slightly simplify reading this code

*
* const nextDevicePath = linuxDrivesNamingIncrement(string)
*/
export const linuxDrivesNamingIncrement = (string, increment) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename string to something more explicit such as drivePath

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally for utils function like this one it seems important for me to add a unit test that covers the edge cases you want to support, but not sure if it is your traditional way of working so we can discuss about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it's a very bad name. I will rename it to devicePath.

* @example
* const string = '/dev/vda'
*
* const nextDevicePath = linuxDrivesNamingIncrement(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example lack increment parameter

@@ -419,3 +419,45 @@ export const useDynamicChartSize = (container_id) => {

return [graphWidth, window.innerHeight / 6 - 30];
};

/**
* This function increments the string by 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description doesn't seems to be accurate

Comment on lines 250 to 295
const RecommendNameField = (props) => {
const {
values: { name },
touched,
setFieldValue,
} = useFormikContext();
const [field, meta] = useField(props);
React.useEffect(() => {
if (name.trim() !== '' && touched.name) {
setFieldValue(props.name, `${name}${props.index + 1}`);
}
}, [name, touched.name, setFieldValue, props.name, props.index]);

return (
<>
<Input {...props} {...field} />
{!!meta.touched && !!meta.error && <div>{meta.error}</div>}
</>
);
};

const RecommendDevicePathField = (props) => {
const {
values: { path },
touched,
setFieldValue,
} = useFormikContext();
const [field, meta] = useField(props);
React.useEffect(() => {
if (path.trim() !== '' && touched.path) {
setFieldValue(
props.name,
linuxDrivesNamingIncrement(path, props.index + 1),
);
}
}, [path, touched.path, setFieldValue, props.name, props.index]);

return (
<>
<Input {...props} {...field} />
{!!meta.touched && !!meta.error && <div>{meta.error}</div>}
</>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As those two components only differs in the way they setFieldValue, they might be factorized.

message: intl.translate('volume_creation_failed', {
name: newVolume.name,
}),
title: 'Volume Form Error',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translation seems to be missing here

@@ -54,6 +55,8 @@ const ActionContainer = styled.div`
const CreateVolumeLayout = styled.div`
display: inline-block;
margin-top: ${padding.base};
overflow-y: scroll;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intended to display scrollbars by default even for non scrollable content ? You might prefer to use auto instead

placement="right"
overlay={
<div style={{ minWidth: '200px' }}>
A devicePath or a partition mount point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a missing translation here

createVolume(newVolume);
const newVolumes = { ...values };
newVolumes.size = `${values.sizeInput}${values.selectedUnit}`;
if (newVolumes.multiVolumeCreation) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if could be transferred in formatDataForBatchVolumeCreation as it already partially exists there and just missing the else branch to return a one element array

@@ -276,3 +276,28 @@ export const getVolumeListData = createSelector(
return nodeVolumes.sort((a, b) => compareHealth(b.health, a.health));
},
);

export const formatDataForBatchVolumeCreation = (newVolumes) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a simple unit test for the two branches of this function, also as mentioned in the usage of this function I would handle the !multiVolumeCreation case here and return a single entry array containing newVolumes, that would allow a simpler usage of the function as its ouput will always be of the same shape (newVolumes: VolumeCreationFormState) => Volume[] instead of (newVolumes: VolumeCreationFormState) => Volume[] | void

@bert-e
Copy link
Contributor

bert-e commented Dec 17, 2020

Conflict

There is a conflict between your branch feature/2964-volume-batch-creation and the
destination branch development/2.7.

Please resolve the conflict on the feature branch (feature/2964-volume-batch-creation).

 $ git fetch
 $ git checkout origin/feature/2964-volume-batch-creation
 $ git merge origin/development/2.7
 $ # <intense conflict resolution>
 $ git commit
 $ git push origin HEAD:feature/2964-volume-batch-creation

@ChengYanJin ChengYanJin force-pushed the feature/2964-volume-batch-creation branch from e497e57 to 1bc8143 Compare December 18, 2020 10:46
"overflow-y: scroll" protentially would display the scrollbar by default
even for non scrollable content, which casue the issue of we have the
scrollbar everywhere.

Refs: #2964
Handle the single volume creation case in the utility function instead
of in the createVolume component so that the return of this function
is always an array.

For single volume, return an array with the origin volume.
For batch volume, return an array with the formatted volumes.

Refs: #2964
Correct the variable declaration too

Refs: #2964
@ChengYanJin ChengYanJin force-pushed the feature/2964-volume-batch-creation branch from 1bc8143 to ac5c3ff Compare December 18, 2020 10:57
@bert-e
Copy link
Contributor

bert-e commented Dec 18, 2020

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

Copy link
Contributor

@thomasdanan thomasdanan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChengYanJin I like the behavior.
I would change one little thing:
When you create multiple Volumes, the Device Path for each Volume is computed from the Global Device Path field. I think the first Volume should get what you input in the Global Device Path field (i.e. not increment the Device Path of the first Volume).

Also when playing with multiple Volume check box and the number of Volumes, you will observe strange behavior. Maybe some state not properly managed

I wonder if we should disable Global Name and Device Path global fields when creating multiple Volumes because if you override Name or Device Path and then you change the Global field, you will lose all your customizations (@JBWatenbergScality what do you think?)

Also for number increments, I would do 01, 02, 03 etc ... instead of 1, 2, 3 ....

Thanks and well done

@bert-e
Copy link
Contributor

bert-e commented Dec 18, 2020

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

The following reviewers are expecting changes from the author, or must review again:

@JBWatenbergScality
Copy link
Contributor

JBWatenbergScality commented Dec 18, 2020

@thomasdanan @ChengYanJin From my point of view once the name or path is touched we shouldn't change automatically their values to maintain the user intentions but should still let the ability for the user to change the first volume name and path.

Also the ui might be a little bit misleading as the user is unsure if the default values will actually create a volume. To be precise mentioning /dev/vda by default and then creating one more volume will pre-complete the first entry with /dev/vdb in the current behavior but when submitting the form just /dev/vdb will be created.

The simplest interaction I could think of closed enough to the current implementation would be to remove the default name and path fields when checking Create multiple volumes? and compute the names of the volumes from the first one if subsequent one are not touched.

The recommend default device path should start from the global one

Refs: #2964
We only recommend the name/path for the empty field, means if the global
name/page get updated, the defaults won't change.

Refs: #2964

/**
* This function formats the name base on the index
* @param {string} name - The name the default volume name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove redundant name The name the default volume

* @example
* const name = 'volume-test'
*
* const nextDevicePath = linuxDrivesNamingIncrement(name, 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const formatedName = formatBatchName(name, 1)

{intl.translate('number_volume_create')}
</span>
{/* TODO: Generalize the number input component to core-ui. */}
<InputNumberComponentStyle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should handle a max number of volumes to avoid dom freeze in case of the user mistakenly ask 10000 volumes, simply add a max prop here should be enough

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, good point!
I am going to set the max number to70 for the moment.

@ChengYanJin ChengYanJin force-pushed the feature/2964-volume-batch-creation branch from 1c36230 to 4c3cbe3 Compare December 22, 2020 16:34
@ChengYanJin
Copy link
Contributor Author

ChengYanJin commented Dec 22, 2020

Hello @thomasdanan @JBWatenbergScality ,

According to the feedback from you and our offline discussions. I've addressed the following issues.

Thomas: When you create multiple Volumes, the Device Path for each Volume is computed from the Global Device Path field. I think the first Volume should get what you input in the Global Device Path field (i.e. not increment the Device Path of the first Volume).

Fix the bug of the Device path, the first volume should be the same as the Global field.

Thomas: Also when playing with multiple Volume check box and the number of Volumes, you will observe strange behavior. Maybe some state not properly managed

Fix the bug, will add interaction test of the form in the following PR.

Thomas: I wonder if we should disable Global Name and Device Path global fields when creating multiple Volumes because if you override Name or Device Path and then you change the Global field, you will lose all your customizations (@JBWatenbergScality what do you think?)

In order to keep the user customization, edit the global value(name/path) should not affect the defaults pre-fill of the touched field.
Unless the users uncheck the box of multi-volume creation and re-check again, we only update the untouched field with the new global value.

Thomas: Also for number increments, I would do 01, 02, 03 etc ... instead of 1, 2, 3 ....

Done.

  1. Set the maximum number of the volume to create 70 to prevent the UI frozen.
    The UI should pop up the error message when the input number is bigger than 70 (Waiting for the PR #213 in core-ui to be landed)

Please let me know if you see any improvements/ bugs to be done.
Thank you!

@ChengYanJin ChengYanJin force-pushed the feature/2964-volume-batch-creation branch from 4c3cbe3 to 6622ce5 Compare December 23, 2020 09:06
Set the max number of the input volume creation to 70, since it frozes
the UI when rendering the form.
We may even want to lower the max number depents on the use case.

Refs: #2964
Comment on lines 430 to 435
if (
touched &&
touched.volumes &&
touched?.volumes[i]?.name === true
) {
continue;
} else {
setFieldValue(`volumes[${i}]name`, '');
}
if (
touched &&
touched.volumes &&
touched?.volumes[i]?.path === true
) {
continue;
} else {
setFieldValue(`volumes[${i}]path`, '');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be simplified to :

if (!touched?.volumes[i]?.name) {
    setFieldValue(`volumes[${i}]name`, '');
}
if (!touched?.volumes[i]?.path) {
    setFieldValue(`volumes[${i}]path`, '');
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @JBWatenbergScality ,

Yes. Good point. But I guess we need to use optional chaining to make sure the Volumes array exists.
Please see:

                  if (!touched?.volumes?.[i]?.name) {
                    setFieldValue(`volumes[${i}]name`, '');
                  }
                  if (!touched?.volumes?.[i]?.path) {
                    setFieldValue(`volumes[${i}]path`, '');
                  }

@ChengYanJin ChengYanJin force-pushed the feature/2964-volume-batch-creation branch from 6622ce5 to 5d584ae Compare December 23, 2020 11:40
In order to keep the user customization, edit the global value
(name/path) should not affect the defaults pre-fill of the touched
field.

Unless the users uncheck the box of multi-volume creation and re-check
again, we only update the untouched field with the new global value.

Refs: #2964
@ChengYanJin
Copy link
Contributor Author

/approve

@bert-e
Copy link
Contributor

bert-e commented Dec 23, 2020

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

The following reviewers are expecting changes from the author, or must review again:

The following options are set: approve

@ChengYanJin ChengYanJin dismissed thomasdanan’s stale review December 23, 2020 16:30

Addressed the issues and improvements.

@bert-e
Copy link
Contributor

bert-e commented Dec 23, 2020

In the queue

The changeset has received all authorizations and has been added to the
relevant queue(s). The queue(s) will be merged in the target development
branch(es) as soon as builds have passed.

The changeset will be merged in:

  • ✔️ development/2.7

The following branches will NOT be impacted:

  • development/1.0
  • development/1.1
  • development/1.2
  • development/1.3
  • development/2.0
  • development/2.1
  • development/2.2
  • development/2.3
  • development/2.4
  • development/2.5
  • development/2.6

There is no action required on your side. You will be notified here once
the changeset has been merged. In the unlikely event that the changeset
fails permanently on the queue, a member of the admin team will
contact you to help resolve the matter.

IMPORTANT

Please do not attempt to modify this pull request.

  • Any commit you add on the source branch will trigger a new cycle after the
    current queue is merged.
  • Any commit you add on one of the integration branches will be lost.

If you need this pull request to be removed from the queue, please contact a
member of the admin team now.

The following options are set: approve

@bert-e
Copy link
Contributor

bert-e commented Dec 27, 2020

I have successfully merged the changeset of this pull request
into targetted development branches:

  • ✔️ development/2.7

The following branches have NOT changed:

  • development/1.0
  • development/1.1
  • development/1.2
  • development/1.3
  • development/2.0
  • development/2.1
  • development/2.2
  • development/2.3
  • development/2.4
  • development/2.5
  • development/2.6

Please check the status of the associated issue None.

Goodbye chengyanjin.

@bert-e bert-e merged commit 7286a2f into development/2.7 Dec 27, 2020
@bert-e bert-e deleted the feature/2964-volume-batch-creation branch December 27, 2020 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Batch Volume Creation from MetalK8s UI
4 participants