import type { TomOption } from "tom-select/dist/types/types"; import type { escape_html } from "tom-select/dist/types/utils"; import { AjaxSelect } from "#core:core/components/ajax-select-base.ts"; import { registerComponent } from "#core:utils/web-components.ts"; import { type CounterSchema, counterSearchCounter, type ProductTypeSchema, productSearchProducts, producttypeFetchAll, type SimpleProductSchema, } from "#openapi"; @registerComponent("product-ajax-select") export class ProductAjaxSelect extends AjaxSelect { protected valueField = "id"; protected labelField = "name"; protected searchField = ["code", "name"]; protected async search(query: string): Promise { const resp = await productSearchProducts({ // biome-ignore lint/style/useNamingConvention: API is snake_case query: { search: query, is_archived: false }, }); if (resp.data) { return resp.data.results; } return []; } protected renderOption(item: SimpleProductSchema, sanitize: typeof escape_html) { return `
${sanitize(item.code)} - ${sanitize(item.name)}
`; } protected renderItem(item: SimpleProductSchema, sanitize: typeof escape_html) { return `${sanitize(item.code)} - ${sanitize(item.name)}`; } } @registerComponent("product-type-ajax-select") export class ProductTypeAjaxSelect extends AjaxSelect { protected valueField = "id"; protected labelField = "name"; protected searchField = ["name"]; private productTypes = null as ProductTypeSchema[]; protected async search(query: string): Promise { // The production database has a grand total of 26 product types // and the filter logic is really simple. // Thus, it's appropriate to fetch all product types during first use, // then to reuse the result again and again. if (this.productTypes === null) { this.productTypes = (await producttypeFetchAll()).data || null; } return this.productTypes.filter((t) => t.name.toLowerCase().includes(query.toLowerCase()), ); } protected renderOption(item: ProductTypeSchema, sanitize: typeof escape_html) { return `
${sanitize(item.name)}
`; } protected renderItem(item: ProductTypeSchema, sanitize: typeof escape_html) { return `${sanitize(item.name)}`; } } @registerComponent("counter-ajax-select") export class CounterAjaxSelect extends AjaxSelect { protected valueField = "id"; protected labelField = "name"; protected searchField = ["code", "name"]; protected async search(query: string): Promise { const resp = await counterSearchCounter({ query: { search: query } }); if (resp.data) { return resp.data.results; } return []; } protected renderOption(item: CounterSchema, sanitize: typeof escape_html) { return `
${sanitize(item.name)}
`; } protected renderItem(item: CounterSchema, sanitize: typeof escape_html) { return `${sanitize(item.name)}`; } }