migrate table config to typescript & update templates

This commit is contained in:
checktheroads 2021-04-19 16:59:56 -07:00
parent 82ef6f8ac5
commit 03390815af
18 changed files with 117 additions and 23 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,7 @@ import { initRackElevation } from './buttons';
import { initClipboard } from './clipboard';
import { initSearchBar, initInterfaceFilter } from './search';
import { initGenerateKeyPair, initLockUnlock, initGetSessionKey } from './secrets';
import { initTableConfig } from './tableConfig';
import { getElements } from './util';
const INITIALIZERS = [
@ -25,6 +26,7 @@ const INITIALIZERS = [
initLockUnlock,
initGetSessionKey,
initInterfaceFilter,
initTableConfig,
] as (() => void)[];
/**

View File

@ -0,0 +1,115 @@
import { createToast } from './toast';
import { getElements, apiPatch, hasError, getSelectedOptions } from './util';
/**
* Mark each option element in the selected columns element as 'selected' so they are submitted to
* the API.
*/
function saveTableConfig() {
for (const element of getElements<HTMLOptionElement>('select[name="columns"] option')) {
element.selected = true;
}
}
/**
* Delete all selected columns, which reverts the user's preferences to the default column set.
*/
function resetTableConfig() {
for (const element of getElements<HTMLSelectElement>('select[name="columns"]')) {
element.value = '';
}
}
/**
* Add columns to the table config select element.
*/
function addColumns(event: Event) {
for (const selectedOption of getElements<HTMLOptionElement>('#id_available_columns > option')) {
if (selectedOption.selected) {
for (const selected of getElements<HTMLSelectElement>('#id_columns')) {
selected.appendChild(selectedOption.cloneNode(true));
}
selectedOption.remove();
}
}
event.preventDefault();
}
/**
* Remove columns from the table config select element.
*/
function removeColumns(event: Event) {
for (const selectedOption of getElements<HTMLOptionElement>('#id_columns > option')) {
if (selectedOption.selected) {
for (const available of getElements<HTMLSelectElement>('#id_available_columns')) {
available.appendChild(selectedOption.cloneNode(true));
}
selectedOption.remove();
}
}
event.preventDefault();
}
/**
* Submit form configuration to the NetBox API.
*/
async function submitFormConfig(formConfig: Dict<Dict>) {
return await apiPatch<APIUserConfig>('/api/users/config/', formConfig);
}
/**
* Handle table config form submission. Sends the selected columns to the NetBox API to update
* the user's table configuration preferences.
*/
function handleSubmit(event: Event) {
event.preventDefault();
const element = event.currentTarget as HTMLFormElement;
// Get all the selected options from any select element in the form.
const options = getSelectedOptions(element);
// Create an object mapping the select element's name to all selected options for that element.
const formData: Dict<Dict<string>> = Object.assign(
{},
...options.map(opt => ({ [opt.name]: opt.options })),
);
// Create an array from the dot-separated config path. E.g. tables.DevicePowerOutletTable becomes
// ['tables', 'DevicePowerOutletTable']
const path = element.getAttribute('data-config-root')?.split('.') ?? [];
// Create an object mapping the configuration path to the select element names, which contain the
// selection options. E.g. {tables: {DevicePowerOutletTable: {columns: ['label', 'type']}}}
const data = path.reduceRight<Dict<Dict>>((value, key) => ({ [key]: value }), formData);
// Submit the resulting object to the API to update the user's preferences for this table.
submitFormConfig(data).then(res => {
if (hasError(res)) {
const toast = createToast('danger', 'Error Updating Table Configuration', res.error);
toast.show();
} else {
location.reload();
}
});
}
/**
* Initialize table configuration elements.
*/
export function initTableConfig() {
for (const element of getElements<HTMLButtonElement>('#save_tableconfig')) {
element.addEventListener('click', saveTableConfig);
}
for (const element of getElements<HTMLButtonElement>('#reset_tableconfig')) {
element.addEventListener('click', resetTableConfig);
}
for (const element of getElements<HTMLButtonElement>('#add_columns')) {
element.addEventListener('click', addColumns);
}
for (const element of getElements<HTMLButtonElement>('#remove_columns')) {
element.addEventListener('click', removeColumns);
}
for (const element of getElements<HTMLFormElement>('form.userconfigform')) {
element.addEventListener('submit', handleSubmit);
}
}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -46,7 +46,3 @@
{% include 'inc/paginator.html' with paginator=devicebay_table.paginator page=devicebay_table.page %}
{% table_config_form devicebay_table %}
{% endblock %}
{% block javascript %}
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -56,5 +56,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/interface_filtering.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -47,6 +47,3 @@
{% table_config_form inventoryitem_table %}
{% endblock %}
{% block javascript %}
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -52,5 +52,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -99,7 +99,3 @@
</div>
{% table_config_form table table_name="ObjectTable" %}
{% endblock %}
{% block javascript %}
<script src="{% static 'js/tableconfig.js' %}"></script>
{% endblock %}

View File

@ -212,7 +212,3 @@
</div>
{% include 'secrets/inc/private_key_modal.html' %}
{% endblock %}
{% block javascript %}
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}

View File

@ -51,5 +51,4 @@
{% block javascript %}
<script src="{% static 'js/connection_toggles.js' %}?v{{ settings.VERSION }}"></script>
<script src="{% static 'js/tableconfig.js' %}?v{{ settings.VERSION }}"></script>
{% endblock %}