Lots of styling tweaks, add filter links between layers

This commit is contained in:
pietervdvn 2022-02-01 04:14:54 +01:00
parent 5cefc4d25f
commit c15f3d2036
28 changed files with 263 additions and 217 deletions

View file

@ -17,6 +17,7 @@ import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource";
import {LocalStorageSource} from "../Web/LocalStorageSource";
import {GeoOperations} from "../GeoOperations";
import TitleHandler from "../Actors/TitleHandler";
import {BBox} from "../BBox";
/**
* Contains all the leaflet-map related state
@ -73,7 +74,7 @@ export default class MapState extends UserRelatedState {
/**
* WHich layers are enabled in the current theme
* Which layers are enabled in the current theme and what filters are applied onto them
*/
public filteredLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<FilteredLayer[]>([], "filteredLayers");
/**
@ -169,11 +170,10 @@ export default class MapState extends UserRelatedState {
];
}
console.warn("Locking the bounds to ", layout.lockLocation);
this.leafletMap.addCallbackAndRunD(map => {
// @ts-ignore
map.setMaxBounds(layout.lockLocation);
map.setMinZoom(layout.startZoom);
})
this.mainMapObject.installBounds(
new BBox(layout.lockLocation),
this.featureSwitchIsTesting.data
)
}
}
@ -377,6 +377,24 @@ export default class MapState extends UserRelatedState {
flayers.push(flayer);
}
for (const layer of layoutToUse.layers) {
if(layer.filterIsSameAs === undefined){
continue
}
const toReuse = flayers.find(l => l.layerDef.id === layer.filterIsSameAs)
if(toReuse === undefined){
throw "Error in layer "+layer.id+": it defines that it should be use the filters of "+layer.filterIsSameAs+", but this layer was not loaded"
}
console.warn("Linking filter and isDisplayed-states of "+layer.id+" and "+layer.filterIsSameAs)
const selfLayer = flayers.findIndex(l => l.layerDef.id === layer.id)
flayers[selfLayer] = {
isDisplayed: toReuse.isDisplayed,
layerDef: layer,
appliedFilters: toReuse.appliedFilters
};
}
return new UIEventSource<FilteredLayer[]>(flayers);
}

View file

@ -237,7 +237,7 @@ export interface LayerConfigJson {
/**
* All the extra questions for filtering
*/
filter?: (FilterConfigJson) [],
filter?: (FilterConfigJson) [] | {sameAs: string},
/**
* This block defines under what circumstances the delete dialog is shown for objects of this layer.

View file

@ -232,7 +232,7 @@ export interface LayoutConfigJson {
/**
* If set to true, the basemap will not scroll outside of the area visible on initial zoom.
* If set to [[lat0, lon0], [lat1, lon1]], the map will not scroll outside of those bounds.
* If set to [[lon, lat], [lon, lat]], the map will not scroll outside of those bounds.
* Off by default, which will enable panning to the entire world
*/
lockLocation?: boolean | [[number, number], [number, number]] | number[][];

View file

@ -24,6 +24,7 @@ import Link from "../../UI/Base/Link";
import {Utils} from "../../Utils";
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
import Table from "../../UI/Base/Table";
import FilterConfigJson from "./Json/FilterConfigJson";
export default class LayerConfig extends WithContextLoader {
@ -58,7 +59,8 @@ export default class LayerConfig extends WithContextLoader {
public readonly tagRenderings: TagRenderingConfig[];
public readonly filters: FilterConfig[];
public readonly filterIsSameAs: string;
constructor(
json: LayerConfigJson,
context?: string,
@ -243,9 +245,14 @@ export default class LayerConfig extends WithContextLoader {
this.tagRenderings = (Utils.NoNull(json.tagRenderings) ?? []).map((tr, i) => new TagRenderingConfig(<TagRenderingConfigJson>tr, this.id + ".tagRenderings[" + i + "]"))
this.filters = (json.filter ?? []).map((option, i) => {
return new FilterConfig(option, `${context}.filter-[${i}]`)
});
if(json.filter !== undefined && json.filter !== null && json.filter["sameAs"] !== undefined){
this.filterIsSameAs = json.filter["sameAs"]
this.filters = []
}else{
this.filters = (<FilterConfigJson[]>json.filter ?? []).map((option, i) => {
return new FilterConfig(option, `${context}.filter-[${i}]`)
});
}
{
const duplicateIds = Utils.Dupiclates(this.filters.map(f => f.id))
@ -302,8 +309,7 @@ export default class LayerConfig extends WithContextLoader {
return undefined
}
const baseTags = TagUtils.changeAsProperties(this.source.osmTags.asChange({id: "node/-1"}))
return mapRendering.GenerateLeafletStyle(new UIEventSource(baseTags), false,
{noSize: true, includeBadges: false}).html
return mapRendering.GetSimpleIcon(new UIEventSource(baseTags))
}
public GenerateDocumentation(usedInThemes: string[], layerIsNeededBy: Map<string, string[]>, dependencies: {

View file

@ -66,7 +66,7 @@ export default class LayoutConfig {
this.maintainer = json.maintainer;
this.credits = json.credits;
this.version = json.version;
this.language = Array.from(Object.keys(json.title));
this.language = json.mustHaveLanguage ?? Array.from(Object.keys(json.title));
{
if (typeof json.title === "string") {

View file

@ -150,8 +150,8 @@ export default class PointRenderingConfig extends WithContextLoader {
tags: UIEventSource<any>,
clickable: boolean,
options?: {
noSize: false | boolean,
includeBadges: true | boolean
noSize?: false | boolean,
includeBadges?: true | boolean
}
):
{

View file

@ -53,14 +53,15 @@ export default class MinimapImplementation extends BaseUIElement implements Mini
public installBounds(factor: number | BBox, showRange?: boolean) {
this.leafletMap.addCallbackD(leaflet => {
let bounds;
let bounds : {getEast(), getNorth(), getWest(), getSouth()};
if (typeof factor === "number") {
bounds = leaflet.getBounds().pad(factor)
leaflet.setMaxBounds(bounds)
const lbounds = leaflet.getBounds().pad(factor)
leaflet.setMaxBounds(lbounds)
bounds = lbounds;
} else {
// @ts-ignore
leaflet.setMaxBounds(factor.toLeaflet())
bounds = leaflet.getBounds()
bounds = factor
}
if (showRange) {

View file

@ -6,6 +6,7 @@ import {UIEventSource} from "../../Logic/UIEventSource";
import Hash from "../../Logic/Web/Hash";
import BaseUIElement from "../BaseUIElement";
import Img from "./Img";
import Title from "./Title";
/**
*
@ -101,7 +102,8 @@ export default class ScrollableFullScreen extends UIElement {
Hash.hash.setData(undefined)
})
title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-0 max-h-20vh overflow-y-auto self-center")
title = new Title(title, 2)
title.SetClass("text-l sm:text-xl md:text-2xl w-full p-0 max-h-20vh overflow-y-auto self-center")
return new Combine([
new Combine([
new Combine([returnToTheMap, title])

View file

@ -21,7 +21,7 @@ export class SubtleButton extends UIElement {
}
protected InnerRender(): string | BaseUIElement {
const classes = "block flex p-3 my-2 bg-blue-100 rounded-lg hover:shadow-xl hover:bg-blue-200 link-no-underline";
const classes = "block flex p-3 my-2 bg-subtle rounded-lg hover:shadow-xl hover:bg-unsubtle transition-colors transition-shadow link-no-underline";
const message = Translations.W(this.message);
let img;
if ((this.imageUrl ?? "") === "") {

View file

@ -185,7 +185,7 @@ export default class CopyrightPanel extends Combine {
...iconAttributions
].map(e => e?.SetClass("mt-4")));
this.SetClass("flex flex-col link-underline overflow-hidden")
this.SetStyle("max-width: calc(100vw - 3em); width: 40rem; margin-left: 0.75rem; margin-right: 0.5rem")
this.SetStyle("max-width:100%; width: 40rem; margin-left: 0.75rem; margin-right: 0.5rem")
}
private static CodeContributors(): BaseUIElement {

View file

@ -115,17 +115,16 @@ export default class FilterView extends VariableUiElement {
)
const style =
"display:flex;align-items:center;padding:0.5rem 0;";
const layerIcon = layer.defaultIcon()?.SetClass("w-8 h-8 ml-2 shrink-0")
const layerIconUnchecked = layer.defaultIcon()?.SetClass("opacity-50 w-8 h-8 ml-2")
const toggleClasses = "layer-toggle flex flex-wrap items-center pt-2 pb-1 px-0";
const layerIcon = layer.defaultIcon()?.SetClass("flex-shrink-0 w-8 h-8 ml-2")
const layerIconUnchecked = layer.defaultIcon()?.SetClass("flex-shrink-0 opacity-50 w-8 h-8 ml-2")
const layerChecked = new Combine([icon, layerIcon, styledNameChecked, zoomStatus])
.SetStyle(style)
.SetClass(toggleClasses)
.onClick(() => filteredLayer.isDisplayed.setData(false));
const layerNotChecked = new Combine([iconUnselected, layerIconUnchecked, styledNameUnChecked])
.SetStyle(style)
.SetClass(toggleClasses)
.onClick(() => filteredLayer.isDisplayed.setData(true));
@ -152,7 +151,7 @@ export default class FilterView extends VariableUiElement {
const [ui, actualTags] = FilterView.createFilter(filter)
ui.SetClass("mt-3")
ui.SetClass("mt-1")
toShow.push(ui)
actualTags.addCallback(tagsToFilterFor => {
flayer.appliedFilters.data.set(filter.id, tagsToFilterFor)
@ -165,7 +164,7 @@ export default class FilterView extends VariableUiElement {
}
return new Combine(toShow)
.SetClass("flex flex-col p-2 ml-0 pl-12 bg-gray-200 pt-0 border-b-2 border-detail mb-4")
.SetClass("flex flex-col p-2 ml-12 pl-1 pt-0 border-b-2 border-detail mb-4")
}

View file

@ -35,9 +35,7 @@ export default class LeftControls extends Combine {
return defaultIcon;
}
const tags = {...feature.properties, button: "yes"}
const elem = currentViewFL.layerDef.mapRendering[0]?.GenerateLeafletStyle(new UIEventSource(tags), false, {
noSize: true
})?.html
const elem = currentViewFL.layerDef.mapRendering[0]?.GetSimpleIcon(new UIEventSource(tags));
if (elem === undefined) {
return defaultIcon
}

View file

@ -75,7 +75,7 @@ export class ImageUploadFlow extends Toggle {
const label = new Combine([
Svg.camera_plus_ui().SetClass("block w-12 h-12 p-1 text-4xl "),
labelContent
]).SetClass("p-2 border-4 border-black rounded-full font-bold h-full align-middle w-full flex justify-center")
]).SetClass("p-2 border-4 border-detail rounded-full font-bold h-full align-middle w-full flex justify-center")
const fileSelector = new FileSelectorButton(label)
fileSelector.GetValue().addCallback(filelist => {

View file

@ -62,7 +62,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
layerConfig: LayerConfig,
state: {}): BaseUIElement {
const title = new TagRenderingAnswer(tags, layerConfig.title ?? new TagRenderingConfig("POI"), state)
.SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2");
.SetClass("break-words font-bold sm:p-0.5 md:p-1 sm:p-1.5 md:p-2 text-2xl");
const titleIcons = new Combine(
layerConfig.titleIcons.map(icon => new TagRenderingAnswer(tags, icon, state,
"block w-8 h-8 max-h-8 align-baseline box-content sm:p-0.5 w-10",)

View file

@ -111,9 +111,8 @@ export default class TagRenderingQuestion extends Combine {
const saveButton = new Combine([
options.saveButtonConstr(inputElement.GetValue()),
new Toggle(Translations.t.general.testing.SetClass("alert"), undefined, state.featureSwitchIsTesting)
])
let bottomTags: BaseUIElement;
if (options.bottomText !== undefined) {
bottomTags = options.bottomText(inputElement.GetValue())
@ -142,7 +141,9 @@ export default class TagRenderingQuestion extends Combine {
inputElement,
options.cancelButton,
saveButton,
bottomTags])
bottomTags,
new Toggle(Translations.t.general.testing.SetClass("alert"), undefined, state.featureSwitchIsTesting)
])
this.SetClass("question disable-links")

View file

@ -36,7 +36,7 @@ export class SubstitutedTranslation extends VariableUiElement {
super(
Locale.language.map(language => {
let txt = translation.textFor(language);
let txt = translation?.textFor(language);
if (txt === undefined) {
return undefined
}

View file

@ -35,7 +35,7 @@ export class Translation extends BaseUIElement {
get txt(): string {
return this.textFor(Translation.forcedLanguage ?? Locale.language.data)
}
}
static ExtractAllTranslationsFrom(object: any, context = ""): { context: string, tr: Translation }[] {
const allTranslations: { context: string, tr: Translation }[] = []

View file

@ -305,6 +305,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
if (!source.hasOwnProperty(key)) {
continue
}
if (key.startsWith("=")) {
const trimmedKey = key.substr(1);
target[trimmedKey] = source[key]
continue
}
if (key.startsWith("+") || key.endsWith("+")) {
const trimmedKey = key.replace("+", "");
const sourceV = source[key];

View file

@ -8,7 +8,7 @@
},
"mapRendering": [
{
"icon": "crosshair:#00f",
"icon": "crosshair:var(--catch-detail-color)",
"iconSize": "40,40,center",
"location": [
"point",

View file

@ -151,8 +151,9 @@
]
},
"then": {
"nl": "<img src=\"./assets/layers/nature_reserve/Natuurpunt.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door Natuurpunt"
}
"nl": "Dit gebied wordt beheerd door Natuurpunt"
},
"icon": "./assets/layers/nature_reserve/Natuurpunt.jpg"
},
{
"if": {
@ -161,8 +162,9 @@
]
},
"then": {
"nl": "<img src=\"./assets/layers/nature_reserve/Natuurpunt.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door {operator}"
"nl": "Dit gebied wordt beheerd door {operator}"
},
"icon": "./assets/layers/nature_reserve/Natuurpunt.jpg",
"hideInAnswer": true
},
{
@ -172,8 +174,9 @@
]
},
"then": {
"nl": "<img src=\"./assets/layers/nature_reserve/ANB.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door het Agentschap Natuur en Bos"
}
"nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos"
},
"icon": "./assets/layers/nature_reserve/ANB.jpg"
}
],
"id": "Operator tag"

View file

@ -1,9 +1,11 @@
:root {
--subtle-detail-color: #007759;
--subtle-detail-color-contrast: #ffffff;
--subtle-detail-color-light-contrast: lightgrey;
--subtle-detail-color-light-contrast: white;
--catch-detail-color: #0fff00;
--unsubtle-detail-color: #b34f26;
--unsubtle-detail-color-contrast: #ffffff;
--catch-detail-color: #FE6F32;
--catch-detail-color-contrast: #ffffff;
--alert-color: #fee4d1;
--background-color: white;
@ -31,7 +33,21 @@ body {
font-family: 'Open Sans Regular', sans-serif;
}
h1 h2 h3 h4 {
.layer-toggle .alert {
background: unset !important;
padding: 0 !important;
}
.layer-toggle svg path {
fill: var(--foreground-color) !important;
}
.layer-toggle .alert::before {
content: " - "
}
h1, h2, h3, h4 {
font-family: 'Amaranth', sans-serif;
}
@ -43,4 +59,4 @@ h1 h2 h3 h4 {
.tab-non-active svg path {
fill: white !important;
stroke: white !important;
}
}

View file

@ -30,6 +30,7 @@
"startLat": 51.20875,
"startLon": 3.22435,
"startZoom": 15,
"lockLocation": [[2.1,50.40],[ 6.4,51.54]],
"widenFactor": 2,
"socialImage": "",
"defaultBackgroundId": "CartoDB.Positron",
@ -64,7 +65,10 @@
"render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg"
}
}
]
],
"=filter": {
"sameAs": "nature_reserve_centerpoints"
}
}
},
{
@ -183,7 +187,12 @@
"source": {
"geoJson": "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/natuurpunt_cache/natuurpunt_{layer}_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 12,
"isOsmCache": true
"isOsmCache": true,
"osmTags": {
"+and": [
"operator~.*[nN]atuurpunt.*"
]
}
},
"mapRendering": [
{
@ -313,7 +322,7 @@
}
},
{
"builtin": "gps_location_history",
"builtin": "gps_track",
"override": {
"name": null
}

View file

@ -896,12 +896,12 @@ video {
margin-left: 0.5rem;
}
.mt-3 {
margin-top: 0.75rem;
.ml-12 {
margin-left: 3rem;
}
.ml-0 {
margin-left: 0px;
.mt-3 {
margin-top: 0.75rem;
}
.mb-10 {
@ -1437,11 +1437,6 @@ video {
background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
}
.bg-blue-100 {
--tw-bg-opacity: 1;
background-color: rgba(219, 234, 254, var(--tw-bg-opacity));
}
.bg-gray-400 {
--tw-bg-opacity: 1;
background-color: rgba(156, 163, 175, var(--tw-bg-opacity));
@ -1452,16 +1447,16 @@ video {
background-color: rgba(224, 231, 255, var(--tw-bg-opacity));
}
.bg-gray-200 {
--tw-bg-opacity: 1;
background-color: rgba(229, 231, 235, var(--tw-bg-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
}
.bg-gray-200 {
--tw-bg-opacity: 1;
background-color: rgba(229, 231, 235, var(--tw-bg-opacity));
}
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgba(243, 244, 246, var(--tw-bg-opacity));
@ -1514,6 +1509,11 @@ video {
padding: 2rem;
}
.px-0 {
padding-left: 0px;
padding-right: 0px;
}
.pb-12 {
padding-bottom: 3rem;
}
@ -1546,8 +1546,8 @@ video {
padding-right: 0.25rem;
}
.pl-12 {
padding-left: 3rem;
.pt-2 {
padding-top: 0.5rem;
}
.pt-0 {
@ -1590,10 +1590,6 @@ video {
padding-left: 1.5rem;
}
.pt-2 {
padding-top: 0.5rem;
}
.text-center {
text-align: center;
}
@ -1783,6 +1779,12 @@ video {
transition-duration: 150ms;
}
.transition-shadow {
transition-property: box-shadow;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.transition-opacity {
transition-property: opacity;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@ -1805,101 +1807,17 @@ video {
z-index: 10001
}
.btn {
display: inline-flex;
justify-content: center;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
padding-right: 1rem;
border-width: 1px;
border-color: transparent;
--tw-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
border-radius: 1.5rem;
--tw-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-ring-opacity: 1;
--tw-ring-color: rgba(191, 219, 254, var(--tw-ring-opacity));
}
.btn:hover {
--tw-ring-opacity: 1;
--tw-ring-color: rgba(147, 197, 253, var(--tw-ring-opacity));
}
.btn {
margin-top: 0.25rem;
margin-right: 0.25rem;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 500;
--tw-text-opacity: 1;
color: rgba(255, 255, 255, var(--tw-text-opacity));
--tw-bg-opacity: 1;
background-color: rgba(37, 99, 235, var(--tw-bg-opacity));
}
.btn:hover {
--tw-bg-opacity: 1;
background-color: rgba(29, 78, 216, var(--tw-bg-opacity));
}
.btn:focus {
outline: 2px solid transparent;
outline-offset: 2px;
--tw-ring-opacity: 1;
--tw-ring-color: rgba(29, 78, 216, var(--tw-ring-opacity));
}
.btn-secondary {
--tw-bg-opacity: 1;
background-color: rgba(75, 85, 99, var(--tw-bg-opacity));
}
.btn-secondary:hover {
--tw-bg-opacity: 1;
background-color: rgba(55, 65, 81, var(--tw-bg-opacity));
}
.btn-disabled {
--tw-bg-opacity: 1;
background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
}
.btn-disabled:hover {
--tw-bg-opacity: 1;
background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
}
.btn-disabled {
--tw-text-opacity: 1;
color: rgba(209, 213, 219, var(--tw-text-opacity));
--tw-ring-opacity: 1;
--tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity));
}
.btn-disabled:hover {
--tw-ring-opacity: 1;
--tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity));
}
.btn-disabled:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgba(229, 231, 235, var(--tw-ring-opacity));
}
.btn-disabled {
cursor: default;
.bg-subtle {
background-color: var(--subtle-detail-color);
color: var(--subtle-detail-color-contrast);
}
:root {
--subtle-detail-color: #e5f5ff;
--subtle-detail-color: #DBEAFE;
--subtle-detail-color-contrast: black;
--subtle-detail-color-light-contrast: lightgrey;
--unsubtle-detail-color: #BFDBFE;
--unsubtle-detail-color-contrast: black;
--catch-detail-color: #3a3aeb;
--catch-detail-color-contrast: white;
--alert-color: #fee4d1;
@ -1967,16 +1885,45 @@ a {
color: var(--foreground-color);
}
btn {
margin-top: 0.25rem;
margin-right: 0.25rem;
font-size: 0.875rem;
.btn {
margin-top: 0.5rem;
margin-right: 0.5rem;
line-height: 1.25rem;
font-weight: 500;
--tw-text-opacity: 1;
color: var(--catch-detail-color-contrast);
--tw-bg-opacity: 1;
background-color: var(--catch-detail-color);
display: inline-flex;
border-radius: 1.5rem;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
padding-left: 1.25rem;
padding-right: 1.25rem;
font-size: large;
font-weight: bold;
/*-- invisible border: rendered on hover*/
border: 3px solid var(--unsubtle-detail-color);
}
.btn:hover {
border: 3px solid var(--catch-detail-color);
}
.btn-secondary {
background-color: var(--unsubtle-detail-color);
}
.btn-secondary:hover {
background-color: var(--catch-detail-color);
}
.btn-disabled {
filter: saturate(0.3);
cursor: default;
}
.btn-disabled:hover {
border: 3px solid var(--unsubtle-detail-color);
}
.h-min {
@ -2000,9 +1947,8 @@ btn {
}
.link-underline a {
-webkit-text-decoration: underline 1px #0078a855;
text-decoration: underline 1px #0078a855;
color: #0078A8;
-webkit-text-decoration: underline 1px var(--foreground-color);
text-decoration: underline 1px var(--foreground-color);
}
.link-no-underline a {
@ -2083,6 +2029,7 @@ li::marker {
}
.leaflet-container {
font: unset !important;
background-color: var(--background-color) !important;
}
@ -2134,6 +2081,7 @@ li::marker {
.alert {
background-color: var(--alert-color);
color: var(--foreground-color);
font-weight: bold;
border-radius: 1em;
margin: 0.25em;
@ -2326,6 +2274,10 @@ li::marker {
/***************** Info box (box containing features and questions ******************/
input {
color: var(--foreground-color)
}
.leaflet-popup-content {
width: 45em !important;
margin: 0.25rem !important;
@ -2383,11 +2335,6 @@ li::marker {
background-color: #f2f2f2;
}
.hover\:bg-blue-200:hover {
--tw-bg-opacity: 1;
background-color: rgba(191, 219, 254, var(--tw-bg-opacity));
}
.hover\:bg-indigo-200:hover {
--tw-bg-opacity: 1;
background-color: rgba(199, 210, 254, var(--tw-bg-opacity));
@ -2407,6 +2354,11 @@ li::marker {
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.hover\:bg-unsubtle:hover {
background-color: var(--unsubtle-detail-color);
color: var(--unsubtle-detail-color-contrast);
}
.group:hover .group-hover\:text-blue-800 {
--tw-text-opacity: 1;
color: rgba(30, 64, 175, var(--tw-text-opacity));

View file

@ -24,38 +24,33 @@
.w-160 {
width: 40rem;
}
.bg-subtle {
background-color: var(--subtle-detail-color);
color: var(--subtle-detail-color-contrast);
}
.bg-unsubtle {
background-color: var(--unsubtle-detail-color);
color: var(--unsubtle-detail-color-contrast);
}
.bg-catch {
background-color: var(--catch-detail-color);
color: var(--catch-detail-color-contrast);
}
}
.btn {
@apply inline-flex justify-center;
@apply py-2 px-4;
@apply border border-transparent shadow-sm;
@apply shadow-sm rounded-3xl;
@apply ring-2 ring-blue-200 hover:ring-blue-300;
@apply mt-1 mr-1;
@apply text-sm font-medium text-white;
@apply bg-blue-600 hover:bg-blue-700;
@apply focus:outline-none focus:ring-blue-700;
}
.btn-secondary {
@apply bg-gray-600 hover:bg-gray-700;
}
.btn-disabled {
@apply bg-gray-500 hover:bg-gray-500;
@apply text-gray-300;
@apply ring-gray-200 hover:ring-gray-200 focus:ring-gray-200;
@apply cursor-default;
}
}
:root {
--subtle-detail-color: #e5f5ff;
--subtle-detail-color: #DBEAFE;
--subtle-detail-color-contrast: black;
--subtle-detail-color-light-contrast: lightgrey;
--unsubtle-detail-color: #BFDBFE;
--unsubtle-detail-color-contrast: black;
--catch-detail-color: #3a3aeb;
--catch-detail-color-contrast: white;
--alert-color: #fee4d1;
@ -123,16 +118,45 @@ a {
color: var(--foreground-color);
}
btn {
margin-top: 0.25rem;
margin-right: 0.25rem;
font-size: 0.875rem;
.btn {
margin-top: 0.5rem;
margin-right: 0.5rem;
line-height: 1.25rem;
font-weight: 500;
--tw-text-opacity: 1;
color: var(--catch-detail-color-contrast);
--tw-bg-opacity: 1;
background-color: var(--catch-detail-color);
display: inline-flex;
border-radius: 1.5rem;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
padding-left: 1.25rem;
padding-right: 1.25rem;
font-size: large;
font-weight: bold;
/*-- invisible border: rendered on hover*/
border: 3px solid var(--unsubtle-detail-color);
}
.btn:hover {
border: 3px solid var(--catch-detail-color);
}
.btn-secondary {
background-color: var(--unsubtle-detail-color);
}
.btn-secondary:hover {
background-color: var(--catch-detail-color);
}
.btn-disabled {
filter: saturate(0.3);
cursor: default;
}
.btn-disabled:hover {
border: 3px solid var(--unsubtle-detail-color);
}
.h-min {
@ -153,8 +177,7 @@ btn {
}
.link-underline a {
text-decoration: underline 1px #0078a855;;
color: #0078A8;
text-decoration: underline 1px var(--foreground-color);
}
.link-no-underline a {
@ -239,6 +262,7 @@ li::marker {
}
.leaflet-container {
font: unset !important;
background-color: var(--background-color) !important;
}
@ -292,6 +316,7 @@ li::marker {
.alert {
background-color: var(--alert-color);
color: var(--foreground-color);
font-weight: bold;
border-radius: 1em;
margin: 0.25em;
@ -434,6 +459,9 @@ li::marker {
/***************** Info box (box containing features and questions ******************/
input {
color: var(--foreground-color)
}
.leaflet-popup-content {
width: 45em !important;
@ -489,6 +517,7 @@ li::marker {
overflow-y: hidden;
}
.zebra-table tr:nth-child(even) {
background-color: #f2f2f2;
}

View file

@ -2,6 +2,7 @@
"name": "index",
"short_name": "MapComplete",
"start_url": "index.html",
"lang": "en",
"display": "standalone",
"background_color": "#fff",
"description": "A thematic map viewer and editor based on OpenStreetMap",

View file

@ -3240,13 +3240,13 @@
"Operator tag": {
"mappings": {
"0": {
"then": "<img src=\"./assets/layers/nature_reserve/Natuurpunt.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door Natuurpunt"
"then": "Dit gebied wordt beheerd door Natuurpunt"
},
"1": {
"then": "<img src=\"./assets/layers/nature_reserve/Natuurpunt.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door {operator}"
"then": "Dit gebied wordt beheerd door {operator}"
},
"2": {
"then": "<img src=\"./assets/layers/nature_reserve/ANB.jpg\" style=\"width:1.5em\">Dit gebied wordt beheerd door het Agentschap Natuur en Bos"
"then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos"
}
},
"question": "Wie beheert dit gebied?",

View file

@ -7,12 +7,9 @@
"homepage": "https://mapcomplete.osm.be",
"main": "index.js",
"scripts": {
"increase-memory": "export NODE_OPTIONS=--max_old_space_size=8364",
"start": "npm run start:prepare && npm-run-all --parallel start:parallel:*",
"strt": "npm run start:prepare && npm run start:parallel:parcel",
"start:prepare": "ts-node scripts/generateLayerOverview.ts --no-fail && npm run increase-memory",
"start:parallel:parcel": "parcel serve *.html UI/** Logic/** assets/*.json assets/svg/* assets/generated/* assets/layers/*/*.svg assets/layers/*/*.jpg assets/layers/*/*.png assets/layers/*/*.css assets/tagRenderings/*.json assets/themes/*/*.svg assets/themes/*/*.ttf assets/themes/*/*/*.ttf aassets/themes/*/*.otf assets/themes/*/*/*.otf ssets/themes/*/*.css assets/themes/*/*.jpg assets/themes/*/*.png vendor/* vendor/*/*",
"start:parallel:tailwindcli": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch",
"start": "npm run generate:layeroverview && npm run ",
"strt": "export NODE_OPTIONS=--max_old_space_size=8364 && parcel serve *.html UI/** Logic/** assets/*.json assets/svg/* assets/generated/* assets/layers/*/*.svg assets/layers/*/*.jpg assets/layers/*/*.png assets/layers/*/*.css assets/tagRenderings/*.json assets/themes/*/*.svg assets/themes/*/*.ttf assets/themes/*/*/*.ttf aassets/themes/*/*.otf assets/themes/*/*/*.otf ssets/themes/*/*.css assets/themes/*/*.jpg assets/themes/*/*.png vendor/* vendor/*/*",
"watch:css": "tailwindcss -i index.css -o css/index-tailwind-output.css --watch",
"generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css",
"test": "ts-node test/TestAll.ts",
"init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean",

View file

@ -195,8 +195,16 @@ if (!existsSync(generatedDir)) {
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
// @ts-ignore
const all: LayoutConfigJson[] = all_known_layouts.themes;
const args = process.argv
const theme = args[2]
if(theme !== undefined){
console.warn("Only generating layout "+theme)
}
for (const i in all) {
const layoutConfigJson: LayoutConfigJson = all[i]
if(theme !== undefined && layoutConfigJson.id !== theme){
continue
}
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
const layoutName = layout.id
if (blacklist.indexOf(layoutName.toLowerCase()) >= 0) {