Skip to content

Commit 9e65a90

Browse files
committed
add table
1 parent 431df44 commit 9e65a90

File tree

5 files changed

+179
-8
lines changed

5 files changed

+179
-8
lines changed

frontend/src/components/ui/data-grid/data-grid.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,14 @@ export class DataGrid<
149149

150150
return html`
151151
<slot name="label">
152-
<label id=${this.formControlLabelId} class="form-label text-xs">
153-
${this.formControlLabel}
154-
</label>
152+
${this.formControlLabel
153+
? html`<label
154+
id=${this.formControlLabelId}
155+
class="form-label text-xs"
156+
>
157+
${this.formControlLabel}
158+
</label>`
159+
: nothing}
155160
</slot>
156161
<div
157162
class=${clsx(
Lines changed: 159 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,168 @@
1-
import { localized } from "@lit/localize";
2-
import { html } from "lit";
3-
import { customElement } from "lit/decorators.js";
1+
import { localized, msg } from "@lit/localize";
2+
import { Task } from "@lit/task";
3+
import { html, type PropertyValues } from "lit";
4+
import { customElement, property, state } from "lit/decorators.js";
5+
import { when } from "lit/directives/when.js";
6+
import queryString from "query-string";
7+
8+
import { loadingPanel } from "../templates/loading-panel";
49

510
import { BtrixElement } from "@/classes/BtrixElement";
11+
import { parsePage, type PageChangeEvent } from "@/components/ui/pagination";
12+
import { OrgTab } from "@/routes";
13+
import { noData } from "@/strings/ui";
14+
import type { APIPaginatedList, APIPaginationQuery } from "@/types/api";
15+
import type { Collection } from "@/types/collection";
16+
import { isNotEqual } from "@/utils/is-not-equal";
17+
18+
const INITIAL_PAGE_SIZE = 10;
619

720
@customElement("btrix-org-settings-deduplication")
821
@localized()
922
export class OrgSettingsDeduplication extends BtrixElement {
23+
@property({ type: Boolean })
24+
visible?: boolean;
25+
26+
@state({ hasChanged: isNotEqual })
27+
private pagination: Required<APIPaginationQuery> = {
28+
page: parsePage(new URLSearchParams(location.search).get("page")),
29+
pageSize: INITIAL_PAGE_SIZE,
30+
};
31+
32+
protected willUpdate(changedProperties: PropertyValues): void {
33+
// Reset pagination when tab is hidden
34+
if (changedProperties.has("visible") && !this.visible) {
35+
this.pagination = {
36+
...this.pagination,
37+
page: 1,
38+
};
39+
}
40+
}
41+
42+
private readonly sources = new Task(this, {
43+
task: async ([pagination], { signal }) => {
44+
return this.getCollections({ ...pagination }, signal);
45+
},
46+
args: () => [this.pagination] as const,
47+
});
48+
1049
render() {
11-
return html`TODO`;
50+
return html` ${this.sources.render({
51+
initial: loadingPanel,
52+
pending: () =>
53+
this.sources.value
54+
? this.renderTable(this.sources.value)
55+
: loadingPanel(),
56+
complete: this.renderTable,
57+
})}`;
58+
}
59+
60+
private readonly renderTable = (
61+
collections: APIPaginatedList<Collection>,
62+
) => {
63+
return html`<btrix-table
64+
class="whitespace-nowrap [--btrix-table-cell-padding-x:var(--sl-spacing-2x-small)]"
65+
style="--btrix-table-grid-template-columns: 10ch 40ch repeat(4, 1fr) min-content"
66+
>
67+
<btrix-table-head class="mb-2">
68+
<btrix-table-header-cell>
69+
${msg("Source Type")}
70+
</btrix-table-header-cell>
71+
<btrix-table-header-cell>${msg("Name")}</btrix-table-header-cell>
72+
<btrix-table-header-cell>
73+
${msg("Archived Items")}
74+
</btrix-table-header-cell>
75+
<btrix-table-header-cell>
76+
${msg("Index Entries")}
77+
</btrix-table-header-cell>
78+
<btrix-table-header-cell>
79+
${msg("Index Size")}
80+
</btrix-table-header-cell>
81+
<btrix-table-header-cell>
82+
${msg("Purgeable Entries")}
83+
</btrix-table-header-cell>
84+
<btrix-table-header-cell>
85+
<span class="sr-only">${msg("Actions")}</span>
86+
</btrix-table-header-cell>
87+
</btrix-table-head>
88+
<btrix-table-body
89+
class="rounded border [--btrix-table-cell-padding:var(--sl-spacing-2x-small)]"
90+
>
91+
${collections.items.map(
92+
(item) => html`
93+
<btrix-table-row
94+
class="border-t first:border-t-0 last:rounded-b hover:bg-neutral-50"
95+
>
96+
<btrix-table-cell>
97+
<btrix-badge>${msg("Collection")}</btrix-badge>
98+
</btrix-table-cell>
99+
<btrix-table-cell>${item.name}</btrix-table-cell>
100+
<btrix-table-cell
101+
>${this.localize.number(item.crawlCount)}</btrix-table-cell
102+
>
103+
<btrix-table-cell>${noData}</btrix-table-cell>
104+
<btrix-table-cell>${noData}</btrix-table-cell>
105+
<btrix-table-cell>${noData}</btrix-table-cell>
106+
<btrix-table-cell>
107+
<sl-tooltip content=${msg("Open in New Tab")}>
108+
<sl-icon-button
109+
name="arrow-up-right"
110+
href="${this.navigate
111+
.orgBasePath}/${OrgTab.Collections}/view/${item.id}"
112+
target="_blank"
113+
>
114+
</sl-icon-button>
115+
</sl-tooltip>
116+
<btrix-overflow-dropdown>
117+
<sl-menu>
118+
<sl-menu-item class="menu-item-warning"
119+
>${msg("Clear Index")}</sl-menu-item
120+
>
121+
<sl-menu-item class="menu-item-danger"
122+
>${msg("Delete Index")}</sl-menu-item
123+
>
124+
</sl-menu>
125+
</btrix-overflow-dropdown>
126+
</btrix-table-cell>
127+
</btrix-table-row>
128+
`,
129+
)}
130+
</btrix-table-body>
131+
</btrix-table>
132+
${when(
133+
collections.total > collections.pageSize,
134+
() => html`
135+
<footer class="mt-6 flex justify-center">
136+
<btrix-pagination
137+
page=${collections.page}
138+
totalCount=${collections.total}
139+
size=${collections.pageSize}
140+
@page-change=${async (e: PageChangeEvent) => {
141+
this.pagination = {
142+
...this.pagination,
143+
page: e.detail.page,
144+
};
145+
}}
146+
></btrix-pagination>
147+
</footer>
148+
`,
149+
)} `;
150+
};
151+
152+
private async getCollections(
153+
params: APIPaginationQuery,
154+
signal: AbortSignal,
155+
) {
156+
const query = queryString.stringify({
157+
pageSize: 2,
158+
...params,
159+
hasDedupeIndex: true,
160+
});
161+
return this.api.fetch<APIPaginatedList<Collection>>(
162+
`/orgs/${this.orgId}/collections?${query}`,
163+
{
164+
signal,
165+
},
166+
);
12167
}
13168
}

frontend/src/pages/org/settings/settings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ export class OrgSettings extends BtrixElement {
219219
<btrix-org-settings-crawling-defaults></btrix-org-settings-crawling-defaults>
220220
</btrix-tab-group-panel>
221221
<btrix-tab-group-panel name="deduplication">
222-
${this.renderPanelHeader({ title: this.tabLabels.deduplication })}
222+
${this.renderPanelHeader({ title: msg("Deduplication Sources") })}
223223
<btrix-org-settings-deduplication></btrix-org-settings-deduplication>
224224
</btrix-tab-group-panel>
225225
</btrix-tab-group>`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { html } from "lit";
2+
3+
export const loadingPanel = () => {
4+
return html`<div class="flex justify-center rounded border p-5 text-xl">
5+
<sl-spinner></sl-spinner>
6+
</div>`;
7+
};

frontend/src/theme.stylesheet.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@
241241
@apply part-[base]:text-success part-[base]:hover:bg-success-50 part-[base]:hover:text-success-700 part-[base]:focus-visible:bg-success-50;
242242
}
243243

244+
.menu-item-warning {
245+
@apply part-[base]:text-warning part-[base]:hover:bg-warning-50 part-[base]:hover:text-warning-700 part-[base]:focus-visible:bg-warning-50;
246+
}
247+
244248
.menu-item-danger {
245249
@apply part-[base]:text-danger part-[base]:hover:bg-danger-50 part-[base]:hover:text-danger-700 part-[base]:focus-visible:bg-danger-50;
246250
}

0 commit comments

Comments
 (0)