This is an automated email from the ASF dual-hosted git repository.

lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 592d8d415 feat: add roadmap page
592d8d415 is described below

commit 592d8d415ca4e720c7048bfa1d572e10169b5120
Author: JingsongLi <[email protected]>
AuthorDate: Tue Dec 23 13:44:09 2025 +0800

    feat: add roadmap page
---
 angular.json                                    |  3 +-
 community/docs/roadmap.md                       | 12 ++++++
 library/markdown-parser/handlers/document.ts    |  7 +++-
 library/markdown-parser/handlers/prerender.ts   |  2 +-
 library/markdown-parser/utils/directory.ts      |  4 +-
 src/app/app.routes.ts                           |  8 ++++
 src/app/components/header/header.component.html | 17 ++++++++
 src/app/routers/roadmap/roadmap.component.html  | 33 +++++++++++++++
 src/app/routers/roadmap/roadmap.component.ts    | 54 +++++++++++++++++++++++++
 src/app/services/document.service.ts            |  4 ++
 src/assets/i18n/en.json                         |  3 +-
 src/assets/i18n/zh.json                         |  1 +
 12 files changed, 141 insertions(+), 7 deletions(-)

diff --git a/angular.json b/angular.json
index 72e277061..395d8ecd8 100644
--- a/angular.json
+++ b/angular.json
@@ -135,6 +135,7 @@
   "cli": {
     "schematicCollections": [
       "@angular-eslint/schematics"
-    ]
+    ],
+    "analytics": "327481a5-f266-47d9-8c71-490982d7676f"
   }
 }
diff --git a/community/docs/roadmap.md b/community/docs/roadmap.md
new file mode 100644
index 000000000..52ef60ba6
--- /dev/null
+++ b/community/docs/roadmap.md
@@ -0,0 +1,12 @@
+---
+title: "Roadmap"
+type: roadmap
+alias: roadmap
+---
+
+# Roadmap
+
+This roadmap means to provide users and contributors with a high-level summary 
of ongoing efforts in the Paimon community.
+The roadmap contains both efforts working in process as well as completed 
efforts, so that users may get a better impression
+of the overall status and direction of those developments.
+
diff --git a/library/markdown-parser/handlers/document.ts 
b/library/markdown-parser/handlers/document.ts
index 7e07b70b1..8e08eb581 100644
--- a/library/markdown-parser/handlers/document.ts
+++ b/library/markdown-parser/handlers/document.ts
@@ -24,7 +24,7 @@ import { parse as parseFileName } from 'path';
 import { BriefRelease, parseDocumentFromBuffer, ResolvedDocument, 
resolveDocument } from '../models/document';
 import { getDirectoryPath } from '../utils/directory';
 
-const { downloadsSource, releasesSource, docsDist } = getDirectoryPath();
+const { markdownSource, releasesSource, docsDist } = getDirectoryPath();
 
 export function processDocuments(): { releases: BriefRelease[] } {
   if (fs.existsSync(docsDist)) {
@@ -37,9 +37,12 @@ export function processDocuments(): { releases: 
BriefRelease[] } {
   }
 
   const releases: ResolvedDocument[] = [];
-  const downloads = parseDocumentFromBuffer('downloads', 
readFileSync(`${downloadsSource}/downloads.md`));
+  const downloads = parseDocumentFromBuffer('downloads', 
readFileSync(`${markdownSource}/downloads.md`));
   const resolvedDownloads = resolveDocument(downloads);
   writeFileSync(`${docsDist}/downloads.json`, 
JSON.stringify(resolvedDownloads));
+  const roadmap = parseDocumentFromBuffer('roadmap', 
readFileSync(`${markdownSource}/roadmap.md`));
+  const resolvedRoadmap = resolveDocument(roadmap);
+  writeFileSync(`${docsDist}/roadmap.json`, JSON.stringify(resolvedRoadmap));
 
   readdirSync(releasesSource).forEach(file => {
     const { name } = parseFileName(file);
diff --git a/library/markdown-parser/handlers/prerender.ts 
b/library/markdown-parser/handlers/prerender.ts
index 39b585ccb..24287b8cb 100644
--- a/library/markdown-parser/handlers/prerender.ts
+++ b/library/markdown-parser/handlers/prerender.ts
@@ -27,7 +27,7 @@ const { dist } = getDirectoryPath();
 export function processRoutes(articles: ResolvedArticle[], releases: 
BriefRelease[]): void {
   const articleUrls = articles.map(item => `/blog/${item.id}`);
   const releaseUrls = releases.map(item => `/releases/${item.version}`);
-  const homeUrls = ['/', '/blog', '/downloads', '/releases'];
+  const homeUrls = ['/', '/blog', '/downloads', '/roadmap', '/releases'];
   const content = [...homeUrls, ...articleUrls, ...releaseUrls].join('\n');
   writeFileSync(`${dist}/routes.txt`, content);
 }
diff --git a/library/markdown-parser/utils/directory.ts 
b/library/markdown-parser/utils/directory.ts
index 15c1581e2..8162e4082 100644
--- a/library/markdown-parser/utils/directory.ts
+++ b/library/markdown-parser/utils/directory.ts
@@ -28,7 +28,7 @@ export const getDirectoryPath = (): {
   articleDist: string;
   profileDist: string;
   articleSource: string;
-  downloadsSource: string;
+  markdownSource: string;
   releasesSource: string;
   docsDist: string;
   profileSource: string;
@@ -44,7 +44,7 @@ export const getDirectoryPath = (): {
     articleDist: resolve(dist, Configuration.directory.article),
     profileDist: resolve(dist, Configuration.directory.profile),
     articleSource: resolve(source, Configuration.directory.article),
-    downloadsSource: resolve(source, 'docs'),
+    markdownSource: resolve(source, 'docs'),
     releasesSource: resolve(source, 'docs', Configuration.directory.release),
     docsDist: resolve(distRoot, `./assets/docs`),
     profileSource: resolve(source, Configuration.directory.profile)
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 109a12217..42e9458dd 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -20,6 +20,7 @@ import { Routes } from '@angular/router';
 
 import { DownloadsComponent, downloadsResolver } from 
'@paimon/app/routers/downloads/downloads.component';
 import { HomeComponent } from '@paimon/app/routers/home/home.component';
+import { RoadmapComponent, roadmapResolver } from 
'@paimon/app/routers/roadmap/roadmap.component';
 import { SecurityComponent } from 
'@paimon/app/routers/security/security.component';
 import { TeamComponent } from '@paimon/app/routers/team/team.component';
 import { UsersComponent } from '@paimon/app/routers/users/users.component';
@@ -48,6 +49,13 @@ export const routes: Routes = [
       downloads: downloadsResolver
     }
   },
+  {
+    path: 'roadmap',
+    component: RoadmapComponent,
+    resolve: {
+      roadmap: roadmapResolver
+    }
+  },
   {
     path: 'users',
     component: UsersComponent
diff --git a/src/app/components/header/header.component.html 
b/src/app/components/header/header.component.html
index 5b1663922..6b46dd5cf 100644
--- a/src/app/components/header/header.component.html
+++ b/src/app/components/header/header.component.html
@@ -48,6 +48,14 @@
           DOWNLOADS
         </a>
         <paimon-divider></paimon-divider>
+        <a
+          [routerLink]="['/', 'roadmap']"
+          class="px-3 py-2 text-sm font-medium text-gray-300 hover:text-white"
+          translate
+        >
+          ROADMAP
+        </a>
+        <paimon-divider></paimon-divider>
         <a
           [routerLink]="
             latestReleaseVersion ? ['/', 'releases', latestReleaseVersion] : 
['/', 'releases']
@@ -186,6 +194,15 @@
                   DOWNLOADS
                 </a>
               </li>
+              <li class="hover:bg-paimon-gray-12">
+                <a
+                  [routerLink]="['/', 'roadmap']"
+                  class="flex h-10 w-full items-center justify-start px-8 
no-underline hover:text-paimon-text-hover"
+                  translate
+                >
+                  ROADMAP
+                </a>
+              </li>
               <li class="hover:bg-paimon-gray-12">
                 <a
                   [routerLink]="
diff --git a/src/app/routers/roadmap/roadmap.component.html 
b/src/app/routers/roadmap/roadmap.component.html
new file mode 100644
index 000000000..0fafd36ee
--- /dev/null
+++ b/src/app/routers/roadmap/roadmap.component.html
@@ -0,0 +1,33 @@
+<paimon-page-container>
+  <div header>
+    <div class="mt-16 text-6xl font-normal text-paimon-gray-3">Roadmap</div>
+  </div>
+  <div content>
+    @if (roadmap) {
+      <paimon-markdown-render [html]="roadmap.content" [toc]="roadmap.toc">
+        <div footer class="my-8">
+          <a
+            class="group/link flex text-paimon-gray-14 
hover:text-paimon-blue-primary"
+            [attr.href]="['docs', roadmap.alias + '.md'] | githubUrl"
+            target="_blank"
+            translate
+          >
+            <svg class="mr-2 w-5 group-hover/link:fill-paimon-blue-primary" 
viewBox="0 0 1024 1024">
+              <path
+                d="M918.125 878h-0.875a0.125 0.125 0 0 0-0.125 
0.125v5h-10.25v-10.25h5a0.125 0.125 0 0 0 0.125-0.125v-0.875a0.125 0.125 0 0 
0-0.125-0.125h-5.625a0.5 0.5 0 0 0-0.5 0.5v11.5a0.5 0.5 0 0 0 0.5 0.5h11.5a0.5 
0.5 0 0 0 0.5-0.5v-5.625a0.125 0.125 0 0 0-0.125-0.125z"
+              ></path>
+              <path
+                d="M909.56 878.358l-0.029 1.858a0.25 0.25 0 0 0 0.25 
0.253h0.007l1.843-0.046a0.13 0.13 0 0 0 0.085-0.036l6.498-6.484a0.125 0.125 0 0 
0 0-0.176l-1.942-1.941a0.13 0.13 0 0 0-0.178 0l-6.497 6.484a0.13 0.13 0 0 
0-0.036 0.088z m0.993 0.369l5.63-5.618 0.706 0.705-5.633 5.62-0.714 0.018 
0.011-0.725z"
+              ></path>
+              <path
+                d="M257.7 752c2 0 4-0.2 6-0.5L431.9 722c2-0.4 3.9-1.3 
5.3-2.8l423.9-423.9c3.9-3.9 3.9-10.2 0-14.1L694.9 
114.9c-1.9-1.9-4.4-2.9-7.1-2.9-2.7 0-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 
3.3-2.8 5.3l-29.5 168.2c-1.9 11.1 1.5 21.9 9.4 29.8 6.6 6.4 14.9 9.9 23.8 9.9z 
m67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 
836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 
8-8v-36c0-17.7-14.3-32-32-32z"
+              ></path>
+            </svg>
+
+            Edit this page
+          </a>
+        </div>
+      </paimon-markdown-render>
+    }
+  </div>
+</paimon-page-container>
diff --git a/src/app/routers/roadmap/roadmap.component.ts 
b/src/app/routers/roadmap/roadmap.component.ts
new file mode 100644
index 000000000..c49e086cc
--- /dev/null
+++ b/src/app/routers/roadmap/roadmap.component.ts
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit 
} from '@angular/core';
+import { ActivatedRoute, ResolveFn } from '@angular/router';
+
+import { ResolvedDocument } from '@paimon-markdown-parser/document';
+
+import { MarkdownRenderComponent } from 
'@paimon/app/components/markdown-render/markdown-render.component';
+import { PageContainerComponent } from 
'@paimon/app/components/page-container/page-container.component';
+import { GithubUrlPipe } from '@paimon/app/components/pipes/github-url.pipe';
+import { DocumentService } from '@paimon/app/services/document.service';
+
+export const roadmapResolver: ResolveFn<unknown> = () => {
+  const documentService = inject(DocumentService);
+  return documentService.getRoadmap();
+};
+
+@Component({
+  selector: 'paimon-roadmap',
+  standalone: true,
+  imports: [PageContainerComponent, MarkdownRenderComponent, GithubUrlPipe],
+  templateUrl: './roadmap.component.html',
+  changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class RoadmapComponent implements OnInit {
+  roadmap: ResolvedDocument | null = null;
+  constructor(
+    private activatedRoute: ActivatedRoute,
+    private cdr: ChangeDetectorRef
+  ) {}
+
+  ngOnInit(): void {
+    this.activatedRoute.data.subscribe(({ roadmap }) => {
+      this.roadmap = roadmap;
+      this.cdr.markForCheck();
+    });
+  }
+}
diff --git a/src/app/services/document.service.ts 
b/src/app/services/document.service.ts
index de36778ea..786c304bc 100644
--- a/src/app/services/document.service.ts
+++ b/src/app/services/document.service.ts
@@ -47,6 +47,10 @@ export class DocumentService {
     return 
this.httpClient.get<ResolvedDocument>(`${this.baseUrl}/downloads.json`);
   }
 
+  getRoadmap(): Observable<ResolvedDocument> {
+    return 
this.httpClient.get<ResolvedDocument>(`${this.baseUrl}/roadmap.json`);
+  }
+
   listRelease(): Observable<BriefRelease[]> {
     if (this.briefReleases$) {
       return this.briefReleases$;
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 9d2883005..603694b1a 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -18,6 +18,7 @@
        "DOCUMENT": "DOCUMENT",
        "DOCUMENTATION": "DOCUMENTATION",
        "DOWNLOADS": "DOWNLOADS",
+       "ROADMAP": "ROADMAP",
        "Data Lake Capabilities": "Data Lake Capabilities",
        "Defining Merge Engines, update records however you like. Deduplicate 
to keep last row, or partial-update, or aggregate records, or first-row, you 
decide.": "Defining Merge Engines, update records however you like. Deduplicate 
to keep last row, or partial-update, or aggregate records, or first-row, you 
decide.",
        "Defining changelog-producer, produce correct and complete changelog in 
updates for merge engines, simplifying your streaming analytics.": "Defining 
changelog-producer, produce correct and complete changelog in updates for merge 
engines, simplifying your streaming analytics.",
@@ -55,4 +56,4 @@
        "Various companies and organizations are using Paimon for production 
and commercial products.": "Various companies and organizations are using 
Paimon for production and commercial products.",
        "WHY PAIMON": "WHY PAIMON",
        "Who's Using": "Who's Using"
-}
\ No newline at end of file
+}
diff --git a/src/assets/i18n/zh.json b/src/assets/i18n/zh.json
index bfd1da520..1e56e5255 100644
--- a/src/assets/i18n/zh.json
+++ b/src/assets/i18n/zh.json
@@ -18,6 +18,7 @@
        "DOCUMENT": "文档",
        "DOCUMENTATION": "文档",
        "DOWNLOADS": "下载",
+       "ROADMAP": "路线",
        "Data Lake Capabilities": "数据湖功能",
        "Defining Merge Engines, update records however you like. Deduplicate 
to keep last row, or partial-update, or aggregate records, or first-row, you 
decide.": "定义合并引擎,按你喜欢的方式更新记录。删除重复项以保留最后一行,或部分更新,或聚合记录,或第一行,由你决定",
        "Defining changelog-producer, produce correct and complete changelog in 
updates for merge engines, simplifying your streaming analytics.": "定义 
changelog-producer,为合并引擎的更新生成正确且完整的变更日志,简化您的流分析",

Reply via email to