Add missing state on the application row component

This fixes the application row component weird state when an
`updating` status is fetched, this causes apps to show as uninstalled
even though they are installed in the cluster.
This commit is contained in:
Jose Vargas 2018-10-16 16:56:07 -05:00
parent d87e88a616
commit d4763515c1
No known key found for this signature in database
GPG key ID: 01F49A6AE27697FB
3 changed files with 184 additions and 149 deletions

View file

@ -1,153 +1,162 @@
<script> <script>
/* eslint-disable vue/require-default-prop */ /* eslint-disable vue/require-default-prop */
import { s__, sprintf } from '../../locale'; import { s__, sprintf } from '../../locale';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import identicon from '../../vue_shared/components/identicon.vue'; import identicon from '../../vue_shared/components/identicon.vue';
import loadingButton from '../../vue_shared/components/loading_button.vue'; import loadingButton from '../../vue_shared/components/loading_button.vue';
import { import {
APPLICATION_STATUS, APPLICATION_STATUS,
REQUEST_LOADING, REQUEST_LOADING,
REQUEST_SUCCESS, REQUEST_SUCCESS,
REQUEST_FAILURE, REQUEST_FAILURE,
} from '../constants'; } from '../constants';
export default { export default {
components: { components: {
loadingButton, loadingButton,
identicon, identicon,
},
props: {
id: {
type: String,
required: true,
}, },
props: { title: {
id: { type: String,
type: String, required: true,
required: true,
},
title: {
type: String,
required: true,
},
titleLink: {
type: String,
required: false,
},
manageLink: {
type: String,
required: false,
},
logoUrl: {
type: String,
required: false,
default: null,
},
disabled: {
type: Boolean,
required: false,
default: false,
},
status: {
type: String,
required: false,
},
statusReason: {
type: String,
required: false,
},
requestStatus: {
type: String,
required: false,
},
requestReason: {
type: String,
required: false,
},
installApplicationRequestParams: {
type: Object,
required: false,
default: () => ({}),
},
}, },
computed: { titleLink: {
isUnknownStatus() { type: String,
return !this.isKnownStatus && this.status !== null; required: false,
}, },
isKnownStatus() { manageLink: {
return Object.values(APPLICATION_STATUS).includes(this.status); type: String,
}, required: false,
isInstalled() { },
return ( logoUrl: {
this.status === APPLICATION_STATUS.INSTALLED || this.status === APPLICATION_STATUS.UPDATED type: String,
); required: false,
}, default: null,
hasLogo() { },
return !!this.logoUrl; disabled: {
}, type: Boolean,
identiconId() { required: false,
// generate a deterministic integer id for the identicon background default: false,
return this.id.charCodeAt(0); },
}, status: {
rowJsClass() { type: String,
return `js-cluster-application-row-${this.id}`; required: false,
}, },
installButtonLoading() { statusReason: {
return !this.status || type: String,
this.status === APPLICATION_STATUS.SCHEDULED || required: false,
this.status === APPLICATION_STATUS.INSTALLING || },
this.requestStatus === REQUEST_LOADING; requestStatus: {
}, type: String,
installButtonDisabled() { required: false,
// Avoid the potential for the real-time data to say APPLICATION_STATUS.INSTALLABLE but },
// we already made a request to install and are just waiting for the real-time requestReason: {
// to sync up. type: String,
return ((this.status !== APPLICATION_STATUS.INSTALLABLE required: false,
&& this.status !== APPLICATION_STATUS.ERROR) || },
installApplicationRequestParams: {
type: Object,
required: false,
default: () => ({}),
},
},
computed: {
isUnknownStatus() {
return !this.isKnownStatus && this.status !== null;
},
isKnownStatus() {
return Object.values(APPLICATION_STATUS).includes(this.status);
},
isInstalled() {
return (
this.status === APPLICATION_STATUS.INSTALLED ||
this.status === APPLICATION_STATUS.UPDATED ||
this.status === APPLICATION_STATUS.UPDATING
);
},
hasLogo() {
return !!this.logoUrl;
},
identiconId() {
// generate a deterministic integer id for the identicon background
return this.id.charCodeAt(0);
},
rowJsClass() {
return `js-cluster-application-row-${this.id}`;
},
installButtonLoading() {
return (
!this.status ||
this.status === APPLICATION_STATUS.SCHEDULED ||
this.status === APPLICATION_STATUS.INSTALLING ||
this.requestStatus === REQUEST_LOADING
);
},
installButtonDisabled() {
// Avoid the potential for the real-time data to say APPLICATION_STATUS.INSTALLABLE but
// we already made a request to install and are just waiting for the real-time
// to sync up.
return (
((this.status !== APPLICATION_STATUS.INSTALLABLE &&
this.status !== APPLICATION_STATUS.ERROR) ||
this.requestStatus === REQUEST_LOADING || this.requestStatus === REQUEST_LOADING ||
this.requestStatus === REQUEST_SUCCESS) && this.isKnownStatus; this.requestStatus === REQUEST_SUCCESS) &&
}, this.isKnownStatus
installButtonLabel() { );
let label; },
if ( installButtonLabel() {
this.status === APPLICATION_STATUS.NOT_INSTALLABLE || let label;
this.status === APPLICATION_STATUS.INSTALLABLE || if (
this.status === APPLICATION_STATUS.ERROR || this.status === APPLICATION_STATUS.NOT_INSTALLABLE ||
this.isUnknownStatus this.status === APPLICATION_STATUS.INSTALLABLE ||
) { this.status === APPLICATION_STATUS.ERROR ||
label = s__('ClusterIntegration|Install'); this.isUnknownStatus
} else if (this.status === APPLICATION_STATUS.SCHEDULED || ) {
this.status === APPLICATION_STATUS.INSTALLING) { label = s__('ClusterIntegration|Install');
label = s__('ClusterIntegration|Installing'); } else if (
} else if (this.status === APPLICATION_STATUS.INSTALLED || this.status === APPLICATION_STATUS.SCHEDULED ||
this.status === APPLICATION_STATUS.UPDATED) { this.status === APPLICATION_STATUS.INSTALLING
label = s__('ClusterIntegration|Installed'); ) {
} label = s__('ClusterIntegration|Installing');
} else if (
this.status === APPLICATION_STATUS.INSTALLED ||
this.status === APPLICATION_STATUS.UPDATED ||
this.status === APPLICATION_STATUS.UPDATING
) {
label = s__('ClusterIntegration|Installed');
}
return label; return label;
},
showManageButton() {
return this.manageLink && this.status === APPLICATION_STATUS.INSTALLED;
},
manageButtonLabel() {
return s__('ClusterIntegration|Manage');
},
hasError() {
return this.status === APPLICATION_STATUS.ERROR ||
this.requestStatus === REQUEST_FAILURE;
},
generalErrorDescription() {
return sprintf(
s__('ClusterIntegration|Something went wrong while installing %{title}'), {
title: this.title,
},
);
},
}, },
methods: { showManageButton() {
installClicked() { return this.manageLink && this.status === APPLICATION_STATUS.INSTALLED;
eventHub.$emit('installApplication', {
id: this.id,
params: this.installApplicationRequestParams,
});
},
}, },
}; manageButtonLabel() {
return s__('ClusterIntegration|Manage');
},
hasError() {
return this.status === APPLICATION_STATUS.ERROR || this.requestStatus === REQUEST_FAILURE;
},
generalErrorDescription() {
return sprintf(s__('ClusterIntegration|Something went wrong while installing %{title}'), {
title: this.title,
});
},
},
methods: {
installClicked() {
eventHub.$emit('installApplication', {
id: this.id,
params: this.installApplicationRequestParams,
});
},
},
};
</script> </script>
<template> <template>

View file

@ -6,6 +6,7 @@ export const APPLICATION_STATUS = {
INSTALLING: 'installing', INSTALLING: 'installing',
INSTALLED: 'installed', INSTALLED: 'installed',
UPDATED: 'updated', UPDATED: 'updated',
UPDATING: 'updating',
ERROR: 'errored', ERROR: 'errored',
}; };

View file

@ -112,6 +112,17 @@ describe('Application Row', () => {
expect(vm.installButtonDisabled).toEqual(true); expect(vm.installButtonDisabled).toEqual(true);
}); });
it('has disabled "Installed" when APPLICATION_STATUS.UPDATING', () => {
vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.UPDATING,
});
expect(vm.installButtonLabel).toEqual('Installed');
expect(vm.installButtonLoading).toEqual(false);
expect(vm.installButtonDisabled).toEqual(true);
});
it('has enabled "Install" when APPLICATION_STATUS.ERROR', () => { it('has enabled "Install" when APPLICATION_STATUS.ERROR', () => {
vm = mountComponent(ApplicationRow, { vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE, ...DEFAULT_APPLICATION_STATE,
@ -215,7 +226,9 @@ describe('Application Row', () => {
status: null, status: null,
requestStatus: null, requestStatus: null,
}); });
const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message'); const generalErrorMessage = vm.$el.querySelector(
'.js-cluster-application-general-error-message',
);
expect(generalErrorMessage).toBeNull(); expect(generalErrorMessage).toBeNull();
}); });
@ -227,10 +240,16 @@ describe('Application Row', () => {
status: APPLICATION_STATUS.ERROR, status: APPLICATION_STATUS.ERROR,
statusReason, statusReason,
}); });
const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message'); const generalErrorMessage = vm.$el.querySelector(
const statusErrorMessage = vm.$el.querySelector('.js-cluster-application-status-error-message'); '.js-cluster-application-general-error-message',
);
const statusErrorMessage = vm.$el.querySelector(
'.js-cluster-application-status-error-message',
);
expect(generalErrorMessage.textContent.trim()).toEqual(`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`); expect(generalErrorMessage.textContent.trim()).toEqual(
`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`,
);
expect(statusErrorMessage.textContent.trim()).toEqual(statusReason); expect(statusErrorMessage.textContent.trim()).toEqual(statusReason);
}); });
@ -242,10 +261,16 @@ describe('Application Row', () => {
requestStatus: REQUEST_FAILURE, requestStatus: REQUEST_FAILURE,
requestReason, requestReason,
}); });
const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message'); const generalErrorMessage = vm.$el.querySelector(
const requestErrorMessage = vm.$el.querySelector('.js-cluster-application-request-error-message'); '.js-cluster-application-general-error-message',
);
const requestErrorMessage = vm.$el.querySelector(
'.js-cluster-application-request-error-message',
);
expect(generalErrorMessage.textContent.trim()).toEqual(`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`); expect(generalErrorMessage.textContent.trim()).toEqual(
`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`,
);
expect(requestErrorMessage.textContent.trim()).toEqual(requestReason); expect(requestErrorMessage.textContent.trim()).toEqual(requestReason);
}); });
}); });