From 3874c8de9b830b099c186f3501ab6fa16ec4b15a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 6 Feb 2024 11:58:38 -0500 Subject: [PATCH] Add support for API path variables --- netbox/project-static/dist/netbox.js | Bin 373264 -> 373953 bytes netbox/project-static/dist/netbox.js.map | Bin 338704 -> 339295 bytes .../src/select/classes/dynamicTomSelect.ts | 72 +++++++++++++++--- netbox/project-static/src/select/dynamic.ts | 1 + 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 6f379af8d608b4a44bdd67ef589908e7813b8f03..17c8eec41491b3cbe122c6b339aafb1cce715670 100644 GIT binary patch delta 7274 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 diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index 5a97f7adc2cbbda97fb7ee83660dde56f1589313..65d52a84892cf632221769457fe4e729ac5ab33e 100644 GIT binary patch delta 783 zcma)4J8x4l6joZZFrW@;rT&2~SZaHd(#L>w>^N6$xVkd8x1pJ+Qc$Z3NKuB8B^{#9 z-7IylIJCRbw6queXIWXUcDGqMsuV2Phumf4jSu5 zzEebxm24B0Qd8I4M66WyeJ>I9Mcvo(4EYaArbJd|RBmX0n~0m$F6n17Cu$>zP8=`0|N(J-3*jtEnv@bgCF>;D5cGUm8MA!5X%M*(DFy zQc)?3Y($YTmH}Ixsf$x{u#18%aWjcv6XsY>2M0AymEFEi9%+B8D!8t~&Wnj*i++I^m9vp*qfviPJreSkxFprWY8o zm@tPHxlG?_#Ikhy6l0dR0=_z)j*h-M-j0smI)RR!5z{A{u-I)6F=hG7$mHv_eYH7D z8k1INg_BM$&`1L(plRM2&N}WOJwT1A5RJ)>j>$Uyj;y?lp~7I>z(k^Zf&X+b8!q0UJ`+gWW{qCNlsaSJ|? diff --git a/netbox/project-static/src/select/classes/dynamicTomSelect.ts b/netbox/project-static/src/select/classes/dynamicTomSelect.ts index c99185e0d..8715e8bc8 100644 --- a/netbox/project-static/src/select/classes/dynamicTomSelect.ts +++ b/netbox/project-static/src/select/classes/dynamicTomSelect.ts @@ -6,7 +6,8 @@ import type { Stringifiable } from 'query-string'; import { DynamicParamsMap } from './dynamicParamsMap'; // Transitional -import { QueryFilter } from '../../select_old/api/types' +import { QueryFilter, PathFilter } from '../../select_old/api/types' +import { getElement, replaceAll } from '../../util'; // Extends TomSelect to provide enhanced fetching of options via the REST API @@ -18,6 +19,7 @@ export class DynamicTomSelect extends TomSelect { private readonly queryParams: QueryFilter = new Map(); private readonly staticParams: QueryFilter = new Map(); private readonly dynamicParams: DynamicParamsMap = new DynamicParamsMap(); + private readonly pathValues: PathFilter = new Map(); /** * Overrides @@ -41,6 +43,12 @@ export class DynamicTomSelect extends TomSelect { this.updateQueryParams(filter); } + // Path values + this.getPathKeys(); + for (const filter of this.pathValues.keys()) { + this.updatePathValues(filter); + } + // Add dependency event listeners. this.addEventListeners(); } @@ -73,7 +81,7 @@ export class DynamicTomSelect extends TomSelect { // Formulate and return the complete URL for an API request, including any query parameters. getRequestUrl(search: string): string { - const url = this.api_url; + let url = this.api_url; // Create new URL query parameters based on the current state of `queryParams` and create an // updated API query URL. @@ -82,6 +90,15 @@ export class DynamicTomSelect extends TomSelect { query[key] = value; } + // Replace any variables in the URL with values from `pathValues` if set. + for (const [key, value] of this.pathValues.entries()) { + for (const result of this.api_url.matchAll(new RegExp(`({{${key}}})`, 'g'))) { + if (value) { + url = replaceAll(url, result[1], value.toString()); + } + } + } + // Append the search query, if any if (search) { query['q'] = [search]; @@ -138,6 +155,16 @@ export class DynamicTomSelect extends TomSelect { } } + + // Parse the `data-url` attribute to add any variables to `pathValues` as keys with empty + // values. As those keys' corresponding form fields' values change, `pathValues` will be + // updated to reflect the new value. + private getPathKeys() { + for (const result of this.api_url.matchAll(new RegExp(`{{(.+)}}`, 'g'))) { + this.pathValues.set(result[1], ''); + } + } + // Update an element's API URL based on the value of another element on which this element // relies. private updateQueryParams(fieldName: string): void { @@ -198,16 +225,39 @@ export class DynamicTomSelect extends TomSelect { } } - /** - * Add event listeners to this element and its dependencies so that when dependencies change - * this element's options are updated. - */ - private addEventListeners(): void { + // Update `pathValues` based on the form value of another element. + private updatePathValues(id: string): void { + const key = replaceAll(id, /^id_/i, ''); + const element = getElement(`id_${key}`); + if (element !== null) { + // If this element's URL contains variable tags ({{), replace the tag with the dependency's + // value. For example, if the dependency is the `rack` field, and the `rack` field's value + // is `1`, this element's URL would change from `/dcim/racks/{{rack}}/` to `/dcim/racks/1/`. + const hasReplacement = + this.api_url.includes(`{{`) && Boolean(this.api_url.match(new RegExp(`({{(${id})}})`, 'g'))); + if (hasReplacement) { + if (element.value) { + // If the field has a value, add it to the map. + this.pathValues.set(id, element.value); + } else { + // Otherwise, reset the value. + this.pathValues.set(id, ''); + } + } + } + } + + /** + * Events + */ + + // Add event listeners to this element and its dependencies so that when dependencies change + //this element's options are updated. + private addEventListeners(): void { // Create a unique iterator of all possible form fields which, when changed, should cause this // element to update its API query. - // const dependencies = new Set([...this.dynamicParams.keys(), ...this.pathValues.keys()]); - const dependencies = this.dynamicParams.keys(); + const dependencies = new Set([...this.dynamicParams.keys(), ...this.pathValues.keys()]); for (const dep of dependencies) { const filterElement = document.querySelector(`[name="${dep}"]`); @@ -225,10 +275,10 @@ export class DynamicTomSelect extends TomSelect { // `tenant_group` and update the query parameters and API query URL for the `tenant` field. private handleEvent(event: Event): void { const target = event.target as HTMLSelectElement; + // Update the element's URL after any changes to a dependency. this.updateQueryParams(target.name); - // this.updatePathValues(target.name); - // this.updateQueryUrl(); + this.updatePathValues(target.name); // Load new data. this.load(this.lastValue); diff --git a/netbox/project-static/src/select/dynamic.ts b/netbox/project-static/src/select/dynamic.ts index 8794ffcc6..60cdfa9e4 100644 --- a/netbox/project-static/src/select/dynamic.ts +++ b/netbox/project-static/src/select/dynamic.ts @@ -16,6 +16,7 @@ export function initDynamicSelects(): void { dropdownParent: 'body', controlInput: '', preload: 'focus', + maxOptions: 100, }); }