mirror of https://github.com/portainer/portainer
style(extensions): minor update to extension UX/UI (#2538)
* style(extensions): update extension icons * style(extensions): style update * feat(extensions): update extension UX * style(extensions): update extension style * style(extension-details): update screenshot default size * style(extensions): update overview diagram image * refactor(support): fix support URLspull/2539/head
parent
f222b3cb1a
commit
5c2e714e69
|
@ -35,6 +35,10 @@ func (handler *Handler) extensionInspect(w http.ResponseWriter, r *http.Request)
|
|||
for _, p := range extensions {
|
||||
if p.ID == extensionID {
|
||||
extension = p
|
||||
if extension.DescriptionURL != "" {
|
||||
description, _ := client.Get(extension.DescriptionURL, 10)
|
||||
extension.Description = string(description)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func (handler *Handler) extensionList(w http.ResponseWriter, r *http.Request) *h
|
|||
if storeDetails {
|
||||
definitions, err := handler.ExtensionManager.FetchExtensionDefinitions()
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extension definitions", err}
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extensions", err}
|
||||
}
|
||||
|
||||
for idx := range definitions {
|
||||
|
|
|
@ -485,6 +485,7 @@ type (
|
|||
Name string `json:"Name,omitempty"`
|
||||
ShortDescription string `json:"ShortDescription,omitempty"`
|
||||
Description string `json:"Description,omitempty"`
|
||||
DescriptionURL string `json:"DescriptionURL,omitempty"`
|
||||
Price string `json:"Price,omitempty"`
|
||||
PriceDescription string `json:"PriceDescription,omitempty"`
|
||||
Deal bool `json:"Deal,omitempty"`
|
||||
|
@ -492,7 +493,7 @@ type (
|
|||
License LicenseInformation `json:"License,omitempty"`
|
||||
Version string `json:"Version"`
|
||||
UpdateAvailable bool `json:"UpdateAvailable"`
|
||||
ProductID int `json:"ProductId,omitempty"`
|
||||
ShopURL string `json:"ShopURL,omitempty"`
|
||||
Images []string `json:"Images,omitempty"`
|
||||
Logo string `json:"Logo,omitempty"`
|
||||
}
|
||||
|
|
|
@ -149,8 +149,8 @@
|
|||
<span ng-show="state.testInProgress">Test in progress...</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="state.updateInProgress || !state.validConfiguration" ng-click="updateConfiguration()" button-spinner="state.updateInProgress">
|
||||
<span ng-hide="state.updateInProgress">Update configuration</span>
|
||||
<span ng-show="state.updateInProgress">Updating configuration...</span>
|
||||
<span ng-hide="state.updateInProgress">Save configuration</span>
|
||||
<span ng-show="state.updateInProgress">Saving configuration...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<a ui-sref="portainer.registries.registry.repositories({id: item.Id})" ng-if="$ctrl.registryManagement" class="space-left">
|
||||
<i class="fa fa-search" aria-hidden="true"></i> Browse
|
||||
</a>
|
||||
<a ui-sref="portainer.extensions.extension({id: 1})" ng-if="!$ctrl.registryManagement" class="space-left">
|
||||
<i class="fa fa-search" aria-hidden="true"></i> Browse ( <extension-tooltip></extension-tooltip> )
|
||||
<a ui-sref="portainer.extensions.extension({id: 1})" ng-if="!$ctrl.registryManagement" class="space-left" style="color: #767676" tooltip-append-to-body="true" tooltip-placement="bottom" tooltip-class="portainer-tooltip" uib-tooltip="Feature available via an extension">
|
||||
<i class="fa fa-search" aria-hidden="true"></i> Browse (extension)
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<!-- extension -->
|
||||
<div class="blocklist-item" ng-click="$ctrl.goToExtensionView()">
|
||||
<div class="blocklist-item" ng-click="$ctrl.goToExtensionView()" ng-class="{ 'blocklist-item--disabled': !$ctrl.model.Available }">
|
||||
<div class="blocklist-item-box">
|
||||
<!-- extension-image -->
|
||||
<span ng-if="$ctrl.model.Logo">
|
||||
<img class="blocklist-item-logo" ng-src="{{ $ctrl.model.Logo }}" />
|
||||
<span ng-if="$ctrl.model.Logo" style="width: 75px; text-align: center;">
|
||||
<!-- <img class="blocklist-item-logo" ng-src="{{ $ctrl.model.Logo }}" /> -->
|
||||
<i class="{{ $ctrl.model.Logo }} fa fa-4x blue-icon" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="blocklist-item-logo" ng-if="!$ctrl.model.Logo">
|
||||
<i class="fa fa-bolt fa-4x blue-icon" style="margin-left: 14px;" aria-hidden="true"></i>
|
||||
|
|
|
@ -7,8 +7,10 @@ function ($state) {
|
|||
ctrl.goToExtensionView = goToExtensionView;
|
||||
|
||||
function goToExtensionView() {
|
||||
if (ctrl.model.Available) {
|
||||
$state.go('portainer.extensions.extension', { id: ctrl.model.Id });
|
||||
}
|
||||
}
|
||||
|
||||
function $onInit() {
|
||||
if (ctrl.currentDate === ctrl.model.License.Expiration) {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<i class="fa fa-bolt orange-icon" aria-hidden="true" tooltip-append-to-body="true" tooltip-placement="bottom" tooltip-class="portainer-tooltip" uib-tooltip="Feature available via a plug-in"></i>
|
|
@ -1,3 +0,0 @@
|
|||
angular.module('portainer.app').component('extensionTooltip', {
|
||||
templateUrl: 'app/portainer/components/extension-tooltip/extension-tooltip.html'
|
||||
});
|
|
@ -11,7 +11,7 @@ function ExtensionViewModel(data) {
|
|||
this.License = data.License;
|
||||
this.Version = data.Version;
|
||||
this.UpdateAvailable = data.UpdateAvailable;
|
||||
this.ProductId = data.ProductId;
|
||||
this.ShopURL = data.ShopURL;
|
||||
this.Images = data.Images;
|
||||
this.Logo = data.Logo;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,54 @@
|
|||
</rd-header>
|
||||
|
||||
<information-panel title-text="Information">
|
||||
<span class="small text-muted">
|
||||
<span class="text-muted" style="font-size: 90%;">
|
||||
<p>
|
||||
Content to be defined
|
||||
Portainer CE is a great way of managing clusters, provisioning containers and services and
|
||||
managing container environment lifecycles. To extend the benefit of Portainer CE even
|
||||
more, and to address the needs of larger, complex or critical environments, the Portainer
|
||||
team provides a growing range of low-cost Extensions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As the diagram shows, running a successful production container environment requires a
|
||||
range of capability across a number of complex technical areas.
|
||||
</p>
|
||||
|
||||
<p style="text-align: center; margin: 15px 0 15px 0;">
|
||||
<img src="images/extensions_overview_diagram.png" alt="extensions overview">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Available through a simple subscription process from the menu, Portainer Extensions
|
||||
answers this need and provides a simple way to enhance the functionality that Portainer
|
||||
makes available through incremental capability in important areas.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The vision for Portainer is to be the standard management layer for container platforms. In
|
||||
order to achieve this vision, Portainer CE will be extended across a range of new functional
|
||||
areas. In order to ensure that Portainer remains the best choice for managing production
|
||||
container platforms, the Portainer team have chosen a modular extensible design approach,
|
||||
where additional capability can be added to the Portainer CE core as needed, and at very
|
||||
low cost.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The advantage of an extensible design is clear: While a range of capability is available, only
|
||||
necessary functionality is added as and when needed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Our first extension is <a ui-sref="portainer.extensions.extension({id: 1})">Registry Manager</a>, available now. Others (such as
|
||||
Single Sign On and Operations Management) are scheduled for the early part of 2019.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Portainer CE is the core of the Portainer management environments. Portainer CE will
|
||||
continue to be developed and made freely available as part of our deep commitment to our
|
||||
Open Source heritage and our user community. Portainer CE will always deliver great
|
||||
functionality and remain the industry standard toolset for managing container-based
|
||||
platforms.
|
||||
</p>
|
||||
</span>
|
||||
</information-panel>
|
||||
|
@ -61,7 +106,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="extensions">
|
||||
<div class="row" ng-if="extensions && extensions.length > 0">
|
||||
<div class="col-sm-12">
|
||||
<extension-list
|
||||
current-date="state.currentDate"
|
||||
|
@ -69,3 +114,12 @@
|
|||
></extension-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<information-panel title-text="Error" ng-if="extensions && extensions.length === 0">
|
||||
<span class="small text-muted">
|
||||
<p>
|
||||
<i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true"></i>
|
||||
Portainer must be connected to the Internet to fetch the list of available extensions.
|
||||
</p>
|
||||
</span>
|
||||
</information-panel>
|
||||
|
|
|
@ -17,6 +17,7 @@ function ($scope, $state, ExtensionService, Notifications) {
|
|||
$scope.extensions = data;
|
||||
})
|
||||
.catch(function onError(err) {
|
||||
$scope.extensions = [];
|
||||
Notifications.error('Failure', err, 'Unable to access extension store');
|
||||
});
|
||||
}
|
||||
|
|
|
@ -51,11 +51,17 @@
|
|||
</div>
|
||||
|
||||
<div style="margin-top: 15px;" ng-if="!extension.Enabled && extension.Available">
|
||||
<a href="https://2-portainer.pi.bypronto.com/checkout/?add-to-cart={{ extension.ProductId }}&quantity={{ formValues.instances }}" target="_blank" class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;">
|
||||
<a href="{{ extension.ShopURL }}&quantity={{ formValues.instances }}" target="_blank" class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;">
|
||||
Buy
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 10px;" ng-if="!extension.Enabled && extension.Available">
|
||||
<a ui-sref="portainer.extensions" class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;">
|
||||
Add license key
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 15px;" ng-if="!extension.Enabled && !extension.Available">
|
||||
<btn class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;" disabled>Coming soon</btn>
|
||||
</div>
|
||||
|
@ -92,10 +98,16 @@
|
|||
Description
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="small text-muted">
|
||||
{{ extension.Description }}
|
||||
</span>
|
||||
<div class="form-group" ng-if="extension.Description">
|
||||
<div class="text-muted" style="font-size: 90%;" ng-bind-html="extension.Description"></div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="!extension.Description">
|
||||
<div class="small text-muted">
|
||||
<p>
|
||||
<i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true"></i>
|
||||
Description for this extension unavailable at the moment.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
@ -113,7 +125,7 @@
|
|||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div ng-repeat="image in extension.Images" style="margin-top: 25px; cursor: zoom-in;">
|
||||
<img ng-src="{{image}}" ng-click="enlargeImage(image)"/>
|
||||
<img ng-src="{{image}}" ng-click="enlargeImage(image)" style="max-width: 1024px;" />
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
|
||||
<div style="margin-top: 15px;" ng-disabled="!formValues.hostCount">
|
||||
<a href="https://2-portainer.pi.bypronto.com/checkout/?add-to-cart={{ product.ProductId }}&quantity={{ formValues.hostCount }}" target="_blank" class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;">
|
||||
<a href="https://portainer.io/checkout/?add-to-cart={{ product.ProductId }}&quantity={{ formValues.hostCount }}" target="_blank" class="btn btn-primary btn-sm" style="width: 100%; margin-left: 0;">
|
||||
Buy
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -174,6 +174,11 @@ a[ng-click]{
|
|||
box-shadow: 0 3px 10px -2px rgba(161, 170, 166, 0.5);
|
||||
}
|
||||
|
||||
.blocklist-item--disabled {
|
||||
cursor: auto;
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
.blocklist-item--selected {
|
||||
border: 2px solid #bbbbbb;
|
||||
background-color: #ececec;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 79 KiB |
Loading…
Reference in New Issue