Skip to content

Commit e5df003

Browse files
authored
Refactor Redaction Examples (#172)
1 parent 3fa7b88 commit e5df003

File tree

7 files changed

+179
-0
lines changed

7 files changed

+179
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import type {
2+
AnnotationTooltipCallback,
3+
Instance,
4+
RedactionAnnotation,
5+
} from "@nutrient-sdk/viewer";
6+
import { baseOptions } from "../../shared/base-options";
7+
8+
let instance: Instance | null = null;
9+
10+
const getAllAnnotations = async () => {
11+
if (!instance)
12+
return window.NutrientViewer.Immutable.List<RedactionAnnotation>();
13+
14+
let annotationsList =
15+
window.NutrientViewer.Immutable.List<RedactionAnnotation>();
16+
17+
for (let i = 0; i < instance.totalPageCount; i++) {
18+
const anns = (await instance.getAnnotations(i)).filter(
19+
(a): a is RedactionAnnotation =>
20+
a instanceof window.NutrientViewer.Annotations.RedactionAnnotation,
21+
);
22+
annotationsList = annotationsList.concat(anns);
23+
}
24+
return annotationsList;
25+
};
26+
27+
const redactionAnnotationsHandlerCallback: AnnotationTooltipCallback = (
28+
annotation,
29+
) =>
30+
annotation instanceof window.NutrientViewer.Annotations.RedactionAnnotation
31+
? [
32+
{
33+
type: "custom",
34+
title: "Accept",
35+
id: "tooltip-accept-annotation",
36+
className: "TooltipItem-Duplication",
37+
onPress: async () => {
38+
if (!instance) return;
39+
40+
const allRedactionAnnotations = (await getAllAnnotations()).filter(
41+
(a) => a.id !== annotation.id,
42+
);
43+
44+
await instance.delete(allRedactionAnnotations);
45+
await instance.applyRedactions();
46+
await instance.create(allRedactionAnnotations);
47+
},
48+
},
49+
{
50+
type: "custom",
51+
title: "Reject",
52+
id: "tooltip-reject-annotation",
53+
className: "TooltipItem-Duplication",
54+
onPress: async () => {
55+
if (!instance) return;
56+
instance.delete(annotation);
57+
},
58+
},
59+
]
60+
: [];
61+
62+
window.NutrientViewer.load({
63+
...baseOptions,
64+
theme: window.NutrientViewer.Theme.DARK,
65+
enableAutomaticLinkExtraction: true,
66+
annotationTooltipCallback: redactionAnnotationsHandlerCallback,
67+
toolbarItems: [
68+
...window.NutrientViewer.defaultToolbarItems,
69+
{ type: "redact-rectangle" },
70+
{ type: "redact-text-highlighter" },
71+
],
72+
}).then((_instance) => {
73+
instance = _instance;
74+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: redaction
3+
title: Apply or Reject Redactions via Tooltip
4+
description: Adds custom tooltip options to accept or reject individual redaction annotations, allowing selective redaction of document content.
5+
keywords: [redaction, tooltip, accept, reject, annotations, custom-tooltip]
6+
---
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* Add your CSS here */
2+
.custom-toolbar-item {
3+
height: 100%;
4+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { RedactionAnnotation, TextLine } from "@nutrient-sdk/viewer";
2+
import { baseOptions } from "../../shared/base-options";
3+
4+
const REDACTION_CONFIG = {
5+
color: window.NutrientViewer.Color.RED,
6+
overlayText: "REDACTED",
7+
};
8+
9+
function createRedactionFromTextLine(textLine: TextLine) {
10+
const { boundingBox, pageIndex } = textLine;
11+
12+
return new window.NutrientViewer.Annotations.RedactionAnnotation({
13+
id: window.NutrientViewer.generateInstantId(),
14+
pageIndex,
15+
boundingBox,
16+
rects: window.NutrientViewer.Immutable.List([boundingBox]),
17+
...REDACTION_CONFIG,
18+
});
19+
}
20+
21+
window.NutrientViewer.load({
22+
...baseOptions,
23+
theme: window.NutrientViewer.Theme.DARK,
24+
}).then(async (instance) => {
25+
const pageIndices = Array.from({ length: instance.totalPageCount });
26+
27+
const allPagesTextLines = await Promise.all(
28+
pageIndices.map((_, index) => instance.textLinesForPageIndex(index)),
29+
);
30+
31+
const redactionAnnotations = allPagesTextLines.flatMap((pageTextLines) =>
32+
pageTextLines.reduce<RedactionAnnotation[]>(
33+
(annotations, textLine) => [
34+
...annotations,
35+
createRedactionFromTextLine(textLine),
36+
],
37+
[],
38+
),
39+
);
40+
41+
await instance.create(redactionAnnotations);
42+
await instance.applyRedactions();
43+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: redaction
3+
title: Overlay Redactions on All Text
4+
description: Creates redactions with an overlay text for every text line in the document and applies them to fully redact all text content.
5+
keywords: [redaction, overlay, text-lines, full-document, batch-redaction]
6+
---
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { baseOptions } from "../../shared/base-options";
2+
3+
const SENSITIVE_DATA = {
4+
places: ["Koram", "NomSao", "Uganda", "Ngogo", "Thailand", "Myanmar"],
5+
names: [
6+
"Lydia V Luncz",
7+
"Amanda Tan",
8+
"Michael Haslam",
9+
"Lars Kulik",
10+
"Tomos Proffitt",
11+
"Suchinda Malaivijitnond",
12+
"Michael Gumert",
13+
],
14+
};
15+
16+
const REDACTION_SEARCH_OPTIONS = {
17+
searchType: window.NutrientViewer.SearchType.TEXT,
18+
searchInAnnotations: false,
19+
caseSensitive: false,
20+
startPageIndex: 0,
21+
} as const;
22+
23+
window.NutrientViewer.load({
24+
...baseOptions,
25+
theme: window.NutrientViewer.Theme.DARK,
26+
}).then(async (instance) => {
27+
await Promise.all(
28+
SENSITIVE_DATA.places.map((place) =>
29+
instance.createRedactionsBySearch(place, REDACTION_SEARCH_OPTIONS),
30+
),
31+
);
32+
33+
await Promise.all(
34+
SENSITIVE_DATA.names.map((name) =>
35+
instance.createRedactionsBySearch(name, REDACTION_SEARCH_OPTIONS),
36+
),
37+
);
38+
39+
await instance.applyRedactions();
40+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: redaction
3+
title: Redact Keywords Programmatically
4+
description: Automatically searches for and redacts sensitive information like place names and personal names using the createRedactionsBySearch API.
5+
keywords: [redaction, search, keywords, sensitive-data, batch-redaction, programmatic]
6+
---

0 commit comments

Comments
 (0)