Prod deploy studio (#9120)

* add initial table for feature status

* js lib is GA

* add docs link

* chore: adds details of software upgrade notification

* Update notifications styling

* Add link to changelog notificaiton

Co-authored-by: Inian <inian1234@gmail.com>
Co-authored-by: Div Arora <root@darora.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
authored and GitHub committed 2022-09-23 12:20:41 +08:00
1 parent 31855341a4
commit ff192a2b18
5 files changed
+159 -74

No files matched your search

+22
View File
@@ -15,3 +15,25 @@ Supabase is not a 1-to-1 mapping of Firebase. While we are building many of the
Our technological choices are quite different from Firebase. Everything we use is open source. Wherever possible, we use and support existing tools rather than developing from scratch.
Most notably, we use Postgres rather than a NoSQL store. This choice was deliberate. We believe that no other database offers the scalability and functionality required to compete with Firebase.
## Feature Status
| Product | Feature | Stage | Docs |
| -------------------------- | ---------------------- | ----- | ------------------------------------------------ |
| Database | Postgres | GA | [Link](/docs/guides/database) |
| Database | Webhooks | Alpha | |
| Database | Point in time Recovery | Alpha | |
| Realtime | Postgres Changes | Beta | [Link](/docs/guides/realtime/postgres-changes) |
| Realtime | Broadcast | Alpha | [Link](/docs/guides/realtime/broadcast) |
| Realtime | Presence | Alpha | [Link](/docs/guides/realtime/presence) |
| Storage | | Beta | [Link](/docs/guides/storage) |
| Storage | CDN | Beta | [Link](/docs/guides/storage-caching) |
| Edge Functions | | Beta | [Link](/docs/guides/functions) |
| Auth | OAuth Providers | Beta | [Link](/docs/guides/auth/auth-apple) |
| Auth | Passwordless | Beta | [Link](/guides/auth/auth-magic-link) |
| Auth | Next.js Auth Helpers | Alpha | [Link](/docs/guides/auth/auth-helpers/nextjs) |
| Auth | SvelteKit Auth Helpers | Alpha | [Link](/docs/guides/auth/auth-helpers/sveltekit) |
| Public API | | Beta | [Link](/docs/reference/api) |
| CLI | | Beta | [Link](/docs/guides/cli) |
| Client Library: JavaScript | | GA | [Link](/docs/reference/javascript/next/) |
| Client Library: Dart | | Beta | [Link](/docs/reference/dart) |
@@ -28,9 +28,9 @@ const NotificationRow: FC<Props> = ({ notification, onSelectRestartProject }) =>
</div>
<div className="mr-8 flex items-center space-x-4">
<div className="space-y-1">
<p className="text-sm">{formatNotificationText(project, notification)}</p>
{formatNotificationText(project, notification)}
<p className="text-sm">{formatNotificationCTAText(availableActions)}</p>
<p className="text-scale-1100 text-sm">{insertedAt}</p>
<p className="text-scale-1100 text-sm !mt-2">{insertedAt}</p>
</div>
<div className="col-span-3 flex items-center justify-end">
{availableActions.length > 0 && (
@@ -1,71 +0,0 @@
import { Project } from 'types'
import {
Action,
ActionType,
ExtensionsUpgrade,
Notification,
NotificationName,
ServerUpgrade,
ServiceUpgrade,
ViolatedLimit,
} from '@supabase/shared-types/out/notifications'
export const formatNotificationText = (project: Project, notification: Notification) => {
const projectName = project.name
if (notification.data.name === NotificationName.ProjectExceedingTierLimit) {
const { violations } = notification.data
const violationsText = violations
.map((violation: ViolatedLimit) => violation.dimension as string)
.reduce((a: string, b: string) => `${a}, ${b}`)
return `Your project "${projectName}" has exceeded its limits in the following areas: ${violationsText}.`
} else if (notification.data.name === NotificationName.PostgresqlUpgradeAvailable) {
const { upgrade_type, additional } = notification.data
if (upgrade_type === 'postgresql-server') {
const { version_to } = additional as ServerUpgrade
return `New version of Postgres (${version_to}) is now available for project "${projectName}".`
} else if (upgrade_type === 'extensions') {
const { name, version_to } = additional as ExtensionsUpgrade
return `New version of "${name}" (${version_to}) is now available for project "${projectName}".`
}
return ''
} else if (notification.data.name === NotificationName.PostgresqlUpgradeCompleted) {
const { upgrade_type, additional } = notification.data
if (upgrade_type === 'postgresql-server') {
const { version_to } = additional as ServerUpgrade
return `Postgres (${version_to}) has been successfully updated to ${version_to} for project "${projectName}".`
} else if (upgrade_type === 'extensions') {
const { name, version_to } = additional as ExtensionsUpgrade
return `The extension "${name}" has been successfully updated to ${version_to} for project "${projectName}".`
}
} else if (notification.data.name === NotificationName.ProjectUpdateCompleted) {
const { upgrades } = notification.data
const upgradesText = upgrades
.map((upgrade: ServiceUpgrade) => upgrade.name)
.reduce((a: string, b: string) => `${a}, ${b}`)
return `The following services have been successfully updated for project "${projectName}": ${upgradesText}.`
} else if (notification.data.name === NotificationName.ProjectInformational) {
return notification.data.message
} else {
return `Unknown notification type: ${notification.notification_name} - Please reach out to support for more information.`
}
}
export const formatNotificationCTAText = (availableActions: Action[]) => {
const [action] = availableActions
if (!action) return ''
switch (action.action_type) {
case ActionType.SchedulePostgresRestart:
return 'Restart your project to get the latest updates.'
case ActionType.UpgradeProjectToPro:
return 'Upgrade your project to ensure continued availability.'
case ActionType.PgBouncerRestart:
return 'Restart your connection pooler to get the latest updates.'
default:
return ''
}
}
@@ -0,0 +1,134 @@
import { Project } from 'types'
import {
Action,
ActionType,
ExtensionsUpgrade,
Notification,
NotificationName,
ServerUpgrade,
ServiceUpgrade,
ViolatedLimit,
} from '@supabase/shared-types/out/notifications'
import { IconArrowRight, IconExternalLink } from '@supabase/ui'
import Link from 'next/link'
export const formatNotificationText = (project: Project, notification: Notification) => {
const projectName = project.name
if (notification.data.name === NotificationName.ProjectExceedingTierLimit) {
const { violations } = notification.data
const violationsText = violations
.map((violation: ViolatedLimit) => violation.dimension as string)
.reduce((a: string, b: string) => `${a}, ${b}`)
return (
<p className="text-sm">
Your project "{projectName}" has exceeded its limits in the following areas:{' '}
{violationsText}.
</p>
)
} else if (notification.data.name === NotificationName.PostgresqlUpgradeAvailable) {
const { upgrade_type, additional } = notification.data
if (upgrade_type === 'postgresql-server') {
const { version_to } = additional as ServerUpgrade
return (
<p className="text-sm">
New version of Postgres ({version_to}) is now available for project "{projectName}".
</p>
)
} else if (upgrade_type === 'extensions') {
const { name, version_to } = additional as ExtensionsUpgrade
return (
<p className="text-sm">
New version of "{name}" ({version_to}) is now available for project "{projectName}".
</p>
)
}
return ''
} else if (notification.data.name === NotificationName.PostgresqlUpgradeCompleted) {
const { upgrade_type, additional } = notification.data
if (upgrade_type === 'postgresql-server') {
const { version_to } = additional as ServerUpgrade
return (
<p className="text-sm">
Postgres ({version_to}) has been successfully updated to {version_to} for project "
{projectName}".
</p>
)
} else if (upgrade_type === 'extensions') {
const { name, version_to } = additional as ExtensionsUpgrade
return (
<p className="text-sm">
The extension "{name}" has been successfully updated to {version_to} for project "
{projectName}".
</p>
)
}
} else if (notification.data.name === NotificationName.ProjectUpdateCompleted) {
const { upgrades } = notification.data
const upgradesText = upgrades
.map(
(upgrade: ServiceUpgrade) =>
`${upgrade.name}: ${upgrade.version_to} ${upgrade.changelog_link}`
)
.reduce((a: string, b: string) => `${a}\n${b}`)
return (
<div>
<p className="text-sm">
The following services have been successfully updated for project "{projectName}":
</p>
<ol className="list-disc pl-6">
{upgrades.map((upgrade: ServiceUpgrade) => (
<li key={upgrade.name}>
<div className="flex items-center space-x-1">
<p className="text-sm">{upgrade.name}</p>
<IconArrowRight size={12} strokeWidth={2} />
<p className="text-sm">{upgrade.version_to}</p>
{upgrade.changelog_link && (
<div className="!ml-4">
<Link href={upgrade.changelog_link}>
<a>
<IconExternalLink
className="cursor-pointer text-scale-1000 hover:text-scale-1200 transition"
size={12}
strokeWidth={2}
/>
</a>
</Link>
</div>
)}
</div>
</li>
))}
</ol>
</div>
)
} else if (notification.data.name === NotificationName.ProjectInformational) {
return notification.data.message
} else {
return (
<p className="text-sm">
Unknown notification type: {notification.notification_name} - Please reach out to support
for more information.
</p>
)
}
}
export const formatNotificationCTAText = (availableActions: Action[]) => {
const [action] = availableActions
if (!action) return ''
switch (action.action_type) {
case ActionType.SchedulePostgresRestart:
return 'Restart your project to get the latest updates.'
case ActionType.UpgradeProjectToPro:
return 'Upgrade your project to ensure continued availability.'
case ActionType.PgBouncerRestart:
return 'Restart your connection pooler to get the latest updates.'
default:
return ''
}
}
@@ -91,7 +91,7 @@ const NotificationsPopover: FC<Props> = () => {
sideOffset={8}
onOpenChange={onOpenChange}
overlay={
<div className="w-[540px]">
<div className="w-[500px]">
<div className="flex items-center justify-between border-b border-gray-500 bg-gray-400 px-4 py-2">
<p className="text-sm">Notifications</p>
{/* Area for improvement: Paginate notifications and show in a side panel */}