ait-cs-IaaS / koord2ool

Koord2ool is an extension of LimeSurvey that visualizes responses to surveys over time.
GNU General Public License v3.0
3 stars 1 forks source link

Simple setting for LimeSurvey endpoint #17

Closed MrManny closed 1 year ago

MrManny commented 2 years ago

Originally, the LimeSurvey endpoint was set through an environment variable (VUE_APP_LIMESURVEY_API) during build time, at which point it was injected into the code base by Vue. Later on, some helpers were introduced in 522a2ab87f54f8879c32cb92cd4fd1c2e7800847 by @b3n4kh to change that in the transpiled code base.

A slightly more elaborate but easier to use approach would be to construct LimesurveyApi asynchronously and pull the endpoint URL from a JSON file (which may or may not be forcefully and subsequently gitignored).

To get the endpoint URL, LimesurveyApi "only" needs to fetch the JSON file and take the URL from there. The only problem with this is that fetch operations are asynchronous, whereas constructors aren't. Luckily, the LimesurveyApi instance is created in an asynchronous store action prior authentication, so it might suffice to add an async static method to LimesurveyApi that fetches the JSON and then returns the newly constructed instance with that URL, e.g.

export class LimesurveyApi {
  // etc.
  async static createFrom(jsonPath: string): Promise<LimesurveyApi> {
    /* probably want to also catch some edge cases here, e.g. file not found, or file has an unexpected format, so only the "good" case is depicted here: */
    const contents = await fetch(jsonPath);
    const { url } = await contents.json(); // or JSON.parse, or something
    return new LimesurveyApi(url);
  }
  // etc.
}

Then the authenticate method in the Vue store can just:

const store = new Vuex.Store<KoordLayout>({
  // etc.
  actions: {
    async authenticate(
      state,
      payload: { username: string; password: string }
    ): Promise<boolean> {
      state.commit("setSyncState", true);

      const api = await LimesurveyApi.createFrom("path/to/file.json"); // changed from constructor to async method above
      const okay = await api.authenticate(payload.username, payload.password);

      // etc.
    },
  },
  // etc.
}

The example above assumes that the JSON file looks like this, but it's just for the sake of demonstration. Feel free to go wild.

{
  "url": "https://limesurvey.example.com/admin/remotecontrol"
}