feat(ui) Update home page template editability (#14772)

This commit is contained in:
Chris Collins 2025-09-16 15:04:07 -04:00 committed by GitHub
parent e8e97beee6
commit 8fafa22c68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 43 additions and 33 deletions

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Announcements } from '@app/homeV3/announcements/Announcements'; import { Announcements } from '@app/homeV3/announcements/Announcements';
import EditDefaultTemplateBar from '@app/homeV3/settings/EditDefaultTemplateBar'; import EditDefaultTemplateBar from '@app/homeV3/settings/EditDefaultTemplateBar';
import EditHomePageSettingsButton from '@app/homeV3/settings/EditHomePageSettingsButton'; // import EditHomePageSettingsButton from '@app/homeV3/settings/EditHomePageSettingsButton';
import { CenteredContainer, ContentContainer, ContentDiv } from '@app/homeV3/styledComponents'; import { CenteredContainer, ContentContainer, ContentDiv } from '@app/homeV3/styledComponents';
import Template from '@app/homeV3/template/Template'; import Template from '@app/homeV3/template/Template';
@ -11,7 +11,7 @@ const HomePageContent = () => {
<ContentContainer> <ContentContainer>
<CenteredContainer> <CenteredContainer>
<ContentDiv> <ContentDiv>
<EditHomePageSettingsButton /> {/* <EditHomePageSettingsButton /> */}
<Announcements /> <Announcements />
<Template /> <Template />
<EditDefaultTemplateBar /> <EditDefaultTemplateBar />

View File

@ -21,7 +21,7 @@ export const PageTemplateProvider = ({ children, templateType }: Props) => {
const { entityData } = useEntityData(); const { entityData } = useEntityData();
const editable = !!entityData?.privileges?.canManageAssetSummary; const editable = !!entityData?.privileges?.canManageAssetSummary;
const isTemplateEditable = useMemo( const isTemplateEditable = useMemo(
() => (templateType === PageTemplateSurfaceType.AssetSummary ? editable : true), () => (templateType === PageTemplateSurfaceType.AssetSummary ? editable : false),
[editable, templateType], [editable, templateType],
); );
// Template state management // Template state management

View File

@ -3,6 +3,7 @@ import { useDraggable } from '@dnd-kit/core';
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { usePageTemplateContext } from '@app/homeV3/context/PageTemplateContext';
import ModuleContainer from '@app/homeV3/module/components/ModuleContainer'; import ModuleContainer from '@app/homeV3/module/components/ModuleContainer';
import ModuleMenu from '@app/homeV3/module/components/ModuleMenu'; import ModuleMenu from '@app/homeV3/module/components/ModuleMenu';
import { ModuleProps } from '@app/homeV3/module/types'; import { ModuleProps } from '@app/homeV3/module/types';
@ -56,6 +57,7 @@ export default function SmallModule({
onClick, onClick,
dataTestId, dataTestId,
}: React.PropsWithChildren<Props>) { }: React.PropsWithChildren<Props>) {
const { isTemplateEditable } = usePageTemplateContext();
const { attributes, listeners, setNodeRef, isDragging } = useDraggable({ const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
id: `module-${module.urn}-${position.rowIndex}-${position.moduleIndex}`, id: `module-${module.urn}-${position.rowIndex}-${position.moduleIndex}`,
data: { data: {
@ -68,20 +70,24 @@ export default function SmallModule({
return ( return (
<StyledModuleContainer ref={setNodeRef} {...attributes} data-testId={dataTestId}> <StyledModuleContainer ref={setNodeRef} {...attributes} data-testId={dataTestId}>
<ContainerWithHover> <ContainerWithHover>
<DragIcon {isTemplateEditable && (
{...listeners} <DragIcon
size="lg" {...listeners}
color="gray" size="lg"
icon="DotsSixVertical" color="gray"
source="phosphor" icon="DotsSixVertical"
isDragging={isDragging} source="phosphor"
/> isDragging={isDragging}
/>
)}
<Content $clickable={!!onClick} onClick={onClick}> <Content $clickable={!!onClick} onClick={onClick}>
{children} {children}
</Content> </Content>
<FloatingRightHeaderSection> {isTemplateEditable && (
<ModuleMenu module={module} position={position} /> <FloatingRightHeaderSection>
</FloatingRightHeaderSection> <ModuleMenu module={module} position={position} />
</FloatingRightHeaderSection>
)}
</ContainerWithHover> </ContainerWithHover>
</StyledModuleContainer> </StyledModuleContainer>
); );

View File

@ -2,12 +2,15 @@ import { Button, Dropdown, Icon, colors } from '@components';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { usePageTemplateContext } from '@app/homeV3/context/PageTemplateContext';
import useAddModuleMenu from '@app/homeV3/template/components/addModuleMenu/useAddModuleMenu'; import useAddModuleMenu from '@app/homeV3/template/components/addModuleMenu/useAddModuleMenu';
import { ModulePositionInput, RowSide } from '@app/homeV3/template/types'; import { ModulePositionInput, RowSide } from '@app/homeV3/template/types';
type AddModuleButtonOrientation = 'vertical' | 'horizontal'; type AddModuleButtonOrientation = 'vertical' | 'horizontal';
const Wrapper = styled.div``; const Wrapper = styled.div<{ $isHidden: boolean }>`
${({ $isHidden }) => $isHidden && `visibility: hidden;`}
`;
const StyledDropdownContainer = styled.div` const StyledDropdownContainer = styled.div`
max-width: 335px; max-width: 335px;
@ -59,6 +62,7 @@ interface Props {
} }
export default function AddModuleButton({ orientation, className, rowIndex, rowSide }: Props) { export default function AddModuleButton({ orientation, className, rowIndex, rowSide }: Props) {
const { isTemplateEditable } = usePageTemplateContext();
const [isOpened, setIsOpened] = useState<boolean>(false); const [isOpened, setIsOpened] = useState<boolean>(false);
const ButtonComponent = useMemo(() => (isOpened ? StyledButton : StyledVisibleOnHoverButton), [isOpened]); const ButtonComponent = useMemo(() => (isOpened ? StyledButton : StyledVisibleOnHoverButton), [isOpened]);
@ -88,7 +92,7 @@ export default function AddModuleButton({ orientation, className, rowIndex, rowS
}; };
return ( return (
<Wrapper className={className} data-testid="add-button-container"> <Wrapper className={className} $isHidden={!isTemplateEditable} data-testid="add-button-container">
<Dropdown <Dropdown
open={isOpened} open={isOpened}
trigger={['click', 'contextMenu']} trigger={['click', 'contextMenu']}

View File

@ -6,7 +6,7 @@ import FeatureAvailability from '@site/src/components/FeatureAvailability';
# Custom Home Page # Custom Home Page
<FeatureAvailability/> <FeatureAvailability saasOnly />
DataHub's **Custom Home Page** empowers organizations and individual users to create personalized, modular home page experiences that put the most relevant data assets and information front and center. DataHub's **Custom Home Page** empowers organizations and individual users to create personalized, modular home page experiences that put the most relevant data assets and information front and center.

View File

@ -28,7 +28,7 @@ describe("home page modules", () => {
Cypress.on("uncaught:exception", (err, runnable) => false); Cypress.on("uncaught:exception", (err, runnable) => false);
it("add default modules", () => { it.skip("add default modules", () => {
addYourAssetsModule(); addYourAssetsModule();
cy.getWithTestId("edited-home-page-toast"); // wait for confirmation before continuing to prevent flakiness cy.getWithTestId("edited-home-page-toast"); // wait for confirmation before continuing to prevent flakiness
cy.getWithTestId("your-assets-module").should("have.length", 2); cy.getWithTestId("your-assets-module").should("have.length", 2);
@ -48,7 +48,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("create custom asset collection module", () => { it.skip("create custom asset collection module", () => {
createAssetCollectionModule("Collection Module"); createAssetCollectionModule("Collection Module");
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
cy.getWithTestId("asset-collection-module").should("be.visible"); cy.getWithTestId("asset-collection-module").should("be.visible");
@ -61,7 +61,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("create custom hierarchy module", () => { it.skip("create custom hierarchy module", () => {
createHierarchyModule("Hierarchy Module"); createHierarchyModule("Hierarchy Module");
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
cy.getWithTestId("hierarchy-module").should("be.visible"); cy.getWithTestId("hierarchy-module").should("be.visible");
@ -74,7 +74,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("create custom link module", () => { it.skip("create custom link module", () => {
const linkName = "Link 1"; const linkName = "Link 1";
createLinkModule(linkName, "www.google.com"); createLinkModule(linkName, "www.google.com");
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
@ -85,7 +85,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("create custom documentation module", () => { it.skip("create custom documentation module", () => {
const moduleName = "Rich Text module"; const moduleName = "Rich Text module";
const text = "Rich text description"; const text = "Rich text description";
createDocumentationModule(moduleName, text); createDocumentationModule(moduleName, text);
@ -98,7 +98,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("remove default module", () => { it.skip("remove default module", () => {
addYourAssetsModule(); addYourAssetsModule();
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
cy.ensureElementWithTestIdPresent("edited-home-page-toast"); cy.ensureElementWithTestIdPresent("edited-home-page-toast");
@ -110,7 +110,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("remove custom module", () => { it.skip("remove custom module", () => {
const moduleName = "Rich Text module"; const moduleName = "Rich Text module";
const text = "Rich text description"; const text = "Rich text description";
createDocumentationModule(moduleName, text); createDocumentationModule(moduleName, text);
@ -123,7 +123,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("should not be able to edit default module", () => { it.skip("should not be able to edit default module", () => {
cy.getWithTestId("your-assets-module") cy.getWithTestId("your-assets-module")
.should("be.visible") .should("be.visible")
.within(() => { .within(() => {
@ -136,7 +136,7 @@ describe("home page modules", () => {
); );
}); });
it("edit custom module", () => { it.skip("edit custom module", () => {
const name = "Collection Module"; const name = "Collection Module";
const updatedName = "Collection Module Updated"; const updatedName = "Collection Module Updated";
createAssetCollectionModule(name); createAssetCollectionModule(name);
@ -152,7 +152,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("add home default module", () => { it.skip("add home default module", () => {
const name = "Global Collection Module"; const name = "Global Collection Module";
addYourAssetsModule(); addYourAssetsModule();
cy.ensureElementWithTestIdPresent("edited-home-page-toast"); cy.ensureElementWithTestIdPresent("edited-home-page-toast");
@ -175,7 +175,7 @@ describe("home page modules", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("reorder module with drag-and-drop", () => { it.skip("reorder module with drag-and-drop", () => {
expectModulesOrder("your-assets-module", "domains-module"); expectModulesOrder("your-assets-module", "domains-module");
dragAndDropModuleToNewRow("your-assets-module"); dragAndDropModuleToNewRow("your-assets-module");
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");

View File

@ -22,14 +22,14 @@ describe("home page templates", () => {
Cypress.on("uncaught:exception", (err, runnable) => false); Cypress.on("uncaught:exception", (err, runnable) => false);
it("view default homepage template", () => { it.skip("view default homepage template", () => {
cy.getWithTestId("page-title").should("exist"); cy.getWithTestId("page-title").should("exist");
cy.getWithTestId("search-bar").should("exist"); cy.getWithTestId("search-bar").should("exist");
cy.getWithTestId("edit-home-page-settings").should("exist"); cy.getWithTestId("edit-home-page-settings").should("exist");
shouldShowDefaultTemplate(); shouldShowDefaultTemplate();
}); });
it("fork the homepage and create personal template", () => { it.skip("fork the homepage and create personal template", () => {
addYourAssetsModule(); addYourAssetsModule();
cy.getWithTestId("edited-home-page-toast"); // wait for confirmation before continuing to prevent flakiness cy.getWithTestId("edited-home-page-toast"); // wait for confirmation before continuing to prevent flakiness
cy.getWithTestId("your-assets-module").should("have.length", 2); cy.getWithTestId("your-assets-module").should("have.length", 2);
@ -37,7 +37,7 @@ describe("home page templates", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("create personal template, then log back in to check the updated template", () => { it.skip("create personal template, then log back in to check the updated template", () => {
addYourAssetsModule(); addYourAssetsModule();
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
createAssetCollectionModule("Collection Module"); createAssetCollectionModule("Collection Module");
@ -53,7 +53,7 @@ describe("home page templates", () => {
resetToOrgDefault(); resetToOrgDefault();
}); });
it("reset the homepage to organization default", () => { it.skip("reset the homepage to organization default", () => {
addYourAssetsModule(); addYourAssetsModule();
cy.getWithTestId("edited-home-page-toast"); cy.getWithTestId("edited-home-page-toast");
cy.wait(1000); cy.wait(1000);
@ -61,7 +61,7 @@ describe("home page templates", () => {
shouldShowDefaultTemplate(); shouldShowDefaultTemplate();
}); });
it("edit the default homepage", () => { it.skip("edit the default homepage", () => {
startEditingDefaultTemplate(); startEditingDefaultTemplate();
addYourAssetsModule(); addYourAssetsModule();
finishEditingDefaultTemplate(); finishEditingDefaultTemplate();