import Vue from "vue/dist/vue.esm.js";
import _ from "lodash";
import { getData } from "../utilities";
import axios from "axios";
// This is binding to a class name, so elem is actually a DOM object
export default function (elem) {
let data = getData(elem, ["communities", "servers", "aliases", "user-id"]);
const userID = data["user-id"];
const app = new Vue({
el: elem,
data: {
communities: data.communities,
servers: data.servers,
alias: {
all: data.aliases,
original: {},
current: {}
},
modal: {},
selectedServer: null,
selectedCommunity: null
},
created: function () {
this.reset();
},
mounted: function () {
$("#alias-modal").on("hidden", () => {
this.reset();
});
},
computed: {
targets: function () {
let targets = _.concat(this.communities, this.servers.flatMap((s) => s.servers));
return _.sortBy(targets, "id");
},
aliases: function () {
let aliases = _.filter(this.alias.all, (a) => a.state != "deleted");
return _.sortBy(aliases, "value");
},
hasAliases: function () {
return !_.isEmpty(this.aliases);
},
hasChanges: function () {
return _.some(this.aliases, (a) => a.state != "unchanged")
},
validAlias: function () {
let currentAlias = this.alias.current;
// let originalAlias = this.alias.original;
let existingAlias = _.find(this.alias.all, (alias) => {
let validAlias = alias.value === currentAlias.value;
let validType = alias.type === currentAlias.type;
let validID = true;
// New alias do not have an ID
if (!_.isEmpty(currentAlias.id)) {
validID = alias.id !== currentAlias.id
}
return validAlias && validType && validID;
}) || null;
let aliasSize = _.size(currentAlias.value);
let hasValidSize = aliasSize > 0 && aliasSize < 64;
let hasTarget = !_.isNull(currentAlias.target);
let hasExistingAlias = !_.isNull(existingAlias);
if (hasExistingAlias) {
Vue.set(this.modal, "error", `This alias already exists for ${existingAlias.target.name}`);
} else {
Vue.set(this.modal, "error", "");
}
return hasValidSize && hasTarget && !hasExistingAlias;
},
submitButtonEnabled: function () {
return this.validAlias;
}
},
methods: {
reset: function () {
this.modal = {
title: "Add a new alias",
error: "",
submitButton: "Add alias",
onSubmitClick: this.addAlias,
};
Vue.set(this.alias, "original", {});
Vue.set(this.alias, "current", {
id: null,
type: "community",
value: "",
target: null,
state: "new"
});
this.resetSelected();
},
resetSelected: function () {
this.selectedServer = null;
this.selectedCommunity = null;
Vue.set(this.alias.current, "target", null);
},
// Force a scroll so the UI is in the correct spot for the first change.
// Allows the user to change the position without forcing them back again
scrollToSection: function () {
if (this.hasChanges) return;
let section = $("#aliases-section");
UIkit.scroll(section).scrollTo(section);
},
onSelectedType: function () {
Vue.set(this.alias.current, "target", this.selectedCommunity || this.selectedServer);
},
addAlias: function () {
this.scrollToSection();
this.alias.current.target = this.selectedCommunity || this.selectedServer;
let { state: _s, id: _i, ...alias } = this.alias.current;
// Add the alias to the UI. Since it doesn't have an ID, a spinner will show where the icons are
this.alias.all.push(alias);
UIkit.modal($("#alias-modal")).hide();
axios.post(`/users/${userID}/aliases`, { user_alias: alias })
.then((response) => {
Vue.set(alias, "id", response.data.id)
}).catch((e) => {
console.error(e);
Toaster.error(`Failed to add a new alias - ${e.response?.data?.message}`);
});
},
editAlias: function (alias) {
this.scrollToSection();
Vue.set(this.alias, "original", alias);
Vue.set(this.alias, "current", _.clone(alias));
// Find the target community/server
let target = _.find(this.targets, ["id", alias.target.id]);
if (alias.type === "community") {
this.selectedCommunity = target;
} else {
this.selectedServer = target;
}
this.modal = {
title: "Editing alias",
submitButton: "Save changes",
onSubmitClick: this.updateAlias,
};
Vue.nextTick(() => {
UIkit.modal($("#alias-modal")).show();
});
},
updateAlias: function () {
let originalAlias = this.alias.original;
let editedAlias = this.alias.current;
Vue.set(originalAlias, "value", editedAlias.value);
Vue.set(originalAlias, "target", editedAlias.target);
Vue.set(originalAlias, "type", editedAlias.type);
Vue.set(originalAlias, "state", "changed");
UIkit.modal($("#alias-modal")).hide();
axios.patch(`/users/${userID}/aliases/${originalAlias.id}`, { user_alias: originalAlias })
.then((_response) => { })
.catch((e) => {
console.error(e);
Toaster.error(`Failed to update the alias - ${e.response?.data?.message}`);
});
},
deleteAlias: function (alias) {
this.scrollToSection();
let confirmation = confirm(
`Are you sure you want to delete the alias "${alias.value}" that represents "${alias.target.name}"?`
);
if (!confirmation) return;
// Hides the alias
Vue.set(alias, "state", "deleted");
axios.delete(`/users/${userID}/aliases/${alias.id}`)
.then(() => {
Vue.delete(this.alias.all, _.indexOf(this.alias.all, alias));
}).catch((e) => {
console.error(e);
// Reset hiding the alias
Vue.set(alias, "state", "unchanged");
Toaster.error(`Failed to delete alias - ${e.response?.data?.message}`);
}).finally(() => {
UIkit.modal($("#alias-modal")).hide();
});
},
},
});
}