Skip to content

Commit

Permalink
Parse new 'hidden_screen' configuration file options
Browse files Browse the repository at this point in the history
Previously we would be using the ISO variant (Boos, Live) from Anaconda configuration
file and we would conditionalize the page visibility in the Web UI code
according to that.
With this commit, the pages can be hidden per-new option of the
configuration file [1].

[1] rhinstaller/anaconda#6047
  • Loading branch information
KKoukiou committed Dec 23, 2024
1 parent 4ac75ad commit 4cff6c5
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 44 deletions.
28 changes: 25 additions & 3 deletions src/components/AnacondaPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,24 @@
* You should have received a copy of the GNU Lesser General Public License
* along with This program; If not, see <http://www.gnu.org/licenses/>.
*/
import React, { cloneElement, useEffect, useRef, useState } from "react";
import cockpit from "cockpit";

import React, { cloneElement, useContext, useEffect, useRef, useState } from "react";
import { Alert, Stack, Title } from "@patternfly/react-core";

export const AnacondaPage = ({ children, isFormDisabled, setIsFormDisabled, step, title, usePageInit }) => {
import { OsReleaseContext } from "./Common.jsx";

const _ = cockpit.gettext;

export const AnacondaPage = ({
children,
isFirstScreen,
isFormDisabled,
setIsFormDisabled,
step,
title,
usePageInit,
}) => {
const [stepNotification, setStepNotification] = useState();
const [showPage, setShowPage] = useState(!isFormDisabled);
const showPageRef = useRef(showPage);
Expand All @@ -43,9 +57,11 @@ export const AnacondaPage = ({ children, isFormDisabled, setIsFormDisabled, step
return null;
}

const titleElem = isFirstScreen ? <InitialPageTitle /> : title;

return (
<Stack hasGutter>
{title && <Title headingLevel="h2">{title}</Title>}
{titleElem && <Title headingLevel="h2">{titleElem}</Title>}
{stepNotification?.step === step &&
<Alert
id={step + "-step-notification"}
Expand All @@ -57,3 +73,9 @@ export const AnacondaPage = ({ children, isFormDisabled, setIsFormDisabled, step
</Stack>
);
};

const InitialPageTitle = () => {
const osRelease = useContext(OsReleaseContext);

return cockpit.format(_("Welcome. Let's install $0 now."), osRelease.REDHAT_SUPPORT_PRODUCT);
};
8 changes: 5 additions & 3 deletions src/components/AnacondaWizard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {

import { AnacondaPage } from "./AnacondaPage.jsx";
import { AnacondaWizardFooter } from "./AnacondaWizardFooter.jsx";
import { FooterContext, StorageContext, SystemTypeContext } from "./Common.jsx";
import { FooterContext, StorageContext, SystemTypeContext, UserInterfaceContext } from "./Common.jsx";
import { getSteps } from "./steps.js";

export const AnacondaWizard = ({ currentStepId, dispatch, isFetching, onCritFail, showStorage }) => {
Expand All @@ -41,6 +41,7 @@ export const AnacondaWizard = ({ currentStepId, dispatch, isFetching, onCritFail
const [isFormValid, setIsFormValid] = useState(false);
const { storageScenarioId } = useContext(StorageContext);
const isBootIso = useContext(SystemTypeContext) === "BOOT_ISO";
const userInterfaceConfig = useContext(UserInterfaceContext);
const { path } = usePageLocation();

const componentProps = {
Expand All @@ -52,7 +53,7 @@ export const AnacondaWizard = ({ currentStepId, dispatch, isFetching, onCritFail
showStorage,
};

const stepsOrder = getSteps(isBootIso, storageScenarioId);
const stepsOrder = getSteps(userInterfaceConfig, isBootIso, storageScenarioId);
const firstStepId = stepsOrder.filter(s => !s.isHidden)[0].id;

const createSteps = (stepsOrder, componentProps) => {
Expand All @@ -75,8 +76,9 @@ export const AnacondaWizard = ({ currentStepId, dispatch, isFetching, onCritFail
setIsFormDisabled={setIsFormDisabled}
step={s.id}
title={s.title}
isFirstScreen={s.isFirstScreen}
usePageInit={s.usePageInit}>
<s.component {...componentProps} />
<s.component {...componentProps} isFirstScreen={s.isFirstScreen} />
</AnacondaPage>
),
...stepProps
Expand Down
5 changes: 4 additions & 1 deletion src/components/Common.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const StorageDefaultsContext = createContext(null);
export const SystemTypeContext = createContext(null);
export const TargetSystemRootContext = createContext(null);
export const UsersContext = createContext(null);
export const UserInterfaceContext = createContext(null);
export const NetworkContext = createContext(null);
export const DialogsContext = createContext(null);

Expand Down Expand Up @@ -74,7 +75,9 @@ const SystemInfoContextWrapper = ({ children, conf, osRelease }) => {
<SystemTypeContext.Provider value={systemType}>
<StorageDefaultsContext.Provider value={{ defaultScheme }}>
<TargetSystemRootContext.Provider value={conf["Installation Target"].system_root}>
{children}
<UserInterfaceContext.Provider value={conf["User Interface"]}>
{children}
</UserInterfaceContext.Provider>
</TargetSystemRootContext.Provider>
</StorageDefaultsContext.Provider>
</SystemTypeContext.Provider>
Expand Down
11 changes: 2 additions & 9 deletions src/components/localization/InstallationLanguage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
setLangCookie
} from "../../helpers/language.js";

import { LanguageContext, OsReleaseContext } from "../Common.jsx";
import { LanguageContext } from "../Common.jsx";

import "./InstallationLanguage.scss";

Expand Down Expand Up @@ -326,17 +326,10 @@ const InstallationLanguage = ({ idPrefix, setIsFormValid, setStepNotification })
);
};

const PageTitle = () => {
const osRelease = useContext(OsReleaseContext);
return cockpit.format(_("Welcome to $0"), osRelease.NAME);
};

export class Page {
constructor (isBootIso) {
constructor () {
this.component = InstallationLanguage;
this.id = "installation-language";
this.isHidden = !isBootIso;
this.label = _("Welcome");
this.title = <PageTitle />;
}
}
13 changes: 7 additions & 6 deletions src/components/review/ReviewConfiguration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
import { getDeviceChildren } from "../../helpers/storage.js";

import { AnacondaWizardFooter } from "../AnacondaWizardFooter.jsx";
import { LanguageContext, OsReleaseContext, StorageContext, SystemTypeContext, UsersContext } from "../Common.jsx";
import { LanguageContext, OsReleaseContext, StorageContext, SystemTypeContext, UserInterfaceContext, UsersContext } from "../Common.jsx";
import { useOriginalDevices, usePlannedActions } from "../storage/Common.jsx";
import { useScenario } from "../storage/InstallationScenario.jsx";
import { ReviewDescriptionListItem } from "./Common.jsx";
Expand Down Expand Up @@ -63,6 +63,8 @@ const ReviewConfiguration = ({ setIsFormValid }) => {
const localizationData = useContext(LanguageContext);
const accounts = useContext(UsersContext);
const { label: scenarioLabel } = useScenario();
const userInterfaceConfig = useContext(UserInterfaceContext);
const hiddenScreens = userInterfaceConfig.hidden_screens || [];
const isBootIso = useContext(SystemTypeContext) === "BOOT_ISO";

// Display custom footer
Expand Down Expand Up @@ -101,19 +103,18 @@ const ReviewConfiguration = ({ setIsFormValid }) => {
description={language ? language["native-name"].v : localizationData.language}
/>
</ReviewDescriptionList>
{isBootIso &&
<>
{!hiddenScreens.includes("accounts") &&
<ReviewDescriptionList>
<ReviewDescriptionListItem
id={`${idPrefix}-target-system-account`}
term={_("Account")}
description={accounts.fullName ? `${accounts.fullName} (${accounts.userName})` : accounts.userName}
/>
</ReviewDescriptionList>
</ReviewDescriptionList>}
{isBootIso &&
<ReviewDescriptionList>
<HostnameRow />
</ReviewDescriptionList>
</>}
</ReviewDescriptionList>}
</ReviewDescriptionList>
</FlexItem>
<FlexItem>
Expand Down
32 changes: 30 additions & 2 deletions src/components/steps.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import cockpit from "cockpit";

import { debug } from "../helpers/log.js";

import { Page as PageProgress } from "./installation/InstallationProgress.jsx";
import { Page as PageInstallationLanguage } from "./localization/InstallationLanguage.jsx";
import { Page as PageReviewConfiguration } from "./review/ReviewConfiguration.jsx";
Expand All @@ -10,8 +12,9 @@ import { Page as PageAccounts } from "./users/Accounts.jsx";

const _ = cockpit.gettext;

export const getSteps = (...args) => {
export const getSteps = (userInterfaceConfig, ...args) => {
const mountPointMappingStep = new PageMountPointMapping(...args);
const hiddenScreens = userInterfaceConfig.hidden_screens || [];
const stepsOrder = [
new PageInstallationLanguage(...args),
new PageInstallationMethod(...args),
Expand All @@ -26,5 +29,30 @@ export const getSteps = (...args) => {
new PageReviewConfiguration(...args),
new PageProgress(...args),
];
return stepsOrder;

/* Screens can be hidden in two ways:
* 1. Dynamically: Controlled by the 'Page.isHidden' method in individual components,
* e.g., see 'MountPointMapping.jsx'.
* 2. Statically: Configured via the 'hidden_screens' key in the 'anaconda.conf'
* For example, the 'Account Creation' screen is hidden in the 'Workstation' ISO
* because this step is handled by the 'Gnome Initial Setup' tool during the first boot.
*/
return stepsOrder
.filter(s => {
const isHidden = hiddenScreens.includes(s.id);

if (isHidden) {
debug(
`Screen '${s.id}' will not be displayed because it is hidden by the Anaconda configuration file.`
);
}

return !isHidden;
})
.map((s, i) => {
if (i === 0) {
s.isFirstScreen = true;
}
return s;
});
};
6 changes: 3 additions & 3 deletions src/components/storage/InstallationDestination.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import { checkIfArraysAreEqual } from "../../helpers/utils.js";

import { EmptyStatePanel } from "cockpit-components-empty-state.jsx";

import { StorageContext, SystemTypeContext } from "../Common.jsx";
import { StorageContext } from "../Common.jsx";
import { useOriginalDevices, useOriginalExistingSystems } from "./Common.jsx";

import "./InstallationDestination.scss";
Expand Down Expand Up @@ -236,11 +236,11 @@ const rescanDisks = (setIsRescanningDisks, dispatch, errorHandler) => {
export const InstallationDestination = ({
dispatch,
idPrefix,
isFirstScreen,
onCritFail,
setIsFormValid,
}) => {
const refUsableDisks = useRef();
const isBootIso = useContext(SystemTypeContext) === "BOOT_ISO";
const { diskSelection } = useContext(StorageContext);
const devices = useOriginalDevices();

Expand Down Expand Up @@ -275,7 +275,7 @@ export const InstallationDestination = ({
setIsFormValid(selectedDisksCnt > 0);
}, [selectedDisksCnt, setIsFormValid]);

const headingLevel = isBootIso ? "h2" : "h3";
const headingLevel = isFirstScreen ? "h3" : "h2";

return (
<FormSection
Expand Down
13 changes: 4 additions & 9 deletions src/components/storage/InstallationMethod.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import { AnacondaWizardFooter } from "../AnacondaWizardFooter.jsx";
import {
DialogsContext,
FooterContext,
OsReleaseContext,
StorageContext,
StorageDefaultsContext,
} from "../Common.jsx";
Expand All @@ -49,6 +48,7 @@ const InstallationMethod = ({
dispatch,
idPrefix,
isEfi,
isFirstScreen,
isFormDisabled,
onCritFail,
setIsFormDisabled,
Expand Down Expand Up @@ -78,6 +78,7 @@ const InstallationMethod = ({
isEfi={isEfi}
dispatch={dispatch}
idPrefix={idPrefix}
isFirstScreen={isFirstScreen}
isFormDisabled={isFormDisabled}
setIsFormValid={setIsFormValid}
setIsFormDisabled={setIsFormDisabled}
Expand All @@ -87,6 +88,7 @@ const InstallationMethod = ({
<InstallationScenario
dispatch={dispatch}
idPrefix={idPrefix}
isFirstScreen={isFirstScreen}
isFormDisabled={isFormDisabled}
onCritFail={onCritFail}
setIsFormValid={setIsFormValid}
Expand Down Expand Up @@ -219,18 +221,11 @@ const usePageInit = () => {
}, [needsReset, setIsFormDisabled]);
};

const PageTitle = () => {
const osRelease = useContext(OsReleaseContext);

return cockpit.format(_("Welcome. Let's install $0 now."), osRelease.REDHAT_SUPPORT_PRODUCT);
};

export class Page {
constructor (isBootIso) {
constructor () {
this.component = InstallationMethod;
this.id = "installation-method";
this.label = _("Installation method");
this.title = !isBootIso ? <PageTitle /> : null;
this.usePageInit = usePageInit;
}
}
5 changes: 2 additions & 3 deletions src/components/storage/InstallationScenario.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import {
DialogsContext,
StorageContext,
StorageDefaultsContext,
SystemTypeContext
} from "../Common.jsx";
import { StorageReview } from "../review/StorageReview.jsx";
import {
Expand Down Expand Up @@ -514,12 +513,12 @@ const InstallationScenarioSelector = ({
export const InstallationScenario = ({
dispatch,
idPrefix,
isFirstScreen,
isFormDisabled,
setIsFormValid,
showStorage,
}) => {
const isBootIso = useContext(SystemTypeContext) === "BOOT_ISO";
const headingLevel = isBootIso ? "h2" : "h3";
const headingLevel = isFirstScreen ? "h3" : "h2";
const { diskSelection, storageScenarioId } = useContext(StorageContext);
const devices = useOriginalDevices();

Expand Down
4 changes: 1 addition & 3 deletions src/components/users/Accounts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,9 @@ const CustomFooter = () => {
};

export class Page {
constructor (isBootIso) {
constructor () {
this.component = Accounts;
this.id = "accounts";
this.isHidden = !isBootIso;
this.label = _("Create Account");
this.title = null;
}
}
2 changes: 1 addition & 1 deletion test/check-language
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class TestLanguage(VirtInstallMachineCase):
i.open()

# Expect the default language - this is en at this point - adjust the test when better guess is implemented
b.wait_in_text("h2", "Welcome to Fedora Linux")
b.wait_in_text("h2", "Welcome. Let's install Fedora now.")

l.check_selected_locale("en_US")

Expand Down
1 change: 1 addition & 0 deletions test/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def pretend_live_iso(test, installer):
installer.steps.hidden_steps.extend([installer.steps.ACCOUNTS, installer.steps.WELCOME])
test.restore_file('/run/anaconda/anaconda.conf')
test.machine.execute("sed -i 's/type = BOOT_ISO/type = LIVE_OS/g' /run/anaconda/anaconda.conf")
test.machine.execute("sed -i '/[anaconda]/a hidden_screens = installation-language accounts' /run/anaconda/anaconda.conf")

def pretend_default_scheme(test, scheme):
test.restore_file('/run/anaconda/anaconda.conf')
Expand Down

0 comments on commit 4cff6c5

Please sign in to comment.