diff --git a/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts b/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts index 9c610a750e..385d3fbc84 100644 --- a/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts +++ b/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts @@ -1,64 +1,56 @@ /** - * EGroupware eTemplate2 - Select Category WebComponent + * Use a custom tag for when multiple=true * - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @package api - * @link https://www.egroupware.org - * @author Nathan Gray + * @returns {string} */ - - -import {css, html, nothing, PropertyValues, TemplateResult, unsafeCSS} from "lit"; -import {Et2Select} from "../Et2Select"; +import {html, literal, StaticValue} from "lit/static-html.js"; +import {property} from "lit/decorators/property.js"; +import {css, PropertyValues, unsafeCSS} from "lit"; +import {Et2TreeDropdown} from "../../Et2Tree/Et2TreeDropdown"; +import {Et2CategoryTag} from "../Tag/Et2CategoryTag"; import {Et2StaticSelectMixin, StaticOptions as so} from "../StaticOptions"; -import {cleanSelectOptions} from "../FindSelectOptions"; -import {StaticValue} from "lit/development/static-html"; -import {literal} from "lit/static-html.js"; -import {repeat} from "lit/directives/repeat.js"; /** - * Customised Select widget for categories - * This widget gives us category colors and icons in the options and selected value. + * @since 23.1.x + * This is not a classical Select box but a structured tree */ -export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select) +export class Et2SelectCategory extends Et2StaticSelectMixin(Et2TreeDropdown) { + static get styles() { return [ ...super.styles, css` - /* Category color on options */ + :host { + --category-color: transparent; + } - sl-option { - border-left: 6px solid var(--category-color, transparent); - } - /* Border on the (single) selected value */ - - :host(:not([multiple]))::part(combobox) { - border-left: 6px solid var(--category-color, var(--sl-input-border-color)); - } + ::part(item-item) { + border-inline-start: 4px solid transparent; + border-inline-start-color: var(--category-color, transparent); + } ` - ] + ]; } + /** + * Application to get categories from + */ + @property({type: String}) application = ''; - static get properties() - { - return { - ...super.properties, - /** - * Include global categories - */ - globalCategories: {type: Boolean}, - /** - * Show categories from this application. If not set, will be the current application - */ - application: {type: String}, - /** - * Show categories below this parent category - */ - parentCat: {type: Number} - } - } + /** + * Include global categories + */ + @property({type: Boolean}) globalCategories = true; + + /** + * Show categories below this parent category + */ + @property({type: Number}) parentCat: { type: Number } + + + + private keep_import : Et2CategoryTag constructor() { @@ -67,40 +59,84 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select) this.noLang = true; } - async connectedCallback() + connectedCallback() { super.connectedCallback(); - if(typeof this.application == 'undefined') + // Default the application if not set + if(!this.application && this.getInstanceManager()) { - 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(); + this.application = this.getInstanceManager().app; } - } + // Set the search options from our properties + this.searchOptions.application = this.application; + this.searchOptions.globalCategories = this.globalCategories; + + this.fetchComplete = so.cat(this).then(options => { + this.select_options = options; + this.requestUpdate("select_options"); + + if (this._tree) + { + this._tree._selectOptions = options + this._tree.requestUpdate(); + } + }); + } willUpdate(changedProperties : PropertyValues) { super.willUpdate(changedProperties); - if(changedProperties.has("globalCategories") || changedProperties.has("application") || changedProperties.has("parentCat")) + if (changedProperties.has("globalCategories") || + changedProperties.has("application") || changedProperties.has("parentCat")) { - this.fetchComplete = so.cat(this).then(options => - { - this._static_options = cleanSelectOptions(options); + this.fetchComplete = so.cat(this).then(options => { + this.select_options = options; this.requestUpdate("select_options"); - - // Shoelace select has rejected our value due to missing option by now, so re-set it - this.updateComplete.then(() => - { - this.value = this.value; - }); }); } + + if(changedProperties.has('application')) + { + this.searchOptions.application = this.application; + } + if(changedProperties.has('globalCategories')) + { + this.searchOptions.globalCategories = this.globalCategories; + } } + public get tagTag() : StaticValue + { + return literal`et2-category-tag`; + } + + /** + * Set CSS category colors + * @returns {TemplateResult} + * @protected + */ + protected styleTemplate() + { + let css = ""; + const catColor = (option) => + { + css += ".cat_" + option.value + " {--category-color: " + (option.data?.color || "transparent") + ";}\n"; + + if (typeof option.children === 'object') + { + option.children?.forEach((option) => catColor(option)) + } + } + this.select_options.forEach((option => catColor(option))); + // @formatter:off + return html` + + `; + // @formatter:on + } protected handleValueChange(e) { @@ -109,43 +145,7 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select) // Just re-draw to get the colors & icon this.requestUpdate(); } - - /** - * Custom, dynamic styling - * - * CSS variables are not making it through to options, re-declaring them here works - * - * @returns {TemplateResult} - * @protected - */ - protected _styleTemplate() : TemplateResult - { - return html` - - `; - } - - /** - * Use a custom tag for when multiple=true - * - * @returns {string} - */ - public get tagTag() : StaticValue - { - return literal`et2-category-tag`; - } } +// @ts-ignore Type problems because of Et2WidgetWithSelectMixin in parent customElements.define("et2-select-cat", Et2SelectCategory); \ No newline at end of file diff --git a/api/js/etemplate/Et2Tree/Et2TreeDropdownCategory.ts b/api/js/etemplate/Et2Tree/Et2TreeDropdownCategory.ts deleted file mode 100644 index 6641b870eb..0000000000 --- a/api/js/etemplate/Et2Tree/Et2TreeDropdownCategory.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Use a custom tag for when multiple=true - * - * @returns {string} - */ -import {html, literal, StaticValue} from "lit/static-html.js"; -import {property} from "lit/decorators/property.js"; -import {css, PropertyValues, unsafeCSS} from "lit"; -import {Et2TreeDropdown} from "./Et2TreeDropdown"; -import {Et2CategoryTag} from "../Et2Select/Tag/Et2CategoryTag"; -import {Et2StaticSelectMixin, StaticOptions as so} from "../Et2Select/StaticOptions"; - -/** - * @since 23.1.x - */ -export class Et2TreeDropdownCategory extends Et2StaticSelectMixin(Et2TreeDropdown) -{ - - static get styles() - { - return [ - super.styles, - css` - :host { - --category-color: transparent; - } - - ::part(item-item) { - border-inline-start: 4px solid transparent; - border-inline-start-color: var(--category-color, transparent); - } - ` - ]; - } - /** - * Application to get categories from - */ - @property({type: String}) application = ''; - - /** - * Include global categories - */ - @property({type: Boolean}) globalCategories = true; - - - - private keep_import : Et2CategoryTag - - connectedCallback() - { - super.connectedCallback(); - - // Default the application if not set - if(!this.application && this.getInstanceManager()) - { - this.application = this.getInstanceManager().app; - } - - // Set the search options from our properties - this.searchOptions.application = this.application; - this.searchOptions.globalCategories = this.globalCategories; - - this.fetchComplete = so.cat(this).then(options => { - this.select_options = options; - this.requestUpdate("select_options"); - - if (this._tree) - { - this._tree._selectOptions = options - this._tree.requestUpdate(); - } - }); - } - - willUpdate(changedProperties : PropertyValues) - { - super.willUpdate(changedProperties); - - if (changedProperties.has("globalCategories") || - changedProperties.has("application") || changedProperties.has("parentCat")) - { - this.fetchComplete = so.cat(this).then(options => { - this.select_options = options; - this.requestUpdate("select_options"); - - // Shoelace select has rejected our value due to missing option by now, so re-set it - // this.updateComplete.then(() => { - // this.value = this.value; - // }); - }); - } - - if(changedProperties.has('application')) - { - this.searchOptions.application = this.application; - } - if(changedProperties.has('globalCategories')) - { - this.searchOptions.globalCategories = this.globalCategories; - } - } - - public get tagTag() : StaticValue - { - return literal`et2-category-tag`; - } - - /** - * Set CSS category colors - * @returns {TemplateResult} - * @protected - */ - protected styleTemplate() - { - let css = ""; - const catColor = (option) => - { - css += ".cat_" + option.value + " {--category-color: " + (option.data?.color || "transparent") + ";}\n"; - - if (typeof option.children === 'object') - { - option.children?.forEach((option) => catColor(option)) - } - } - this.select_options.forEach((option => catColor(option))); - // @formatter:off - return html` - - `; - // @formatter:on - } -} - -// @ts-ignore Type problems because of Et2WidgetWithSelectMixin in parent -customElements.define("et2-tree-cat", Et2TreeDropdownCategory); \ No newline at end of file diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index 205c2c775f..c85a1c15ca 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -113,7 +113,6 @@ import "./Et2Textbox/Et2Password"; import './Et2Textbox/Et2Searchbox'; import "./Et2Tree/Et2Tree"; import "./Et2Tree/Et2TreeDropdown"; -import "./Et2Tree/Et2TreeDropdownCategory"; /* Include all widget classes here, we only care about them registering, not importing anything*/