Skip to content

Commit

Permalink
[Feature]: Manage Select options Via interface (#291)
Browse files Browse the repository at this point in the history
* Manage Select options Vis interface

* Move the event CLASS_SELECTOPTIONS_UPDATE_CONFIGURATION to admin-bundle

* Moved src/OptionsProvider/SelectOptionsOptionsProvider.php to the Core

* Renamed the option 'Class/Service' to 'Options Provider'

* Update namespace of options provider

* Fix PHP Stan

* Small refactoring

* Use ::class for SelectOptionsOptionsProvider

---------

Co-authored-by: K J Kooistra <[email protected]>
  • Loading branch information
aryaantony92 and kjkooistra-youwe authored Oct 2, 2023
1 parent e414e6b commit e9ad0da
Show file tree
Hide file tree
Showing 16 changed files with 1,186 additions and 20 deletions.
4 changes: 4 additions & 0 deletions public/css/icons.css
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@
background: url(/bundles/pimcoreadmin/img/flat-white-icons/bricks.svg) center center no-repeat !important;
}

.pimcore_nav_icon_selectoptions {
background: url(/bundles/pimcoreadmin/img/flat-white-icons/expand.svg) center center no-repeat !important;
}

.pimcore_nav_icon_quantityValue {
background: url(/bundles/pimcoreadmin/img/flat-white-icons/calculator.svg) center center no-repeat !important;
}
Expand Down
17 changes: 17 additions & 0 deletions public/js/pimcore/layout/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,15 @@ pimcore.layout.toolbar = Class.create({
});
}

if (perspectiveCfg.inToolbar('settings.objects.selectoptions') && user.isAllowed('selectoptions')) {
objectMenu.menu.items.push({
text: t('selectoptions'),
iconCls: 'pimcore_nav_icon_selectoptions',
itemId: 'pimcore_menu_settings_data_objects_selectoptions',
handler: this.editSelectOptions
});
}

if (perspectiveCfg.inToolbar("settings.objects.quantityValue") && user.isAllowed("quantityValueUnits")) {
objectMenu.menu.items.push({
text: t("quantityValue_field"),
Expand Down Expand Up @@ -1204,6 +1213,14 @@ pimcore.layout.toolbar = Class.create({
}
},

editSelectOptions: function () {
try {
pimcore.globalmanager.get('selectoptions').activate();
} catch (e) {
pimcore.globalmanager.add('selectoptions', new pimcore.object.selectoptions());
}
},

clearCache: function (params) {
Ext.Msg.confirm(t('warning'), t('system_performance_stability_warning'), function(btn){
if (btn == 'yes'){
Expand Down
10 changes: 9 additions & 1 deletion public/js/pimcore/object/classes/data/multiselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ pimcore.object.classes.data.multiselect = Class.create(pimcore.object.classes.da

this.selectionModel = valueGrid.getSelectionModel();

return stylingItems.concat([
let appendedStylingItems = stylingItems.concat([
{
xtype: "numberfield",
fieldLabel: t("maximum_items"),
Expand Down Expand Up @@ -298,6 +298,13 @@ pimcore.object.classes.data.multiselect = Class.create(pimcore.object.classes.da
},
valueGrid
]);

appendedStylingItems = appendedStylingItems.concat(
pimcore.object.helpers.selectField.getOptionsProviderFields(datax, valueGrid)
);
appendedStylingItems.push(valueGrid);

return appendedStylingItems;
},

applyData: function ($super) {
Expand Down Expand Up @@ -333,6 +340,7 @@ pimcore.object.classes.data.multiselect = Class.create(pimcore.object.classes.da
height: source.datax.height,
maxItems: source.datax.maxItems,
renderType: source.datax.renderType,
optionsProviderType: source.datax.optionsProviderType,
optionsProviderClass: source.datax.optionsProviderClass,
optionsProviderData: source.datax.optionsProviderData
});
Expand Down
23 changes: 6 additions & 17 deletions public/js/pimcore/object/classes/data/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,25 +273,13 @@ pimcore.object.classes.data.select = Class.create(pimcore.object.classes.data.da
value: datax.defaultValueGenerator
});

stylingItems.push({
xtype: "textfield",
fieldLabel: t("options_provider_class"),
width: 600,
name: "optionsProviderClass",
value: datax.optionsProviderClass
});

stylingItems.push({
xtype: "textfield",
fieldLabel: t("options_provider_data"),
width: 600,
value: datax.optionsProviderData,
name: "optionsProviderData"
});
let appendedStylingItems = stylingItems.concat(
pimcore.object.helpers.selectField.getOptionsProviderFields(datax, valueGrid)
)

stylingItems.push(valueGrid);
appendedStylingItems.push(valueGrid);

return stylingItems;
return appendedStylingItems;
},

applyData: function ($super) {
Expand Down Expand Up @@ -323,6 +311,7 @@ pimcore.object.classes.data.select = Class.create(pimcore.object.classes.data.da
{
options: source.datax.options,
width: source.datax.width,
optionsProviderType: source.datax.optionsProviderType,
optionsProviderClass: source.datax.optionsProviderClass,
optionsProviderData: source.datax.optionsProviderData,
defaultValue: source.datax.defaultValue,
Expand Down
2 changes: 1 addition & 1 deletion public/js/pimcore/object/helpers/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pimcore.object.helpers.grid = Class.create({
var key = fieldConfig.key;
var readerFieldConfig = {name: key};
// dynamic select returns data + options on cell level
if ((type == "select" || type == "multiselect") && fieldConfig.layout.optionsProviderClass) {
if ((type == "select" || type == "multiselect") && fieldConfig.layout.optionsProviderType !== pimcore.object.helpers.selectField.OPTIONS_PROVIDER_TYPE_CLASS && fieldConfig.layout.optionsProviderClass) {
if (typeof noBatchColumns != "undefined") {
if (fieldConfig.layout.dynamicOptions) {
noBatchColumns.push(key);
Expand Down
55 changes: 55 additions & 0 deletions public/js/pimcore/object/helpers/reservedWords.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

pimcore.registerNS('pimcore.object.helpers.reservedWords');

pimcore.object.helpers.reservedWords = {
// https://www.php.net/manual/en/reserved.keywords.php
phpReservedKeywords: [
'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue',
'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach',
'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'fn', 'for', 'foreach',
'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof',
'interface', 'isset', 'list', 'match', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public',
'readonly', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use',
'var', 'while', 'xor', 'yield', 'yield_from'
],

// https://www.php.net/manual/en/reserved.classes.php
phpReservedClasses: [
'self', 'static', 'parent'
],

// https://www.php.net/manual/en/reserved.other-reserved-words.php
phpOtherReservedWords: [
'int', 'float', 'bool', 'string', 'true', 'false', 'null', 'void', 'iterable', 'object', 'mixed', 'never',
'enum', 'resource', 'numeric'
],

pimcore: [
// Pimcore
'data', 'folder', 'permissions', 'dao', 'concrete', 'items'
],

isReservedWord: function (word) {
return in_arrayi(word, this.getAllReservedWords());
},

getAllReservedWords: function () {
return this.phpReservedKeywords.concat(
this.phpReservedClasses,
this.phpOtherReservedWords,
this.pimcore
);
}
};
163 changes: 163 additions & 0 deletions public/js/pimcore/object/helpers/selectField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PCL
*/

pimcore.registerNS('pimcore.object.helpers.selectField');

/**
* @private
*/
pimcore.object.helpers.selectField = {
OPTIONS_PROVIDER_TYPE_CONFIGURE: 'configure',
OPTIONS_PROVIDER_TYPE_SELECT_OPTIONS: 'select_options',
OPTIONS_PROVIDER_TYPE_CLASS: 'class',

selectOptionsStore: null,

/**
* @param {Object} datax
* @param {Ext.grid.Panel} valueGrid
* @returns {[
* Ext.form.field.ComboBox,
* Ext.form.field.Text,
* Ext.form.field.Text,
* Ext.form.field.ComboBox
* ]}
*/
getOptionsProviderFields: function (datax, valueGrid) {
var selectOptionsSelector = Ext.create('Ext.form.field.ComboBox', {
fieldLabel: t('selectoptions'),
emptyText: '',
value: datax.optionsProviderData,
hidden: true,
valueField: 'id',
displayField: 'text',
editable: false,
forceSelection: true,
queryMode: 'local',
store: this.getSelectOptionsStore(),
listeners: {
change: function (comboBox, newValue) {
optionsProviderClass.setValue(pimcore.settings.select_options_provider_class);
optionsProviderData.setValue(newValue);
}
}
});

var optionsProviderClass = Ext.create('Ext.form.field.Text', {
fieldLabel: t('options_provider_class'),
width: 600,
name: 'optionsProviderClass',
hidden: true,
value: datax.optionsProviderClass
});

var optionsProviderData = Ext.create('Ext.form.field.Text', {
fieldLabel: t('options_provider_data'),
width: 600,
value: datax.optionsProviderData,
hidden: true,
name: 'optionsProviderData'
});

var toggleFields = function (optionsProviderType) {
switch (optionsProviderType) {
case this.OPTIONS_PROVIDER_TYPE_SELECT_OPTIONS:
optionsProviderClass.hide();
optionsProviderData.hide();
selectOptionsSelector.show();
valueGrid.hide();
break;
case this.OPTIONS_PROVIDER_TYPE_CLASS:
optionsProviderClass.show();
optionsProviderData.show();
selectOptionsSelector.hide();
valueGrid.hide();
break;
// Configure
default:
optionsProviderClass.hide();
optionsProviderData.hide();
selectOptionsSelector.hide();
valueGrid.show();
}
}.bind(this)

var typeValue = this.OPTIONS_PROVIDER_TYPE_CONFIGURE;
if (datax.optionsProviderType) {
typeValue = datax.optionsProviderType;
// Legacy fallback in case no type is set and a class/service is configured
} else if (datax.optionsProviderClass) {
typeValue = this.OPTIONS_PROVIDER_TYPE_CLASS;
}

toggleFields(typeValue);

var optionsProviderType = Ext.create('Ext.form.field.ComboBox', {
name: 'optionsProviderType',
fieldLabel: t('options_provider_type'),
value: typeValue,
valueField: 'value',
displayField: 'label',
editable: false,
forceSelection: true,
queryMode: 'local',
store: Ext.create('Ext.data.Store', {
fields: ['value', 'label'],
data: [
{value: this.OPTIONS_PROVIDER_TYPE_CONFIGURE, label: t('options_provider_type_configure')},
{value: this.OPTIONS_PROVIDER_TYPE_SELECT_OPTIONS, label: t('options_provider_type_select_options')},
{value: this.OPTIONS_PROVIDER_TYPE_CLASS, label: t('options_provider_type_class')}
]
}),
listeners: {
change: function (comboBox, newValue) {
toggleFields(newValue);
}
}
});

return [
optionsProviderType,
optionsProviderClass,
optionsProviderData,
selectOptionsSelector
];
},

/**
* @returns {Ext.data.JsonStore}
*/
getSelectOptionsStore: function () {
if (this.selectOptionsStore === null) {
this.selectOptionsStore = Ext.create('Ext.data.JsonStore', {
fields: [
{name: 'id'},
{name: 'text'}
],
autoLoad: true,
proxy: {
type: 'ajax',
url: Routing.generate('pimcore_admin_dataobject_class_selectoptionstree'),
reader: {
type: 'json'
},
extraParams: {
grouped: 0
}
},
});
}

return this.selectOptionsStore;
}
};
Loading

0 comments on commit e9ad0da

Please sign in to comment.