2022-06-20 17:35:38 +02:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Select Category WebComponent
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @link https://www.egroupware.org
|
|
|
|
* @author Nathan Gray
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import {css, PropertyValues} from "@lion/core";
|
|
|
|
import {Et2Select} from "./Et2Select";
|
2022-07-15 20:56:24 +02:00
|
|
|
import {Et2StaticSelectMixin, StaticOptions} from "./StaticOptions";
|
2022-08-09 17:24:28 +02:00
|
|
|
import {cleanSelectOptions} from "./FindSelectOptions";
|
2022-06-20 17:35:38 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Customised Select widget for categories
|
|
|
|
* This widget gives us category colors and icons in the options and selected value.
|
|
|
|
*/
|
2022-07-15 20:56:24 +02:00
|
|
|
export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select)
|
2022-06-20 17:35:38 +02:00
|
|
|
{
|
|
|
|
static get styles()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
...super.styles,
|
|
|
|
css`
|
|
|
|
/* Category color on options */
|
|
|
|
::slotted(*) {
|
2022-06-21 16:44:28 +02:00
|
|
|
border-left: 6px solid var(--category-color, transparent);
|
2022-06-20 17:35:38 +02:00
|
|
|
}
|
2022-06-21 16:44:28 +02:00
|
|
|
/* Border on the (single) selected value */
|
2022-10-13 16:41:05 +02:00
|
|
|
:host(.hasValue:not([multiple])) .select--standard .select__control {
|
2022-09-12 15:15:56 +02:00
|
|
|
border-left: 6px solid var(--sl-input-border-color);
|
2022-06-20 17:35:38 +02:00
|
|
|
}
|
|
|
|
`
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
static get properties()
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
...super.properties,
|
|
|
|
/**
|
|
|
|
* Include global categories
|
|
|
|
*/
|
2023-01-11 23:49:56 +01:00
|
|
|
globalCategories: {type: Boolean},
|
2022-06-20 17:35:38 +02:00
|
|
|
/**
|
|
|
|
* Show categories from this application. If not set, will be the current application
|
|
|
|
*/
|
|
|
|
application: {type: String},
|
|
|
|
/**
|
|
|
|
* Show categories below this parent category
|
|
|
|
*/
|
2022-07-21 17:57:50 +02:00
|
|
|
parentCat: {type: Number}
|
2022-06-20 17:35:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-07-07 18:06:41 +02:00
|
|
|
async connectedCallback()
|
2022-06-20 17:35:38 +02:00
|
|
|
{
|
|
|
|
super.connectedCallback();
|
|
|
|
|
|
|
|
if(typeof this.application == 'undefined')
|
|
|
|
{
|
|
|
|
this.application =
|
|
|
|
// When the widget is first created, it doesn't have a parent and can't find it's instanceManager
|
|
|
|
(this.getInstanceManager() && this.getInstanceManager().app) ||
|
|
|
|
this.egw().app_name();
|
|
|
|
}
|
2022-07-07 18:06:41 +02:00
|
|
|
// If app passes options (addressbook index) we'll use those instead.
|
|
|
|
// They will be found automatically by update() after ID is set.
|
|
|
|
await this.updateComplete;
|
|
|
|
if(this.select_options.length == 0)
|
|
|
|
{
|
2022-07-19 19:47:03 +02:00
|
|
|
|
2022-07-07 18:06:41 +02:00
|
|
|
}
|
2022-06-20 17:35:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-19 19:07:16 +02:00
|
|
|
willUpdate(changedProperties : PropertyValues)
|
2022-06-20 17:35:38 +02:00
|
|
|
{
|
2022-08-19 19:07:16 +02:00
|
|
|
super.willUpdate(changedProperties);
|
|
|
|
|
|
|
|
if(changedProperties.has("global_categories") || changedProperties.has("application") || changedProperties.has("parentCat"))
|
|
|
|
{
|
2022-10-03 17:12:00 +02:00
|
|
|
this.fetchComplete = so.cat(this).then(options =>
|
2022-08-19 19:07:16 +02:00
|
|
|
{
|
|
|
|
this.static_options = cleanSelectOptions(options);
|
|
|
|
this.requestUpdate("select_options");
|
|
|
|
});
|
|
|
|
}
|
2022-06-20 17:35:38 +02:00
|
|
|
|
2022-08-09 17:24:28 +02:00
|
|
|
if(changedProperties.has("value") || changedProperties.has('select_options'))
|
2022-06-20 17:35:38 +02:00
|
|
|
{
|
|
|
|
this.doLabelChange()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override from parent (SlSelect) to customise display of the current value.
|
|
|
|
* Here's where we add the icon & color border
|
|
|
|
*/
|
|
|
|
doLabelChange()
|
|
|
|
{
|
|
|
|
// Update the display label when checked menu item's label changes
|
|
|
|
if(this.multiple)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const checkedItem = this.menuItems.find(item => item.value === this.value);
|
|
|
|
this.displayLabel = checkedItem ? checkedItem.textContent : '';
|
|
|
|
this.querySelector("[slot=prefix].tag_image")?.remove();
|
|
|
|
if(checkedItem)
|
|
|
|
{
|
|
|
|
let image = this._createImage(checkedItem)
|
|
|
|
if(image)
|
|
|
|
{
|
|
|
|
this.append(image);
|
|
|
|
}
|
|
|
|
this.dropdown.querySelector(".select__control").style.borderColor =
|
2022-07-22 18:43:30 +02:00
|
|
|
getComputedStyle(checkedItem).getPropertyValue("--category-color") || "";
|
2022-06-20 17:35:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-04 17:17:31 +02:00
|
|
|
/**
|
|
|
|
* Render select_options as child DOM Nodes
|
|
|
|
*
|
|
|
|
* Overridden here so we can re-do the displayed label after first load of select options.
|
|
|
|
* Initial load order / lifecycle does not have all the options at the right time
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected _renderOptions()
|
|
|
|
{
|
|
|
|
// @ts-ignore Doesn't know about Et2WidgetWithSelectMixin._renderOptions()
|
|
|
|
return super._renderOptions().then(() =>
|
|
|
|
{
|
|
|
|
// @ts-ignore Doesn't know about SlSelect.menuItems
|
|
|
|
if(this.menuItems.length > 0)
|
|
|
|
{
|
|
|
|
this.doLabelChange();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-20 17:35:38 +02:00
|
|
|
/**
|
|
|
|
* Use a custom tag for when multiple=true
|
|
|
|
*
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
get tagTag() : string
|
|
|
|
{
|
|
|
|
return "et2-category-tag";
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Customise how tags are rendered.
|
|
|
|
* This overrides parent to set application
|
|
|
|
*
|
|
|
|
* @param item
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected _createTagNode(item)
|
|
|
|
{
|
|
|
|
let tag = super._createTagNode(item);
|
|
|
|
tag.application = this.application;
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use a single StaticOptions, since it should have no state
|
|
|
|
* @type {StaticOptions}
|
|
|
|
*/
|
|
|
|
const so = new StaticOptions();
|
|
|
|
|
2022-07-21 17:57:50 +02:00
|
|
|
customElements.define("et2-select-cat", Et2SelectCategory);
|