diff --git a/web/src/api/product/config.ts b/web/src/api/product/config.ts
new file mode 100644
index 0000000000..383cb9bc0b
--- /dev/null
+++ b/web/src/api/product/config.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) [2025] SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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.
+ */
+
+type Config = {
+ id?: string;
+};
+
+export type { Config };
diff --git a/web/src/api/software/proposal.ts b/web/src/api/software/proposal.ts
new file mode 100644
index 0000000000..02d92d008b
--- /dev/null
+++ b/web/src/api/software/proposal.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) [2025] SUSE LLC
+ *
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * 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 { PatternsSelection } from "~/types/software";
+
+type Proposal = {
+ size: string;
+ patterns: PatternsSelection;
+};
+
+export type { Proposal };
diff --git a/web/src/api/system.ts b/web/src/api/system.ts
index 7e9589c538..a90d8f0ab6 100644
--- a/web/src/api/system.ts
+++ b/web/src/api/system.ts
@@ -22,12 +22,13 @@
import * as l10n from "~/api/l10n/system";
import * as storage from "~/api/storage/system";
-import { Product } from "~/types/software";
+import { AddonInfo, Pattern, Product, Repository } from "~/types/software";
type System = {
l10n?: l10n.System;
storage?: storage.System;
products?: Product[];
+ software?: { addons: AddonInfo[]; patterns: Pattern[]; repositories: Repository[] };
};
export { l10n, storage };
diff --git a/web/src/components/overview/SoftwareSection.tsx b/web/src/components/overview/SoftwareSection.tsx
index 669951acf4..fb7e993371 100644
--- a/web/src/components/overview/SoftwareSection.tsx
+++ b/web/src/components/overview/SoftwareSection.tsx
@@ -22,21 +22,21 @@
import React from "react";
import { Content, List, ListItem } from "@patternfly/react-core";
-import { SelectedBy } from "~/types/software";
import { isEmpty } from "radashi";
import { _ } from "~/i18n";
import { useProposal, useSystem } from "~/hooks/api";
export default function SoftwareSection(): React.ReactNode {
- const { software: proposal } = useProposal({ suspense: true });
- const { patterns = [] } = useSystem();
+ const { software: available } = useSystem({ suspense: true });
+ const { software: proposed } = useProposal({ suspense: true });
- if (isEmpty(proposal.patterns)) return;
+ if (isEmpty(proposed.patterns)) return;
+ const selectedPatternsIds = Object.keys(proposed.patterns);
const TextWithoutList = () => {
return (
<>
- {_("The installation will take")} {proposal.size}
+ {_("The installation will take")} {proposed.size}
>
);
};
@@ -44,13 +44,13 @@ export default function SoftwareSection(): React.ReactNode {
const TextWithList = () => {
// TRANSLATORS: %s will be replaced with the installation size, example: "5GiB".
const [msg1, msg2] = _("The installation will take %s including:").split("%s");
- const selectedPatterns = patterns.filter((p) => p.selectedBy !== SelectedBy.NONE);
+ const selectedPatterns = available.patterns.filter((p) => selectedPatternsIds.includes(p.name));
return (
<>
{msg1}
- {proposal.size}
+ {proposed.size}
{msg2}
@@ -65,7 +65,7 @@ export default function SoftwareSection(): React.ReactNode {
return (
{_("Software")}
- {patterns.length ? : }
+ {selectedPatternsIds.length ? : }
);
}