Compare commits

..

10 Commits

Author SHA1 Message Date
Nikita Kraev
5088bd113c feat: [] init
Some checks failed
Merge release to pg / merge-release-to-pg (push) Waiting to run
Release Drafter / update_release_draft (push) Has been cancelled
2025-11-12 22:43:13 +04:00
Goutham Pratapa
15113b4bbb
chore: replace Docker build action with Depot action (#41323)
## Description
> [!TIP]  
> _Add a TL;DR when the description is longer than 500 words or
extremely technical (helps the content, marketing, and DevRel team)._
>
> _Please also include relevant motivation and context. List any
dependencies that are required for this change. Add links to Notion,
Figma or any other documents that might be relevant to the PR._


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags=""

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
2025-10-27 17:58:54 +05:30
Goutham Pratapa
ca8e4c8372
chore: update base docker image gh action to depot (#41322)
## Description
> [!TIP]  
> _Add a TL;DR when the description is longer than 500 words or
extremely technical (helps the content, marketing, and DevRel team)._
>
> _Please also include relevant motivation and context. List any
dependencies that are required for this change. Add links to Notion,
Figma or any other documents that might be relevant to the PR._


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags=""

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
2025-10-27 17:42:33 +05:30
Goutham Pratapa
b7714252ca
Revert "chore: move docker base image build to depot (#41320)" (#41321)
This reverts commit 07e003f68a.

## Description
> [!TIP]  
> _Add a TL;DR when the description is longer than 500 words or
extremely technical (helps the content, marketing, and DevRel team)._
>
> _Please also include relevant motivation and context. List any
dependencies that are required for this change. Add links to Notion,
Figma or any other documents that might be relevant to the PR._


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags=""

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
2025-10-27 17:31:36 +05:30
Goutham Pratapa
07e003f68a
chore: move docker base image build to depot (#41320)
## Description
> [!TIP]  
> _Add a TL;DR when the description is longer than 500 words or
extremely technical (helps the content, marketing, and DevRel team)._
>
> _Please also include relevant motivation and context. List any
dependencies that are required for this change. Add links to Notion,
Figma or any other documents that might be relevant to the PR._


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags=""

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
2025-10-27 17:21:41 +05:30
Jacques Ikot
b345d08fa0
fix: revert applications display correctly when AI agent flags are partially enabled (#41318)
Reverts appsmithorg/appsmith#41317

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Updated application display conditions for different application
types.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


/ok-to-test tags="@tag.Sanity"

<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/18837702804>
> Commit: 5a0df5d6500ea84fd54647fafdf10329bdf41747
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=18837702804&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Mon, 27 Oct 2025 11:08:21 UTC
<!-- end of auto-generated comment: Cypress test results  -->
2025-10-27 04:50:14 -07:00
Jacques Ikot
506d12418d
fix: ensure applications display correctly when AI agent flags are partially enabled (#41317)
## Description
Fixed a logic gap in the Applications page where no applications would
be displayed when `isAiAgentInstanceEnabled` is true but
`isAiAgentFlowEnabled` is false.

## Changes
- Updated conditional rendering logic for application lists to handle
all combinations of AI agent feature flags
- Non-anvil applications now display when either flag is disabled:
`(!isAiAgentInstanceEnabled || !isAiAgentFlowEnabled)`
- Anvil applications (AI agents) now only display when both flags are
enabled: `isAiAgentFlowEnabled && isAiAgentInstanceEnabled`

## Problem
Previously, when `isAiAgentInstanceEnabled` was `true` and
`isAiAgentFlowEnabled` was `false`, neither ApplicationCardList
component would render, resulting in no applications being shown to the
user.

### Logic Gap:
- First list: `!isAiAgentInstanceEnabled` → evaluates to `false`,
doesn't render
- Second list: `isAiAgentFlowEnabled` → evaluates to `false`, doesn't
render
- Result: No applications displayed

## Solution
Updated the conditions to ensure at least one list always renders based
on the flag states:
- Regular applications display unless both AI flags are enabled
- AI agent applications only display when both flags are enabled

## Testing
- [ ] Verified applications display when both flags are false
- [ ] Verified applications display when `isAiAgentInstanceEnabled` is
true but `isAiAgentFlowEnabled` is false
- [ ] Verified both application types display correctly when both flags
are true
- [ ] Verified AI agent applications only when both flags are enabled

## Files Changed
- `app/client/src/ce/pages/Applications/index.tsx`


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.Git"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]  
> If you modify the content in this section, you are likely to disrupt
the CI result for your PR.

<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Enhanced application availability by refining the logic that
determines which application card lists are displayed based on different
system configuration combinations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-24 19:40:48 +05:30
Jacques Ikot
fb723a7d07
fix: handle potential null basePageId in URL generation (#41315)
# PR Description

## Summary
Fixes an issue where `basePageId` could be undefined during initial page
load or navigation, causing errors in the URL builder.

## Changes
- Added fallback to `null` for `basePageId` in Header component when
undefined
- Wrapped `urlBuilderFn` call in try-catch block to gracefully handle
missing `basePageId`
- Returns empty string for href when `basePageId` is not yet available

## Why
During initial page load or navigation transitions,
`currentPage?.basePageId` may not be available yet, which could cause
the URL builder to throw errors. This change ensures the application
handles this edge case gracefully by providing a fallback value and
catching any errors that may occur.

## Automation

/ok-to-test tags="@tag.Git"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/18742901184>
> Commit: 48dc01a73bbb816b63acd186d9d80eb36cdf5814
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=18742901184&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Thu, 23 Oct 2025 09:48:19 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No
2025-10-23 03:01:22 -07:00
subratadeypappu
d7ddbdeff2
fix: CVE-2025-58754 by upgrading axios dependency (#41295)
## Description
https://github.com/appsmithorg/appsmith-ee/security/dependabot/438


Fixes CVE-2025-58754


```
client % yarn why axios
├─ appsmith-rts@workspace:packages/rts
│  └─ axios@npm:1.12.2 (via npm:^1.12.0)
│
├─ appsmith@workspace:.
│  └─ axios@npm:1.12.2 (via npm:^1.12.0)
│
└─ wait-on@npm:7.2.0
   └─ axios@npm:1.12.2 (via npm:^1.12.0)

```

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/18520882251>
> Commit: 59f9b9b973b9673e983ab9e0437d812471d179b8
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=18520882251&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Wed, 15 Oct 2025 08:31:04 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated axios to ^1.12.0 across the client, including the RTS package
and resolution map, ensuring consistent dependency versions.
* Improves overall stability and compatibility by incorporating upstream
fixes and enhancements.
  * Reduces the risk of dependency conflicts in the client workspace.
  * No user-facing behavior changes are expected.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-17 17:02:48 +06:00
subratadeypappu
ef79d5f847
chore: Enforce permission while updating instance-config (#41289)
## Description
[Slack
Thread](https://theappsmith.slack.com/archives/C03RPDB936Z/p1759920222623799)
EE Counterpart PR: https://github.com/appsmithorg/appsmith-ee/pull/8242


Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/18408366993>
> Commit: 698d87930627197831d1ec9f89c40a02928d1b28
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=18408366993&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Fri, 10 Oct 2025 15:02:32 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Breaking Changes**
* Config REST endpoints for fetching/updating by name and ACL-guarded
config update paths have been removed; clients relying on those
endpoints or permissioned fetch/update should adjust.

* **Bug Fixes**
* Simplified config access surface to reduce permission-related
complexity and potential inconsistencies.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-14 11:17:15 +06:00
16 changed files with 442 additions and 100 deletions

View File

@ -44,12 +44,19 @@ jobs:
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- name: Set up Depot CLI
uses: depot/setup-action@v1
- name: Build and push base image
uses: docker/build-push-action@v5
uses: depot/build-push-action@v1
with:
project: ${{ secrets.DEPOT_PROJECT_ID }}
context: .
file: deploy/docker/base.dockerfile
push: true
pull: true
platforms: linux/arm64,linux/amd64
tags: |
${{ vars.DOCKER_HUB_ORGANIZATION }}/base-${{ vars.EDITION }}:${{ steps.tag.outputs.tag }}
env:
DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }}

View File

@ -110,7 +110,7 @@
"assert-never": "^1.2.1",
"astring": "^1.7.5",
"async-mutex": "^0.5.0",
"axios": "^1.8.3",
"axios": "^1.12.0",
"bfj": "^7.0.2",
"camelcase": "^6.2.1",
"classnames": "^2.3.1",
@ -142,6 +142,7 @@
"js-sha256": "^0.9.0",
"jshint": "^2.13.4",
"klona": "^2.0.5",
"leaflet": "^1.9.4",
"libphonenumber-js": "^1.9.44",
"linkedom": "^0.14.20",
"localforage": "^1.7.3",
@ -185,6 +186,7 @@
"react-helmet": "^5.2.1",
"react-hook-form": "^7.28.0",
"react-json-view": "^1.21.3",
"react-leaflet": "3.2.5",
"react-media-recorder": "^1.6.1",
"react-modal": "^3.15.1",
"react-page-visibility": "^7.0.0",
@ -426,7 +428,7 @@
"@blueprintjs/icons": "3.22.0",
"@types/react": "^17.0.2",
"postcss": "8.4.31",
"axios": "^1.8.3",
"axios": "^1.12.0",
"esbuild": "^0.25.1",
"path-to-regexp@^1.7.0": "1.9.0",
"prismjs": "1.30.0",

View File

@ -23,7 +23,7 @@
"@opentelemetry/sdk-trace-node": "^1.27.0",
"@opentelemetry/semantic-conventions": "^1.27.0",
"@shared/ast": "workspace:^",
"axios": "^1.8.3",
"axios": "^1.12.0",
"dotenv": "10.0.0",
"express": "^4.20.0",
"express-validator": "^6.14.2",

View File

@ -142,7 +142,7 @@ const Header = () => {
);
const deployLink = useHref(viewerURL, {
basePageId: currentPage?.basePageId,
basePageId: currentPage?.basePageId || null,
});
const updateApplicationDispatch = (

View File

@ -300,7 +300,15 @@ export function useHref<T extends URLBuilderParams>(
const pageId = useSelector(getCurrentPageId);
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]);
return href;

View 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='&copy; <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;

View 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",
}

View 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

View File

@ -0,0 +1,3 @@
import Widget from "./widget";
export default Widget;

View 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;

View File

@ -368,6 +368,10 @@ const WidgetLoaders = new Map<string, () => Promise<typeof BaseWidget>>([
"EXTERNAL_WIDGET",
async () => import("./ExternalWidget").then((m) => m.default),
],
[
"OPENSTREETMAP_WIDGET",
async () => import("./OpenStreetMapWidget").then((m) => m.default),
],
// Deprecated Widgets
[

View File

@ -7436,6 +7436,17 @@ __metadata:
languageName: node
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":
version: 3.11.10
resolution: "@react-spectrum/utils@npm:3.11.10"
@ -13605,7 +13616,7 @@ __metadata:
"@types/node": "*"
"@types/nodemailer": ^6.4.17
"@types/readline-sync": ^1.4.8
axios: ^1.8.3
axios: ^1.12.0
dotenv: 10.0.0
express: ^4.20.0
express-validator: ^6.14.2
@ -13748,7 +13759,7 @@ __metadata:
assert-never: ^1.2.1
astring: ^1.7.5
async-mutex: ^0.5.0
axios: ^1.8.3
axios: ^1.12.0
babel-jest: ^27.4.2
babel-loader: ^8.2.3
babel-plugin-lodash: ^3.3.4
@ -13837,6 +13848,7 @@ __metadata:
json5: ^2.2.3
klona: ^2.0.5
knip: ^5.30.2
leaflet: ^1.9.4
libphonenumber-js: ^1.9.44
linkedom: ^0.14.20
lint-staged: ^14.0.1
@ -13900,6 +13912,7 @@ __metadata:
react-hook-form: ^7.28.0
react-is: ^16.12.0
react-json-view: ^1.21.3
react-leaflet: 3.2.5
react-media-recorder: ^1.6.1
react-modal: ^3.15.1
react-page-visibility: ^7.0.0
@ -14416,14 +14429,14 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^1.8.3":
version: 1.8.3
resolution: "axios@npm:1.8.3"
"axios@npm:^1.12.0":
version: 1.12.2
resolution: "axios@npm:1.12.2"
dependencies:
follow-redirects: ^1.15.6
form-data: ^4.0.0
form-data: ^4.0.4
proxy-from-env: ^1.1.0
checksum: 85fc8ad7d968e43ea9da5513310637d29654b181411012ee14cc0a4b3662782e6c81ac25eea40b5684f86ed2d8a01fa6fc20b9b48c4da14ef4eaee848fea43bc
checksum: f0331594fe053a4bbff04104edb073973a3aabfad2e56b0aa18de82428aa63f6f0839ca3d837258ec739cb4528014121793b1649a21e5115ffb2bf8237eadca3
languageName: node
linkType: hard
@ -24138,6 +24151,13 @@ __metadata:
languageName: node
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":
version: 3.1.0
resolution: "leven@npm:3.1.0"
@ -29956,6 +29976,19 @@ __metadata:
languageName: node
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":
version: 3.0.4
resolution: "react-lifecycles-compat@npm:3.0.4"

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -1,8 +1,6 @@
package com.appsmith.server.services.ce;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.domains.Config;
import com.appsmith.server.domains.User;
import reactor.core.publisher.Mono;
import java.util.Map;
@ -11,8 +9,6 @@ public interface ConfigServiceCE {
Mono<Config> getByName(String name);
Mono<Config> updateByName(Config config);
Mono<Config> save(Config config);
Mono<Config> save(String name, Map<String, Object> config);
@ -21,10 +17,6 @@ public interface ConfigServiceCE {
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
* @return Map containing the instance variables

View File

@ -1,9 +1,7 @@
package com.appsmith.server.services.ce;
import com.appsmith.server.acl.AclPermission;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Config;
import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
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)));
}
@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
public Mono<Config> save(Config config) {
return repository
@ -85,16 +69,6 @@ public class ConfigServiceCEImpl implements ConfigServiceCE {
.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
public Mono<Map<String, Object>> getInstanceVariables() {
return getByName(FieldName.INSTANCE_CONFIG).map(config -> {