@allbluecn/web-app 0.4.10 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -7
- package/public/tanstack-landscape-black.svg +23 -0
- package/public/tanstack-landscape-white.svg +23 -0
- package/src/components/changelog/changelog-page.tsx +382 -0
- package/src/components/layout/sidebar-03/app-sidebar.tsx +3 -1
- package/src/components/layout/sidebar-03/nav-secondary.tsx +93 -0
- package/src/lib/app-version.ts +20 -0
- package/src/lib/changelog/sdk-versions-types.ts +14 -0
- package/src/lib/changelog/sdk-versions.ts +151 -0
- package/src/routeTree.gen.ts +23 -0
- package/src/routes/_nav/changelog/route.lazy.tsx +7 -0
- package/src/routes/_nav/changelog/route.tsx +13 -0
- package/src/server/serverFns/changelog/fetch.ts +28 -0
- package/src/styles/globals.css +18 -0
- package/src/styles/typeset.css +464 -0
- /package/src/components/layout/sidebar-03/{sidebar-search-trigger.tsx → nav-search-trigger.tsx} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allbluecn/web-app",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"@base-ui/react": "^1.4.1",
|
|
25
25
|
"@dnd-kit/react": "^0.5.0",
|
|
26
26
|
"@floating-ui/react": "^0.27.19",
|
|
27
|
+
"@fontsource-variable/geist": "^5.3.0",
|
|
28
|
+
"@fontsource-variable/geist-mono": "^5.3.0",
|
|
27
29
|
"@iconify/react": "^6.0.2",
|
|
28
30
|
"@lobehub/icons": "^5.10.0",
|
|
29
31
|
"@prisma/client": "^7.8.0",
|
|
@@ -133,14 +135,14 @@
|
|
|
133
135
|
"three": "^0.180.0",
|
|
134
136
|
"tw-animate-css": "^1.4.0",
|
|
135
137
|
"zod": "^4.4.3",
|
|
136
|
-
"@allbluecn/
|
|
138
|
+
"@allbluecn/ai-gateway": "0.4.11",
|
|
139
|
+
"@allbluecn/database": "0.4.11",
|
|
137
140
|
"@allbluecn/kernel": "0.3.0",
|
|
138
|
-
"@allbluecn/
|
|
139
|
-
"@allbluecn/plugins-core": "0.4.10",
|
|
141
|
+
"@allbluecn/plugins-core": "0.4.11",
|
|
140
142
|
"@allbluecn/prototype": "0.1.1",
|
|
141
|
-
"@allbluecn/
|
|
142
|
-
"@allbluecn/
|
|
143
|
-
"@allbluecn/ui": "0.4.
|
|
143
|
+
"@allbluecn/tiptap": "0.4.11",
|
|
144
|
+
"@allbluecn/shared": "0.4.11",
|
|
145
|
+
"@allbluecn/ui": "0.4.11"
|
|
144
146
|
},
|
|
145
147
|
"devDependencies": {
|
|
146
148
|
"@babel/parser": "^8.0.4",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 321.33 50">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill-rule: evenodd;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-1, .cls-2 {
|
|
10
|
+
fill: #121212;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
</defs>
|
|
14
|
+
<path class="cls-1" d="M19.03,0c13.76,0,19.03,8.54,19.03,25s-5.27,25-19.03,25S0,41.46,0,25C0,8.54,5.27,0,19.03,0ZM25.32,36.42c-1.79,0-2.76.49-3.55.88-.68.34-1.21.61-2.38.61-1.17,0-1.71-.27-2.38-.61-.78-.39-1.76-.88-3.55-.88-1.79,0-2.76.49-3.55.88-.68.34-1.21.61-2.38.61v2.6c1.79,0,2.76-.49,3.55-.88.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88s2.76-.49,3.55-.88c.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88v-2.6c-1.17,0-1.71-.27-2.38-.61-.78-.39-1.76-.88-3.55-.88ZM26.17,10.31c1.35-1.22,0-3.43-1.69-2.76-.93.37-1.81.91-2.59,1.62-1.23,1.11-2.05,2.52-2.5,4.04-.44-1.53-1.27-2.93-2.5-4.04-.78-.7-1.66-1.25-2.6-1.62-1.69-.67-3.04,1.54-1.69,2.76l4.95,4.49c-1.62-1.1-3.56-1.75-5.67-1.75-1.15,0-2.25.19-3.28.54-1.73.59-1.25,3.19.57,3.19h6.91c-1.52.29-2.97.97-4.18,2.06-.78.7-1.4,1.53-1.87,2.43-.84,1.61,1.22,3.18,2.57,1.97l5.57-5.04-.42,13.87c0,.17-.1.33-.22.46-.18-.08-.35-.16-.53-.26-.78-.39-1.76-.88-3.55-.88s-2.76.49-3.55.88c-.68.34-1.21.61-2.38.61v2.6c1.79,0,2.76-.49,3.55-.88.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88s2.76-.49,3.55-.88c.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88v-2.6c-1.17,0-1.71-.27-2.38-.61h0c-.78-.4-1.76-.89-3.55-.89s-2.76.49-3.55.88c-.2.1-.39.2-.59.28-.15-.13-.24-.3-.25-.48l-.42-13.94,5.65,5.12c1.35,1.22,3.4-.35,2.57-1.97-.46-.89-1.08-1.72-1.87-2.43-1.21-1.1-2.65-1.77-4.18-2.06h6.91c1.83,0,2.3-2.6.57-3.19-1.03-.35-2.13-.54-3.28-.54-2.1,0-4.04.65-5.67,1.75l4.95-4.49Z"/>
|
|
15
|
+
<path class="cls-2" d="M151.71,43.25h-12.45c-.67,0-1.28-.42-1.53-1.04l-2.55-6.55c-.65-1.7-3.15-1.22-3.17.58-.02,1.8-.02,3.53-.02,5.37,0,.9-.74,1.64-1.64,1.64h-10.47c-.92,0-1.64-.72-1.64-1.64V8.34c0-.9.72-1.64,1.64-1.64h12.43c.69-.02,1.28.41,1.53,1.04l2.61,6.84c.65,1.7,3.15,1.25,3.17-.57l.07-5.69c0-.9.74-1.63,1.64-1.63h10.4c.9,0,1.64.74,1.64,1.66v33.26c0,.92-.74,1.64-1.64,1.64l-.02-.02Z"/>
|
|
16
|
+
<path class="cls-2" d="M98.25,37.35l-3.85-.04c-.81,0-1.5.58-1.64,1.38l-.53,3.18c-.12.79-.81,1.38-1.62,1.38h-11.07c-1.07,0-1.85-.99-1.6-2.03l8.38-33.28c.18-.72.85-1.24,1.6-1.24h16.76c.76.02,1.41.53,1.58,1.27l8.4,33.25c.26,1.04-.51,2.05-1.58,2.05l-11.07.04c-.81,0-1.5-.58-1.62-1.38l-.53-3.16c-.12-.79-.81-1.38-1.6-1.38v-.04ZM97.94,27.4l-.85-4.19c-.18-.88-1.44-.88-1.62,0l-.76,4.2c-.19,1.02.62,1.98,1.65,1.94,1.02-.04,1.76-.97,1.57-1.98v.02Z"/>
|
|
17
|
+
<path class="cls-2" d="M69.77,43.23l-10.49.04c-.92,0-1.65-.74-1.65-1.64v-21.76c0-.9-.72-1.64-1.64-1.64h-5.39c-.9,0-1.64-.76-1.64-1.66v-8.2c0-.9.74-1.64,1.65-1.64h27.8c.9,0,1.64.74,1.64,1.64v8.2c0,.9-.72,1.64-1.64,1.64h-5.39c-.9,0-1.64.74-1.64,1.66v21.75c0,.9-.74,1.64-1.64,1.64l.02-.02Z"/>
|
|
18
|
+
<path class="cls-2" d="M311.9,24.92l9.21,15.85c.63,1.1-.14,2.47-1.41,2.47l-10.72.05c-.6,0-1.14-.32-1.44-.83l-4.07-7.21c-.6-1.08-2.24-.65-2.25.58l-.1,5.81c0,.9-.74,1.63-1.64,1.63h-10.47c-.92,0-1.64-.72-1.64-1.64V8.37c0-.9.72-1.64,1.64-1.64h10.49c.9,0,1.62.71,1.64,1.59l.11,4.26c.04,1.27,1.74,1.64,2.29.49l2.59-5.39c.28-.57.85-.94,1.48-.94h10.88c1.27-.02,2.06,1.34,1.43,2.44l-7.97,14.1c-.28.51-.28,1.13,0,1.64h-.02Z"/>
|
|
19
|
+
<path class="cls-2" d="M238.4,37.38l-3.85-.04c-.81,0-1.5.58-1.64,1.38l-.53,3.18c-.12.79-.81,1.38-1.62,1.38h-11.09c-1.07,0-1.85-.99-1.6-2.03l8.38-33.26c.18-.72.85-1.24,1.58-1.24h16.78c.76-.02,1.41.49,1.6,1.22l8.4,33.26c.26,1.04-.51,2.05-1.58,2.05h-11.07c-.81.04-1.5-.55-1.62-1.34l-.53-3.16c-.12-.79-.81-1.38-1.6-1.38v-.02ZM238.07,27.43l-.74-3.67c-.19-.99-1.62-.99-1.81.02l-.67,3.69c-.19,1.02.62,1.98,1.65,1.94,1.02-.04,1.76-.97,1.57-1.98Z"/>
|
|
20
|
+
<path class="cls-2" d="M189.42,33.35c-.99,11.71-17.78,12.35-29.17,8.2-.67-.25-1.11-.9-1.11-1.61v-9.57c0-1.31,1.37-2.14,2.52-1.5,3.68,2.01,7.39,3.44,11.6,4.29,0,0,1.39.11,1.9-.79.51-.9-.46-1.25-.88-1.61-8.01-3.48-17.32-5.53-16.49-14.59.97-10.48,16.83-11.75,27.62-8.39.7.21,1.18.9,1.18,1.64v9.38c0,1.24-1.27,2.07-2.41,1.57-5.16-2.28-12.16-4.29-11.81-2.95.9,3.39,18.06,3.76,17.04,15.9l.02.04Z"/>
|
|
21
|
+
<path class="cls-2" d="M271.32,29.38c2.8,2.33,6.25,2.44,9.22.94,1.41-.71,3.06.25,3.06,1.82l.05,8.37c0,.87-.51,1.68-1.34,1.96-8.08,2.86-17.55,1.24-23.25-5.81-5.7-7.05-5.42-16.91.23-23.62,5.65-6.71,15.03-8.27,23.01-5.55.83.28,1.36,1.1,1.36,1.98l-.05,8.37c0,1.57-1.65,2.53-3.06,1.84-2.94-1.47-6.28-1.47-9.12.79-2.48,1.98-2.75,6.69-.11,8.9Z"/>
|
|
22
|
+
<path class="cls-2" d="M210.7,43.24l-10.49.04c-.92,0-1.65-.74-1.65-1.64v-21.76c0-.9-.72-1.64-1.64-1.64h-5.39c-.9,0-1.64-.76-1.64-1.66v-8.2c0-.9.74-1.64,1.65-1.64h27.79c.9,0,1.64.74,1.64,1.64v8.2c0,.9-.72,1.64-1.64,1.64h-5.39c-.9,0-1.64.74-1.64,1.66v21.75c0,.9-.72,1.64-1.64,1.64l.02-.02Z"/>
|
|
23
|
+
</svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 321.33 50">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill-rule: evenodd;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-1, .cls-2 {
|
|
10
|
+
fill: #fff;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
</defs>
|
|
14
|
+
<path class="cls-1" d="M19.03,0c13.76,0,19.03,8.54,19.03,25s-5.27,25-19.03,25S0,41.46,0,25C0,8.54,5.27,0,19.03,0ZM25.32,36.42c-1.79,0-2.76.49-3.55.88-.68.34-1.21.61-2.38.61-1.17,0-1.71-.27-2.38-.61-.78-.39-1.76-.88-3.55-.88-1.79,0-2.76.49-3.55.88-.68.34-1.21.61-2.38.61v2.6c1.79,0,2.76-.49,3.55-.88.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88s2.76-.49,3.55-.88c.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88v-2.6c-1.17,0-1.71-.27-2.38-.61-.78-.39-1.76-.88-3.55-.88ZM26.17,10.31c1.35-1.22,0-3.43-1.69-2.76-.93.37-1.81.91-2.59,1.62-1.23,1.11-2.05,2.52-2.5,4.04-.44-1.53-1.27-2.93-2.5-4.04-.78-.7-1.66-1.25-2.6-1.62-1.69-.67-3.04,1.54-1.69,2.76l4.95,4.49c-1.62-1.1-3.56-1.75-5.67-1.75-1.15,0-2.25.19-3.28.54-1.73.59-1.25,3.19.57,3.19h6.91c-1.52.29-2.97.97-4.18,2.06-.78.7-1.4,1.53-1.87,2.43-.84,1.61,1.22,3.18,2.57,1.97l5.57-5.04-.42,13.87c0,.17-.1.33-.22.46-.18-.08-.35-.16-.53-.26-.78-.39-1.76-.88-3.55-.88s-2.76.49-3.55.88c-.68.34-1.21.61-2.38.61v2.6c1.79,0,2.76-.49,3.55-.88.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88s2.76-.49,3.55-.88c.68-.34,1.21-.61,2.38-.61s1.71.27,2.38.61c.78.39,1.76.88,3.55.88v-2.6c-1.17,0-1.71-.27-2.38-.61h0c-.78-.4-1.76-.89-3.55-.89s-2.76.49-3.55.88c-.2.1-.39.2-.59.28-.15-.13-.24-.3-.25-.48l-.42-13.94,5.65,5.12c1.35,1.22,3.4-.35,2.57-1.97-.46-.89-1.08-1.72-1.87-2.43-1.21-1.1-2.65-1.77-4.18-2.06h6.91c1.83,0,2.3-2.6.57-3.19-1.03-.35-2.13-.54-3.28-.54-2.1,0-4.04.65-5.67,1.75l4.95-4.49Z"/>
|
|
15
|
+
<path class="cls-2" d="M151.71,43.25h-12.45c-.67,0-1.28-.42-1.53-1.04l-2.55-6.55c-.65-1.7-3.15-1.22-3.17.58-.02,1.8-.02,3.53-.02,5.37,0,.9-.74,1.64-1.64,1.64h-10.47c-.92,0-1.64-.72-1.64-1.64V8.34c0-.9.72-1.64,1.64-1.64h12.43c.69-.02,1.28.41,1.53,1.04l2.61,6.84c.65,1.7,3.15,1.25,3.17-.57l.07-5.69c0-.9.74-1.63,1.64-1.63h10.4c.9,0,1.64.74,1.64,1.66v33.26c0,.92-.74,1.64-1.64,1.64l-.02-.02Z"/>
|
|
16
|
+
<path class="cls-2" d="M98.25,37.35l-3.85-.04c-.81,0-1.5.58-1.64,1.38l-.53,3.18c-.12.79-.81,1.38-1.62,1.38h-11.07c-1.07,0-1.85-.99-1.6-2.03l8.38-33.28c.18-.72.85-1.24,1.6-1.24h16.76c.76.02,1.41.53,1.58,1.27l8.4,33.25c.26,1.04-.51,2.05-1.58,2.05l-11.07.04c-.81,0-1.5-.58-1.62-1.38l-.53-3.16c-.12-.79-.81-1.38-1.6-1.38v-.04ZM97.94,27.4l-.85-4.19c-.18-.88-1.44-.88-1.62,0l-.76,4.2c-.19,1.02.62,1.98,1.65,1.94,1.02-.04,1.76-.97,1.57-1.98v.02Z"/>
|
|
17
|
+
<path class="cls-2" d="M69.77,43.23l-10.49.04c-.92,0-1.65-.74-1.65-1.64v-21.76c0-.9-.72-1.64-1.64-1.64h-5.39c-.9,0-1.64-.76-1.64-1.66v-8.2c0-.9.74-1.64,1.65-1.64h27.8c.9,0,1.64.74,1.64,1.64v8.2c0,.9-.72,1.64-1.64,1.64h-5.39c-.9,0-1.64.74-1.64,1.66v21.75c0,.9-.74,1.64-1.64,1.64l.02-.02Z"/>
|
|
18
|
+
<path class="cls-2" d="M311.9,24.92l9.21,15.85c.63,1.1-.14,2.47-1.41,2.47l-10.72.05c-.6,0-1.14-.32-1.44-.83l-4.07-7.21c-.6-1.08-2.24-.65-2.25.58l-.1,5.81c0,.9-.74,1.63-1.64,1.63h-10.47c-.92,0-1.64-.72-1.64-1.64V8.37c0-.9.72-1.64,1.64-1.64h10.49c.9,0,1.62.71,1.64,1.59l.11,4.26c.04,1.27,1.74,1.64,2.29.49l2.59-5.39c.28-.57.85-.94,1.48-.94h10.88c1.27-.02,2.06,1.34,1.43,2.44l-7.97,14.1c-.28.51-.28,1.13,0,1.64h-.02Z"/>
|
|
19
|
+
<path class="cls-2" d="M238.4,37.38l-3.85-.04c-.81,0-1.5.58-1.64,1.38l-.53,3.18c-.12.79-.81,1.38-1.62,1.38h-11.09c-1.07,0-1.85-.99-1.6-2.03l8.38-33.26c.18-.72.85-1.24,1.58-1.24h16.78c.76-.02,1.41.49,1.6,1.22l8.4,33.26c.26,1.04-.51,2.05-1.58,2.05h-11.07c-.81.04-1.5-.55-1.62-1.34l-.53-3.16c-.12-.79-.81-1.38-1.6-1.38v-.02ZM238.07,27.43l-.74-3.67c-.19-.99-1.62-.99-1.81.02l-.67,3.69c-.19,1.02.62,1.98,1.65,1.94,1.02-.04,1.76-.97,1.57-1.98Z"/>
|
|
20
|
+
<path class="cls-2" d="M189.42,33.35c-.99,11.71-17.78,12.35-29.17,8.2-.67-.25-1.11-.9-1.11-1.61v-9.57c0-1.31,1.37-2.14,2.52-1.5,3.68,2.01,7.39,3.44,11.6,4.29,0,0,1.39.11,1.9-.79.51-.9-.46-1.25-.88-1.61-8.01-3.48-17.32-5.53-16.49-14.59.97-10.48,16.83-11.75,27.62-8.39.7.21,1.18.9,1.18,1.64v9.38c0,1.24-1.27,2.07-2.41,1.57-5.16-2.28-12.16-4.29-11.81-2.95.9,3.39,18.06,3.76,17.04,15.9l.02.04Z"/>
|
|
21
|
+
<path class="cls-2" d="M271.32,29.38c2.8,2.33,6.25,2.44,9.22.94,1.41-.71,3.06.25,3.06,1.82l.05,8.37c0,.87-.51,1.68-1.34,1.96-8.08,2.86-17.55,1.24-23.25-5.81-5.7-7.05-5.42-16.91.23-23.62,5.65-6.71,15.03-8.27,23.01-5.55.83.28,1.36,1.1,1.36,1.98l-.05,8.37c0,1.57-1.65,2.53-3.06,1.84-2.94-1.47-6.28-1.47-9.12.79-2.48,1.98-2.75,6.69-.11,8.9Z"/>
|
|
22
|
+
<path class="cls-2" d="M210.7,43.24l-10.49.04c-.92,0-1.65-.74-1.65-1.64v-21.76c0-.9-.72-1.64-1.64-1.64h-5.39c-.9,0-1.64-.76-1.64-1.66v-8.2c0-.9.74-1.64,1.65-1.64h27.79c.9,0,1.64.74,1.64,1.64v8.2c0,.9-.72,1.64-1.64,1.64h-5.39c-.9,0-1.64.74-1.64,1.66v21.75c0,.9-.72,1.64-1.64,1.64l.02-.02Z"/>
|
|
23
|
+
</svg>
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
//
|
|
5
|
+
// This program is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU Affero General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import { cn } from '@/lib/utils'
|
|
19
|
+
import { ScrollText, AlertTriangle, ArrowLeft } from 'lucide-react'
|
|
20
|
+
import ReactMarkdown from 'react-markdown'
|
|
21
|
+
import { useTranslation } from 'react-i18next'
|
|
22
|
+
import { useMemo, useState } from 'react'
|
|
23
|
+
import { Route } from '@/routes/_nav/changelog/route'
|
|
24
|
+
import type { DeveloperLogEntry } from '@allbluecn/shared'
|
|
25
|
+
import { SDK_GROUPS } from '@/lib/changelog/sdk-versions'
|
|
26
|
+
import { APP_FULL_VERSION } from '@/lib/app-version'
|
|
27
|
+
|
|
28
|
+
const TAG_KEYS = ['all', 'feat', 'fix', 'improvement', 'design', 'refactor', 'breaking', 'docs', 'security', 'perf']
|
|
29
|
+
|
|
30
|
+
const REQUIRES_ACTION_TAGS = new Set(['breaking'])
|
|
31
|
+
|
|
32
|
+
function ChangelogSidebar() {
|
|
33
|
+
const { t } = useTranslation('common')
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<aside className="shrink-0 w-150 h-full flex flex-col py-6 pr-12 pl-10 border-r border-border bg-muted/50">
|
|
37
|
+
<div className="flex-1 flex flex-col gap-8 justify-center">
|
|
38
|
+
<div>
|
|
39
|
+
<h1 className="text-4xl font-medium tracking-tight">
|
|
40
|
+
{t('changelog.title')}
|
|
41
|
+
</h1>
|
|
42
|
+
<p className="text-sm text-muted-foreground mt-3 leading-relaxed">
|
|
43
|
+
{t('changelog.description')}
|
|
44
|
+
</p>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div className="flex flex-col gap-4">
|
|
48
|
+
<h2 className="text-sm font-semibold tracking-tight">
|
|
49
|
+
{t('changelog.sdkVersions')}
|
|
50
|
+
</h2>
|
|
51
|
+
{SDK_GROUPS.map((group) => (
|
|
52
|
+
<SdkGroupSection key={group.id} group={group} t={t} />
|
|
53
|
+
))}
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div>
|
|
57
|
+
<h3 className="text-sm font-semibold tracking-tight">
|
|
58
|
+
{t('changelog.subscribe.title')}
|
|
59
|
+
</h3>
|
|
60
|
+
<p className="text-xs text-muted-foreground mt-1 leading-relaxed">
|
|
61
|
+
{t('changelog.subscribe.subtitle')}
|
|
62
|
+
</p>
|
|
63
|
+
<div className="mt-3 flex gap-1.5">
|
|
64
|
+
<input
|
|
65
|
+
type="email"
|
|
66
|
+
placeholder={t('changelog.subscribe.placeholder')}
|
|
67
|
+
className="flex-1 min-w-0 h-8 rounded-md border border-border bg-background px-3 text-xs placeholder:text-muted-foreground/70 focus:outline-none focus:ring-2 focus:ring-primary/20 transition-shadow"
|
|
68
|
+
/>
|
|
69
|
+
<button className="h-8 px-3 rounded-md bg-primary text-primary-foreground text-xs font-medium hover:bg-primary/90 transition-colors shrink-0">
|
|
70
|
+
{t('changelog.subscribe.submit')}
|
|
71
|
+
</button>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div className="pt-4 border-border/50">
|
|
77
|
+
<code className="text-[10px] font-mono text-primary/80 bg-primary/5 px-2 py-0.5 rounded-full">
|
|
78
|
+
{APP_FULL_VERSION}
|
|
79
|
+
</code>
|
|
80
|
+
</div>
|
|
81
|
+
</aside>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function TagFilter({
|
|
86
|
+
activeTag,
|
|
87
|
+
onTagChange,
|
|
88
|
+
}: {
|
|
89
|
+
activeTag: string
|
|
90
|
+
onTagChange: (tag: string) => void
|
|
91
|
+
}) {
|
|
92
|
+
const { t } = useTranslation('common')
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className="flex flex-wrap gap-1.5">
|
|
96
|
+
{TAG_KEYS.map((tag) => {
|
|
97
|
+
const isActive = activeTag === tag
|
|
98
|
+
const label = t(`changelog.tags.${tag}`)
|
|
99
|
+
return (
|
|
100
|
+
<button
|
|
101
|
+
key={tag}
|
|
102
|
+
onClick={() => onTagChange(tag)}
|
|
103
|
+
className={cn(
|
|
104
|
+
'inline-flex items-center gap-1 px-2.5 py-1 rounded-md text-xs font-medium transition-colors border',
|
|
105
|
+
isActive
|
|
106
|
+
? 'bg-primary/10 text-primary border-primary/20'
|
|
107
|
+
: 'bg-transparent text-muted-foreground border-border/50 hover:text-foreground hover:border-border'
|
|
108
|
+
)}
|
|
109
|
+
>
|
|
110
|
+
{label}
|
|
111
|
+
{REQUIRES_ACTION_TAGS.has(tag) && (
|
|
112
|
+
<AlertTriangle className="size-3" />
|
|
113
|
+
)}
|
|
114
|
+
</button>
|
|
115
|
+
)
|
|
116
|
+
})}
|
|
117
|
+
</div>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function YearHeader({ year, count }: { year: string; count: number }) {
|
|
122
|
+
const { t } = useTranslation('common')
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div className="flex items-center gap-3 py-4 mb-1">
|
|
126
|
+
<h3 className="text-xl font-semibold tracking-tight">{year}</h3>
|
|
127
|
+
<span className="text-xs text-muted-foreground font-mono">
|
|
128
|
+
{count} {t('changelog.entries')}
|
|
129
|
+
</span>
|
|
130
|
+
<div className="flex-1 h-px bg-border/50" />
|
|
131
|
+
</div>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function ChangelogEntry({
|
|
136
|
+
entry,
|
|
137
|
+
onClick,
|
|
138
|
+
}: {
|
|
139
|
+
entry: { id: string; date: string; title: string; desc: string; tags: string[] }
|
|
140
|
+
onClick: (id: string) => void
|
|
141
|
+
}) {
|
|
142
|
+
const { t } = useTranslation('common')
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<div
|
|
146
|
+
className="group py-3 hover:bg-muted/30 -mx-3 px-3 rounded-lg transition-colors cursor-pointer"
|
|
147
|
+
onClick={() => onClick(entry.id)}
|
|
148
|
+
>
|
|
149
|
+
<div className="flex items-start gap-3">
|
|
150
|
+
<div className="shrink-0 pt-0.5">
|
|
151
|
+
<span className="text-xs text-muted-foreground tabular-nums">
|
|
152
|
+
{entry.date}
|
|
153
|
+
</span>
|
|
154
|
+
</div>
|
|
155
|
+
<div className="flex-1 min-w-0">
|
|
156
|
+
<div className="flex items-start gap-2">
|
|
157
|
+
<h4 className="text-sm font-semibold leading-snug group-hover:text-primary transition-colors">
|
|
158
|
+
{entry.title}
|
|
159
|
+
</h4>
|
|
160
|
+
{entry.tags.includes('breaking') && (
|
|
161
|
+
<span className="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium bg-destructive/10 text-destructive shrink-0 mt-0.5">
|
|
162
|
+
<AlertTriangle className="size-2.5" />
|
|
163
|
+
{t('changelog.requiresAction')}
|
|
164
|
+
</span>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
<p className="text-xs text-muted-foreground leading-relaxed mt-1 line-clamp-2">
|
|
168
|
+
{entry.desc}
|
|
169
|
+
</p>
|
|
170
|
+
{entry.tags.length > 0 && (
|
|
171
|
+
<div className="flex flex-wrap gap-1 mt-1.5">
|
|
172
|
+
{entry.tags.map((tag) => (
|
|
173
|
+
<span
|
|
174
|
+
key={tag}
|
|
175
|
+
className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] text-muted-foreground bg-muted/50"
|
|
176
|
+
>
|
|
177
|
+
{t(`changelog.tags.${tag}`)}
|
|
178
|
+
</span>
|
|
179
|
+
))}
|
|
180
|
+
</div>
|
|
181
|
+
)}
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function ChangelogDetail({
|
|
189
|
+
entry,
|
|
190
|
+
onBack,
|
|
191
|
+
}: {
|
|
192
|
+
entry: DeveloperLogEntry
|
|
193
|
+
onBack: () => void
|
|
194
|
+
}) {
|
|
195
|
+
const { t } = useTranslation('common')
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<div className="h-full flex justify-center">
|
|
199
|
+
<div className="max-w-4xl flex flex-col py-5">
|
|
200
|
+
<button
|
|
201
|
+
onClick={onBack}
|
|
202
|
+
className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors mb-6 shrink-0"
|
|
203
|
+
>
|
|
204
|
+
<ArrowLeft className="size-3.5" />
|
|
205
|
+
{t('changelog.backToList')}
|
|
206
|
+
</button>
|
|
207
|
+
|
|
208
|
+
<div className="flex items-start gap-3 mb-4">
|
|
209
|
+
<span className="text-xs text-muted-foreground font-mono tabular-nums pt-0.5 shrink-0">
|
|
210
|
+
{entry.date}
|
|
211
|
+
</span>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<h2 className="text-2xl font-semibold tracking-tight mb-4">
|
|
215
|
+
{entry.title}
|
|
216
|
+
</h2>
|
|
217
|
+
|
|
218
|
+
{entry.tags.length > 0 && (
|
|
219
|
+
<div className="flex flex-wrap gap-1.5 mb-6">
|
|
220
|
+
{entry.tags.map((tag) => (
|
|
221
|
+
<span
|
|
222
|
+
key={tag}
|
|
223
|
+
className={cn(
|
|
224
|
+
'inline-flex items-center gap-1 px-2 py-0.5 rounded text-[10px] font-medium border',
|
|
225
|
+
tag === 'breaking'
|
|
226
|
+
? 'bg-destructive/10 text-destructive border-destructive/20'
|
|
227
|
+
: 'text-muted-foreground bg-muted/50 border-border/50'
|
|
228
|
+
)}
|
|
229
|
+
>
|
|
230
|
+
{t(`changelog.tags.${tag}`)}
|
|
231
|
+
</span>
|
|
232
|
+
))}
|
|
233
|
+
</div>
|
|
234
|
+
)}
|
|
235
|
+
|
|
236
|
+
<div className="typeset typeset-article max-w-[37em]">
|
|
237
|
+
<ReactMarkdown>{entry.desc}</ReactMarkdown>
|
|
238
|
+
</div>
|
|
239
|
+
|
|
240
|
+
{entry.commitSha && (
|
|
241
|
+
<div className="mt-6 pt-4 border-t border-border/50">
|
|
242
|
+
<code className="text-[10px] font-mono text-muted-foreground">
|
|
243
|
+
commit: {entry.commitSha}
|
|
244
|
+
</code>
|
|
245
|
+
</div>
|
|
246
|
+
)}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function SdkGroupSection({ group, t }: { group: (typeof SDK_GROUPS)[0]; t: (key: string) => string }) {
|
|
253
|
+
const isTanstack = group.id === 'tanstack'
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
<div>
|
|
257
|
+
<div
|
|
258
|
+
className="flex items-center gap-1.5 w-full py-1"
|
|
259
|
+
>
|
|
260
|
+
{isTanstack ? (
|
|
261
|
+
<span className="shrink-0">
|
|
262
|
+
<img
|
|
263
|
+
src="/tanstack-landscape-black.svg"
|
|
264
|
+
alt="TanStack"
|
|
265
|
+
className="h-4 dark:hidden"
|
|
266
|
+
/>
|
|
267
|
+
<img
|
|
268
|
+
src="/tanstack-landscape-white.svg"
|
|
269
|
+
alt="TanStack"
|
|
270
|
+
className="hidden h-4 dark:block"
|
|
271
|
+
/>
|
|
272
|
+
</span>
|
|
273
|
+
) : (
|
|
274
|
+
<span className="text-base">{group.icon}</span>
|
|
275
|
+
)}
|
|
276
|
+
<span className="text-xs mt-1 font-semibold text-foreground/80">
|
|
277
|
+
{t(`changelog.sdkGroups.${group.label}`)}
|
|
278
|
+
</span>
|
|
279
|
+
</div>
|
|
280
|
+
<ul className="mt-1 flex flex-col">
|
|
281
|
+
{group.items.map((sdk) => (
|
|
282
|
+
<li key={sdk.name}>
|
|
283
|
+
<a
|
|
284
|
+
href={sdk.docsUrl || undefined}
|
|
285
|
+
target={sdk.docsUrl ? '_blank' : undefined}
|
|
286
|
+
rel={sdk.docsUrl ? 'noopener noreferrer' : undefined}
|
|
287
|
+
className="flex items-center justify-between gap-2 py-1.5 group"
|
|
288
|
+
>
|
|
289
|
+
<span className="text-xs font-medium text-muted-foreground group-hover:text-primary transition-colors truncate">
|
|
290
|
+
{sdk.name}
|
|
291
|
+
</span>
|
|
292
|
+
<code className="text-[10px] font-mono text-muted-foreground bg-muted/50 px-1.5 py-0.5 rounded shrink-0 group-hover:text-primary transition-colors">
|
|
293
|
+
{sdk.version}
|
|
294
|
+
</code>
|
|
295
|
+
</a>
|
|
296
|
+
</li>
|
|
297
|
+
))}
|
|
298
|
+
</ul>
|
|
299
|
+
</div>
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function ChangelogPage() {
|
|
304
|
+
const { t } = useTranslation('common')
|
|
305
|
+
const [activeTag, setActiveTag] = useState<string>('all')
|
|
306
|
+
const [selectedEntryId, setSelectedEntryId] = useState<string | null>(null)
|
|
307
|
+
const { entries } = Route.useLoaderData()
|
|
308
|
+
|
|
309
|
+
const filteredEntries = useMemo(() => {
|
|
310
|
+
if (activeTag === 'all') return entries
|
|
311
|
+
return entries.filter((entry) => entry.tags.includes(activeTag))
|
|
312
|
+
}, [activeTag, entries])
|
|
313
|
+
|
|
314
|
+
const grouped = useMemo(() => {
|
|
315
|
+
const groups: Record<string, DeveloperLogEntry[]> = {}
|
|
316
|
+
filteredEntries.forEach((entry) => {
|
|
317
|
+
if (!groups[entry.year]) groups[entry.year] = []
|
|
318
|
+
groups[entry.year].push(entry)
|
|
319
|
+
})
|
|
320
|
+
return Object.entries(groups).sort(([a], [b]) => Number(b) - Number(a))
|
|
321
|
+
}, [filteredEntries])
|
|
322
|
+
|
|
323
|
+
const selectedEntry = useMemo(
|
|
324
|
+
() => entries.find((e) => e.id === selectedEntryId) ?? null,
|
|
325
|
+
[entries, selectedEntryId]
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
const handleEntryClick = (id: string) => {
|
|
329
|
+
setSelectedEntryId(id)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const handleBack = () => {
|
|
333
|
+
setSelectedEntryId(null)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<div className="h-full flex">
|
|
338
|
+
<ChangelogSidebar />
|
|
339
|
+
|
|
340
|
+
<div className="flex-1 min-w-0 flex flex-col h-full pl-8 pr-6 py-5">
|
|
341
|
+
{selectedEntry ? (
|
|
342
|
+
<ChangelogDetail entry={selectedEntry} onBack={handleBack} />
|
|
343
|
+
) : (
|
|
344
|
+
<>
|
|
345
|
+
<div className="shrink-0 pb-3">
|
|
346
|
+
<TagFilter activeTag={activeTag} onTagChange={setActiveTag} />
|
|
347
|
+
</div>
|
|
348
|
+
|
|
349
|
+
<div className="flex-1 min-h-0 overflow-y-auto">
|
|
350
|
+
{grouped.length === 0 ? (
|
|
351
|
+
<div className="flex flex-col items-center justify-center h-40 text-center">
|
|
352
|
+
<ScrollText className="size-8 text-muted-foreground/40 mb-2" />
|
|
353
|
+
<p className="text-sm text-muted-foreground">{t('changelog.noMatch')}</p>
|
|
354
|
+
<p className="text-xs text-muted-foreground mt-0.5">{t('changelog.noMatchHint')}</p>
|
|
355
|
+
</div>
|
|
356
|
+
) : (
|
|
357
|
+
<div className="space-y-4">
|
|
358
|
+
{grouped.map(([year, yearEntries]) => (
|
|
359
|
+
<div key={year}>
|
|
360
|
+
<YearHeader year={year} count={yearEntries.length} />
|
|
361
|
+
<div className="space-y-0">
|
|
362
|
+
{yearEntries.map((entry) => (
|
|
363
|
+
<ChangelogEntry
|
|
364
|
+
key={entry.id}
|
|
365
|
+
entry={entry}
|
|
366
|
+
onClick={handleEntryClick}
|
|
367
|
+
/>
|
|
368
|
+
))}
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
))}
|
|
372
|
+
</div>
|
|
373
|
+
)}
|
|
374
|
+
</div>
|
|
375
|
+
</>
|
|
376
|
+
)}
|
|
377
|
+
</div>
|
|
378
|
+
</div>
|
|
379
|
+
)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export { ChangelogPage }
|
|
@@ -39,7 +39,8 @@ import { Badge } from "@/components/ui/badge"
|
|
|
39
39
|
import { workspaceRoutes } from "@/config/sidebar-routes";
|
|
40
40
|
import { notifications } from "@/config/sidebar-notifications";
|
|
41
41
|
import type { Route } from "@/config/sidebar-routes";
|
|
42
|
-
import { SidebarSearchTrigger } from "@/components/layout/sidebar-03/
|
|
42
|
+
import { SidebarSearchTrigger } from "@/components/layout/sidebar-03/nav-search-trigger"
|
|
43
|
+
import { NavSecondary } from "@/components/layout/sidebar-03/nav-secondary"
|
|
43
44
|
import { PluginNavItems } from '@/components/plugin-slots/plugin-nav-items'
|
|
44
45
|
|
|
45
46
|
export function DashboardSidebar() {
|
|
@@ -101,6 +102,7 @@ export function DashboardSidebar() {
|
|
|
101
102
|
<NavAnyHub />
|
|
102
103
|
</SidebarContent>
|
|
103
104
|
<SidebarFooter className="gap-2 px-2 pb-3">
|
|
105
|
+
<NavSecondary />
|
|
104
106
|
<SidebarSearchTrigger />
|
|
105
107
|
<UserMenu />
|
|
106
108
|
</SidebarFooter>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SidebarMenu,
|
|
3
|
+
SidebarMenuButton,
|
|
4
|
+
SidebarMenuItem,
|
|
5
|
+
useSidebar,
|
|
6
|
+
} from "@/components/ui/sidebar"
|
|
7
|
+
import { BookOpen, ScrollText } from "lucide-react"
|
|
8
|
+
import { cn } from "@/lib/utils"
|
|
9
|
+
import { Link } from "@tanstack/react-router"
|
|
10
|
+
import { APP_VERSION_DISPLAY } from "@/lib/app-version"
|
|
11
|
+
|
|
12
|
+
const items = [
|
|
13
|
+
{
|
|
14
|
+
title: "使用文档",
|
|
15
|
+
Icon: BookOpen,
|
|
16
|
+
href: "/docs",
|
|
17
|
+
tooltip: "使用文档",
|
|
18
|
+
external: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: "开发者日志",
|
|
22
|
+
Icon: ScrollText,
|
|
23
|
+
href: "/changelog",
|
|
24
|
+
tooltip: "开发者日志",
|
|
25
|
+
badge: APP_VERSION_DISPLAY,
|
|
26
|
+
},
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
export function NavSecondary() {
|
|
30
|
+
const { state } = useSidebar()
|
|
31
|
+
const isCollapsed = state === "collapsed"
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<SidebarMenu className={cn("space-y-1", isCollapsed && "px-1")}>
|
|
35
|
+
{!isCollapsed && (
|
|
36
|
+
<div className="px-2 text-xs font-medium text-muted-foreground/70">
|
|
37
|
+
{/* 资源 */}
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
{items.map((item) => (
|
|
41
|
+
<SidebarMenuItem key={item.title}>
|
|
42
|
+
<SidebarMenuButton
|
|
43
|
+
asChild
|
|
44
|
+
tooltip={item.tooltip}
|
|
45
|
+
className={cn(
|
|
46
|
+
"flex items-center rounded-lg px-2",
|
|
47
|
+
isCollapsed && "justify-center"
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
{item.external ? (
|
|
51
|
+
<a
|
|
52
|
+
href={item.href}
|
|
53
|
+
className={cn(
|
|
54
|
+
"flex w-full items-center gap-3 text-muted-foreground hover:text-foreground",
|
|
55
|
+
isCollapsed && "justify-center -ml-1"
|
|
56
|
+
)}
|
|
57
|
+
target="_blank"
|
|
58
|
+
rel="noopener noreferrer"
|
|
59
|
+
style={{ width: "100%", height: "100%" }}
|
|
60
|
+
>
|
|
61
|
+
<item.Icon className={cn("text-muted-foreground", !isCollapsed && "size-3.5!")} />
|
|
62
|
+
{!isCollapsed && (
|
|
63
|
+
<span className="text-xs text-muted-foreground">{item.title}</span>
|
|
64
|
+
)}
|
|
65
|
+
</a>
|
|
66
|
+
) : (
|
|
67
|
+
<Link
|
|
68
|
+
to={item.href}
|
|
69
|
+
className={cn(
|
|
70
|
+
"flex w-full items-center justify-between gap-3 text-muted-foreground hover:text-foreground",
|
|
71
|
+
isCollapsed && "justify-center -ml-1"
|
|
72
|
+
)}
|
|
73
|
+
style={{ width: "100%", height: "100%" }}
|
|
74
|
+
>
|
|
75
|
+
<div className="flex items-center gap-3">
|
|
76
|
+
<item.Icon className={cn("text-muted-foreground", !isCollapsed && "size-3.5!")} />
|
|
77
|
+
{!isCollapsed && (
|
|
78
|
+
<span className="text-xs text-muted-foreground">{item.title}</span>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
{!isCollapsed && item.badge && (
|
|
82
|
+
<code className="text-[10px] font-mono text-muted-foreground/60 bg-muted/50 px-1.5 py-0.5 rounded shrink-0">
|
|
83
|
+
{item.badge}
|
|
84
|
+
</code>
|
|
85
|
+
)}
|
|
86
|
+
</Link>
|
|
87
|
+
)}
|
|
88
|
+
</SidebarMenuButton>
|
|
89
|
+
</SidebarMenuItem>
|
|
90
|
+
))}
|
|
91
|
+
</SidebarMenu>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
// AllBlue - 理想之海
|
|
3
|
+
// Copyright (C) 2026 AllBlue Contributors
|
|
4
|
+
//
|
|
5
|
+
// This program is free software: you can redistribute it and/or modify
|
|
6
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
// (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU Affero General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
export const APP_VERSION = '0.5.0'
|
|
19
|
+
export const APP_VERSION_DISPLAY = `v${APP_VERSION}`
|
|
20
|
+
export const APP_FULL_VERSION = `AllBlue v${APP_VERSION}`
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SdkVersion {
|
|
2
|
+
name: string
|
|
3
|
+
version: string
|
|
4
|
+
lastUpdate: string
|
|
5
|
+
source: string
|
|
6
|
+
docsUrl: string | null
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface SdkGroup {
|
|
10
|
+
id: 'tanstack' | 'allblue' | 'core'
|
|
11
|
+
label: string
|
|
12
|
+
icon: string
|
|
13
|
+
items: SdkVersion[]
|
|
14
|
+
}
|