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

web: Allow opening popups with "stable" size #1156

Merged
merged 5 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
14 changes: 0 additions & 14 deletions web/src/assets/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,6 @@
}
}

.auto-modal-popup {
block-size: auto;
}

.medium-modal-popup {
min-block-size: 55vh;
max-block-size: 55vh;
}

.large-modal-popup {
min-block-size: 85vh;
max-block-size: 85vh;
}

// *DataLists custom styles
li.pf-v5-c-data-list__item {
border-block-end-width: thin;
Expand Down
57 changes: 57 additions & 0 deletions web/src/assets/styles/utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,63 @@
--stack-gutter: 0;
}

.block-size-auto {
block-size: auto;
}


.inline-size-auto {
inline-size: auto;
}

.block-size-small,
.block-size-medium,
.block-size-large {
block-size: calc(100dvb - var(--space-large));
}

.inline-size-small,
.inline-size-medium,
.inline-size-large {
inline-size: calc(100dvi - var(--spacer-large));
}

@media (height > 500px) {
.block-size-small {
block-size: 30dvb;
}

.block-size-medium {
block-size: 60dvb;
}

.block-size-large {
block-size: 90dvb;
}
}

@media (width > 500px) {
.inline-size-small,
.inline-size-medium,
.inline-size-large {
min-inline-size: calc(500px - var(--spacer-large));
}

.inline-size-small {
inline-size: 30dvi;
}

.inline-size-medium {
inline-size: 60dvi;
max-inline-size: var(--ui-max-inline-size);
}

.inline-size-large {
inline-size: 90dvi;
max-inline-size: calc(var(--ui-max-inline-size) * 2);
}
}

.large {
/** block-size fallbacks **/
height: 95dvh;
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/core/FileViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export default function FileViewer({ file, title, onCloseCallback }) {
<Popup
isOpen={isOpen}
title={title || file}
className="large"
blockSize="large"
inlineSize="large"
>
{state === "loading" && <Loading text={_("Reading file...")} />}
{(content === null || error) &&
Expand Down
19 changes: 13 additions & 6 deletions web/src/components/core/Popup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,34 @@ const AncillaryAction = ({ children, ...actionsProps }) => (
* </Popup.Actions>
* </Popup>
*
* @param {ModalProps} props
* @typedef {object} PopupBaseProps
* @property {"auto" | "small" | "medium" | "large"} [blockSize="auto"] - The block/height size for the dialog. Default is "auto".
* @property {"auto" | "small" | "medium" | "large"} [inlineSize="medium"] - The inline/width size for the dialog. Default is "medium".
* @typedef {Omit<ModalProps, "variant" | "size"> & PopupBaseProps} PopupProps
*
* @param {PopupProps} props
*/
const Popup = ({
isOpen = false,
showClose = false,
variant = "small",
inlineSize = "medium",
blockSize = "auto",
className = "",
children,
...pfModalProps
...props
}) => {
const [actions, content] = partition(React.Children.toArray(children), child => child.type === Actions);

return (
/** @ts-ignore */
<Modal
{ ...pfModalProps }
{...props}
isOpen={isOpen}
showClose={showClose}
variant={variant}
actions={actions}
className={`${className} block-size-${blockSize} inline-size-${inlineSize}`.trim()}
>
{ content }
{content}
</Modal>
);
};
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/core/Terminal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ export default function Terminal({ onCloseCallback }) {
return (
<Popup
isOpen={isOpen}
className="large"
aria-label="terminal popup"
blockSize="large"
inlineSize="large"
>

<iframe className="vertically-centered" src="/cockpit/@localhost/system/terminal.html" />
Expand Down
6 changes: 3 additions & 3 deletions web/src/components/l10n/L10nPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const TimezonePopup = ({ onFinish = noop, onCancel = noop }) => {
isOpen
title={_("Select time zone")}
description={sprintf(_("%s will use the selected time zone."), selectedProduct.name)}
className="height-75"
blockSize="large"
>
<Form id="timezoneForm" onSubmit={onSubmit}>
<TimezoneSelector value={timezoneId} timezones={sortedTimezones} onChange={setTimezoneId} />
Expand Down Expand Up @@ -181,7 +181,7 @@ const LocalePopup = ({ onFinish = noop, onCancel = noop }) => {
isOpen
title={_("Select language")}
description={sprintf(_("%s will use the selected language."), selectedProduct.name)}
className="height-75"
blockSize="large"
>
<Form id="localeForm" onSubmit={onSubmit}>
<LocaleSelector value={localeId} locales={sortedLocales} onChange={setLocaleId} />
Expand Down Expand Up @@ -294,7 +294,7 @@ const KeymapPopup = ({ onFinish = noop, onCancel = noop }) => {
isOpen
title={_("Select keyboard")}
description={sprintf(_("%s will use the selected keyboard."), selectedProduct.name)}
className="height-75"
blockSize="large"
>
<Form id="keymapForm" onSubmit={onSubmit}>
<KeymapSelector value={keymapId} keymaps={sortedKeymaps} onChange={setKeymapId} />
Expand Down
6 changes: 5 additions & 1 deletion web/src/components/network/IpSettingsForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ export default function IpSettingsForm({ connection, onClose }) {
// TRANSLATORS: manual network configuration mode with a static IP address
// %s is replaced by the connection name
return (
<Popup isOpen title={sprintf(_("Edit %s"), connection.id)}>
<Popup
isOpen
title={sprintf(_("Edit %s"), connection.id)}
blockSize="medium"
>
{renderError("object")}
<Form id="edit-connection" onSubmit={onSubmit}>
<FormGroup fieldId="method" label={_("Mode")} isRequired>
Expand Down
6 changes: 5 additions & 1 deletion web/src/components/network/WifiSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ function WifiSelector({ isOpen = false, onClose }) {
});

return (
<Popup isOpen={isOpen} title={_("Connect to a Wi-Fi network")}>
<Popup
isOpen={isOpen}
title={_("Connect to a Wi-Fi network")}
blockSize="medium"
>
<WifiNetworksList
networks={networksFromValues(networks)}
hiddenNetwork={baseHiddenNetwork}
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/storage/DeviceSelectionDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ devices.").split(/[[\]]/);
<Popup
title={_("Device for installing the system")}
isOpen={isOpen}
variant="medium"
blockSize="large"
inlineSize="large"
{...props}
>
<Form id="target-form" onSubmit={onSubmit}>
Expand Down
10 changes: 6 additions & 4 deletions web/src/components/storage/ProposalActionsDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const ActionsList = ({ actions }) => {
* @param {object} props
* @param {object[]} [props.actions=[]] - The actions to perform in the system.
* @param {boolean} [props.isOpen=false] - Whether the dialog is visible or not.
* @param {function} props.onClose - Whether the dialog is visible or not.
* @param {() => void} props.onClose - Whether the dialog is visible or not.
*/
export default function ProposalActionsDialog({ actions = [], isOpen = false, onClose }) {
const [isExpanded, setIsExpanded] = useState(false);
Expand All @@ -68,14 +68,16 @@ export default function ProposalActionsDialog({ actions = [], isOpen = false, on
// TRANSLATORS: show/hide toggle action, this is a clickable link
: sprintf(n_("Show %d subvolume action", "Show %d subvolume actions", subvolActions.length), subvolActions.length);

const blockSize = actions.length < 15 ? "medium" : "large";

return (
<Popup
// TRANSLATORS: The storage "Planned Actions" section's title. The
// section shows a list of planned actions for the selected device, e.g.
// TRANSLATORS: The storage "Planned Actions" dialog's title. The
// dialog shows a list of planned actions for the selected device, e.g.
// "delete partition A", "create partition B with filesystem C", ...
title={_("Planned Actions")}
isOpen={isOpen}
variant="large"
blockSize={subvolActions.length === 0 ? "auto" : blockSize}
>
<ActionsList actions={generalActions} />
<If
Expand Down
3 changes: 2 additions & 1 deletion web/src/components/storage/SpacePolicyDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ in the devices listed below. Choose how to do it.");
title={_("Find space")}
description={description}
isOpen={isOpen}
variant="medium"
blockSize="medium"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use "large" for the blockSize here. In my system only two lines of the table are visible which is not enough to make sense out of the table.

not-enough

Sometimes there are several disks involved at the installation. Or maybe just one disk but with many partitions (bear in mind the list of partitions is expanded automatically when clicking on "custom"). In all those cases, a lot of information is not visible at first sight which makes it harder to understand how to use the whole thing.

If you think "large" is too much, maybe we can use an approach similar to the one in the list of actions, deciding the size based on the number of disks and partitions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think "large" is too much, maybe we can use an approach similar to the one in the list of actions, deciding the size based on the number of disks and partitions.

I prefer this option, but bearing in mind that it is not so straightforward and I expect more changes in this dialog in the short/mid term, let's go for blockSize="large" as you suggested.

Good catch, BTW.

inlineSize="large"
{...props}
>
<Form id="space-policy-form" onSubmit={onSubmit}>
Expand Down
12 changes: 8 additions & 4 deletions web/src/components/users/FirstUser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,14 @@ export default function FirstUser() {

return (
<>
{ isUserDefined ? <UserData user={user} actions={actions} /> : <UserNotDefined actionCb={openForm} /> }
{ /* TODO: Extract this form to a component, if possible */ }
{ isFormOpen &&
<Popup isOpen title={isEditing ? _("Edit user account") : _("Create user account")}>
{isUserDefined ? <UserData user={user} actions={actions} /> : <UserNotDefined actionCb={openForm} />}
{ /* TODO: Extract this form to a component, if possible */}
{isFormOpen &&
<Popup
isOpen
title={isEditing ? _("Edit user account") : _("Create user account")}
inlineSize="small"
>
<Form id="createUser" onSubmit={(e) => accept("createUser", e)}>
{ showErrors() &&
<Alert variant="warning" isInline title={_("Something went wrong")}>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/users/RootPasswordPopup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function RootPasswordPopup({
const onPasswordValidation = (isValid) => setIsValidPassword(isValid);

return (
<Popup title={title} isOpen={isOpen}>
<Popup title={title} isOpen={isOpen} inlineSize="small">
<Form id="root-password" onSubmit={accept}>
<PasswordAndConfirmationInput
value={password}
Expand Down
Loading