Skip to content

Commit

Permalink
feat: add taxonomy detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Oct 19, 2023
1 parent e70ea01 commit b27e35f
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 12 deletions.
19 changes: 13 additions & 6 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import CourseAuthoringRoutes from './CourseAuthoringRoutes';
import Head from './head/Head';
import { StudioHome } from './studio-home';
import CourseRerun from './course-rerun';
import { TaxonomyListPage } from './taxonomy';
import { TaxonomyDetailPage, TaxonomyListPage } from './taxonomy';

import 'react-datepicker/dist/react-datepicker.css';
import './index.scss';
Expand Down Expand Up @@ -71,11 +71,18 @@ const App = () => {
}}
/>
{process.env.ENABLE_TAGGING_TAXONOMY_PAGES === 'true' && (
<Route
path="/taxonomy-list"
>
<TaxonomyListPage />
</Route>
<>
<Route exact path="/taxonomy-list" component={TaxonomyListPage} />
<Route
path="/taxonomy-list/:taxonomyId"
render={({ match }) => {
const { params: { taxonomyId } } = match;
return (
<TaxonomyDetailPage taxonomyId={taxonomyId} />
);
}}
/>
</>
)}
</Switch>
</QueryClientProvider>
Expand Down
25 changes: 22 additions & 3 deletions src/taxonomy/api/hooks/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,35 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;
const getTaxonomyListApiUrl = new URL('api/content_tagging/v1/taxonomies/?enabled=true', getApiBaseUrl()).href;

/**
* @param {number} taxonomyId
*/
const getTaxonomyDetailApiUrl = (taxonomyId) => new URL(
`api/content_tagging/v1/taxonomies/${taxonomyId}/`,
getApiBaseUrl(),
).href;
/**
* @returns {import("../types.mjs").UseQueryResult}
*/
const useTaxonomyListData = () => (
useQuery({
queryKey: ['taxonomyList'],
queryFn: () => getAuthenticatedHttpClient().get(getTaxonomyListApiUrl)
.then(camelCaseObject),
.then(camelCaseObject).then(({ data }) => data),
})
);

/**
* @param {number} taxonomyId
* @returns {import('@tanstack/react-query').UseQueryResult<import('../types.mjs').TaxonomyData>}
*/
const useTaxonomyDetailData = (taxonomyId) => (
useQuery({
queryKey: ['taxonomyList', taxonomyId],
queryFn: () => getAuthenticatedHttpClient().get(getTaxonomyDetailApiUrl(taxonomyId))
.then(camelCaseObject)
.then((response) => response.data),
})
);

export default useTaxonomyListData;
export { useTaxonomyListData, useTaxonomyDetailData };
34 changes: 33 additions & 1 deletion src/taxonomy/api/hooks/selectors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-check
import useTaxonomyListData from './api';
import { useTaxonomyListData, useTaxonomyDetailData } from './api';

/**
* @returns {import("../types.mjs").TaxonomyListData | undefined}
Expand All @@ -18,3 +18,35 @@ export const useTaxonomyListDataResponse = () => {
export const useIsTaxonomyListDataLoaded = () => (
useTaxonomyListData().status === 'success'
);

/**
* @params {number} taxonomyId
* @returns {Pick<import('@tanstack/react-query').UseQueryResult, "error" | "isError" | "isFetched" | "isSuccess">}
*/
export const useTaxonomyDetailDataStatus = (taxonomyId) => {
const {
isError,
error,
isFetched,
isSuccess,
} = useTaxonomyDetailData(taxonomyId);
return {
isError,
error,
isFetched,
isSuccess,
};
};

/**
* @params {number} taxonomyId
* @returns {import("../types.mjs").TaxonomyData | undefined}
*/
export const useTaxonomyDetailDataResponse = (taxonomyId) => {
const { isSuccess, data } = useTaxonomyDetailData(taxonomyId);
if (isSuccess) {
return data;
}

return undefined;
};
2 changes: 1 addition & 1 deletion src/taxonomy/api/types.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-check

/**
/**
* @typedef {Object} TaxonomyData
* @property {number} id
* @property {string} name
Expand Down
2 changes: 1 addition & 1 deletion src/taxonomy/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as TaxonomyListPage } from './TaxonomyListPage';
export { TaxonomyDetailPage } from './taxonomy-detail';
89 changes: 89 additions & 0 deletions src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react';
import {
Container,
} from '@edx/paragon';
import Proptypes from 'prop-types';

import PermissionDeniedAlert from '../../generic/PermissionDeniedAlert';
import Loading from '../../generic/Loading';
import Header from '../../header';
import SubHeader from '../../generic/sub-header/SubHeader';
import { useTaxonomyDetailDataResponse, useTaxonomyDetailDataStatus } from '../api/hooks/selectors';


Check failure on line 13 in src/taxonomy/taxonomy-detail/TaxonomyDetailPage.jsx

View workflow job for this annotation

GitHub Actions / tests

More than 1 blank line not allowed
const TaxonomyDetailTemp = ({ taxonomyId }) => {
const useTaxonomyDetailData = () => {
const { isError, isFetched } = useTaxonomyDetailDataStatus(taxonomyId);
const taxonomy = useTaxonomyDetailDataResponse(taxonomyId);
return { isError, isFetched, taxonomy };
};

const { isError, isFetched, taxonomy } = useTaxonomyDetailData(taxonomyId);

if (isError) {
return (
<PermissionDeniedAlert />
);
}

if (!isFetched) {
return (
<Loading />
);
}

if (taxonomy) {
return (
<>
<div className="pt-4.5 pr-4.5 pl-4.5 pb-2 bg-light-100 box-shadow-down-2">
<Container size="xl">
<SubHeader
title={taxonomy.name}
hideBorder
/>
</Container>
</div>
<div className="bg-light-400 mt-1">
<Container size="xl">
{
taxonomy ? (
<div>
<pre>{JSON.stringify(taxonomy, null, 2)}</pre>
</div>
) : (<>Taxonomy not found</>)
}
</Container>
</div>
</>
);
}

return undefined;
};

const TaxonomyDetailPage = ({ taxonomyId }) => (
<>
<style>
{`
body {
background-color: #E9E6E4; /* light-400 */
}
`}
</style>
<Header isHiddenMainMenu />
<TaxonomyDetailTemp taxonomyId={taxonomyId} />
</>
);

TaxonomyDetailPage.propTypes = {
taxonomyId: Proptypes.number,
};

TaxonomyDetailPage.defaultProps = {
taxonomyId: undefined,
};

TaxonomyDetailTemp.propTypes = TaxonomyDetailPage.propTypes;
TaxonomyDetailTemp.defaultProps = TaxonomyDetailPage.defaultProps;

export default TaxonomyDetailPage;
2 changes: 2 additions & 0 deletions src/taxonomy/taxonomy-detail/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export { default as TaxonomyDetailPage } from './TaxonomyDetailPage';

0 comments on commit b27e35f

Please sign in to comment.