Components
Reusable page components used throughout the CenturyLink Platform UI/UX.
Account Switcher
The CenturyLink Platform supports the ability to create sub-accounts, which fall under a parent account. Sub accounts have of the advantage of:
- Hierarchy: user permissions flow down, but not up or sideways
- Billing: sub accounts may be billed separately or to the parent account
- Share Parent Networks: sub accounts may access their parent account's networks, in addition to their own network
- Inheritance: account settings are inherited
If a user has access to multiple accounts, their account context needs to be maintained as they navigate to different platform satellite apps. This component is a means for platform customers to view their current account context, change account context, and maintain that context across CenturyLink Platform satelite apps.
Keyboard Shortcuts
ctl + i
: toogle account switcher open or closedesc
: close account switcher when openup, down
: navigate the list of accountsenter
: change to selected account context
<account-switcher params="{accounts: accounts, currentAccountAlias: currentAccountAlias}"></account-switcher>
$(function(){ ko.applyBindings({ accounts: [...], currentAccountAlias: '...' }); });
Page Header Navigation
Key to a positive customer experience is having a standard header navigation across Platform services. Adopt the page header navigation component for your product to ensure your UI is consistent with the rest of the CenturyLink Platform.
Responsive behavior is built in, so at narrow viewports (portrait tablet or mobile device), the links will collapse into a vertical menu.
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="tiny" id="Layer_1" x="0" y="0" viewBox="0 0 196.6 41" xml:space="preserve"><path fill="#8DC63F" d="M3.7 32.3c1.4 1.9 3 3.6 5 5l6.8-11.8L3.7 32.3"/><path fill="#8DC63F" d="M8.6 3.7c-1.9 1.4-3.6 3-5 5l11.8 6.8L8.6 3.7"/><path fill="#8DC63F" d="M29.1 1.8c-2.1-1-4.4-1.6-6.8-1.8v13.6L29.1 1.8"/><path fill="#8DC63F" d="M11.8 39.2c2.1 1 4.4 1.6 6.8 1.8V27.4L11.8 39.2"/><path fill="#8DC63F" d="M37.3 8.6c-1.4-1.9-3-3.6-5-5l-6.8 11.8L37.3 8.6"/><path fill="#8DC63F" d="M32.3 37.3c1.9-1.4 3.6-3 5-5l-11.8-6.8L32.3 37.3"/><path fill="#007F3E" d="M41 18.6c-0.2-2.4-0.8-4.7-1.8-6.8l-11.8 6.8H41"/><path fill="#007F3E" d="M0 22.3c0.2 2.4 0.8 4.7 1.8 6.8l11.8-6.8H0"/><path fill="#007F3E" d="M1.8 11.8c-1 2.1-1.6 4.4-1.8 6.8h13.6L1.8 11.8"/><path fill="#007F3E" d="M27.4 22.3l11.8 6.8c1-2.1 1.6-4.4 1.8-6.8H27.4"/><path fill="#007F3E" d="M18.6 0c-2.4 0.2-4.7 0.8-6.8 1.8l6.8 11.8V0"/><path fill="#007F3E" d="M22.3 41c2.4-0.2 4.7-0.8 6.8-1.8l-6.8-11.8V41"/><path fill="#FFFFFF" d="M64.6 15.9c-0.1-1.8-2.1-3-4-3 -4.7 0-5.5 4.3-5.5 7.6 0 3.9 1.2 7.6 5.3 7.6 2 0 3.8-1 4.2-3h2.7c-0.3 3.2-3.5 5.2-7.1 5.2 -5.6 0-7.8-4.5-7.8-9.8 0-4.6 2-10 8.4-9.8 3.6 0.1 6.4 1.9 6.6 5.3H64.6"/><path fill="#FFFFFF" d="M71.8 23.8c-0.2 2.3 0.8 4.7 3.3 4.7 1.9 0 2.9-0.8 3.2-2.7h2.6c-0.4 3-2.7 4.5-5.8 4.5 -4.2 0-5.9-3-5.9-6.8 0-3.8 1.9-7.1 6.1-7.1 3.9 0.1 5.8 2.6 5.8 6.2v1.2H71.8M78.5 22.1c0.1-2.2-0.9-3.9-3.3-3.9 -2.1 0-3.3 1.8-3.3 3.9H78.5z"/><path fill="#FFFFFF" d="M86.1 18.7L86.1 18.7c0.9-1.6 2.7-2.3 4-2.3 0.9 0 5 0.2 5 4.4v9.1h-2.5v-8.3c0-2.2-0.9-3.3-3-3.3 0 0-1.4-0.1-2.4 1 -0.4 0.4-1 0.9-1 3.5v7.1h-2.5V16.8h2.4V18.7"/><path fill="#FFFFFF" d="M99 16.8V14l2.5-0.8v3.6h3v1.8h-3V27c0 0.9 0.7 1.4 1.6 1.4 0.4 0 0.9-0.1 1.3-0.2v1.9c-0.6 0-1.1 0.2-1.7 0.2 -0.6 0-1.1 0-1.7-0.1 -0.4-0.1-1.1-0.3-1.5-0.9 -0.4-0.6-0.6-0.7-0.6-2.4v-8.3h-2.2v-1.8H99"/><path fill="#FFFFFF" d="M115.4 16.8h2.5v13.1h-2.4V28h-0.1c-1 1.6-2.7 2.3-4.5 2.3 -2.7 0-4.3-2.1-4.3-4.7v-8.8h2.5v7.8c0 2.3 0.5 3.9 2.9 3.9 1 0 2.4-0.5 2.9-1.9 0.5-1.2 0.5-2.8 0.5-3.1V16.8"/><path fill="#FFFFFF" d="M123.7 29.9h-2.5V16.8h2.5v2.5h0.1c0.4-1.8 2-2.7 3.8-2.7 0.3 0 0.6 0 0.9 0V19c-0.3-0.1-0.7-0.1-1.1-0.1 -3.1 0.1-3.7 1.8-3.7 4.5V29.9"/><polyline fill="#FFFFFF" points="135.8 34.9 133.3 34.9 135.3 29.9 129.8 16.8 132.6 16.8 136.7 27.2 140.9 16.8 143.5 16.8 135.8 34.9 "/><polyline fill="#FFFFFF" points="145.4 29.9 145.4 11 149.4 11 149.4 26.8 157.6 26.8 157.6 29.9 145.4 29.9 "/><path fill="#FFFFFF" d="M159.9 11h4.2v3.4h-4.2V11zM160.1 16.8h3.9v13.1h-3.9V16.8z"/><path fill="#FFFFFF" d="M171.6 18.3L171.6 18.3c0.9-1.1 2.1-1.9 4.1-1.9 1.3 0 3.8 1 4.3 2.9 0.2 0.8 0.3 1.6 0.3 2.1v8.5h-3.9V22c0-1.4-0.4-3-2.4-3 -1.2 0-2.3 1.1-2.4 3v7.9h-3.9V16.8h3.9V18.3"/><polyline fill="#FFFFFF" points="188 22.1 188.1 22.2 191.9 16.6 196.3 16.6 191.8 22.4 196.6 29.9 192 29.9 188.1 22.7 188 22.8 188 29.9 184.1 29.9 184.1 11 188 11 188 22.1 "/></svg>
</a>
<a class="navbar-service" href="/">Service Name</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
<!-- Link back to the Control Portal, and give a sign out link -->
<ul class="nav navbar-nav navbar-right navbar-account">
<li><a href="https://control.ctl.io">Control Portal</a></li>
<li><a href="#" class="navbar-link">Sign Out</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
Primary Content
Increase page speed to comprehension by giving the page a visual hierachy. Use the .primary
class to wrap a .container
to add a white background to the main content of the view. For an example, see the basic starter page.
Page Header Content
Secondary Content
<div class="primary">
<div class="container">
<div class="row">
<div class="col-sm-12">...</div>
</div>
</div>
</div>
Action Toolbar
Use .action-toolbar
on an <ol>
or <ul>
to
get a menu style toolbar. using the overflowMenu
widget, as seen bellow, allowes
for dynamic creation of a "more" dropdown link when the toolbar is too narrow.
<div class="action-area">
<ol class="action-toolbar" data-bind="widget: 'overflowMenu'">
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-play'></svg> start</button></li>
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> stop</button></li>
<li><button type="button" class="disabled"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> disabled</button></li>
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-refresh'></svg> restart</button></li>
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-archive'></svg> archive</button></li>
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-snapshot'></svg> snapshot</button></li>
<li><button type="button"><svg class="cyclops-icon"><use xlink:href='#icon-disaster-recovery'></svg> recovery</button></li>
</ol>
</div>
If you need to have a right align link use the classes action-toolbar-left
and
action-toolbar-right
. If you need more than a single link use a
dropdown.
<div class="action-area">
<ol class="action-toolbar-left" data-bind="widget: 'overflowMenu'">
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-play'></svg> start</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> stop</a></li>
<li><a href="#" class="disabled"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> disabled</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-refresh'></svg> restart</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-archive'></svg> archive</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-snapshot'></svg> snapshot</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-disaster-recovery'></svg> recovery</a></li>
</ol>
<ol class="action-toolbar-right">
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-settings'></svg> settings</a></li>
</ol>
</div>
Confirmations
Some actions can be costly or even dangerous and therefore should be confirmed to make sure that the user actually wants to preform them. This shouldn’t be done on every action just ones that have possible negative side effects, like taking a service offline for a period of time.
Cyclops provides a widget, the actionToolbarConfirm
, that can be used to get
confirmation from the user. For more information about the specific options and
configurations available please see the
actionToolbarConfirm code page.
<div class="action-area">
<ol class="action-toolbar-left" data-bind="widget: 'overflowMenu'">
<li><a href="#" data-bind="widget: 'actionToolbarConfirm'"><svg class="cyclops-icon"><use xlink:href='#icon-play'></svg> start</a></li>
<li><a href="#" data-bind="widget: {
name: 'actionToolbarConfirm',
options: {
classes: 'action-toolbar-confirm-danger',
messageHtml: 'Are you sure you want to delete this server?',
yesHtml: '<svg class="cyclops-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-trash"></use></svg> Delete'}}"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> stop</a></li>
<li><a href="#" class="disabled"><svg class="cyclops-icon"><use xlink:href='#icon-stop'></svg> disabled</a></li>
<li><a href="#" data-bind="widget: 'actionToolbarConfirm'"><svg class="cyclops-icon"><use xlink:href='#icon-refresh'></svg> restart</a></li>
<li><a href="#" data-bind="widget: 'actionToolbarConfirm'"><svg class="cyclops-icon"><use xlink:href='#icon-archive'></svg> archive</a></li>
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-snapshot'></svg> snapshot</a></li>
<li><a href="#" data-bind="widget: 'actionToolbarConfirm'"><svg class="cyclops-icon"><use xlink:href='#icon-disaster-recovery'></svg> recovery</a></li>
</ol>
<ol class="action-toolbar-right">
<li><a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-settings'></svg> settings</a></li>
</ol>
</div>
Activity History
An important part of the CenturyLink Control Portal experience, is the logging of user activity. Actions performed by the user against your service (CRUD operations for example) should be logged and displayed in the Accounts' activity history, as well as on the entity (e.g. server) or rollup pages (e.g. data center, server group).
RECENT ACTIVITY
Tuesday Sep 29
-
Password change for user trent.andersonPassword change for user trent.anderson by systemsystem
-
Password change for user alyssa.carizalesPassword change for user alyssa.carizales by systemsystem
-
User alyssa.carizales Password ResetUser alyssa.carizales password reset by systemsystem
-
Server WA1ACMEVMA01 DeletedServer WA1ACMEVMA01 Deleted by trent.andersonsystem
Thursday Jul 30
-
Roles updated for user trent.andersonRoles updated to:
AccountAdmintrent.anderson -
User nathan.young.corp createdUser trent.anderson created by trevor.transomtrevor.transom
<div class="activity-history">
<h5 class="content-header">
RECENT ACTIVITY
</h5>
<section class="day">
<h5 class="content-header">Tuesday Sep 29</h5>
<ol>
<li>
<div class="timestamp">2:50:05 PM</div>
<div class="details">
<div class="subject">Password change for user trent.anderson</div>
<div class="body">Password change for user trent.anderson by system</div>
<div class="attribution">
<span class="createdBy">system</span>
</div>
</div>
</li>
</ol>
</section>
<section class="day">
<h5 class="content-header">Tuesday Sep 29</h5>
<ol>
<li>
<div class="timestamp">2:50:05 PM</div>
<div class="details">
<div class="subject">Password change for user trent.anderson</div>
<div class="body">Password change for user trent.anderson by system</div>
<div class="attribution">
<span class="createdBy">system</span>
</div>
</div>
</li>
</ol>
</section>
</div>
Alerts
Provide contextual feedback messages for user actions with alert messages. Wrap any text and an optional dismiss button in .alert
and one of the four contextual classes (e.g., .alert-success
) for basic alert messages. Responsive behavior is built in.
Success!
This is a successful message.
Helpful Information!
This alert should be used to display information that isn't inherently obvious.
Warning!
This is a warning message.
Danger!
This message is important and may have a major impact.
A message with a button.
// alert with an icon and header
<div class="alert alert-success" role="alert">
<div class="alert-icon ">
<svg class="cyclops-icon"><use xlink:href='#icon-plus-circle'></svg>
</div>
<h4>Success!</h4>
<p>This is a successful message.</p>
</div>
// text only alert
<div class="alert alert-info" role="alert">
...
</div>
Billing Summary
When possible, expose a billing estimate for your service so that customers can see how their usage of individual services will impact their total bill. Add .billing-summary
to a .row
, and within each grid column, wrap the unit in .heading
and the value in .currency
.
<div class="row billing-summary">
<div class="col-sm-4 col-xs-6">
<div class="heading">MONTH ESTIMATE</div>
<div class="currency">$15.74</div>
</div>
<div class="col-sm-4 col-xs-6">
<div class="heading">CURRENT HOUR</div>
<div class="currency">$0.02</div>
</div>
<div class="col-sm-4 col-xs-6">
<div class="heading">MONTH TO DATE</div>
<div class="currency">$7.08</div>
</div>
</div>
Billing estimate with a one time charge (setup fees)
<div class="row billing-summary">
<div class="col-sm-3 col-xs-6">
<div class="heading">MONTH ESTIMATE</div>
<div class="currency">$1,136.34</div>
</div>
<div class="col-sm-3 col-xs-6">
<div class="heading">CURRENT HOUR</div>
<div class="currency">$1.51</div>
</div>
<div class="col-sm-3 col-xs-6">
<div class="heading">ONE TIME CHARGES</div>
<div class="currency">$0.00</div>
</div>
<div class="col-sm-3 col-xs-6">
<div class="heading">MONTH TO DATE</div>
<div class="currency">$480.40</div>
</div>
</div>
Billing estimate with one time charge and promo balance.
<div class="row billing-summary">
<div class="col-sm-1-5">
<div class="heading">MONTH ESTIMATE</div>
<div class="currency">$1,136.34</div>
</div>
<div class="col-sm-1-5">
<div class="heading">CURRENT HOUR</div>
<div class="currency">$1.51</div>
</div>
<div class="col-sm-1-5">
<div class="heading">ONE TIME CHARGES</div>
<div class="currency">$0.00</div>
</div>
<div class="col-sm-1-5">
<div class="heading">MONTH TO DATE</div>
<div class="currency">$480.40</div>
</div>
<div class="col-sm-1-5">
<div class="heading">PROMO BALANCE</div>
<div class="currency">($623.40)</div>
</div>
</div>
Loading Behavior
When loading data, use a …
to indicate that data is loading in place, and a —
when the data fails to load.
Price Estimate
When possible, show a price estimate on the left side of a Create form page so that customers can get an understanding of how their actions impact potential costs. Changes in to settings in the create form (e.g. changing cpu count), should impact the values displayed in the price estimate.
Within a .row
, use the .priceEstimateContainer
to display the estimate values and .createFormContainer
to contain the <form>
.
<div class="row">
<div id="priceEstimateContainer">
<div id="priceEstimate">
<h5 class="content-header">ESTIMATED COST AS CONFIGURED</h5>
<div class="cost-value">$75.29</div>
<div class="cost-interval">PER MONTH</div>
<div class="cost-value">$0.10</div>
<div class="cost-interval">PER HOUR</div>
<div class="disclaimer">Does not include bandwidth charges. Final cost will vary based on usage.</div>
</div>
<div id="priceBreakdown">
<div class="lineItem">
<div class="line-item-display">2 CPUs</div>
<div class="line-item-cost">(~$0.02/hr)</div>
</div>
<div class="lineItem">
<div class="line-item-display">4GB Memory</div>
<div class="line-item-cost">(~$0.06/hr)</div>
</div>
<div class="lineItem">
<div class="line-item-display">100GB Storage</div>
<div class="line-item-cost">(~$0.02/hr)</div>
</div>
</div>
</div>
<div id="createFormContainer">
<form>...</form>
</div>
</div>
Breadcrumb
Use .breadcrumb
on an <ol>
to automatically get breadcrumb styles. If the breadcrumb is immediately followed by an <h1>
, the top margin of the <h1>
will be spaced accordingly.
Page Title
<ol class="breadcrumb">
<li><a href="#">US West - Seattle (WA1)</a></li>
<li><a href="#">Public Web App</a></li>
<li class="active">WA1WEBAP01</li>
</ol>
Git Stats
Display the github stats of a repo.
<ul class="git-stats">
<li>
<svg class="cyclops-icon"><use xlink:href='#icon-cloud-upload'></svg> 20 deploys
</li>
<li>
<a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-code-fork'></svg> 2 forks</a>
</li>
<li>
<a href="#"><svg class="cyclops-icon"><use xlink:href='#icon-star'></svg> 21 stars</a>
</li>
</ul>
Pagination
Simple pagination for lists with many results. Use .active
to indicate the current page, and .disabled
for unclickable links (i.e. beginning or end of the list).
<nav>
<ul class="pagination">
<li class="disabled">
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
<li class="active"><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</nav>
Progress Bars
Progress bars are block elements that can be displayed using the progress
HTML5 tag. Set the
max
to the amount of work to complete — the value which the value property
will be divided by. Set the value
attribute to the amount of work complete.
To indicate a state, the color of the bar can be changed using .info
, .warning
or .danger
. The default color is green.
0%
50%
100%
info
warning
error
<progress value="0" max="100">0%</progress>
<progress value="50" max="100">50%</progress>
<progress value="100" max="100">100%</progress>
<progress class="info" value="75" max="100">75%</progress>
<progress class="warning" value="75" max="100">75%</progress>
<progress class="danger" value="75" max="100">75%</progress>
Supporting IE9
Not all browsers support the progress element, in our support matrix it is only IE9 for this case we need to offer a decent fall back to our users. This is where the text inside the progress tag comes into play. On browsers that do not support the tag it will just be treated like a div and the text will be displayed. So the text in the tag needs to be meaningful to the current use case. For instance, something like "70% complete" or "100GB of 1000GB used"
<progress value="0" max="100" data-bind="value: progress">
<!-- ko text: progressText--><!-- /ko -->
</progress>
Search Input
A set of standard markup to make a simple search box.
<span class="search-input">
<input type="text"/>
<svg class="cyclops-icon">
<use xlink:href='#icon-search'></use>
</svg>
</span>
Show Password
A control to show a password. After 15 seconds
, it will automatically hide itself.
-
usernamematthew.osborn
-
password
-
IP Adrress192.168.1.1
<ul class="list-info">
<li>
<div class="info-label">password</div>
<div class="info-value">
<show-password params="getPassword: getPassword"></show-password>
</div>
</li>
</ul>
Slide Well
Slide wells are used to reveal additional content (i.e. forms) when toggled by a button or link.
<button class="btn btn-default" data-bind="click: toggleOpen">toggle slide well</button> <div class="slide-well" data-bind="fadeSlide: open"> ... </div>
self.open = ko.observable(false); self.toggleOpen = function(){ self.open(!self.open()) };
Upcoming Events
Use .upcoming-events
to display scheduled events. The .task-datetime
should link to the task's respective scheduling page. Responsive behavior is built in.
UPCOMING EVENTS
<div class="upcoming-events">
<h5 class="content-header">UPCOMING EVENTS</h5>
<div class="event">
<a class="task-datetime" href="#">
<span class=" date">10/17</span>
<span class="time">11:24 am</span>
</a>
<div class="details">
<div class="category">Delete Snapshot</div>
<div class="subject">CA3-DNS-01</div>
</div>
</div>
<div class="event">
<a class="task-datetime" href="#">
<span class=" date">10/21</span>
<span class="time">07:33 am</span>
</a>
<div class="details">
<div class="category">Delete Snapshot</div>
<div class="subject">WA1-DEMO-01</div>
</div>
</div>
</div>