feat: Show published components on content picker (#1420)
* feat: Show published components on content picker --------- Co-authored-by: Braden MacDonald <braden@opencraft.com>
This commit is contained in:
@@ -148,6 +148,7 @@ const LibraryAuthoringPage = ({ returnToLibrarySelection }: LibraryAuthoringPage
|
||||
libraryData,
|
||||
isLoadingLibraryData,
|
||||
componentPickerMode,
|
||||
showOnlyPublished,
|
||||
sidebarComponentInfo,
|
||||
openInfoSidebar,
|
||||
} = useLibraryContext();
|
||||
@@ -212,6 +213,11 @@ const LibraryAuthoringPage = ({ returnToLibrarySelection }: LibraryAuthoringPage
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
const extraFilter = [`context_key = "${libraryId}"`];
|
||||
if (showOnlyPublished) {
|
||||
extraFilter.push('last_published IS NOT NULL');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="d-flex">
|
||||
<div className="flex-grow-1">
|
||||
@@ -230,7 +236,7 @@ const LibraryAuthoringPage = ({ returnToLibrarySelection }: LibraryAuthoringPage
|
||||
)}
|
||||
<Container className="px-4 mt-4 mb-5 library-authoring-page">
|
||||
<SearchContextProvider
|
||||
extraFilter={`context_key = "${libraryId}"`}
|
||||
extraFilter={extraFilter}
|
||||
>
|
||||
<SubHeader
|
||||
title={<SubHeaderTitle title={libraryData.title} />}
|
||||
|
||||
@@ -56,11 +56,21 @@ const RecentlyModified: React.FC<Record<never, never>> = () => {
|
||||
};
|
||||
|
||||
const LibraryRecentlyModified: React.FC<Record<never, never>> = () => {
|
||||
const { libraryId } = useLibraryContext();
|
||||
const { libraryId, showOnlyPublished } = useLibraryContext();
|
||||
|
||||
const extraFilter = [`context_key = "${libraryId}"`];
|
||||
if (showOnlyPublished) {
|
||||
extraFilter.push('last_published IS NOT NULL');
|
||||
}
|
||||
|
||||
return (
|
||||
<SearchContextProvider
|
||||
extraFilter={`context_key = "${libraryId}"`}
|
||||
overrideSearchSortOrder={SearchSortOption.RECENTLY_MODIFIED}
|
||||
extraFilter={extraFilter}
|
||||
overrideSearchSortOrder={
|
||||
showOnlyPublished
|
||||
? SearchSortOption.RECENTLY_PUBLISHED
|
||||
: SearchSortOption.RECENTLY_MODIFIED
|
||||
}
|
||||
>
|
||||
<RecentlyModified />
|
||||
</SearchContextProvider>
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
"key": [
|
||||
"my-first-collection"
|
||||
]
|
||||
},
|
||||
"published": {
|
||||
"display_name": "Introduction to Testing",
|
||||
"description": "Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -64,6 +68,10 @@
|
||||
"key": [
|
||||
"my-first-collection"
|
||||
]
|
||||
},
|
||||
"published": {
|
||||
"display_name": "Second Text Component",
|
||||
"description": "Second Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -97,6 +105,10 @@
|
||||
"my-first-collection",
|
||||
"my-second-collection"
|
||||
]
|
||||
},
|
||||
"published": {
|
||||
"display_name": "Third Text component",
|
||||
"description": "Third Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -128,6 +140,10 @@
|
||||
"key": [
|
||||
"my-first-collection"
|
||||
]
|
||||
},
|
||||
"published": {
|
||||
"display_name": "Text 4",
|
||||
"description": "Testing 4"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -159,6 +175,10 @@
|
||||
"key": [
|
||||
"my-first-collection"
|
||||
]
|
||||
},
|
||||
"published": {
|
||||
"display_name": "Blank Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -26,7 +26,11 @@
|
||||
"block_type": "html",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Introduction to Testing",
|
||||
"description": "Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtesthtml73a22298-bcd9-4f4c-ae34-0bc2b0612480-46b4a7f2",
|
||||
@@ -48,7 +52,11 @@
|
||||
"block_type": "html",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Second Text Component",
|
||||
"description": "Second Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtesthtmlbe5b5db9-26ba-4fac-86af-654538c70b5e-73dbaa95",
|
||||
@@ -71,7 +79,11 @@
|
||||
"block_type": "html",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Third Text component",
|
||||
"description": "Third Testing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtesthtmle59e8c73-4056-4894-bca4-062781fb3f68-46a404b2",
|
||||
@@ -94,7 +106,11 @@
|
||||
"block_type": "html",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Text 4",
|
||||
"description": "Testing 4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblemf16116c9-516e-4bb9-b99e-103599f62417-f2798115",
|
||||
@@ -117,7 +133,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Blank Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblem2ace6b9b-6620-413c-a66f-19c797527f34-3a7973b7",
|
||||
@@ -143,7 +163,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Multiple Choice Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblem7d7e98ba-3ac9-4aa8-8946-159129b39a28-3a7973b7",
|
||||
@@ -169,7 +193,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Single Choice Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblem4e1a72f9-ac93-42aa-a61c-ab5f9698c398-3a7973b7",
|
||||
@@ -195,7 +223,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Numerical Response Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblemad483625-ade2-4712-88d8-c9743abbd291-3a7973b7",
|
||||
@@ -221,7 +253,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "Option Response Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lbaximtestproblemb4c859cb-de70-421a-917b-e6e01ce44bd8-3a7973b7",
|
||||
@@ -247,7 +283,11 @@
|
||||
"block_type": "problem",
|
||||
"context_key": "lib:Axim:TEST",
|
||||
"org": "Axim",
|
||||
"access_id": 15
|
||||
"access_id": 15,
|
||||
"published": {
|
||||
"display_name": "String Response Problem",
|
||||
"description": "Problem"
|
||||
}
|
||||
}
|
||||
],
|
||||
"query": "",
|
||||
|
||||
@@ -3,11 +3,13 @@ export default [
|
||||
id: '1',
|
||||
usageKey: 'lb:org:lib:html:1',
|
||||
displayName: 'Text Component 1',
|
||||
description: 'This is a text: ID=1',
|
||||
formatted: {
|
||||
displayName: 'Text Component 1',
|
||||
content: {
|
||||
htmlContent: 'This is a text: ID=1',
|
||||
},
|
||||
description: 'This is a text: ID=1',
|
||||
},
|
||||
tags: {
|
||||
level0: ['1', '2', '3'],
|
||||
@@ -18,11 +20,13 @@ export default [
|
||||
id: '2',
|
||||
usageKey: 'lb:org:lib:html:2',
|
||||
displayName: 'Text Component 2',
|
||||
description: 'This is a text: ID=2',
|
||||
formatted: {
|
||||
displayName: 'Text Component 2',
|
||||
content: {
|
||||
htmlContent: 'This is a text: ID=2',
|
||||
},
|
||||
description: 'This is a text: ID=2',
|
||||
},
|
||||
tags: {
|
||||
level0: ['1', '2', '3'],
|
||||
@@ -60,11 +64,13 @@ export default [
|
||||
id: '5',
|
||||
usageKey: 'lb:org:lib:problem:5',
|
||||
displayName: 'Problem',
|
||||
description: 'This is a problem: ID=5',
|
||||
formatted: {
|
||||
displayName: 'Problem',
|
||||
content: {
|
||||
capaContent: 'This is a problem: ID=5',
|
||||
},
|
||||
description: 'This is a problem: ID=5',
|
||||
},
|
||||
blockType: 'problem',
|
||||
},
|
||||
@@ -72,11 +78,13 @@ export default [
|
||||
id: '6',
|
||||
usageKey: 'lb:org:lib:problem:6',
|
||||
displayName: 'Problem',
|
||||
description: 'This is a problem: ID=6',
|
||||
formatted: {
|
||||
displayName: 'Problem',
|
||||
content: {
|
||||
capaContent: 'This is a problem: ID=6',
|
||||
},
|
||||
description: 'This is a problem: ID=6',
|
||||
},
|
||||
blockType: 'problem',
|
||||
},
|
||||
|
||||
@@ -107,6 +107,7 @@ const LibraryCollectionPage = () => {
|
||||
sidebarComponentInfo,
|
||||
openCollectionInfoSidebar,
|
||||
componentPickerMode,
|
||||
showOnlyPublished,
|
||||
setCollectionId,
|
||||
} = useLibraryContext();
|
||||
|
||||
@@ -175,6 +176,11 @@ const LibraryCollectionPage = () => {
|
||||
/>
|
||||
);
|
||||
|
||||
const extraFilter = [`context_key = "${libraryId}"`, `collections.key = "${collectionId}"`];
|
||||
if (showOnlyPublished) {
|
||||
extraFilter.push('last_published IS NOT NULL');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="d-flex">
|
||||
<div className="flex-grow-1">
|
||||
@@ -189,7 +195,7 @@ const LibraryCollectionPage = () => {
|
||||
)}
|
||||
<Container size="xl" className="px-4 mt-4 mb-5 library-authoring-page">
|
||||
<SearchContextProvider
|
||||
extraFilter={[`context_key = "${libraryId}"`, `collections.key = "${collectionId}"`]}
|
||||
extraFilter={extraFilter}
|
||||
overrideQueries={{ collections: { limit: 0 } }}
|
||||
>
|
||||
<SubHeader
|
||||
|
||||
@@ -37,6 +37,8 @@ export interface LibraryContextData {
|
||||
setCollectionId: (collectionId?: string) => void;
|
||||
// Whether we're in "component picker" mode
|
||||
componentPickerMode: boolean;
|
||||
// Only show published components
|
||||
showOnlyPublished: boolean;
|
||||
// Sidebar stuff - only one sidebar is active at any given time:
|
||||
closeLibrarySidebar: () => void;
|
||||
openAddContentSidebar: () => void;
|
||||
@@ -79,6 +81,7 @@ interface LibraryProviderProps {
|
||||
/** The component picker mode is a special mode where the user is selecting a component to add to a Unit (or another
|
||||
* XBlock) */
|
||||
componentPickerMode?: boolean;
|
||||
showOnlyPublished?: boolean;
|
||||
/** Only used for testing */
|
||||
initialSidebarComponentInfo?: SidebarComponentInfo;
|
||||
}
|
||||
@@ -91,6 +94,7 @@ export const LibraryProvider = ({
|
||||
libraryId,
|
||||
collectionId: collectionIdProp,
|
||||
componentPickerMode = false,
|
||||
showOnlyPublished = false,
|
||||
initialSidebarComponentInfo,
|
||||
}: LibraryProviderProps) => {
|
||||
const [collectionId, setCollectionId] = useState(collectionIdProp);
|
||||
@@ -148,6 +152,7 @@ export const LibraryProvider = ({
|
||||
readOnly,
|
||||
isLoadingLibraryData,
|
||||
componentPickerMode,
|
||||
showOnlyPublished,
|
||||
closeLibrarySidebar,
|
||||
openAddContentSidebar,
|
||||
openInfoSidebar,
|
||||
@@ -172,6 +177,7 @@ export const LibraryProvider = ({
|
||||
readOnly,
|
||||
isLoadingLibraryData,
|
||||
componentPickerMode,
|
||||
showOnlyPublished,
|
||||
closeLibrarySidebar,
|
||||
openAddContentSidebar,
|
||||
openInfoSidebar,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
initializeMocks,
|
||||
} from '../../testUtils';
|
||||
import { mockContentLibrary } from '../data/api.mocks';
|
||||
import { getXBlockFieldsApiUrl } from '../data/api';
|
||||
import { getXBlockFieldsVersionApiUrl, getXBlockFieldsApiUrl } from '../data/api';
|
||||
import { LibraryProvider, SidebarBodyComponentId } from '../common/context';
|
||||
import ComponentInfoHeader from './ComponentInfoHeader';
|
||||
|
||||
@@ -45,7 +45,7 @@ describe('<ComponentInfoHeader />', () => {
|
||||
beforeEach(() => {
|
||||
const mocks = initializeMocks();
|
||||
axiosMock = mocks.axiosMock;
|
||||
axiosMock.onGet(getXBlockFieldsApiUrl(usageKey)).reply(200, xBlockFields);
|
||||
axiosMock.onGet(getXBlockFieldsVersionApiUrl(usageKey, 'draft')).reply(200, xBlockFields);
|
||||
mockShowToast = mocks.mockShowToast;
|
||||
});
|
||||
|
||||
@@ -97,7 +97,7 @@ describe('<ComponentInfoHeader />', () => {
|
||||
});
|
||||
|
||||
it('should close edit library title on press Escape', async () => {
|
||||
const url = getXBlockFieldsApiUrl(usageKey);
|
||||
const url = getXBlockFieldsVersionApiUrl(usageKey, 'draft');
|
||||
axiosMock.onPost(url).reply(200);
|
||||
render();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const ComponentInfoHeader = () => {
|
||||
const {
|
||||
sidebarComponentInfo,
|
||||
readOnly,
|
||||
showOnlyPublished,
|
||||
} = useLibraryContext();
|
||||
|
||||
const usageKey = sidebarComponentInfo?.id;
|
||||
@@ -29,7 +30,7 @@ const ComponentInfoHeader = () => {
|
||||
}
|
||||
const {
|
||||
data: xblockFields,
|
||||
} = useXBlockFields(usageKey);
|
||||
} = useXBlockFields(usageKey, showOnlyPublished ? 'published' : 'draft');
|
||||
|
||||
const updateMutation = useUpdateXBlockFields(usageKey);
|
||||
const { showToast } = useContext(ToastContext);
|
||||
|
||||
@@ -15,6 +15,7 @@ interface ModalComponentPreviewProps {
|
||||
|
||||
const ModalComponentPreview = ({ isOpen, close, usageKey }: ModalComponentPreviewProps) => {
|
||||
const intl = useIntl();
|
||||
const { showOnlyPublished } = useLibraryContext();
|
||||
|
||||
return (
|
||||
<StandardModal
|
||||
@@ -24,7 +25,10 @@ const ModalComponentPreview = ({ isOpen, close, usageKey }: ModalComponentPrevie
|
||||
isOverflowVisible={false}
|
||||
className="component-preview-modal"
|
||||
>
|
||||
<LibraryBlock usageKey={usageKey} />
|
||||
<LibraryBlock
|
||||
usageKey={usageKey}
|
||||
version={showOnlyPublished ? 'published' : undefined}
|
||||
/>
|
||||
</StandardModal>
|
||||
);
|
||||
};
|
||||
@@ -33,7 +37,7 @@ const ComponentPreview = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
const [isModalOpen, openModal, closeModal] = useToggle();
|
||||
const { sidebarComponentInfo } = useLibraryContext();
|
||||
const { sidebarComponentInfo, showOnlyPublished } = useLibraryContext();
|
||||
|
||||
const usageKey = sidebarComponentInfo?.id;
|
||||
// istanbul ignore if: this should never happen
|
||||
@@ -58,7 +62,13 @@ const ComponentPreview = () => {
|
||||
{
|
||||
// key=modified below is used to auto-refresh the preview when changes are made, e.g. via OLX editor
|
||||
componentMetadata
|
||||
? <LibraryBlock usageKey={usageKey} key={componentMetadata.modified} />
|
||||
? (
|
||||
<LibraryBlock
|
||||
usageKey={usageKey}
|
||||
key={componentMetadata.modified}
|
||||
version={showOnlyPublished ? 'published' : undefined}
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,15 @@ import {
|
||||
|
||||
import { ComponentPicker } from './ComponentPicker';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useLocation: () => ({
|
||||
pathname: '/evilguy',
|
||||
search: {
|
||||
variant: 'published',
|
||||
},
|
||||
}),
|
||||
}));
|
||||
mockContentLibrary.applyMock();
|
||||
mockContentSearchConfig.applyMock();
|
||||
mockGetCollectionMetadata.applyMock();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Stepper } from '@openedx/paragon';
|
||||
|
||||
import { LibraryProvider, useLibraryContext } from '../common/context';
|
||||
@@ -24,6 +25,11 @@ export const ComponentPicker = () => {
|
||||
const [currentStep, setCurrentStep] = useState('select-library');
|
||||
const [selectedLibrary, setSelectedLibrary] = useState('');
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
const queryParams = new URLSearchParams(location.search);
|
||||
const variant = queryParams.get('variant') || 'draft';
|
||||
|
||||
const handleLibrarySelection = (library: string) => {
|
||||
setCurrentStep('pick-components');
|
||||
setSelectedLibrary(library);
|
||||
@@ -43,7 +49,7 @@ export const ComponentPicker = () => {
|
||||
</Stepper.Step>
|
||||
|
||||
<Stepper.Step eventKey="pick-components" title="Pick some components">
|
||||
<LibraryProvider libraryId={selectedLibrary} componentPickerMode>
|
||||
<LibraryProvider libraryId={selectedLibrary} componentPickerMode showOnlyPublished={variant === 'published'}>
|
||||
<InnerComponentPicker returnToLibrarySelection={returnToLibrarySelection} />
|
||||
</LibraryProvider>
|
||||
</Stepper.Step>
|
||||
|
||||
@@ -19,11 +19,13 @@ const contentHit: ContentHit = {
|
||||
org: 'org1',
|
||||
breadcrumbs: [{ displayName: 'Demo Lib' }],
|
||||
displayName: 'Text Display Name',
|
||||
description: 'This is a text: ID=1',
|
||||
formatted: {
|
||||
displayName: 'Text Display Formated Name',
|
||||
content: {
|
||||
htmlContent: 'This is a text: ID=1',
|
||||
},
|
||||
description: 'This is a text: ID=1',
|
||||
},
|
||||
tags: {
|
||||
level0: ['1', '2', '3'],
|
||||
|
||||
@@ -106,6 +106,7 @@ const ComponentCard = ({ contentHit }: ComponentCardProps) => {
|
||||
const {
|
||||
openComponentInfoSidebar,
|
||||
componentPickerMode,
|
||||
showOnlyPublished,
|
||||
} = useLibraryContext();
|
||||
|
||||
const {
|
||||
@@ -114,12 +115,12 @@ const ComponentCard = ({ contentHit }: ComponentCardProps) => {
|
||||
tags,
|
||||
usageKey,
|
||||
} = contentHit;
|
||||
const description: string = (/* eslint-disable */
|
||||
blockType === 'html' ? formatted?.content?.htmlContent :
|
||||
blockType === 'problem' ? formatted?.content?.capaContent :
|
||||
undefined
|
||||
) ?? '';/* eslint-enable */
|
||||
const displayName = formatted?.displayName ?? '';
|
||||
const componentDescription: string = (
|
||||
showOnlyPublished ? formatted.published?.description : formatted.description
|
||||
) ?? '';
|
||||
const displayName: string = (
|
||||
showOnlyPublished ? formatted.published?.displayName : formatted.displayName
|
||||
) ?? '';
|
||||
|
||||
const handleAddComponentToCourse = () => {
|
||||
window.parent.postMessage({
|
||||
@@ -133,7 +134,7 @@ const ComponentCard = ({ contentHit }: ComponentCardProps) => {
|
||||
<BaseComponentCard
|
||||
componentType={blockType}
|
||||
displayName={displayName}
|
||||
description={description}
|
||||
description={componentDescription}
|
||||
tags={tags}
|
||||
actions={(
|
||||
<ActionRow>
|
||||
|
||||
@@ -52,6 +52,8 @@ export const getLibraryPasteClipboardUrl = (libraryId: string) => `${getApiBaseU
|
||||
* Get the URL for the xblock fields/metadata API.
|
||||
*/
|
||||
export const getXBlockFieldsApiUrl = (usageKey: string) => `${getApiBaseUrl()}/api/xblock/v2/xblocks/${usageKey}/fields/`;
|
||||
export const getXBlockFieldsVersionApiUrl = (usageKey: string, version: string) => `${getApiBaseUrl()}/api/xblock/v2/xblocks/${usageKey}@${version}/fields/`;
|
||||
|
||||
/**
|
||||
* Get the URL for the xblock OLX API
|
||||
*/
|
||||
@@ -383,8 +385,8 @@ export async function getLibraryBlockMetadata(usageKey: string): Promise<Library
|
||||
/**
|
||||
* Fetch xblock fields.
|
||||
*/
|
||||
export async function getXBlockFields(usageKey: string): Promise<XBlockFields> {
|
||||
const { data } = await getAuthenticatedHttpClient().get(getXBlockFieldsApiUrl(usageKey));
|
||||
export async function getXBlockFields(usageKey: string, version: string = 'draft'): Promise<XBlockFields> {
|
||||
const { data } = await getAuthenticatedHttpClient().get(getXBlockFieldsVersionApiUrl(usageKey, version));
|
||||
return camelCaseObject(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ export const xblockQueryKeys = {
|
||||
*/
|
||||
xblock: (usageKey?: string) => [...xblockQueryKeys.all, usageKey],
|
||||
/** Fields (i.e. the content, display name, etc.) of an XBlock */
|
||||
xblockFields: (usageKey: string) => [...xblockQueryKeys.xblock(usageKey), 'fields'],
|
||||
xblockFields: (usageKey: string, version: string = 'draft') => [...xblockQueryKeys.xblock(usageKey), 'fields', version],
|
||||
/** OLX (XML representation of the fields/content) */
|
||||
xblockOLX: (usageKey: string) => [...xblockQueryKeys.xblock(usageKey), 'OLX'],
|
||||
/** assets (static files) */
|
||||
@@ -290,10 +290,10 @@ export const useLibraryBlockMetadata = (usageId: string) => (
|
||||
})
|
||||
);
|
||||
|
||||
export const useXBlockFields = (usageKey: string) => (
|
||||
export const useXBlockFields = (usageKey: string, version: string = 'draft') => (
|
||||
useQuery({
|
||||
queryKey: xblockQueryKeys.xblockFields(usageKey),
|
||||
queryFn: () => getXBlockFields(usageKey),
|
||||
queryKey: xblockQueryKeys.xblockFields(usageKey, version),
|
||||
queryFn: () => getXBlockFields(usageKey, version),
|
||||
enabled: !!usageKey,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -127,9 +127,21 @@ export interface ContentHit extends BaseContentHit {
|
||||
* - After that is the name and usage key of any parent Section/Subsection/Unit/etc.
|
||||
*/
|
||||
breadcrumbs: [{ displayName: string }, ...Array<{ displayName: string, usageKey: string }>];
|
||||
description?: string;
|
||||
content?: ContentDetails;
|
||||
lastPublished: number | null;
|
||||
collections: { displayName?: string[], key?: string[] },
|
||||
collections: { displayName?: string[], key?: string[] };
|
||||
published?: ContentPublishedData;
|
||||
formatted: BaseContentHit['formatted'] & { published?: ContentPublishedData, };
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about the published data of single Xblock returned in search results
|
||||
* Defined in edx-platform/openedx/core/djangoapps/content/search/documents.py
|
||||
*/
|
||||
export interface ContentPublishedData {
|
||||
description?: string,
|
||||
displayName?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,6 +164,7 @@ export function formatSearchHit(hit: Record<string, any>): ContentHit | Collecti
|
||||
displayName: _formatted?.display_name,
|
||||
content: _formatted?.content ?? {},
|
||||
description: _formatted?.description,
|
||||
published: _formatted?.published,
|
||||
};
|
||||
return camelCaseObject(newHit);
|
||||
}
|
||||
@@ -247,10 +260,10 @@ export async function fetchSearchResults({
|
||||
...extraFilterFormatted,
|
||||
...tagsFilterFormatted,
|
||||
],
|
||||
attributesToHighlight: ['display_name', 'content'],
|
||||
attributesToHighlight: ['display_name', 'description', 'published'],
|
||||
highlightPreTag: HIGHLIGHT_PRE_TAG,
|
||||
highlightPostTag: HIGHLIGHT_POST_TAG,
|
||||
attributesToCrop: ['content'],
|
||||
attributesToCrop: ['description', 'published'],
|
||||
sort,
|
||||
offset,
|
||||
limit,
|
||||
|
||||
Reference in New Issue
Block a user