web: code quality pass, extra comments, pre-commit check.

This commit is contained in:
Ken Sternberg 2024-01-04 13:21:13 -08:00
parent e1c0cd44ae
commit 8fa2bf4713
6 changed files with 68 additions and 62 deletions

View File

@ -1,4 +1,5 @@
import { AKElement } from "@goauthentik/elements/Base";
import { debounce } from "@goauthentik/elements/utils/debounce";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { msg } from "@lit/localize";
@ -6,7 +7,6 @@ import { PropertyValues, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { createRef, 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";
@ -55,10 +55,6 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
private pagination?: Pagination;
get value() {
return this.dualSelector.value!.selected.map(([k, _]) => k);
}
selectedMap: WeakMap<DataProvider, DualSelectPair[]> = new WeakMap();
constructor() {
@ -74,32 +70,6 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
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>) {
if (changedProperties.has("searchDelay")) {
this.doSearch = debounce(this.doSearch.bind(this), this.searchDelay);
@ -127,6 +97,36 @@ export class AkDualSelectProvider extends CustomListenerElement(AKElement) {
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() {
return html`<ak-dual-select
${ref(this.dualSelector)}

View File

@ -113,10 +113,6 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
this.addCustomListener("ak-search", this.handleSearch);
}
get value() {
return this.selected;
}
willUpdate(changedProperties: PropertyValues<this>) {
if (changedProperties.has("selected")) {
this.selectedKeys = new Set(this.selected.map(([key, _]) => key));
@ -246,6 +242,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
this.selectedPane.value!.clearMove();
}
get value() {
return this.selected;
}
get canAddAll() {
// False unless any visible option cannot be found in the selected list, so can still be
// added.
@ -268,14 +268,16 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
}
render() {
const selected = this.selectedFilter === "" ? this.selected :
this.selected.filter(([_k, v, s]) => {
const value = s !== undefined ? s : v;
if (typeof value !== "string") {
throw new Error("Filter only works when there's a string comparator");
}
return value.toLowerCase().includes(this.selectedFilter.toLowerCase())
});
const selected =
this.selectedFilter === ""
? this.selected
: this.selected.filter(([_k, v, s]) => {
const value = s !== undefined ? s : v;
if (typeof value !== "string") {
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 selectedCount = this.selectedPane.value?.toMove.size ?? 0;

View File

@ -80,10 +80,6 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
});
}
get moveable() {
return Array.from(this.toMove.values());
}
clearMove() {
this.toMove = new Set();
}
@ -112,6 +108,10 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
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
// 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

View File

@ -63,8 +63,13 @@ export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
this.onMove = this.onMove.bind(this);
}
get moveable() {
return Array.from(this.toMove.values());
connectedCallback() {
super.connectedCallback();
hostAttributes.forEach(([attr, value]) => {
if (!this.hasAttribute(attr)) {
this.setAttribute(attr, value);
}
});
}
clearMove() {
@ -92,13 +97,8 @@ export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
this.requestUpdate();
}
connectedCallback() {
super.connectedCallback();
hostAttributes.forEach(([attr, value]) => {
if (!this.hasAttribute(attr)) {
this.setAttribute(attr, value);
}
});
get moveable() {
return Array.from(this.toMove.values());
}
render() {

View File

@ -19,14 +19,18 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
return styles;
}
input: Ref<HTMLInputElement> = createRef();
@property({ type: String, reflect: true })
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 })
name = "";
input: Ref<HTMLInputElement> = createRef();
constructor() {
super();
this.onChange = this.onChange.bind(this);
@ -38,7 +42,7 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
}
this.dispatchCustomEvent<SearchbarEvent>("ak-search", {
source: this.name,
value: this.value
value: this.value,
});
}

View File

@ -22,5 +22,5 @@ export interface SearchbarEvent extends CustomEvent {
detail: {
source: string;
value: string;
}
};
}