Compare commits
10 Commits
7711058ce3
...
5088bd113c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5088bd113c | ||
|
|
15113b4bbb | ||
|
|
ca8e4c8372 | ||
|
|
b7714252ca | ||
|
|
07e003f68a | ||
|
|
b345d08fa0 | ||
|
|
506d12418d | ||
|
|
fb723a7d07 | ||
|
|
d7ddbdeff2 | ||
|
|
ef79d5f847 |
9
.github/workflows/docker-base-image.yml
vendored
9
.github/workflows/docker-base-image.yml
vendored
|
|
@ -44,12 +44,19 @@ jobs:
|
||||||
fi
|
fi
|
||||||
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Set up Depot CLI
|
||||||
|
uses: depot/setup-action@v1
|
||||||
|
|
||||||
- name: Build and push base image
|
- name: Build and push base image
|
||||||
uses: docker/build-push-action@v5
|
uses: depot/build-push-action@v1
|
||||||
with:
|
with:
|
||||||
|
project: ${{ secrets.DEPOT_PROJECT_ID }}
|
||||||
context: .
|
context: .
|
||||||
file: deploy/docker/base.dockerfile
|
file: deploy/docker/base.dockerfile
|
||||||
push: true
|
push: true
|
||||||
|
pull: true
|
||||||
platforms: linux/arm64,linux/amd64
|
platforms: linux/arm64,linux/amd64
|
||||||
tags: |
|
tags: |
|
||||||
${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:${{ steps.tag.outputs.tag }}
|
${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:${{ steps.tag.outputs.tag }}
|
||||||
|
env:
|
||||||
|
DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }}
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@
|
||||||
"assert-never": "^1.2.1",
|
"assert-never": "^1.2.1",
|
||||||
"astring": "^1.7.5",
|
"astring": "^1.7.5",
|
||||||
"async-mutex": "^0.5.0",
|
"async-mutex": "^0.5.0",
|
||||||
"axios": "^1.8.3",
|
"axios": "^1.12.0",
|
||||||
"bfj": "^7.0.2",
|
"bfj": "^7.0.2",
|
||||||
"camelcase": "^6.2.1",
|
"camelcase": "^6.2.1",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
|
@ -142,6 +142,7 @@
|
||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
"jshint": "^2.13.4",
|
"jshint": "^2.13.4",
|
||||||
"klona": "^2.0.5",
|
"klona": "^2.0.5",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
"libphonenumber-js": "^1.9.44",
|
"libphonenumber-js": "^1.9.44",
|
||||||
"linkedom": "^0.14.20",
|
"linkedom": "^0.14.20",
|
||||||
"localforage": "^1.7.3",
|
"localforage": "^1.7.3",
|
||||||
|
|
@ -185,6 +186,7 @@
|
||||||
"react-helmet": "^5.2.1",
|
"react-helmet": "^5.2.1",
|
||||||
"react-hook-form": "^7.28.0",
|
"react-hook-form": "^7.28.0",
|
||||||
"react-json-view": "^1.21.3",
|
"react-json-view": "^1.21.3",
|
||||||
|
"react-leaflet": "3.2.5",
|
||||||
"react-media-recorder": "^1.6.1",
|
"react-media-recorder": "^1.6.1",
|
||||||
"react-modal": "^3.15.1",
|
"react-modal": "^3.15.1",
|
||||||
"react-page-visibility": "^7.0.0",
|
"react-page-visibility": "^7.0.0",
|
||||||
|
|
@ -426,7 +428,7 @@
|
||||||
"@blueprintjs/icons": "3.22.0",
|
"@blueprintjs/icons": "3.22.0",
|
||||||
"@types/react": "^17.0.2",
|
"@types/react": "^17.0.2",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
"axios": "^1.8.3",
|
"axios": "^1.12.0",
|
||||||
"esbuild": "^0.25.1",
|
"esbuild": "^0.25.1",
|
||||||
"path-to-regexp@^1.7.0": "1.9.0",
|
"path-to-regexp@^1.7.0": "1.9.0",
|
||||||
"prismjs": "1.30.0",
|
"prismjs": "1.30.0",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
"@opentelemetry/sdk-trace-node": "^1.27.0",
|
"@opentelemetry/sdk-trace-node": "^1.27.0",
|
||||||
"@opentelemetry/semantic-conventions": "^1.27.0",
|
"@opentelemetry/semantic-conventions": "^1.27.0",
|
||||||
"@shared/ast": "workspace:^",
|
"@shared/ast": "workspace:^",
|
||||||
"axios": "^1.8.3",
|
"axios": "^1.12.0",
|
||||||
"dotenv": "10.0.0",
|
"dotenv": "10.0.0",
|
||||||
"express": "^4.20.0",
|
"express": "^4.20.0",
|
||||||
"express-validator": "^6.14.2",
|
"express-validator": "^6.14.2",
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ const Header = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const deployLink = useHref(viewerURL, {
|
const deployLink = useHref(viewerURL, {
|
||||||
basePageId: currentPage?.basePageId,
|
basePageId: currentPage?.basePageId || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateApplicationDispatch = (
|
const updateApplicationDispatch = (
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,15 @@ export function useHref<T extends URLBuilderParams>(
|
||||||
const pageId = useSelector(getCurrentPageId);
|
const pageId = useSelector(getCurrentPageId);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (pageId) setHref(urlBuilderFn(params));
|
if (pageId) {
|
||||||
|
try {
|
||||||
|
setHref(urlBuilderFn(params));
|
||||||
|
} catch (error) {
|
||||||
|
// If basePageId is not available yet, keep href as empty string
|
||||||
|
// This can happen during initial page load or navigation
|
||||||
|
setHref("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}, [params, urlBuilderFn, pageId]);
|
}, [params, urlBuilderFn, pageId]);
|
||||||
|
|
||||||
return href;
|
return href;
|
||||||
|
|
|
||||||
158
app/client/src/widgets/OpenStreetMapWidget/component/index.tsx
Normal file
158
app/client/src/widgets/OpenStreetMapWidget/component/index.tsx
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
import React, { useEffect } from "react";
|
||||||
|
import type { WidgetProps } from "widgets/BaseWidget";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
|
||||||
|
import "leaflet/dist/leaflet.css";
|
||||||
|
import L from "leaflet";
|
||||||
|
import { FullScreen, useFullScreenHandle } from "react-full-screen";
|
||||||
|
import { Icon } from "@blueprintjs/core";
|
||||||
|
|
||||||
|
// Контейнер для карты с относительным позиционированием
|
||||||
|
const MapWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Кнопка для переключения полноэкранного режима
|
||||||
|
const FullscreenButton = styled.button`
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 1000;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 🧩 фикс, чтобы маркеры отображались (иначе пустые иконки)
|
||||||
|
delete (L.Icon.Default.prototype as any)._getIconUrl;
|
||||||
|
|
||||||
|
L.Icon.Default.mergeOptions({
|
||||||
|
iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
|
||||||
|
iconUrl: require("leaflet/dist/images/marker-icon.png"),
|
||||||
|
shadowUrl: require("leaflet/dist/images/marker-shadow.png"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Компонент для обновления размера карты при изменении размера контейнера
|
||||||
|
function MapResizer() {
|
||||||
|
const map = useMap();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Обновляем размер карты при монтировании
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
map.invalidateSize();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [map]);
|
||||||
|
|
||||||
|
// Обновляем размер при изменении размера окна
|
||||||
|
useEffect(() => {
|
||||||
|
const handleResize = () => {
|
||||||
|
map.invalidateSize();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
|
}, [map]);
|
||||||
|
|
||||||
|
// Обновляем размер при переключении полноэкранного режима
|
||||||
|
useEffect(() => {
|
||||||
|
const handleFullscreenChange = () => {
|
||||||
|
// Небольшая задержка, чтобы контейнер успел изменить размер
|
||||||
|
setTimeout(() => {
|
||||||
|
map.invalidateSize();
|
||||||
|
}, 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
||||||
|
document.addEventListener("webkitfullscreenchange", handleFullscreenChange);
|
||||||
|
document.addEventListener("mozfullscreenchange", handleFullscreenChange);
|
||||||
|
document.addEventListener("MSFullscreenChange", handleFullscreenChange);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
||||||
|
document.removeEventListener("webkitfullscreenchange", handleFullscreenChange);
|
||||||
|
document.removeEventListener("mozfullscreenchange", handleFullscreenChange);
|
||||||
|
document.removeEventListener("MSFullscreenChange", handleFullscreenChange);
|
||||||
|
};
|
||||||
|
}, [map]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function OpenStreetMapComponent(props: OpenStreetMapComponentProps) {
|
||||||
|
// Получаем значения из props или используем значения по умолчанию
|
||||||
|
const centerLat = props.centerLat ?? 55.751244;
|
||||||
|
const centerLng = props.centerLng ?? 37.618423;
|
||||||
|
const zoom = props.zoom ?? 7;
|
||||||
|
const markerLat = props.markerLat ?? centerLat;
|
||||||
|
const markerLng = props.markerLng ?? centerLng;
|
||||||
|
const markerText = props.markerText ?? "Привет! Это Москва 🏙️";
|
||||||
|
|
||||||
|
const center: [number, number] = [centerLat, centerLng];
|
||||||
|
const markerPosition: [number, number] = [markerLat, markerLng];
|
||||||
|
|
||||||
|
// Хук для управления полноэкранным режимом
|
||||||
|
const fullScreenHandle = useFullScreenHandle();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MapWrapper>
|
||||||
|
<FullScreen handle={fullScreenHandle}>
|
||||||
|
<MapContainer
|
||||||
|
center={center}
|
||||||
|
zoom={zoom}
|
||||||
|
style={{ height: "500px", width: "500px" }}
|
||||||
|
>
|
||||||
|
<MapResizer />
|
||||||
|
<TileLayer
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
|
attribution='© <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
|
||||||
|
/>
|
||||||
|
<Marker position={markerPosition}>
|
||||||
|
<Popup>{markerText}</Popup>
|
||||||
|
</Marker>
|
||||||
|
</MapContainer>
|
||||||
|
</FullScreen>
|
||||||
|
|
||||||
|
{/* Кнопка для переключения полноэкранного режима */}
|
||||||
|
<FullscreenButton
|
||||||
|
onClick={fullScreenHandle.active ? fullScreenHandle.exit : fullScreenHandle.enter}
|
||||||
|
title={fullScreenHandle.active ? "Выйти из полноэкранного режима" : "Развернуть на весь экран"}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon={fullScreenHandle.active ? "minimize" : "maximize"}
|
||||||
|
iconSize={16}
|
||||||
|
/>
|
||||||
|
</FullscreenButton>
|
||||||
|
</MapWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpenStreetMapComponentProps extends WidgetProps {
|
||||||
|
centerLat?: number;
|
||||||
|
centerLng?: number;
|
||||||
|
zoom?: number;
|
||||||
|
markerLat?: number;
|
||||||
|
markerLng?: number;
|
||||||
|
markerText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OpenStreetMapComponent;
|
||||||
9
app/client/src/widgets/OpenStreetMapWidget/constants.ts
Normal file
9
app/client/src/widgets/OpenStreetMapWidget/constants.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// This file contains common constants which can be used across the widget configuration file (index.ts), widget and component folders.
|
||||||
|
export const OPENSTREETMAP_WIDGET_CONSTANT = "";
|
||||||
|
|
||||||
|
export enum OverflowTypes {
|
||||||
|
SCROLL = "SCROLL",
|
||||||
|
TRUNCATE = "TRUNCATE",
|
||||||
|
NONE = "NONE",
|
||||||
|
}
|
||||||
|
|
||||||
2
app/client/src/widgets/OpenStreetMapWidget/icon.svg
Normal file
2
app/client/src/widgets/OpenStreetMapWidget/icon.svg
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img"><title>OpenStreetMap icon</title><path d="M2.672 23.969c-.352-.089-.534-.234-1.471-1.168C.085 21.688.014 21.579.018 20.999c0-.645-.196-.414 3.368-3.986 3.6-3.608 3.415-3.451 4.064-3.449.302 0 .378.016.62.14l.277.14 1.744-1.744-.218-.343c-.425-.662-.825-1.629-1.006-2.429a7.657 7.657 0 0 1 1.479-6.44c2.49-3.12 6.959-3.812 10.26-1.588 1.812 1.218 2.99 3.099 3.328 5.314.07.467.07 1.579 0 2.074a7.554 7.554 0 0 1-2.205 4.402 6.712 6.712 0 0 1-1.943 1.401c-.959.483-1.775.71-2.881.803-1.573.131-3.32-.305-4.656-1.163l-.343-.218-1.744 1.744.14.28c.125.241.14.316.14.617.003.651.156.467-3.426 4.049-2.761 2.756-3.186 3.164-3.398 3.261-.271.125-.69.171-.945.106zM17.485 13.95a6.425 6.425 0 0 0 4.603-3.51c1.391-2.899.455-6.306-2.227-8.108-.638-.43-1.529-.794-2.367-.962-.581-.117-1.809-.104-2.414.025a6.593 6.593 0 0 0-2.452 1.064c-.444.315-1.177 1.048-1.487 1.487a6.384 6.384 0 0 0 .38 7.907 6.406 6.406 0 0 0 3.901 2.136c.509.078 1.542.058 2.065-.037zm-3.738 7.376a80.97 80.97 0 0 1-2.196-.651c-.025-.028 1.207-4.396 1.257-4.449.023-.026 4.242 1.152 4.414 1.236.062.026-.003.288-.525 2.102a398.513 398.513 0 0 0-.635 2.236c-.025.087-.069.156-.097.156-.028-.003-1.028-.287-2.219-.631zm2.912.524c0-.053 1.227-4.333 1.246-4.347.047-.034 4.324-1.23 4.341-1.211.019.019-1.199 4.337-1.23 4.36-.02.019-4.126 1.191-4.259 1.218-.054.011-.098 0-.098-.019zm-7.105-1.911c.846-.852 1.599-1.627 1.674-1.728.171-.218.405-.732.472-1.015.026-.118.053-.352.058-.522l.011-.307.182-.051c.103-.028.193-.044.202-.034.023.025-1.207 4.321-1.246 4.36-.02.016-.677.213-1.464.436l-1.425.405 1.537-1.542zm8.289-3.06a1.371 1.371 0 0 1-.059-.187l-.044-.156.156-.028c1.339-.227 2.776-.856 3.908-1.713.16-.125.252-.171.265-.134.054.165.272.95.265.959-.034.034-4.48 1.282-4.492 1.261zm-15.083-1.3c-.05-.039-1.179-3.866-1.264-4.29-.016-.084.146-.044 2.174.536 2.121.604 2.192.629 2.222.74.028.098.011.129-.125.223-.084.059-.769.724-1.523 1.479a63.877 63.877 0 0 1-1.39 1.367c-.016 0-.056-.025-.093-.054zm.821-4.378c-1.188-.343-2.164-.623-2.167-.626-.016-.012 1.261-4.433 1.285-4.46.022-.022 4.422 1.211 4.469 1.252.009.009-.269 1.017-.618 2.239-.576 2.02-.643 2.224-.723 2.22-.05-.003-1.059-.285-2.247-.626zm2.959.538c.012-.031.212-.723.444-1.534l.42-1.476.056.321c.093.556.265 1.188.464 1.741.106.296.187.539.181.545-.008.006-.332.101-.719.212-.389.109-.741.21-.786.224-.058.016-.075.006-.059-.034zM4.905 6.112c-1.187-.339-2.167-.635-2.18-.654-.04-.062-1.246-4.321-1.23-4.338.026-.025 4.31 1.204 4.351 1.246.047.051 1.28 4.379 1.246 4.376L4.91 6.113zm2.148-1.713l-.519-1.806-.078-.28 1.693-.483c.934-.265 1.724-.495 1.76-.508.034-.016-.083.14-.26.336A8.729 8.729 0 0 0 7.69 5.23a4.348 4.348 0 0 0-.132.561c0 .293-.115-.025-.505-1.39z"/></svg>
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
3
app/client/src/widgets/OpenStreetMapWidget/index.ts
Normal file
3
app/client/src/widgets/OpenStreetMapWidget/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Widget from "./widget";
|
||||||
|
|
||||||
|
export default Widget;
|
||||||
203
app/client/src/widgets/OpenStreetMapWidget/widget/index.tsx
Normal file
203
app/client/src/widgets/OpenStreetMapWidget/widget/index.tsx
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import type { DerivedPropertiesMap } from "WidgetProvider/factory/types";
|
||||||
|
|
||||||
|
import BaseWidget from "widgets/BaseWidget";
|
||||||
|
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||||
|
|
||||||
|
import OpenStreetMapComponent from "../component";
|
||||||
|
import { ValidationTypes } from "constants/WidgetValidation";
|
||||||
|
|
||||||
|
import IconSVG from "../icon.svg";
|
||||||
|
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||||
|
|
||||||
|
class OpenStreetMapWidget extends BaseWidget<OpenStreetMapWidgetProps, WidgetState> {
|
||||||
|
static type = "OPENSTREETMAP_WIDGET";
|
||||||
|
|
||||||
|
//Метаданные
|
||||||
|
static getConfig() {
|
||||||
|
return {
|
||||||
|
name: "OpenStreetMap",
|
||||||
|
iconSVG: IconSVG,
|
||||||
|
needsMeta: false,
|
||||||
|
isCanvas: false,
|
||||||
|
tags: [WIDGET_TAGS.CONTENT],
|
||||||
|
searchTags: ["map", "openstreet", "open"],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getFeatures() {
|
||||||
|
return {
|
||||||
|
dynamicHeight: {
|
||||||
|
sectionIndex: 0,
|
||||||
|
active: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//Значения по умолчанию
|
||||||
|
static getDefaults() {
|
||||||
|
return {
|
||||||
|
widgetName: "OpenStreetMap",
|
||||||
|
rows: 10,
|
||||||
|
columns: 10,
|
||||||
|
version: 1,
|
||||||
|
// Значения по умолчанию для карты
|
||||||
|
centerLat: 55.751244,
|
||||||
|
centerLng: 37.618423,
|
||||||
|
zoom: 7,
|
||||||
|
markerLat: 55.751244,
|
||||||
|
markerLng: 37.618423,
|
||||||
|
markerText: "Привет! Это Москва 🏙️",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPropertyPaneContentConfig() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
sectionName: "General",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
propertyName: "centerLat",
|
||||||
|
helpText: "Широта центра карты",
|
||||||
|
label: "Широта центра",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "55.751244",
|
||||||
|
defaultValue: 55.751244,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.NUMBER,
|
||||||
|
params: {
|
||||||
|
min: -90,
|
||||||
|
max: 90,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "centerLng",
|
||||||
|
helpText: "Долгота центра карты",
|
||||||
|
label: "Долгота центра",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "37.618423",
|
||||||
|
defaultValue: 37.618423,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.NUMBER,
|
||||||
|
params: {
|
||||||
|
min: -180,
|
||||||
|
max: 180,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "zoom",
|
||||||
|
helpText: "Уровень масштабирования карты (1-18)",
|
||||||
|
label: "Масштаб",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "7",
|
||||||
|
defaultValue: 7,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.NUMBER,
|
||||||
|
params: {
|
||||||
|
min: 1,
|
||||||
|
max: 18,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "markerLat",
|
||||||
|
helpText: "Широта маркера",
|
||||||
|
label: "Широта маркера",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "55.751244",
|
||||||
|
defaultValue: 55.751244,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.NUMBER,
|
||||||
|
params: {
|
||||||
|
min: -90,
|
||||||
|
max: 90,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "markerLng",
|
||||||
|
helpText: "Долгота маркера",
|
||||||
|
label: "Долгота маркера",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "37.618423",
|
||||||
|
defaultValue: 37.618423,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.NUMBER,
|
||||||
|
params: {
|
||||||
|
min: -180,
|
||||||
|
max: 180,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "markerText",
|
||||||
|
helpText: "Текст во всплывающем окне маркера",
|
||||||
|
label: "Текст маркера",
|
||||||
|
controlType: "INPUT_TEXT",
|
||||||
|
placeholderText: "Привет! Это Москва 🏙️",
|
||||||
|
defaultValue: "Привет! Это Москва 🏙️",
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
propertyName: "isVisible",
|
||||||
|
helpText: "Управляет видимостью виджета",
|
||||||
|
label: "Видимый",
|
||||||
|
controlType: "SWITCH",
|
||||||
|
isJSConvertible: true,
|
||||||
|
isBindProperty: true,
|
||||||
|
isTriggerProperty: false,
|
||||||
|
validation: { type: ValidationTypes.BOOLEAN },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getPropertyPaneStyleConfig() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedPropertiesMap(): DerivedPropertiesMap {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDefaultPropertiesMap(): Record<string, string> {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Рендерит компонент
|
||||||
|
getWidgetView() {
|
||||||
|
return <OpenStreetMapComponent {...this.props} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OpenStreetMapWidgetProps extends WidgetProps {
|
||||||
|
centerLat?: number;
|
||||||
|
centerLng?: number;
|
||||||
|
zoom?: number;
|
||||||
|
markerLat?: number;
|
||||||
|
markerLng?: number;
|
||||||
|
markerText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OpenStreetMapWidget;
|
||||||
|
|
@ -368,6 +368,10 @@ const WidgetLoaders = new Map<string, () => Promise<typeof BaseWidget>>([
|
||||||
"EXTERNAL_WIDGET",
|
"EXTERNAL_WIDGET",
|
||||||
async () => import("./ExternalWidget").then((m) => m.default),
|
async () => import("./ExternalWidget").then((m) => m.default),
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"OPENSTREETMAP_WIDGET",
|
||||||
|
async () => import("./OpenStreetMapWidget").then((m) => m.default),
|
||||||
|
],
|
||||||
|
|
||||||
// Deprecated Widgets
|
// Deprecated Widgets
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -7436,6 +7436,17 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@react-leaflet/core@npm:^1.1.1":
|
||||||
|
version: 1.1.1
|
||||||
|
resolution: "@react-leaflet/core@npm:1.1.1"
|
||||||
|
peerDependencies:
|
||||||
|
leaflet: ^1.7.1
|
||||||
|
react: ^17.0.1
|
||||||
|
react-dom: ^17.0.1
|
||||||
|
checksum: 2fc4a80e5524f9437ac6cef0f95e63388f2df6ecc5107fef85fd097eb2455436e796d41a4c43cdcbb983a4132403646823ba1dc0d953e866eb80808cbfaf0232
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@react-spectrum/utils@npm:^3.11.10, @react-spectrum/utils@npm:^3.9.0":
|
"@react-spectrum/utils@npm:^3.11.10, @react-spectrum/utils@npm:^3.9.0":
|
||||||
version: 3.11.10
|
version: 3.11.10
|
||||||
resolution: "@react-spectrum/utils@npm:3.11.10"
|
resolution: "@react-spectrum/utils@npm:3.11.10"
|
||||||
|
|
@ -13605,7 +13616,7 @@ __metadata:
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
"@types/nodemailer": ^6.4.17
|
"@types/nodemailer": ^6.4.17
|
||||||
"@types/readline-sync": ^1.4.8
|
"@types/readline-sync": ^1.4.8
|
||||||
axios: ^1.8.3
|
axios: ^1.12.0
|
||||||
dotenv: 10.0.0
|
dotenv: 10.0.0
|
||||||
express: ^4.20.0
|
express: ^4.20.0
|
||||||
express-validator: ^6.14.2
|
express-validator: ^6.14.2
|
||||||
|
|
@ -13748,7 +13759,7 @@ __metadata:
|
||||||
assert-never: ^1.2.1
|
assert-never: ^1.2.1
|
||||||
astring: ^1.7.5
|
astring: ^1.7.5
|
||||||
async-mutex: ^0.5.0
|
async-mutex: ^0.5.0
|
||||||
axios: ^1.8.3
|
axios: ^1.12.0
|
||||||
babel-jest: ^27.4.2
|
babel-jest: ^27.4.2
|
||||||
babel-loader: ^8.2.3
|
babel-loader: ^8.2.3
|
||||||
babel-plugin-lodash: ^3.3.4
|
babel-plugin-lodash: ^3.3.4
|
||||||
|
|
@ -13837,6 +13848,7 @@ __metadata:
|
||||||
json5: ^2.2.3
|
json5: ^2.2.3
|
||||||
klona: ^2.0.5
|
klona: ^2.0.5
|
||||||
knip: ^5.30.2
|
knip: ^5.30.2
|
||||||
|
leaflet: ^1.9.4
|
||||||
libphonenumber-js: ^1.9.44
|
libphonenumber-js: ^1.9.44
|
||||||
linkedom: ^0.14.20
|
linkedom: ^0.14.20
|
||||||
lint-staged: ^14.0.1
|
lint-staged: ^14.0.1
|
||||||
|
|
@ -13900,6 +13912,7 @@ __metadata:
|
||||||
react-hook-form: ^7.28.0
|
react-hook-form: ^7.28.0
|
||||||
react-is: ^16.12.0
|
react-is: ^16.12.0
|
||||||
react-json-view: ^1.21.3
|
react-json-view: ^1.21.3
|
||||||
|
react-leaflet: 3.2.5
|
||||||
react-media-recorder: ^1.6.1
|
react-media-recorder: ^1.6.1
|
||||||
react-modal: ^3.15.1
|
react-modal: ^3.15.1
|
||||||
react-page-visibility: ^7.0.0
|
react-page-visibility: ^7.0.0
|
||||||
|
|
@ -14416,14 +14429,14 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"axios@npm:^1.8.3":
|
"axios@npm:^1.12.0":
|
||||||
version: 1.8.3
|
version: 1.12.2
|
||||||
resolution: "axios@npm:1.8.3"
|
resolution: "axios@npm:1.12.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: ^1.15.6
|
follow-redirects: ^1.15.6
|
||||||
form-data: ^4.0.0
|
form-data: ^4.0.4
|
||||||
proxy-from-env: ^1.1.0
|
proxy-from-env: ^1.1.0
|
||||||
checksum: 85fc8ad7d968e43ea9da5513310637d29654b181411012ee14cc0a4b3662782e6c81ac25eea40b5684f86ed2d8a01fa6fc20b9b48c4da14ef4eaee848fea43bc
|
checksum: f0331594fe053a4bbff04104edb073973a3aabfad2e56b0aa18de82428aa63f6f0839ca3d837258ec739cb4528014121793b1649a21e5115ffb2bf8237eadca3
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
@ -24138,6 +24151,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"leaflet@npm:^1.9.4":
|
||||||
|
version: 1.9.4
|
||||||
|
resolution: "leaflet@npm:1.9.4"
|
||||||
|
checksum: bfc79f17a247b37b92d84b3c78702501603392d6589fde606de4a825d11f1609d90225388834f2e0709dac327e52dcd4b4b9cc9fd3d590060c5b1e53b84fa6c6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"leven@npm:^3.1.0":
|
"leven@npm:^3.1.0":
|
||||||
version: 3.1.0
|
version: 3.1.0
|
||||||
resolution: "leven@npm:3.1.0"
|
resolution: "leven@npm:3.1.0"
|
||||||
|
|
@ -29956,6 +29976,19 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-leaflet@npm:3.2.5":
|
||||||
|
version: 3.2.5
|
||||||
|
resolution: "react-leaflet@npm:3.2.5"
|
||||||
|
dependencies:
|
||||||
|
"@react-leaflet/core": ^1.1.1
|
||||||
|
peerDependencies:
|
||||||
|
leaflet: ^1.7.1
|
||||||
|
react: ^17.0.1
|
||||||
|
react-dom: ^17.0.1
|
||||||
|
checksum: 503b7cee8acc12e0e2c5e7675432e7ef5742463e3e5420282ce60a9efd306430caefae3cb282c976e3df7665f19aef5b49cdce44a034979b4ea3ee968c2621d2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-lifecycles-compat@npm:^3.0.0, react-lifecycles-compat@npm:^3.0.4":
|
"react-lifecycles-compat@npm:^3.0.0, react-lifecycles-compat@npm:^3.0.4":
|
||||||
version: 3.0.4
|
version: 3.0.4
|
||||||
resolution: "react-lifecycles-compat@npm:3.0.4"
|
resolution: "react-lifecycles-compat@npm:3.0.4"
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package com.appsmith.server.controllers;
|
|
||||||
|
|
||||||
import com.appsmith.server.constants.Url;
|
|
||||||
import com.appsmith.server.controllers.ce.ConfigControllerCE;
|
|
||||||
import com.appsmith.server.services.ConfigService;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(Url.CONFIG_URL)
|
|
||||||
public class ConfigController extends ConfigControllerCE {
|
|
||||||
|
|
||||||
public ConfigController(ConfigService service) {
|
|
||||||
super(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package com.appsmith.server.controllers.ce;
|
|
||||||
|
|
||||||
import com.appsmith.external.views.Views;
|
|
||||||
import com.appsmith.server.constants.Url;
|
|
||||||
import com.appsmith.server.domains.Config;
|
|
||||||
import com.appsmith.server.dtos.ResponseDTO;
|
|
||||||
import com.appsmith.server.services.ConfigService;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonView;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
@RequestMapping(Url.CONFIG_URL)
|
|
||||||
public class ConfigControllerCE {
|
|
||||||
|
|
||||||
private final ConfigService service;
|
|
||||||
|
|
||||||
public ConfigControllerCE(ConfigService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
@GetMapping("/name/{name}")
|
|
||||||
public Mono<ResponseDTO<Config>> getByName(@PathVariable String name) {
|
|
||||||
return service.getByName(name).map(resource -> new ResponseDTO<>(HttpStatus.OK, resource));
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonView(Views.Public.class)
|
|
||||||
@PutMapping("/name/{name}")
|
|
||||||
public Mono<ResponseDTO<Config>> updateByName(@PathVariable String name, @RequestBody Config config) {
|
|
||||||
return service.updateByName(config).map(resource -> new ResponseDTO<>(HttpStatus.OK, resource));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package com.appsmith.server.services.ce;
|
package com.appsmith.server.services.ce;
|
||||||
|
|
||||||
import com.appsmith.server.acl.AclPermission;
|
|
||||||
import com.appsmith.server.domains.Config;
|
import com.appsmith.server.domains.Config;
|
||||||
import com.appsmith.server.domains.User;
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -11,8 +9,6 @@ public interface ConfigServiceCE {
|
||||||
|
|
||||||
Mono<Config> getByName(String name);
|
Mono<Config> getByName(String name);
|
||||||
|
|
||||||
Mono<Config> updateByName(Config config);
|
|
||||||
|
|
||||||
Mono<Config> save(Config config);
|
Mono<Config> save(Config config);
|
||||||
|
|
||||||
Mono<Config> save(String name, Map<String, Object> config);
|
Mono<Config> save(String name, Map<String, Object> config);
|
||||||
|
|
@ -21,10 +17,6 @@ public interface ConfigServiceCE {
|
||||||
|
|
||||||
Mono<Void> delete(String name);
|
Mono<Void> delete(String name);
|
||||||
|
|
||||||
Mono<Config> getByName(String name, AclPermission permission);
|
|
||||||
|
|
||||||
Mono<Config> getByNameAsUser(String name, User user, AclPermission permission);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the instance variables from the instance config
|
* Get the instance variables from the instance config
|
||||||
* @return Map containing the instance variables
|
* @return Map containing the instance variables
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package com.appsmith.server.services.ce;
|
package com.appsmith.server.services.ce;
|
||||||
|
|
||||||
import com.appsmith.server.acl.AclPermission;
|
|
||||||
import com.appsmith.server.constants.FieldName;
|
import com.appsmith.server.constants.FieldName;
|
||||||
import com.appsmith.server.domains.Config;
|
import com.appsmith.server.domains.Config;
|
||||||
import com.appsmith.server.domains.User;
|
|
||||||
import com.appsmith.server.exceptions.AppsmithError;
|
import com.appsmith.server.exceptions.AppsmithError;
|
||||||
import com.appsmith.server.exceptions.AppsmithException;
|
import com.appsmith.server.exceptions.AppsmithException;
|
||||||
import com.appsmith.server.repositories.ConfigRepository;
|
import com.appsmith.server.repositories.ConfigRepository;
|
||||||
|
|
@ -34,20 +32,6 @@ public class ConfigServiceCEImpl implements ConfigServiceCE {
|
||||||
Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.CONFIG, name)));
|
Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.CONFIG, name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Config> updateByName(Config config) {
|
|
||||||
final String name = config.getName();
|
|
||||||
return repository
|
|
||||||
.findByName(name)
|
|
||||||
.switchIfEmpty(
|
|
||||||
Mono.error(new AppsmithException(AppsmithError.NO_RESOURCE_FOUND, FieldName.CONFIG, name)))
|
|
||||||
.flatMap(dbConfig -> {
|
|
||||||
log.debug("Found config with name: {} and id: {}", name, dbConfig.getId());
|
|
||||||
dbConfig.setConfig(config.getConfig());
|
|
||||||
return repository.save(dbConfig);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Config> save(Config config) {
|
public Mono<Config> save(Config config) {
|
||||||
return repository
|
return repository
|
||||||
|
|
@ -85,16 +69,6 @@ public class ConfigServiceCEImpl implements ConfigServiceCE {
|
||||||
.flatMap(repository::delete);
|
.flatMap(repository::delete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Config> getByName(String name, AclPermission permission) {
|
|
||||||
return repository.findByName(name, permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Mono<Config> getByNameAsUser(String name, User user, AclPermission permission) {
|
|
||||||
return repository.findByNameAsUser(name, user, permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Map<String, Object>> getInstanceVariables() {
|
public Mono<Map<String, Object>> getInstanceVariables() {
|
||||||
return getByName(FieldName.INSTANCE_CONFIG).map(config -> {
|
return getByName(FieldName.INSTANCE_CONFIG).map(config -> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user