scripts/apps/publish/views/subscribers.html
<div class="sd-page__flex-helper">
<div class="sd-page__header" ng-hide="hideHeader">
<sd-search-handler ng-model="search.name" data-debounce="200"></sd-search-handler>
<div class="sortbar">
<span class="lab" translate>Target Type:</span>
<div class="sd-line-input sd-line-input--is-select sd-line-input--no-label sd-line-input--no-margin" style="min-width:120px;">
<select class="sd-line-input__select"
ng-model="search.subscriber_type"
ng-options="s.qcode as s.name for s in subTypes">
<option value="" translate>Select</option>
</select>
</div>
</div>
<div class="sortbar">
<span class="lab" translate>Status:</span>
<div class="sd-line-input sd-line-input--is-select sd-line-input--no-label sd-line-input--no-margin" style="min-width:120px;">
<select class="sd-line-input__select"
ng-model="search.subscriber_status"
ng-options="status.label for status in statusFilters track by status.id"
>
</select>
</div>
</div>
<span class="sd-page__element-grow"></span>
<button id="addSubscriber" class="btn btn--primary" ng-click="edit()">
<i class="icon-plus-sign icon-/white"></i>{{ :: 'Add New' | translate }}
</button>
</div>
<div class="sd-page__content">
<ul class="sd-list-item-group sd-list-item-group--space-between-items" style="max-width: 1000px;">
<li ng-repeat="subscriber in subscribers | subscribersBy:search as filtered_subscribers track by subscriber._id" class="sd-list-item sd-shadow--z1">
<div class="sd-list-item__border"></div>
<div class="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
<div class="sd-list-item__row">
<span class="sd-overflow-ellipsis sd-list-item--element-grow" id="subscriberName">{{ subscriber.name }}</span>
<span class="label label--hollow label--alert" ng-if="!subscriber.is_active" translate>Not Active</span>
</div>
</div>
<div class="sd-list-item__action-menu sd-list-item__action-menu--direction-row">
<button class="icn-btn" ng-click="edit(subscriber)" title="{{:: 'Edit Subscriber' | translate }}"><i class="icon-pencil"></i></button>
</div>
</li>
<li ng-show="subscribers.length > 0 && !filtered_subscribers.length" class="sd-list-item sd-list-item--no-hover sd-shadow--z1">
<div class="sd-list-item__border"></div>
<div class="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
<div class="sd-list-item__row">
<span translate>No Subscribers Found</span>
</div>
</div>
</li>
</ul>
</div>
</div>
<!-- Modal -->
<div sd-modal data-model="subscriber" data-close="cancel()" class="modal--large modal--tabs sd-wizard">
<div class="modal__header modal__header--flex">
<h3 class="modal__heading" ng-show="subscriber._id"><span translate>Edit Subscriber</span> "{{ origSubscriber.name}}"</h3>
<h3 class="modal__heading" translate ng-hide="subscriber._id">Add New Subscriber</h3>
<a href="" class="icn-btn" ng-click="cancel()"><i class="icon-close-small"></i></a>
</div>
<div class="modal__body" sd-wizard data-name="subscribers" data-current-step="step.current" data-finish="cancel()">
<form name="editForm">
<fieldset>
<div sd-wizard-step data-title="{{ 'General' | translate }}" data-code="general">
<div class="content">
<div class="form__row">
<span title="{{ subscriber.is_active ? 'Deactivate' : 'Activate' | translate }}">
<span sd-switch ng-model="subscriber.is_active"></span><label>{{:: 'Status' | translate }}</label>
</span>
</div>
<div class="form__row">
<div class="sd-line-input sd-line-input--boxed sd-line-input--required">
<label class="sd-line-input__label" for="subscriber-name" translate>Name</label>
<input class="sd-line-input__input" id="subscriber-name" type="text" required ng-model="subscriber.name">
</div>
</div>
<div class="form__row">
<div class="sd-line-input sd-line-input--required">
<label class="sd-line-input__label" for="subscriber-email" ranslate>E-Mail to broadcast Kill Events</label>
<input type="text"
class="sd-line-input__input"
id="subscriber-email"
ng-model="subscriber.email"
required sd-multiple-emails>
</div>
</div>
<div class="form__row">
<div class="sd-line-input sd-line-input--is-select sd-line-input--required">
<label class="sd-line-input__label" for="subType" translate>Target Type</label>
<select class="sd-line-input__select"
id="subType"
ng-model="subscriber.subscriber_type"
ng-options="s.qcode as s.name for s in subTypes"
required>
<option value=""></option>
</select>
</div>
</div>
<div class="form__row">
<div class="sd-line-input sd-line-input--is-select">
<label class="sd-line-input__label" for="media-type" translate>Media Type</label>
<select class="sd-line-input__select"
id="media-type"
ng-model="subscriber.media_type">
<option value="media" translate>Media</option>
<option value="nonmedia" translate>Non-media</option>
<option value="" translate>Both</option>
</select>
</div>
</div>
<div class="form__row">
<div class="sd-line-input">
<label class="sd-line-input__label" translate>Subscriber codes</label>
<textarea class="sd-line-input__input" ng-model="subscriber.codes"sd-auto-height></textarea>
<span class="sd-line-input__hint" translate>Comma separated values</span>
</div>
</div>
<div class="form__row form__row--l-padding">
<span title="{{ subscriber.is_targetable ? 'Deactivate' : 'Activate' | translate }}">
<span sd-switch ng-model="subscriber.is_targetable"></span><label>{{:: 'Targetable by users' | translate }}</label>
</span>
</div>
<div class="form__row form__row--l-padding">
<label class="form-label" translate>Products</label>
<div sd-meta-terms
class="subscriber-products"
data-reload-list="true"
data-item="subscriber"
data-field="products"
data-unique="_id"
data-list="directProducts"
data-header="true">
</div>
</div>
<div class="form__row">
<label class="form-label form-label--required"translate>Sequence Number Settings</label>
<div class="form__row form__row--flex form__row--no-padding">
<div class="form__row-item form__row-item--no-grow">
<span translate>Minimum</span>
</div>
<div class="form__row-item form__row-item--no-grow">
<div class="sd-line-input">
<input type="number" class="sd-line-input__input sd-line-input__input--mini" ng-model="subscriber.sequence_num_settings.min" min ="1" id="subscriber-seq_num_settings.min" required>
</div>
</div>
<div class="form__row-item form__row-item--no-grow">
<span translate>Maximum</span>
</div>
<div class="form__row-item form__row-item--no-grow">
<div class="sd-line-input">
<input type="number" class="sd-line-input__input sd-line-input__input--small" ng-model="subscriber.sequence_num_settings.max" min ="2" id="subscriber-seq_num_settings.max" required>
</div>
</div>
</div>
<div class="form__row form__row--flex">
<div class="form__row-item form__row-item--no-grow">
<span sd-switch ng-model="subscriber.async"></span><label translate>Parallel publishing</label>
<span class="sd-display--block sd-margin-t--1 sd-font-size--x-small sd-text-color--light sd-text--light" translate>When enabled it can send multiple items at the same time.</span>
</div>
</div>
<div class="form__row form__row--flex" ng-if="highPriorityQueueEnabled">
<div class="form__row-item form__row-item--no-grow">
<span sd-switch ng-model="subscriber.priority"></span><label translate>High priority</label>
<span class="sd-line-input__hint" translate>Use priority queue for transmission.</span>
</div>
</div>
</div>
<fieldset class="separated">
<legend translate>Destinations</legend>
<div class="sd-alert sd-alert--hollow sd-alert--primary sd-alert--small">
<span translate>For Content API only subscriber destinations are not required.</i>
</div>
<div sd-destination ng-repeat="destination in destinations" data-destination="destination"
data-actions="[{label: 'Delete', fn: deleteDestination}]"></div>
<div sd-destination ng-if="newDestination"
data-destination="newDestination"
data-actions="[{label: 'Cancel', fn: cancelNewDestination}, {label: 'Save', fn: saveNewDestination}]"></div>
<div style="text-align:right;">
<button type="button" class="btn btn--primary btn--hollow btn--large btn--expanded" ng-click="addNewDestination()" ng-show="newDestination === null">
<i class="icon-plus-sign"></i> <span translate>Add New Destination</span>
</button>
</div>
</fieldset>
</div>
</div>
<div sd-wizard-step data-title="{{ 'Critical Errors' | translate }}" data-code="critical-errors">
<div class="content">
<ul class="simple-list simple-list--dotted">
<li ng-repeat="(key, val) in all_errors" class="simple-list__item">
<span sd-switch ng-model="subscriber.critical_errors[key]"></span><label>{{::key}}: {{::val}}</label>
</li>
</ul>
</div>
</div>
<div sd-wizard-step data-title="{{ 'Applied Global Block Filters' | translate }}" data-code="global-block-filters">
<div class="content privileges-settings">
<ul class="simple-list simple-list--dotted">
<li ng-repeat="gf in globalFilters track by gf._id" class="simple-list__item">
<span sd-switch ng-model="subscriber.global_filters[gf._id]"></span><label>{{:: gf.name}}</label>
</li>
</ul>
</div>
</div>
<div sd-wizard-step data-title="{{ :: 'Content API' | translate }}" data-code="content-api">
<div class="content">
<div class="field">
<label translate>Products</label>
<div sd-meta-terms
class="subscriber-products"
data-reload-list="true"
data-item="subscriber"
data-field="api_products"
data-unique="_id"
data-list="apiProducts"
data-header="true">
</div>
</div>
<div class="field" ng-controller="SubscriberTokenCtrl as tokens">
<label translate>Authentication Token</label>
<ul class="sd-list-item-group sd-list-item-group--space-between-items">
<li ng-repeat="token in tokens.tokens track by token._id" class="sd-list-item sd-shadow--z1">
<div class="sd-list-item__border"></div>
<div class="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
<div class="sd-list-item__row">
<span class="sd-overflow-ellipsis sd-list-item--element-grow"><code contenteditable="false" spellcheck="false">{{ :: token._id}}</code></span>
<span class="sd-list-item__text-label">{{ :: 'expires:' | translate }}
<time ng-if="token.expiry" sd-datetime data-date="token.expiry" data-from-now="true"></time>
<span ng-if="token.expiry == null" translate>Never</span>
</span>
</div>
</div>
<div class="sd-list-item__action-menu sd-list-item__action-menu--direction-row">
<button class="icn-btn" ng-click="tokens.revoke(token)" title="{{ :: 'Revoke' | translate }}">
<i class="icon-trash"></i>
</button>
<button class="icn-btn" ng-click="tokens.copy(token._id)" title="{{ :: 'Copy' | translate }}">
<i class="icon-copy"></i>
</button>
</div>
</li>
<li ng-show="tokens.tokens.length === 0" class="sd-list-item sd-list-item--no-hover sd-shadow--z1">
<div class="sd-list-item__border"></div>
<div class="sd-list-item__column sd-list-item__column--grow sd-list-item__column--no-border">
<div class="sd-list-item__row">
<span translate>There is no token for subscriber.</span>
</div>
</div>
</li>
</ul>
<fieldset ng-show="tokens.tokens.length < 5">
<div class="form__row form__row--flex">
<div class="form__row-item form__row-item--no-grow">
<span translate>Expire in:</span>
</div>
<div class="form__row-item">
<div class="sd-line-input sd-line-input--is-select">
<select class="sd-line-input__select"
ng-model="tokens.ttl"
ng-disabled="tokens.neverExpire"
title="{{ :: 'Token expiry' | translate }}">
<option ng-repeat="key in tokens.getExpiryFields" value="{{key.value}}">{{key.days}}</option>
</select>
</div>
</div>
<div class="form__row-item"></div>
<div class="form__row-item form__row-item--no-grow">
<button class="btn btn--hollow" ng-click="tokens.generate(tokens.ttl)"
ng-disabled="!subscriber._id"
translate>Generate token</button>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</fieldset>
</form>
<div class="modal__footer">
<button class="btn" ng-click="cancel()" translate>Cancel</button>
<button class="btn btn--primary" ng-click="save()"
ng-disabled="editForm.$invalid || !saveEnabled" translate>Save</button>
</div>
</div>
</div>