Skip to content

Commit

Permalink
web: Start adapting keymap selection
Browse files Browse the repository at this point in the history
  • Loading branch information
dgdavid committed May 16, 2024
1 parent 18dc8a6 commit 77876d9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 100 deletions.
100 changes: 100 additions & 0 deletions web/src/components/l10n/KeyboardSelection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) [2023-2024] SUSE LLC
*
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, contact SUSE LLC.
*
* To contact SUSE LLC about this file by physical or electronic mail, you may
* find current contact information at www.suse.com.
*/

import React, { useEffect, useState } from "react";
import {
Form, FormGroup,
Radio,
Stack,
Text
} from "@patternfly/react-core";
import { useNavigate } from "react-router-dom";
import { _ } from "~/i18n";
import { useL10n } from "~/context/l10n";
import { useInstallerClient } from "~/context/installer";
import { ListSearch, Page } from "~/components/core";
import textStyles from '@patternfly/react-styles/css/utilities/Text/text';

// TODO: Add documentation and typechecking
// TODO: Evaluate if worth it extracting the selector
export default function KeyboardSelection() {
const { l10n } = useInstallerClient();
const { keymaps, selectedKeymap: currentKeymap } = useL10n();
const [selected, setSelected] = useState(currentKeymap);
const [filteredKeymaps, setFilteredKeymaps] = useState(keymaps);
const navigate = useNavigate();

const sortedKeymaps = keymaps.sort((k1, k2) => k1.name > k2.name ? 1 : -1);
const searchHelp = _("Filter by language, territory or locale code");

useEffect(() => {
setFilteredKeymaps(sortedKeymaps);
}, [sortedKeymaps, setFilteredKeymaps]);

const onSubmit = async (e) => {
e.preventDefault();
const dataForm = new FormData(e.target);
const nextKeymapId = JSON.parse(dataForm.get("keymap"))?.id;

if (nextKeymapId !== currentKeymap?.id) {
await l10n.setKeymap(nextKeymapId);
}

navigate("..");
};

return (
<>
<Page.MainContent>
<Stack hasGutter>
<ListSearch placeholder={searchHelp} elements={keymaps} onChange={setFilteredKeymaps} />
<Form id="keymapSelection" onSubmit={onSubmit}>
<FormGroup isStack>
{filteredKeymaps.map((keymap) => (
<Radio
key={keymap.id}
name="keymap"
id={keymap.id}
onChange={() => setSelected(keymap)}
label={
<>
<span className={`${textStyles.fontSizeLg}`}>
<b>{keymap.name}</b>
</span> <Text component="small">{keymap.id}</Text>
</>
}
value={JSON.stringify(keymap)}
checked={keymap === selected}
/>
))}
</FormGroup>
</Form>
</Stack>
</Page.MainContent>
<Page.NextActions>
<Page.CancelAction />
<Page.Action type="submit" form="keymapSelection">
{_("Select")}
</Page.Action>
</Page.NextActions>
</>
);
}
108 changes: 8 additions & 100 deletions web/src/components/l10n/L10nPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { sprintf } from "sprintf-js";
import { useInstallerClient } from "~/context/installer";
import { _ } from "~/i18n";
import { If, Popup, Section } from "~/components/core";
import { KeymapSelector, TimezoneSelector } from "~/components/l10n";
import { TimezoneSelector } from "~/components/l10n";
import { noop } from "~/utils";
import { useL10n } from "~/context/l10n";
import { useProduct } from "~/context/product";
Expand Down Expand Up @@ -166,113 +166,21 @@ const LocaleSection = () => {
);
};

/**
* Popup for selecting a keymap.
* @component
*
* @param {object} props
* @param {function} props.onFinish - Callback to be called when the keymap is correctly selected.
* @param {function} props.onCancel - Callback to be called when the keymap selection is canceled.
*/
const KeymapPopup = ({ onFinish = noop, onCancel = noop }) => {
const { l10n } = useInstallerClient();
const { keymaps, selectedKeymap } = useL10n();
const { selectedProduct } = useProduct();
const [keymapId, setKeymapId] = useState(selectedKeymap?.id);

const sortedKeymaps = keymaps.sort((k1, k2) => k1.name > k2.name ? 1 : -1);

const onSubmit = async (e) => {
e.preventDefault();

if (keymapId !== selectedKeymap?.id) {
await l10n.setKeymap(keymapId);
}

onFinish();
};

return (
<Popup
isOpen
title={_("Select keyboard")}
description={sprintf(_("%s will use the selected keyboard."), selectedProduct.name)}
blockSize="large"
>
<Form id="keymapForm" onSubmit={onSubmit}>
<KeymapSelector value={keymapId} keymaps={sortedKeymaps} onChange={setKeymapId} />
</Form>
<Popup.Actions>
<Popup.Confirm form="keymapForm" type="submit">
{_("Accept")}
</Popup.Confirm>
<Popup.Cancel onClick={onCancel} />
</Popup.Actions>
</Popup>
);
};

/**
* Button for opening the selection of keymaps.
* @component
*
* @param {object} props
* @param {React.ReactNode} props.children - Button children.
*/
const KeymapButton = ({ children }) => {
const [isPopupOpen, setIsPopupOpen] = useState(false);

const openPopup = () => setIsPopupOpen(true);
const closePopup = () => setIsPopupOpen(false);

return (
<>
<Button
variant="link"
className="p-0"
onClick={openPopup}
>
{children}
</Button>

<If
condition={isPopupOpen}
then={
<KeymapPopup
isOpen
onFinish={closePopup}
onCancel={closePopup}
/>
}
/>
</>
);
};

/**
* Section for configuring keymaps.
* @component
*/
const KeymapSection = () => {
const { selectedKeymap } = useL10n();
const { keymap } = useL10n();

return (
<Section title={_("Keyboard")} icon="keyboard">
<If
condition={selectedKeymap}
then={
<>
<p>{selectedKeymap?.name}</p>
<KeymapButton>{_("Change keyboard")}</KeymapButton>
</>
}
else={
<>
<p>{_("Keyboard not selected yet")}</p>
<KeymapButton>{_("Select keyboard")}</KeymapButton>
</>
}
/>
<p>
{keymap ? keymap.name : _("Keyboard not selected yet")}
</p>
<Link to="keymap/select">
{keymap ? _("Change keyboard") : _("Select keyboard")}
</Link>
</Section>
);
};
Expand Down
1 change: 1 addition & 0 deletions web/src/components/l10n/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export { default as InstallerLocaleSwitcher } from "./InstallerLocaleSwitcher";
export { default as KeymapSelector } from "./KeymapSelector";
export { default as L10nPage } from "./L10nPage";
export { default as LocaleSelection } from "./LocaleSelection";
export { default as KeymapSelection } from "./KeyboardSelection";
export { default as TimezoneSelector } from "./TimezoneSelector";

0 comments on commit 77876d9

Please sign in to comment.