From 612b00179ba407c82494dda57dab540f95c63881 Mon Sep 17 00:00:00 2001 From: Yash Date: Thu, 25 Dec 2025 00:21:10 +0530 Subject: [PATCH 1/3] feat : Add version settings and API endpoint to display application version --- .../preferences/PreferenceSettings.tsx | 5 +++ .../settings/preferences/VersionSetting.tsx | 31 ++++++++++++++++ src/app/api/version/route.ts | 35 +++++++++++++++++++ src/components/messages.ts | 1 + 4 files changed, 72 insertions(+) create mode 100644 src/app/(main)/settings/preferences/VersionSetting.tsx create mode 100644 src/app/api/version/route.ts diff --git a/src/app/(main)/settings/preferences/PreferenceSettings.tsx b/src/app/(main)/settings/preferences/PreferenceSettings.tsx index a2890ce9..cc2d1b62 100644 --- a/src/app/(main)/settings/preferences/PreferenceSettings.tsx +++ b/src/app/(main)/settings/preferences/PreferenceSettings.tsx @@ -4,6 +4,7 @@ import { DateRangeSetting } from './DateRangeSetting'; import { LanguageSetting } from './LanguageSetting'; import { ThemeSetting } from './ThemeSetting'; import { TimezoneSetting } from './TimezoneSetting'; +import { VersionSetting } from './VersionSetting'; export function PreferenceSettings() { const { user } = useLoginQuery(); @@ -31,6 +32,10 @@ export function PreferenceSettings() { + + + + ); } diff --git a/src/app/(main)/settings/preferences/VersionSetting.tsx b/src/app/(main)/settings/preferences/VersionSetting.tsx new file mode 100644 index 00000000..2cfdbeb7 --- /dev/null +++ b/src/app/(main)/settings/preferences/VersionSetting.tsx @@ -0,0 +1,31 @@ +'use client'; + +import { Text } from '@umami/react-zen'; +import { useEffect, useState } from 'react'; + +export function VersionSetting() { + const [version, setVersion] = useState(''); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchVersion = async () => { + try { + const response = await fetch('/api/version'); + const data = await response.json(); + setVersion(data.version || 'unknown'); + } catch (error) { + setVersion('unknown'); + } finally { + setLoading(false); + } + }; + + fetchVersion(); + }, []); + + if (loading) { + return Loading...; + } + + return {version}; +} diff --git a/src/app/api/version/route.ts b/src/app/api/version/route.ts new file mode 100644 index 00000000..af548f73 --- /dev/null +++ b/src/app/api/version/route.ts @@ -0,0 +1,35 @@ +import { readFile } from 'fs/promises'; +import { join } from 'path'; +import { parseRequest } from '@/lib/request'; +import { json } from '@/lib/response'; + +let cachedVersion: string | null = null; + +async function getVersion(): Promise { + if (cachedVersion) { + return cachedVersion; + } + + try { + const packageJsonPath = join(process.cwd(), 'package.json'); + const data = await readFile(packageJsonPath, 'utf-8'); + const packageJson = JSON.parse(data); + cachedVersion = packageJson.version || 'unknown'; + } catch (error) { + cachedVersion = 'unknown'; + } + + return cachedVersion; +} + +export async function GET(request: Request) { + const { error } = await parseRequest(request, null, { skipAuth: true }); + + if (error) { + return error(); + } + + const version = await getVersion(); + + return json({ version }); +} diff --git a/src/components/messages.ts b/src/components/messages.ts index 0438c06e..712495d8 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -351,6 +351,7 @@ export const labels = defineMessages({ growth: { id: 'label.growth', defaultMessage: 'Growth' }, account: { id: 'label.account', defaultMessage: 'Account' }, application: { id: 'label.application', defaultMessage: 'Application' }, + version: { id: 'label.version', defaultMessage: 'Version' }, saveSegment: { id: 'label.save-segment', defaultMessage: 'Save as segment' }, saveCohort: { id: 'label.save-cohort', defaultMessage: 'Save as cohort' }, analysis: { id: 'label.analysis', defaultMessage: 'Analysis' }, From 5e3e6b3edda495d80bb1e86ed3ccae949c07a469 Mon Sep 17 00:00:00 2001 From: Yash Date: Thu, 25 Dec 2025 09:48:09 +0530 Subject: [PATCH 2/3] refactor: Simplify version display by removing API endpoint and using constant --- .../settings/preferences/VersionSetting.tsx | 27 ++------------ src/app/api/version/route.ts | 35 ------------------- 2 files changed, 2 insertions(+), 60 deletions(-) delete mode 100644 src/app/api/version/route.ts diff --git a/src/app/(main)/settings/preferences/VersionSetting.tsx b/src/app/(main)/settings/preferences/VersionSetting.tsx index 2cfdbeb7..afca1de6 100644 --- a/src/app/(main)/settings/preferences/VersionSetting.tsx +++ b/src/app/(main)/settings/preferences/VersionSetting.tsx @@ -1,31 +1,8 @@ 'use client'; import { Text } from '@umami/react-zen'; -import { useEffect, useState } from 'react'; +import { CURRENT_VERSION } from '@/lib/constants'; export function VersionSetting() { - const [version, setVersion] = useState(''); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchVersion = async () => { - try { - const response = await fetch('/api/version'); - const data = await response.json(); - setVersion(data.version || 'unknown'); - } catch (error) { - setVersion('unknown'); - } finally { - setLoading(false); - } - }; - - fetchVersion(); - }, []); - - if (loading) { - return Loading...; - } - - return {version}; + return {CURRENT_VERSION}; } diff --git a/src/app/api/version/route.ts b/src/app/api/version/route.ts deleted file mode 100644 index af548f73..00000000 --- a/src/app/api/version/route.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { readFile } from 'fs/promises'; -import { join } from 'path'; -import { parseRequest } from '@/lib/request'; -import { json } from '@/lib/response'; - -let cachedVersion: string | null = null; - -async function getVersion(): Promise { - if (cachedVersion) { - return cachedVersion; - } - - try { - const packageJsonPath = join(process.cwd(), 'package.json'); - const data = await readFile(packageJsonPath, 'utf-8'); - const packageJson = JSON.parse(data); - cachedVersion = packageJson.version || 'unknown'; - } catch (error) { - cachedVersion = 'unknown'; - } - - return cachedVersion; -} - -export async function GET(request: Request) { - const { error } = await parseRequest(request, null, { skipAuth: true }); - - if (error) { - return error(); - } - - const version = await getVersion(); - - return json({ version }); -} From b0aa6fd6efa55fbb5402d3a171ff3e1fcf251b41 Mon Sep 17 00:00:00 2001 From: Yash Date: Fri, 26 Dec 2025 22:13:23 +0530 Subject: [PATCH 3/3] feat: Add current version to API response --- src/app/api/config/route.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/api/config/route.ts b/src/app/api/config/route.ts index 4e40caa4..101a1224 100644 --- a/src/app/api/config/route.ts +++ b/src/app/api/config/route.ts @@ -17,5 +17,6 @@ export async function GET(request: Request) { telemetryDisabled: !!process.env.DISABLE_TELEMETRY, trackerScriptName: process.env.TRACKER_SCRIPT_NAME, updatesDisabled: !!process.env.DISABLE_UPDATES, + currentVersion: !!process.env.currentVersion, }); }