You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2018/02/22 22:10:37 UTC
[airavata-django-portal] 01/02: AIRAVATA-2688 Group edit view and
refactored Autocomplete
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 0acb40596366838e195d515b4208de6578f9e6fe
Author: Marcus Christie <ma...@iu.edu>
AuthorDate: Thu Feb 22 15:47:57 2018 -0500
AIRAVATA-2688 Group edit view and refactored Autocomplete
---
.../js/services/GroupService.js | 30 +++++-------
.../js/group-create-entry-point.js | 6 +--
.../js/group-edit-entry-point.js | 25 ++++++++++
.../js/groups_components/Autocomplete.vue | 57 +++++++++++++---------
.../js/groups_components/GroupCreateContainer.vue | 31 ++++++++++++
.../js/groups_components/GroupEditContainer.vue | 37 ++++++++++++++
.../{GroupCreate.vue => GroupEditor.vue} | 24 +++++----
.../js/groups_components/GroupsManageContainer.vue | 5 +-
.../django_airavata_groups/group_edit.html | 42 ++++------------
.../django_airavata_groups/groups_create.html | 32 ++----------
django_airavata/apps/groups/urls.py | 2 +-
django_airavata/apps/groups/views.py | 41 ++--------------
django_airavata/apps/groups/webpack.config.js | 3 +-
django_airavata/static/common/package-lock.json | 23 ++++++++-
14 files changed, 200 insertions(+), 158 deletions(-)
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/services/GroupService.js b/django_airavata/apps/api/static/django_airavata_api/js/services/GroupService.js
index 015cc38..5ca6e9d 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/services/GroupService.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/services/GroupService.js
@@ -5,7 +5,7 @@ import FetchUtils from '../utils/FetchUtils'
class GroupService {
- listMemberGroups(data={}) {
+ list(data={}) {
if (data && data.results) {
return Promise.resolve(new PaginationIterator(data, Group));
} else {
@@ -17,30 +17,24 @@ class GroupService {
}
}
- listOwnerGroups(data={}) {
- if (data && data.results) {
- return Promise.resolve(new PaginationIterator(data, Group));
- }
- else {
- return fetch('/api/groups/', {
- credentials: 'include'
- })
- .then(response => response.json())
- .then(json => new PaginationIterator(json, Group));
- }
- }
-
create(group) {
return FetchUtils.post('/api/groups/', JSON.stringify(group))
.then(result => new Group(result))
}
- update() {
- // TODO
+ update(group) {
+ return FetchUtils.put('/api/groups/' + encodeURIComponent(group.id) + '/', JSON.stringify(group))
+ .then(result => new Group(result));
}
- get() {
- // TODO
+ get(groupId, data = null) {
+ if (data) {
+ return Promise.resolve(new Group(data));
+ } else {
+ return FetchUtils.get('/api/groups/'
+ + encodeURIComponent(groupId) + '/')
+ .then(result => new Group(result));
+ }
}
}
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/group-create-entry-point.js b/django_airavata/apps/groups/static/django_airavata_groups/js/group-create-entry-point.js
index ab5a023..96e8767 100644
--- a/django_airavata/apps/groups/static/django_airavata_groups/js/group-create-entry-point.js
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/group-create-entry-point.js
@@ -1,6 +1,6 @@
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
-import GroupCreate from './groups_components/GroupCreate.vue'
+import GroupCreateContainer from './groups_components/GroupCreateContainer.vue'
// This is imported globally on the website so no need to include it again in this view
// import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
@@ -9,8 +9,8 @@ Vue.use(BootstrapVue);
new Vue({
el: "#create-group",
- template: '<group-create></group-create>',
+ template: '<group-create-container></group-create-container>',
components: {
- GroupCreate
+ GroupCreateContainer
}
})
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/group-edit-entry-point.js b/django_airavata/apps/groups/static/django_airavata_groups/js/group-edit-entry-point.js
new file mode 100644
index 0000000..8303e66
--- /dev/null
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/group-edit-entry-point.js
@@ -0,0 +1,25 @@
+import Vue from 'vue'
+import BootstrapVue from 'bootstrap-vue'
+import GroupEditContainer from './groups_components/GroupEditContainer.vue'
+// This is imported globally on the website so no need to include it again in this view
+// import 'bootstrap/dist/css/bootstrap.css'
+import 'bootstrap-vue/dist/bootstrap-vue.css'
+
+Vue.use(BootstrapVue);
+
+new Vue({
+ el: "#edit-group",
+ template: '<group-edit-container :groupId="groupId"></group-edit-container>',
+ data: {
+ groupId: null,
+ },
+ components: {
+ GroupEditContainer,
+ },
+ beforeMount: function() {
+ if (this.$el.dataset.groupId) {
+ this.groupId = this.$el.dataset.groupId;
+ console.log("groupId", this.groupId);
+ }
+ }
+})
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/Autocomplete.vue b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/Autocomplete.vue
index 9352805..12e57cb 100644
--- a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/Autocomplete.vue
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/Autocomplete.vue
@@ -1,12 +1,12 @@
<template>
<div style="position:relative">
- <span class="selected-cards" style="position:relative" v-for="item in selected" v-bind:key="item.id">
- <b-button disabled variant="warning">
- {{ item.name }} <b-badge variant="light"><a href="#" @click="removeClick(item)">x</a></b-badge>
- </b-button>
+ <span class="selected-cards" style="position:relative">
+ <b-button variant="warning" v-for="item in selected" v-bind:key="item.id" @click="removeClick(item)">
+ {{ item.name }} <b-badge variant="light"><a href="#">x</a></b-badge>
+ </b-button>
</span>
<hr>
- <input class="form-control" type="text" :value="value" placeholder="Type to get suggestions..." @input="updateValue($event.target.value)"
+ <input class="form-control" type="text" :value="searchValue" placeholder="Type to get suggestions..." @input="updateSearchValue($event.target.value)"
@keydown.enter = 'enter'
@keydown.down = 'down'
@keydown.up = 'up'
@@ -25,8 +25,8 @@ export default {
props: {
value: {
- type: String,
- required: true
+ type: Array,
+ required: false
},
suggestions: {
@@ -39,19 +39,25 @@ export default {
return {
open: false,
current: 0,
- selected: [],
+ localValue: this.value ? this.value.slice() : [],
+ searchValue: '',
}
},
computed: {
filtered () {
return this.suggestions.filter((data) => {
- return data.name.indexOf(this.value) >= 0
+ return data.name.indexOf(this.searchValue) >= 0
})
},
+ selected () {
+ return this.suggestions.filter((suggestion) => {
+ return this.localValue.indexOf(suggestion.id) >= 0;
+ });
+ }
},
methods: {
- updateValue (value) {
+ updateSearchValue (value) {
if (this.open === false) {
this.open = true
this.current = 0
@@ -59,16 +65,15 @@ export default {
if(value===''){
this.open = false;
}
- this.$emit('input', value)
+ this.searchValue = value;
},
enter () {
- // this.$emit('input', this.filtered[this.current].name)
- this.$emit('input','');
var index = this.suggestions.indexOf(this.filtered[this.current].name);
- if(this.selected.indexOf(this.filtered[this.current])==-1){
- this.selected.push(this.filtered[this.current]);
+ if(this.localValue.indexOf(this.filtered[this.current].id)==-1){
+ this.localValue.push(this.filtered[this.current].id);
}
- this.$emit('updateSelected',this.selected);
+ this.$emit('input',this.localValue);
+ this.searchValue = '';
this.open = false
},
up () {
@@ -85,20 +90,24 @@ export default {
return index === this.current
},
suggestionClick (index) {
- // this.$emit('input', this.filtered[index].name)
- this.$emit('input','');
- if(this.selected.indexOf(this.filtered[index])==-1) {
- this.selected.push(this.filtered[index]);
+ if(this.localValue.indexOf(this.filtered[index].id)==-1) {
+ this.localValue.push(this.filtered[index].id);
}
- this.$emit('updateSelected',this.selected);
+ this.$emit('input',this.localValue);
+ this.searchValue = '';
this.open = false;
},
removeClick(data) {
- var index = this.selected.indexOf(data);
- this.selected.splice(index,1);
- this.$emit('updateSelected',this.selected);
+ var index = this.localValue.indexOf(data.id);
+ this.localValue.splice(index,1);
+ this.$emit('input',this.localValue);
}
}
}
</script>
+<style>
+.selected-cards > button + button {
+ margin-left: 10px;
+}
+</style>
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreateContainer.vue b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreateContainer.vue
new file mode 100644
index 0000000..81b1dd9
--- /dev/null
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreateContainer.vue
@@ -0,0 +1,31 @@
+<template>
+ <group-editor :group="newGroup"></group-editor>
+</template>
+
+<script>
+
+import GroupOwnerList from './GroupOwnerList.vue';
+import GroupMemberList from './GroupMemberList.vue';
+import GroupEditor from './GroupEditor.vue';
+
+import { models, services } from 'django-airavata-api'
+import { components as comps } from 'django-airavata-common-ui'
+
+export default {
+ name: 'group-create-container',
+ data () {
+ return {
+ newGroup: new models.Group(),
+ }
+ },
+ components: {
+ GroupEditor,
+ },
+ methods: {
+ },
+ computed: {
+ },
+ beforeMount: function () {
+ },
+}
+</script>
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditContainer.vue b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditContainer.vue
new file mode 100644
index 0000000..19907d9
--- /dev/null
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditContainer.vue
@@ -0,0 +1,37 @@
+<template>
+ <group-editor v-if="group" :group="group"></group-editor>
+</template>
+
+<script>
+
+import GroupEditor from './GroupEditor.vue';
+
+import { models, services } from 'django-airavata-api'
+import { components as comps } from 'django-airavata-common-ui'
+
+export default {
+ name: 'group-edit-container',
+ props: {
+ groupId: {
+ type: String,
+ required: true,
+ }
+ },
+ data () {
+ return {
+ group: null,
+ }
+ },
+ components: {
+ GroupEditor,
+ },
+ methods: {
+ },
+ computed: {
+ },
+ mounted: function () {
+ services.GroupService.get(this.groupId)
+ .then(group => this.group = group);
+ },
+}
+</script>
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreate.vue b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditor.vue
similarity index 79%
rename from django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreate.vue
rename to django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditor.vue
index 90dbadc..ddba0dc 100644
--- a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupCreate.vue
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupEditor.vue
@@ -7,17 +7,17 @@
<b-form v-if="show">
<b-form-group id="group1" label="Group Name:" label-for="group_name" description="Name should only contain Alpha Characters">
- <b-form-input id="group_name" type="text" v-model="newGroup.name" required placeholder="Enter group name">
+ <b-form-input id="group_name" type="text" v-model="localGroup.name" required placeholder="Enter group name">
</b-form-input>
</b-form-group>
<b-form-group id="group2" label="Description:" label-for="description">
- <b-form-textarea id="description" type="text" :rows="6" v-model="newGroup.description" required placeholder="Enter description of the group">
+ <b-form-textarea id="description" type="text" :rows="6" v-model="localGroup.description" required placeholder="Enter description of the group">
</b-form-textarea>
</b-form-group>
<b-form-group id="group3" label="Add Members:" label-for="members">
- <autocomplete id="members" :suggestions="suggestions" v-model="selection" v-on:updateSelected="updateSelectedValue"></autocomplete>
+ <autocomplete id="members" :suggestions="suggestions" v-model="localGroup.members"></autocomplete>
</b-form-group>
<b-button @click="submitForm" variant="primary">Submit</b-button>
@@ -32,10 +32,16 @@ import { models, services } from 'django-airavata-api'
import Autocomplete from './Autocomplete.vue'
export default {
+ props: {
+ group: {
+ type: models.Group,
+ required: true,
+ },
+ },
data () {
return {
selection: '',
- newGroup: new models.Group(),
+ localGroup: this.group.clone(),
show: true,
selected: [],
showDismissibleAlert: {'variant':'success', 'message':'no data', 'dismissable':false},
@@ -51,12 +57,10 @@ export default {
for(var i=0;i<this.selected.length;i++) {
temp.push(this.selected[i].id);
}
- this.newGroup.members = temp;
- console.log(JSON.stringify(this.newGroup));
- services.GroupService.create(this.newGroup)
- .then(result => {
- // TODO: redirect to the group view page
- window.location.assign("/groups/");
+ this.localGroup.members = temp;
+ services.GroupService.create(this.localGroup)
+ .then(group => {
+ this.$emit('saved', result);
})
.catch(error => {
this.showDismissibleAlert.dismissable = true;
diff --git a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupsManageContainer.vue b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupsManageContainer.vue
index 78a9f70..1d679ca 100755
--- a/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupsManageContainer.vue
+++ b/django_airavata/apps/groups/static/django_airavata_groups/js/groups_components/GroupsManageContainer.vue
@@ -67,10 +67,7 @@ export default {
},
},
beforeMount: function () {
- services.GroupService.listMemberGroups(this.groupsDataMembers)
- .then(result => this.groupMembersPaginator = result);
-
- services.GroupService.listOwnerGroups(this.groupsDataOwners)
+ services.GroupService.list(this.groupsDataOwners)
.then(result => this.groupOwnersPaginator = result);
},
}
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html b/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
index 507a456..c46fcc8 100755
--- a/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
@@ -1,38 +1,16 @@
{% extends 'base.html' %}
-{% block content %}
+{% load static %}
-<h1 align="center">Edit Group</h1>
-<br>
-{% block body %}
-<div class="container">
- {% if user.is_authenticated %}
- <h5>Group Name: {{ group_name }}</h5>
- <div class="row">
- <div class="col-lg-6">
- <h3>Add</h3>
- <form action="" method="post">
- {% csrf_token %}
- {{ add_form.as_p }}
- <button class="btn btn-primary btn-xs" type="submit" role="button" name="add">Add</button>
- </form>
- </div>
- <div class="col-lg-6">
- <h3>Remove</h3>
- <form action="" method="post">
- {% csrf_token %}
- {{ remove_form.as_p }}
- <button class="btn btn-primary btn-xs" type="submit" role="button" name="remove" onclick="return confirm('Are you sure you want to remove the selected members from the group? This action cannot be undone!')">Remove</button>
- </form>
- </div>
- </div>
- <br>
- <br>
- <p align="right"><a class="btn btn-primary btn-xs" href="{% url 'django_airavata_groups:manage' %}" role="button">Back</a></p>
- {% else %}
- <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
- {% endif %}
-</div>
+{% block css %}
+{{ block.super }}
+<link rel=stylesheet type=text/css href="{% static 'django_airavata_groups/dist/group-edit.css' %}">
{% endblock %}
+{% block content %}
+<div id="edit-group" data-group-id="{{ group_id }}"></div>
{% endblock content %}
+
+{% block scripts %}
+<script src="{% static 'django_airavata_groups/dist/group-edit.js' %}"></script>
+{% endblock %}
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html b/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
index fc728de..aeaf012 100755
--- a/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
@@ -2,6 +2,11 @@
{% load static %}
+{% block css %}
+{{ block.super }}
+<link rel=stylesheet type=text/css href="{% static 'django_airavata_groups/dist/group-create.css' %}">
+{% endblock %}
+
{% block content %}
<div id="create-group"></div>
{% endblock content %}
@@ -9,30 +14,3 @@
{% block scripts %}
<script src="{% static 'django_airavata_groups/dist/group-create.js' %}"></script>
{% endblock %}
-
-
-<!-- OLD CODE -->
-
-<!--
-<h1 align="center">Create a Group</h1>
-<br>
-{% block body %}
-<div class="container">
- {% if user.is_authenticated %}
- <div class="row">
- <div class="col-md-12">
- <h3>Enter Group Details</h3>
- <form action="" method="post">
- {% csrf_token %}
- {{ form.as_p }}
- <button class="btn btn-primary btn-xs" type="submit" role="button">Submit</button>
- </form>
- </div>
- </div>
- <br>
- <p align="right"><a class="btn btn-primary btn-xs" href="{% url 'django_airavata_groups:manage' %}" role="button">Back</a></p>
- {% else %}
- <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
- {% endif %}
-</div>
-{% endblock %} -->
diff --git a/django_airavata/apps/groups/urls.py b/django_airavata/apps/groups/urls.py
index 7a599d0..e60076b 100755
--- a/django_airavata/apps/groups/urls.py
+++ b/django_airavata/apps/groups/urls.py
@@ -8,7 +8,7 @@ urlpatterns = [
url(r'^$', views.groups_manage, name="manage"),
url(r'^create/', views.groups_create, name='create'),
url(r'^view/', views.view_group, name='view'),
- url(r'^edit/', views.edit_group, name='edit'),
+ url(r'^edit/(?P<group_id>[^/]+)/$', views.edit_group, name='edit'),
url(r'^delete/', views.delete_group, name='delete'),
url(r'^leave/', views.leave_group, name='leave'),
]
\ No newline at end of file
diff --git a/django_airavata/apps/groups/views.py b/django_airavata/apps/groups/views.py
index c448618..69ce264 100755
--- a/django_airavata/apps/groups/views.py
+++ b/django_airavata/apps/groups/views.py
@@ -102,48 +102,15 @@ def view_group(request):
logger.exception("Failed to load the group details")
return redirect('/groups')
-@login_required
-def edit_group(request):
-
- gateway_id = settings.GATEWAY_ID
- group_id = request.GET.get('group_id')
- users = request.POST.getlist('users')
- members = request.POST.getlist('members')
-
- try:
- user_choices = request.sharing_client.getUsers(gateway_id, 0, -1)
- member_choices = request.sharing_client.getGroupMembersOfTypeUser(gateway_id, group_id, 0, -1)
- for user in user_choices:
- for member in member_choices:
- if user.userId == member.userId:
- user_choices.remove(user)
- if request.method == 'POST':
- add_form = AddForm(request.POST, user_choices=[(user.userId, user.userId) for user in user_choices])
- remove_form = RemoveForm(request.POST, user_choices=[(member.userId, member.userId) for member in member_choices])
- if 'add' in request.POST:
- if add_form.is_valid():
- add = request.sharing_client.addUsersToGroup(gateway_id, users, group_id)
- messages.success(request, 'Selected members have been added successfully!')
- return redirect('/groups')
- elif 'remove' in request.POST:
- if remove_form.is_valid():
- remove = request.sharing_client.removeUsersFromGroup(gateway_id, members, group_id)
- messages.success(request, 'Selected members have been removed successfully!')
- return redirect('/groups')
-
- else:
- add_form = AddForm(user_choices=[(user.userId, user.userId) for user in user_choices])
- remove_form = RemoveForm(user_choices=[(member.userId, member.userId) for member in member_choices])
- group_details = request.sharing_client.getGroup(gateway_id, group_id)
- except Exception as e:
- logger.exception("Failed to edit the group")
- return redirect('/groups')
+@login_required
+def edit_group(request, group_id):
return render(request, 'django_airavata_groups/group_edit.html', {
- 'group_name': group_details.name, 'add_form': add_form, 'remove_form': remove_form
+ 'group_id': group_id,
})
+
@login_required
def delete_group(request):
diff --git a/django_airavata/apps/groups/webpack.config.js b/django_airavata/apps/groups/webpack.config.js
index f3196ff..1f68b37 100755
--- a/django_airavata/apps/groups/webpack.config.js
+++ b/django_airavata/apps/groups/webpack.config.js
@@ -6,6 +6,7 @@ module.exports = {
entry: {
'group-list': './static/django_airavata_groups/js/group-listing-entry-point.js',
'group-create': './static/django_airavata_groups/js/group-create-entry-point.js',
+ 'group-edit': './static/django_airavata_groups/js/group-edit-entry-point.js',
},
output: {
path: path.resolve(__dirname, './static/django_airavata_groups/dist/'),
@@ -61,7 +62,7 @@ module.exports = {
plugins: [
// Exclude all but the 'en' locale from moment's locales
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /^en$/),
- new ExtractTextPlugin("main.css"),
+ new ExtractTextPlugin("[name].css"),
]
}
diff --git a/django_airavata/static/common/package-lock.json b/django_airavata/static/common/package-lock.json
index 1f00f23..10905ae 100644
--- a/django_airavata/static/common/package-lock.json
+++ b/django_airavata/static/common/package-lock.json
@@ -1927,7 +1927,28 @@
}
},
"django-airavata-api": {
- "version": "file:../../apps/api"
+ "version": "file:../../apps/api",
+ "requires": {
+ "url-parse": "1.2.0"
+ },
+ "dependencies": {
+ "querystringify": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "bundled": true
+ },
+ "url-parse": {
+ "version": "1.2.0",
+ "bundled": true,
+ "requires": {
+ "querystringify": "1.0.0",
+ "requires-port": "1.0.0"
+ }
+ }
+ }
},
"dns-equal": {
"version": "1.0.0",
--
To stop receiving notification emails like this one, please contact
machristie@apache.org.