Skip to content

Commit

Permalink
CLAPPS - fix dynamic label (#4601)
Browse files Browse the repository at this point in the history
* fix dynamic label logic

* fix logic

* address feedback
  • Loading branch information
martinmckenna committed Mar 25, 2019
1 parent 00867d9 commit 8901f9c
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 18 deletions.
98 changes: 81 additions & 17 deletions src/features/linodes/LinodesCreate/LinodeCreateContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { compose as recompose } from 'recompose';
import regionsContainer from 'src/containers/regions.container';
import withImages from 'src/containers/withImages.container';
import withLinodes from 'src/containers/withLinodes.container';
import { CreateTypes } from 'src/store/linodeCreate/linodeCreate.actions';
import {
LinodeActionsProps,
withLinodeActions
Expand All @@ -20,6 +21,9 @@ import Grid from 'src/components/Grid';
import { Tag } from 'src/components/TagsInput';

import { dcDisplayNames } from 'src/constants';
import withLabelGenerator, {
LabelProps
} from 'src/features/linodes/LinodesCreate/withLabelGenerator';
import { typeLabelDetails } from 'src/features/linodes/presentation';
import userSSHKeyHoc, {
State as userSSHKeyProps
Expand Down Expand Up @@ -72,11 +76,13 @@ interface State {
}

type CombinedProps = InjectedNotistackProps &
CreateType &
ReduxStateProps &
LinodeActionsProps &
WithLinodesImagesTypesAndRegions &
userSSHKeyProps &
DispatchProps &
LabelProps &
RouteComponentProps<{}>;

const defaultState: State = {
Expand All @@ -97,6 +103,20 @@ const defaultState: State = {
class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
state: State = defaultState;

componentDidUpdate(prevProps: CombinedProps) {
/**
* if we're clicking on the stackscript create flow, we need to stop
* defaulting to Debian 9 because it's possible the user chooses a stackscript
* that isn't compatible with the defaulted image
*/
if (
prevProps.createType !== 'fromStackScript' &&
this.props.createType === 'fromStackScript'
) {
this.setState({ selectedImageID: undefined });
}
}

clearCreationState = () => {
this.props.resetSSHKeys();
this.setState(defaultState);
Expand Down Expand Up @@ -143,17 +163,13 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
selectedStackScriptUsername: username,
availableUserDefinedFields: userDefinedFields,
availableStackScriptImages: images,
udfs: defaultData
udfs: defaultData,
/** reset image because stackscript might not be compatible with selected one */
selectedImageID: undefined
});

setDiskSize = (size: number) => this.setState({ selectedDiskSize: size });

setLabel = (
event: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
) => this.setState({ label: event.target.value });

setPassword = (password: string) => this.setState({ password });

toggleBackupsEnabled = () =>
Expand All @@ -166,13 +182,50 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {

setUDFs = (udfs: any[]) => this.setState({ udfs });

generateLabel = () => {
const { getLabel, imagesData, regionsData } = this.props;
const { selectedImageID, selectedRegionID } = this.state;

/* tslint:disable-next-line */
let arg1,
arg2,
arg3 = '';

if (selectedImageID) {
const selectedImage = imagesData.find(img => img.id === selectedImageID);
/**
* Use 'vendor' if it's a public image, otherwise use label (because 'vendor' will be null)
*
* If we have no selectedImage, just use an empty string
*/
arg1 = selectedImage
? selectedImage.is_public
? selectedImage.vendor
: selectedImage.label
: '';
}

if (selectedRegionID) {
const selectedRegion = regionsData.find(
region => region.id === selectedRegionID
);

arg2 = selectedRegion ? selectedRegion.id : '';
}

arg3 = this.props.createType;

return getLabel(arg1, arg2, arg3);
};

submitForm: HandleSubmit = (type, payload, linodeID?: number) => {
const { createType } = this.props;
/**
* run a certain linode action based on the type
* if clone, run clone service request and upsert linode
* if create, run create action
*/
if (type === 'clone' && !linodeID) {
if (createType === 'fromLinode' && !linodeID) {
return this.setState(
() => ({
errors: [
Expand All @@ -186,7 +239,7 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
);
}

if (type === 'createFromStackScript' && !this.state.selectedStackScriptID) {
if (createType === 'fromStackScript' && !this.state.selectedStackScriptID) {
return this.setState(
() => ({
errors: [
Expand All @@ -201,7 +254,7 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
}

const request =
type === 'clone'
createType === 'fromLinode'
? () => cloneLinode(linodeID!, payload)
: () => this.props.linodeActions.createLinode(payload);

Expand All @@ -212,7 +265,7 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
this.setState({ formIsSubmitting: false });

/** if cloning a Linode, upsert Linode in redux */
if (type === 'clone') {
if (createType === 'fromLinode') {
this.props.upsertLinode(response);
}

Expand All @@ -227,7 +280,9 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
/**
* allocate private IP if we have one
*
* @todo we need to update redux state here as well
* @todo we need to update redux state here as well but it's not
* crucial now because the networking tab already makes a request to
* /ips on componentDidMount
*/
if (payload.private_ip) {
allocatePrivateIP(response.id);
Expand Down Expand Up @@ -359,8 +414,8 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
this.state.selectedStackScriptUsername
}
updateStackScript={this.setStackScript}
label={this.state.label}
updateLabel={this.setLabel}
label={this.generateLabel()}
updateLabel={this.props.updateCustomLabel}
password={this.state.password}
updatePassword={this.setPassword}
backupsEnabled={this.state.backupsEnabled}
Expand All @@ -384,7 +439,14 @@ class LinodeCreateContainer extends React.PureComponent<CombinedProps, State> {
}
}

const mapStateToProps: MapState<ReduxStateProps, CombinedProps> = state => ({
interface CreateType {
createType: CreateTypes;
}

const mapStateToProps: MapState<
ReduxStateProps & CreateType,
CombinedProps
> = state => ({
accountBackupsEnabled: pathOr(
false,
['__resources', 'accountSettings', 'data', 'backups_enabled'],
Expand All @@ -395,7 +457,8 @@ const mapStateToProps: MapState<ReduxStateProps, CombinedProps> = state => ({
* and do not have the "add_linodes" grant
*/
userCannotCreateLinode:
isRestrictedUser(state) && !hasGrant(state, 'add_linodes')
isRestrictedUser(state) && !hasGrant(state, 'add_linodes'),
createType: state.createLinode.type
});

interface DispatchProps {
Expand Down Expand Up @@ -461,5 +524,6 @@ export default recompose<CombinedProps, {}>(
connected,
withRouter,
withSnackbar,
userSSHKeyHoc
userSSHKeyHoc,
withLabelGenerator
)(LinodeCreateContainer);
6 changes: 5 additions & 1 deletion src/features/linodes/LinodesCreate/withLabelGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { deriveDefaultLabel, LabelArgTypes } from './deriveDefaultLabel';

export interface LabelProps {
customLabel: string;
updateCustomLabel: (e: any) => void;
updateCustomLabel: (
e: React.ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
) => void;
getLabel: (...args: any[]) => string;
}

Expand Down

0 comments on commit 8901f9c

Please sign in to comment.