diff --git a/dashboard/src/components/DeploymentForm/DeploymentForm.test.tsx b/dashboard/src/components/DeploymentForm/DeploymentForm.test.tsx index 848c9d44271..d3ade4d0151 100644 --- a/dashboard/src/components/DeploymentForm/DeploymentForm.test.tsx +++ b/dashboard/src/components/DeploymentForm/DeploymentForm.test.tsx @@ -22,6 +22,8 @@ const defaultProps = { pkgName: "foo", cluster: "default", namespace: "default", + packageCluster: "default", + packageNamespace: "kubeapps", releaseName: "my-release", version: "0.0.1", plugin: { name: "my.plugin", version: "0.0.1" } as Plugin, @@ -37,9 +39,9 @@ const defaultSelectedPkg = { values: "bar: foo", }; -const routePathParam = `/c/${defaultProps.cluster}/ns/${defaultProps.namespace}/apps/new/${defaultProps.plugin.name}/${defaultProps.plugin.version}/${defaultProps.pkgName}/versions/${defaultProps.version}`; +const routePathParam = `/c/${defaultProps.cluster}/ns/${defaultProps.namespace}/apps/new/${defaultProps.plugin.name}/${defaultProps.plugin.version}/${defaultProps.packageCluster}/${defaultProps.packageNamespace}/${defaultProps.pkgName}/versions/${defaultProps.version}`; const routePath = - "/c/:cluster/ns/:namespace/apps/new/:pluginName/:pluginVersion/:packageId/versions/:packageVersion"; + "/c/:cluster/ns/:namespace/apps/new/:pluginName/:pluginVersion/:packageCluster/:packageNamespace/:packageId/versions/:packageVersion"; const history = createMemoryHistory({ initialEntries: [routePathParam] }); let spyOnUseDispatch: jest.SpyInstance; @@ -74,7 +76,7 @@ it("fetches the available versions", () => { expect(fetchAvailablePackageVersions).toHaveBeenCalledWith( { - context: { cluster: defaultProps.cluster, namespace: defaultProps.namespace }, + context: { cluster: defaultProps.packageCluster, namespace: defaultProps.packageNamespace }, identifier: defaultProps.pkgName, plugin: defaultProps.plugin, } as AvailablePackageReference, @@ -244,7 +246,7 @@ describe("renders an error", () => { ); expect(history.location.pathname).toBe( - "/c/default/ns/default/apps/new/my.plugin/0.0.1/foo/versions/0.0.1", + `/c/${defaultProps.cluster}/ns/${defaultProps.namespace}/apps/new/my.plugin/0.0.1/${defaultProps.packageCluster}/${defaultProps.packageNamespace}/foo/versions/0.0.1`, ); }); }); diff --git a/dashboard/src/components/DeploymentForm/DeploymentForm.tsx b/dashboard/src/components/DeploymentForm/DeploymentForm.tsx index 3bc83038c51..211bd745aa9 100644 --- a/dashboard/src/components/DeploymentForm/DeploymentForm.tsx +++ b/dashboard/src/components/DeploymentForm/DeploymentForm.tsx @@ -21,9 +21,10 @@ import LoadingWrapper from "../LoadingWrapper/LoadingWrapper"; interface IRouteParams { cluster: string; namespace: string; - global: string; pluginName: string; pluginVersion: string; + packageCluster: string; + packageNamespace: string; packageId: string; packageVersion?: string; } @@ -33,14 +34,14 @@ export default function DeploymentForm() { const { cluster: targetCluster, namespace: targetNamespace, - global, packageId, pluginName, pluginVersion, + packageCluster, + packageNamespace, packageVersion, } = ReactRouter.useParams() as IRouteParams; const { - config, packages: { isFetching: packagesIsFetching, selected: selectedPackage }, apps, } = useSelector((state: IStoreState) => state); @@ -54,13 +55,10 @@ export default function DeploymentForm() { const [pluginObj] = useState({ name: pluginName, version: pluginVersion } as Plugin); - // Use the cluster/namespace from the URL unless it comes from a "global" repository. - // In that case, use the cluster/namespace from where kubeapps has been installed on - const isGlobal = global === "global"; const [packageReference] = useState({ context: { - cluster: isGlobal ? config.kubeappsCluster : targetCluster, - namespace: isGlobal ? config.kubeappsNamespace : targetNamespace, + cluster: packageCluster, + namespace: packageNamespace, }, plugin: pluginObj, identifier: packageId, @@ -130,14 +128,7 @@ export default function DeploymentForm() { const selectVersion = (e: React.ChangeEvent) => { dispatch( push( - url.app.apps.new( - targetCluster, - targetNamespace, - pluginObj, - packageId, - e.currentTarget.value, - isGlobal, - ), + url.app.apps.new(targetCluster, targetNamespace, packageReference, e.currentTarget.value), ), ); }; diff --git a/dashboard/src/components/PackageHeader/PackageView.tsx b/dashboard/src/components/PackageHeader/PackageView.tsx index ce8c34b6e3a..4236ea4a60d 100644 --- a/dashboard/src/components/PackageHeader/PackageView.tsx +++ b/dashboard/src/components/PackageHeader/PackageView.tsx @@ -45,29 +45,26 @@ export default function PackageView() { packageVersion, } = ReactRouter.useParams() as IRouteParams; const { - config, packages: { isFetching, selected: selectedPackage }, } = useSelector((state: IStoreState) => state); const [pluginObj] = useState({ name: pluginName, version: pluginVersion } as Plugin); - - const isGlobal = - packageCluster === config.kubeappsCluster && packageNamespace === config.kubeappsNamespace; + const [packageReference] = useState({ + context: { + cluster: packageCluster, + namespace: packageNamespace, + }, + plugin: pluginObj, + identifier: packageId, + } as AvailablePackageReference); // Fetch the selected/latest version on the initial load useEffect(() => { dispatch( - actions.packages.fetchAndSelectAvailablePackageDetail( - { - context: { cluster: packageCluster, namespace: packageNamespace }, - plugin: pluginObj, - identifier: packageId, - } as AvailablePackageReference, - packageVersion, - ), + actions.packages.fetchAndSelectAvailablePackageDetail(packageReference, packageVersion), ); return () => {}; - }, [dispatch, packageId, packageNamespace, packageCluster, packageVersion, pluginObj]); + }, [dispatch, packageReference, packageVersion]); // Fetch all versions useEffect(() => { @@ -114,10 +111,8 @@ export default function PackageView() { to={app.apps.new( targetCluster, targetNamespace, - pluginObj, - packageId, + packageReference, selectedPackage.pkgVersion, - isGlobal, )} > @@ -141,10 +136,8 @@ export default function PackageView() { to={app.apps.new( targetCluster, targetNamespace, - pluginObj, - packageId, + packageReference, selectedPackage.pkgVersion, - isGlobal, )} > diff --git a/dashboard/src/containers/RoutesContainer/Routes.tsx b/dashboard/src/containers/RoutesContainer/Routes.tsx index 00088421052..b62f89c1f28 100644 --- a/dashboard/src/containers/RoutesContainer/Routes.tsx +++ b/dashboard/src/containers/RoutesContainer/Routes.tsx @@ -29,9 +29,7 @@ const privateRoutes = { "/c/:cluster/ns/:namespace/apps/:pluginName/:pluginVersion/:releaseName/upgrade": AppUpgrade, "/c/:cluster/ns/:namespace/apps/:pluginName/:pluginVersion/:releaseName/upgrade/:version": AppUpgrade, - "/c/:cluster/ns/:namespace/apps/new/:pluginName/:pluginVersion/:packageId/versions/:packageVersion": - DeploymentForm, - "/c/:cluster/ns/:namespace/apps/new-from-:global(global)/:pluginName/:pluginVersion/:packageId/versions/:packageVersion": + "/c/:cluster/ns/:namespace/apps/new/:pluginName/:pluginVersion/:packageCluster/:packageNamespace/:packageId/versions/:packageVersion": DeploymentForm, "/c/:cluster/ns/:namespace/catalog": Catalog, "/c/:cluster/ns/:namespace/packages/:pluginName/:pluginVersion/:packageCluster/:packageNamespace/:packageId": diff --git a/dashboard/src/shared/url.ts b/dashboard/src/shared/url.ts index b774de76f8d..50fb8729230 100644 --- a/dashboard/src/shared/url.ts +++ b/dashboard/src/shared/url.ts @@ -2,22 +2,26 @@ import { AvailablePackageReference, InstalledPackageReference, } from "gen/kubeappsapis/core/packages/v1alpha1/packages"; -import { Plugin } from "gen/kubeappsapis/core/plugins/v1alpha1/plugins"; export const app = { apps: { new: ( cluster: string, namespace: string, - plugin: Plugin, - packageId: string, + availablePackageReference: AvailablePackageReference, version: string, - isGlobal: boolean, ) => { - const globalSegment = isGlobal ? "new-from-global" : "new"; - return `/c/${cluster}/ns/${namespace}/apps/${globalSegment}/${plugin?.name}/${ - plugin?.version - }/${encodeURIComponent(packageId)}/versions/${version}`; + const pkgPluginName = availablePackageReference?.plugin?.name; + const pkgPluginVersion = availablePackageReference?.plugin?.version; + const pkgId = availablePackageReference?.identifier || ""; + // Some plugins may not be cluster-aware nor support multi-cluster, so + // if the returned available package ref doesn't set cluster, use the current + // one. + const pkgCluster = availablePackageReference?.context?.cluster || cluster; + const pkgNamespace = availablePackageReference?.context?.namespace; + return `/c/${cluster}/ns/${namespace}/apps/new/${pkgPluginName}/${pkgPluginVersion}/${pkgCluster}/${pkgNamespace}/${encodeURIComponent( + pkgId, + )}/versions/${version}`; }, list: (cluster?: string, namespace?: string) => `/c/${cluster}/ns/${namespace}/apps`, get: (installedPackageReference: InstalledPackageReference) => {