Skip to content

Commit 1350fe2

Browse files
feat(homePage): add the ability to create asset collection module (#14050)
Co-authored-by: Chris Collins <[email protected]>
1 parent b550b8a commit 1350fe2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1516
-169
lines changed

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/module/UpsertPageModuleResolver.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
44

5+
import com.linkedin.common.UrnArray;
56
import com.linkedin.common.urn.Urn;
67
import com.linkedin.common.urn.UrnUtils;
78
import com.linkedin.datahub.graphql.QueryContext;
@@ -16,7 +17,9 @@
1617
import com.linkedin.module.DataHubPageModuleParams;
1718
import graphql.schema.DataFetcher;
1819
import graphql.schema.DataFetchingEnvironment;
20+
import java.util.List;
1921
import java.util.concurrent.CompletableFuture;
22+
import java.util.stream.Collectors;
2023
import javax.annotation.Nonnull;
2124
import lombok.RequiredArgsConstructor;
2225
import lombok.extern.slf4j.Slf4j;
@@ -91,6 +94,20 @@ private DataHubPageModuleParams mapParamsInput(
9194
gmsParams.setRichTextParams(richTextParams);
9295
}
9396

97+
if (paramsInput.getAssetCollectionParams() != null) {
98+
com.linkedin.module.AssetCollectionModuleParams assetCollectionParams =
99+
new com.linkedin.module.AssetCollectionModuleParams();
100+
101+
List<Urn> urns =
102+
paramsInput.getAssetCollectionParams().getAssetUrns().stream()
103+
.map(UrnUtils::getUrn)
104+
.collect(Collectors.toList());
105+
106+
UrnArray urnArray = new UrnArray(urns);
107+
108+
assetCollectionParams.setAssetUrns(urnArray);
109+
gmsParams.setAssetCollectionParams(assetCollectionParams);
110+
}
94111
return gmsParams;
95112
}
96113

@@ -106,6 +123,11 @@ private void validateInput(
106123
if (params.getLinkParams() == null) {
107124
throw new IllegalArgumentException("Did not provide link params for link module");
108125
}
126+
} else if (type.equals(com.linkedin.module.DataHubPageModuleType.ASSET_COLLECTION)) {
127+
if (params.getAssetCollectionParams() == null) {
128+
throw new IllegalArgumentException(
129+
"Did not provide asset collection params for asset collection module");
130+
}
109131
} else {
110132
// TODO: add more blocks to this check as we support creating more types of modules to this
111133
// resolver

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/types/module/PageModuleParamsMapper.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.linkedin.datahub.graphql.types.module;
22

3+
import com.linkedin.common.urn.Urn;
34
import com.linkedin.datahub.graphql.QueryContext;
5+
import com.linkedin.datahub.graphql.generated.AssetCollectionModuleParams;
46
import com.linkedin.datahub.graphql.generated.EntityType;
57
import com.linkedin.datahub.graphql.generated.LinkModuleParams;
68
import com.linkedin.datahub.graphql.generated.Post;
79
import com.linkedin.datahub.graphql.generated.RichTextModuleParams;
810
import com.linkedin.datahub.graphql.types.mappers.ModelMapper;
911
import com.linkedin.module.DataHubPageModuleParams;
12+
import java.util.List;
13+
import java.util.stream.Collectors;
1014
import javax.annotation.Nonnull;
1115
import javax.annotation.Nullable;
1216

@@ -44,6 +48,21 @@ public com.linkedin.datahub.graphql.generated.DataHubPageModuleParams apply(
4448
result.setRichTextParams(richTextParams);
4549
}
4650

51+
// Map asset collection params if present
52+
if (params.getAssetCollectionParams() != null
53+
&& params.getAssetCollectionParams().getAssetUrns() != null) {
54+
55+
AssetCollectionModuleParams assetCollectionParams = new AssetCollectionModuleParams();
56+
57+
List<String> assetUrnStrings =
58+
params.getAssetCollectionParams().getAssetUrns().stream()
59+
.map(Urn::toString)
60+
.collect(Collectors.toList());
61+
62+
assetCollectionParams.setAssetUrns(assetUrnStrings);
63+
result.setAssetCollectionParams(assetCollectionParams);
64+
}
65+
4766
return result;
4867
}
4968
}

datahub-graphql-core/src/main/resources/module.graphql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ input PageModuleParamsInput {
7878
The params required if the module is type RICH_TEXT
7979
"""
8080
richTextParams: RichTextModuleParamsInput
81+
82+
"""
83+
The params required if the module is type ASSET_COLLECTION
84+
"""
85+
assetCollectionParams: AssetCollectionModuleParamsInput
8186
}
8287

8388
"""
@@ -100,6 +105,16 @@ input RichTextModuleParamsInput {
100105
content: String!
101106
}
102107

108+
"""
109+
Input for the params required if the module is type ASSET_COLLECTION
110+
"""
111+
input AssetCollectionModuleParamsInput {
112+
"""
113+
The list of asset urns for the asset collection module
114+
"""
115+
assetUrns: [String!]!
116+
}
117+
103118
"""
104119
The main properties of a DataHub page module
105120
"""
@@ -202,6 +217,11 @@ type DataHubPageModuleParams {
202217
The params required if the module is type RICH_TEXT
203218
"""
204219
richTextParams: RichTextModuleParams
220+
221+
"""
222+
The params required if the module is type ASSET_COLLECTION
223+
"""
224+
assetCollectionParams: AssetCollectionModuleParams
205225
}
206226

207227
"""
@@ -224,6 +244,16 @@ type RichTextModuleParams {
224244
content: String!
225245
}
226246

247+
"""
248+
The params required if the module is type ASSET_COLLECTION
249+
"""
250+
type AssetCollectionModuleParams {
251+
"""
252+
The list of asset urns for the asset collection module
253+
"""
254+
assetUrns: [String!]!
255+
}
256+
227257
"""
228258
Input for deleting a DataHub page module
229259
"""

datahub-web-react/src/alchemy-components/components/Checkbox/Checkbox.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export const Checkbox = ({
4949
</Label>
5050
) : null}
5151
<CheckboxBase
52-
onClick={() => {
52+
onClick={(e) => {
53+
e.stopPropagation();
54+
e.preventDefault();
5355
if (!isDisabled) {
5456
setChecked(!checked);
5557
setIsChecked?.(!checked);

datahub-web-react/src/app/entityV2/shared/tabs/Properties/useHydratedEntityMap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function useHydratedEntityMap(urns?: (string | undefined | null)[]) {
1111
);
1212

1313
// Fetch entities
14-
const hydratedEntities = useGetEntities(uniqueEntityUrns);
14+
const { entities: hydratedEntities } = useGetEntities(uniqueEntityUrns);
1515

1616
// Create entity map
1717
const hydratedEntityMap = useMemo(

datahub-web-react/src/app/homeV3/context/PageTemplateContext.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { ReactNode, createContext, useContext, useMemo } from 'react';
22

3+
import { useModuleModalState } from '@app/homeV3/context/hooks/useModuleModalState';
34
import { useModuleOperations } from '@app/homeV3/context/hooks/useModuleOperations';
45
import { useTemplateOperations } from '@app/homeV3/context/hooks/useTemplateOperations';
56
import { useTemplateState } from '@app/homeV3/context/hooks/useTemplateState';
@@ -33,8 +34,11 @@ export const PageTemplateProvider = ({
3334
// Template operations
3435
const { updateTemplateWithModule, removeModuleFromTemplate, upsertTemplate } = useTemplateOperations();
3536

37+
// Modal state
38+
const moduleModalState = useModuleModalState();
39+
3640
// Module operations
37-
const { addModule, removeModule, createModule } = useModuleOperations(
41+
const { addModule, removeModule, upsertModule } = useModuleOperations(
3842
isEditingGlobalTemplate,
3943
personalTemplate,
4044
globalTemplate,
@@ -43,6 +47,7 @@ export const PageTemplateProvider = ({
4347
updateTemplateWithModule,
4448
removeModuleFromTemplate,
4549
upsertTemplate,
50+
moduleModalState.isEditing,
4651
);
4752

4853
const value = useMemo(
@@ -57,7 +62,8 @@ export const PageTemplateProvider = ({
5762
setTemplate,
5863
addModule,
5964
removeModule,
60-
createModule,
65+
upsertModule,
66+
moduleModalState,
6167
}),
6268
[
6369
personalTemplate,
@@ -70,7 +76,8 @@ export const PageTemplateProvider = ({
7076
setTemplate,
7177
addModule,
7278
removeModule,
73-
createModule,
79+
upsertModule,
80+
moduleModalState,
7481
],
7582
);
7683

@@ -86,4 +93,4 @@ export function usePageTemplateContext() {
8693
}
8794

8895
// Re-export types for convenience
89-
export type { CreateModuleInput, AddModuleInput, RemoveModuleInput } from './types';
96+
export type { UpsertModuleInput, AddModuleInput, RemoveModuleInput } from './types';

datahub-web-react/src/app/homeV3/context/__tests__/PageTemplateContext.test.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const mockSetGlobalTemplate = vi.fn();
8787
const mockSetTemplate = vi.fn();
8888
const mockAddModule = vi.fn();
8989
const mockRemoveModule = vi.fn();
90-
const mockCreateModule = vi.fn();
90+
const mockUpsertModule = vi.fn();
9191
const mockUpdateTemplateWithModule = vi.fn();
9292
const mockRemoveModuleFromTemplate = vi.fn();
9393
const mockUpsertTemplate = vi.fn();
@@ -117,7 +117,7 @@ describe('PageTemplateContext', () => {
117117
mockUseModuleOperations.mockReturnValue({
118118
addModule: mockAddModule,
119119
removeModule: mockRemoveModule,
120-
createModule: mockCreateModule,
120+
upsertModule: mockUpsertModule,
121121
});
122122
});
123123

@@ -183,6 +183,7 @@ describe('PageTemplateContext', () => {
183183
mockUpdateTemplateWithModule,
184184
mockRemoveModuleFromTemplate,
185185
mockUpsertTemplate,
186+
false,
186187
);
187188
});
188189

@@ -281,6 +282,7 @@ describe('PageTemplateContext', () => {
281282
mockUpdateTemplateWithModule,
282283
mockRemoveModuleFromTemplate,
283284
mockUpsertTemplate,
285+
false,
284286
);
285287
});
286288

@@ -328,7 +330,13 @@ describe('PageTemplateContext', () => {
328330
expect(result.current.setGlobalTemplate).toBe(mockSetGlobalTemplate);
329331
expect(result.current.setTemplate).toBe(mockSetTemplate);
330332
expect(result.current.addModule).toBe(mockAddModule);
331-
expect(result.current.createModule).toBe(mockCreateModule);
333+
expect(result.current.upsertModule).toBe(mockUpsertModule);
334+
expect(result.current.moduleModalState).toMatchObject({
335+
isOpen: false,
336+
isEditing: false,
337+
open: expect.any(Function),
338+
close: expect.any(Function),
339+
});
332340
});
333341

334342
it('should throw error when used outside provider', () => {
@@ -372,7 +380,7 @@ describe('PageTemplateContext', () => {
372380
expect(mockAddModule).toHaveBeenCalledWith(moduleInput);
373381
});
374382

375-
it('should provide working createModule function', () => {
383+
it('should provide working upsertModule function', () => {
376384
const { result } = renderHook(() => usePageTemplateContext(), {
377385
wrapper: ({ children }) => (
378386
<PageTemplateProvider personalTemplate={mockPersonalTemplate} globalTemplate={mockGlobalTemplate}>
@@ -381,7 +389,7 @@ describe('PageTemplateContext', () => {
381389
),
382390
});
383391

384-
const createModuleInput = {
392+
const upsertModuleInput = {
385393
name: 'New Module',
386394
type: DataHubPageModuleType.Link,
387395
scope: PageModuleScope.Personal,
@@ -393,10 +401,10 @@ describe('PageTemplateContext', () => {
393401
};
394402

395403
act(() => {
396-
result.current.createModule(createModuleInput);
404+
result.current.upsertModule(upsertModuleInput);
397405
});
398406

399-
expect(mockCreateModule).toHaveBeenCalledWith(createModuleInput);
407+
expect(mockUpsertModule).toHaveBeenCalledWith(upsertModuleInput);
400408
});
401409

402410
it('should provide working setIsEditingGlobalTemplate function', () => {

0 commit comments

Comments
 (0)