Studio+UX: various UX tweaks after usertesting

This commit is contained in:
Pieter Vander Vennet 2023-11-03 02:04:42 +01:00
parent 4219b23af1
commit 3a915bdf25
31 changed files with 2476 additions and 108 deletions

View file

@ -217,7 +217,7 @@
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -253,7 +253,7 @@
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [
@ -854,7 +854,7 @@
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"
@ -1169,7 +1169,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1387,7 +1387,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {

View file

@ -217,7 +217,7 @@ export default {
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -253,7 +253,7 @@ export default {
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [
@ -845,7 +845,7 @@ export default {
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"
@ -1156,7 +1156,7 @@ export default {
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1373,7 +1373,7 @@ export default {
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {

View file

@ -766,7 +766,7 @@
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"
@ -1081,7 +1081,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1299,7 +1299,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1998,7 +1998,7 @@
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -2034,7 +2034,7 @@
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [
@ -2398,7 +2398,7 @@
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -2434,7 +2434,7 @@
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [

View file

@ -757,7 +757,7 @@ export default {
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"
@ -1068,7 +1068,7 @@ export default {
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1285,7 +1285,7 @@ export default {
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -1977,7 +1977,7 @@ export default {
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -2013,7 +2013,7 @@ export default {
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [
@ -2376,7 +2376,7 @@ export default {
} }
}, },
"description": { "description": {
"description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?", "description": "An extra explanation of what the feature is, if it is not immediately clear from the title alone.\n\nThe _first sentence_ of the description is shown on the button of the `add` menu.\nThe full description is shown in the confirmation dialog.\n\n(The first sentence is until the first '.'-character in the description)\n\nquestion: How would you describe this feature?\nifunset: No extra description is given. This can be used to further explain the preset",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/Record<string,string>" "$ref": "#/definitions/Record<string,string>"
@ -2412,7 +2412,7 @@ export default {
} }
}, },
"tagRenderings": { "tagRenderings": {
"description": "question: Which tagRenderings should be shown in the infobox?\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings", "description": "question: Edit this tagRendering\n\nA tag rendering is a block that either shows the known value or asks a question.\n\nRefer to the class `TagRenderingConfigJson` to see the possibilities.\n\nNote that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,\nwhere a few very general questions are defined e.g. website, phone number, ...\nFurthermore, _all_ the questions of another layer can be reused with `otherlayer.*`\nIf you need only a single of the tagRenderings, use `otherlayer.tagrenderingId`\nIf one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group`\nRemark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition.\nIf they are not wanted, remove them with an override\n\nA special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.\n\nAt last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.\nThis is mainly create questions for a 'left' and a 'right' side of the road.\nThese will be grouped and questions will be asked together\n\ntype: tagrendering[]\ngroup: tagrenderings",
"type": "array", "type": "array",
"items": { "items": {
"anyOf": [ "anyOf": [

View file

@ -58,7 +58,7 @@
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -58,7 +58,7 @@ export default {
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -21,7 +21,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -672,7 +672,7 @@
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -21,7 +21,7 @@ export default {
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -663,7 +663,7 @@ export default {
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -489,7 +489,7 @@
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -480,7 +480,7 @@ export default {
] ]
}, },
"ifnot": { "ifnot": {
"description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`", "description": "question: What tags should be applied if this mapping is _not_ chosen?\n\nOnly applicable if 'multiAnswer' is set.\nThis is for situations such as:\n`accepts:coins=no` where one can select all the possible payment methods. However, we want to make explicit that some options _were not_ selected.\nThis can be done with `ifnot`\nNote that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.\nIf this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`\n\nifunset: Do not apply a tag if a different mapping is chosen.",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/{and:TagConfigJson[];}" "$ref": "#/definitions/{and:TagConfigJson[];}"

View file

@ -12,8 +12,29 @@ User has used mapcomplete a few times before but has very little OSM-knowledge.
## Surfaced issues ## Surfaced issues
- [ ] dev.mapcomplete.org crashes - [x] dev.mapcomplete.org crashes
- [x] Switching tagRenderings or creating them sometimes creates a 'null' value which crashes downstream: should be filtered out - [x] Switching tagRenderings or creating them sometimes creates a 'null' value which crashes downstream: should be filtered out
- [x] Switching between editing layers does not update the title - [x] Switching between editing layers does not update the title
- [x] The warning messages don't update when editing - [x] The warning messages don't update when editing
- [x] The distinction between a 'warning' and an 'error' is unclear
- [x] A questionHint without a question should give an error - [x] A questionHint without a question should give an error
- [x] The 'title'-field should not have a 'question', as it is read-only
- [x] Button to edit the tagRendering is unclear
- [x] Change text
- [x] Change to primary
- [ ] The markers (which can be built from multiple, stacked images) approach is unclear
- [ ] When creating a new layer, perhaps force 'source' too?
- [ ] Forced questions in the beginning: do not show errors
- [x] Validation: forbid that a mapping starts with "yes" or "no"
- [ ] TagRenderings: freeform key cannot be set to 'undefined' again
- [ ] How to create a mapping for `key=yes` or `key=no` is unclear. Person searched for a 'binary'-type instead
- [ ] When a new tagRendering is added, the floatover should open immediately
- [ ] Mappings with different keys do not erase each other/freeform (e.g. noname=yes should erase `name`)
- [ ] Rename `mapping` to `predifined icon`, perhaps add a clarifying icon
- [x] In tagRenderings: the `question`-field should be in question-mode right from the start
- [ ] If _only_ freeform.key is set (but no question nor render): an error should be generated
- [x] The questionHints take too much space and should be unstickied
- [x] There should be some space for the 'close'-button in the tagRendering
- [ ] Changing the icon: the term 'icon badge' is misunderstood and interpreted as "the logo"
- [ ] Trying to change the 'iconBadges' does not work
- [ ] Creating a preset: initially very unclear

View file

@ -1133,10 +1133,6 @@ video {
height: 16rem; height: 16rem;
} }
.h-96 {
height: 24rem;
}
.max-h-12 { .max-h-12 {
max-height: 3rem; max-height: 3rem;
} }
@ -1149,10 +1145,6 @@ video {
max-height: 1.75rem; max-height: 1.75rem;
} }
.max-h-screen {
max-height: 100vh;
}
.max-h-60 { .max-h-60 {
max-height: 15rem; max-height: 15rem;
} }
@ -1808,6 +1800,10 @@ video {
text-align: justify; text-align: justify;
} }
.align-middle {
vertical-align: middle;
}
.text-xl { .text-xl {
font-size: 1.25rem; font-size: 1.25rem;
line-height: 1.75rem; line-height: 1.75rem;
@ -2481,6 +2477,37 @@ select:hover {
border: 2px dotted #ff9143; border: 2px dotted #ff9143;
} }
.warning {
/* The class to convey important information, but not as grave as 'alert' */
background-color: var(--low-interaction-background);
color: var(--alert-foreground-color);
font-weight: bold;
border-radius: 1em;
margin: 0.25em;
text-align: center;
padding: 0.15em 0.3em;
border: 3px dotted #ff9143;
}
.low-interaction .warning {
background-color: var(--interactive-background);
}
.information {
/* The class to convey important information which does _not_ denote an error... */
background-color: var(--low-interaction-background);
color: var(--alert-foreground-color);
border-radius: 1em;
margin: 0.25em;
text-align: center;
padding: 0.15em 0.3em;
border: 3px dotted var(--catch-detail-color-contrast);
}
.low-interaction .interactive {
background-color: var(--interactive-background);
}
.subtle { .subtle {
/* For all information that is not important for 99% of the users */ /* For all information that is not important for 99% of the users */
color: #999; color: #999;
@ -2684,6 +2711,10 @@ a.link-underline {
overflow-y: hidden; overflow-y: hidden;
} }
.min-h-32 {
min-height: 8rem;
}
.hover\:bg-indigo-200:hover { .hover\:bg-indigo-200:hover {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(199 210 254 / var(--tw-bg-opacity)); background-color: rgb(199 210 254 / var(--tw-bg-opacity));
@ -2923,5 +2954,3 @@ a.link-underline {
width: 33.333333%; width: 33.333333%;
} }
} }

View file

@ -732,6 +732,14 @@ class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJson> {
if (!mapping.if) { if (!mapping.if) {
context.enters("mappings", i).err("No `if` is defined") context.enters("mappings", i).err("No `if` is defined")
} }
const en = mapping?.then?.["en"]
if (en && en.toLowerCase().match(/(yes|no)([ ,:;.?]|$)/)) {
context
.enters("mappings", i, "then")
.warn(
"A mapping should not start with 'yes' or 'no'. If the attribute is known, it will only show 'yes' or 'no' <i>without</i> the question, resulting in a weird popup"
)
}
} }
} }
if (json["group"]) { if (json["group"]) {
@ -1168,17 +1176,23 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (json.presets !== undefined) { if (json.presets !== undefined) {
if (typeof json.source === "string") { if (typeof json.source === "string") {
context.err("A special layer cannot have presets") context.enter("presets").err("A special layer cannot have presets")
} }
// Check that a preset will be picked up by the layer itself // Check that a preset will be picked up by the layer itself
const baseTags = TagUtils.Tag(json.source["osmTags"]) const baseTags = TagUtils.Tag(json.source["osmTags"])
for (let i = 0; i < json.presets.length; i++) { for (let i = 0; i < json.presets.length; i++) {
const preset = json.presets[i] const preset = json.presets[i]
const tags: { k: string; v: string }[] = new And( if (!preset.tags) {
preset.tags.map((t) => TagUtils.Tag(t)) context.enters("presets", i, "tags").err("No tags defined for this preset")
).asChange({ id: "node/-1" }) continue
}
if (!preset.tags) {
context.enters("presets", i, "title").err("No title defined for this preset")
}
const tags = new And(preset.tags.map((t) => TagUtils.Tag(t)))
const properties = {} const properties = {}
for (const tag of tags) { for (const tag of tags.asChange({ id: "node/-1" })) {
properties[tag.k] = tag.v properties[tag.k] = tag.v
} }
const doMatch = baseTags.matchesProperties(properties) const doMatch = baseTags.matchesProperties(properties)
@ -1187,7 +1201,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
.enters("presets", i, "tags") .enters("presets", i, "tags")
.err( .err(
"This preset does not match the required tags of this layer. This implies that a newly added point will not show up.\n A newly created point will have properties: " + "This preset does not match the required tags of this layer. This implies that a newly added point will not show up.\n A newly created point will have properties: " +
JSON.stringify(properties) + tags.asHumanString(false, false, {}) +
"\n The required tags are: " + "\n The required tags are: " +
baseTags.asHumanString(false, false, {}) baseTags.asHumanString(false, false, {})
) )

View file

@ -338,6 +338,7 @@ export interface LayerConfigJson {
* (The first sentence is until the first '.'-character in the description) * (The first sentence is until the first '.'-character in the description)
* *
* question: How would you describe this feature? * question: How would you describe this feature?
* ifunset: No extra description is given. This can be used to further explain the preset
*/ */
description?: Translatable description?: Translatable
@ -375,7 +376,7 @@ export interface LayerConfigJson {
}[] }[]
/** /**
* question: Which tagRenderings should be shown in the infobox? * question: Edit this tagRendering
* *
* A tag rendering is a block that either shows the known value or asks a question. * A tag rendering is a block that either shows the known value or asks a question.
* *

View file

@ -114,6 +114,8 @@ export interface MappingConfigJson {
* This can be done with `ifnot` * This can be done with `ifnot`
* Note that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`. * Note that we can not explicitly render this negative case to the user, we cannot show `does _not_ accept coins`.
* If this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer` * If this is important to your usecase, consider using multiple radiobutton-fields without `multiAnswer`
*
* ifunset: Do not apply a tag if a different mapping is chosen.
*/ */
ifnot?: TagConfigJson ifnot?: TagConfigJson
@ -199,8 +201,8 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs
/** /**
* question: What is the name of the attribute that should be written to? * question: What is the name of the attribute that should be written to?
* This is the OpenStreetMap-key that that value will be written to * This is the OpenStreetMap-key that that value will be written to
*
* ifunset: do not offer a freeform textfield as answer option * ifunset: do not offer a freeform textfield as answer option
*
*/ */
key: string key: string

View file

@ -27,7 +27,7 @@
/** /**
* Indicates if this tagRendering currently shows the attribute or asks the question to _change_ the property * Indicates if this tagRendering currently shows the attribute or asks the question to _change_ the property
*/ */
export let editMode = !config.IsKnown(tags) || showQuestionIfUnknown; export let editMode = !config.IsKnown(tags.data) || showQuestionIfUnknown;
if (tags) { if (tags) {
onDestroy( onDestroy(
tags.addCallbackD((tags) => { tags.addCallbackD((tags) => {

View file

@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import type { ConfigMeta } from "./configMeta"; import type { ConfigMeta } from "./configMeta";
import EditLayerState from "./EditLayerState"; import EditLayerState from "./EditLayerState";
import type { QuestionableTagRenderingConfigJson } from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"; import type {
QuestionableTagRenderingConfigJson
} from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson";
import { UIEventSource } from "../../Logic/UIEventSource"; import { UIEventSource } from "../../Logic/UIEventSource";
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte"; import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"; import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig";
export let schema: ConfigMeta; export let schema: ConfigMeta;

View file

@ -117,8 +117,8 @@
</div> </div>
<div slot="title2"> <div slot="title2">
<ErrorIndicatorForRegion firstPaths={firstPathsFor("presets")} {state} />
Creating a new point Creating a new point
<ErrorIndicatorForRegion firstPaths={firstPathsFor("presets")} {state} />
</div> </div>
<div slot="content2"> <div slot="content2">

View file

@ -13,7 +13,6 @@
import configs from "../../assets/schemas/questionabletagrenderingconfigmeta.json"; import configs from "../../assets/schemas/questionabletagrenderingconfigmeta.json";
import { Utils } from "../../Utils"; import { Utils } from "../../Utils";
export let mapping: MappingConfigJson;
export let state: EditLayerState; export let state: EditLayerState;
export let path: (string | number)[]; export let path: (string | number)[];
let tag: UIEventSource<TagConfigJson> = state.getStoreFor([...path, "if"]); let tag: UIEventSource<TagConfigJson> = state.getStoreFor([...path, "if"]);

View file

@ -12,6 +12,8 @@
import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson"; import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson";
import FromHtml from "../Base/FromHtml.svelte"; import FromHtml from "../Base/FromHtml.svelte";
import { Utils } from "../../Utils"; import { Utils } from "../../Utils";
import ShowConversionMessage from "./ShowConversionMessage.svelte";
import NextButton from "../Base/NextButton.svelte";
export let state: EditLayerState; export let state: EditLayerState;
export let path: ReadonlyArray<string | number>; export let path: ReadonlyArray<string | number>;
@ -73,18 +75,16 @@
{#if $id} {#if $id}
TagRendering {$id} TagRendering {$id}
{/if} {/if}
<button on:click={() => state.highlightedItem.setData({path, schema})}> <NextButton clss="primary" on:click={() => state.highlightedItem.setData({path, schema})}>
{#if schema.hints.question} {#if schema.hints.question}
{schema.hints.question} {schema.hints.question}
{/if} {/if}
</button> </NextButton>
{#if description} {#if description}
<FromHtml src={description} /> <FromHtml src={description} />
{/if} {/if}
{#each $messages as message} {#each $messages as message}
<div class="alert"> <ShowConversionMessage {message}/>
{message.message}
</div>
{/each} {/each}
<slot class="self-end my-4"></slot> <slot class="self-end my-4"></slot>
@ -93,6 +93,7 @@
</div> </div>
<div class="flex flex-col w-full m-4"> <div class="flex flex-col w-full m-4">
<h3>Preview of this question</h3>
{#each $configs as config} {#each $configs as config}
<TagRenderingEditable <TagRenderingEditable
selectedElement={state.exampleFeature} selectedElement={state.exampleFeature}

View file

@ -8,6 +8,7 @@
import QuestionPreview from "./QuestionPreview.svelte"; import QuestionPreview from "./QuestionPreview.svelte";
import { Utils } from "../../Utils"; import { Utils } from "../../Utils";
import SchemaBasedMultiType from "./SchemaBasedMultiType.svelte"; import SchemaBasedMultiType from "./SchemaBasedMultiType.svelte";
import ShowConversionMessage from "./ShowConversionMessage.svelte";
export let state: EditLayerState; export let state: EditLayerState;
export let schema: ConfigMeta; export let schema: ConfigMeta;
@ -46,6 +47,7 @@
} }
} }
let createdItems = values.data.length; let createdItems = values.data.length;
let messages = state.messagesFor(path)
function createItem(valueToSet?: any) { function createItem(valueToSet?: any) {
@ -125,6 +127,11 @@
{#if $values.length === 0} {#if $values.length === 0}
No values are defined No values are defined
{#if $messages.length > 0}
{#each $messages as message}
<ShowConversionMessage {message}/>
{/each}
{/if}
{:else if subparts.length === 0} {:else if subparts.length === 0}
<!-- We need an array of values, so we use the typehint of the _parent_ element as field --> <!-- We need an array of values, so we use the typehint of the _parent_ element as field -->
{#each $values as value (value)} {#each $values as value (value)}

View file

@ -12,11 +12,12 @@
import { onDestroy } from "svelte"; import { onDestroy } from "svelte";
import type { JsonSchemaType } from "./jsonSchema"; import type { JsonSchemaType } from "./jsonSchema";
import { ConfigMetaUtils } from "./configMeta.ts"; import { ConfigMetaUtils } from "./configMeta.ts";
import ShowConversionMessage from "./ShowConversionMessage.svelte";
export let state: EditLayerState; export let state: EditLayerState;
export let path: (string | number)[] = []; export let path: (string | number)[] = [];
export let schema: ConfigMeta; export let schema: ConfigMeta;
export let startInEditModeIfUnset: boolean = false export let startInEditModeIfUnset: boolean = !schema.hints.ifunset
let value = new UIEventSource<string | any>(undefined); let value = new UIEventSource<string | any>(undefined);
const isTranslation = schema.hints.typehint === "translation" || schema.hints.typehint === "rendered" || ConfigMetaUtils.isTranslation(schema); const isTranslation = schema.hints.typehint === "translation" || schema.hints.typehint === "rendered" || ConfigMetaUtils.isTranslation(schema);
@ -118,8 +119,8 @@
err = path.join(".") + " " + e; err = path.join(".") + " " + e;
} }
let startValue = state.getCurrentValueFor(path); let startValue = state.getCurrentValueFor(path);
const tags = new UIEventSource<Record<string, string>>({ value: startValue });
let startInEditMode = !startValue && startInEditModeIfUnset let startInEditMode = !startValue && startInEditModeIfUnset
const tags = new UIEventSource<Record<string, string>>({ value: startValue });
try { try {
onDestroy(state.register(path, tags.map(tgs => { onDestroy(state.register(path, tags.map(tgs => {
const v = tgs["value"]; const v = tgs["value"];
@ -161,12 +162,12 @@
<div class="w-full flex flex-col"> <div class="w-full flex flex-col">
<TagRenderingEditable editMode={startInEditMode} {config} selectedElement={undefined} showQuestionIfUnknown={true} {state} {tags} /> <TagRenderingEditable editMode={startInEditMode} {config} selectedElement={undefined} showQuestionIfUnknown={true} {state} {tags} />
{#if $messages.length > 0} {#if $messages.length > 0}
{#each $messages as msg} {#each $messages as message}
<div class="alert">{msg.message}</div> <ShowConversionMessage {message}/>
{/each} {/each}
{/if} {/if}
{#if window.location.hostname === "127.0.0.1"} {#if window.location.hostname === "127.0.0.1"}
<span class="subtle">{path.join(".")} {schema.hints.typehint}</span> <span class="subtle">SchemaBasedField <b>{path.join(".")}</b> <span class="cursor-pointer" on:click={() => console.log(schema)}>{schema.hints.typehint}</span></span>
{/if} {/if}
</div> </div>
{/if} {/if}

View file

@ -13,6 +13,7 @@
import type { JsonSchemaType } from "./jsonSchema"; import type { JsonSchemaType } from "./jsonSchema";
// @ts-ignore // @ts-ignore
import nmd from "nano-markdown"; import nmd from "nano-markdown";
import ShowConversionMessage from "./ShowConversionMessage.svelte";
/** /**
* If 'types' is defined: allow the user to pick one of the types to input. * If 'types' is defined: allow the user to pick one of the types to input.
@ -216,9 +217,12 @@
path={[...subpath, (subschema?.path?.at(-1) ?? "???")]}></SchemaBasedInput> path={[...subpath, (subschema?.path?.at(-1) ?? "???")]}></SchemaBasedInput>
{/each} {/each}
{:else if $messages.length > 0} {:else if $messages.length > 0}
{#each $messages as msg} {#each $messages as message}
<div class="alert">{msg.message}</div> <ShowConversionMessage {message}/>
{/each} {/each}
{/if} {/if}
{/if} {/if}
{#if window.location.hostname === "127.0.0.1"}
<span class="subtle">SchemaBasedMultiType <b>{path.join(".")}</b> <span class="cursor-pointer" on:click={() => console.log(schema)}>{schema.hints.typehint}</span></span>
{/if}
</div> </div>

View file

@ -0,0 +1,30 @@
<script lang="ts">
import type { ConversionMessage } from "../../Models/ThemeConfig/Conversion/Conversion";
import { ExclamationTriangleIcon } from "@babeard/svelte-heroicons/solid";
import { ExclamationCircleIcon, ExclamationIcon, InformationCircleIcon } from "@rgossiaux/svelte-heroicons/solid";
/**
* Single conversion message, styled depending on the type
*/
export let message: ConversionMessage;
</script>
{#if message.level === "error"}
<div class="alert flex justify-between items-center">
<ExclamationIcon class="w-6 h-6 mx-1 shrink-0" />
{message.message}
<div/>
</div>
{:else if message.level === "warning"}
<div class="warning flex justify-between items-center">
<ExclamationIcon class="w-6 h-6 mx-1 shrink-0" />
{message.message}
<div/>
</div>
{:else if message.level === "information"}
<div class="information flex justify-between items-center">
<InformationCircleIcon class="w-6 h-6 mx-1 shrink-0" />
{message.message}
<div/>
</div>
{/if}

View file

@ -28,7 +28,7 @@ let value = state.getCurrentValueFor(path);
* Allows the theme builder to create 'writable' themes. * Allows the theme builder to create 'writable' themes.
* Should only be enabled for 'tagrenderings' in the theme, if the source is OSM * Should only be enabled for 'tagrenderings' in the theme, if the source is OSM
*/ */
let allowQuestions: Store<boolean> = (state.configuration.mapD(config => config.source?.geoJson === undefined)) let allowQuestions: Store<boolean> = (state.configuration.mapD(config => path.at(0) === "tagRenderings" && config.source?.geoJson === undefined))
let mappingsBuiltin: MappingConfigJson[] = []; let mappingsBuiltin: MappingConfigJson[] = [];
@ -118,7 +118,7 @@ const missing: string[] = questionableTagRenderingSchemaRaw.filter(schema => sch
{/if} {/if}
{#each ($mappings ?? []) as mapping, i (mapping)} {#each ($mappings ?? []) as mapping, i (mapping)}
<div class="flex interactive w-full"> <div class="flex interactive w-full">
<MappingInput {mapping} {state} path={path.concat(["mappings", i])}> <MappingInput {state} path={path.concat(["mappings", i])}>
<button slot="delete" class="rounded-full no-image-background" on:click={() => { <button slot="delete" class="rounded-full no-image-background" on:click={() => {
initMappings(); initMappings();
mappings.data.splice(i, 1) mappings.data.splice(i, 1)
@ -132,7 +132,7 @@ const missing: string[] = questionableTagRenderingSchemaRaw.filter(schema => sch
<button class="primary" <button class="primary"
on:click={() =>{ initMappings(); mappings.data.push({if: undefined, then: {}}); mappings.ping()} }> on:click={() =>{ initMappings(); mappings.data.push({if: undefined, then: {}}); mappings.ping()} }>
Add a mapping Add a predefined option
</button> </button>
<SchemaBasedField {state} path={[...path,"multiAnswer"]} schema={topLevelItems["multiAnswer"]} /> <SchemaBasedField {state} path={[...path,"multiAnswer"]} schema={topLevelItems["multiAnswer"]} />

View file

@ -16,8 +16,12 @@
-style which is used if there is nothing special going on. Some general information, with at most -style which is used if there is nothing special going on. Some general information, with at most
<a href="https://example.com" target="_blank">a link to someplace</a> <a href="https://example.com" target="_blank">a link to someplace</a>
. .
<span class="alert">Alert: something went wrong</span> <div class="alert">Alert: something went wrong</div>
<span class="thanks">Thank you! Operation successful</span> <div class="warning">Warning</div>
<div class="information">Some important information</div>
<div class="thanks">Thank you! Operation successful</div>
<ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} /> <ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} />
<Loading>Loading...</Loading> <Loading>Loading...</Loading>
</div> </div>
@ -63,7 +67,7 @@
</div> </div>
<input type="text" /> <input type="text" />
<div> <div class="flex flex-col">
<label class="checked" for="html"> <label class="checked" for="html">
<input id="html" name="fav_language" type="radio" value="HTML" /> <input id="html" name="fav_language" type="radio" value="HTML" />
HTML (mimicks a HTML (mimicks a
@ -81,8 +85,11 @@
</label> </label>
</div> </div>
<span class="alert">Alert: something went wrong</span> <div class="alert">Alert: something went wrong</div>
<span class="thanks">Thank you! Operation successful</span> <div class="warning">Warning</div>
<div class="information">Some important information</div>
<div class="thanks">Thank you! Operation successful</div>
<ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} /> <ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} />
<Loading>Loading...</Loading> <Loading>Loading...</Loading>
</div> </div>
@ -118,8 +125,12 @@
Secondary action (disabled) Secondary action (disabled)
</button> </button>
</div> </div>
<span class="alert">Alert: something went wrong</span> <div class="alert">Alert: something went wrong</div>
<span class="thanks">Thank you! Operation successful</span> <div class="warning">Warning</div>
<div class="information">Some important information</div>
<div class="thanks">Thank you! Operation successful</div>
<ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} /> <ToSvelte construct={Svg.login_svg().SetClass("w-12 h-12")} />
<Loading>Loading...</Loading> <Loading>Loading...</Loading>
<div> <div>

View file

@ -290,7 +290,7 @@
selectedElement.setData(undefined) selectedElement.setData(undefined)
}} }}
> >
<ToSvelte construct={new VariableUiElement(selectedElementView)} /> <ToSvelte construct={new VariableUiElement(selectedElementView).SetClass("h-full flex")} />
</FloatOver> </FloatOver>
</If> </If>

View file

@ -9783,7 +9783,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "How would you describe this feature?" "question": "How would you describe this feature?",
"ifunset": "No extra description is given. This can be used to further explain the preset"
}, },
"type": [ "type": [
{ {
@ -9816,7 +9817,556 @@
"required": false, "required": false,
"hints": { "hints": {
"question": "Should the created point be snapped to a line layer?", "question": "Should the created point be snapped to a line layer?",
"suggestions": [] "suggestions": [
{
"if": "value=address",
"then": "address - Addresses"
},
{
"if": "value=advertising",
"then": "advertising - We will complete data from advertising features with reference, operator and lit"
},
{
"if": "value=ambulancestation",
"then": "ambulancestation - An ambulance station is an area for storage of ambulance vehicles, medical equipment, personal protective equipment, and other medical supplies."
},
{
"if": "value=animal_shelter",
"then": "animal_shelter - An animal shelter is a facility where animals in trouble are brought and facility's staff (volunteers or not) feeds them and cares of them, rehabilitating and healing them if necessary. This definition includes kennels for abandoned dogs, catteries for abandoned cats, shelters for other abandoned pets and wildlife recovery centres. "
},
{
"if": "value=artwork",
"then": "artwork - An open map of statues, busts, graffitis and other artwork all over the world"
},
{
"if": "value=atm",
"then": "atm - ATMs to withdraw money"
},
{
"if": "value=bank",
"then": "bank - A financial institution to deposit money"
},
{
"if": "value=barrier",
"then": "barrier - Obstacles while cycling, such as bollards and cycle barriers"
},
{
"if": "value=bench",
"then": "bench - A bench is a wooden, metal, stone, … surface where a human can sit. This layers visualises them and asks a few questions about them."
},
{
"if": "value=bench_at_pt",
"then": "bench_at_pt - A layer showing all public-transport-stops which do have a bench"
},
{
"if": "value=bicycle_library",
"then": "bicycle_library - A facility where bicycles can be lent for longer period of times"
},
{
"if": "value=bicycle_rental",
"then": "bicycle_rental - Bicycle rental stations"
},
{
"if": "value=bicycle_tube_vending_machine",
"then": "bicycle_tube_vending_machine - A layer showing vending machines for bicycle tubes (either purpose-built bicycle tube vending machines or classical vending machines with bicycle tubes and optionally additional bicycle related objects such as lights, gloves, locks, …)"
},
{
"if": "value=bike_cafe",
"then": "bike_cafe - A bike café is a café geared towards cyclists, for example with services such as a pump, with lots of bicycle-related decoration, …"
},
{
"if": "value=bike_cleaning",
"then": "bike_cleaning - A layer showing facilities where one can clean their bike"
},
{
"if": "value=bike_parking",
"then": "bike_parking - A layer showing where you can park your bike"
},
{
"if": "value=bike_repair_station",
"then": "bike_repair_station - A layer showing bicycle pumps and bicycle repair tool stands"
},
{
"if": "value=bike_shop",
"then": "bike_shop - A shop specifically selling bicycles or related items"
},
{
"if": "value=bike_themed_object",
"then": "bike_themed_object - A layer with bike-themed objects but who don't match any other layer"
},
{
"if": "value=binocular",
"then": "binocular - Binoculars"
},
{
"if": "value=birdhide",
"then": "birdhide - A birdhide"
},
{
"if": "value=cafe_pub",
"then": "cafe_pub - A layer showing cafés and pubs where one can gather around a drink. The layer asks for some relevant questions"
},
{
"if": "value=car_rental",
"then": "car_rental - Places where you can rent a car"
},
{
"if": "value=charging_station",
"then": "charging_station - A charging station"
},
{
"if": "value=climbing",
"then": "climbing - A dummy layer which contains tagrenderings, shared among the climbing layers"
},
{
"if": "value=climbing_area",
"then": "climbing_area - An area where climbing is possible, e.g. a crag, site, boulder, … Contains aggregation of routes"
},
{
"if": "value=climbing_club",
"then": "climbing_club - A climbing club or organisation"
},
{
"if": "value=climbing_gym",
"then": "climbing_gym - A climbing gym"
},
{
"if": "value=climbing_opportunity",
"then": "climbing_opportunity - Fallback layer with items on which climbing _might_ be possible. It is loaded when zoomed in a lot, to prevent duplicate items to be added"
},
{
"if": "value=climbing_route",
"then": "climbing_route - A single climbing route and its properties. Some properties are derived from the containing features"
},
{
"if": "value=clock",
"then": "clock - Layer with public clocks"
},
{
"if": "value=conflation",
"then": "conflation - If the import-button moves OSM points, the imported way points or conflates, a preview is shown. This layer defines how this preview is rendered. This layer cannot be included in a theme."
},
{
"if": "value=crab_address",
"then": "crab_address - Address data for Flanders by the governement, suited for import into OpenStreetMap. Datadump from 2021-10-26. This layer contains only visualisation logic. Import buttons should be added via an override. Note that HNRLABEL contains the original value, whereas _HNRLABEL contains a slightly cleaned version"
},
{
"if": "value=crossings",
"then": "crossings - Crossings for pedestrians and cyclists"
},
{
"if": "value=current_view",
"then": "current_view - A meta-layer which contains one single feature, namely the bounding box of the current map view. This can be used to trigger special actions. If a popup is defined for this layer, this popup will be accessible via an extra button on screen.\n\nThe icon on the button is the default icon of the layer, but can be customized by detecting 'button=yes'."
},
{
"if": "value=cycleways_and_roads",
"then": "cycleways_and_roads - All infrastructure that someone can cycle over, accompanied with questions about this infrastructure"
},
{
"if": "value=defibrillator",
"then": "defibrillator - A layer showing defibrillators which can be used in case of emergency. This contains public defibrillators, but also defibrillators which might need staff to fetch the actual device"
},
{
"if": "value=dentist",
"then": "dentist - This layer shows dentist offices"
},
{
"if": "value=direction",
"then": "direction - This layer visualizes directions"
},
{
"if": "value=doctors",
"then": "doctors - This layer shows doctor offices"
},
{
"if": "value=dogpark",
"then": "dogpark - A layer showing dogparks, which are areas where dog are allowed to run without a leash"
},
{
"if": "value=drinking_water",
"then": "drinking_water - A layer showing drinking water fountains"
},
{
"if": "value=elevator",
"then": "elevator - This layer show elevators and asks for operational status and elevator dimensions. Useful for wheelchair accessibility information"
},
{
"if": "value=elongated_coin",
"then": "elongated_coin - Layer showing penny presses."
},
{
"if": "value=entrance",
"then": "entrance - A layer showing entrances and offering capabilities to survey some advanced data which is important for e.g. wheelchair users (but also bicycle users, people who want to deliver, …)"
},
{
"if": "value=etymology",
"then": "etymology - All objects which have an etymology known"
},
{
"if": "value=extinguisher",
"then": "extinguisher - Map layer to show fire extinguishers."
},
{
"if": "value=filters",
"then": "filters - This layer acts as library for common filters"
},
{
"if": "value=fire_station",
"then": "fire_station - Map layer to show fire stations."
},
{
"if": "value=fitness_centre",
"then": "fitness_centre - Layer showing fitness centres"
},
{
"if": "value=fitness_station",
"then": "fitness_station - Find a fitness station near you, and add missing ones."
},
{
"if": "value=fixme",
"then": "fixme - OSM objects that likely need to be fixed, based on a FIXME tag."
},
{
"if": "value=food",
"then": "food - A layer showing restaurants and fast-food amenities (with a special rendering for friteries)"
},
{
"if": "value=ghost_bike",
"then": "ghost_bike - A layer showing memorials for cyclists, killed in road accidents"
},
{
"if": "value=governments",
"then": "governments - This layer show governmental buildings. It was setup as commissioned layer for the client of OSOC '22"
},
{
"if": "value=gps_location",
"then": "gps_location - Meta layer showing the current location of the user. Add this to your theme and override the icon to change the appearance of the current location. The object will always have `id=gps` and will have _all_ the properties included in the [`Coordinates`-object](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationCoordinates) (except latitude and longitude) returned by the browser, such as `speed`, `altitude`, `heading`, ...."
},
{
"if": "value=gps_location_history",
"then": "gps_location_history - Meta layer which contains the previous locations of the user as single points. This is mainly for technical reasons, e.g. to keep match the distance to the modified object"
},
{
"if": "value=gps_track",
"then": "gps_track - Meta layer showing the previous locations of the user as single line with controls, e.g. to erase, upload or download this track. Add this to your theme and override the maprendering to change the appearance of the travelled track."
},
{
"if": "value=guidepost",
"then": "guidepost - Guideposts (also known as fingerposts or finger posts) are often found along official hiking/cycling/riding/skiing routes to indicate the directions to different destinations"
},
{
"if": "value=hackerspace",
"then": "hackerspace - Hackerspace"
},
{
"if": "value=home_location",
"then": "home_location - Meta layer showing the home location of the user. The home location can be set in the [profile settings](https://www.openstreetmap.org/profile/edit) of OpenStreetMap."
},
{
"if": "value=hospital",
"then": "hospital - A layer showing hospital grounds"
},
{
"if": "value=hotel",
"then": "hotel - Layer showing all hotels"
},
{
"if": "value=hydrant",
"then": "hydrant - Map layer to show fire hydrants."
},
{
"if": "value=ice_cream",
"then": "ice_cream - A place where ice cream is sold over the counter"
},
{
"if": "value=icons",
"then": "icons - A layer acting as library for icon-tagrenderings, especially to show as badge next to a POI"
},
{
"if": "value=id_presets",
"then": "id_presets - Layer containing various presets and questions generated by ID. These are meant to be reused in other layers by importing the tagRenderings with `id_preset.<tagrendering>"
},
{
"if": "value=import_candidate",
"then": "import_candidate - Layer used as template in the importHelper"
},
{
"if": "value=indoors",
"then": "indoors - Basic indoor mapping: shows room outlines"
},
{
"if": "value=information_board",
"then": "information_board - A layer showing touristical, road side information boards (e.g. giving information about the landscape, a building, a feature, a map, …)"
},
{
"if": "value=kerbs",
"then": "kerbs - A layer showing kerbs."
},
{
"if": "value=kindergarten_childcare",
"then": "kindergarten_childcare - Shows kindergartens and preschools. Both are grouped in one layer, as they are regularly confused with each other"
},
{
"if": "value=last_click",
"then": "last_click - This layer defines how to render the 'last click'-location. By default, it will show a marker with the possibility to add a new point (if there are some presets) and/or to add a new note (if the 'note' layer attribute is set). If none are possible, this layer won't show up"
},
{
"if": "value=map",
"then": "map - A map, meant for tourists which is permanently installed in the public space"
},
{
"if": "value=maproulette",
"then": "maproulette - Layer showing all tasks in MapRoulette"
},
{
"if": "value=maproulette_challenge",
"then": "maproulette_challenge - Layer showing tasks of a single MapRoulette challenge. This layer is intended to be reused and extended in themes; refer to [the documentation](https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Integrating_Maproulette.md) on how to do this."
},
{
"if": "value=maxspeed",
"then": "maxspeed - Shows the allowed speed for every road"
},
{
"if": "value=memorial",
"then": "memorial - Layer showing memorial plaques, based upon a unofficial theme. Can be expanded to have multiple types of memorials later on"
},
{
"if": "value=named_streets",
"then": "named_streets - Hidden layer with all streets which have a name. Useful to detect addresses"
},
{
"if": "value=nature_reserve",
"then": "nature_reserve - A nature reserve is an area where nature can take its course"
},
{
"if": "value=note",
"then": "note - This layer shows notes on OpenStreetMap. Having this layer in your theme will trigger the 'add new note' functionality in the 'addNewPoint'-popup (or if your theme has no presets, it'll enable adding notes)"
},
{
"if": "value=observation_tower",
"then": "observation_tower - Towers with a panoramic view"
},
{
"if": "value=osm_community_index",
"then": "osm_community_index - A layer showing the OpenStreetMap Communities"
},
{
"if": "value=parcel_lockers",
"then": "parcel_lockers - Layer showing parcel lockers for collecting and sending parcels."
},
{
"if": "value=parking",
"then": "parking - A layer showing car parkings"
},
{
"if": "value=parking_spaces",
"then": "parking_spaces - Layer showing individual parking spaces."
},
{
"if": "value=parking_ticket_machine",
"then": "parking_ticket_machine - Layer with parking ticket machines to pay for parking."
},
{
"if": "value=pedestrian_path",
"then": "pedestrian_path - Pedestrian footpaths, especially used for indoor navigation and snapping entrances to this layer"
},
{
"if": "value=pharmacy",
"then": "pharmacy - A layer showing pharmacies, which (probably) dispense prescription drugs"
},
{
"if": "value=physiotherapist",
"then": "physiotherapist - This layer shows physiotherapists"
},
{
"if": "value=picnic_table",
"then": "picnic_table - The layer showing picnic tables"
},
{
"if": "value=play_forest",
"then": "play_forest - Een speelbos is een vrij toegankelijke zone in een bos"
},
{
"if": "value=playground",
"then": "playground - Playgrounds"
},
{
"if": "value=postboxes",
"then": "postboxes - The layer showing postboxes."
},
{
"if": "value=postoffices",
"then": "postoffices - A layer showing post offices."
},
{
"if": "value=public_bookcase",
"then": "public_bookcase - A streetside cabinet with books, accessible to anyone"
},
{
"if": "value=questions",
"then": "questions - Special library layer which does not need a '.questions'-prefix before being imported"
},
{
"if": "value=railway_platforms",
"then": "railway_platforms - Find every platform in the station, and the train routes that use them."
},
{
"if": "value=rainbow_crossings",
"then": "rainbow_crossings - A layer showing pedestrian crossings with rainbow paintings"
},
{
"if": "value=range",
"then": "range - Meta-layer, simply showing a bbox in red"
},
{
"if": "value=reception_desk",
"then": "reception_desk - A layer showing where the reception desks are and which asks some accessibility information"
},
{
"if": "value=recycling",
"then": "recycling - A layer with recycling containers and centres"
},
{
"if": "value=route_marker",
"then": "route_marker - Route markers are small markers often found along official hiking/cycling/riding/skiing routes to indicate the direction of the route."
},
{
"if": "value=school",
"then": "school - Schools giving primary and secondary education and post-secondary, non-tertiary education. Note that this level of education does not imply an age of the pupiles"
},
{
"if": "value=selected_element",
"then": "selected_element - Highlights the currently selected element. Override this layer to have different colors"
},
{
"if": "value=shelter",
"then": "shelter - Layer showing shelter structures"
},
{
"if": "value=shops",
"then": "shops - A shop"
},
{
"if": "value=shower",
"then": "shower - A layer showing (public) showers"
},
{
"if": "value=slow_roads",
"then": "slow_roads - All carfree roads"
},
{
"if": "value=speed_camera",
"then": "speed_camera - Layer showing speed cameras"
},
{
"if": "value=speed_display",
"then": "speed_display - Layer showing speed displays that alert drivers of their speed."
},
{
"if": "value=split_point",
"then": "split_point - Layer rendering the little scissors for the minimap in the 'splitRoadWizard'"
},
{
"if": "value=split_road",
"then": "split_road - Layer rendering the way to split in the 'splitRoadWizard'. This one is used instead of the variable rendering by the themes themselves, as they might not always be very visible"
},
{
"if": "value=sport_pitch",
"then": "sport_pitch - A sport pitch"
},
{
"if": "value=sports_centre",
"then": "sports_centre - Indoor and outdoor sports centres can be found on this layer"
},
{
"if": "value=stairs",
"then": "stairs - Layer showing stairs and escalators"
},
{
"if": "value=street_lamps",
"then": "street_lamps - A layer showing street lights"
},
{
"if": "value=surveillance_camera",
"then": "surveillance_camera - This layer shows surveillance cameras and allows a contributor to update information and add new cameras"
},
{
"if": "value=tertiary_education",
"then": "tertiary_education - Layer with all tertiary education institutes (ISCED:2011 levels 6,7 and 8)"
},
{
"if": "value=ticket_machine",
"then": "ticket_machine - Find ticket machines for public transport tickets"
},
{
"if": "value=ticket_validator",
"then": "ticket_validator - Find ticket validators to validate public transport tickets"
},
{
"if": "value=toilet",
"then": "toilet - A layer showing (public) toilets"
},
{
"if": "value=toilet_at_amenity",
"then": "toilet_at_amenity - A layer showing (public) toilets located at different places."
},
{
"if": "value=trail",
"then": "trail - Waymarked trails"
},
{
"if": "value=transit_routes",
"then": "transit_routes - Layer showing bus lines"
},
{
"if": "value=transit_stops",
"then": "transit_stops - Layer showing different types of transit stops."
},
{
"if": "value=tree_node",
"then": "tree_node - A layer showing trees"
},
{
"if": "value=usersettings",
"then": "usersettings - A special layer which is not meant to be shown on a map, but which is used to set user settings"
},
{
"if": "value=vending_machine",
"then": "vending_machine - Layer showing vending machines"
},
{
"if": "value=veterinary",
"then": "veterinary - A layer showing veterinarians"
},
{
"if": "value=viewpoint",
"then": "viewpoint - A nice viewpoint or nice view. Ideal to add an image if no other category fits"
},
{
"if": "value=village_green",
"then": "village_green - A layer showing village-green (which are communal green areas, but not quite parks)"
},
{
"if": "value=visitor_information_centre",
"then": "visitor_information_centre - A visitor center offers information about a specific attraction or place of interest where it is located."
},
{
"if": "value=walls_and_buildings",
"then": "walls_and_buildings - Special builtin layer providing all walls and buildings. This layer is useful in presets for objects which can be placed against walls (e.g. AEDs, postboxes, entrances, addresses, surveillance cameras, …). This layer is invisible by default and not toggleable by the user."
},
{
"if": "value=waste_basket",
"then": "waste_basket - This is a public waste basket, thrash can, where you can throw away your thrash."
},
{
"if": "value=waste_disposal",
"then": "waste_disposal - Waste Disposal Bin, medium to large bin for disposal of (household) waste"
},
{
"if": "value=windturbine",
"then": "windturbine - Modern windmills generating electricity"
}
]
}, },
"type": "array", "type": "array",
"description": "If specified, these layers will be shown in the precise location picker and the new point will be snapped towards it.\nFor example, this can be used to snap against `walls_and_buildings` (e.g. to attach a defibrillator, an entrance, an artwork, ... to the wall)\nor to snap an obstacle (such as a bollard) to the `cycleways_and_roads`." "description": "If specified, these layers will be shown in the precise location picker and the new point will be snapped towards it.\nFor example, this can be used to snap against `walls_and_buildings` (e.g. to attach a defibrillator, an entrance, an artwork, ... to the wall)\nor to snap an obstacle (such as a bollard) to the `cycleways_and_roads`."
@ -9843,7 +10393,7 @@
"hints": { "hints": {
"typehint": "tagrendering[]", "typehint": "tagrendering[]",
"group": "tagrenderings", "group": "tagrenderings",
"question": "Which tagRenderings should be shown in the infobox?" "question": "Edit this tagRendering"
}, },
"type": [ "type": [
{ {
@ -9869,7 +10419,7 @@
"type": "object", "type": "object",
"properties": { "properties": {
"key": { "key": {
"description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\n\nifunset: do not offer a freeform textfield as answer option", "description": "question: What is the name of the attribute that should be written to?\nThis is the OpenStreetMap-key that that value will be written to\nifunset: do not offer a freeform textfield as answer option",
"type": "string" "type": "string"
}, },
"type": { "type": {
@ -10353,7 +10903,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "What tags should be applied if this mapping is _not_ chosen?" "question": "What tags should be applied if this mapping is _not_ chosen?",
"ifunset": "Do not apply a tag if a different mapping is chosen."
}, },
"type": [ "type": [
{ {
@ -11477,7 +12028,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "What tags should be applied if this mapping is _not_ chosen?" "question": "What tags should be applied if this mapping is _not_ chosen?",
"ifunset": "Do not apply a tag if a different mapping is chosen."
}, },
"type": [ "type": [
{ {
@ -12645,7 +13197,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "What tags should be applied if this mapping is _not_ chosen?" "question": "What tags should be applied if this mapping is _not_ chosen?",
"ifunset": "Do not apply a tag if a different mapping is chosen."
}, },
"type": [ "type": [
{ {
@ -13814,7 +14367,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "What tags should be applied if this mapping is _not_ chosen?" "question": "What tags should be applied if this mapping is _not_ chosen?",
"ifunset": "Do not apply a tag if a different mapping is chosen."
}, },
"type": [ "type": [
{ {

File diff suppressed because it is too large Load diff

View file

@ -232,7 +232,8 @@
], ],
"required": false, "required": false,
"hints": { "hints": {
"question": "What tags should be applied if this mapping is _not_ chosen?" "question": "What tags should be applied if this mapping is _not_ chosen?",
"ifunset": "Do not apply a tag if a different mapping is chosen."
}, },
"type": [ "type": [
{ {

View file

@ -404,6 +404,38 @@ select:hover {
border: 2px dotted #ff9143; border: 2px dotted #ff9143;
} }
.warning {
/* The class to convey important information, but not as grave as 'alert' */
background-color: var(--low-interaction-background);
color: var(--alert-foreground-color);
font-weight: bold;
border-radius: 1em;
margin: 0.25em;
text-align: center;
padding: 0.15em 0.3em;
border: 3px dotted #ff9143;
}
.low-interaction .warning {
background-color: var(--interactive-background);
}
.information {
/* The class to convey important information which does _not_ denote an error... */
background-color: var(--low-interaction-background);
color: var(--alert-foreground-color);
border-radius: 1em;
margin: 0.25em;
text-align: center;
padding: 0.15em 0.3em;
border: 3px dotted var(--catch-detail-color-contrast);
}
.low-interaction .interactive {
background-color: var(--interactive-background);
}
.subtle { .subtle {
/* For all information that is not important for 99% of the users */ /* For all information that is not important for 99% of the users */
color: #999; color: #999;
@ -594,3 +626,6 @@ a.link-underline {
} }
.min-h-32 {
min-height: 8rem;
}