2015-07-20 00:09:47 -07:00
<!-- Modal install app -->
2015-07-28 13:06:55 +02:00
< div class = "modal fade appstore-install" id = "appInstallModal" tabindex = "-1" role = "dialog" aria-labelledby = "updateModalLabel" aria-hidden = "true" >
2015-07-20 00:09:47 -07:00
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2015-07-28 12:53:33 +02:00
< img ng-src = "{{appInstall.app.iconUrl}}" onerror = "this.onerror=null;this.src='img/appicon_fallback.png'" class = "app-icon" / >
2016-01-29 12:29:35 +01:00
< h3 class = "appstore-install-title" title = "Version {{ appInstall.app.manifest.version }}" > {{ appInstall.app.manifest.title }} < span class = "badge badge-danger" ng-show = "appInstall.app.publishState === 'testing'" > Testing< / span > < / h3 >
2015-07-28 12:53:33 +02:00
< br / >
2016-07-13 10:55:01 -07:00
< span class = "appstore-install-meta" > < a href = "{{ appInstall.app.manifest.website }}" target = "_blank" > {{ appInstall.app.manifest.author }}< / a > < / span >
2015-07-28 12:53:33 +02:00
< br / >
2016-07-13 10:55:01 -07:00
< span class = "appstore-install-meta" > Last updated {{ appInstall.app.creationDate | prettyDate }}< / span >
2016-12-30 12:51:41 +01:00
< br / >
2017-01-09 11:53:18 +01:00
< span class = "appstore-install-meta hand" > Requires atleast {{ appInstall.app.manifest.memoryLimit | prettyMemory }}MB memory< / span >
2015-07-20 00:09:47 -07:00
< / div >
< div class = "modal-body" >
< div class = "collapse" id = "collapseInstallForm" data-toggle = "false" >
2016-02-26 12:50:05 +01:00
< form role = "form" name = "appInstallForm" ng-submit = "appInstall.submit()" autocomplete = "off" >
2015-07-20 00:09:47 -07:00
< div class = "has-error text-center" ng-show = "appInstall.error.other" ng-bind-html = "appInstall.error.other" > < / div >
< div class = "form-group" ng-class = "{ 'has-error': (appInstallForm.location.$dirty && appInstallForm.location.$invalid) || (!appInstallForm.location.$dirty && appInstall.error.location) }" >
< label class = "control-label" for = "appInstallLocationInput" > Location {{ appInstall.error.location }} < / label >
< div class = "input-group form-inline" >
< input type = "text" class = "form-control" ng-model = "appInstall.location" id = "appInstallLocationInput" name = "location" placeholder = "Leave empty to use bare domain" autofocus >
< div class = "input-group-addon" >
{{ !appInstall.location ? '' : (config.isCustomDomain ? '.' : '-') }}{{ config.fqdn }}
< / div >
< / div >
< / div >
2015-10-28 20:30:15 +01:00
2017-01-10 13:47:58 +01:00
< p class = "text-center" ng-show = "appInstall.location && dnsConfig.provider === 'manual' && !dnsConfig.wildcard" >
< b > Do not forget, to add an A record for {{ appInstall.location }}.{{ config.fqdn }}< / b >
< br >
< / p >
2015-07-20 00:09:47 -07:00
< div class = "has-error text-center" ng-show = "appInstall.error.port" > {{ appInstall.error.port }}< / div >
< div ng-repeat = "(env, info) in appInstall.portBindingsInfo" >
< ng-form name = "portInfo_form" >
< div class = "form-group" ng-class = "{ 'has-error': (!appInstallForm.itemName{{$index}}.$dirty && appInstall.error.port) || (portInfo_form.itemName{{$index}}.$dirty && portInfo_form.itemName{{$index}}.$invalid) }" >
< label class = "control-label" for = "inputPortInfo{{env}}" > < input type = "checkbox" ng-model = "appInstall.portBindingsEnabled[env]" > {{ info.description }} ({{ hostPortMin }} - {{ hostPortMax }})< / label >
< input type = "number" class = "form-control" ng-model = "appInstall.portBindings[env]" ng-disabled = "!appInstall.portBindingsEnabled[env]" id = "inputPortInfo{{env}}" later-name = "itemName{{$index}}" min = "{{hostPortMin}}" max = "{{hostPortMax}}" required >
< / div >
< / ng-form >
< / div >
2015-10-28 20:30:15 +01:00
2016-11-12 06:37:55 +05:30
< div class = "form-group" ng-show = "appInstall.customAuth" >
2016-09-07 16:24:19 -07:00
< label class = "control-label" > Access control< / label >
< p >
2016-11-21 12:57:42 +01:00
This app has it's own access control and does not use the Cloudron user management.
2016-09-07 16:24:19 -07:00
< / p >
< / div >
2016-09-11 23:01:25 -07:00
< div class = "form-group" ng-show = "appInstall.app.manifest.addons.email" >
< label class = "control-label" > Access control< / label >
< p >
2016-09-29 12:31:26 -07:00
This app authenticates all users using IMAP & SMTP and requires the mail server
to be enabled (under settings).
2016-09-11 23:01:25 -07:00
< / p >
< / div >
2016-11-12 06:37:55 +05:30
< div class = "form-group" ng-hide = "appInstall.customAuth || appInstall.app.manifest.addons.email" >
2016-02-26 11:47:20 +01:00
< label class = "control-label" > Access control< / label >
2016-12-08 22:35:49 +01:00
< div class = "radio" ng-show = "appInstall.optionalSso" >
< label >
< input type = "radio" ng-model = "appInstall.accessRestrictionOption" value = "nosso" >
Disable Cloudron user management
< / label >
< / div >
2016-02-26 11:47:20 +01:00
< div class = "radio" >
< label >
2016-09-06 17:56:31 -07:00
< input type = "radio" ng-model = "appInstall.accessRestrictionOption" value = "any" >
2016-09-07 01:13:20 -07:00
All users
2016-02-26 11:47:20 +01:00
< / label >
< / div >
< div class = "radio" >
< label >
2016-09-06 17:56:31 -07:00
< input type = "radio" ng-model = "appInstall.accessRestrictionOption" value = "groups" ng-disabled = "groups.length <= 1" >
2016-11-24 12:11:23 +01:00
Restrict to groups < span class = "label label-danger" ng-show = "appInstall.accessRestrictionOption === 'groups' && !appInstall.isAccessRestrictionValid()" > Select at least one group< / span >
2016-02-26 11:47:20 +01:00
< / label >
< / div >
2016-12-08 22:43:58 +01:00
< div ng-show = "groups.length <= 1" style = "margin-left: 20px;" > No groups available. < a href = "#/users" > Create groups< / a > < / div >
2016-02-26 11:47:20 +01:00
< div >
2016-12-08 22:40:40 +01:00
< div style = "margin-left: 20px;" >
2016-02-26 11:47:20 +01:00
< span ng-repeat = "group in groups | ignoreAdminGroup" >
2016-09-06 17:56:31 -07:00
< button class = "btn btn-default" type = "button" ng-disabled = "appInstall.accessRestrictionOption !== 'groups'" ng-click = "appInstall.toggleGroup(group);" ng-class = "{ 'btn-primary': (appInstall.accessRestriction.groups && appInstall.accessRestriction.groups.indexOf(group.id) !== -1) }" > {{ group.name }}< / button >
2016-02-26 11:47:20 +01:00
< / span >
< / div >
< / div >
2015-07-20 00:09:47 -07:00
< / div >
2015-10-28 20:30:15 +01:00
< br / >
2016-01-13 15:53:14 +01:00
< div class = "hide" >
2015-10-29 21:01:16 +01:00
< label class = "control-label" for = "appInstallCertificateInput" ng-show = "config.isCustomDomain" > Certificate (optional)< / label >
< div class = "has-error text-center" ng-show = "appInstall.error.cert && config.isCustomDomain" > {{ appInstall.error.cert }}< / div >
2015-10-28 20:50:55 +01:00
< div class = "form-group" ng-class = "{ 'has-error': !appInstallForm.certificate.$dirty && appInstall.error.cert }" ng-show = "config.isCustomDomain" >
2015-10-28 20:30:15 +01:00
< div class = "input-group" >
< input type = "file" id = "appInstallCertificateFileInput" style = "display:none" / >
2015-10-28 21:20:59 +01:00
< input type = "text" class = "form-control" placeholder = "Certificate" ng-model = "appInstall.certificateFileName" id = "appInstallCertificateInput" name = "certificate" onclick = "getElementById('appInstallCertificateFileInput').click();" style = "cursor: pointer;" ng-required = "appInstall.keyFileName" >
2015-10-28 20:30:15 +01:00
< span class = "input-group-addon" >
< i class = "fa fa-upload" onclick = "getElementById('appInstallCertificateFileInput').click();" > < / i >
< / span >
< / div >
< / div >
2015-10-28 20:50:55 +01:00
< div class = "form-group" ng-class = "{ 'has-error': !appInstallForm.key.$dirty && appInstall.error.cert }" ng-show = "config.isCustomDomain" >
2015-10-28 20:30:15 +01:00
< div class = "input-group" >
< input type = "file" id = "appInstallKeyFileInput" style = "display:none" / >
2015-10-28 21:20:59 +01:00
< input type = "text" class = "form-control" placeholder = "Key" ng-model = "appInstall.keyFileName" id = "appInstallKeyInput" name = "key" onclick = "getElementById('appInstallKeyFileInput').click();" style = "cursor: pointer;" ng-required = "appInstall.certificateFileName" >
2015-10-28 20:30:15 +01:00
< span class = "input-group-addon" >
< i class = "fa fa-upload" onclick = "getElementById('appInstallKeyFileInput').click();" > < / i >
< / span >
< / div >
< / div >
2016-01-13 15:53:14 +01:00
< / div >
2015-10-28 20:30:15 +01:00
2015-07-20 00:09:47 -07:00
< input class = "ng-hide" type = "submit" ng-disabled = "appInstallForm.$invalid || busy" / >
< / form >
< / div >
< div class = "collapse" id = "collapseMediaLinksCarousel" data-toggle = "false" >
< div ng-repeat = "mediaLink in appInstall.mediaLinks" class = "slick-item" style = "background-image: url('{{mediaLink}}');" ng-show = "appInstall.mediaLinks.length == 1" > < / div >
< slick init-onload = "true" current-index = "0" autoplay = "true" arrows = "false" autoplay-speed = "2000" data = "appInstall.mediaLinks" ng-show = "appInstall.mediaLinks.length > 1" >
< div ng-repeat = "mediaLink in appInstall.mediaLinks" class = "slick-item" style = "background-image: url('{{mediaLink}}');" > < / div >
< / slick >
< div class = "appstore-install-description" >
< div ng-bind-html = "appInstall.app.manifest.description | markdown2html" > < / div >
< / div >
< / div >
2015-10-22 10:40:33 +02:00
< div class = "collapse" id = "collapseResourceConstraint" data-toggle = "false" >
2016-02-25 12:41:15 +01:00
< h4 class = "text-danger" > This Cloudron is running low on resources.< / h4 >
2016-11-29 13:28:17 +01:00
< p ng-show = "config.provider === 'caas'" > Please upgrade to a bigger plan. Alternately, free up resources by uninstalling unused applications.< / p >
< p ng-hide = "config.provider === 'caas'" > Please upgrade to a server instance with more memory. Alternately, free up resources by uninstalling unused applications.< / p >
2015-10-22 10:40:33 +02:00
< / div >
2016-09-07 12:36:49 -07:00
< div class = "collapse" id = "postInstallMessage" data-toggle = "false" >
< div class = "appstore-install-description" >
2016-11-24 15:33:45 +01:00
< div ng-bind-html = "appInstall.app.manifest.postInstallMessage | postInstallMessage:appInstall.app | markdown2html" > < / div >
2016-09-07 12:36:49 -07:00
< / div >
< / div >
2015-07-20 00:09:47 -07:00
< / div >
< div class = "modal-footer" >
2016-09-07 12:36:49 -07:00
< button type = "button" class = "btn btn-default" ng-show = "appInstall.state !== 'postInstall'" data-dismiss = "modal" > Close< / button >
2016-09-07 13:11:28 -07:00
< button type = "button" class = "btn btn-default" ng-show = "appInstall.state === 'postInstall'" data-dismiss = "modal" ng-click = "appInstall.switchToAppsView()" > Got it< / button >
2016-09-07 11:49:44 -07:00
< button type = "button" class = "btn btn-success" ng-show = "config.provider === 'caas' && user.admin && appInstall.state === 'resourceConstraint'" ng-click = "showRequestUpgrade()" > Upgrade Cloudron< / button >
< button type = "button" class = "btn btn-danger" ng-show = "(config.isDev || config.provider !== 'caas') && user.admin && appInstall.state === 'resourceConstraint'" ng-click = "appInstall.showForm(true)" > Install anyway< / button >
< button type = "button" class = "btn btn-success" ng-show = "appInstall.state === 'appInfo' && user.admin" ng-click = "appInstall.showForm()" > Install< / button >
< button type = "button" class = "btn btn-success" ng-show = "appInstall.state === 'installForm' && user.admin" ng-click = "appInstall.submit()" ng-disabled = "appInstallForm.$invalid || appInstall.busy" > < i class = "fa fa-spinner fa-pulse" ng-show = "appInstall.busy" > < / i > Install< / button >
2015-07-20 00:09:47 -07:00
< / div >
< / div >
< / div >
< / div >
2015-08-09 14:48:00 +02:00
<!-- Modal feedback -->
< div class = "modal fade" id = "feedbackModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > App Feedback< / h4 >
< / div >
< div class = "modal-body" >
< fieldset >
2016-02-26 12:50:05 +01:00
< form name = "feedbackForm" ng-submit = "feedback.submit()" >
2015-08-09 14:48:00 +02:00
< div ng-show = "feedback.error" class = "text-danger text-bold" > {{feedback.error}}< / div >
< textarea class = "form-control" id = "feedbackDescriptionTextarea" cols = "3" ng-model = "feedback.description" ng-minlength = "1" required placeholder = "Name, Category, Links ..." autofocus > < / textarea >
< input class = "ng-hide" type = "submit" ng-disabled = "feedbackForm.$invalid || feedback.busy" / >
< / form >
< / fieldset >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2016-02-26 12:50:05 +01:00
< button type = "button" class = "btn btn-success" ng-click = "feedback.submit()" ng-disabled = "feedbackForm.$invalid || feedback.busy" > < i class = "fa fa-fw fa-paper-plane" > < / i > Submit< / button >
2015-08-09 14:48:00 +02:00
< / div >
< / div >
< / div >
< / div >
2015-08-10 16:16:38 +02:00
<!-- Modal app not found -->
< div class = "modal fade" id = "appNotFoundModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
< h4 class = "modal-title" > App not found< / h4 >
< / div >
< div class = "modal-body" >
There is no such app < b > {{ appNotFound.appId }}< / b > < span ng-show = "appNotFound.version" > with version < b > {{ appNotFound.version }}< / b > < / span > .
< / div >
< div class = "modal-footer" >
2016-09-28 15:23:17 -07:00
< button type = "button" class = "btn btn-primary" data-dismiss = "modal" > OK< / button >
2015-08-10 16:16:38 +02:00
< / div >
< / div >
< / div >
< / div >
2016-08-01 13:42:28 +02:00
<!-- Modal appstore login -->
< div class = "modal fade" id = "appstoreLoginModal" tabindex = "-1" role = "dialog" >
< div class = "modal-dialog" >
< div class = "modal-content" >
< div class = "modal-header" >
2016-08-02 16:15:00 +02:00
< h4 class = "modal-title" ng-hide = "appstoreLogin.register" > Login to the Cloudron App Store< / h4 >
< h4 class = "modal-title" ng-show = "appstoreLogin.register" > Sign up at the Cloudron App Store< / h4 >
2016-08-01 13:42:28 +02:00
< / div >
< div class = "modal-body" >
< center >
< img ng-src = "{{ config.webServerOrigin }}/img/logo.png" width = "128px" height = "128px" / >
< br / > < br / >
< p > For using the Cloudron App Store, you have to login with your < a href = "{{ config.webServerOrigin }}" target = "_blank" > cloudron.io< / a > account.< / p >
< br / >
2016-08-01 16:09:30 +02:00
< small class = "text-danger" ng-show = "appstoreLogin.error.generic" > {{ appstoreLogin.error.generic }}< / small >
2016-08-01 13:42:28 +02:00
< / center >
< form name = "appstoreLoginForm" role = "form" novalidate ng-submit = "appstoreLogin.submit()" autocomplete = "off" >
< input type = "password" style = "display: none;" >
2016-08-01 16:09:30 +02:00
< div class = "form-group" ng-class = "{ 'has-error': (appstoreLoginForm.email.$dirty && appstoreLoginForm.email.$invalid) || appstoreLogin.error.generic }" >
2016-08-01 13:42:28 +02:00
< label class = "control-label" > Email Address< / label >
2016-08-01 16:09:30 +02:00
< input type = "email" class = "form-control" ng-model = "appstoreLogin.email" id = "inputAppstoreLoginEmail" name = "email" required autofocus >
< div class = "control-label" ng-show = "(!appstoreLoginForm.email.$dirty && appstoreLogin.error.email) || (appstoreLoginForm.email.$dirty && appstoreLoginForm.email.$invalid) || appstoreLogin.error.email" >
2016-08-01 13:42:28 +02:00
< small ng-show = "appstoreLoginForm.email.$error.required" > A valid email address is required< / small >
< small ng-show = "(appstoreLoginForm.email.$dirty && appstoreLoginForm.email.$invalid) && !appstoreLoginForm.email.$error.required" > The Email address is not valid< / small >
< / div >
< / div >
2016-08-01 16:09:30 +02:00
< div class = "form-group" ng-class = "{ 'has-error': (!appstoreLoginForm.password.$dirty && appstoreLogin.error.password) || (appstoreLoginForm.password.$dirty && appstoreLoginForm.password.$invalid) || appstoreLogin.error.generic }" >
2016-08-01 13:42:28 +02:00
< label class = "control-label" > Password< / label >
2016-08-01 16:09:30 +02:00
< input type = "password" class = "form-control" ng-model = "appstoreLogin.password" id = "inputAppstoreLoginPassword" name = "password" required >
2016-08-01 13:42:28 +02:00
< div class = "control-label" ng-show = "(!appstoreLoginForm.password.$dirty && appstoreLogin.error.password) || (appstoreLoginForm.password.$dirty && appstoreLoginForm.password.$invalid)" >
< small ng-show = " appstoreLoginForm.password.$dirty && appstoreLoginForm.password.$invalid" > A password is required< / small >
< small ng-show = "!appstoreLoginForm.password.$dirty && appstoreLogin.error.password" > Wrong password< / small >
< / div >
< / div >
< input class = "ng-hide" type = "submit" ng-disabled = "appstoreLoginForm.$invalid" / >
< / form >
< / div >
< div class = "modal-footer" >
2016-08-02 16:15:00 +02:00
< a class = "pull-left" href = "" ng-click = "appstoreLogin.register = true" ng-hide = "appstoreLogin.register" > No Account yet?< / a >
< a class = "pull-left" href = "" ng-click = "appstoreLogin.register = false" ng-show = "appstoreLogin.register" > Already an Account?< / a >
2016-08-01 13:42:28 +02:00
< button type = "button" class = "btn btn-default" data-dismiss = "modal" > Cancel< / button >
2016-08-02 16:15:00 +02:00
< button type = "button" class = "btn btn-success" ng-click = "appstoreLogin.submit()" ng-disabled = "appstoreLoginForm.$invalid || appstoreLogin.busy" >
< i class = "fa fa-spinner fa-pulse" ng-show = "appstoreLogin.busy" > < / i > < span ng-hide = "appstoreLogin.register" > Login< / span > < span ng-show = "appstoreLogin.register" > Sign up< / span >
< / button >
2016-08-01 13:42:28 +02:00
< / div >
< / div >
< / div >
< / div >
2015-07-20 00:09:47 -07:00
< div >
< div class = "row-no-margin" >
< div class = "col-md-2" >
< / div >
< div class = "col-md-8 col-same-height" >
< br / >
< h1 > Available Applications< / h1 >
< br / >
< / div >
< div class = "col-md-2 col-same-height" style = "float: right;" >
< br / >
< div class = "appstore-search" >
< form ng-submit = "search()" >
< div class = "input-group" >
< input type = "text" class = "form-control" placeholder = "Search for..." ng-model = "searchString" ng-change = "search()" >
< span class = "input-group-btn" >
< button class = "btn btn-default" type = "button" type = "submit" ng-click = "search()" > < i class = "fa fa-search" > < / i > < / button >
< / span >
< / div >
< / form >
< / div >
< / div >
< / div >
< div class = "row" >
< div class = "col-md-2" >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === '' }" category = "" > All< / a >
2016-12-07 14:50:20 +01:00
< br / >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'blog' }" category = "blog" > < i class = "fa fa-font" > < / i > Blog< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'chat' }" category = "chat" > < i class = "fa fa-comments-o" > < / i > Chat< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'git' }" category = "git" > < i class = "fa fa-code-fork" > < / i > Code Hosting< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'email' }" category = "email" > < i class = "fa fa-envelope-o" > < / i > Email< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'gallery' }" category = "gallery" > < i class = "fa fa-picture-o" > < / i > Image Galleries< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'sync' }" category = "sync" > < i class = "fa fa-refresh" > < / i > Sync< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'notes' }" category = "notes" > < i class = "fa fa-sticky-note-o" > < / i > Notes< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'project' }" category = "project" > < i class = "fa fa-line-chart" > < / i > Project Management< / a >
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'wiki' }" category = "wiki" > < i class = "fa fa-wikipedia-w" > < / i > Wiki< / a >
2015-07-27 17:09:57 +02:00
< br / >
2017-01-09 19:56:31 -08:00
< a href = "" class = "appstore-category-link" ng-click = "showCategory($event);" ng-class = "{'category-active': category === 'testing' }" category = "testing" ng-show = "false && config.developerMode" > Testing< / a >
2015-08-06 18:30:46 +02:00
< br / >
< br / >
< br / >
2016-02-26 12:50:05 +01:00
< a href = "" ng-click = "feedback.show()" > Missing an app? Let us know.< / a >
2015-07-20 00:09:47 -07:00
< / div >
< div class = "col-md-10" ng-show = "ready && apps.length" >
< div class = "row-no-margin" >
2016-12-16 17:36:16 +01:00
< div class = "col-sm-1 appstore-item" ng-repeat = "app in apps | orderBy:'installCount':true" " >
2016-01-25 16:21:41 +01:00
< div class = "appstore-item-content highlight" ng-click = "gotoApp(app)" ng-class = "{ 'appstore-item-content-testing': (app.publishState === 'testing' || app.publishState === 'pending_approval') }" >
2015-07-28 13:21:23 +02:00
< span class = "badge badge-danger appstore-item-badge-testing" ng-show = "app.publishState === 'testing'" > Testing< / span >
2015-08-17 11:50:06 +02:00
< span class = "badge badge-warning appstore-item-badge-testing" ng-show = "app.publishState === 'pending_approval'" > Pending Approval< / span >
2015-07-20 00:09:47 -07:00
< div class = "appstore-item-content-icon col-same-height" >
< img ng-src = "{{app.iconUrl}}" onerror = "this.onerror=null;this.src='img/appicon_fallback.png'" class = "app-icon" / >
< / div >
< div class = "appstore-item-content-description col-same-height" >
< h4 class = "appstore-item-content-title" > {{ app.manifest.title }}< / h4 >
< div class = "appstore-item-content-tagline text-muted" > {{ app.manifest.tagline }}< / div >
<!-- <div class="appstore - item - rating"><i class="fa fa - star"></i><i class="fa fa - star"></i><i class="fa fa - star"></i><i class="fa fa - star - half - o"></i><i class="fa fa - star - o"></i></div> -->
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "col-md-10 animateMeOpacity loading-banner" ng-show = "ready && !apps.length" >
2015-08-06 18:35:08 +02:00
< h3 class = "text-muted" > No applications in this category.< / h3 >
2016-02-26 12:50:05 +01:00
< a href = "" ng-click = "feedback.show()" > < h3 > Let us know if you miss something.< / h3 > < / a >
2015-07-20 00:09:47 -07:00
< / div >
< div class = "col-md-10 animateMeOpacity loading-banner" ng-show = "!ready" >
< h2 > < i class = "fa fa-spinner fa-pulse" > < / i > Loading< / h2 >
< / div >
< / div >
< / div >
<!-- Offset the footer -->
< br / > < br / >