Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/23852-setup-empty-states.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@objectstack/platform-objects': patch
'@objectstack/service-messaging': patch
---

Setup's Invitations, API Keys, OAuth Applications and Notification Preferences, Subscriptions and Templates lists say what belongs on them when they are empty, and API Keys gains a Create Key button (#23852)

Clause-②: no

**What an admin saw.** An empty Invitations, API Keys or OAuth Applications list read "No identity records — these records are created by the authentication provider … not added by hand here", which is false for all three. The three notification lists read the generic "Nothing here yet". API Keys had no way to create a key at all.

**What changes.**

- Every list view of `sys_invitation`, `sys_api_key` and `sys_oauth_application` declares its own `emptyState` (a title and one sentence), and a filtered view names itself: Invitations opens on "No pending invitations", the Revoked keys view reads "No revoked keys".
- `sys_notification_preference`, `sys_notification_subscription` and `sys_notification_template` each ship one list view, `all`, declared only for its `emptyState`: it sets no columns (`columns: []`, so the grid keeps the columns it derived before), no filter, no sort and no page size.
- `sys_api_key` gains `create_api_key` ("Create Key"), a primary list-toolbar action on every API Keys list, Setup's and the Account app's. It calls the existing `POST /api/v1/keys` route with the name you give it; the key is created for you, in the organization you are working in, and the raw key is shown once in a dialog you close after copying it. Nothing about the route changes, and the data API still does not create keys.
- The new copy ships in `en`, `zh-CN`, `ja-JP` and `es-ES`.

Unchanged: every field, index, permission and the `revoke_api_key` / `restore_api_key` row actions.
Original file line number Diff line number Diff line change
Expand Up @@ -719,16 +719,32 @@ export const enObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
pending: {
label: "Pending"
label: "Pending",
emptyState: {
title: "No pending invitations",
message: "An invitation stays here until it is accepted, declined or canceled, or until it expires."
}
},
accepted: {
label: "Accepted"
label: "Accepted",
emptyState: {
title: "No accepted invitations",
message: "An invitation moves here when the person accepts it and joins the organization."
}
},
expired: {
label: "Expired / Canceled"
label: "Expired / Canceled",
emptyState: {
title: "No expired or canceled invitations",
message: "Invitations that expired, were declined or were canceled are kept here."
}
},
all_invitations: {
label: "All"
label: "All",
emptyState: {
title: "No invitations yet",
message: "Every invitation to join an organization is listed here, whatever its status."
}
}
},
_actions: {
Expand Down Expand Up @@ -1024,19 +1040,47 @@ export const enObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_keys: {
label: "All"
label: "All",
emptyState: {
title: "No API keys yet",
message: "Create a key for scripts and integrations with Create Key; the key is shown once, when it is created."
}
},
mine: {
label: "My Keys"
label: "My Keys",
emptyState: {
title: "You have no API keys yet",
message: "Create a key for your scripts and integrations with Create Key; the key is shown once, when it is created."
}
},
active: {
label: "Active"
label: "Active",
emptyState: {
title: "No active API keys",
message: "Every key that has not been revoked is listed here."
}
},
revoked: {
label: "Revoked"
label: "Revoked",
emptyState: {
title: "No revoked keys",
message: "A key moves here when it is revoked; clients using it lose access until it is restored."
}
}
},
_actions: {
create_api_key: {
label: "Create Key",
description: "Create a key for a script or integration. The key acts as you, with your access, in the organization you are working in now.",
resultDialog: {
title: "API key created",
description: "Copy the key now — it is shown only once and cannot be recovered. If it leaks, revoke it and create a new one.",
acknowledge: "I have saved the key",
fields: {
key: "API Key"
}
}
},
revoke_api_key: {
label: "Revoke API Key",
confirmText: "Revoke this API key? Any clients using it will immediately lose access.",
Expand Down Expand Up @@ -1388,16 +1432,32 @@ export const enObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_apps: {
label: "All"
label: "All",
emptyState: {
title: "No OAuth applications yet",
message: "Register an application to let its clients sign users in with this environment."
}
},
mine: {
label: "My Applications"
label: "My Applications",
emptyState: {
title: "You have no OAuth applications yet",
message: "Applications you register are listed here."
}
},
active: {
label: "Active"
label: "Active",
emptyState: {
title: "No active OAuth applications",
message: "An application stays active until it is disabled; disabled applications are listed under Disabled."
}
},
disabled_apps: {
label: "Disabled"
label: "Disabled",
emptyState: {
title: "No disabled OAuth applications",
message: "An application moves here when it is disabled; its clients cannot sign in until it is enabled again."
}
}
},
_actions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,16 +719,32 @@ export const esESObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
pending: {
label: "Pendientes"
label: "Pendientes",
emptyState: {
title: "No hay invitaciones pendientes",
message: "Una invitación permanece aquí hasta que se acepta, se rechaza o se cancela, o hasta que caduca."
}
},
accepted: {
label: "Aceptadas"
label: "Aceptadas",
emptyState: {
title: "No hay invitaciones aceptadas",
message: "Una invitación pasa aquí cuando la persona la acepta y se une a la organización."
}
},
expired: {
label: "Caducadas / canceladas"
label: "Caducadas / canceladas",
emptyState: {
title: "No hay invitaciones caducadas ni canceladas",
message: "Aquí se conservan las invitaciones que caducaron, se rechazaron o se cancelaron."
}
},
all_invitations: {
label: "Todas"
label: "Todas",
emptyState: {
title: "Aún no hay invitaciones",
message: "Aquí aparece cada invitación para unirse a una organización, sea cual sea su estado."
}
}
},
_actions: {
Expand Down Expand Up @@ -1024,19 +1040,47 @@ export const esESObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_keys: {
label: "Todas"
label: "Todas",
emptyState: {
title: "Aún no hay claves de API",
message: "Crea una clave para scripts e integraciones con Crear clave; la clave se muestra una sola vez, al crearla."
}
},
mine: {
label: "Mis claves"
label: "Mis claves",
emptyState: {
title: "Aún no tienes claves de API",
message: "Crea una clave para tus scripts e integraciones con Crear clave; la clave se muestra una sola vez, al crearla."
}
},
active: {
label: "Activo"
label: "Activo",
emptyState: {
title: "No hay claves de API activas",
message: "Aquí aparece cada clave que no se ha revocado."
}
},
revoked: {
label: "Revocado"
label: "Revocado",
emptyState: {
title: "No hay claves revocadas",
message: "Una clave pasa aquí cuando se revoca; los clientes que la usan pierden el acceso hasta que se restaura."
}
}
},
_actions: {
create_api_key: {
label: "Crear clave",
description: "Crea una clave para un script o una integración. La clave actúa como tú, con tu acceso, en la organización en la que trabajas ahora.",
resultDialog: {
title: "Clave de API creada",
description: "Copia la clave ahora: solo se muestra una vez y no se puede recuperar. Si se filtra, revócala y crea una nueva.",
acknowledge: "He guardado la clave",
fields: {
key: "Clave de API"
}
}
},
revoke_api_key: {
label: "Revocar clave de API",
confirmText: "¿Revocar esta clave de API? Los clientes que la utilicen perderán el acceso inmediatamente.",
Expand Down Expand Up @@ -1388,16 +1432,32 @@ export const esESObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_apps: {
label: "Todas"
label: "Todas",
emptyState: {
title: "Aún no hay aplicaciones OAuth",
message: "Registra una aplicación para que sus clientes puedan iniciar la sesión de los usuarios con este entorno."
}
},
mine: {
label: "Mis aplicaciones"
label: "Mis aplicaciones",
emptyState: {
title: "Aún no tienes aplicaciones OAuth",
message: "Aquí aparecen las aplicaciones que registras."
}
},
active: {
label: "Activo"
label: "Activo",
emptyState: {
title: "No hay aplicaciones OAuth activas",
message: "Una aplicación sigue activa hasta que se deshabilita; las aplicaciones deshabilitadas aparecen en Deshabilitado."
}
},
disabled_apps: {
label: "Deshabilitado"
label: "Deshabilitado",
emptyState: {
title: "No hay aplicaciones OAuth deshabilitadas",
message: "Una aplicación pasa aquí cuando se deshabilita; sus clientes no pueden iniciar sesión hasta que se vuelva a habilitar."
}
}
},
_actions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -719,16 +719,32 @@ export const jaJPObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
pending: {
label: "保留中"
label: "保留中",
emptyState: {
title: "保留中の招待はありません",
message: "招待は、承認・辞退・キャンセルされるか、期限切れになるまでここに表示されます。"
}
},
accepted: {
label: "承認済み"
label: "承認済み",
emptyState: {
title: "承認済みの招待はありません",
message: "相手が招待を承認して組織に参加すると、招待はここに移動します。"
}
},
expired: {
label: "期限切れ / キャンセル済み"
label: "期限切れ / キャンセル済み",
emptyState: {
title: "期限切れまたはキャンセル済みの招待はありません",
message: "期限切れ、辞退、またはキャンセルされた招待はここに保持されます。"
}
},
all_invitations: {
label: "すべて"
label: "すべて",
emptyState: {
title: "まだ招待がありません",
message: "組織への招待は、状態にかかわらずすべてここに一覧表示されます。"
}
}
},
_actions: {
Expand Down Expand Up @@ -1024,19 +1040,47 @@ export const jaJPObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_keys: {
label: "すべて"
label: "すべて",
emptyState: {
title: "まだ API キーがありません",
message: "「キーを作成」でスクリプトや連携用のキーを作成できます。キーは作成時に一度だけ表示されます。"
}
},
mine: {
label: "自分のキー"
label: "自分のキー",
emptyState: {
title: "自分の API キーはまだありません",
message: "「キーを作成」で自分のスクリプトや連携用のキーを作成できます。キーは作成時に一度だけ表示されます。"
}
},
active: {
label: "有効"
label: "有効",
emptyState: {
title: "有効な API キーはありません",
message: "失効していないキーはすべてここに一覧表示されます。"
}
},
revoked: {
label: "失効済み"
label: "失効済み",
emptyState: {
title: "失効済みのキーはありません",
message: "失効したキーはここに移動し、そのキーを使うクライアントは復元されるまでアクセスを失います。"
}
}
},
_actions: {
create_api_key: {
label: "キーを作成",
description: "スクリプトや連携用のキーを作成します。キーはあなたとして、あなたのアクセス権で、現在作業中の組織で動作します。",
resultDialog: {
title: "API キーを作成しました",
description: "今すぐキーをコピーしてください。キーは一度しか表示されず、後から取得することはできません。漏えいした場合は失効させて新しいキーを作成してください。",
acknowledge: "キーを保存しました",
fields: {
key: "API キー"
}
}
},
revoke_api_key: {
label: "API キーを失効",
confirmText: "この API キーを失効しますか?使用中のクライアントはすぐにアクセスを失います。",
Expand Down Expand Up @@ -1388,16 +1432,32 @@ export const jaJPObjects: NonNullable<TranslationData['objects']> = {
},
_views: {
all_apps: {
label: "すべて"
label: "すべて",
emptyState: {
title: "まだ OAuth アプリケーションがありません",
message: "アプリケーションを登録すると、そのクライアントがこの環境でユーザーをサインインさせられるようになります。"
}
},
mine: {
label: "自分のアプリケーション"
label: "自分のアプリケーション",
emptyState: {
title: "自分の OAuth アプリケーションはまだありません",
message: "登録したアプリケーションはここに一覧表示されます。"
}
},
active: {
label: "有効"
label: "有効",
emptyState: {
title: "有効な OAuth アプリケーションはありません",
message: "アプリケーションは無効化されるまで有効です。無効化されたアプリケーションは「無効」に表示されます。"
}
},
disabled_apps: {
label: "無効"
label: "無効",
emptyState: {
title: "無効な OAuth アプリケーションはありません",
message: "無効化されたアプリケーションはここに移動し、再び有効化されるまでそのクライアントはサインインできません。"
}
}
},
_actions: {
Expand Down
Loading
Loading