Zuora Connect UI

Installation

Add these lines to your application's Gemfile:

gem 'zuora_connect_ui'

# Peek
gem 'peek'
gem 'peek-git'
gem 'peek-pg'
gem 'peek-performance_bar'
gem 'peek-redis'
gem 'peek-resque'

And then execute:

$ bundle

Or install it yourself as:

$ gem install zuora_connect_ui

Usage

HTML Imports

Add to <head> in layouts/application.html.erb

<%= stylesheet_link_tag "application", :media => "all"%>
<%= javascript_include_tag "application" %>
<%= zuo_include_tag %> <!-- ADD THIS LINE WHEN UPGRADING ABOVE VERSION 0.3 -->
<%= yield :head %>

If these lines are in the <head>, they are no longer necesary as of version 0.2.9

<link href="https://fonts.googleapis.com/css?family=Muli:400,600,700" rel="stylesheet">
<link href="https://d3ntcvh9ql14ma.cloudfront.net/zui/1.4.0/css/zui.icons.css" rel="stylesheet">

SCSS Imports

Add to app/assets/stylesheets/application.scss

//************ Peek ************
@import "peek";
@import "peek/views/performance_bar";
@import "peek/vendor/tipsy";

@import "zuora_connect_ui";

Any style you create for your app should be imported below this

Javascript Imports

Add to app/assets/javascripts/application.js

//************** Peek ****************
//= require peek
//= require peek/views/performance_bar
//
//= require zuora_connect_ui

Any scripts you create for your app should be imported below this

Peek

Add the peek initializer in config/initializers/peek.rb:

# List of Peek Views shown in the container
require 'peek'
Peek.into Peek::Views::Git if Rails.env.development?
Peek.into Peek::Views::PerformanceBar
Peek.into Peek::Views::PG
Peek.into Peek::Views::Redis
Peek.into Peek::Views::Resque
Peek.into Peek::Views::Connect if Gem.loaded_specs.has_key?('zuora_connect')

Peek::Railtie.configure do
  config.peek.adapter = :redis
end

and the peek route in config/routes.rb under the app_admin constraint

constraints app_admin do
  ...
  mount Peek::Railtie => '/peek'
end

Layout

Admin Button

Partial: partials/admin_menu

<div id="breadcrumb-bar">
  <div id='breadcrumbs'>
    <%= yield :breadcrumbs %>
  </div>
  <%= render 'partials/admin_menu', peek_bar: true do %>
    <li><a href="/admin/resque_web">Resque Web</a></li>
    <li><a href="/admin/redis-browser" target="_blank">Redis Web</a></li>
    <li><%= link_to 'App Instances', admin_app_instances_path %></li>
  <% end %>
</div>

Additional links can be added by putting <li> tags in the block

If you added Peek, you can enable it by passing peek_bar: true to the partial

Row Actions Dropdown Menu

Partial: `partials/row_actions'

<%= render 'shared/row_actions' do %>
  <anj-dropdown-item>
    <%= link_to 'Show', page, remote: true, data: { toggle: 'modal', target: '#z_hub_modal' } %>
  </anj-dropdown-item>
  <anj-dropdown-item>
    <%= link_to 'Edit', edit_page_path(page), remote: true, data: { toggle: 'modal', target: '#z_hub_modal' } %>
  </anj-dropdown-item>
  <anj-divider></anj-divider>
  <anj-dropdown-item>
    <%= link_to 'Delete', page, :remote => true, method: :delete, data: { confirm: 'Are you sure?' } %>
  </anj-dropdown-item>
<% end %>

Table

Classes

Class Description
.zuo-table Base table class
.zuo-table__th Header cell class (for th-like container)
.zuo-table__tr Content cell class (for td-like container)

Example

<table class="zuo-table">
  <tr>
    <th class="zuo-table__th">Description</th>
    <th class="zuo-table__th">Status</th>
    <th class="zuo-table__th">Priority</th>
    <th class="zuo-table__th">Action</th>
  </tr>
  <% @notifications.each do |n|%>
    <tr>
      <td class="zuo-table__td"><%= n.metadata["description"]%></td>
      <td class="zuo-table__td"><%= n.status %></td>
      <td class="zuo-table__td"><%= n.priority %></td>
      <td class="zuo-table__td">
        <anj-button href="<%= tools_promos_path %>" shape="circle" context="icon" data-remote="true">
          <i class="z-icon-search"></i>
        </anj-button>
        <anj-button href="<%= tools_promos_path %>" shape="circle" context="icon" data-remote="true">
          <i class="z-icon-pencil"></i>
        </anj-button>
        <anj-button href="<%= tools_promos_path %>" shape="circle" context="icon" data-remote="true">
          <i class="z-icon-trash"></i>
        </anj-button>
      </td>
    </tr>
  <% end %>
</table>

Datatable

See datatable.md

Components

Component's labels must come directly after their input, and have for html attribute corresponding to their input. Using a .zuo-form-group is recommended but not required.

Textbox

<%= f.text_field :name, class: 'zuo-textbox' %>
<%= f.label :name, class: 'zuo-floating-label' %>

Text Area

<%= f.text_area :description, class: 'zuo-textbox' %>
<%= f.label :description, class: 'zuo-floating-label' %>

Floating Label

See Textbox for code example

Label must come directly after input, and have zuo-floating-label class

Basic Support Label

<div class="zuo-form-group">
  <%= f.text_field :name, class: 'zuo-textbox' %>
  <%= f.label :name, class: 'zuo-floating-label' %>
  <label class="zuo-support-label">Required</label>
</div>

Error Support Label

<div class="zuo-form-group <%= 'has-error' if @workflow.errors[:name].blank? %>">
  <%= f.text_field :name, class: 'zuo-textbox' %>
  <%= f.label :name, class: 'zuo-floating-label' %>
  <% if @workflow.errors[:name].present? %>
    <label class="zuo-support-label" ><%= @workflow.errors[:name].first %></label>
  <% end %>
</div>

Buttons

Use anjuna buttons, as documented here

data-* attributes placed on the anj-button will be passed to the button/a inside it, so you can still use data-remote="true"

<%# submit button %>
<anj-button type="submit"><%= f.object.new_record? ? "Create" : "Update" %></anj-button>

<%# <a> button %>
<anj-button href="<%= edit_campaign_path(campaign) %>" data-remote="true">Edit Campaign</anj-button>

<%# js button %>
<anj-button id="my-app-button">Start Logging</anj-button>
...
<% content_for :scripts do %>
  $('#my-app-button').on('click' () => alert('Logging Started'));
<% end %>

Only if you **REALLY can't get the anjuna buttons to work should you can use the following, keeping in mind that it will not be supported for as long:**

<%= link_to "Cancel", "#", class: "zuo-btn secondary", data: {dismiss: "modal"} %>
<%= f.submit f.object.new_record? ? "Create" : "Update", class: "zuo-btn primary" %>

<div>, <button>, and <a> tags can all be buttons.

The style of the buttons can be changed with an additional class

Class Style
primary Solid blue, white text. Use for the primary action.
secondary Solid white, blue outline and text. Use for a secondary action.
danger Solid white, red outlne and text. Use for destructive actions.
disabled Greyed out. Use when button is disabled (usually done programmatically)

Icon Button

Use anjuna buttons, as documented here

Only if you **REALLY can't get the anjuna buttons to work should you can use the following, keeping in mind that it will not be supported for as long:**

<%= link_to actions_path('ResetCache'), :remote => true, :class => 'zuo-btn secondary' do %>
  <span class="z-icon-refresh zuo-btn-icon"></span> Refresh Cache
<% end %>

Icon

All Material Icons are supported in anj-icon as of gem version 0.8.3

<anj-icon>brush</anj-icon>

Single Select

<%= f.select(:type, [['Plaintext'], ['HTML', 'Html'], ['CSS','Css'], ['Javascript'], ['Image'], ['Video']], prompt: '') %>
<%= f.label :type, class: 'zuo-floating-label' %>

...

<% content_for :scripts do %>
  $('#page_type').select2({
    minimumResultsForSearch: Infinity, // if you want to disable search
  });
<% end %>

Multiple Select

Multiple Select will not work with include_blank: true

<%= f.collection_select(:page_ids, Page.all, :id, :name, { prompt: false }, { multiple: true }) %>
<%= f.label :page_ids, class: 'zuo-floating-label' %>

...

<% content_for :scripts do %>
  $('#chapter_page_ids').select2({
    minimumResultsForSearch: Infinity, // if you want to disable search
  });
<% end %>

Select2 Options

Option Values
minimumResultsForSearch Integer (-1 or Infinity to disable search)
allowClear Boolean, true if you want the select to be clearable

Checkbox

Label does not a for html attribute, however, both the label and the div.checkbox are required

<div class='checkbox'>
  <%= f.check_box :enabled, { checked: @currently_enabled[chapter.id]}, chapter.id, false %>
  <label><%= chapter.name %></label>
</div>

Radio Button

Label does not need the for html attribute, however the div.radio is required

<div class='radio'>
  <%= f.radio_button :toggle %>
  <label>Radio Button</label>
</div>

Date Picker

UPGRADING to 0.3+: ensure that HTML import is present

<div class="zuo-datepicker date">
  <%= f.text_field :Start_Date, value: Date.yesterday, class: "zuo-textbox" %>
  <%= f.label :Start_Date, class: "zuo-floating-label floating" %>
  <span class="input-group-addon z-icon-calendar"></span>
</div>

...

<% content_for :scripts do %>
  $('.zuo-datepicker.date').datepicker({
    autoclose: true,
    format: 'yyyy-mm-dd',
    templates: {
      leftArrow: '<span class="z-icon-arrow-left"></span>',
      rightArrow: '<span class="z-icon-arrow-right"></span>'
    }
  });
<% end >

License

The gem is available as open source under the terms of the MIT License.