Commit 1e4c2a2e authored by Dennis Tang's avatar Dennis Tang

complete vuex implementation + refactoring

parent 41f2c1d5
<script>
import _ from 'underscore';
import Flash from '~/flash';
import { s__, sprintf } from '~/locale';
import { s__ } from '~/locale';
import { mapState, mapGetters, mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
......@@ -23,10 +22,6 @@ export default {
DropdownHiddenInput,
},
props: {
service: {
type: Object,
required: true,
},
fieldId: {
type: String,
required: true,
......@@ -35,7 +30,7 @@ export default {
type: String,
required: true,
},
inputValue: {
defaultValue: {
type: String,
required: false,
default: '',
......@@ -46,17 +41,19 @@ export default {
isLoading: false,
hasErrors: false,
searchQuery: '',
items: [],
};
},
computed: {
...mapState(['selectedProject', 'selectedZone', 'selectedMachineType']),
...mapGetters(['hasProject', 'hasZone']),
...mapState({ machineTypes: 'fetchedMachineTypes' }),
...mapGetters(['hasProject', 'hasZone', 'hasMachineType']),
isDisabled() {
return !this.selectedProject || !this.selectedZone;
},
searchResults() {
return this.items.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
return this.machineTypes.filter(
item => item.name.toLowerCase().indexOf(this.searchQuery) > -1,
);
},
toggleText() {
if (this.isLoading) {
......@@ -75,54 +72,44 @@ export default {
? s__('ClusterIntegration|Select machine type')
: s__('ClusterIntegration|Select zone to choose machine type');
},
placeholderText() {
searchPlaceholderText() {
return s__('ClusterIntegration|Search machine types');
},
},
created() {
eventHub.$on('zoneSelected', this.fetchItems);
eventHub.$on('zoneSelected', this.fetchMachineTypes);
eventHub.$on('machineTypeSelected', this.enableSubmit);
},
methods: {
...mapActions(['setMachineType']),
fetchItems() {
...mapActions(['setMachineType', 'getMachineTypes']),
fetchMachineTypes() {
this.isLoading = true;
const request = this.service.machineTypes.list({
project: this.selectedProject.projectId,
zone: this.selectedZone,
});
return request.then(
resp => {
let machineTypeToSelect;
this.items = resp.result.items;
this.getMachineTypes()
.then(() => {
if (this.defaultValue) {
const machineTypeToSelect = _.find(
this.machineTypes,
item => item.name === this.defaultValue,
);
if (this.inputValue) {
machineTypeToSelect = _.find(this.items, item => item.name === this.inputValue);
this.setMachineType(machineTypeToSelect.name);
if (machineTypeToSelect) {
this.setMachineType(machineTypeToSelect.name);
}
}
this.isLoading = false;
this.hasErrors = false;
},
() => {
})
.catch(() => {
this.isLoading = false;
this.hasErrors = true;
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch zone machine types: %{error}',
{ error: resp.result.error.message },
),
);
}
},
this,
);
});
},
enableSubmit() {
document.querySelector('.js-gke-cluster-creation-submit').removeAttribute('disabled');
if (this.hasProject && this.hasZone && this.hasMachineType) {
document.querySelector('.js-gke-cluster-creation-submit').removeAttribute('disabled');
}
},
},
};
......@@ -146,7 +133,7 @@ export default {
<div class="dropdown-menu dropdown-select">
<dropdown-search-input
v-model="searchQuery"
:placeholder-text="placeholderText"
:placeholder-text="searchPlaceholderText"
/>
<div class="dropdown-content">
<ul>
......
<script>
import _ from 'underscore';
import Flash from '~/flash';
import { s__, sprintf } from '~/locale';
import { mapState, mapGetters, mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
......@@ -10,7 +9,6 @@ import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidde
import store from '../stores';
import DropdownButton from './dropdown_button.vue';
// TODO: Consolidate dropdown code
export default {
name: 'GkeProjectIdDropdown',
......@@ -27,10 +25,6 @@ export default {
type: String,
required: true,
},
service: {
type: Object,
required: true,
},
fieldId: {
type: String,
required: true,
......@@ -39,7 +33,7 @@ export default {
type: String,
required: true,
},
inputValue: {
defaultValue: {
type: String,
required: false,
default: '',
......@@ -50,20 +44,20 @@ export default {
isLoading: true,
hasErrors: false,
searchQuery: '',
items: [],
};
},
computed: {
...mapState(['selectedProject']),
...mapState({ projects: 'fetchedProjects' }),
...mapGetters(['hasProject']),
hasOneProject() {
return this.items.length === 1;
return this.projects.length === 1;
},
isDisabled() {
return this.items.length < 2;
return this.projects.length < 2;
},
searchResults() {
return this.items.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
return this.projects.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
},
toggleText() {
if (this.isLoading) {
......@@ -74,11 +68,11 @@ export default {
return this.selectedProject.name;
}
return this.items.length
return this.projects.length
? s__('ClusterIntegration|Select project')
: s__('ClusterIntegration|No projects found');
},
placeholderText() {
searchPlaceholderText() {
return s__('ClusterIntegration|Search projects');
},
helpText() {
......@@ -88,7 +82,7 @@ export default {
'ClusterIntegration|We were unable to fetch any projects. Ensure that you have a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.';
}
message = this.items.length
message = this.projects.length
? 'ClusterIntegration|To use a new project, first create one on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.'
: 'ClusterIntegration|To create a cluster, first create a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}.';
......@@ -105,46 +99,33 @@ export default {
},
},
created() {
this.fetchItems();
this.fetchProjects();
},
methods: {
...mapActions(['setProject']),
fetchItems() {
const request = this.service.projects.list();
return request.then(
resp => {
let projectToSelect;
this.items = resp.result.projects;
...mapActions(['setProject', 'getProjects']),
fetchProjects() {
this.getProjects()
.then(() => {
if (this.defaultValue) {
const projectToSelect = _.find(
this.projects,
item => item.projectId === this.defaultValue,
);
if (this.inputValue) {
projectToSelect = _.find(this.items, item => item.projectId === this.inputValue);
this.setProject(projectToSelect);
} else if (this.items.length === 1) {
projectToSelect = this.items[0];
this.setProject(projectToSelect);
if (projectToSelect) {
this.setProject(projectToSelect);
}
} else if (this.projects.length === 1) {
this.setProject(this.projects[0]);
}
this.isLoading = false;
this.hasErrors = false;
},
resp => {
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch your projects: %{error}',
{
error: resp.result.error.message,
},
),
);
}
})
.catch(() => {
this.isLoading = false;
this.hasErrors = true;
},
this,
);
});
},
},
};
......@@ -161,7 +142,10 @@ export default {
:value="selectedProject.projectId"
/>
<dropdown-button
:class="{ 'gl-field-error-outline': hasErrors, 'read-only': hasOneProject }"
:class="{
'gl-field-error-outline': hasErrors,
'read-only': hasOneProject
}"
:is-disabled="isDisabled"
:is-loading="isLoading"
:toggle-text="toggleText"
......@@ -169,7 +153,7 @@ export default {
<div class="dropdown-menu dropdown-select">
<dropdown-search-input
v-model="searchQuery"
:placeholder-text="placeholderText"
:placeholder-text="searchPlaceholderText"
/>
<div class="dropdown-content">
<ul>
......
<script>
import _ from 'underscore';
import Flash from '~/flash';
import { s__, sprintf } from '~/locale';
import { s__ } from '~/locale';
import { mapState, mapGetters, mapActions } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import LoadingIcon from '~/vue_shared/components/loading_icon.vue';
......@@ -23,10 +22,6 @@ export default {
DropdownHiddenInput,
},
props: {
service: {
type: Object,
required: true,
},
fieldId: {
type: String,
required: true,
......@@ -35,7 +30,7 @@ export default {
type: String,
required: true,
},
inputValue: {
defaultValue: {
type: String,
required: false,
default: '',
......@@ -46,17 +41,17 @@ export default {
isLoading: false,
hasErrors: false,
searchQuery: '',
items: [],
};
},
computed: {
...mapState(['selectedProject', 'selectedZone']),
...mapState({ zones: 'fetchedZones' }),
...mapGetters(['hasProject']),
isDisabled() {
return !this.hasProject;
},
searchResults() {
return this.items.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
return this.zones.filter(item => item.name.toLowerCase().indexOf(this.searchQuery) > -1);
},
toggleText() {
if (this.isLoading) {
......@@ -71,49 +66,35 @@ export default {
? s__('ClusterIntegration|Select zone')
: s__('ClusterIntegration|Select project to choose zone');
},
placeholderText() {
searchPlaceholderText() {
return s__('ClusterIntegration|Search zones');
},
},
created() {
eventHub.$on('projectSelected', this.fetchItems);
eventHub.$on('projectSelected', this.fetchZones);
},
methods: {
...mapActions(['setZone']),
fetchItems() {
...mapActions(['setZone', 'getZones']),
fetchZones() {
this.isLoading = true;
const request = this.service.zones.list({
project: this.selectedProject.projectId,
});
return request.then(
resp => {
let zoneToSelect;
this.items = resp.result.items;
this.getZones()
.then(() => {
if (this.defaultValue) {
const zoneToSelect = _.find(this.zones, item => item.name === this.defaultValue);
if (this.inputValue) {
zoneToSelect = _.find(this.items, item => item.name === this.inputValue);
this.setZone(zoneToSelect.name);
if (zoneToSelect) {
this.setZone(zoneToSelect.name);
}
}
this.isLoading = false;
this.hasErrors = false;
},
resp => {
})
.catch(() => {
this.isLoading = false;
this.hasErrors = true;
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch project zones: %{error}',
{ error: resp.result.error.message },
),
);
}
},
this,
);
});
},
},
};
......@@ -137,7 +118,7 @@ export default {
<div class="dropdown-menu dropdown-select">
<dropdown-search-input
v-model="searchQuery"
:placeholder-text="placeholderText"
:placeholder-text="searchPlaceholderText"
/>
<div class="dropdown-content">
<ul>
......
......@@ -21,10 +21,9 @@ const mountGkeProjectIdDropdown = () => {
createElement('gke-project-id-dropdown', {
props: {
docsUrl: el.dataset.docsurl,
service: gapi.client.cloudresourcemanager,
fieldName: hiddenInput.getAttribute('name'),
fieldId: hiddenInput.getAttribute('id'),
inputValue: hiddenInput.value,
defaultValue: hiddenInput.value,
},
}),
});
......@@ -44,10 +43,9 @@ const mountGkeZoneDropdown = () => {
render: createElement =>
createElement('gke-zone-dropdown', {
props: {
service: gapi.client.compute,
fieldName: hiddenInput.getAttribute('name'),
fieldId: hiddenInput.getAttribute('id'),
inputValue: hiddenInput.value,
defaultValue: hiddenInput.value,
},
}),
});
......@@ -67,10 +65,9 @@ const mountGkeMachineTypeDropdown = () => {
render: createElement =>
createElement('gke-machine-type-dropdown', {
props: {
service: gapi.client.compute,
fieldName: hiddenInput.getAttribute('name'),
fieldId: hiddenInput.getAttribute('id'),
inputValue: hiddenInput.value,
defaultValue: hiddenInput.value,
},
}),
});
......
/* global gapi */
import Flash from '~/flash';
import { sprintf } from '~/locale';
import * as types from './mutation_types';
import eventHub from '../eventhub';
......@@ -18,3 +22,85 @@ export const setMachineType = ({ commit }, selectedMachineType) => {
eventHub.$emit('machineTypeSelected');
};
export const getProjects = ({ commit }) =>
new Promise((resolve, reject) => {
const request = gapi.client.cloudresourcemanager.projects.list();
return request.then(
resp => {
commit(types.SET_FETCHED_PROJECTS, resp.result.projects);
resolve();
},
resp => {
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch your projects: %{error}',
{
error: resp.result.error.message,
},
),
);
}
reject();
},
);
});
export const getZones = ({ commit, state }) =>
new Promise((resolve, reject) => {
const request = gapi.client.compute.zones.list({
project: state.selectedProject.projectId,
});
return request.then(
resp => {
commit(types.SET_FETCHED_ZONES, resp.result.items);
resolve();
},
resp => {
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch project zones: %{error}',
{ error: resp.result.error.message },
),
);
}
reject();
},
);
});
export const getMachineTypes = ({ commit, state }) =>
new Promise((resolve, reject) => {
const request = gapi.client.compute.machineTypes.list({
project: state.selectedProject.projectId,
zone: state.selectedZone,
});
return request.then(
resp => {
commit(types.SET_FETCHED_MACHINE_TYPES, resp.result.items);
resolve();
},
resp => {
if (resp.result.error) {
Flash(
sprintf(
'ClusterIntegration|An error occured while trying to fetch zone machine types: %{error}',
{ error: resp.result.error.message },
),
);
}
reject();
},
);
});
......@@ -17,5 +17,8 @@ export default new Vuex.Store({
},
selectedZone: '',
selectedMachineType: '',
fetchedProjects: [],
fetchedZones: [],
fetchedMachineTypes: [],
},
});
export const SET_PROJECT = 'SET_PROJECT';
export const SET_ZONE = 'SET_ZONE';
export const SET_MACHINE_TYPE = 'SET_MACHINE_TYPE';
export const SET_FETCHED_PROJECTS = 'SET_FETCHED_PROJECTS';
export const SET_FETCHED_ZONES = 'SET_FETCHED_ZONES';
export const SET_FETCHED_MACHINE_TYPES = 'SET_FETCHED_MACHINE_TYPES';
......@@ -10,4 +10,13 @@ export default {
[types.SET_MACHINE_TYPE](state, selectedMachineType) {
Object.assign(state, { selectedMachineType });
},
[types.SET_FETCHED_PROJECTS](state, fetchedProjects) {
Object.assign(state, { fetchedProjects });
},
[types.SET_FETCHED_ZONES](state, fetchedZones) {
Object.assign(state, { fetchedZones });
},
[types.SET_FETCHED_MACHINE_TYPES](state, fetchedMachineTypes) {
Object.assign(state, { fetchedMachineTypes });
},
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment