@searpent/react-image-annotate 2.3.5 → 2.3.6
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/Annotator/index.js
CHANGED
|
@@ -85,7 +85,8 @@ export var Annotator = function Annotator(_ref) {
|
|
|
85
85
|
save = _ref$save === void 0 ? function () {} : _ref$save,
|
|
86
86
|
_ref$fetchImage = _ref.fetchImage,
|
|
87
87
|
fetchImage = _ref$fetchImage === void 0 ? function () {} : _ref$fetchImage,
|
|
88
|
-
updatedBy = _ref.updatedBy
|
|
88
|
+
updatedBy = _ref.updatedBy,
|
|
89
|
+
mediaPresenterLeaseUntil = _ref.mediaPresenterLeaseUntil;
|
|
89
90
|
|
|
90
91
|
if (typeof selectedImage === "string") {
|
|
91
92
|
selectedImage = (images || []).findIndex(function (img) {
|
|
@@ -447,7 +448,8 @@ export var Annotator = function Annotator(_ref) {
|
|
|
447
448
|
onMetadataChange: handleMetadataChange,
|
|
448
449
|
onAddGroup: handleAddGroup,
|
|
449
450
|
onRecalcClick: handleRecalcClicked,
|
|
450
|
-
updatedBy: updatedBy
|
|
451
|
+
updatedBy: updatedBy,
|
|
452
|
+
mediaPresenterLeaseUntil: mediaPresenterLeaseUntil
|
|
451
453
|
}))
|
|
452
454
|
);
|
|
453
455
|
};
|
package/MainLayout/index.js
CHANGED
|
@@ -134,7 +134,8 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
134
134
|
onMetadataChange = _ref5.onMetadataChange,
|
|
135
135
|
onAddGroup = _ref5.onAddGroup,
|
|
136
136
|
onRecalcClick = _ref5.onRecalcClick,
|
|
137
|
-
updatedBy = _ref5.updatedBy
|
|
137
|
+
updatedBy = _ref5.updatedBy,
|
|
138
|
+
mediaPresenterLeaseUntil = _ref5.mediaPresenterLeaseUntil;
|
|
138
139
|
var classes = useStyles();
|
|
139
140
|
var settings = useSettings();
|
|
140
141
|
var fullScreenHandle = useFullScreenHandle();
|
|
@@ -377,7 +378,8 @@ export var MainLayout = function MainLayout(_ref5) {
|
|
|
377
378
|
onMetadataChange: onMetadataChange,
|
|
378
379
|
metadataConfigs: state.metadataConfigs || [],
|
|
379
380
|
onRecalcClick: onRecalcClick,
|
|
380
|
-
updatedBy: updatedBy
|
|
381
|
+
updatedBy: updatedBy,
|
|
382
|
+
mediaPresenterLeaseUntil: mediaPresenterLeaseUntil
|
|
381
383
|
}),
|
|
382
384
|
/*#__PURE__*/
|
|
383
385
|
React.createElement(WorkspaceWrapper, null,
|
|
@@ -1,29 +1,74 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
3
3
|
export function isUpdatedByAggregator(updatedBy) {
|
|
4
4
|
if (updatedBy == null) return false;
|
|
5
5
|
return String(updatedBy).trim() === "AGGREGATOR";
|
|
6
6
|
}
|
|
7
|
+
/** Non-empty lease string or null (treat undefined / "" / whitespace as no lock). */
|
|
8
|
+
|
|
9
|
+
export function normalizeMediaPresenterLeaseUntil(raw) {
|
|
10
|
+
if (raw == null) return null;
|
|
11
|
+
var s = String(raw).trim();
|
|
12
|
+
return s === "" ? null : s;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* True when Dynamo `mediaPresenterLeaseUntil` (ISO UTC string) is still in the future.
|
|
16
|
+
* Matches the media-presenter webhook lease written by BasicLinkingFunction.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export function isMediaPresenterLockActive(mediaPresenterLeaseUntil) {
|
|
20
|
+
var s = normalizeMediaPresenterLeaseUntil(mediaPresenterLeaseUntil);
|
|
21
|
+
if (s == null) return false;
|
|
22
|
+
var t = Date.parse(s);
|
|
23
|
+
if (Number.isNaN(t)) return false;
|
|
24
|
+
return t > Date.now();
|
|
25
|
+
}
|
|
7
26
|
/**
|
|
8
27
|
* Case-level “UPDATED BY” indicator for the page strip (left panel).
|
|
9
|
-
* Red (left) / green (right) discs, left-aligned with the page-strip switch column;
|
|
10
|
-
* Green lit only when
|
|
28
|
+
* Red (left) / green (right) discs, left-aligned with the page-strip switch column; status label after them.
|
|
29
|
+
* Green lit only when `updatedBy` is exactly AGGREGATOR and the media-presenter Dynamo lease is not active.
|
|
11
30
|
* `selectionKey` should change per selected page so the control remounts when paging.
|
|
12
31
|
*/
|
|
13
32
|
|
|
14
33
|
export default function UpdatedBySemaphore(_ref) {
|
|
15
34
|
var updatedBy = _ref.updatedBy,
|
|
35
|
+
mediaPresenterLeaseUntil = _ref.mediaPresenterLeaseUntil,
|
|
16
36
|
selectionKey = _ref.selectionKey;
|
|
17
|
-
var
|
|
37
|
+
var leaseStr = useMemo(function () {
|
|
38
|
+
return normalizeMediaPresenterLeaseUntil(mediaPresenterLeaseUntil);
|
|
39
|
+
}, [mediaPresenterLeaseUntil]); // While a lease string is present, re-evaluate every second so expiry clears without a parent refetch.
|
|
40
|
+
|
|
41
|
+
var _useState = useState(0),
|
|
42
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
43
|
+
setLeasePulse = _useState2[1];
|
|
44
|
+
|
|
45
|
+
useEffect(function () {
|
|
46
|
+
if (leaseStr == null) return undefined;
|
|
47
|
+
var id = window.setInterval(function () {
|
|
48
|
+
return setLeasePulse(function (n) {
|
|
49
|
+
return n + 1;
|
|
50
|
+
});
|
|
51
|
+
}, 1000);
|
|
52
|
+
return function () {
|
|
53
|
+
return window.clearInterval(id);
|
|
54
|
+
};
|
|
55
|
+
}, [leaseStr]);
|
|
56
|
+
var lockActive = isMediaPresenterLockActive(leaseStr);
|
|
57
|
+
var green = isUpdatedByAggregator(updatedBy) && !lockActive;
|
|
18
58
|
var source = updatedBy == null || updatedBy === "" ? "—" : String(updatedBy);
|
|
59
|
+
var leaseHint = lockActive ? " Media presenter lock active (lease until ".concat(leaseStr, ").") : "";
|
|
60
|
+
var statusLabel = green ? "Ready" : "Do not modify";
|
|
61
|
+
var title = "Case last updated by: ".concat(source, ".").concat(leaseHint, " Status: ").concat(statusLabel, ". Green lamp: safe to modify (AGGREGATOR and no active media-presenter lease). Red lamp: do not modify (other updater and/or lock).");
|
|
62
|
+
var redClass = "ps-semaphore-lamp ps-semaphore-red" + (green ? "" : " ps-semaphore-lit");
|
|
63
|
+
var greenClass = "ps-semaphore-lamp ps-semaphore-green" + (green ? " ps-semaphore-lit" : "");
|
|
19
64
|
return (
|
|
20
65
|
/*#__PURE__*/
|
|
21
66
|
React.createElement("div", {
|
|
22
|
-
key: selectionKey,
|
|
67
|
+
key: "".concat(selectionKey, "|").concat(leaseStr !== null && leaseStr !== void 0 ? leaseStr : ""),
|
|
23
68
|
className: "ps-updated-by-semaphore",
|
|
24
|
-
title:
|
|
69
|
+
title: title,
|
|
25
70
|
role: "img",
|
|
26
|
-
"aria-label":
|
|
71
|
+
"aria-label": statusLabel
|
|
27
72
|
},
|
|
28
73
|
/*#__PURE__*/
|
|
29
74
|
React.createElement("span", {
|
|
@@ -36,19 +81,15 @@ export default function UpdatedBySemaphore(_ref) {
|
|
|
36
81
|
},
|
|
37
82
|
/*#__PURE__*/
|
|
38
83
|
React.createElement("span", {
|
|
39
|
-
className:
|
|
40
|
-
"ps-semaphore-lit": !green
|
|
41
|
-
})
|
|
84
|
+
className: redClass
|
|
42
85
|
}),
|
|
43
86
|
/*#__PURE__*/
|
|
44
87
|
React.createElement("span", {
|
|
45
|
-
className:
|
|
46
|
-
"ps-semaphore-lit": green
|
|
47
|
-
})
|
|
88
|
+
className: greenClass
|
|
48
89
|
}))),
|
|
49
90
|
/*#__PURE__*/
|
|
50
91
|
React.createElement("span", {
|
|
51
92
|
className: "ps-top-bar-label ps-updated-by-semaphore__label"
|
|
52
|
-
},
|
|
93
|
+
}, statusLabel))
|
|
53
94
|
);
|
|
54
95
|
}
|
package/PageSelector/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import classnames from "classnames";
|
|
|
4
4
|
import './page-selector.css';
|
|
5
5
|
import Locker from '../Locker';
|
|
6
6
|
import Errorer from '../Errorer';
|
|
7
|
-
import UpdatedBySemaphore from './UpdatedBySemaphore';
|
|
7
|
+
import UpdatedBySemaphore, { normalizeMediaPresenterLeaseUntil } from './UpdatedBySemaphore';
|
|
8
8
|
|
|
9
9
|
function PageThumbnail(_ref) {
|
|
10
10
|
var _metadata$find, _metadata$find$call;
|
|
@@ -148,6 +148,12 @@ function isLocked(page) {
|
|
|
148
148
|
return false;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
function showUpdatedBySemaphore(updatedBy, mediaPresenterLeaseUntil) {
|
|
152
|
+
if (updatedBy !== undefined && updatedBy !== null) return true;
|
|
153
|
+
if (normalizeMediaPresenterLeaseUntil(mediaPresenterLeaseUntil) != null) return true;
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
151
157
|
function PageSelector(_ref3) {
|
|
152
158
|
var _ref4, _ref5;
|
|
153
159
|
|
|
@@ -156,7 +162,8 @@ function PageSelector(_ref3) {
|
|
|
156
162
|
onMetadataChange = _ref3.onMetadataChange,
|
|
157
163
|
metadataConfigs = _ref3.metadataConfigs,
|
|
158
164
|
onRecalcClick = _ref3.onRecalcClick,
|
|
159
|
-
updatedBy = _ref3.updatedBy
|
|
165
|
+
updatedBy = _ref3.updatedBy,
|
|
166
|
+
mediaPresenterLeaseUntil = _ref3.mediaPresenterLeaseUntil;
|
|
160
167
|
|
|
161
168
|
var _useState = useState(false),
|
|
162
169
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -208,7 +215,7 @@ function PageSelector(_ref3) {
|
|
|
208
215
|
/*#__PURE__*/
|
|
209
216
|
React.createElement("label", {
|
|
210
217
|
className: "ps-top-bar-label"
|
|
211
|
-
}, "Metadata")), updatedBy
|
|
218
|
+
}, "Metadata")), showUpdatedBySemaphore(updatedBy, mediaPresenterLeaseUntil) &&
|
|
212
219
|
/*#__PURE__*/
|
|
213
220
|
React.createElement("div", {
|
|
214
221
|
className: "ps-semaphore-below-metadata"
|
|
@@ -216,6 +223,7 @@ function PageSelector(_ref3) {
|
|
|
216
223
|
/*#__PURE__*/
|
|
217
224
|
React.createElement(UpdatedBySemaphore, {
|
|
218
225
|
updatedBy: updatedBy,
|
|
226
|
+
mediaPresenterLeaseUntil: mediaPresenterLeaseUntil,
|
|
219
227
|
selectionKey: selectionKey
|
|
220
228
|
})))),
|
|
221
229
|
/*#__PURE__*/
|
|
@@ -185,9 +185,9 @@
|
|
|
185
185
|
flex-shrink: 0;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
/* Inactive
|
|
188
|
+
/* Inactive lamps read as “off” (neutral); lit lamp pops. */
|
|
189
189
|
.ps-semaphore-lamp:not(.ps-semaphore-lit) {
|
|
190
|
-
opacity: 0.
|
|
190
|
+
opacity: 0.88;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
.ps-semaphore-lamp.ps-semaphore-lit {
|
|
@@ -195,13 +195,14 @@
|
|
|
195
195
|
transform: scale(1.02);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
/*
|
|
199
|
-
.ps-semaphore-red
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
/* Off state: neutral gray so only the lit lamp reads as red/green (traffic-light style). */
|
|
199
|
+
.ps-semaphore-red:not(.ps-semaphore-lit),
|
|
200
|
+
.ps-semaphore-green:not(.ps-semaphore-lit) {
|
|
201
|
+
background: linear-gradient(165deg, #ececec 0%, #d4d4d4 45%, #bdbdbd 100%);
|
|
202
|
+
border-color: rgba(0, 0, 0, 0.12);
|
|
202
203
|
box-shadow:
|
|
203
|
-
inset 0 2px
|
|
204
|
-
inset 0 -2px
|
|
204
|
+
inset 0 2px 4px rgba(255, 255, 255, 0.55),
|
|
205
|
+
inset 0 -2px 5px rgba(0, 0, 0, 0.1);
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
.ps-semaphore-red.ps-semaphore-lit {
|
|
@@ -212,15 +213,6 @@
|
|
|
212
213
|
inset 0 -2px 5px rgba(0, 0, 0, 0.18);
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
/* Inactive green: soft mint / dusty green */
|
|
216
|
-
.ps-semaphore-green {
|
|
217
|
-
background: linear-gradient(165deg, #dff2df 0%, #b8dcb8 45%, #92c592 100%);
|
|
218
|
-
border-color: rgba(80, 140, 80, 0.35);
|
|
219
|
-
box-shadow:
|
|
220
|
-
inset 0 2px 5px rgba(255, 255, 255, 0.4),
|
|
221
|
-
inset 0 -2px 6px rgba(60, 120, 60, 0.18);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
216
|
.ps-semaphore-green.ps-semaphore-lit {
|
|
225
217
|
background: linear-gradient(180deg, #b9f6ca 0%, #00e676 40%, #00c853 100%);
|
|
226
218
|
border-color: rgba(200, 255, 220, 0.9);
|