This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit 6c36ecc74c79d5497b152c93d593fef1a39386d3 Author: Marcus Christie <[email protected]> AuthorDate: Fri Sep 7 12:17:57 2018 -0400 AIRAVATA-2876 List of deployments --- .../applications/ApplicationDeploymentsList.vue | 84 ++++++++++++++++++++-- .../applications/ApplicationEditorContainer.vue | 24 +++++-- .../static/django_airavata_admin/src/router.js | 13 ++-- .../src/store/applications/app_deployments.js | 47 ++++++++++++ .../src/store/applications/index.js | 2 + .../api/static/django_airavata_api/js/index.js | 2 +- .../django_airavata_api/js/service_config.js | 23 +++++- .../js/services/ApplicationDeploymentService.js | 37 ---------- 8 files changed, 178 insertions(+), 54 deletions(-) diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentsList.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentsList.vue index f7a53c8..29e29af 100644 --- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentsList.vue +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationDeploymentsList.vue @@ -1,13 +1,85 @@ <template> - <div> - Application Deployments List - <router-link :to="{name: 'application_deployment', params: {id: 'foo', deployment_id: 'bar'}}">Deployment</router-link> - </div> + <list-layout @add-new-item="newApplicationDeployment" :items="deployments" title="Application Deployments" new-item-button-text="New Deployment"> + <template slot="item-list" slot-scope="slotProps"> + + <b-table striped hover :fields="fields" :items="slotProps.items" sort-by="computeHostId"> + <template slot="action" slot-scope="data"> + <router-link :to="{name: 'application_deployment', params: {id: id, deployment_id: data.item.appDeploymentId}}"> + Edit + <i class="fa fa-edit" aria-hidden="true"></i> + </router-link> + <a href="#" class="text-danger" @click.prevent="removeApplicationDeployment(data.item)" v-if="data.item.userHasWriteAccess"> + Delete + <i class="fa fa-trash" aria-hidden="true"></i> + </a> + </template> + </b-table> + </template> + </list-layout> </template> <script> +import { models, services } from "django-airavata-api"; +import { layouts } from "django-airavata-common-ui"; + export default { - name: 'application-deployments-list' -} + name: "application-deployments-list", + components: { + "list-layout": layouts.ListLayout + }, + props: { + deployments: { + type: Array, + required: true + }, + id: { + // app module id + type: String, + required: true + } + }, + data() { + return { + computeResourceNames: null + }; + }, + computed: { + fields() { + return [ + { + label: "Compute Resource", + key: "computeHostId", + sortable: true, + formatter: value => this.getComputeResourceName(value) + }, + { + label: "Description", + key: "appDeploymentDescription" + }, + { + label: "Action", + key: "action" + } + ]; + } + }, + mounted() { + services.ComputeResourceService.names().then( + names => (this.computeResourceNames = names) + ); + }, + methods: { + getComputeResourceName(computeResourceId) { + if ( + this.computeResourceNames && + computeResourceId in this.computeResourceNames + ) { + return this.computeResourceNames[computeResourceId]; + } else { + return computeResourceId.substring(0, 10) + "..."; + } + } + } +}; </script> diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationEditorContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationEditorContainer.vue index 9b8e21b..a31261d 100644 --- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationEditorContainer.vue +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/applications/ApplicationEditorContainer.vue @@ -9,7 +9,7 @@ </div> <div class="row"> <div class="col"> - <b-nav tabs> + <b-nav tabs class="mb-3"> <b-nav-item exact-active-class="active" exact :to="{name: id ? 'application_module' : 'new_application_module', params: {id: id}}">Details</b-nav-item> <b-nav-item exact-active-class="active" exact :to="{name: 'application_interface', params: {id: id}}" :disabled="!id">Interface</b-nav-item> <b-nav-item active-class="active" :to="{name: 'application_deployments', params: {id: id}}" :disabled="!id">Deployments</b-nav-item> @@ -17,8 +17,8 @@ <router-view name="module" v-if="module" v-model="module" @save="saveModule" @cancel="cancelModule" /> <router-view name="interface" v-if="appInterface" v-model="appInterface" @save="saveInterface" @cancel="cancelInterface" /> - <router-view name="deployments" /> - <router-view name="deployment" /> + <router-view name="deployments" v-if="deployments" :deployments="deployments" /> + <router-view name="deployment" v-if="deployment" v-model="deployment" @save="saveDeployment" @cancel="cancelDeployment" /> </div> </div> </div> @@ -38,7 +38,6 @@ export default { return { module: null, appInterface: null, - deployments: null, deployment: null }; }, @@ -53,7 +52,11 @@ export default { } }, ...mapState("applications/modules", ["currentModule"]), - ...mapState("applications/interfaces", ["currentInterface"]) + ...mapState("applications/interfaces", ["currentInterface"]), + ...mapState("applications/deployments", [ + "currentDeployment", + "deployments" + ]) }, created() { this.initialize(); @@ -69,6 +72,12 @@ export default { "createApplicationInterface", "updateApplicationInterface" ]), + ...mapActions("applications/deployments", [ + "loadApplicationDeployments", + "loadApplicationDeployment", + "createApplicationDeployment", + "updateApplicationDeployment" + ]), initialize() { // TODO: move this to applications store? if (this.currentModule && this.currentModule.appModuleId === this.id) { @@ -76,11 +85,13 @@ export default { this.loadApplicationInterface(this.id).catch(error => { notifications.NotificationList.addError(error); }); + this.loadApplicationDeployments(this.id); } else if (this.id) { this.loadApplicationModule(this.id); this.loadApplicationInterface(this.id).catch(error => { notifications.NotificationList.addError(error); }); + this.loadApplicationDeployments(this.id); } else { this.module = new models.ApplicationModule(); } @@ -142,6 +153,9 @@ export default { }, currentInterface: function(newInterface) { this.appInterface = newInterface.clone(); + }, + currentDeployment: function(newDeployment) { + this.deployment = newDeployment.clone(); } } }; diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/router.js b/django_airavata/apps/admin/static/django_airavata_admin/src/router.js index 9e737a2..23d68cc 100644 --- a/django_airavata/apps/admin/static/django_airavata_admin/src/router.js +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/router.js @@ -69,19 +69,24 @@ const routes = [ path: 'deployments', components: { deployments: ApplicationDeploymentsList }, - name: 'application_deployments' + name: 'application_deployments', + props: { + deployments: true + } }, { path: 'deployments/:deployment_id', components: { deployment: ApplicationDeploymentEditor }, name: 'application_deployment', - props: true + props: { + deployment: true + } }, ] }, - {path: '/applications', component: ApplicationsDashboard}, - {path: '/experiments', component: ExperimentsDashboard, name: 'experiments_dashboard'}, + { path: '/applications', component: ApplicationsDashboard }, + { path: '/experiments', component: ExperimentsDashboard, name: 'experiments_dashboard' }, { path: '/group-resource-profiles/new', component: GroupComputeResourcePreference, name: 'new_group_resource_preference', props: true diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/app_deployments.js b/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/app_deployments.js new file mode 100644 index 0000000..c042e8c --- /dev/null +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/app_deployments.js @@ -0,0 +1,47 @@ +import { services, models } from 'django-airavata-api' + +export default { + namespaced: true, + state: { + currentDeployment: null, + deployments: null, + }, + mutations: { + setCurrentDeployment(state, currentDeployment) { + state.currentDeployment = currentDeployment; + }, + setDeployments(state, deployments) { + state.deployments = deployments; + } + }, + actions: { + loadApplicationDeployments({ commit }, appModuleId) { + services.ApplicationModuleService.getApplicationDeployments({ lookup: appModuleId }) + .then(appDeployments => { + commit('setDeployments', appDeployments); + return appDeployments; + }); + }, + loadApplicationDeployment({ commit }, appDeploymentId) { + services.ApplicationDeploymentService.retrieve({ lookup: appDeploymentId }) + .then(appDeployment => { + commit('setCurrentDeployment', appDeployment); + return appDeployment; + }); + }, + createApplicationDeployment({ commit }, appDeployment) { + return services.ApplicationDeploymentService.create({ data: appDeployment }) + .then(appDeployment => { + commit('setCurrentDeployment', appDeployment); + return appDeployment; + }); + }, + updateApplicationDeployment({ commit }, appDeployment) { + return services.ApplicationDeploymentService.update({ lookup: appDeployment.appDeploymentId, data: appDeployment }) + .then(appDeployment => { + commit('setCurrentDeployment', appDeployment); + return appDeployment; + }) + } + } +} diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/index.js b/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/index.js index b83d783..5a9bbdc 100644 --- a/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/index.js +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/store/applications/index.js @@ -1,10 +1,12 @@ import interfaces from './app_interfaces' import modules from './app_modules' +import deployments from './app_deployments' export default { namespaced: true, modules: { interfaces, modules, + deployments } } diff --git a/django_airavata/apps/api/static/django_airavata_api/js/index.js b/django_airavata/apps/api/static/django_airavata_api/js/index.js index ecb1e59..6546388 100644 --- a/django_airavata/apps/api/static/django_airavata_api/js/index.js +++ b/django_airavata/apps/api/static/django_airavata_api/js/index.js @@ -76,7 +76,7 @@ exports.models = { } exports.services = { - ApplicationDeploymentService, + ApplicationDeploymentService: ServiceFactory.service("ApplicationDeployments"), ApplicationInterfaceService: ServiceFactory.service("ApplicationInterfaces"), ApplicationModuleService: ServiceFactory.service("ApplicationModules"), CredentialSummaryService: ServiceFactory.service("CredentialSummaries"), diff --git a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js index a3536a3..a737ea2 100644 --- a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js +++ b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js @@ -6,6 +6,7 @@ import GroupResourceProfile from './models/GroupResourceProfile' import SharedEntity from './models/SharedEntity' import UserProfile from './models/UserProfile' import ApplicationInterfaceDefinition from './models/ApplicationInterfaceDefinition'; +import BatchQueue from './models/BatchQueue'; const post = "post"; const get = "get"; @@ -42,7 +43,22 @@ pagination:true # whether to treat the response as a paginated response export default { "ApplicationDeployments": { url: "/api/application-deployments", - viewSet: true, + viewSet: [{ + name: "list" + }, { + name: "create" + }, { + name: "retrieve" + }, { + name: "update" + }, { + name: "delete" + }, { + name: "getQueues", + url: "/api/application-deployments/<lookup>/queues/", + requestType: 'get', + modelClass: BatchQueue + }], queryParams: ['appModuleId', 'groupResourceProfileId'], modelClass: ApplicationDeploymentDescription, }, @@ -68,6 +84,11 @@ export default { url: "/api/applications/<lookup>/application_interface/", requestType: 'get', modelClass: ApplicationInterfaceDefinition + }, { + name: "getApplicationDeployments", + url: "/api/applications/<lookup>/application_deployments/", + requestType: 'get', + modelClass: ApplicationDeploymentDescription }], modelClass: ApplicationModule, }, diff --git a/django_airavata/apps/api/static/django_airavata_api/js/services/ApplicationDeploymentService.js b/django_airavata/apps/api/static/django_airavata_api/js/services/ApplicationDeploymentService.js deleted file mode 100644 index ea43477..0000000 --- a/django_airavata/apps/api/static/django_airavata_api/js/services/ApplicationDeploymentService.js +++ /dev/null @@ -1,37 +0,0 @@ - -import ApplicationDeploymentDescription from '../models/ApplicationDeploymentDescription' -import BatchQueue from '../models/BatchQueue' - -import FetchUtils from '../utils/FetchUtils' - -class ApplicationDeploymentService { - list(data = null) { - if (data) { - return Promise.resolve(data.map(result => new ApplicationDeploymentDescription(result))); - } else { - return FetchUtils.get('/api/application-deployments/') - .then(json => json.map(result => new ApplicationDeploymentDescription(result))); - } - } - - create(project) { - // TODO - } - - update() { - // TODO - } - - get(appDeploymentId) { - return FetchUtils.get('/api/application-deployments/' + encodeURIComponent(appDeploymentId) + '/') - .then(json => new ApplicationDeploymentDescription(json)) - } - - getQueues(appDeploymentId) { - return FetchUtils.get('/api/application-deployments/' + encodeURIComponent(appDeploymentId) + '/queues/') - .then(json => json.map(result => new BatchQueue(result))); - } -} - -// Export as a singleton -export default new ApplicationDeploymentService(); \ No newline at end of file
