Refactoring: fix small errors, simplify 'sortedByLevehnstein'-function, improve error messgae

This commit is contained in:
Pieter Vander Vennet 2025-07-03 17:33:29 +02:00
parent 97b8202b14
commit 8a0023377a
13 changed files with 27 additions and 19 deletions

View file

@ -565,6 +565,10 @@
"if": "theme=rainbow_crossings",
"then": "./assets/themes/rainbow_crossings/logo.svg"
},
{
"if": "theme=sauna",
"then": "./assets/layers/sauna/sauna.svg"
},
{
"if": "theme=scouting",
"then": "./assets/layers/scouting_group/scouting.svg"

View file

@ -108,8 +108,7 @@ export default class DetermineTheme {
if (themeInfo === undefined) {
const alternatives = Utils.sortedByLevenshteinDistance(
id,
themes.map((th) => th.id),
(i) => i
themes.map((th) => th.id)
).slice(0, 3)
const msg = `No builtin map theme with name ${layoutId} exists. Perhaps you meant one of ${alternatives.join(
", "

View file

@ -111,8 +111,7 @@ export class MenuState {
"No tagRendering with id '" + highlightTagRendering + "'; maybe you meant:",
Utils.sortedByLevenshteinDistance(
highlightTagRendering,
UserRelatedState.availableUserSettingsIds,
(x) => x
UserRelatedState.availableUserSettingsIds
)
)
}

View file

@ -259,8 +259,7 @@ export class ExpandFilter extends DesugaringStep<LayerConfigJson> {
if (found === undefined) {
const suggestions = Utils.sortedByLevenshteinDistance(
filter,
Array.from(ExpandFilter.predefinedFilters.keys()),
(t) => t
Array.from(ExpandFilter.predefinedFilters.keys())
)
context
.enter(filter)

View file

@ -387,8 +387,7 @@ export class ExpandTagRendering extends Conversion<
if (layer === undefined) {
const candidates = Utils.sortedByLevenshteinDistance(
layerName,
Utils.NoNull(Array.from(state.sharedLayers.keys())),
(s) => s
Utils.NoNull(Array.from(state.sharedLayers.keys()))
)
if (candidates.length === 0) {
ctx.err(
@ -419,7 +418,7 @@ export class ExpandTagRendering extends Conversion<
)
}
candidates = Utils.sortedByLevenshteinDistance(name, candidates, (i) => i)
candidates = Utils.sortedByLevenshteinDistance(name, candidates)
ctx.err(
"The tagRendering with identifier " +
name +

View file

@ -71,7 +71,8 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
for (const name of names) {
const found = Utils.Clone(state.sharedLayers.get(name))
if (found === undefined) {
context.err("Layer with name " + name + " not found")
const nearbyNames = Utils.sortedByLevenshteinDistance(name, Array.from(state.sharedLayers.keys()))
context.err("Layer with name " + name + " not found. Dit you mean one of "+nearbyNames.slice(0, 3))
continue
}
found["_basedOn"] = name

View file

@ -167,7 +167,7 @@ export class ValidateTheme extends DesugaringStep<ThemeConfigJson> {
)
const available = new Set(knownIds)
if (!isCategory && !available.has(backgroundId)) {
const nearby = Utils.sortedByLevenshteinDistance(backgroundId, knownIds, (t) => t)
const nearby = Utils.sortedByLevenshteinDistance(backgroundId, knownIds)
context
.enter("defaultBackgroundId")
.err(

View file

@ -65,8 +65,7 @@ export default class FilterConfig {
if (Validators.availableTypes.indexOf(type) < 0) {
throw `Invalid filter: type is not a valid validator. Did you mean one of ${Utils.sortedByLevenshteinDistance(
type,
<ReadonlyArray<string>>Validators.availableTypes,
(x) => x
<ReadonlyArray<string>>Validators.availableTypes
).slice(0, 3)}`
}
// Type is validated against 'ValidatedTextField' in Validation.ts, in ValidateFilterConfig

View file

@ -212,8 +212,7 @@ export default class TagRenderingConfig {
json.freeform.type
}, perhaps you meant ${Utils.sortedByLevenshteinDistance(
json.freeform.key,
<any>Validators.availableTypes,
(s) => <any>s
Validators.availableTypes
)}. See https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/Docs/SpecialInputElements.md for more information`
}
const type: ValidatorType = <any>json.freeform.type ?? "string"

View file

@ -166,8 +166,7 @@
"'; did you perhaps mean one of: " +
Utils.sortedByLevenshteinDistance(
type,
Validators.AllValidators.map((v) => v.name),
(v) => v
Validators.AllValidators.map((v) => v.name)
)
.slice(0, 5)
.join(", ")

View file

@ -47,7 +47,7 @@ export default class DistanceValidator extends Validator {
if (bg && eliCategory.indexOf(bg) < 0) {
return (
"The given background layer is not a recognized ELI-type. Perhaps you meant one of " +
Utils.sortedByLevenshteinDistance(bg, eliCategory, (x) => x).slice(0, 5)
Utils.sortedByLevenshteinDistance(bg, eliCategory).slice(0, 5)
)
}
if (typeof args["zoom"] !== "number") {

View file

@ -198,7 +198,7 @@ class QrLogin extends SpecialVisualizationSvelte {
class Logout extends SpecialVisualizationSvelte {
funcName = "logout"
args = []
needsUrls = [Constants.osmAuthConfig.url]
needsUrls = [Constants.osmAuthConfig]
docs = "Shows a button where the user can log out"
group = "settings"

View file

@ -1259,11 +1259,21 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
}
}
public static sortedByLevenshteinDistance(
reference: string,
ts: ReadonlyArray<string>
): string[]
public static sortedByLevenshteinDistance<T>(
reference: string,
ts: ReadonlyArray<T>,
getName: (t: T) => string
): string[]
public static sortedByLevenshteinDistance<T>(
reference: string,
ts: ReadonlyArray<T>,
getName?: (t: T) => string
): T[] {
getName ??= (str) => <string> str;
const withDistance: [T, number][] = ts.map((t) => [
t,
Utils.levenshteinDistance(getName(t), reference),