forked from MapComplete/MapComplete
Refactoring: move specialVisulations into groups
This commit is contained in:
parent
644445248c
commit
b59524733c
13 changed files with 894 additions and 900 deletions
53
src/UI/SpecialVisualisations/FavouriteVisualisations.ts
Normal file
53
src/UI/SpecialVisualisations/FavouriteVisualisations.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import MarkAsFavourite from "../Popup/MarkAsFavourite.svelte"
|
||||
import MarkAsFavouriteMini from "../Popup/MarkAsFavouriteMini.svelte"
|
||||
|
||||
export class FavouriteVisualisations {
|
||||
public static initList(): SpecialVisualizationSvelte[] {
|
||||
return [{
|
||||
funcName: "favourite_status",
|
||||
|
||||
docs: "A button that allows a (logged in) contributor to mark a location as a favourite location",
|
||||
args: [],
|
||||
group: "favourites",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement(MarkAsFavourite, {
|
||||
tags: tagSource,
|
||||
state,
|
||||
layer,
|
||||
feature
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "favourite_icon",
|
||||
group: "favourites",
|
||||
docs: "A small button that allows a (logged in) contributor to mark a location as a favourite location, sized to fit a title-icon",
|
||||
args: [],
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement(MarkAsFavouriteMini, {
|
||||
tags: tagSource,
|
||||
state,
|
||||
layer,
|
||||
feature
|
||||
})
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
122
src/UI/SpecialVisualisations/ImageVisualisations.ts
Normal file
122
src/UI/SpecialVisualisations/ImageVisualisations.ts
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import ImageCarousel from "../Image/ImageCarousel.svelte"
|
||||
import { Imgur } from "../../Logic/ImageProviders/Imgur"
|
||||
import UploadImage from "../Image/UploadImage.svelte"
|
||||
import { CombinedFetcher } from "../../Logic/Web/NearbyImagesSearch"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import NearbyImages from "../Image/NearbyImages.svelte"
|
||||
import NearbyImagesCollapsed from "../Image/NearbyImagesCollapsed.svelte"
|
||||
|
||||
class NearbyImageVis implements SpecialVisualizationSvelte {
|
||||
// Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
|
||||
args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
|
||||
{
|
||||
name: "mode",
|
||||
defaultValue: "closed",
|
||||
doc: "Either `open` or `closed`. If `open`, then the image carousel will always be shown"
|
||||
},
|
||||
{
|
||||
name: "readonly",
|
||||
required: false,
|
||||
doc: "If 'readonly' or 'yes', will not show the 'link'-button"
|
||||
}
|
||||
]
|
||||
group: "images"
|
||||
docs =
|
||||
"A component showing nearby images loaded from various online services such as Mapillary. In edit mode and when used on a feature, the user can select an image to add to the feature"
|
||||
funcName = "nearby_images"
|
||||
needsUrls = CombinedFetcher.apiUrls
|
||||
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
args: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
const isOpen = args[0] === "open"
|
||||
const readonly = args[1] === "readonly" || args[1] === "yes"
|
||||
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
|
||||
return new SvelteUIElement(isOpen ? NearbyImages : NearbyImagesCollapsed, {
|
||||
tags,
|
||||
state,
|
||||
lon,
|
||||
lat,
|
||||
feature,
|
||||
layer,
|
||||
linkable: !readonly
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class ImageVisualisations {
|
||||
|
||||
static initList(): SpecialVisualizationSvelte[] {
|
||||
return [
|
||||
new NearbyImageVis(),
|
||||
{
|
||||
funcName: "image_carousel",
|
||||
group: "images",
|
||||
docs: "Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)",
|
||||
args: [
|
||||
{
|
||||
name: "image_key",
|
||||
defaultValue: AllImageProviders.defaultKeys.join(","),
|
||||
doc: "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated "
|
||||
}
|
||||
],
|
||||
needsUrls: AllImageProviders.apiUrls,
|
||||
constr: (state, tags, args) => {
|
||||
let imagePrefixes: string[] = undefined
|
||||
if (args.length > 0) {
|
||||
imagePrefixes = [].concat(...args.map((a) => a.split(",")))
|
||||
}
|
||||
const images = AllImageProviders.loadImagesFor(tags, imagePrefixes)
|
||||
const estimated = tags.mapD(tags => AllImageProviders.estimateNumberOfImages(tags, imagePrefixes))
|
||||
return new SvelteUIElement(ImageCarousel, { state, tags, images, estimated })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "image_upload",
|
||||
group: "images",
|
||||
docs: "Creates a button where a user can upload an image to IMGUR",
|
||||
needsUrls: [Imgur.apiUrl, ...Imgur.supportingUrls],
|
||||
args: [
|
||||
{
|
||||
name: "image-key",
|
||||
doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: "label",
|
||||
doc: "The text to show on the button",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: "disable_blur",
|
||||
doc: "If set to 'true' or 'yes', then face blurring will be disabled. To be used sparingly",
|
||||
required: false
|
||||
}
|
||||
],
|
||||
constr: (state, tags, args, feature) => {
|
||||
const targetKey = args[0] === "" ? undefined : args[0]
|
||||
const noBlur = args[3]?.toLowerCase()?.trim()
|
||||
return new SvelteUIElement(UploadImage, {
|
||||
state,
|
||||
tags,
|
||||
targetKey,
|
||||
feature,
|
||||
labelText: args[1],
|
||||
image: args[2],
|
||||
noBlur: noBlur === "true" || noBlur === "yes"
|
||||
})
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
}
|
||||
139
src/UI/SpecialVisualisations/NoteVisualisations.ts
Normal file
139
src/UI/SpecialVisualisations/NoteVisualisations.ts
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import Constants from "../../Models/Constants"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Feature } from "geojson"
|
||||
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import CreateNewNote from "../Popup/Notes/CreateNewNote.svelte"
|
||||
import { Utils } from "../../Utils"
|
||||
import CloseNoteButton from "../Popup/Notes/CloseNoteButton.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import AddNoteComment from "../Popup/Notes/AddNoteComment.svelte"
|
||||
import { Imgur } from "../../Logic/ImageProviders/Imgur"
|
||||
import UploadImage from "../Image/UploadImage.svelte"
|
||||
|
||||
class CloseNoteViz implements SpecialVisualizationSvelte {
|
||||
public readonly funcName = "close_note"
|
||||
public readonly needsUrls = [Constants.osmAuthConfig.url]
|
||||
public readonly docs =
|
||||
"Button to close a note. A predefined text can be defined to close the note with. If the note is already closed, will show a small text."
|
||||
public readonly args = [
|
||||
{
|
||||
name: "text",
|
||||
doc: "Text to show on this button",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "icon",
|
||||
doc: "Icon to show",
|
||||
defaultValue: "checkmark.svg"
|
||||
},
|
||||
{
|
||||
name: "idkey",
|
||||
doc: "The property name where the ID of the note to close can be found",
|
||||
defaultValue: "id"
|
||||
},
|
||||
{
|
||||
name: "comment",
|
||||
doc: "Text to add onto the note when closing"
|
||||
},
|
||||
{
|
||||
name: "minZoom",
|
||||
doc: "If set, only show the closenote button if zoomed in enough"
|
||||
},
|
||||
{
|
||||
name: "zoomButton",
|
||||
doc: "Text to show if not zoomed in enough"
|
||||
}
|
||||
]
|
||||
public readonly group: "notes"
|
||||
|
||||
public constr(
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
args: string[]
|
||||
): SvelteUIElement {
|
||||
const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs(
|
||||
this.args,
|
||||
args
|
||||
)
|
||||
|
||||
return new SvelteUIElement(CloseNoteButton, {
|
||||
state,
|
||||
tags,
|
||||
icon,
|
||||
idkey,
|
||||
message: comment,
|
||||
text: Translations.T(text),
|
||||
minzoom: minZoom,
|
||||
zoomMoreMessage: zoomButton
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class AddNoteCommentViz implements SpecialVisualizationSvelte {
|
||||
funcName = "add_note_comment"
|
||||
needsUrls = [Constants.osmAuthConfig.url]
|
||||
docs = "A textfield to add a comment to a node (with the option to close the note)."
|
||||
args = [
|
||||
{
|
||||
name: "Id-key",
|
||||
doc: "The property name where the ID of the note to close can be found",
|
||||
defaultValue: "id"
|
||||
}
|
||||
]
|
||||
public readonly group: "notes"
|
||||
|
||||
|
||||
public constr(state: SpecialVisualizationState, tags: UIEventSource<Record<string, string>>): SvelteUIElement {
|
||||
return new SvelteUIElement(AddNoteComment, { state, tags })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class NoteVisualisations {
|
||||
public static initList(): SpecialVisualizationSvelte[] {
|
||||
return [new AddNoteCommentViz(),
|
||||
{
|
||||
funcName: "open_note",
|
||||
args: [],
|
||||
group: "notes",
|
||||
needsUrls: [Constants.osmAuthConfig.url],
|
||||
docs: "Creates a new map note on the given location. This options is placed in the 'last_click'-popup automatically if the 'notes'-layer is enabled",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature
|
||||
): SvelteUIElement {
|
||||
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
|
||||
return new SvelteUIElement(CreateNewNote, {
|
||||
state,
|
||||
coordinate: new UIEventSource({ lon, lat })
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "add_image_to_note",
|
||||
docs: "Adds an image to a node",
|
||||
args: [
|
||||
{
|
||||
name: "Id-key",
|
||||
doc: "The property name where the ID of the note to close can be found",
|
||||
defaultValue: "id"
|
||||
}
|
||||
],
|
||||
group: "notes",
|
||||
needsUrls: [Imgur.apiUrl, ...Imgur.supportingUrls],
|
||||
|
||||
constr: (state, tags, args, feature, layer) => {
|
||||
const id = tags.data[args[0] ?? "id"]
|
||||
tags = state.featureProperties.getStore(id)
|
||||
return new SvelteUIElement(UploadImage, { state, tags, layer, feature })
|
||||
}
|
||||
},
|
||||
new CloseNoteViz()
|
||||
]
|
||||
}
|
||||
}
|
||||
147
src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts
Normal file
147
src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import { MangroveReviews } from "mangrove-reviews-typescript"
|
||||
import FeatureReviews from "../../Logic/Web/MangroveReviews"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import StarsBarIcon from "../Reviews/StarsBarIcon.svelte"
|
||||
import ReviewForm from "../Reviews/ReviewForm.svelte"
|
||||
import AllReviews from "../Reviews/AllReviews.svelte"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import ImportReviewIdentity from "../Reviews/ImportReviewIdentity.svelte"
|
||||
|
||||
export class ReviewSpecialVisualisations {
|
||||
public static initList(): SpecialVisualizationSvelte[] {
|
||||
return [{
|
||||
funcName: "rating",
|
||||
group: "reviews",
|
||||
docs: "Shows stars which represent the average rating on mangrove.",
|
||||
needsUrls: [MangroveReviews.ORIGINAL_API],
|
||||
args: [
|
||||
{
|
||||
name: "subjectKey",
|
||||
defaultValue: "name",
|
||||
doc: "The key to use to determine the subject. If the value is specified, the subject will be <b>tags[subjectKey]</b> and will use this to filter the reviews."
|
||||
},
|
||||
{
|
||||
name: "fallback",
|
||||
doc: "The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value"
|
||||
}
|
||||
],
|
||||
constr: (state, tags, args, feature) => {
|
||||
const nameKey = args[0] ?? "name"
|
||||
const fallbackName = args[1]
|
||||
const reviews = FeatureReviews.construct(
|
||||
feature,
|
||||
tags,
|
||||
state.userRelatedState.mangroveIdentity,
|
||||
{
|
||||
nameKey: nameKey,
|
||||
fallbackName
|
||||
},
|
||||
state.featureSwitchIsTesting
|
||||
)
|
||||
return new SvelteUIElement(StarsBarIcon, {
|
||||
score: reviews.average
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "create_review",
|
||||
group: "reviews",
|
||||
|
||||
docs: "Invites the contributor to leave a review. Somewhat small UI-element until interacted",
|
||||
needsUrls: [MangroveReviews.ORIGINAL_API],
|
||||
args: [
|
||||
{
|
||||
name: "subjectKey",
|
||||
defaultValue: "name",
|
||||
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>"
|
||||
},
|
||||
{
|
||||
name: "fallback",
|
||||
doc: "The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value"
|
||||
},
|
||||
{
|
||||
name: "question",
|
||||
doc: "The question to ask during the review"
|
||||
}
|
||||
],
|
||||
constr: (state, tags, args, feature, layer) => {
|
||||
const nameKey = args[0] ?? "name"
|
||||
const fallbackName = args[1]
|
||||
const question = args[2]
|
||||
const reviews = FeatureReviews.construct(
|
||||
feature,
|
||||
tags,
|
||||
state.userRelatedState?.mangroveIdentity,
|
||||
{
|
||||
nameKey: nameKey,
|
||||
fallbackName
|
||||
},
|
||||
state.featureSwitchIsTesting
|
||||
)
|
||||
return new SvelteUIElement(ReviewForm, {
|
||||
reviews,
|
||||
state,
|
||||
tags,
|
||||
feature,
|
||||
layer,
|
||||
question
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "list_reviews",
|
||||
group: "reviews",
|
||||
|
||||
docs: "Adds an overview of the mangrove-reviews of this object. Mangrove.Reviews needs - in order to identify the reviewed object - a coordinate and a name. By default, the name of the object is given, but this can be overwritten",
|
||||
needsUrls: [MangroveReviews.ORIGINAL_API],
|
||||
args: [
|
||||
{
|
||||
name: "subjectKey",
|
||||
defaultValue: "name",
|
||||
doc: "The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b>"
|
||||
},
|
||||
{
|
||||
name: "fallback",
|
||||
doc: "The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value"
|
||||
}
|
||||
],
|
||||
constr: (state, tags, args, feature, layer) => {
|
||||
const nameKey = args[0] ?? "name"
|
||||
const fallbackName = args[1]
|
||||
const reviews = FeatureReviews.construct(
|
||||
feature,
|
||||
tags,
|
||||
state.userRelatedState?.mangroveIdentity,
|
||||
{
|
||||
nameKey: nameKey,
|
||||
fallbackName
|
||||
},
|
||||
state.featureSwitchIsTesting
|
||||
)
|
||||
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "import_mangrove_key",
|
||||
group: "settings",
|
||||
|
||||
docs: "Only makes sense in the usersettings. Allows to import a mangrove public key and to use this to make reviews",
|
||||
args: [
|
||||
{
|
||||
name: "text",
|
||||
doc: "The text that is shown on the button"
|
||||
}
|
||||
],
|
||||
needsUrls: [],
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
_: UIEventSource<Record<string, string>>,
|
||||
argument: string[]
|
||||
): SvelteUIElement {
|
||||
const [text] = argument
|
||||
return new SvelteUIElement(ImportReviewIdentity, { state, text })
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
103
src/UI/SpecialVisualisations/SettingsVisualisations.ts
Normal file
103
src/UI/SpecialVisualisations/SettingsVisualisations.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import DisabledQuestions from "../Popup/DisabledQuestions.svelte"
|
||||
import Constants from "../../Models/Constants"
|
||||
import LogoutButton from "../Base/LogoutButton.svelte"
|
||||
import LoginButton from "../Base/LoginButton.svelte"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
import OrientationDebugPanel from "../Debug/OrientationDebugPanel.svelte"
|
||||
import AllTagsPanel from "../Popup/AllTagsPanel.svelte"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import ClearCaches from "../Popup/ClearCaches.svelte"
|
||||
|
||||
export class SettingsVisualisations {
|
||||
public static initList(): SpecialVisualizationSvelte[] {
|
||||
return [
|
||||
{
|
||||
funcName: "disabled_questions",
|
||||
group: "settings",
|
||||
docs: "Shows which questions are disabled for every layer. Used in 'settings'",
|
||||
needsUrls: [],
|
||||
args: [],
|
||||
constr(state) {
|
||||
return new SvelteUIElement(DisabledQuestions, { state })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "gyroscope_all_tags",
|
||||
group: "settings",
|
||||
docs: "Shows the current tags of the GPS-representing object, used for debugging",
|
||||
args: [],
|
||||
constr(): SvelteUIElement {
|
||||
return new SvelteUIElement(OrientationDebugPanel, {})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "gps_all_tags",
|
||||
group: "settings",
|
||||
docs: "Shows the current tags of the GPS-representing object, used for debugging",
|
||||
args: [],
|
||||
constr(
|
||||
state: SpecialVisualizationState
|
||||
): SvelteUIElement {
|
||||
const tags = (<ThemeViewState>(
|
||||
state
|
||||
)).geolocation.currentUserLocation.features.map(
|
||||
(features) => features[0]?.properties
|
||||
)
|
||||
return new SvelteUIElement(AllTagsPanel, {
|
||||
state,
|
||||
tags
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "clear_caches",
|
||||
docs: "A button which clears the locally downloaded data and the service worker. Login status etc will be kept",
|
||||
args: [
|
||||
{
|
||||
name: "text",
|
||||
required: true,
|
||||
doc: "The text to show on the button"
|
||||
}
|
||||
],
|
||||
group: "settings",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement<any, any, any>(ClearCaches, {
|
||||
msg: argument[0] ?? "Clear local caches"
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "login_button",
|
||||
args: [],
|
||||
docs: "Show a login button",
|
||||
needsUrls: [],
|
||||
group: "settings",
|
||||
constr(state: SpecialVisualizationState): SvelteUIElement {
|
||||
return new SvelteUIElement(LoginButton, { osmConnection: state.osmConnection })
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
funcName: "logout",
|
||||
args: [],
|
||||
needsUrls: [Constants.osmAuthConfig.url],
|
||||
docs: "Shows a button where the user can log out",
|
||||
group: "settings",
|
||||
constr(state: SpecialVisualizationState): SvelteUIElement {
|
||||
return new SvelteUIElement(LogoutButton, { osmConnection: state.osmConnection })
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
204
src/UI/SpecialVisualisations/UISpecialVisualisations.ts
Normal file
204
src/UI/SpecialVisualisations/UISpecialVisualisations.ts
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import { SpecialVisualizationState, SpecialVisualizationSvelte } from "../SpecialVisualization"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import Questionbox from "../Popup/TagRendering/Questionbox.svelte"
|
||||
import MinimapViz from "../Popup/MinimapViz.svelte"
|
||||
import SplitRoadWizard from "../Popup/SplitRoadWizard.svelte"
|
||||
import MoveWizard from "../Popup/MoveWizard.svelte"
|
||||
import DeleteWizard from "../Popup/DeleteFlow/DeleteWizard.svelte"
|
||||
import QrCode from "../Popup/QrCode.svelte"
|
||||
import NothingKnown from "../Popup/NothingKnown.svelte"
|
||||
import { ShareLinkViz } from "../Popup/ShareLinkViz"
|
||||
|
||||
/**
|
||||
* Thin wrapper around QuestionBox.svelte to include it into the special Visualisations
|
||||
*/
|
||||
class QuestionViz implements SpecialVisualizationSvelte {
|
||||
funcName = "questions"
|
||||
needsUrls = []
|
||||
docs =
|
||||
"The special element which shows the questions which are unkown. Added by default if not yet there"
|
||||
args = [
|
||||
{
|
||||
name: "labels",
|
||||
doc: "One or more ';'-separated labels. If these are given, only questions with these labels will be given. Use `unlabeled` for all questions that don't have an explicit label. If none given, all questions will be shown"
|
||||
},
|
||||
{
|
||||
name: "blacklisted-labels",
|
||||
doc: "One or more ';'-separated labels of questions which should _not_ be included"
|
||||
}
|
||||
]
|
||||
svelteBased = true
|
||||
group: "default"
|
||||
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
args: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
|
||||
const labels = args[0]
|
||||
?.split(";")
|
||||
?.map((s) => s.trim())
|
||||
?.filter((s) => s !== "")
|
||||
const blacklist = args[1]
|
||||
?.split(";")
|
||||
?.map((s) => s.trim())
|
||||
?.filter((s) => s !== "")
|
||||
return new SvelteUIElement(Questionbox, {
|
||||
layer,
|
||||
tags,
|
||||
selectedElement: feature,
|
||||
state,
|
||||
onlyForLabels: labels,
|
||||
notForLabels: blacklist
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class UISpecialVisualisations {
|
||||
public static initList(): SpecialVisualizationSvelte [] {
|
||||
return [new QuestionViz(),
|
||||
{
|
||||
funcName: "minimap",
|
||||
docs: "A small map showing the selected feature.",
|
||||
needsUrls: [],
|
||||
group: "default",
|
||||
|
||||
args: [
|
||||
{
|
||||
doc: "The (maximum) zoomlevel: the target zoomlevel after fitting the entire feature. The minimap will fit the entire feature, then zoom out to this zoom level. The higher, the more zoomed in with 1 being the entire world and 19 being really close",
|
||||
name: "zoomlevel",
|
||||
defaultValue: "18"
|
||||
},
|
||||
{
|
||||
doc: "(Matches all resting arguments) This argument should be the key of a property of the feature. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. (Note: if the key is 'id', list interpration is disabled)",
|
||||
name: "idKey",
|
||||
defaultValue: "id"
|
||||
}
|
||||
],
|
||||
example:
|
||||
"`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`",
|
||||
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
args: string[],
|
||||
feature: Feature
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement(MinimapViz, { state, args, feature, tagSource })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "split_button",
|
||||
docs: "Adds a button which allows to split a way",
|
||||
args: [],
|
||||
group: "default",
|
||||
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement(SplitRoadWizard, { id: tagSource.map(pr => pr.id), state })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "move_button",
|
||||
docs: "Adds a button which allows to move the object to another location. The config will be read from the layer config",
|
||||
args: [],
|
||||
group: "default",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
if (feature.geometry.type !== "Point") {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return new SvelteUIElement(MoveWizard, {
|
||||
state,
|
||||
featureToMove: feature,
|
||||
layer
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "delete_button",
|
||||
docs: "Adds a button which allows to delete the object at this location. The config will be read from the layer config",
|
||||
args: [],
|
||||
group: "default",
|
||||
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
if (!layer.deletion) {
|
||||
return undefined
|
||||
}
|
||||
return new SvelteUIElement(DeleteWizard, {
|
||||
tags: tagSource,
|
||||
deleteConfig: layer.deletion,
|
||||
state,
|
||||
feature,
|
||||
layer
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "qr_code",
|
||||
args: [],
|
||||
group: "default",
|
||||
docs: "Generates a QR-code to share the selected object",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tags: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature
|
||||
): SvelteUIElement {
|
||||
return new SvelteUIElement(QrCode, { state, tags, feature })
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "if_nothing_known",
|
||||
args: [
|
||||
{
|
||||
name: "text",
|
||||
doc: "Text to show",
|
||||
required: true
|
||||
},
|
||||
{ name: "cssClasses", doc: "Classes to apply onto the text" }
|
||||
],
|
||||
group: "default",
|
||||
docs: "Shows a 'nothing is currently known-message if there is at least one unanswered question and no known (answerable) question",
|
||||
constr(
|
||||
state: SpecialVisualizationState,
|
||||
tagSource: UIEventSource<Record<string, string>>,
|
||||
argument: string[],
|
||||
feature: Feature,
|
||||
layer: LayerConfig
|
||||
): SvelteUIElement {
|
||||
const text = argument[0]
|
||||
const cssClasses = argument[1]
|
||||
return new SvelteUIElement(NothingKnown, {
|
||||
state,
|
||||
tags: tagSource,
|
||||
layer,
|
||||
text,
|
||||
cssClasses
|
||||
})
|
||||
}
|
||||
},
|
||||
new ShareLinkViz()
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue