diff --git a/backend/btrixcloud/crawls.py b/backend/btrixcloud/crawls.py
index 8d877d0a..7f35da1e 100644
--- a/backend/btrixcloud/crawls.py
+++ b/backend/btrixcloud/crawls.py
@@ -833,7 +833,7 @@ def init_crawls_api(app, user_dep, *args):
crawl_id: str,
pageSize: int = DEFAULT_PAGE_SIZE,
page: int = 1,
- org: Organization = Depends(org_crawl_dep),
+ org: Organization = Depends(org_viewer_dep),
):
crawl_raw = await ops.get_crawl_raw(crawl_id, org)
crawl = Crawl.from_dict(crawl_raw)
diff --git a/frontend/src/components/crawl-list.ts b/frontend/src/components/crawl-list.ts
index d2287448..8f17ca0b 100644
--- a/frontend/src/components/crawl-list.ts
+++ b/frontend/src/components/crawl-list.ts
@@ -207,6 +207,9 @@ export class CrawlListItem extends LitElement {
@state()
private dropdownIsOpen?: boolean;
+ @state()
+ private hasMenuItems?: boolean;
+
// TODO localize
private numberFormatter = new Intl.NumberFormat(undefined, {
notation: "compact",
@@ -357,35 +360,7 @@ export class CrawlListItem extends LitElement {
)}
-
- {
- // Prevent anchor link default behavior
- e.preventDefault();
- // Stop prop to anchor link
- e.stopPropagation();
- this.dropdownIsOpen = !this.dropdownIsOpen;
- }}
- @focusout=${(e: FocusEvent) => {
- const relatedTarget = e.relatedTarget as HTMLElement;
- if (relatedTarget) {
- if (this.menuArr[0]?.contains(relatedTarget)) {
- // Keep dropdown open if moving to menu selection
- return;
- }
- if (this.row?.isEqualNode(relatedTarget)) {
- // Handle with click event
- return;
- }
- }
- this.dropdownIsOpen = false;
- }}
- >
-
-
+ ${this.renderActions()}
`;
}
@@ -406,6 +381,7 @@ export class CrawlListItem extends LitElement {
>
(this.hasMenuItems = this.menuArr.length > 0)}
@sl-select=${() => (this.dropdownIsOpen = false)}
>
`;
@@ -440,6 +416,42 @@ export class CrawlListItem extends LitElement {
`;
}
+ private renderActions() {
+ if (!this.hasMenuItems) {
+ return;
+ }
+
+ return html`
+ {
+ // Prevent anchor link default behavior
+ e.preventDefault();
+ // Stop prop to anchor link
+ e.stopPropagation();
+ this.dropdownIsOpen = !this.dropdownIsOpen;
+ }}
+ @focusout=${(e: FocusEvent) => {
+ const relatedTarget = e.relatedTarget as HTMLElement;
+ if (relatedTarget) {
+ if (this.menuArr[0]?.contains(relatedTarget)) {
+ // Keep dropdown open if moving to menu selection
+ return;
+ }
+ if (this.row?.isEqualNode(relatedTarget)) {
+ // Handle with click event
+ return;
+ }
+ }
+ this.dropdownIsOpen = false;
+ }}
+ >
+
+
`;
+ }
+
private repositionDropdown() {
const { x, y } = this.dropdownTrigger.getBoundingClientRect();
this.dropdown.style.left = `${x + window.scrollX}px`;
diff --git a/frontend/src/pages/org/collection-detail.ts b/frontend/src/pages/org/collection-detail.ts
index 455d3e97..1d3676b1 100644
--- a/frontend/src/pages/org/collection-detail.ts
+++ b/frontend/src/pages/org/collection-detail.ts
@@ -623,15 +623,19 @@ export class CollectionDetail extends LiteElement {
orgSlug=${this.appState.orgSlug || ""}
.crawl=${item}
>
-
- this.removeArchivedItem(item.id, idx)}
- >
-
- ${msg("Remove from Collection")}
-
-
+ ${when(
+ this.isCrawler,
+ () =>
+ html`
+ this.removeArchivedItem(item.id, idx)}
+ >
+
+ ${msg("Remove from Collection")}
+
+ `
+ )}
`;
diff --git a/frontend/src/pages/org/crawls-list.ts b/frontend/src/pages/org/crawls-list.ts
index 1b815176..6ce55572 100644
--- a/frontend/src/pages/org/crawls-list.ts
+++ b/frontend/src/pages/org/crawls-list.ts
@@ -447,28 +447,11 @@ export class CrawlsList extends LiteElement {
orgSlug=${this.appState.orgSlug || ""}
.crawl=${item}
>
-
- ${when(
- this.isCrawler,
- this.crawlerMenuItemsRenderer(item),
- () => html`
-
- this.navTo(
- `${this.orgBasePath}/items/${
- item.type === "upload" ? "upload" : "crawl"
- }/${item.id}`
- )}
- >
- ${msg("View Crawl Details")}
-
- `
- )}
-
+ ${this.crawlerMenuItemsRenderer(item)}
`;
- private crawlerMenuItemsRenderer = (item: Crawl) => () =>
+ private crawlerMenuItemsRenderer = (item: Crawl) =>
// HACK shoelace doesn't current have a way to override non-hover
// color without resetting the --sl-color-neutral-700 variable
html`
diff --git a/frontend/src/pages/org/dashboard.ts b/frontend/src/pages/org/dashboard.ts
index 440c80a3..098057b4 100644
--- a/frontend/src/pages/org/dashboard.ts
+++ b/frontend/src/pages/org/dashboard.ts
@@ -36,6 +36,12 @@ export class Dashboard extends LiteElement {
@property({ type: Object })
authState!: AuthState;
+ @property({ type: Boolean })
+ isCrawler?: boolean;
+
+ @property({ type: Boolean })
+ isAdmin?: boolean;
+
@property({ type: String })
orgId!: string;
@@ -96,48 +102,55 @@ export class Dashboard extends LiteElement {
${this.org?.name}
-
- {
- this.dispatchEvent(
- new CustomEvent("select-new-dialog", {
- detail: e.detail.item.value,
- })
- );
- }}
- >
-
-
- ${msg("Create New...")}
-
-
- ${msg("Crawl Workflow")}
- ${msg("Upload")}
-
- ${msg("Collection")}
-
-
- ${msg("Browser Profile")}
-
-
-
+ ${when(
+ this.isAdmin,
+ () =>
+ html` `
+ )}
+ ${when(
+ this.isCrawler,
+ () => html` {
+ this.dispatchEvent(
+ new CustomEvent("select-new-dialog", {
+ detail: e.detail.item.value,
+ })
+ );
+ }}
+ >
+
+
+ ${msg("Create New...")}
+
+
+ ${msg("Crawl Workflow")}
+ ${msg("Upload")}
+
+ ${msg("Collection")}
+
+
+ ${msg("Browser Profile")}
+
+
+ `
+ )}
diff --git a/frontend/src/pages/org/index.ts b/frontend/src/pages/org/index.ts
index 0c8ef24c..c9ed4f54 100644
--- a/frontend/src/pages/org/index.ts
+++ b/frontend/src/pages/org/index.ts
@@ -455,6 +455,8 @@ export class Org extends LiteElement {
.authState=${this.authState!}
orgId=${this.orgId}
.org=${this.org || null}
+ ?isCrawler=${this.isCrawler}
+ ?isAdmin=${this.isAdmin}
@select-new-dialog=${this.onSelectNewDialog}
>
`;
diff --git a/frontend/src/pages/org/workflow-detail.ts b/frontend/src/pages/org/workflow-detail.ts
index 04a28ccd..3d36d971 100644
--- a/frontend/src/pages/org/workflow-detail.ts
+++ b/frontend/src/pages/org/workflow-detail.ts
@@ -448,7 +448,7 @@ export class WorkflowDetail extends LiteElement {
)}
`;
}
- if (this.activePanel === "settings") {
+ if (this.activePanel === "settings" && this.isCrawler == true) {
return html`
${this.tabLabels[this.activePanel]}
`;
}
- if (this.activePanel === "watch") {
+ if (this.activePanel === "watch" && this.isCrawler == true) {
return html`
${this.tabLabels[this.activePanel]}
this.crawls!.items.map(
- (crawl: Crawl) => html`
-
-
-
+ (crawl: Crawl) => html`
+
+ ${when(
+ this.isCrawler,
+ () => html`
this.deleteCrawl(crawl)}
@@ -858,9 +859,9 @@ export class WorkflowDetail extends LiteElement {
${msg("Delete Crawl")}
-
-
- `
+ `
+ )}`
),
() => html`
`
)}
-
-
- this.runNow()}
+ ${when(
+ this.isCrawler,
+ () => html`
-
- ${msg("Run Crawl")}
-
-
+ this.runNow()}
+ >
+
+ ${msg("Run Crawl")}
+
+ `
+ )}
`;
diff --git a/frontend/src/pages/org/workflows-list.ts b/frontend/src/pages/org/workflows-list.ts
index 14b3db71..4a002f20 100644
--- a/frontend/src/pages/org/workflows-list.ts
+++ b/frontend/src/pages/org/workflows-list.ts
@@ -421,7 +421,7 @@ export class WorkflowsList extends LiteElement {
private renderMenuItems(workflow: ListWorkflow) {
return html`
${when(
- workflow.isCrawlRunning,
+ workflow.isCrawlRunning && this.isCrawler,
// HACK shoelace doesn't current have a way to override non-hover
// color without resetting the --sl-color-neutral-700 variable
() => html`
@@ -439,7 +439,10 @@ export class WorkflowsList extends LiteElement {
${msg("Cancel & Discard Crawl")}
- `,
+ `
+ )}
+ ${when(
+ this.isCrawler && !workflow.isCrawlRunning,
() => html`
html`
@@ -485,14 +488,19 @@ export class WorkflowsList extends LiteElement {
`
)}
-
-
- this.navTo(`${this.orgBasePath}/workflows/crawl/${workflow.id}?edit`)}
- >
-
- ${msg("Edit Workflow Settings")}
-
+ ${when(
+ this.isCrawler,
+ () => html`
+
+ this.navTo(
+ `${this.orgBasePath}/workflows/crawl/${workflow.id}?edit`
+ )}
+ >
+
+ ${msg("Edit Workflow Settings")}
+ `
+ )}
CopyButton.copyToClipboard(workflow.tags.join(", "))}
?disabled=${!workflow.tags.length}
@@ -500,28 +508,15 @@ export class WorkflowsList extends LiteElement {
${msg("Copy Tags")}
- this.duplicateConfig(workflow)}>
-
- ${msg("Duplicate Workflow")}
-
- ${when(workflow.isCrawlRunning, () => {
- const shouldDeactivate = workflow.crawlCount && !workflow.inactive;
- return html`
-
-
- shouldDeactivate
- ? this.deactivate(workflow)
- : this.delete(workflow)}
- >
-
- ${shouldDeactivate
- ? msg("Deactivate Workflow")
- : msg("Delete Workflow")}
-
- `;
- })}
+ ${when(
+ this.isCrawler,
+ () => html` this.duplicateConfig(workflow)}
+ >
+
+ ${msg("Duplicate Workflow")}
+ `
+ )}
`;
}