diff --git a/messages/de.json b/messages/de.json index cfadbd90c..1b78ce9d0 100644 --- a/messages/de.json +++ b/messages/de.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "Schlaf ansehen", "googleHealthViewData": "Schritte ansehen", "apiTokens": "API-Tokens", - "apiTokensDescription": "API-Tokens für die externe Medikamenten-Einnahme prüfen und widerrufen.", + "apiTokensDescription": "Tokens für Messwerte, Trainings, Dokumente und Medikamenten-Einnahme prüfen und widerrufen.", "measurementsToken": { "title": "Messwert-Tokens", "description": "Erzeuge ein Token, damit eine Waage, eine Uhr oder deine Hausautomatisierung Werte eintragen kann.", "detail": "Das Token wird nur einmal angezeigt.", "scopeNote": "Es kann ausschließlich neue Werte in deine eigene Akte eintragen — deine Daten nicht lesen, nichts ändern oder löschen und kein weiteres Token erstellen. Werte werden als von einem externen Gerät gekennzeichnet, damit du sie später erkennst, und lassen sich jederzeit korrigieren.", - "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut." + "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut.", + "namePlaceholder": "Name, z. B. Home Assistant" }, "workoutsToken": { "title": "Training-Tokens", "description": "Erzeuge ein Token, damit eine Uhren-Brücke oder ein Sync-Skript deine Trainings eintragen kann.", "detail": "Das Token wird nur einmal angezeigt.", "scopeNote": "Es kann ausschließlich neue Trainings in deine eigene Akte eintragen. Es kann deine Daten nicht lesen, nichts ändern oder löschen und kein weiteres Token erstellen. Trainings, die darüber kommen, werden als von einem externen Gerät gekennzeichnet. Hat dein Telefon dieselbe Einheit aufgezeichnet, siehst du die Aufzeichnung des Telefons.", - "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut." + "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut.", + "namePlaceholder": "Name, z. B. Garmin" }, "documentsToken": { "title": "Dokument-Tokens", "description": "Erzeuge ein Token, damit Paperless-ngx, Papra oder das Import-Skript Dokumente in deine Ablage legen können.", "detail": "Das Token wird nur einmal angezeigt.", "scopeNote": "Es kann ausschließlich neue Dokumente in deine eigene Ablage legen. Es kann nichts auflisten, öffnen, herunterladen, ändern oder löschen und kein weiteres Token erstellen. Zurück bekommt es nur, ob eine Datei gespeichert wurde, nicht wie du sie abgelegt hast.", - "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut." + "createFailed": "Das Token konnte nicht erstellt werden. Bitte versuche es erneut.", + "namePlaceholder": "Name, z. B. Paperless-ngx" }, - "tokenMintMovedDescription": "Tokens werden dort ausgestellt, wo sie gelten: oben für Messwerte und Dokumente, oder im API-Endpoint eines Medikaments für genau dieses Medikament.", - "tokenNamePlaceholder": "Token-Name (z. B. iPhone Shortcut)", + "tokenMintMovedDescription": "Tokens werden dort ausgestellt, wo sie gelten: oben für Messwerte, Trainings und Dokumente, oder im API-Endpoint eines Medikaments für genau dieses Medikament.", "tokenCreated": "Token erstellt — kopiere ihn jetzt! Er wird nicht erneut angezeigt.", "tokenCopy": "Token kopieren", "tokenCopied": "Token in die Zwischenablage kopiert", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Inhalt neu wählen", "reselectReason": "Dieser Link lieferte einen Umfang, den niemand gewählt hatte, und wurde deshalb geschlossen. Lege einen neuen an und wähle den Inhalt.", "reselectAction": "Ersatz anlegen", - "createDetail": "Der Token wird nur einmal bei der Erstellung angezeigt — sichere ihn dann; er lässt sich nicht wiederherstellen." + "createDetail": "Der Token wird nur einmal bei der Erstellung angezeigt — sichere ihn dann; er lässt sich nicht wiederherstellen.", + "activeDescription": "Deine geteilten Links, wann sie ablaufen und wie oft sie geöffnet wurden." }, "genderOther": "Divers", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Remote-MCP-Endpunkt", "enableDescription": "Erlaube einem MCP-fähigen Assistenten (Claude.ai, ChatGPT), deine Gesundheitsdaten über ein begrenztes Token zu lesen.", - "enabled": "Aktiv", - "disabled": "Inaktiv", "enableToggleLabel": "MCP-Endpunkt aktivieren", "endpointLabel": "Connector-URL", "connectDescription": "Füge diese URL in die Einrichtung des eigenen Connectors deines Assistenten ein und autorisiere dich mit dem Token unten oder melde dich bei Aufforderung an.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "Dies beendet den Zugriff des Assistenten sofort und verhindert eine Erneuerung. Für eine erneute Verbindung ist eine neue Autorisierung nötig.", "connectionRevokeFailed": "Assistent konnte nicht getrennt werden.", "tokensDetail": "Das Token wird nur einmal angezeigt.", - "connectionsDetail": "Das Widerrufen einer Verbindung beendet den Zugriff sofort, einschließlich der Möglichkeit zur Erneuerung." + "connectionsDetail": "Das Widerrufen einer Verbindung beendet den Zugriff sofort, einschließlich der Möglichkeit zur Erneuerung.", + "tokenNamePlaceholder": "Name, z. B. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Verbinde dein Strava-Konto, um deine Aktivitäten in deinen Trainingsverlauf zu übernehmen.", @@ -7169,7 +7171,8 @@ "signInAgain": "Melde dich neu an und versuche es dann noch einmal. Dein Konto hat kein Passwort und keinen Passkey, den du hier bestätigen könntest.", "failed": "Das hat nicht geklappt. Prüfe deine Eingabe und versuche es noch einmal." }, - "passwordTitle": "Passwort" + "passwordTitle": "Passwort", + "tokenNameLabel": "Token-Name" }, "admin": { "title": "Administration", diff --git a/messages/en.json b/messages/en.json index 03ea6e8c7..3be86c0aa 100644 --- a/messages/en.json +++ b/messages/en.json @@ -6541,31 +6541,33 @@ "whoopViewData": "View your recovery", "fitbitViewData": "View your sleep", "googleHealthViewData": "View your steps", - "apiTokens": "API Tokens", - "apiTokensDescription": "Review and revoke API tokens for external medication intake.", + "apiTokens": "API tokens", + "apiTokensDescription": "Review and revoke tokens for measurements, workouts, documents and medication intake.", "measurementsToken": { "title": "Measurement tokens", "description": "Mint a token so a scale, a watch bridge or your home automation can add readings.", "detail": "The token is shown once.", "scopeNote": "It can only add new readings to your own record — it cannot read your data, change or delete anything, or create another token. Readings are marked as coming from an external device, so you can tell them apart later, and you can still correct them yourself.", - "createFailed": "The token could not be created. Please try again." + "createFailed": "The token could not be created. Please try again.", + "namePlaceholder": "Name, e.g. Home Assistant" }, "workoutsToken": { "title": "Workout tokens", "description": "Mint a token so a watch bridge or a sync script can add your workouts.", "detail": "The token is shown once.", "scopeNote": "It can only add new workouts to your own record. It cannot read your data, change or delete anything, or create another token. Workouts it adds are marked as coming from an external device, and when your phone recorded the same session, you see the phone's copy.", - "createFailed": "The token could not be created. Please try again." + "createFailed": "The token could not be created. Please try again.", + "namePlaceholder": "Name, e.g. Garmin" }, "documentsToken": { "title": "Document tokens", "description": "Mint a token so Paperless-ngx, Papra or the import script can add documents to your vault.", "detail": "The token is shown once.", "scopeNote": "It can only add new documents to your own vault. It cannot list, open, download, change or delete anything, and it cannot create another token. What it gets back is whether a file was stored, not how you filed it.", - "createFailed": "The token could not be created. Please try again." + "createFailed": "The token could not be created. Please try again.", + "namePlaceholder": "Name, e.g. Paperless-ngx" }, - "tokenMintMovedDescription": "Tokens are issued where they apply: above for measurements and documents, or in a medication's own API endpoint for that one medication.", - "tokenNamePlaceholder": "Token name (e.g., iPhone Shortcut)", + "tokenMintMovedDescription": "Tokens are issued where they apply: above for measurements, workouts and documents, or in a medication's own API endpoint for that one medication.", "tokenCreated": "Token created — copy it now! It won't be shown again.", "tokenCopy": "Copy token", "tokenCopied": "Token copied to clipboard", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Pick contents again", "reselectReason": "This link served a scope that was never chosen, so it was closed. Create a new one and pick what it should contain.", "reselectAction": "Create a replacement", - "createDetail": "The token is shown once on creation — store it then; it cannot be recovered." + "createDetail": "The token is shown once on creation — store it then; it cannot be recovered.", + "activeDescription": "Links you have shared, when they expire and how often they were opened." }, "genderOther": "Other", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Remote MCP endpoint", "enableDescription": "Let an MCP-capable assistant (Claude.ai, ChatGPT) read your health data over a scoped token.", - "enabled": "Enabled", - "disabled": "Disabled", "enableToggleLabel": "Enable the MCP endpoint", "endpointLabel": "Connector URL", "connectDescription": "Paste this URL into your assistant's custom-connector setup, then authorize with the token below or sign in when prompted.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "This ends the assistant's access immediately and stops it from renewing. It will need to be re-authorized to reconnect.", "connectionRevokeFailed": "Could not disconnect the assistant.", "connectionsDetail": "Revoking a connection ends its access immediately, including its ability to refresh.", - "tokensDetail": "The token is shown once." + "tokensDetail": "The token is shown once.", + "tokenNamePlaceholder": "Name, e.g. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Connect your Strava account to sync your activities into your workout history.", @@ -7169,7 +7171,8 @@ "signInAgain": "Sign in again, then try once more. Your account has no password or passkey to confirm here.", "failed": "That did not work. Check what you entered and try again." }, - "passwordTitle": "Password" + "passwordTitle": "Password", + "tokenNameLabel": "Token name" }, "admin": { "title": "Administration", diff --git a/messages/es.json b/messages/es.json index 207e50d34..1cf707450 100644 --- a/messages/es.json +++ b/messages/es.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "Ver tu sueño", "googleHealthViewData": "Ver tus pasos", "apiTokens": "Tokens de API", - "apiTokensDescription": "Revisa y revoca tokens de API para el registro externo de tomas de medicación.", + "apiTokensDescription": "Revisa y revoca los tokens de mediciones, entrenamientos, documentos y tomas de medicación.", "measurementsToken": { "title": "Tokens de mediciones", "description": "Crea un token para que una báscula, un reloj o tu domótica añadan mediciones.", "detail": "El token se muestra una sola vez.", "scopeNote": "Solo puede añadir mediciones nuevas a tu propio historial: no puede leer tus datos, ni modificar o borrar nada, ni crear otro token. Las mediciones se marcan como procedentes de un dispositivo externo, así las distingues más tarde, y puedes corregirlas igualmente.", - "createFailed": "No se pudo crear el token. Inténtalo de nuevo." + "createFailed": "No se pudo crear el token. Inténtalo de nuevo.", + "namePlaceholder": "Nombre, p. ej. Home Assistant" }, "workoutsToken": { "title": "Tokens de entrenamientos", "description": "Crea un token para que un puente de tu reloj o un script de sincronización añadan tus entrenamientos.", "detail": "El token se muestra una sola vez.", "scopeNote": "Solo puede añadir entrenamientos nuevos a tu propio historial. No puede leer tus datos, ni modificar o borrar nada, ni crear otro token. Los entrenamientos que añade se marcan como procedentes de un dispositivo externo, y si tu teléfono registró la misma sesión, ves la copia del teléfono.", - "createFailed": "No se pudo crear el token. Inténtalo de nuevo." + "createFailed": "No se pudo crear el token. Inténtalo de nuevo.", + "namePlaceholder": "Nombre, p. ej. Garmin" }, "documentsToken": { "title": "Tokens de documentos", "description": "Crea un token para que Paperless-ngx, Papra o el script de importación añadan documentos a tu archivo.", "detail": "El token se muestra una sola vez.", "scopeNote": "Solo puede añadir documentos nuevos a tu propio archivo. No puede listar, abrir, descargar, modificar ni borrar nada, ni crear otro token. Lo único que recibe es si un archivo se guardó, no cómo lo archivaste.", - "createFailed": "No se pudo crear el token. Inténtalo de nuevo." + "createFailed": "No se pudo crear el token. Inténtalo de nuevo.", + "namePlaceholder": "Nombre, p. ej. Paperless-ngx" }, - "tokenMintMovedDescription": "Los tokens se emiten donde se aplican: arriba para las mediciones y los documentos, o en el endpoint de API de un medicamento para ese medicamento concreto.", - "tokenNamePlaceholder": "Nombre del token (p. ej., Atajo de iPhone)", + "tokenMintMovedDescription": "Los tokens se emiten donde se aplican: arriba para las mediciones, los entrenamientos y los documentos, o en el endpoint de API de un medicamento para ese medicamento concreto.", "tokenCreated": "Token creado — ¡cópialo ahora! No se mostrará de nuevo.", "tokenCopy": "Copiar token", "tokenCopied": "Token copiado al portapapeles", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Elegir contenido de nuevo", "reselectReason": "Este enlace mostraba un alcance que nadie eligió, por eso se cerró. Crea uno nuevo y elige su contenido.", "reselectAction": "Crear un reemplazo", - "createDetail": "El token se muestra una sola vez al crearlo — guárdalo entonces; no se puede recuperar." + "createDetail": "El token se muestra una sola vez al crearlo — guárdalo entonces; no se puede recuperar.", + "activeDescription": "Los enlaces que has compartido, cuándo caducan y cuántas veces se abrieron." }, "genderOther": "Otro", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Endpoint MCP remoto", "enableDescription": "Permite que un asistente compatible con MCP (Claude.ai, ChatGPT) lea tus datos de salud mediante un token limitado.", - "enabled": "Activado", - "disabled": "Desactivado", "enableToggleLabel": "Activar el endpoint MCP", "endpointLabel": "URL del conector", "connectDescription": "Pega esta URL en la configuración del conector personalizado de tu asistente y autoriza con el token de abajo o inicia sesión cuando se te solicite.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "Esto finaliza el acceso del asistente de inmediato e impide su renovación. Será necesario autorizarlo de nuevo para volver a conectarlo.", "connectionRevokeFailed": "No se pudo desconectar el asistente.", "tokensDetail": "El token se muestra una sola vez.", - "connectionsDetail": "Revocar una conexión finaliza su acceso de inmediato, incluida su capacidad de renovación." + "connectionsDetail": "Revocar una conexión finaliza su acceso de inmediato, incluida su capacidad de renovación.", + "tokenNamePlaceholder": "Nombre, p. ej. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Conecta tu cuenta de Strava para sincronizar tus actividades con tu historial de entrenamientos.", @@ -7169,7 +7171,8 @@ "signInAgain": "Vuelve a iniciar sesión y inténtalo de nuevo. Tu cuenta no tiene contraseña ni llave de acceso que confirmar aquí.", "failed": "No ha funcionado. Revisa lo que has introducido e inténtalo de nuevo." }, - "passwordTitle": "Contraseña" + "passwordTitle": "Contraseña", + "tokenNameLabel": "Nombre del token" }, "admin": { "title": "Administration", diff --git a/messages/fr.json b/messages/fr.json index 0f3cd67f7..45cd54c60 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "Voir votre sommeil", "googleHealthViewData": "Voir vos pas", "apiTokens": "Jetons API", - "apiTokensDescription": "Consultez et révoquez les jetons API pour l’enregistrement externe des prises de médicaments.", + "apiTokensDescription": "Consultez et révoquez les jetons des mesures, entraînements, documents et prises de médicaments.", "measurementsToken": { "title": "Jetons de mesures", "description": "Créez un jeton pour qu'une balance, une montre ou votre domotique ajoutent des mesures.", "detail": "Le jeton n'est affiché qu'une fois.", "scopeNote": "Il peut uniquement ajouter de nouvelles mesures à votre propre dossier : il ne peut pas lire vos données, ni modifier ou supprimer quoi que ce soit, ni créer un autre jeton. Les mesures sont signalées comme provenant d'un appareil externe, ce qui vous permet de les reconnaître plus tard, et vous pouvez toujours les corriger.", - "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer." + "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer.", + "namePlaceholder": "Nom, p. ex. Home Assistant" }, "workoutsToken": { "title": "Jetons d'entraînements", "description": "Créez un jeton pour qu'une passerelle de montre ou un script de synchronisation ajoutent vos entraînements.", "detail": "Le jeton n'est affiché qu'une fois.", "scopeNote": "Il peut uniquement ajouter de nouveaux entraînements à votre propre dossier. Il ne peut pas lire vos données, ni modifier ou supprimer quoi que ce soit, ni créer un autre jeton. Les entraînements qu'il ajoute sont signalés comme provenant d'un appareil externe, et si votre téléphone a enregistré la même séance, c'est la copie du téléphone que vous voyez.", - "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer." + "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer.", + "namePlaceholder": "Nom, p. ex. Garmin" }, "documentsToken": { "title": "Jetons de documents", "description": "Créez un jeton pour que Paperless-ngx, Papra ou le script d'import ajoutent des documents à votre coffre.", "detail": "Le jeton n'est affiché qu'une fois.", "scopeNote": "Il peut uniquement ajouter de nouveaux documents à votre propre coffre. Il ne peut rien lister, ouvrir, télécharger, modifier ou supprimer, ni créer un autre jeton. Il apprend seulement si un fichier a été enregistré, pas comment vous l'avez classé.", - "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer." + "createFailed": "Le jeton n'a pas pu être créé. Veuillez réessayer.", + "namePlaceholder": "Nom, p. ex. Paperless-ngx" }, - "tokenMintMovedDescription": "Les jetons sont émis là où ils s'appliquent : ci-dessus pour les mesures et les documents, ou dans le point de terminaison API d'un médicament pour ce seul médicament.", - "tokenNamePlaceholder": "Nom du jeton (par exemple Raccourci iPhone)", + "tokenMintMovedDescription": "Les jetons sont émis là où ils s'appliquent : ci-dessus pour les mesures, les entraînements et les documents, ou dans le point de terminaison API d'un médicament pour ce seul médicament.", "tokenCreated": "Jeton créé — copiez-le maintenant ! Il ne sera plus affiché.", "tokenCopy": "Copier le jeton", "tokenCopied": "Jeton copié dans le presse-papiers", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Choisir à nouveau le contenu", "reselectReason": "Ce lien diffusait un périmètre que personne n'avait choisi ; il a donc été fermé. Créez-en un nouveau et choisissez son contenu.", "reselectAction": "Créer un remplacement", - "createDetail": "Le jeton n'est affiché qu'une fois à la création — conservez-le alors ; il ne peut pas être récupéré." + "createDetail": "Le jeton n'est affiché qu'une fois à la création — conservez-le alors ; il ne peut pas être récupéré.", + "activeDescription": "Les liens que vous avez partagés, leur expiration et le nombre d'ouvertures." }, "genderOther": "Autre", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Point de terminaison MCP distant", "enableDescription": "Autorisez un assistant compatible MCP (Claude.ai, ChatGPT) à lire vos données de santé via un jeton restreint.", - "enabled": "Activé", - "disabled": "Désactivé", "enableToggleLabel": "Activer le point de terminaison MCP", "endpointLabel": "URL du connecteur", "connectDescription": "Collez cette URL dans la configuration du connecteur personnalisé de votre assistant, puis autorisez avec le jeton ci-dessous ou connectez-vous lorsque vous y êtes invité.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "Cela met fin immédiatement à l'accès de l'assistant et l'empêche de se renouveler. Une nouvelle autorisation sera nécessaire pour le reconnecter.", "connectionRevokeFailed": "Impossible de déconnecter l'assistant.", "tokensDetail": "Le jeton n'est affiché qu'une seule fois.", - "connectionsDetail": "Révoquer une connexion met fin à son accès immédiatement, y compris sa capacité à se renouveler." + "connectionsDetail": "Révoquer une connexion met fin à son accès immédiatement, y compris sa capacité à se renouveler.", + "tokenNamePlaceholder": "Nom, p. ex. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Connecte ton compte Strava pour synchroniser tes activités avec ton historique d'entraînement.", @@ -7169,7 +7171,8 @@ "signInAgain": "Reconnectez-vous, puis réessayez. Votre compte n'a ni mot de passe ni clé d'accès à confirmer ici.", "failed": "Cela n'a pas fonctionné. Vérifiez votre saisie et réessayez." }, - "passwordTitle": "Mot de passe" + "passwordTitle": "Mot de passe", + "tokenNameLabel": "Nom du jeton" }, "admin": { "title": "Administration", diff --git a/messages/it.json b/messages/it.json index 2ae1490d2..a8b186614 100644 --- a/messages/it.json +++ b/messages/it.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "Vedi il tuo sonno", "googleHealthViewData": "Vedi i tuoi passi", "apiTokens": "Token API", - "apiTokensDescription": "Rivedi e revoca i token API per la registrazione esterna delle assunzioni di farmaci.", + "apiTokensDescription": "Rivedi e revoca i token per misurazioni, allenamenti, documenti e assunzioni di farmaci.", "measurementsToken": { "title": "Token per misurazioni", "description": "Crea un token perché una bilancia, un orologio o la tua domotica aggiungano misurazioni.", "detail": "Il token viene mostrato una sola volta.", "scopeNote": "Può soltanto aggiungere nuove misurazioni alla tua cartella: non può leggere i tuoi dati, modificare o eliminare nulla, né creare un altro token. Le misurazioni vengono contrassegnate come provenienti da un dispositivo esterno, così le riconosci in seguito, e puoi comunque correggerle.", - "createFailed": "Non è stato possibile creare il token. Riprova." + "createFailed": "Non è stato possibile creare il token. Riprova.", + "namePlaceholder": "Nome, ad es. Home Assistant" }, "workoutsToken": { "title": "Token per allenamenti", "description": "Crea un token perché un ponte dell'orologio o uno script di sincronizzazione aggiungano i tuoi allenamenti.", "detail": "Il token viene mostrato una sola volta.", "scopeNote": "Può soltanto aggiungere nuovi allenamenti alla tua cartella. Non può leggere i tuoi dati, modificare o eliminare nulla, né creare un altro token. Gli allenamenti che aggiunge vengono contrassegnati come provenienti da un dispositivo esterno e, se il telefono ha registrato la stessa sessione, vedi la copia del telefono.", - "createFailed": "Non è stato possibile creare il token. Riprova." + "createFailed": "Non è stato possibile creare il token. Riprova.", + "namePlaceholder": "Nome, ad es. Garmin" }, "documentsToken": { "title": "Token per documenti", "description": "Crea un token perché Paperless-ngx, Papra o lo script di importazione aggiungano documenti al tuo archivio.", "detail": "Il token viene mostrato una sola volta.", "scopeNote": "Può soltanto aggiungere nuovi documenti al tuo archivio. Non può elencare, aprire, scaricare, modificare o eliminare nulla, né creare un altro token. Riceve solo l'informazione se un file è stato salvato, non come l'hai archiviato.", - "createFailed": "Non è stato possibile creare il token. Riprova." + "createFailed": "Non è stato possibile creare il token. Riprova.", + "namePlaceholder": "Nome, ad es. Paperless-ngx" }, - "tokenMintMovedDescription": "I token vengono emessi dove si applicano: qui sopra per le misurazioni e i documenti, oppure nell'endpoint API di un farmaco per quel singolo farmaco.", - "tokenNamePlaceholder": "Nome del token (ad es. Comando rapido iPhone)", + "tokenMintMovedDescription": "I token vengono emessi dove si applicano: qui sopra per le misurazioni, gli allenamenti e i documenti, oppure nell'endpoint API di un farmaco per quel singolo farmaco.", "tokenCreated": "Token creato — copialo ora! Non verrà mostrato di nuovo.", "tokenCopy": "Copia token", "tokenCopied": "Token copiato negli appunti", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Scegli di nuovo il contenuto", "reselectReason": "Questo link mostrava un ambito che nessuno aveva scelto, perciò è stato chiuso. Creane uno nuovo e scegli cosa deve contenere.", "reselectAction": "Crea un sostituto", - "createDetail": "Il token viene mostrato una sola volta alla creazione — salvalo subito; non può essere recuperato." + "createDetail": "Il token viene mostrato una sola volta alla creazione — salvalo subito; non può essere recuperato.", + "activeDescription": "I link che hai condiviso, quando scadono e quante volte sono stati aperti." }, "genderOther": "Altro", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Endpoint MCP remoto", "enableDescription": "Consenti a un assistente compatibile con MCP (Claude.ai, ChatGPT) di leggere i tuoi dati sulla salute tramite un token limitato.", - "enabled": "Attivo", - "disabled": "Inattivo", "enableToggleLabel": "Attiva l'endpoint MCP", "endpointLabel": "URL del connettore", "connectDescription": "Incolla questo URL nella configurazione del connettore personalizzato del tuo assistente e autorizza con il token qui sotto o accedi quando richiesto.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "Questo termina immediatamente l'accesso dell'assistente e ne impedisce il rinnovo. Per riconnetterlo sarà necessaria una nuova autorizzazione.", "connectionRevokeFailed": "Impossibile disconnettere l'assistente.", "tokensDetail": "Il token viene mostrato una sola volta.", - "connectionsDetail": "Revocare una connessione ne termina subito l'accesso, inclusa la capacità di rinnovarsi." + "connectionsDetail": "Revocare una connessione ne termina subito l'accesso, inclusa la capacità di rinnovarsi.", + "tokenNamePlaceholder": "Nome, ad es. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Collega il tuo account Strava per sincronizzare le tue attività con la cronologia degli allenamenti.", @@ -7169,7 +7171,8 @@ "signInAgain": "Accedi di nuovo, poi riprova. Il tuo account non ha una password o una passkey da confermare qui.", "failed": "Non ha funzionato. Controlla quanto inserito e riprova." }, - "passwordTitle": "Password" + "passwordTitle": "Password", + "tokenNameLabel": "Nome del token" }, "admin": { "title": "Administration", diff --git a/messages/ko.json b/messages/ko.json index 21cffb63a..7a761719e 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "수면 보기", "googleHealthViewData": "걸음 수 보기", "apiTokens": "API 토큰", - "apiTokensDescription": "외부에서 복용을 기록할 때 쓰는 API 토큰을 확인하고 폐기해요.", + "apiTokensDescription": "측정값, 운동, 문서, 복용 기록용 토큰을 확인하고 폐기해요.", "measurementsToken": { "title": "측정 토큰", "description": "체중계나 시계, 홈 오토메이션이 측정값을 기록할 수 있도록 토큰을 만들어요.", "detail": "토큰은 한 번만 표시돼요.", "scopeNote": "본인 기록에 새 측정값을 추가하는 것만 할 수 있어요. 데이터를 읽거나, 무언가를 고치거나 지우거나, 다른 토큰을 만들 수는 없어요. 측정값은 외부 기기에서 온 것으로 표시되니 나중에 구분할 수 있고, 언제든 고칠 수 있어요.", - "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요." + "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요.", + "namePlaceholder": "이름 (예: Home Assistant)" }, "workoutsToken": { "title": "운동 토큰", "description": "시계 연동 브리지나 동기화 스크립트가 운동 기록을 추가할 수 있도록 토큰을 만들어요.", "detail": "토큰은 한 번만 표시돼요.", "scopeNote": "본인 기록에 새 운동을 추가하는 것만 할 수 있어요. 데이터를 읽거나, 무언가를 고치거나 지우거나, 다른 토큰을 만들 수는 없어요. 이 토큰으로 추가된 운동은 외부 기기에서 온 것으로 표시되고, 휴대폰이 같은 운동을 기록했다면 휴대폰의 기록이 보여요.", - "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요." + "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요.", + "namePlaceholder": "이름 (예: Garmin)" }, "documentsToken": { "title": "문서 토큰", "description": "Paperless-ngx, Papra 또는 가져오기 스크립트가 문서함에 문서를 추가할 수 있도록 토큰을 만들어요.", "detail": "토큰은 한 번만 표시돼요.", "scopeNote": "본인 문서함에 새 문서를 추가하는 것만 할 수 있어요. 목록을 보거나, 열거나, 내려받거나, 고치거나 지울 수 없고, 다른 토큰을 만들 수도 없어요. 파일이 저장됐는지만 알 수 있고, 어떻게 정리했는지는 알 수 없어요.", - "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요." + "createFailed": "토큰을 만들지 못했어요. 다시 시도해 주세요.", + "namePlaceholder": "이름 (예: Paperless-ngx)" }, - "tokenMintMovedDescription": "토큰은 쓰이는 곳에서 발급돼요. 측정값과 문서는 위에서, 특정 약은 그 약의 API 엔드포인트에서 만들 수 있어요.", - "tokenNamePlaceholder": "토큰 이름 (예: iPhone 단축어)", + "tokenMintMovedDescription": "토큰은 쓰이는 곳에서 발급돼요. 측정값, 운동, 문서는 위에서, 특정 약은 그 약의 API 엔드포인트에서 만들 수 있어요.", "tokenCreated": "토큰을 만들었어요 — 지금 복사하세요! 다시 보여주지 않아요.", "tokenCopy": "토큰 복사", "tokenCopied": "토큰을 클립보드에 복사했어요", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "내용 다시 선택", "reselectReason": "이 링크는 선택한 적 없는 범위를 제공하고 있어서 닫았어요. 새로 만들고 담을 내용을 골라 주세요.", "reselectAction": "새 링크 만들기", - "createDetail": "토큰은 만들 때 한 번만 보여줘요 — 그때 저장해 두세요. 복구할 수 없어요." + "createDetail": "토큰은 만들 때 한 번만 보여줘요 — 그때 저장해 두세요. 복구할 수 없어요.", + "activeDescription": "공유한 링크와 만료 시점, 열람 횟수를 보여줘요." }, "genderOther": "기타", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "원격 MCP 엔드포인트", "enableDescription": "MCP를 지원하는 어시스턴트(Claude.ai, ChatGPT)가 범위가 제한된 토큰으로 건강 데이터를 읽게 해요.", - "enabled": "켜짐", - "disabled": "꺼짐", "enableToggleLabel": "MCP 엔드포인트 켜기", "endpointLabel": "커넥터 URL", "connectDescription": "어시스턴트의 커스텀 커넥터 설정에 이 URL을 붙여 넣고, 아래 토큰으로 인증하거나 안내가 나오면 로그인하세요.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "어시스턴트의 접근을 즉시 끊고 갱신도 막아요. 다시 연결하려면 승인을 새로 받아야 해요.", "connectionRevokeFailed": "어시스턴트 연결을 해제하지 못했어요.", "connectionsDetail": "연결을 해지하면 갱신 권한까지 포함해 접근이 즉시 끊겨요.", - "tokensDetail": "토큰은 한 번만 보여줘요." + "tokensDetail": "토큰은 한 번만 보여줘요.", + "tokenNamePlaceholder": "이름 (예: Claude Desktop)" }, "strava": "Strava", "stravaDescription": "Strava 계정을 연결해 활동을 운동 기록으로 동기화해요.", @@ -7169,7 +7171,8 @@ "signInAgain": "다시 로그인한 후 한 번 더 시도하세요. 이 계정에는 여기서 확인할 비밀번호나 패스키가 없습니다.", "failed": "확인하지 못했습니다. 입력한 내용을 확인하고 다시 시도하세요." }, - "passwordTitle": "비밀번호" + "passwordTitle": "비밀번호", + "tokenNameLabel": "토큰 이름" }, "admin": { "title": "관리자", diff --git a/messages/pl.json b/messages/pl.json index 53ba3023f..e04ece9e0 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -6542,30 +6542,32 @@ "fitbitViewData": "Zobacz swój sen", "googleHealthViewData": "Zobacz swoje kroki", "apiTokens": "Tokeny API", - "apiTokensDescription": "Przeglądaj i unieważniaj tokeny API do zewnętrznego rejestrowania przyjęć leków.", + "apiTokensDescription": "Przeglądaj i unieważniaj tokeny do pomiarów, treningów, dokumentów i przyjęć leków.", "measurementsToken": { "title": "Tokeny pomiarów", "description": "Utwórz token, aby waga, zegarek lub automatyka domowa mogły dodawać pomiary.", "detail": "Token pokazujemy tylko raz.", "scopeNote": "Może wyłącznie dodawać nowe pomiary do Twojej dokumentacji — nie odczyta danych, niczego nie zmieni ani nie usunie i nie utworzy kolejnego tokenu. Pomiary są oznaczane jako pochodzące z urządzenia zewnętrznego, dzięki czemu później je rozpoznasz, i nadal możesz je poprawić.", - "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie." + "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie.", + "namePlaceholder": "Nazwa, np. Home Assistant" }, "workoutsToken": { "title": "Tokeny treningów", "description": "Utwórz token, aby mostek zegarka lub skrypt synchronizacji mogły dodawać Twoje treningi.", "detail": "Token pokazujemy tylko raz.", "scopeNote": "Może wyłącznie dodawać nowe treningi do Twojej dokumentacji. Nie odczyta danych, niczego nie zmieni ani nie usunie i nie utworzy kolejnego tokenu. Dodane przez niego treningi są oznaczane jako pochodzące z urządzenia zewnętrznego, a jeśli telefon zapisał tę samą sesję, widzisz zapis z telefonu.", - "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie." + "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie.", + "namePlaceholder": "Nazwa, np. Garmin" }, "documentsToken": { "title": "Tokeny dokumentów", "description": "Utwórz token, aby Paperless-ngx, Papra lub skrypt importu mogły dodawać dokumenty do Twojego archiwum.", "detail": "Token pokazujemy tylko raz.", "scopeNote": "Może wyłącznie dodawać nowe dokumenty do Twojego archiwum. Niczego nie wyświetli, nie otworzy, nie pobierze, nie zmieni ani nie usunie i nie utworzy kolejnego tokenu. Dowiaduje się tylko, czy plik został zapisany, a nie to, jak został opisany.", - "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie." + "createFailed": "Nie udało się utworzyć tokenu. Spróbuj ponownie.", + "namePlaceholder": "Nazwa, np. Paperless-ngx" }, - "tokenMintMovedDescription": "Tokeny wydajemy tam, gdzie działają: powyżej dla pomiarów i dokumentów albo w punkcie końcowym API danego leku dla tego jednego leku.", - "tokenNamePlaceholder": "Nazwa tokena (np. Skrót iPhone)", + "tokenMintMovedDescription": "Tokeny wydajemy tam, gdzie działają: powyżej dla pomiarów, treningów i dokumentów albo w punkcie końcowym API danego leku dla tego jednego leku.", "tokenCreated": "Token utworzony — skopiuj go teraz! Nie zostanie pokazany ponownie.", "tokenCopy": "Kopiuj token", "tokenCopied": "Token skopiowany do schowka", @@ -6757,7 +6759,8 @@ "statusNeedsReselect": "Wybierz zawartość ponownie", "reselectReason": "Ten link udostępniał zakres, którego nikt nie wybrał, więc został zamknięty. Utwórz nowy i wybierz jego zawartość.", "reselectAction": "Utwórz zamiennik", - "createDetail": "Token jest pokazywany tylko raz przy tworzeniu — zapisz go wtedy; nie można go odzyskać." + "createDetail": "Token jest pokazywany tylko raz przy tworzeniu — zapisz go wtedy; nie można go odzyskać.", + "activeDescription": "Udostępnione linki, termin ich wygaśnięcia i liczba otwarć." }, "genderOther": "Inna", "nightscout": "Nightscout", @@ -7019,8 +7022,6 @@ "mcp": { "enableTitle": "Zdalny punkt końcowy MCP", "enableDescription": "Zezwól asystentowi obsługującemu MCP (Claude.ai, ChatGPT) na odczyt danych zdrowotnych za pomocą ograniczonego tokenu.", - "enabled": "Włączony", - "disabled": "Wyłączony", "enableToggleLabel": "Włącz punkt końcowy MCP", "endpointLabel": "Adres URL łącznika", "connectDescription": "Wklej ten adres URL w konfiguracji własnego łącznika asystenta, a następnie autoryzuj za pomocą poniższego tokenu lub zaloguj się po wyświetleniu monitu.", @@ -7039,7 +7040,8 @@ "connectionRevokeDescription": "To natychmiast kończy dostęp asystenta i uniemożliwia odnawianie. Ponowne połączenie będzie wymagać nowej autoryzacji.", "connectionRevokeFailed": "Nie udało się rozłączyć asystenta.", "tokensDetail": "Token jest wyświetlany tylko raz.", - "connectionsDetail": "Cofnięcie połączenia natychmiast kończy dostęp, w tym możliwość odnawiania." + "connectionsDetail": "Cofnięcie połączenia natychmiast kończy dostęp, w tym możliwość odnawiania.", + "tokenNamePlaceholder": "Nazwa, np. Claude Desktop" }, "strava": "Strava", "stravaDescription": "Połącz konto Strava, aby synchronizować aktywności z historią treningów.", @@ -7169,7 +7171,8 @@ "signInAgain": "Zaloguj się ponownie, a potem spróbuj jeszcze raz. Twoje konto nie ma hasła ani klucza dostępu do potwierdzenia tutaj.", "failed": "To się nie udało. Sprawdź wprowadzone dane i spróbuj ponownie." }, - "passwordTitle": "Hasło" + "passwordTitle": "Hasło", + "tokenNameLabel": "Nazwa tokena" }, "admin": { "title": "Administracja", diff --git a/src/components/settings/api-section.tsx b/src/components/settings/api-section.tsx index c73749b12..fcd9016a3 100644 --- a/src/components/settings/api-section.tsx +++ b/src/components/settings/api-section.tsx @@ -91,6 +91,7 @@ function MeasurementTokensCard() { description: t("settings.measurementsToken.description"), detail: t("settings.measurementsToken.detail"), scopeNote: t("settings.measurementsToken.scopeNote"), + namePlaceholder: t("settings.measurementsToken.namePlaceholder"), createFailed: t("settings.measurementsToken.createFailed"), }} /> @@ -114,6 +115,7 @@ function WorkoutTokensCard() { description: t("settings.workoutsToken.description"), detail: t("settings.workoutsToken.detail"), scopeNote: t("settings.workoutsToken.scopeNote"), + namePlaceholder: t("settings.workoutsToken.namePlaceholder"), createFailed: t("settings.workoutsToken.createFailed"), }} /> @@ -137,6 +139,7 @@ function DocumentTokensCard() { description: t("settings.documentsToken.description"), detail: t("settings.documentsToken.detail"), scopeNote: t("settings.documentsToken.scopeNote"), + namePlaceholder: t("settings.documentsToken.namePlaceholder"), createFailed: t("settings.documentsToken.createFailed"), }} /> @@ -161,6 +164,7 @@ function IngestTokenCard({ description: string; detail: string; scopeNote: string; + namePlaceholder: string; createFailed: string; }; }) { @@ -234,16 +238,18 @@ function IngestTokenCard({ />
-

{copy.detail}

-

- {copy.scopeNote} + {/* "Shown once" and what the token can do are one statement about + the credential, so they read as one paragraph. */} +

+ {copy.detail} {copy.scopeNote}

setNewName(e.target.value)} - placeholder={t("settings.tokenNamePlaceholder")} + placeholder={copy.namePlaceholder} + aria-label={t("settings.tokenNameLabel")} maxLength={100} className="flex-1" /> diff --git a/src/components/settings/mcp-section.tsx b/src/components/settings/mcp-section.tsx index 75ec5efc9..d064be455 100644 --- a/src/components/settings/mcp-section.tsx +++ b/src/components/settings/mcp-section.tsx @@ -232,15 +232,6 @@ function McpEnableCard() { icon={Plug} title={t("settings.mcp.enableTitle")} description={t("settings.mcp.enableDescription")} - status={ - enabled ? ( - - {t("settings.mcp.enabled")} - - ) : ( - {t("settings.mcp.disabled")} - ) - } />
@@ -371,10 +362,12 @@ function McpTokensCard() { title={t("settings.mcp.tokensTitle")} description={t("settings.mcp.tokensDescription")} /> -

{t("settings.mcp.tokensDetail")}

-
-

{t("settings.mcp.scopeNote")}

+ {/* "Shown once" is part of the same statement as the scope note, so + it reads inside that paragraph rather than as a line of its own. */} +

+ {t("settings.mcp.tokensDetail")} {t("settings.mcp.scopeNote")} +

@@ -396,7 +389,8 @@ function McpTokensCard() { setNewName(e.target.value)} - placeholder={t("settings.tokenNamePlaceholder")} + placeholder={t("settings.mcp.tokenNamePlaceholder")} + aria-label={t("settings.tokenNameLabel")} maxLength={100} className="flex-1" /> diff --git a/src/components/settings/sharing-section.tsx b/src/components/settings/sharing-section.tsx index c39fe0b96..d3b82d1f1 100644 --- a/src/components/settings/sharing-section.tsx +++ b/src/components/settings/sharing-section.tsx @@ -23,7 +23,7 @@ */ import { useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { FileText, KeyRound, Link2, Trash2 } from "lucide-react"; +import { FileText, KeyRound, Link2, List, Trash2 } from "lucide-react"; import { AlertDialog, @@ -138,213 +138,227 @@ function ShareLinksCard() { [links], ); + // Two cards: making a link and the links already out are separate jobs, and + // a growing list under the form pushed the create action out of reach. return ( - - -

{t("settings.sharing.createDetail")}

+ <> + + +

{t("settings.sharing.createDetail")}

- + +
- {isError ? ( - // A read failure must not read as "no active links" on a clinical - // sharing surface — that is the §6 fall-through this card must avoid. - refetch()} /> - ) : isLoading ? ( -
- - -
- ) : ( - <> -
-

- {t("settings.sharing.activeTitle")} -

- {activeLinks.length === 0 ? ( - - ) : ( -
    - {activeLinks.map((link) => ( -
  • -
    -

    - {link.label} -

    -
    - - {t("settings.sharing.statusActive")} - - {link.protected && ( - - - {t("settings.sharing.protected")} - - )} - {link.documentCount > 0 && ( - - - {link.documentCount} - - )} -
    -
    -

    - - {t("settings.sharing.created")}: - {" "} - {formatDate(link.createdAt)} -

    -

    - - {t("settings.sharing.expires")}: - {" "} - {formatDateTime(link.expiresAt)} -

    -

    - - {t("settings.sharing.accessCount")}: - {" "} - {link.accessCount} - {link.lastAccessAt - ? ` · ${formatDateTime(link.lastAccessAt)}` - : ""} -

    - {/* §12 — a right-aligned row action, not a full-width - destructive strip stacked once per link (which reads as - an alarm wall on a list of shares). */} - - - - - - - - {t("settings.sharing.revoke")} - - - {t("settings.sharing.revokeDescription")} - - - - - {t("common.cancel")} - - revokeMutation.mutate(link.id)} - > - {t("settings.sharing.revoke")} - - - - -
  • - ))} -
- )} + + + {isError ? ( + // A read failure must not read as "no active links" on a clinical + // sharing surface — that is the §6 fall-through this card must avoid. + refetch()} /> + ) : isLoading ? ( +
+ +
- - {inactiveLinks.length > 0 && ( + ) : ( + <>
- - {showRevoked && ( -
    - {inactiveLinks.map((link) => ( + {activeLinks.length === 0 ? ( + + ) : ( +
      + {activeLinks.map((link) => (
    • {link.label}

      - - {link.needsReselection - ? t("settings.sharing.statusNeedsReselect") - : link.revokedAt - ? t("settings.sharing.statusRevoked") - : t("settings.sharing.statusExpired")} - -
      - {/* A link whose frozen scope predates the selection model. - It served a scope nobody chose, so it was closed; the - owner re-mints above with the label, window and expiry - still in front of them. */} - {link.needsReselection ? ( -
      -

      - {t("settings.sharing.reselectReason")} -

      - +
      + + {t("settings.sharing.statusActive")} + + {link.protected && ( + + + {t("settings.sharing.protected")} + + )} + {link.documentCount > 0 && ( + + + {link.documentCount} + + )}
      - ) : null} +
      +

      + + {t("settings.sharing.created")}: + {" "} + {formatDate(link.createdAt)} +

      +

      + + {t("settings.sharing.expires")}: + {" "} + {formatDateTime(link.expiresAt)} +

      {t("settings.sharing.accessCount")}: {" "} {link.accessCount} + {link.lastAccessAt + ? ` · ${formatDateTime(link.lastAccessAt)}` + : ""}

      + {/* §12 — a right-aligned row action, not a full-width + destructive strip stacked once per link (which reads as + an alarm wall on a list of shares). */} + + + + + + + + {t("settings.sharing.revoke")} + + + {t("settings.sharing.revokeDescription")} + + + + + {t("common.cancel")} + + revokeMutation.mutate(link.id)} + > + {t("settings.sharing.revoke")} + + + +
    • ))}
    )}
- )} - - )} -
+ + {inactiveLinks.length > 0 && ( +
+ + {showRevoked && ( +
    + {inactiveLinks.map((link) => ( +
  • +
    +

    + {link.label} +

    + + {link.needsReselection + ? t("settings.sharing.statusNeedsReselect") + : link.revokedAt + ? t("settings.sharing.statusRevoked") + : t("settings.sharing.statusExpired")} + +
    + {/* A link whose frozen scope predates the selection model. + It served a scope nobody chose, so it was closed; the + owner re-mints above with the label, window and expiry + still in front of them. */} + {link.needsReselection ? ( +
    +

    + {t("settings.sharing.reselectReason")} +

    + +
    + ) : null} +

    + + {t("settings.sharing.accessCount")}: + {" "} + {link.accessCount} +

    +
  • + ))} +
+ )} +
+ )} + + )} + + ); }