Filter crawls, configs, browser profiles by user ID (#463)

* filter crawls by user id

* filter crawl configs by user id

* text change: Filter My Crawls -> Show Only Mine

Co-authored-by: Ilya Kreymer <ikreymer@users.noreply.github.com>
This commit is contained in:
sua yoo 2023-01-11 20:32:14 -08:00 committed by GitHub
parent 5efeaa58b1
commit a7457ca334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 19 deletions

View File

@ -1,4 +1,4 @@
import type { HTMLTemplateResult } from "lit";
import type { HTMLTemplateResult, PropertyValueMap } from "lit";
import { state, property } from "lit/decorators.js";
import { msg, localized, str } from "@lit/localize";
import { parseCron } from "@cheap-glitch/mi-cron";
@ -18,6 +18,7 @@ import {
humanizeSchedule,
} from "../../utils/cron";
import "../../components/crawl-scheduler";
import { SlCheckbox } from "@shoelace-style/shoelace";
type RunningCrawlsMap = {
/** Map of configId: crawlId */
@ -46,6 +47,9 @@ export class CrawlTemplatesList extends LiteElement {
@property({ type: String })
archiveId!: string;
@property({ type: String })
userId!: string;
@state()
crawlTemplates?: CrawlConfig[];
@ -67,6 +71,9 @@ export class CrawlTemplatesList extends LiteElement {
direction: "desc",
};
@state()
private filterByCurrentUser = true;
@state()
private searchBy: string = "";
@ -80,18 +87,23 @@ export class CrawlTemplatesList extends LiteElement {
threshold: 0.4, // stricter; default is 0.6
});
async firstUpdated() {
try {
this.crawlTemplates = await this.getCrawlTemplates();
protected async willUpdate(changedProperties: Map<string, any>) {
if (
changedProperties.has("archiveId") ||
changedProperties.has("filterByCurrentUser")
) {
try {
this.crawlTemplates = await this.getCrawlTemplates();
// Update search/filter collection
this.fuse.setCollection(this.crawlTemplates as any);
} catch (e) {
this.notify({
message: msg("Sorry, couldn't retrieve crawl configs at this time."),
variant: "danger",
icon: "exclamation-octagon",
});
// Update search/filter collection
this.fuse.setCollection(this.crawlTemplates as any);
} catch (e) {
this.notify({
message: msg("Sorry, couldn't retrieve crawl configs at this time."),
variant: "danger",
icon: "exclamation-octagon",
});
}
}
}
@ -200,6 +212,21 @@ export class CrawlTemplatesList extends LiteElement {
</button>
</div>
<div class="flex items-center justify-end">
${this.userId
? html`<label class="mr-3">
<span class="text-neutral-500 mr-1"
>${msg("Show Only Mine")}</span
>
<sl-switch
@sl-change=${(e: CustomEvent) =>
(this.filterByCurrentUser = (
e.target as SlCheckbox
).checked)}
?checked=${this.filterByCurrentUser}
></sl-switch>
</label>`
: ""}
<div class="whitespace-nowrap text-sm text-0-500 mr-2">
${msg("Sort By")}
</div>
@ -553,8 +580,11 @@ export class CrawlTemplatesList extends LiteElement {
* associated with the crawl configs
**/
private async getCrawlTemplates(): Promise<CrawlConfig[]> {
const params =
this.userId && this.filterByCurrentUser ? `?userid=${this.userId}` : "";
const data: { crawlConfigs: CrawlConfig[] } = await this.apiFetch(
`/archives/${this.archiveId}/crawlconfigs`,
`/archives/${this.archiveId}/crawlconfigs${params}`,
this.authState!
);

View File

@ -12,6 +12,7 @@ import { RelativeDuration } from "../../components/relative-duration";
import type { AuthState } from "../../utils/AuthService";
import LiteElement, { html } from "../../utils/LiteElement";
import type { Crawl, CrawlConfig, InitialCrawlConfig } from "./types";
import { SlCheckbox } from "@shoelace-style/shoelace";
type CrawlSearchResult = {
item: Crawl;
@ -50,6 +51,9 @@ export class CrawlsList extends LiteElement {
@property({ type: Object })
authState!: AuthState;
@property({ type: String })
userId!: string;
// e.g. `/archive/${this.archiveId}/crawls`
@property({ type: String })
crawlsBaseUrl!: string;
@ -80,6 +84,9 @@ export class CrawlsList extends LiteElement {
direction: "desc",
};
@state()
private filterByCurrentUser = true;
@state()
private filterBy: string = "";
@ -104,7 +111,8 @@ export class CrawlsList extends LiteElement {
if (
changedProperties.has("shouldFetch") ||
changedProperties.get("crawlsBaseUrl") ||
changedProperties.get("crawlsAPIBaseUrl")
changedProperties.get("crawlsAPIBaseUrl") ||
changedProperties.has("filterByCurrentUser")
) {
if (this.shouldFetch) {
if (!this.crawlsBaseUrl) {
@ -182,6 +190,21 @@ export class CrawlsList extends LiteElement {
</sl-input>
</div>
<div class="col-span-12 md:col-span-1 flex items-center justify-end">
${this.userId
? html`<label class="mr-3">
<span class="text-neutral-500 mr-1"
>${msg("Show Only Mine")}</span
>
<sl-switch
@sl-change=${(e: CustomEvent) =>
(this.filterByCurrentUser = (
e.target as SlCheckbox
).checked)}
?checked=${this.filterByCurrentUser}
></sl-switch>
</label>`
: ""}
<div class="whitespace-nowrap text-neutral-500 mr-2">
${msg("Sort By")}
</div>
@ -554,13 +577,11 @@ export class CrawlsList extends LiteElement {
}
private async getCrawls(): Promise<{ crawls: Crawl[] }> {
// Mock to use in dev:
// return import("../../__mocks__/api/archives/[id]/crawls").then(
// (module) => module.default
// );
const params =
this.userId && this.filterByCurrentUser ? `?userid=${this.userId}` : "";
const data = await this.apiFetch(
this.crawlsAPIBaseUrl || this.crawlsBaseUrl,
`${this.crawlsAPIBaseUrl || this.crawlsBaseUrl}${params}`,
this.authState!
);

View File

@ -164,6 +164,7 @@ export class Archive extends LiteElement {
return html`<btrix-crawls-list
.authState=${this.authState!}
userId=${this.userInfo!.id}
crawlsBaseUrl=${crawlsBaseUrl}
?shouldFetch=${this.archiveTab === "crawls"}
></btrix-crawls-list>`;
@ -196,6 +197,7 @@ export class Archive extends LiteElement {
return html`<btrix-crawl-templates-list
.authState=${this.authState!}
.archiveId=${this.archiveId!}
userId=${this.userInfo!.id}
></btrix-crawl-templates-list>`;
}