diff --git a/.github/workflows/weblate-update-pot.yml b/.github/workflows/weblate-update-pot.yml index 6d4db70d63..8402c76d1e 100644 --- a/.github/workflows/weblate-update-pot.yml +++ b/.github/workflows/weblate-update-pot.yml @@ -35,13 +35,11 @@ jobs: # TODO: use a shared script for this run: | cd agama/web - xgettext --default-domain=agama --output=- --language=C --keyword= \ - --keyword=_:1,1t --keyword=_:1c,2,2t --keyword=C_:1c,2 \ - --keyword=N_ --keyword=NC_:1c,2 --foreign-user \ - --copyright-holder="SuSE Linux Products GmbH, Nuernberg" \ + xgettext --default-domain=agama --output=agama.pot --language=JavaScript --keyword= \ + --keyword=_:1 --keyword=N_:1 --keyword=n_:1,2,3t --keyword=Nn_:1,2,3t \ + --foreign-user --copyright-holder="SuSE Linux Products GmbH, Nuernberg" \ --from-code=UTF-8 --add-comments=TRANSLATORS --sort-by-file \ - $(find . ! -name cockpit.js -name '*.js' -o ! -name '*.test.jsx' -name '*.jsx') | \ - sed '/^#/ s/, c-format//' > agama.pot + $(find . ! -name cockpit.js -name '*.js' -o ! -name '*.test.jsx' -name '*.jsx') msgfmt --statistics agama.pot - name: Validate the generated POT file diff --git a/web/src/components/core/About.jsx b/web/src/components/core/About.jsx index 65649a27ef..e4cf5efe3b 100644 --- a/web/src/components/core/About.jsx +++ b/web/src/components/core/About.jsx @@ -23,6 +23,9 @@ import React, { useState } from "react"; import { Button, Text } from "@patternfly/react-core"; import { Icon } from "~/components/layout"; import { Popup } from "~/components/core"; +import { _ } from "~/i18n"; + +import cockpit from "~/lib/cockpit"; export default function About() { const [isOpen, setIsOpen] = useState(false); @@ -37,23 +40,35 @@ export default function About() { icon={} onClick={open} > - About Agama + {_("About Agama")} - Agama is an experimental installer for (open)SUSE systems. It is - still under development so, please, do not use it in production environments. If you want - to give it a try, we recommend to use a virtual machine to prevent any possible data loss. + { + // TRANSLATORS: content of the "About" popup (1/2) + _(`Agama is an experimental installer for (open)SUSE systems. It +still under development so, please, do not use it in +production environments. If you want to give it a try, we +recommend to use a virtual machine to prevent any possible +data loss.`) + } - For more information, please visit the project's repository at https://github.com/openSUSE/Agama. + { + cockpit.format( + // TRANSLATORS: content of the "About" popup (2/2) + // $0 is replaced by the project URL + _("For more information, please visit the project's repository at $0."), + "https://github.com/openSUSE/agama" + ) + } - Close + {_("Close")} diff --git a/web/src/components/core/InstallButton.jsx b/web/src/components/core/InstallButton.jsx index 9dcc75cfc0..b996a884b6 100644 --- a/web/src/components/core/InstallButton.jsx +++ b/web/src/components/core/InstallButton.jsx @@ -26,6 +26,7 @@ import { Button } from "@patternfly/react-core"; import { useNavigate } from "react-router-dom"; import { If, Popup } from "~/components/core"; +import { _ } from "~/i18n"; const InstallConfirmationPopup = ({ hasIssues, onAccept, onClose }) => { const navigate = useNavigate(); @@ -41,29 +42,46 @@ const InstallConfirmationPopup = ({ hasIssues, onAccept, onClose }) => { return (

- There are some reported issues. Please, check before - proceeding with the installation. + { + // TRANSLATORS: the installer reports some errors, + // the beginning (1/3) + _("There are some reported issues. Please, check") + } + + { + // TRANSLATORS: the installer reports some errors, + // the end (3/3) + _("before proceeding with the installation.") + }

); }; return (
} />

- If you continue, partitions on your hard disk will be modified according to the provided - installation settings. + { _(`If you continue, partitions on your hard disk will be modified +according to the provided installation settings.`) }

- Please, cancel and check the settings if you are unsure. + {_("Please, cancel and check the settings if you are unsure.")}

- Continue + + {/* TRANSLATORS: button label */} + {_("Continue")} +
@@ -72,16 +90,19 @@ const InstallConfirmationPopup = ({ hasIssues, onAccept, onClose }) => { const CannotInstallPopup = ({ onClose }) => (

- Some problems were found when trying to start the installation. - Please, have a look to the reported errors and try again. + {_(`Some problems were found when trying to start the installation. +Please, have a look to the reported errors and try again.`)}

- Accept + + {/* TRANSLATORS: button label */} + {_("Accept")} +
); @@ -127,7 +148,8 @@ const InstallButton = ({ onClick }) => { return ( <> { isOpen && renderPopup(error, hasIssues, { onAccept: install, onClose: close }) } diff --git a/web/src/components/core/InstallationFinished.jsx b/web/src/components/core/InstallationFinished.jsx index c51f6cfce1..4e784665c5 100644 --- a/web/src/components/core/InstallationFinished.jsx +++ b/web/src/components/core/InstallationFinished.jsx @@ -31,12 +31,17 @@ import { import { Center, Icon, Title as SectionTitle, PageIcon, MainActions } from "~/components/layout"; import { useInstallerClient } from "~/context/installer"; +import { _ } from "~/i18n"; function InstallationFinished() { const client = useInstallerClient(); const [iguana, setIguana] = useState(false); const closingAction = () => client.manager.finishInstallation(); - const buttonCaption = iguana ? "Finish" : "Reboot"; + const buttonCaption = iguana + // TRANSLATORS: button label + ? _("Finish") + // TRANSLATORS: button label + : _("Reboot"); useEffect(() => { async function getIguana() { @@ -49,7 +54,7 @@ function InstallationFinished() { return (
- Installation Finished + {_("Installation Finished")} { isCollecting && @@ -102,7 +103,7 @@ const LogsButton = ({ ...props }) => { isInline isPlain variant="info" - title="The browser will run the logs download as soon as they are ready. Please, be patient." + title={_("The browser will run the logs download as soon as they are ready. Please, be patient.")} /> } { error && @@ -110,7 +111,7 @@ const LogsButton = ({ ...props }) => { isInline isPlain variant="warning" - title="Something went wrong while collecting logs. Please, try again." + title={_("Something went wrong while collecting logs. Please, try again.")} /> } ); diff --git a/web/src/components/core/PasswordAndConfirmationInput.jsx b/web/src/components/core/PasswordAndConfirmationInput.jsx index f3e1cb3d05..0358b902ba 100644 --- a/web/src/components/core/PasswordAndConfirmationInput.jsx +++ b/web/src/components/core/PasswordAndConfirmationInput.jsx @@ -24,6 +24,7 @@ import { FormGroup, TextInput } from "@patternfly/react-core"; +import { _ } from "~/i18n"; const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisabled, split = false }) => { const [confirmation, setConfirmation] = useState(value || ""); @@ -33,7 +34,7 @@ const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisable let newError = ""; if (password !== passwordConfirmation) { - newError = "Passwords do not match"; + newError = _("Passwords do not match"); } setError(newError); @@ -54,12 +55,12 @@ const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisable return (
- + @@ -76,7 +77,7 @@ const PasswordAndConfirmationInput = ({ value, onChange, onValidation, isDisable id="passwordConfirmation" name="passwordConfirmation" type="password" - aria-label="User password confirmation" + aria-label={_("User password confirmation")} value={confirmation} isDisabled={isDisabled} onChange={onChangeConfirmation} diff --git a/web/src/components/core/RowActions.jsx b/web/src/components/core/RowActions.jsx index b5d69c0450..1355167631 100644 --- a/web/src/components/core/RowActions.jsx +++ b/web/src/components/core/RowActions.jsx @@ -24,6 +24,7 @@ import { DropdownToggle } from "@patternfly/react-core"; import { ActionsColumn } from '@patternfly/react-table'; import { Icon } from '~/components/layout'; +import { _ } from "~/i18n"; /** * Renders icon for selecting the options of a row in a table @@ -58,7 +59,7 @@ export default function RowActions({ id, actions, "aria-label": toggleAriaLabel, const actionsToggle = (props) => ( ( <> diff --git a/web/src/components/core/ShowLogButton.jsx b/web/src/components/core/ShowLogButton.jsx index 979a91b0cd..0d2066bfb7 100644 --- a/web/src/components/core/ShowLogButton.jsx +++ b/web/src/components/core/ShowLogButton.jsx @@ -23,6 +23,7 @@ import React, { useState } from "react"; import { FileViewer } from "~/components/core"; import { Icon } from "~/components/layout"; import { Button } from "@patternfly/react-core"; +import { _ } from "~/i18n"; /** * Button for displaying the YaST logs @@ -42,12 +43,14 @@ const ShowLogButton = () => { isDisabled={isLogDisplayed} icon={} > - Show Logs + {/* TRANSLATORS: button label */} + {_("Show Logs")} { isLogDisplayed && } diff --git a/web/src/components/core/ShowTerminalButton.jsx b/web/src/components/core/ShowTerminalButton.jsx index 59df0a4eca..e6cea495ba 100644 --- a/web/src/components/core/ShowTerminalButton.jsx +++ b/web/src/components/core/ShowTerminalButton.jsx @@ -24,6 +24,7 @@ import { Button } from "@patternfly/react-core"; import { Terminal } from "~/components/core"; import { Icon } from "~/components/layout"; +import { _ } from "~/i18n"; /** * Button for displaying the terminal application @@ -43,7 +44,8 @@ const ShowTerminalButton = () => { isDisabled={isTermDisplayed} icon={} > - Open Terminal + {/* TRANSLATORS: button label */} + {_("Open Terminal")} { isTermDisplayed && diff --git a/web/src/components/core/Sidebar.jsx b/web/src/components/core/Sidebar.jsx index 4ae7bb418f..d51629b172 100644 --- a/web/src/components/core/Sidebar.jsx +++ b/web/src/components/core/Sidebar.jsx @@ -25,6 +25,7 @@ import { Icon, AppActions } from "~/components/layout"; import { If, NotificationMark } from "~/components/core"; import { useNotification } from "~/context/notification"; import useNodeSiblings from "~/hooks/useNodeSiblings"; +import { _ } from "~/i18n"; /** * Agama sidebar navigation @@ -129,13 +130,13 @@ export default function Sidebar ({ children }) { @@ -145,17 +146,20 @@ export default function Sidebar ({ children }) { id="global-options" ref={asideRef} className="wrapper sidebar" - aria-label="Global options" + aria-label={_("Global options")} data-state={isOpen ? "visible" : "hidden"} >
-

Options

+

+ {/* TRANSLATORS: sidebar header */} + {_("Options")} +

@@ -167,7 +171,9 @@ export default function Sidebar ({ children }) { diff --git a/web/src/components/core/Terminal.jsx b/web/src/components/core/Terminal.jsx index 42e648240f..c07e26ad2d 100644 --- a/web/src/components/core/Terminal.jsx +++ b/web/src/components/core/Terminal.jsx @@ -21,6 +21,7 @@ import React, { useState } from "react"; import { Popup } from "~/components/core"; +import { _ } from "~/i18n"; export default function Terminal({ onCloseCallback }) { // the popup is visible @@ -44,7 +45,7 @@ export default function Terminal({ onCloseCallback }) {