fix(nacos): format history timestamps
This commit is contained in:
3 files changed
+43
-2
No files matched your search
@@ -5,6 +5,7 @@ import { useI18n } from "vue-i18n";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { formatNacosHistoryTime } from "@/lib/nacos/nacosAdmin";
|
||||
import type { NacosConfigHistoryItem, NacosConfigItem } from "@/types/nacos";
|
||||
|
||||
const open = defineModel<boolean>("open", { default: false });
|
||||
@@ -69,6 +70,10 @@ function display(value?: string | null) {
|
||||
return trimmed || "-";
|
||||
}
|
||||
|
||||
function displayHistoryTime(value?: string | null) {
|
||||
return formatNacosHistoryTime(value);
|
||||
}
|
||||
|
||||
function operationLabel(value?: string) {
|
||||
const normalized = value?.trim().toLowerCase();
|
||||
if (!normalized) return "-";
|
||||
@@ -128,7 +133,7 @@ function loadPage(pageNo: number) {
|
||||
<tr v-for="item in items" :key="`${item.historyId}:${item.nid ?? ''}`" class="border-b">
|
||||
<td class="max-w-72 truncate px-4 py-2 font-medium" :title="item.dataId">{{ item.dataId }}</td>
|
||||
<td class="max-w-44 truncate px-4 py-2 text-xs text-muted-foreground" :title="item.group">{{ item.group || "DEFAULT_GROUP" }}</td>
|
||||
<td class="whitespace-nowrap px-4 py-2 text-xs text-muted-foreground">{{ display(item.lastModifiedTime) }}</td>
|
||||
<td class="whitespace-nowrap px-4 py-2 text-xs text-muted-foreground" :title="display(item.lastModifiedTime)">{{ displayHistoryTime(item.lastModifiedTime) }}</td>
|
||||
<td class="max-w-40 truncate px-4 py-2 text-xs text-muted-foreground" :title="item.appName || ''">{{ display(item.appName) }}</td>
|
||||
<td class="px-4 py-2">
|
||||
<Badge variant="outline">{{ operationLabel(item.operation) }}</Badge>
|
||||
@@ -189,7 +194,7 @@ function loadPage(pageNo: number) {
|
||||
<div class="min-w-0 truncate font-mono" :title="viewingItem.namespace || 'public'">namespace={{ viewingItem.namespace || "public" }}</div>
|
||||
<div class="min-w-0 truncate font-mono" :title="viewingItem.dataId">dataId={{ viewingItem.dataId }}</div>
|
||||
<div class="min-w-0 truncate font-mono" :title="viewingItem.group || 'DEFAULT_GROUP'">group={{ viewingItem.group || "DEFAULT_GROUP" }}</div>
|
||||
<div class="min-w-0 truncate" :title="display(viewingItem.lastModifiedTime)">{{ t("nacos.updatedAt") }}={{ display(viewingItem.lastModifiedTime) }}</div>
|
||||
<div class="min-w-0 truncate" :title="display(viewingItem.lastModifiedTime)">{{ t("nacos.updatedAt") }}={{ displayHistoryTime(viewingItem.lastModifiedTime) }}</div>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
<div class="min-h-0 flex-1 overflow-auto bg-muted/20 p-4">
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
createNacosConfigDeleteSnapshot,
|
||||
createNacosConfigSaveSnapshot,
|
||||
createNacosLatestRequestGuard,
|
||||
formatNacosHistoryTime,
|
||||
isNacosRawMutation,
|
||||
isNacosErrorCode,
|
||||
isNacosConfigSaveSnapshotCurrent,
|
||||
@@ -98,6 +99,23 @@ describe("nacosAdmin helpers", () => {
|
||||
expect(isNacosErrorCode(new Error("stalePreview"), "stalePreview")).toBe(false);
|
||||
});
|
||||
|
||||
it("formats Nacos history timestamps for display", () => {
|
||||
const epochDate = new Date(1_710_000_000_000);
|
||||
const epochDatePart = [epochDate.getFullYear(), epochDate.getMonth() + 1, epochDate.getDate()].map((part) => String(part).padStart(2, "0")).join("-");
|
||||
const epochTimePart = [epochDate.getHours(), epochDate.getMinutes(), epochDate.getSeconds()].map((part) => String(part).padStart(2, "0")).join(":");
|
||||
const epochDisplay = `${epochDatePart} ${epochTimePart}`;
|
||||
|
||||
expect(formatNacosHistoryTime("2026-07-27T18:16:36.000+08:00")).toBe("2026-07-27 18:16:36");
|
||||
expect(formatNacosHistoryTime("2026-07-27T18:16:36Z")).toBe("2026-07-27 18:16:36");
|
||||
expect(formatNacosHistoryTime("2026-07-27 18:16:36")).toBe("2026-07-27 18:16:36");
|
||||
expect(formatNacosHistoryTime("1710000000000")).toBe(epochDisplay);
|
||||
expect(formatNacosHistoryTime("1710000000")).toBe(epochDisplay);
|
||||
expect(formatNacosHistoryTime("0")).toBe("-");
|
||||
expect(formatNacosHistoryTime("")).toBe("-");
|
||||
expect(formatNacosHistoryTime(null)).toBe("-");
|
||||
expect(formatNacosHistoryTime("not-a-time")).toBe("not-a-time");
|
||||
});
|
||||
|
||||
it("redirects r-nacos console settings to the compatible OpenAPI endpoint", () => {
|
||||
expect(resolveRNacosOpenApiFallback("http://rnacos.example:10848", "/rnacos")).toEqual({
|
||||
serverAddr: "http://rnacos.example:8848",
|
||||
|
||||
@@ -672,6 +672,24 @@ export function buildNacosConfigDeleteConfirm(item: NacosConfigItem, fallbackNam
|
||||
return formatNacosConfigIdentity(item, fallbackNamespace);
|
||||
}
|
||||
|
||||
export function formatNacosHistoryTime(value?: string | null): string {
|
||||
const trimmed = value?.trim();
|
||||
if (!trimmed) return "-";
|
||||
if (/^0+$/.test(trimmed)) return "-";
|
||||
if (/^\d{10}(?:\d{3})?$/.test(trimmed)) {
|
||||
const timestamp = Number(trimmed);
|
||||
const date = new Date(trimmed.length === 10 ? timestamp * 1_000 : timestamp);
|
||||
if (!Number.isNaN(date.getTime())) {
|
||||
const datePart = [date.getFullYear(), date.getMonth() + 1, date.getDate()].map((part) => String(part).padStart(2, "0")).join("-");
|
||||
const timePart = [date.getHours(), date.getMinutes(), date.getSeconds()].map((part) => String(part).padStart(2, "0")).join(":");
|
||||
return `${datePart} ${timePart}`;
|
||||
}
|
||||
}
|
||||
const match = trimmed.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/);
|
||||
if (!match) return trimmed;
|
||||
return `${match[1]} ${match[2]}`;
|
||||
}
|
||||
|
||||
export function buildNacosConfigHistoryRollbackConfirm(item: NacosConfigHistoryItem, fallbackNamespace = ""): string {
|
||||
return [`namespace=${item.namespace || fallbackNamespace || "public"}`, `dataId=${item.dataId}`, `group=${item.group || "DEFAULT_GROUP"}`, item.lastModifiedTime ? `historyTime=${item.lastModifiedTime}` : "", item.operator ? `operator=${item.operator}` : ""].filter(Boolean).join("\n");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user