Skip to content

Commit

Permalink
chore: support additional contents - catalog (#3215)
Browse files Browse the repository at this point in the history
* add content mapping - wip

Signed-off-by: at670475 <[email protected]>

* fix slint

Signed-off-by: at670475 <[email protected]>

* embed medium blogs

Signed-off-by: at670475 <[email protected]>

* remove config

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* add expandable icons

Signed-off-by: at670475 <[email protected]>

* wip - use cases work

Signed-off-by: at670475 <[email protected]>

* format cases

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* open new tab for links

Signed-off-by: at670475 <[email protected]>

* embed internal doc

Signed-off-by: at670475 <[email protected]>

* adjusting based on the design decision

Signed-off-by: at670475 <[email protected]>

* fix css

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* fix window size

Signed-off-by: at670475 <[email protected]>

* fix css

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* fix margin between videos

Signed-off-by: at670475 <[email protected]>

* revert back

Signed-off-by: at670475 <[email protected]>

* fix label name

Signed-off-by: at670475 <[email protected]>

* add check for title and description

Signed-off-by: at670475 <[email protected]>

* disable link

Signed-off-by: at670475 <[email protected]>

* add tests

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* clean up of codea nd tests

Signed-off-by: at670475 <[email protected]>

* clean up

Signed-off-by: at670475 <[email protected]>

* increase default counter

Signed-off-by: at670475 <[email protected]>

* revert back tests

Signed-off-by: at670475 <[email protected]>

* add margin to blogs

Signed-off-by: at670475 <[email protected]>

* fix button

Signed-off-by: at670475 <[email protected]>

* support zowe doc tutorials

Signed-off-by: at670475 <[email protected]>

* fix testa

Signed-off-by: at670475 <[email protected]>

* fix test

Signed-off-by: at670475 <[email protected]>

* increase coverage

Signed-off-by: at670475 <[email protected]>

* reduce complexity

Signed-off-by: at670475 <[email protected]>

* fix code smells

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* fix code smells

Signed-off-by: at670475 <[email protected]>

* fix code smell

Signed-off-by: at670475 <[email protected]>

* fix bug

Signed-off-by: at670475 <[email protected]>

* add tests

Signed-off-by: at670475 <[email protected]>

* fix bug

Signed-off-by: at670475 <[email protected]>

* add test

Signed-off-by: at670475 <[email protected]>

* fix test

Signed-off-by: at670475 <[email protected]>

* refactoring

Signed-off-by: at670475 <[email protected]>

* fix test

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* optymize

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* add tests

Signed-off-by: at670475 <[email protected]>

* fix test

Signed-off-by: at670475 <[email protected]>

* add test

Signed-off-by: at670475 <[email protected]>

* add tests

Signed-off-by: at670475 <[email protected]>

* fix

Signed-off-by: at670475 <[email protected]>

* fix issue with description

Signed-off-by: at670475 <[email protected]>

* add test

Signed-off-by: at670475 <[email protected]>

* add test

Signed-off-by: at670475 <[email protected]>

---------

Signed-off-by: at670475 <[email protected]>
(cherry picked from commit 2aac3b6)
Signed-off-by: achmelo <[email protected]>
  • Loading branch information
taban03 authored and achmelo committed Dec 14, 2023
1 parent 0bafb31 commit bd5a1ae
Show file tree
Hide file tree
Showing 15 changed files with 1,103 additions and 104 deletions.
18 changes: 16 additions & 2 deletions api-catalog-ui/frontend/src/components/DetailPage/DetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export default class DetailPage extends Component {
history,
currentTileId,
fetchNewTiles,
selectedService,
} = this.props;
let { tiles } = this.props;
const iconBack = <ChevronLeftIcon />;
Expand All @@ -102,7 +103,15 @@ export default class DetailPage extends Component {
}
const apiPortalEnabled = isAPIPortal();
const hasTiles = !fetchTilesError && tiles && tiles.length > 0;
const { useCasesCounter, tutorialsCounter, videosCounter } = countAdditionalContents(services);
const {
useCasesCounter,
tutorialsCounter,
videosCounter,
filteredUseCases,
filteredTutorials,
videos,
documentation,
} = countAdditionalContents(selectedService);
const onlySwaggerPresent = tutorialsCounter === 0 && videosCounter === 0 && useCasesCounter === 0;
const showSideBar = false;
if (
Expand Down Expand Up @@ -202,7 +211,7 @@ export default class DetailPage extends Component {
className="links"
onClick={(e) => this.handleLinkClick(e, '#tutorials-label')}
>
Tutorials ({tutorialsCounter})
TechDocs Resources ({tutorialsCounter})
</Link>
<Link
className="links"
Expand Down Expand Up @@ -236,9 +245,13 @@ export default class DetailPage extends Component {
render={() => (
<div className="tabs-swagger">
<ServiceTabContainer
videos={videos}
useCases={filteredUseCases}
tutorials={filteredTutorials}
videosCounter={videosCounter}
tutorialsCounter={tutorialsCounter}
useCasesCounter={useCasesCounter}
documentation={documentation}
tiles={tiles}
/>
</div>
Expand Down Expand Up @@ -271,4 +284,5 @@ DetailPage.propTypes = {
history: PropTypes.shape({
push: PropTypes.func.isRequired,
}).isRequired,
selectedService: PropTypes.object.isRequired,
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Copyright Contributors to the Zowe Project.
*/
import { shallow } from 'enzyme';
import { describe, expect, it, jest } from '@jest/globals';
import { describe, expect, it } from '@jest/globals';
import DetailPage from './DetailPage';

const tile = {
Expand Down Expand Up @@ -51,6 +51,10 @@ describe('>>> Detailed Page component tests', () => {
process.env.REACT_APP_API_PORTAL = false;
});

afterEach(() => {
jest.clearAllMocks();
});

it('should start epic on mount', () => {
const fetchTilesStart = jest.fn();
const fetchNewTiles = jest.fn();
Expand Down Expand Up @@ -252,9 +256,19 @@ describe('>>> Detailed Page component tests', () => {
process.env.REACT_APP_API_PORTAL = true;
const fetchTilesStart = jest.fn();
const fetchNewTiles = jest.fn();
tile.services[0].videos = ['video1', 'video2'];
tile.services[0].tutorials = ['tutorial1', 'tutorial2'];
tile.services[0].useCases = ['useCase1', 'useCase2'];
// eslint-disable-next-line global-require
const utils = require('../../utils/utilFunctions');
const spyOnCountAdditionalContents = jest.spyOn(utils, 'default');
spyOnCountAdditionalContents.mockImplementation(() => ({
useCasesCounter: 2,
tutorialsCounter: 2,
videosCounter: 2,
hasSwagger: true,
useCases: [],
tutorials: [],
videos: [],
documentation: '',
}));
const wrapper = shallow(
<DetailPage
tiles={[tile]}
Expand All @@ -268,6 +282,7 @@ describe('>>> Detailed Page component tests', () => {
/>
);
expect(wrapper.find('#right-resources-menu').exists()).toEqual(true);
spyOnCountAdditionalContents.mockRestore();
});

it('should click on the links', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const mapStateToProps = (state) => ({
fetchTilesError: state.tilesReducer.error,
selectedTile: state.selectedServiceReducer.selectedTile,
selectedServiceId: state.selectedServiceReducer.selectedService.serviceId,
selectedService: state.selectedServiceReducer.selectedService,
isLoading: loadingSelector(state),
currentTileId: state.tilesReducer.currentTileId,
});
Expand Down
110 changes: 110 additions & 0 deletions api-catalog-ui/frontend/src/components/ExtraContents/BlogContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*/
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import BlogTile from './BlogTile';

export default function BlogContainer({ user, url, title }) {
const rss2json = `https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fmedium.com%2Ffeed%2F%40${user}`;
const [myBlog, setMyBlog] = useState([]);

const fetchData = async () => {
try {
const res = await fetch(url);
const data = await res.text();

const parser = new DOMParser();
const doc = parser.parseFromString(data, 'text/html');
const divs = doc.querySelector('.linklist.relatedlinks');
if (divs) {
divs.parentNode.removeChild(divs);
}

let content = doc.querySelector('.shortdesc');
if (!content?.textContent) {
content = doc.querySelector('.p');
}
const tutorialTitle = doc.querySelector('h1.title');
const blogTitle = tutorialTitle?.textContent;
const blogContent = content?.textContent;

const blogData = {
content: blogContent,
description: blogContent,
title: blogTitle,
link: url,
};

setMyBlog(blogData);
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error fetching data:', error);
return null;
}
};

useEffect(() => {
const fetchDataEffect = async () => {
if (!url?.includes('medium.com') && !url?.includes('docs.zowe.org')) {
await fetchData();
} else if (url?.includes('docs.zowe.org')) {
const blogData = {
content: '',
description: `Tutorial from the Zowe documentation related to ${title}`,
title,
link: url,
};
setMyBlog(blogData);
} else {
try {
const res = await fetch(rss2json);
const data = await res.json();
setMyBlog(data);
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error fetching data:', error);
return null;
}
}
};

fetchDataEffect();
}, [rss2json]);

function displayBlogs() {
if (myBlog?.items) {
const correctBlog = myBlog.items.find((blog) => blog?.link.includes(url));
return correctBlog && <BlogTile blogData={correctBlog} />;
}
}
if (url?.includes('medium.com')) {
return (
<div data-testid="medium-blog-container" className="BlogsContainer">
{displayBlogs()}
</div>
);
}

return (
myBlog && (
<div data-testid="tech-blog-container" className="BlogsContainer">
<BlogTile blogData={myBlog} />
</div>
)
);
}

BlogContainer.propTypes = {
url: PropTypes.shape({
includes: PropTypes.func.isRequired,
}).isRequired,
user: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
};
Loading

0 comments on commit bd5a1ae

Please sign in to comment.