void
@@ -37,7 +37,7 @@ export const BackupsList = ({ onSelectRestore, disabled }: BackupsListProps) =>
return (
-
+
{JSON.stringify(backup.status).replaceAll('"', '')}
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/AuthColumnRenderer.tsx b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/AuthColumnRenderer.tsx
index 32401f8ffd5..6262a2ef899 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/AuthColumnRenderer.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/AuthColumnRenderer.tsx
@@ -16,7 +16,7 @@ const columns: Column
[] = [
return (
-
+
{props.row.level && }
[] = [
}
return (
-
+
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DatabasePostgresColumnRender.tsx b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DatabasePostgresColumnRender.tsx
index 46e8f5aa4ed..6692a29465d 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DatabasePostgresColumnRender.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DatabasePostgresColumnRender.tsx
@@ -14,7 +14,7 @@ const columns: Column[] = [
}
return (
-
+
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DefaultPreviewColumnRenderer.tsx b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DefaultPreviewColumnRenderer.tsx
index 5025e2b513e..997361ffbb9 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DefaultPreviewColumnRenderer.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/DefaultPreviewColumnRenderer.tsx
@@ -5,7 +5,7 @@ import { TimestampInfo } from 'ui-patterns/TimestampInfo'
export const defaultRenderCell = (props: RenderCellProps) => (
-
+
)
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsEdgeColumnRender.tsx b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsEdgeColumnRender.tsx
index 147732803d3..9d76d5a880f 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsEdgeColumnRender.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsEdgeColumnRender.tsx
@@ -14,7 +14,7 @@ const columns: Column[] = [
}
return (
-
+
diff --git a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsLogsColumnRender.tsx b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsLogsColumnRender.tsx
index ba43620699f..9fcb99c4216 100644
--- a/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsLogsColumnRender.tsx
+++ b/apps/studio/components/interfaces/Settings/Logs/LogColumnRenderers/FunctionsLogsColumnRender.tsx
@@ -14,7 +14,7 @@ const columns: Column[] = [
}
return (
-
+
{props.row.event_type === 'uncaughtException' ? (
) : (
diff --git a/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx b/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx
index c9fc727a6f1..a4ffed86e90 100644
--- a/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx
+++ b/apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx
@@ -150,7 +150,7 @@ const RestoreToNewProject = () => {
@@ -168,7 +168,7 @@ const RestoreToNewProject = () => {
diff --git a/packages/ui-patterns/TimestampInfo/index.tsx b/packages/ui-patterns/TimestampInfo/index.tsx
index b537382b9b1..7b0cf1a82cf 100644
--- a/packages/ui-patterns/TimestampInfo/index.tsx
+++ b/packages/ui-patterns/TimestampInfo/index.tsx
@@ -6,6 +6,7 @@ import { cn } from 'ui/src/lib/utils'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc'
+import { Clipboard } from 'lucide-react'
dayjs.extend(relativeTime)
dayjs.extend(utc)
@@ -20,51 +21,56 @@ const isUnixMicro = (unix: string | number): boolean => {
return isNum && digitLength
}
-const timestampLabelFormatter = (value: string | number, format: string) => {
- const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
- return dayjs(timestamp).format(format)
+type TimestampFormatter = {
+ utcTimestamp: string | number
+ format?: string
}
-const timestampLocalFormatter = (value: string | number) => {
- const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
- return dayjs(timestamp).format('DD MMM YYYY HH:mm:ss')
+export const timestampLocalFormatter = ({ utcTimestamp, format }: TimestampFormatter) => {
+ const timestamp = isUnixMicro(utcTimestamp) ? unixMicroToIsoTimestamp(utcTimestamp) : utcTimestamp
+ return dayjs.utc(timestamp).local().format(format)
}
-const timestampUtcFormatter = (value: string | number) => {
- const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
- return dayjs(timestamp).utc().format('DD MMM YYYY HH:mm:ss')
+const timestampUtcFormatter = ({ utcTimestamp, format }: TimestampFormatter) => {
+ const timestamp = isUnixMicro(utcTimestamp) ? unixMicroToIsoTimestamp(utcTimestamp) : utcTimestamp
+ return dayjs.utc(timestamp).format(format)
}
-const timestampRelativeFormatter = (value: string | number) => {
- const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
- return dayjs(timestamp).fromNow()
-}
-
-const timestampFormatter = (value: string) => {
- const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
- return String(Number(dayjs(timestamp)))
+const timestampRelativeFormatter = ({ utcTimestamp }: TimestampFormatter) => {
+ const timestamp = isUnixMicro(utcTimestamp) ? unixMicroToIsoTimestamp(utcTimestamp) : utcTimestamp
+ return dayjs.utc(timestamp).fromNow()
}
+/**
+ * TimestampInfo component displays a timestamp with a tooltip showing various time formats.
+ * @param {string|number} props.utcTimestamp - UTC timestamp value. Can be either:
+ * - ISO 8601 string (e.g., "2024-01-01T00:00:00Z")
+ * - Unix microseconds (16-digit number)
+ * @param {string} [props.format="DD MMM HH:mm:ss"] - Display format for the timestamp (using dayjs format)
+ * @returns {JSX.Element} Timestamp display with tooltip showing UTC, local, relative, and raw timestamp values
+ */
export const TimestampInfo = ({
- value,
+ utcTimestamp,
className,
- labelFormatter = 'DD MMM HH:mm:ss',
+ displayAs = 'local',
+ format = 'DD MMM HH:mm:ss',
+ labelFormat = 'DD MMM HH:mm:ss',
}: {
- value: string | number
className?: string
- labelFormatter?: string
+ utcTimestamp: string | number
+ displayAs?: 'local' | 'utc'
+ format?: string
+ labelFormat?: string
}) => {
- const triggerRef = useRef(null)
+ const local = timestampLocalFormatter({ utcTimestamp, format })
+ const utc = timestampUtcFormatter({ utcTimestamp, format })
+ const relative = timestampRelativeFormatter({ utcTimestamp })
const [align, setAlign] = useState<'start' | 'end'>('start')
-
- const local = timestampLocalFormatter(value)
- const utc = timestampUtcFormatter(value)
- const relative = timestampRelativeFormatter(value)
+ const triggerRef = useRef(null)
const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
- const timestamp = typeof value === 'number' ? String(value) : timestampFormatter(value)
// Calculate alignment based on trigger position
- // Needed so that the tooltip isn't hidden behind the header on top rows
+ // Needed so that the tooltip isn't hidden behind the header on top rows (in logs)
useEffect(() => {
const updateAlignment = () => {
if (triggerRef.current) {
@@ -91,6 +97,7 @@ export const TimestampInfo = ({
{
e.stopPropagation()
+ e.preventDefault()
navigator.clipboard.writeText(value)
setCopied(true)
@@ -99,10 +106,8 @@ export const TimestampInfo = ({
}, 1000)
}}
className={cn(
- 'relative cursor-default grid grid-cols-2 gap-2 hover:bg-surface-100 px-2 py-1',
- {
- 'bg-surface-100': copied,
- }
+ 'relative cursor-default grid grid-cols-2 gap-2 hover:bg-surface-100 px-2 py-1 group',
+ { 'bg-surface-100': copied }
)}
>
{label}:
@@ -112,7 +117,10 @@ export const TimestampInfo = ({
Copied!
)}
- {value}
+
+ {value}
+
+
)
@@ -122,16 +130,19 @@ export const TimestampInfo = ({
- {timestampLabelFormatter(value, labelFormatter)}
+
+ {displayAs === 'local'
+ ? timestampLocalFormatter({ utcTimestamp, format: labelFormat })
+ : timestampUtcFormatter({ utcTimestamp, format: labelFormat })}
+
-
+
)