web: code quality pass, extra comments, pre-commit check.
This commit is contained in:
parent
e1c0cd44ae
commit
8fa2bf4713
|
@ -1,4 +1,5 @@
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
import { debounce } from "@goauthentik/elements/utils/debounce";
|
||||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
|
@ -6,7 +7,6 @@ import { PropertyValues, html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
import { createRef, ref } from "lit/directives/ref.js";
|
import { createRef, ref } from "lit/directives/ref.js";
|
||||||
import type { Ref } from "lit/directives/ref.js";
|
import type { Ref } from "lit/directives/ref.js";
|
||||||
import { debounce } from "@goauthentik/elements/utils/debounce";
|
|
||||||
|
|
||||||
import type { Pagination } from "@goauthentik/api";
|
import type { Pagination } from "@goauthentik/api";
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
|
||||||
/** The remote lists are debounced by definition. This is the interval for the debounce. */
|
/** The remote lists are debounced by definition. This is the interval for the debounce. */
|
||||||
@property({ attribute: "search-delay", type: Number })
|
@property({ attribute: "search-delay", type: Number })
|
||||||
searchDelay = 250;
|
searchDelay = 250;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private options: DualSelectPair[] = [];
|
private options: DualSelectPair[] = [];
|
||||||
|
|
||||||
|
@ -55,10 +55,6 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
|
||||||
|
|
||||||
private pagination?: Pagination;
|
private pagination?: Pagination;
|
||||||
|
|
||||||
get value() {
|
|
||||||
return this.dualSelector.value!.selected.map(([k, _]) => k);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedMap: WeakMap<DataProvider, DualSelectPair[]> = new WeakMap();
|
selectedMap: WeakMap<DataProvider, DualSelectPair[]> = new WeakMap();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -74,32 +70,6 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
|
||||||
this.addCustomListener("ak-dual-select-search", this.onSearch);
|
this.addCustomListener("ak-dual-select-search", this.onSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
onNav(event: Event) {
|
|
||||||
if (!(event instanceof CustomEvent)) {
|
|
||||||
throw new Error(`Expecting a CustomEvent for navigation, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.fetch(event.detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange(event: Event) {
|
|
||||||
if (!(event instanceof CustomEvent)) {
|
|
||||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.selected = event.detail.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
doSearch(search: string) {
|
|
||||||
this.pagination = undefined;
|
|
||||||
this.fetch(undefined, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch(event: Event) {
|
|
||||||
if (!(event instanceof CustomEvent)) {
|
|
||||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
|
||||||
}
|
|
||||||
this.doSearch(event.detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
willUpdate(changedProperties: PropertyValues<this>) {
|
willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
if (changedProperties.has("searchDelay")) {
|
if (changedProperties.has("searchDelay")) {
|
||||||
this.doSearch = debounce(this.doSearch.bind(this), this.searchDelay);
|
this.doSearch = debounce(this.doSearch.bind(this), this.searchDelay);
|
||||||
|
@ -127,6 +97,36 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onNav(event: Event) {
|
||||||
|
if (!(event instanceof CustomEvent)) {
|
||||||
|
throw new Error(`Expecting a CustomEvent for navigation, received ${event} instead`);
|
||||||
|
}
|
||||||
|
this.fetch(event.detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(event: Event) {
|
||||||
|
if (!(event instanceof CustomEvent)) {
|
||||||
|
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
||||||
|
}
|
||||||
|
this.selected = event.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearch(event: Event) {
|
||||||
|
if (!(event instanceof CustomEvent)) {
|
||||||
|
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
||||||
|
}
|
||||||
|
this.doSearch(event.detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
doSearch(search: string) {
|
||||||
|
this.pagination = undefined;
|
||||||
|
this.fetch(undefined, search);
|
||||||
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this.dualSelector.value!.selected.map(([k, _]) => k);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`<ak-dual-select
|
return html`<ak-dual-select
|
||||||
${ref(this.dualSelector)}
|
${ref(this.dualSelector)}
|
||||||
|
|
|
@ -113,10 +113,6 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||||
this.addCustomListener("ak-search", this.handleSearch);
|
this.addCustomListener("ak-search", this.handleSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
|
||||||
return this.selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
willUpdate(changedProperties: PropertyValues<this>) {
|
willUpdate(changedProperties: PropertyValues<this>) {
|
||||||
if (changedProperties.has("selected")) {
|
if (changedProperties.has("selected")) {
|
||||||
this.selectedKeys = new Set(this.selected.map(([key, _]) => key));
|
this.selectedKeys = new Set(this.selected.map(([key, _]) => key));
|
||||||
|
@ -246,6 +242,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||||
this.selectedPane.value!.clearMove();
|
this.selectedPane.value!.clearMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get value() {
|
||||||
|
return this.selected;
|
||||||
|
}
|
||||||
|
|
||||||
get canAddAll() {
|
get canAddAll() {
|
||||||
// False unless any visible option cannot be found in the selected list, so can still be
|
// False unless any visible option cannot be found in the selected list, so can still be
|
||||||
// added.
|
// added.
|
||||||
|
@ -268,15 +268,17 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const selected = this.selectedFilter === "" ? this.selected :
|
const selected =
|
||||||
this.selected.filter(([_k, v, s]) => {
|
this.selectedFilter === ""
|
||||||
const value = s !== undefined ? s : v;
|
? this.selected
|
||||||
if (typeof value !== "string") {
|
: this.selected.filter(([_k, v, s]) => {
|
||||||
throw new Error("Filter only works when there's a string comparator");
|
const value = s !== undefined ? s : v;
|
||||||
}
|
if (typeof value !== "string") {
|
||||||
return value.toLowerCase().includes(this.selectedFilter.toLowerCase())
|
throw new Error("Filter only works when there's a string comparator");
|
||||||
});
|
}
|
||||||
|
return value.toLowerCase().includes(this.selectedFilter.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
const availableCount = this.availablePane.value?.toMove.size ?? 0;
|
const availableCount = this.availablePane.value?.toMove.size ?? 0;
|
||||||
const selectedCount = this.selectedPane.value?.toMove.size ?? 0;
|
const selectedCount = this.selectedPane.value?.toMove.size ?? 0;
|
||||||
const selectedTotal = selected.length;
|
const selectedTotal = selected.length;
|
||||||
|
|
|
@ -80,10 +80,6 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveable() {
|
|
||||||
return Array.from(this.toMove.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
clearMove() {
|
clearMove() {
|
||||||
this.toMove = new Set();
|
this.toMove = new Set();
|
||||||
}
|
}
|
||||||
|
@ -112,6 +108,10 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get moveable() {
|
||||||
|
return Array.from(this.toMove.values());
|
||||||
|
}
|
||||||
|
|
||||||
// DO NOT use `Array.map()` instead of Lit's `map()` function. Lit's `map()` is object-aware and
|
// DO NOT use `Array.map()` instead of Lit's `map()` function. Lit's `map()` is object-aware and
|
||||||
// will not re-arrange or reconstruct the list automatically if the actual sources do not
|
// will not re-arrange or reconstruct the list automatically if the actual sources do not
|
||||||
// change; this allows the available pane to illustrate selected items with the checkmark
|
// change; this allows the available pane to illustrate selected items with the checkmark
|
||||||
|
|
|
@ -63,8 +63,13 @@ export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
|
||||||
this.onMove = this.onMove.bind(this);
|
this.onMove = this.onMove.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get moveable() {
|
connectedCallback() {
|
||||||
return Array.from(this.toMove.values());
|
super.connectedCallback();
|
||||||
|
hostAttributes.forEach(([attr, value]) => {
|
||||||
|
if (!this.hasAttribute(attr)) {
|
||||||
|
this.setAttribute(attr, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
clearMove() {
|
clearMove() {
|
||||||
|
@ -92,13 +97,8 @@ export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
|
||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
get moveable() {
|
||||||
super.connectedCallback();
|
return Array.from(this.toMove.values());
|
||||||
hostAttributes.forEach(([attr, value]) => {
|
|
||||||
if (!this.hasAttribute(attr)) {
|
|
||||||
this.setAttribute(attr, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -19,14 +19,18 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
input: Ref<HTMLInputElement> = createRef();
|
|
||||||
|
|
||||||
@property({ type: String, reflect: true })
|
@property({ type: String, reflect: true })
|
||||||
value = "";
|
value = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If you're using more than one search, this token can help listeners distinguishing between
|
||||||
|
* those searches. Lit's own helpers sometimes erase the source and current targets.
|
||||||
|
*/
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
name = "";
|
name = "";
|
||||||
|
|
||||||
|
input: Ref<HTMLInputElement> = createRef();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
|
@ -38,7 +42,7 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
||||||
}
|
}
|
||||||
this.dispatchCustomEvent<SearchbarEvent>("ak-search", {
|
this.dispatchCustomEvent<SearchbarEvent>("ak-search", {
|
||||||
source: this.name,
|
source: this.name,
|
||||||
value: this.value
|
value: this.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,5 @@ export interface SearchbarEvent extends CustomEvent {
|
||||||
detail: {
|
detail: {
|
||||||
source: string;
|
source: string;
|
||||||
value: string;
|
value: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue