diff --git a/Gruntfile.js b/Gruntfile.js index bce2363734c..d2b5e1e89ea 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,7 +39,6 @@ module.exports = function(grunt) { 'desktop/core/src/desktop/static/desktop/css/hue.css': 'desktop/core/src/desktop/static/desktop/less/hue.less', 'desktop/core/src/desktop/static/desktop/css/hue3-extra.css': 'desktop/core/src/desktop/static/desktop/less/hue3-extra.less', 'desktop/core/src/desktop/static/desktop/css/login.css': 'desktop/core/src/desktop/static/desktop/less/login.less', - 'desktop/core/src/desktop/static/desktop/css/login4.css': 'desktop/core/src/desktop/static/desktop/less/login4.less', 'desktop/core/src/desktop/static/desktop/css/httperrors.css': 'desktop/core/src/desktop/static/desktop/less/httperrors.less', 'apps/metastore/src/metastore/static/metastore/css/metastore.css': 'apps/metastore/src/metastore/static/metastore/less/metastore.less', 'desktop/libs/notebook/src/notebook/static/notebook/css/notebook.css': 'desktop/libs/notebook/src/notebook/static/notebook/less/notebook.less', diff --git a/desktop/core/src/desktop/js/api/urls.js b/desktop/core/src/desktop/js/api/urls.js index 44fe60651cb..0e03461433c 100644 --- a/desktop/core/src/desktop/js/api/urls.js +++ b/desktop/core/src/desktop/js/api/urls.js @@ -15,6 +15,7 @@ // limitations under the License. export const AUTOCOMPLETE_API_PREFIX = '/api/editor/autocomplete/'; +export const BANNERS_API = '/api/banners/'; export const SAMPLE_API_PREFIX = '/notebook/api/sample/'; export const EXECUTE_API_PREFIX = '/api/editor/execute/'; // Dups with api.ts export const DOCUMENTS_API = '/desktop/api2/doc/'; diff --git a/desktop/core/src/desktop/js/hue.js b/desktop/core/src/desktop/js/hue.js index 0ef133b4716..bb49d966b4c 100644 --- a/desktop/core/src/desktop/js/hue.js +++ b/desktop/core/src/desktop/js/hue.js @@ -119,6 +119,8 @@ window.createReactComponents = createReactComponents; $(document).ready(async () => { await refreshConfig(); // Make sure we have config up front + createReactComponents('.main-page'); + const onePageViewModel = new OnePageViewModel(); ko.applyBindings(onePageViewModel, $('.page-content')[0]); diff --git a/desktop/core/src/desktop/js/login.js b/desktop/core/src/desktop/js/login.js index 761b87940d6..7d5c44adcc9 100644 --- a/desktop/core/src/desktop/js/login.js +++ b/desktop/core/src/desktop/js/login.js @@ -27,8 +27,11 @@ window.huePubSub = huePubSub; import { createApp } from 'vue'; import TrademarkBanner from 'vue/components/login/TrademarkBanner.vue'; +import { createReactComponents } from './reactComponents/createRootElements'; window.addEventListener('DOMContentLoaded', () => { + createReactComponents('.login-page'); + createApp({ components: { 'trademark-banner': TrademarkBanner diff --git a/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.scss b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.scss new file mode 100644 index 00000000000..6b168d6da7f --- /dev/null +++ b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.scss @@ -0,0 +1,29 @@ +// Licensed to Cloudera, Inc. under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. Cloudera, Inc. licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +@import '../../components/styles/colors.scss'; +@import '../../components/styles/mixins.scss'; + +.app-banner { + @include flex(0 0 auto); +} + +.app-banner--system { + padding: 4px; + text-align: center; + background-color: $fluid-blue-800; + color: $fluid-blue-050; +} diff --git a/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.test.tsx b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.test.tsx new file mode 100644 index 00000000000..c04ff382152 --- /dev/null +++ b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.test.tsx @@ -0,0 +1,88 @@ +// Licensed to Cloudera, Inc. under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. Cloudera, Inc. licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; + +import AppBanner from './AppBanner'; +import { CancellablePromise } from '../../api/cancellablePromise'; +import * as ApiUtils from '../../api/utils'; + +describe('AppBanner', () => { + let apiMock; + + const setupMock = (configured?: string, system?: string) => { + apiMock = jest + .spyOn(ApiUtils, 'get') + .mockReturnValue(CancellablePromise.resolve({ configured, system })); + }; + + afterEach(() => { + apiMock?.mockClear(); + }); + + test('it should show a configured banner', async () => { + const configuredBanner = '
Configured text Link
'; + setupMock(configuredBanner); + + render(); + + expect((await screen.findByText(/Configured/))?.outerHTML).toEqual(configuredBanner); + }); + + test('it should show a sanitized configured banner', async () => { + const configuredBanner = + '
Configured text Link
'; + const expectedBanner = '
Configured text Link
'; + setupMock(configuredBanner); + + render(); + + expect((await screen.findByText(/Configured/))?.outerHTML).toEqual(expectedBanner); + }); + + test('it should show a configured banner with sanitized styles', async () => { + const configuredBanner = + '
Configured text
'; + const expectedBanner = '
Configured text
'; + setupMock(configuredBanner); + + render(); + + expect((await screen.findByText(/Configured/))?.outerHTML).toEqual(expectedBanner); + }); + + test('it should show a system banner', async () => { + const systemBanner = '
System text
'; + setupMock(undefined, systemBanner); + + render(); + + expect((await screen.findByText(/System/))?.outerHTML).toEqual(systemBanner); + }); + + test('it should show a system banner instead of configured if both are present', async () => { + const configuredBanner = '
Configured text Link
'; + const systemBanner = '
System text
'; + setupMock(configuredBanner, systemBanner); + + render(); + + expect(await screen.findByText(/System/)).toBeInTheDocument(); + expect(screen.queryByText(/Configured/)).not.toBeInTheDocument(); + }); +}); diff --git a/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.tsx b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.tsx new file mode 100644 index 00000000000..6ee3b94fcf7 --- /dev/null +++ b/desktop/core/src/desktop/js/reactComponents/AppBanner/AppBanner.tsx @@ -0,0 +1,88 @@ +// Licensed to Cloudera, Inc. under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. Cloudera, Inc. licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React, { useEffect, useState } from 'react'; +import sanitizeHtml, { IOptions } from 'sanitize-html'; + +import './AppBanner.scss'; +import { BANNERS_API } from '../../api/urls'; +import { get } from '../../api/utils'; +import deXSS from '../../utils/html/deXSS'; +import noop from '../../utils/timing/noop'; + +interface ApiBanners { + system?: string; + configured?: string; +} + +const allowedCssColorRegex = [ + /^#(0x)?[0-9a-f]+$/i, + /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/ +]; +const allowedCssSizeRegex = [/^[\d.]+(?:px|pt|em|%|rem|vw)$/i]; + +// Based on defaults from https://github.com/apostrophecms/sanitize-html with support for a select set of styles that +// would make sense to use in a banner. +const sanitizeOptions: IOptions = { + allowedAttributes: { + '*': ['style'], + ...sanitizeHtml.defaults.allowedAttributes + }, + allowedStyles: { + '*': { + background: allowedCssColorRegex, + 'background-color': allowedCssColorRegex, + color: allowedCssColorRegex, + direction: [/^ltr|rtl$/i], + 'font-size': allowedCssSizeRegex, + height: allowedCssSizeRegex, + padding: allowedCssSizeRegex, + 'padding-bottom': allowedCssSizeRegex, + 'padding-left': allowedCssSizeRegex, + 'padding-right': allowedCssSizeRegex, + 'padding-top': allowedCssSizeRegex, + 'text-align': [/^left|right|center$/i], + width: allowedCssSizeRegex + } + } +}; + +export const AppBanner = (): JSX.Element => { + const [banners, setBanners] = useState(); + + useEffect(() => { + if (!banners) { + get(BANNERS_API).then(setBanners).catch(noop); + } + }); + + return ( + banners && + (banners.system ? ( +
+ ) : ( +
+ )) + ); +}; + +export default AppBanner; diff --git a/desktop/core/src/desktop/js/reactComponents/imports.js b/desktop/core/src/desktop/js/reactComponents/imports.js index 81d4301b700..ac3c6018240 100644 --- a/desktop/core/src/desktop/js/reactComponents/imports.js +++ b/desktop/core/src/desktop/js/reactComponents/imports.js @@ -8,6 +8,9 @@ export async function loadComponent(name) { return (await import('../apps/editor/components/result/reactExample/ReactExample')).default; // Application global components here + case 'AppBanner': + return (await import('./AppBanner/AppBanner')).default; + case 'ReactExampleGlobal': return (await import('./ReactExampleGlobal/ReactExampleGlobal')).default; diff --git a/desktop/core/src/desktop/js/utils/html/deXSS.ts b/desktop/core/src/desktop/js/utils/html/deXSS.ts index d34bd490d5b..00059d4be01 100644 --- a/desktop/core/src/desktop/js/utils/html/deXSS.ts +++ b/desktop/core/src/desktop/js/utils/html/deXSS.ts @@ -14,14 +14,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import sanitizeHtml from 'sanitize-html'; +import sanitizeHtml, { IOptions } from 'sanitize-html'; -const deXSS = (str?: boolean | string | number | null): string => { +const deXSS = (str?: undefined | boolean | string | number | null, options?: IOptions): string => { if (str === null) { return 'null'; } if (typeof str !== 'undefined') { - return sanitizeHtml(str as string) || ''; + return sanitizeHtml(str as string, options) || ''; } return ''; }; diff --git a/desktop/core/src/desktop/static/desktop/css/login.css b/desktop/core/src/desktop/static/desktop/css/login.css index 949102ca5af..028f87a4244 100644 --- a/desktop/core/src/desktop/static/desktop/css/login.css +++ b/desktop/core/src/desktop/static/desktop/css/login.css @@ -14,4 +14,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */@-webkit-keyframes spinner{from{-webkit-transform:rotateY(0deg)}to{-webkit-transform:rotateY(-360deg)}}.login-container{width:500px;display:block;margin:auto;margin-bottom:50px;background:#FFFFFF;border:1px solid #d6d8db;border-radius:4px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='248' height='196' viewBox='0 0 248 196'%3E%3Cdefs%3E%3Cpath id='6zd0wr4qxa' d='M0 0H248V196H0z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg%3E%3Cg%3E%3Cg transform='translate(-125 -842) translate(125 270) translate(0 572)'%3E%3Cmask id='4w2gcddqub' fill='%23fff'%3E%3Cuse xlink:href='%236zd0wr4qxa'/%3E%3C/mask%3E%3Cuse fill='%23132329' xlink:href='%236zd0wr4qxa'/%3E%3Cg mask='url(%234w2gcddqub)' opacity='.503'%3E%3Cg%3E%3Cpath fill='%2319323C' d='M117.744 164.685L0 282.43 42.867 282.43 160.612 164.685z' transform='translate(53 -87)'/%3E%3Cpath fill='%23224452' d='M282.73 0L117.913 164.685 160.612 164.685 42.868 282.429 349.591 282.459 349.591 0.002z' transform='translate(53 -87)'/%3E%3Cg%3E%3Cpath fill='%23224452' d='M148.278 0L146.067 0 28.322 117.745 30.533 117.745zM141.346 0L23.602 117.745 25.813 117.745 143.558 0zM35.253 117.745L152.998 0 150.786 0 33.041 117.745zM39.973 117.745L157.718 0 155.507 0 37.762 117.745zM136.626 0L18.881 117.745 21.092 117.745 138.838 0zM122.466 0L4.721 117.745 6.933 117.745 124.677 0zM117.746 0L0 117.745 2.212 117.745 119.956 0zM127.187 0L9.441 117.745 11.653 117.745 129.398 0zM131.907 0L14.161 117.745 16.372 117.745 134.118 0z' transform='translate(53 -87) translate(13.957 108.673)'/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A");background-position:right bottom;background-repeat:no-repeat;background-color:#132329}.login-container a{white-space:normal}.login-container .logo{width:70px;height:70px;text-align:center;margin-left:auto;margin-right:auto;margin-top:35px;margin-bottom:35px}.login-container h3{color:#0B7FAD;margin-bottom:25px;text-align:center}.login-container .empty-logo{background-color:#FFFFFF;width:70px;height:70px}.login-container .logo img{margin-top:2px}.login-container form{margin-left:75px;margin-right:75px}.login-container form input[type='submit'],.login-container form .login-container form select{width:100%}.login-container form .text-input{padding:0;border:1px solid #adb2b6;border-radius:4px;margin-bottom:20px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.login-container form .text-input input:focus{border-color:initial !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important}.login-container form .text-input.error{border-color:#d9150c}.login-container form ul.errorlist li{color:#d9150c;padding:0;font-weight:normal;font-style:normal;margin-top:-10px;margin-bottom:20px}.login-container form input[type='text'],.login-container form input[type='email'],.login-container form input[type='password'],.login-container form input[type='text']:hover,.login-container form input[type='password']:hover{padding:1px 10px 1px 19px;box-sizing:border-box;border:none;box-shadow:none;background:#FFFFFF;height:44px;font-size:14px;color:#333e47;font-weight:400;resize:none;margin:0;width:100%}.login-container form input[type='submit']{height:45px;min-height:45px;font-weight:normal;text-shadow:none;margin-left:0;border-radius:3px;font-size:16px;margin-bottom:55px}.login-container h4{text-align:center;margin-bottom:20px}:-webkit-autofill,:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 1000px white inset !important}input[type='password']::-ms-reveal{display:none}.tooltip{z-index:10000}.trademark{position:fixed;bottom:10px;margin-left:auto;margin-right:auto;width:100%;background-color:#f4f5f6}@media screen and (max-width:800px){body{padding-top:40px !important}.login-box{width:300px}.login-container form{margin-left:10px;margin-right:10px}.login-container form input[type='submit']{margin-bottom:20px}}@media screen and (max-width:540px){.login-container{width:90%}}#login-modal{padding:0 !important;box-shadow:none;background:transparent;border:none} \ No newline at end of file + */.login-page{position:absolute;top:0;bottom:0;left:0;right:0;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:-ms-flex;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;background-color:#F8F8F8}#login-modal{padding:0 !important;box-shadow:none;background:transparent;border:none}#login-modal>.login-container{border:1px solid transparent !important}.login-container{-ms-flex:0 1 auto;-webkit-flex:0 1 auto;flex:0 1 auto;-webkit-box-shadow:0 2px 8px rgba(0,0,0,0.18);-moz-box-shadow:0 2px 8px rgba(0,0,0,0.18);box-shadow:0 2px 6px 0 rgba(0,0,0,0.18),0 2px 8px 0 rgba(0,0,0,0.13);width:500px;display:block;margin:auto;border:1px solid #d6d8db;border-radius:4px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='248' height='196' viewBox='0 0 248 196'%3E%3Cdefs%3E%3Cpath id='6zd0wr4qxa' d='M0 0H248V196H0z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg%3E%3Cg%3E%3Cg transform='translate(-125 -842) translate(125 270) translate(0 572)'%3E%3Cmask id='4w2gcddqub' fill='%23fff'%3E%3Cuse xlink:href='%236zd0wr4qxa'/%3E%3C/mask%3E%3Cuse fill='%23132329' xlink:href='%236zd0wr4qxa'/%3E%3Cg mask='url(%234w2gcddqub)' opacity='.503'%3E%3Cg%3E%3Cpath fill='%2319323C' d='M117.744 164.685L0 282.43 42.867 282.43 160.612 164.685z' transform='translate(53 -87)'/%3E%3Cpath fill='%23224452' d='M282.73 0L117.913 164.685 160.612 164.685 42.868 282.429 349.591 282.459 349.591 0.002z' transform='translate(53 -87)'/%3E%3Cg%3E%3Cpath fill='%23224452' d='M148.278 0L146.067 0 28.322 117.745 30.533 117.745zM141.346 0L23.602 117.745 25.813 117.745 143.558 0zM35.253 117.745L152.998 0 150.786 0 33.041 117.745zM39.973 117.745L157.718 0 155.507 0 37.762 117.745zM136.626 0L18.881 117.745 21.092 117.745 138.838 0zM122.466 0L4.721 117.745 6.933 117.745 124.677 0zM117.746 0L0 117.745 2.212 117.745 119.956 0zM127.187 0L9.441 117.745 11.653 117.745 129.398 0zM131.907 0L14.161 117.745 16.372 117.745 134.118 0z' transform='translate(53 -87) translate(13.957 108.673)'/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A");background-position:right bottom;background-repeat:no-repeat;background-color:#132329}.login-container a{white-space:normal}.login-container select{width:100%}.login-container .logo{height:70px;text-align:center;margin:35px auto}.login-container .logo img{margin-top:2px}.login-container h3{color:#0B7FAD;margin-bottom:25px;text-align:center}.login-container .empty-logo{background-color:#FFFFFF;width:70px;height:70px}.login-container form{margin-left:75px;margin-right:75px}.login-container form input[type='submit'],.login-container form .login-container form select{width:100%}.login-container form .text-input{padding:0;border:1px solid #adb2b6;border-radius:4px;margin-bottom:20px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.login-container form .text-input input:focus{border-color:initial !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important}.login-container form .text-input.error{border-color:#d9150c}.login-container form ul.errorlist li{color:#d9150c;padding:0;font-weight:normal;font-style:normal;margin-top:-10px;margin-bottom:20px}.login-container form input[type='text'],.login-container form input[type='email'],.login-container form input[type='password'],.login-container form input[type='text']:hover,.login-container form input[type='password']:hover{padding:1px 10px 1px 19px;box-sizing:border-box;border:none;box-shadow:none;background:#FFFFFF;height:44px;font-size:14px;color:#333e47;font-weight:400;resize:none;margin:0;width:100%}.login-container form input[type='submit']{height:45px;min-height:45px;font-weight:normal;text-shadow:none;margin-left:0;border-radius:3px;font-size:16px;margin-bottom:55px}.login-container h4{text-align:center;margin-bottom:20px}input[type='password']::-ms-reveal{display:none}.tooltip{z-index:10000}.trademark{-ms-flex:0 1 auto;-webkit-flex:0 1 auto;flex:0 1 auto;margin-left:auto;margin-right:auto;padding-bottom:10px}.svg-hue-logo-main{fill:#0B7FAD}.svg-hue-logo-trunk{fill:#9678d3}@-webkit-keyframes autofill{to{background:transparent}}:-webkit-autofill{-webkit-animation-name:autofill;-webkit-animation-fill-mode:both}:-webkit-autofill,:-webkit-autofill:focus{-webkit-box-shadow:0 0 0 1000px white inset !important} \ No newline at end of file diff --git a/desktop/core/src/desktop/static/desktop/css/login4.css b/desktop/core/src/desktop/static/desktop/css/login4.css deleted file mode 100644 index af7fc09d161..00000000000 --- a/desktop/core/src/desktop/static/desktop/css/login4.css +++ /dev/null @@ -1,17 +0,0 @@ -/*! -Licensed to Cloudera, Inc. under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. Cloudera, Inc. licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - */.login-container{-webkit-box-shadow:0 2px 8px rgba(0,0,0,0.18);-moz-box-shadow:0 2px 8px rgba(0,0,0,0.18);box-shadow:0 2px 6px 0 rgba(0,0,0,0.18),0 2px 8px 0 rgba(0,0,0,0.13)}.login-container .logo{width:200px;height:70px;text-align:center}.svg-hue-logo-main{fill:#0B7FAD}.svg-hue-logo-trunk{fill:#9678d3}@-webkit-keyframes autofill{to{background:transparent}}:-webkit-autofill{-webkit-animation-name:autofill;-webkit-animation-fill-mode:both} \ No newline at end of file diff --git a/desktop/core/src/desktop/static/desktop/less/login.less b/desktop/core/src/desktop/static/desktop/less/login.less index 8bffb027892..2676d1b02ae 100644 --- a/desktop/core/src/desktop/static/desktop/less/login.less +++ b/desktop/core/src/desktop/static/desktop/less/login.less @@ -20,22 +20,32 @@ @sidebar-bg-color: #132329; -@-webkit-keyframes spinner { - from { - -webkit-transform: rotateY(0deg); - } +.login-page { + .fillAbsolute(); + .display-flex(); + .flex-direction(column); - to { - -webkit-transform: rotateY(-360deg); + background-color: #f8f8f8; +} + +#login-modal { + padding: 0 !important; + box-shadow: none; + background: transparent; + border: none; + + > .login-container { + border: 1px solid transparent !important; } } .login-container { + .flex(0 1 auto); + .hue-box-shadow-bottom; + width: 500px; display: block; margin: auto; - margin-bottom: 50px; - background: @cui-white; border: 1px solid @cui-default-border-color; border-radius: 4px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='248' height='196' viewBox='0 0 248 196'%3E%3Cdefs%3E%3Cpath id='6zd0wr4qxa' d='M0 0H248V196H0z'/%3E%3C/defs%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg%3E%3Cg%3E%3Cg transform='translate(-125 -842) translate(125 270) translate(0 572)'%3E%3Cmask id='4w2gcddqub' fill='%23fff'%3E%3Cuse xlink:href='%236zd0wr4qxa'/%3E%3C/mask%3E%3Cuse fill='%23132329' xlink:href='%236zd0wr4qxa'/%3E%3Cg mask='url(%234w2gcddqub)' opacity='.503'%3E%3Cg%3E%3Cpath fill='%2319323C' d='M117.744 164.685L0 282.43 42.867 282.43 160.612 164.685z' transform='translate(53 -87)'/%3E%3Cpath fill='%23224452' d='M282.73 0L117.913 164.685 160.612 164.685 42.868 282.429 349.591 282.459 349.591 0.002z' transform='translate(53 -87)'/%3E%3Cg%3E%3Cpath fill='%23224452' d='M148.278 0L146.067 0 28.322 117.745 30.533 117.745zM141.346 0L23.602 117.745 25.813 117.745 143.558 0zM35.253 117.745L152.998 0 150.786 0 33.041 117.745zM39.973 117.745L157.718 0 155.507 0 37.762 117.745zM136.626 0L18.881 117.745 21.092 117.745 138.838 0zM122.466 0L4.721 117.745 6.933 117.745 124.677 0zM117.746 0L0 117.745 2.212 117.745 119.956 0zM127.187 0L9.441 117.745 11.653 117.745 129.398 0zM131.907 0L14.161 117.745 16.372 117.745 134.118 0z' transform='translate(53 -87) translate(13.957 108.673)'/%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A"); @@ -47,14 +57,18 @@ white-space: normal; } + select { + width: 100%; + } + .logo { - width: 70px; height: 70px; text-align: center; - margin-left: auto; - margin-right: auto; - margin-top: 35px; - margin-bottom: 35px; + margin: 35px auto; + + img { + margin-top: 2px; + } } h3 { @@ -69,10 +83,6 @@ height: 70px; } - .logo img { - margin-top: 2px; - } - form { margin-left: 75px; margin-right: 75px; @@ -99,10 +109,10 @@ -moz-box-shadow: none !important; box-shadow: none !important; } - } - .text-input.error { - border-color: @cui-red-500; + &.error { + border-color: @cui-red-500; + } } ul.errorlist li { @@ -151,11 +161,6 @@ } } -:-webkit-autofill, -:-webkit-autofill:focus { - -webkit-box-shadow: 0 0 0 1000px white inset !important; -} - input[type='password']::-ms-reveal { display: none; } @@ -165,42 +170,33 @@ input[type='password']::-ms-reveal { } .trademark { - position: fixed; - bottom: 10px; + .flex(0 1 auto); + margin-left: auto; margin-right: auto; - width: 100%; - background-color: @cui-gray-050; + padding-bottom: 10px; } -@media screen and (max-width: 800px) { - body { - padding-top: 40px !important; - } - - .login-box { - width: 300px; - } +.svg-hue-logo-main { + fill: @hue-primary-color-dark; +} - .login-container form { - margin-left: 10px; - margin-right: 10px; - } +.svg-hue-logo-trunk { + fill: @hue-trunk; +} - .login-container form input[type='submit'] { - margin-bottom: 20px; +@-webkit-keyframes autofill { + to { + background: transparent; } } -@media screen and (max-width: 540px) { - .login-container { - width: 90%; - } +:-webkit-autofill { + -webkit-animation-name: autofill; + -webkit-animation-fill-mode: both; } -#login-modal { - padding: 0 !important; - box-shadow: none; - background: transparent; - border: none; +:-webkit-autofill, +:-webkit-autofill:focus { + -webkit-box-shadow: 0 0 0 1000px white inset !important; } diff --git a/desktop/core/src/desktop/static/desktop/less/login4.less b/desktop/core/src/desktop/static/desktop/less/login4.less deleted file mode 100644 index c702570b0c8..00000000000 --- a/desktop/core/src/desktop/static/desktop/less/login4.less +++ /dev/null @@ -1,46 +0,0 @@ -/* - Licensed to Cloudera, Inc. under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. Cloudera, Inc. licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -@import (reference) "hue-mixins.less"; - -.login-container { - .logo { - width: 200px; - height: 70px; - text-align: center; - } - .hue-box-shadow-bottom; -} - -.svg-hue-logo-main { - fill: @hue-primary-color-dark; -} - -.svg-hue-logo-trunk { - fill: @hue-trunk; -} - -@-webkit-keyframes autofill { - to { - background: transparent; - } -} - -:-webkit-autofill { - -webkit-animation-name: autofill; - -webkit-animation-fill-mode: both; -} diff --git a/desktop/core/src/desktop/templates/common_header.mako b/desktop/core/src/desktop/templates/common_header.mako index ef2b09d759f..cd0216fd3e1 100644 --- a/desktop/core/src/desktop/templates/common_header.mako +++ b/desktop/core/src/desktop/templates/common_header.mako @@ -207,12 +207,6 @@ ${ hueIcons.symbols() } % endif -% if banner_message or conf.CUSTOM.BANNER_TOP_HTML.get(): - -% endif - <% def count_apps(apps, app_list): count = 0 diff --git a/desktop/core/src/desktop/templates/hue.mako b/desktop/core/src/desktop/templates/hue.mako index f76a5940864..f2a4f099e81 100644 --- a/desktop/core/src/desktop/templates/hue.mako +++ b/desktop/core/src/desktop/templates/hue.mako @@ -146,11 +146,7 @@ ${ hueIcons.symbols() }
- % if banner_message or conf.CUSTOM.BANNER_TOP_HTML.get(): - - % endif +