2017-05-18 21:00:08 +00:00
< rd-header id = "view-top" >
2016-08-24 03:45:44 +00:00
< rd-header-title title = "Application templates list" >
2016-08-23 06:09:14 +00:00
< a data-toggle = "tooltip" title = "Refresh" ui-sref = "templates" ui-sref-opts = "{reload: true}" >
< i class = "fa fa-refresh" aria-hidden = "true" > < / i >
< / a >
2017-01-24 01:28:40 +00:00
< i id = "loadTemplatesSpinner" class = "fa fa-cog fa-spin" style = "margin-left: 5px;" > < / i >
2016-08-23 06:09:14 +00:00
< / rd-header-title >
2016-08-24 03:45:44 +00:00
< rd-header-content > Templates< / rd-header-content >
2016-08-23 06:09:14 +00:00
< / rd-header >
2017-05-18 21:00:08 +00:00
< div class = "row" style = "height: 90%" >
< div class = "col-sm-12" ng-if = "state.selectedTemplate" >
2016-08-23 06:09:14 +00:00
< rd-widget >
2017-02-10 01:11:36 +00:00
< rd-widget-custom-header icon = "state.selectedTemplate.Logo" title = "state.selectedTemplate.Image" >
2017-05-18 21:00:08 +00:00
< div class = "pull-right" >
< button type = "button" class = "btn btn-sm btn-primary" ng-click = "unselectTemplate()" > Hide< / button >
< / div >
2016-10-02 03:11:20 +00:00
< / rd-widget-custom-header >
2016-08-23 06:09:14 +00:00
< rd-widget-body classes = "padding" >
2017-05-18 21:00:08 +00:00
2016-08-23 06:09:14 +00:00
< form class = "form-horizontal" >
2017-04-05 08:13:32 +00:00
<!-- description -->
2017-05-18 21:00:08 +00:00
< div ng-if = "state.selectedTemplate.Note" >
< div class = "col-sm-12 form-section-title" >
Information
< / div >
< div class = "form-group" >
< div class = "col-sm-12" >
< span class = "template-note" ng-bind-html = "state.selectedTemplate.Note" > < / span >
< / div >
2016-09-23 04:54:58 +00:00
< / div >
< / div >
2017-04-05 08:13:32 +00:00
<!-- !description -->
2017-05-18 21:00:08 +00:00
< div class = "col-sm-12 form-section-title" >
Configuration
< / div >
<!-- name - input -->
2016-08-23 06:09:14 +00:00
< div class = "form-group" >
2017-05-18 21:00:08 +00:00
< label for = "container_name" class = "col-sm-2 control-label text-left" > Name< / label >
< div class = "col-sm-10" >
2017-02-10 01:11:36 +00:00
< input type = "text" name = "container_name" class = "form-control" ng-model = "formValues.name" placeholder = "e.g. web (optional)" >
2016-08-23 06:09:14 +00:00
< / div >
2017-05-18 21:00:08 +00:00
< / div >
<!-- !name - input -->
<!-- network - input -->
< div class = "form-group" >
< label for = "container_network" class = "col-sm-2 control-label text-left" > Network< / label >
< div class = "col-sm-10" >
2016-12-25 20:34:02 +00:00
< select class = "form-control" ng-options = "net.Name for net in availableNetworks" ng-model = "formValues.network" >
2016-08-24 06:32:54 +00:00
< option disabled hidden value = "" > Select a network< / option >
2016-08-23 06:09:14 +00:00
< / select >
< / div >
< / div >
2017-05-18 21:00:08 +00:00
<!-- !network - input -->
2017-03-12 16:24:15 +00:00
<!-- env -->
2017-02-10 01:11:36 +00:00
< div ng-repeat = "var in state.selectedTemplate.Env" ng-if = "!var.set" class = "form-group" >
2016-08-24 06:32:54 +00:00
< label for = "field_{{ $index }}" class = "col-sm-2 control-label text-left" > {{ var.label }}< / label >
< div class = "col-sm-10" >
2017-01-22 23:14:34 +00:00
< select ng-if = "applicationState.endpoint.mode.provider !== 'DOCKER_SWARM' && var.type === 'container'" ng-options = "container|containername for container in runningContainers" class = "form-control" ng-model = "var.value" >
2016-08-24 06:32:54 +00:00
< option selected disabled hidden value = "" > Select a container< / option >
< / select >
2017-01-22 23:14:34 +00:00
< select ng-if = "applicationState.endpoint.mode.provider === 'DOCKER_SWARM' && var.type === 'container'" ng-options = "container|swarmcontainername for container in runningContainers" class = "form-control" ng-model = "var.value" >
2016-08-24 06:32:54 +00:00
< option selected disabled hidden value = "" > Select a container< / option >
< / select >
< input ng-if = "!var.type || !var.type === 'container'" type = "text" class = "form-control" ng-model = "var.value" id = "field_{{ $index }}" >
2016-08-23 06:09:14 +00:00
< / div >
< / div >
2017-03-12 16:24:15 +00:00
<!-- !env -->
2017-05-23 18:56:10 +00:00
<!-- access - control -->
2017-08-10 08:35:23 +00:00
< por-access-control-form form-data = "formValues.AccessControlData" ng-if = "applicationState.application.authentication" > < / por-access-control-form >
2017-05-23 18:56:10 +00:00
<!-- !access - control -->
2016-10-27 06:55:44 +00:00
< div class = "form-group" >
< div class = "col-sm-12" >
< a class = "small interactive" ng-if = "!state.showAdvancedOptions" ng-click = "state.showAdvancedOptions = true;" >
2016-10-27 08:33:39 +00:00
< i class = "fa fa-plus space-right" aria-hidden = "true" > < / i > Show advanced options
2016-10-27 06:55:44 +00:00
< / a >
< a class = "small interactive" ng-if = "state.showAdvancedOptions" ng-click = "state.showAdvancedOptions = false;" >
2016-10-27 08:33:39 +00:00
< i class = "fa fa-minus space-right" aria-hidden = "true" > < / i > Hide advanced options
2016-10-27 06:55:44 +00:00
< / a >
< / div >
< / div >
2017-02-13 05:16:14 +00:00
< div ng-if = "state.showAdvancedOptions" >
<!-- port - mapping -->
< div class = "form-group" >
< div class = "col-sm-12" style = "margin-top: 5px;" >
< label class = "control-label text-left" > Port mapping< / label >
< span class = "label label-default interactive" style = "margin-left: 10px;" ng-click = "addPortBinding()" >
< i class = "fa fa-plus-circle" aria-hidden = "true" > < / i > map additional port
< / span >
< / div >
< div class = "col-sm-12" style = "margin-top: 10px" ng-if = "state.selectedTemplate.Ports.length > 0" >
< span class = "small text-muted" > Portainer will automatically assign a port if you leave the host port empty.< / span >
< / div >
<!-- !port - mapping -->
<!-- port - mapping - input - list -->
< div class = "col-sm-12" >
< div class = "col-sm-12 form-inline" style = "margin-top: 10px;" >
< div ng-repeat = "portBinding in state.selectedTemplate.Ports" style = "margin-top: 2px;" >
<!-- host - port -->
< div class = "input-group col-sm-4 input-group-sm" >
< span class = "input-group-addon" > host< / span >
< input type = "text" class = "form-control" ng-model = "portBinding.hostPort" placeholder = "e.g. 80 or 1.2.3.4:80 (optional)" >
< / div >
<!-- !host - port -->
< span style = "margin: 0 10px 0 10px;" >
< i class = "fa fa-long-arrow-right" aria-hidden = "true" > < / i >
< / span >
<!-- container - port -->
< div class = "input-group col-sm-4 input-group-sm" >
< span class = "input-group-addon" > container< / span >
< input type = "text" class = "form-control" ng-model = "portBinding.containerPort" placeholder = "e.g. 80" >
< / div >
<!-- !container - port -->
<!-- protocol - actions -->
< div class = "input-group col-sm-3 input-group-sm" >
< div class = "btn-group btn-group-sm" >
2017-03-27 12:44:39 +00:00
< label class = "btn btn-primary" ng-model = "portBinding.protocol" uib-btn-radio = "'tcp'" > TCP< / label >
< label class = "btn btn-primary" ng-model = "portBinding.protocol" uib-btn-radio = "'udp'" > UDP< / label >
2017-02-13 05:16:14 +00:00
< / div >
< button class = "btn btn-sm btn-danger" type = "button" ng-click = "removePortBinding($index)" >
< i class = "fa fa-trash" aria-hidden = "true" > < / i >
< / button >
< / div >
<!-- !protocol - actions -->
< / div >
2016-10-27 06:55:44 +00:00
< / div >
< / div >
< / div >
<!-- !port - mapping - input - list -->
2017-02-13 05:16:14 +00:00
<!-- volume - mapping -->
< div class = "form-group" >
< div class = "col-sm-12" style = "margin-top: 5px;" >
< label class = "control-label text-left" > Volume mapping< / label >
< span class = "label label-default interactive" style = "margin-left: 10px;" ng-click = "addVolume()" >
< i class = "fa fa-plus-circle" aria-hidden = "true" > < / i > map additional volume
< / span >
< / div >
< div class = "col-sm-12" style = "margin-top: 10px" ng-if = "state.selectedTemplate.Volumes.length > 0" >
< span class = "small text-muted" > Portainer will automatically create and map a local volume when using the < b > auto< / b > option.< / span >
< / div >
< div ng-repeat = "volume in state.selectedTemplate.Volumes" >
< div class = "col-sm-12" style = "margin-top: 10px;" >
<!-- volume - line1 -->
< div class = "col-sm-12 form-inline" >
<!-- container - path -->
< div class = "input-group input-group-sm col-sm-6" >
< span class = "input-group-addon" > container< / span >
< input type = "text" class = "form-control" ng-model = "volume.containerPath" placeholder = "e.g. /path/in/container" >
< / div >
<!-- !container - path -->
<!-- volume - type -->
< div class = "input-group col-sm-5" style = "margin-left: 5px;" >
< div class = "btn-group btn-group-sm" >
< label class = "btn btn-primary" ng-model = "volume.type" uib-btn-radio = "'auto'" ng-click = "volume.name = ''" > Auto< / label >
< label class = "btn btn-primary" ng-model = "volume.type" uib-btn-radio = "'volume'" ng-click = "volume.name = ''" > Volume< / label >
< label class = "btn btn-primary" ng-model = "volume.type" uib-btn-radio = "'bind'" ng-click = "volume.name = ''" > Bind< / label >
< / div >
< button class = "btn btn-sm btn-danger" type = "button" ng-click = "removeVolume($index)" >
< i class = "fa fa-trash" aria-hidden = "true" > < / i >
< / button >
< / div >
<!-- !volume - type -->
< / div >
<!-- !volume - line1 -->
<!-- volume - line2 -->
< div class = "col-sm-12 form-inline" style = "margin-top: 5px;" ng-if = "volume.type !== 'auto'" >
< i class = "fa fa-long-arrow-right" aria-hidden = "true" > < / i >
<!-- volume -->
< div class = "input-group input-group-sm col-sm-6" ng-if = "volume.type === 'volume'" >
< span class = "input-group-addon" > volume< / span >
< select class = "form-control" ng-model = "volume.name" >
< option selected disabled hidden value = "" > Select a volume< / option >
< option ng-repeat = "vol in availableVolumes" ng-value = "vol.Name" > {{ vol.Name|truncate:30}}< / option >
< / select >
< / div >
<!-- !volume -->
<!-- bind -->
< div class = "input-group input-group-sm col-sm-6" ng-if = "volume.type === 'bind'" >
< span class = "input-group-addon" > host< / span >
< input type = "text" class = "form-control" ng-model = "volume.name" placeholder = "e.g. /path/on/host" >
< / div >
<!-- !bind -->
<!-- read - only -->
< div class = "input-group input-group-sm col-sm-5" style = "margin-left: 5px;" >
< div class = "btn-group btn-group-sm" >
2017-03-27 12:44:39 +00:00
< label class = "btn btn-primary" ng-model = "volume.readOnly" uib-btn-radio = "false" > Writable< / label >
< label class = "btn btn-primary" ng-model = "volume.readOnly" uib-btn-radio = "true" > Read-only< / label >
2017-02-13 05:16:14 +00:00
< / div >
< / div >
<!-- !read - only -->
< / div >
<!-- !volume - line2 -->
< / div >
< / div >
< / div >
<!-- !volume - mapping -->
2016-10-27 06:55:44 +00:00
< / div >
2017-02-13 05:16:14 +00:00
<!-- !advanced - options -->
2017-05-18 21:00:08 +00:00
<!-- actions -->
2016-10-02 03:11:20 +00:00
< div class = "form-group" >
< div class = "col-sm-12" >
2017-03-27 12:44:39 +00:00
< button type = "button" class = "btn btn-primary btn-sm" ng-disabled = "!formValues.network" ng-click = "createTemplate()" > Create< / button >
2016-10-02 03:11:20 +00:00
< i id = "createContainerSpinner" class = "fa fa-cog fa-spin" style = "margin-left: 5px; display: none;" > < / i >
2017-07-12 07:51:51 +00:00
< span class = "small text-muted" style = "margin-left: 10px" ng-if = "globalNetworkCount === 0 && applicationState.endpoint.mode.provider === 'DOCKER_SWARM' && !state.formValidationError" >
2017-04-05 08:13:32 +00:00
When using Swarm, we recommend deploying containers in a shared network. Looks like you don't have any shared network, head over the < a ui-sref = "networks" > networks view< / a > to create one.
< / span >
2017-07-12 07:51:51 +00:00
< span ng-if = "applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE' && !state.formValidationError" style = "margin-left: 10px" >
2017-04-05 08:13:32 +00:00
< i class = "fa fa-exclamation-triangle" aria-hidden = "true" > < / i >
< span class = "small text-muted" style = "margin-left: 5px;" > App templates cannot be deployed as Swarm Mode services for the moment. You can still use them to quickly deploy containers on the Docker host.< / span >
< / span >
2017-07-12 07:51:51 +00:00
< span class = "text-danger" ng-if = "state.formValidationError" style = "margin-left: 5px;" > {{ state.formValidationError }}< / span >
2016-10-02 03:11:20 +00:00
< / div >
< / div >
2017-05-18 21:00:08 +00:00
<!-- !actions -->
2016-08-23 06:09:14 +00:00
< / form >
2017-05-18 21:00:08 +00:00
2016-08-23 06:09:14 +00:00
< / rd-widget-body >
< / rd-widget >
< / div >
2017-05-18 21:00:08 +00:00
< div class = "col-sm-12" style = "height: 100%" >
< rd-template-widget >
< rd-widget-header icon = "fa-rocket" title = "Templates" >
< div ng-if = "availableCategories.length > 0" class = "pull-right" >
Category
< select ng-model = "state.filters.Categories" >
< option value = "!" > All< / option >
< option ng-repeat = "category in availableCategories" value = "{{ category }}" > {{ category }}< / option >
2017-01-24 01:28:40 +00:00
< / select >
2016-10-02 03:11:20 +00:00
< / div >
< / rd-widget-header >
2017-05-18 21:00:08 +00:00
< rd-widget-taskbar >
< div >
<!-- Platform -->
< span class = "btn-group btn-group-sm" style = "margin-right: 15px;" >
< label class = "btn btn-primary" ng-model = "state.filters.Platform" uib-btn-radio = "'!'" >
All
< / label >
< label class = "btn btn-primary" ng-model = "state.filters.Platform" uib-btn-radio = "'windows'" >
< i class = "fa fa-windows" aria-hidden = "true" > < / i >
Windows
< / label >
< label class = "btn btn-primary" ng-model = "state.filters.Platform" uib-btn-radio = "'linux'" >
< i class = "fa fa-linux" aria-hidden = "true" > < / i >
Linux
< / label >
< / span >
< / div >
< / rd-widget-taskbar >
< rd-widget-body classes = "padding template-widget-body" >
2016-10-02 03:11:20 +00:00
< div class = "template-list" >
2017-05-18 21:00:08 +00:00
<!-- template -->
2017-05-24 12:38:53 +00:00
< div ng-repeat = "tpl in templates | filter:state.filters:true" class = "template-container" id = "template_{{ tpl.index }}" ng-click = "selectTemplate(tpl.index, $index)" >
2017-05-18 21:00:08 +00:00
< div class = "template-main" >
<!-- template - image -->
< span class = "" >
< img class = "template-logo" ng-src = "{{ tpl.Logo }}" / >
< / span >
<!-- !template - image -->
<!-- template - details -->
< span class = "col-sm-12" >
<!-- template - line1 -->
< div class = "template-line" >
< span class = "template-title" >
{{ tpl.Title }}
< / span >
< span >
< i class = "fa fa-windows" aria-hidden = "true" ng-if = "tpl.Platform === 'windows'" > < / i >
< i class = "fa fa-linux" aria-hidden = "true" ng-if = "tpl.Platform === 'linux'" > < / i >
<!-- Arch / Platform -->
< / span >
< / div >
<!-- !template - line1 -->
<!-- template - line2 -->
< div class = "template-line" >
< span class = "template-description" >
{{ tpl.Description }}
< / span >
< span class = "small text-muted" ng-if = "tpl.Categories.length > 0" >
{{ tpl.Categories.join(', ') }}
< / span >
< / div >
<!-- !template - line2 -->
< / span >
<!-- !template - details -->
< / div >
<!-- !template -->
2016-10-02 03:11:20 +00:00
< / div >
2016-10-08 21:49:24 +00:00
< div ng-if = "!templates" class = "text-center text-muted" >
Loading...
< / div >
2017-05-24 12:38:53 +00:00
< div ng-if = "(templates | filter:state.filters:true).length == 0" class = "text-center text-muted" >
2016-10-07 04:55:09 +00:00
No templates available.
< / div >
2016-10-02 03:11:20 +00:00
< / div >
< / rd-widget-body >
2017-05-18 21:00:08 +00:00
< / rd-template-widget >
2016-08-23 06:09:14 +00:00
< / div >
2017-05-18 21:00:08 +00:00
2016-08-23 06:09:14 +00:00
< / div >