GEOLYTIX / xyz

An open source javascript framework for spatial data and application interfaces.
MIT License
87 stars 25 forks source link

User IndexedDB #1230

Closed dbauszus-glx closed 1 month ago

dbauszus-glx commented 2 months ago

This indexedDB implementation allows to store, get, and update a locale object from the 'locales' object store in a user indexedDB.

https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Terminology

userIndexedDB methods are added to mapp.utils.

userIndexedDB.open(store) will open a DB with following name ${mapp.user.email} - ${mapp.user.title}. The database will be created if it not already exists. The creation will trigger the onupgradeneeded event which will create the store object store in the database. This will trigger the onsucess event which checks whether the requested store exists in the user indexedDB.

The process.env.TITLE will be added to the user object in the cookie module.

The user.title is required to generate a unique indexedDB for each user[email]/instance[title].

All objectstores use the key value as keypath for object indices.

userIndexedDB.add(store, obj) will add the keyed object to the named store. The key will be returned on success. Adding the same keyed object twice will result in an error.

userIndexedDB.get(store, key) will get the keyed object from the named store.

userIndexedDB.put(store, obj) will put the keyed object to the named store. This will override the existing keyed object. Updates work by replacing (put) the same keyed object into an user indexedDB.

userIndexedDB.deleteDB() will delete the user indexedDB.

Adding the url parameter useridb=true will ask the default script to get the keyed locale from the user indexedDB. The userLocale will be assigned as locale if available.

  if (mapp.hooks.current.useridb) {

    let userLocale = await mapp.utils.userIndexedDB.get('locales', locale.key)

    if (!userLocale) {
      await mapp.utils.userIndexedDB.add('locales', locale)
    } else {
      locale = userLocale
    }
  }

The userIDB plugin adds a button to put [update] the locale in the user indexedDB.

export function userIDB(plugin, mapview) {

  // Find the btnColumn element.
  const btnColumn = document.getElementById('mapButton');

  if (!btnColumn) return;

  // Append the plugin btn to the btnColumn.
  btnColumn.append(mapp.utils.html.node`
    <button
      title="Update userIDB locale"
      onclick=${()=>{

        mapp.utils.userIndexedDB.put('locales', mapview.locale)

      }}>
      <div class="mask-icon" style="mask-image:url(https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/rule_settings/default/24px.svg)">`);
}

This can be tested but updating the mapview.locale in another plugin, e.g. dark_mode

The enabled status will be stored with the local applying the setting when the locale is loaded with the useridb=true url param.

mapp.plugins.dark_mode = (plugin, mapview) => {

  // Get the map button
  const mapButton = document.getElementById("mapButton");

  // If mapbutton doesn't exist, return (for custom views).
  if (!mapButton) return;

  // toggle dark_mode if enabled in config.
  mapview.locale.dark_mode.enabled && toggleDarkMode()

  // If the button container exists, append the dark mode button.
  mapButton.append(mapp.utils.html.node`
    <button
      title="Color Mode"
      class="btn-color-mode"
      onclick=${()=>{
        mapview.locale.dark_mode.enabled = toggleDarkMode()
      }}>
      <div class="mask-icon">`);
}

dbauszus-glx commented 1 month ago

I've added an update layer method to the userIDB module. This method updates the layer key values in the layer json with current values from the mapview.layers object.

sonarcloud[bot] commented 1 month ago

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

dbauszus-glx commented 1 month ago

The userIDB plugin is mainly for testing the interface which otherwise would only be accessible through script.

The title for the button will now be assigned from the plugin.title.

There will be an alert after the update statement.

The plugin will warn and short-circuit if there is no mapp.user.email which is required for the IDB.