diff --git a/e2e/scene7.acceptance.spec.ts b/e2e/scene7.acceptance.spec.ts index 351b03d..d52c4d2 100644 --- a/e2e/scene7.acceptance.spec.ts +++ b/e2e/scene7.acceptance.spec.ts @@ -56,6 +56,7 @@ test('pasting, connecting, and citing one patent screenshot completes the Scene await expect(page.locator('.source-file-widget')).toHaveCount(1) await expect(page.locator('.source-file-widget')).toHaveAttribute('data-capture-kind','clipping') await expect(page.locator('.source-file-widget > strong')).toHaveCount(0) + await expect(page.locator('.clip-provenance')).toHaveText('ADD DATE + SOURCE') await expect(page.locator('.source-file-widget')).toHaveClass(/\barriving\b/) await expect(page.locator('.goal-complete-card')).toHaveCount(0) await expect(page.locator('.evidence-card.claim')).toContainText('Nils Aall Barricelli was an inventor') @@ -77,6 +78,7 @@ test('pasting, connecting, and citing one patent screenshot completes the Scene await page.getByLabel('Source URL').fill('https://patents.google.com/patent/GB695913A/en') await page.getByRole('button',{ name:'SAVE METADATA' }).click() await expect(page.locator('.file-editor')).toHaveCount(0) + await expect(page.locator('.clip-provenance')).toHaveText('SOURCE RECORDED') await page.getByRole('button',{ name:'FILE',exact:true }).click() await page.getByRole('menuitem',{ name:/INFO/ }).click() await expect(page.getByLabel('Document title')).toHaveValue('Google Patents ยท GB695913A') diff --git a/src/App.tsx b/src/App.tsx index 7ef7265..2e9816f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -971,13 +971,13 @@ function Board({ state, selected, locatorDocumentId, linkFrom, recentlyCreatedEx
{definition.heading(ev, widgetContext)}{String(i + 1).padStart(3, '0')}
})} - {documentExhibits(state.exhibits).filter(document => !document.hidden).map(document => { const membership = containmentRelations.find(relation => relation.toExhibitId === document.id); const folder = membership ? byId.get(membership.fromExhibitId) : undefined; const open = folder?.type !== 'folder' || folder.isOpen; const located = open && locatorDocumentId === document.id; const left = open ? document.x : folder.x + folder.width / 2 - document.width / 2, top = open ? document.y : folder.y + 45; const definition = documentWidget(document.fileType); const presentation=documentCapture(document.captureKind); const identification=mugshotIdentification(document,state.exhibits,state.connections); const Preview = definition.Preview; const source = document.assetId ? `/api/assets/${encodeURIComponent(document.assetId)}` : ''; return
!document.hidden).map(document => { const membership = containmentRelations.find(relation => relation.toExhibitId === document.id); const folder = membership ? byId.get(membership.fromExhibitId) : undefined; const open = folder?.type !== 'folder' || folder.isOpen; const located = open && locatorDocumentId === document.id; const left = open ? document.x : folder.x + folder.width / 2 - document.width / 2, top = open ? document.y : folder.y + 45; const definition = documentWidget(document.fileType); const presentation=documentCapture(document.captureKind); const identification=mugshotIdentification(document,state.exhibits,state.connections); const Preview = definition.Preview; const source = document.assetId ? `/api/assets/${encodeURIComponent(document.assetId)}` : ''; const missingProvenance=[!document.publishedAt ? 'DATE' : '',!document.sourceCitation?.trim() ? 'SOURCE' : ''].filter(Boolean); return
{ event.stopPropagation(); if (linkFrom && event.button === 0) return; if (tool === 'hand' || event.button === 1) { event.preventDefault(); pointerDown(event) } else if (open && event.button === 0) pointerDown(event, { kind: 'widget', id: document.id }) }} onPointerMove={event => { event.stopPropagation(); pointerMove(event) }} onPointerUp={event => { event.stopPropagation(); finishDrag(event) }} onPointerCancel={event => { event.stopPropagation(); finishDrag(event) }} onClick={event => { event.stopPropagation(); if (suppressClick.current) { suppressClick.current = false; return } if (!open) return; if (tool === 'move') onCardClick(document.id) }} onDoubleClick={() => open && !linkFrom && onOpenSource(document.id)}>
{(document.captureKind === 'unclassified' ? definition.label : presentation.label).toUpperCase()}{String(document.displayNumber || (membership?.sortOrder || 0) + 1).padStart(2, '0')}
onUpdateDocumentCue(document.id, cue)}/>
{document.captureKind === 'photo' ? : document.captureKind !== 'clipping' ? {document.title} : null} -
+
{document.captureKind === 'clipping' && {missingProvenance.length ? `ADD ${missingProvenance.join(' + ')}` : 'SOURCE RECORDED'}}
})} diff --git a/src/styles.css b/src/styles.css index 70ef0db..056cbd0 100644 --- a/src/styles.css +++ b/src/styles.css @@ -223,9 +223,11 @@ button:focus-visible { outline: 2px solid #e99a44; outline-offset: 2px; } .source-file-widget.capture-kind-clipping { padding:14px 13px 10px;overflow:visible;background:linear-gradient(105deg,#e2dfcf,#d3d1c2);border:2px solid #b99a68;box-shadow:8px 10px 0 #020b0980,0 0 0 2px #526059; } .source-file-widget.capture-kind-clipping::after { content:'';position:absolute;z-index:5;top:-7px;left:50%;width:13px;height:13px;translate:-50% 0;border-radius:50%;background:#9e392f;border:2px solid #5d1e1b;box-shadow:0 2px 2px #0006; } .source-file-widget.capture-kind-clipping.open { transform:scale(1); } -.source-file-widget.capture-kind-clipping .source-file-preview { width:100%;height:218px;margin:3px 0 10px;border:2px solid #f4efe1;background:#c8c2b3;box-shadow:2px 3px 3px #10151170;transform:rotate(var(--clip-inset-rotation,.7deg));transform-origin:50% 48%; } +.source-file-widget.capture-kind-clipping .source-file-preview { box-sizing:border-box;width:100%;height:210px;margin:3px 0 8px;border:2px solid #f4efe1;background:#c8c2b3;box-shadow:2px 3px 3px #10151170;transform:rotate(var(--clip-inset-rotation,.7deg));transform-origin:50% 48%; } .source-file-widget.capture-kind-clipping .source-file-preview img { object-fit:contain;filter:grayscale(.12) contrast(1.08); } -.source-file-widget.capture-kind-clipping .source-file-footer { display:flex;align-items:flex-end;justify-content:space-between;gap:8px; } +.source-file-widget.capture-kind-clipping .source-file-footer { display:grid;grid-template-columns:auto minmax(0,1fr);align-items:end;gap:3px 8px; } +.source-file-widget.capture-kind-clipping .clip-provenance { grid-column:1/-1;justify-self:start;padding:2px 4px;border:1px solid #99554d;color:#873e37;background:#dcc7ba99;font:600 5px IBM Plex Mono;letter-spacing:.08em;transform:rotate(-.7deg);opacity:.82; } +.source-file-widget.capture-kind-clipping .clip-provenance.complete { border-color:#557565;color:#3d6652;background:#c9d5c999;transform:rotate(.45deg); } .source-file-widget.capture-kind-clipping .source-file-footer > time { flex:0 0 auto;margin:0 0 2px;color:#775332; } .source-file-widget.capture-kind-clipping .source-file-actions { flex:1;justify-content:flex-end;gap:9px;margin-top:0; } .source-file-widget.capture-kind-clipping .source-file-actions button { color:#4e5d57;text-shadow:none; }