Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add storybook #6496

Merged
merged 56 commits into from
Apr 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
195a021
add storybook
meirish Mar 6, 2019
1279820
add storybook files
meirish Mar 6, 2019
1cd63a9
add ToggleButton and AlertBanner stories
andaley Mar 6, 2019
dc08de5
add knobs addon
andaley Mar 6, 2019
26fa861
add notes addon
andaley Mar 6, 2019
b848b00
add ToggleButton and AlertsBanner notes
andaley Mar 8, 2019
4b6213a
move panel to right
andaley Mar 8, 2019
17f8f70
add ICon
andaley Mar 8, 2019
2dbcf48
create story blueprint
Mar 11, 2019
b7dfc94
add header to blueprint
Mar 11, 2019
1b657f6
upgrade to storybook 5.0.1
andaley Mar 11, 2019
c842b9a
add confirm-action stories
andaley Mar 11, 2019
36ee8c4
move addon panel to bottom
andaley Mar 11, 2019
334963d
update ConfirmAction
andaley Mar 11, 2019
cde7bbf
add jsdoc comments to alert banner component
Mar 12, 2019
36c9d8e
add AlertInline
andaley Mar 12, 2019
b8d2bd2
set showPanel to true in blueprint
Mar 13, 2019
79e76c2
include newly generated markdown for stories
Mar 13, 2019
58ae37d
adjust code example for toggle button
Mar 13, 2019
415a153
add json-to-markdown to package.json
Mar 13, 2019
92db363
update AuthForm
andaley Mar 14, 2019
eed8b2b
add Storybook readme
andaley Mar 13, 2019
a4d9ae4
add AlertPopup
andaley Mar 15, 2019
75ca866
add story markdown custom template
Mar 26, 2019
f137ca9
make storybook dependencies optional
andaley Mar 26, 2019
e6f5b38
center all stories
andaley Mar 27, 2019
b6140bb
use message-types helper to dynamically render alerts
andaley Mar 27, 2019
f89b2ee
hide panel
andaley Mar 27, 2019
d894ca8
nest alert stories
andaley Mar 27, 2019
dae52d6
move icons into table
andaley Mar 27, 2019
2d82466
separate homelink into multiple stories
andaley Mar 27, 2019
d8762a0
add homelink with nav example
andaley Mar 27, 2019
22c3105
add viewport addon and remove centered addon
andaley Mar 28, 2019
c0be542
remove see links from alert-banner
Mar 28, 2019
8128b8f
add script to autogenerate markdown from component and add it to stories
Mar 28, 2019
680e986
update README to include markdown generation
Mar 28, 2019
050755e
remove @see links from jsdoc comments
Mar 28, 2019
c839a09
update README to include jsdoc example
Mar 28, 2019
d8ff818
update alert banner md
Mar 28, 2019
e54b8f1
get rid of trailing ######
Mar 28, 2019
385fdc6
update jsdoc and regenerate notes files
Mar 28, 2019
5c9ddc5
update i-con md
Mar 28, 2019
4b523f2
Merge branch 'master' into ui/add-storybook
Mar 28, 2019
b2c1bbb
Update ui/scripts/gen-story-md.js
meirish Mar 29, 2019
c3b58c8
Update ui/scripts/gen-story-md.js
meirish Mar 29, 2019
a033353
add storybook docs to vault ui readme
andaley Mar 29, 2019
9404ade
Merge https://github.com/hashicorp/vault into ui/add-storybook
andaley Mar 29, 2019
1ad5667
Merge branch 'ui/add-storybook' of https://github.com/hashicorp/vault…
andaley Mar 29, 2019
c6c5861
add jsdoc comments to component blueprint, automatically import md fi…
Mar 29, 2019
cf76ebe
add template template to component blueprint override
Mar 29, 2019
ed21a57
apply basic theme to storybook
andaley Mar 29, 2019
e583d85
remove comment
andaley Apr 1, 2019
c0affa9
make sure all stories are using auto generated md
andaley Apr 1, 2019
2f2ae82
storybook: show optional props in brackets
andaley Apr 2, 2019
d303063
storybook: 🔪 HomeLink
andaley Apr 2, 2019
89bfecd
storybook: show AuthConfigForm stories with knobs
andaley Apr 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
STORYBOOK_NAME=vault
5 changes: 5 additions & 0 deletions ui/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-viewport/register';
44 changes: 44 additions & 0 deletions ui/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { configure, addParameters, addDecorator } from '@storybook/ember';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import theme from './theme.js';

function loadStories() {
// automatically import all files ending in *.stories.js
const req = require.context('../stories/', true, /.stories.js$/);
req.keys().forEach(filename => req(filename));
}

addParameters({
viewport: { viewports: INITIAL_VIEWPORTS },
options: { theme },
});

addDecorator(storyFn => {
const { template, context } = storyFn();

// This adds styling to the Canvas tab.
const styles = {
style: {
margin: '20px',
},
};

// Create a div to wrap the Canvas tab with the applied styles.
const element = document.createElement('div');
Object.assign(element.style, styles.style);

const innerElement = document.createElement('div');

element.appendChild(innerElement);
innerElement.appendTo = function appendTo(el) {
el.appendChild(element);
};

return {
template,
context,
element: innerElement,
};
});

configure(loadStories, module);
22 changes: 22 additions & 0 deletions ui/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<meta name="vault/config/environment" content="%7B%22modulePrefix%22%3A%22vault%22%2C%22environment%22%3A%22development%22%2C%22rootURL%22%3A%22/ui/%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%7D%2C%22APP%22%3A%7B%22POLLING_URLS%22%3A%5B%22sys/health%22%2C%22sys/replication/status%22%2C%22sys/seal-status%22%5D%2C%22NAMESPACE_ROOT_URLS%22%3A%5B%22sys/health%22%2C%22sys/seal-status%22%2C%22sys/license/features%22%5D%2C%22DEFAULT_PAGE_SIZE%22%3A15%2C%22LOG_TRANSITIONS%22%3Atrue%7D%2C%22flashMessageDefaults%22%3A%7B%22timeout%22%3A7000%2C%22sticky%22%3Afalse%2C%22preventDuplicates%22%3Atrue%7D%2C%22contentSecurityPolicyHeader%22%3A%22Content-Security-Policy%22%2C%22contentSecurityPolicyMeta%22%3Atrue%2C%22contentSecurityPolicy%22%3A%7B%22connect-src%22%3A%5B%22%27self%27%22%5D%2C%22img-src%22%3A%5B%22%27self%27%22%2C%22data%3A%22%5D%2C%22form-action%22%3A%5B%22%27none%27%22%5D%2C%22script-src%22%3A%5B%22%27self%27%22%5D%2C%22style-src%22%3A%5B%22%27unsafe-inline%27%22%2C%22%27self%27%22%5D%2C%22default-src%22%3A%5B%22%27none%27%22%5D%2C%22font-src%22%3A%5B%22%27self%27%22%5D%2C%22media-src%22%3A%5B%22%27self%27%22%5D%7D%2C%22emberData%22%3A%7B%22enableRecordDataRFCBuild%22%3Afalse%7D%2C%22exportApplicationGlobal%22%3Atrue%7D" />
<link rel="stylesheet" href="/assets/vendor.css" />
<link rel="stylesheet" href="/assets/vault.css" />
<link rel="icon" href="/favicon.png" />
<script>
(function() {
var srcUrl = null;
var host = location.hostname || 'localhost';
var defaultPort = location.protocol === 'https:' ? 443 : 80;
var port = 4200;
var path = '';
var prefixURL = '';
var src = srcUrl || prefixURL + '/_lr/livereload.js?port=' + port + '&host=' + host + path;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = location.protocol + '//' + host + ':4200' + src;
document.getElementsByTagName('head')[0].appendChild(script);
}());
</script>
<script>runningTests = true;</script>
<script src="/assets/vendor.js"></script>
<script src="/assets/vault.js"></script>
32 changes: 32 additions & 0 deletions ui/.storybook/theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { create } from '@storybook/theming';

// Fonts and colors are pulled from _colors.scss and _bulma_variables.scss.

const uiGray300 = '#BAC1CC';
const uiGray900 = '#1f2124';
const blue500 = '#1563ff';

export default create({
base: 'light',

colorPrimary: uiGray900,
colorSecondary: blue500,

// UI
appBorderColor: uiGray300,

// Typography
fontBase: 'system-ui, -apple-system, BlinkMacSystemFont, sans-serif',
fontCode: '"SFMono-Regular", Consolas, monospace',

// Text colors
textColor: uiGray900,

// Toolbar default and active colors
barTextColor: uiGray300,
barSelectedColor: 'white',
barBg: uiGray900,

brandTitle: 'Vault UI Storybook',
brandUrl: 'https://www.vaultproject.io/',
});
82 changes: 79 additions & 3 deletions ui/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
# vault
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**

- [Vault UI](#vault-ui)
- [Prerequisites](#prerequisites)
- [Running / Development](#running--development)
- [Code Generators](#code-generators)
- [Running Tests](#running-tests)
- [Linting](#linting)
- [Building Vault UI into a Vault Binary](#building-vault-ui-into-a-vault-binary)
- [Vault Storybook](#vault-storybook)
- [Storybook Commands at a Glance](#storybook-commands-at-a-glance)
- [Writing Stories](#writing-stories)
- [Adding a new story](#adding-a-new-story)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# Vault UI

This README outlines the details of collaborating on this Ember application.
A short introduction of this app could easily go here.

## Prerequisites

Expand All @@ -24,7 +41,7 @@ running `yarn --force`.

To get all of the JavaScript dependencies installed, run this in the `ui` directory:

`yarn`
- `yarn`

If you want to run Vault UI and proxy back to a Vault server running
on the default port, 8200, run the following in the `ui` directory:
Expand Down Expand Up @@ -74,10 +91,69 @@ This will result in a Vault binary that has the UI built-in - though in
a non-dev setup it will still need to be enabled via the `ui` config or
setting `VAULT_UI` environment variable.

## Vault Storybook

The Vault UI uses Storybook to catalog all of its components. Below are details for running and contributing to Storybook.

### Storybook Commands at a Glance

| Command | Description |
| ------------------------------------------ | ------------------------- |
| `yarn storybook` | run storybook |
| `ember generate story [name-of-component]` | generate a new story |
| `yarn gen-story-md [name-of-component]` | update a story notes file |

### Writing Stories

Each component in `vault/ui/app/components` should have a corresponding `[component-name].stories.js` and `[component-name].md` files within `vault/ui/stories`.

#### Adding a new story

1. Make sure the component is well-documented using [jsdoc](http://usejsdoc.org/tags-exports.html). This documentation should at minimum include the module name, an example of usage, and the params passed into the handlebars template. For example, here is how we document the ToggleButton Component:

````js
/**
* @module ToggleButton
* `ToggleButton` components are used to expand and collapse content with a toggle.
*
* @example
* ```js
* <ToggleButton @openLabel="Encrypt Output with PGP" @closedLabel="Encrypt Output with PGP" @toggleTarget={{this}} @toggleAttr="showOptions"/>
* {{#if showOptions}}
* <div>
* <p>
* I will be toggled!
* </p>
* </div>
* {{/if}}
* ```
*
* @param toggleAttr=null {String} - The attribute upon which to toggle.
* @param attrTarget=null {Object} - The target upon which the event handler should be added.
* @param [openLabel=Hide options] {String} - The message to display when the toggle is open. //optional params are denoted by square brackets
* @param [closedLabel=More options] {String} - The message to display when the toggle is closed.
*/
````
Note that placing a param inside brackets (e.g. `[closedLabel=More options]` indicates it is optional and has a default value of `'More options'`.)

2. Generate a new story with `ember generate story [name-of-component]`
3. Inside the newly generated `stories` file, add at least one example of the component. If the component should be interactive, enable the [Storybook Knobs addon](https://github.com/storybooks/storybook/tree/master/addons/knobs).
4. Generate the `notes` file for the component with `yarn gen-story-md [name-of-component]` (e.g. `yarn gen-md alert-banner`). This will generate markdown documentation of the component and place it at `vault/ui/stories/[name-of-component].md`. If your component is a template-only component, you will need to manually create the markdown file.

See the [Storybook Docs](https://storybook.js.org/docs/basics/introduction/) for more information on writing stories.

### Code Generators

It is important to add all new components into Storybook and to keep the story and notes files up to date. To ease the process of creating and updating stories please use the code generators using the [commands listed above](#storybook-commands-at-a-glance).


## Further Reading / Useful Links

- [ember.js](http://emberjs.com/)
- [ember-cli](https://ember-cli.com/)
- Development Browser Extensions
- [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
- [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
- [Storybook for Ember Live Example](https://storybooks-ember.netlify.com/?path=/story/addon-centered--button)
- [Storybook Addons](https://github.com/storybooks/storybook/tree/master/addons/)
- [Storybook Docs](https://storybook.js.org/docs/basics/introduction/)
18 changes: 15 additions & 3 deletions ui/app/components/alert-banner.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import Component from '@ember/component';
import { computed } from '@ember/object';

import { messageTypes } from 'vault/helpers/message-types';

/**
* @module AlertBanner
* `AlertBanner` components are used to inform users of important messages.
*
* @example
* ```js
* <AlertBanner @type="danger" @message="{{model.keyId}} is not a valid lease ID"/>
* ```
*
* @param type=null {String} - The banner type. This comes from the message-types helper.
* @param [message=null {String}] - The message to display within the banner.
*
*/

export default Component.extend({
type: null,

message: null,
yieldWithoutColumn: false,

classNameBindings: ['containerClass'],

containerClass: computed('type', function() {
Expand Down
15 changes: 14 additions & 1 deletion ui/app/components/alert-inline.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import Component from '@ember/component';
import { computed } from '@ember/object';

import { messageTypes } from 'vault/helpers/message-types';

/**
* @module AlertInline
* `AlertInline` components are used to inform users of important messages.
*
* @example
* ```js
* <AlertInline @type="danger" @message="{{model.keyId}} is not a valid lease ID"/>
* ```
*
* @param type=null{String} - The alert type. This comes from the message-types helper.
* @param [message=null]{String} - The message to display within the alert.
*
*/

export default Component.extend({
type: null,
message: null,
Expand Down
14 changes: 14 additions & 0 deletions ui/app/components/alert-popup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import OuterHTML from './outer-html';

/**
* @module AlertPopup
* The `AlertPopup` is an implementation of the [ember-cli-flash](https://github.com/poteto/ember-cli-flash) `flashMessage`.
*
* @example ```js
* // All properties are passed in from the flashMessage service.
* <AlertPopup @type={{message-types flash.type}} @message={{flash.message}} @close={{close}}/>```
*
* @param type=null {String} - The alert type. This comes from the message-types helper.
* @param [message=null] {String} - The alert message.
* @param close=null {Func} - The close action which will close the alert.
*
*/

export default OuterHTML.extend({
type: null,
message: null,
Expand Down
13 changes: 13 additions & 0 deletions ui/app/components/auth-config-form/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import Component from '@ember/component';
import { task } from 'ember-concurrency';
import DS from 'ember-data';

/**
* @module AuthConfigForm/Config
* The `AuthConfigForm/Config` is the base form to configure auth methods.
*
* @example
* ```js
* {{auth-config-form/config model.model}}
* ```
*
* @property model=null {String} - The corresponding auth model that is being configured.
*
*/

const AuthConfigBase = Component.extend({
tagName: '',
model: null,
Expand Down
13 changes: 13 additions & 0 deletions ui/app/components/auth-config-form/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import DS from 'ember-data';

/**
* @module AuthConfigForm/Options
* The `AuthConfigForm/Options` is options portion of the auth config form.
*
* @example
* ```js
* {{auth-config-form/options model.model}}
* ```
*
* @property model=null {String} - The corresponding auth model that is being configured.
*
*/

export default AuthConfigComponent.extend({
router: service(),
wizard: service(),
Expand Down
15 changes: 15 additions & 0 deletions ui/app/components/auth-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends';
import { task } from 'ember-concurrency';
const BACKENDS = supportedAuthBackends();

/**
* @module AuthForm
* The `AuthForm` is used to sign users into Vault.
*
* @example ```js
* // All properties are passed in via query params.
* <AuthForm @wrappedToken={{wrappedToken}} @cluster={{model}} @namespace={{namespaceQueryParam}} @redirectTo={{redirectTo}} @selectedAuth={{authMethod}}/>```
*
* @param wrappedToken=null {String} - The auth method that is currently selected in the dropdown.
* @param cluster=null {Object} - The auth method that is currently selected in the dropdown. This corresponds to an Ember Model.
* @param namespace=null {String} - The currently active namespace.
* @param redirectTo=null {String} - The name of the route to redirect to.
* @param selectedAuth=null {String} - The auth method that is currently selected in the dropdown.
*/

const DEFAULTS = {
token: null,
username: null,
Expand Down
21 changes: 21 additions & 0 deletions ui/app/components/confirm-action.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
import Component from '@ember/component';
import hbs from 'htmlbars-inline-precompile';

/**
* @module ConfirmAction
* `ConfirmAction` is a button followed by a confirmation message and button used to prevent users from performing actions they do not intend to.
*
* @example
* ```js
* <ConfirmAction
* @onConfirmAction={{ () => { console.log('Action!') } }}
* @confirmMessage="Are you sure you want to delete this config?">
* Delete
* </ConfirmAction>
* ```
*
* @property {Func} onConfirmAction=null - The action to take upon confirming.
* @property {String} [confirmMessage=Are you sure you want to do this?] - The message to display upon confirming.
* @property {String} [confirmButtonText=Delete] - The confirm button text.
* @property {String} [cancelButtonText=Cancel] - The cancel button text.
* @property {String} [disabledMessage=Complete the form to complete this action] - The message to display when the button is disabled.
*
*/

export default Component.extend({
tagName: 'span',
classNames: ['confirm-action'],
Expand Down
Loading