Skip to content

Commit 39f74fd

Browse files
agatha197claude
andcommitted
refactor(FR-3223): swap enabled toggle for footer Reset + Delete actions
The manager stores the announcement purely by presence, so the `enabled` flag cannot be persisted and its footer toggle could not work. Comment out the toggle (kept for a future backend that can persist it) and give the footer two explicit actions, following the Edit Bootstrap Script modal: - Reset: clears the editor content locally (Popconfirm-guarded) so the admin can start over without touching the server. - Delete: removes the published announcement via update_announcement(false, ''), routed through a confirm modal (not an inline Popconfirm); disabled when nothing is stored. Publishing always enables (enabled=true) and requires a non-empty message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e9c1de2 commit 39f74fd

22 files changed

Lines changed: 205 additions & 110 deletions

react/src/components/AnnouncementEditModal.tsx

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import BAICodeEditor from './BAICodeEditor';
99
import { SyntaxHighlighter } from './Chat/SyntaxHighlighter';
1010
import {
1111
BoldOutlined,
12+
ClearOutlined,
1213
CodeOutlined,
14+
DeleteOutlined,
1315
FontSizeOutlined,
1416
ItalicOutlined,
1517
LinkOutlined,
@@ -23,8 +25,8 @@ import { useQueryClient } from '@tanstack/react-query';
2325
import {
2426
App,
2527
Button,
26-
Checkbox,
2728
Dropdown,
29+
Popconfirm,
2830
Skeleton,
2931
theme,
3032
Tooltip,
@@ -222,7 +224,7 @@ const AnnouncementEditModal: React.FC<AnnouncementEditModalProps> = ({
222224
const { t } = useTranslation();
223225
const { token } = theme.useToken();
224226
const { styles } = useStyles();
225-
const { message: appMessage } = App.useApp();
227+
const { message: appMessage, modal } = App.useApp();
226228
const { logger } = useBAILogger();
227229
const { getErrorMessage } = useErrorMessageResolver();
228230

@@ -236,19 +238,22 @@ const AnnouncementEditModal: React.FC<AnnouncementEditModalProps> = ({
236238
announcementQueryOptions(baiClient),
237239
);
238240

239-
// `enabled` and `message` are plain local state, not antd Form fields: the
240-
// Enabled toggle lives in the modal footer (outside any <Form>), so keeping
241-
// both in one state model avoids bridging a footer control into a form store.
242-
// `undefined` means "not edited yet" → fall back to the server value; once the
243-
// user changes a field the draft takes over.
244-
const [enabledDraft, setEnabledDraft] = useState<boolean>();
241+
// The `enabled` flag is not user-controllable for now: the manager stores the
242+
// announcement purely by presence — publishing a message enables it, and
243+
// "disabling" it just deletes the stored message (there is no way to persist a
244+
// disabled-but-present announcement). So the footer exposes an explicit Delete
245+
// action instead of an Enabled toggle. The toggle implementation is kept below
246+
// (commented out) so it can be restored once the backend can persist the flag.
247+
//
248+
// const [enabledDraft, setEnabledDraft] = useState<boolean>();
249+
// const enabled = enabledDraft ?? announcement?.enabled ?? true;
245250
const [messageDraft, setMessageDraft] = useState<string>();
246-
const enabled = enabledDraft ?? announcement?.enabled ?? true;
247251
const message = messageDraft ?? announcement?.message ?? '';
248252

249-
// The backend rejects enabling an announcement with an empty message ("Empty
250-
// message not allowed to enable announcement"); enforce the same rule here.
251-
const isMessageMissing = enabled && !message.trim();
253+
// Publishing always enables the announcement, and the backend rejects an empty
254+
// message ("Empty message not allowed to enable announcement"), so a non-empty
255+
// message is required to publish. (Previously gated on `enabled && ...`.)
256+
const isMessageMissing = !message.trim();
252257

253258
const updateMutation = useTanMutation({
254259
mutationFn: (values: AnnouncementValues) => {
@@ -259,10 +264,16 @@ const AnnouncementEditModal: React.FC<AnnouncementEditModalProps> = ({
259264
},
260265
});
261266

267+
// Deleting is `update_announcement(false, ...)`: with `enabled: false` the
268+
// manager removes the stored message from etcd, clearing the announcement.
269+
const deleteMutation = useTanMutation({
270+
mutationFn: () => baiClient.service.update_announcement(false, ''),
271+
});
272+
262273
const handleSubmit = () => {
263274
if (isMessageMissing) return;
264275
updateMutation.mutate(
265-
{ enabled, message },
276+
{ enabled: true, message },
266277
{
267278
onSuccess: () => {
268279
appMessage.success(t('summary.AnnouncementUpdated'));
@@ -279,20 +290,83 @@ const AnnouncementEditModal: React.FC<AnnouncementEditModalProps> = ({
279290
);
280291
};
281292

293+
// Reset only clears the editor content locally so the admin can start over;
294+
// it does not touch the server. Publish stays disabled until a non-empty
295+
// message exists again.
296+
const handleReset = () => {
297+
setMessageDraft('');
298+
};
299+
300+
const handleDelete = async () => {
301+
try {
302+
await deleteMutation.mutateAsync();
303+
appMessage.success(t('summary.AnnouncementDeleted'));
304+
queryClient.invalidateQueries({
305+
queryKey: announcementQueryOptions(baiClient).queryKey,
306+
});
307+
onRequestClose(true);
308+
} catch (error) {
309+
appMessage.error(getErrorMessage(error));
310+
logger.error(error);
311+
}
312+
};
313+
314+
// Delete removes the published announcement from the server, so it goes
315+
// through a confirm modal instead of firing on the footer click. `onOk`
316+
// returns the delete promise so the modal's OK button shows a spinner until
317+
// the request settles.
318+
const confirmDelete = () => {
319+
modal.confirm({
320+
title: t('dialog.ask.DoYouWantToDelete'),
321+
content: t('dialog.warning.CannotBeUndone'),
322+
okText: t('button.Delete'),
323+
okButtonProps: { danger: true },
324+
onOk: handleDelete,
325+
});
326+
};
327+
282328
return (
283329
<BAIModal
284330
width="90%"
285331
style={{ maxWidth: 1900 }}
286332
title={t('summary.EditAnnouncement')}
287333
onCancel={() => onRequestClose()}
288334
footer={
289-
<BAIFlex justify="between" align="center" gap="sm">
335+
<BAIFlex
336+
justify="between"
337+
align="center"
338+
gap="sm"
339+
style={{ width: '100%' }}
340+
>
341+
{/* Delete clears the published announcement. Disabled when there is
342+
nothing stored to delete. Restore the Enabled checkbox here once
343+
the backend can persist a disabled-but-present announcement:
290344
<Checkbox
291345
checked={enabled}
292346
onChange={(e) => setEnabledDraft(e.target.checked)}
293347
>
294348
{t('summary.AnnouncementEnabled')}
295-
</Checkbox>
349+
</Checkbox> */}
350+
<BAIFlex gap="xs" align="center">
351+
<Popconfirm
352+
title={t('dialog.ask.DoYouWantToResetChanges')}
353+
okButtonProps={{ danger: true }}
354+
onConfirm={handleReset}
355+
>
356+
<Button icon={<ClearOutlined />} disabled={isLoading}>
357+
{t('button.Reset')}
358+
</Button>
359+
</Popconfirm>
360+
<Button
361+
danger
362+
icon={<DeleteOutlined />}
363+
disabled={isLoading || !announcement?.enabled}
364+
loading={deleteMutation.isPending}
365+
onClick={confirmDelete}
366+
>
367+
{t('button.Delete')}
368+
</Button>
369+
</BAIFlex>
296370
<BAIFlex gap="xs" align="center">
297371
<Button onClick={() => onRequestClose()}>
298372
{t('button.Cancel')}

resources/i18n/de.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,18 +3222,19 @@
32223222
"AcceptSharedVFolder": "Sie können jetzt auf den Ordner zugreifen:",
32233223
"ActiveSessions": "Aktive Sitzungen",
32243224
"Announcement": "Ankündigung",
3225+
"AnnouncementDeleted": "Ankündigung wurde gelöscht.",
3226+
"AnnouncementEnabled": "Aktiviert",
3227+
"AnnouncementMessage": "Nachricht",
3228+
"AnnouncementMessageRequired": "Bitte geben Sie eine Nachricht ein, um die Ankündigung zu aktivieren.",
3229+
"AnnouncementPreview": "Vorschau",
3230+
"AnnouncementUpdated": "Ankündigung wurde aktualisiert.",
32253231
"CLI": "CLI",
32263232
"CLIDownloadExecutable": "Eigenständige ausführbare Datei herunterladen",
32273233
"CLIGetStartedDescription": "Konfigurieren Sie mit Ihren aktuellen Sitzungsanmeldedaten:",
32283234
"CLIInstallViaPip": "Über pip installieren",
32293235
"CLIMacOSUnsignedDescription": "Dieser Build ist nicht signiert, daher könnte macOS ihn blockieren. Entfernen Sie nach dem Herunterladen das Quarantäne-Flag und machen Sie die Datei ausführbar:",
32303236
"CLIMacOSUnsignedTitle": "macOS könnte diesen unsignierten Build blockieren",
32313237
"CLIRunExecutableDescription": "Machen Sie die Datei nach dem Herunterladen ausführbar und führen Sie sie aus:",
3232-
"AnnouncementEnabled": "Aktiviert",
3233-
"AnnouncementMessage": "Nachricht",
3234-
"AnnouncementMessageRequired": "Bitte geben Sie eine Nachricht ein, um die Ankündigung zu aktivieren.",
3235-
"AnnouncementPreview": "Vorschau",
3236-
"AnnouncementUpdated": "Ankündigung wurde aktualisiert.",
32373238
"ChangeSystemSetting": "Systemeinstellung ändern",
32383239
"CheckResources": "Ressourcen prüfen",
32393240
"ConnectedNodes": "Verbunden <br/> Knoten",

resources/i18n/el.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,18 +3220,19 @@
32203220
"AcceptSharedVFolder": "Τώρα μπορείτε να αποκτήσετε πρόσβαση σε φάκελο:",
32213221
"ActiveSessions": "Ενεργές Συνεδρίες",
32223222
"Announcement": "Ανακοίνωση",
3223+
"AnnouncementDeleted": "Η ανακοίνωση διαγράφηκε.",
3224+
"AnnouncementEnabled": "Ενεργοποιημένο",
3225+
"AnnouncementMessage": "Μήνυμα",
3226+
"AnnouncementMessageRequired": "Παρακαλώ εισάγετε ένα μήνυμα για να ενεργοποιήσετε την ανακοίνωση.",
3227+
"AnnouncementPreview": "Προεπισκόπηση",
3228+
"AnnouncementUpdated": "Η ανακοίνωση ενημερώθηκε.",
32233229
"CLI": "CLI",
32243230
"CLIDownloadExecutable": "Λήψη αυτόνομου εκτελέσιμου αρχείου",
32253231
"CLIGetStartedDescription": "Διαμορφώστε με τα διαπιστευτήρια της τρέχουσας περιόδου σύνδεσής σας:",
32263232
"CLIInstallViaPip": "Εγκατάσταση μέσω pip",
32273233
"CLIMacOSUnsignedDescription": "Αυτή η έκδοση δεν είναι υπογεγραμμένη, επομένως το macOS ενδέχεται να την αποκλείσει. Μετά τη λήψη, καταργήστε τη σήμανση quarantine και κάντε το αρχείο εκτελέσιμο:",
32283234
"CLIMacOSUnsignedTitle": "Το macOS ενδέχεται να αποκλείσει αυτήν την ανυπόγραφη έκδοση",
32293235
"CLIRunExecutableDescription": "Μετά τη λήψη, κάντε το αρχείο εκτελέσιμο και εκτελέστε το:",
3230-
"AnnouncementEnabled": "Ενεργοποιημένο",
3231-
"AnnouncementMessage": "Μήνυμα",
3232-
"AnnouncementMessageRequired": "Παρακαλώ εισάγετε ένα μήνυμα για να ενεργοποιήσετε την ανακοίνωση.",
3233-
"AnnouncementPreview": "Προεπισκόπηση",
3234-
"AnnouncementUpdated": "Η ανακοίνωση ενημερώθηκε.",
32353236
"ChangeSystemSetting": "Αλλαγή ρύθμισης συστήματος",
32363237
"CheckResources": "Ελέγξτε πόρους",
32373238
"ConnectedNodes": "Συνδεδεμένοι κόμβοι <br/>",

resources/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,6 +3207,7 @@
32073207
"AcceptSharedVFolder": "You can now access folder: ",
32083208
"ActiveSessions": "Active Sessions",
32093209
"Announcement": "Announcement",
3210+
"AnnouncementDeleted": "Announcement deleted.",
32103211
"AnnouncementEnabled": "Enabled",
32113212
"AnnouncementMessage": "Message",
32123213
"AnnouncementMessageRequired": "Please enter a message to enable the announcement.",

resources/i18n/es.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,18 +3220,19 @@
32203220
"AcceptSharedVFolder": "Ahora puede acceder a la carpeta:",
32213221
"ActiveSessions": "Sesiones activas",
32223222
"Announcement": "Anuncio",
3223+
"AnnouncementDeleted": "El anuncio ha sido eliminado.",
3224+
"AnnouncementEnabled": "Habilitado",
3225+
"AnnouncementMessage": "Mensaje",
3226+
"AnnouncementMessageRequired": "Por favor, ingrese un mensaje para habilitar el anuncio.",
3227+
"AnnouncementPreview": "Vista previa",
3228+
"AnnouncementUpdated": "El anuncio ha sido actualizado.",
32233229
"CLI": "CLI",
32243230
"CLIDownloadExecutable": "Descargar ejecutable independiente",
32253231
"CLIGetStartedDescription": "Configura con las credenciales de tu sesión actual:",
32263232
"CLIInstallViaPip": "Instalar mediante pip",
32273233
"CLIMacOSUnsignedDescription": "Esta compilación no está firmada, por lo que macOS puede bloquearla. Después de descargarla, elimina el indicador de quarantine y hazla ejecutable:",
32283234
"CLIMacOSUnsignedTitle": "macOS puede bloquear esta compilación sin firmar",
32293235
"CLIRunExecutableDescription": "Después de descargarlo, hazlo ejecutable y ejecútalo:",
3230-
"AnnouncementEnabled": "Habilitado",
3231-
"AnnouncementMessage": "Mensaje",
3232-
"AnnouncementMessageRequired": "Por favor, ingrese un mensaje para habilitar el anuncio.",
3233-
"AnnouncementPreview": "Vista previa",
3234-
"AnnouncementUpdated": "El anuncio ha sido actualizado.",
32353236
"ChangeSystemSetting": "Cambiar la configuración del sistema",
32363237
"CheckResources": "Comprobar recursos",
32373238
"ConnectedNodes": "Conectado<br/>Nodos",

resources/i18n/fi.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,18 +3220,19 @@
32203220
"AcceptSharedVFolder": "Voit nyt käyttää kansiota:",
32213221
"ActiveSessions": "Aktiiviset istunnot",
32223222
"Announcement": "Ilmoitus",
3223+
"AnnouncementDeleted": "Ilmoitus on poistettu.",
3224+
"AnnouncementEnabled": "Käytössä",
3225+
"AnnouncementMessage": "Viesti",
3226+
"AnnouncementMessageRequired": "Syötä viesti ottaaksesi ilmoituksen käyttöön.",
3227+
"AnnouncementPreview": "Esikatselu",
3228+
"AnnouncementUpdated": "Ilmoitus on päivitetty.",
32233229
"CLI": "CLI",
32243230
"CLIDownloadExecutable": "Lataa itsenäinen suoritettava tiedosto",
32253231
"CLIGetStartedDescription": "Määritä nykyisen istuntosi tunnistetiedoilla:",
32263232
"CLIInstallViaPip": "Asenna pip-komennolla",
32273233
"CLIMacOSUnsignedDescription": "Tätä koontiversiota ei ole allekirjoitettu, joten macOS saattaa estää sen. Poista latauksen jälkeen quarantine-merkintä ja tee tiedostosta suoritettava:",
32283234
"CLIMacOSUnsignedTitle": "macOS saattaa estää tämän allekirjoittamattoman koontiversion",
32293235
"CLIRunExecutableDescription": "Tee lataamisen jälkeen tiedostosta suoritettava ja suorita se:",
3230-
"AnnouncementEnabled": "Käytössä",
3231-
"AnnouncementMessage": "Viesti",
3232-
"AnnouncementMessageRequired": "Syötä viesti ottaaksesi ilmoituksen käyttöön.",
3233-
"AnnouncementPreview": "Esikatselu",
3234-
"AnnouncementUpdated": "Ilmoitus on päivitetty.",
32353236
"ChangeSystemSetting": "Vaihda järjestelmäasetusta",
32363237
"CheckResources": "Tarkista resurssit",
32373238
"ConnectedNodes": "Yhdistetyt<br/>Solmut",

resources/i18n/fr.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,18 +3223,19 @@
32233223
"AcceptSharedVFolder": "Vous pouvez maintenant accéder au dossier :",
32243224
"ActiveSessions": "sessions actives",
32253225
"Announcement": "Annonce",
3226+
"AnnouncementDeleted": "L'annonce a été supprimée.",
3227+
"AnnouncementEnabled": "Activé",
3228+
"AnnouncementMessage": "Message",
3229+
"AnnouncementMessageRequired": "Veuillez saisir un message pour activer l'annonce.",
3230+
"AnnouncementPreview": "Aperçu",
3231+
"AnnouncementUpdated": "L'annonce a été mise à jour.",
32263232
"CLI": "CLI",
32273233
"CLIDownloadExecutable": "Télécharger l'exécutable autonome",
32283234
"CLIGetStartedDescription": "Configurez avec les informations d'identification de votre session actuelle :",
32293235
"CLIInstallViaPip": "Installer via pip",
32303236
"CLIMacOSUnsignedDescription": "Cette version n'est pas signée, macOS peut donc la bloquer. Après le téléchargement, retirez l'attribut quarantine et rendez le fichier exécutable :",
32313237
"CLIMacOSUnsignedTitle": "macOS peut bloquer cette version non signée",
32323238
"CLIRunExecutableDescription": "Après le téléchargement, rendez-le exécutable et exécutez-le :",
3233-
"AnnouncementEnabled": "Activé",
3234-
"AnnouncementMessage": "Message",
3235-
"AnnouncementMessageRequired": "Veuillez saisir un message pour activer l'annonce.",
3236-
"AnnouncementPreview": "Aperçu",
3237-
"AnnouncementUpdated": "L'annonce a été mise à jour.",
32383239
"ChangeSystemSetting": "Modifier les paramètres du système",
32393240
"CheckResources": "Consulter les ressources",
32403241
"ConnectedNodes": "Nœuds connectés <br/>",

resources/i18n/id.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,18 +3224,19 @@
32243224
"AcceptSharedVFolder": "Anda sekarang dapat mengakses folder: ",
32253225
"ActiveSessions": "Sesi Aktif",
32263226
"Announcement": "Pengumuman",
3227+
"AnnouncementDeleted": "Pengumuman telah dihapus.",
3228+
"AnnouncementEnabled": "Diaktifkan",
3229+
"AnnouncementMessage": "Pesan",
3230+
"AnnouncementMessageRequired": "Masukkan pesan untuk mengaktifkan pengumuman.",
3231+
"AnnouncementPreview": "Pratinjau",
3232+
"AnnouncementUpdated": "Pengumuman telah diperbarui.",
32273233
"CLI": "CLI",
32283234
"CLIDownloadExecutable": "Unduh executable mandiri",
32293235
"CLIGetStartedDescription": "Konfigurasikan dengan kredensial sesi Anda saat ini:",
32303236
"CLIInstallViaPip": "Instal melalui pip",
32313237
"CLIMacOSUnsignedDescription": "Build ini tidak ditandatangani, sehingga macOS mungkin memblokirnya. Setelah mengunduh, hapus flag quarantine dan jadikan dapat dieksekusi:",
32323238
"CLIMacOSUnsignedTitle": "macOS mungkin memblokir build yang tidak ditandatangani ini",
32333239
"CLIRunExecutableDescription": "Setelah mengunduh, jadikan dapat dieksekusi dan jalankan:",
3234-
"AnnouncementEnabled": "Diaktifkan",
3235-
"AnnouncementMessage": "Pesan",
3236-
"AnnouncementMessageRequired": "Masukkan pesan untuk mengaktifkan pengumuman.",
3237-
"AnnouncementPreview": "Pratinjau",
3238-
"AnnouncementUpdated": "Pengumuman telah diperbarui.",
32393240
"ChangeSystemSetting": "Ubah pengaturan sistem",
32403241
"CheckResources": "Periksa sumber daya",
32413242
"ConnectedNodes": "Node<br/>Terhubung",

resources/i18n/it.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,18 +3220,19 @@
32203220
"AcceptSharedVFolder": "Ora puoi accedere alla cartella:",
32213221
"ActiveSessions": "Sessioni Attive",
32223222
"Announcement": "Annuncio",
3223+
"AnnouncementDeleted": "L'annuncio è stato eliminato.",
3224+
"AnnouncementEnabled": "Abilitato",
3225+
"AnnouncementMessage": "Messaggio",
3226+
"AnnouncementMessageRequired": "Inserisci un messaggio per abilitare l'annuncio.",
3227+
"AnnouncementPreview": "Anteprima",
3228+
"AnnouncementUpdated": "L'annuncio è stato aggiornato.",
32233229
"CLI": "CLI",
32243230
"CLIDownloadExecutable": "Scarica l'eseguibile standalone",
32253231
"CLIGetStartedDescription": "Configura con le credenziali della sessione corrente:",
32263232
"CLIInstallViaPip": "Installa tramite pip",
32273233
"CLIMacOSUnsignedDescription": "Questa build non è firmata, quindi macOS potrebbe bloccarla. Dopo il download, rimuovi il flag di quarantine e rendila eseguibile:",
32283234
"CLIMacOSUnsignedTitle": "macOS potrebbe bloccare questa build non firmata",
32293235
"CLIRunExecutableDescription": "Dopo il download, rendilo eseguibile ed eseguilo:",
3230-
"AnnouncementEnabled": "Abilitato",
3231-
"AnnouncementMessage": "Messaggio",
3232-
"AnnouncementMessageRequired": "Inserisci un messaggio per abilitare l'annuncio.",
3233-
"AnnouncementPreview": "Anteprima",
3234-
"AnnouncementUpdated": "L'annuncio è stato aggiornato.",
32353236
"ChangeSystemSetting": "Modifica impostazioni di sistema",
32363237
"CheckResources": "Controlla le risorse",
32373238
"ConnectedNodes": "Nodi connessi <br/>",

resources/i18n/ja.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,18 +3222,19 @@
32223222
"AcceptSharedVFolder": "これで、フォルダにアクセスできます。",
32233223
"ActiveSessions": "アクティブセッション",
32243224
"Announcement": "発表",
3225+
"AnnouncementDeleted": "発表が削除されました。",
3226+
"AnnouncementEnabled": "有効",
3227+
"AnnouncementMessage": "メッセージ",
3228+
"AnnouncementMessageRequired": "発表を有効にするには、メッセージを入力してください。",
3229+
"AnnouncementPreview": "プレビュー",
3230+
"AnnouncementUpdated": "発表が更新されました。",
32253231
"CLI": "CLI",
32263232
"CLIDownloadExecutable": "スタンドアロン実行ファイルをダウンロード",
32273233
"CLIGetStartedDescription": "現在のセッションの認証情報で設定してください:",
32283234
"CLIInstallViaPip": "pipでインストール",
32293235
"CLIMacOSUnsignedDescription": "このビルドは署名されていないため、macOSによってブロックされる場合があります。ダウンロード後、quarantine属性を解除して実行可能にしてください:",
32303236
"CLIMacOSUnsignedTitle": "macOSがこの未署名ビルドをブロックする場合があります",
32313237
"CLIRunExecutableDescription": "ダウンロード後、実行可能にして実行してください:",
3232-
"AnnouncementEnabled": "有効",
3233-
"AnnouncementMessage": "メッセージ",
3234-
"AnnouncementMessageRequired": "発表を有効にするには、メッセージを入力してください。",
3235-
"AnnouncementPreview": "プレビュー",
3236-
"AnnouncementUpdated": "発表が更新されました。",
32373238
"ChangeSystemSetting": "システム設定変更",
32383239
"CheckResources": "リソース確認",
32393240
"ConnectedNodes": "接続中ノード数",

0 commit comments

Comments
 (0)