diff --git a/frontend/src/features/admin/active-crawls-badge.ts b/frontend/src/features/admin/active-crawls-badge.ts
new file mode 100644
index 0000000000..f7b87acae3
--- /dev/null
+++ b/frontend/src/features/admin/active-crawls-badge.ts
@@ -0,0 +1,60 @@
+import { localized } from "@lit/localize";
+import { Task } from "@lit/task";
+import { html } from "lit";
+import { customElement } from "lit/decorators.js";
+import queryString from "query-string";
+
+import { BtrixElement } from "@/classes/BtrixElement";
+import type { APIPaginatedList } from "@/types/api";
+import type { Crawl } from "@/types/crawler";
+
+const POLL_INTERVAL_SECONDS = 30;
+
+@customElement("btrix-active-crawls-badge")
+@localized()
+export class ActiveCrawlsBadge extends BtrixElement {
+ private readonly activeCrawlsTotalTask = new Task(this, {
+ task: async () => {
+ return await this.getActiveCrawlsTotal();
+ },
+ args: () => [] as const,
+ });
+
+ private readonly pollTask = new Task(this, {
+ task: async () => {
+ window.clearTimeout(this.pollTask.value);
+
+ return window.setTimeout(() => {
+ void this.activeCrawlsTotalTask.run();
+ }, POLL_INTERVAL_SECONDS * 1000);
+ },
+ args: () => [this.activeCrawlsTotalTask.value] as const,
+ });
+
+ disconnectedCallback(): void {
+ super.disconnectedCallback();
+
+ window.clearTimeout(this.pollTask.value);
+ }
+
+ render() {
+ if (this.activeCrawlsTotalTask.value) {
+ const { total } = this.activeCrawlsTotalTask.value;
+ return html` 0 ? "primary" : "blue"}>
+ ${this.localize.number(total)}
+ `;
+ }
+ }
+
+ private async getActiveCrawlsTotal() {
+ const query = queryString.stringify({
+ pageSize: 1,
+ });
+
+ const data = await this.api.fetch>(
+ `/orgs/all/crawls?${query}`,
+ );
+
+ return data;
+ }
+}
diff --git a/frontend/src/features/admin/index.ts b/frontend/src/features/admin/index.ts
index 1bf1a4e1d5..cb10e490c3 100644
--- a/frontend/src/features/admin/index.ts
+++ b/frontend/src/features/admin/index.ts
@@ -1,2 +1,3 @@
+import "./active-crawls-badge";
import "./stats";
import "./super-admin-banner";
diff --git a/frontend/src/index.ts b/frontend/src/index.ts
index 1a019fb0f5..61f4f981c7 100644
--- a/frontend/src/index.ts
+++ b/frontend/src/index.ts
@@ -3,7 +3,6 @@ import "./global";
import { provide } from "@lit/context";
import { localized, msg, str } from "@lit/localize";
-import { Task } from "@lit/task";
import type {
SlDialog,
SlDrawer,
@@ -15,7 +14,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import { when } from "lit/directives/when.js";
import isEqual from "lodash/fp/isEqual";
-import queryString from "query-string";
import "./components";
import "./features";
@@ -35,9 +33,7 @@ import AuthService, {
import { BtrixElement } from "@/classes/BtrixElement";
import type { NavigateEventDetail } from "@/controllers/navigate";
import type { NotifyEventDetail } from "@/controllers/notify";
-import type { APIPaginatedList } from "@/types/api";
import { type Auth } from "@/types/auth";
-import type { Crawl } from "@/types/crawler";
import {
translatedLocales,
type TranslatedLocaleEnum,
@@ -70,8 +66,6 @@ export interface UserGuideEventMap {
"btrix-user-guide-show": CustomEvent<{ path?: string }>;
}
-const POLL_INTERVAL_SECONDS = 30;
-
@customElement("browsertrix-app")
@localized()
export class App extends BtrixElement {
@@ -114,24 +108,6 @@ export class App extends BtrixElement {
@query("#userGuideDrawer")
private readonly userGuideDrawer!: SlDrawer;
- private readonly activeCrawlsTotalTask = new Task(this, {
- task: async () => {
- return await this.getActiveCrawlsTotal();
- },
- args: () => [] as const,
- });
-
- private readonly pollTask = new Task(this, {
- task: async ([crawls]) => {
- if (!crawls) return;
-
- return window.setTimeout(() => {
- void this.activeCrawlsTotalTask.run();
- }, POLL_INTERVAL_SECONDS * 1000);
- },
- args: () => [this.activeCrawlsTotalTask.value] as const,
- });
-
get orgSlugInPath() {
return this.viewState.params.slug || "";
}
@@ -188,12 +164,6 @@ export class App extends BtrixElement {
this.startSyncBrowserTabs();
}
- disconnectedCallback(): void {
- super.disconnectedCallback();
-
- window.clearTimeout(this.pollTask.value);
- }
-
private attachUserGuideListeners() {
this.addEventListener(
"btrix-user-guide-show",
@@ -479,7 +449,7 @@ export class App extends BtrixElement {
}
private renderNavBar() {
- const isSuperAdmin = this.userInfo?.isSuperAdmin;
+ const isSuperAdmin = this.authState && this.userInfo?.isSuperAdmin;
const showFullLogo =
this.viewState.route === "login" || !this.authService.authState;
@@ -629,14 +599,7 @@ export class App extends BtrixElement {
@click=${this.navigate.link}
>
${msg("Active Crawls")}
- ${when(
- this.activeCrawlsTotalTask.value,
- (total) => html`
- 0 ? "primary" : "blue"}>
- ${this.localize.number(total)}
-
- `,
- )}
+
`
@@ -1183,16 +1146,4 @@ export class App extends BtrixElement {
private clearSelectedOrg() {
AppStateService.updateOrgSlug(null);
}
-
- private async getActiveCrawlsTotal() {
- const query = queryString.stringify({
- pageSize: 1,
- });
-
- const data = await this.api.fetch>(
- `/orgs/all/crawls?${query}`,
- );
-
- return data.total;
- }
}