mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
changed Et2SelectCategory to be the Et2TreeDropdownCategory and and removed theold one
This commit is contained in:
parent
0605f6c2f5
commit
3e577c738f
@ -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
|
* @returns {string}
|
||||||
* @package api
|
|
||||||
* @link https://www.egroupware.org
|
|
||||||
* @author Nathan Gray
|
|
||||||
*/
|
*/
|
||||||
|
import {html, literal, StaticValue} from "lit/static-html.js";
|
||||||
|
import {property} from "lit/decorators/property.js";
|
||||||
import {css, html, nothing, PropertyValues, TemplateResult, unsafeCSS} from "lit";
|
import {css, PropertyValues, unsafeCSS} from "lit";
|
||||||
import {Et2Select} from "../Et2Select";
|
import {Et2TreeDropdown} from "../../Et2Tree/Et2TreeDropdown";
|
||||||
|
import {Et2CategoryTag} from "../Tag/Et2CategoryTag";
|
||||||
import {Et2StaticSelectMixin, StaticOptions as so} from "../StaticOptions";
|
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
|
* @since 23.1.x
|
||||||
* This widget gives us category colors and icons in the options and selected value.
|
* 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()
|
static get styles()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
...super.styles,
|
...super.styles,
|
||||||
css`
|
css`
|
||||||
/* Category color on options */
|
:host {
|
||||||
|
--category-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
sl-option {
|
::part(item-item) {
|
||||||
border-left: 6px solid var(--category-color, transparent);
|
border-inline-start: 4px solid transparent;
|
||||||
}
|
border-inline-start-color: 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));
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
]
|
];
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Application to get categories from
|
||||||
|
*/
|
||||||
|
@property({type: String}) application = '';
|
||||||
|
|
||||||
static get properties()
|
/**
|
||||||
{
|
* Include global categories
|
||||||
return {
|
*/
|
||||||
...super.properties,
|
@property({type: Boolean}) globalCategories = true;
|
||||||
/**
|
|
||||||
* Include global categories
|
/**
|
||||||
*/
|
* Show categories below this parent category
|
||||||
globalCategories: {type: Boolean},
|
*/
|
||||||
/**
|
@property({type: Number}) parentCat: { type: Number }
|
||||||
* Show categories from this application. If not set, will be the current application
|
|
||||||
*/
|
|
||||||
application: {type: String},
|
|
||||||
/**
|
private keep_import : Et2CategoryTag
|
||||||
* Show categories below this parent category
|
|
||||||
*/
|
|
||||||
parentCat: {type: Number}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
@ -67,40 +59,84 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select)
|
|||||||
this.noLang = true;
|
this.noLang = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback()
|
connectedCallback()
|
||||||
{
|
{
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
if(typeof this.application == 'undefined')
|
// Default the application if not set
|
||||||
|
if(!this.application && this.getInstanceManager())
|
||||||
{
|
{
|
||||||
this.application =
|
this.application = this.getInstanceManager().app;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// 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)
|
willUpdate(changedProperties : PropertyValues)
|
||||||
{
|
{
|
||||||
super.willUpdate(changedProperties);
|
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.fetchComplete = so.cat(this).then(options => {
|
||||||
{
|
this.select_options = options;
|
||||||
this._static_options = cleanSelectOptions(options);
|
|
||||||
this.requestUpdate("select_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`
|
||||||
|
<style>${unsafeCSS(css)}</style>
|
||||||
|
`;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
protected handleValueChange(e)
|
protected handleValueChange(e)
|
||||||
{
|
{
|
||||||
@ -109,43 +145,7 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select)
|
|||||||
// Just re-draw to get the colors & icon
|
// Just re-draw to get the colors & icon
|
||||||
this.requestUpdate();
|
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`
|
|
||||||
<style>
|
|
||||||
${repeat(this.select_options, (option) =>
|
|
||||||
{
|
|
||||||
if(typeof option.color == "undefined" || !option.color)
|
|
||||||
{
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
return unsafeCSS(
|
|
||||||
(this.getValueAsArray().includes(option.value) ? "::part(combobox) { --category-color: " + option.color + ";}" : "") +
|
|
||||||
".cat_" + option.value + " {--category-color: " + option.color + ";}"
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</style>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
customElements.define("et2-select-cat", Et2SelectCategory);
|
@ -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`
|
|
||||||
<style>${unsafeCSS(css)}</style>
|
|
||||||
`;
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore Type problems because of Et2WidgetWithSelectMixin in parent
|
|
||||||
customElements.define("et2-tree-cat", Et2TreeDropdownCategory);
|
|
@ -113,7 +113,6 @@ import "./Et2Textbox/Et2Password";
|
|||||||
import './Et2Textbox/Et2Searchbox';
|
import './Et2Textbox/Et2Searchbox';
|
||||||
import "./Et2Tree/Et2Tree";
|
import "./Et2Tree/Et2Tree";
|
||||||
import "./Et2Tree/Et2TreeDropdown";
|
import "./Et2Tree/Et2TreeDropdown";
|
||||||
import "./Et2Tree/Et2TreeDropdownCategory";
|
|
||||||
|
|
||||||
|
|
||||||
/* Include all widget classes here, we only care about them registering, not importing anything*/
|
/* Include all widget classes here, we only care about them registering, not importing anything*/
|
||||||
|
Loading…
Reference in New Issue
Block a user