Skip to content

Commit

Permalink
feat(web): allow displaying a product license
Browse files Browse the repository at this point in the history
Apart from displaying only available languages, still pending interface
improvements and unit tests.
  • Loading branch information
dgdavid committed Jan 17, 2025
1 parent e5eb11f commit 9046792
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 35 deletions.
17 changes: 16 additions & 1 deletion web/src/api/software.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2024] SUSE LLC
* Copyright (c) [2024-2025] SUSE LLC
*
* All Rights Reserved.
*
Expand All @@ -26,6 +26,8 @@ import {
SoftwareConfig,
RegistrationInfo,
SoftwareProposal,
License,
LicenseContent,
} from "~/types/software";
import { get, post, put } from "~/api/http";

Expand All @@ -44,6 +46,17 @@ const fetchProposal = (): Promise<SoftwareProposal> => get("/api/software/propos
*/
const fetchProducts = (): Promise<Product[]> => get("/api/software/products");

/**
* Returns the list of available licenses
*/
const fetchLicenses = (): Promise<License[]> => get("/api/software/licenses");

/**
* Returns the content for given license id
*/
const fetchLicense = (id: string, lang: string = "en"): Promise<LicenseContent> =>
get(`/api/software/licenses/${id}?lang=${lang}`);

/**
* Returns an object with the registration info
*/
Expand Down Expand Up @@ -72,6 +85,8 @@ export {
fetchPatterns,
fetchProposal,
fetchProducts,
fetchLicenses,
fetchLicense,
fetchRegistration,
updateConfig,
register,
Expand Down
78 changes: 44 additions & 34 deletions web/src/components/product/LicenseDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@
* find current contact information at www.suse.com.
*/

import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { Popup } from "~/components/core";
import { _ } from "~/i18n";
import {
Divider,
MenuToggle,
ModalProps,
Select,
Expand All @@ -35,51 +34,62 @@ import {
} from "@patternfly/react-core";
import { Product } from "~/types/software";
import { sprintf } from "sprintf-js";
import { fetchLicense } from "~/api/software";
import { useInstallerL10n } from "~/context/installerL10n";
import supportedLanguages from "~/languages.json";

function LicenseDialog({ onClose, product }: { onClose: ModalProps["onClose"]; product: Product }) {
const [locale, setLocale] = useState("en");
const [localeSelectorOpen, setLocaleSelectorOpen] = useState(false);
const locales = ["en", "es", "de", "cz", "pt"];
const { language: uiLanguage } = useInstallerL10n();
const [language, setLanguage] = useState<string>(uiLanguage);
const [license, setLicense] = useState<string>();
const [languageSelectorOpen, setLanguageSelectorOpen] = useState(false);
const localesToggler = (toggleRef) => (
<MenuToggle
ref={toggleRef}
onClick={() => setLocaleSelectorOpen(!localeSelectorOpen)}
isExpanded={localeSelectorOpen}
onClick={() => setLanguageSelectorOpen(!languageSelectorOpen)}
isExpanded={languageSelectorOpen}
>
{locale}
{supportedLanguages[language]}
</MenuToggle>
);

const onLocaleSelection = (_, locale: string) => {
setLocale(locale);
setLocaleSelectorOpen(false);
};
useEffect(() => {
language && fetchLicense(product.licenseId, language).then(({ body }) => setLicense(body));
}, [language, product.licenseId]);

const eula = "Lorem ipsum";
const onLocaleSelection = (_, lang: string) => {
setLanguage(lang);
setLanguageSelectorOpen(false);
};

return (
<Popup isOpen>
<Popup
isOpen
title={
<>
<Split>
<SplitItem isFilled>
<h1>{sprintf(_("License for %s"), product.name)}</h1>
</SplitItem>
<Select
isOpen={languageSelectorOpen}
selected={language}
onSelect={onLocaleSelection}
onOpenChange={(isOpen) => setLanguageSelectorOpen(!isOpen)}
toggle={localesToggler}
>
{Object.entries(supportedLanguages).map(([id, name]) => (
<SelectOption key={id} value={id}>
{name}
</SelectOption>
))}
</Select>
</Split>
</>
}
>
<Stack hasGutter>
<Split>
<SplitItem isFilled>
<h1>{sprintf(_("License for %s"), product.name)}</h1>
</SplitItem>
<Select
isOpen={localeSelectorOpen}
selected={locale}
onSelect={onLocaleSelection}
onOpenChange={(isOpen) => setLocaleSelectorOpen(!isOpen)}
toggle={localesToggler}
>
{locales.map((locale) => (
<SelectOption key={locale} value={locale}>
{locale}
</SelectOption>
))}
</Select>
</Split>
<Divider />
{eula}
<pre>{license}</pre>
</Stack>
<Popup.Actions>
<Popup.Confirm onClick={onClose}>{_("Close")}</Popup.Confirm>
Expand Down
21 changes: 21 additions & 0 deletions web/src/queries/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import React from "react";
import {
useMutation,
useQueries,
useQuery,
useQueryClient,
useSuspenseQueries,
useSuspenseQuery,
} from "@tanstack/react-query";
import { useInstallerClient } from "~/context/installer";
import {
License,
Pattern,
PatternsSelection,
Product,
Expand All @@ -40,6 +42,7 @@ import {
} from "~/types/software";
import {
fetchConfig,
fetchLicenses,
fetchPatterns,
fetchProducts,
fetchProposal,
Expand Down Expand Up @@ -75,6 +78,15 @@ const productsQuery = () => ({
staleTime: Infinity,
});

/**
* Query to retrieve available licenses
*/
const licensesQuery = () => ({
queryKey: ["software/licenses"],
queryFn: fetchLicenses,
staleTime: Infinity,
});

/**
* Query to retrieve selected product
*/
Expand Down Expand Up @@ -166,6 +178,14 @@ const useProduct = (
};
};

/**
* Returns available products and selected one, if any
*/
const useLicenses = (): { licenses: License[]; isPending: boolean } => {
const { data: licenses, isPending } = useQuery(licensesQuery());
return { licenses, isPending };
};

/**
* Returns a list of patterns with their selectedBy property properly set based on current proposal.
*/
Expand Down Expand Up @@ -261,6 +281,7 @@ export {
useConfigMutation,
usePatterns,
useProduct,
useLicenses,
useProductChanges,
useProposal,
useProposalChanges,
Expand Down
16 changes: 16 additions & 0 deletions web/src/types/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ type Product = {
licenseId?: string;
};

type License = {
/** License ID (e.g., "license.sle") */
id: string;
/** Available locales */
languages: string[];
};

type LicenseContent = {
/** License ID (e.g., "license.sle") */
id: string;
/** License body */
body: string;
};

type PatternsSelection = { [key: string]: SelectedBy };

type SoftwareProposal = {
Expand Down Expand Up @@ -90,6 +104,8 @@ export type {
Pattern,
PatternsSelection,
Product,
License,
LicenseContent,
SoftwareConfig,
RegistrationInfo,
SoftwareProposal,
Expand Down

0 comments on commit 9046792

Please sign in to comment.