This is an automated email from the ASF dual-hosted git repository.
jscheffl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new aad6d490cfe Fix edge3 router (#61078)
aad6d490cfe is described below
commit aad6d490cfe159540fc593b6226f7df84705b2a3
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Tue Jan 27 20:31:35 2026 +0100
Fix edge3 router (#61078)
* Fix edge3 router
* Add backward compatibility support
---
.../providers/edge3/plugins/www/dist/main.umd.cjs | 16 ++++++-------
.../providers/edge3/plugins/www/package.json | 2 ++
.../providers/edge3/plugins/www/pnpm-lock.yaml | 11 +++++++++
.../edge3/plugins/www/src/layouts/NavTabs.tsx | 28 +++++++++++++++++++---
providers/edge3/www-hash.txt | 2 +-
5 files changed, 47 insertions(+), 12 deletions(-)
diff --git
a/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs
b/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs
index 78d3433fc76..d9957a8877c 100644
--- a/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs
+++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/dist/main.umd.cjs
@@ -1,14 +1,14 @@
-(function(h,S){typeof exports=="object"&&typeof
module<"u"?module.exports=S(require("react/jsx-runtime"),require("react"),require("react-router-dom"),require("react-dom")):typeof
define=="function"&&define.amd?define(["react/jsx-runtime","react","react-router-dom","react-dom"],S):(h=typeof
globalThis<"u"?globalThis:h||self,h.AirflowPlugin=S(h.ReactJSXRuntime,h.React,h.ReactRouterDOM,h.ReactDOM))})(this,(function(h,S,st,yo){"use
strict";function gm(e){const t=Object.create(null,{[Symbol.t [...]
+(function(f,C){typeof exports=="object"&&typeof
module<"u"?module.exports=C(require("react/jsx-runtime"),require("react"),require("react-router-dom"),require("react-dom")):typeof
define=="function"&&define.amd?define(["react/jsx-runtime","react","react-router-dom","react-dom"],C):(f=typeof
globalThis<"u"?globalThis:f||self,f.AirflowPlugin=C(f.ReactJSXRuntime,f.React,f.ReactRouterDOM,f.ReactDOM))})(this,(function(f,C,ct,ko){"use
strict";function m0(e){const t=Object.create(null,{[Symbol.t [...]
<svg width="46" height="15" style="left: -15.5px; position: absolute;
top: 0; filter: drop-shadow(rgba(0, 0, 0, 0.4) 0px 1px 1.1px);">
<g transform="translate(2 3)">
<path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L
31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z" style="stroke-width: 2px; stroke:
white;"></path>
<path fill-rule="evenodd" d="M 15 4.5L 15 2L 11.5 5.5L 15 9L 15 6.5L
31 6.5L 31 9L 34.5 5.5L 31 2L 31 4.5Z"></path>
</g>
- </svg>`,r.body.appendChild(n)};function
TC(e,t){if(!(!e||!t.isActiveElement(e)))try{const{selectionStart:r,selectionEnd:n,value:o}=e;return
r==null||n==null?void 0:{start:r,end:n,value:o}}catch{return}}function
PC(e,t,r){if(!(!e||!r.isActiveElement(e))){if(!t){const
n=e.value.length;e.setSelectionRange(n,n);return}try{const
n=e.value,{start:o,end:i,value:s}=t;if(n===s){e.setSelectionRange(o,i);return}const
a=ah(s,n,o),l=o===i?a:ah(s,n,i),c=Math.max(0,Math.min(a,n.length)),d=Math.ma
[...]
+ </svg>`,r.body.appendChild(n)};function
Nw(e,t){if(!(!e||!t.isActiveElement(e)))try{const{selectionStart:r,selectionEnd:n,value:o}=e;return
r==null||n==null?void 0:{start:r,end:n,value:o}}catch{return}}function
Rw(e,t,r){if(!(!e||!r.isActiveElement(e))){if(!t){const
n=e.value.length;e.setSelectionRange(n,n);return}try{const
n=e.value,{start:o,end:i,value:s}=t;if(n===s){e.setSelectionRange(o,i);return}const
a=mf(s,n,o),l=o===i?a:mf(s,n,i),u=Math.max(0,Math.min(a,n.length)),c=Math.ma
[...]
)+\\(\\s*max(-device)?-${e}`,"i"),min:new
RegExp(`\\(\\s*min(-device)?-${e}`,"i"),maxMin:new
RegExp(`(!?\\(\\s*max(-device)?-${e})(.|
-)+\\(\\s*min(-device)?-${e}`,"i"),max:new
RegExp(`\\(\\s*max(-device)?-${e}`,"i")}),aw=lf("width"),lw=lf("height"),cf=e=>({isMin:pf(e.minMax,e.maxMin,e.min),isMax:pf(e.maxMin,e.minMax,e.max)}),{isMin:ja,isMax:df}=cf(aw),{isMin:Ga,isMax:uf}=cf(lw),hf=/print/i,ff=/^print$/i,cw=/(-?\d*\.?\d+)(ch|em|ex|px|rem)/,dw=/(\d)/,ro=Number.MAX_VALUE,uw={ch:8.8984375,em:16,rem:16,ex:8.296875,px:1};function
gf(e){const t=cw.exec(e)||(ja(e)||Ga(e)?dw.exec(e):null);if(!t)return
ro;if(t[0]==="0")return 0; [...]
-`).forEach(function(s){o=s.indexOf(":"),r=s.substring(0,o).trim().toLowerCase(),n=s.substring(o+1).trim(),!(!r||t[r]&&iP[r])&&(r==="set-cookie"?t[r]?t[r].push(n):t[r]=[n]:t[r]=t[r]?t[r]+",
"+n:n)}),t},dp=Symbol("internals");function fo(e){return
e&&String(e).trim().toLowerCase()}function Ui(e){return
e===!1||e==null?e:I.isArray(e)?e.map(Ui):String(e)}function aP(e){const
t=Object.create(null),r=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let
n;for(;n=r.exec(e);)t[n[1]]=n[2];return t}const lP=e=>/ [...]
-`)}getSetCookie(){return
this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static
from(t){return t instanceof this?t:new this(t)}static concat(t,...r){const
n=new this(t);return r.forEach(o=>n.set(o)),n}static accessor(t){const
n=(this[dp]=this[dp]={accessors:{}}).accessors,o=this.prototype;function
i(s){const a=fo(s);n[a]||(dP(o,s),n[a]=!0)}return
I.isArray(t)?t.forEach(i):i(t),this}};Ye.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-A
[...]
-`+s.map(wp).join(`
-`):" "+wp(s[0]):"as no adapter specified";throw new j("There is no suitable
adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return o}const
Ep={getAdapter:IP,adapters:Sl};function
Cl(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw
new go(null,e)}function Op(e){return
Cl(e),e.headers=Ye.from(e.headers),e.data=xl.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded"
[...]
-`+i):n.stack=i}catch{}}throw n}}_request(t,r){typeof
t=="string"?(r=r||{},r.url=t):r=t||{},r=Wr(this.defaults,r);const{transitional:n,paramsSerializer:o,headers:i}=r;n!==void
0&&Ki.assertOptions(n,{silentJSONParsing:Ot.transitional(Ot.boolean),forcedJSONParsing:Ot.transitional(Ot.boolean),clarifyTimeoutError:Ot.transitional(Ot.boolean)},!1),o!=null&&(I.isFunction(o)?r.paramsSerializer={serialize:o}:Ki.assertOptions(o,{encode:Ot.function,serialize:Ot.function},!0)),r.allowAbsoluteUrls!==v
[...]
+)+\\(\\s*min(-device)?-${e}`,"i"),max:new
RegExp(`\\(\\s*max(-device)?-${e}`,"i")}),cI=mg("width"),uI=mg("height"),vg=e=>({isMin:Cg(e.minMax,e.maxMin,e.min),isMax:Cg(e.maxMin,e.minMax,e.max)}),{isMin:nl,isMax:bg}=vg(cI),{isMin:ol,isMax:yg}=vg(uI),xg=/print/i,Eg=/^print$/i,dI=/(-?\d*\.?\d+)(ch|em|ex|px|rem)/,hI=/(\d)/,ao=Number.MAX_VALUE,fI={ch:8.8984375,em:16,rem:16,ex:8.296875,px:1};function
Sg(e){const t=dI.exec(e)||(nl(e)||ol(e)?hI.exec(e):null);if(!t)return
ao;if(t[0]==="0")return 0; [...]
+`).forEach(function(s){o=s.indexOf(":"),r=s.substring(0,o).trim().toLowerCase(),n=s.substring(o+1).trim(),!(!r||t[r]&&aR[r])&&(r==="set-cookie"?t[r]?t[r].push(n):t[r]=[n]:t[r]=t[r]?t[r]+",
"+n:n)}),t},vm=Symbol("internals");function bo(e){return
e&&String(e).trim().toLowerCase()}function Yi(e){return
e===!1||e==null?e:R.isArray(e)?e.map(Yi):String(e)}function cR(e){const
t=Object.create(null),r=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let
n;for(;n=r.exec(e);)t[n[1]]=n[2];return t}const uR=e=>/ [...]
+`)}getSetCookie(){return
this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static
from(t){return t instanceof this?t:new this(t)}static concat(t,...r){const
n=new this(t);return r.forEach(o=>n.set(o)),n}static accessor(t){const
n=(this[vm]=this[vm]={accessors:{}}).accessors,o=this.prototype;function
i(s){const a=bo(s);n[a]||(hR(o,s),n[a]=!0)}return
R.isArray(t)?t.forEach(i):i(t),this}};Ze.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-A
[...]
+`+s.map(Rm).join(`
+`):" "+Rm(s[0]):"as no adapter specified";throw new Y("There is no suitable
adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return o}const
Am={getAdapter:PR,adapters:_l};function
Ll(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw
new yo(null,e)}function Vm(e){return
Ll(e),e.headers=Ze.from(e.headers),e.data=Vl.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded"
[...]
+`+i):n.stack=i}catch{}}throw n}}_request(t,r){typeof
t=="string"?(r=r||{},r.url=t):r=t||{},r=Ur(this.defaults,r);const{transitional:n,paramsSerializer:o,headers:i}=r;n!==void
0&&es.assertOptions(n,{silentJSONParsing:Rt.transitional(Rt.boolean),forcedJSONParsing:Rt.transitional(Rt.boolean),clarifyTimeoutError:Rt.transitional(Rt.boolean)},!1),o!=null&&(R.isFunction(o)?r.paramsSerializer={serialize:o}:es.assertOptions(o,{encode:Rt.function,serialize:Rt.function},!0)),r.allowAbsoluteUrls!==v
[...]
diff --git
a/providers/edge3/src/airflow/providers/edge3/plugins/www/package.json
b/providers/edge3/src/airflow/providers/edge3/plugins/www/package.json
index c099f637e22..0bdb8b5496f 100644
--- a/providers/edge3/src/airflow/providers/edge3/plugins/www/package.json
+++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/package.json
@@ -35,6 +35,7 @@
"@chakra-ui/react": "^3.31.0",
"@emotion/react": "^11.14.0",
"@tanstack/react-query": "^5.90.19",
+ "@types/semver": "^7.7.1",
"axios": "^1.13.2",
"next-themes": "^0.4.6",
"react": "^19.2.3",
@@ -43,6 +44,7 @@
"react-icons": "^5.5.0",
"react-router-dom": "^7.12.0",
"react-timeago": "^8.3.0",
+ "semver": "^7.7.3",
"use-debounce": "^10.1.0"
},
"devDependencies": {
diff --git
a/providers/edge3/src/airflow/providers/edge3/plugins/www/pnpm-lock.yaml
b/providers/edge3/src/airflow/providers/edge3/plugins/www/pnpm-lock.yaml
index 798bf9725d2..0285a4c0038 100644
--- a/providers/edge3/src/airflow/providers/edge3/plugins/www/pnpm-lock.yaml
+++ b/providers/edge3/src/airflow/providers/edge3/plugins/www/pnpm-lock.yaml
@@ -17,6 +17,9 @@ importers:
'@tanstack/react-query':
specifier: ^5.90.19
version: 5.90.19([email protected])
+ '@types/semver':
+ specifier: ^7.7.1
+ version: 7.7.1
axios:
specifier: ^1.13.2
version: 1.13.2
@@ -41,6 +44,9 @@ importers:
react-timeago:
specifier: ^8.3.0
version: 8.3.0([email protected])
+ semver:
+ specifier: ^7.7.3
+ version: 7.7.3
use-debounce:
specifier: ^10.1.0
version: 10.1.0([email protected])
@@ -959,6 +965,9 @@ packages:
'@types/[email protected]':
resolution: {integrity:
sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==}
+ '@types/[email protected]':
+ resolution: {integrity:
sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==}
+
'@types/[email protected]':
resolution: {integrity:
sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==}
@@ -3962,6 +3971,8 @@ snapshots:
dependencies:
csstype: 3.2.3
+ '@types/[email protected]': {}
+
'@types/[email protected]': {}
'@types/[email protected]':
diff --git
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx
index e537575176f..0d8e4efe010 100644
---
a/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx
+++
b/providers/edge3/src/airflow/providers/edge3/plugins/www/src/layouts/NavTabs.tsx
@@ -17,10 +17,13 @@
* under the License.
*/
import { Center, Flex } from "@chakra-ui/react";
+import axios from "axios";
+import { useQuery } from "@tanstack/react-query";
import { useRef, type ReactNode } from "react";
import { NavLink } from "react-router-dom";
import { useContainerWidth } from "src/utils";
+import { lte } from "semver";
type Props = {
readonly tabs: Array<{ icon?: ReactNode; label: string; value: string }>;
@@ -30,10 +33,29 @@ export const NavTabs = ({ tabs }: Props) => {
const containerRef = useRef<HTMLDivElement>(null);
const containerWidth = useContainerWidth(containerRef);
+ const { data } = useQuery<{version: string, git_version: string | null}>({
+ queryFn: async () => {
+ const res = await axios.get("/api/v2/version");
+ return res.data;
+ },
+ queryKey: ["appVersion"],
+ });
+
+ let legacyRouterNavigation: boolean | undefined = undefined;
+
+ if (data) {
+ const airflowCoreVersion = data.version;
+ if (lte(airflowCoreVersion, "3.1.6")) {
+ legacyRouterNavigation = true;
+ } else {
+ legacyRouterNavigation = false;
+ }
+ }
+
return (
<Flex alignItems="center" borderBottomWidth={1} mb={2} ref={containerRef}>
- {tabs.map(({ icon, label, value }) => (
- <NavLink end key={value} title={label} to={value}>
+ {legacyRouterNavigation !== undefined ? tabs.map(({ icon, label, value
}) => (
+ <NavLink end key={value} title={label} to={legacyRouterNavigation ?
value : `../${value}`} relative={legacyRouterNavigation ? "route" : "path"}>
{({ isActive }) => (
<Center
borderBottomColor="border.info"
@@ -50,7 +72,7 @@ export const NavTabs = ({ tabs }: Props) => {
</Center>
)}
</NavLink>
- ))}
+ )): undefined}
</Flex>
);
};
diff --git a/providers/edge3/www-hash.txt b/providers/edge3/www-hash.txt
index 5d9ab4a3b44..99ba24aa16d 100644
--- a/providers/edge3/www-hash.txt
+++ b/providers/edge3/www-hash.txt
@@ -1 +1 @@
-4368fe2c5258f6cf92c4b9e3df47e23e9b6db199d2b3b1643d6f679708d51302
+10cb23ea3b5d740866aa436e75bb44e68501ef5aebb30836d924282414777792