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:
parent
d87e88a616
commit
d4763515c1
3 changed files with 184 additions and 149 deletions
|
@ -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>
|
||||||
|
|
|
@ -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',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue