Skip to content

Commit

Permalink
Custom homepage plugin (#324)
Browse files Browse the repository at this point in the history
#324
closes #308
  • Loading branch information
czgu committed Nov 19, 2020
1 parent f79701d commit 949f75b
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 55 deletions.
10 changes: 10 additions & 0 deletions datahub/webapp/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ declare global {
interface Window {
reduxStore?: typeof reduxStore;
receiveChildMessage?: () => void;

// Web Plugin Variables
NO_ENVIRONMENT_MESSAGE?: string;
CUSTOM_LANDING_PAGE?: {
// Two modes of custom landing page
// replace: replace the entire landing page with custom content
// not specified: add the custom content to the middle of the
// landing page
mode?: 'replace';
renderer: () => React.ReactElement;
};
CUSTOM_COLUMN_STATS_ANALYZERS?: IColumnStatsAnalyzer[];
CUSTOM_COLUMN_DETECTORS?: IColumnDetector[];
CUSTOM_COLUMN_TRANSFORMERS?: IColumnTransformer[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const InfoMenuRoute: React.FunctionComponent<RouteComponentProps> = ({
infoType === 'shortcut'
? 'Keyboard Shortcuts'
: infoType === 'tour'
? 'DataHub Tours'
? 'DataHub Tutorials'
: 'Frequently Asked Questions';

return isModal ? (
Expand Down
4 changes: 2 additions & 2 deletions datahub/webapp/components/Info/Tours.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export const Tours: React.FunctionComponent = () => {
return (
<div className="Tours m12">
<Title subtitle className="mb12">
Welcome to DataHub Tours!
Welcome to the DataHub Tutorial!
</Title>
<Title subtitle size={5}>
Click on a card to start a tour
Click on a card to start the tutorial.
</Title>
<div className="Tours-cards flex-center mv24">
<Card
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const InfoMenuButton: React.FunctionComponent = () => {
})
}
>
Tours
Tutorials
</MenuItem>
</Menu>
);
Expand Down
8 changes: 4 additions & 4 deletions datahub/webapp/components/Landing/Landing.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@

.Landing-top {
.Landing-greeting {
margin-left: 12px;
margin-left: 4px;
font-weight: bold;
font-size: var(--xxlarge-text-size);
font-size: var(--xlarge-text-size);
}

.Landing-desc {
margin-left: 12px;
margin-left: 4px;

font-weight: bold;
font-size: var(--xlarge-text-size);
font-size: var(--large-text-size);
color: var(--light-text-color);
}
}
Expand Down
104 changes: 60 additions & 44 deletions datahub/webapp/components/Landing/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ import { Title } from 'ui/Title/Title';
import './Landing.scss';

const datahubHints: string[] = require('config/loading_hints.yaml').hints;
/*
* TODO: clean up the urls so they are open source friendly
*/
export const Landing: React.FunctionComponent = () => {
useBrowserTitle();

const DefaultLanding: React.FC = ({ children }) => {
const {
userInfo,
recentDataDocs,
Expand Down Expand Up @@ -81,47 +77,67 @@ export const Landing: React.FunctionComponent = () => {

const [hint] = React.useState(sample(datahubHints));

return (
<div className="Landing flex-column">
<div className="Landing-top">
<div className="Landing-greeting">
Hi {titleize(userInfo.fullname || userInfo.username)},
welcome to
</div>
<div className="Landing-logo">
<DataHubLogo size={8} />
</div>
<div className="Landing-desc">{descriptionDOM}</div>
const LandingHeader = (
<div className="Landing-top">
<div className="Landing-greeting">
Hi {titleize(userInfo.fullname || userInfo.username)}, welcome
to
</div>
<div className="Landing-bottom">
<Columns>
<Column>
<DataHubSidebarUIGuide />
</Column>
</Columns>
<Columns>
<Column>
<Title size={5} weight={'bold'}>
Did you know?
</Title>
<p>{hint}</p>
</Column>
</Columns>
<Columns>
<Column>
<Title weight={'bold'} size={5}>
Recent DataDocs
</Title>
<div className="Landing-list">{getRecentDOM()}</div>
</Column>
<Column>
<Title weight={'bold'} size={5}>
Favorite DataDocs
</Title>
<div className="Landing-list">{getFavoriteDOM()}</div>
</Column>
</Columns>
<div className="Landing-logo">
<DataHubLogo size={5} />
</div>
<div className="Landing-desc">{descriptionDOM}</div>
</div>
);

const LandingFooter = (
<div className="Landing-bottom">
<Columns>
<Column>
<DataHubSidebarUIGuide />
</Column>
</Columns>
<Columns>
<Column>
<Title size={5} weight={'bold'}>
Did you know?
</Title>
<p>{hint}</p>
</Column>
</Columns>
<Columns>
<Column>
<Title weight={'bold'} size={5}>
Recent DataDocs
</Title>
<div className="Landing-list">{getRecentDOM()}</div>
</Column>
<Column>
<Title weight={'bold'} size={5}>
Favorite DataDocs
</Title>
<div className="Landing-list">{getFavoriteDOM()}</div>
</Column>
</Columns>
</div>
);

return (
<div className="Landing flex-column">
{LandingHeader}
<div className="Landing-middle">{children}</div>
{LandingFooter}
</div>
);
};

export const Landing: React.FC = () => {
useBrowserTitle();

const customLandingConfig = window.CUSTOM_LANDING_PAGE;
if (customLandingConfig?.mode === 'replace') {
return customLandingConfig.renderer();
}

return <DefaultLanding>{customLandingConfig?.renderer()}</DefaultLanding>;
};
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export const DataHubSidebarUIGuide: React.FC = () => {
borderless
inverted
>
Begin Tour
DataHub UI Tutorial
</Button>
<Tour
isOpen={isOpen}
Expand Down
18 changes: 17 additions & 1 deletion docs/admin_guide/customize_html.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_label: Customize HTML

DataHub allows for some basic customization in the frontend. You can use the web plugin to inject custom javascript into DataHub frontend. Please check [Plugins Guide](./plugins.md) to see how to get started.

Right now there are two use cases for custom javascript:
Right now there are four use cases for custom javascript:

1. Inject trackers such as google analytics. For example:

Expand All @@ -33,3 +33,19 @@ You can set the message directly in the custom_script.ts:
```typescript
window.NO_ENVIRONMENT_MESSAGE = 'Lorem ipsum dolor sit amet.';
```

3. Customize query result transformation such as adding url link or to transform the text into image. To see the complete guide, please check out [Plugins Guide](../developer_guide/add_query_result_transform.md) on how.
4. Customize the landing page for '/'. You can do so by modifying the window variable with the following type:

```typescript
interface Window {
CUSTOM_LANDING_PAGE?: {
mode?: 'replace';
renderer: () => React.ReactElement;
};
}
```

The renderer should be treated as the entry point into your customized react view. You can add any default HTML elements you want or import UI elements from DataHub.

If the mode variable is not provided, then DataHub would show this custom content in the middle section (currently empty) of the default landing page. However, if you specify the mode to be "replace", then the entire landing page will be replaced with your custom content.
9 changes: 8 additions & 1 deletion plugins/webpage_plugin/custom_script.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Place your custom css/js logic here
import React from 'react';

export {};

interface IColumnDetector {
Expand Down Expand Up @@ -35,6 +34,14 @@ declare global {
// Users will see this message if they cannot
// access any
NO_ENVIRONMENT_MESSAGE?: string;
CUSTOM_LANDING_PAGE?: {
// Two modes of custom landing page
// replace: replace the entire landing page with custom content
// not specified: add the custom content to the middle of the
// landing page
mode?: 'replace';
renderer: () => React.ReactElement;
};
CUSTOM_COLUMN_STATS_ANALYZERS?: IColumnStatsAnalyzer[];
CUSTOM_COLUMN_DETECTORS?: IColumnDetector[];
CUSTOM_COLUMN_TRANSFORMERS?: IColumnTransformer[];
Expand Down

0 comments on commit 949f75b

Please sign in to comment.