From 211ae9afad6300245de461dd85a7e632cecce9ca Mon Sep 17 00:00:00 2001 From: Leigh Johnson Date: Mon, 29 Feb 2016 15:01:44 -0500 Subject: [PATCH] create 1/3+2/3 LESS layout, normalize site-wide footer positioning, move CheckLicense factory to separate file, upgrade URL, add file picker + form reset behavior, #1055, #1057, #1007 --- awx/ui/client/legacy-styles/main-layout.less | 2 +- awx/ui/client/src/footer/footer.block.less | 2 +- .../src/license/checkLicense.factory.js | 62 +++++++ .../src/license/fileOnChange.directive.js | 16 ++ awx/ui/client/src/license/license.block.less | 76 ++++----- .../client/src/license/license.controller.js | 53 ++++-- .../client/src/license/license.partial.html | 161 ++++++++++-------- awx/ui/client/src/license/main.js | 60 +------ .../src/shared/layouts/one-plus-two.less | 79 +++++++++ awx/ui/templates/ui/index.html | 5 +- 10 files changed, 325 insertions(+), 191 deletions(-) create mode 100644 awx/ui/client/src/license/checkLicense.factory.js create mode 100644 awx/ui/client/src/license/fileOnChange.directive.js create mode 100644 awx/ui/client/src/shared/layouts/one-plus-two.less diff --git a/awx/ui/client/legacy-styles/main-layout.less b/awx/ui/client/legacy-styles/main-layout.less index 803d554eaf..38c6ffbb19 100644 --- a/awx/ui/client/legacy-styles/main-layout.less +++ b/awx/ui/client/legacy-styles/main-layout.less @@ -60,7 +60,7 @@ body { } #content-container { - margin-top: 40px; + padding-bottom: 40px; } .group-breadcrumbs { diff --git a/awx/ui/client/src/footer/footer.block.less b/awx/ui/client/src/footer/footer.block.less index 86ca6888b5..057d926568 100644 --- a/awx/ui/client/src/footer/footer.block.less +++ b/awx/ui/client/src/footer/footer.block.less @@ -6,7 +6,7 @@ color: #848992; width: 100%; z-index: 1040; - position: absolute; + position: fixed; right: 0; left: 0; bottom: 0; diff --git a/awx/ui/client/src/license/checkLicense.factory.js b/awx/ui/client/src/license/checkLicense.factory.js new file mode 100644 index 0000000000..a654e1dc32 --- /dev/null +++ b/awx/ui/client/src/license/checkLicense.factory.js @@ -0,0 +1,62 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default + ['$state', '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', function($state, $rootScope, Rest, GetBasePath, ProcessErrors){ + return { + get: function() { + var defaultUrl = GetBasePath('config'); + Rest.setUrl(defaultUrl); + return Rest.get() + .success(function(res){ + return res + }) + .error(function(res, status){ + ProcessErrors($rootScope, res, status, null, {hdr: 'Error!', + msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status}); + }); + }, + post: function(license, eula){ + var defaultUrl = GetBasePath('config'); + Rest.setUrl(defaultUrl); + var data = license; + data.eula_accepted = eula; + return Rest.post(JSON.stringify(data)) + .success(function(res){ + return res + }) + .error(function(res, status){ + ProcessErrors($rootScope, res, status, null, {hdr: 'Error!', + msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status}); + }); + }, + // Checks current license validity + // Intended to for runtime or pre-state checks + // Returns false if invalid + valid: function(license) { + if (!license.valid_key){ + return false + } + else if (license.free_instances <= 0){ + return false + } + // notify if less than 15 days remaining + else if (license.time_remaining / 1000 / 60 / 60 / 24 > 15){ + return false + } + return true + }, + notify: function(){ + self = this; + this.get() + .then(function(res){ + self.valid(res.data.license_info) ? null : $state.go('license'); + }); + } + + } + } + ]; \ No newline at end of file diff --git a/awx/ui/client/src/license/fileOnChange.directive.js b/awx/ui/client/src/license/fileOnChange.directive.js new file mode 100644 index 0000000000..eac1f5ffe2 --- /dev/null +++ b/awx/ui/client/src/license/fileOnChange.directive.js @@ -0,0 +1,16 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default + [function(){ + return { + restrict: 'A', + link: function(scope, el, attrs){ + var onChange = scope.$eval(attrs.fileOnChange); + el.bind('change', onChange); + } + } + }]; \ No newline at end of file diff --git a/awx/ui/client/src/license/license.block.less b/awx/ui/client/src/license/license.block.less index 3cd5b2d213..58ce83542a 100644 --- a/awx/ui/client/src/license/license.block.less +++ b/awx/ui/client/src/license/license.block.less @@ -1,14 +1,17 @@ +/* +* Style conventions +* .ModuleName-component-subComponent +* Naming describes components of the view +*/ @import "awx/ui/client/src/shared/branding/colors.default.less"; +@import "awx/ui/client/src/shared/layouts/one-plus-two.less"; + .License-container{ - display: flex; - flex-direction: row; - flex-wrap: wrap; + .OnePlusTwo-container; } -.License-container label{ - text-transform: uppercase; - color: @default-interface-txt; - font-weight: 500; +.License-field--label{ + .OnePlusTwo-left--detailsLabel; } .License-management .CodeMirror-scroll{ min-height: 140px; @@ -19,20 +22,16 @@ } .License-eula textarea{ width: 100%; - height: 140px; + height: 300px; } .License-field label{ width: 155px; } -.License-field span{ - width: 255px; - display: inline-block; +.License-field--content{ + .OnePlusTwo-left--detailsContent; } .License-field{ - word-wrap: break-word; - width: 100%; - margin-top: 4px; - margin-bottom: 4px; + .OnePlusTwo-left--detailsRow; } .License-greenText{ color: @submit-button-bg; @@ -41,40 +40,27 @@ color: #d9534f; } .License-fields{ - display: flex; - flex-flow: row wrap; - justify-content: space-around; + .OnePlusTwo-left--details; } .License-details { - height: 520px; - width: 460px; - flex-grow: 1; - display: inline-block; - background-color: @default-bg; - padding: 20px; - border-radius: 5px; - border: @default-interface-txt; - align-items: baseline; - margin-top: 20px; - margin-bottom: 20px; - margin-right: 20px; + .OnePlusTwo-left--panel(600px); } .License-titleText { - color: @default-interface-txt; - font-size: 14px; - font-weight: bold; - margin-right: 10px; - margin-bottom: 10px; - text-transform: uppercase; + .OnePlusTwo-panelHeader; } .License-management{ - height: 520px; - flex-grow: 2; - display: inline-block; - background-color: @default-bg; - padding: 20px; - border-radius: 5px; - border: @default-interface-txt; - align-items: baseline; - margin-top: 20px; + .OnePlusTwo-right--panel(600px); +} +.License-submit--container{ + height: 33px; +} +.License-submit--success{ + line-height:33px; + margin: 0 10px 0 0; +} +.License-file--container { + margin: 20px 0 20px 0; + input[type=file] { + display: none; + } } \ No newline at end of file diff --git a/awx/ui/client/src/license/license.controller.js b/awx/ui/client/src/license/license.controller.js index a7cb28b56e..56a586cf0d 100644 --- a/awx/ui/client/src/license/license.controller.js +++ b/awx/ui/client/src/license/license.controller.js @@ -9,35 +9,47 @@ export default 'GetBasePath', 'Rest', 'ProcessErrors', 'CheckLicense', 'moment', function( Wait, $state, $scope, $location, GetBasePath, Rest, ProcessErrors, CheckLicense, moment){ - // codemirror - var textArea = document.getElementById('License-codemirror'); - var editor = CodeMirror.fromTextArea(textArea, { - lineNumbers: true, - mode: 'json' - }); - editor.on('blur', function(cm){ - $scope.newLicense.file = cm.getValue() - }); + $scope.getKey = function(event){ + // Mimic HTML5 spec, show filename + $scope.fileName = event.target.files[0].name; + // Grab the key from the raw license file + var raw = new FileReader(); + // readAsFoo runs async + raw.onload = function(){ + $scope.newLicense.file = JSON.parse(raw.result); + } + raw.readAsText(event.target.files[0]); + }; + // HTML5 spec doesn't provide a way to customize file input css + // So we hide the default input, show our own, and simulate clicks to the hidden input + $scope.fakeClick = function(){ + $('#License-file').click(); + //document.getElementById('License-file').click(); + } $scope.newLicense = {}; - $scope.submit = function(e){ - Wait('start') + $scope.submit = function(event){ + Wait('start'); CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula) .success(function(res){ - console.log(res) + reset(); + init(); + $scope.success = true; }); - } + }; var calcDaysRemaining = function(ms){ // calculate the number of days remaining on the license var duration = moment.duration(ms); return duration.days() - } + }; var calcExpiresOn = function(days){ // calculate the expiration date of the license return moment().add(days, 'days').calendar() - } - Wait('start'); - CheckLicense.get() + }; + var init = function(){ + $scope.fileName = "Please choose a file..." + Wait('start'); + CheckLicense.get() .then(function(res){ $scope.license = res.data; $scope.time = {}; @@ -46,5 +58,10 @@ export default $scope.valid = CheckLicense.valid($scope.license.license_info); Wait('stop'); }); - } + }; + var reset = function(){ + document.getElementById('License-form').reset() + }; + init(); + } ]; \ No newline at end of file diff --git a/awx/ui/client/src/license/license.partial.html b/awx/ui/client/src/license/license.partial.html index 3584c441e6..dcbde280e7 100644 --- a/awx/ui/client/src/license/license.partial.html +++ b/awx/ui/client/src/license/license.partial.html @@ -1,72 +1,99 @@
-
-
Details
-
-
- - Valid - Invalid -
-
- - {{license.version}} -
-
- - {{license.license_info.license_type}} -
-
- - {{license.license_info.subscription_name}} -
-
- - {{license.license_info.license_key}} -
-
- - {{time.expiresOn}} -
-
- - {{time.remaining}} Days -
-
- - {{license.license_info.available_instances}} -
-
- - {{license.license_info.current_instances}} -
-
- - {{license.license_info.free_instances}} -
-
-
-

If you are ready to upgrade, please contact us by clicking the button below

- -
-
-
License Management
-

Copy and paste the contents of your license in the field below, agree to the End User License Agreement, and click submit.

-
-
- - -
-
End User License Agreement
-
- -
-
-
- - +
+
+
Details
+
+
+
License
+
+ Valid + Invalid +
+
+
+
Version
+
+ {{license.version}} +
+
+
+
License Type
+
+ {{license.license_info.license_type}} +
+
+
+
Subscription
+
+ {{license.license_info.subscription_name}} +
+
+
+
License Key
+
+ {{license.license_info.license_key}} +
+
+
+
Expires On
+
+ {{time.expiresOn}} +
+
+
+
Time Remaining
+
+ {{time.remaining}} Day +
+
+
+
Hosts Available
+
+ {{license.license_info.available_instances}} +
+
+
+
Hosts Used
+
+ {{license.license_info.current_instances}} +
+
+
+
Hosts Remaining
+
+ {{license.license_info.free_instances}} +
- +

If you are ready to upgrade, please contact us by clicking the button below

+ +
+
+
+
+
License Management
+

Choose your license file, agree to the End User License Agreement, and click submit.

+
+
+ Browse... + + +
+
End User License Agreement
+
+ +
+
+
+
I agree to the End User License Agreement
+
+ Save successful! + +
+
+
+
+
\ No newline at end of file diff --git a/awx/ui/client/src/license/main.js b/awx/ui/client/src/license/main.js index c97613816d..6eeb8bf12e 100644 --- a/awx/ui/client/src/license/main.js +++ b/awx/ui/client/src/license/main.js @@ -6,66 +6,14 @@ import route from './license.route'; import controller from './license.controller'; +import CheckLicense from './checkLicense.factory'; +import fileOnChange from './fileOnChange.directive'; export default angular.module('license', []) .controller('licenseController', controller) - .factory('CheckLicense', ['$state', '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', function($state, $rootScope, Rest, GetBasePath, ProcessErrors){ - return { - get: function() { - var defaultUrl = GetBasePath('config'); - Rest.setUrl(defaultUrl); - return Rest.get() - .success(function(res){ - return res - }) - .error(function(res, status){ - ProcessErrors($rootScope, res, status, null, {hdr: 'Error!', - msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status}); - }); - }, - post: function(license, eula){ - var defaultUrl = GetBasePath('config'); - Rest.setUrl(defaultUrl); - var data = { - eula_accepted: eula, - license_key: license - }; - console.log(data) - return Rest.post(JSON.stringify(data)) - .success(function(res){ - return res - }) - .error(function(res, status){ - ProcessErrors($rootScope, res, status, null, {hdr: 'Error!', - msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status}); - }); - }, - // Checks current license validity - // Intended to for runtime or pre-state checks - // Returns false if invalid - valid: function(license) { - if (!license.valid_key){ - return false - } - else if (license.free_instances <= 0){ - return false - } - // notify if less than 15 days remaining - else if (license.time_remaining / 1000 / 60 / 60 / 24 > 15){ - return false - } - return true - }, - notify: function(){ - this.get() - .then(function(res){ - this.valid(res.license_info) ? null : $state.go('license'); - }); - } - - } - }]) + .directive('fileOnChange', fileOnChange) + .factory('CheckLicense', CheckLicense) .run(['$stateExtender', function($stateExtender) { $stateExtender.addState(route); }]); \ No newline at end of file diff --git a/awx/ui/client/src/shared/layouts/one-plus-two.less b/awx/ui/client/src/shared/layouts/one-plus-two.less new file mode 100644 index 0000000000..fe43e40b65 --- /dev/null +++ b/awx/ui/client/src/shared/layouts/one-plus-two.less @@ -0,0 +1,79 @@ +/* +* Large resolution: 1/3 + 2/3 width panels +* Small resolution: 100% width panels, stacked +* Options: static height, custom breakpoint +* +* Style conventions +* .ModuleName-component--subComponent +*/ +@import "awx/ui/client/src/shared/branding/colors.default.less"; + + +.OnePlusTwo-container(@height: 100%; @breakpoint: 900px){ + height: @height; + display: flex; + flex-direction: row; + @media screen and (max-width: @breakpoint){ + flex-direction: column; + } +} + +.OnePlusTwo-left--panel(@height: 100%; @breakpoint: 900px) { + flex: 0 0; + height: @height; + width: 100%; + .Panel{ + height: 100%; + } + @media screen and (min-width: @breakpoint){ + max-width: 400px; + } +} + +.OnePlusTwo-right--panel(@height: 100%; @breakpoint: 900px) { + height: @height; + flex: 1 0; + margin-left: 20px; + .Panel{ + height: 100%; + } + @media screen and (max-width: @breakpoint){ + flex-direction: column; + margin-left: 0px; + margin-top: 25px; + } +} + +.OnePlusTwo-panelHeader { + color: @default-interface-txt; + font-size: 14px; + font-weight: bold; + margin-right: 10px; + text-transform: uppercase; +} + +.OnePlusTwo-left--details { + margin-top: 25px; +} + +.OnePlusTwo-left--detailsRow { + display: flex; + :not(:last-child){ + margin-bottom: 20px; + } +} + +.OnePlusTwo-left--detailsLabel { + width: 140px; + display: inline-block; + color: @default-interface-txt; + text-transform: uppercase; + font-weight: 400; +} + +.OnePlusTwo-left--detailsContent { + display: inline-block; + max-width: 220px; + word-wrap: break-word; +} + diff --git a/awx/ui/templates/ui/index.html b/awx/ui/templates/ui/index.html index b431239a5a..79111c287d 100644 --- a/awx/ui/templates/ui/index.html +++ b/awx/ui/templates/ui/index.html @@ -41,7 +41,7 @@ -
+
@@ -221,8 +221,7 @@

working...

- - +