Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extended string config type (stringX). Closes #2005 #2006

Merged
merged 1 commit into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/common/viz/ConfigDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ define([
return deferred.promise;
};

ConfigDialog.prototype._initDialog = function(metadata, prevConfig, options) {
ConfigDialog.prototype._initDialog = async function(metadata, prevConfig, options) {
this._dialog = $(pluginConfigDialogTemplate);

this._btnSave = this._dialog.find('.btn-save');
Expand All @@ -108,7 +108,7 @@ define([
this._title = this._modalHeader.find('.modal-title');
this._title.text(config.title);

this.generateConfigSection(metadata, prevConfig);
await this.generateConfigSection(metadata, prevConfig);
};

ConfigDialog.prototype.getDialogConfig = function(metadata, options) {
Expand Down Expand Up @@ -217,12 +217,12 @@ define([
return settings;
};

ConfigDialog.prototype.generateConfigSection = function (metadata, prevConfig, htmlClass) {
const html = this.getConfigHtml(metadata, prevConfig, htmlClass);
ConfigDialog.prototype.generateConfigSection = async function (metadata, prevConfig, htmlClass) {
const html = await this.getConfigHtml(metadata, prevConfig, htmlClass);
this._divContainer.append(html);
};

ConfigDialog.prototype.getConfigHtml = function (metadata, prevConfig, htmlClass) {
ConfigDialog.prototype.getConfigHtml = async function (metadata, prevConfig, htmlClass) {
var len = metadata.configStructure.length,
pluginConfigEntry,
pluginSectionEl = PLUGIN_CONFIG_SECTION_BASE.clone(),
Expand All @@ -247,7 +247,7 @@ define([
}

const config = prevConfig && prevConfig[metadata.id];
const entry = this.getEntryForProperty(pluginConfigEntry, config);
const entry = await this.getEntryForProperty(pluginConfigEntry, config);
if (pluginConfigEntry.valueType === 'section') {
if (i > 0) {
const {name} = pluginConfigEntry;
Expand All @@ -266,10 +266,10 @@ define([
return html;
};

ConfigDialog.prototype.getEntryForProperty = function (configEntry, prevConfig = {}) {
ConfigDialog.prototype.getEntryForProperty = async function (configEntry, prevConfig = {}) {
let entry = null;
if (CustomConfigEntries.isCustomEntryValueType(configEntry.valueType)) {
entry = this._customEntriesManager[configEntry.valueType](configEntry, prevConfig);
entry = await this._customEntriesManager[configEntry.valueType](configEntry, prevConfig);
} else {
const widget = this.getWidgetForProperty(configEntry);
const el = ENTRY_BASE.clone();
Expand Down
108 changes: 91 additions & 17 deletions src/common/viz/ConfigDialogEntries/CustomConfigEntries.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
/* eslint-env browser */

define([
'deepforge/storage/index'
'js/Controls/PropertyGrid/Widgets/StringWidget',
'deepforge/storage/index',
'underscore',
], function (
Storage
StringWidget,
Storage,
_,
) {
const SECTION_HEADER = $('<h6 class="config-section-header">');
const CUSTOM_WIDGET_TYPES = ['dict', 'section', 'group', 'userAsset'];
const CUSTOM_WIDGET_TYPES = ['dict', 'section', 'group', 'userAsset', 'stringX'];

class CustomConfigEntries {
section(configEntry) {
Expand All @@ -16,12 +20,12 @@ define([
return {el: sectionHeader};
}

group(configEntry, config) {
async group(configEntry, config) {
const widget = {el: null};
widget.el = $('<div>', {class: configEntry.name});
const entries = configEntry.valueItems.map(item => {
return this.getEntryForProperty(item, config);
});
const entries = await Promise.all(
configEntry.valueItems.map(item => this.getEntryForProperty(item, config))
);

entries.forEach(entry => widget.el.append(entry.el));

Expand All @@ -48,19 +52,18 @@ define([
return {widget, el: widget.el};
}

dict(configEntry, config) {
async dict(configEntry, config) {
const widget = {el: null, active: null};
widget.el = $('<div>', {class: configEntry.name});

const entriesForItem = {};
const valueItemsDict = {};
for (let i = 0; i < configEntry.valueItems.length; i++) {
const valueItem = configEntry.valueItems[i];
const entries = valueItem.configStructure
.map(item => {
const entry = this.getEntryForProperty(item, config);
return entry;
});
const entries = await Promise.all(
valueItem.configStructure
.map(item => this.getEntryForProperty(item, config))
);

entries.forEach(entry => {
if (i > 0) {
Expand All @@ -83,7 +86,7 @@ define([
valueType: 'string',
valueItems: itemNames
};
const selector = this.getEntryForProperty(configForKeys);
const selector = await this.getEntryForProperty(configForKeys);

widget.active = defaultValue;
widget.onSetSelector = value => {
Expand Down Expand Up @@ -128,7 +131,7 @@ define([
return {widget, el: widget.el};
}

userAsset(configEntry, config) {
async userAsset(configEntry, config) {
const widget = {el: null, active: null};
const storageOpts = this._getStorageOpts();
widget.el = $('<div>', {class: configEntry.name});
Expand All @@ -137,8 +140,8 @@ define([
displayName: configEntry.displayName,
valueType: 'file'
};
const browserAssetWidget = this.getEntryForProperty(browserAssetConfig, config);
const storageWidget = this.getEntryForProperty(storageOpts, config);
const browserAssetWidget = await this.getEntryForProperty(browserAssetConfig, config);
const storageWidget = await this.getEntryForProperty(storageOpts, config);
widget.el.append(browserAssetWidget.el);
widget.el.append(storageWidget.el);

Expand Down Expand Up @@ -167,6 +170,77 @@ define([
return {widget, el: widget.el};
}

async stringX(configEntry) {
const stringEntry = Object.assign({}, configEntry);
stringEntry.valueType = 'string';
if (configEntry.valueItemsURL) {
const valueItems = await this._fetchValueItems(configEntry);
stringEntry.valueItems = valueItems;
if (!stringEntry.value && valueItems.length) {
stringEntry.value = valueItems[0];
}
} else if (configEntry.extraValueItems) {
stringEntry.valueItems = stringEntry.valueItems || [];
}

const widget = await this.getEntryForProperty(stringEntry);
if (configEntry.valueItemsURL) {
const $dropdown = widget.el.find('select');
const updateDropdown = async () => {
const valueItems = await this._fetchValueItems(configEntry);
$dropdown.empty();
const [dropdown] = $dropdown;
valueItems.forEach(value => {
const opt = document.createElement('option');
opt.innerText = value;
dropdown.appendChild(opt);
});

if (configEntry.extraValueItems) {
if (!valueItems.length) {
const opt = document.createElement('option');
opt.innerText = '';
dropdown.appendChild(opt);
}
this._addExtraValueItems(widget, configEntry);
}
};
$dropdown.on('focus', _.throttle(updateDropdown, 1000));
}

return {widget, el: widget.el};
}

async _fetchValueItems(configEntry) {
const response = await fetch(configEntry.valueItemsURL);
return await response.json();
}

async _addExtraValueItems(widget, configEntry) {
const [dropdown] = widget.el.find('select');
configEntry.extraValueItems.forEach(item => {
if (item.type !== 'URL') {
throw new Error('Unsupported extra value item for ' + JSON.stringify(configEntry));
}
const opt = document.createElement('option');
const url = _.template(item.value)({window});
opt.innerText = item.name;
opt.setAttribute('data-url', url);
opt.style = 'font-style: italic;';
dropdown.appendChild(opt);
});
dropdown.onchange = event => {
const selectedOption = [].find.call(
event.target.children,
opt => opt.value === event.target.value
);
const url = selectedOption && selectedOption.getAttribute('data-url');
if (url) {
window.open(url, '_blank');
}
};
}

_getStorageOpts() {
const backends = Storage.getAvailableBackends();
const storageMetadata = backends.map(id => Storage.getStorageMetadata(id));
Expand Down