198 lines
5.7 KiB
TypeScript
198 lines
5.7 KiB
TypeScript
import type { TemplateResult, LitElement } from "lit";
|
|
import { state, property } from "lit/decorators.js";
|
|
import { when } from "lit/directives/when.js";
|
|
import { msg, localized, str } from "@lit/localize";
|
|
import { mergeDeep } from "immutable";
|
|
|
|
import type { AuthState } from "../../utils/AuthService";
|
|
import LiteElement, { html } from "../../utils/LiteElement";
|
|
import type { JobType, WorkflowParams } from "./types";
|
|
import "./workflow-editor";
|
|
import seededCrawlSvg from "../../assets/images/new-crawl-config_Seeded-Crawl.svg";
|
|
import urlListSvg from "../../assets/images/new-crawl-config_URL-List.svg";
|
|
|
|
const defaultValue = {
|
|
name: "",
|
|
description: null,
|
|
profileid: null,
|
|
schedule: "",
|
|
config: {
|
|
seeds: [],
|
|
scopeType: "prefix",
|
|
exclude: [""],
|
|
},
|
|
tags: [],
|
|
crawlTimeout: null,
|
|
jobType: undefined,
|
|
scale: 1,
|
|
} as WorkflowParams;
|
|
|
|
/**
|
|
* Usage:
|
|
* ```ts
|
|
* <btrix-workflows-new></btrix-workflows-new>
|
|
* ```
|
|
*/
|
|
@localized()
|
|
export class WorkflowsNew extends LiteElement {
|
|
@property({ type: Object })
|
|
authState!: AuthState;
|
|
|
|
@property({ type: String })
|
|
orgId!: string;
|
|
|
|
@property({ type: Boolean })
|
|
isCrawler!: boolean;
|
|
|
|
// Use custom property accessor to prevent
|
|
// overriding default Workflow values
|
|
@property({ type: Object })
|
|
get initialWorkflow(): WorkflowParams {
|
|
return this._initialWorkflow;
|
|
}
|
|
private _initialWorkflow: WorkflowParams = defaultValue;
|
|
set initialWorkflow(val: Partial<WorkflowParams>) {
|
|
this._initialWorkflow = mergeDeep(this._initialWorkflow, val);
|
|
}
|
|
|
|
@state()
|
|
private jobType?: JobType;
|
|
|
|
connectedCallback() {
|
|
super.connectedCallback();
|
|
if (!this.jobType) {
|
|
const url = new URL(window.location.href);
|
|
this.jobType = (url.searchParams.get("jobType") as JobType) || undefined;
|
|
}
|
|
}
|
|
|
|
private renderHeader() {
|
|
let href = `/orgs/${this.orgId}/workflows`;
|
|
let label = msg("Back to Workflows");
|
|
|
|
// Allow user to go back to choose crawl type if new (not duplicated) config
|
|
if (this.jobType && !this.initialWorkflow.jobType) {
|
|
href = `/orgs/${this.orgId}/workflows?new`;
|
|
label = msg("Choose Crawl Type");
|
|
}
|
|
return html`
|
|
<nav class="mb-5">
|
|
<a
|
|
class="text-gray-600 hover:text-gray-800 text-sm font-medium"
|
|
href=${href}
|
|
@click=${(e: any) => {
|
|
this.navLink(e);
|
|
this.jobType = undefined;
|
|
}}
|
|
>
|
|
<sl-icon
|
|
name="arrow-left"
|
|
class="inline-block align-middle"
|
|
></sl-icon>
|
|
<span class="inline-block align-middle">${label}</span>
|
|
</a>
|
|
</nav>
|
|
`;
|
|
}
|
|
|
|
render() {
|
|
const jobTypeLabels: Record<JobType, string> = {
|
|
"url-list": msg("URL List"),
|
|
"seed-crawl": msg("Seeded Crawl"),
|
|
custom: msg("Custom"),
|
|
};
|
|
|
|
const jobType = this.initialWorkflow.jobType || this.jobType;
|
|
|
|
if (this.isCrawler && jobType) {
|
|
return html`
|
|
${this.renderHeader()}
|
|
<h2 class="text-xl font-medium mb-6">
|
|
${msg(html`New Workflow — ${jobTypeLabels[jobType]}`)}
|
|
</h2>
|
|
<btrix-workflow-editor
|
|
.initialWorkflow=${this.initialWorkflow}
|
|
jobType=${jobType}
|
|
orgId=${this.orgId}
|
|
.authState=${this.authState}
|
|
@reset=${async (e: Event) => {
|
|
await (e.target as LitElement).updateComplete;
|
|
this.jobType = undefined;
|
|
}}
|
|
></btrix-workflow-editor>
|
|
`;
|
|
}
|
|
|
|
return html`
|
|
${this.renderHeader()}
|
|
<h2 class="text-xl font-medium mb-6">${msg("New Workflow")}</h2>
|
|
${when(this.isCrawler, this.renderChooseJobType, this.renderNoAccess)}
|
|
`;
|
|
}
|
|
|
|
private renderChooseJobType = () => {
|
|
return html`
|
|
<style>
|
|
.jobTypeButton:hover img {
|
|
transform: scale(1.05);
|
|
}
|
|
</style>
|
|
<h3 class="text-lg font-medium mb-3">${msg("Choose Crawl Type")}</h3>
|
|
<div
|
|
class="border rounded p-8 md:py-12 flex flex-col md:flex-row items-start justify-evenly"
|
|
>
|
|
<a
|
|
role="button"
|
|
class="jobTypeButton"
|
|
href=${`/orgs/${this.orgId}/workflows?new&jobType=url-list`}
|
|
@click=${(e: any) => {
|
|
this.navLink(e);
|
|
this.jobType = "url-list";
|
|
}}
|
|
>
|
|
<figure class="w-64 m-4">
|
|
<img class="transition-transform" src=${urlListSvg} />
|
|
<figcaption>
|
|
<div class="text-lg font-medium my-3">${msg("URL List")}</div>
|
|
<p class="text-sm text-neutral-500">
|
|
${msg(
|
|
"The crawler visits every URL specified in a list, and optionally every URL linked on those pages."
|
|
)}
|
|
</p>
|
|
</figcaption>
|
|
</figure>
|
|
</a>
|
|
<a
|
|
role="button"
|
|
class="jobTypeButton"
|
|
href=${`/orgs/${this.orgId}/workflows?new&jobType=seed-crawl`}
|
|
@click=${(e: any) => {
|
|
this.navLink(e);
|
|
this.jobType = "seed-crawl";
|
|
}}
|
|
>
|
|
<figure class="w-64 m-4">
|
|
<img class="transition-transform" src=${seededCrawlSvg} />
|
|
<figcaption>
|
|
<div class="text-lg font-medium my-3">${msg("Seeded Crawl")}</div>
|
|
<p class="text-sm text-neutral-500">
|
|
${msg(
|
|
"The crawler automatically discovers and archives pages starting from a single seed URL."
|
|
)}
|
|
</p>
|
|
</figcaption>
|
|
</figure>
|
|
</a>
|
|
</div>
|
|
`;
|
|
};
|
|
|
|
private renderNoAccess = () => html`
|
|
<btrix-alert variant="danger">
|
|
${msg(`You don't have permission to create a new Workflow.`)}
|
|
</btrix-alert>
|
|
`;
|
|
}
|
|
|
|
customElements.define("btrix-workflows-new", WorkflowsNew);
|