Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
21 changes: 21 additions & 0 deletions backend/companion/communityRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import express from 'express';
import cors from 'cors';

const router = express.Router();
router.use(express.json());
router.use(cors());

async function handleGetCommunityResource(req, res) {
const { link } = JSON.parse(req.body.toString());
try {
const response = await fetch(link);
const data = await response.text();
res.json(data);
} catch (error) {
res.status(500).json(`Failed to fetch community resource. ${error}`);
}
}

router.post('/resource', handleGetCommunityResource);

export default router;
3 changes: 3 additions & 0 deletions backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { handleTracking } from './tracking.js';
import jsyaml from 'js-yaml';
import { proxyHandler, proxyRateLimiter } from './proxy.js';
import companionRouter from './companion/companionRouter';
import communityRouter from './companion/communityRouter';
//import { requestLogger } from './utils/other'; //uncomment this to log the outgoing traffic

const express = require('express');
Expand Down Expand Up @@ -94,12 +95,14 @@ if (isDocker) {
// yup, order matters here
serveMonaco(app);
app.use('/backend/ai-chat', companionRouter);
app.use('/backend/community', communityRouter);
app.use('/backend', handleRequest);
serveStaticApp(app, '/', '/core-ui');
} else {
// Running in prod mode
handleTracking(app);
app.use('/backend/ai-chat', companionRouter);
app.use('/backend/community', communityRouter);
app.use('/backend', handleRequest);
}

Expand Down
3 changes: 2 additions & 1 deletion src/components/KymaModules/KymaModulesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function KymaModulesList({ namespaced }) {
installedCommunityModules,
communityModulesLoading,
setOpenedModuleIndex: setOpenedCommunityModuleIndex,
handleResourceDelete: handleCommunityModuleDelete,
} = useContext(CommunityModuleContext);

const [selectedEntry, setSelectedEntry] = useState(null);
Expand Down Expand Up @@ -94,7 +95,7 @@ export default function KymaModulesList({ namespaced }) {
modulesLoading={communityModulesLoading}
namespaced={namespaced}
setOpenedModuleIndex={setOpenedCommunityModuleIndex}
handleResourceDelete={handleResourceDelete}
handleResourceDelete={handleCommunityModuleDelete}
customSelectedEntry={selectedEntry}
setSelectedEntry={setSelectedEntry}
/>
Expand Down
44 changes: 33 additions & 11 deletions src/components/KymaModules/components/ModulesDeleteBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
fetchResourceCounts,
generateAssociatedResourcesUrls,
getAssociatedResources,
getCommunityResources,
getCRResource,
handleItemClick,
} from '../deleteModulesHelpers';
Expand All @@ -26,15 +27,17 @@
import { KymaResourceType, ModuleTemplateListType } from '../support';
import { SetterOrUpdater } from 'recoil';
import { ColumnLayoutState } from 'state/columnLayoutAtom';
import { usePost } from 'shared/hooks/BackendAPI/usePost';

type ModulesListDeleteBoxProps = {
DeleteMessageBox: React.FC<any>;
moduleTemplates: ModuleTemplateListType;
selectedModules: { name: string }[];
chosenModuleIndex: number | null;
kymaResource: KymaResourceType;
kymaResourceState: KymaResourceType;
kymaResource?: KymaResourceType;
kymaResourceState?: KymaResourceType;
detailsOpen: boolean;
isCommunity?: boolean;
setLayoutColumn: SetterOrUpdater<ColumnLayoutState>;
handleModuleUninstall: () => void;
setChosenModuleIndex: React.Dispatch<React.SetStateAction<number | null>>;
Expand All @@ -50,6 +53,7 @@
kymaResource,
kymaResourceState,
detailsOpen,
isCommunity,
setLayoutColumn,
handleModuleUninstall,
setChosenModuleIndex,
Expand All @@ -62,10 +66,12 @@
const { clusterUrl, namespaceUrl } = useUrl();
const deleteResourceMutation = useDelete();
const fetchFn = useSingleGet();
const post = usePost();

const [resourceCounts, setResourceCounts] = useState<Record<string, any>>({});
const [forceDeleteUrls, setForceDeleteUrls] = useState<string[]>([]);
const [crUrls, setCrUrls] = useState<string[]>([]);
const [communityUrls, setCommunityUrls] = useState<string[]>([]);

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-namespace-test

'setCommunityUrls' is assigned a value but never used

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-namespace-test

'communityUrls' is assigned a value but never used

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-lighthouse-test

'setCommunityUrls' is assigned a value but never used

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-lighthouse-test

'communityUrls' is assigned a value but never used

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-cluster-test

'setCommunityUrls' is assigned a value but never used

Check warning on line 74 in src/components/KymaModules/components/ModulesDeleteBox.tsx

View workflow job for this annotation

GitHub Actions / run-cluster-test

'communityUrls' is assigned a value but never used
const [allowForceDelete, setAllowForceDelete] = useState(false);
const [associatedResourceLeft, setAssociatedResourceLeft] = useState(false);

Expand Down Expand Up @@ -110,6 +116,19 @@
navigate,
);

if (isCommunity) {
const communityResources = await getCommunityResources(
chosenModuleIndex,
selectedModules,
kymaResource,
moduleTemplates,
post,
);
console.log('TEST-communityResources:', communityResources.flat());
// TODO: Get Community Urls.
// setCommunityUrls(communityUrl);
}

setResourceCounts(counts);
setForceDeleteUrls(urls);
setCrUrls(Array.isArray(crUrl) ? crUrl : [crUrl]);
Expand Down Expand Up @@ -236,15 +255,18 @@
if (chosenModuleIndex != null) {
selectedModules.splice(chosenModuleIndex, 1);
}
setKymaResourceState({
...kymaResource,
spec: {
...kymaResource.spec,
modules: selectedModules,
},
});
handleModuleUninstall();
setInitialUnchangedResource(cloneDeep(kymaResourceState));
if (!isCommunity && kymaResource) {
setKymaResourceState({
...kymaResource,
spec: {
...kymaResource.spec,
modules: selectedModules,
},
});
handleModuleUninstall();
setInitialUnchangedResource(cloneDeep(kymaResourceState));
}

if (detailsOpen) {
setLayoutColumn({
layout: 'OneColumn',
Expand Down
61 changes: 61 additions & 0 deletions src/components/KymaModules/deleteModulesHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
findModuleTemplate,
ModuleTemplateListType,
} from './support';
import jsyaml from 'js-yaml';
import { PostFn } from 'shared/hooks/BackendAPI/usePost';

interface Counts {
[key: string]: number;
Expand Down Expand Up @@ -72,6 +74,41 @@ export const getCRResource = (
return resource ? [resource] : [];
};

export const getCommunityResources = async (
chosenModuleIndex: number | null,
selectedModules: any,
kymaResource: any,
moduleTemplates: ModuleTemplateListType,
post: PostFn,
) => {
if (chosenModuleIndex == null) {
return [];
}
const selectedModule = selectedModules[chosenModuleIndex];
const moduleChannel = selectedModule?.channel || kymaResource?.spec?.channel;
const moduleVersion =
selectedModule?.version ||
findModuleStatus(kymaResource, selectedModule?.name)?.version;

const module = findModuleTemplate(
moduleTemplates,
selectedModule?.name,
moduleChannel,
moduleVersion,
);

const resources = (module?.spec as any)?.resources;
if (resources?.length) {
const test = resources.map(async (res: any) => {
if (res.link) {
return await postForCommunityResources(post, res.link);
}
});
return await Promise.all(test);
}
return [];
};

export const handleItemClick = async (
kind: string,
group: string,
Expand Down Expand Up @@ -235,3 +272,27 @@ export const deleteCrResources = async (
return 'Error while deleting Custom Resource';
}
};

export default async function postForCommunityResources(
post: PostFn,
link: string,
) {
if (!link) {
console.error('No link provided for community resource');
return false;
}

try {
const response = await post('/community/resource', { link });

if (response && typeof response === 'string') {
return jsyaml.loadAll(response);
}

console.error('Invalid response format:', response);
return false;
} catch (error) {
console.error('Error fetching data:', error);
return false;
}
}
68 changes: 59 additions & 9 deletions src/components/KymaModules/providers/CommunityModuleProvider.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { createContext, useContext, useEffect, useState } from 'react';
import { t } from 'i18next';
import { useGetInstalledModules } from '../hooks';
import { ModuleTemplatesContext } from './ModuleTemplatesProvider';
import { createPortal } from 'react-dom';
import { ModulesDeleteBox } from '../components/ModulesDeleteBox';
import { checkSelectedModule } from '../support';
import { Button } from '@ui5/webcomponents-react';

export const CommunityModuleContext = createContext({
setOpenedModuleIndex: () => {},
Expand All @@ -15,34 +20,79 @@ export function CommunityModuleContextProvider({
children,
layoutState,
showDeleteDialog,
DeleteMessageBox,
handleResourceDelete,
setLayoutColumn,
}) {
const [, setOpenedModuleIndex] = useState();
const [, setDetailsOpen] = useState(false);

useEffect(() => {
if (layoutState?.layout) {
setDetailsOpen(layoutState?.layout !== 'OneColumn');
}
}, [layoutState]);
const [openedModuleIndex, setOpenedModuleIndex] = useState();
const [detailsOpen, setDetailsOpen] = useState(false);

const { moduleTemplatesLoading, communityModuleTemplates } = useContext(
ModuleTemplatesContext,
);

const {
installed: installedCommunityModules,
loading: communityModulesLoading,
} = useGetInstalledModules(communityModuleTemplates, moduleTemplatesLoading);

useEffect(() => {
if (layoutState?.layout) {
setDetailsOpen(layoutState?.layout !== 'OneColumn');
}
}, [layoutState]);

const getOpenedModuleIndex = (moduleIndex, activeModules) => {
const index =
moduleIndex ??
// Find index of the selected module after a refresh or other case after which we have undefined.
activeModules?.findIndex(module =>
checkSelectedModule(module, layoutState),
);
return index > -1 ? index : undefined;
};

const deleteModuleButton = (
<div>
<Button onClick={() => handleResourceDelete({})} design="Transparent">
{t('common.buttons.delete-module')}
</Button>
</div>
);

return (
<CommunityModuleContext.Provider
value={{
setOpenedModuleIndex: setOpenedModuleIndex,
showDeleteDialog: showDeleteDialog,
installedCommunityModules: installedCommunityModules,
communityModulesLoading: communityModulesLoading,
DeleteMessageBox: DeleteMessageBox,
deleteModuleButton: deleteModuleButton,
handleResourceDelete: handleResourceDelete,
}}
>
{createPortal(
getOpenedModuleIndex(openedModuleIndex, installedCommunityModules) !==
undefined &&
!communityModulesLoading &&
!moduleTemplatesLoading &&
showDeleteDialog && (
<ModulesDeleteBox
DeleteMessageBox={DeleteMessageBox}
selectedModules={installedCommunityModules}
chosenModuleIndex={getOpenedModuleIndex(
openedModuleIndex,
installedCommunityModules,
)}
moduleTemplates={communityModuleTemplates}
detailsOpen={detailsOpen}
setChosenModuleIndex={setOpenedModuleIndex}
setLayoutColumn={setLayoutColumn}
isCommunity={true}
/>
),
document.body,
)}
{children}
</CommunityModuleContext.Provider>
);
Expand Down
Loading
Loading