-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UIAPPS-164 Start custom widget with 3rd-party data (#125)
Motivation ---------- - We want to make a template for a custom widget that interacts with 3rd-party data. This should continue to grow and change as features evolve. - Jira Issue: https://datadoghq.atlassian.net/browse/UIAPPS-164 Changes ------- - We create an example we can use as a template that solves a specific use case: an App where there's a custom widget that interacts with 3rd-party data. - We're following a lot of the setup from the custom widget with 1st-party data from #120. Testing ------- - This is likely best tested once we have support for templates in the Datadog UI. We are almost assuredly going to need to make adjustments to this template afteward. Releases -------- Choose one: - [x] No release is necessary. If you're only updating examples/documentation, this is likely what you want. - [ ] All packages that need a release have a changeset.
- Loading branch information
1 parent
77766af
commit 56ced43
Showing
24 changed files
with
586 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.eslintcache | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Datadog App | ||
|
||
## Custom widget with 3rd-party data | ||
|
||
This App provides a custom widget that interacts with 3rd-party data. | ||
3rd-party data is data provided by something external to Datadog (like your service or another service). | ||
It can be used as a starting point for building out a real-world App on the Datadog Developer Platform. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"name": "datadog-app-example-custom-widget-with-3rd-party-data", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@datadog/ui-extensions-react": "0.30.1", | ||
"@datadog/ui-extensions-sdk": "0.30.1", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^14.14.14", | ||
"@types/react": "^17.0.0", | ||
"@types/react-dom": "^17.0.0", | ||
"react-scripts": "4.0.3", | ||
"typescript": "^4.5.4" | ||
}, | ||
"scripts": { | ||
"build": "react-scripts build", | ||
"eject": "react-scripts eject", | ||
"format:check": "prettier --check .", | ||
"format:fix": "prettier --write .", | ||
"lint:check": "eslint .", | ||
"lint:fix": "yarn run lint:check --fix", | ||
"lint": "yarn run lint:check && yarn run format:check", | ||
"prepare": "exit 0", | ||
"start": "react-scripts start", | ||
"test": "react-scripts test --passWithNoTests --watchAll=false" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"react-app", | ||
"react-app/jest" | ||
] | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/custom-widget /index.html 200 |
Binary file not shown.
36 changes: 36 additions & 0 deletions
36
examples/custom-widget-with-3rd-party-data/public/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
<meta | ||
name="Datadog App" | ||
content="A simple scaffolding for Datadog Apps" | ||
/> | ||
<!-- | ||
Notice the use of %PUBLIC_URL% in the tags above. | ||
It will be replaced with the URL of the `public` folder during the build. | ||
Only files inside the `public` folder can be referenced from the HTML. | ||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | ||
work correctly both with client-side routing and a non-root public URL. | ||
Learn how to configure a non-root public URL by running `npm run build`. | ||
--> | ||
<title>Datadog App</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
<!-- | ||
This HTML file is a template. | ||
If you open it directly in the browser, you will see an empty page. | ||
You can add webfonts, meta tags, or analytics to this file. | ||
The build step will place the bundled scripts into the <body> tag. | ||
To begin the development, run `npm start` or `yarn start`. | ||
To create a production bundle, use `npm run build` or `yarn build`. | ||
--></body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# https://www.robotstxt.org/robotstxt.html | ||
User-agent: * | ||
Disallow: |
38 changes: 38 additions & 0 deletions
38
examples/custom-widget-with-3rd-party-data/src/client/client.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { DDClient, init } from '@datadog/ui-extensions-sdk'; | ||
import { getUser, User } from '../user'; | ||
|
||
/** | ||
* We initialize the {@link DDClient} in one place and use it throughout the App. | ||
* Having the {@link DDClient} initialized in one place helps centralize auth logic and provide better type inference. | ||
*/ | ||
const client: DDClient = init({ | ||
authProvider: { | ||
/** | ||
* The `authStateCallback` can be pretty simple, | ||
* but can do whatever you need to check the authentication status. | ||
* This should not be used to perform actual authentication, | ||
* only to get the current authentication status. | ||
* | ||
* In this case, | ||
* we grab the current user if they exist, | ||
* and return the appropriate `isAuthenticated` value. | ||
*/ | ||
authStateCallback: async (): Promise<boolean> => { | ||
const user: User | undefined = await getUser(); | ||
return user != null; | ||
}, | ||
/** | ||
* We use `'close'` so the login page can close the window to notify successful login. | ||
* Once that happens, the `authStateCallback` is invoked again to check the state. | ||
* | ||
* @see https://github.com/DataDog/apps/blob/-/docs/en/programming-model.md#authentication | ||
*/ | ||
resolution: 'close', | ||
/** | ||
* This where we want Datadog to direct users to authenticate. | ||
*/ | ||
url: '/login' | ||
} | ||
}); | ||
|
||
export { client }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { client } from './client'; |
38 changes: 38 additions & 0 deletions
38
examples/custom-widget-with-3rd-party-data/src/controller/controller.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { DDClient } from '@datadog/ui-extensions-sdk'; | ||
import * as React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { useSetupCustomWidget } from './custom-widget'; | ||
|
||
type ControllerProps = { | ||
client: DDClient; | ||
}; | ||
|
||
/** | ||
* This component renders the main controller. | ||
* The main controller responds to the initial handshake from Datadog and sets up any App-wide behavior. | ||
* | ||
* @see https://github.com/DataDog/apps/blob/-/docs/en/programming-model.md#main-controller-iframe | ||
*/ | ||
function Controller(props: ControllerProps): JSX.Element { | ||
useSetupCustomWidget(props.client); | ||
|
||
return ( | ||
<> | ||
<div>The application controller is running in the background.</div> | ||
<a href="http://localhost:3000/custom-widget"> | ||
Click here to open your custom widget | ||
</a> | ||
</> | ||
); | ||
} | ||
|
||
function renderController(client: DDClient) { | ||
ReactDOM.render( | ||
<React.StrictMode> | ||
<Controller client={client} /> | ||
</React.StrictMode>, | ||
document.getElementById('root') | ||
); | ||
} | ||
|
||
export { renderController }; |
47 changes: 47 additions & 0 deletions
47
examples/custom-widget-with-3rd-party-data/src/controller/custom-widget.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { | ||
DDClient, | ||
EventType, | ||
WidgetSettingsMenuClickData | ||
} from '@datadog/ui-extensions-sdk'; | ||
import * as React from 'react'; | ||
import { logoutUser } from '../user'; | ||
|
||
/** | ||
* This hook performs any app-wide for the custom widget. | ||
* @param client The initialized {@link DDClient} | ||
*/ | ||
function useSetupCustomWidget(client: DDClient): void { | ||
/** | ||
* We set up an event listener for the logout widget settings menu item. | ||
* This event handler lets us perform the actual logging out of a user. | ||
*/ | ||
React.useEffect(() => { | ||
const unsubscribeLogout = client.events.on( | ||
EventType.WIDGET_SETTINGS_MENU_CLICK, | ||
async (data: WidgetSettingsMenuClickData): Promise<void> => { | ||
/** | ||
* We only want to handle events from the `'logout'` settings menu item. | ||
*/ | ||
if (data.menuItem.key !== 'logout') { | ||
return; | ||
} | ||
|
||
/** | ||
* Perform the actual logout, | ||
* then make sure to update the auth state so it's reflected in Datadog. | ||
*/ | ||
await logoutUser(); | ||
await client.auth.updateAuthState(); | ||
} | ||
); | ||
|
||
/** | ||
* We make sure to unsubscribe the event listener we set up. | ||
*/ | ||
return () => { | ||
unsubscribeLogout(); | ||
}; | ||
}, [client.auth, client.events]); | ||
} | ||
|
||
export { useSetupCustomWidget }; |
1 change: 1 addition & 0 deletions
1
examples/custom-widget-with-3rd-party-data/src/controller/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { renderController } from './controller'; |
64 changes: 64 additions & 0 deletions
64
examples/custom-widget-with-3rd-party-data/src/custom-widget/custom-widget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { DDClient } from '@datadog/ui-extensions-sdk'; | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { getUser, User } from '../user'; | ||
import { Post } from '../post'; | ||
|
||
type CustomWidgetProps = { | ||
client: DDClient; | ||
}; | ||
|
||
/** | ||
* This component brings together all the pieces and renders a custom widget. | ||
*/ | ||
function CustomWidget(props: CustomWidgetProps): JSX.Element { | ||
/** | ||
* We grab the {@link User} from the 3rd-party. | ||
*/ | ||
const [user, setUser] = React.useState<User>(); | ||
React.useEffect(() => { | ||
getUser().then((user?: User): void => { | ||
setUser(user); | ||
}); | ||
}, []); | ||
|
||
/** | ||
* If we do not have a {@link User}, | ||
* then authentication was not successful. | ||
* Datadog will not actually render the custom widget in this case, | ||
* but we still have to handle this case. | ||
*/ | ||
if (user == null) { | ||
return <></>; | ||
} | ||
|
||
return ( | ||
<div | ||
style={{ | ||
fontFamily: 'helvetica, arial, sans-serif', | ||
margin: '2rem' | ||
}} | ||
> | ||
<h2>Custom widget with 3rd-party data</h2> | ||
<p>Posts from {user.username}!</p> | ||
<ol> | ||
{user.posts.map( | ||
(post: Post): JSX.Element => { | ||
return <li key={post.title}>{post.title}</li>; | ||
} | ||
)} | ||
</ol> | ||
</div> | ||
); | ||
} | ||
|
||
function renderCustomWidget(client: DDClient) { | ||
ReactDOM.render( | ||
<React.StrictMode> | ||
<CustomWidget client={client} /> | ||
</React.StrictMode>, | ||
document.getElementById('root') | ||
); | ||
} | ||
|
||
export { renderCustomWidget }; |
1 change: 1 addition & 0 deletions
1
examples/custom-widget-with-3rd-party-data/src/custom-widget/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { renderCustomWidget } from './custom-widget'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { client } from './client'; | ||
import { renderController } from './controller'; | ||
import { renderCustomWidget } from './custom-widget'; | ||
import { renderLogin } from './login'; | ||
|
||
switch (window.location.pathname) { | ||
case '/custom-widget': | ||
renderCustomWidget(client); | ||
break; | ||
|
||
/** | ||
* This authentication route is part of this App, | ||
* but the system is designed to be able to leverage a preexisting authentication route if you have access to it. | ||
* If you already have an authentication route, | ||
* this route should be removed. | ||
*/ | ||
case '/login': | ||
renderLogin(client); | ||
break; | ||
|
||
default: | ||
renderController(client); | ||
break; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { renderLogin } from './login'; |
Oops, something went wrong.