Skip to content

Commit b101364

Browse files
authored
Merge pull request #223 from pedromml/feat-multiple-sources
Add multiple source fields
2 parents 55524e9 + 577fb55 commit b101364

File tree

6 files changed

+63
-12
lines changed

6 files changed

+63
-12
lines changed

data/core.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,8 @@ en:
25422542
terms: copyleft, copyright
25432543
source:
25442544
label: Source
2545+
source_multiple:
2546+
label: Source {index}
25452547
presets:
25462548
type/chronology:
25472549
name: Chronology

modules/presets/field.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export function presetField(fieldID, field, allFields) {
1010
allFields = allFields || {};
1111
let _this = Object.assign({}, field); // shallow copy
1212

13+
// This handles fields that are composed of a base key and an index, like 'source:1'
14+
let localizerFieldID = fieldID;
15+
if (field.baseKey && field.index){
16+
localizerFieldID = field.baseKey + '_multiple';
17+
}
18+
1319
_this.id = fieldID;
1420

1521
// for use in classes, element ids, css selectors
@@ -21,14 +27,14 @@ export function presetField(fieldID, field, allFields) {
2127
return !_this.geometry || geometries.every(geom => _this.geometry.indexOf(geom) !== -1);
2228
};
2329

24-
_this.t = (scope, options) => t(localizer.coalesceStringIds([`custom_presets.fields.${fieldID}.${scope}`,
25-
`_tagging.presets.fields.${fieldID}.${scope}`]), options);
26-
_this.t.html = (scope, options) => t.html(localizer.coalesceStringIds([`custom_presets.fields.${fieldID}.${scope}`,
27-
`_tagging.presets.fields.${fieldID}.${scope}`]), options);
28-
_this.t.append = (scope, options) => t.append(localizer.coalesceStringIds([`custom_presets.fields.${fieldID}.${scope}`,
29-
`_tagging.presets.fields.${fieldID}.${scope}`]), options);
30-
_this.hasTextForStringId = (scope) => localizer.hasTextForStringId(`custom_presets.fields.${fieldID}.${scope}`) ||
31-
localizer.hasTextForStringId(`_tagging.presets.fields.${fieldID}.${scope}`);
30+
_this.t = (scope, options) => t(localizer.coalesceStringIds([`custom_presets.fields.${localizerFieldID}.${scope}`,
31+
`_tagging.presets.fields.${localizerFieldID}.${scope}`]), options);
32+
_this.t.html = (scope, options) => t.html(localizer.coalesceStringIds([`custom_presets.fields.${localizerFieldID}.${scope}`,
33+
`_tagging.presets.fields.${localizerFieldID}.${scope}`]), options);
34+
_this.t.append = (scope, options) => t.append(localizer.coalesceStringIds([`custom_presets.fields.${localizerFieldID}.${scope}`,
35+
`_tagging.presets.fields.${localizerFieldID}.${scope}`]), options);
36+
_this.hasTextForStringId = (scope) => localizer.hasTextForStringId(`custom_presets.fields.${localizerFieldID}.${scope}`) ||
37+
localizer.hasTextForStringId(`_tagging.presets.fields.${localizerFieldID}.${scope}`);
3238

3339
_this.resolveReference = which => {
3440
const referenceRegex = /^\{(.*)\}$/;
@@ -43,10 +49,10 @@ export function presetField(fieldID, field, allFields) {
4349
return _this;
4450
};
4551

46-
_this.title = () => _this.overrideLabel || _this.resolveReference('label').t('label', { 'default': fieldID });
52+
_this.title = () => _this.overrideLabel || _this.resolveReference('label').t('label', { 'default': fieldID, 'index': field.index });
4753
_this.label = () => _this.overrideLabel ?
4854
selection => selection.text(_this.overrideLabel) :
49-
_this.resolveReference('label').t.append('label', { 'default': fieldID });
55+
_this.resolveReference('label').t.append('label', { 'default': fieldID, 'index': field.index });
5056

5157
_this.placeholder = () => _this.resolveReference('placeholder').t('placeholder', { 'default': '' });
5258

modules/presets/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ function addHistoricalFields(fields) {
6060
fields.source.type = 'source';
6161
fields.source.source = false;
6262
fields.source.keys = ['source', 'source:url', 'source:name', 'source:date'];
63+
64+
for (let i = 1; i < 4; i++){
65+
let id = 'source:' + i.toString();
66+
let previousId = 'source' + ((i-1) > 0 ? ':' + (i-1).toString() : '');
67+
fields[id] = {
68+
...fields.source,
69+
key: id,
70+
keys: [id, id + ':url', id + ':name', id + ':date'],
71+
// baseKey and index will be used to create a localized label for this field
72+
baseKey: 'source',
73+
index: i,
74+
prerequisiteTag: {
75+
keys: [
76+
previousId,
77+
previousId + ':url',
78+
previousId + ':name',
79+
previousId + ':date']}};
80+
}
6381
}
6482

6583
fields.license = {

modules/ui/field.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ export function uiField(context, presetField, entityIDs, options) {
216216
referenceKey = referenceKey.replace(/:$/, '');
217217
}
218218

219+
if (d.type === 'source') { // lookup key without the trailing ':'
220+
referenceKey = referenceKey.split(':')[0];
221+
}
222+
219223
var referenceOptions = d.reference || {
220224
key: referenceKey,
221225
value: _tags[referenceKey]
@@ -350,6 +354,12 @@ export function uiField(context, presetField, entityIDs, options) {
350354

351355
if (!entityIDs.every(function(entityID) {
352356
var entity = context.graph().entity(entityID);
357+
if (prerequisiteTag.keys) {
358+
// Return true if any key in prerequisiteTag.keys is present, return false otherwise
359+
// If prerequisiteTag.keys is present, prerequisiteTag.key will be ignored
360+
const inEntityTags = (e) => e in entity.tags;
361+
return prerequisiteTag.keys.some(inEntityTags);
362+
}
353363
if (prerequisiteTag.key) {
354364
var value = entity.tags[prerequisiteTag.key];
355365
if (!value) return false;

modules/ui/fields/sources.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function uiFieldSources(field, context) {
1111
let _selection = d3_select(null);
1212
let _pendingChange;
1313

14-
const mainKey = 'source';
14+
const mainKey = field.key;
1515
const sourceHeader = mainKey + ':';
1616

1717
// Pre-selected subkeys to show
@@ -130,5 +130,10 @@ export function uiFieldSources(field, context) {
130130
_selection.call(sources);
131131
};
132132

133+
sources.focus = function() {
134+
var node = _selection.selectAll('input').node();
135+
if (node) node.focus();
136+
};
137+
133138
return utilRebind(sources, dispatch, 'on');
134139
}

modules/ui/sections/preset_fields.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,17 @@ export function uiSectionPresetFields(context) {
7878
}
7979
});
8080

81+
let optionalCoreKeys = ['source:1', 'source:2', 'source:3'];
82+
optionalCoreKeys.forEach(key => {
83+
let field = presetsManager.field(key);
84+
if (field && !_fieldsArr.includes(field)) {
85+
_fieldsArr.push(uiField(context, field, _entityIDs, { show: false }));
86+
}
87+
});
88+
89+
8190
sharedFields.forEach(function(field) {
82-
if (!coreKeys.includes(field.id) && field.matchAllGeometry(geometries)) {
91+
if (!coreKeys.includes(field.id) && !optionalCoreKeys.includes(field.id) && field.matchAllGeometry(geometries)) {
8392
_fieldsArr.push(
8493
uiField(context, field, _entityIDs)
8594
);
@@ -101,6 +110,7 @@ export function uiSectionPresetFields(context) {
101110
additionalFields.forEach(function(field) {
102111
if (sharedFields.indexOf(field) === -1 &&
103112
!coreKeys.includes(field.id) &&
113+
!optionalCoreKeys.includes(field.id) &&
104114
field.matchAllGeometry(geometries)) {
105115
_fieldsArr.push(
106116
uiField(context, field, _entityIDs, { show: false })

0 commit comments

Comments
 (0)