AIRAVATA-3564 Allow adding and removing Links
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
index 118655c..bf4ab5a 100644
--- 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
@@ -14,9 +14,15 @@
<div class="col">
<b-dropdown text="Add Field">
<b-dropdown-item @click="addField('text')">Text</b-dropdown-item>
- <b-dropdown-item @click="addField('single_choice')">Single Choice</b-dropdown-item>
- <b-dropdown-item @click="addField('multi_choice')">Multi Choice</b-dropdown-item>
- <b-dropdown-item @click="addField('user_agreement')">User Agreement</b-dropdown-item>
+ <b-dropdown-item @click="addField('single_choice')"
+ >Single Choice</b-dropdown-item
+ >
+ <b-dropdown-item @click="addField('multi_choice')"
+ >Multi Choice</b-dropdown-item
+ >
+ <b-dropdown-item @click="addField('user_agreement')"
+ >User Agreement</b-dropdown-item
+ >
</b-dropdown>
</div>
</div>
@@ -34,8 +40,7 @@
export default {
components: { ExtendedUserProfileFieldEditor },
data() {
- return {
- };
+ return {};
},
created() {
this.loadExtendedUserProfileFields();
@@ -48,7 +53,7 @@
]),
addField(field_type) {
// TODO: post an empty field to the API
- this.addExtendedUserProfileField({field_type})
+ this.addExtendedUserProfileField({ field_type });
},
addOption(field) {
if (!field.options) {
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/field-editors/ExtendedUserProfileFieldEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/field-editors/ExtendedUserProfileFieldEditor.vue
index b8bd979..186b07f 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/field-editors/ExtendedUserProfileFieldEditor.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/users/field-editors/ExtendedUserProfileFieldEditor.vue
@@ -76,26 +76,52 @@
Allow user to type in an "Other" option
</b-form-checkbox>
</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="Label">
- <b-form-input v-model="link.label" />
- </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="
+ extendedUserProfileField.links &&
+ extendedUserProfileField.links.length > 0
+ "
+ >
+ <transition-group name="fade">
+ <b-card
+ :title="`Link: ${link.label}`"
+ v-for="link in extendedUserProfileField.links"
+ :key="link.key"
+ >
+ <b-form-group label="Label">
+ <b-form-input
+ :value="link.label"
+ @input="handleLinkLabelChanged(link, $event)"
+ />
+ </b-form-group>
+ <b-form-group label="URL">
+ <b-form-input
+ :value="link.url"
+ @input="handleLinkURLChanged(link, $event)"
+ />
+ </b-form-group>
+ <b-form-group label="Show as link?">
+ <b-form-checkbox
+ :checked="link.display_link"
+ @input="handleLinkDisplayLinkChanged(link, $event)"
+ />
+ </b-form-group>
+ <b-form-group label="Show inline?">
+ <b-form-checkbox
+ :checked="link.display_inline"
+ @input="handleLinkDisplayInlineChanged(link, $event)"
+ />
+ </b-form-group>
+ <b-button @click="handleLinkDeleted(link)" variant="danger">
+ Delete Link
+ </b-button>
+ </b-card>
+ </transition-group>
+ </template>
+ <b-button @click="addLink({ field: extendedUserProfileField })"
+ >Add Link</b-button
+ >
</b-card>
</template>
@@ -158,6 +184,12 @@
"updateChoiceDisplayText",
"deleteChoice",
"updateChoiceIndex",
+ "addLink",
+ "updateLinkLabel",
+ "updateLinkURL",
+ "updateLinkDisplayLink",
+ "updateLinkDisplayInline",
+ "deleteLink",
]),
handleChoiceDisplayTextChanged(choice, display_text) {
this.updateChoiceDisplayText({ choice, display_text });
@@ -183,6 +215,21 @@
index,
});
},
+ handleLinkLabelChanged(link, label) {
+ this.updateLinkLabel({ link, label });
+ },
+ handleLinkURLChanged(link, url) {
+ this.updateLinkURL({ link, url });
+ },
+ handleLinkDisplayLinkChanged(link, display_link) {
+ this.updateLinkDisplayLink({ link, display_link });
+ },
+ handleLinkDisplayInlineChanged(link, display_inline) {
+ this.updateLinkDisplayInline({ link, display_inline });
+ },
+ handleLinkDeleted(link) {
+ this.deleteLink({ field: this.extendedUserProfileField, link });
+ },
},
};
</script>
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/store/modules/extendedUserProfile.js b/django_airavata/apps/admin/static/django_airavata_admin/src/store/modules/extendedUserProfile.js
index 044f574..1a577ad 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/store/modules/extendedUserProfile.js
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/store/modules/extendedUserProfile.js
@@ -23,6 +23,10 @@
commit("setChoiceOrder", { choice, order: index });
}
}
+ for (let index = 0; index < field.links.length; index++) {
+ const link = field.links[index];
+ commit("setLinkOrder", { link, order: index });
+ }
// Create or update each field
if (field.id) {
await services.ExtendedUserProfileFieldService.update({
@@ -110,6 +114,35 @@
const index = field.choices.indexOf(choice);
field.choices.splice(index, 1);
},
+ addLink(state, { field }) {
+ field.links.push(
+ new models.ExtendedUserProfileFieldLink({
+ label: "",
+ url: "",
+ display_link: true,
+ display_inline: false,
+ })
+ );
+ },
+ updateLinkLabel(state, { link, label }) {
+ link.label = label;
+ },
+ updateLinkURL(state, { link, url }) {
+ link.url = url;
+ },
+ updateLinkDisplayLink(state, { link, display_link }) {
+ link.display_link = display_link;
+ },
+ updateLinkDisplayInline(state, { link, display_inline }) {
+ link.display_inline = display_inline;
+ },
+ setLinkOrder(state, { link, order }) {
+ link.order = order;
+ },
+ deleteLink(state, { field, link }) {
+ const index = field.links.indexOf(link);
+ field.links.splice(index, 1);
+ },
};
export default {
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 8f9f759..b7255f0 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
@@ -20,6 +20,7 @@
import ExperimentState from "./models/ExperimentState";
import ExtendedUserProfileField from "./models/ExtendedUserProfileField";
import ExtendedUserProfileFieldChoice from "./models/ExtendedUserProfileFieldChoice";
+import ExtendedUserProfileFieldLink from "./models/ExtendedUserProfileFieldLink";
import FullExperiment from "./models/FullExperiment";
import Group from "./models/Group";
import GroupComputeResourcePreference from "./models/GroupComputeResourcePreference";
@@ -84,6 +85,7 @@
ExperimentState,
ExtendedUserProfileField,
ExtendedUserProfileFieldChoice,
+ ExtendedUserProfileFieldLink,
FullExperiment,
Group,
GroupComputeResourcePreference,
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileFieldLink.js b/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileFieldLink.js
index 5d52803..31e007e 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileFieldLink.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/ExtendedUserProfileFieldLink.js
@@ -1,4 +1,5 @@
import BaseModel from "./BaseModel";
+import uuidv4 from "uuid/v4";
const FIELDS = [
"id",
@@ -12,5 +13,19 @@
export default class ExtendedUserProfileFieldLink extends BaseModel {
constructor(data = {}) {
super(FIELDS, data);
+ this._key = data.key ? data.key : uuidv4();
+ }
+
+ get key() {
+ return this._key;
+ }
+
+ toJSON() {
+ const copy = Object.assign({}, this);
+ // id must either have a value or be missing, it can't be null
+ if (!copy.id) {
+ delete copy.id;
+ }
+ return copy;
}
}