From 4d1191dd79ada32a4bc5720a8292d3063395b20f Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Wed, 8 Nov 2023 11:26:40 -0500 Subject: [PATCH 01/40] Creates stories for Document and DocumentThumbnail --- src/pages/app/test/fixtures/document.json | 74 +++++++++++++++++++ .../app/test/stories/Document.stories.svelte | 27 +++++++ .../stories/DocumentThumbnail.stories.svelte | 46 ++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 src/pages/app/test/fixtures/document.json create mode 100644 src/pages/app/test/stories/Document.stories.svelte create mode 100644 src/pages/app/test/stories/DocumentThumbnail.stories.svelte diff --git a/src/pages/app/test/fixtures/document.json b/src/pages/app/test/fixtures/document.json new file mode 100644 index 000000000..1cb707277 --- /dev/null +++ b/src/pages/app/test/fixtures/document.json @@ -0,0 +1,74 @@ +{ + "id": 24002098, + "access": "public", + "admin_noindex": false, + "asset_url": "https://s3.documentcloud.org/", + "canonical_url": "https://www.documentcloud.org/documents/24002098-quarterly-reports-created-pursuant-to-the-letter-from-the-national-archives-and-records-administration-dated-june-1-2018", + "created_at": "2023-10-02T00:05:27.632309Z", + "data": {}, + "description": "", + "edit_access": true, + "file_hash": "0a90fe2c7096c7aa83ff9f6daf302a3b83466060", + "noindex": false, + "language": "eng", + "organization": { + "id": 125, + "avatar_url": "https://cdn.muckrock.com/media/org_avatars/logo.png", + "individual": false, + "monthly_ai_credits": 10000, + "name": "MuckRock", + "number_ai_credits": 0, + "slug": "muckrock", + "uuid": "97109cc6-e52e-41e7-adb7-834ab7c6819c" + }, + "original_extension": "pdf", + "page_count": 20, + "page_spec": "612.0x792.0:0-19", + "projects": [215678, 208091], + "publish_at": null, + "published_url": "", + "related_article": "", + "slug": "quarterly-reports-created-pursuant-to-the-letter-from-the-national-archives-and-records-administration-dated-june-1-2018", + "source": "Scraped from https://www.ssa.gov/foia/readingroom.html", + "status": "success", + "title": "Quarterly Reports created pursuant to the letter from the National Archives and Records Administration dated June 1, 2018", + "updated_at": "2023-10-26T16:13:43.082660Z", + "user": { + "id": 20080, + "avatar_url": "https://cdn.muckrock.com/media/account_images/22_MuckRock_2018_PRELIMANRY_EDITS_DSC_5387_2018_Derek_Kouyoumjian_preview_SfuGGnJ.jpg", + "is_staff": true, + "name": "Mitchell Kotler", + "organization": 125, + "organizations": [10000, 3168, 125, 41248, 10002], + "admin_organizations": [10000, 3168, 125, 41248, 10002], + "username": "mitch", + "uuid": "8136b9b8-95b9-4302-950d-5402e9065978", + "verified_journalist": true + }, + "revision_control": true, + "revisions": [ + { + "version": 1, + "user": 20080, + "created_at": "2023-10-26T16:11:44.202208Z", + "comment": "Initial", + "url": "https://api.www.documentcloud.org/files/documents/24002098/revisions/0001-quarterly-reports-created-pursuant-to-the-letter-from-the-national-archives-and-records-administration-dated-june-1-2018.pdf" + }, + { + "version": 2, + "user": 20080, + "created_at": "2023-10-26T16:12:06.155780Z", + "comment": "Redacting", + "url": "https://api.www.documentcloud.org/files/documents/24002098/revisions/0002-quarterly-reports-created-pursuant-to-the-letter-from-the-national-archives-and-records-administration-dated-june-1-2018.pdf" + }, + { + "version": 3, + "user": 20080, + "created_at": "2023-10-26T16:12:41.997682Z", + "comment": "Modifying", + "url": "https://api.www.documentcloud.org/files/documents/24002098/revisions/0003-quarterly-reports-created-pursuant-to-the-letter-from-the-national-archives-and-records-administration-dated-june-1-2018.pdf" + } + ], + "notes": [], + "sections": [] +} diff --git a/src/pages/app/test/stories/Document.stories.svelte b/src/pages/app/test/stories/Document.stories.svelte new file mode 100644 index 000000000..9e66ae149 --- /dev/null +++ b/src/pages/app/test/stories/Document.stories.svelte @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/src/pages/app/test/stories/DocumentThumbnail.stories.svelte b/src/pages/app/test/stories/DocumentThumbnail.stories.svelte new file mode 100644 index 000000000..6f31dd978 --- /dev/null +++ b/src/pages/app/test/stories/DocumentThumbnail.stories.svelte @@ -0,0 +1,46 @@ + + + + + + + + + + + From 80d001ece106504c7d3da66fd9029554d62b6303 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 2 Nov 2023 12:48:26 -0400 Subject: [PATCH 02/40] Adds Storybook for `src/common/Progress.svelte` --- src/common/Progress.svelte | 18 +++++++-------- src/common/stories/Progress.stories.svelte | 27 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 src/common/stories/Progress.stories.svelte diff --git a/src/common/Progress.svelte b/src/common/Progress.svelte index 50801061b..a6be3de18 100644 --- a/src/common/Progress.svelte +++ b/src/common/Progress.svelte @@ -1,8 +1,8 @@ - + + + + + + + + + From 46d5c355ed53bfe82b4d48ddab7f199692e30650 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Wed, 8 Nov 2023 11:26:27 -0500 Subject: [PATCH 03/40] Create story for AccessIcon and updates component API Uses Octicons for AccessType icons Improve storybook argtype Update Component in viewer sidebar --- src/common/AccessIcon.svelte | 103 +++++++++---------- src/common/stories/AccessIcon.stories.svelte | 38 +++++++ src/pages/app/Document.svelte | 5 +- src/pages/viewer/Sidebar.svelte | 6 +- 4 files changed, 97 insertions(+), 55 deletions(-) create mode 100644 src/common/stories/AccessIcon.stories.svelte diff --git a/src/common/AccessIcon.svelte b/src/common/AccessIcon.svelte index 6de7b7e15..80e5dbd1b 100644 --- a/src/common/AccessIcon.svelte +++ b/src/common/AccessIcon.svelte @@ -1,76 +1,73 @@ - -{#if showText} + -{:else} - - - -{/if} + + +{#if revisions !== null} + + + +{/if} diff --git a/src/common/stories/RevisionIcon.stories.svelte b/src/common/stories/RevisionIcon.stories.svelte new file mode 100644 index 000000000..60a63b016 --- /dev/null +++ b/src/common/stories/RevisionIcon.stories.svelte @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/src/langs/json/en.json b/src/langs/json/en.json index a617ad52a..913214422 100644 --- a/src/langs/json/en.json +++ b/src/langs/json/en.json @@ -34,6 +34,9 @@ "organizationExplanation": "Only members of your organization can view this document", "publicExplanation": "Anyone can search and view this document" }, + "revisionIcon": { + "tooltip": "Revision control is enabled on this document. It has {count, plural, one {revision} other {# revisions}}" + }, "appearanceCustomizer": { "customizeAppearance": "Customize Appearance", "hide": "Hide help text", @@ -838,6 +841,5 @@ "p3": "Want more fascinating documents, open data and original reporting to your inbox? Subscribe to MuckRock's newsletter:", "p4": "DocumentCloud is part of a suite of transparency tools from the MuckRock Foundation, a 501c3 registered non-profit. This archive is open to the public and advertisement free thanks to support from readers like you — you can learn more about our work or make a donation.", "subscribe": "Subscribe" - }, - "premium": {} + } } diff --git a/src/pages/app/Document.svelte b/src/pages/app/Document.svelte index 887f3d6f7..615f61281 100644 --- a/src/pages/app/Document.svelte +++ b/src/pages/app/Document.svelte @@ -26,6 +26,7 @@ import pencilSvg from "@/assets/pencil.svg?raw"; import { pageImageUrl } from "@/api/viewer.js"; + import RevisionIcon from "../../common/RevisionIcon.svelte"; export let document; export let embed = false; @@ -90,31 +91,34 @@ />
-

- {document.title} +
+

{document.title}

{#if !embed} - +
openAccess([document])} /> - + +
{/if} -

+
{#if !embed} -

- {#if document.pageCount > 0} - {$_("document.pageCount", { values: { n: document.pageCount } })} - - {/if} - {#if document.source != null && document.source.trim().length > 0} - {$_("document.source")}: {document.source} - - {/if} - {#if document.userName !== null} - {document.userOrgString} - - {/if} - {$date(document.createdAt, { format: "medium" })} -

+
+

+ {#if document.pageCount > 0} + {$_("document.pageCount", { values: { n: document.pageCount } })} - + {/if} + {#if document.source != null && document.source.trim().length > 0} + {$_("document.source")}: {document.source} - + {/if} + {#if document.userName !== null} + {document.userOrgString} - + {/if} + {$date(document.createdAt, { format: "medium" })} +

+
{/if} {#if document.description != null && document.description.trim().length > 0}
@@ -479,4 +483,26 @@ } } } + + .document-title-row { + display: flex; + align-items: flex-start; + gap: 1em; + } + + .document-title-row h2 { + flex: 1 1 auto; + } + + .document-title-row-actions { + display: flex; + gap: 0.5em 0; + flex-direction: row; + } + + @media only screen and (max-width: 720px) { + .document-title-row-actions { + flex-direction: column; + } + } diff --git a/src/pages/app/DocumentThumbnail.svelte b/src/pages/app/DocumentThumbnail.svelte index dce61c8fe..7415cbcb4 100644 --- a/src/pages/app/DocumentThumbnail.svelte +++ b/src/pages/app/DocumentThumbnail.svelte @@ -99,7 +99,7 @@ position: relative; @media only screen and (max-width: 720px) { - padding: 10px 15px 20px 15px; + padding: 0 15px 20px 15px; } :global(img), diff --git a/src/structure/document.js b/src/structure/document.js index 8576f8363..4612553a4 100644 --- a/src/structure/document.js +++ b/src/structure/document.js @@ -368,6 +368,12 @@ export class Document extends Svue { } return organizationName; }, + + // Revision Properties + revisions(doc) { + if (!doc.revision_control) return null; + return doc.revisions; + }, }, }); } From 46860b995abe31a08fa04966dd9bfc3c4a261f8d Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 9 Nov 2023 10:18:01 -0500 Subject: [PATCH 06/40] Small style tweaks --- src/common/RevisionIcon.svelte | 1 + src/pages/app/Document.svelte | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/RevisionIcon.svelte b/src/common/RevisionIcon.svelte index c80b9a68b..857e2e94b 100644 --- a/src/common/RevisionIcon.svelte +++ b/src/common/RevisionIcon.svelte @@ -37,6 +37,7 @@ .count { font-size: 12px; + font-weight: 600; color: var(--viewerLink, #004276); vertical-align: middle; margin-left: 2px; diff --git a/src/pages/app/Document.svelte b/src/pages/app/Document.svelte index 615f61281..1c6f6f976 100644 --- a/src/pages/app/Document.svelte +++ b/src/pages/app/Document.svelte @@ -100,7 +100,7 @@ editable={document.editAccess} on:click={() => openAccess([document])} /> - +
{/if} @@ -486,7 +486,6 @@ .document-title-row { display: flex; - align-items: flex-start; gap: 1em; } @@ -498,11 +497,15 @@ display: flex; gap: 0.5em 0; flex-direction: row; + align-items: center; + height: 1.5em; } @media only screen and (max-width: 720px) { .document-title-row-actions { flex-direction: column; + height: auto; + padding: 0.25em 0; } } From c25dd87dd6b2c81767d796383104fd71ee0c3de8 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 9 Nov 2023 11:40:42 -0500 Subject: [PATCH 07/40] Update document metadata structure/styling --- src/pages/app/Document.svelte | 81 +++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/src/pages/app/Document.svelte b/src/pages/app/Document.svelte index 1c6f6f976..2343fd36f 100644 --- a/src/pages/app/Document.svelte +++ b/src/pages/app/Document.svelte @@ -106,18 +106,25 @@ {#if !embed}
-

- {#if document.pageCount > 0} - {$_("document.pageCount", { values: { n: document.pageCount } })} - - {/if} - {#if document.source != null && document.source.trim().length > 0} - {$_("document.source")}: {document.source} - - {/if} - {#if document.userName !== null} - {document.userOrgString} - - {/if} - {$date(document.createdAt, { format: "medium" })} -

+ {#if document.pageCount > 0} +

+ {$_("document.pageCount", { values: { n: document.pageCount } })} +

+ {/if} + {#if document.source != null && document.source.trim().length > 0} +

+ {$_("document.source")}: {document.source} +

+ {/if} + {#if document.userName !== null} +

{document.userOrgString}

+ {/if} +
{/if} {#if document.description != null && document.description.trim().length > 0} @@ -307,7 +314,8 @@ From 671c8a761c835dde8451c8463ca9842af7c0ea78 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 9 Nov 2023 13:20:35 -0500 Subject: [PATCH 08/40] Adds "download" target option to Button --- src/common/Button.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/Button.svelte b/src/common/Button.svelte index 421c9adde..9a5a462aa 100644 --- a/src/common/Button.svelte +++ b/src/common/Button.svelte @@ -3,6 +3,7 @@ export let href: string | null = null; export let external = false; + export let download = false; export let title = ""; export let small = false; @@ -42,7 +43,7 @@ class:fullWidth class:disabled={disabled || disabledReason != null} rel={external ? "noopener noreferrer" : null} - target={external ? "_blank" : null} + target={external ? "_blank" : download ? "download" : null} > {label} From 1598ca9c0c61d7eaa18e35f46f40e8775321b956 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 9 Nov 2023 13:21:36 -0500 Subject: [PATCH 09/40] Adds a dialog for browsing revisions --- src/common/RevisionIcon.svelte | 2 +- src/common/dialog/RevisionsDialog.svelte | 16 +++++++++++ .../stories/RevisionsDialog.stories.svelte | 28 +++++++++++++++++++ .../stories/RevisionIcon.stories.svelte | 5 +++- src/manager/layout.js | 9 ++++++ src/pages/app/Document.svelte | 9 ++++-- src/pages/app/MainContainer.svelte | 6 +++- 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 src/common/dialog/RevisionsDialog.svelte create mode 100644 src/common/dialog/stories/RevisionsDialog.stories.svelte diff --git a/src/common/RevisionIcon.svelte b/src/common/RevisionIcon.svelte index 857e2e94b..8206e5d6c 100644 --- a/src/common/RevisionIcon.svelte +++ b/src/common/RevisionIcon.svelte @@ -1,5 +1,5 @@ + + + {#each revisions as revision} + + + + + + {/each} +
{revision.version}{revision.comment}
diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte new file mode 100644 index 000000000..9b93c1413 --- /dev/null +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/src/common/stories/RevisionIcon.stories.svelte b/src/common/stories/RevisionIcon.stories.svelte index 60a63b016..70eed17b3 100644 --- a/src/common/stories/RevisionIcon.stories.svelte +++ b/src/common/stories/RevisionIcon.stories.svelte @@ -1,5 +1,6 @@ diff --git a/src/manager/layout.js b/src/manager/layout.js index 75e07712d..b819c32bb 100644 --- a/src/manager/layout.js +++ b/src/manager/layout.js @@ -37,6 +37,7 @@ export const layout = new Svue({ searchTipsOpen: false, diagnosticsOpen: false, mailkeyOpen: false, + viewDocumentRevisions: null, // nest any captured URL params here params: { @@ -250,6 +251,14 @@ export function hideAccess() { layout.accessEditDocuments = []; } +export function openRevisions(document) { + layout.viewDocumentRevisions = document; +} + +export function hideRevisions() { + layout.viewDocumentRevisions = null; +} + export function hideReprocess() { layout.reprocessDocuments = []; } diff --git a/src/pages/app/Document.svelte b/src/pages/app/Document.svelte index 2343fd36f..58021a3aa 100644 --- a/src/pages/app/Document.svelte +++ b/src/pages/app/Document.svelte @@ -16,7 +16,8 @@ unselectDocument, editData, openAccess, - } from "@/manager/layout.js"; + openRevisions, + } from "../../manager/layout.js"; import { removeDocument, selectDocument } from "@/manager/documents.js"; import { projects } from "@/manager/projects.js"; import { projectUrl, dataUrl } from "@/search/search.js"; @@ -100,7 +101,11 @@ editable={document.editAccess} on:click={() => openAccess([document])} /> - + openRevisions([document])} + /> {/if} diff --git a/src/pages/app/MainContainer.svelte b/src/pages/app/MainContainer.svelte index b5da16456..1af6e0309 100644 --- a/src/pages/app/MainContainer.svelte +++ b/src/pages/app/MainContainer.svelte @@ -16,6 +16,7 @@ import ProjectAccessDialog from "@/common/dialog/ProjectAccessDialog.svelte"; import ProjectEmbedDialog from "@/common/dialog/ProjectEmbedDialog.svelte"; import ReprocessDialog from "@/common/dialog/ReprocessDialog.svelte"; + import RevisionsDialog from "../../common/dialog/RevisionsDialog.svelte"; import SearchTipsDialog from "@/common/dialog/SearchTipsDialog.svelte"; import UploadEmailDialog from "@/common/dialog/UploadEmailDialog.svelte"; @@ -40,7 +41,8 @@ hideSearchTips, hideDiagnostics, hideMailkey, - } from "@/manager/layout.js"; + hideRevisions, + } from "../../manager/layout.js"; import { confirmDialog, hideConfirm } from "@/manager/confirmDialog.js"; import { documents } from "@/manager/documents.js"; @@ -64,6 +66,8 @@ {:else if $layout.accessOpen} +{:else if $layout.viewDocumentRevisions} + {:else if $layout.ownerOpen} {:else if $layout.dataOpen} From cef888f98afe0ced0bd006c937ab48d3e0dcec9d Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 28 Nov 2023 11:07:39 -0500 Subject: [PATCH 10/40] Adds RelativeTime component --- src/common/RelativeTime.svelte | 46 +++++++++++++++++++ .../stories/RelativeTime.stories.svelte | 24 ++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/common/RelativeTime.svelte create mode 100644 src/common/stories/RelativeTime.stories.svelte diff --git a/src/common/RelativeTime.svelte b/src/common/RelativeTime.svelte new file mode 100644 index 000000000..182e1e68f --- /dev/null +++ b/src/common/RelativeTime.svelte @@ -0,0 +1,46 @@ + + + + + diff --git a/src/common/stories/RelativeTime.stories.svelte b/src/common/stories/RelativeTime.stories.svelte new file mode 100644 index 000000000..e25f7dc38 --- /dev/null +++ b/src/common/stories/RelativeTime.stories.svelte @@ -0,0 +1,24 @@ + + + + + + + + From 15c178a2dfeb04994de8a46043c6df2dad1fbd67 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 28 Nov 2023 11:07:49 -0500 Subject: [PATCH 11/40] Styling for RevisionsDialog --- src/common/Button.svelte | 3 +- src/common/dialog/RevisionsDialog.svelte | 124 ++++++++++++++++-- .../stories/RevisionsDialog.stories.svelte | 51 +++++-- 3 files changed, 154 insertions(+), 24 deletions(-) diff --git a/src/common/Button.svelte b/src/common/Button.svelte index 9a5a462aa..edde6fc53 100644 --- a/src/common/Button.svelte +++ b/src/common/Button.svelte @@ -90,7 +90,8 @@ font-family: inherit; } - button.nomargin { + button.nomargin, + a.nomargin { margin: 0; } diff --git a/src/common/dialog/RevisionsDialog.svelte b/src/common/dialog/RevisionsDialog.svelte index bc2454847..2bc13835a 100644 --- a/src/common/dialog/RevisionsDialog.svelte +++ b/src/common/dialog/RevisionsDialog.svelte @@ -1,16 +1,120 @@ - - {#each revisions as revision} - - - - - - {/each} -
{revision.version}{revision.comment}
+ + +

Revision History

+
+ +
+{#if enabled} +
+ + {#each sortedRevisions as revision} + + + + + + {:else} + + {/each} +
{revision.version} +

{revision.comment}

+ +
No revisions found
+
+ {#if revisions.length > 0}

{revisions.length} total

{/if} +{/if} diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte index 9b93c1413..335feb37e 100644 --- a/src/common/dialog/stories/RevisionsDialog.stories.svelte +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -1,28 +1,53 @@ - - + export const meta = { + title: "Dialogs / Revision", + component: RevisionsDialog, + parameters: { + layout: "centered", + }, + argTypes: { + enabled: { + control: { + type: "boolean", + }, + }, + }, + }; + - - + + + From 89840f1dc8b6307ed412e4a2d153b9bc70cca6c1 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 28 Nov 2023 11:08:34 -0500 Subject: [PATCH 12/40] Adds API function for toggling document revisions --- src/api/document.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/api/document.js b/src/api/document.js index 7414d0eea..40816101a 100644 --- a/src/api/document.js +++ b/src/api/document.js @@ -161,6 +161,16 @@ export async function changeAccess(ids, access) { ); } +export async function changeRevisionControl(ids, revision_control) { + // Enable or disable revision control on specified documents + await session.patch( + apiUrl(`documents/`), + ids.map((id) => { + id, revision_control; + }), + ); +} + export async function reprocessDocument(ids, forceOcr, ocrEngine) { // Reprocess the documents with the specified ids await session.post( From abba76d91ea8352ded5b4537f2f9ef1e7dfed1de Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 5 Dec 2023 17:44:17 -0500 Subject: [PATCH 13/40] Stories for File upload controls --- src/common/stories/DropZone.stories.svelte | 34 ++++++++++++++++++++ src/common/stories/FilePicker.stories.svelte | 26 +++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/common/stories/DropZone.stories.svelte create mode 100644 src/common/stories/FilePicker.stories.svelte diff --git a/src/common/stories/DropZone.stories.svelte b/src/common/stories/DropZone.stories.svelte new file mode 100644 index 000000000..44e4c578f --- /dev/null +++ b/src/common/stories/DropZone.stories.svelte @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/src/common/stories/FilePicker.stories.svelte b/src/common/stories/FilePicker.stories.svelte new file mode 100644 index 000000000..6c0e28fd3 --- /dev/null +++ b/src/common/stories/FilePicker.stories.svelte @@ -0,0 +1,26 @@ + + + + + + From 536e776ed0404adc62d0a247e7ed69918ea84930 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 5 Dec 2023 17:44:43 -0500 Subject: [PATCH 14/40] Creates subdirectory for UploadDialog --- src/pages/app/Documents.svelte | 2 +- src/pages/app/{ => upload}/UploadDialog.svelte | 2 +- src/pages/app/upload/UploadDialogContainer.svelte | 0 src/pages/app/upload/stories/UploadDialog.stories.svelte | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename src/pages/app/{ => upload}/UploadDialog.svelte (99%) create mode 100644 src/pages/app/upload/UploadDialogContainer.svelte create mode 100644 src/pages/app/upload/stories/UploadDialog.stories.svelte diff --git a/src/pages/app/Documents.svelte b/src/pages/app/Documents.svelte index 25c81eecf..a3cad2fde 100644 --- a/src/pages/app/Documents.svelte +++ b/src/pages/app/Documents.svelte @@ -21,7 +21,7 @@ import SearchLink from "./SearchLink.svelte"; import SpecialMessage from "@/common/SpecialMessage.svelte"; import Title from "@/common/Title.svelte"; - import UploadDialog from "./UploadDialog.svelte"; + import UploadDialog from "./upload/UploadDialog.svelte"; // Store properties import { layout } from "@/manager/layout.js"; diff --git a/src/pages/app/UploadDialog.svelte b/src/pages/app/upload/UploadDialog.svelte similarity index 99% rename from src/pages/app/UploadDialog.svelte rename to src/pages/app/upload/UploadDialog.svelte index f489e066d..c48e928ba 100644 --- a/src/pages/app/UploadDialog.svelte +++ b/src/pages/app/upload/UploadDialog.svelte @@ -1,6 +1,6 @@
@@ -50,51 +71,84 @@
-
- +
+ +
-
-
- - -
+

{@html $_("uploadOptions.tesseract")}

{#if !hasTextract} -

- {@html $_("uploadOptions.textractPremium")} +

+ {@html $_("uploadOptions.textract")}

+

{@html $_("uploadOptions.premiumTout")}

{:else} -

- {$_("uploadOptions.creditHelpText", { - values: { - organization: $orgsAndUsers.me.organization.name, - n: $orgsAndUsers.me.organization.monthly_credits, - }, - })} -

+ {#await getUserPromise then} +

+ {$_("uploadOptions.creditHelpText", { + values: { + organization: org.name, + n: org.monthly_credits, + }, + })} +

+ {/await} {/if}
+
+
+ +

{$_("uploadOptions.revisionControlHelp")}

+

{@html $_("uploadOptions.premiumTout")}

+
+
+ -

Revision History

-
-
- -{#if enabled} -
- - {#each sortedRevisions as revision} - - - - - - {:else} - - {/each} -
{revision.version} -

{revision.comment}

- -
No revisions found
+ {/if} +{:catch} + +
+
+

An error occurred

- {#if revisions.length > 0}

{revisions.length} total

{/if} -{/if} +{/await} diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte index b3741d523..fac0ff583 100644 --- a/src/common/dialog/stories/RevisionsDialog.stories.svelte +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -6,6 +6,8 @@ import documentFixture from "../../../pages/app/test/fixtures/document.json"; import { revisionControl } from "./mockData"; + import { mockGetMe } from "../../../pages/app/accounts/stories/mockData"; + const today = new Date().getDate(); const manyRevisions = Array(100) .fill(1) @@ -31,7 +33,7 @@ parameters: { layout: "centered", msw: { - handlers: [revisionControl.success], + handlers: [revisionControl.success, mockGetMe.data], }, }, argTypes: { @@ -58,10 +60,24 @@ + + diff --git a/src/pages/app/accounts/stories/mockData.ts b/src/pages/app/accounts/stories/mockData.ts index a658827a6..9fe27a38a 100644 --- a/src/pages/app/accounts/stories/mockData.ts +++ b/src/pages/app/accounts/stories/mockData.ts @@ -21,6 +21,20 @@ export const mockGetMe = { }), ), ), + freeOrgMember: rest.get(mockMeUrl, (req, res, ctx) => + res( + ctx.json({ ...me, organization: { ...me.organization, plan: "Free" } }), + ), + ), + freeOrgAdmin: rest.get(mockMeUrl, (req, res, ctx) => + res( + ctx.json({ + ...me, + organization: { ...me.organization, plan: "Free" }, + admin_organizations: [...me.admin_organizations, 1], + }), + ), + ), loading: rest.get(mockMeUrl, (req, res, ctx) => res(ctx.delay("infinite"))), error: rest.get(mockMeUrl, (req, res, ctx) => res(ctx.status(404, "Not Found"), ctx.json({ detail: "Not found." })), diff --git a/src/pages/viewer/Sidebar.svelte b/src/pages/viewer/Sidebar.svelte index 4bf684d91..480c173db 100644 --- a/src/pages/viewer/Sidebar.svelte +++ b/src/pages/viewer/Sidebar.svelte @@ -13,6 +13,7 @@ enterInfoMode, enterDataMode, enterSectionsMode, + enterRevisionsMode, } from "../../viewer/actions"; import { showEmbedFlow, @@ -59,6 +60,7 @@ header: string; description: string; disabled?: boolean; + premium?: boolean; } let actions: Action[] = [ @@ -103,6 +105,14 @@ description: $_("sidebar.dataDesc"), disabled: document?.readable, }, + { + id: "revisions", + action: enterRevisionsMode, + header: $_("sidebar.revisions"), + description: $_("sidebar.revisionsDesc"), + disabled: document?.readable, + premium: true, + }, { id: "sections", action: enterSectionsMode, @@ -220,13 +230,14 @@ {#if signedIn}
{$_("sidebar.actions")}
{#if document?.editAccess} - {#each actions as { id, action, header, description, disabled }} + {#each actions as { id, action, header, description, disabled, premium }} {/each} {:else} diff --git a/src/pages/viewer/SidebarAction.svelte b/src/pages/viewer/SidebarAction.svelte index b10a75e74..bef6f4bcf 100644 --- a/src/pages/viewer/SidebarAction.svelte +++ b/src/pages/viewer/SidebarAction.svelte @@ -1,14 +1,34 @@ - @@ -38,6 +58,13 @@ background: rgba(0, 0, 0, 0.02); } + .action header { + display: flex; + gap: 1em; + align-items: center; + justify-content: space-between; + } + .action h3 { font-weight: bold; font-size: 14px; diff --git a/src/pages/viewer/stories/SidebarAction.stories.svelte b/src/pages/viewer/stories/SidebarAction.stories.svelte index 36519bb23..81b57fc13 100644 --- a/src/pages/viewer/stories/SidebarAction.stories.svelte +++ b/src/pages/viewer/stories/SidebarAction.stories.svelte @@ -24,3 +24,4 @@ + diff --git a/src/viewer/actions.js b/src/viewer/actions.js index 3e541d544..709b2d8e2 100644 --- a/src/viewer/actions.js +++ b/src/viewer/actions.js @@ -33,6 +33,10 @@ export function enterDataMode() { layout.showData = true; } +export function enterRevisionsMode() { + layout.showRevisions = true; +} + export function enterSectionsMode() { layout.showEditSections = true; } diff --git a/src/viewer/layout.js b/src/viewer/layout.js index 06ddd5af4..0fbf799b1 100644 --- a/src/viewer/layout.js +++ b/src/viewer/layout.js @@ -81,6 +81,7 @@ export const layout = new Svue({ showInfo: false, showData: false, showAccess: false, + showRevisions: false, // Sections showEditSections: false, From 591a3723239e674f1e4f846cc3cfc7c6e78a9183 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 12 Dec 2023 16:46:36 -0500 Subject: [PATCH 20/40] Creates PremiumBadge component to replace duplicated code --- src/addons/browser/AddOnListItem.svelte | 13 +- src/addons/dispatch/Header.svelte | 12 +- src/common/RevisionIcon.svelte | 18 +-- src/common/dialog/RevisionsDialog.svelte | 133 +++++++++--------- src/langs/json/en.json | 3 + src/pages/viewer/SidebarAction.svelte | 13 +- src/premium-credits/PremiumBadge.svelte | 13 ++ .../stories/PremiumBadge.stories.svelte | 17 +++ 8 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 src/premium-credits/PremiumBadge.svelte create mode 100644 src/premium-credits/stories/PremiumBadge.stories.svelte diff --git a/src/addons/browser/AddOnListItem.svelte b/src/addons/browser/AddOnListItem.svelte index 40284d260..698bbfdfa 100644 --- a/src/addons/browser/AddOnListItem.svelte +++ b/src/addons/browser/AddOnListItem.svelte @@ -4,8 +4,7 @@ import AddOnPin from "../AddOnPin.svelte"; import AddOnPopularity from "../Popularity.svelte"; import type { AddOnListItem } from "../types.js"; - import Credit from "../../common/icons/Credit.svelte"; - import Badge from "../../common/Badge.svelte"; + import PremiumBadge from "../../premium-credits/PremiumBadge.svelte"; export let addon: AddOnListItem; @@ -39,15 +38,7 @@ {/if} {#if isPremium} - - - + {/if}
diff --git a/src/addons/dispatch/Header.svelte b/src/addons/dispatch/Header.svelte index 713af05ba..968a0ffa5 100644 --- a/src/addons/dispatch/Header.svelte +++ b/src/addons/dispatch/Header.svelte @@ -9,8 +9,7 @@ import { pushToast } from "../../common/Toast.svelte"; import AddOnPin from "../AddOnPin.svelte"; - import Badge from "../../common/Badge.svelte"; - import Credit from "../../common/icons/Credit.svelte"; + import PremiumBadge from "../../premium-credits/PremiumBadge.svelte"; export let addon: AddOnListItem; @@ -77,14 +76,7 @@ {/if}
{#if isPremium} - + {/if} diff --git a/src/common/RevisionIcon.svelte b/src/common/RevisionIcon.svelte index 8206e5d6c..d5a334c36 100644 --- a/src/common/RevisionIcon.svelte +++ b/src/common/RevisionIcon.svelte @@ -23,6 +23,15 @@ }); +{#if revisions !== null} + + + +{/if} + - -{#if revisions !== null} - - - -{/if} diff --git a/src/common/dialog/RevisionsDialog.svelte b/src/common/dialog/RevisionsDialog.svelte index 9f51532da..ee461491f 100644 --- a/src/common/dialog/RevisionsDialog.svelte +++ b/src/common/dialog/RevisionsDialog.svelte @@ -26,10 +26,71 @@ } from "../../manager/orgsAndUsers.js"; import UpgradePrompt from "../../premium-credits/UpgradePrompt.svelte"; import Error from "../../common/icons/Error.svelte"; - import Credit from "../icons/Credit.svelte"; - import Badge from "../Badge.svelte"; + import PremiumBadge from "../../premium-credits/PremiumBadge.svelte"; +
+

Revision History

+ +
+{#await getMe() then user} + {#if isPremiumOrg(user.organization)} +
+ +
+ {#if enabled} +
+ + {#each sortedRevisions as revision} + + + + + + {:else} + + {/each} +
{revision.version} +

{revision.comment}

+ +
No revisions found
+
+ {#if revisions.length > 0}

+ {revisions.length} total +

{/if} + {/if} + {:else if isOrgAdmin(user)} + triggerPremiumUpgradeFlow(user?.organization)} + /> + {:else} + + {/if} +{:catch} + +
+
+

An error occurred

+
+{/await} + - -
-

Revision History

- - - -
-{#await getMe() then user} - {#if isPremiumOrg(user.organization)} -
- -
- {#if enabled} -
- - {#each sortedRevisions as revision} - - - - - - {:else} - - {/each} -
{revision.version} -

{revision.comment}

- -
No revisions found
-
- {#if revisions.length > 0}

- {revisions.length} total -

{/if} - {/if} - {:else if isOrgAdmin(user)} - triggerPremiumUpgradeFlow(user?.organization)} - /> - {:else} - - {/if} -{:catch} - -
-
-

An error occurred

-
-{/await} diff --git a/src/langs/json/en.json b/src/langs/json/en.json index acf56ef22..b22fb104d 100644 --- a/src/langs/json/en.json +++ b/src/langs/json/en.json @@ -844,5 +844,8 @@ "p3": "Want more fascinating documents, open data and original reporting to your inbox? Subscribe to MuckRock's newsletter:", "p4": "DocumentCloud is part of a suite of transparency tools from the MuckRock Foundation, a 501c3 registered non-profit. This archive is open to the public and advertisement free thanks to support from readers like you — you can learn more about our work or make a donation.", "subscribe": "Subscribe" + }, + "premium": { + "badge": "Premium" } } diff --git a/src/pages/viewer/SidebarAction.svelte b/src/pages/viewer/SidebarAction.svelte index bef6f4bcf..6a39ec114 100644 --- a/src/pages/viewer/SidebarAction.svelte +++ b/src/pages/viewer/SidebarAction.svelte @@ -1,6 +1,5 @@ + + + + diff --git a/src/premium-credits/stories/PremiumBadge.stories.svelte b/src/premium-credits/stories/PremiumBadge.stories.svelte new file mode 100644 index 000000000..a6e857563 --- /dev/null +++ b/src/premium-credits/stories/PremiumBadge.stories.svelte @@ -0,0 +1,17 @@ + + + + + From 04cfeb6719896065eea3ffa44a352b136049f985 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 12 Dec 2023 14:47:28 -0500 Subject: [PATCH 21/40] Localization --- src/langs/json/en.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/langs/json/en.json b/src/langs/json/en.json index b22fb104d..da877b3b7 100644 --- a/src/langs/json/en.json +++ b/src/langs/json/en.json @@ -736,7 +736,9 @@ "sections": "Edit Sections", "sectionsDesc": "Add sections to organize your document with a table of contents.", "privateNote": "Add Private Note", - "privateNoteDesc": "Leave a public, private or shared note, which can be embedded within an article." + "privateNoteDesc": "Leave a public, private or shared note, which can be embedded within an article.", + "revisions": "Revision History", + "revisionsDesc": "Toggle revision history and view previous versions of yoru document." }, "viewer": { "notFound": "Document not found", From 7475f950ba5d85f876beb1c4f2b815674821a583 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 12 Dec 2023 18:31:10 -0500 Subject: [PATCH 22/40] Creates reusable ErrorMessage component --- src/common/ErrorMessage.svelte | 30 +++++++++++++++++++ .../stories/ErrorMessage.stories.svelte | 26 ++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/common/ErrorMessage.svelte create mode 100644 src/common/stories/ErrorMessage.stories.svelte diff --git a/src/common/ErrorMessage.svelte b/src/common/ErrorMessage.svelte new file mode 100644 index 000000000..3295e4609 --- /dev/null +++ b/src/common/ErrorMessage.svelte @@ -0,0 +1,30 @@ + + +
+
+

{message}

+ +
+ + diff --git a/src/common/stories/ErrorMessage.stories.svelte b/src/common/stories/ErrorMessage.stories.svelte new file mode 100644 index 000000000..a8a451a7b --- /dev/null +++ b/src/common/stories/ErrorMessage.stories.svelte @@ -0,0 +1,26 @@ + + + + + From 40e83f30f8615cc76213e7e2746496a007dbe19d Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 12 Dec 2023 18:31:20 -0500 Subject: [PATCH 23/40] Localization for RevisionsDialog --- src/common/dialog/RevisionsDialog.svelte | 70 ++++++++----------- .../stories/RevisionsDialog.stories.svelte | 5 ++ src/langs/json/en.json | 13 ++++ 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/common/dialog/RevisionsDialog.svelte b/src/common/dialog/RevisionsDialog.svelte index ee461491f..ae610fa11 100644 --- a/src/common/dialog/RevisionsDialog.svelte +++ b/src/common/dialog/RevisionsDialog.svelte @@ -1,8 +1,19 @@
-

Revision History

+

{$_("dialogRevisionsDialog.heading")}

-{#await getMe() then user} +{#await getMePromise then user} {#if isPremiumOrg(user.organization)}
{#if enabled} @@ -59,36 +65,37 @@ > {:else} - No revisions found + {$_("dialogRevisionsDialog.empty")} {/each} {#if revisions.length > 0}

- {revisions.length} total + {$_("dialogRevisionsDialog.total", { + values: { n: revisions.length }, + })}

{/if} {/if} {:else if isOrgAdmin(user)} triggerPremiumUpgradeFlow(user?.organization)} /> {:else} {/if} {:catch} - -
-
-

An error occurred

-
+ {/await} diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte index fac0ff583..75ced9d12 100644 --- a/src/common/dialog/stories/RevisionsDialog.stories.svelte +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -81,3 +81,8 @@ msw: { handlers: [revisionControl.error, mockGetMe.freeOrgMember] }, }} /> + diff --git a/src/langs/json/en.json b/src/langs/json/en.json index da877b3b7..eaedc70bc 100644 --- a/src/langs/json/en.json +++ b/src/langs/json/en.json @@ -315,6 +315,19 @@ "invalid": "Invalid project", "cannotEmbed": "Cannot embed this project, as it does not appear to exist." }, + "dialogRevisionsDialog": { + "heading": "Revision History", + "controlLabel": "Revision Control", + "total": "{n} total", + "download": "Download", + "empty": "No revisions found", + "error": "Error loading revision data. Please contact support for assistance.", + "upgrade": { + "message": "Pro and Organization users can record and access the entire version history of their documents.", + "nonAdminCta": "Contact your organization administrator about upgrading your account.", + "adminCta": "Upgrade" + } + }, "htmlEditor": { "preview": "Preview:" }, From 1ac435a003ecc2f0705cbe9234837a81b16a5bcb Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 12 Dec 2023 18:35:44 -0500 Subject: [PATCH 24/40] Wires up RevisionsDialog into Viewer layout logic --- src/pages/viewer/Viewer.svelte | 6 ++++++ src/pages/viewer/viewerEditDialogs.js | 3 +++ src/viewer/layout.js | 8 +++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/pages/viewer/Viewer.svelte b/src/pages/viewer/Viewer.svelte index a0fbab1eb..fcb911c6e 100644 --- a/src/pages/viewer/Viewer.svelte +++ b/src/pages/viewer/Viewer.svelte @@ -33,6 +33,7 @@ hideDocumentInfo, hideDocumentData, hideEditSections, + hideRevisions, hideInsertDialog, forceReprocess, } from "@/viewer/layout.js"; @@ -166,6 +167,11 @@ component={$viewerEditDialogs.dataDialog} on:close={hideDocumentData} /> +{:else if $layout.showRevisions} + {:else if $layout.showEditSections} Date: Wed, 13 Dec 2023 11:01:39 -0500 Subject: [PATCH 25/40] Fixes unprotected access check in RevisionIcon --- src/common/RevisionIcon.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/RevisionIcon.svelte b/src/common/RevisionIcon.svelte index d5a334c36..9920fd483 100644 --- a/src/common/RevisionIcon.svelte +++ b/src/common/RevisionIcon.svelte @@ -19,7 +19,7 @@ export let showCount: boolean = false; const tooltipText = $_("revisionIcon.tooltip", { - values: { count: revisions.length }, + values: { count: revisions?.length }, }); From 3c7b80360129aa56f0cebc79108fbd83df3acda7 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Wed, 13 Dec 2023 11:03:36 -0500 Subject: [PATCH 26/40] Add rendering delays in Chromatic This allows network mocks to resolve before snapshots are taken. --- src/common/dialog/stories/RevisionsDialog.stories.svelte | 1 + src/pages/app/accounts/stories/OrgMemberList.stories.svelte | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte index 75ced9d12..bef681d35 100644 --- a/src/common/dialog/stories/RevisionsDialog.stories.svelte +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -32,6 +32,7 @@ component: RevisionsDialog, parameters: { layout: "centered", + chromatic: { delay: 300 }, msw: { handlers: [revisionControl.success, mockGetMe.data], }, diff --git a/src/pages/app/accounts/stories/OrgMemberList.stories.svelte b/src/pages/app/accounts/stories/OrgMemberList.stories.svelte index 56cd2b0e9..cc6092e9d 100644 --- a/src/pages/app/accounts/stories/OrgMemberList.stories.svelte +++ b/src/pages/app/accounts/stories/OrgMemberList.stories.svelte @@ -9,7 +9,10 @@ export const meta = { title: "App / Accounts / Menus / Org / Member List", component: OrgMemberList, - parameters: { layout: "centered" }, + parameters: { + layout: "centered", + chromatic: { delay: 300 }, + }, }; From 50742343bfb5a9cf2d44a76e55849bfe5623fc6c Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Wed, 13 Dec 2023 11:49:25 -0500 Subject: [PATCH 27/40] Makes uploadOptions responsive to user premium status --- src/api/fixtures/orgAndUser.fixtures.js | 28 +++ src/common/UploadOptions.svelte | 162 ++++++++++++------ .../stories/UploadOptions.stories.svelte | 27 ++- src/langs/json/en.json | 5 +- src/manager/orgsAndUsers.js | 15 +- src/pages/app/accounts/stories/mockData.ts | 20 +++ 6 files changed, 194 insertions(+), 63 deletions(-) diff --git a/src/api/fixtures/orgAndUser.fixtures.js b/src/api/fixtures/orgAndUser.fixtures.js index 80e3db25e..387c24afe 100644 --- a/src/api/fixtures/orgAndUser.fixtures.js +++ b/src/api/fixtures/orgAndUser.fixtures.js @@ -205,3 +205,31 @@ export const organization = { monthly_credit_allowance: 5000, plan: "Organization", }; + +export const proOrg = { + id: 4, + avatar_url: + "https://cdn.muckrock.com/media/account_images/allan-headshot-2016.jpg", + individual: true, + name: "lasser.allan", + slug: "lasserallan", + monthly_credits: 2500, + purchased_credits: 3000, + credit_reset_date: "2023-11-28", + monthly_credit_allowance: 2500, + plan: "Professional", +}; + +export const freeOrg = { + id: 4, + avatar_url: + "https://cdn.muckrock.com/media/account_images/allan-headshot-2016.jpg", + individual: true, + name: "lasser.allan", + slug: "lasserallan", + monthly_credits: 0, + purchased_credits: 0, + credit_reset_date: "2023-11-28", + monthly_credit_allowance: 0, + plan: "Free", +}; diff --git a/src/common/UploadOptions.svelte b/src/common/UploadOptions.svelte index 8a1f00237..73b494feb 100644 --- a/src/common/UploadOptions.svelte +++ b/src/common/UploadOptions.svelte @@ -9,10 +9,16 @@ import type { Org, User } from "../pages/app/accounts/types.js"; import { getMe, getOrganization } from "../api/orgAndUser.js"; import { onMount } from "svelte"; + import { + getUpgradeURL, + isOrgAdmin, + isPremiumOrg, + } from "../manager/orgsAndUsers.js"; + import PremiumBadge from "../premium-credits/PremiumBadge.svelte"; export let language = defaultLanguage; export let forceOcr = false; - export let ocrEngine = "tess4"; + export let ocrEngine: "tess4" | "textract" = "tess4"; export let revisionControl = false; let languageName = defaultLanguageName(languages); @@ -23,25 +29,31 @@ async function getUser() { try { user = await getMe(); - const activeOrg = user?.organization; + } catch (e) { + user = null; + console.error("Error setting User: ", JSON.stringify(e, null, 2)); + } + try { + let activeOrg = user?.organization; if (typeof activeOrg === "string") { - org = await getOrganization(activeOrg); + org = (await getOrganization(activeOrg)) as Org; } else { org = activeOrg; } } catch (e) { - user = null; + org = null; + console.error("Error setting Org: ", JSON.stringify(e, null, 2)); } } - $: hasTextract = user?.feature_level > 0; $: selectLanguages = ocrEngine === "textract" ? textractLanguages : languages; + $: hasTextract = isPremiumOrg(org); // value, name, disabled - type OCREngine = [string, string, boolean]; + type OCREngine = [value: string, name: string, isPremium: boolean]; const ocrEngines: OCREngine[] = [ ["tess4", "Tesseract", false], - ["textract", "Textract", !hasTextract], + ["textract", "Textract", true], ]; function defaultLanguageName(languages) { @@ -59,42 +71,55 @@ }); -
- - {#each ocrEngines as [value, name, disabled]} - - {/each} - - - +{#await getUserPromise then} +
+ + {#each ocrEngines as [value, name, isPremium]} + + {/each} + + + +
+ +
+

{@html $_("uploadOptions.tesseract")}

- {@html $_("uploadOptions.textract")} + {@html $_("uploadOptions.textract")} + {#if !isPremiumOrg(org)} + {#if isOrgAdmin(user)} + {@html $_("uploadOptions.premiumToutAdmin", { + values: { upgradeUrl: getUpgradeURL(org) }, + })} + {:else} + {@html $_("uploadOptions.premiumToutMember")} + {/if} + {/if}

-

{@html $_("uploadOptions.premiumTout")}

- {:else} - {#await getUserPromise then} + {#if isPremiumOrg(org) && ocrEngine == "textract"}

{$_("uploadOptions.creditHelpText", { values: { @@ -103,21 +128,46 @@ }, })}

- {/await} - {/if} + {/if} +
- - -
-
- -

{$_("uploadOptions.revisionControlHelp")}

-

{@html $_("uploadOptions.premiumTout")}

+ +
+
+
+
+ +

+ {$_("uploadOptions.revisionControlHelp")} +

+
+ +
+ {#if !isPremiumOrg(org)} +

+ {#if isOrgAdmin(user)} + {@html $_("uploadOptions.premiumToutAdmin", { + values: { upgradeUrl: getUpgradeURL(org) }, + })} + {:else} + {@html $_("uploadOptions.premiumToutMember")} + {/if} +

+ {/if} +
-
+{/await} diff --git a/src/pages/app/accounts/PremiumMenu.svelte b/src/pages/app/accounts/PremiumMenu.svelte index 0bb33b144..a9eb842b0 100644 --- a/src/pages/app/accounts/PremiumMenu.svelte +++ b/src/pages/app/accounts/PremiumMenu.svelte @@ -6,7 +6,7 @@ import MenuItem from "../../../common/MenuItem.svelte"; import MenuTitle from "../../../common/MenuTitle.svelte"; import Button from "../../../common/Button.svelte"; - import Credit from "../../../common/icons/Credit.svelte"; + import Premium from "../../../common/icons/Premium.svelte"; import CreditMeter, { formatResetDate, } from "../../../premium-credits/CreditMeter.svelte"; @@ -41,7 +41,7 @@ -
+
@@ -122,7 +122,7 @@ justify-content: center; height: 1.5rem; width: 1.5rem; - background: var(--white, #ffffff); + background: transparent; } .learnMore { font-size: 0.8em; diff --git a/src/premium-credits/PremiumBadge.svelte b/src/premium-credits/PremiumBadge.svelte index 66f02edef..8cf3d8af3 100644 --- a/src/premium-credits/PremiumBadge.svelte +++ b/src/premium-credits/PremiumBadge.svelte @@ -2,12 +2,13 @@ import { _ } from "svelte-i18n"; import Badge from "../common/Badge.svelte"; import Credit from "../common/icons/Credit.svelte"; + import Premium from "../common/icons/Premium.svelte"; - + From 789302c39681ce798c5254c943ff0525db192798 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 21 Dec 2023 15:54:03 -0500 Subject: [PATCH 31/40] Adjust styling of document row item --- src/pages/app/Document.svelte | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/pages/app/Document.svelte b/src/pages/app/Document.svelte index 58021a3aa..99fb772fc 100644 --- a/src/pages/app/Document.svelte +++ b/src/pages/app/Document.svelte @@ -479,14 +479,15 @@ .document-title-row { display: flex; - gap: 1em; + gap: 0.5rem; } .document-title-row h2 { - flex: 1 1 auto; + flex: 0 1 auto; } .document-title-row-actions { + flex: 0 1 auto; display: flex; gap: 0.5em 0; flex-direction: row; @@ -497,7 +498,6 @@ .document-meta-row { display: flex; flex-wrap: wrap; - gap: 0 1em; } .document-meta { @@ -509,12 +509,9 @@ padding: 0; } - @media only screen and (max-width: 720px) { - .document-title-row-actions { - flex-direction: column; - height: auto; - padding: 0.25em 0; - } + .document-meta:not(:last-child)::after { + content: "–"; + margin: 0 0.25rem; } .description { From 7f4ae26a8d88c23dd5f4e6f5e4df48f087a390f1 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 21 Dec 2023 16:08:24 -0500 Subject: [PATCH 32/40] Changes revisionDialog to change property on save --- src/common/dialog/RevisionsDialog.svelte | 91 ++++++++++--------- .../dialog/RevisionsDialogContainer.svelte | 11 ++- .../stories/RevisionsDialog.stories.svelte | 3 + 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/common/dialog/RevisionsDialog.svelte b/src/common/dialog/RevisionsDialog.svelte index 5eecfb0d5..0bd9e70ba 100644 --- a/src/common/dialog/RevisionsDialog.svelte +++ b/src/common/dialog/RevisionsDialog.svelte @@ -1,7 +1,6 @@ - + diff --git a/src/common/dialog/stories/RevisionsDialog.stories.svelte b/src/common/dialog/stories/RevisionsDialog.stories.svelte index 165ec5031..80cf40096 100644 --- a/src/common/dialog/stories/RevisionsDialog.stories.svelte +++ b/src/common/dialog/stories/RevisionsDialog.stories.svelte @@ -7,6 +7,7 @@ import { revisionControl } from "./mockData"; import { mockGetMe } from "../../../pages/app/accounts/stories/mockData"; + import { Action } from "../../stories/Button.stories"; const today = new Date().getDate(); const manyRevisions = Array(100) @@ -25,6 +26,8 @@ enabled: true, documentId: "1", revisions: documentFixture.revisions, + onSave: action("Save"), + onCancel: action("Cancel"), }; export const meta = { From 8536fbf4dc457b3402dedebfcef570651122f026 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Thu, 21 Dec 2023 16:08:35 -0500 Subject: [PATCH 33/40] cleanup uploadOptions --- src/common/UploadOptions.svelte | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/common/UploadOptions.svelte b/src/common/UploadOptions.svelte index 73b494feb..ea0e18018 100644 --- a/src/common/UploadOptions.svelte +++ b/src/common/UploadOptions.svelte @@ -134,21 +134,19 @@
-
-
- -

- {$_("uploadOptions.revisionControlHelp")} -

-
- +
+ +

+ {$_("uploadOptions.revisionControlHelp")} +

{#if !isPremiumOrg(org)}

From 74a886505e6caad97bdd0e1edaa3a79424700309 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 8 Jan 2024 13:27:01 -0500 Subject: [PATCH 34/40] Fixes for RevisionsDialog - Dismiss modal on save - Prevent form from submitting on button clicks - Controls document revision change through manager fn - Fix unchecked access on revisions list --- src/api/document.js | 9 ++++-- src/common/dialog/RevisionsDialog.svelte | 12 +++++--- .../dialog/RevisionsDialogContainer.svelte | 12 +++++--- src/manager/documents.js | 28 +++++++++++++++++-- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/api/document.js b/src/api/document.js index 643e4ddc4..61dcd3737 100644 --- a/src/api/document.js +++ b/src/api/document.js @@ -163,13 +163,18 @@ export async function changeAccess(ids, access) { export async function changeRevisionControl(ids, revision_control) { // Enable or disable revision control on specified documents - await session.patch( - apiUrl(`documents/`), + const { data } = await session.patch( + apiUrl( + queryBuilder(`documents/`, { + expand: [DEFAULT_EXPAND, "revisions"].join(","), + }), + ), ids.map((id) => ({ id, revision_control, })), ); + return data; } export async function reprocessDocument(ids, forceOcr, ocrEngine) { diff --git a/src/common/dialog/RevisionsDialog.svelte b/src/common/dialog/RevisionsDialog.svelte index 0bd9e70ba..aaa289b7f 100644 --- a/src/common/dialog/RevisionsDialog.svelte +++ b/src/common/dialog/RevisionsDialog.svelte @@ -18,12 +18,12 @@ export let enabled: boolean = false; export let revisions: Revision[] | null = []; export let onSave: (enabled: boolean) => void; - export let onCancel: () => {}; + export let onCancel: () => void; $: sortedRevisions = revisions?.sort((a, b) => { return b.version - a.version; - }) ?? []; + }) ?? null; let getMePromise = getMe(); function retryGetMe() { @@ -41,7 +41,7 @@ - {#if enabled} + {#if enabled && Array.isArray(revisions)}

{#each sortedRevisions as revision} @@ -73,7 +73,11 @@ {/if} {#if isPremiumOrg(user?.organization)} - + { + event.preventDefault(); + }} + >