Skip to content

Commit 846e2f2

Browse files
authored
Merge pull request #222 from pedromml/update-sources-field
Update sources field
2 parents 5cfff58 + 59b8e94 commit 846e2f2

6 files changed

Lines changed: 167 additions & 6 deletions

File tree

css/80_app.css

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,12 +1591,20 @@ input.date-selector {
15911591
display: flex;
15921592
flex-flow: row nowrap;
15931593
}
1594-
.form-field ul.rows li.labeled-input > div {
1594+
.form-field ul.rows li.labeled-input > div,
1595+
.form-field ul.rows li.labeled-input-source > div {
15951596
flex: 1 1 auto;
15961597
width: 100%;
15971598
border-radius: 0;
15981599
line-height: 0.95rem;
15991600
}
1601+
.form-field ul.rows li.labeled-input div > span,
1602+
.form-field ul.rows li.labeled-input-source div > span{
1603+
vertical-align: middle;
1604+
}
1605+
.form-field ul.rows li.labeled-input-source > div {
1606+
width: auto;
1607+
}
16001608
.form-field ul.rows li input {
16011609
border-radius: 0;
16021610
border-width: 0;
@@ -1620,18 +1628,21 @@ input.date-selector {
16201628
display: table;
16211629
width: 100%;
16221630
}
1623-
.form-field ul.rows.rows-table li.labeled-input {
1631+
.form-field ul.rows.rows-table li.labeled-input,
1632+
.form-field ul.rows.rows-table li.labeled-input-source {
16241633
display: table-row;
16251634
}
1626-
.form-field ul.rows.rows-table li.labeled-input > div:first-child {
1635+
.form-field ul.rows.rows-table li.labeled-input > div:first-child,
1636+
.form-field ul.rows.rows-table li.labeled-input-source > div:first-child {
16271637
display: table-cell;
16281638
width: auto;
16291639
max-width: 170px;
16301640
white-space: nowrap;
16311641
text-overflow: ellipsis;
16321642
overflow: hidden;
16331643
}
1634-
.form-field ul.rows.rows-table li.labeled-input > div:nth-child(2) {
1644+
.form-field ul.rows.rows-table li.labeled-input > div:nth-child(2),
1645+
.form-field ul.rows.rows-table li.labeled-input-source > div:nth-child(2) {
16351646
display: table-cell;
16361647
width: auto;
16371648
}
@@ -2051,6 +2062,9 @@ input.date-selector {
20512062

20522063
/* Field - date, roadheight, and roadspeed
20532064
------------------------------------------------------- */
2065+
.form-field-input-source {
2066+
flex-direction: column;
2067+
}
20542068
.form-field-input-date input.date-year,
20552069
.form-field-input-date input.date-month,
20562070
.form-field-input-roadheight input.roadheight-number,
@@ -2960,6 +2974,10 @@ img.tag-reference-wiki-image {
29602974
.add-row .space-value {
29612975
flex: 1 1 50%;
29622976
}
2977+
.add-row .add-subkey {
2978+
width: 32px;
2979+
flex: 0 1 auto;
2980+
}
29632981
.add-row .space-buttons {
29642982
flex: 0 0 62px;
29652983
}

data/core.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,11 @@ en:
801801
field_source: add source
802802
field_source_label: Source for {field_name}
803803
field_source_placeholder: URL, newspaper article, book...
804+
source:
805+
main_input: Description
806+
name: Name
807+
url: https://example.com
808+
date: Date the source was created
804809
max_length_reached: "This string is longer than the maximum length of {maxChars} characters. Anything exceeding that length will be truncated."
805810
set_today: "Sets the value to today."
806811
background:
@@ -2535,6 +2540,8 @@ en:
25352540
label: License
25362541
placeholder: CC0
25372542
terms: copyleft, copyright
2543+
source:
2544+
label: Source
25382545
presets:
25392546
type/chronology:
25402547
name: Chronology

modules/presets/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ function addHistoricalFields(fields) {
5757

5858
// A combo box would encourage mappers to choose one of the suggestions, but we want mappers to be as detailed as possible.
5959
if (fields.source) {
60-
fields.source.type = 'text';
60+
fields.source.type = 'source';
6161
fields.source.source = false;
62+
fields.source.keys = ['source', 'source:url', 'source:name', 'source:date'];
6263
}
6364

6465
fields.license = {

modules/ui/fields/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import { uiFieldLocalized } from './localized';
5454
import { uiFieldRoadheight } from './roadheight';
5555
import { uiFieldRoadspeed } from './roadspeed';
5656
import { uiFieldRestrictions } from './restrictions';
57+
import { uiFieldSources } from './sources';
5758
import { uiFieldTextarea } from './textarea';
5859
import { uiFieldWikidata } from './wikidata';
5960
import { uiFieldWikipedia } from './wikipedia';
@@ -82,6 +83,7 @@ export var uiFields = {
8283
radio: uiFieldRadio,
8384
restrictions: uiFieldRestrictions,
8485
semiCombo: uiFieldSemiCombo,
86+
source: uiFieldSources,
8587
structureRadio: uiFieldStructureRadio,
8688
tel: uiFieldTel,
8789
text: uiFieldText,

modules/ui/fields/sources.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { dispatch as d3_dispatch } from 'd3-dispatch';
2+
import { select as d3_select } from 'd3-selection';
3+
4+
import { t } from '../../core/localizer';
5+
import { utilGetSetValue, utilNoAuto, utilRebind } from '../../util';
6+
7+
export function uiFieldSources(field, context) {
8+
let dispatch = d3_dispatch('change');
9+
let items = d3_select(null);
10+
let _tags = {};
11+
let _selection = d3_select(null);
12+
let _pendingChange;
13+
14+
const mainKey = 'source';
15+
const sourceHeader = mainKey + ':';
16+
17+
// Pre-selected subkeys to show
18+
const possibleSourceSubkeys = [{key:'name'}, {key:'url'}, {key:'date'}];
19+
20+
function scheduleChange() {
21+
if (!_pendingChange) return;
22+
dispatch.call('change', this, _pendingChange);
23+
_pendingChange = null;
24+
_selection.call(sources);
25+
}
26+
27+
function valueChange(d3_event, d) {
28+
// exit if this is a multiselection and no value was entered
29+
if (typeof d.key !== 'string' && !this.value) return;
30+
31+
var key = sourceHeader + d.key;
32+
33+
_pendingChange = _pendingChange || {};
34+
35+
var value = context.cleanTagValue(this.value);
36+
37+
_pendingChange[key] = value === '' ? undefined : value;
38+
_tags[key] = value === '' ? undefined : value;
39+
scheduleChange();
40+
}
41+
42+
function mainChange() {
43+
_pendingChange = _pendingChange || {};
44+
var value = context.cleanTagValue(this.value);
45+
_pendingChange[mainKey] = value === '' ? undefined : value;
46+
_tags[mainKey] = value === '' ? undefined : value;
47+
scheduleChange();
48+
}
49+
50+
function sources(selection) {
51+
_selection = selection;
52+
53+
var wrap = selection.selectAll('.form-field-input-wrap')
54+
.data([0]);
55+
56+
selection.exit()
57+
.style('top', '0')
58+
.style('max-height', '240px')
59+
.transition()
60+
.duration(200)
61+
.style('opacity', '0')
62+
.style('max-height', '0px')
63+
.remove();
64+
65+
wrap = wrap.enter()
66+
.append('div')
67+
.attr('class', 'form-field-input-wrap form-field-input-' + field.type)
68+
.merge(wrap);
69+
70+
// source key
71+
wrap.selectAll('input')
72+
.data([0])
73+
.enter()
74+
.append('input')
75+
.attr('class', 'main-value')
76+
.attr('type', 'text')
77+
.attr('placeholder', t('inspector.source.main_input'))
78+
.call(utilNoAuto)
79+
.on('change', mainChange)
80+
.on('blur', mainChange);
81+
82+
var list = wrap.selectAll('ul')
83+
.data([0]);
84+
85+
list = list.enter()
86+
.append('ul')
87+
.attr('class', 'rows')
88+
.merge(list);
89+
90+
list = list.merge(list);
91+
92+
// source:*= keys
93+
items = list.selectAll('li.labeled-input-source')
94+
.data(possibleSourceSubkeys);
95+
96+
items = items.enter()
97+
.append('li')
98+
.attr('class', 'labeled-input-source');
99+
100+
items
101+
.append('input')
102+
.attr('type', 'text')
103+
.attr('class', 'value')
104+
.attr('placeholder', function(d) {
105+
return t('inspector.source.' + d.key);
106+
})
107+
.call(utilNoAuto)
108+
.call(utilGetSetValue, function(d) {
109+
return _tags[sourceHeader + d.key];
110+
})
111+
.on('change', valueChange)
112+
.on('blur', valueChange);
113+
114+
items.exit()
115+
.remove();
116+
117+
utilGetSetValue(_selection.selectAll('.value'), function(d) {
118+
return (_tags[sourceHeader + d.key] === undefined) ? '' : _tags[sourceHeader + d.key];
119+
});
120+
121+
utilGetSetValue(_selection.selectAll('.main-value'), function() {
122+
return (_tags[mainKey] === undefined) ? '' : _tags[mainKey];
123+
});
124+
}
125+
126+
sources.tags = function(tags){
127+
if (!arguments.length) return _tags;
128+
_tags = tags;
129+
130+
_selection.call(sources);
131+
};
132+
133+
return utilRebind(sources, dispatch, 'on');
134+
}

modules/ui/source_subfield.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44

55
import { t } from '../core/localizer';
66
import { svgIcon } from '../svg/icon';
7-
import { uiTooltip } from './tooltip';
87
import { utilGetSetValue, utilUniqueDomId } from '../util';
98

109
export function uiSourceSubfield(context, field, tags, dispatch) {

0 commit comments

Comments
 (0)