overhaul dropdown-dependent states

This commit is contained in:
Dennis Tang 2018-05-28 17:29:25 +02:00
parent 95a63a8816
commit 2e4bea09a6
7 changed files with 59 additions and 31 deletions

View File

@ -8,14 +8,24 @@ export default {
name: 'GkeMachineTypeDropdown', name: 'GkeMachineTypeDropdown',
mixins: [gkeDropdownMixin], mixins: [gkeDropdownMixin],
computed: { computed: {
...mapState(['projectHasBillingEnabled', 'selectedZone', 'selectedMachineType']), ...mapState([
'isValidatingProjectBilling',
'projectHasBillingEnabled',
'selectedZone',
'selectedMachineType',
]),
...mapState({ items: 'machineTypes' }), ...mapState({ items: 'machineTypes' }),
...mapGetters(['hasZone', 'hasMachineType']), ...mapGetters(['hasZone', 'hasMachineType']),
allDropdownsSelected() { allDropdownsSelected() {
return this.projectHasBillingEnabled && this.hasZone && this.hasMachineType; return this.projectHasBillingEnabled && this.hasZone && this.hasMachineType;
}, },
isDisabled() { isDisabled() {
return !this.projectHasBillingEnabled || !this.selectedZone; return (
this.isLoading ||
this.isValidatingProjectBilling ||
!this.projectHasBillingEnabled ||
!this.hasZone
);
}, },
toggleText() { toggleText() {
if (this.isLoading) { if (this.isLoading) {
@ -45,11 +55,15 @@ export default {
}, },
watch: { watch: {
selectedZone() { selectedZone() {
this.isLoading = true; this.hasErrors = false;
this.fetchMachineTypes() if (this.hasZone) {
.then(this.fetchSuccessHandler) this.isLoading = true;
.catch(this.fetchFailureHandler);
this.fetchMachineTypes()
.then(this.fetchSuccessHandler)
.catch(this.fetchFailureHandler);
}
}, },
selectedMachineType() { selectedMachineType() {
this.enableSubmit(); this.enableSubmit();

View File

@ -14,20 +14,17 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
isValidatingProjectBilling: false,
};
},
computed: { computed: {
...mapState(['selectedProject', 'projectHasBillingEnabled']), ...mapState(['selectedProject', 'isValidatingProjectBilling', 'projectHasBillingEnabled']),
...mapState({ items: 'projects' }), ...mapState({ items: 'projects' }),
...mapGetters(['hasProject']), ...mapGetters(['hasProject']),
hasOneProject() { hasOneProject() {
return this.items && this.items.length === 1; return this.items && this.items.length === 1;
}, },
isDisabled() { isDisabled() {
return this.items && this.items.length < 2; return (
this.isLoading || this.isValidatingProjectBilling || (this.items && this.items.length < 2)
);
}, },
toggleText() { toggleText() {
if (this.isValidatingProjectBilling) { if (this.isValidatingProjectBilling) {
@ -103,17 +100,12 @@ export default {
}, },
watch: { watch: {
selectedProject() { selectedProject() {
this.isLoading = true; this.setIsValidatingProjectBilling(true);
this.isValidatingProjectBilling = true;
this.validateProjectBilling() this.validateProjectBilling()
.then(this.validateProjectBillingSuccessHandler) .then(this.validateProjectBillingSuccessHandler)
.catch(this.validateProjectBillingFailureHandler); .catch(this.validateProjectBillingFailureHandler);
}, },
projectHasBillingEnabled(billingEnabled) {
this.hasErrors = !billingEnabled;
this.isValidatingProjectBilling = false;
},
}, },
created() { created() {
this.isLoading = true; this.isLoading = true;
@ -123,7 +115,7 @@ export default {
.catch(this.fetchFailureHandler); .catch(this.fetchFailureHandler);
}, },
methods: { methods: {
...mapActions(['fetchProjects', 'validateProjectBilling']), ...mapActions(['fetchProjects', 'setIsValidatingProjectBilling', 'validateProjectBilling']),
...mapActions({ setItem: 'setProject' }), ...mapActions({ setItem: 'setProject' }),
fetchSuccessHandler() { fetchSuccessHandler() {
if (this.defaultValue) { if (this.defaultValue) {
@ -140,10 +132,9 @@ export default {
this.hasErrors = false; this.hasErrors = false;
}, },
validateProjectBillingSuccessHandler() { validateProjectBillingSuccessHandler() {
this.isLoading = false; this.hasErrors = !this.projectHasBillingEnabled;
}, },
validateProjectBillingFailureHandler(resp) { validateProjectBillingFailureHandler(resp) {
this.isLoading = false;
this.hasErrors = true; this.hasErrors = true;
this.gapiError = resp.result ? resp.result.error.message : resp; this.gapiError = resp.result ? resp.result.error.message : resp;

View File

@ -8,10 +8,16 @@ export default {
name: 'GkeZoneDropdown', name: 'GkeZoneDropdown',
mixins: [gkeDropdownMixin], mixins: [gkeDropdownMixin],
computed: { computed: {
...mapState(['selectedProject', 'selectedZone', 'projects', 'projectHasBillingEnabled']), ...mapState([
'selectedProject',
'selectedZone',
'projects',
'isValidatingProjectBilling',
'projectHasBillingEnabled',
]),
...mapState({ items: 'zones' }), ...mapState({ items: 'zones' }),
isDisabled() { isDisabled() {
return !this.projectHasBillingEnabled; return this.isLoading || this.isValidatingProjectBilling || !this.projectHasBillingEnabled;
}, },
toggleText() { toggleText() {
if (this.isLoading) { if (this.isLoading) {
@ -34,13 +40,16 @@ export default {
}, },
}, },
watch: { watch: {
projectHasBillingEnabled(billingEnabled) { isValidatingProjectBilling(isValidating) {
if (!billingEnabled) return false; this.hasErrors = false;
this.isLoading = true;
return this.fetchZones() if (!isValidating && this.projectHasBillingEnabled) {
.then(this.fetchSuccessHandler) this.isLoading = true;
.catch(this.fetchFailureHandler);
this.fetchZones()
.then(this.fetchSuccessHandler)
.catch(this.fetchFailureHandler);
}
}, },
}, },
methods: { methods: {

View File

@ -31,6 +31,10 @@ export const setMachineType = ({ commit }, selectedMachineType) => {
commit(types.SET_MACHINE_TYPE, selectedMachineType); commit(types.SET_MACHINE_TYPE, selectedMachineType);
}; };
export const setIsValidatingProjectBilling = ({ commit }, isValidatingProjectBilling) => {
commit(types.SET_IS_VALIDATING_PROJECT_BILLING, isValidatingProjectBilling);
};
export const fetchProjects = ({ commit }) => export const fetchProjects = ({ commit }) =>
gapiResourceListRequest({ gapiResourceListRequest({
resource: gapi.client.cloudresourcemanager.projects, resource: gapi.client.cloudresourcemanager.projects,
@ -40,20 +44,25 @@ export const fetchProjects = ({ commit }) =>
payloadKey: 'projects', payloadKey: 'projects',
}); });
export const validateProjectBilling = ({ commit, state }) => export const validateProjectBilling = ({ dispatch, commit, state }) =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
const request = gapi.client.cloudbilling.projects.getBillingInfo({ const request = gapi.client.cloudbilling.projects.getBillingInfo({
name: `projects/${state.selectedProject.projectId}`, name: `projects/${state.selectedProject.projectId}`,
}); });
commit(types.SET_ZONE, '');
commit(types.SET_MACHINE_TYPE, '');
return request.then( return request.then(
resp => { resp => {
const { billingEnabled } = resp.result; const { billingEnabled } = resp.result;
commit(types.SET_PROJECT_BILLING_STATUS, !!billingEnabled); commit(types.SET_PROJECT_BILLING_STATUS, !!billingEnabled);
dispatch('setIsValidatingProjectBilling', false);
resolve(); resolve();
}, },
resp => { resp => {
dispatch('setIsValidatingProjectBilling', false);
reject(resp); reject(resp);
}, },
); );

View File

@ -1,5 +1,6 @@
export const SET_PROJECT = 'SET_PROJECT'; export const SET_PROJECT = 'SET_PROJECT';
export const SET_PROJECT_BILLING_STATUS = 'SET_PROJECT_BILLING_STATUS'; export const SET_PROJECT_BILLING_STATUS = 'SET_PROJECT_BILLING_STATUS';
export const SET_IS_VALIDATING_PROJECT_BILLING = 'SET_IS_VALIDATING_PROJECT_BILLING';
export const SET_ZONE = 'SET_ZONE'; export const SET_ZONE = 'SET_ZONE';
export const SET_MACHINE_TYPE = 'SET_MACHINE_TYPE'; export const SET_MACHINE_TYPE = 'SET_MACHINE_TYPE';
export const SET_PROJECTS = 'SET_PROJECTS'; export const SET_PROJECTS = 'SET_PROJECTS';

View File

@ -4,6 +4,9 @@ export default {
[types.SET_PROJECT](state, selectedProject) { [types.SET_PROJECT](state, selectedProject) {
Object.assign(state, { selectedProject }); Object.assign(state, { selectedProject });
}, },
[types.SET_IS_VALIDATING_PROJECT_BILLING](state, isValidatingProjectBilling) {
Object.assign(state, { isValidatingProjectBilling });
},
[types.SET_PROJECT_BILLING_STATUS](state, projectHasBillingEnabled) { [types.SET_PROJECT_BILLING_STATUS](state, projectHasBillingEnabled) {
Object.assign(state, { projectHasBillingEnabled }); Object.assign(state, { projectHasBillingEnabled });
}, },

View File

@ -5,6 +5,7 @@ export default () => ({
}, },
selectedZone: '', selectedZone: '',
selectedMachineType: '', selectedMachineType: '',
isValidatingProjectBilling: null,
projectHasBillingEnabled: null, projectHasBillingEnabled: null,
projects: [], projects: [],
zones: [], zones: [],