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 2022/03/11 17:56:21 UTC
[airavata-django-portal] 01/02: AIRAVATA-3562 Mocked up UI for admins to edit extended user profile fields
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 <ma...@apache.org>
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')