@semiont/react-ui 0.5.23 → 0.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PdfAnnotationCanvas.client-V7Q3BEEQ.js → PdfAnnotationCanvas.client-EHQWF6BR.js} +45 -10
- package/dist/PdfAnnotationCanvas.client-EHQWF6BR.js.map +1 -0
- package/dist/{ar-JRTKCMTF.js → ar-CULRHLNG.js} +20 -6
- package/dist/ar-CULRHLNG.js.map +1 -0
- package/dist/{bn-LO6EDSCC.js → bn-HYR7CEL2.js} +20 -6
- package/dist/bn-HYR7CEL2.js.map +1 -0
- package/dist/{chunk-5Y5JDCKC.js → chunk-NH6L2GIL.js} +20 -6
- package/dist/chunk-NH6L2GIL.js.map +1 -0
- package/dist/{chunk-RO5CRVIA.js → chunk-TG2XQEC4.js} +92 -60
- package/dist/chunk-TG2XQEC4.js.map +1 -0
- package/dist/{cs-LCHHOR4O.js → cs-YBRWY7NH.js} +20 -6
- package/dist/cs-YBRWY7NH.js.map +1 -0
- package/dist/{da-TARGPMJR.js → da-PHDEOBV3.js} +20 -6
- package/dist/da-PHDEOBV3.js.map +1 -0
- package/dist/{de-SBH4QBPJ.js → de-O4UCCVLJ.js} +20 -6
- package/dist/de-O4UCCVLJ.js.map +1 -0
- package/dist/{el-2D2OLGWB.js → el-MVGO6WZV.js} +20 -6
- package/dist/el-MVGO6WZV.js.map +1 -0
- package/dist/{en-QFIEG3CA.js → en-2KQILFKQ.js} +4 -2
- package/dist/{es-U6YK2LX6.js → es-USSLXQY7.js} +20 -6
- package/dist/es-USSLXQY7.js.map +1 -0
- package/dist/{fa-S7SZE37M.js → fa-WMAREFWY.js} +20 -6
- package/dist/fa-WMAREFWY.js.map +1 -0
- package/dist/{fi-CBL3NIXN.js → fi-B3NBNOTS.js} +20 -6
- package/dist/fi-B3NBNOTS.js.map +1 -0
- package/dist/{fr-EABUHV6S.js → fr-TXYK5T5W.js} +20 -6
- package/dist/fr-TXYK5T5W.js.map +1 -0
- package/dist/{he-THWD244Y.js → he-JCJACW5D.js} +20 -6
- package/dist/he-JCJACW5D.js.map +1 -0
- package/dist/{hi-GHGFZJ44.js → hi-VOQLZNJU.js} +20 -6
- package/dist/hi-VOQLZNJU.js.map +1 -0
- package/dist/{id-POZOUMDW.js → id-BFN5RZNZ.js} +20 -6
- package/dist/id-BFN5RZNZ.js.map +1 -0
- package/dist/index.css +0 -36
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +102 -53
- package/dist/index.js +2132 -2097
- package/dist/index.js.map +1 -1
- package/dist/{it-KDYJADSH.js → it-TWWDHKKM.js} +20 -6
- package/dist/it-TWWDHKKM.js.map +1 -0
- package/dist/{ja-Z5Z6ZF3P.js → ja-YRQLEBFM.js} +20 -6
- package/dist/ja-YRQLEBFM.js.map +1 -0
- package/dist/{ko-7X3XUXRN.js → ko-PG6B3CRB.js} +20 -6
- package/dist/ko-PG6B3CRB.js.map +1 -0
- package/dist/{ms-BTWEIW43.js → ms-7EZECVKM.js} +20 -6
- package/dist/ms-7EZECVKM.js.map +1 -0
- package/dist/{nl-IS2CGF5I.js → nl-HP753YAP.js} +20 -6
- package/dist/nl-HP753YAP.js.map +1 -0
- package/dist/{no-AAMEVA26.js → no-JUD5WX3N.js} +20 -6
- package/dist/no-JUD5WX3N.js.map +1 -0
- package/dist/{pl-PVXUQYFT.js → pl-RVUL4CBM.js} +20 -6
- package/dist/pl-RVUL4CBM.js.map +1 -0
- package/dist/{pt-3ITQ76TL.js → pt-RPOVD4QM.js} +20 -6
- package/dist/pt-RPOVD4QM.js.map +1 -0
- package/dist/{ro-FRB4IIVS.js → ro-DMYWQTRD.js} +20 -6
- package/dist/ro-DMYWQTRD.js.map +1 -0
- package/dist/{sv-DS3RO24M.js → sv-DMZ4FGXD.js} +20 -6
- package/dist/sv-DMZ4FGXD.js.map +1 -0
- package/dist/test-utils.js +4 -3
- package/dist/test-utils.js.map +1 -1
- package/dist/{th-AX66MWWB.js → th-4HVBJBQ2.js} +20 -6
- package/dist/th-4HVBJBQ2.js.map +1 -0
- package/dist/{tr-7KTB67TT.js → tr-6BDPU5ML.js} +20 -6
- package/dist/tr-6BDPU5ML.js.map +1 -0
- package/dist/{uk-SMQS2MAQ.js → uk-TBZBT2TL.js} +20 -6
- package/dist/uk-TBZBT2TL.js.map +1 -0
- package/dist/{vi-D3JXL2EZ.js → vi-UMKZKZL3.js} +20 -6
- package/dist/vi-UMKZKZL3.js.map +1 -0
- package/dist/{zh-S754AWFS.js → zh-YBJWJJYB.js} +20 -6
- package/dist/zh-YBJWJJYB.js.map +1 -0
- package/package.json +8 -8
- package/src/components/AssistProgress.tsx +42 -30
- package/src/components/EntityFoundLog.tsx +38 -0
- package/src/components/__tests__/AssistProgress.test.tsx +86 -28
- package/src/components/annotation-popups/JsonLdView.tsx +1 -1
- package/src/components/annotation-popups/__tests__/JsonLdView.test.tsx +8 -2
- package/src/components/modals/ReferenceWizardModal.tsx +2 -1
- package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +112 -12
- package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +247 -1
- package/src/components/resource/AnnotateView.tsx +14 -7
- package/src/components/resource/BrowseView.tsx +2 -7
- package/src/components/resource/DownloadFileLink.tsx +49 -0
- package/src/components/resource/__tests__/AnnotateView.focus.test.tsx +58 -0
- package/src/components/resource/__tests__/download-link.test.tsx +129 -0
- package/src/components/resource/panels/AssistSection.css +0 -43
- package/src/components/resource/panels/AssistSection.tsx +11 -2
- package/src/components/resource/panels/AssistShell.tsx +5 -1
- package/src/components/resource/panels/JsonLdPanel.tsx +1 -1
- package/src/components/resource/panels/ReferencesPanel.tsx +12 -13
- package/src/components/resource/panels/TaggingPanel.tsx +21 -1
- package/src/components/resource/panels/__tests__/AssistSection.test.tsx +2 -2
- package/src/components/resource/panels/__tests__/AssistShell.test.tsx +9 -4
- package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +1 -1
- package/src/components/resource/panels/__tests__/JsonLdPanel.test.tsx +8 -2
- package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +26 -0
- package/src/components/settings/SettingsPanel.tsx +6 -2
- package/src/components/settings/__tests__/SettingsPanel.test.tsx +28 -3
- package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +3 -11
- package/src/features/admin-devops/components/AdminDevOpsPage.tsx +0 -3
- package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +0 -1
- package/src/features/admin-exchange/components/AdminExchangePage.tsx +0 -3
- package/src/features/admin-exchange/state/__tests__/exchange-state-unit.test.ts +1 -1
- package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +0 -8
- package/src/features/admin-security/components/AdminSecurityPage.tsx +0 -3
- package/src/features/admin-security/state/__tests__/admin-security-state-unit.test.ts +1 -1
- package/src/features/admin-users/__tests__/AdminUsersPage.test.tsx +0 -1
- package/src/features/admin-users/components/AdminUsersPage.tsx +0 -3
- package/src/features/admin-users/state/__tests__/admin-users-state-unit.test.ts +1 -1
- package/src/features/auth-welcome/state/__tests__/welcome-state-unit.test.ts +1 -1
- package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +0 -2
- package/src/features/moderate-entity-tags/components/EntityTagsPage.tsx +0 -3
- package/src/features/moderate-entity-tags/state/__tests__/entity-tags-state-unit.test.ts +1 -1
- package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +3 -5
- package/src/features/moderate-recent/components/RecentDocumentsPage.tsx +0 -3
- package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +3 -5
- package/src/features/moderate-tag-schemas/components/TagSchemasPage.tsx +0 -3
- package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +0 -1
- package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +0 -3
- package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +17 -7
- package/src/features/resource-compose/components/ResourceComposePage.tsx +5 -3
- package/src/features/resource-compose/state/__tests__/compose-page-state-unit.test.ts +1 -1
- package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +0 -1
- package/src/features/resource-discovery/components/ResourceDiscoveryPage.tsx +0 -3
- package/src/features/resource-discovery/state/__tests__/discover-state-unit.test.ts +1 -1
- package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +40 -8
- package/src/features/resource-viewer/components/ResourceViewerPage.tsx +20 -16
- package/src/features/resource-viewer/state/__tests__/resource-loader-state-unit.test.ts +1 -1
- package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts +1 -1
- package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +2 -2
- package/translations/ar.json +17 -5
- package/translations/bn.json +17 -5
- package/translations/cs.json +17 -5
- package/translations/da.json +17 -5
- package/translations/de.json +17 -5
- package/translations/el.json +17 -5
- package/translations/en.json +17 -5
- package/translations/es.json +17 -5
- package/translations/fa.json +17 -5
- package/translations/fi.json +17 -5
- package/translations/fr.json +17 -5
- package/translations/he.json +17 -5
- package/translations/hi.json +17 -5
- package/translations/id.json +17 -5
- package/translations/it.json +17 -5
- package/translations/ja.json +17 -5
- package/translations/ko.json +17 -5
- package/translations/ms.json +17 -5
- package/translations/nl.json +17 -5
- package/translations/no.json +17 -5
- package/translations/pl.json +17 -5
- package/translations/pt.json +17 -5
- package/translations/ro.json +17 -5
- package/translations/sv.json +17 -5
- package/translations/th.json +17 -5
- package/translations/tr.json +17 -5
- package/translations/uk.json +17 -5
- package/translations/vi.json +17 -5
- package/translations/zh.json +17 -5
- package/dist/PdfAnnotationCanvas.client-V7Q3BEEQ.js.map +0 -1
- package/dist/ar-JRTKCMTF.js.map +0 -1
- package/dist/bn-LO6EDSCC.js.map +0 -1
- package/dist/chunk-5Y5JDCKC.js.map +0 -1
- package/dist/chunk-RO5CRVIA.js.map +0 -1
- package/dist/cs-LCHHOR4O.js.map +0 -1
- package/dist/da-TARGPMJR.js.map +0 -1
- package/dist/de-SBH4QBPJ.js.map +0 -1
- package/dist/el-2D2OLGWB.js.map +0 -1
- package/dist/es-U6YK2LX6.js.map +0 -1
- package/dist/fa-S7SZE37M.js.map +0 -1
- package/dist/fi-CBL3NIXN.js.map +0 -1
- package/dist/fr-EABUHV6S.js.map +0 -1
- package/dist/he-THWD244Y.js.map +0 -1
- package/dist/hi-GHGFZJ44.js.map +0 -1
- package/dist/id-POZOUMDW.js.map +0 -1
- package/dist/it-KDYJADSH.js.map +0 -1
- package/dist/ja-Z5Z6ZF3P.js.map +0 -1
- package/dist/ko-7X3XUXRN.js.map +0 -1
- package/dist/ms-BTWEIW43.js.map +0 -1
- package/dist/nl-IS2CGF5I.js.map +0 -1
- package/dist/no-AAMEVA26.js.map +0 -1
- package/dist/pl-PVXUQYFT.js.map +0 -1
- package/dist/pt-3ITQ76TL.js.map +0 -1
- package/dist/ro-FRB4IIVS.js.map +0 -1
- package/dist/sv-DS3RO24M.js.map +0 -1
- package/dist/th-AX66MWWB.js.map +0 -1
- package/dist/tr-7KTB67TT.js.map +0 -1
- package/dist/uk-SMQS2MAQ.js.map +0 -1
- package/dist/vi-D3JXL2EZ.js.map +0 -1
- package/dist/zh-S754AWFS.js.map +0 -1
- /package/dist/{en-QFIEG3CA.js.map → en-2KQILFKQ.js.map} +0 -0
|
@@ -15,7 +15,6 @@ export interface RecentDocumentsPageProps {
|
|
|
15
15
|
|
|
16
16
|
// UI state
|
|
17
17
|
theme: 'light' | 'dark' | 'system';
|
|
18
|
-
showLineNumbers: boolean;
|
|
19
18
|
activePanel: string | null;
|
|
20
19
|
|
|
21
20
|
// Translations
|
|
@@ -37,7 +36,6 @@ export interface RecentDocumentsPageProps {
|
|
|
37
36
|
export function RecentDocumentsPage({
|
|
38
37
|
isLoading,
|
|
39
38
|
theme,
|
|
40
|
-
showLineNumbers,
|
|
41
39
|
activePanel,
|
|
42
40
|
translations: t,
|
|
43
41
|
ToolbarPanels,
|
|
@@ -95,7 +93,6 @@ export function RecentDocumentsPage({
|
|
|
95
93
|
<ToolbarPanels
|
|
96
94
|
activePanel={activePanel}
|
|
97
95
|
theme={theme}
|
|
98
|
-
showLineNumbers={showLineNumbers}
|
|
99
96
|
/>
|
|
100
97
|
|
|
101
98
|
<Toolbar
|
|
@@ -61,7 +61,6 @@ const createMockProps = (overrides?: Partial<TagSchemasPageProps>): TagSchemasPa
|
|
|
61
61
|
schemas: mockSchemas,
|
|
62
62
|
isLoading: false,
|
|
63
63
|
theme: 'light',
|
|
64
|
-
showLineNumbers: false,
|
|
65
64
|
activePanel: null,
|
|
66
65
|
translations: {
|
|
67
66
|
pageTitle: 'Tag Schemas',
|
|
@@ -276,13 +275,13 @@ describe('TagSchemasPage', () => {
|
|
|
276
275
|
);
|
|
277
276
|
});
|
|
278
277
|
|
|
279
|
-
it('
|
|
278
|
+
it('does not thread showLineNumbers to toolbar panels — the setting is context-backed', () => {
|
|
280
279
|
const ToolbarPanels = vi.fn(() => <div data-testid="toolbar-panels" />);
|
|
281
|
-
const props = createMockProps({
|
|
280
|
+
const props = createMockProps({ToolbarPanels });
|
|
282
281
|
render(<TagSchemasPage {...props} />);
|
|
283
282
|
|
|
284
283
|
expect(ToolbarPanels).toHaveBeenCalledWith(
|
|
285
|
-
expect.objectContaining({ showLineNumbers:
|
|
284
|
+
expect.not.objectContaining({ showLineNumbers: expect.anything() }),
|
|
286
285
|
undefined,
|
|
287
286
|
);
|
|
288
287
|
});
|
|
@@ -420,7 +419,6 @@ describe('TagSchemasPage', () => {
|
|
|
420
419
|
it('handles all props being defined', () => {
|
|
421
420
|
const props = createMockProps({
|
|
422
421
|
theme: 'dark',
|
|
423
|
-
showLineNumbers: true,
|
|
424
422
|
activePanel: 'settings',
|
|
425
423
|
});
|
|
426
424
|
render(<TagSchemasPage {...props} />);
|
|
@@ -22,7 +22,6 @@ export interface TagSchemasPageProps {
|
|
|
22
22
|
|
|
23
23
|
// UI state
|
|
24
24
|
theme: 'light' | 'dark' | 'system';
|
|
25
|
-
showLineNumbers: boolean;
|
|
26
25
|
activePanel: string | null;
|
|
27
26
|
|
|
28
27
|
// Translations
|
|
@@ -54,7 +53,6 @@ export function TagSchemasPage({
|
|
|
54
53
|
schemas,
|
|
55
54
|
isLoading,
|
|
56
55
|
theme,
|
|
57
|
-
showLineNumbers,
|
|
58
56
|
activePanel,
|
|
59
57
|
translations: t,
|
|
60
58
|
ToolbarPanels,
|
|
@@ -153,7 +151,6 @@ export function TagSchemasPage({
|
|
|
153
151
|
<ToolbarPanels
|
|
154
152
|
activePanel={activePanel}
|
|
155
153
|
theme={theme}
|
|
156
|
-
showLineNumbers={showLineNumbers}
|
|
157
154
|
/>
|
|
158
155
|
|
|
159
156
|
<Toolbar
|
|
@@ -39,7 +39,6 @@ export interface LinkedDataPageProps {
|
|
|
39
39
|
|
|
40
40
|
// UI state
|
|
41
41
|
theme: 'light' | 'dark' | 'system';
|
|
42
|
-
showLineNumbers: boolean;
|
|
43
42
|
activePanel: string | null;
|
|
44
43
|
|
|
45
44
|
// Translations
|
|
@@ -63,7 +62,6 @@ export function LinkedDataPage({
|
|
|
63
62
|
importMessage,
|
|
64
63
|
importResult,
|
|
65
64
|
theme,
|
|
66
|
-
showLineNumbers,
|
|
67
65
|
activePanel,
|
|
68
66
|
translations: t,
|
|
69
67
|
ToolbarPanels,
|
|
@@ -109,7 +107,6 @@ export function LinkedDataPage({
|
|
|
109
107
|
<ToolbarPanels
|
|
110
108
|
activePanel={activePanel}
|
|
111
109
|
theme={theme}
|
|
112
|
-
showLineNumbers={showLineNumbers}
|
|
113
110
|
/>
|
|
114
111
|
<Toolbar
|
|
115
112
|
context="simple"
|
|
@@ -10,12 +10,14 @@ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
|
10
10
|
import { ResourceComposePage } from '../components/ResourceComposePage';
|
|
11
11
|
import type { ResourceComposePageProps } from '../components/ResourceComposePage';
|
|
12
12
|
import { createTestSemiontWrapper } from '../../../test-utils';
|
|
13
|
+
import { LineNumbersProvider } from '../../../contexts/LineNumbersContext';
|
|
13
14
|
|
|
14
15
|
// Mock CodeMirrorRenderer to avoid CodeMirror dependencies
|
|
15
16
|
vi.mock('../../../components/CodeMirrorRenderer', () => ({
|
|
16
|
-
CodeMirrorRenderer: ({ content, onChange, editable }: any) => (
|
|
17
|
+
CodeMirrorRenderer: ({ content, onChange, editable, showLineNumbers }: any) => (
|
|
17
18
|
<textarea
|
|
18
19
|
data-testid="code-editor"
|
|
20
|
+
data-line-numbers={String(showLineNumbers)}
|
|
19
21
|
value={content}
|
|
20
22
|
onChange={(e) => editable && onChange?.(e.target.value)}
|
|
21
23
|
disabled={!editable}
|
|
@@ -62,7 +64,6 @@ const createMockProps = (overrides?: Partial<ResourceComposePageProps>): Resourc
|
|
|
62
64
|
availableEntityTypes: ['Document', 'Article', 'Report'],
|
|
63
65
|
initialLocale: 'en',
|
|
64
66
|
theme: 'light',
|
|
65
|
-
showLineNumbers: false,
|
|
66
67
|
hoverDelayMs: 0,
|
|
67
68
|
activePanel: null,
|
|
68
69
|
onSaveResource: vi.fn().mockResolvedValue(undefined),
|
|
@@ -77,7 +78,11 @@ const createMockProps = (overrides?: Partial<ResourceComposePageProps>): Resourc
|
|
|
77
78
|
// component reaches for via useSemiont/useObservable).
|
|
78
79
|
const renderWithProviders = (ui: React.ReactElement) => {
|
|
79
80
|
const { SemiontWrapper } = createTestSemiontWrapper();
|
|
80
|
-
return render(
|
|
81
|
+
return render(
|
|
82
|
+
<LineNumbersProvider>
|
|
83
|
+
<SemiontWrapper>{ui}</SemiontWrapper>
|
|
84
|
+
</LineNumbersProvider>,
|
|
85
|
+
);
|
|
81
86
|
};
|
|
82
87
|
|
|
83
88
|
describe('ResourceComposePage', () => {
|
|
@@ -500,11 +505,16 @@ describe('ResourceComposePage', () => {
|
|
|
500
505
|
expect(editor.value).toBe('New content');
|
|
501
506
|
});
|
|
502
507
|
|
|
503
|
-
it('
|
|
504
|
-
|
|
505
|
-
|
|
508
|
+
it('feeds the editor the shared line-numbers setting from context', () => {
|
|
509
|
+
localStorage.setItem('showLineNumbers', 'true');
|
|
510
|
+
try {
|
|
511
|
+
const props = createMockProps({});
|
|
512
|
+
renderWithProviders(<ResourceComposePage {...props} />);
|
|
506
513
|
|
|
507
|
-
|
|
514
|
+
expect(screen.getByTestId('code-editor')).toHaveAttribute('data-line-numbers', 'true');
|
|
515
|
+
} finally {
|
|
516
|
+
localStorage.removeItem('showLineNumbers');
|
|
517
|
+
}
|
|
508
518
|
});
|
|
509
519
|
});
|
|
510
520
|
});
|
|
@@ -15,6 +15,7 @@ import { COMMON_PANELS, type ToolbarPanelType } from '../../../state/shell-state
|
|
|
15
15
|
import { buttonStyles } from '../../../lib/button-styles';
|
|
16
16
|
import { CodeMirrorRenderer } from '../../../components/CodeMirrorRenderer';
|
|
17
17
|
import { useFormAnnouncements } from '../../../components/LiveRegion';
|
|
18
|
+
import { useLineNumbers } from '../../../contexts/LineNumbersContext';
|
|
18
19
|
import { UploadProgressBar } from './UploadProgressBar';
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -54,7 +55,6 @@ export interface ResourceComposePageProps {
|
|
|
54
55
|
|
|
55
56
|
// UI state
|
|
56
57
|
theme: 'light' | 'dark';
|
|
57
|
-
showLineNumbers: boolean;
|
|
58
58
|
hoverDelayMs: number;
|
|
59
59
|
activePanel: string | null;
|
|
60
60
|
|
|
@@ -133,7 +133,6 @@ export function ResourceComposePage({
|
|
|
133
133
|
availableEntityTypes,
|
|
134
134
|
initialLocale,
|
|
135
135
|
theme,
|
|
136
|
-
showLineNumbers,
|
|
137
136
|
hoverDelayMs,
|
|
138
137
|
activePanel,
|
|
139
138
|
onSaveResource,
|
|
@@ -146,6 +145,10 @@ export function ResourceComposePage({
|
|
|
146
145
|
// Form announcements
|
|
147
146
|
const { announceFormSubmitting, announceFormSuccess, announceFormError } = useFormAnnouncements();
|
|
148
147
|
|
|
148
|
+
// Shared display setting (LineNumbersContext) — was a prop threaded from
|
|
149
|
+
// the route, which desynced it from the Settings toggle.
|
|
150
|
+
const { showLineNumbers } = useLineNumbers();
|
|
151
|
+
|
|
149
152
|
// Form state
|
|
150
153
|
const [newResourceName, setNewResourceName] = useState('');
|
|
151
154
|
const [newResourceContent, setNewResourceContent] = useState('');
|
|
@@ -746,7 +749,6 @@ export function ResourceComposePage({
|
|
|
746
749
|
<ToolbarPanels
|
|
747
750
|
activePanel={activePanel}
|
|
748
751
|
theme={theme}
|
|
749
|
-
showLineNumbers={showLineNumbers}
|
|
750
752
|
/>
|
|
751
753
|
|
|
752
754
|
{/* Toolbar - Always visible on the right */}
|
|
@@ -6,7 +6,7 @@ import { filter } from 'rxjs/operators';
|
|
|
6
6
|
import type { SemiontClient } from '@semiont/sdk';
|
|
7
7
|
import type { ShellStateUnit } from '../../../../state/shell-state-unit';
|
|
8
8
|
import { createComposePageStateUnit } from '../compose-page-state-unit';
|
|
9
|
-
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing';
|
|
9
|
+
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing/axioms';
|
|
10
10
|
|
|
11
11
|
/** Build an `UploadObservable`-shaped mock that emits started → finished. */
|
|
12
12
|
function mockUpload(resourceId: string) {
|
|
@@ -36,7 +36,6 @@ const createMockProps = (overrides?: Partial<ResourceDiscoveryPageProps>): Resou
|
|
|
36
36
|
selectedEntityType: '',
|
|
37
37
|
onSelectedEntityTypeChange: vi.fn(),
|
|
38
38
|
theme: 'light',
|
|
39
|
-
showLineNumbers: false,
|
|
40
39
|
activePanel: null,
|
|
41
40
|
onNavigateToResource: vi.fn(),
|
|
42
41
|
onNavigateToCompose: vi.fn(),
|
|
@@ -40,7 +40,6 @@ export interface ResourceDiscoveryPageProps {
|
|
|
40
40
|
|
|
41
41
|
// UI state props
|
|
42
42
|
theme: 'light' | 'dark';
|
|
43
|
-
showLineNumbers: boolean;
|
|
44
43
|
activePanel: string | null;
|
|
45
44
|
|
|
46
45
|
// Navigation props
|
|
@@ -86,7 +85,6 @@ export function ResourceDiscoveryPage({
|
|
|
86
85
|
selectedEntityType,
|
|
87
86
|
onSelectedEntityTypeChange,
|
|
88
87
|
theme,
|
|
89
|
-
showLineNumbers,
|
|
90
88
|
activePanel,
|
|
91
89
|
onNavigateToResource,
|
|
92
90
|
onNavigateToCompose,
|
|
@@ -286,7 +284,6 @@ export function ResourceDiscoveryPage({
|
|
|
286
284
|
<ToolbarPanels
|
|
287
285
|
activePanel={activePanel}
|
|
288
286
|
theme={theme}
|
|
289
|
-
showLineNumbers={showLineNumbers}
|
|
290
287
|
/>
|
|
291
288
|
|
|
292
289
|
{/* Toolbar - Always visible on the right */}
|
|
@@ -6,7 +6,7 @@ import { filter, skip, take, toArray } from 'rxjs/operators';
|
|
|
6
6
|
import type { SemiontClient } from '@semiont/sdk';
|
|
7
7
|
import type { ShellStateUnit } from '../../../../state/shell-state-unit';
|
|
8
8
|
import { createDiscoverStateUnit } from '../discover-state-unit';
|
|
9
|
-
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing';
|
|
9
|
+
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing/axioms';
|
|
10
10
|
|
|
11
11
|
function mockBrowse(): ShellStateUnit {
|
|
12
12
|
return { dispose: vi.fn() } as unknown as ShellStateUnit;
|
|
@@ -12,6 +12,7 @@ import { ResourceViewerPage } from '../components/ResourceViewerPage';
|
|
|
12
12
|
import type { ResourceViewerPageProps } from '../components/ResourceViewerPage';
|
|
13
13
|
import { ToastProvider } from '../../../components/Toast';
|
|
14
14
|
import { ThemeProvider } from '../../../contexts/ThemeContext';
|
|
15
|
+
import { LineNumbersProvider } from '../../../contexts/LineNumbersContext';
|
|
15
16
|
import { createTestSemiontWrapper } from '../../../test-utils';
|
|
16
17
|
import type { ResourceId } from '@semiont/core';
|
|
17
18
|
|
|
@@ -40,7 +41,7 @@ vi.mock('../../../hooks/useResourceContent', () => ({
|
|
|
40
41
|
// SemiontClient (wired to a dummy baseUrl). The real client surface lets
|
|
41
42
|
// createResourceViewerPageStateUnit run against the full namespace API without us
|
|
42
43
|
// hand-stubbing every method it touches.
|
|
43
|
-
const { stubBrowser } = vi.hoisted(() => {
|
|
44
|
+
const { stubBrowser, stubClient } = vi.hoisted(() => {
|
|
44
45
|
const { BehaviorSubject } = require('rxjs');
|
|
45
46
|
const { SemiontClient, HttpTransport, HttpContentTransport } = require('@semiont/sdk');
|
|
46
47
|
const { baseUrl } = require('@semiont/core');
|
|
@@ -62,7 +63,7 @@ const { stubBrowser } = vi.hoisted(() => {
|
|
|
62
63
|
on: vi.fn(() => () => {}),
|
|
63
64
|
stream: vi.fn(() => ({ subscribe: () => ({ unsubscribe: () => {} }) })),
|
|
64
65
|
};
|
|
65
|
-
return { stubBrowser };
|
|
66
|
+
return { stubBrowser, stubClient: client };
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
vi.mock('../../../session/SemiontProvider', async () => {
|
|
@@ -75,6 +76,8 @@ vi.mock('../../../session/SemiontProvider', async () => {
|
|
|
75
76
|
};
|
|
76
77
|
});
|
|
77
78
|
|
|
79
|
+
const capturedHistory = vi.hoisted(() => ({ props: null as any }));
|
|
80
|
+
|
|
78
81
|
vi.mock('@semiont/react-ui', async () => {
|
|
79
82
|
const actual = await vi.importActual('@semiont/react-ui');
|
|
80
83
|
return {
|
|
@@ -83,7 +86,10 @@ vi.mock('@semiont/react-ui', async () => {
|
|
|
83
86
|
Toolbar: () => <div data-testid="toolbar">Toolbar</div>,
|
|
84
87
|
ToolbarPanels: ({ children }: any) => <div data-testid="toolbar-panels">{children}</div>,
|
|
85
88
|
UnifiedAnnotationsPanel: () => <div data-testid="annotations-panel">Annotations</div>,
|
|
86
|
-
AnnotationHistory: () =>
|
|
89
|
+
AnnotationHistory: (props: any) => {
|
|
90
|
+
capturedHistory.props = props;
|
|
91
|
+
return <div data-testid="history-panel">History</div>;
|
|
92
|
+
},
|
|
87
93
|
ResourceInfoPanel: () => <div data-testid="info-panel">Info</div>,
|
|
88
94
|
CollaborationPanel: () => <div data-testid="collaboration-panel">Collaboration</div>,
|
|
89
95
|
JsonLdPanel: () => <div data-testid="jsonld-panel">JSON-LD</div>,
|
|
@@ -163,11 +169,13 @@ const renderWithProviders = (ui: React.ReactElement) => {
|
|
|
163
169
|
const { SemiontWrapper } = createTestSemiontWrapper();
|
|
164
170
|
return render(
|
|
165
171
|
<ThemeProvider>
|
|
166
|
-
<
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
<LineNumbersProvider>
|
|
173
|
+
<ToastProvider>
|
|
174
|
+
<SemiontWrapper>
|
|
175
|
+
{ui}
|
|
176
|
+
</SemiontWrapper>
|
|
177
|
+
</ToastProvider>
|
|
178
|
+
</LineNumbersProvider>
|
|
171
179
|
</ThemeProvider>
|
|
172
180
|
);
|
|
173
181
|
};
|
|
@@ -225,6 +233,30 @@ describe('ResourceViewerPage', () => {
|
|
|
225
233
|
localStorage.clear();
|
|
226
234
|
});
|
|
227
235
|
|
|
236
|
+
it('clicking a history event focuses that annotation in the content', () => {
|
|
237
|
+
// ASSIST-SURFACE-WARTS Lane D. `handleEventClick` used to be a no-op with
|
|
238
|
+
// a stale comment, while HistoryEvent still rendered a focusable button
|
|
239
|
+
// labelled "View annotation" — a promise to screen-reader users that
|
|
240
|
+
// nothing kept. `beckon:focus` is the existing "scroll to and highlight"
|
|
241
|
+
// contract (BrowseView already subscribes); this makes the page a producer.
|
|
242
|
+
localStorage.setItem('activeToolbarPanel', 'history');
|
|
243
|
+
capturedHistory.props = null;
|
|
244
|
+
const props = createMockProps();
|
|
245
|
+
renderWithProviders(<ResourceViewerPage {...props} />);
|
|
246
|
+
|
|
247
|
+
expect(capturedHistory.props).not.toBeNull();
|
|
248
|
+
|
|
249
|
+
const focused: Array<string | null> = [];
|
|
250
|
+
const sub = stubClient.bus.get('beckon:focus').subscribe(({ annotationId }: any) => focused.push(annotationId));
|
|
251
|
+
|
|
252
|
+
expect(capturedHistory.props?.onEventClick).toBeTypeOf('function');
|
|
253
|
+
capturedHistory.props!.onEventClick('ann-42');
|
|
254
|
+
expect(focused).toEqual(['ann-42']);
|
|
255
|
+
|
|
256
|
+
sub.unsubscribe();
|
|
257
|
+
localStorage.clear();
|
|
258
|
+
});
|
|
259
|
+
|
|
228
260
|
it('shows history panel when activePanel is history', () => {
|
|
229
261
|
localStorage.setItem('activeToolbarPanel', 'history');
|
|
230
262
|
const props = createMockProps();
|
|
@@ -24,10 +24,11 @@ import type { BrowseMediaRenderers, AnnotateMediaRenderers } from '@semiont/reac
|
|
|
24
24
|
import { useObservable } from '@semiont/react-ui';
|
|
25
25
|
import { useResourceContent } from '../../../hooks/useResourceContent';
|
|
26
26
|
import { useMediaToken } from '../../../hooks/useMediaToken';
|
|
27
|
+
import { mediaUrl } from '../../../lib/media-url';
|
|
27
28
|
import { useToast } from '../../../components/Toast';
|
|
28
29
|
import { useOutcomeToasts } from '../../../hooks/useOutcomeToasts';
|
|
29
30
|
import { useTheme } from '../../../contexts/ThemeContext';
|
|
30
|
-
import { useLineNumbers } from '../../../
|
|
31
|
+
import { useLineNumbers } from '../../../contexts/LineNumbersContext';
|
|
31
32
|
import { useHoverDelay } from '../../../hooks/useHoverDelay';
|
|
32
33
|
import { useEventSubscriptions } from '../../../contexts/useEventSubscription';
|
|
33
34
|
import { useObservableExternalNavigation } from '../../../hooks/useObservableBrowse';
|
|
@@ -116,8 +117,6 @@ export interface ResourceViewerPageProps {
|
|
|
116
117
|
* @subscribes yield:clone - Clone the current resource
|
|
117
118
|
* @subscribes beckon:sparkle - Trigger sparkle animation
|
|
118
119
|
* @subscribes mark:added - Annotation was created (sparkle)
|
|
119
|
-
* @subscribes settings:theme-changed - UI theme changed
|
|
120
|
-
* @subscribes settings:line-numbers-toggled - Line numbers display toggled
|
|
121
120
|
* @subscribes browse:reference-navigate - Navigate to a referenced document
|
|
122
121
|
* @subscribes browse:entity-type-clicked - Navigate filtered by entity type
|
|
123
122
|
*
|
|
@@ -141,6 +140,7 @@ export function ResourceViewerPage({
|
|
|
141
140
|
// Translations
|
|
142
141
|
const tw = useTranslations('ReferenceWizard');
|
|
143
142
|
const tg = useTranslations('ResourceGenerate');
|
|
143
|
+
const ta = useTranslations('AssistProgress');
|
|
144
144
|
|
|
145
145
|
const browser = useSemiont();
|
|
146
146
|
const session = useObservable(browser.activeSession$);
|
|
@@ -159,8 +159,8 @@ export function ResourceViewerPage({
|
|
|
159
159
|
|
|
160
160
|
// UI state hooks
|
|
161
161
|
const { showError, showSuccess } = useToast();
|
|
162
|
-
const { theme
|
|
163
|
-
const { showLineNumbers
|
|
162
|
+
const { theme } = useTheme();
|
|
163
|
+
const { showLineNumbers } = useLineNumbers();
|
|
164
164
|
const { hoverDelayMs } = useHoverDelay();
|
|
165
165
|
const { triggerSparkleAnimation, clearNewAnnotationId, newAnnotationIds } = useResourceAnnotations();
|
|
166
166
|
|
|
@@ -187,9 +187,7 @@ export function ResourceViewerPage({
|
|
|
187
187
|
|
|
188
188
|
// Binary path: fetch short-lived media token, construct URL
|
|
189
189
|
const { token: mediaToken, loading: mediaTokenLoading } = useMediaToken(semiont ?? null, rUri);
|
|
190
|
-
const binaryContent = (isBinary
|
|
191
|
-
? `${semiont.baseUrl}/api/resources/${rUri}?token=${mediaToken}`
|
|
192
|
-
: '';
|
|
190
|
+
const binaryContent = (isBinary ? mediaUrl(semiont, rUri, mediaToken) : undefined) ?? '';
|
|
193
191
|
|
|
194
192
|
const content = isBinary ? binaryContent : textContent;
|
|
195
193
|
const contentLoading = isBinary ? mediaTokenLoading : textLoading;
|
|
@@ -380,8 +378,6 @@ export function ResourceViewerPage({
|
|
|
380
378
|
triggerSparkleAnimation(stored.payload.annotation.id);
|
|
381
379
|
}, [triggerSparkleAnimation]);
|
|
382
380
|
|
|
383
|
-
const handleSettingsThemeChanged = useCallback(({ theme }: { theme: any }) => setTheme(theme), [setTheme]);
|
|
384
|
-
|
|
385
381
|
const handleReferenceNavigate = useCallback(({ resourceId }: { resourceId: string }) => {
|
|
386
382
|
if (routes.resourceDetail) {
|
|
387
383
|
const path = routes.resourceDetail(resourceId);
|
|
@@ -411,8 +407,6 @@ export function ResourceViewerPage({
|
|
|
411
407
|
'yield:clone': handleResourceClone,
|
|
412
408
|
'beckon:sparkle': handleAnnotationSparkle,
|
|
413
409
|
'mark:added': handleAnnotationAdded,
|
|
414
|
-
'settings:theme-changed': handleSettingsThemeChanged,
|
|
415
|
-
'settings:line-numbers-toggled': toggleLineNumbers,
|
|
416
410
|
'browse:reference-navigate': handleReferenceNavigate,
|
|
417
411
|
'browse:entity-type-clicked': handleEntityTypeClicked,
|
|
418
412
|
});
|
|
@@ -450,9 +444,17 @@ export function ResourceViewerPage({
|
|
|
450
444
|
}
|
|
451
445
|
}, [session]);
|
|
452
446
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
447
|
+
// Clicking a history row reveals that annotation in the content. HistoryEvent
|
|
448
|
+
// renders these rows as buttons labelled "View annotation", so this used to be
|
|
449
|
+
// a focusable, screen-reader-announced control wired to a no-op.
|
|
450
|
+
// `beckon:focus` is the existing "scroll to and highlight" contract rather
|
|
451
|
+
// than a new prop chain — BrowseView already subscribed to it, AnnotateView
|
|
452
|
+
// now does too. See .plans/ASSIST-SURFACE-WARTS.md Lane D.
|
|
453
|
+
const handleEventClick = useCallback((id: string | null) => {
|
|
454
|
+
if (id) {
|
|
455
|
+
stateUnit?.beckon.focus(annotationId(id));
|
|
456
|
+
}
|
|
457
|
+
}, [stateUnit]);
|
|
456
458
|
|
|
457
459
|
// Document rendering
|
|
458
460
|
return (
|
|
@@ -481,6 +483,9 @@ export function ResourceViewerPage({
|
|
|
481
483
|
inProgress: tg('progressInProgress'),
|
|
482
484
|
complete: tg('progressComplete'),
|
|
483
485
|
failed: tg('progressFailed'),
|
|
486
|
+
paramsTitle: ta('paramsTitle'),
|
|
487
|
+
processing: (label) => ta('processing', { label }),
|
|
488
|
+
close: ta('close'),
|
|
484
489
|
}}
|
|
485
490
|
/>
|
|
486
491
|
)}
|
|
@@ -542,7 +547,6 @@ export function ResourceViewerPage({
|
|
|
542
547
|
<ToolbarPanels
|
|
543
548
|
activePanel={activePanel}
|
|
544
549
|
theme={theme}
|
|
545
|
-
showLineNumbers={showLineNumbers}
|
|
546
550
|
width={
|
|
547
551
|
activePanel === 'jsonld' ? 'w-[600px]' :
|
|
548
552
|
activePanel === 'annotations' ? 'w-[400px]' :
|
|
@@ -6,7 +6,7 @@ import { filter } from 'rxjs/operators';
|
|
|
6
6
|
import { resourceId as makeResourceId } from '@semiont/core';
|
|
7
7
|
import type { SemiontClient } from '@semiont/sdk';
|
|
8
8
|
import { createResourceLoaderStateUnit } from '../resource-loader-state-unit';
|
|
9
|
-
import { assertStateUnitAxioms } from '@semiont/core/testing';
|
|
9
|
+
import { assertStateUnitAxioms } from '@semiont/core/testing/axioms';
|
|
10
10
|
|
|
11
11
|
const RID = makeResourceId('res-1');
|
|
12
12
|
|
package/src/features/resource-viewer/state/__tests__/resource-viewer-page-state-unit.test.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { filter } from 'rxjs/operators';
|
|
|
5
5
|
import { annotationId, resourceId as makeResourceId } from '@semiont/core';
|
|
6
6
|
import type { ShellStateUnit } from '../../../../state/shell-state-unit';
|
|
7
7
|
import { createResourceViewerPageStateUnit, type ResourceViewerPageStateUnit } from '../resource-viewer-page-state-unit';
|
|
8
|
-
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing';
|
|
8
|
+
import { assertStateUnitAxioms, disposeProbe } from '@semiont/core/testing/axioms';
|
|
9
9
|
import { makeTestSession, type TestSession } from '../../../../__tests__/test-client';
|
|
10
10
|
|
|
11
11
|
const RID = makeResourceId('res-1');
|
|
@@ -10,7 +10,7 @@ import { createGatherStateUnit, type GatherStateUnit } from '@semiont/sdk';
|
|
|
10
10
|
import { createMatchStateUnit } from '@semiont/sdk';
|
|
11
11
|
import { createYieldStateUnit, type YieldStateUnit } from '@semiont/sdk';
|
|
12
12
|
import type { SemiontSession } from '@semiont/sdk';
|
|
13
|
-
import { decodeWithCharset, textExtractionOf } from '@semiont/core';
|
|
13
|
+
import { decodeWithCharset, textExtractionOf, uuidV4 } from '@semiont/core';
|
|
14
14
|
import { groupAnnotations } from '../../../lib/annotation-groups';
|
|
15
15
|
import type { ReferencedByEntry } from '@semiont/sdk';
|
|
16
16
|
|
|
@@ -144,7 +144,7 @@ export function createResourceViewerPageStateUnit(
|
|
|
144
144
|
entityTypes: event.entityTypes,
|
|
145
145
|
});
|
|
146
146
|
client.bus.get('gather:requested').next({
|
|
147
|
-
correlationId:
|
|
147
|
+
correlationId: uuidV4(),
|
|
148
148
|
annotationId: event.annotationId,
|
|
149
149
|
resourceId: event.resourceId,
|
|
150
150
|
options: { contextWindow: 2000 },
|
package/translations/ar.json
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
+
"AssistProgress": {
|
|
3
|
+
"close": "إغلاق",
|
|
4
|
+
"paramsTitle": "معاملات الطلب:",
|
|
5
|
+
"processing": "الحالي: {{label}}"
|
|
6
|
+
},
|
|
2
7
|
"Toolbar": {
|
|
3
8
|
"annotations": "التعليقات التوضيحية",
|
|
4
9
|
"history": "السجل",
|
|
@@ -105,7 +110,9 @@
|
|
|
105
110
|
"densityDense": "كثيف",
|
|
106
111
|
"fragmentSelected": "تم تحديد جزء",
|
|
107
112
|
"imageRegionSelected": "تم تحديد منطقة من الصورة",
|
|
108
|
-
"
|
|
113
|
+
"complete": "اكتمل التوضيح!",
|
|
114
|
+
"failed": "فشل التوضيح",
|
|
115
|
+
"densityPerWords": "{{density}} لكل 2000 كلمة"
|
|
109
116
|
},
|
|
110
117
|
"HighlightPanel": {
|
|
111
118
|
"title": "التمييزات",
|
|
@@ -120,7 +127,9 @@
|
|
|
120
127
|
"densityLabel": "الكثافة",
|
|
121
128
|
"densitySparse": "متفرق",
|
|
122
129
|
"densityDense": "كثيف",
|
|
123
|
-
"
|
|
130
|
+
"complete": "اكتمل التوضيح!",
|
|
131
|
+
"failed": "فشل التوضيح",
|
|
132
|
+
"densityPerWords": "{{density}} لكل 2000 كلمة"
|
|
124
133
|
},
|
|
125
134
|
"AssessmentPanel": {
|
|
126
135
|
"title": "التقييمات",
|
|
@@ -145,7 +154,9 @@
|
|
|
145
154
|
"densityDense": "كثيف",
|
|
146
155
|
"fragmentSelected": "تم تحديد جزء",
|
|
147
156
|
"imageRegionSelected": "تم تحديد منطقة من الصورة",
|
|
148
|
-
"
|
|
157
|
+
"complete": "اكتمل التوضيح!",
|
|
158
|
+
"failed": "فشل التوضيح",
|
|
159
|
+
"densityPerWords": "{{density}} لكل 2000 كلمة"
|
|
149
160
|
},
|
|
150
161
|
"TaggingPanel": {
|
|
151
162
|
"title": "العلامات",
|
|
@@ -164,7 +175,9 @@
|
|
|
164
175
|
"selectCategory": "اختيار الفئة",
|
|
165
176
|
"chooseCategory": "اختر فئة...",
|
|
166
177
|
"fragmentSelected": "تم تحديد جزء",
|
|
167
|
-
"imageRegionSelected": "تم تحديد منطقة من الصورة"
|
|
178
|
+
"imageRegionSelected": "تم تحديد منطقة من الصورة",
|
|
179
|
+
"complete": "اكتمل التوضيح!",
|
|
180
|
+
"failed": "فشل التوضيح"
|
|
168
181
|
},
|
|
169
182
|
"UnifiedAnnotationsPanel": {
|
|
170
183
|
"title": "التعليقات التوضيحية",
|
|
@@ -220,7 +233,6 @@
|
|
|
220
233
|
"complete": "اكتمل التوضيح!",
|
|
221
234
|
"failed": "فشل التوضيح",
|
|
222
235
|
"current": "الحالي: {{entityType}}",
|
|
223
|
-
"closeProgress": "إغلاق",
|
|
224
236
|
"loading": "جارٍ التحميل...",
|
|
225
237
|
"loadingEllipsis": "جارٍ التحميل...",
|
|
226
238
|
"untitledResource": "مورد بدون عنوان",
|
package/translations/bn.json
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
+
"AssistProgress": {
|
|
3
|
+
"close": "বন্ধ করুন",
|
|
4
|
+
"paramsTitle": "অনুরোধের প্যারামিটার:",
|
|
5
|
+
"processing": "বর্তমান: {{label}}"
|
|
6
|
+
},
|
|
2
7
|
"Toolbar": {
|
|
3
8
|
"annotations": "টীকাসমূহ",
|
|
4
9
|
"history": "ইতিহাস",
|
|
@@ -105,7 +110,9 @@
|
|
|
105
110
|
"densityDense": "ঘন",
|
|
106
111
|
"fragmentSelected": "অংশ নির্বাচিত",
|
|
107
112
|
"imageRegionSelected": "ছবির অঞ্চল নির্বাচিত",
|
|
108
|
-
"
|
|
113
|
+
"complete": "টীকাকরণ সম্পূর্ণ!",
|
|
114
|
+
"failed": "টীকাকরণ ব্যর্থ",
|
|
115
|
+
"densityPerWords": "প্রতি ২০০০ শব্দে {{density}}"
|
|
109
116
|
},
|
|
110
117
|
"HighlightPanel": {
|
|
111
118
|
"title": "হাইলাইটসমূহ",
|
|
@@ -120,7 +127,9 @@
|
|
|
120
127
|
"densityLabel": "ঘনত্ব",
|
|
121
128
|
"densitySparse": "বিরল",
|
|
122
129
|
"densityDense": "ঘন",
|
|
123
|
-
"
|
|
130
|
+
"complete": "টীকাকরণ সম্পূর্ণ!",
|
|
131
|
+
"failed": "টীকাকরণ ব্যর্থ",
|
|
132
|
+
"densityPerWords": "প্রতি ২০০০ শব্দে {{density}}"
|
|
124
133
|
},
|
|
125
134
|
"AssessmentPanel": {
|
|
126
135
|
"title": "মূল্যায়নসমূহ",
|
|
@@ -145,7 +154,9 @@
|
|
|
145
154
|
"densityDense": "ঘন",
|
|
146
155
|
"fragmentSelected": "অংশ নির্বাচিত",
|
|
147
156
|
"imageRegionSelected": "ছবির অঞ্চল নির্বাচিত",
|
|
148
|
-
"
|
|
157
|
+
"complete": "টীকাকরণ সম্পূর্ণ!",
|
|
158
|
+
"failed": "টীকাকরণ ব্যর্থ",
|
|
159
|
+
"densityPerWords": "প্রতি ২০০০ শব্দে {{density}}"
|
|
149
160
|
},
|
|
150
161
|
"TaggingPanel": {
|
|
151
162
|
"title": "ট্যাগসমূহ",
|
|
@@ -164,7 +175,9 @@
|
|
|
164
175
|
"selectCategory": "বিভাগ নির্বাচন করুন",
|
|
165
176
|
"chooseCategory": "একটি বিভাগ বেছে নিন...",
|
|
166
177
|
"fragmentSelected": "অংশ নির্বাচিত",
|
|
167
|
-
"imageRegionSelected": "ছবির অঞ্চল নির্বাচিত"
|
|
178
|
+
"imageRegionSelected": "ছবির অঞ্চল নির্বাচিত",
|
|
179
|
+
"complete": "টীকাকরণ সম্পূর্ণ!",
|
|
180
|
+
"failed": "টীকাকরণ ব্যর্থ"
|
|
168
181
|
},
|
|
169
182
|
"UnifiedAnnotationsPanel": {
|
|
170
183
|
"title": "টীকাসমূহ",
|
|
@@ -220,7 +233,6 @@
|
|
|
220
233
|
"complete": "টীকাকরণ সম্পূর্ণ!",
|
|
221
234
|
"failed": "টীকাকরণ ব্যর্থ",
|
|
222
235
|
"current": "বর্তমান: {{entityType}}",
|
|
223
|
-
"closeProgress": "বন্ধ করুন",
|
|
224
236
|
"loading": "লোড হচ্ছে...",
|
|
225
237
|
"loadingEllipsis": "লোড হচ্ছে...",
|
|
226
238
|
"untitledResource": "শিরোনামবিহীন সম্পদ",
|