girder-large-image 1.22.3.dev18__tar.gz → 1.22.3.dev26__tar.gz
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.
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/PKG-INFO +1 -1
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/rest/tiles.py +8 -0
- girder-large-image-1.22.3.dev26/girder_large_image/web_client/stylesheets/metadataWidget.styl +5 -0
- girder-large-image-1.22.3.dev26/girder_large_image/web_client/templates/metadataWidget.pug +22 -0
- girder-large-image-1.22.3.dev26/girder_large_image/web_client/templates/metadatumEditWidget.pug +30 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/configView.js +4 -4
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/index.js +3 -1
- girder-large-image-1.22.3.dev26/girder_large_image/web_client/views/metadataWidget.js +672 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/PKG-INFO +1 -1
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/SOURCES.txt +4 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/requires.txt +2 -2
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_tiles_rest.py +13 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/LICENSE +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/README.rst +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/__init__.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/constants.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/girder_tilesource.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/loadmodelcache.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/models/__init__.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/models/image_item.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/rest/__init__.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/rest/large_image_resource.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/eventStream.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/extra/.gitignore +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/index.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/main.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/package.json +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/routes.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/fileList.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/imageViewerSelectWidget.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/itemList.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/itemView.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/itemViewCodemirror.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/stylesheets/largeImageConfig.styl +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/imageViewerSelectWidget.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/itemList.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/itemView.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/itemViewCodemirror.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/largeImageConfig.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/templates/largeImage_fileAction.pug +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/fileList.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerSelectWidget.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/base.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/geojs.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/index.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/leaflet.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/openlayers.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/openseadragon.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/setFrameQuad.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/itemList.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/itemView.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/itemViewCodemirror.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/views/itemViewWidget.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/vue/colors.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/vue/components/CompositeLayers.vue +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/vue/components/DualInput.vue +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/vue/components/FrameSelector.vue +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/web_client/webpack.helper.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/dependency_links.txt +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/entry_points.txt +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/not-zip-safe +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image.egg-info/top_level.txt +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/setup.cfg +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/setup.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/__init__.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/conftest.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/girder_utilities.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_large_image.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_web_client.py +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/web_client_specs/.eslintrc +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/web_client_specs/imageViewerSpec.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/web_client_specs/largeImageSpec.js +0 -0
- {girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/web_client_specs/otherFeatures.js +0 -0
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/rest/tiles.py
RENAMED
|
@@ -985,6 +985,10 @@ class TilesItemResource(ItemResource):
|
|
|
985
985
|
.param('rangeMax', 'The maximum value in the histogram. Defaults to '
|
|
986
986
|
'the maximum value in the image.',
|
|
987
987
|
required=False, dataType='float')
|
|
988
|
+
.param('roundRange', 'If true and neither a minimum or maximum is '
|
|
989
|
+
'specified for the range, round the bin edges and adjust the '
|
|
990
|
+
'number of bins for integer data with smaller ranges.',
|
|
991
|
+
required=False, dataType='boolean', default=False)
|
|
988
992
|
.param('density', 'If true, scale the results by the number of '
|
|
989
993
|
'samples.', required=False, dataType='boolean', default=False)
|
|
990
994
|
.errorResponse('ID was invalid.')
|
|
@@ -1020,12 +1024,16 @@ class TilesItemResource(ItemResource):
|
|
|
1020
1024
|
('bins', int),
|
|
1021
1025
|
('rangeMin', int),
|
|
1022
1026
|
('rangeMax', int),
|
|
1027
|
+
('roundRange', bool),
|
|
1023
1028
|
('density', bool),
|
|
1024
1029
|
])
|
|
1025
1030
|
_handleETag('getHistogram', item, params)
|
|
1026
1031
|
histRange = None
|
|
1027
1032
|
if 'rangeMin' in params or 'rangeMax' in params:
|
|
1028
1033
|
histRange = [params.pop('rangeMin', 0), params.pop('rangeMax', 256)]
|
|
1034
|
+
if params.get('roundRange'):
|
|
1035
|
+
if params.pop('roundRange', False) and histRange is None:
|
|
1036
|
+
histRange = 'round'
|
|
1029
1037
|
result = self.imageItemModel.histogram(item, range=histRange, **params)
|
|
1030
1038
|
result = result['histogram']
|
|
1031
1039
|
# Cast everything to lists and floats so json with encode properly
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
if (accessLevel >= AccessType.WRITE)
|
|
2
|
+
.btn-group.pull-right
|
|
3
|
+
button.g-widget-metadata-add-button.btn.btn-sm.btn-primary.btn-default.dropdown-toggle(data-toggle="dropdown", title="Add Metadata")
|
|
4
|
+
i.icon-plus
|
|
5
|
+
ul.dropdown-menu.pull-right(role="menu")
|
|
6
|
+
if limetadata
|
|
7
|
+
for entry in limetadata
|
|
8
|
+
if entry && entry.value
|
|
9
|
+
li.li-metadata-menuitem(role="presentation")
|
|
10
|
+
a.li-add-metadata(metadata-key=entry.value)
|
|
11
|
+
= entry.title || entry.value
|
|
12
|
+
li(role="presentation")
|
|
13
|
+
a.g-add-simple-metadata(role="menuitem")
|
|
14
|
+
| Simple
|
|
15
|
+
li(role="presentation")
|
|
16
|
+
a.g-add-json-metadata
|
|
17
|
+
| JSON
|
|
18
|
+
|
|
19
|
+
.g-widget-metadata-header
|
|
20
|
+
i.icon-tags
|
|
21
|
+
| #{title}
|
|
22
|
+
.g-widget-metadata-container
|
girder-large-image-1.22.3.dev26/girder_large_image/web_client/templates/metadatumEditWidget.pug
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
if !lientry
|
|
2
|
+
input.input-sm.form-control.g-widget-metadata-key-input(type="text", value=key, placeholder="Key")
|
|
3
|
+
else
|
|
4
|
+
span.g-widget-metadata-key-edit.g-widget-metadata-key-input(key=key)
|
|
5
|
+
= lientry.title || key
|
|
6
|
+
|
|
7
|
+
if !lientry
|
|
8
|
+
- var rows = value.length <= 40 ? 1 : (value.length <= 100 ? 3 : 5)
|
|
9
|
+
textarea.input-sm.form-control.g-widget-metadata-value-input(placeholder="Value", rows=rows)
|
|
10
|
+
= value
|
|
11
|
+
else
|
|
12
|
+
if lientry.enum
|
|
13
|
+
select.input-sm.form-control.g-widget-metadata-value-input.g-widget-metadata-lientry(title=lientry.description)
|
|
14
|
+
for enumval in lientry.enum
|
|
15
|
+
option(value=enumval, selected=enumval === value ? 'selected' : null)
|
|
16
|
+
= enumval
|
|
17
|
+
else
|
|
18
|
+
input.input-sm.form-control.g-widget-metadata-value-input.g-widget-metadata-lientry(placeholder=lientry.description || "Value", value=value, title=lientry.description)
|
|
19
|
+
|
|
20
|
+
button.btn.btn-sm.btn-warning.g-widget-metadata-cancel-button(title="Cancel")
|
|
21
|
+
i.icon-cancel
|
|
22
|
+
button.btn.btn-sm.btn-primary.g-widget-metadata-save-button(title="Accept")
|
|
23
|
+
i.icon-ok
|
|
24
|
+
if !newDatum
|
|
25
|
+
if !lientry
|
|
26
|
+
button.btn.btn-sm.btn-primary.g-widget-metadata-toggle-button(title="Convert to JSON")
|
|
27
|
+
i.icon-cog
|
|
28
|
+
if !lientry || !lientry.required
|
|
29
|
+
button.btn.btn-sm.btn-danger.g-widget-metadata-delete-button(title="Delete")
|
|
30
|
+
i.icon-trash
|
|
@@ -247,15 +247,15 @@ var ConfigView = View.extend({
|
|
|
247
247
|
}
|
|
248
248
|
if (ConfigView._lastliconfig === folderId && !reload) {
|
|
249
249
|
if (callback) {
|
|
250
|
-
callback(ConfigView._liconfig);
|
|
250
|
+
callback(ConfigView._liconfig || {});
|
|
251
251
|
}
|
|
252
252
|
return $.Deferred().resolve(ConfigView._liconfig);
|
|
253
253
|
}
|
|
254
254
|
if (ConfigView._liconfigSettingsRequest) {
|
|
255
255
|
if (ConfigView._nextliconfig === folderId) {
|
|
256
256
|
if (callback) {
|
|
257
|
-
ConfigView._liconfigSettingsRequest.done(() => {
|
|
258
|
-
callback(
|
|
257
|
+
ConfigView._liconfigSettingsRequest.done((val) => {
|
|
258
|
+
callback(val || {});
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
return ConfigView._liconfigSettingsRequest;
|
|
@@ -269,7 +269,7 @@ var ConfigView = View.extend({
|
|
|
269
269
|
val = val || {};
|
|
270
270
|
ConfigView._lastliconfig = folderId;
|
|
271
271
|
ConfigView._liconfigSettingsRequest = null;
|
|
272
|
-
ConfigView._liconfig = val
|
|
272
|
+
ConfigView._liconfig = val;
|
|
273
273
|
if (callback) {
|
|
274
274
|
callback(ConfigView._liconfig);
|
|
275
275
|
}
|
|
@@ -2,10 +2,12 @@ import ConfigView from './configView';
|
|
|
2
2
|
import ImageViewerSelectWidget from './imageViewerSelectWidget';
|
|
3
3
|
import * as imageViewerWidget from './imageViewerWidget';
|
|
4
4
|
import ItemViewWidget from './itemViewWidget';
|
|
5
|
+
import * as MetadataWidget from './metadataWidget';
|
|
5
6
|
|
|
6
7
|
export {
|
|
7
8
|
ConfigView,
|
|
8
9
|
ImageViewerSelectWidget,
|
|
9
10
|
imageViewerWidget,
|
|
10
|
-
ItemViewWidget
|
|
11
|
+
ItemViewWidget,
|
|
12
|
+
MetadataWidget
|
|
11
13
|
};
|
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
import $ from 'jquery';
|
|
2
|
+
import {wrap} from '@girder/core/utilities/PluginUtils';
|
|
3
|
+
|
|
4
|
+
import _ from 'underscore';
|
|
5
|
+
|
|
6
|
+
import View from '@girder/core/views/View';
|
|
7
|
+
import {AccessType} from '@girder/core/constants';
|
|
8
|
+
import {confirm} from '@girder/core/dialog';
|
|
9
|
+
import events from '@girder/core/events';
|
|
10
|
+
import {localeSort} from '@girder/core/misc';
|
|
11
|
+
|
|
12
|
+
import JsonMetadatumEditWidgetTemplate from '@girder/core/templates/widgets/jsonMetadatumEditWidget.pug';
|
|
13
|
+
|
|
14
|
+
import MetadatumViewTemplate from '@girder/core/templates/widgets/metadatumView.pug';
|
|
15
|
+
|
|
16
|
+
import '@girder/core/stylesheets/widgets/metadataWidget.styl';
|
|
17
|
+
|
|
18
|
+
import JSONEditor from 'jsoneditor/dist/jsoneditor.js'; // can't 'jsoneditor'
|
|
19
|
+
import 'jsoneditor/dist/jsoneditor.css';
|
|
20
|
+
|
|
21
|
+
import 'bootstrap/js/dropdown';
|
|
22
|
+
|
|
23
|
+
import MetadataWidget from '@girder/core/views/widgets/MetadataWidget';
|
|
24
|
+
|
|
25
|
+
import '../stylesheets/metadataWidget.styl';
|
|
26
|
+
import MetadataWidgetTemplate from '../templates/metadataWidget.pug';
|
|
27
|
+
import MetadatumEditWidgetTemplate from '../templates/metadatumEditWidget.pug';
|
|
28
|
+
import largeImageConfig from './configView';
|
|
29
|
+
|
|
30
|
+
function getMetadataRecord(item, fieldName) {
|
|
31
|
+
if (item[fieldName]) {
|
|
32
|
+
return item[fieldName];
|
|
33
|
+
}
|
|
34
|
+
let meta = item.attributes;
|
|
35
|
+
fieldName.split('.').forEach((part) => {
|
|
36
|
+
if (!meta[part]) {
|
|
37
|
+
meta[part] = {};
|
|
38
|
+
}
|
|
39
|
+
meta = meta[part];
|
|
40
|
+
});
|
|
41
|
+
return meta;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function liMetadataKeyEntry(limetadata, key) {
|
|
45
|
+
if (!limetadata || !key) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
let result;
|
|
49
|
+
limetadata.forEach((entry, idx) => {
|
|
50
|
+
if (entry.value === key) {
|
|
51
|
+
result = entry;
|
|
52
|
+
result.idx = idx;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var MetadatumWidget = View.extend({
|
|
59
|
+
className: 'g-widget-metadata-row',
|
|
60
|
+
|
|
61
|
+
events: {
|
|
62
|
+
'click .g-widget-metadata-edit-button': 'editMetadata'
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
initialize: function (settings) {
|
|
66
|
+
if (!_.has(this.parentView.modes, settings.mode)) {
|
|
67
|
+
throw new Error('Unsupported metadatum mode ' + settings.mode + ' detected.');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.mode = settings.mode;
|
|
71
|
+
this.key = settings.key;
|
|
72
|
+
this.value = settings.value;
|
|
73
|
+
this.accessLevel = settings.accessLevel;
|
|
74
|
+
this.parentView = settings.parentView;
|
|
75
|
+
this.fieldName = settings.fieldName;
|
|
76
|
+
this.apiPath = settings.apiPath;
|
|
77
|
+
this.noSave = settings.noSave;
|
|
78
|
+
this.limetadata = settings.limetadata;
|
|
79
|
+
this.onMetadataEdited = settings.onMetadataEdited;
|
|
80
|
+
this.onMetadataAdded = settings.onMetadataAdded;
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
_validate: function (from, to, value) {
|
|
84
|
+
var newMode = this.parentView.modes[to];
|
|
85
|
+
|
|
86
|
+
if (_.has(newMode, 'validation') &&
|
|
87
|
+
_.has(newMode.validation, 'from') &&
|
|
88
|
+
_.has(newMode.validation.from, from)) {
|
|
89
|
+
var validate = newMode.validation.from[from][0];
|
|
90
|
+
var msg = newMode.validation.from[from][1];
|
|
91
|
+
|
|
92
|
+
if (!validate(value)) {
|
|
93
|
+
events.trigger('g:alert', {
|
|
94
|
+
text: msg,
|
|
95
|
+
type: 'warning'
|
|
96
|
+
});
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// @todo too much duplication with editMetadata
|
|
105
|
+
toggleEditor: function (event, newEditorMode, existingEditor, overrides) {
|
|
106
|
+
var fromEditorMode = (existingEditor instanceof JsonMetadatumEditWidget) ? 'json' : 'simple';
|
|
107
|
+
var newValue = (overrides || {}).value || existingEditor.$el.attr('g-value');
|
|
108
|
+
if (!this._validate(fromEditorMode, newEditorMode, newValue)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
var row = existingEditor.$el;
|
|
113
|
+
existingEditor.destroy();
|
|
114
|
+
row.addClass('editing').empty();
|
|
115
|
+
|
|
116
|
+
var opts = _.extend({
|
|
117
|
+
el: row,
|
|
118
|
+
item: this.parentView.item,
|
|
119
|
+
key: row.attr('g-key'),
|
|
120
|
+
value: row.attr('g-value'),
|
|
121
|
+
accessLevel: this.accessLevel,
|
|
122
|
+
newDatum: false,
|
|
123
|
+
parentView: this,
|
|
124
|
+
fieldName: this.fieldName,
|
|
125
|
+
apiPath: this.apiPath,
|
|
126
|
+
noSave: this.noSave,
|
|
127
|
+
limetadata: this.limetadata,
|
|
128
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
129
|
+
onMetadataAdded: this.onMetadataAdded
|
|
130
|
+
}, overrides || {});
|
|
131
|
+
|
|
132
|
+
this.parentView.modes[newEditorMode].editor(opts).render();
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
editMetadata: function (event) {
|
|
136
|
+
this.$el.addClass('editing');
|
|
137
|
+
this.$el.empty();
|
|
138
|
+
|
|
139
|
+
var opts = {
|
|
140
|
+
item: this.parentView.item,
|
|
141
|
+
key: this.$el.attr('g-key'),
|
|
142
|
+
value: this.$el.attr('g-value'),
|
|
143
|
+
accessLevel: this.accessLevel,
|
|
144
|
+
newDatum: false,
|
|
145
|
+
parentView: this,
|
|
146
|
+
fieldName: this.fieldName,
|
|
147
|
+
apiPath: this.apiPath,
|
|
148
|
+
noSave: this.noSave,
|
|
149
|
+
limetadata: this.limetadata,
|
|
150
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
151
|
+
onMetadataAdded: this.onMetadataAdded
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// If they're trying to open false, null, 6, etc which are not stored as strings
|
|
155
|
+
if (this.mode === 'json') {
|
|
156
|
+
try {
|
|
157
|
+
var jsonValue = JSON.parse(this.$el.attr('g-value'));
|
|
158
|
+
|
|
159
|
+
if (jsonValue !== undefined && !_.isObject(jsonValue)) {
|
|
160
|
+
opts.value = jsonValue;
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this.parentView.modes[this.mode].editor(opts)
|
|
166
|
+
.render()
|
|
167
|
+
.$el.appendTo(this.$el);
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
render: function () {
|
|
171
|
+
this.$el.attr({
|
|
172
|
+
'g-key': this.key,
|
|
173
|
+
'g-value': _.bind(this.parentView.modes[this.mode].displayValue, this)()
|
|
174
|
+
}).empty();
|
|
175
|
+
this.$el.removeClass('editing');
|
|
176
|
+
this.$el.html(this.parentView.modes[this.mode].template({
|
|
177
|
+
key: this.mode === 'key' && liMetadataKeyEntry(this.limetadata, this.key) ? liMetadataKeyEntry(this.limetadata, this.key).title || this.key : this.key,
|
|
178
|
+
value: _.bind(this.parentView.modes[this.mode].displayValue, this)(),
|
|
179
|
+
accessLevel: this.accessLevel,
|
|
180
|
+
AccessType
|
|
181
|
+
}));
|
|
182
|
+
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
var MetadatumEditWidget = View.extend({
|
|
188
|
+
events: {
|
|
189
|
+
'click .g-widget-metadata-cancel-button': 'cancelEdit',
|
|
190
|
+
'click .g-widget-metadata-save-button': 'save',
|
|
191
|
+
'click .g-widget-metadata-delete-button': 'deleteMetadatum',
|
|
192
|
+
'click .g-widget-metadata-toggle-button': function (event) {
|
|
193
|
+
var editorType;
|
|
194
|
+
// @todo modal
|
|
195
|
+
// in the future this event will have the new editorType (assuming a dropdown)
|
|
196
|
+
if (this instanceof JsonMetadatumEditWidget) {
|
|
197
|
+
editorType = 'simple';
|
|
198
|
+
} else {
|
|
199
|
+
editorType = 'json';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this.parentView.toggleEditor(event, editorType, this, {
|
|
203
|
+
// Save state before toggling editor
|
|
204
|
+
key: this.$el.find('.g-widget-metadata-key-input').val(),
|
|
205
|
+
value: this.getCurrentValue()
|
|
206
|
+
});
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
initialize: function (settings) {
|
|
212
|
+
this.item = settings.item;
|
|
213
|
+
this.key = settings.key || '';
|
|
214
|
+
this.fieldName = settings.fieldName || 'meta';
|
|
215
|
+
this.value = (settings.value !== undefined) ? settings.value : '';
|
|
216
|
+
this.accessLevel = settings.accessLevel;
|
|
217
|
+
this.newDatum = settings.newDatum;
|
|
218
|
+
this.fieldName = settings.fieldName;
|
|
219
|
+
this.apiPath = settings.apiPath;
|
|
220
|
+
this.noSave = settings.noSave;
|
|
221
|
+
this.limetadata = settings.limetadata;
|
|
222
|
+
this.onMetadataEdited = settings.onMetadataEdited;
|
|
223
|
+
this.onMetadataAdded = settings.onMetadataAdded;
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
editTemplate: MetadatumEditWidgetTemplate,
|
|
227
|
+
|
|
228
|
+
getCurrentValue: function () {
|
|
229
|
+
return this.$el.find('.g-widget-metadata-value-input').val();
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
deleteMetadatum: function (event) {
|
|
233
|
+
event.stopImmediatePropagation();
|
|
234
|
+
const target = $(event.currentTarget);
|
|
235
|
+
var metadataList = target.parent().parent();
|
|
236
|
+
if (this.noSave) {
|
|
237
|
+
delete getMetadataRecord(this.item, this.fieldName)[this.key];
|
|
238
|
+
metadataList.remove();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
var params = {
|
|
242
|
+
text: 'Are you sure you want to delete the metadatum <b>' +
|
|
243
|
+
_.escape(this.key) + '</b>?',
|
|
244
|
+
escapedHtml: true,
|
|
245
|
+
yesText: 'Delete',
|
|
246
|
+
confirmCallback: () => {
|
|
247
|
+
this.item.removeMetadata(this.key, function () {
|
|
248
|
+
metadataList.remove();
|
|
249
|
+
this.parentView.parentView.trigger('li-metadata-widget-update', {});
|
|
250
|
+
}, null, {
|
|
251
|
+
field: this.fieldName,
|
|
252
|
+
path: this.apiPath
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
confirm(params);
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
cancelEdit: function (event) {
|
|
260
|
+
event.stopImmediatePropagation();
|
|
261
|
+
const target = $(event.currentTarget);
|
|
262
|
+
var curRow = target.parent().parent();
|
|
263
|
+
if (this.newDatum) {
|
|
264
|
+
curRow.remove();
|
|
265
|
+
} else {
|
|
266
|
+
this.parentView.render();
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
save: function (event, value) {
|
|
271
|
+
event.stopImmediatePropagation();
|
|
272
|
+
const target = $(event.currentTarget);
|
|
273
|
+
var curRow = target.parent(),
|
|
274
|
+
tempKey = curRow.find('.g-widget-metadata-key-input').val().trim() || curRow.find('.g-widget-metadata-key-input').attr('key'),
|
|
275
|
+
keyMode = curRow.find('.g-widget-metadata-key-input').attr('key'),
|
|
276
|
+
tempValue = (value !== undefined) ? value : curRow.find('.g-widget-metadata-value-input').val();
|
|
277
|
+
|
|
278
|
+
if (this.newDatum && tempKey === '') {
|
|
279
|
+
events.trigger('g:alert', {
|
|
280
|
+
text: 'A key is required for all metadata.',
|
|
281
|
+
type: 'warning'
|
|
282
|
+
});
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const lientry = keyMode ? liMetadataKeyEntry(this.limetadata, this.key) : undefined;
|
|
286
|
+
if (keyMode && lientry) {
|
|
287
|
+
tempValue = tempValue.trim();
|
|
288
|
+
}
|
|
289
|
+
if (lientry && lientry.regex && !(new RegExp(lientry.regex).exec(tempValue))) {
|
|
290
|
+
events.trigger('g:alert', {
|
|
291
|
+
text: 'The value does not match the required format.',
|
|
292
|
+
type: 'warning'
|
|
293
|
+
});
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
if (lientry && (lientry.type === 'number' || lientry.type === 'integer')) {
|
|
297
|
+
if (!Number.isFinite(parseFloat(tempValue)) || (lientry.type === 'integer' && !Number.isInteger(parseFloat(tempValue)))) {
|
|
298
|
+
events.trigger('g:alert', {
|
|
299
|
+
text: `The value must be a ${lientry.type}.`,
|
|
300
|
+
type: 'warning'
|
|
301
|
+
});
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
tempValue = parseFloat(tempValue);
|
|
305
|
+
if ((lientry.minimum !== undefined && tempValue < lientry.minimum) ||
|
|
306
|
+
(lientry.exclusiveMinimum !== undefined && tempValue <= lientry.exclusiveMinimum) ||
|
|
307
|
+
(lientry.maximum !== undefined && tempValue > lientry.maximum) ||
|
|
308
|
+
(lientry.exclusiveMaximum !== undefined && tempValue >= lientry.exclusiveMaximum)) {
|
|
309
|
+
events.trigger('g:alert', {
|
|
310
|
+
text: 'The value is outside of the allowed range.',
|
|
311
|
+
type: 'warning'
|
|
312
|
+
});
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
var saveCallback = () => {
|
|
318
|
+
this.key = tempKey;
|
|
319
|
+
this.value = tempValue;
|
|
320
|
+
|
|
321
|
+
this.parentView.key = this.key;
|
|
322
|
+
this.parentView.value = this.value;
|
|
323
|
+
|
|
324
|
+
if (keyMode) {
|
|
325
|
+
this.parentView.mode = 'key';
|
|
326
|
+
} else if (this instanceof JsonMetadatumEditWidget) {
|
|
327
|
+
this.parentView.mode = 'json';
|
|
328
|
+
} else {
|
|
329
|
+
this.parentView.mode = 'simple';
|
|
330
|
+
}
|
|
331
|
+
// event to re-render metadata panel header when metadata is edited
|
|
332
|
+
this.parentView.parentView.trigger('li-metadata-widget-update', {});
|
|
333
|
+
this.parentView.render();
|
|
334
|
+
|
|
335
|
+
this.newDatum = false;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
var errorCallback = function (out) {
|
|
339
|
+
events.trigger('g:alert', {
|
|
340
|
+
text: out.message,
|
|
341
|
+
type: 'danger'
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
if (this.newDatum) {
|
|
346
|
+
if (this.onMetadataAdded) {
|
|
347
|
+
this.onMetadataAdded(tempKey, tempValue, saveCallback, errorCallback);
|
|
348
|
+
} else {
|
|
349
|
+
if (this.noSave) {
|
|
350
|
+
if (getMetadataRecord(this.item, this.fieldName)[tempKey] !== undefined) {
|
|
351
|
+
events.trigger('g:alert', {
|
|
352
|
+
text: tempKey + ' is already a metadata key',
|
|
353
|
+
type: 'warning'
|
|
354
|
+
});
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
getMetadataRecord(this.item, this.fieldName)[tempKey] = tempValue;
|
|
358
|
+
this.parentView.parentView.render();
|
|
359
|
+
}
|
|
360
|
+
this.item.addMetadata(tempKey, tempValue, saveCallback, errorCallback, {
|
|
361
|
+
field: this.fieldName,
|
|
362
|
+
path: this.apiPath
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
if (this.onMetadataEdited) {
|
|
367
|
+
this.onMetadataEdited(tempKey, this.key, tempValue, saveCallback, errorCallback);
|
|
368
|
+
} else {
|
|
369
|
+
if (this.noSave) {
|
|
370
|
+
tempKey = tempKey === '' ? this.key : tempKey;
|
|
371
|
+
if (tempKey !== this.key && getMetadataRecord(this.item, this.fieldName)[tempKey] !== undefined) {
|
|
372
|
+
events.trigger('g:alert', {
|
|
373
|
+
text: tempKey + ' is already a metadata key',
|
|
374
|
+
type: 'warning'
|
|
375
|
+
});
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
delete getMetadataRecord(this.item, this.fieldName)[this.key];
|
|
379
|
+
getMetadataRecord(this.item, this.fieldName)[tempKey] = tempValue;
|
|
380
|
+
this.parentView.parentView.render();
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
this.item.editMetadata(tempKey, this.key, tempValue, saveCallback, errorCallback, {
|
|
384
|
+
field: this.fieldName,
|
|
385
|
+
path: this.apiPath
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
render: function () {
|
|
392
|
+
this.$el.html(this.editTemplate({
|
|
393
|
+
item: this.item,
|
|
394
|
+
lientry: liMetadataKeyEntry(this.limetadata, this.key),
|
|
395
|
+
key: this.key,
|
|
396
|
+
value: this.value,
|
|
397
|
+
accessLevel: this.accessLevel,
|
|
398
|
+
newDatum: this.newDatum,
|
|
399
|
+
AccessType
|
|
400
|
+
}));
|
|
401
|
+
this.$el.find('.g-widget-metadata-key-input').trigger('focus');
|
|
402
|
+
|
|
403
|
+
return this;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
var JsonMetadatumEditWidget = MetadatumEditWidget.extend({
|
|
408
|
+
editTemplate: JsonMetadatumEditWidgetTemplate,
|
|
409
|
+
|
|
410
|
+
getCurrentValue: function () {
|
|
411
|
+
return this.editor.getText();
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
save: function (event) {
|
|
415
|
+
try {
|
|
416
|
+
return MetadatumEditWidget.prototype.save.call(
|
|
417
|
+
this, event, this.editor.get());
|
|
418
|
+
} catch (err) {
|
|
419
|
+
events.trigger('g:alert', {
|
|
420
|
+
text: 'The field contains invalid JSON and can not be saved.',
|
|
421
|
+
type: 'warning'
|
|
422
|
+
});
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
render: function () {
|
|
428
|
+
MetadatumEditWidget.prototype.render.apply(this, arguments);
|
|
429
|
+
|
|
430
|
+
const jsonEditorEl = this.$el.find('.g-json-editor');
|
|
431
|
+
this.editor = new JSONEditor(jsonEditorEl[0], {
|
|
432
|
+
mode: 'tree',
|
|
433
|
+
modes: ['code', 'tree'],
|
|
434
|
+
onError: () => {
|
|
435
|
+
events.trigger('g:alert', {
|
|
436
|
+
text: 'The field contains invalid JSON and can not be viewed in Tree Mode.',
|
|
437
|
+
type: 'warning'
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
if (this.value !== undefined) {
|
|
443
|
+
this.editor.setText(JSON.stringify(this.value));
|
|
444
|
+
this.editor.expandAll();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
wrap(MetadataWidget, 'initialize', function (initialize, settings) {
|
|
452
|
+
try {
|
|
453
|
+
initialize.call(this, settings);
|
|
454
|
+
} catch (err) {
|
|
455
|
+
}
|
|
456
|
+
this.noSave = settings.noSave;
|
|
457
|
+
if (this.item && this.item.get('_modelType') === 'item') {
|
|
458
|
+
largeImageConfig.getConfigFile(this.item.get('folderId')).done((val) => {
|
|
459
|
+
this._limetadata = (val || {}).itemMetadata;
|
|
460
|
+
if (this._limetadata) {
|
|
461
|
+
this.render();
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
} else {
|
|
465
|
+
this._limetadata = null;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
wrap(MetadataWidget, 'render', function (render) {
|
|
470
|
+
let metaDict;
|
|
471
|
+
if (this.item.get(this.fieldName)) {
|
|
472
|
+
metaDict = this.item.get(this.fieldName) || {};
|
|
473
|
+
} else if (this.item[this.fieldName]) {
|
|
474
|
+
metaDict = this.item[this.fieldName] || {};
|
|
475
|
+
} else {
|
|
476
|
+
const fieldParts = this.fieldName.split('.');
|
|
477
|
+
metaDict = this.item.get(fieldParts[0]) || {};
|
|
478
|
+
fieldParts.slice(1).forEach((part) => {
|
|
479
|
+
metaDict = metaDict[part] || {};
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
var metaKeys = Object.keys(metaDict);
|
|
483
|
+
metaKeys.sort(localeSort);
|
|
484
|
+
if (this._limetadata) {
|
|
485
|
+
const origOrder = metaKeys.slice();
|
|
486
|
+
metaKeys.sort((a, b) => {
|
|
487
|
+
const aentry = liMetadataKeyEntry(this._limetadata, a);
|
|
488
|
+
const bentry = liMetadataKeyEntry(this._limetadata, b);
|
|
489
|
+
if (aentry && !bentry) {
|
|
490
|
+
return -1;
|
|
491
|
+
}
|
|
492
|
+
if (bentry && !aentry) {
|
|
493
|
+
return 1;
|
|
494
|
+
}
|
|
495
|
+
if (aentry && bentry) {
|
|
496
|
+
return aentry.idx - bentry.idx;
|
|
497
|
+
}
|
|
498
|
+
return origOrder.indexOf(a) - origOrder.indexOf(b);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
this._sortedMetaKeys = metaKeys;
|
|
502
|
+
this._renderedMetaDict = metaDict;
|
|
503
|
+
const contents = (this.MetadataWidgetTemplate || MetadataWidgetTemplate)({
|
|
504
|
+
item: this.item,
|
|
505
|
+
title: this.title,
|
|
506
|
+
accessLevel: this.accessLevel,
|
|
507
|
+
AccessType: AccessType,
|
|
508
|
+
limetadata: this._limetadata
|
|
509
|
+
});
|
|
510
|
+
this._renderHeader(contents);
|
|
511
|
+
|
|
512
|
+
// Append each metadatum
|
|
513
|
+
_.each(metaKeys, function (metaKey) {
|
|
514
|
+
this.$el.find('.g-widget-metadata-container').append(new MetadatumWidget({
|
|
515
|
+
mode: this.getModeFromValue(metaDict[metaKey], metaKey),
|
|
516
|
+
key: metaKey,
|
|
517
|
+
value: metaDict[metaKey],
|
|
518
|
+
accessLevel: this.accessLevel,
|
|
519
|
+
parentView: this,
|
|
520
|
+
fieldName: this.fieldName,
|
|
521
|
+
apiPath: this.apiPath,
|
|
522
|
+
limetadata: this._limetadata,
|
|
523
|
+
noSave: this.noSave,
|
|
524
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
525
|
+
onMetadataAdded: this.onMetadataAdded
|
|
526
|
+
}).render().$el);
|
|
527
|
+
}, this);
|
|
528
|
+
|
|
529
|
+
return this;
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
wrap(MetadataWidget, 'setItem', function (setItem, item) {
|
|
533
|
+
if (item !== this.item) {
|
|
534
|
+
this._limetadata = null;
|
|
535
|
+
if (item && item.get('_modelType') === 'item') {
|
|
536
|
+
largeImageConfig.getConfigFile(item.get('folderId')).done((val) => {
|
|
537
|
+
this._limetadata = (val || {}).itemMetadata;
|
|
538
|
+
if (this._limetadata) {
|
|
539
|
+
this.render();
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
setItem.call(this, item);
|
|
545
|
+
this.item.on('g:changed', function () {
|
|
546
|
+
this.render();
|
|
547
|
+
}, this);
|
|
548
|
+
this.render();
|
|
549
|
+
return this;
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
MetadataWidget.prototype.modes.simple.editor = (args) => new MetadatumEditWidget(args);
|
|
553
|
+
MetadataWidget.prototype.modes.json.editor = (args) => {
|
|
554
|
+
if (args.value !== undefined) {
|
|
555
|
+
args.value = JSON.parse(args.value);
|
|
556
|
+
}
|
|
557
|
+
return new JsonMetadatumEditWidget(args);
|
|
558
|
+
};
|
|
559
|
+
MetadataWidget.prototype.modes.key = {
|
|
560
|
+
editor: function (args) {
|
|
561
|
+
return new MetadatumEditWidget(args);
|
|
562
|
+
},
|
|
563
|
+
displayValue: function () {
|
|
564
|
+
return this.value;
|
|
565
|
+
},
|
|
566
|
+
template: MetadatumViewTemplate
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
MetadataWidget.prototype.events['click .li-add-metadata'] = function (evt) {
|
|
570
|
+
this.addMetadataByKey(evt);
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
MetadataWidget.prototype.getModeFromValue = function (value, key) {
|
|
574
|
+
if (liMetadataKeyEntry(this._limetadata, key)) {
|
|
575
|
+
return 'key';
|
|
576
|
+
}
|
|
577
|
+
return _.isString(value) ? 'simple' : 'json';
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
MetadataWidget.prototype.addMetadata = function (evt, mode) {
|
|
581
|
+
var EditWidget = this.modes[mode].editor;
|
|
582
|
+
var value = (mode === 'json') ? '{}' : '';
|
|
583
|
+
|
|
584
|
+
var widget = new MetadatumWidget({
|
|
585
|
+
className: 'g-widget-metadata-row editing',
|
|
586
|
+
mode: mode,
|
|
587
|
+
key: '',
|
|
588
|
+
value: value,
|
|
589
|
+
item: this.item,
|
|
590
|
+
fieldName: this.fieldName,
|
|
591
|
+
noSave: this.noSave,
|
|
592
|
+
apiPath: this.apiPath,
|
|
593
|
+
accessLevel: this.accessLevel,
|
|
594
|
+
parentView: this,
|
|
595
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
596
|
+
onMetadataAdded: this.onMetadataAdded
|
|
597
|
+
});
|
|
598
|
+
widget.$el.appendTo(this.$('.g-widget-metadata-container'));
|
|
599
|
+
|
|
600
|
+
new EditWidget({
|
|
601
|
+
item: this.item,
|
|
602
|
+
key: '',
|
|
603
|
+
value: value,
|
|
604
|
+
fieldName: this.fieldName,
|
|
605
|
+
noSave: this.noSave,
|
|
606
|
+
apiPath: this.apiPath,
|
|
607
|
+
accessLevel: this.accessLevel,
|
|
608
|
+
newDatum: true,
|
|
609
|
+
parentView: widget,
|
|
610
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
611
|
+
onMetadataAdded: this.onMetadataAdded
|
|
612
|
+
})
|
|
613
|
+
.render()
|
|
614
|
+
.$el.appendTo(widget.$el);
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
MetadataWidget.prototype.addMetadataByKey = function (evt) {
|
|
618
|
+
const key = $(evt.target).attr('metadata-key');
|
|
619
|
+
// if this key already exists, just go to editing it
|
|
620
|
+
if (this.$el.find(`.g-widget-metadata-row[g-key="${key}"]`).length) {
|
|
621
|
+
this.$el.find(`.g-widget-metadata-row[g-key="${key}"] button.g-widget-metadata-edit-button`).click();
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
var EditWidget = this.modes.key.editor;
|
|
625
|
+
var lientry = liMetadataKeyEntry(this._limetadata, key) || {};
|
|
626
|
+
var value = lientry.default ? lientry.default : '';
|
|
627
|
+
|
|
628
|
+
var widget = new MetadatumWidget({
|
|
629
|
+
className: 'g-widget-metadata-row editing',
|
|
630
|
+
mode: 'key',
|
|
631
|
+
key: key,
|
|
632
|
+
value: value,
|
|
633
|
+
item: this.item,
|
|
634
|
+
fieldName: this.fieldName,
|
|
635
|
+
apiPath: this.apiPath,
|
|
636
|
+
accessLevel: this.accessLevel,
|
|
637
|
+
parentView: this,
|
|
638
|
+
limetadata: this._limetadata,
|
|
639
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
640
|
+
onMetadataAdded: this.onMetadataAdded
|
|
641
|
+
});
|
|
642
|
+
widget.$el.appendTo(this.$('.g-widget-metadata-container'));
|
|
643
|
+
|
|
644
|
+
new EditWidget({
|
|
645
|
+
item: this.item,
|
|
646
|
+
key: key,
|
|
647
|
+
value: value,
|
|
648
|
+
fieldName: this.fieldName,
|
|
649
|
+
apiPath: this.apiPath,
|
|
650
|
+
accessLevel: this.accessLevel,
|
|
651
|
+
newDatum: true,
|
|
652
|
+
noSave: this.noSave,
|
|
653
|
+
parentView: widget,
|
|
654
|
+
limetadata: this._limetadata,
|
|
655
|
+
onMetadataEdited: this.onMetadataEdited,
|
|
656
|
+
onMetadataAdded: this.onMetadataAdded
|
|
657
|
+
})
|
|
658
|
+
.render()
|
|
659
|
+
.$el.appendTo(widget.$el);
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
MetadataWidget.prototype._renderHeader = function (contents) {
|
|
663
|
+
this.$el.html(contents);
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
export {
|
|
667
|
+
MetadataWidget,
|
|
668
|
+
MetadatumWidget,
|
|
669
|
+
MetadatumEditWidget,
|
|
670
|
+
JsonMetadatumEditWidget,
|
|
671
|
+
liMetadataKeyEntry
|
|
672
|
+
};
|
|
@@ -30,12 +30,15 @@ girder_large_image/web_client/stylesheets/itemList.styl
|
|
|
30
30
|
girder_large_image/web_client/stylesheets/itemView.styl
|
|
31
31
|
girder_large_image/web_client/stylesheets/itemViewCodemirror.styl
|
|
32
32
|
girder_large_image/web_client/stylesheets/largeImageConfig.styl
|
|
33
|
+
girder_large_image/web_client/stylesheets/metadataWidget.styl
|
|
33
34
|
girder_large_image/web_client/templates/imageViewerSelectWidget.pug
|
|
34
35
|
girder_large_image/web_client/templates/itemList.pug
|
|
35
36
|
girder_large_image/web_client/templates/itemView.pug
|
|
36
37
|
girder_large_image/web_client/templates/itemViewCodemirror.pug
|
|
37
38
|
girder_large_image/web_client/templates/largeImageConfig.pug
|
|
38
39
|
girder_large_image/web_client/templates/largeImage_fileAction.pug
|
|
40
|
+
girder_large_image/web_client/templates/metadataWidget.pug
|
|
41
|
+
girder_large_image/web_client/templates/metadatumEditWidget.pug
|
|
39
42
|
girder_large_image/web_client/views/configView.js
|
|
40
43
|
girder_large_image/web_client/views/fileList.js
|
|
41
44
|
girder_large_image/web_client/views/imageViewerSelectWidget.js
|
|
@@ -44,6 +47,7 @@ girder_large_image/web_client/views/itemList.js
|
|
|
44
47
|
girder_large_image/web_client/views/itemView.js
|
|
45
48
|
girder_large_image/web_client/views/itemViewCodemirror.js
|
|
46
49
|
girder_large_image/web_client/views/itemViewWidget.js
|
|
50
|
+
girder_large_image/web_client/views/metadataWidget.js
|
|
47
51
|
girder_large_image/web_client/views/imageViewerWidget/base.js
|
|
48
52
|
girder_large_image/web_client/views/imageViewerWidget/geojs.js
|
|
49
53
|
girder_large_image/web_client/views/imageViewerWidget/index.js
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
girder>=3.1.18
|
|
2
2
|
girder-jobs>=3.0.3
|
|
3
|
-
large_image>=1.22.3.
|
|
3
|
+
large_image>=1.22.3.dev26
|
|
4
4
|
|
|
5
5
|
[:python_version < "3.8"]
|
|
6
6
|
importlib-metadata<5
|
|
7
7
|
|
|
8
8
|
[tasks]
|
|
9
|
-
large-image-tasks[girder]>=1.22.3.
|
|
9
|
+
large-image-tasks[girder]>=1.22.3.dev26
|
|
10
10
|
girder-worker[girder]>=0.6.0
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_tiles_rest.py
RENAMED
|
@@ -1218,6 +1218,19 @@ def testTilesHistogram(server, admin, fsAssetstore):
|
|
|
1218
1218
|
assert len(resp.json) == 3
|
|
1219
1219
|
assert len(resp.json[0]['hist']) == 256
|
|
1220
1220
|
|
|
1221
|
+
resp = server.request(
|
|
1222
|
+
path='/item/%s/tiles/histogram' % itemId,
|
|
1223
|
+
params={'width': 2048, 'height': 2048, 'resample': False,
|
|
1224
|
+
'roundRange': False, 'bins': 512})
|
|
1225
|
+
assert len(resp.json) == 3
|
|
1226
|
+
assert len(resp.json[0]['hist']) == 512
|
|
1227
|
+
resp = server.request(
|
|
1228
|
+
path='/item/%s/tiles/histogram' % itemId,
|
|
1229
|
+
params={'width': 2048, 'height': 2048, 'resample': False,
|
|
1230
|
+
'roundRange': True, 'bins': 512})
|
|
1231
|
+
assert len(resp.json) == 3
|
|
1232
|
+
assert len(resp.json[0]['hist']) == 256
|
|
1233
|
+
|
|
1221
1234
|
|
|
1222
1235
|
@pytest.mark.usefixtures('unbindLargeImage')
|
|
1223
1236
|
@pytest.mark.plugin('large_image')
|
|
File without changes
|
|
File without changes
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/__init__.py
RENAMED
|
File without changes
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/girder_large_image/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/girder_utilities.py
RENAMED
|
File without changes
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_large_image.py
RENAMED
|
File without changes
|
{girder-large-image-1.22.3.dev18 → girder-large-image-1.22.3.dev26}/test_girder/test_web_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|