From 6d86067ceaa2d47dbd0e73a488b72a4be7c9e30b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 29 Dec 2022 10:51:43 +0100 Subject: [PATCH] web/elements: add grouping and descriptions to search select Signed-off-by: Jens Langhammer --- web/src/elements/SearchSelect.ts | 89 +++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/web/src/elements/SearchSelect.ts b/web/src/elements/SearchSelect.ts index 07a6365f0..99fc02bb8 100644 --- a/web/src/elements/SearchSelect.ts +++ b/web/src/elements/SearchSelect.ts @@ -1,3 +1,4 @@ +import { groupBy } from "@goauthentik/common/utils"; import { AKElement } from "@goauthentik/elements/Base"; import { t } from "@lingui/macro"; @@ -44,23 +45,33 @@ export class SearchSelect extends AKElement { @property({ attribute: false }) renderElement!: (element: T) => string; + @property({ attribute: false }) + renderDescription?: (element: T) => TemplateResult; + @property({ attribute: false }) value!: (element: T | undefined) => unknown; @property({ attribute: false }) - selected!: (element: T) => boolean; + selected?: (element: T) => boolean; firstUpdated(): void { this.fetchObjects(this.query).then((objects) => { this.objects = objects; this.objects.forEach((obj) => { - if (this.selected(obj)) { + if (this.selected && this.selected(obj)) { this.selectedObject = obj; } }); }); } + @property({ attribute: false }) + groupBy: (items: T[]) => [string, T[]][] = (items: T[]): [string, T[]][] => { + return groupBy(items, () => { + return ""; + }); + }; + menuId: string; constructor() { @@ -86,6 +97,50 @@ export class SearchSelect extends AKElement { */ renderMenu(): void { const pos = this.getBoundingClientRect(); + let groupedItems = this.groupBy(this.objects); + let shouldRenderGroups = true; + if (groupedItems.length === 1) { + if (groupedItems[0].length < 1 || groupedItems[0][0] === "") { + shouldRenderGroups = false; + } + } + if (groupedItems.length === 0) { + shouldRenderGroups = false; + groupedItems = [["", []]]; + } + const renderGroup = (items: T[]): TemplateResult => { + return html`${items.map((obj) => { + let desc = undefined; + if (this.renderDescription) { + desc = this.renderDescription(obj); + } + return html` +
  • + +
  • + `; + })}`; + }; render( html`
    extends AKElement {
      ${this.blankable ? html` -
    • +
    • ` : html``} - ${this.objects.map((obj) => { - return html` -
    • - -
    • - `; - })} + ${shouldRenderGroups + ? html`${groupedItems.map(([group, items]) => { + return html` +
      +

      ${group}

      +
        + ${renderGroup(items)} +
      +
      + `; + })}` + : html`${renderGroup(groupedItems[0][1])}`}
    `, document.body,