Lock down some fields when a brand preset has been chosen

This commit is contained in:
Bryan Housel
2018-11-26 15:13:40 -05:00
parent da9ce2a3bf
commit f6f146f79b
5 changed files with 102 additions and 71 deletions
+27 -38
View File
@@ -175,24 +175,18 @@ input[type=email] {
padding: 5px 10px 5px 20px;
}
.disabled,
textarea[disabled],
input[type=text][disabled],
input[type=search][disabled],
input[type=number][disabled],
input[type=url][disabled],
input[type=tel][disabled],
input[type=email][disabled] {
color: #777;
background-color: #eee;
cursor: not-allowed;
}
textarea:focus,
input:focus {
background-color: #f1f1f1;
}
textarea.disabled,
input.disabled {
color: #777;
background-color: #eee;
cursor: not-allowed;
}
input[type="checkbox"],
input[type="radio"] {
float: left;
@@ -217,18 +211,15 @@ input[type="radio"] {
}
/* tables */
table {
background-color: #fff;
border-collapse: collapse;
width: 100%;
border-spacing: 0;
}
table th {
text-align: left;
}
table.tags, table.tags td, table.tags th {
border: 1px solid #ccc;
padding: 4px;
@@ -261,22 +252,18 @@ ul li { list-style: none;}
.toggle-list > label:hover {
background-color: #ececec;
}
.toggle-list > label:not(:last-child) {
border-bottom: 1px solid #ccc;
}
.toggle-list > label:last-child {
border-radius: 0 0 3px 3px;
}
.toggle-list label > span {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.toggle-list > label.active {
background: #e8ebff;
}
@@ -373,9 +360,7 @@ button.minor:hover {
background-color: #f1f1f1;
}
button[disabled],
button.disabled,
button.minor[disabled],
button.minor.disabled {
background-color: rgba(255,255,255,.25);
color: rgba(0,0,0,.4);
@@ -408,15 +393,12 @@ button.minor.disabled {
border-radius: 4px 0 0 4px;
}
/* Action buttons */
button.action {
background: #7092ff;
color: #fff;
}
button[disabled].action,
button[disabled].action:hover {
background: #cccccc;
color: #888;
}
button.action:focus,
button.action:hover {
background: #597be7;
@@ -424,12 +406,18 @@ button.action:hover {
button.secondary-action {
background: #ececec;
}
button.secondary-action:focus,
button.secondary-action:hover {
background: #cccccc;
}
button[disabled].action,
button[disabled].action:hover {
background: #cccccc;
color: #888;
cursor: not-allowed;
}
/* Icons
------------------------------------------------------- */
@@ -1298,6 +1286,7 @@ a.hide-toggle {
.form-field > input,
.form-field > textarea,
.form-field .localized-input-wrap > input,
.form-field .preset-input-wrap {
border: 1px solid #ccc;
min-height: 30px;
@@ -1804,15 +1793,15 @@ button.localized-add {
border-radius: 0 0 0 4px;
}
.localized-wrap {
.localized-multilingual {
padding: 0 10px;
}
.localized-wrap .entry {
.localized-multilingual .entry {
position: relative;
overflow: hidden;
}
.localized-wrap .entry::before {
.localized-multilingual .entry::before {
content: "";
display: block;
position: absolute;
@@ -1825,22 +1814,22 @@ button.localized-add {
margin: auto;
}
.localized-wrap .entry .localized-lang {
.localized-multilingual .entry .localized-lang {
border-radius: 0;
border-top-width: 0;
}
.localized-wrap .entry .localized-value {
.localized-multilingual .entry .localized-value {
border-top-width: 0;
border-radius: 0 0 4px 4px;
}
.localized-wrap .form-label button {
.localized-multilingual .form-label button {
border-top-right-radius: 3px;
}
button.localized-add[disabled],
.localized-wrap .form-label button[disabled],
.localized-wrap .localized-lang[disabled],
.localized-wrap .localized-value[disabled] {
button.localized-add.disabled,
.localized-multilingual .form-label button.disabled,
.localized-multilingual .localized-lang.disabled,
.localized-multilingual .localized-value.disabled {
color: #777;
background-color: #eee;
cursor: not-allowed;
+3
View File
@@ -438,6 +438,9 @@ en:
relation: Relation
location: Location
add_fields: "Add field:"
lock:
brand: 'This brand name is locked. You can delete it or edit the tags in the "All tags" section.'
official: 'This official name is locked. You can delete it or edit the tags in the "All tags" section.'
background:
title: Background
description: Background settings
+5 -1
View File
@@ -534,7 +534,11 @@
"way": "Way",
"relation": "Relation",
"location": "Location",
"add_fields": "Add field:"
"add_fields": "Add field:",
"lock": {
"brand": "This brand name is locked. You can delete it or edit the tags in the \"All tags\" section.",
"official": "This official name is locked. You can delete it or edit the tags in the \"All tags\" section."
}
},
"background": {
"title": "Background",
+20 -6
View File
@@ -1,9 +1,14 @@
import { dispatch as d3_dispatch } from 'd3-dispatch';
import { event as d3_event } from 'd3-selection';
import {
select as d3_select,
event as d3_event
} from 'd3-selection';
import { t, textDirection } from '../../util/locale';
import { dataPhoneFormats } from '../../../data';
import { services } from '../../services';
import { tooltip } from '../../util/tooltip';
import {
utilGetSetValue,
utilNoAuto,
@@ -22,15 +27,20 @@ export {
export function uiFieldText(field, context) {
var dispatch = d3_dispatch('change');
var nominatim = services.geocoder;
var input;
var input = d3_select(null);
var _entity;
var _brandTip;
if (field.id === 'brand') {
_brandTip = tooltip().title(t('inspector.lock.brand')).placement('bottom');
}
function i(selection) {
var preset = _entity && context.presets().match(_entity, context.graph());
var isSuggestion = preset && preset.suggestion && field.id === 'brand';
var fieldId = 'preset-input-' + field.safeid;
var fieldID = 'preset-input-' + field.safeid;
input = selection.selectAll('input')
.data([0]);
@@ -38,23 +48,27 @@ export function uiFieldText(field, context) {
input = input.enter()
.append('input')
.attr('type', field.type)
.attr('id', fieldId)
.attr('id', fieldID)
.attr('placeholder', field.placeholder() || t('inspector.unknown'))
.call(utilNoAuto)
.merge(input);
input
.property('disabled', !!isSuggestion)
.classed('disabled', !!isSuggestion)
.on('input', change(true))
.on('blur', change())
.on('change', change());
if (field.id === 'brand') {
selection.call(isSuggestion ? _brandTip : _brandTip.destroy);
}
if (field.type === 'tel' && nominatim && _entity) {
var center = _entity.extent(context.graph()).center();
nominatim.countryCode(center, function (err, countryCode) {
if (err || !dataPhoneFormats[countryCode]) return;
selection.selectAll('#' + fieldId)
selection.selectAll('#' + fieldID)
.attr('placeholder', dataPhoneFormats[countryCode]);
});
+47 -26
View File
@@ -28,16 +28,38 @@ export function uiFieldLocalized(field, context) {
var wikipedia = services.wikipedia;
var input = d3_select(null);
var localizedInputs = d3_select(null);
var _isLocked = false;
var _brandTip = tooltip().title(t('inspector.lock.brand')).placement('bottom');
var _buttonTip = tooltip().title(t('translate.translate')).placement('left');
var _wikiTitles;
var _entity;
function localized(selection) {
var presets = context.presets();
var preset = _entity && presets.match(_entity, context.graph());
var isSuggestion = preset && preset.suggestion && field.id === 'name';
function checkLocked() {
var preset = _entity && context.presets().match(_entity, context.graph());
var isSuggestion = preset && preset.suggestion;
var showsBrand = preset && preset.fields
.filter(function(d) { return d.id === 'brand'; }).length;
_isLocked = field.id === 'name' && isSuggestion && !showsBrand;
}
input = selection.selectAll('.localized-main')
function localized(selection) {
checkLocked();
var preset = _entity && context.presets().match(_entity, context.graph());
var wrap = selection.selectAll('.localized-input-wrap')
.data([0]);
// enter/update
wrap = wrap.enter()
.append('div')
.attr('class', 'localized-input-wrap')
.merge(wrap)
.call(_isLocked ? _brandTip : _brandTip.destroy);
input = wrap.selectAll('.localized-main')
.data([0]);
// enter/update
@@ -55,7 +77,7 @@ export function uiFieldLocalized(field, context) {
var pKey = pTag[0];
var pValue = pTag[1];
if (isSuggestion) {
if (preset.suggestion) {
// A "suggestion" preset (brand name)
// Put suggestion keys in `field.keys` so delete button can remove them all.
field.keys = Object.keys(preset.removeTags)
@@ -63,7 +85,7 @@ export function uiFieldLocalized(field, context) {
} else {
// Not a suggestion preset - Add a suggestions dropdown if it makes sense to.
var allSuggestions = presets.collection.filter(function(p) {
var allSuggestions = context.presets().collection.filter(function(p) {
return p.suggestion === true;
});
@@ -95,6 +117,7 @@ export function uiFieldLocalized(field, context) {
tags[k] = removed[k]; // set removed tags to `undefined`
}
tags = d.suggestion.setTags(tags, geometry);
utilGetSetValue(input, tags.name);
dispatch.call('change', this, tags);
})
);
@@ -103,40 +126,41 @@ export function uiFieldLocalized(field, context) {
}
input
.property('disabled', !!isSuggestion)
.classed('disabled', !!_isLocked)
.attr('readonly', _isLocked)
.on('input', change(true))
.on('blur', change())
.on('change', change());
var translateButton = selection.selectAll('.localized-add')
var translateButton = wrap.selectAll('.localized-add')
.data([0]);
translateButton = translateButton.enter()
.append('button')
.attr('class', 'button-input-action localized-add minor')
.attr('class', 'localized-add button-input-action minor')
.attr('tabindex', -1)
.call(svgIcon('#iD-icon-plus'))
.call(tooltip()
.title(t('translate.translate'))
.placement('left'))
.merge(translateButton);
translateButton
.property('disabled', !!isSuggestion)
.classed('disabled', !!_isLocked)
.call(_isLocked ? _buttonTip.destroy : _buttonTip)
.on('click', addNew);
localizedInputs = selection.selectAll('.localized-wrap')
localizedInputs = selection.selectAll('.localized-multilingual')
.data([0]);
localizedInputs = localizedInputs.enter()
.append('div')
.attr('class', 'localized-wrap')
.attr('class', 'localized-multilingual')
.merge(localizedInputs);
localizedInputs.selectAll('button, input')
.property('disabled', !!isSuggestion);
.classed('disabled', !!_isLocked)
.attr('readonly', _isLocked);
function suggestNames(preset, suggestions) {
@@ -176,7 +200,7 @@ export function uiFieldLocalized(field, context) {
function addNew() {
d3_event.preventDefault();
if (isSuggestion) return;
if (_isLocked) return;
var data = localizedInputs.selectAll('div.entry').data();
var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
@@ -194,6 +218,10 @@ export function uiFieldLocalized(field, context) {
function change(onInput) {
return function() {
if (_isLocked) {
d3_event.preventDefault();
return;
}
var t = {};
t[field.key] = utilGetSetValue(d3_select(this)) || undefined;
dispatch.call('change', this, t, onInput);
@@ -257,10 +285,6 @@ export function uiFieldLocalized(field, context) {
function renderMultilingual(selection, data) {
var presets = context.presets();
var preset = _entity && presets.match(_entity, context.graph());
var isSuggestion = preset && preset.suggestion && field.id === 'name';
var wraps = selection.selectAll('div.entry')
.data(data, function(d) { return d.lang; });
@@ -293,9 +317,8 @@ export function uiFieldLocalized(field, context) {
label
.append('button')
.attr('class', 'minor remove')
.property('disabled', !!isSuggestion)
.on('click', function(d) {
if (isSuggestion) return;
if (_isLocked) return;
d3_event.preventDefault();
var t = {};
t[key(d.lang)] = undefined;
@@ -315,7 +338,6 @@ export function uiFieldLocalized(field, context) {
.attr('class', 'localized-lang')
.attr('type', 'text')
.attr('placeholder', t('translate.localized_translation_language'))
.property('disabled', !!isSuggestion)
.on('blur', changeLang)
.on('change', changeLang)
.call(langcombo);
@@ -325,7 +347,6 @@ export function uiFieldLocalized(field, context) {
.attr('type', 'text')
.attr('placeholder', t('translate.localized_translation_name'))
.attr('class', 'localized-value')
.property('disabled', !!isSuggestion)
.on('blur', changeValue)
.on('change', changeValue);
});