Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: translate storage component when UI language changes #1644

Merged
merged 2 commits into from
Sep 27, 2024
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
6 changes: 6 additions & 0 deletions web/package/agama-web-ui.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri Sep 27 13:00:05 UTC 2024 - Imobach Gonzalez Sosa <[email protected]>

- Properly translate the storage interface when switching
the language of the UI (gh#agama-project/agama#1629).

-------------------------------------------------------------------
Fri Sep 20 11:42:25 UTC 2024 - Imobach Gonzalez Sosa <[email protected]>

Expand Down
23 changes: 10 additions & 13 deletions web/src/components/storage/EncryptionField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,18 @@ import { EncryptionMethods } from "~/types/storage";
import { _ } from "~/i18n";
import { noop } from "~/utils";

// Field texts at root level to avoid redefinitions every time the component
// is rendered.
const LABEL = _("Encryption");
const DESCRIPTION = _(
"Protection for the information stored at \
the device, including data, programs, and system files.",
);
const VALUES = {
const encryptionMethods = () => ({
disabled: _("disabled"),
[EncryptionMethods.LUKS2]: _("enabled"),
[EncryptionMethods.TPM]: _("using TPM unlocking"),
};
});

const Value = ({ isLoading, isEnabled, method }) => {
const values = encryptionMethods();
if (isLoading) return <Skeleton fontSize="sm" width="75%" />;
if (isEnabled) return VALUES[method];
if (isEnabled) return values[method];

return VALUES.disabled;
return values.disabled;
};

const Action = ({ isEnabled, isLoading, onClick }) => {
Expand Down Expand Up @@ -107,9 +101,12 @@ export default function EncryptionField({

return (
<Page.Section
title={LABEL}
title={_("Encryption")}
value={<Value isLoading={isLoading} isEnabled={isEnabled} method={method} />}
description={DESCRIPTION}
description={_(
"Protection for the information stored at \
the device, including data, programs, and system files.",
)}
pfCardBodyProps={{ isFilled: true }}
actions={<Action isEnabled={isEnabled} isLoading={isLoading} onClick={openDialog} />}
>
Expand Down
38 changes: 19 additions & 19 deletions web/src/components/storage/EncryptionSettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,6 @@ import { _ } from "~/i18n";
import { PasswordAndConfirmationInput, Popup } from "~/components/core";
import { EncryptionMethods } from "~/client/storage";

const DIALOG_TITLE = _("Encryption");
const DIALOG_DESCRIPTION = _(
"Full Disk Encryption (FDE) allows to protect the information stored \
at the device, including data, programs, and system files.",
);
// TRANSLATORS: "Trusted Platform Module" is the name of the technology and TPM its abbreviation
const TPM_LABEL = _("Use the Trusted Platform Module (TPM) to decrypt automatically on each boot");
// TRANSLATORS: The word 'directly' is key here. For example, booting to the installer media and then choosing
// 'Boot from Hard Disk' from there will not work. Keep it sort (this is a hint in a form) but keep it clear.
const TPM_EXPLANATION = _(
"The password will not be needed to boot and access the data if the \
TPM can verify the integrity of the system. TPM sealing requires the new system to be booted \
directly on its first run.",
);

export type EncryptionSetting = {
password: string;
method?: string;
Expand Down Expand Up @@ -114,12 +99,27 @@ export default function EncryptionSettingsDialog({
}
};

// TRANSLATORS: "Trusted Platform Module" is the name of the technology and TPM its abbreviation
const tpm_label = _(
"Use the Trusted Platform Module (TPM) to decrypt automatically on each boot",
);
// TRANSLATORS: The word 'directly' is key here. For example, booting to the installer media and then choosing
// 'Boot from Hard Disk' from there will not work. Keep it sort (this is a hint in a form) but keep it clear.
const tpm_explanation = _(
"The password will not be needed to boot and access the data if the \
TPM can verify the integrity of the system. TPM sealing requires the new system to be booted \
directly on its first run.",
);

const tpmAvailable = methods.includes(EncryptionMethods.TPM);

return (
<Popup
title={DIALOG_TITLE}
description={DIALOG_DESCRIPTION}
title={_("Encryption")}
description={_(
"Full Disk Encryption (FDE) allows to protect the information stored \
at the device, including data, programs, and system files.",
)}
isOpen={isOpen}
isLoading={isLoading}
>
Expand All @@ -140,8 +140,8 @@ export default function EncryptionSettingsDialog({
{tpmAvailable && (
<Checkbox
id="tpm_encryption_method"
label={TPM_LABEL}
description={TPM_EXPLANATION}
label={tpm_label}
description={tpm_explanation}
isChecked={method === EncryptionMethods.TPM}
isDisabled={!isEnabled}
onChange={changeMethod}
Expand Down
11 changes: 5 additions & 6 deletions web/src/components/storage/InstallationDeviceField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ import { deviceLabel } from "~/components/storage/utils";
import { sprintf } from "sprintf-js";
import { _ } from "~/i18n";

const LABEL = _("Installation device");
// TRANSLATORS: The storage "Installation device" field's description.
const DESCRIPTION = _("Main disk or LVM Volume Group for installation.");

/**
* Generates the target value.
*/
Expand Down Expand Up @@ -94,10 +90,13 @@ export default function InstallationDeviceField({
if (isLoading || !target) value = <Skeleton fontSize="sm" width="75%" />;
else value = targetValue(target, targetDevice, targetPVDevices);

// TRANSLATORS: The storage "Installation device" field's description.
const description = _("Main disk or LVM Volume Group for installation.");

return (
<Page.Section
title={LABEL}
description={DESCRIPTION}
title={_("Installation device")}
description={description}
actions={
isLoading ? (
<Skeleton fontSize="sm" width="100px" />
Expand Down
19 changes: 10 additions & 9 deletions web/src/components/storage/SnapshotsField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ import { hasFS } from "~/components/storage/utils";
import textStyles from "@patternfly/react-styles/css/utilities/Text/text";
import { Volume } from "~/types/storage";

const LABEL = _("Use Btrfs snapshots for the root file system");
const DESCRIPTION = _(
"Allows to boot to a previous version of the \
system after configuration changes or software upgrades.",
);

export type SnapshotsFieldProps = {
rootVolume: Volume;
onChange?: (config: SnapshotsConfig) => void;
Expand All @@ -51,6 +45,8 @@ export type SnapshotsConfig = {
export default function SnapshotsField({ rootVolume, onChange }: SnapshotsFieldProps) {
const isChecked = hasFS(rootVolume, "Btrfs") && rootVolume.snapshots;

const label = _("Use Btrfs snapshots for the root file system");

const switchState = () => {
if (onChange) onChange({ active: !isChecked });
};
Expand All @@ -59,14 +55,19 @@ export default function SnapshotsField({ rootVolume, onChange }: SnapshotsFieldP
<Split hasGutter>
<Switch
id="snapshots"
aria-label={LABEL}
aria-label={label}
isChecked={isChecked}
onChange={switchState}
hasCheckIcon
/>
<div>
<div>{LABEL}</div>
<div className={textStyles.color_200}>{DESCRIPTION}</div>
<div>{label}</div>
<div className={textStyles.color_200}>
{_(
"Allows to boot to a previous version of the \
system after configuration changes or software upgrades.",
)}
</div>
</div>
</Split>
);
Expand Down
14 changes: 7 additions & 7 deletions web/src/components/storage/VolumeLocationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ import { sprintf } from "sprintf-js";
import { deviceChildren, volumeLabel } from "~/components/storage/utils";
import { StorageDevice, Volume, VolumeTarget } from "~/types/storage";

// TRANSLATORS: Description of the dialog for changing the location of a file system.
const DIALOG_DESCRIPTION = _(
"The file systems are allocated at the installation device by \
default. Indicate a custom location to create the file system at a specific device.",
);

const defaultTarget: (device: StorageDevice | undefined) => VolumeTarget = (
device,
): VolumeTarget => {
Expand Down Expand Up @@ -130,12 +124,18 @@ export default function VolumeLocationDialog({

if (!targetDevice) return null;

// TRANSLATORS: Description of the dialog for changing the location of a file system.
const dialogDescription = _(
"The file systems are allocated at the installation device by \
default. Indicate a custom location to create the file system at a specific device.",
);

return (
<Popup
// TRANSLATORS: Title of the dialog for changing the location of a file system. %s is replaced
// by a mount path (e.g., /home).
title={sprintf(_("Location for %s file system"), volumeLabel(volume))}
description={DIALOG_DESCRIPTION}
description={dialogDescription}
inlineSize="large"
blockSize="large"
isOpen={isOpen}
Expand Down
Loading