veritone-widgets
v10.1.1
Published
As of v5.0.0, this package exports both React "smart components" and framework agnostic "widgets" for most components. When both are available, the smart component is the default export and the widget is a named export. For example, `import FilePicker, {
Downloads
92
Keywords
Readme
Quick Start
As of v5.0.0, this package exports both React "smart components" and framework agnostic "widgets" for most components. When both are available, the smart component is the default export and the widget is a named export. For example, import FilePicker, { FilePickerWidget } from 'veritone-widgets'
imports the smart component as FilePicker and the widget as FilePickerWidget. Smart components usually require redux reducers and sagas to be imported as well, see Using Smart Components
Widgets (framework agnostic)
import { VeritoneApp, OAuthLoginButtonWidget, AppBarWidget } from 'veritone-widgets'
const app = VeritoneApp();
// a "log in with veritone" button
const oauthButton = new OAuthLoginButtonWidget({
// the ID of an existing element in your document where the button will appear
elId: 'login-button-widget',
// the ID of your Veritone application (found in Developer App)
clientId: 'my-client-id',
// the route in your app that will handle OAuth responses (more details below)
redirectUri: 'https://my-app.com/handle_oauth_callback',
// optional callbacks to retrieve the OAuth token for using outside of VeritoneApp:
onAuthSuccess: ({ OAuthToken }) => console.log(OAuthToken),
onAuthFailure: (error) => console.log(error)
});
// the Veritone app bar, which will receive auth after the user completes
// the oauth flow using the OAuthLoginButton
const appBar = new AppBarWidget({
elId: 'appBar-widget',
title: 'My App',
backgroundColor: '#4caf50',
profileMenu: true,
appSwitcher: true
});
React Components
import { OAuthLoginButton } from 'veritone-widgets'
render(
<OAuthLoginButton
clientId="my-client-id"
redirectUri="https://my-app.com/handle_oauth_callback"
/>
)
Using Smart Components
Because smart components are not rendered within the VeritoneApp widget framework, they require the user's app to have its own redux store with the components' reducers installed. Often, sagas are also included and must be started as part of the app's root saga.
Smart component reducer/saga requirements
FilePicker
reducer:
import {filePickerReducer} from 'veritone-widgets'
saga:
import {filePickerSaga} from 'veritone-widgets'
Notifications
- reducer:
import {notificationsReducer} from 'veritone-widgets'
EngineOutputExport
- reducer:
import {engineOutputExportReducer} from 'veritone-widgets'
OAuthLoginButton
- reducers:
veritone-redux-common
User
,Auth
andConfig
reducers
Smart component theme wrapper requirements
In your app, import the VeritoneSDKThemeProvider
from veritone-react-common
:
import {VeritoneSDKThemeProvider } from 'veritone-react-common'
then wrap your root component with <VeritoneSDKThemeProvider>
. If this is not possible, the @withVeritoneSDKThemeProvider
decorator is provided to wrap individual components.
Components can be customized using material-ui themes by passing a theme into the theme
prop of the provider. Passed-in themes will be merged with the default Veritone theme.
Using Widgets
1. Create an instance of VeritoneApp
VeritoneApp
is a container for all the widgets and widget data in an app. Before using any widgets, you need to import and call it. Typically this will be done when your application is loaded and initialized.
import { VeritoneApp } from 'veritone-widgets'
const app = VeritoneApp();
Note: VeritoneApp
creates a singleton, so you do not need to manage the constructed app instance yourself. As long as VeritoneApp() has been imported and called at least once, you can retrieve the same instance by importing and calling VeritoneApp() again elsewhere in your app, if needed.
2. Authenticate with Veritone via OAuth
If you already have an OAuth token (because your app handles the client-side OAuth flow on its own), provide it by calling login()
on the returned app instance.
import { VeritoneApp } from 'veritone-widgets'
const app = VeritoneApp().login({
OAuthToken: 'my-token-here'
});
Calling login()
is usually not necessary; we provide an OAuthLoginButton
widget, which handles the OAuth token exchange automatically. See the instructions in the next section for more information.
3. Add widgets to your app
After you've initialized the app framework by calling VeritoneApp()
, you can begin using widgets.
A "widget" is a self-contained frontend component. Widgets always render into an empty element which you provide. They are self-contained and handle rendering a UI, responding to user interactions, making api calls, and so on.
For example, the AppBar
widget renders the Veritone application toolbar, fetches the required data to render the Veritone app switcher and profile menu, and allows the developer to configure their application logo and title. When the user uses the app switcher or uses the profile menu to log out, the AppBar widget handles those events.
Widgets typically can be configured with a variety of options, but always require at least elId
. This is the id (string) of an element in your document, often a div
, into which the widget will be rendered. By applying styling to that div, you can position the widget around your app. The element specified in elId must exist in the document before you create the widget that will use it.
Example: Using the OAuthLoginButton widget
The first widget you are likely to include is OAuthLoginButton
. OAuthLoginButton
renders a "log in with Veritone" button that your users can click to start the OAuth authentication flow. At the end of that flow, your VeritoneApp instance will be authenticated and able to make requests to our API. You can also retrieve the oauth token to use in your own app.
Note: Unless you are handling the OAuth flow on your own and providing the token to VeritoneApp manually, the OAuthLoginButton
widget is required for Veritone widgets to work.
The actual code you write to use widgets will vary based on your framework of choice, but in general, it should be as follows.
// assuming VeritoneApp has already been initialized as described earlier, and given a document like:
<body>
...
<div id="login-button-widget" />
</body>
// you can render the login button to the document like this:
import { OAuthLoginButtonWidget } from 'veritone-widgets'
const oauthButton = new OAuthLoginButtonWidget({
// the ID of an existing element in your document where the button will appear
elId: 'login-button-widget',
// the ID of your Veritone application (found in Developer App)
clientId: 'my-client-id',
// the route in your app that will handle OAuth responses (more details below)
redirectUri: 'https://my-app.com/handle_oauth_callback',
// optional callbacks to retrieve the OAuth token for using outside of VeritoneApp:
onAuthSuccess: ({ OAuthToken }) => console.log(OAuthToken),
onAuthFailure: (error) => console.log(error)
});
When new OAuthLoginButtonWidget({ ... })
runs, the widget will appear on your page.
Example: Using the AppBar widget
All Veritone apps should also include the AppBar widget.
<body>
<div id="appBar-widget" />
...
</body>
import { AppBarWidget } from 'veritone-widgets'
const appBar = new AppBarWidget({
elId: 'appBar-widget',
title: 'My App',
backgroundColor: '#4caf50',
profileMenu: true,
appSwitcher: true
});
Use via script tag
For environments that do not support javascript module imports, widgets can also be included in an app via script tags.
<body>
<div id="appBar-widget"></div>
<script src="https://unpkg.com/veritone-widgets@^5/dist/umd/VeritoneApp.js"></script>
<script src="https://unpkg.com/veritone-widgets@^5/dist/umd/AppBar.js"></script>
<script>
const app = VeritoneApp.default();
const appBar = new AppBar.AppBarWidget({
elId: 'appBar-widget',
title: 'AppBar Widget',
profileMenu: true,
appSwitcher: true
});
</script>
</body>
As you can see, each widget is bundled individually to keep file sizes small. In addition, VeritoneApp is separately bundled and required to use widgets. Scripts can be accessed from the the unpkg cdn or downloaded and hosted on your own infrastructure. Unpkg supports semver ranges, or a specific version can be specified exactly.
Configuring widgets
Note that the OAuthLoginButton widget in the example above is being configured with five properties: elId, clientId, OAuthURI, onAuthSuccess and onAuthFailure. As mentioned earlier, an elId is required for every widget. OAuthURI, clientId, onAuthSuccess and onAuthFailure are specific configurable properties on the OAuthLoginButton. As it is in the example, configuration is always provided to the widget constructor.
Widget instance methods
Some widgets have methods which can be called on an instance of that widget. For example, the FilePicker widget has the methods pick()
and cancel()
to open and close the picker dialog, respectively.
this._picker = new FilePickerWidget({
elId: 'file-picker-widget',
accept: ['image/*'],
multiple: true
});
...
// call the pick() instance method on the widget
this._picker.pick(files => console.log(files))
Where to look for widget options
In practice, a widget is just a wrapper around a React component. The easiest way to determine all the possible options for a given widget is to look at the PropTypes of its component. Remember to watch for console warnings which will indicate when an option was configured incorrectly, or when a required option was not provided.
The "storybook" dev environments in veritone-widgets and veritone-react-common have live examples of the various widgets and components.
The
story.js
file in the root of each widget folder in veritone-widgets and in the root of each component folder in veritone-react-common show the code used to create the storybook pages. If you are using React to write your application, these can be used directly as a basis for your own implementation.The PropTypes in the source files of the various widgets (in veritone-widgets) and their respective components (in veritone-react-common) generally correspond to configurable options. Likewise, instance methods for a widget will be defined on its widget class in veritone-widgets.
Destroying widgets
To remove a widget, call destroy()
on the instance
const oauthButton = new OAuthLoginButtonWidget({ ... });
...
oauthButton.destroy();
Available widgets
The current widgets are:
AppBar
The title and navigation bar common between all Veritone applications. Includes a logo, title, the Veritone app switcher and profile menu.
Options:
- title: string, a title to show in the center of the AppBar
- logoSrc: string, a URL or image (like an SVG) to use as the logo on the left-hand side of the AppBar.
- backgroundColor: string, a color (in hex) to use for the AppBar background
- profileMenu: bool, whether or not to show the profile menu
- appSwitcher: bool, whether or not to show the app switcher menu
- logo: bool, whether or not to show the veritone logo on the left side of the AppBar
- onLogout: func, called when the user clicks "logout". Apps must implement their own logout logic (usually by deleting the stored oauth token and redirecting or refreshing the page appropriately)
OAuthLoginButton The "Log in with Veritone" button and corresponding frontend logic to handle the OAuth2 authentication flow.
Options:
- mode: "implicit" (default) or "authCode", the OAuth grant type you wish to use.
- OAuthURI: string (required if using
authCode
mode), the URL of your app server's OAuth callback endpoint. - redirectUri: string (required if using
implicit
mode), the URL of your app frontend's OAuth callback endpoint. - clientID: string (required if using implicit mode), the ID of your Veritone application (found in Developer App)
- onAuthSuccess: function, a callback that will be called with the OAuth token when the OAuth flow is completed successfully.
- onAuthFailure: function, a callback that will be called with the error when the OAuth flow fails.
Requirements
Veritone provides two OAuth modes to suit different app requirements:
Implicit
, the default mode, is a frontend-only grant flow with no serverside requirement. Most apps will use this mode. This flow is much easier for apps to implement but has the downside of not returning a refresh token; users will need to log in again each time their token expires.
Auth Code
is a server-based grant flow, which uses your Veritone app's OAuth secret to retrieve both an auth token and refresh token. Auth code flow requires a server because the OAuth secret cannot be exposed to the client; the veritone-widets-server package is an example implementation, and more information can be found in its readme.
FilePicker
The Veritone file upload dialog. Handles selecting and uploading files to S3 for use on the Veritone platform.
Options:
- accept: oneOfType([arrayOf(string), string]), file extension(s) or mimetype(s) which the file picker will accept
- multiple: bool, whether the picker will accept multiple files to upload in a batch
- width: number, the width of the filepicker dialog
- height: number, the height of the filepicker dialog
- allowUrlUpload: bool, whether the filepicker will allow files to be selected by URL
Instance methods
pick(callback): open the filepicker dialog.
- callback signature is (result, { warning, error, cancelled })
- result: array of result objects, one for each file uploaded
- key: string, the filename as stored on the server (may include a UUID)
- fileName: string, the original filename
- size: number, the file size in bytes
- type: string, the mime type of the file
- error: string or
false
, the error that prevented the file from uploading, if any - bucket: string, the S3 bucket to which the file was uploaded
- expiresInSeconds: number, the length of time the credentials in
getUrl
will be valid, in seconds. - getUrl: string or
null
, the resulting S3 URL, if successful. Includes credentials that are valid forexpires
seconds. - unsignedUrl: string or
null
, the resulting S3 URL, if successful. Does not include credentials and will need to be signed to be used.
- warning: string or
false
, a warning message if some (but not all) files failed to upload. A warning indicates thatresult
contains some successful upload result objects, and some that were not successful (unsuccessful objects will haveerror
populated with an error message, as noted above) - error: string or
false
, an error message, if all files failed to upload. - cancelled: bool, whether or not the filepicker interaction was cancelled (by the user, or by calling cancel()).
- result: array of result objects, one for each file uploaded
- callback signature is (result, { warning, error, cancelled })
cancel(): close the filepicker dialog. The callback provided to pick() will be called with
(null, { cancelled: true })
.
Table
A Veritone table to display data.
Options:
- data: arrayOf(object) (required), the dataset
- columns: arrayOf(shape) (required), a set of defintions for each column to be displayed
- shape: object with the following keys:
- dataKey: string (required), the data attribute to display within column
- header: string, the column heading
- transform: function, specifies how column data should be displayed
- signature:
(cellValue) => {}
- signature:
- menu: bool, identifies a column as a menu column
- onSelectItem: function, when
menu
istrue
, specifies action(s) to take when a menu option is clicked- signature:
(menuAction) => {}
- signature:
- cursorPointer: bool, show cursor pointer over table cells
- align: string, specifies columm alignment:
['left', 'right', 'center']
- width: number, specifies the width of a column
- shape: object with the following keys:
- paginate: bool, specifies whether table data should be paginated
- initialItemsPerPage: number, the number of items to display per page in a paginated table,
- onCellClick: function, specifies action to take when a table cell is clicked
- signature:
(cellRow, cellColumn, cellData) => {}
- signature:
- focusedRow: number, identifies a row to display additional content for
- renderFocusedRowDetails: function, specifies additional content to display for
focusedRow
- signature:
(focusedRowData) => (string | react component)
- signature:
- onShowCellRange: function, fires when table page or rows (on page) changes;
- signature:
({ start: firstRowIndex, end: lastRowIndex }) => {}
- signature:
- onRefreshPageData: function, specifies how to refresh data (if needed)
- signature:
() => {}
- signature:
- emptyMessage: string, text to display when table has no data
EngineOutputExport
The Veritone export engine outputs full screen dialog. This will fetch the engines ran on a tdo/recording and allow the user to configure what file types are included in the export
Options:
- tdos: arrayOf(shape), array of tdo data objects that engine outputs will be exported for
- shape: object with the following keys:
- tdoId: string (required), the unique id of a tdo you want to export engine outputs for
- mentionId: string, the unique id of a mention you want to export engine outputs for. If a mentionId is provided the engine results of the mention will be returned rather than those of the tdo
- startOffsetMs: number, an integer representing the number of milliseconds from the start of the tdo where the exported engine outputs will begin
- stopOffsetMs: number, an integer representing the number of milliseconds from the start of the tdo where the exported engine outputs will end
- shape: object with the following keys:
- onExport: func, specifies action to take when export button is clicked
- signature:
(response) => {}
- signature:
- onCancel: func, specifies action to take when cancel button is clicked
- signature:
() => {}
- signature:
Instance methods
- open(): opens the export engine output dialog.
Running the development environment (storybook)
- Set up your local clone of veritone-sdk, following the instructions in the main readme
- cd to this package
- In
config.dev.json
, fill in the missing fields with your own app's information (see our application quick-start guide for more info on how to create an app). Your app'sURL
andredirect URL
should be set to the same value for the purposes of dev in this package. This default allows the environment to run with minimal config. - run
yarn start
. - When the build finishes, access the storybook at the url provided in your terminal.
License
Copyright 2019, Veritone Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.