mirror of
https://github.com/supabase/supabase.git
synced 2026-10-17 23:29:08 +03:00
* add new ui for restore to new project * rm false * fix typeerr badly * add form with name and new project pass * fix flash in loading > results state change * restore api types * update api types, add pitr picker * add additional monthly spend section * fix loading state jump * update copy * update api types * update to new clone status api res * fix mutation missing vars * dont render logical backups in list * fix state issue on submit * better pitr empty state * Update apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx Co-authored-by: Wen Bo Xie <5532241+w3b6x9@users.noreply.github.com> * Update apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx Co-authored-by: Joshen Lim <joshenlimek@gmail.com> * Apply suggestions from code review Co-authored-by: Joshen Lim <joshenlimek@gmail.com> Co-authored-by: Wen Bo Xie <5532241+w3b6x9@users.noreply.github.com> * update api types to accept recoveryTimeTarget for PITR restores * simplify pitr code a bit cleanup state bugs * cleanup * add PITR submit * dont show restore btn unless status is complete * update api types * fix backups nav * markdown descs and fix type err in nav * check if project is cloned * fix: make source project data optional * fix datepicker highlighted day style * fix tz picker * check if its same or before/after in isWithinRange * update api types fix issue with clones * unsus * fix markdown rendering issues * add badge * Update database roles and permissions description * Update restore message text in PITR form component * Update key attribute to item.id in DatabaseBackupsNav component * Add conditional rendering for multiple available dates * Refactor dialog section styles in restore-to-new-project.tsx * Update null to undefined in conditional text assignment * reuse component in pitr backups * Update apps/studio/pages/project/[ref]/database/backups/restore-to-new-project.tsx Co-authored-by: Wen Bo Xie <5532241+w3b6x9@users.noreply.github.com> * Update link to original project in RestoreToNewProject * fix prettier --------- Co-authored-by: Wen Bo Xie <5532241+w3b6x9@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com> Co-authored-by: Crispy1975 <12525875+Crispy1975@users.noreply.github.com>
124 lines
3.9 KiB
TypeScript
124 lines
3.9 KiB
TypeScript
'use client'
|
|
import { useEffect, useRef, useState } from 'react'
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from 'ui/src/components/shadcn/ui/tooltip'
|
|
import { cn } from 'ui/src/lib/utils'
|
|
|
|
import dayjs from 'dayjs'
|
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
|
import utc from 'dayjs/plugin/utc'
|
|
|
|
dayjs.extend(relativeTime)
|
|
dayjs.extend(utc)
|
|
|
|
const unixMicroToIsoTimestamp = (unix: string | number): string => {
|
|
return dayjs.unix(Number(unix) / 1000 / 1000).toISOString()
|
|
}
|
|
|
|
const isUnixMicro = (unix: string | number): boolean => {
|
|
const digitLength = String(unix).length === 16
|
|
const isNum = !Number.isNaN(Number(unix))
|
|
return isNum && digitLength
|
|
}
|
|
|
|
const timestampLocalFormatter = (value: string | number) => {
|
|
const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
|
|
return dayjs(timestamp).format('DD MMM HH:mm:ss')
|
|
}
|
|
|
|
const timestampUtcFormatter = (value: string | number) => {
|
|
const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
|
|
return dayjs(timestamp).utc().format('DD MMM HH:mm:ss')
|
|
}
|
|
|
|
const timestampRelativeFormatter = (value: string | number) => {
|
|
const timestamp = isUnixMicro(value) ? unixMicroToIsoTimestamp(value) : value
|
|
return dayjs(timestamp).fromNow()
|
|
}
|
|
|
|
export const TimestampInfo = ({
|
|
value,
|
|
className,
|
|
}: {
|
|
className?: string
|
|
value: string | number
|
|
}) => {
|
|
const local = timestampLocalFormatter(value)
|
|
const utc = timestampUtcFormatter(value)
|
|
const relative = timestampRelativeFormatter(value)
|
|
const [align, setAlign] = useState<'start' | 'end'>('start')
|
|
const triggerRef = useRef<HTMLButtonElement>(null)
|
|
const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
|
|
// Calculate alignment based on trigger position
|
|
// Needed so that the tooltip isn't hidden behind the header on top rows
|
|
useEffect(() => {
|
|
const updateAlignment = () => {
|
|
if (triggerRef.current) {
|
|
const rect = triggerRef.current.getBoundingClientRect()
|
|
const windowHeight = window.innerHeight
|
|
setAlign(rect.top < windowHeight / 2 ? 'start' : 'end')
|
|
}
|
|
}
|
|
|
|
updateAlignment()
|
|
window.addEventListener('scroll', updateAlignment)
|
|
window.addEventListener('resize', updateAlignment)
|
|
|
|
return () => {
|
|
window.removeEventListener('scroll', updateAlignment)
|
|
window.removeEventListener('resize', updateAlignment)
|
|
}
|
|
}, [])
|
|
|
|
const TooltipRow = ({ label, value }: { label: string; value: string }) => {
|
|
const [copied, setCopied] = useState(false)
|
|
|
|
return (
|
|
<span
|
|
onClick={(e) => {
|
|
e.stopPropagation()
|
|
navigator.clipboard.writeText(value)
|
|
setCopied(true)
|
|
|
|
setTimeout(() => {
|
|
setCopied(false)
|
|
}, 1000)
|
|
}}
|
|
className={cn(
|
|
'relative cursor-default grid grid-cols-2 gap-2 hover:bg-surface-100 px-2 py-1',
|
|
{
|
|
'bg-surface-100': copied,
|
|
}
|
|
)}
|
|
>
|
|
<span className="text-right truncate">{label}:</span>
|
|
<div className="relative">
|
|
{copied && (
|
|
<span className="absolute inset-0 flex items-center text-brand-600 bg-surface-100">
|
|
Copied!
|
|
</span>
|
|
)}
|
|
<span>{value}</span>
|
|
</div>
|
|
</span>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Tooltip>
|
|
<TooltipTrigger
|
|
ref={triggerRef}
|
|
className={`text-xs ${className} border-b border-transparent hover:border-dashed hover:border-foreground-light`}
|
|
>
|
|
<span>{timestampLocalFormatter(value)}</span>
|
|
</TooltipTrigger>
|
|
<TooltipContent align={align} side="right" className="font-mono p-0 py-1">
|
|
<TooltipRow label="UTC" value={utc} />
|
|
<TooltipRow label={`${localTimezone}`} value={local} />
|
|
<TooltipRow label="Relative" value={relative} />
|
|
<TooltipRow label="Timestamp" value={String(value)} />
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
}
|