Friday, September 20, 2024 2:49:55 AM
> settings

Customize


Authenticate

> index.js
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();
          });
      },
    },
  });
}
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8