This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch AIRAVATA-3562 in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit 8ce0bb667173656db21ba6571d4d7eb52c99e846 Author: Marcus Christie <[email protected]> AuthorDate: Fri Mar 11 12:47:12 2022 -0500 AIRAVATA-3562 Mocked up UI for admins to edit extended user profile fields --- django_airavata/apps/admin/apps.py | 2 +- .../users/ExtendedUserProfileContainer.vue | 181 +++++++++++++++++++++ .../static/django_airavata_admin/src/router.js | 6 + django_airavata/apps/admin/urls.py | 1 + django_airavata/apps/admin/views.py | 6 + 5 files changed, 195 insertions(+), 1 deletion(-) diff --git a/django_airavata/apps/admin/apps.py b/django_airavata/apps/admin/apps.py index 82876b9..a9a6642 100644 --- a/django_airavata/apps/admin/apps.py +++ b/django_airavata/apps/admin/apps.py @@ -25,7 +25,7 @@ class AdminConfig(AiravataAppConfig): 'label': 'Manage Users', 'icon': 'fa fa-users', 'url': 'django_airavata_admin:users', - 'active_prefixes': ['users'], + 'active_prefixes': ['users', 'extended-user-profile'], 'enabled': lambda req: (req.is_gateway_admin or req.is_read_only_gateway_admin), }, diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/ExtendedUserProfileContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/ExtendedUserProfileContainer.vue new file mode 100644 index 0000000..faaba0b --- /dev/null +++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/ExtendedUserProfileContainer.vue @@ -0,0 +1,181 @@ +<template> + <div> + <div class="row"> + <div class="col-auto mr-auto"> + <h1 class="h4 mb-4">Extended User Profile Editor</h1> + </div> + </div> + <div v-for="field in fields" class="row" :key="field.id"> + <div class="col"> + <b-card :title="'Field: ' + field.name"> + <b-form-group label="Name"> + <b-form-input v-model="field.name" /> + </b-form-group> + <b-form-group label="Description"> + <b-form-input v-model="field.description" /> + </b-form-group> + <b-form-group label="Required"> + <b-form-checkbox v-model="field.required" /> + </b-form-group> + <b-form-group label="Type"> + <b-form-select v-model="field.type" :options="fieldTypeOptions" /> + </b-form-group> + <b-card + title="Options" + v-if=" + field.type === 'single-select' || field.type === 'multi-select' + " + > + <template v-for="option in field.options"> + <b-input-group :key="option.id"> + <b-form-input v-model="option.name" /> + <b-input-group-append> + <b-button @click="deleteOption(field, option)" + >Delete</b-button + > + </b-input-group-append> + </b-input-group> + </template> + <b-button @click="addOption(field)">Add Option</b-button> + </b-card> + <template v-if="field.links && field.links.length > 0"> + <b-card title="Links" v-for="link in field.links" :key="link.id"> + <b-form-group label="Title"> + <b-form-input v-model="link.title" /> + </b-form-group> + <b-form-group label="URL"> + <b-form-input v-model="link.url" /> + </b-form-group> + <b-form-group label="Show as link?"> + <b-form-checkbox v-model="link.display_link" /> + </b-form-group> + <b-form-group label="Show inline?"> + <b-form-checkbox v-model="link.display_inline" /> + </b-form-group> + </b-card> + </template> + <b-button v-if="!field.links" @click="addLink(field)" + >Add Link</b-button + > + <template v-if="field.conditional"> + <b-card title="Conditional"> + When + <br /> + <template v-for="condition in field.conditional.conditions"> + <div :key="condition.id"> + <b-form-select + :options="getConditionFieldOptions(field)" + v-model="condition.field" + /> + = + <b-form-select + v-if=" + (condition.field && + condition.field.type === 'multi-select') || + condition.field.type === 'single-select' || + condition.field.type === 'user-agreement' + " + :disabled="condition.field" + :options="getConditionFieldValueOptions(condition.field)" + v-model="condition.value" + /> + <b-form-input + v-else-if=" + condition.field && condition.field.type === 'text' + " + v-model="condition.value" + /> + </div> + </template> + </b-card> + </template> + <b-button v-if="!field.conditional" @click="addConditional(field)" + >Add Conditional</b-button + > + </b-card> + </div> + </div> + <div class="row"> + <div class="col"> + <b-button variant="primary" @click="addField"> Add Field </b-button> + </div> + </div> + <div class="row mt-4"> + <div class="col"> + <b-button variant="primary" @click="save">Save</b-button> + </div> + </div> + <pre>{{ JSON.stringify(fields, null, 4) }}</pre> + </div> +</template> + +<script> +export default { + data() { + return { + fields: [], + }; + }, + methods: { + addField() { + // TODO: post an empty field to the API + this.fields.push({ + id: null, + name: "", + description: "", + type: "text", + required: false, + options: null, + links: null, + }); + }, + addOption(field) { + if (!field.options) { + field.options = []; + } + field.options.push({ id: null, name: "" }); + }, + deleteOption(field, option) { + const i = field.options.indexOf(option); + field.options.splice(i, 1); + }, + addLink(field) { + if (!field.links) { + field.links = []; + } + field.links.push({ + id: null, + url: "", + title: "", + display_link: true, + display_inline: false, + }); + }, + addConditional(field) { + if (!field.conditional) { + field.conditional = { + id: null, + conditions: [], + require_when: true, + show_when: true, + }; + } + }, + deleteLink(field, link) { + const i = field.links.indexOf(link); + field.links.splice(i, 1); + }, + save() {}, + }, + computed: { + fieldTypeOptions() { + return [ + { value: "text", text: "Text" }, + { value: "single-select", text: "Single Select" }, + { value: "multi-select", text: "Multi Select" }, + { value: "user-agreement", text: "User Agreement" }, + ]; + }, + }, +}; +</script> 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 de0c0d4..b5e722e 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 @@ -9,6 +9,7 @@ import ComputeResourcePreferenceDashboard from "./components/dashboards/ComputeR import CredentialStoreDashboard from "./components/dashboards/CredentialStoreDashboard"; import DevelopersContainer from "./components/developers//DevelopersContainer.vue"; import ExperimentStatisticsContainer from "./components/statistics/ExperimentStatisticsContainer"; +import ExtendedUserProfileContainer from "./components/users/ExtendedUserProfileContainer"; import GatewayResourceProfileEditorContainer from "./components/gatewayprofile/GatewayResourceProfileEditorContainer.vue"; import GroupComputeResourcePreference from "./components/admin/group_resource_preferences/GroupComputeResourcePreference"; import IdentityServiceUserManagementContainer from "./components/users/IdentityServiceUserManagementContainer.vue"; @@ -141,6 +142,11 @@ const routes = [ ], }, { + path: "/extended-user-profile", + component: ExtendedUserProfileContainer, + name: "extended-user-profile", + }, + { path: "/notices", component: NoticesManagementContainer, name: "notices", diff --git a/django_airavata/apps/admin/urls.py b/django_airavata/apps/admin/urls.py index 24a4b90..f526727 100644 --- a/django_airavata/apps/admin/urls.py +++ b/django_airavata/apps/admin/urls.py @@ -15,5 +15,6 @@ urlpatterns = [ name='gateway_resource_profile'), re_path(r'^notices/', views.notices, name='notices'), re_path(r'^users/', views.users, name='users'), + path('extended-user-profile/', views.extended_user_profile, name="extended_user_profile"), path('developers/', views.developers, name='developers'), ] diff --git a/django_airavata/apps/admin/views.py b/django_airavata/apps/admin/views.py index caca63a..e8be104 100644 --- a/django_airavata/apps/admin/views.py +++ b/django_airavata/apps/admin/views.py @@ -54,6 +54,12 @@ def users(request): @login_required +def extended_user_profile(request): + request.active_nav_item = 'users' + return render(request, 'admin/admin_base.html') + + +@login_required def experiment_statistics(request): request.active_nav_item = 'experiment-statistics' return render(request, 'admin/admin_base.html')
