Add pageCount to crawls and uploads and use in frontend for page counts (#2315)

Fixes #2257 

This is a follow-up to the public collections work, which adds pages to
the database for uploads. All crawls and uploads now have a `pageCount`
field which is populated when the item is successfully added. A new
migration is also added to populate the field for existing archived
items that don't have it set yet.

OrgMetrics have also been modified to include `crawlPageCount` and
`uploadPageCount`, and to include the total of both in `pageCount`, and
all three included in the frontend org dashboard.

The frontend has been updated to use `pageCount` rather than
`stats.done` wherever appropriate, meaning that in archived item lists
and details we now have a consistent page count for both crawls and
uploads.

### New functionality

- Deploy this branch
- Create new crawls and uploads and verify that page count appears
correctly throughout the frontend for all new crawls and uploads

### Migration

- Deploy from latest main
- Create some crawls and uploads
- Change to this branch and re-deploy
- Verify migration ran without errors in backend logs
- Verify that page count has been populated successfully by checking
archived items lists, crawl and upload detail pages, and dashboard to
ensure there are no longer any missing page counts.

---------

Co-authored-by: emma <hi@emma.cafe>
This commit is contained in:
Tessa Walsh 2025-01-16 17:41:14 -05:00 committed by GitHub
parent 5684e896af
commit 6797b41de0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 435 additions and 116 deletions

View File

@ -17,7 +17,7 @@ from pymongo.errors import InvalidName
from .migrations import BaseMigration
CURR_DB_VERSION = "0039"
CURR_DB_VERSION = "0040"
# ============================================================================

View File

@ -0,0 +1,43 @@
"""
Migration 0040 -- archived item pageCount
"""
from btrixcloud.migrations import BaseMigration
MIGRATION_VERSION = "0040"
class Migration(BaseMigration):
"""Migration class."""
# pylint: disable=unused-argument
def __init__(self, mdb, **kwargs):
super().__init__(mdb, migration_version=MIGRATION_VERSION)
self.page_ops = kwargs.get("page_ops")
async def migrate_up(self):
"""Perform migration up.
Calculate and store pageCount for archived items that don't have it yet
"""
crawls_mdb = self.mdb["crawls"]
if self.page_ops is None:
print(
"Unable to set pageCount for archived items, missing page_ops",
flush=True,
)
return
async for crawl_raw in crawls_mdb.find({"pageCount": None}):
crawl_id = crawl_raw["_id"]
try:
await self.page_ops.set_archived_item_page_count(crawl_id)
# pylint: disable=broad-exception-caught
except Exception as err:
print(
f"Error saving pageCount for archived item {crawl_id}: {err}",
flush=True,
)

View File

@ -797,6 +797,8 @@ class BaseCrawl(CoreCrawlable, BaseMongoModel):
reviewStatus: ReviewStatus = None
pageCount: Optional[int] = 0
filePageCount: Optional[int] = 0
errorPageCount: Optional[int] = 0
@ -872,6 +874,7 @@ class CrawlOut(BaseMongoModel):
lastQAState: Optional[str] = None
lastQAStarted: Optional[datetime] = None
pageCount: Optional[int] = 0
filePageCount: Optional[int] = 0
errorPageCount: Optional[int] = 0
@ -1914,6 +1917,8 @@ class OrgMetrics(BaseModel):
crawlCount: int
uploadCount: int
pageCount: int
crawlPageCount: int
uploadPageCount: int
profileCount: int
workflowsRunningCount: int
maxConcurrentCrawls: int

View File

@ -1534,6 +1534,7 @@ class CrawlOperator(BaseOperator):
)
if state in SUCCESSFUL_STATES and crawl.oid:
await self.page_ops.set_archived_item_page_count(crawl.id)
await self.org_ops.inc_org_bytes_stored(
crawl.oid, status.filesAddedSize, "crawl"
)

View File

@ -939,7 +939,10 @@ class OrgOps:
archived_item_count = 0
crawl_count = 0
upload_count = 0
page_count = 0
crawl_page_count = 0
upload_page_count = 0
async for item_data in self.crawls_db.find({"oid": org.id}):
item = BaseCrawl.from_dict(item_data)
@ -948,10 +951,12 @@ class OrgOps:
archived_item_count += 1
if item.type == "crawl":
crawl_count += 1
crawl_page_count += item.pageCount or 0
if item.type == "upload":
upload_count += 1
if item.stats:
page_count += item.stats.done
upload_page_count += item.pageCount or 0
if item.pageCount:
page_count += item.pageCount
profile_count = await self.profiles_db.count_documents({"oid": org.id})
workflows_running_count = await self.crawls_db.count_documents(
@ -975,6 +980,8 @@ class OrgOps:
"crawlCount": crawl_count,
"uploadCount": upload_count,
"pageCount": page_count,
"crawlPageCount": crawl_page_count,
"uploadPageCount": upload_page_count,
"profileCount": profile_count,
"workflowsRunningCount": workflows_running_count,
"maxConcurrentCrawls": max_concurrent_crawls,

View File

@ -92,6 +92,8 @@ class PageOps:
if pages_buffer:
await self._add_pages_to_db(crawl_id, pages_buffer)
await self.set_archived_item_page_count(crawl_id)
print(f"Added pages for crawl {crawl_id} to db", flush=True)
# pylint: disable=broad-exception-caught, raise-missing-from
except Exception as err:
@ -661,6 +663,14 @@ class PageOps:
return crawl_type
async def set_archived_item_page_count(self, crawl_id: str):
"""Store archived item page count in crawl document"""
_, page_count = await self.list_pages(crawl_id)
await self.crawls.find_one_and_update(
{"_id": crawl_id}, {"$set": {"pageCount": page_count}}
)
# ============================================================================
# pylint: disable=too-many-arguments, too-many-locals, invalid-name, fixme

View File

@ -877,6 +877,14 @@ def test_re_add_crawl_pages(crawler_auth_headers, default_org_id, crawler_crawl_
)
assert r.status_code == 403
# Check that pageCount was stored on crawl
r = requests.get(
f"{API_PREFIX}/orgs/{default_org_id}/crawls/{crawler_crawl_id}",
headers=crawler_auth_headers,
)
assert r.status_code == 200
assert r.json()["pageCount"] > 0
def test_crawl_page_notes(crawler_auth_headers, default_org_id, crawler_crawl_id):
note_text = "testing"

View File

@ -274,6 +274,14 @@ def test_get_upload_pages(admin_auth_headers, default_org_id, upload_id):
assert page.get("modified") is None
assert page.get("approved") is None
# Check that pageCount was stored on upload
r = requests.get(
f"{API_PREFIX}/orgs/{default_org_id}/uploads/{upload_id}",
headers=admin_auth_headers,
)
assert r.status_code == 200
assert r.json()["pageCount"] > 0
def test_replace_upload(
admin_auth_headers, default_org_id, uploads_collection_id, upload_id

View File

@ -252,7 +252,24 @@ export class ArchivedItemListItem extends BtrixElement {
</btrix-table-cell>
<btrix-table-cell class="tabular-nums">
${isUpload
? notApplicable
? html`<sl-tooltip
hoist
@click=${this.onTooltipClick}
content=${msg(
str`${this.localize.number(
this.item.pageCount ? +this.item.pageCount : 0,
)}`,
)}
>
<div class="min-w-4">
${this.localize.number(
this.item.pageCount ? +this.item.pageCount : 0,
{
notation: "compact",
},
)}
</div>
</sl-tooltip>`
: html`<sl-tooltip
hoist
@click=${this.onTooltipClick}

View File

@ -191,12 +191,13 @@ export class CrawlListItem extends BtrixElement {
</btrix-table-cell>
<btrix-table-cell>
${this.safeRender((crawl) => {
const pagesComplete = +(crawl.stats?.done || 0);
const pagesFound = +(crawl.stats?.found || 0);
if (crawl.finished) {
const pagesComplete = crawl.pageCount ? +crawl.pageCount : 0;
return `${this.localize.number(pagesComplete, { notation: "compact" })} ${pluralOf("pages", pagesComplete)}`;
}
const pagesComplete = +(crawl.stats?.done || 0);
return `${this.localize.number(pagesComplete, { notation: "compact" })} / ${this.localize.number(pagesFound, { notation: "compact" })} ${pluralOf("pages", pagesFound)}`;
})}
</btrix-table-cell>

View File

@ -859,7 +859,7 @@ export class ArchivedItemDetail extends BtrixElement {
? html`${this.item.fileSize
? html`${this.localize.bytes(this.item.fileSize || 0, {
unitDisplay: "narrow",
})}${this.item.stats
})}${this.item.stats?.done
? html`<span>,</span
><span
class="tracking-tighter${this.isActive
@ -873,7 +873,18 @@ export class ArchivedItemDetail extends BtrixElement {
<span
>${pluralOf("pages", +this.item.stats.found)}</span
>`
: ""}`
: html`<span>,</span
><span>
${this.localize.number(
this.item.pageCount ? +this.item.pageCount : 0,
)}
</span>
<span
>${pluralOf(
"pages",
this.item.pageCount ? +this.item.pageCount : 0,
)}</span
>`}`
: html`<span class="text-0-400">${msg("Unknown")}</span>`}`
: html`<sl-skeleton class="h-[16px] w-24"></sl-skeleton>`}
</btrix-desc-list-item>

View File

@ -28,6 +28,8 @@ type Metrics = {
crawlCount: number;
uploadCount: number;
pageCount: number;
crawlPageCount: number;
uploadPageCount: number;
profileCount: number;
workflowsRunningCount: number;
maxConcurrentCrawls: number;
@ -236,10 +238,31 @@ export class Dashboard extends BtrixElement {
pluralLabel: msg("Crawl Workflows Waiting"),
iconProps: { name: "hourglass-split", color: "violet" },
})}
<sl-divider
style="--spacing:var(--sl-spacing-small)"
></sl-divider>
${this.renderStat({
value: metrics.pageCount,
value: metrics.crawlPageCount,
singleLabel: msg("Page Crawled"),
pluralLabel: msg("Pages Crawled"),
iconProps: {
name: "file-richtext-fill",
color: this.colors.crawls,
},
})}
${this.renderStat({
value: metrics.uploadPageCount,
singleLabel: msg("Page Uploaded"),
pluralLabel: msg("Pages Uploaded"),
iconProps: {
name: "file-richtext-fill",
color: this.colors.uploads,
},
})}
${this.renderStat({
value: metrics.pageCount,
singleLabel: msg("Page Total"),
pluralLabel: msg("Pages Total"),
iconProps: { name: "file-richtext-fill" },
})}
</dl>

View File

@ -164,6 +164,7 @@ type ArchivedItemBase = {
activeQAStats: { done: number; found: number } | null;
lastQAState: CrawlState | null;
lastQAStarted: string | null;
pageCount?: number;
filePageCount?: number;
errorPageCount?: number;
};

View File

@ -5,7 +5,6 @@ const childProcess = require("child_process");
const fs = require("fs");
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

98
frontend/xliff/de.xlf generated
View File

@ -1597,18 +1597,6 @@
<source>Are you sure you want to delete
<x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</source>
</trans-unit>
<trans-unit id="s777098c61f6b518a">
<source>Start building your Collection.</source>
</trans-unit>
<trans-unit id="s04200a50c7577767">
<source>No Collections Found</source>
</trans-unit>
<trans-unit id="s9f8154ea8167f3f7">
<source>Organize your crawls into a Collection to easily replay them together.</source>
</trans-unit>
<trans-unit id="s15aac264eaeac4fc">
<source>Your organization doesn't have any Collections, yet.</source>
</trans-unit>
<trans-unit id="s7be481b712fcb089">
<source>Search by Name</source>
</trans-unit>
@ -1624,9 +1612,6 @@
<trans-unit id="sa3242c7021e01280">
<source>Row Actions</source>
</trans-unit>
<trans-unit id="sf0c64ac402e1e0b9">
<source>No Collections Yet.</source>
</trans-unit>
<trans-unit id="s5ac7d4f485d82e8c">
<source>Shareable Collection</source>
</trans-unit>
@ -3018,7 +3003,7 @@
</trans-unit>
<trans-unit id="saf63d34c8601dd41">
<source>
<x id="0" equiv-text="${humanizeSchedule(workflow.schedule, {&#10; length: &quot;short&quot;,&#10;})}"/>
<x id="0" equiv-text="${this.localize.number(this.item.pageCount ? +this.item.pageCount : 0)}"/>
</source>
</trans-unit>
<trans-unit id="s136b21dec9a221bd">
@ -3861,9 +3846,6 @@
<trans-unit id="s66da7b7937e76a3a">
<source>Start typing a URL...</source>
</trans-unit>
<trans-unit id="sfedd97f6911305d1">
<source>No matching pages found.</source>
</trans-unit>
<trans-unit id="s7bec6de4e84e7519">
<source>ReplayWeb.Page default view</source>
</trans-unit>
@ -3873,9 +3855,6 @@
<trans-unit id="s5d948bb5f9f0a378">
<source>Show a single URL snapshot</source>
</trans-unit>
<trans-unit id="s7cdd26a53c30f8c5">
<source>Configure Replay Home</source>
</trans-unit>
<trans-unit id="s417b90913e05bc17">
<source>Preview</source>
</trans-unit>
@ -3992,9 +3971,6 @@
<trans-unit id="s1cb226f223599f56">
<source>Add items to select a home page</source>
</trans-unit>
<trans-unit id="s3879a0e50452a712">
<source>Configure Home</source>
</trans-unit>
<trans-unit id="s1f45d250722817c7">
<source>Edit About Section</source>
</trans-unit>
@ -4166,6 +4142,78 @@
<source><x id="0" equiv-text="${dateEarliest}"/> to <x id="1" equiv-text="${dateLatest}"/></source>
<note from="lit-localize">Date range formatted to show full month name and year</note>
</trans-unit>
<trans-unit id="s2428027aa3e49f16">
<source>Last Crawl</source>
</trans-unit>
<trans-unit id="sb9e424bd9e3e2723">
<source>No Subscription</source>
</trans-unit>
<trans-unit id="s7da138cc56abec6c">
<source>Active Subscription</source>
</trans-unit>
<trans-unit id="se3d7a30d5e45c393">
<source>Trial</source>
</trans-unit>
<trans-unit id="s5aff130b6d78c668">
<source>Trial Cancelled</source>
</trans-unit>
<trans-unit id="s2e515f3ca456f9c6">
<source>Trial Canceled</source>
</trans-unit>
<trans-unit id="s31e12850da47731e">
<source>Payment Failed</source>
</trans-unit>
<trans-unit id="s1ebb825e892a8359">
<source>Choose a snapshot</source>
</trans-unit>
<trans-unit id="s6e8c186600b4f8a6">
<source>Enter a page URL to choose snapshot</source>
</trans-unit>
<trans-unit id="s537d04835ef62b2b">
<source>Search for a page in this collection</source>
</trans-unit>
<trans-unit id="sb48ebdd9325e370b">
<source>Page exists in collection</source>
</trans-unit>
<trans-unit id="s485d151771b0a33c">
<source>Page not found in collection. Please check the URL and try again</source>
</trans-unit>
<trans-unit id="sd632247a75e16736">
<source>No matching page found.</source>
</trans-unit>
<trans-unit id="s6bea976384dcc959">
<source>Couldn't load preview. Try another snapshot</source>
</trans-unit>
<trans-unit id="s1b5466748e5d9733">
<source>Configure Replay View</source>
</trans-unit>
<trans-unit id="s8df0435252529c62">
<source>Choose a page snapshot</source>
</trans-unit>
<trans-unit id="s7239e04f3953266c">
<source>Configure View</source>
</trans-unit>
<trans-unit id="s9b649a5c57384213">
<source>Your org doesnt have any collections yet.</source>
</trans-unit>
<trans-unit id="sa35d8dcb231a2c75">
<source>Collections let you easily organize, replay, and share multiple crawls.</source>
</trans-unit>
<trans-unit id="sd42ed7f1a573d096">
<source>Page Uploaded</source>
</trans-unit>
<trans-unit id="s8a3aa1db56f18c55">
<source>Pages Uploaded</source>
</trans-unit>
<trans-unit id="saff358234fee600c">
<source>Page Total</source>
</trans-unit>
<trans-unit id="s1fda6e1bbcd65195">
<source>Pages Total</source>
</trans-unit>
<trans-unit id="s2f8856b910d3ebf8">
<source>Copy Link to Profile</source>
</trans-unit>
</body>
</file>
</xliff>

100
frontend/xliff/es.xlf generated
View File

@ -1766,19 +1766,6 @@
<x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</source>
<target state="translated">¿Está seguro que desea eliminar <x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</target>
</trans-unit>
<trans-unit id="s777098c61f6b518a">
<source>Start building your Collection.</source>
</trans-unit>
<trans-unit xml:space="preserve" id="s04200a50c7577767">
<source>No Collections Found</source>
<target state="translated">No se han encontrado colecciones</target>
</trans-unit>
<trans-unit id="s9f8154ea8167f3f7">
<source>Organize your crawls into a Collection to easily replay them together.</source>
</trans-unit>
<trans-unit id="s15aac264eaeac4fc">
<source>Your organization doesn't have any Collections, yet.</source>
</trans-unit>
<trans-unit xml:space="preserve" id="s7be481b712fcb089">
<source>Search by Name</source>
<target state="translated">Buscar por nombre</target>
@ -1797,10 +1784,6 @@
<trans-unit id="sa3242c7021e01280">
<source>Row Actions</source>
</trans-unit>
<trans-unit xml:space="preserve" id="sf0c64ac402e1e0b9">
<source>No Collections Yet.</source>
<target state="translated">Aún no hay colecciones.</target>
</trans-unit>
<trans-unit xml:space="preserve" id="s5ac7d4f485d82e8c">
<source>Shareable Collection</source>
<target state="translated">Colección compartible</target>
@ -3273,7 +3256,7 @@
</trans-unit>
<trans-unit xml:space="preserve" id="saf63d34c8601dd41">
<source>
<x id="0" equiv-text="${humanizeSchedule(workflow.schedule, {&#10; length: &quot;short&quot;,&#10;})}"/>
<x id="0" equiv-text="${this.localize.number(this.item.pageCount ? +this.item.pageCount : 0)}"/>
</source>
<target state="translated">
<x id="0" equiv-text="${humanizeSchedule(workflow.schedule, {&#10; length: &quot;short&quot;,&#10;})}"/>
@ -4501,9 +4484,6 @@
<trans-unit id="s66da7b7937e76a3a">
<source>Start typing a URL...</source>
</trans-unit>
<trans-unit id="sfedd97f6911305d1">
<source>No matching pages found.</source>
</trans-unit>
<trans-unit id="s7bec6de4e84e7519">
<source>ReplayWeb.Page default view</source>
</trans-unit>
@ -4513,9 +4493,6 @@
<trans-unit id="s5d948bb5f9f0a378">
<source>Show a single URL snapshot</source>
</trans-unit>
<trans-unit id="s7cdd26a53c30f8c5">
<source>Configure Replay Home</source>
</trans-unit>
<trans-unit id="s417b90913e05bc17">
<source>Preview</source>
</trans-unit>
@ -4632,9 +4609,6 @@
<trans-unit id="s1cb226f223599f56">
<source>Add items to select a home page</source>
</trans-unit>
<trans-unit id="s3879a0e50452a712">
<source>Configure Home</source>
</trans-unit>
<trans-unit id="s1f45d250722817c7">
<source>Edit About Section</source>
</trans-unit>
@ -4806,6 +4780,78 @@
<source><x id="0" equiv-text="${dateEarliest}"/> to <x id="1" equiv-text="${dateLatest}"/></source>
<note from="lit-localize">Date range formatted to show full month name and year</note>
</trans-unit>
<trans-unit id="s2428027aa3e49f16">
<source>Last Crawl</source>
</trans-unit>
<trans-unit id="sb9e424bd9e3e2723">
<source>No Subscription</source>
</trans-unit>
<trans-unit id="s7da138cc56abec6c">
<source>Active Subscription</source>
</trans-unit>
<trans-unit id="se3d7a30d5e45c393">
<source>Trial</source>
</trans-unit>
<trans-unit id="s5aff130b6d78c668">
<source>Trial Cancelled</source>
</trans-unit>
<trans-unit id="s2e515f3ca456f9c6">
<source>Trial Canceled</source>
</trans-unit>
<trans-unit id="s31e12850da47731e">
<source>Payment Failed</source>
</trans-unit>
<trans-unit id="s1ebb825e892a8359">
<source>Choose a snapshot</source>
</trans-unit>
<trans-unit id="s6e8c186600b4f8a6">
<source>Enter a page URL to choose snapshot</source>
</trans-unit>
<trans-unit id="s537d04835ef62b2b">
<source>Search for a page in this collection</source>
</trans-unit>
<trans-unit id="sb48ebdd9325e370b">
<source>Page exists in collection</source>
</trans-unit>
<trans-unit id="s485d151771b0a33c">
<source>Page not found in collection. Please check the URL and try again</source>
</trans-unit>
<trans-unit id="sd632247a75e16736">
<source>No matching page found.</source>
</trans-unit>
<trans-unit id="s6bea976384dcc959">
<source>Couldn't load preview. Try another snapshot</source>
</trans-unit>
<trans-unit id="s1b5466748e5d9733">
<source>Configure Replay View</source>
</trans-unit>
<trans-unit id="s8df0435252529c62">
<source>Choose a page snapshot</source>
</trans-unit>
<trans-unit id="s7239e04f3953266c">
<source>Configure View</source>
</trans-unit>
<trans-unit id="s9b649a5c57384213">
<source>Your org doesnt have any collections yet.</source>
</trans-unit>
<trans-unit id="sa35d8dcb231a2c75">
<source>Collections let you easily organize, replay, and share multiple crawls.</source>
</trans-unit>
<trans-unit id="sd42ed7f1a573d096">
<source>Page Uploaded</source>
</trans-unit>
<trans-unit id="s8a3aa1db56f18c55">
<source>Pages Uploaded</source>
</trans-unit>
<trans-unit id="saff358234fee600c">
<source>Page Total</source>
</trans-unit>
<trans-unit id="s1fda6e1bbcd65195">
<source>Pages Total</source>
</trans-unit>
<trans-unit id="s2f8856b910d3ebf8">
<source>Copy Link to Profile</source>
</trans-unit>
</body>
</file>
</xliff>

103
frontend/xliff/fr.xlf generated
View File

@ -2125,22 +2125,6 @@
<x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</source>
<target state="translated">Êtes-vous certain de vouloir supprimer <x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</target>
</trans-unit>
<trans-unit id="s777098c61f6b518a" xml:space="preserve">
<source>Start building your Collection.</source>
<target state="translated">Démarrer la création de la collection.</target>
</trans-unit>
<trans-unit id="s04200a50c7577767" xml:space="preserve">
<source>No Collections Found</source>
<target state="translated">Aucune collection trouvée</target>
</trans-unit>
<trans-unit id="s9f8154ea8167f3f7" xml:space="preserve">
<source>Organize your crawls into a Collection to easily replay them together.</source>
<target state="translated">Organiser vos collectes en collection pour pouvoir les rejouer ensemble.</target>
</trans-unit>
<trans-unit id="s15aac264eaeac4fc" xml:space="preserve">
<source>Your organization doesn't have any Collections, yet.</source>
<target state="translated">Votre organisation ne détient aucune collection présentement.</target>
</trans-unit>
<trans-unit id="s7be481b712fcb089" xml:space="preserve">
<source>Search by Name</source>
<target state="translated">Rechercher par nom</target>
@ -2161,10 +2145,6 @@
<source>Row Actions</source>
<target state="translated">Rangée actions</target>
</trans-unit>
<trans-unit id="sf0c64ac402e1e0b9" xml:space="preserve">
<source>No Collections Yet.</source>
<target state="translated">Aucune collection jusqu'à présent.</target>
</trans-unit>
<trans-unit id="s5ac7d4f485d82e8c" xml:space="preserve">
<source>Shareable Collection</source>
<target state="translated">Collection partageable</target>
@ -3782,7 +3762,7 @@
</trans-unit>
<trans-unit id="saf63d34c8601dd41">
<source>
<x id="0" equiv-text="${humanizeSchedule(workflow.schedule, {&#10; length: &quot;short&quot;,&#10;})}"/>
<x id="0" equiv-text="${this.localize.number(this.item.pageCount ? +this.item.pageCount : 0)}"/>
</source>
</trans-unit>
<trans-unit id="s136b21dec9a221bd">
@ -4625,9 +4605,6 @@
<trans-unit id="s66da7b7937e76a3a">
<source>Start typing a URL...</source>
</trans-unit>
<trans-unit id="sfedd97f6911305d1">
<source>No matching pages found.</source>
</trans-unit>
<trans-unit id="s7bec6de4e84e7519">
<source>ReplayWeb.Page default view</source>
</trans-unit>
@ -4637,9 +4614,6 @@
<trans-unit id="s5d948bb5f9f0a378">
<source>Show a single URL snapshot</source>
</trans-unit>
<trans-unit id="s7cdd26a53c30f8c5">
<source>Configure Replay Home</source>
</trans-unit>
<trans-unit id="s417b90913e05bc17">
<source>Preview</source>
</trans-unit>
@ -4756,9 +4730,6 @@
<trans-unit id="s1cb226f223599f56">
<source>Add items to select a home page</source>
</trans-unit>
<trans-unit id="s3879a0e50452a712">
<source>Configure Home</source>
</trans-unit>
<trans-unit id="s1f45d250722817c7">
<source>Edit About Section</source>
</trans-unit>
@ -4930,6 +4901,78 @@
<source><x id="0" equiv-text="${dateEarliest}"/> to <x id="1" equiv-text="${dateLatest}"/></source>
<note from="lit-localize">Date range formatted to show full month name and year</note>
</trans-unit>
<trans-unit id="s2428027aa3e49f16">
<source>Last Crawl</source>
</trans-unit>
<trans-unit id="sb9e424bd9e3e2723">
<source>No Subscription</source>
</trans-unit>
<trans-unit id="s7da138cc56abec6c">
<source>Active Subscription</source>
</trans-unit>
<trans-unit id="se3d7a30d5e45c393">
<source>Trial</source>
</trans-unit>
<trans-unit id="s5aff130b6d78c668">
<source>Trial Cancelled</source>
</trans-unit>
<trans-unit id="s2e515f3ca456f9c6">
<source>Trial Canceled</source>
</trans-unit>
<trans-unit id="s31e12850da47731e">
<source>Payment Failed</source>
</trans-unit>
<trans-unit id="s1ebb825e892a8359">
<source>Choose a snapshot</source>
</trans-unit>
<trans-unit id="s6e8c186600b4f8a6">
<source>Enter a page URL to choose snapshot</source>
</trans-unit>
<trans-unit id="s537d04835ef62b2b">
<source>Search for a page in this collection</source>
</trans-unit>
<trans-unit id="sb48ebdd9325e370b">
<source>Page exists in collection</source>
</trans-unit>
<trans-unit id="s485d151771b0a33c">
<source>Page not found in collection. Please check the URL and try again</source>
</trans-unit>
<trans-unit id="sd632247a75e16736">
<source>No matching page found.</source>
</trans-unit>
<trans-unit id="s6bea976384dcc959">
<source>Couldn't load preview. Try another snapshot</source>
</trans-unit>
<trans-unit id="s1b5466748e5d9733">
<source>Configure Replay View</source>
</trans-unit>
<trans-unit id="s8df0435252529c62">
<source>Choose a page snapshot</source>
</trans-unit>
<trans-unit id="s7239e04f3953266c">
<source>Configure View</source>
</trans-unit>
<trans-unit id="s9b649a5c57384213">
<source>Your org doesnt have any collections yet.</source>
</trans-unit>
<trans-unit id="sa35d8dcb231a2c75">
<source>Collections let you easily organize, replay, and share multiple crawls.</source>
</trans-unit>
<trans-unit id="sd42ed7f1a573d096">
<source>Page Uploaded</source>
</trans-unit>
<trans-unit id="s8a3aa1db56f18c55">
<source>Pages Uploaded</source>
</trans-unit>
<trans-unit id="saff358234fee600c">
<source>Page Total</source>
</trans-unit>
<trans-unit id="s1fda6e1bbcd65195">
<source>Pages Total</source>
</trans-unit>
<trans-unit id="s2f8856b910d3ebf8">
<source>Copy Link to Profile</source>
</trans-unit>
</body>
</file>
</xliff>

98
frontend/xliff/pt.xlf generated
View File

@ -1597,18 +1597,6 @@
<source>Are you sure you want to delete
<x id="0" equiv-text="&lt;strong&gt;${this.selectedCollection?.name}&lt;/strong&gt;"/>?</source>
</trans-unit>
<trans-unit id="s777098c61f6b518a">
<source>Start building your Collection.</source>
</trans-unit>
<trans-unit id="s04200a50c7577767">
<source>No Collections Found</source>
</trans-unit>
<trans-unit id="s9f8154ea8167f3f7">
<source>Organize your crawls into a Collection to easily replay them together.</source>
</trans-unit>
<trans-unit id="s15aac264eaeac4fc">
<source>Your organization doesn't have any Collections, yet.</source>
</trans-unit>
<trans-unit id="s7be481b712fcb089">
<source>Search by Name</source>
</trans-unit>
@ -1624,9 +1612,6 @@
<trans-unit id="sa3242c7021e01280">
<source>Row Actions</source>
</trans-unit>
<trans-unit id="sf0c64ac402e1e0b9">
<source>No Collections Yet.</source>
</trans-unit>
<trans-unit id="s5ac7d4f485d82e8c">
<source>Shareable Collection</source>
</trans-unit>
@ -3018,7 +3003,7 @@
</trans-unit>
<trans-unit id="saf63d34c8601dd41">
<source>
<x id="0" equiv-text="${humanizeSchedule(workflow.schedule, {&#10; length: &quot;short&quot;,&#10;})}"/>
<x id="0" equiv-text="${this.localize.number(this.item.pageCount ? +this.item.pageCount : 0)}"/>
</source>
</trans-unit>
<trans-unit id="s136b21dec9a221bd">
@ -3861,9 +3846,6 @@
<trans-unit id="s66da7b7937e76a3a">
<source>Start typing a URL...</source>
</trans-unit>
<trans-unit id="sfedd97f6911305d1">
<source>No matching pages found.</source>
</trans-unit>
<trans-unit id="s7bec6de4e84e7519">
<source>ReplayWeb.Page default view</source>
</trans-unit>
@ -3873,9 +3855,6 @@
<trans-unit id="s5d948bb5f9f0a378">
<source>Show a single URL snapshot</source>
</trans-unit>
<trans-unit id="s7cdd26a53c30f8c5">
<source>Configure Replay Home</source>
</trans-unit>
<trans-unit id="s417b90913e05bc17">
<source>Preview</source>
</trans-unit>
@ -3992,9 +3971,6 @@
<trans-unit id="s1cb226f223599f56">
<source>Add items to select a home page</source>
</trans-unit>
<trans-unit id="s3879a0e50452a712">
<source>Configure Home</source>
</trans-unit>
<trans-unit id="s1f45d250722817c7">
<source>Edit About Section</source>
</trans-unit>
@ -4166,6 +4142,78 @@
<source><x id="0" equiv-text="${dateEarliest}"/> to <x id="1" equiv-text="${dateLatest}"/></source>
<note from="lit-localize">Date range formatted to show full month name and year</note>
</trans-unit>
<trans-unit id="s2428027aa3e49f16">
<source>Last Crawl</source>
</trans-unit>
<trans-unit id="sb9e424bd9e3e2723">
<source>No Subscription</source>
</trans-unit>
<trans-unit id="s7da138cc56abec6c">
<source>Active Subscription</source>
</trans-unit>
<trans-unit id="se3d7a30d5e45c393">
<source>Trial</source>
</trans-unit>
<trans-unit id="s5aff130b6d78c668">
<source>Trial Cancelled</source>
</trans-unit>
<trans-unit id="s2e515f3ca456f9c6">
<source>Trial Canceled</source>
</trans-unit>
<trans-unit id="s31e12850da47731e">
<source>Payment Failed</source>
</trans-unit>
<trans-unit id="s1ebb825e892a8359">
<source>Choose a snapshot</source>
</trans-unit>
<trans-unit id="s6e8c186600b4f8a6">
<source>Enter a page URL to choose snapshot</source>
</trans-unit>
<trans-unit id="s537d04835ef62b2b">
<source>Search for a page in this collection</source>
</trans-unit>
<trans-unit id="sb48ebdd9325e370b">
<source>Page exists in collection</source>
</trans-unit>
<trans-unit id="s485d151771b0a33c">
<source>Page not found in collection. Please check the URL and try again</source>
</trans-unit>
<trans-unit id="sd632247a75e16736">
<source>No matching page found.</source>
</trans-unit>
<trans-unit id="s6bea976384dcc959">
<source>Couldn't load preview. Try another snapshot</source>
</trans-unit>
<trans-unit id="s1b5466748e5d9733">
<source>Configure Replay View</source>
</trans-unit>
<trans-unit id="s8df0435252529c62">
<source>Choose a page snapshot</source>
</trans-unit>
<trans-unit id="s7239e04f3953266c">
<source>Configure View</source>
</trans-unit>
<trans-unit id="s9b649a5c57384213">
<source>Your org doesnt have any collections yet.</source>
</trans-unit>
<trans-unit id="sa35d8dcb231a2c75">
<source>Collections let you easily organize, replay, and share multiple crawls.</source>
</trans-unit>
<trans-unit id="sd42ed7f1a573d096">
<source>Page Uploaded</source>
</trans-unit>
<trans-unit id="s8a3aa1db56f18c55">
<source>Pages Uploaded</source>
</trans-unit>
<trans-unit id="saff358234fee600c">
<source>Page Total</source>
</trans-unit>
<trans-unit id="s1fda6e1bbcd65195">
<source>Pages Total</source>
</trans-unit>
<trans-unit id="s2f8856b910d3ebf8">
<source>Copy Link to Profile</source>
</trans-unit>
</body>
</file>
</xliff>