From 58e202bf1d2de7867ebcb067d4201736ee81762c Mon Sep 17 00:00:00 2001 From: thanicz Date: Wed, 3 Dec 2025 14:57:27 +0100 Subject: [PATCH 1/9] KNOX-3224: Refactor token generation UI, upgrade node ,angular, bootstrap, jquery and other dependencies --- knox-token-generation-ui/.eslintrc.json | 98 - knox-token-generation-ui/angular.json | 37 +- knox-token-generation-ui/eslint.config.js | 75 + knox-token-generation-ui/package.json | 50 +- knox-token-generation-ui/pom.xml | 2 +- .../token-generation/app/app.module.ts | 15 +- .../app/model/session.information.ts | 26 + .../token-generation/app/model/token.data.ts | 23 + .../app/model/token.request.params.ts | 25 + .../app/model/token.result.data.ts | 25 + .../tss.status.data.ts} | 39 +- .../{ => service}/token-generation.service.ts | 19 +- .../session.information.component.html | 0 .../session.information.component.ts | 20 +- .../app/token-generation.component.html | 97 - .../token-generation.component.css | 34 + .../token-generation.component.html | 117 + .../token-generation.component.ts | 34 +- .../token-generation/app/util/safehtml.ts | 27 + .../assets/styles/bootstrap.min.css | 6422 ----------------- .../token-generation/assets/styles/knox.css | 8 +- .../token-generation/index.html | 1 + .../token-generation/main.ts | 29 +- .../token-generation/polyfills.ts | 20 +- .../token-generation/styles.css | 9 + .../token-generation/tsconfig.json | 7 +- 26 files changed, 481 insertions(+), 6778 deletions(-) delete mode 100644 knox-token-generation-ui/.eslintrc.json create mode 100644 knox-token-generation-ui/eslint.config.js create mode 100644 knox-token-generation-ui/token-generation/app/model/session.information.ts create mode 100644 knox-token-generation-ui/token-generation/app/model/token.data.ts create mode 100644 knox-token-generation-ui/token-generation/app/model/token.request.params.ts create mode 100644 knox-token-generation-ui/token-generation/app/model/token.result.data.ts rename knox-token-generation-ui/token-generation/app/{token-generation.models.ts => model/tss.status.data.ts} (59%) rename knox-token-generation-ui/token-generation/app/{ => service}/token-generation.service.ts (91%) rename knox-token-generation-ui/token-generation/app/{ => sessionInformation}/session.information.component.html (100%) rename knox-token-generation-ui/token-generation/app/{ => sessionInformation}/session.information.component.ts (81%) delete mode 100644 knox-token-generation-ui/token-generation/app/token-generation.component.html create mode 100644 knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css create mode 100644 knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html rename knox-token-generation-ui/token-generation/app/{ => token-generation}/token-generation.component.ts (86%) create mode 100644 knox-token-generation-ui/token-generation/app/util/safehtml.ts delete mode 100644 knox-token-generation-ui/token-generation/assets/styles/bootstrap.min.css diff --git a/knox-token-generation-ui/.eslintrc.json b/knox-token-generation-ui/.eslintrc.json deleted file mode 100644 index d58c24696c..0000000000 --- a/knox-token-generation-ui/.eslintrc.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "root": true, - "overrides": [ - { - "files": [ - "*.ts" - ], - "parserOptions": { - "project": [ - "token-generation/tsconfig.json" - ], - "createDefaultProgram": true - }, - "extends": [ - "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" - ], - "rules": { - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": ["class"], - "format": ["PascalCase"] - } - ], - "spaced-comment": "error", - "curly": "error", - "eol-last": "error", - "guard-for-in": "error", - "no-unused-labels": "error", - "max-len": [ - "error", - { "code": 140 } - ], - "@typescript-eslint/explicit-member-accessibility": [ - "off", - {"accessibility": "no-public"} - ], - "@typescript-eslint/member-ordering": [ - "error", - { "default": ["static-field", "instance-field", "field", "method"] } - ], - "no-caller": "error", - "no-bitwise": "error", - "no-console": "off", - "no-new-wrappers": "error", - "no-debugger": "error", - "no-redeclare": "off", - "no-empty": "error", - "no-eval": "error", - "@typescript-eslint/no-inferrable-types": "error", - "no-shadow": "error", - "dot-notation": "off", - "no-fallthrough": "error", - "no-trailing-spaces": "error", - "no-unused-expressions": "error", - "no-var": "error", - "sort-keys": "off", - "brace-style": ["error","1tbs", { "allowSingleLine": true }], - "quotes": ["error", "single"], - "radix": "error", - "@typescript-eslint/semi": "error", - "eqeqeq": ["error", "always", {"null": "ignore"}], - "@typescript-eslint/type-annotation-spacing": "error", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "error", - "@angular-eslint/use-pipe-transform-interface": "error", - "@angular-eslint/component-class-suffix": "error", - "@angular-eslint/directive-class-suffix": "error" - } - }, - { - "files": [ - "*.html" - ], - "extends": [ - "plugin:@angular-eslint/template/recommended" - ], - "rules": {} - } - ] -} diff --git a/knox-token-generation-ui/angular.json b/knox-token-generation-ui/angular.json index 4c1bc67998..b6058417f8 100644 --- a/knox-token-generation-ui/angular.json +++ b/knox-token-generation-ui/angular.json @@ -36,26 +36,30 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular/build:application", "options": { - "outputPath": "target/classes/token-generation/app", + "outputPath": { + "base": "target/classes/token-generation/app", + "browser": "" + }, "index": "token-generation/index.html", - "main": "token-generation/main.ts", - "polyfills": "token-generation/polyfills.ts", + "polyfills": ["token-generation/polyfills.ts"], "tsConfig": "token-generation/tsconfig.json", "assets": [ "token-generation/favicon.ico", "token-generation/assets" ], "styles": [ - "token-generation/assets/styles/bootstrap.min.css", + "node_modules/bootstrap/dist/css/bootstrap.min.css", "token-generation/assets/styles/app-font.css", "token-generation/assets/styles/knox.css", "token-generation/styles.css" ], "scripts": [ - "node_modules/jquery/dist/jquery.min.js" - ] + "node_modules/jquery/dist/jquery.min.js", + "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" + ], + "browser": "token-generation/main.ts" }, "configurations": { "production": { @@ -68,9 +72,8 @@ "outputHashing": "all" }, "development": { - "buildOptimizer": false, + "aot": false, "optimization": false, - "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -79,21 +82,21 @@ "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "configurations": { "production": { - "browserTarget": "token-generation:build:production" + "buildTarget": "token-generation:build:production" }, "development": { - "browserTarget": "token-generation:build:development" + "buildTarget": "token-generation:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", + "builder": "@angular/build:extract-i18n", "options": { - "browserTarget": "token-generation:build" + "buildTarget": "token-generation:build" } }, "lint": { @@ -107,11 +110,5 @@ } } } - }, - "defaultProject": "token-generation", - "cli": { - "schematicCollections": [ - "@angular-eslint/schematics" - ] } } diff --git a/knox-token-generation-ui/eslint.config.js b/knox-token-generation-ui/eslint.config.js new file mode 100644 index 0000000000..565327301b --- /dev/null +++ b/knox-token-generation-ui/eslint.config.js @@ -0,0 +1,75 @@ +import js from "@eslint/js"; +import tseslint from "typescript-eslint"; +import angular from "@angular-eslint/eslint-plugin"; +import angularTemplate from "@angular-eslint/eslint-plugin-template"; +import tsParser from "@typescript-eslint/parser"; + +export default [ + { + ignores: ["**/dist/**", "**/node_modules/**"], + }, + + js.configs.recommended, + + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + parserOptions: { + project: ["./token-generation/tsconfig.json"], + tsconfigRootDir: import.meta.dirname, + }, + globals: { + console: "readonly", + window: "readonly", + document: "readonly", + setTimeout: "readonly", + atob: "readonly" + }, + }, + plugins: { + "@typescript-eslint": tseslint.plugin, + "@angular-eslint": angular, + }, + rules: { + "@typescript-eslint/naming-convention": [ + "error", + {selector: "class", format: ["PascalCase"]}, + ], + + curly: "error", + eqeqeq: ["error", "always", {null: "ignore"}], + "guard-for-in": "error", + "max-len": ["error", {code: 140}], + "no-bitwise": "error", + "no-caller": "error", + "no-console": "off", + "no-debugger": "error", + "no-empty": "error", + "no-eval": "error", + "no-fallthrough": "error", + "no-trailing-spaces": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-var": "error", + quotes: ["error", "single"], + radix: "error", + semi: ["error", "always"], + "spaced-comment": "error", + "brace-style": ["error", "1tbs", {allowSingleLine: true}], + + "@angular-eslint/directive-selector": [ + "error", + {type: "attribute", prefix: "app", style: "camelCase"}, + ], + "@angular-eslint/component-selector": [ + "error", + {type: "element", prefix: "app", style: "kebab-case"}, + ], + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/use-pipe-transform-interface": "error", + "@angular-eslint/component-class-suffix": "error", + "@angular-eslint/directive-class-suffix": "error", + }, + }, +]; \ No newline at end of file diff --git a/knox-token-generation-ui/package.json b/knox-token-generation-ui/package.json index ab1933601c..f4d9b0d74b 100644 --- a/knox-token-generation-ui/package.json +++ b/knox-token-generation-ui/package.json @@ -2,6 +2,7 @@ "name": "ng-knox-token-generation", "version": "1.0.0", "license": "Apache-2.0", + "type": "module", "scripts": { "start": "ng serve --verbose=true", "build": "ng build", @@ -10,30 +11,33 @@ }, "private": true, "dependencies": { - "@angular/common": "^13.0.1", - "@angular/compiler": "^13.0.1", - "@angular/core": "^13.0.1", - "@angular/forms": "^13.0.1", - "@angular/platform-browser": "^13.0.1", - "@angular/platform-browser-dynamic": "^13.0.1", - "jquery": "^3.5.1", - "sweetalert2": "^11.6.5", - "zone.js": "~0.11.4" + "@angular/common": "^20.3.15", + "@angular/compiler": "^20.3.15", + "@angular/core": "^20.3.15", + "@angular/forms": "^20.3.15", + "@angular/platform-browser": "^20.3.15", + "@angular/platform-browser-dynamic": "^20.3.15", + "@angular/material": "^20.2.5", + "@angular/router": "^20.3.2", + "jquery": "^3.7.1", + "sweetalert2": "^11.26.3", + "zone.js": "~0.15.1", + "bootstrap": "^5.3.8" }, "devDependencies": { - "@angular-devkit/build-angular": "^13.3.11", - "@angular-eslint/builder": "14.1.2", - "@angular-eslint/eslint-plugin": "14.1.2", - "@angular-eslint/eslint-plugin-template": "14.1.2", - "@angular-eslint/schematics": "14.1.2", - "@angular-eslint/template-parser": "14.1.2", - "@angular/cli": "^14.2.9", - "@angular/compiler-cli": "^13.0.1", - "@angular/language-service": "^5.2.0", - "@types/node": "16.18.11", - "@typescript-eslint/eslint-plugin": "5.37.0", - "@typescript-eslint/parser": "5.37.0", - "eslint": "^8.23.1", - "typescript": "~4.4.4" + "@angular-devkit/build-angular": "^20.3.13", + "@angular-eslint/builder": "20.7.0", + "@angular-eslint/eslint-plugin": "20.7.0", + "@angular-eslint/eslint-plugin-template": "20.7.0", + "@angular-eslint/schematics": "20.7.0", + "@angular-eslint/template-parser": "20.7.0", + "@angular/cli": "^20.3.13", + "@angular/compiler-cli": "^20.3.15", + "@angular/language-service": "^20.3.15", + "@types/node": "^24.5.2", + "eslint": "^9.39.0", + "ts-node": "~10.9.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.46.2" } } diff --git a/knox-token-generation-ui/pom.xml b/knox-token-generation-ui/pom.xml index 913d1eb906..fc49fc3af2 100644 --- a/knox-token-generation-ui/pom.xml +++ b/knox-token-generation-ui/pom.xml @@ -65,7 +65,7 @@ npm - install --legacy-peer-deps + install diff --git a/knox-token-generation-ui/token-generation/app/app.module.ts b/knox-token-generation-ui/token-generation/app/app.module.ts index 1ff7d3044c..c51d439470 100644 --- a/knox-token-generation-ui/token-generation/app/app.module.ts +++ b/knox-token-generation-ui/token-generation/app/app.module.ts @@ -16,21 +16,12 @@ */ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; -import { HttpClientModule } from '@angular/common/http'; -import { TokenGenerationComponent } from './token-generation.component'; import { ReactiveFormsModule } from '@angular/forms'; -import { TokenGenService } from './token-generation.service'; -import { SessionInformationComponent } from './session.information.component'; -import { SafeHtmlPipe } from './session.information.component'; +import { TokenGenService } from './service/token-generation.service'; @NgModule({ - imports: [BrowserModule, - HttpClientModule, - ReactiveFormsModule - ], - declarations: [TokenGenerationComponent, SessionInformationComponent, SafeHtmlPipe], - providers: [TokenGenService], - bootstrap: [TokenGenerationComponent, SessionInformationComponent] + imports: [BrowserModule, ReactiveFormsModule], + providers: [TokenGenService] }) export class AppModule { } diff --git a/knox-token-generation-ui/token-generation/app/model/session.information.ts b/knox-token-generation-ui/token-generation/app/model/session.information.ts new file mode 100644 index 0000000000..00990e2216 --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/model/session.information.ts @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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. + */ + +export class SessionInformation { + user: string; + logoutUrl: string; + logoutPageUrl: string; + globalLgoutPageUrl: string; + canSeeAllTokens: boolean; + currentKnoxSsoCookieTokenId: string; + bannerText: string; +} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/model/token.data.ts b/knox-token-generation-ui/token-generation/app/model/token.data.ts new file mode 100644 index 0000000000..0527b4817f --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/model/token.data.ts @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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. + */ +export interface TokenData { + access_token: string; + target_url: string; + homepage_url: string; + expires_in: number; + passcode: string; + } \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/model/token.request.params.ts b/knox-token-generation-ui/token-generation/app/model/token.request.params.ts new file mode 100644 index 0000000000..e9bd92be16 --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/model/token.request.params.ts @@ -0,0 +1,25 @@ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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. + */ + + export interface TokenRequestParams { + lifespanInputEnabled: boolean; + comment: string; + impersonation: string; + lifespanDays: number; + lifespanHours: number; + lifespanMins: number; + } \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/model/token.result.data.ts b/knox-token-generation-ui/token-generation/app/model/token.result.data.ts new file mode 100644 index 0000000000..df9d52df2d --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/model/token.result.data.ts @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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. + */ + +export class TokenResultData { + accessToken: string; + accessPasscode: string; + expiry: string; + user: string; + homepageURL: string; + targetURL: string; +} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation.models.ts b/knox-token-generation-ui/token-generation/app/model/tss.status.data.ts similarity index 59% rename from knox-token-generation-ui/token-generation/app/token-generation.models.ts rename to knox-token-generation-ui/token-generation/app/model/tss.status.data.ts index c14e6ea661..9b96bdd4d4 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation.models.ts +++ b/knox-token-generation-ui/token-generation/app/model/tss.status.data.ts @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + export class TssStatusData { tokenManagementEnabled: boolean; maximumLifetimeText: string; @@ -23,40 +24,4 @@ export class TssStatusData { configuredTssBackend: string; allowedTssForTokengen: boolean; actualTssBackend: string; -} - -export class TokenResultData { - accessToken: string; - accessPasscode: string; - expiry: string; - user: string; - homepageURL: string; - targetURL: string; -} - -export interface TokenData { - access_token: string; - target_url: string; - homepage_url: string; - expires_in: number; - passcode: string; - } - - export interface TokenRequestParams { - lifespanInputEnabled: boolean; - comment: string; - impersonation: string; - lifespanDays: number; - lifespanHours: number; - lifespanMins: number; - } - -export class SessionInformation { - user: string; - logoutUrl: string; - logoutPageUrl: string; - globalLgoutPageUrl: string; - canSeeAllTokens: boolean; - currentKnoxSsoCookieTokenId: string; - bannerText: string; -} +} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation.service.ts b/knox-token-generation-ui/token-generation/app/service/token-generation.service.ts similarity index 91% rename from knox-token-generation-ui/token-generation/app/token-generation.service.ts rename to knox-token-generation-ui/token-generation/app/service/token-generation.service.ts index 7122336e6f..2d98ee658a 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation.service.ts +++ b/knox-token-generation-ui/token-generation/app/service/token-generation.service.ts @@ -17,7 +17,12 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http'; import Swal from 'sweetalert2'; -import { TokenData, TokenRequestParams, TokenResultData, TssStatusData, SessionInformation } from './token-generation.models'; +import { TokenData } from '../model/token.data'; +import { TokenRequestParams } from '../model/token.request.params'; +import { TssStatusData } from '../model/tss.status.data'; +import { SessionInformation } from '../model/session.information'; +import { TokenResultData } from '../model/token.result.data'; +import { firstValueFrom } from 'rxjs'; @Injectable() export class TokenGenService { @@ -45,8 +50,7 @@ export class TokenGenService { let headers = new HttpHeaders(); headers = this.addHeaders(headers); - return this.http.get(this.tssStatusRequestURL, { headers: headers }) - .toPromise() + return firstValueFrom(this.http.get(this.tssStatusRequestURL, { headers: headers })) .then(responseData => { /** * The data needs to be returned this way, because if the return type would be set to and the responseData @@ -78,8 +82,7 @@ export class TokenGenService { isTokenHashKeyPresent(): Promise { let headers = new HttpHeaders(); headers = this.addHeaders(headers); - return this.http.get(this.metadataInfoUrl, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(this.metadataInfoUrl, { headers: headers})) .then(response => { return response['generalProxyInfo']?.['enableTokenManagement'] === 'true'; }) @@ -95,8 +98,7 @@ export class TokenGenService { getSessionInformation(): Promise { let headers = new HttpHeaders(); headers = this.addHeaders(headers); - return this.http.get(this.sessionUrl, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(this.sessionUrl, { headers: headers})) .then(response => response['sessioninfo'] as SessionInformation) .catch((err: HttpErrorResponse) => { console.debug('TokenGenService --> getSessionInformation() --> ' + this.sessionUrl + '\n error: ' + err.message); @@ -124,8 +126,7 @@ export class TokenGenService { httpParams = httpParams.append('doAs', params.impersonation); } - return this.http.get(this.tokenURL, { params: httpParams, headers: headers }) - .toPromise() + return firstValueFrom(this.http.get(this.tokenURL, { params: httpParams, headers: headers })) .then(tokenData => { let decodedToken = this.b64DecodeUnicode(tokenData.access_token.split('.')[1]); let jwtJson = JSON.parse(decodedToken); diff --git a/knox-token-generation-ui/token-generation/app/session.information.component.html b/knox-token-generation-ui/token-generation/app/sessionInformation/session.information.component.html similarity index 100% rename from knox-token-generation-ui/token-generation/app/session.information.component.html rename to knox-token-generation-ui/token-generation/app/sessionInformation/session.information.component.html diff --git a/knox-token-generation-ui/token-generation/app/session.information.component.ts b/knox-token-generation-ui/token-generation/app/sessionInformation/session.information.component.ts similarity index 81% rename from knox-token-generation-ui/token-generation/app/session.information.component.ts rename to knox-token-generation-ui/token-generation/app/sessionInformation/session.information.component.ts index 618d67b5b5..3311f64659 100644 --- a/knox-token-generation-ui/token-generation/app/session.information.component.ts +++ b/knox-token-generation-ui/token-generation/app/sessionInformation/session.information.component.ts @@ -14,24 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {Component, OnInit, Pipe, PipeTransform} from '@angular/core'; -import {DomSanitizer} from '@angular/platform-browser'; -import {TokenGenService} from './token-generation.service'; -import {SessionInformation} from './token-generation.models'; - -@Pipe({ name: 'safeHtml' }) -export class SafeHtmlPipe implements PipeTransform { - constructor(private sanitizer: DomSanitizer) {} - - transform(value) { - return this.sanitizer.bypassSecurityTrustHtml(value); - } -} +import {Component, OnInit } from '@angular/core'; +import {TokenGenService} from '../service/token-generation.service'; +import { SessionInformation } from '../model/session.information'; +import { SafeHtmlPipe } from '../util/safehtml'; @Component({ selector: 'app-session-information', templateUrl: './session.information.component.html', - providers: [TokenGenService] + providers: [TokenGenService], + imports: [SafeHtmlPipe] }) export class SessionInformationComponent implements OnInit { diff --git a/knox-token-generation-ui/token-generation/app/token-generation.component.html b/knox-token-generation-ui/token-generation/app/token-generation.component.html deleted file mode 100644 index 16e9afeb50..0000000000 --- a/knox-token-generation-ui/token-generation/app/token-generation.component.html +++ /dev/null @@ -1,97 +0,0 @@ - -
-
-
-
-

Token Generation

- - - - - - - - - - - -
- - - - - - - -
- -
- -
- - - -
-
- - {{requestErrorMessage}} - - - -
- -
-
-
-
- -
- -
- - {{tokenResultData.accessToken}} -
- -
- - {{tokenResultData.accessPasscode}} -
- -
- - {{tokenResultData.expiry}} -
- -
- - {{tokenResultData.user}} -
- -
- - {{tokenResultData.targetURL}} -
- -
- - Homepage URL -
-
-
\ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css new file mode 100644 index 0000000000..f6f023b411 --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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. + */ + +.reduce-icon-size { + transform: scale(0.65); +} + +.icon-label { + display: flex; + align-items: center; + gap: 4px; + margin-bottom: 4px; +} + +.tokenResultDisplay { + margin-left: 1.75%; + margin-right: 1.75%; + background-color: #e1e1e1; +} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html new file mode 100644 index 0000000000..07ecb34b52 --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html @@ -0,0 +1,117 @@ + +
+
+
+
+

Token Generation

+ + + + + + + + + +
+ + + + + + + +
+ +
+ +
+ + + +
+
+ + {{requestErrorMessage}} + warning + + +
+ +
+
+
+
+ +
+ + +
+ {{tokenResultData.accessToken}} +
+ + +
+ {{tokenResultData.accessPasscode}} +
+ + +
+ {{tokenResultData.expiry}} +
+ + +
+ {{tokenResultData.user}} +
+ + +
+ {{tokenResultData.targetURL}} +
+ + + +
+
\ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation.component.ts b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts similarity index 86% rename from knox-token-generation-ui/token-generation/app/token-generation.component.ts rename to knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts index 4eb7030893..fd45fef878 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation.component.ts +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts @@ -14,17 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { HttpClient} from '@angular/common/http'; +import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; -import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms'; import Swal from 'sweetalert2'; -import { TokenResultData, TssStatusData } from './token-generation.models'; -import { TokenGenService } from './token-generation.service'; +import { TokenResultData } from '../model/token.result.data'; +import { TssStatusData } from '../model/tss.status.data'; +import { TokenGenService } from '../service/token-generation.service'; +import { CommonModule } from '@angular/common'; +import { MatIconModule } from '@angular/material/icon'; @Component({ - selector: 'app-token-generation', - templateUrl: './token-generation.component.html', - providers: [] + selector: 'app-token-generation', + templateUrl: './token-generation.component.html', + styleUrls: ['./token-generation.component.css'], + providers: [TokenGenService], + standalone: true, + imports: [CommonModule, ReactiveFormsModule, MatIconModule] }) export class TokenGenerationComponent implements OnInit { tssStatusMessageLevel: 'info' | 'warning' | 'error'; @@ -33,27 +39,27 @@ export class TokenGenerationComponent implements OnInit { hasResult: boolean; // Data coming from the form - tokenGenFrom = new FormGroup({ - comment : new FormControl('', Validators.maxLength(255)), - lifespanDays : new FormControl(0, [ + tokenGenFrom = new UntypedFormGroup({ + comment : new UntypedFormControl('', Validators.maxLength(255)), + lifespanDays : new UntypedFormControl(0, [ Validators.min(0), Validators.max(3650), Validators.required, Validators.pattern('^[0-9]*$') ]), - lifespanHours : new FormControl(1, [ + lifespanHours : new UntypedFormControl(1, [ Validators.min(0), Validators.max(23), Validators.required, Validators.pattern('^[0-9]*$') ]), - lifespanMins : new FormControl(0, [ + lifespanMins : new UntypedFormControl(0, [ Validators.min(0), Validators.max(59), Validators.required, Validators.pattern('^[0-9]*$') ]), - impersonation : new FormControl('', Validators.maxLength(255)) + impersonation : new UntypedFormControl('', Validators.maxLength(255)) }, this.allZeroValidator()); get comment() { return this.tokenGenFrom.get('comment'); } @@ -166,7 +172,7 @@ export class TokenGenerationComponent implements OnInit { } private allZeroValidator(): ValidatorFn { - return (formGroup: FormGroup) => { + return (formGroup: UntypedFormGroup) => { if ( formGroup.get('lifespanDays').value === 0 && formGroup.get('lifespanHours').value === 0 && diff --git a/knox-token-generation-ui/token-generation/app/util/safehtml.ts b/knox-token-generation-ui/token-generation/app/util/safehtml.ts new file mode 100644 index 0000000000..cdf6aef477 --- /dev/null +++ b/knox-token-generation-ui/token-generation/app/util/safehtml.ts @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 {Pipe, PipeTransform} from '@angular/core'; +import {DomSanitizer} from '@angular/platform-browser'; + +@Pipe({ name: 'safeHtml' }) +export class SafeHtmlPipe implements PipeTransform { + constructor(private sanitizer: DomSanitizer) {} + + transform(value) { + return this.sanitizer.bypassSecurityTrustHtml(value); + } +} diff --git a/knox-token-generation-ui/token-generation/assets/styles/bootstrap.min.css b/knox-token-generation-ui/token-generation/assets/styles/bootstrap.min.css deleted file mode 100644 index 3f51c490f9..0000000000 --- a/knox-token-generation-ui/token-generation/assets/styles/bootstrap.min.css +++ /dev/null @@ -1,6422 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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. - */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} -audio:not([controls]) { - display: none; -} -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -a:hover, -a:active { - outline: 0; -} -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - /* Responsive images (ensure images don't scale beyond their parents) */ - max-width: 100%; - /* Part 1: Set a maxium relative to the parent */ - width: auto\9; - /* IE7-8 need help adjusting responsive images */ - height: auto; - /* Part 2: Scale the height according to the width, otherwise you get stretching */ - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} -#map_canvas img, -.google-maps img { - max-width: none; -} -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; -} -button, -input { - *overflow: visible; - line-height: normal; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; -} -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; -} -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; -} -textarea { - overflow: auto; - vertical-align: top; -} -@media print { - * { - text-shadow: none !important; - color: #000 !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 0.5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } -} -.clearfix { - *zoom: 1; -} -.clearfix:before, -.clearfix:after { - display: table; - content: ""; - line-height: 0; -} -.clearfix:after { - clear: both; -} -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.input-block-level { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -body { - margin: 0; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - line-height: 20px; - color: #444444; - background-color: #f1f1f1; -} -a { - color: #3ea211; - text-decoration: none; -} -a:hover, -a:focus { - color: #245d0a; - text-decoration: underline; -} -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.img-polaroid { - padding: 4px; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} -.img-circle { - -webkit-border-radius: 500px; - -moz-border-radius: 500px; - border-radius: 500px; -} -.row { - margin-left: -30px; - *zoom: 1; -} -.row:before, -.row:after { - display: table; - content: ""; - line-height: 0; -} -.row:after { - clear: both; -} -[class*="span"] { - float: left; - min-height: 1px; - margin-left: 30px; -} -.container, -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 870px; -} -.span12 { - width: 870px; -} -.span11 { - width: 795px; -} -.span10 { - width: 720px; -} -.span9 { - width: 645px; -} -.span8 { - width: 570px; -} -.span7 { - width: 495px; -} -.span6 { - width: 420px; -} -.span5 { - width: 345px; -} -.span4 { - width: 270px; -} -.span3 { - width: 195px; -} -.span2 { - width: 120px; -} -.span1 { - width: 45px; -} -.offset12 { - margin-left: 930px; -} -.offset11 { - margin-left: 855px; -} -.offset10 { - margin-left: 780px; -} -.offset9 { - margin-left: 705px; -} -.offset8 { - margin-left: 630px; -} -.offset7 { - margin-left: 555px; -} -.offset6 { - margin-left: 480px; -} -.offset5 { - margin-left: 405px; -} -.offset4 { - margin-left: 330px; -} -.offset3 { - margin-left: 255px; -} -.offset2 { - margin-left: 180px; -} -.offset1 { - margin-left: 105px; -} -.row-fluid { - width: 100%; - *zoom: 1; -} -.row-fluid:before, -.row-fluid:after { - display: table; - content: ""; - line-height: 0; -} -.row-fluid:after { - clear: both; -} -.row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 3.44827586%; - *margin-left: 3.3908046%; -} -.row-fluid [class*="span"]:first-child { - margin-left: 0; -} -.row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 3.44827586%; -} -.row-fluid .span12 { - width: 100%; - *width: 99.94252874%; -} -.row-fluid .span11 { - width: 91.37931034%; - *width: 91.32183908%; -} -.row-fluid .span10 { - width: 82.75862069%; - *width: 82.70114943%; -} -.row-fluid .span9 { - width: 74.13793103%; - *width: 74.08045977%; -} -.row-fluid .span8 { - width: 65.51724138%; - *width: 65.45977011%; -} -.row-fluid .span7 { - width: 56.89655172%; - *width: 56.83908046%; -} -.row-fluid .span6 { - width: 48.27586207%; - *width: 48.2183908%; -} -.row-fluid .span5 { - width: 39.65517241%; - *width: 39.59770115%; -} -.row-fluid .span4 { - width: 31.03448276%; - *width: 30.97701149%; -} -.row-fluid .span3 { - width: 22.4137931%; - *width: 22.35632184%; -} -.row-fluid .span2 { - width: 13.79310345%; - *width: 13.73563218%; -} -.row-fluid .span1 { - width: 5.17241379%; - *width: 5.11494253%; -} -.row-fluid .offset12 { - margin-left: 106.89655172%; - *margin-left: 106.7816092%; -} -.row-fluid .offset12:first-child { - margin-left: 103.44827586%; - *margin-left: 103.33333333%; -} -.row-fluid .offset11 { - margin-left: 98.27586207%; - *margin-left: 98.16091954%; -} -.row-fluid .offset11:first-child { - margin-left: 94.82758621%; - *margin-left: 94.71264368%; -} -.row-fluid .offset10 { - margin-left: 89.65517241%; - *margin-left: 89.54022989%; -} -.row-fluid .offset10:first-child { - margin-left: 86.20689655%; - *margin-left: 86.09195402%; -} -.row-fluid .offset9 { - margin-left: 81.03448276%; - *margin-left: 80.91954023%; -} -.row-fluid .offset9:first-child { - margin-left: 77.5862069%; - *margin-left: 77.47126437%; -} -.row-fluid .offset8 { - margin-left: 72.4137931%; - *margin-left: 72.29885057%; -} -.row-fluid .offset8:first-child { - margin-left: 68.96551724%; - *margin-left: 68.85057471%; -} -.row-fluid .offset7 { - margin-left: 63.79310345%; - *margin-left: 63.67816092%; -} -.row-fluid .offset7:first-child { - margin-left: 60.34482759%; - *margin-left: 60.22988506%; -} -.row-fluid .offset6 { - margin-left: 55.17241379%; - *margin-left: 55.05747126%; -} -.row-fluid .offset6:first-child { - margin-left: 51.72413793%; - *margin-left: 51.6091954%; -} -.row-fluid .offset5 { - margin-left: 46.55172414%; - *margin-left: 46.43678161%; -} -.row-fluid .offset5:first-child { - margin-left: 43.10344828%; - *margin-left: 42.98850575%; -} -.row-fluid .offset4 { - margin-left: 37.93103448%; - *margin-left: 37.81609195%; -} -.row-fluid .offset4:first-child { - margin-left: 34.48275862%; - *margin-left: 34.36781609%; -} -.row-fluid .offset3 { - margin-left: 29.31034483%; - *margin-left: 29.1954023%; -} -.row-fluid .offset3:first-child { - margin-left: 25.86206897%; - *margin-left: 25.74712644%; -} -.row-fluid .offset2 { - margin-left: 20.68965517%; - *margin-left: 20.57471264%; -} -.row-fluid .offset2:first-child { - margin-left: 17.24137931%; - *margin-left: 17.12643678%; -} -.row-fluid .offset1 { - margin-left: 12.06896552%; - *margin-left: 11.95402299%; -} -.row-fluid .offset1:first-child { - margin-left: 8.62068966%; - *margin-left: 8.50574713%; -} -[class*="span"].hide, -.row-fluid [class*="span"].hide { - display: none; -} -[class*="span"].pull-right, -.row-fluid [class*="span"].pull-right { - float: right; -} -.container { - margin-right: auto; - margin-left: auto; - *zoom: 1; -} -.container:before, -.container:after { - display: table; - content: ""; - line-height: 0; -} -.container:after { - clear: both; -} -.container-fluid { - padding-right: 30px; - padding-left: 30px; - *zoom: 1; -} -.container-fluid:before, -.container-fluid:after { - display: table; - content: ""; - line-height: 0; -} -.container-fluid:after { - clear: both; -} -p { - margin: 0 0 10px; -} -.lead { - margin-bottom: 20px; - font-size: 19.5px; - font-weight: 200; - line-height: 30px; -} -small { - font-size: 85%; -} -strong { - font-weight: bold; -} -em { - font-style: italic; -} -cite { - font-style: normal; -} -.muted { - color: #999999; -} -a.muted:hover, -a.muted:focus { - color: #808080; -} -.text-warning { - color: #aa7d29; -} -a.text-warning:hover, -a.text-warning:focus { - color: #815f1f; -} -.text-error { - color: #b85355; -} -a.text-error:hover, -a.text-error:focus { - color: #993f41; -} -.text-info { - color: #4e7b86; -} -a.text-info:hover, -a.text-info:focus { - color: #3b5d66; -} -.text-success { - color: #5c8846; -} -a.text-success:hover, -a.text-success:focus { - color: #456635; -} -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 10px 0; - font-family: inherit; - font-weight: bold; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; -} -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} -h1, -h2, -h3 { - line-height: 40px; -} -h1 { - font-size: 35.75px; -} -h2 { - font-size: 29.25px; -} -h3 { - font-size: 22.75px; -} -h4 { - font-size: 16.25px; -} -h5 { - font-size: 13px; -} -h6 { - font-size: 11.05px; -} -h1 small { - font-size: 22.75px; -} -h2 small { - font-size: 16.25px; -} -h3 small { - font-size: 13px; -} -h4 small { - font-size: 13px; -} -.page-header { - padding-bottom: 9px; - margin: 20px 0 30px; - border-bottom: 1px solid #eeeeee; -} -ul, -ol { - padding: 0; - margin: 0 0 10px 25px; -} -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} -li { - line-height: 20px; -} -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; -} -ul.inline > li, -ol.inline > li { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - padding-left: 5px; - padding-right: 5px; -} -dl { - margin-bottom: 20px; -} -dt, -dd { - line-height: 20px; -} -dt { - font-weight: bold; -} -dd { - margin-left: 10px; -} -.dl-horizontal { - *zoom: 1; -} -.dl-horizontal:before, -.dl-horizontal:after { - display: table; - content: ""; - line-height: 0; -} -.dl-horizontal:after { - clear: both; -} -.dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.dl-horizontal dd { - margin-left: 180px; -} -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; -} -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} -blockquote p { - margin-bottom: 0; - font-size: 16.25px; - font-weight: 300; - line-height: 1.25; -} -blockquote small { - display: block; - line-height: 20px; - color: #999999; -} -blockquote small:before { - content: '\2014 \00A0'; -} -blockquote.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} -blockquote.pull-right small:before { - content: ''; -} -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; -} -code, -pre { - padding: 0 3px 2px; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - font-size: 11px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -code { - padding: 2px 4px; - color: #d14; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; - white-space: nowrap; -} -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 12px; - line-height: 20px; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -pre.prettyprint { - margin-bottom: 20px; -} -pre code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} -form { - margin: 0 0 20px; -} -fieldset { - padding: 0; - margin: 0; - border: 0; -} -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 19.5px; - line-height: 40px; - color: #444444; - border: 0; - border-bottom: 1px solid #e5e5e5; -} -legend small { - font-size: 15px; - color: #999999; -} -label, -input, -button, -select, -textarea { - font-size: 13px; - font-weight: normal; - line-height: 20px; -} -input, -button, -select, -textarea { - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; -} -label { - display: block; - margin-bottom: 5px; -} -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 20px; - padding: 4px 6px; - margin-bottom: 10px; - font-size: 13px; - line-height: 20px; - color: #555555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - vertical-align: middle; -} -input, -textarea, -.uneditable-input { - width: 206px; -} -textarea { - height: auto; -} -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: #ffffff; - border: 1px solid #c4c4c4; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-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 linear .2s, box-shadow linear .2s; - -moz-transition: border linear .2s, box-shadow linear .2s; - -o-transition: border linear .2s, box-shadow linear .2s; - transition: border linear .2s, box-shadow linear .2s; -} -textarea:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="datetime"]:focus, -input[type="datetime-local"]:focus, -input[type="date"]:focus, -input[type="month"]:focus, -input[type="time"]:focus, -input[type="week"]:focus, -input[type="number"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="search"]:focus, -input[type="tel"]:focus, -input[type="color"]:focus, -.uneditable-input:focus { - border-color: rgba(82, 168, 236, 0.8); - outline: 0; - outline: thin dotted \9; - /* IE6-9 */ - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); -} -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; - /* IE7 */ - margin-top: 1px \9; - /* IE8-9 */ - line-height: normal; -} -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; -} -select, -input[type="file"] { - height: 30px; - /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ - line-height: 30px; -} -select { - width: 220px; - border: 1px solid #c4c4c4; - background-color: #ffffff; -} -select[multiple], -select[size] { - height: auto; -} -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.uneditable-input, -.uneditable-textarea { - color: #999999; - background-color: #fcfcfc; - border-color: #c4c4c4; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - cursor: not-allowed; -} -.uneditable-input { - overflow: hidden; - white-space: nowrap; -} -.uneditable-textarea { - width: auto; - height: auto; -} -input:-moz-placeholder, -textarea:-moz-placeholder { - color: #999999; -} -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #999999; -} -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #999999; -} -.radio, -.checkbox { - min-height: 20px; - padding-left: 20px; -} -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; -} -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; -} -.input-mini { - width: 60px; -} -.input-small { - width: 90px; -} -.input-medium { - width: 150px; -} -.input-large { - width: 210px; -} -.input-xlarge { - width: 270px; -} -.input-xxlarge { - width: 530px; -} -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} -input, -textarea, -.uneditable-input { - margin-left: 0; -} -.controls-row [class*="span"] + [class*="span"] { - margin-left: 30px; -} -input.span12, -textarea.span12, -.uneditable-input.span12 { - width: 856px; -} -input.span11, -textarea.span11, -.uneditable-input.span11 { - width: 781px; -} -input.span10, -textarea.span10, -.uneditable-input.span10 { - width: 706px; -} -input.span9, -textarea.span9, -.uneditable-input.span9 { - width: 631px; -} -input.span8, -textarea.span8, -.uneditable-input.span8 { - width: 556px; -} -input.span7, -textarea.span7, -.uneditable-input.span7 { - width: 481px; -} -input.span6, -textarea.span6, -.uneditable-input.span6 { - width: 406px; -} -input.span5, -textarea.span5, -.uneditable-input.span5 { - width: 331px; -} -input.span4, -textarea.span4, -.uneditable-input.span4 { - width: 256px; -} -input.span3, -textarea.span3, -.uneditable-input.span3 { - width: 181px; -} -input.span2, -textarea.span2, -.uneditable-input.span2 { - width: 106px; -} -input.span1, -textarea.span1, -.uneditable-input.span1 { - width: 31px; -} -.controls-row { - *zoom: 1; -} -.controls-row:before, -.controls-row:after { - display: table; - content: ""; - line-height: 0; -} -.controls-row:after { - clear: both; -} -.controls-row [class*="span"], -.row-fluid .controls-row [class*="span"] { - float: left; -} -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: #eeeeee; -} -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} -.control-group.warning .control-label, -.control-group.warning .help-block, -.control-group.warning .help-inline { - color: #aa7d29; -} -.control-group.warning .checkbox, -.control-group.warning .radio, -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - color: #aa7d29; -} -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - border-color: #aa7d29; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.control-group.warning input:focus, -.control-group.warning select:focus, -.control-group.warning textarea:focus { - border-color: #815f1f; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d9af60; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d9af60; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d9af60; -} -.control-group.warning .input-prepend .add-on, -.control-group.warning .input-append .add-on { - color: #aa7d29; - background-color: #fcf8e3; - border-color: #aa7d29; -} -.control-group.error .control-label, -.control-group.error .help-block, -.control-group.error .help-inline { - color: #b85355; -} -.control-group.error .checkbox, -.control-group.error .radio, -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - color: #b85355; -} -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - border-color: #b85355; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.control-group.error input:focus, -.control-group.error select:focus, -.control-group.error textarea:focus { - border-color: #993f41; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d69b9c; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d69b9c; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d69b9c; -} -.control-group.error .input-prepend .add-on, -.control-group.error .input-append .add-on { - color: #b85355; - background-color: #f2dede; - border-color: #b85355; -} -.control-group.success .control-label, -.control-group.success .help-block, -.control-group.success .help-inline { - color: #5c8846; -} -.control-group.success .checkbox, -.control-group.success .radio, -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - color: #5c8846; -} -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - border-color: #5c8846; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.control-group.success input:focus, -.control-group.success select:focus, -.control-group.success textarea:focus { - border-color: #456635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #8fba7a; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #8fba7a; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #8fba7a; -} -.control-group.success .input-prepend .add-on, -.control-group.success .input-append .add-on { - color: #5c8846; - background-color: #dff0d8; - border-color: #5c8846; -} -.control-group.info .control-label, -.control-group.info .help-block, -.control-group.info .help-inline { - color: #4e7b86; -} -.control-group.info .checkbox, -.control-group.info .radio, -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - color: #4e7b86; -} -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - border-color: #4e7b86; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} -.control-group.info input:focus, -.control-group.info select:focus, -.control-group.info textarea:focus { - border-color: #3b5d66; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #83adb7; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #83adb7; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #83adb7; -} -.control-group.info .input-prepend .add-on, -.control-group.info .input-append .add-on { - color: #4e7b86; - background-color: #d9edf7; - border-color: #4e7b86; -} -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; -} -input:focus:invalid:focus, -textarea:focus:invalid:focus, -select:focus:invalid:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} -.form-actions { - padding: 19px 20px 20px; - margin-top: 20px; - margin-bottom: 20px; - background-color: #f5f5f5; - border-top: 1px solid #e5e5e5; - *zoom: 1; -} -.form-actions:before, -.form-actions:after { - display: table; - content: ""; - line-height: 0; -} -.form-actions:after { - clear: both; -} -.help-block, -.help-inline { - color: #6a6a6a; -} -.help-block { - display: block; - margin-bottom: 10px; -} -.help-inline { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - vertical-align: middle; - padding-left: 5px; -} -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: 10px; - vertical-align: middle; - font-size: 0; - white-space: nowrap; -} -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input, -.input-append .dropdown-menu, -.input-prepend .dropdown-menu, -.input-append .popover, -.input-prepend .popover { - font-size: 13px; -} -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input { - position: relative; - margin-bottom: 0; - *margin-left: 0; - vertical-align: top; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append input:focus, -.input-prepend input:focus, -.input-append select:focus, -.input-prepend select:focus, -.input-append .uneditable-input:focus, -.input-prepend .uneditable-input:focus { - z-index: 2; -} -.input-append .add-on, -.input-prepend .add-on { - display: inline-block; - width: auto; - height: 20px; - min-width: 16px; - padding: 4px 5px; - font-size: 13px; - font-weight: normal; - line-height: 20px; - text-align: center; - text-shadow: 0 1px 0 #ffffff; - background-color: #eeeeee; - border: 1px solid #ccc; -} -.input-append .add-on, -.input-prepend .add-on, -.input-append .btn, -.input-prepend .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .btn-group > .dropdown-toggle { - vertical-align: top; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-append .active, -.input-prepend .active { - background-color: #a9dba9; - border-color: #46a546; -} -.input-prepend .add-on, -.input-prepend .btn { - margin-right: -1px; -} -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input + .btn-group .btn:last-child, -.input-append select + .btn-group .btn:last-child, -.input-append .uneditable-input + .btn-group .btn:last-child { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group { - margin-left: -1px; -} -.input-append .add-on:last-child, -.input-append .btn:last-child, -.input-append .btn-group:last-child > .dropdown-toggle { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend.input-append input + .btn-group .btn, -.input-prepend.input-append select + .btn-group .btn, -.input-prepend.input-append .uneditable-input + .btn-group .btn { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-right: -1px; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-left: -1px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .btn-group:first-child { - margin-left: 0; -} -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; - /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin-bottom: 0; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -/* Allow for input prepend/append in search forms */ -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.form-search .input-append .search-query { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.form-search .input-append .btn { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .search-query { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .btn { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.form-search input, -.form-inline input, -.form-horizontal input, -.form-search textarea, -.form-inline textarea, -.form-horizontal textarea, -.form-search select, -.form-inline select, -.form-horizontal select, -.form-search .help-inline, -.form-inline .help-inline, -.form-horizontal .help-inline, -.form-search .uneditable-input, -.form-inline .uneditable-input, -.form-horizontal .uneditable-input, -.form-search .input-prepend, -.form-inline .input-prepend, -.form-horizontal .input-prepend, -.form-search .input-append, -.form-inline .input-append, -.form-horizontal .input-append { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .hide, -.form-inline .hide, -.form-horizontal .hide { - display: none; -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} -.control-group { - margin-bottom: 10px; -} -legend + .control-group { - margin-top: 20px; - -webkit-margin-top-collapse: separate; -} -.form-horizontal .control-group { - margin-bottom: 20px; - *zoom: 1; -} -.form-horizontal .control-group:before, -.form-horizontal .control-group:after { - display: table; - content: ""; - line-height: 0; -} -.form-horizontal .control-group:after { - clear: both; -} -.form-horizontal .control-label { - float: left; - width: 160px; - padding-top: 5px; - text-align: right; -} -.form-horizontal .controls { - *display: inline-block; - *padding-left: 20px; - margin-left: 180px; - *margin-left: 0; -} -.form-horizontal .controls:first-child { - *padding-left: 180px; -} -.form-horizontal .help-block { - margin-bottom: 0; -} -.form-horizontal input + .help-block, -.form-horizontal select + .help-block, -.form-horizontal textarea + .help-block, -.form-horizontal .uneditable-input + .help-block, -.form-horizontal .input-prepend + .help-block, -.form-horizontal .input-append + .help-block { - margin-top: 10px; -} -.form-horizontal .form-actions { - padding-left: 180px; -} -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} -.table { - width: 100%; - margin-bottom: 20px; -} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #dddddd; -} -.table th { - font-weight: bold; -} -.table thead th { - vertical-align: bottom; -} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; -} -.table tbody + tbody { - border-top: 2px solid #dddddd; -} -.table .table { - background-color: #f1f1f1; -} -.table-condensed th, -.table-condensed td { - padding: 4px 5px; -} -.table-bordered { - border: 1px solid #dddddd; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.table-bordered th, -.table-bordered td { - border-left: 1px solid #dddddd; -} -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; -} -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; - border-bottom-left-radius: 0; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; - border-bottom-right-radius: 0; -} -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: #f5f5f5; -} -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; -} -.table td.span1, -.table th.span1 { - float: none; - width: 29px; - margin-left: 0; -} -.table td.span2, -.table th.span2 { - float: none; - width: 104px; - margin-left: 0; -} -.table td.span3, -.table th.span3 { - float: none; - width: 179px; - margin-left: 0; -} -.table td.span4, -.table th.span4 { - float: none; - width: 254px; - margin-left: 0; -} -.table td.span5, -.table th.span5 { - float: none; - width: 329px; - margin-left: 0; -} -.table td.span6, -.table th.span6 { - float: none; - width: 404px; - margin-left: 0; -} -.table td.span7, -.table th.span7 { - float: none; - width: 479px; - margin-left: 0; -} -.table td.span8, -.table th.span8 { - float: none; - width: 554px; - margin-left: 0; -} -.table td.span9, -.table th.span9 { - float: none; - width: 629px; - margin-left: 0; -} -.table td.span10, -.table th.span10 { - float: none; - width: 704px; - margin-left: 0; -} -.table td.span11, -.table th.span11 { - float: none; - width: 779px; - margin-left: 0; -} -.table td.span12, -.table th.span12 { - float: none; - width: 854px; - margin-left: 0; -} -.table tbody tr.success > td { - background-color: #dff0d8; -} -.table tbody tr.error > td { - background-color: #f2dede; -} -.table tbody tr.warning > td { - background-color: #fcf8e3; -} -.table tbody tr.info > td { - background-color: #d9edf7; -} -.table-hover tbody tr.success:hover > td { - background-color: #d0e9c6; -} -.table-hover tbody tr.error:hover > td { - background-color: #ebcccc; -} -.table-hover tbody tr.warning:hover > td { - background-color: #faf2cc; -} -.table-hover tbody tr.info:hover > td { - background-color: #c4e3f3; -} -/*! - * Font Awesome 3.2.1 - * the iconic font designed for Bootstrap - * ------------------------------------------------------------------------------ - * The full suite of pictographic icons, examples, and documentation can be - * found at http://fontawesome.io. Stay up to date on Twitter at - * http://twitter.com/fontawesome. - * - * License - * ------------------------------------------------------------------------------ - * - The Font Awesome font is licensed under SIL OFL 1.1 - - * http://scripts.sil.org/OFL - * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - - * http://opensource.org/licenses/mit-license.html - * - Font Awesome documentation licensed under CC BY 3.0 - - * http://creativecommons.org/licenses/by/3.0/ - * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: - * "Font Awesome by Dave Gandy - http://fontawesome.io" - * - * Author - Dave Gandy - * ------------------------------------------------------------------------------ - * Email: dave@fontawesome.io - * Twitter: http://twitter.com/davegandy - * Work: Lead Product Designer @ Kyruus - http://kyruus.com - */ -/* FONT PATH - * -------------------------- */ -@font-face { - font-family: 'FontAwesome'; - src: url('../../assets/fonts/fontawesome/fontawesome-webfont.eot?v=3.2.1'); - src: url('../../assets/fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../../assets/fonts/fontawesome/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../../assets/fonts/fontawesome/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../../assets/fonts/fontawesome/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); - font-weight: normal; - font-style: normal; -} -/* FONT AWESOME CORE - * -------------------------- */ -[class^="icon-"], -[class*=" icon-"] { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - text-decoration: inherit; - -webkit-font-smoothing: antialiased; - *margin-right: .3em; -} -[class^="icon-"]:before, -[class*=" icon-"]:before { - text-decoration: inherit; - display: inline-block; - speak: none; -} -/* makes the font 33% larger relative to the icon container */ -.icon-large:before { - vertical-align: -10%; - font-size: 1.33333333em; -} -/* makes sure icons active on rollover in links */ -a [class^="icon-"], -a [class*=" icon-"] { - display: inline; -} -/* increased font size for icon-large */ -[class^="icon-"].icon-fixed-width, -[class*=" icon-"].icon-fixed-width { - display: inline-block; - width: 1.14285714em; - text-align: right; - padding-right: 0.28571429em; -} -[class^="icon-"].icon-fixed-width.icon-large, -[class*=" icon-"].icon-fixed-width.icon-large { - width: 1.42857143em; -} -.icons-ul { - margin-left: 2.14285714em; - list-style-type: none; -} -.icons-ul > li { - position: relative; -} -.icons-ul .icon-li { - position: absolute; - left: -2.14285714em; - width: 2.14285714em; - text-align: center; - line-height: inherit; -} -[class^="icon-"].hide, -[class*=" icon-"].hide { - display: none; -} -.icon-muted { - color: #eeeeee; -} -.icon-light { - color: #ffffff; -} -.icon-dark { - color: #333333; -} -.icon-border { - border: solid 1px #eeeeee; - padding: .2em .25em .15em; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.icon-2x { - font-size: 2em; -} -.icon-2x.icon-border { - border-width: 2px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.icon-3x { - font-size: 3em; -} -.icon-3x.icon-border { - border-width: 3px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.icon-4x { - font-size: 4em; -} -.icon-4x.icon-border { - border-width: 4px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.icon-5x { - font-size: 5em; -} -.icon-5x.icon-border { - border-width: 5px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -[class^="icon-"].pull-left, -[class*=" icon-"].pull-left { - margin-right: .3em; -} -[class^="icon-"].pull-right, -[class*=" icon-"].pull-right { - margin-left: .3em; -} -/* BOOTSTRAP SPECIFIC CLASSES - * -------------------------- */ -/* Bootstrap 2.0 sprites.less reset */ -[class^="icon-"], -[class*=" icon-"] { - display: inline; - width: auto; - height: auto; - line-height: normal; - vertical-align: baseline; - background-image: none; - background-position: 0% 0%; - background-repeat: repeat; - margin-top: 0; -} -/* more sprites.less reset */ -.icon-white, -.nav-pills > .active > a > [class^="icon-"], -.nav-pills > .active > a > [class*=" icon-"], -.nav-list > .active > a > [class^="icon-"], -.nav-list > .active > a > [class*=" icon-"], -.navbar-inverse .nav > .active > a > [class^="icon-"], -.navbar-inverse .nav > .active > a > [class*=" icon-"], -.dropdown-menu > li > a:hover > [class^="icon-"], -.dropdown-menu > li > a:hover > [class*=" icon-"], -.dropdown-menu > .active > a > [class^="icon-"], -.dropdown-menu > .active > a > [class*=" icon-"], -.dropdown-submenu:hover > a > [class^="icon-"], -.dropdown-submenu:hover > a > [class*=" icon-"] { - background-image: none; -} -/* keeps Bootstrap styles with and without icons the same */ -.btn [class^="icon-"].icon-large, -.nav [class^="icon-"].icon-large, -.btn [class*=" icon-"].icon-large, -.nav [class*=" icon-"].icon-large { - line-height: .9em; -} -.btn [class^="icon-"].icon-spin, -.nav [class^="icon-"].icon-spin, -.btn [class*=" icon-"].icon-spin, -.nav [class*=" icon-"].icon-spin { - display: inline-block; -} -.nav-tabs [class^="icon-"], -.nav-pills [class^="icon-"], -.nav-tabs [class*=" icon-"], -.nav-pills [class*=" icon-"], -.nav-tabs [class^="icon-"].icon-large, -.nav-pills [class^="icon-"].icon-large, -.nav-tabs [class*=" icon-"].icon-large, -.nav-pills [class*=" icon-"].icon-large { - line-height: .9em; -} -.btn [class^="icon-"].pull-left.icon-2x, -.btn [class*=" icon-"].pull-left.icon-2x, -.btn [class^="icon-"].pull-right.icon-2x, -.btn [class*=" icon-"].pull-right.icon-2x { - margin-top: .18em; -} -.btn [class^="icon-"].icon-spin.icon-large, -.btn [class*=" icon-"].icon-spin.icon-large { - line-height: .8em; -} -.btn.btn-small [class^="icon-"].pull-left.icon-2x, -.btn.btn-small [class*=" icon-"].pull-left.icon-2x, -.btn.btn-small [class^="icon-"].pull-right.icon-2x, -.btn.btn-small [class*=" icon-"].pull-right.icon-2x { - margin-top: .25em; -} -.btn.btn-large [class^="icon-"], -.btn.btn-large [class*=" icon-"] { - margin-top: 0; -} -.btn.btn-large [class^="icon-"].pull-left.icon-2x, -.btn.btn-large [class*=" icon-"].pull-left.icon-2x, -.btn.btn-large [class^="icon-"].pull-right.icon-2x, -.btn.btn-large [class*=" icon-"].pull-right.icon-2x { - margin-top: .05em; -} -.btn.btn-large [class^="icon-"].pull-left.icon-2x, -.btn.btn-large [class*=" icon-"].pull-left.icon-2x { - margin-right: .2em; -} -.btn.btn-large [class^="icon-"].pull-right.icon-2x, -.btn.btn-large [class*=" icon-"].pull-right.icon-2x { - margin-left: .2em; -} -/* Fixes alignment in nav lists */ -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - line-height: inherit; -} -/* EXTRAS - * -------------------------- */ -/* Stacked and layered icon */ -.icon-stack { - position: relative; - display: inline-block; - width: 2em; - height: 2em; - line-height: 2em; - vertical-align: -35%; -} -.icon-stack [class^="icon-"], -.icon-stack [class*=" icon-"] { - display: block; - text-align: center; - position: absolute; - width: 100%; - height: 100%; - font-size: 1em; - line-height: inherit; - *line-height: 2em; -} -.icon-stack .icon-stack-base { - font-size: 2em; - *line-height: 1em; -} -/* Animated rotating icon */ -.icon-spin { - display: inline-block; - -moz-animation: spin 2s infinite linear; - -o-animation: spin 2s infinite linear; - -webkit-animation: spin 2s infinite linear; - animation: spin 2s infinite linear; -} -/* Prevent stack and spinners from being taken inline when inside a link */ -a .icon-stack, -a .icon-spin { - display: inline-block; - text-decoration: none; -} -@-moz-keyframes spin { - 0% { - -moz-transform: rotate(0deg); - } - 100% { - -moz-transform: rotate(359deg); - } -} -@-webkit-keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - } -} -@-o-keyframes spin { - 0% { - -o-transform: rotate(0deg); - } - 100% { - -o-transform: rotate(359deg); - } -} -@-ms-keyframes spin { - 0% { - -ms-transform: rotate(0deg); - } - 100% { - -ms-transform: rotate(359deg); - } -} -@keyframes spin { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(359deg); - } -} -/* Icon rotations and mirroring */ -.icon-rotate-90:before { - -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); - -ms-transform: rotate(90deg); - -o-transform: rotate(90deg); - transform: rotate(90deg); - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -} -.icon-rotate-180:before { - -webkit-transform: rotate(180deg); - -moz-transform: rotate(180deg); - -ms-transform: rotate(180deg); - -o-transform: rotate(180deg); - transform: rotate(180deg); - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); -} -.icon-rotate-270:before { - -webkit-transform: rotate(270deg); - -moz-transform: rotate(270deg); - -ms-transform: rotate(270deg); - -o-transform: rotate(270deg); - transform: rotate(270deg); - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); -} -.icon-flip-horizontal:before { - -webkit-transform: scale(-1, 1); - -moz-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - -o-transform: scale(-1, 1); - transform: scale(-1, 1); -} -.icon-flip-vertical:before { - -webkit-transform: scale(1, -1); - -moz-transform: scale(1, -1); - -ms-transform: scale(1, -1); - -o-transform: scale(1, -1); - transform: scale(1, -1); -} -/* ensure rotation occurs inside anchor tags */ -a .icon-rotate-90:before, -a .icon-rotate-180:before, -a .icon-rotate-270:before, -a .icon-flip-horizontal:before, -a .icon-flip-vertical:before { - display: inline-block; -} -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.icon-glass:before { - content: "\f000"; -} -.icon-music:before { - content: "\f001"; -} -.icon-search:before { - content: "\f002"; -} -.icon-envelope-alt:before { - content: "\f003"; -} -.icon-heart:before { - content: "\f004"; -} -.icon-star:before { - content: "\f005"; -} -.icon-star-empty:before { - content: "\f006"; -} -.icon-user:before { - content: "\f007"; -} -.icon-film:before { - content: "\f008"; -} -.icon-th-large:before { - content: "\f009"; -} -.icon-th:before { - content: "\f00a"; -} -.icon-th-list:before { - content: "\f00b"; -} -.icon-ok:before { - content: "\f00c"; -} -.icon-remove:before { - content: "\f00d"; -} -.icon-zoom-in:before { - content: "\f00e"; -} -.icon-zoom-out:before { - content: "\f010"; -} -.icon-power-off:before, -.icon-off:before { - content: "\f011"; -} -.icon-signal:before { - content: "\f012"; -} -.icon-gear:before, -.icon-cog:before { - content: "\f013"; -} -.icon-trash:before { - content: "\f014"; -} -.icon-home:before { - content: "\f015"; -} -.icon-file-alt:before { - content: "\f016"; -} -.icon-time:before { - content: "\f017"; -} -.icon-road:before { - content: "\f018"; -} -.icon-download-alt:before { - content: "\f019"; -} -.icon-download:before { - content: "\f01a"; -} -.icon-upload:before { - content: "\f01b"; -} -.icon-inbox:before { - content: "\f01c"; -} -.icon-play-circle:before { - content: "\f01d"; -} -.icon-rotate-right:before, -.icon-repeat:before { - content: "\f01e"; -} -.icon-refresh:before { - content: "\f021"; -} -.icon-list-alt:before { - content: "\f022"; -} -.icon-lock:before { - content: "\f023"; -} -.icon-flag:before { - content: "\f024"; -} -.icon-headphones:before { - content: "\f025"; -} -.icon-volume-off:before { - content: "\f026"; -} -.icon-volume-down:before { - content: "\f027"; -} -.icon-volume-up:before { - content: "\f028"; -} -.icon-qrcode:before { - content: "\f029"; -} -.icon-barcode:before { - content: "\f02a"; -} -.icon-tag:before { - content: "\f02b"; -} -.icon-tags:before { - content: "\f02c"; -} -.icon-book:before { - content: "\f02d"; -} -.icon-bookmark:before { - content: "\f02e"; -} -.icon-print:before { - content: "\f02f"; -} -.icon-camera:before { - content: "\f030"; -} -.icon-font:before { - content: "\f031"; -} -.icon-bold:before { - content: "\f032"; -} -.icon-italic:before { - content: "\f033"; -} -.icon-text-height:before { - content: "\f034"; -} -.icon-text-width:before { - content: "\f035"; -} -.icon-align-left:before { - content: "\f036"; -} -.icon-align-center:before { - content: "\f037"; -} -.icon-align-right:before { - content: "\f038"; -} -.icon-align-justify:before { - content: "\f039"; -} -.icon-list:before { - content: "\f03a"; -} -.icon-indent-left:before { - content: "\f03b"; -} -.icon-indent-right:before { - content: "\f03c"; -} -.icon-facetime-video:before { - content: "\f03d"; -} -.icon-picture:before { - content: "\f03e"; -} -.icon-pencil:before { - content: "\f040"; -} -.icon-map-marker:before { - content: "\f041"; -} -.icon-adjust:before { - content: "\f042"; -} -.icon-tint:before { - content: "\f043"; -} -.icon-edit:before { - content: "\f044"; -} -.icon-share:before { - content: "\f045"; -} -.icon-check:before { - content: "\f046"; -} -.icon-move:before { - content: "\f047"; -} -.icon-step-backward:before { - content: "\f048"; -} -.icon-fast-backward:before { - content: "\f049"; -} -.icon-backward:before { - content: "\f04a"; -} -.icon-play:before { - content: "\f04b"; -} -.icon-pause:before { - content: "\f04c"; -} -.icon-stop:before { - content: "\f04d"; -} -.icon-forward:before { - content: "\f04e"; -} -.icon-fast-forward:before { - content: "\f050"; -} -.icon-step-forward:before { - content: "\f051"; -} -.icon-eject:before { - content: "\f052"; -} -.icon-chevron-left:before { - content: "\f053"; -} -.icon-chevron-right:before { - content: "\f054"; -} -.icon-plus-sign:before { - content: "\f055"; -} -.icon-minus-sign:before { - content: "\f056"; -} -.icon-remove-sign:before { - content: "\f057"; -} -.icon-ok-sign:before { - content: "\f058"; -} -.icon-question-sign:before { - content: "\f059"; -} -.icon-info-sign:before { - content: "\f05a"; -} -.icon-screenshot:before { - content: "\f05b"; -} -.icon-remove-circle:before { - content: "\f05c"; -} -.icon-ok-circle:before { - content: "\f05d"; -} -.icon-ban-circle:before { - content: "\f05e"; -} -.icon-arrow-left:before { - content: "\f060"; -} -.icon-arrow-right:before { - content: "\f061"; -} -.icon-arrow-up:before { - content: "\f062"; -} -.icon-arrow-down:before { - content: "\f063"; -} -.icon-mail-forward:before, -.icon-share-alt:before { - content: "\f064"; -} -.icon-resize-full:before { - content: "\f065"; -} -.icon-resize-small:before { - content: "\f066"; -} -.icon-plus:before { - content: "\f067"; -} -.icon-minus:before { - content: "\f068"; -} -.icon-asterisk:before { - content: "\f069"; -} -.icon-exclamation-sign:before { - content: "\f06a"; -} -.icon-gift:before { - content: "\f06b"; -} -.icon-leaf:before { - content: "\f06c"; -} -.icon-fire:before { - content: "\f06d"; -} -.icon-eye-open:before { - content: "\f06e"; -} -.icon-eye-close:before { - content: "\f070"; -} -.icon-warning-sign:before { - content: "\f071"; -} -.icon-plane:before { - content: "\f072"; -} -.icon-calendar:before { - content: "\f073"; -} -.icon-random:before { - content: "\f074"; -} -.icon-comment:before { - content: "\f075"; -} -.icon-magnet:before { - content: "\f076"; -} -.icon-chevron-up:before { - content: "\f077"; -} -.icon-chevron-down:before { - content: "\f078"; -} -.icon-retweet:before { - content: "\f079"; -} -.icon-shopping-cart:before { - content: "\f07a"; -} -.icon-folder-close:before { - content: "\f07b"; -} -.icon-folder-open:before { - content: "\f07c"; -} -.icon-resize-vertical:before { - content: "\f07d"; -} -.icon-resize-horizontal:before { - content: "\f07e"; -} -.icon-bar-chart:before { - content: "\f080"; -} -.icon-twitter-sign:before { - content: "\f081"; -} -.icon-facebook-sign:before { - content: "\f082"; -} -.icon-camera-retro:before { - content: "\f083"; -} -.icon-key:before { - content: "\f084"; -} -.icon-gears:before, -.icon-cogs:before { - content: "\f085"; -} -.icon-comments:before { - content: "\f086"; -} -.icon-thumbs-up-alt:before { - content: "\f087"; -} -.icon-thumbs-down-alt:before { - content: "\f088"; -} -.icon-star-half:before { - content: "\f089"; -} -.icon-heart-empty:before { - content: "\f08a"; -} -.icon-signout:before { - content: "\f08b"; -} -.icon-linkedin-sign:before { - content: "\f08c"; -} -.icon-pushpin:before { - content: "\f08d"; -} -.icon-external-link:before { - content: "\f08e"; -} -.icon-signin:before { - content: "\f090"; -} -.icon-trophy:before { - content: "\f091"; -} -.icon-github-sign:before { - content: "\f092"; -} -.icon-upload-alt:before { - content: "\f093"; -} -.icon-lemon:before { - content: "\f094"; -} -.icon-phone:before { - content: "\f095"; -} -.icon-unchecked:before, -.icon-check-empty:before { - content: "\f096"; -} -.icon-bookmark-empty:before { - content: "\f097"; -} -.icon-phone-sign:before { - content: "\f098"; -} -.icon-twitter:before { - content: "\f099"; -} -.icon-facebook:before { - content: "\f09a"; -} -.icon-github:before { - content: "\f09b"; -} -.icon-unlock:before { - content: "\f09c"; -} -.icon-credit-card:before { - content: "\f09d"; -} -.icon-rss:before { - content: "\f09e"; -} -.icon-hdd:before { - content: "\f0a0"; -} -.icon-bullhorn:before { - content: "\f0a1"; -} -.icon-bell:before { - content: "\f0a2"; -} -.icon-certificate:before { - content: "\f0a3"; -} -.icon-hand-right:before { - content: "\f0a4"; -} -.icon-hand-left:before { - content: "\f0a5"; -} -.icon-hand-up:before { - content: "\f0a6"; -} -.icon-hand-down:before { - content: "\f0a7"; -} -.icon-circle-arrow-left:before { - content: "\f0a8"; -} -.icon-circle-arrow-right:before { - content: "\f0a9"; -} -.icon-circle-arrow-up:before { - content: "\f0aa"; -} -.icon-circle-arrow-down:before { - content: "\f0ab"; -} -.icon-globe:before { - content: "\f0ac"; -} -.icon-wrench:before { - content: "\f0ad"; -} -.icon-tasks:before { - content: "\f0ae"; -} -.icon-filter:before { - content: "\f0b0"; -} -.icon-briefcase:before { - content: "\f0b1"; -} -.icon-fullscreen:before { - content: "\f0b2"; -} -.icon-group:before { - content: "\f0c0"; -} -.icon-link:before { - content: "\f0c1"; -} -.icon-cloud:before { - content: "\f0c2"; -} -.icon-beaker:before { - content: "\f0c3"; -} -.icon-cut:before { - content: "\f0c4"; -} -.icon-copy:before { - content: "\f0c5"; -} -.icon-paperclip:before, -.icon-paper-clip:before { - content: "\f0c6"; -} -.icon-save:before { - content: "\f0c7"; -} -.icon-sign-blank:before { - content: "\f0c8"; -} -.icon-reorder:before { - content: "\f0c9"; -} -.icon-list-ul:before { - content: "\f0ca"; -} -.icon-list-ol:before { - content: "\f0cb"; -} -.icon-strikethrough:before { - content: "\f0cc"; -} -.icon-underline:before { - content: "\f0cd"; -} -.icon-table:before { - content: "\f0ce"; -} -.icon-magic:before { - content: "\f0d0"; -} -.icon-truck:before { - content: "\f0d1"; -} -.icon-pinterest:before { - content: "\f0d2"; -} -.icon-pinterest-sign:before { - content: "\f0d3"; -} -.icon-google-plus-sign:before { - content: "\f0d4"; -} -.icon-google-plus:before { - content: "\f0d5"; -} -.icon-money:before { - content: "\f0d6"; -} -.icon-caret-down:before { - content: "\f0d7"; -} -.icon-caret-up:before { - content: "\f0d8"; -} -.icon-caret-left:before { - content: "\f0d9"; -} -.icon-caret-right:before { - content: "\f0da"; -} -.icon-columns:before { - content: "\f0db"; -} -.icon-sort:before { - content: "\f0dc"; -} -.icon-sort-down:before { - content: "\f0dd"; -} -.icon-sort-up:before { - content: "\f0de"; -} -.icon-envelope:before { - content: "\f0e0"; -} -.icon-linkedin:before { - content: "\f0e1"; -} -.icon-rotate-left:before, -.icon-undo:before { - content: "\f0e2"; -} -.icon-legal:before { - content: "\f0e3"; -} -.icon-dashboard:before { - content: "\f0e4"; -} -.icon-comment-alt:before { - content: "\f0e5"; -} -.icon-comments-alt:before { - content: "\f0e6"; -} -.icon-bolt:before { - content: "\f0e7"; -} -.icon-sitemap:before { - content: "\f0e8"; -} -.icon-umbrella:before { - content: "\f0e9"; -} -.icon-paste:before { - content: "\f0ea"; -} -.icon-lightbulb:before { - content: "\f0eb"; -} -.icon-exchange:before { - content: "\f0ec"; -} -.icon-cloud-download:before { - content: "\f0ed"; -} -.icon-cloud-upload:before { - content: "\f0ee"; -} -.icon-user-md:before { - content: "\f0f0"; -} -.icon-stethoscope:before { - content: "\f0f1"; -} -.icon-suitcase:before { - content: "\f0f2"; -} -.icon-bell-alt:before { - content: "\f0f3"; -} -.icon-coffee:before { - content: "\f0f4"; -} -.icon-food:before { - content: "\f0f5"; -} -.icon-file-text-alt:before { - content: "\f0f6"; -} -.icon-building:before { - content: "\f0f7"; -} -.icon-hospital:before { - content: "\f0f8"; -} -.icon-ambulance:before { - content: "\f0f9"; -} -.icon-medkit:before { - content: "\f0fa"; -} -.icon-fighter-jet:before { - content: "\f0fb"; -} -.icon-beer:before { - content: "\f0fc"; -} -.icon-h-sign:before { - content: "\f0fd"; -} -.icon-plus-sign-alt:before { - content: "\f0fe"; -} -.icon-double-angle-left:before { - content: "\f100"; -} -.icon-double-angle-right:before { - content: "\f101"; -} -.icon-double-angle-up:before { - content: "\f102"; -} -.icon-double-angle-down:before { - content: "\f103"; -} -.icon-angle-left:before { - content: "\f104"; -} -.icon-angle-right:before { - content: "\f105"; -} -.icon-angle-up:before { - content: "\f106"; -} -.icon-angle-down:before { - content: "\f107"; -} -.icon-desktop:before { - content: "\f108"; -} -.icon-laptop:before { - content: "\f109"; -} -.icon-tablet:before { - content: "\f10a"; -} -.icon-mobile-phone:before { - content: "\f10b"; -} -.icon-circle-blank:before { - content: "\f10c"; -} -.icon-quote-left:before { - content: "\f10d"; -} -.icon-quote-right:before { - content: "\f10e"; -} -.icon-spinner:before { - content: "\f110"; -} -.icon-circle:before { - content: "\f111"; -} -.icon-mail-reply:before, -.icon-reply:before { - content: "\f112"; -} -.icon-github-alt:before { - content: "\f113"; -} -.icon-folder-close-alt:before { - content: "\f114"; -} -.icon-folder-open-alt:before { - content: "\f115"; -} -.icon-expand-alt:before { - content: "\f116"; -} -.icon-collapse-alt:before { - content: "\f117"; -} -.icon-smile:before { - content: "\f118"; -} -.icon-frown:before { - content: "\f119"; -} -.icon-meh:before { - content: "\f11a"; -} -.icon-gamepad:before { - content: "\f11b"; -} -.icon-keyboard:before { - content: "\f11c"; -} -.icon-flag-alt:before { - content: "\f11d"; -} -.icon-flag-checkered:before { - content: "\f11e"; -} -.icon-terminal:before { - content: "\f120"; -} -.icon-code:before { - content: "\f121"; -} -.icon-reply-all:before { - content: "\f122"; -} -.icon-mail-reply-all:before { - content: "\f122"; -} -.icon-star-half-full:before, -.icon-star-half-empty:before { - content: "\f123"; -} -.icon-location-arrow:before { - content: "\f124"; -} -.icon-crop:before { - content: "\f125"; -} -.icon-code-fork:before { - content: "\f126"; -} -.icon-unlink:before { - content: "\f127"; -} -.icon-question:before { - content: "\f128"; -} -.icon-info:before { - content: "\f129"; -} -.icon-exclamation:before { - content: "\f12a"; -} -.icon-superscript:before { - content: "\f12b"; -} -.icon-subscript:before { - content: "\f12c"; -} -.icon-eraser:before { - content: "\f12d"; -} -.icon-puzzle-piece:before { - content: "\f12e"; -} -.icon-microphone:before { - content: "\f130"; -} -.icon-microphone-off:before { - content: "\f131"; -} -.icon-shield:before { - content: "\f132"; -} -.icon-calendar-empty:before { - content: "\f133"; -} -.icon-fire-extinguisher:before { - content: "\f134"; -} -.icon-rocket:before { - content: "\f135"; -} -.icon-maxcdn:before { - content: "\f136"; -} -.icon-chevron-sign-left:before { - content: "\f137"; -} -.icon-chevron-sign-right:before { - content: "\f138"; -} -.icon-chevron-sign-up:before { - content: "\f139"; -} -.icon-chevron-sign-down:before { - content: "\f13a"; -} -.icon-html5:before { - content: "\f13b"; -} -.icon-css3:before { - content: "\f13c"; -} -.icon-anchor:before { - content: "\f13d"; -} -.icon-unlock-alt:before { - content: "\f13e"; -} -.icon-bullseye:before { - content: "\f140"; -} -.icon-ellipsis-horizontal:before { - content: "\f141"; -} -.icon-ellipsis-vertical:before { - content: "\f142"; -} -.icon-rss-sign:before { - content: "\f143"; -} -.icon-play-sign:before { - content: "\f144"; -} -.icon-ticket:before { - content: "\f145"; -} -.icon-minus-sign-alt:before { - content: "\f146"; -} -.icon-check-minus:before { - content: "\f147"; -} -.icon-level-up:before { - content: "\f148"; -} -.icon-level-down:before { - content: "\f149"; -} -.icon-check-sign:before { - content: "\f14a"; -} -.icon-edit-sign:before { - content: "\f14b"; -} -.icon-external-link-sign:before { - content: "\f14c"; -} -.icon-share-sign:before { - content: "\f14d"; -} -.icon-compass:before { - content: "\f14e"; -} -.icon-collapse:before { - content: "\f150"; -} -.icon-collapse-top:before { - content: "\f151"; -} -.icon-expand:before { - content: "\f152"; -} -.icon-euro:before, -.icon-eur:before { - content: "\f153"; -} -.icon-gbp:before { - content: "\f154"; -} -.icon-dollar:before, -.icon-usd:before { - content: "\f155"; -} -.icon-rupee:before, -.icon-inr:before { - content: "\f156"; -} -.icon-yen:before, -.icon-jpy:before { - content: "\f157"; -} -.icon-renminbi:before, -.icon-cny:before { - content: "\f158"; -} -.icon-won:before, -.icon-krw:before { - content: "\f159"; -} -.icon-bitcoin:before, -.icon-btc:before { - content: "\f15a"; -} -.icon-file:before { - content: "\f15b"; -} -.icon-file-text:before { - content: "\f15c"; -} -.icon-sort-by-alphabet:before { - content: "\f15d"; -} -.icon-sort-by-alphabet-alt:before { - content: "\f15e"; -} -.icon-sort-by-attributes:before { - content: "\f160"; -} -.icon-sort-by-attributes-alt:before { - content: "\f161"; -} -.icon-sort-by-order:before { - content: "\f162"; -} -.icon-sort-by-order-alt:before { - content: "\f163"; -} -.icon-thumbs-up:before { - content: "\f164"; -} -.icon-thumbs-down:before { - content: "\f165"; -} -.icon-youtube-sign:before { - content: "\f166"; -} -.icon-youtube:before { - content: "\f167"; -} -.icon-xing:before { - content: "\f168"; -} -.icon-xing-sign:before { - content: "\f169"; -} -.icon-youtube-play:before { - content: "\f16a"; -} -.icon-dropbox:before { - content: "\f16b"; -} -.icon-stackexchange:before { - content: "\f16c"; -} -.icon-instagram:before { - content: "\f16d"; -} -.icon-flickr:before { - content: "\f16e"; -} -.icon-adn:before { - content: "\f170"; -} -.icon-bitbucket:before { - content: "\f171"; -} -.icon-bitbucket-sign:before { - content: "\f172"; -} -.icon-tumblr:before { - content: "\f173"; -} -.icon-tumblr-sign:before { - content: "\f174"; -} -.icon-long-arrow-down:before { - content: "\f175"; -} -.icon-long-arrow-up:before { - content: "\f176"; -} -.icon-long-arrow-left:before { - content: "\f177"; -} -.icon-long-arrow-right:before { - content: "\f178"; -} -.icon-apple:before { - content: "\f179"; -} -.icon-windows:before { - content: "\f17a"; -} -.icon-android:before { - content: "\f17b"; -} -.icon-linux:before { - content: "\f17c"; -} -.icon-dribbble:before { - content: "\f17d"; -} -.icon-skype:before { - content: "\f17e"; -} -.icon-foursquare:before { - content: "\f180"; -} -.icon-trello:before { - content: "\f181"; -} -.icon-female:before { - content: "\f182"; -} -.icon-male:before { - content: "\f183"; -} -.icon-gittip:before { - content: "\f184"; -} -.icon-sun:before { - content: "\f185"; -} -.icon-moon:before { - content: "\f186"; -} -.icon-archive:before { - content: "\f187"; -} -.icon-bug:before { - content: "\f188"; -} -.icon-vk:before { - content: "\f189"; -} -.icon-weibo:before { - content: "\f18a"; -} -.icon-renren:before { - content: "\f18b"; -} -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle { - *margin-bottom: -3px; -} -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - background-color: #ffffff; - border: 1px solid #ccc; - border: 1px solid #c0c0c0; - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; -} -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 20px; - color: #444444; - white-space: nowrap; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - text-decoration: none; - color: #ffffff; - background-color: #3a9910; - background-image: -moz-linear-gradient(top, #3ea211, #358b0f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3ea211), to(#358b0f)); - background-image: -webkit-linear-gradient(top, #3ea211, #358b0f); - background-image: -o-linear-gradient(top, #3ea211, #358b0f); - background-image: linear-gradient(to bottom, #3ea211, #358b0f); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3ea211', endColorstr='#ff358b0f', GradientType=0); -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - outline: 0; - background-color: #3a9910; - background-image: -moz-linear-gradient(top, #3ea211, #358b0f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3ea211), to(#358b0f)); - background-image: -webkit-linear-gradient(top, #3ea211, #358b0f); - background-image: -o-linear-gradient(top, #3ea211, #358b0f); - background-image: linear-gradient(to bottom, #3ea211, #358b0f); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3ea211', endColorstr='#ff358b0f', GradientType=0); -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: default; -} -.open { - *z-index: 1000; -} -.open > .dropdown-menu { - display: block; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid #000000; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} -.dropdown-submenu { - position: relative; -} -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - -webkit-border-radius: 0 6px 6px 6px; - -moz-border-radius: 0 6px 6px 6px; - border-radius: 0 6px 6px 6px; -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - -webkit-border-radius: 5px 5px 5px 0; - -moz-border-radius: 5px 5px 5px 0; - border-radius: 5px 5px 5px 0; -} -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: #cccccc; - margin-top: 5px; - margin-right: -10px; -} -.dropdown-submenu:hover > a:after { - border-left-color: #ffffff; -} -.dropdown-submenu.pull-left { - float: none; -} -.dropdown-submenu.pull-left > .dropdown-menu { - left: -100%; - margin-left: 10px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.dropdown .dropdown-menu .nav-header { - padding-left: 20px; - padding-right: 20px; -} -.typeahead { - z-index: 1051; - margin-top: 2px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} -.well-large { - padding: 24px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.well-small { - padding: 9px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -moz-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - -moz-transition: height 0.35s ease; - -o-transition: height 0.35s ease; - transition: height 0.35s ease; -} -.collapse.in { - height: auto; -} -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: 20px; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.btn { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - padding: 4px 12px; - margin-bottom: 0; - font-size: 13px; - line-height: 20px; - text-align: center; - vertical-align: middle; - cursor: pointer; - color: #444444; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - background-color: #f5f5f5; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #e6e6e6; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border: 1px solid #bbbbbb; - *border: 0; - border-bottom-color: #a2a2a2; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - *margin-left: .3em; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); -} -.btn:hover, -.btn:focus, -.btn:active, -.btn.active, -.btn.disabled, -.btn[disabled] { - color: #444444; - background-color: #e6e6e6; - *background-color: #d9d9d9; -} -.btn:active, -.btn.active { - background-color: #cccccc \9; -} -.btn:first-child { - *margin-left: 0; -} -.btn:hover, -.btn:focus { - color: #444444; - text-decoration: none; - background-position: 0 -15px; - -webkit-transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - transition: background-position 0.1s linear; -} -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn.active, -.btn:active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); -} -.btn.disabled, -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-large { - padding: 11px 19px; - font-size: 16.25px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} -.btn-small { - padding: 2px 10px; - font-size: 11.05px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} -.btn-mini { - padding: 0 6px; - font-size: 9.75px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - color: rgba(255, 255, 255, 0.75); -} -.btn-primary { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #2ca212; - background-image: -moz-linear-gradient(top, #3ea211, #11a214); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3ea211), to(#11a214)); - background-image: -webkit-linear-gradient(top, #3ea211, #11a214); - background-image: -o-linear-gradient(top, #3ea211, #11a214); - background-image: linear-gradient(to bottom, #3ea211, #11a214); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3ea211', endColorstr='#ff11a214', GradientType=0); - border-color: #11a214 #11a214 #0a5d0c; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #11a214; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.btn-primary.disabled, -.btn-primary[disabled] { - color: #ffffff; - background-color: #11a214; - *background-color: #0f8b11; -} -.btn-primary:active, -.btn-primary.active { - background-color: #0c740f \9; -} -.btn-warning { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #faa732; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); - border-color: #f89406 #f89406 #ad6704; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #f89406; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.btn-warning.disabled, -.btn-warning[disabled] { - color: #ffffff; - background-color: #f89406; - *background-color: #df8505; -} -.btn-warning:active, -.btn-warning.active { - background-color: #c67605 \9; -} -.btn-danger { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #da4f49; - background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); - background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); - border-color: #bd362f #bd362f #802420; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #bd362f; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.btn-danger.disabled, -.btn-danger[disabled] { - color: #ffffff; - background-color: #bd362f; - *background-color: #a9302a; -} -.btn-danger:active, -.btn-danger.active { - background-color: #942a25 \9; -} -.btn-success { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #5bb75b; - background-image: -moz-linear-gradient(top, #62c462, #51a351); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); - background-image: -webkit-linear-gradient(top, #62c462, #51a351); - background-image: -o-linear-gradient(top, #62c462, #51a351); - background-image: linear-gradient(to bottom, #62c462, #51a351); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); - border-color: #51a351 #51a351 #387038; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #51a351; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.btn-success.disabled, -.btn-success[disabled] { - color: #ffffff; - background-color: #51a351; - *background-color: #499249; -} -.btn-success:active, -.btn-success.active { - background-color: #408140 \9; -} -.btn-info { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #49afcd; - background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); - background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); - background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); - border-color: #2f96b4 #2f96b4 #1f6377; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #2f96b4; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.btn-info.disabled, -.btn-info[disabled] { - color: #ffffff; - background-color: #2f96b4; - *background-color: #2a85a0; -} -.btn-info:active, -.btn-info.active { - background-color: #24748c \9; -} -.btn-inverse { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #363636; - background-image: -moz-linear-gradient(top, #444444, #222222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); - background-image: -webkit-linear-gradient(top, #444444, #222222); - background-image: -o-linear-gradient(top, #444444, #222222); - background-image: linear-gradient(to bottom, #444444, #222222); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); - border-color: #222222 #222222 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #222222; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.btn-inverse:hover, -.btn-inverse:focus, -.btn-inverse:active, -.btn-inverse.active, -.btn-inverse.disabled, -.btn-inverse[disabled] { - color: #ffffff; - background-color: #222222; - *background-color: #151515; -} -.btn-inverse:active, -.btn-inverse.active { - background-color: #080808 \9; -} -button.btn, -input[type="submit"].btn { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn::-moz-focus-inner, -input[type="submit"].btn::-moz-focus-inner { - padding: 0; - border: 0; -} -button.btn.btn-large, -input[type="submit"].btn.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; -} -button.btn.btn-small, -input[type="submit"].btn.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn.btn-mini, -input[type="submit"].btn.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; -} -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-link { - border-color: transparent; - cursor: pointer; - color: #3ea211; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-link:hover, -.btn-link:focus { - color: #245d0a; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: #444444; - text-decoration: none; -} -.btn-group { - position: relative; - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - font-size: 0; - vertical-align: middle; - white-space: nowrap; - *margin-left: .3em; -} -.btn-group:first-child { - *margin-left: 0; -} -.btn-group + .btn-group { - margin-left: 5px; -} -.btn-toolbar { - font-size: 0; - margin-top: 10px; - margin-bottom: 10px; -} -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group { - margin-left: 5px; -} -.btn-group > .btn { - position: relative; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group > .btn + .btn { - margin-left: -1px; -} -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: 13px; -} -.btn-group > .btn-mini { - font-size: 9.75px; -} -.btn-group > .btn-small { - font-size: 11.05px; -} -.btn-group > .btn-large { - font-size: 16.25px; -} -.btn-group > .btn:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.btn-group > .btn.large:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-left-radius: 5px; - -webkit-border-bottom-left-radius: 5px; - -moz-border-radius-bottomleft: 5px; - border-bottom-left-radius: 5px; -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-top-right-radius: 5px; - -webkit-border-bottom-right-radius: 5px; - -moz-border-radius-bottomright: 5px; - border-bottom-right-radius: 5px; -} -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} -.btn-group.open .dropdown-toggle { - background-image: none; - -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); -} -.btn-group.open .btn.dropdown-toggle { - background-color: #e6e6e6; -} -.btn-group.open .btn-primary.dropdown-toggle { - background-color: #11a214; -} -.btn-group.open .btn-warning.dropdown-toggle { - background-color: #f89406; -} -.btn-group.open .btn-danger.dropdown-toggle { - background-color: #bd362f; -} -.btn-group.open .btn-success.dropdown-toggle { - background-color: #51a351; -} -.btn-group.open .btn-info.dropdown-toggle { - background-color: #2f96b4; -} -.btn-group.open .btn-inverse.dropdown-toggle { - background-color: #222222; -} -.btn .caret { - margin-top: 8px; - margin-left: 0; -} -.btn-large .caret { - margin-top: 6px; -} -.btn-large .caret { - border-left-width: 5px; - border-right-width: 5px; - border-top-width: 5px; -} -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} -.dropup .btn-large .caret { - border-bottom-width: 5px; -} -.btn-primary .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret, -.btn-success .caret, -.btn-inverse .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} -.btn-group-vertical { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; -} -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group-vertical > .btn + .btn { - margin-left: 0; - margin-top: -1px; -} -.btn-group-vertical > .btn:first-child { - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.btn-group-vertical > .btn:last-child { - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; -} -.btn-group-vertical > .btn-large:first-child { - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} -.btn-group-vertical > .btn-large:last-child { - -webkit-border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - border-radius: 0 0 5px 5px; -} -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 20px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #aa8134; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.alert, -.alert h4 { - color: #aa7d29; -} -.alert h4 { - margin: 0; -} -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 20px; -} -.alert-success { - background-color: #dff0d8; - border-color: #779867; - color: #5c8846; -} -.alert-success h4 { - color: #5c8846; -} -.alert-danger, -.alert-error { - background-color: #f2dede; - border-color: #b35d5e; - color: #b85355; -} -.alert-danger h4, -.alert-error h4 { - color: #b85355; -} -.alert-info { - background-color: #d9edf7; - border-color: #577981; - color: #4e7b86; -} -.alert-info h4 { - color: #4e7b86; -} -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} -.alert-block p + p { - margin-top: 5px; -} -.nav { - margin-left: 0; - margin-bottom: 20px; - list-style: none; -} -.nav > li > a { - display: block; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} -.nav > li > a > img { - max-width: none; -} -.nav > .pull-right { - float: right; -} -.nav-header { - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: 20px; - color: #999999; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-transform: uppercase; -} -.nav li + .nav-header { - margin-top: 9px; -} -.nav-list { - padding-left: 15px; - padding-right: 15px; - margin-bottom: 0; -} -.nav-list > li > a, -.nav-list .nav-header { - margin-left: -15px; - margin-right: -15px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.nav-list > li > a { - padding: 3px 15px; -} -.nav-list > .active > a, -.nav-list > .active > a:hover, -.nav-list > .active > a:focus { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); - background-color: #3ea211; -} -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} -.nav-list .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; -} -.nav-tabs, -.nav-pills { - *zoom: 1; -} -.nav-tabs:before, -.nav-pills:before, -.nav-tabs:after, -.nav-pills:after { - display: table; - content: ""; - line-height: 0; -} -.nav-tabs:after, -.nav-pills:after { - clear: both; -} -.nav-tabs > li, -.nav-pills > li { - float: left; -} -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; -} -.nav-tabs { - border-bottom: 1px solid #ddd; -} -.nav-tabs > li { - margin-bottom: -1px; -} -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 20px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #dddddd; -} -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - color: #555555; - background-color: #f1f1f1; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.nav-pills > .active > a, -.nav-pills > .active > a:hover, -.nav-pills > .active > a:focus { - color: #ffffff; - background-color: #3ea211; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li > a { - margin-right: 0; -} -.nav-tabs.nav-stacked { - border-bottom: 0; -} -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.nav-tabs.nav-stacked > li:first-child > a { - -webkit-border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; - border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; - border-top-left-radius: 4px; -} -.nav-tabs.nav-stacked > li:last-child > a { - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - border-bottom-left-radius: 4px; -} -.nav-tabs.nav-stacked > li > a:hover, -.nav-tabs.nav-stacked > li > a:focus { - border-color: #ddd; - z-index: 2; -} -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; -} -.nav-tabs .dropdown-menu { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.nav-pills .dropdown-menu { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.nav .dropdown-toggle .caret { - border-top-color: #3ea211; - border-bottom-color: #3ea211; - margin-top: 6px; -} -.nav .dropdown-toggle:hover .caret, -.nav .dropdown-toggle:focus .caret { - border-top-color: #245d0a; - border-bottom-color: #245d0a; -} -/* move down carets for tabs */ -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} -.nav > .dropdown.active > a:hover, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - color: #ffffff; - background-color: #999999; - border-color: #999999; -} -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret, -.nav li.dropdown.open a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; - opacity: 1; - filter: alpha(opacity=100); -} -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - border-color: #999999; -} -.tabbable { - *zoom: 1; -} -.tabbable:before, -.tabbable:after { - display: table; - content: ""; - line-height: 0; -} -.tabbable:after { - clear: both; -} -.tab-content { - overflow: auto; -} -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} -.tab-content > .active, -.pill-content > .active { - display: block; -} -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} -.tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} -.tabs-below > .nav-tabs > li > a:hover, -.tabs-below > .nav-tabs > li > a:focus { - border-bottom-color: transparent; - border-top-color: #ddd; -} -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - border-color: transparent #ddd #ddd #ddd; -} -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} -.tabs-left > .nav-tabs > li > a:hover, -.tabs-left > .nav-tabs > li > a:focus { - border-color: #eeeeee #dddddd #eeeeee #eeeeee; -} -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #ffffff; -} -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} -.tabs-right > .nav-tabs > li > a:hover, -.tabs-right > .nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #eeeeee #dddddd; -} -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #ffffff; -} -.nav > .disabled > a { - color: #999999; -} -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - cursor: default; -} -.navbar { - overflow: visible; - margin-bottom: 20px; - *position: relative; - *z-index: 2; -} -.navbar-inner { - min-height: 40px; - padding-left: 20px; - padding-right: 20px; - background-color: #fafafa; - background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); - background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); - background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); - border: 1px solid #d4d4d4; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - *zoom: 1; -} -.navbar-inner:before, -.navbar-inner:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-inner:after { - clear: both; -} -.navbar .container { - width: auto; -} -.nav-collapse.collapse { - height: auto; - overflow: visible; -} -.navbar .brand { - float: left; - display: block; - padding: 10px 20px 10px; - margin-left: -20px; - font-size: 20px; - font-weight: 200; - color: #777777; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #777777; -} -.navbar-link { - color: #777777; -} -.navbar-link:hover, -.navbar-link:focus { - color: #444444; -} -.navbar .divider-vertical { - height: 40px; - margin: 0 9px; - border-left: 1px solid #f2f2f2; - border-right: 1px solid #ffffff; -} -.navbar .btn, -.navbar .btn-group { - margin-top: 5px; -} -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - margin-top: 0; -} -.navbar-form { - margin-bottom: 0; - *zoom: 1; -} -.navbar-form:before, -.navbar-form:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-form:after { - clear: both; -} -.navbar-form input, -.navbar-form select, -.navbar-form .radio, -.navbar-form .checkbox { - margin-top: 5px; -} -.navbar-form input, -.navbar-form select, -.navbar-form .btn { - display: inline-block; - margin-bottom: 0; -} -.navbar-form input[type="image"], -.navbar-form input[type="checkbox"], -.navbar-form input[type="radio"] { - margin-top: 3px; -} -.navbar-form .input-append, -.navbar-form .input-prepend { - margin-top: 5px; - white-space: nowrap; -} -.navbar-form .input-append input, -.navbar-form .input-prepend input { - margin-top: 0; -} -.navbar-search { - position: relative; - float: left; - margin-top: 5px; - margin-bottom: 0; -} -.navbar-search .search-query { - margin-bottom: 0; - padding: 4px 14px; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.navbar-static-top { - position: static; - margin-bottom: 0; -} -.navbar-static-top .navbar-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; - margin-bottom: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 870px; -} -.navbar-fixed-top { - top: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); - box-shadow: 0 1px 10px rgba(0,0,0,.1); -} -.navbar-fixed-bottom { - bottom: 0; -} -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - box-shadow: 0 -1px 10px rgba(0,0,0,.1); -} -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} -.navbar .nav.pull-right { - float: right; - margin-right: 0; -} -.navbar .nav > li { - float: left; -} -.navbar .nav > li > a { - float: none; - padding: 10px 15px 10px; - color: #777777; - text-decoration: none; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - background-color: transparent; - color: #444444; - text-decoration: none; -} -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: #555555; - text-decoration: none; - background-color: #e5e5e5; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); -} -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-left: 5px; - margin-right: 5px; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #ededed; - background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); - background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); - border-color: #e5e5e5 #e5e5e5 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #e5e5e5; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); -} -.navbar .btn-navbar:hover, -.navbar .btn-navbar:focus, -.navbar .btn-navbar:active, -.navbar .btn-navbar.active, -.navbar .btn-navbar.disabled, -.navbar .btn-navbar[disabled] { - color: #ffffff; - background-color: #e5e5e5; - *background-color: #d9d9d9; -} -.navbar .btn-navbar:active, -.navbar .btn-navbar.active { - background-color: #cccccc \9; -} -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); -} -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} -.navbar .nav > li > .dropdown-menu:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: #c0c0c0; - position: absolute; - top: -7px; - left: 9px; -} -.navbar .nav > li > .dropdown-menu:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - position: absolute; - top: -6px; - left: 10px; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:before { - border-top: 7px solid #ccc; - border-top-color: #c0c0c0; - border-bottom: 0; - bottom: -7px; - top: auto; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:after { - border-top: 6px solid #ffffff; - border-bottom: 0; - bottom: -6px; - top: auto; -} -.navbar .nav li.dropdown > a:hover .caret, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: #444444; - border-bottom-color: #444444; -} -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #e5e5e5; - color: #555555; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - left: auto; - right: 0; -} -.navbar .pull-right > li > .dropdown-menu:before, -.navbar .nav > li > .dropdown-menu.pull-right:before { - left: auto; - right: 12px; -} -.navbar .pull-right > li > .dropdown-menu:after, -.navbar .nav > li > .dropdown-menu.pull-right:after { - left: auto; - right: 13px; -} -.navbar .pull-right > li > .dropdown-menu .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { - left: auto; - right: 100%; - margin-left: 0; - margin-right: -1px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.navbar-inverse .navbar-inner { - background-color: #1b1b1b; - background-image: -moz-linear-gradient(top, #222222, #111111); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); - background-image: -webkit-linear-gradient(top, #222222, #111111); - background-image: -o-linear-gradient(top, #222222, #111111); - background-image: linear-gradient(to bottom, #222222, #111111); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); - border-color: #252525; -} -.navbar-inverse .brand, -.navbar-inverse .nav > li > a { - color: #999999; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} -.navbar-inverse .brand:hover, -.navbar-inverse .nav > li > a:hover, -.navbar-inverse .brand:focus, -.navbar-inverse .nav > li > a:focus { - color: #ffffff; -} -.navbar-inverse .brand { - color: #999999; -} -.navbar-inverse .navbar-text { - color: #999999; -} -.navbar-inverse .nav > li > a:focus, -.navbar-inverse .nav > li > a:hover { - background-color: transparent; - color: #ffffff; -} -.navbar-inverse .nav .active > a, -.navbar-inverse .nav .active > a:hover, -.navbar-inverse .nav .active > a:focus { - color: #ffffff; - background-color: #111111; -} -.navbar-inverse .navbar-link { - color: #999999; -} -.navbar-inverse .navbar-link:hover, -.navbar-inverse .navbar-link:focus { - color: #ffffff; -} -.navbar-inverse .divider-vertical { - border-left-color: #111111; - border-right-color: #222222; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #111111; - color: #ffffff; -} -.navbar-inverse .nav li.dropdown > a:hover .caret, -.navbar-inverse .nav li.dropdown > a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} -.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} -.navbar-inverse .navbar-search .search-query { - color: #ffffff; - background-color: #515151; - border-color: #111111; - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} -.navbar-inverse .navbar-search .search-query:-moz-placeholder { - color: #cccccc; -} -.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { - color: #cccccc; -} -.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { - color: #cccccc; -} -.navbar-inverse .navbar-search .search-query:focus, -.navbar-inverse .navbar-search .search-query.focused { - padding: 5px 15px; - color: #444444; - text-shadow: 0 1px 0 #ffffff; - background-color: #ffffff; - border: 0; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - outline: 0; -} -.navbar-inverse .btn-navbar { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e0e0e; - background-image: -moz-linear-gradient(top, #151515, #040404); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); - background-image: -webkit-linear-gradient(top, #151515, #040404); - background-image: -o-linear-gradient(top, #151515, #040404); - background-image: linear-gradient(to bottom, #151515, #040404); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); - border-color: #040404 #040404 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - *background-color: #040404; - /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.navbar-inverse .btn-navbar:hover, -.navbar-inverse .btn-navbar:focus, -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active, -.navbar-inverse .btn-navbar.disabled, -.navbar-inverse .btn-navbar[disabled] { - color: #ffffff; - background-color: #040404; - *background-color: #000000; -} -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active { - background-color: #000000 \9; -} -@media (max-width: 767px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 20px; - } - .navbar-fixed-bottom { - margin-top: 20px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-left: 10px; - padding-right: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 10px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #777777; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: #777777; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - background-color: #f2f2f2; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: #999999; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - background-color: #111111; - } - .nav-collapse.in .btn-group { - margin-top: 5px; - padding: 0; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - float: none; - display: none; - max-width: none; - margin: 0 15px; - padding: 0; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu:before, - .nav-collapse .nav > li > .dropdown-menu:after { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 10px 15px; - margin: 10px 0; - border-top: 1px solid #f2f2f2; - border-bottom: 1px solid #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: #111111; - border-bottom-color: #111111; - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - overflow: hidden; - height: 0; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-left: 10px; - padding-right: 10px; - } -} -@media (min-width: 768px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} -.breadcrumb { - padding: 8px 15px; - margin: 0 0 20px; - list-style: none; - background-color: #f5f5f5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.breadcrumb > li { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - text-shadow: 0 1px 0 #ffffff; -} -.breadcrumb > li > .divider { - padding: 0 5px; - color: #ccc; -} -.breadcrumb > .active { - color: #999999; -} -.pagination { - margin: 20px 0; -} -.pagination ul { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - *zoom: 1; - margin-left: 0; - margin-bottom: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} -.pagination ul > li { - display: inline; -} -.pagination ul > li > a, -.pagination ul > li > span { - float: left; - padding: 4px 12px; - line-height: 20px; - text-decoration: none; - background-color: transparent; - border: 1px solid #dddddd; - border-left-width: 0; -} -.pagination ul > li > a:hover, -.pagination ul > li > a:focus, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: #3690e6; -} -.pagination ul > .active > a, -.pagination ul > .active > span { - color: #999999; - cursor: default; -} -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover, -.pagination ul > .disabled > a:focus { - color: #999999; - background-color: transparent; - cursor: default; -} -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.pagination-centered { - text-align: center; -} -.pagination-right { - text-align: right; -} -.pagination-large ul > li > a, -.pagination-large ul > li > span { - padding: 11px 19px; - font-size: 16.25px; -} -.pagination-large ul > li:first-child > a, -.pagination-large ul > li:first-child > span { - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-left-radius: 5px; - -webkit-border-bottom-left-radius: 5px; - -moz-border-radius-bottomleft: 5px; - border-bottom-left-radius: 5px; -} -.pagination-large ul > li:last-child > a, -.pagination-large ul > li:last-child > span { - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-top-right-radius: 5px; - -webkit-border-bottom-right-radius: 5px; - -moz-border-radius-bottomright: 5px; - border-bottom-right-radius: 5px; -} -.pagination-mini ul > li:first-child > a, -.pagination-small ul > li:first-child > a, -.pagination-mini ul > li:first-child > span, -.pagination-small ul > li:first-child > span { - -webkit-border-top-left-radius: 2px; - -moz-border-radius-topleft: 2px; - border-top-left-radius: 2px; - -webkit-border-bottom-left-radius: 2px; - -moz-border-radius-bottomleft: 2px; - border-bottom-left-radius: 2px; -} -.pagination-mini ul > li:last-child > a, -.pagination-small ul > li:last-child > a, -.pagination-mini ul > li:last-child > span, -.pagination-small ul > li:last-child > span { - -webkit-border-top-right-radius: 2px; - -moz-border-radius-topright: 2px; - border-top-right-radius: 2px; - -webkit-border-bottom-right-radius: 2px; - -moz-border-radius-bottomright: 2px; - border-bottom-right-radius: 2px; -} -.pagination-small ul > li > a, -.pagination-small ul > li > span { - padding: 2px 10px; - font-size: 11.05px; -} -.pagination-mini ul > li > a, -.pagination-mini ul > li > span { - padding: 0 6px; - font-size: 9.75px; -} -.pager { - margin: 20px 0; - list-style: none; - text-align: center; - *zoom: 1; -} -.pager:before, -.pager:after { - display: table; - content: ""; - line-height: 0; -} -.pager:after { - clear: both; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #f5f5f5; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999999; - background-color: #fff; - cursor: default; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.modal { - position: fixed; - top: 10%; - left: 50%; - z-index: 1050; - width: 560px; - margin-left: -280px; - background-color: #ffffff; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - /* IE6-7 */ - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; - outline: none; -} -.modal.fade { - -webkit-transition: opacity .3s linear, top .3s ease-out; - -moz-transition: opacity .3s linear, top .3s ease-out; - -o-transition: opacity .3s linear, top .3s ease-out; - transition: opacity .3s linear, top .3s ease-out; - top: -25%; -} -.modal.fade.in { - top: 10%; -} -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; -} -.modal-header .close { - margin-top: 2px; -} -.modal-header h3 { - margin: 0; - line-height: 30px; -} -.modal-body { - position: relative; - overflow-y: auto; - max-height: 400px; - padding: 15px; -} -.modal-form { - margin-bottom: 0; -} -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - -webkit-box-shadow: inset 0 1px 0 #ffffff; - -moz-box-shadow: inset 0 1px 0 #ffffff; - box-shadow: inset 0 1px 0 #ffffff; - *zoom: 1; -} -.modal-footer:before, -.modal-footer:after { - display: table; - content: ""; - line-height: 0; -} -.modal-footer:after { - clear: both; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.tooltip { - position: absolute; - z-index: 1030; - display: block; - visibility: visible; - font-size: 11px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); -} -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.tooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.tooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.tooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.tooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000000; -} -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000000; -} -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000000; -} -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000000; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - background-color: #ffffff; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - white-space: normal; -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} -.popover-title:empty { - display: none; -} -.popover-content { - padding: 9px 14px; -} -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover .arrow { - border-width: 11px; -} -.popover .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: #999; - border-top-color: rgba(0, 0, 0, 0.25); - bottom: -11px; -} -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #ffffff; -} -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: #999; - border-right-color: rgba(0, 0, 0, 0.25); -} -.popover.right .arrow:after { - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #ffffff; -} -.popover.bottom .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #999; - border-bottom-color: rgba(0, 0, 0, 0.25); - top: -11px; -} -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #ffffff; -} -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #999; - border-left-color: rgba(0, 0, 0, 0.25); -} -.popover.left .arrow:after { - right: 1px; - border-right-width: 0; - border-left-color: #ffffff; - bottom: -10px; -} -.thumbnails { - margin-left: -30px; - list-style: none; - *zoom: 1; -} -.thumbnails:before, -.thumbnails:after { - display: table; - content: ""; - line-height: 0; -} -.thumbnails:after { - clear: both; -} -.row-fluid .thumbnails { - margin-left: 0; -} -.thumbnails > li { - float: left; - margin-bottom: 20px; - margin-left: 30px; -} -.thumbnail { - display: block; - padding: 4px; - line-height: 20px; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #3ea211; - -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -} -.thumbnail > img { - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} -.thumbnail .caption { - padding: 9px; - color: #555555; -} -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} -.media, -.media .media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} -.media-object { - display: block; -} -.media-heading { - margin: 0 0 5px; -} -.media > .pull-left { - margin-right: 10px; -} -.media > .pull-right { - margin-left: 10px; -} -.media-list { - margin-left: 0; - list-style: none; -} -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: 10.998px; - font-weight: bold; - line-height: 14px; - color: #ffffff; - vertical-align: baseline; - white-space: nowrap; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #999999; -} -.label { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.badge { - padding-left: 9px; - padding-right: 9px; - -webkit-border-radius: 9px; - -moz-border-radius: 9px; - border-radius: 9px; -} -.label:empty, -.badge:empty { - display: none; -} -a.label:hover, -a.label:focus, -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} -.label-important, -.badge-important { - background-color: #b85355; -} -.label-important[href], -.badge-important[href] { - background-color: #993f41; -} -.label-warning, -.badge-warning { - background-color: #f89406; -} -.label-warning[href], -.badge-warning[href] { - background-color: #c67605; -} -.label-success, -.badge-success { - background-color: #5c8846; -} -.label-success[href], -.badge-success[href] { - background-color: #456635; -} -.label-info, -.badge-info { - background-color: #4e7b86; -} -.label-info[href], -.badge-info[href] { - background-color: #3b5d66; -} -.label-inverse, -.badge-inverse { - background-color: #444444; -} -.label-inverse[href], -.badge-inverse[href] { - background-color: #2b2b2b; -} -.btn .label, -.btn .badge { - position: relative; - top: -1px; -} -.btn-mini .label, -.btn-mini .badge { - top: 0; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-ms-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 20px; - margin-bottom: 20px; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); - background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.progress .bar { - width: 0%; - height: 100%; - color: #ffffff; - float: left; - font-size: 12px; - text-align: center; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top, #149bdf, #0480be); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); - background-image: -webkit-linear-gradient(top, #149bdf, #0480be); - background-image: -o-linear-gradient(top, #149bdf, #0480be); - background-image: linear-gradient(to bottom, #149bdf, #0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width 0.6s ease; - -moz-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} -.progress .bar + .bar { - -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); -} -.progress-striped .bar { - background-color: #149bdf; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-danger .bar, -.progress .bar-danger { - background-color: #dd514c; - background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); - background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); -} -.progress-danger.progress-striped .bar, -.progress-striped .bar-danger { - background-color: #ee5f5b; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-success .bar, -.progress .bar-success { - background-color: #5eb95e; - background-image: -moz-linear-gradient(top, #62c462, #57a957); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); - background-image: -webkit-linear-gradient(top, #62c462, #57a957); - background-image: -o-linear-gradient(top, #62c462, #57a957); - background-image: linear-gradient(to bottom, #62c462, #57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); -} -.progress-success.progress-striped .bar, -.progress-striped .bar-success { - background-color: #62c462; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-info .bar, -.progress .bar-info { - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); - background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); - background-image: -o-linear-gradient(top, #5bc0de, #339bb9); - background-image: linear-gradient(to bottom, #5bc0de, #339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); -} -.progress-info.progress-striped .bar, -.progress-striped .bar-info { - background-color: #5bc0de; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.progress-warning .bar, -.progress .bar-warning { - background-color: #faa732; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); -} -.progress-warning.progress-striped .bar, -.progress-striped .bar-warning { - background-color: #fbb450; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} -.accordion { - margin-bottom: 20px; -} -.accordion-group { - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.accordion-heading { - border-bottom: 0; -} -.accordion-heading .accordion-toggle { - display: block; - padding: 8px 15px; -} -.accordion-toggle { - cursor: pointer; -} -.accordion-inner { - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} -.carousel { - position: relative; - margin-bottom: 20px; - line-height: 1; -} -.carousel-inner { - overflow: hidden; - width: 100%; - position: relative; -} -.carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - line-height: 1; -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} -.carousel-inner > .active { - left: 0; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} -.carousel-inner > .next { - left: 100%; -} -.carousel-inner > .prev { - left: -100%; -} -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} -.carousel-inner > .active.left { - left: -100%; -} -.carousel-inner > .active.right { - left: 100%; -} -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #ffffff; - text-align: center; - background: #222222; - border: 3px solid #ffffff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} -.carousel-control.right { - left: auto; - right: 15px; -} -.carousel-control:hover, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; -} -.carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255, 255, 255, 0.25); - border-radius: 5px; -} -.carousel-indicators .active { - background-color: #fff; -} -.carousel-caption { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 15px; - background: #444444; - background: rgba(0, 0, 0, 0.75); -} -.carousel-caption h4, -.carousel-caption p { - color: #ffffff; - line-height: 20px; -} -.carousel-caption h4 { - margin: 0 0 5px; -} -.carousel-caption p { - margin-bottom: 0; -} -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: #eeeeee; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - color: inherit; - letter-spacing: -1px; -} -.hero-unit li { - line-height: 30px; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.hide { - display: none; -} -.show { - display: block; -} -.invisible { - visibility: hidden; -} -.affix { - position: fixed; -} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/assets/styles/knox.css b/knox-token-generation-ui/token-generation/assets/styles/knox.css index 7b73e41766..e3b5a15a59 100644 --- a/knox-token-generation-ui/token-generation/assets/styles/knox.css +++ b/knox-token-generation-ui/token-generation/assets/styles/knox.css @@ -160,7 +160,7 @@ body { -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; - *zoom: 1; + zoom: 1; } .wrap:before, .wrap:after { @@ -305,7 +305,7 @@ body { background-image: linear-gradient(to bottom, #1b4607, #3ea211); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1b4607', endColorstr='#ff3ea211', GradientType=0); - *background-color: #358b0f; + background-color: #358b0f; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } .toggle-xa .toggle-slide .toggle-off { @@ -324,7 +324,7 @@ body { background-image: linear-gradient(to bottom, #b3b3b3, #e6e6e6); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffb3b3b3', endColorstr='#ffe6e6e6', GradientType=0); - *background-color: #a6a6a6; + background-color: #a6a6a6; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } .toggle-xa .toggle-slide .toggle-blob { @@ -340,7 +340,7 @@ body { background-image: linear-gradient(to bottom, #ffffff, #cccccc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffcccccc', GradientType=0); - *background-color: #cccccc; + background-color: #cccccc; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } diff --git a/knox-token-generation-ui/token-generation/index.html b/knox-token-generation-ui/token-generation/index.html index c26d66dea1..082e5bf880 100644 --- a/knox-token-generation-ui/token-generation/index.html +++ b/knox-token-generation-ui/token-generation/index.html @@ -19,6 +19,7 @@ Apache Knox Token Generation + diff --git a/knox-token-generation-ui/token-generation/main.ts b/knox-token-generation-ui/token-generation/main.ts index be5f383523..89cd6afdcf 100644 --- a/knox-token-generation-ui/token-generation/main.ts +++ b/knox-token-generation-ui/token-generation/main.ts @@ -16,13 +16,34 @@ */ import './polyfills.ts'; -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import {enableProdMode} from '@angular/core'; import {environment} from './environments/environment'; -import {AppModule} from './app/app.module'; +import { SessionInformationComponent } from './app/sessionInformation/session.information.component.js'; +import { TokenGenerationComponent } from './app/token-generation/token-generation.component.js'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { APP_BASE_HREF } from '@angular/common'; +import { provideHttpClient } from '@angular/common/http'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule); +const bootstrapComponents = [ + SessionInformationComponent, + TokenGenerationComponent +]; + +bootstrapComponents.forEach(component => { + bootstrapApplication(component, { + providers: [ + importProvidersFrom(), + provideHttpClient(), + provideRouter([]), + { + provide: APP_BASE_HREF, + useValue: window['base-href'] || '/' + } + ] + }).catch(err => console.error(err)); +}); diff --git a/knox-token-generation-ui/token-generation/polyfills.ts b/knox-token-generation-ui/token-generation/polyfills.ts index 560dbecd0a..aebd58c4ed 100644 --- a/knox-token-generation-ui/token-generation/polyfills.ts +++ b/knox-token-generation-ui/token-generation/polyfills.ts @@ -14,22 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// This file includes polyfills needed by Angular 2 and is loaded before -// the app. You can add your own extra polyfills to this file. -import 'core-js/es/symbol'; -import 'core-js/es/object'; -import 'core-js/es/function'; -import 'core-js/es/parse-int'; -import 'core-js/es/parse-float'; -import 'core-js/es/number'; -import 'core-js/es/math'; -import 'core-js/es/string'; -import 'core-js/es/date'; -import 'core-js/es/array'; -import 'core-js/es/regexp'; -import 'core-js/es/map'; -import 'core-js/es/set'; -import 'core-js/es/reflect'; - -import 'core-js/es/reflect'; -import 'zone.js/dist/zone'; +import 'zone.js'; diff --git a/knox-token-generation-ui/token-generation/styles.css b/knox-token-generation-ui/token-generation/styles.css index 813bed9162..24b8fc04b3 100644 --- a/knox-token-generation-ui/token-generation/styles.css +++ b/knox-token-generation-ui/token-generation/styles.css @@ -24,4 +24,13 @@ .clickable { cursor: pointer; +} + +html, body { + font-size: 14px; +} + +a { + color: #3ea211; + text-decoration: none; } \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/tsconfig.json b/knox-token-generation-ui/token-generation/tsconfig.json index 6f9eac1f6d..525839e013 100644 --- a/knox-token-generation-ui/token-generation/tsconfig.json +++ b/knox-token-generation-ui/token-generation/tsconfig.json @@ -8,12 +8,11 @@ "es2017", "dom" ], - "mapRoot": "./", - "module": "es6", - "moduleResolution": "node", + "module": "ES2022", + "moduleResolution": "bundler", "outDir": "../dist/out-tsc", "sourceMap": true, - "target": "es5", + "target": "ES2022", "typeRoots": [ "../node_modules/@types" ] From 7c37c4b2dfb526628e693f484079d5eee9ef0de1 Mon Sep 17 00:00:00 2001 From: thanicz Date: Thu, 4 Dec 2025 17:46:04 +0100 Subject: [PATCH 2/9] KNOX-3224: Upgrade Token Management UI --- knox-homepage-ui/home/app/app.module.ts | 3 - knox-homepage-ui/home/index.html | 2 - knox-homepage-ui/home/main.ts | 8 +- knox-homepage-ui/package.json | 6 - .../app/service/token-generation.service.ts | 2 +- .../token-generation.component.ts | 2 +- .../token-generation/index.html | 9 +- knox-token-management-ui/.eslintrc.json | 98 ---------- knox-token-management-ui/angular.json | 33 ++-- knox-token-management-ui/eslint.config.js | 75 +++++++ knox-token-management-ui/package.json | 68 +++---- knox-token-management-ui/pom.xml | 2 +- .../token-management/app/app.module.ts | 48 +---- .../app/{ => model}/knox.token.ts | 0 .../app/{ => model}/metadata.ts | 0 .../app/{ => model}/session.information.ts | 0 .../{ => service}/token.management.service.ts | 35 ++-- .../session.information.component.html | 0 .../session.information.component.ts | 28 +-- .../app/token.management.component.html | 151 -------------- .../token.management.component.css} | 10 + .../token.management.component.html | 185 ++++++++++++++++++ .../token.management.component.ts | 150 +++++++------- .../token-management/app/util/safehtml.ts | 27 +++ .../token-management/index.html | 53 +++-- .../token-management/main.ts | 33 +++- .../token-management/polyfills.ts | 20 +- .../token-management/styles.css | 6 +- .../token-management/tsconfig.json | 7 +- 29 files changed, 525 insertions(+), 536 deletions(-) delete mode 100644 knox-token-management-ui/.eslintrc.json create mode 100644 knox-token-management-ui/eslint.config.js rename knox-token-management-ui/token-management/app/{ => model}/knox.token.ts (100%) rename knox-token-management-ui/token-management/app/{ => model}/metadata.ts (100%) rename knox-token-management-ui/token-management/app/{ => model}/session.information.ts (100%) rename knox-token-management-ui/token-management/app/{ => service}/token.management.service.ts (88%) rename knox-token-management-ui/token-management/app/{ => sessioninformation}/session.information.component.html (100%) rename knox-token-management-ui/token-management/app/{ => sessioninformation}/session.information.component.ts (73%) delete mode 100644 knox-token-management-ui/token-management/app/token.management.component.html rename knox-token-management-ui/token-management/{assets/token-management-ui.css => app/tokenmanagement/token.management.component.css} (89%) create mode 100644 knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html rename knox-token-management-ui/token-management/app/{ => tokenmanagement}/token.management.component.ts (63%) create mode 100644 knox-token-management-ui/token-management/app/util/safehtml.ts diff --git a/knox-homepage-ui/home/app/app.module.ts b/knox-homepage-ui/home/app/app.module.ts index 9b22cf7355..44765d2a25 100644 --- a/knox-homepage-ui/home/app/app.module.ts +++ b/knox-homepage-ui/home/app/app.module.ts @@ -16,7 +16,6 @@ */ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; -import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; import { MatGridListModule } from '@angular/material/grid-list'; import { RouterModule } from '@angular/router'; @@ -25,8 +24,6 @@ import { HomepageService } from './service/homepage.service'; @NgModule({ imports: [ BrowserModule, - HttpClientModule, - HttpClientXsrfModule, MatGridListModule, RouterModule.forRoot([]), ], diff --git a/knox-homepage-ui/home/index.html b/knox-homepage-ui/home/index.html index 7ce0fd1906..0dbf1dc039 100644 --- a/knox-homepage-ui/home/index.html +++ b/knox-homepage-ui/home/index.html @@ -19,9 +19,7 @@ Apache Knox Home - - +
diff --git a/knox-token-management-ui/.eslintrc.json b/knox-token-management-ui/.eslintrc.json deleted file mode 100644 index e143690256..0000000000 --- a/knox-token-management-ui/.eslintrc.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "root": true, - "overrides": [ - { - "files": [ - "*.ts" - ], - "parserOptions": { - "project": [ - "token-management/tsconfig.json" - ], - "createDefaultProgram": true - }, - "extends": [ - "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" - ], - "rules": { - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": ["class"], - "format": ["PascalCase"] - } - ], - "spaced-comment": "error", - "curly": "error", - "eol-last": "error", - "guard-for-in": "error", - "no-unused-labels": "error", - "max-len": [ - "error", - { "code": 140 } - ], - "@typescript-eslint/explicit-member-accessibility": [ - "off", - {"accessibility": "no-public"} - ], - "@typescript-eslint/member-ordering": [ - "error", - { "default": ["static-field", "instance-field", "field", "method"] } - ], - "no-caller": "error", - "no-bitwise": "error", - "no-console": "off", - "no-new-wrappers": "error", - "no-debugger": "error", - "no-redeclare": "off", - "no-empty": "error", - "no-eval": "error", - "@typescript-eslint/no-inferrable-types": "error", - "no-shadow": "error", - "dot-notation": "off", - "no-fallthrough": "error", - "no-trailing-spaces": "error", - "no-unused-expressions": "error", - "no-var": "error", - "sort-keys": "off", - "brace-style": ["error","1tbs", { "allowSingleLine": true }], - "quotes": ["error", "single"], - "radix": "error", - "@typescript-eslint/semi": "error", - "eqeqeq": ["error", "always", {"null": "ignore"}], - "@typescript-eslint/type-annotation-spacing": "error", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "error", - "@angular-eslint/use-pipe-transform-interface": "error", - "@angular-eslint/component-class-suffix": "error", - "@angular-eslint/directive-class-suffix": "error" - } - }, - { - "files": [ - "*.html" - ], - "extends": [ - "plugin:@angular-eslint/template/recommended" - ], - "rules": {} - } - ] -} diff --git a/knox-token-management-ui/angular.json b/knox-token-management-ui/angular.json index 761ec958a4..0c3d27f7e5 100644 --- a/knox-token-management-ui/angular.json +++ b/knox-token-management-ui/angular.json @@ -36,12 +36,14 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular/build:application", "options": { - "outputPath": "target/classes/token-management/app", + "outputPath": { + "base": "target/classes/token-management/app", + "browser": "" + }, "index": "token-management/index.html", - "main": "token-management/main.ts", - "polyfills": "token-management/polyfills.ts", + "polyfills": ["token-management/polyfills.ts"], "tsConfig": "token-management/tsconfig.json", "assets": [ "token-management/favicon.ico", @@ -54,11 +56,11 @@ "scripts": [ "node_modules/jquery/dist/jquery.min.js", "node_modules/bootstrap/dist/js/bootstrap.js" - ] + ], + "browser": "token-management/main.ts" }, "configurations": { "production": { - "buildOptimizer": false, "aot": false, "fileReplacements": [ { @@ -69,10 +71,8 @@ "outputHashing": "all" }, "development": { - "buildOptimizer": false, "aot": false, "optimization": false, - "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -81,21 +81,21 @@ "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "configurations": { "production": { - "browserTarget": "token-management:build:production" + "buildTarget": "token-management:build:production" }, "development": { - "browserTarget": "token-management:build:development" + "buildTarget": "token-management:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", + "builder": "@angular/build:extract-i18n", "options": { - "browserTarget": "token-management:build" + "buildTarget": "token-management:build" } }, "lint": { @@ -109,12 +109,5 @@ } } } - }, - "defaultProject": "token-management", - "cli": { - "schematicCollections": [ - "@angular-eslint/schematics", - "@angular-eslint/schematics" - ] } } diff --git a/knox-token-management-ui/eslint.config.js b/knox-token-management-ui/eslint.config.js new file mode 100644 index 0000000000..45ab1adc3f --- /dev/null +++ b/knox-token-management-ui/eslint.config.js @@ -0,0 +1,75 @@ +import js from "@eslint/js"; +import tseslint from "typescript-eslint"; +import angular from "@angular-eslint/eslint-plugin"; +import angularTemplate from "@angular-eslint/eslint-plugin-template"; +import tsParser from "@typescript-eslint/parser"; + +export default [ + { + ignores: ["**/dist/**", "**/node_modules/**"], + }, + + js.configs.recommended, + + { + files: ["**/*.ts"], + languageOptions: { + parser: tsParser, + parserOptions: { + project: ["./token-management/tsconfig.json"], + tsconfigRootDir: import.meta.dirname, + }, + globals: { + console: "readonly", + window: "readonly", + document: "readonly", + setTimeout: "readonly", + atob: "readonly" + }, + }, + plugins: { + "@typescript-eslint": tseslint.plugin, + "@angular-eslint": angular, + }, + rules: { + "@typescript-eslint/naming-convention": [ + "error", + {selector: "class", format: ["PascalCase"]}, + ], + + curly: "error", + eqeqeq: ["error", "always", {null: "ignore"}], + "guard-for-in": "error", + "max-len": ["error", {code: 140}], + "no-bitwise": "error", + "no-caller": "error", + "no-console": "off", + "no-debugger": "error", + "no-empty": "error", + "no-eval": "error", + "no-fallthrough": "error", + "no-trailing-spaces": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-var": "error", + quotes: ["error", "single"], + radix: "error", + semi: ["error", "always"], + "spaced-comment": "error", + "brace-style": ["error", "1tbs", {allowSingleLine: true}], + + "@angular-eslint/directive-selector": [ + "error", + {type: "attribute", prefix: "app", style: "camelCase"}, + ], + "@angular-eslint/component-selector": [ + "error", + {type: "element", prefix: "app", style: "kebab-case"}, + ], + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/use-pipe-transform-interface": "error", + "@angular-eslint/component-class-suffix": "error", + "@angular-eslint/directive-class-suffix": "error", + }, + }, +]; \ No newline at end of file diff --git a/knox-token-management-ui/package.json b/knox-token-management-ui/package.json index b70d3d8937..86566d8fde 100644 --- a/knox-token-management-ui/package.json +++ b/knox-token-management-ui/package.json @@ -2,6 +2,7 @@ "name": "ng-knox-token-management", "version": "1.0.0", "license": "Apache-2.0", + "type": "module", "scripts": { "start": "ng serve --verbose=true", "build": "ng build", @@ -10,47 +11,38 @@ }, "private": true, "dependencies": { - "@angular/animations": "^13.0.1", - "@angular/cdk": "^13.0.1", - "@angular/common": "^13.0.1", - "@angular/compiler": "^13.0.1", - "@angular/core": "^13.0.1", - "@angular/forms": "^13.0.1", - "@angular/material": "^13.0.1", - "@angular/platform-browser": "^13.0.1", - "@angular/platform-browser-dynamic": "^13.0.1", - "@angular/router": "^13.0.1", - "bootstrap": "^3.4.1", - "core-js": "^2.6.11", - "jquery": "^3.5.1", - "js-yaml": "^3.13.1", - "ng2-bs3-modal": "^0.15.0", - "popper.js": "^1.16.1", - "rxjs": "^6.6.7", - "rxjs-compat": "^6.6.7", - "sweetalert2": "^11.6.5", - "ts-helpers": "^1.1.1", - "vkbeautify": "^0.99.3", - "zone.js": "~0.11.4" + "@angular/animations": "^20.3.15", + "@angular/cdk": "^20.2.14", + "@angular/common": "^20.3.15", + "@angular/compiler": "^20.3.15", + "@angular/core": "^20.3.15", + "@angular/forms": "^20.3.15", + "@angular/material": "^20.2.14", + "@angular/platform-browser": "^20.3.15", + "@angular/platform-browser-dynamic": "^20.3.15", + "@angular/router": "^20.3.15", + "bootstrap": "^5.3.8", + "core-js": "^3.47.0", + "jquery": "^3.7.1", + "sweetalert2": "^11.26.3", + "zone.js": "~0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^13.3.11", - "@angular-eslint/builder": "14.1.2", - "@angular-eslint/eslint-plugin": "14.1.2", - "@angular-eslint/eslint-plugin-template": "14.1.2", - "@angular-eslint/schematics": "14.1.2", - "@angular-eslint/template-parser": "14.1.2", - "@angular/cli": "^14.2.9", - "@angular/compiler-cli": "^13.0.1", - "@angular/language-service": "^5.2.0", + "@angular-devkit/build-angular": "^20.3.13", + "@angular-eslint/builder": "20.7.0", + "@angular-eslint/eslint-plugin": "20.7.0", + "@angular-eslint/eslint-plugin-template": "20.7.0", + "@angular-eslint/schematics": "20.7.0", + "@angular-eslint/template-parser": "20.7.0", + "@angular/cli": "^20.3.13", + "@angular/compiler-cli": "^20.3.15", + "@angular/language-service": "^20.3.15", "@types/jasmine": "~2.5.53", "@types/jasminewd2": "^2.0.8", - "@types/node": "16.18.11", - "@typescript-eslint/eslint-plugin": "5.37.0", - "@typescript-eslint/parser": "5.37.0", - "eslint": "^8.23.1", - "ts-node": "~3.2.0", - "typescript": "~4.4.4", - "webdriver-manager": "10.2.5" + "@types/node": "^24.5.2", + "eslint": "^9.39.0", + "ts-node": "~10.9.0", + "typescript": "~5.8.3", + "typescript-eslint": "^8.46.2" } } diff --git a/knox-token-management-ui/pom.xml b/knox-token-management-ui/pom.xml index b6a6cfe697..424d4422b3 100644 --- a/knox-token-management-ui/pom.xml +++ b/knox-token-management-ui/pom.xml @@ -65,7 +65,7 @@ npm - install --legacy-peer-deps + install diff --git a/knox-token-management-ui/token-management/app/app.module.ts b/knox-token-management-ui/token-management/app/app.module.ts index f64a49437e..cf3acd2d68 100644 --- a/knox-token-management-ui/token-management/app/app.module.ts +++ b/knox-token-management-ui/token-management/app/app.module.ts @@ -14,49 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {NgModule} from '@angular/core'; -import {BrowserModule} from '@angular/platform-browser'; -import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http'; -import {MatGridListModule} from '@angular/material/grid-list'; -import {BsModalModule} from 'ng2-bs3-modal'; -import {MatTableModule, MatTableDataSource} from '@angular/material/table'; -import {MatSortModule} from '@angular/material/sort'; -import {MatPaginatorModule} from '@angular/material/paginator'; -import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; -import {MatInputModule} from '@angular/material/input'; -import {MatSlideToggleModule} from '@angular/material/slide-toggle'; -import {MatCheckboxModule} from '@angular/material/checkbox'; -import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {FormsModule, ReactiveFormsModule} from '@angular/forms'; - - -import {TokenManagementComponent} from './token.management.component'; -import {TokenManagementService} from './token.management.service'; -import {SessionInformationComponent} from './session.information.component'; -import {SafeHtmlPipe} from './session.information.component'; +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { ReactiveFormsModule } from '@angular/forms'; +import { TokenManagementService } from './service/token.management.service'; @NgModule({ - imports: [BrowserModule, - BrowserAnimationsModule, - HttpClientModule, - HttpClientXsrfModule, - MatGridListModule, - BsModalModule, - FormsModule, - ReactiveFormsModule - ], - exports: [MatTableModule, - MatTableDataSource, - MatSortModule, - MatPaginatorModule, - MatProgressSpinnerModule, - MatInputModule, - MatSlideToggleModule, - MatCheckboxModule - ], - declarations: [TokenManagementComponent, SessionInformationComponent, SafeHtmlPipe], - providers: [TokenManagementService], - bootstrap: [TokenManagementComponent, SessionInformationComponent] + imports: [BrowserModule, ReactiveFormsModule], + providers: [TokenManagementService] }) export class AppModule { } + diff --git a/knox-token-management-ui/token-management/app/knox.token.ts b/knox-token-management-ui/token-management/app/model/knox.token.ts similarity index 100% rename from knox-token-management-ui/token-management/app/knox.token.ts rename to knox-token-management-ui/token-management/app/model/knox.token.ts diff --git a/knox-token-management-ui/token-management/app/metadata.ts b/knox-token-management-ui/token-management/app/model/metadata.ts similarity index 100% rename from knox-token-management-ui/token-management/app/metadata.ts rename to knox-token-management-ui/token-management/app/model/metadata.ts diff --git a/knox-token-management-ui/token-management/app/session.information.ts b/knox-token-management-ui/token-management/app/model/session.information.ts similarity index 100% rename from knox-token-management-ui/token-management/app/session.information.ts rename to knox-token-management-ui/token-management/app/model/session.information.ts diff --git a/knox-token-management-ui/token-management/app/token.management.service.ts b/knox-token-management-ui/token-management/app/service/token.management.service.ts similarity index 88% rename from knox-token-management-ui/token-management/app/token.management.service.ts rename to knox-token-management-ui/token-management/app/service/token.management.service.ts index 0cb52705a1..30759bac3b 100644 --- a/knox-token-management-ui/token-management/app/token.management.service.ts +++ b/knox-token-management-ui/token-management/app/service/token.management.service.ts @@ -15,13 +15,11 @@ * limitations under the License. */ import {Injectable} from '@angular/core'; -import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http'; -import Swal from 'sweetalert2'; - -import 'rxjs/add/operator/toPromise'; - -import {KnoxToken} from './knox.token'; -import {SessionInformation} from './session.information'; +import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; +import Swal from 'sweetalert2/dist/sweetalert2.esm.all.js'; +import { firstValueFrom } from 'rxjs'; +import { KnoxToken } from '../model/knox.token'; +import { SessionInformation } from '../model/session.information'; @Injectable() export class TokenManagementService { @@ -46,8 +44,7 @@ export class TokenManagementService { let headers = new HttpHeaders(); headers = this.addJsonHeaders(headers); let url = canSeeAllTokens ? this.getAllKnoxTokensUrl : (this.getKnoxTokensUrl + userName); - return this.http.get(url, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(url, { headers: headers})) .then(response => response['tokens'] as KnoxToken[]) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> getKnoxTokens() --> ' + this.getKnoxTokensUrl + '\n error: ' + err.message); @@ -63,8 +60,7 @@ export class TokenManagementService { let xheaders = new HttpHeaders(); xheaders = this.addJsonHeaders(xheaders); let urlToUse = enable ? this.enableKnoxTokenUrl : this.disableKnoxTokenUrl; - return this.http.put(urlToUse, tokenId, {headers: xheaders, responseType: 'text'}) - .toPromise() + return firstValueFrom(this.http.put(urlToUse, tokenId, {headers: xheaders, responseType: 'text'})) .then(response => response) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> setEnabledDisabledFlag() --> ' + urlToUse @@ -81,8 +77,7 @@ export class TokenManagementService { let xheaders = new HttpHeaders(); xheaders = this.addJsonHeaders(xheaders); let urlToUse = enable ? this.enableKnoxTokensBatchUrl : this.disableKnoxTokensBatchUrl; - return this.http.put(urlToUse, JSON.stringify(tokenIds), {headers: xheaders, responseType: 'text'}) - .toPromise() + return firstValueFrom(this.http.put(urlToUse, JSON.stringify(tokenIds), {headers: xheaders, responseType: 'text'})) .then(response => response) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> setEnabledDisabledFlagsInBatch() --> ' + urlToUse @@ -115,9 +110,8 @@ export class TokenManagementService { revokeTokensInBatch(tokenIds: string[]) { let xheaders = new HttpHeaders(); xheaders = this.addJsonHeaders(xheaders); - return this.http.request('DELETE', this.revokeKnoxTokensBatchUrl, - {headers: xheaders, body: JSON.stringify(tokenIds), responseType: 'text'}) - .toPromise() + return firstValueFrom(this.http.request('DELETE', this.revokeKnoxTokensBatchUrl, + {headers: xheaders, body: JSON.stringify(tokenIds), responseType: 'text'})) .then(response => response) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> revokeTokensInBatch() --> ' + this.revokeKnoxTokensBatchUrl @@ -133,8 +127,7 @@ export class TokenManagementService { isTokenHashKeyPresent(): Promise { let headers = new HttpHeaders(); headers = this.addJsonHeaders(headers); - return this.http.get(this.metadataInfoUrl, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(this.metadataInfoUrl, { headers: headers})) .then(response => { return response['generalProxyInfo']?.['enableTokenManagement'] === 'true'; }) @@ -152,8 +145,7 @@ export class TokenManagementService { getSessionInformation(): Promise { let headers = new HttpHeaders(); headers = this.addJsonHeaders(headers); - return this.http.get(this.sessionUrl, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(this.sessionUrl, { headers: headers})) .then(response => response['sessioninfo'] as SessionInformation) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> getSessionInformation() --> ' + this.sessionUrl + '\n error: ' + err.message); @@ -168,8 +160,7 @@ export class TokenManagementService { getImpersonationEnabled(): Promise { let headers = new HttpHeaders(); headers = this.addJsonHeaders(headers); - return this.http.get(this.getTssStatusUrl, { headers: headers}) - .toPromise() + return firstValueFrom(this.http.get(this.getTssStatusUrl, { headers: headers})) .then(response => response['impersonationEnabled'] as string) .catch((err: HttpErrorResponse) => { console.debug('TokenManagementService --> getImpersonationEnabled() --> ' + this.getTssStatusUrl diff --git a/knox-token-management-ui/token-management/app/session.information.component.html b/knox-token-management-ui/token-management/app/sessioninformation/session.information.component.html similarity index 100% rename from knox-token-management-ui/token-management/app/session.information.component.html rename to knox-token-management-ui/token-management/app/sessioninformation/session.information.component.html diff --git a/knox-token-management-ui/token-management/app/session.information.component.ts b/knox-token-management-ui/token-management/app/sessioninformation/session.information.component.ts similarity index 73% rename from knox-token-management-ui/token-management/app/session.information.component.ts rename to knox-token-management-ui/token-management/app/sessioninformation/session.information.component.ts index 3475d2202b..964bbe5ce8 100644 --- a/knox-token-management-ui/token-management/app/session.information.component.ts +++ b/knox-token-management-ui/token-management/app/sessioninformation/session.information.component.ts @@ -14,24 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {Component, OnInit, Pipe, PipeTransform} from '@angular/core'; -import {DomSanitizer} from '@angular/platform-browser'; -import {TokenManagementService} from './token.management.service'; -import {SessionInformation} from './session.information'; - -@Pipe({ name: 'safeHtml' }) -export class SafeHtmlPipe implements PipeTransform { - constructor(private sanitizer: DomSanitizer) {} - - transform(value) { - return this.sanitizer.bypassSecurityTrustHtml(value); - } -} +import { Component, OnInit } from '@angular/core'; +import { TokenManagementService } from '../service/token.management.service'; +import { SessionInformation } from '../model/session.information'; +import { SafeHtmlPipe } from '../util/safehtml'; @Component({ selector: 'app-session-information', templateUrl: './session.information.component.html', - providers: [TokenManagementService] + providers: [TokenManagementService], + imports: [ SafeHtmlPipe ] }) export class SessionInformationComponent implements OnInit { @@ -45,10 +37,10 @@ export class SessionInformationComponent implements OnInit { getUser() { if (this.sessionInformation) { - return this.sessionInformation.user; + return this.sessionInformation.user; } else { - console.debug('SessionInformationComponent --> getUser() --> dr.who'); - return 'dr.who'; + console.debug('SessionInformationComponent --> getUser() --> dr.who'); + return 'dr.who'; } } @@ -67,7 +59,7 @@ export class SessionInformationComponent implements OnInit { } private setSessionInformation(sessionInformation: SessionInformation) { - this.sessionInformation = sessionInformation; + this.sessionInformation = sessionInformation; console.debug('SessionInformationComponent --> setSessionInformation() --> ' + this.sessionInformation.user); } diff --git a/knox-token-management-ui/token-management/app/token.management.component.html b/knox-token-management-ui/token-management/app/token.management.component.html deleted file mode 100644 index 6260b964c3..0000000000 --- a/knox-token-management-ui/token-management/app/token.management.component.html +++ /dev/null @@ -1,151 +0,0 @@ - -
- -
- - - - - Show Disabled KnoxSSO Cookies - - -
- -
- - - Show My Tokens Only - - -
- -
- - Search by Token ID, (Impersonated) User Name, Comment or Metadata... - - - - - - - - - - - - - - - - - Token ID - -
{{knoxToken.tokenId}}
-
{{knoxToken.tokenId}}
-
-
- - - Issued - {{formatDateTime(knoxToken.issueTimeLong)}} - - - - Expires - {{formatDateTime(knoxToken.expirationLong)}} - - - - User Name - {{knoxToken.metadata.userName}} - - - - Impersonated - -
- - -

{{knoxToken.metadata.createdBy}}

-
-
-
- - - Type - - - - - - - Comment - {{knoxToken.metadata.comment}} - - - - Additional Metadata - -
    -
  • - {{metadata[0]}} = {{metadata[1]}} -
  • -
-
-
- - - Actions - - - - -

Previously Disabled SSO Cookie!

-
-
- - - - -
- -
- -
- - - -
- -
- Expired tokens cannot be disabled in batches (nor individually). -
-
- Expired tokens cannot be enabed in batches (nor individually). -
-
- KnoxSSO Cookies cannot be revoked in batches (nor individually). -
- -
- diff --git a/knox-token-management-ui/token-management/assets/token-management-ui.css b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css similarity index 89% rename from knox-token-management-ui/token-management/assets/token-management-ui.css rename to knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css index 565ae446fd..e30a820453 100644 --- a/knox-token-management-ui/token-management/assets/token-management-ui.css +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css @@ -35,4 +35,14 @@ .mat-table { overflow: auto; max-height: 500px; +} + +.select-column { + width: 70px; + max-width: 70px; + min-width: 70px; +} + +.reduce-icon-size { + transform: scale(0.65); } \ No newline at end of file diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html new file mode 100644 index 0000000000..d2e5fe79b8 --- /dev/null +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html @@ -0,0 +1,185 @@ + +
+ +
+ + + + + Show Disabled KnoxSSO Cookies + + +
+ +
+ + + Show My Tokens Only + + +
+ +
+ + Search by Token ID, (Impersonated) User Name, Comment or Metadata... + + + + + + + + + + + + + + + + + Token ID + +
{{knoxToken.tokenId}}
+
{{knoxToken.tokenId}}
+
+
+ + + Issued + {{formatDateTime(knoxToken.issueTimeLong)}} + + + + Expires + {{formatDateTime(knoxToken.expirationLong)}} + + + + User Name + {{knoxToken.metadata.userName}} + + + + Impersonated + +
+ + +

{{knoxToken.metadata.createdBy}}

+
+
+
+ + + Type + + + + + + + Comment + {{knoxToken.metadata.comment}} + + + + Additional + Metadata + +
    +
  • + {{metadata[0]}} = {{metadata[1]}} +
  • +
+
+
+ + + Actions + + + + +

Previously Disabled SSO Cookie! +

+
+
+ + + + +
+ +
+ +
+ + + +
+ +
+ Expired tokens cannot be disabled in batches + (nor individually). +
+
+ Expired tokens cannot be enabed in batches + (nor individually). +
+
+ KnoxSSO Cookies cannot be revoked in batches + (nor individually). +
+ +
\ No newline at end of file diff --git a/knox-token-management-ui/token-management/app/token.management.component.ts b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts similarity index 63% rename from knox-token-management-ui/token-management/app/token.management.component.ts rename to knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts index 74777b7a4f..48fc4ab4d8 100644 --- a/knox-token-management-ui/token-management/app/token.management.component.ts +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts @@ -14,21 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {Component, OnInit, ViewChild} from '@angular/core'; -import {TokenManagementService} from './token.management.service'; -import {KnoxToken} from './knox.token'; -import {MatTableDataSource} from '@angular/material/table'; -import {MatPaginator} from '@angular/material/paginator'; -import {MatSort} from '@angular/material/sort'; -import {MatSlideToggleChange} from '@angular/material/slide-toggle'; -import {SelectionModel} from '@angular/cdk/collections'; -import Swal from 'sweetalert2'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { TokenManagementService } from '../service/token.management.service'; +import { KnoxToken } from '../model/knox.token'; +import { MatTableDataSource } from '@angular/material/table'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { MatSlideToggleChange } from '@angular/material/slide-toggle'; +import { SelectionModel } from '@angular/cdk/collections'; +import Swal from 'sweetalert2/dist/sweetalert2.esm.all.js'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSortModule } from '@angular/material/sort'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MatTableModule } from '@angular/material/table'; +import { MatInputModule } from '@angular/material/input'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; @Component({ selector: 'app-token-management', templateUrl: './token.management.component.html', - styleUrls: ['../assets/token-management-ui.css'], - providers: [TokenManagementService] + styleUrls: ['./token.management.component.css'], + providers: [TokenManagementService], + imports: [CommonModule, MatSlideToggleModule, MatFormFieldModule, MatSortModule, MatPaginatorModule, FormsModule, + MatTableModule, MatInputModule, MatCheckboxModule, MatIconModule, MatButtonModule], + standalone: true }) export class TokenManagementComponent implements OnInit { @@ -59,37 +73,38 @@ export class TokenManagementComponent implements OnInit { constructor(private tokenManagementService: TokenManagementService) { this.showDisabledKnoxSsoCookies = true; let isMatch: (record: KnoxToken, filter: String) => boolean = (record, filter) => { - let normalizedFilter = filter.trim().toLocaleLowerCase(); - let matchesTokenId = record.tokenId.toLocaleLowerCase().includes(normalizedFilter); - let matchesComment = record.metadata.comment && record.metadata.comment.toLocaleLowerCase().includes(normalizedFilter); - let matchesUserName = record.metadata.userName.toLocaleLowerCase().includes(normalizedFilter); - let matchesCreatedBy = record.metadata.createdBy && record.metadata.createdBy.toLocaleLowerCase().includes(normalizedFilter); - let matchesCustomMetadata = false; - if (record.metadata.customMetadataMap) { - for (let entry of Array.from(Object.entries(record.metadata.customMetadataMap))) { - if (entry[0].toLocaleLowerCase().includes(normalizedFilter) || entry[1].toLocaleLowerCase().includes(normalizedFilter)) { - matchesCustomMetadata = true; - break; - } + let normalizedFilter = filter.trim().toLocaleLowerCase(); + let matchesTokenId = record.tokenId.toLocaleLowerCase().includes(normalizedFilter); + let matchesComment = record.metadata.comment && record.metadata.comment.toLocaleLowerCase().includes(normalizedFilter); + let matchesUserName = record.metadata.userName.toLocaleLowerCase().includes(normalizedFilter); + let matchesCreatedBy = record.metadata.createdBy && record.metadata.createdBy.toLocaleLowerCase().includes(normalizedFilter); + let matchesCustomMetadata = false; + if (record.metadata.customMetadataMap) { + for (let entry of Array.from(Object.entries(record.metadata.customMetadataMap))) { + if (entry[0].toLocaleLowerCase().includes(normalizedFilter) + || entry[1].toLocaleLowerCase().includes(normalizedFilter)) { + matchesCustomMetadata = true; + break; + } + } + } else { + matchesCustomMetadata = true; // nothing to match } - } else { - matchesCustomMetadata = true; // nothing to match - } - return matchesTokenId || matchesComment || matchesCustomMetadata || matchesUserName || matchesCreatedBy; + return matchesTokenId || matchesComment || matchesCustomMetadata || matchesUserName || matchesCreatedBy; }; this.knoxTokens.filterPredicate = function (record, filter) { - return isMatch(record, filter); + return isMatch(record, filter); }; this.knoxTokens.sortingDataAccessor = (item, property) => { - switch(property) { - case 'metadata.comment': return item.metadata.comment; - case 'metadata.username': return item.metadata.userName; - case 'metadata.createdBy': return item.metadata.createdBy; - default: return item[property]; - } + switch (property) { + case 'metadata.comment': return item.metadata.comment; + case 'metadata.username': return item.metadata.userName; + case 'metadata.createdBy': return item.metadata.createdBy; + default: return item[property]; + } }; } @@ -116,13 +131,13 @@ export class TokenManagementComponent implements OnInit { this.tokenManagementService.getSessionInformation() .then(sessionInformation => { - this.canSeeAllTokens = sessionInformation.canSeeAllTokens; - this.currentKnoxSsoCookieTokenId = sessionInformation.currentKnoxSsoCookieTokenId; - this.setUserName(sessionInformation.user); + this.canSeeAllTokens = sessionInformation.canSeeAllTokens; + this.currentKnoxSsoCookieTokenId = sessionInformation.currentKnoxSsoCookieTokenId; + this.setUserName(sessionInformation.user); }); } - isTokenHashKeyPresent(): boolean{ + isTokenHashKeyPresent(): boolean { return this.tokenHashKeyPresent; } @@ -145,7 +160,7 @@ export class TokenManagementComponent implements OnInit { } private isMyToken(token: KnoxToken): boolean { - return token.metadata.userName === this.userName || (token.metadata.createdBy && token.metadata.createdBy === this.userName); + return token.metadata.userName === this.userName || (token.metadata.createdBy && token.metadata.createdBy === this.userName); } private isDisabledKnoxSsoCookie(token: KnoxToken): boolean { @@ -160,31 +175,34 @@ export class TokenManagementComponent implements OnInit { } private actualizeTokensToDisplay(): void { - let tokensToDisplay = this.allKnoxTokens; + if(!this.allKnoxTokens) { + return; + } + let tokensToDisplay = this.allKnoxTokens; if (!this.showDisabledKnoxSsoCookies) { tokensToDisplay = tokensToDisplay.filter(token => !this.isDisabledKnoxSsoCookie(token)); } if (this.showMyTokensOnly) { - tokensToDisplay = tokensToDisplay.filter(token => this.isMyToken(token)); - } + tokensToDisplay = tokensToDisplay.filter(token => this.isMyToken(token)); + } - this.knoxTokens.data = tokensToDisplay; + this.knoxTokens.data = tokensToDisplay; - setTimeout(() => { + setTimeout(() => { this.knoxTokens.paginator = this.paginator; this.knoxTokens.sort = this.sort; - }); + }); } disableToken(tokenId: string) { - this.tokenManagementService.setEnabledDisabledFlag(false, tokenId).then((response: string) => this.fetchKnoxTokens()); + this.tokenManagementService.setEnabledDisabledFlag(false, tokenId).then(() => this.fetchKnoxTokens()); } disableSelectedTokens(): void { this.tokenManagementService.setEnabledDisabledFlagsInBatch(false, this.getSelectedTokenIds()) - .then((response: string) => this.fetchKnoxTokens()); + .then(() => this.fetchKnoxTokens()); } private getSelectedTokenIds(): string[] { @@ -194,20 +212,20 @@ export class TokenManagementComponent implements OnInit { } enableToken(tokenId: string) { - this.tokenManagementService.setEnabledDisabledFlag(true, tokenId).then((response: string) => this.fetchKnoxTokens()); + this.tokenManagementService.setEnabledDisabledFlag(true, tokenId).then(() => this.fetchKnoxTokens()); } enableSelectedTokens(): void { this.tokenManagementService.setEnabledDisabledFlagsInBatch(true, this.getSelectedTokenIds()) - .then((response: string) => this.fetchKnoxTokens()); + .then(() => this.fetchKnoxTokens()); } revokeToken(tokenId: string) { - this.tokenManagementService.revokeToken(tokenId).then((response: string) => this.fetchKnoxTokens()); + this.tokenManagementService.revokeToken(tokenId).then(() => this.fetchKnoxTokens()); } revokeSelectedTokens() { - this.tokenManagementService.revokeTokensInBatch(this.getSelectedTokenIds()).then((response: string) => this.fetchKnoxTokens()); + this.tokenManagementService.revokeTokensInBatch(this.getSelectedTokenIds()).then(() => this.fetchKnoxTokens()); } gotoTokenGenerationPage() { @@ -227,20 +245,20 @@ export class TokenManagementComponent implements OnInit { } getCustomMetadataArray(knoxToken: KnoxToken): [string, string][] { - let mdMap = new Map(); - if (knoxToken.metadata.customMetadataMap) { - mdMap = new Map(Object.entries(knoxToken.metadata.customMetadataMap)); - } + let mdMap = new Map(); + if (knoxToken.metadata.customMetadataMap) { + mdMap = new Map(Object.entries(knoxToken.metadata.customMetadataMap)); + } - return Array.from(mdMap); + return Array.from(mdMap); } isKnoxSsoCookie(knoxToken: KnoxToken): boolean { - return 'KNOXSSO_COOKIE' === knoxToken.metadata.type; + return 'KNOXSSO_COOKIE' === knoxToken.metadata.type; } isDisabledKnoxSSoCookie(knoxToken: KnoxToken): boolean { - return this.isKnoxSsoCookie(knoxToken) && !knoxToken.metadata.enabled; + return this.isKnoxSsoCookie(knoxToken) && !knoxToken.metadata.enabled; } applyFilter(filterValue: string) { @@ -251,9 +269,9 @@ export class TokenManagementComponent implements OnInit { /** Whether the number of selected elements matches the total number of rows. */ isAllSelected(): boolean { - const numSelected = this.selection.selected.length; - const numRows = this.knoxTokens.filteredData.length; - return numSelected === numRows; + const numSelected = this.selection.selected.length; + const numRows = this.knoxTokens.filteredData.length; + return numSelected === numRows; } /** Selects all rows if they are not all selected; otherwise clear selection. */ @@ -262,7 +280,7 @@ export class TokenManagementComponent implements OnInit { this.selection.clear(); } else { this.knoxTokens.filteredData.forEach(row => { - if (!this.isDisabledKnoxSsoCookie(row)) { + if (!this.isDisabledKnoxSsoCookie(row)) { this.selection.select(row); } }); @@ -276,15 +294,15 @@ export class TokenManagementComponent implements OnInit { } showHideBatchOperations() { - if (this.selection.isEmpty()) { - this.showDisableSelectedTokensButton = false; + if (this.selection.isEmpty()) { + this.showDisableSelectedTokensButton = false; this.showEnableSelectedTokensButton = false; this.showRevokeSelectedTokensButton = false; - } else { + } else { this.showDisableSelectedTokensButton = this.selectionHasZeroExpiredToken(); // expired tokens must not be disabled this.showEnableSelectedTokensButton = this.selectionHasZeroExpiredToken(); // expired tokens must not be enabled this.showRevokeSelectedTokensButton = this.selectionHasZeroKnoxSsoCookie(); // KnoxSSO cookies must not be revoked - } + } } private selectionHasZeroKnoxSsoCookie(): boolean { diff --git a/knox-token-management-ui/token-management/app/util/safehtml.ts b/knox-token-management-ui/token-management/app/util/safehtml.ts new file mode 100644 index 0000000000..cdf6aef477 --- /dev/null +++ b/knox-token-management-ui/token-management/app/util/safehtml.ts @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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 {Pipe, PipeTransform} from '@angular/core'; +import {DomSanitizer} from '@angular/platform-browser'; + +@Pipe({ name: 'safeHtml' }) +export class SafeHtmlPipe implements PipeTransform { + constructor(private sanitizer: DomSanitizer) {} + + transform(value) { + return this.sanitizer.bypassSecurityTrustHtml(value); + } +} diff --git a/knox-token-management-ui/token-management/index.html b/knox-token-management-ui/token-management/index.html index f347e1afc0..d14f389780 100644 --- a/knox-token-management-ui/token-management/index.html +++ b/knox-token-management-ui/token-management/index.html @@ -14,43 +14,42 @@ --> + Apache Knox Token Management - - - - + + - - + + \ No newline at end of file diff --git a/knox-token-management-ui/token-management/main.ts b/knox-token-management-ui/token-management/main.ts index be5f383523..797e447b92 100644 --- a/knox-token-management-ui/token-management/main.ts +++ b/knox-token-management-ui/token-management/main.ts @@ -16,13 +16,34 @@ */ import './polyfills.ts'; -import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import {enableProdMode} from '@angular/core'; -import {environment} from './environments/environment'; -import {AppModule} from './app/app.module'; +import { environment } from './environments/environment'; +import { SessionInformationComponent } from './app/sessioninformation/session.information.component.js'; +import { TokenManagementComponent } from './app/tokenmanagement/token.management.component.js'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { APP_BASE_HREF } from '@angular/common'; +import { provideHttpClient } from '@angular/common/http'; if (environment.production) { - enableProdMode(); + enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule); +const bootstrapComponents = [ + SessionInformationComponent, + TokenManagementComponent +]; + +bootstrapComponents.forEach(component => { + bootstrapApplication(component, { + providers: [ + importProvidersFrom(), + provideHttpClient(), + provideRouter([]), + { + provide: APP_BASE_HREF, + useValue: window['base-href'] || '/' + } + ] + }).catch(err => console.error(err)); +}); \ No newline at end of file diff --git a/knox-token-management-ui/token-management/polyfills.ts b/knox-token-management-ui/token-management/polyfills.ts index 78cba47477..aebd58c4ed 100644 --- a/knox-token-management-ui/token-management/polyfills.ts +++ b/knox-token-management-ui/token-management/polyfills.ts @@ -14,22 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// This file includes polyfills needed by Angular 2 and is loaded before -// the app. You can add your own extra polyfills to this file. -import 'core-js/es6/symbol'; -import 'core-js/es6/object'; -import 'core-js/es6/function'; -import 'core-js/es6/parse-int'; -import 'core-js/es6/parse-float'; -import 'core-js/es6/number'; -import 'core-js/es6/math'; -import 'core-js/es6/string'; -import 'core-js/es6/date'; -import 'core-js/es6/array'; -import 'core-js/es6/regexp'; -import 'core-js/es6/map'; -import 'core-js/es6/set'; -import 'core-js/es6/reflect'; - -import 'core-js/es7/reflect'; -import 'zone.js/dist/zone'; +import 'zone.js'; diff --git a/knox-token-management-ui/token-management/styles.css b/knox-token-management-ui/token-management/styles.css index 7240de9e32..0e2d7a08a9 100644 --- a/knox-token-management-ui/token-management/styles.css +++ b/knox-token-management-ui/token-management/styles.css @@ -18,7 +18,7 @@ /* You can add global styles to this file, and also import other style files */ -@import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; +@import '@angular/material/prebuilt-themes/deeppurple-amber.css'; .navbar-static-top { min-height: 110px; @@ -27,3 +27,7 @@ .clickable { cursor: pointer; } + +html, body { + font-size: 14px; +} diff --git a/knox-token-management-ui/token-management/tsconfig.json b/knox-token-management-ui/token-management/tsconfig.json index 5ceb8f1978..af90e6cbd0 100644 --- a/knox-token-management-ui/token-management/tsconfig.json +++ b/knox-token-management-ui/token-management/tsconfig.json @@ -8,12 +8,11 @@ "es2017", "dom" ], - "mapRoot": "./", - "module": "es6", - "moduleResolution": "node", + "module": "ES2022", + "moduleResolution": "bundler", "outDir": "../dist/out-tsc", "sourceMap": true, - "target": "es5", + "target": "ES2022", "typeRoots": [ "../node_modules/@types" ] From d2b5bb7ff801588e899c15ac375f6880e0fd373e Mon Sep 17 00:00:00 2001 From: thanicz Date: Mon, 8 Dec 2025 07:49:00 +0100 Subject: [PATCH 3/9] KNOX-3224: Replaced old token-management prebuilt theme, Changed default show proxy information to true, Fixed invalid profiles call (duplicate '/' in URL) --- .../general.proxy.information.component.ts | 2 +- .../home/app/service/homepage.service.ts | 2 +- knox-token-management-ui/angular.json | 2 +- .../token.management.component.html | 12 +++---- .../{styles.css => styles.scss} | 32 +++++++++++++++++-- 5 files changed, 39 insertions(+), 11 deletions(-) rename knox-token-management-ui/token-management/{styles.css => styles.scss} (65%) diff --git a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts index efa6c087d2..4a5e9de7c5 100644 --- a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts +++ b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts @@ -34,7 +34,7 @@ export class GeneralProxyInformationComponent implements OnInit { profile: JSON; constructor(private homepageService: HomepageService, private route: ActivatedRoute) { - this['showGeneralProxyInformation'] = false; + this['showGeneralProxyInformation'] = true; this['showKnoxVersion'] = true; this['showKnoxHostname'] = true; this['showPublicCerts'] = true; diff --git a/knox-homepage-ui/home/app/service/homepage.service.ts b/knox-homepage-ui/home/app/service/homepage.service.ts index b4ef43d7d3..3fce7834c5 100644 --- a/knox-homepage-ui/home/app/service/homepage.service.ts +++ b/knox-homepage-ui/home/app/service/homepage.service.ts @@ -65,7 +65,7 @@ export class HomepageService { getProfile(profileName: string): Promise { let headers = this.addJsonHeaders(new HttpHeaders()); - let url = `${this.apiUrl}/profiles/${profileName}`; + let url = `${this.apiUrl}profiles/${profileName}`; return firstValueFrom(this.http.get(url, { headers })) .catch(err => this.handleError(err)); } diff --git a/knox-token-management-ui/angular.json b/knox-token-management-ui/angular.json index 0c3d27f7e5..8589fc4c03 100644 --- a/knox-token-management-ui/angular.json +++ b/knox-token-management-ui/angular.json @@ -51,7 +51,7 @@ ], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", - "token-management/styles.css" + "token-management/styles.scss" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html index d2e5fe79b8..48762a0bf8 100644 --- a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html @@ -15,7 +15,7 @@
- + + (click)="disableToken(knoxToken.tokenId);"class="me-1">Disable + (click)="enableToken(knoxToken.tokenId);" class="me-1">Enable

Previously Disabled SSO Cookie! @@ -161,11 +161,11 @@

- - -
diff --git a/knox-token-management-ui/token-management/styles.css b/knox-token-management-ui/token-management/styles.scss similarity index 65% rename from knox-token-management-ui/token-management/styles.css rename to knox-token-management-ui/token-management/styles.scss index 0e2d7a08a9..cf55f03c90 100644 --- a/knox-token-management-ui/token-management/styles.css +++ b/knox-token-management-ui/token-management/styles.scss @@ -16,9 +16,15 @@ * limitations under the License. */ -/* You can add global styles to this file, and also import other style files */ +@use '@angular/material' as mat; -@import '@angular/material/prebuilt-themes/deeppurple-amber.css'; +:root { + @include mat.theme(( + color: ( + primary: mat.$green-palette + ) + )); +} .navbar-static-top { min-height: 110px; @@ -31,3 +37,25 @@ html, body { font-size: 14px; } + +.mat-mdc-table { + background-color: white !important; +} + +.mat-mdc-paginator { + background-color: white !important; +} + +.mat-mdc-button, +.mat-mdc-button-base { + border-radius: 0 !important; +} + +.mat-mdc-outlined-button { + border-color: rgb(182, 182, 182) !important; +} + +.mat-mdc-outlined-button>.mat-icon { + margin-right: 0px !important; + margin-left: 0px !important; +} \ No newline at end of file From 2af4acbfc5e6d91af54b7987ae067914277b6526 Mon Sep 17 00:00:00 2001 From: thanicz Date: Mon, 8 Dec 2025 14:25:18 +0100 Subject: [PATCH 4/9] KNOX-3224: Styled paginator on token management UI --- .../token.management.component.css | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css index e30a820453..d84fc7dd70 100644 --- a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.css @@ -45,4 +45,43 @@ .reduce-icon-size { transform: scale(0.65); +} + +::ng-deep .mat-mdc-paginator { + padding: 8px 12px; + min-height: 48px; + font-size: 13px; +} + +::ng-deep .mat-mdc-paginator .mat-mdc-icon-button { + width: 36px; + height: 36px; +} + +::ng-deep .mat-mdc-paginator .mat-mdc-select { + margin: 0 8px; + min-width: 56px; +} + +::ng-deep div.mat-mdc-select-panel { + background-color: white !important; +} + +::ng-deep .mat-mdc-paginator .mat-mdc-select .mat-mdc-select-value { + color: #333; + font-size: 13px; +} + +::ng-deep .mat-mdc-paginator .mat-mdc-select .mat-mdc-select-arrow { + color: #666; +} + +::ng-deep .mat-mdc-paginator .mat-mdc-select-trigger { + padding: 4px 8px; + border-radius: 4px; + border: 1px solid #ddd; +} + +::ng-deep .mdc-notched-outline > * { + border: none !important; } \ No newline at end of file From 9f3ea3355cc17d5a45dfe84fca1f501eb4ad136d Mon Sep 17 00:00:00 2001 From: thanicz Date: Mon, 8 Dec 2025 17:22:39 +0100 Subject: [PATCH 5/9] KNOX-3224: Remove package-lock.json as well during clean --- knox-token-generation-ui/pom.xml | 8 ++++++-- knox-token-management-ui/pom.xml | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/knox-token-generation-ui/pom.xml b/knox-token-generation-ui/pom.xml index fc49fc3af2..e04caa4166 100644 --- a/knox-token-generation-ui/pom.xml +++ b/knox-token-generation-ui/pom.xml @@ -37,7 +37,11 @@ - node_modules + ${project.basedir} + + package-lock.json + node_modules/** + @@ -91,4 +95,4 @@ - \ No newline at end of file + diff --git a/knox-token-management-ui/pom.xml b/knox-token-management-ui/pom.xml index 424d4422b3..a89a724100 100644 --- a/knox-token-management-ui/pom.xml +++ b/knox-token-management-ui/pom.xml @@ -37,7 +37,11 @@ - node_modules + ${project.basedir} + + package-lock.json + node_modules/** + From c21af15a36cb14bd4f0ddca010ea351c00cedeb2 Mon Sep 17 00:00:00 2001 From: thanicz Date: Mon, 15 Dec 2025 18:22:28 +0100 Subject: [PATCH 6/9] KNOX-3224: Green-palette style for Token Generation UI --- gateway-release/home/conf/gateway-site.xml | 8 - .../home/conf/topologies/homepage.xml | 43 +- knox-token-generation-ui/angular.json | 4 +- .../token-generation.component.css | 2 +- .../token-generation.component.html | 59 +- .../token-generation.component.ts | 6 +- .../assets/styles/app-font.css | 64 - .../token-generation/assets/styles/knox.css | 1908 ----------------- .../token-generation/index.html | 31 +- .../{styles.css => styles.scss} | 18 +- .../token-management/index.html | 1 - 11 files changed, 116 insertions(+), 2028 deletions(-) delete mode 100644 knox-token-generation-ui/token-generation/assets/styles/app-font.css delete mode 100644 knox-token-generation-ui/token-generation/assets/styles/knox.css rename knox-token-generation-ui/token-generation/{styles.css => styles.scss} (77%) diff --git a/gateway-release/home/conf/gateway-site.xml b/gateway-release/home/conf/gateway-site.xml index a33e908dd9..ba8865eb08 100644 --- a/gateway-release/home/conf/gateway-site.xml +++ b/gateway-release/home/conf/gateway-site.xml @@ -64,13 +64,6 @@ limitations under the License. Boolean flag indicating whether to enable debug messages for krb5 authentication - - - gateway.websocket.feature.enabled - false - Enable/Disable websocket feature. - - gateway.scope.cookies.feature.enabled false @@ -207,5 +200,4 @@ limitations under the License. LIVYSERVER Add service name to x-forward-context header for the list of services defined above. - diff --git a/gateway-release/home/conf/topologies/homepage.xml b/gateway-release/home/conf/topologies/homepage.xml index 089ce39101..5f14c8b351 100644 --- a/gateway-release/home/conf/topologies/homepage.xml +++ b/gateway-release/home/conf/topologies/homepage.xml @@ -61,25 +61,54 @@ false + + + + + + + + + + + + + + + + + + + + + identity-assertion Default true + + principal.mapping + guest=hdfs; + + + group.principal.mapping + *=users;hdfs=admin + hadoop.proxyuser.impersonation.enabled - false + true - hadoop.proxyuser.changeme.users - NONE + hadoop.proxyuser.admin.users + * - hadoop.proxyuser.changeme.groups - NONE + hadoop.proxyuser.admin.groups + * - hadoop.proxyuser.changeme.hosts - NONE + hadoop.proxyuser.admin.hosts + * diff --git a/knox-token-generation-ui/angular.json b/knox-token-generation-ui/angular.json index b6058417f8..f100e9d922 100644 --- a/knox-token-generation-ui/angular.json +++ b/knox-token-generation-ui/angular.json @@ -51,9 +51,7 @@ ], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", - "token-generation/assets/styles/app-font.css", - "token-generation/assets/styles/knox.css", - "token-generation/styles.css" + "token-generation/styles.scss" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css index f6f023b411..dd755e6e8c 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.css @@ -30,5 +30,5 @@ .tokenResultDisplay { margin-left: 1.75%; margin-right: 1.75%; - background-color: #e1e1e1; + background-color: rgb(223, 228, 215); } \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html index 07ecb34b52..a72d87a8fe 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html @@ -12,7 +12,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -
+
@@ -26,38 +26,43 @@

Token Generation

token as an authorization bearer token. Copy the JWT token from the resulting text area and protect it securely from others as this token represents your identity and is active until expired. - - - -
- - - - - - - -
+ + Lifetime Days + + + + Hours + + + + Minutes + + +
+ + mode_comment Comment + + +
- - + + person Generating token for (impersonation): + +
@@ -68,17 +73,17 @@

Token Generation

warning -
-
- +
+ class="reduce-icon-size">content_copy Target Base URL:
{{tokenResultData.targetURL}}
diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts index 15f9190545..3bc04bfe93 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts @@ -23,6 +23,10 @@ import { TssStatusData } from '../model/tss.status.data'; import { TokenGenService } from '../service/token-generation.service'; import { CommonModule } from '@angular/common'; import { MatIconModule } from '@angular/material/icon'; +import { MatButtonModule } from '@angular/material/button'; +import { MatInputModule } from '@angular/material/input'; +import { FormsModule } from '@angular/forms'; +import {MatFormFieldModule} from '@angular/material/form-field'; @Component({ selector: 'app-token-generation', @@ -30,7 +34,7 @@ import { MatIconModule } from '@angular/material/icon'; styleUrls: ['./token-generation.component.css'], providers: [TokenGenService], standalone: true, - imports: [CommonModule, ReactiveFormsModule, MatIconModule] + imports: [CommonModule, ReactiveFormsModule, MatIconModule, MatButtonModule, MatInputModule, FormsModule, MatFormFieldModule] }) export class TokenGenerationComponent implements OnInit { tssStatusMessageLevel: 'info' | 'warning' | 'error'; diff --git a/knox-token-generation-ui/token-generation/assets/styles/app-font.css b/knox-token-generation-ui/token-generation/assets/styles/app-font.css deleted file mode 100644 index 78b450f7d2..0000000000 --- a/knox-token-generation-ui/token-generation/assets/styles/app-font.css +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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. - */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 300; - src: local('Open Sans Light'), local('OpenSans-Light'), url(../../assets/fonts/fontopensans/open-sans-300.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(../../assets/fonts/fontopensans/open-sans-400.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 600; - src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../../assets/fonts/fontopensans/open-sans-600.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../../assets/fonts/fontopensans/open-sans-700.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 300; - src: local('Open Sans Light Italic'), local('OpenSansLight-Italic'), url(../../assets/fonts/fontopensans/open-sans-300i.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 400; - src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../../assets/fonts/fontopensans/open-sans-400i.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 600; - src: local('Open Sans Semibold Italic'), local('OpenSans-SemiboldItalic'), url(../../assets/fonts/fontopensans/open-sans-600i.woff) format('woff'); -} -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 700; - src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), url(../../assets/fonts/fontopensans/open-sans-700i.woff) format('woff'); -} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/assets/styles/knox.css b/knox-token-generation-ui/token-generation/assets/styles/knox.css deleted file mode 100644 index e3b5a15a59..0000000000 --- a/knox-token-generation-ui/token-generation/assets/styles/knox.css +++ /dev/null @@ -1,1908 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF 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. - */ -body { - background:#eee; - padding: 52px 0 0 30px; -} - -.fluid-layout .container, -.fluid-layout #top-navbar .container { - padding-right: 30px; - width: inherit; -} -.nav-button { - display: none; - float: right; - font-size: 17px; - margin-right: 12px; -} -#top-navbar .navbar-inner { - background: #3ea211; - border-bottom: 1px solid #1b4607; - -webkit-box-shadow: rgba(255, 255, 255, 0.25) 0px 1px 0px inset; - -moz-box-shadow: rgba(255, 255, 255, 0.25) 0px 1px 0px inset; - box-shadow: rgba(255, 255, 255, 0.25) 0px 1px 0px inset; - background-color: #58b31f; - background-image: -moz-linear-gradient(top, #69be28, #3ea211); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#69be28), to(#3ea211)); - background-image: -webkit-linear-gradient(top, #69be28, #3ea211); - background-image: -o-linear-gradient(top, #69be28, #3ea211); - background-image: linear-gradient(to bottom, #69be28, #3ea211); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff69be28', endColorstr='#ff3ea211', GradientType=0); -} - -#top-navbar .nav .dropdown-toggle .icon-caret-down { - margin-right: -6px; -} - -#top-navbar .logo { - display: block; - float: left; - margin: 5px 15px 0 15px; -} -#top-navbar .logo:hover { - opacity: 0.7; -} - -#top-navbar .nav > li > a.usermenu > img { - display: inline-block; - height: 23px; - vertical-align: top; - width: 23px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -#top-navbar .nav > li > a { - color: #fff; - display: block; - line-height: 22px; - font-size: 15px; - font-weight: 600; - padding: 9px 15px 0 15px; - height: 31px; - text-decoration: none; - text-shadow: rgba(0, 0, 0, 0.2) 0px -1px 0; -} -#top-navbar .nav > li > a:hover { - opacity: 0.7; -} -#top-navbar .nav > li.active > a, -#top-navbar .nav > li.open > a, -#top-navbar .nav > li.open > a:hover { - background: rgba(0, 0, 0, 0.15); - -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 5px inset; - -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 5px inset; - box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 5px inset; - opacity: 1; -} -#top-navbar .dropdown-menu li a { - font-size: 13px; -} - -#main-footer { - margin-top: 20px; - padding: 20px 0; - border-top: 1px solid #e3e3e3; - color: #999; - font-size: 13px; - text-align: center; -} -#main-footer a { - color: #999; - text-decoration: underline; -} -#main-footer a:hover { - color: #444; -} -#main-footer a.pull-right { - text-decoration: none; - line-height: 20px; -} -#main-footer a.pull-right i { - font-size: 8px; - position: relative; - top: -1px; -} - -.nav-tabs { - border-bottom: 2px solid #e1e1e1; - margin-bottom: 12px; - -webkit-box-shadow: rgba(255, 255, 255, 0.75) 0 1px 0; - -moz-box-shadow: rgba(255, 255, 255, 0.75) 0 1px 0; - box-shadow: rgba(255, 255, 255, 0.75) 0 1px 0; -} -.nav-tabs > li > a, -.nav-tabs > li > a:focus, -.nav-tabs > li > a:active { - background: none; - border: none; - color: #999999; - font-size: 14px; - margin-bottom: -1px; - padding: 3px 15px; -} -.nav-tabs > li > a:hover { - background: none; - color: #444; -} -.nav-tabs > .active > a, -.nav-tabs > .active > a:focus, -.nav-tabs > .active > a:active, -.nav-tabs > .active > a:hover { - background: none; - border: none; - border-bottom: 2px solid #3ea211; - color: #444; -} - -.wrap { - display: block; - background-color: #fff; - border: 1px solid #d6d6d6; - margin: 0 0 20px 0; - padding: 20px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - zoom: 1; -} -.wrap:before, -.wrap:after { - display: table; - content: ""; - line-height: 0; -} -.wrap:after { - clear: both; -} - -.wrap-header { - color: #222222; - font-size: 16px; - font-weight: 300; - line-height: 20px; - margin: 3px 0 0 0px; - padding-bottom: 10px; - text-transform: none; -} -.wrap-header > i { - display: inline-block; - font-size: 17px; - width: 20px; -} - -.wrap-header:hover .wrap-collapse { - opacity: 1; -} -.wrap-collapse, -.wrap-expand { - color: #888; - font-size: 11px; - font-weight: 600; - margin: 2px 10px 0 0; - position: relative; - text-transform: none; -} -.wrap-collapse:hover, -.wrap-expand:hover { - color: #444; - text-decoration: none; -} -.wrap-collapse { - opacity: 0.3; -} -.wrap-collapse i { - position: relative; - top: -1px; -} - -.pagination ul { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.pagination ul > li > a, -.pagination ul > li > span { - border: 1px solid #ddd; - color: #777777; - margin-right: 5px; - -webkit-border-radius: 3px !important; - -moz-border-radius: 3px !important; - border-radius: 3px !important; -} -.pagination ul > li > span { - border: none; -} -.pagination ul > li > a:focus { - background: none; -} -.pagination ul > li > a:hover { - background: none; - border-color: #3ea211; - color: #444; -} -.pagination ul > li.active > a, -.pagination ul > li.active > a:hover, -.pagination ul > li.active > a:focus, -.pagination ul > li.active > span { - background: #3ea211; - border-color: #3ea211; - color: #fff; - font-weight: 700; -} -.pagination ul > li.disabled > a:hover { - border-color: #ddd; -} - -.toggle { - height: 28px; - width: 80px; -} -.toggle-slide { - overflow: hidden; - cursor: pointer; - direction: ltr; -} -.toggle-slide .toggle-on, -.toggle-slide .toggle-off, -.toggle-slide .toggle-blob { - float: left; -} -.toggle-slide .toggle-blob { - position: relative; - z-index: 99; - cursor: hand; - cursor: grab; - cursor: -moz-grab; - cursor: -webkit-grab; -} -.toggle-xa .toggle-slide { - -webkit-box-shadow: #ffffff 0 1px 0; - -moz-box-shadow: #ffffff 0 1px 0; - box-shadow: #ffffff 0 1px 0; - -webkit-border-radius: 9999px; - -moz-border-radius: 9999px; - border-radius: 9999px; - overflow: hidden !important; -} -.toggle-xa .toggle-slide .toggle-on, -.toggle-xa .toggle-slide .toggle-off, -.toggle-xa .toggle-slide .toggle-blob { - color: rgba(0, 0, 0, 0.7); - font-size: 13px; - font-weight: 600; -} -.toggle-xa .toggle-slide .toggle-on { - background: #3ea211; - color: #fff; - -webkit-border-top-left-radius: 999px; - -moz-border-radius-topleft: 999px; - border-top-left-radius: 999px; - -webkit-border-bottom-left-radius: 999px; - -moz-border-radius-bottomleft: 999px; - border-bottom-left-radius: 999px; - background-color: #296b0b; - background-image: -moz-linear-gradient(top, #1b4607, #3ea211); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1b4607), to(#3ea211)); - background-image: -webkit-linear-gradient(top, #1b4607, #3ea211); - background-image: -o-linear-gradient(top, #1b4607, #3ea211); - background-image: linear-gradient(to bottom, #1b4607, #3ea211); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1b4607', endColorstr='#ff3ea211', GradientType=0); - background-color: #358b0f; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.toggle-xa .toggle-slide .toggle-off { - background: #cccccc; - -webkit-border-top-right-radius: 999px; - -moz-border-radius-topright: 999px; - border-top-right-radius: 999px; - -webkit-border-bottom-right-radius: 999px; - -moz-border-radius-bottomright: 999px; - border-bottom-right-radius: 999px; - background-color: #c7c7c7; - background-image: -moz-linear-gradient(top, #b3b3b3, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #b3b3b3, #e6e6e6); - background-image: -o-linear-gradient(top, #b3b3b3, #e6e6e6); - background-image: linear-gradient(to bottom, #b3b3b3, #e6e6e6); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffb3b3b3', endColorstr='#ffe6e6e6', GradientType=0); - background-color: #a6a6a6; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} -.toggle-xa .toggle-slide .toggle-blob { - background: #fff; - -webkit-border-radius: 9999px; - -moz-border-radius: 9999px; - border-radius: 9999px; - background-color: #ebebeb; - background-image: -moz-linear-gradient(top, #ffffff, #cccccc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#cccccc)); - background-image: -webkit-linear-gradient(top, #ffffff, #cccccc); - background-image: -o-linear-gradient(top, #ffffff, #cccccc); - background-image: linear-gradient(to bottom, #ffffff, #cccccc); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffcccccc', GradientType=0); - background-color: #cccccc; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); -} - -/* body css */ -@media (min-width: 768px) and (max-width: 979px) { - body, .fluid-layout, .centered-layout { - padding: 52px 15px 0 15px; - } - - #top-navbar .nav > li > a { - font-size: 12px !important; - } - - #top-navbar .nav > li > a { - padding: 9px 10px 0 10px !important; - } -} - -@media (max-width: 767px) { - body, .centered-layout { - padding: 52px 15px 0 15px; - } - - #top-navbar .nav-collapse .page-nav { - margin: 30px 0 6px !important; - } - - /* button stacks below form elements without space */ - .controls .btn { - margin-top: 5px; - } - - table.table-permission tr th:last-child, table.table-permission tr td:last-child { - padding-left: 6% !important; - } -} - -@media (max-width: 480px) { - body, .centered-layout { - padding: 62px 0 0 0; - } -} -/* overriding backgrid height property */ -.backgrid td { - height: auto; -} - -/* page logo */ -#top-navbar .page-logo { - float: none; - position: absolute; - left: 0; - top: 0; -} - -#top-navbar .page-logo img { - max-height: 33px; -} - -.navbar .page-nav { - margin: 0 0 0 130px; -} - -/* Added class hr */ -.hr { - display: block; - height: 0; - overflow: hidden; - font-size: 0; - border-top: 1px solid #e3e3e3; - margin: 12px 0; -} - -/* Added space class, where spans are stacked on top of each other */ -.space-6 { - max-height: 1px; - min-height: 1px; - overflow: hidden; - margin: 12px 0; - margin: 6px 0 5px; -} - -.vspace-6 { - max-height: 1px; - min-height: 1px; - overflow: hidden; - margin: 12px 0; - margin: 6px 0 5px 0; - display: none; -} - -.help-inline { - padding-right: 5px; -} - -.dropdown-menu > li > a > [class*="icon-"] { - margin-right: 6px; - font-size: 120%; - display: inline-block; - width: 1.25em; - text-align: center; -} - -/* over-ride top menu styles */ -#top-navbar .nav .dropdown-toggle .icon-caret-down { - margin-right: 0; -} - -.navbar .page-nav > li > a > [class*="icon-"] { - margin-right: 3px; -} - -/* footer */ -.nav-footer li { - float: left; -} - -.nav-footer li a { - background: 0; - border: 0; - color: #999; - font-size: 12px; - padding: 0 10px; - text-decoration: none !important; -} - -.copy-right-text p { - margin: 0 0 5px; - line-height: 15px; -} - -.js-formInput .select2-container { - width: 220px; -} - -.datagrid-stretch-wrapper { - border: 0; -} - -.table-permission td { - vertical-align: middle; - text-align: center; -} - -.table-permission td input[type="checkbox"] { - margin: 0; -} - -.table-permission { - float: left; - width: 90% -} - -/* toggle */ -.toggle-xa .toggle-slide { - box-shadow: 0 0 0 1px #999; -} - -.toggle { - height: 20px; - width: 80px; - margin-top: 5px; -} - -table.backgrid tr.tr-active { - background-color: #D7EFF1; -} - -table.backgrid tr.tr-active td, table.backgrid tr.tr-active td a { - /* Developer: Commenting out for time being - * font-weight: bold; - * color: #444444; - */ -} - -table.backgrid tr:hover { - background-color: #E8F1FB; -} - -.ui-pnotify-history-container { - display: none; -} - -.img-db-tb { - margin-right: 5px; - max-width: 24px !important; -} - -.backgrid tr.empty td, .backgrid td { - display: table-cell; -} - -.loading { - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: 0; - /* background-color: rgba(0,0,0,0.3); */ - text-align: center; - /* z-index: 999; */ - background: url('../../assets/images/loading.gif') no-repeat center center rgba(0,0,0,0.3); -} -.white { - color: #fff !important; -} - -.position-relative { - position: relative; -} - -.spin-position { - top: 40%; - position: absolute; -} - -.bold { - font-weight: bold; -} - -.box-filter { - margin-left: 1%; -} - -/* backgrid table css */ -/* Commenting backgrid filter css -table td.backgrid-filter input[type="search"] { - width: 70%; - padding-left: 1px; - height: 85%; - font-size: 11px; - padding-right: 0px; -} -table td.backgrid-filter .select2-container .select2-choice { - height: 21px; - line-height: 21px; -} -table td.backgrid-filter .select2-container .select2-choice .select2-arrow b { - background-position: 0 -2px; -} -table td.backgrid-filter .clear { - margin-left: -21px; - font-size: 19px; -} */ - -.table-permission th, .table-permission td { - border: 1px solid #dddddd; -} - -.table-permission thead { - background-color: #eeeeee; -} - -/*table.table-permission tr th:last-child, table.table-permission tr td:last-child { - border: 0; - padding-left: 6%; - color: transparent; - background-color: #fff; -}*/ - -.table-permission thead tr { - color: #4F4F4F; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); -} - -/* backgrid table header css*/ - -table.backgrid thead th, table.backgrid thead td { - text-align: center; -} - -table.backgrid thead th, table.backgrid thead td { - border-bottom: 0; - border-top: 0; -} - -table.backgrid thead th { - background: transparent; -} - -table.backgrid thead { - background: #eeeeee; -} - -table.backgrid thead tr a { - color: #4F4F4F; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); -} - -table.backgrid thead tr:hover { - background: transparent; -} - -.table-read-only tr th:last-child, table.table-read-only tr td:last-child { - border: 1px solid #dddddd !important; - color: #4F4F4F !important; - background-color: inherit !important; -} -.serviceInfo{ - margin-top: -5px; -} -.updateInfo{ - margin-top: 10px; -} -.updateInfo p { - margin-bottom: 0px; - margin-top: 0px; - font-size: 11px; -} -.policyVer{ - font-size: 23px; - padding: 5px 0 0 3px; -} -.policyVer i{ - color : #3C9C11 !important; - opacity: 0.4; - -webkit-user-select: none; -} -.policyVer i.active{ - color : #3C9C11 !important; - cursor : pointer; - opacity: 1; -} -.policyVer text{ - padding : 0 10px; - color : black; - font-size: 14px; - position: relative; - top: -3px; -} - -.r-path { - word-break: break-all; - font-weight: normal; - color: #444; - font-size: 13px; -} - -.ul-db .dropdown-menu > li > a { - white-space: normal; - word-break: break-word; -} - -.hdfs-table table.backgrid thead th:nth-child(2) { - width: 35%; -} - -.m-height { - min-height: 500px; -} - -.btn-right { - margin-bottom: 1%; - float: right; - margin-left: 1%; -} - -.hide-tooltip .tooltip.in { - display: none !important; -} - -/* loader */ - -.loading-img { - position: relative; - text-align: center; -} - -.loading-img img { - animation: rotateThis 2s infinite linear; - -webkit-animation: rotateThis 2s infinite linear; - max-width: 50px; -} - -@keyframes rotateThis { -0% {transform:rotateY(0deg);} -10% {transform:rotateY(0deg);} -100% {transform:rotateY(360deg);} -} - -@-webkit-keyframes rotateThis { -0% {-webkit-transform:rotateY(0deg);transform:rotateY(0deg);} -10% {-webkit-transform:rotateY(0deg);transform:rotateY(0deg);} -100% {-webkit-transform:rotateY(360deg);transform:rotateY(360deg);} -} - -div#center { - margin-top: 1%; -} - -div#center span { - position: relative; - font-family: Helvetica; - font-size: 20px; - font-weight: bolder; - color: #3ea211; - /* color: #7c9710; */ - -} - -@keyframes janimation { -0% {transform: rotate(0deg) scale(1.5);color: #aaa;} -10% {transform: rotate(0deg) scale(1.7);color: #ccc;} -100% {transform: rotate(0deg) scale(1.2);color: #333;text-shadow: #666 0 0 10px;} -} - -@-webkit-keyframes janimation { -0% {-webkit-transform: rotate(0deg) scale(1.5);color: #aaa;} -10% {-webkit-transform: rotate(0deg) scale(1.7);color: #ccc;} -100% {-webkit-transform: rotate(0deg) scale(1.2);color: #333;text-shadow: #666 0 0 10px;} -} - -div#center div { - position: relative; - display: inline-block; - animation: janimation 2.2s infinite; - -webkit-animation: janimation 2.2s infinite; -} - -div#center div.letter_container_1 { - animation-delay: 0s; - -webkit-animation-delay: 0s; -} - -div#center div.letter_container_2 { - animation-delay: .2s; - -webkit-animation-delay: .2s; -} - -div#center div.letter_container_3 { - animation-delay: .4s; - -webkit-animation-delay: .4s; -} - -div#center div.letter_container_4 { - animation-delay: .6s; - -webkit-animation-delay: .6s; -} - -div#center div.letter_container_5 { - animation-delay: .8s; - -webkit-animation-delay: .8s; -} - -div#center div.letter_container_6 { - animation-delay: 1s; - -webkit-animation-delay: 1s; -} -div#center div.letter_container_7 { - animation-delay: 1.2s; - -webkit-animation-delay: 1.2s; -} - -/* policy manager table */ -table.table-policy tbody > tr:hover { - cursor: pointer; -} - -table.table-policy thead { - background: #eeeeee; -} - -table.table-policy thead tr > th { - vertical-align: middle; - font-size: 16px; -} - -table.table-policy thead tr > th a { - color: #444 !important; -} - -table.table-policy thead tr > th img { - margin-right: 5px; - max-width: 20px; -} - -.nav.nav-option { - margin: 0; -} - -.nav.nav-option > li > a:hover, .nav-option > li > a:focus { - text-decoration: none; - background-color: transparent; -} - -.nav-option .open .dropdown-toggle { - background-color: transparent; - -webkit-box-shadow: none !important; - -moz-box-shadow: none !important; - box-shadow: none !important; -} - -.nav.nav-option .dropdown-menu { - min-width: 80px; - right: 0; - left: auto; -} - -.nav-option .icon-caret-down { - font-size: 18px; -} - -.display-none { - display: none; -} - -table.table-policy tbody tr:hover .nav.nav-option { - display: block; -} - -.select2-container-multi .select2-choices li > div { - word-break: break-all; -} - -.select2-container-multi .select2-choices .select2-search-choice { - margin: 3px 3px 3px 5px; -} - -.controls ul { - list-style: none; - margin: 0; -} - -.controls ul li input[type="radio"] { - margin: 0; -} - -.controls ul li { - float: left; - margin-right: 10px; - margin-top: 4px; -} - -.controls ul li label { - display: inline-block; - margin-left: 5px; -} - -.backgrid th, .backgrid td { - display: table-cell; -} - -/* form controls css for hdfs */ -.form-horizontal .configProp .control-label { - width: 335px; -} - -.form-horizontal .configProp .controls { - margin-left: 360px; -} -/* backgrid style over-ride*/ -.backgrid th, .backgrid td { - max-width: 184px; -} - -.working.ui-autocomplete-loading { - background: url('../../assets/images/loading.gif') no-repeat right center !important; -} - -.form-actions.form-asset { - padding-left: 360px; -} - -.form-actions.form-policy { - padding-left: 180px; -} -/* jquery tagit css over-ride */ -ul.tagit li.tagit-choice-editable { - padding: 3px 5px 3px 18px; -} - -ul.tagit li.tagit-choice { - line-height: 13px; - font-size: 13px; - color: #333; - word-break: break-all; -} - -ul.tagit li.tagit-choice .tagit-close { - left: 0; - display: block; - width: 12px; - height: 13px; -} -.ui-state-default, .ui-widget-content .ui-state-default { - border: 1px solid #aaa !important; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0); - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee)) !important; - background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%) !important; - background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%) !important; - background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%) !important; -} - -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { - border: 0 !important; - color: #fff !important; - background: #3ea211 !important; -} - -.ui-menu .ui-menu-item a { - border-radius: 0 !important; -} - -table.backgrid tr > td > .label { - float: left; - margin: 0 3px 2px 0; -} - -.control-group.search-by .dropdown-menu { - min-width: 75px; -} - -.control-group.search-by .dropdown-menu li { - margin-right: 0px; -} -.control-group.search-by .dropdown-menu > li > a { - min-width: 75px; -} - -ul.tagit { - width: 300px; - border: 1px solid #c4c4c4; - border-top-color: #aaa; -} - -ul.tagit input[type="text"] { - width: 300px; - padding-right: 25px; -} - -.ui-widget-content { - background: #fff; - overflow: auto; - max-height: 200px; -} - -.link-tag { - display: inline-block; - background-color: #F7FDFF; - text-decoration: none; - padding: 0.1em 0.8em; - border: 1px solid #C0D4DB; - border-radius: 15px; - margin-top: 4px; -} - -.btn-top { - position: fixed; - bottom: 3px; - right: 5px; - -webkit-transition: 1s; - -moz-transition: 1s; - transition: 1s; - display: none; - color: #fff; - background-color: rgba(0,0,0,0.3); - padding: 5px 10px; - border-radius: 3px; -} - -.btn-top:hover { - text-decoration: none; -} - -.m-top-10 { - margin-top: 10px; -} - -.m-right-15 { - margin-right: 15px; -} - -.tab-content.user-profile-tab-content { - border: 1px solid #ddd; - padding: 8px 32px 32px; - -webkit-box-shadow: 1px 1px 0 0 rgba(0,0,0,0.2); - -moz-box-shadow: 1px 1px 0 0 rgba(0,0,0,0.2); - box-shadow: 1px 1px 0 0 rgba(0,0,0,0.2); - background-color: #FFF; -} - -.select2-results { - overflow-x: auto; -} -/* Tab */ -ul.tabs { - list-style-type: none; - line-height: 35px; - max-height: 35px; - overflow: hidden; - display: inline-block; - margin: 0; -} - -ul.tabs > li.active { - z-index: 2; - background: #efefef; -} - -ul.tabs > li { - float: right; - margin: 5px 5px 0; - border-top-right-radius: 6px; - border-top-left-radius: 6px; - padding: 0 15px; - /* height: 170px; */ - background: #ddd; - position: relative; - -webkit-box-shadow: 0 0 3px rgba(0,0,0,.5); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.5); - max-width: 200px; -} - -ul.tabs > li > a { - display: inline-block; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - text-decoration: none; - color: #222; -} -.controls-row .tags { - width: 225px; - max-height: 180px; - overflow-y: auto; -} - -.controls-row .link-tag { - vertical-align: top; -} - -/* controlling table width */ -.table-responsive { - width: 100%; - margin-bottom: 15px; - overflow-y: hidden; - overflow-x: auto; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #dddddd; - -webkit-overflow-scrolling: touch; -} -.table-responsive > .table { - margin-bottom: 0; -} -.table-responsive > .table > thead > tr > th, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; -} -.table-responsive > .table-bordered { - border: 0; -} -.table-responsive > .table-bordered > thead > tr > th:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; -} -.table-responsive > .table-bordered > thead > tr > th:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; -} -.table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > th, .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; -} - -/* Table Scroll Design */ -.tableBorder { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - background-color: #fff; -} -.table-responsive::-webkit-scrollbar { - width: 10px; - height: 9px; - background-color: #E0E0E0; -} -.table-responsive::-webkit-scrollbar-thumb { - background-color: #AAA; - border-radius: 10px; -} -.formHeader { - padding: 2px 4px; - font-size: 15px; - font-weight: bold; - line-height: 26px; - color: #333; - white-space: nowrap; - border-bottom: 1px solid #64a424; - /* text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #57A6EE; - border-radius: 3px; */ -} - -/* breadcrumb flat */ -.breadcrumb-flat { - list-style: none; - display: inline-block; - margin: 0; -} -.breadcrumb-flat .icon { - font-size: 14px; -} -.breadcrumb-flat li { - float: left; - line-height: 26px; - height: 26px; -} -.breadcrumb-flat li a { - color: #FFF; - display: block; - background: #64a424; - text-decoration: none; - position: relative; - height: 22px; - line-height: 22px; - padding: 0 10px 0 3px; - text-align: center; - margin-right: 23px; -} -.breadcrumb-flat li:nth-child(even) a { - background-color: #46662a; -} -.breadcrumb-flat li:nth-child(even) a:before { - border-color: #46662a; - border-left-color: transparent; -} -.breadcrumb-flat li:nth-child(even) a:after { - border-left-color: #46662a; -} -.breadcrumb-flat li:first-child a { - padding-left: 15px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - -ms-border-radius: 4px 0 0 4px; - -o-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} -.breadcrumb-flat li:first-child a:before { - border: none; -} -.breadcrumb-flat li:last-child a { - padding-right: 15px; -} -.breadcrumb-flat li:last-child a:after { -} -.breadcrumb-flat li a:before, .breadcrumb-flat li a:after { - content: ""; - position: absolute; - top: 0; - border: 0 solid #64a424; - border-width: 11px 10px; - width: 0; - height: 0; -} -.breadcrumb-flat li a:before { - left: -20px; - border-left-color: transparent; -} -.breadcrumb-flat li a:after { - left: 100%; - border-color: transparent; - border-left-color: #64a424; -} -.breadcrumb-flat li a:hover { - background-color: #46662a; -} -.breadcrumb-flat li a:hover:before { - border-color: #46662a; - border-left-color: transparent; -} -.breadcrumb-flat li a:hover:after { - border-left-color: #46662a; -} -.breadcrumb-flat li a:active { - background-color: #46662a; -} -.breadcrumb-flat li a:active:before { - border-color: #46662a; - border-left-color: transparent; -} -.breadcrumb-flat li a:active:after { - border-left-color: #46662a; -} -.reportSearchHeader { - margin-bottom: 18px; - margin-left: 1px; - padding: 8px 5px; - background-color: #f5f5f5; -} - -/* loading indicator for button */ -.btn-spinner { - position: relative; - overflow: hidden; -} - -.btn-spinner .icon-spin { - position: absolute; - top: 10%; - left: 33%; - opacity: 0; -} -.btn-spinner[data-loading] > span { - opacity: 0; -} -.btn-spinner[data-loading] .icon-spin { - opacity: 1; - font-size: 22px; -} -.newScroll::-webkit-scrollbar-track, -.select2-results::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - background-color: #F5F5F5; - border-radius: 10px; -} -.newScroll::-webkit-scrollbar, -.select2-results::-webkit-scrollbar { - width: 10px; - height: 9px; - background-color: #F5F5F5; -} -.newScroll::-webkit-scrollbar-thumb, -.select2-results::-webkit-scrollbar-thumb { - background-color: #AAA; - border-radius: 10px; -} -.labelInverse { - background-color: #FFFFFF; - background-color: #505050; - border-bottom: 1px solid #b3cee1; - border-right: 1px solid #b3cee1; - padding: 3px 4px 3px 4px; - text-decoration: blink; - font-size: 90%; - display: inline-block; - color: white; -} - -/* jQuery MSG Plugin : CSS */ - -#jquery-msg-bg { - -moz-opacity: 0.6; - -khtml-opacity: 0.6; - opacity: 0.6; - filter: alpha(opacity=60); - background: black; -} - -.jquery-msg-content { - -webkit-background-clip: padding-box; - padding: 15px; -} - -.black-on-white .jquery-msg-content { - background: white; - color: #333333; - -moz-opacity: 0.9; - -khtml-opacity: 0.9; - opacity: 0.9; - filter: alpha(opacity=90); - -webkit-box-shadow: 5px 5px 30px 0 black; - -moz-box-shadow: 5px 5px 30px 0 black; - box-shadow: 5px 5px 30px 0 black; - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - -o-border-radius: 8px; - -khtml-border-radius: 8px; - -ms-border-radius: 8px; - border-radius: 8px; - /* ie fix */ - -pie-lazy-init: true; - /* TODO causes error */ - /* behavior: url(PIE.htc); */ -} - -.white-on-black .jquery-msg-content { - -moz-opacity: 0.5; - -khtml-opacity: 0.5; - opacity: 0.5; - filter: alpha(opacity=50); - background: black; - color: white; - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - -o-border-radius: 8px; - -khtml-border-radius: 8px; - -ms-border-radius: 8px; - border-radius: 8px; - /* ie fix */ - -pie-lazy-init: true; - /* TODO causes error */ - /* behavior: url(PIE.htc); */ -} - -/* End :jQuery MSG Plugin : CSS */ - -.fancy { - text-align: center; - overflow: hidden; - font-size: 18px; -} -.fancy span { - display: inline-block; - position: relative; -} -.fancy span:before, .fancy span:after { - content: ""; - position: absolute; - margin-top: 0.45em; - border-top: 8px solid #5E5E5E; - top: 0; - width: 900px; -} -.fancy span:before { - right: 100%; - margin-right: 0.5em; -} -.fancy span:after { - left: 100%; - margin-left: 0.5em; -} - -.error-page{ - margin-top: 0px; - background: #fff; - height: 160px; - margin: 30px auto 0 auto; - padding-left: 190px; - width: 540px; - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1); - box-shadow: 0 1px 3px rgba(0,0,0,0.1); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.error-page .icon-box { - background: #f9f9f9; - border-right: 1px solid #eaeaea; - height: 160px; - margin-left: -190px; - position: absolute; - width: 160px; -} - -.error-page .icon-box img { - display: block; - margin: 40px auto 0 auto; -} -.error-page .error-box h1 { - display: block; - font-size: 19px; - font-weight: 600; - line-height: 20px; - margin: 0; - padding: 35px 0 0 0; -} -.error-page .error-box p { - color: #888; - font-size: 14px; - line-height: 14px; - margin: 0; - padding: 10px 0 20px 0; -} -.table-license tbody tr td:first-child{ - width: 15%; -} -/* Operation Diff (Diff Modal)*/ -.diff-content h5 { - word-break: break-all; -} -.attr { - font-weight: normal; - padding: 0; - text-align: right; -} -.diff { - border-style: solid; - border-width: 1px 0 1px 1px; - display: inline-block; - margin: 0 1em 1em 0; - position: relative; - border-color: #ddd; -} -.diff .diff-left, .diff .diff-right { - display: table-cell; - border-style: solid; - border-width: 0 1px 0 0; - border-color: #ddd; -} -.diff .diff-right { - margin-left: -.1em; - min-width: 16.5em; - right: 0; - top: 0; -} -.diff ol { - min-width: 250px; - display: table-cell; - margin: 0; - padding: 0; -} -.diff li { - display: block; - line-height: 1.2; - list-style-type: none; - margin: 0; - padding-bottom: 0; - padding-right: .5em; - border-style: solid; - border-width: 0 0 1px 0; - border-color: #ddd; - height: 15px; - min-width : 6.5em; - -} -.diff li { - padding: 6px 5px; - white-space: nowrap; - text-align: left; -} -.diff .data li { - /*padding-left: .5em;*/ - min-width: 6.5em; -} -.diff-right .data li { - min-width: 16.5em; -} - -.change { - background-color: #ffd; - border: 1px solid #963; - color: #630; -} -.change-row { - background-color: #fef7cd; -} -.add-text { - background-color: #e1f2d3; - border: 1px solid #cbe7c5; - color: #5c8847; -} -.delete-text { - border: 1px solid #f7cccc; - background-color: #f7e4e4; - color: #b85355; -} - -.diff h3 { - box-shadow: none; - display: block; - margin: 0; - padding: 4px 5px; - text-align: center; - font-size: 12px; - line-height: 20px; - background-color: #eee; - color: #4F4F4F; - font-weight: bold; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); - border-style: solid; - border-width: 0px 0 1px 0; - border-color: #ddd; -} -.label { - background-color: #bcbcbc; - font-size: 12px; - font-weight: 700; - padding: 2px 5px; -} -.label-user { - background-color: #78D3A0; -} -.label-group { - background-color: #78ABD3; -} -.label-resource { - background-color: #D3A478; -} -.label-asset { - background-color: #8A78D3; -} -.label-success { - background-color: #9bb921; -} -.label-info { -background-color: #63c0c8; -} -.label-important { -background-color: #dc6343; -} -.inline-block { - display:inline-block; -} -.is-table-include { - display: inline-block; - margin-left: 12px; - vertical-align: top; - margin-top: 7px; -} -.is-column-include { - display: inline-block; - vertical-align: top; - margin-top: 5px; -} -.modal-diff { - width: 1000px; - margin-left: -480px; -} -.modal-diff .modal-header { - background-color: #eff3f8; -} -.no-margin { - margin: 0; -} -.legend { - height: 10px; - width: 10px; - display: inline-block; - margin-right: 3px; -} -table.table.backgrid thead th.repoName { - border-top: 1px solid #ddd; -} -.label-size13-weightbold{ - font-size: 13px; - font-weight: bold; -} -.clickable tr { - cursor: pointer; -} -/* overridding select2 option hover css */ -.select2-results .select2-highlighted { - background: #3ea211; -} -.stretchTextInput{ - width:40%; -} -.editable-buttons { - display: block; - margin-top: 6%; -} - -/* Login Page */ -body.login { - background: #eeeeee; - padding: 0; -} -.login #signin-container { - margin: 0 auto; - width: 560px; -} -.login .l-logo { - text-align: center; - width: 100%; - margin-bottom: 20px; -} - -.icon-sign-in { - margin-left: 15px; - visibility: hidden; - font-size: 20px; - margin-top: 3px; - position:relative; - right:80px; -} -.login form .btn, -.login input { - font-size: 14px; -} -.login input, -.login form { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.login form { - margin: 0; - width: 100%; -} -.login form .btn { - line-height: 26px; - margin-top: 15px; - font-weight: bold; -} -.login .fields { - padding: 20px; - background-color: rgba(0,0,0,0.15); - - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - - border-right: 1px solid #595959; - border-bottom: 1px solid #595959; - border-left: 1px solid #2F2F2F; - border-top: 1px solid #2F2F2F; -} -.login a.forgot-password { - background: rgba(0, 0, 0, 0.05); - color: #888; - display: block; - float: right; - font-size: 11px; - height: 22px; - line-height: 22px; - margin: -32px 10px 0 0; - padding: 0 6px; - position: relative; - z-index: 10; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.login input { - background: #ffffff; - border: solid #dedede; - border-width: 0 0 1px 0; - height: 30px; - padding: 0 10px; - width: 100%; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.login label { - color: #727272; - font-size: 14px; - font-weight: bold; -} - -.login input:focus { - border-color: #dedede; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.label-yellow{ - background-color: #f3a139; -} -.label-inverse { -background-color: #444444; -} -.alert { - border:none; -} -tr.disable-policy td { - background-color: #F0F0F0; -} - -.policy-disabled .formHeader, -.policy-disabled .control-label { - color:#aaa; -} - -td.html-cell.renderable:last-child { - text-align:center; -} - -.policy-manager span.policy-title { - font-size: 20px; - line-height: 32px; - text-transform: uppercase; - color: #707070; -} -.policy-manager table thead tr th:first-child { - background-color: #d8d8d8; -} -.policy-manager table thead tr th:first-child a { - color: #707070; -} -.label-green{ - background-color: #3ea211; -} -.connection-error-font { - font-size: 11px; - font-family: monospace; -} -/**************/ -.policy-form .field-name{ - float: left; - margin-bottom: 0 !important; -} -.policy-form .field-isEnabled{ -margin-left: 413px; -margin-bottom: 12px !important; -} -.policy-form .field-isEnabled .controls{ - margin-left:30px; -} -.margin-bottom-5{ -margin-bottom: 5px; -} - -.popover-content { - /*overflow-y: auto; - max-height: 250px;*/ - padding-right: 25px; -} -.margin-bottom-57 { - margin-bottom:57px; -} -.table .table { - width:auto; -} -.width-25{ - width:25%; -} -.margin-left-0{ - margin-left:0%!important; -} - -.policy-manager .row-fluid [class*="span"]:first-child { - margin-left: 1%; -} -.policy-manager .row-fluid [class*="span"] { - margin-left: 1%; - margin-right: 1%; -} -.policy-manager .row-fluid [class*="span"]:nth-child(3n+4) { - clear: both; -} -.field-isEnabled + div { - clear:both; -} -.include-toggle{ - margin-left: 264px; - margin-top: -29px; -} -.recursive-toggle{ - margin-left: 363px; - margin-top: -20px; -} -.recursive-toggle-path { -margin-left: 347px; -margin-top: -29px; -} -.policy-form .help-inline { - position: relative; - top: 10px; -} -.hideResource{ - display:none; -} -.btn-mini { - padding: 0px 8px; - font-size: 11.05px; -} -.label-ranger { - background-color: #3C9C11; -} -.sameLevelDropdown{ - margin-right: 31px; - margin-left: -130px; - width: 100px; - height: 29px; - font-family: Tahoma; - font-size: 14px; - border-radius: 10px; - border: 2px #cccccc solid; -} -.margin-left-5{ - margin-left:5px; -} -.tr-inactive { - background-color: #F5F5F5; -} -.tr-inactive a { - color: #CCC; -} -.tr-inactive td span.label{ - background-color: #BCBCBC; - color: #fff; - font-weight: normal; - text-shadow: none; -} -td.select-row-cell { - text-align: center; -} -.ranger-notifications { - right: 33px!important; - top: 41px!important; -}table.table-permission.visible-border tr td:last-child { - border: 1px solid #dddddd; - padding-left: 0; -} -.set-height-groups{ - width: 100%; - height: 100px; - overflow-x: hidden; -} -.float-left-margin-2{ - float: left; - margin: 2px; -} - -#r_topNav .dropdown-menu { - margin:0; -} - -.table-policy-condition th, -.table-policy-condition td { - border: none !important; - white-space: nowrap; - color: #444444 !important; -} - -.table-policy-condition tr:nth-child(even) td, .table-policy-condition tr:nth-child(even) th {background-color: #FFFFFF;} -.table-policy-condition tr:nth-child(odd) td, .table-policy-condition tr:nth-child(odd) th {background-color: #EEEEEE;} - -.table-policy-condition label { - float: left; - margin-right: 10px; -} -.label-lightblue, .label-lightgreen {text-shadow:none; display: block; margin-bottom: 2px;} -.label-lightblue {background-color: #DEEEF9; color: #000;} -.label-lightgreen {background-color: #E4F4D8; color: #000;} - -input[type="radio"], input[type="checkbox"] {margin-top: 0;} - -.table-policy-condition td:nth-child(3) { - border-left: 2px solid #fff !important; -} -.table-policy-condition td:nth-child(3) label { - float: none; - text-align: center; - margin-left: 10px; -} -.white-space-normal{ - white-space: normal; - word-break: break-all; -} -.margin-top-6{ - margin-top: 6px; -} -.tag-fixed-popover { - top: 50px !important; - left: 55% !important; - margin-left: -350px !important; - max-width: 700px !important; - max-height: 500px; - overflow-y: auto; -} -.tag-fixed-popover-wrapper { - position: fixed !important; - top: 0 !important; - bottom: 0 !important; - right: 0 !important; - left: 0 !important; - z-index: 99 !important; - background-color: rgba(0,0,0,0.5); -} -.table-policy-condition label { - font-size: 12px; - text-align: left; -} -.table-policy-condition tr[data-id=storm] td label { - min-width: 170px; -} -/* align all component -.table-policy-condition td label { - min-width: 170px; -} */ -.pause-play-close{ - margin-left: -5px; - margin-top: -2px; - font-size: 11px; -} \ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/index.html b/knox-token-generation-ui/token-generation/index.html index e181dd1ad9..68a6e415d8 100644 --- a/knox-token-generation-ui/token-generation/index.html +++ b/knox-token-generation-ui/token-generation/index.html @@ -24,13 +24,30 @@ window['base-href'] = window.location.pathname.replace('index.html', ''); - -
- - Apache Knox Home -
- -
+ + +
+ +
+
diff --git a/knox-token-generation-ui/token-generation/styles.css b/knox-token-generation-ui/token-generation/styles.scss similarity index 77% rename from knox-token-generation-ui/token-generation/styles.css rename to knox-token-generation-ui/token-generation/styles.scss index 24b8fc04b3..a35a96aebb 100644 --- a/knox-token-generation-ui/token-generation/styles.css +++ b/knox-token-generation-ui/token-generation/styles.scss @@ -15,8 +15,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@use '@angular/material' as mat; -/* You can add global styles to this file, and also import other style files */ +:root { + @include mat.theme(( + color: ( + primary: mat.$green-palette + ) + )); +} .navbar-static-top { min-height: 110px; @@ -33,4 +40,13 @@ html, body { a { color: #3ea211; text-decoration: none; +} + +.mat-mdc-button, +.mat-mdc-button-base { + border-radius: 0 !important; +} + +.mat-mdc-outlined-button { + border-color: rgb(182, 182, 182) !important; } \ No newline at end of file diff --git a/knox-token-management-ui/token-management/index.html b/knox-token-management-ui/token-management/index.html index d14f389780..c088ffafa2 100644 --- a/knox-token-management-ui/token-management/index.html +++ b/knox-token-management-ui/token-management/index.html @@ -14,7 +14,6 @@ --> - Apache Knox Token Management From e958e826c2dc53c8463c5f4a1ed5b8d75af345b0 Mon Sep 17 00:00:00 2001 From: thanicz Date: Tue, 16 Dec 2025 07:11:37 +0100 Subject: [PATCH 7/9] KNOX-3224: Update token management and generation UIs to Angular v21 --- gateway-release/home/conf/gateway-site.xml | 8 + .../home/conf/topologies/homepage.xml | 43 +-- knox-token-generation-ui/package.json | 36 +- .../token-generation.component.html | 66 ++-- .../token-generation.component.ts | 4 +- .../token-generation/assets/sticky-footer.css | 42 -- .../token-generation/main.ts | 4 +- .../token-generation/tsconfig.json | 4 - knox-token-management-ui/package.json | 40 +- .../token.management.component.html | 364 ++++++++++-------- .../token.management.component.ts | 8 +- .../token-management/assets/sticky-footer.css | 42 -- .../token-management/main.ts | 4 +- .../token-management/tsconfig.json | 4 - 14 files changed, 301 insertions(+), 368 deletions(-) delete mode 100644 knox-token-generation-ui/token-generation/assets/sticky-footer.css delete mode 100644 knox-token-management-ui/token-management/assets/sticky-footer.css diff --git a/gateway-release/home/conf/gateway-site.xml b/gateway-release/home/conf/gateway-site.xml index ba8865eb08..a33e908dd9 100644 --- a/gateway-release/home/conf/gateway-site.xml +++ b/gateway-release/home/conf/gateway-site.xml @@ -64,6 +64,13 @@ limitations under the License. Boolean flag indicating whether to enable debug messages for krb5 authentication + + + gateway.websocket.feature.enabled + false + Enable/Disable websocket feature. + + gateway.scope.cookies.feature.enabled false @@ -200,4 +207,5 @@ limitations under the License. LIVYSERVER Add service name to x-forward-context header for the list of services defined above. + diff --git a/gateway-release/home/conf/topologies/homepage.xml b/gateway-release/home/conf/topologies/homepage.xml index 5f14c8b351..089ce39101 100644 --- a/gateway-release/home/conf/topologies/homepage.xml +++ b/gateway-release/home/conf/topologies/homepage.xml @@ -61,54 +61,25 @@ false - - - - - - - - - - - - - - - - - - - - - identity-assertion Default true - - principal.mapping - guest=hdfs; - - - group.principal.mapping - *=users;hdfs=admin - hadoop.proxyuser.impersonation.enabled - true + false - hadoop.proxyuser.admin.users - * + hadoop.proxyuser.changeme.users + NONE - hadoop.proxyuser.admin.groups - * + hadoop.proxyuser.changeme.groups + NONE - hadoop.proxyuser.admin.hosts - * + hadoop.proxyuser.changeme.hosts + NONE diff --git a/knox-token-generation-ui/package.json b/knox-token-generation-ui/package.json index f4d9b0d74b..38923575fe 100644 --- a/knox-token-generation-ui/package.json +++ b/knox-token-generation-ui/package.json @@ -11,33 +11,33 @@ }, "private": true, "dependencies": { - "@angular/common": "^20.3.15", - "@angular/compiler": "^20.3.15", - "@angular/core": "^20.3.15", - "@angular/forms": "^20.3.15", - "@angular/platform-browser": "^20.3.15", - "@angular/platform-browser-dynamic": "^20.3.15", - "@angular/material": "^20.2.5", - "@angular/router": "^20.3.2", + "@angular/common": "^21.0.5", + "@angular/compiler": "^21.0.5", + "@angular/core": "^21.0.5", + "@angular/forms": "^21.0.5", + "@angular/platform-browser": "^21.0.5", + "@angular/platform-browser-dynamic": "^21.0.5", + "@angular/material": "^21.0.3", + "@angular/router": "^21.0.5", "jquery": "^3.7.1", "sweetalert2": "^11.26.3", "zone.js": "~0.15.1", "bootstrap": "^5.3.8" }, "devDependencies": { - "@angular-devkit/build-angular": "^20.3.13", - "@angular-eslint/builder": "20.7.0", - "@angular-eslint/eslint-plugin": "20.7.0", - "@angular-eslint/eslint-plugin-template": "20.7.0", - "@angular-eslint/schematics": "20.7.0", - "@angular-eslint/template-parser": "20.7.0", - "@angular/cli": "^20.3.13", - "@angular/compiler-cli": "^20.3.15", - "@angular/language-service": "^20.3.15", + "@angular-devkit/build-angular": "^21.0.3", + "@angular-eslint/builder": "21.1.0", + "@angular-eslint/eslint-plugin": "21.1.0", + "@angular-eslint/eslint-plugin-template": "21.1.0", + "@angular-eslint/schematics": "21.1.0", + "@angular-eslint/template-parser": "21.1.0", + "@angular/cli": "^21.0.3", + "@angular/compiler-cli": "^21.0.5", + "@angular/language-service": "^21.0.5", "@types/node": "^24.5.2", "eslint": "^9.39.0", "ts-node": "~10.9.0", - "typescript": "~5.8.3", + "typescript": "~5.9.3", "typescript-eslint": "^8.46.2" } } diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html index a72d87a8fe..23e262626e 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.html @@ -17,19 +17,27 @@

Token Generation

- - - + @if (tssStatusMessageLevel === 'info') { + + } + @if (tssStatusMessageLevel === 'warning') { + + } + @if (tssStatusMessageLevel === 'error') { + + } -
+ lifetime: {{tssStatus.maximumLifetimeText}} @if ('Unlimited lifetime' === + tssStatus.maximumLifetimeText) { + priority_high + } + @if (tssStatus.lifespanInputEnabled) { +
Lifetime Days Token Generation - -
+ } mode_comment Comment - + } -
+ @if (tssStatus.impersonationEnabled) { +
- person Generating token for (impersonation): + person Generating token for + (impersonation): - + @if (impersonation.invalid) { + + }
+ }
- {{requestErrorMessage}} + @if (requestErrorMessage) { + {{requestErrorMessage}} warning + }

- + @if (hasResult) { +
{{tokenResultData.accessToken}}
- -
+ @if (tokenResultData.accessPasscode) { +
{{tokenResultData.accessPasscode}}
- + }
{{tokenResultData.expiry}}
-
{{tokenResultData.user}}
-
{{tokenResultData.targetURL}}
- + }
\ No newline at end of file diff --git a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts index 3bc04bfe93..6d9757abba 100644 --- a/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts +++ b/knox-token-generation-ui/token-generation/app/token-generation/token-generation.component.ts @@ -21,7 +21,7 @@ import Swal from 'sweetalert2/dist/sweetalert2.esm.all.js'; import { TokenResultData } from '../model/token.result.data'; import { TssStatusData } from '../model/tss.status.data'; import { TokenGenService } from '../service/token-generation.service'; -import { CommonModule } from '@angular/common'; + import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatInputModule } from '@angular/material/input'; @@ -34,7 +34,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; styleUrls: ['./token-generation.component.css'], providers: [TokenGenService], standalone: true, - imports: [CommonModule, ReactiveFormsModule, MatIconModule, MatButtonModule, MatInputModule, FormsModule, MatFormFieldModule] + imports: [ReactiveFormsModule, MatIconModule, MatButtonModule, MatInputModule, FormsModule, MatFormFieldModule] }) export class TokenGenerationComponent implements OnInit { tssStatusMessageLevel: 'info' | 'warning' | 'error'; diff --git a/knox-token-generation-ui/token-generation/assets/sticky-footer.css b/knox-token-generation-ui/token-generation/assets/sticky-footer.css deleted file mode 100644 index 59b129bd78..0000000000 --- a/knox-token-generation-ui/token-generation/assets/sticky-footer.css +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF 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. - */ - -/* Sticky footer styles --------------------------------------------------- */ -html { - position: relative; - min-height: 100%; -} - -body { - /* Margin bottom by footer height */ - margin-bottom: 60px; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - /* Set the fixed height of the footer here */ - height: 60px; - background-color: #f5f5f5; -} - -.jumbotron { - padding: 0.5em 0.6em; -} diff --git a/knox-token-generation-ui/token-generation/main.ts b/knox-token-generation-ui/token-generation/main.ts index 89cd6afdcf..8acc0100e5 100644 --- a/knox-token-generation-ui/token-generation/main.ts +++ b/knox-token-generation-ui/token-generation/main.ts @@ -20,7 +20,7 @@ import {environment} from './environments/environment'; import { SessionInformationComponent } from './app/sessionInformation/session.information.component.js'; import { TokenGenerationComponent } from './app/token-generation/token-generation.component.js'; import { bootstrapApplication } from '@angular/platform-browser'; -import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { enableProdMode, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { APP_BASE_HREF } from '@angular/common'; import { provideHttpClient } from '@angular/common/http'; @@ -37,7 +37,7 @@ const bootstrapComponents = [ bootstrapComponents.forEach(component => { bootstrapApplication(component, { providers: [ - importProvidersFrom(), + provideZoneChangeDetection(),importProvidersFrom(), provideHttpClient(), provideRouter([]), { diff --git a/knox-token-generation-ui/token-generation/tsconfig.json b/knox-token-generation-ui/token-generation/tsconfig.json index 525839e013..50820bd582 100644 --- a/knox-token-generation-ui/token-generation/tsconfig.json +++ b/knox-token-generation-ui/token-generation/tsconfig.json @@ -4,10 +4,6 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "lib": [ - "es2017", - "dom" - ], "module": "ES2022", "moduleResolution": "bundler", "outDir": "../dist/out-tsc", diff --git a/knox-token-management-ui/package.json b/knox-token-management-ui/package.json index 86566d8fde..c3c363404e 100644 --- a/knox-token-management-ui/package.json +++ b/knox-token-management-ui/package.json @@ -11,16 +11,16 @@ }, "private": true, "dependencies": { - "@angular/animations": "^20.3.15", - "@angular/cdk": "^20.2.14", - "@angular/common": "^20.3.15", - "@angular/compiler": "^20.3.15", - "@angular/core": "^20.3.15", - "@angular/forms": "^20.3.15", - "@angular/material": "^20.2.14", - "@angular/platform-browser": "^20.3.15", - "@angular/platform-browser-dynamic": "^20.3.15", - "@angular/router": "^20.3.15", + "@angular/animations": "^21.0.5", + "@angular/cdk": "^21.0.3", + "@angular/common": "^21.0.5", + "@angular/compiler": "^21.0.5", + "@angular/core": "^21.0.5", + "@angular/forms": "^21.0.5", + "@angular/material": "^21.0.3", + "@angular/platform-browser": "^21.0.5", + "@angular/platform-browser-dynamic": "^21.0.5", + "@angular/router": "^21.0.5", "bootstrap": "^5.3.8", "core-js": "^3.47.0", "jquery": "^3.7.1", @@ -28,21 +28,21 @@ "zone.js": "~0.15.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^20.3.13", - "@angular-eslint/builder": "20.7.0", - "@angular-eslint/eslint-plugin": "20.7.0", - "@angular-eslint/eslint-plugin-template": "20.7.0", - "@angular-eslint/schematics": "20.7.0", - "@angular-eslint/template-parser": "20.7.0", - "@angular/cli": "^20.3.13", - "@angular/compiler-cli": "^20.3.15", - "@angular/language-service": "^20.3.15", + "@angular-devkit/build-angular": "^21.0.3", + "@angular-eslint/builder": "21.1.0", + "@angular-eslint/eslint-plugin": "21.1.0", + "@angular-eslint/eslint-plugin-template": "21.1.0", + "@angular-eslint/schematics": "21.1.0", + "@angular-eslint/template-parser": "21.1.0", + "@angular/cli": "^21.0.3", + "@angular/compiler-cli": "^21.0.5", + "@angular/language-service": "^21.0.5", "@types/jasmine": "~2.5.53", "@types/jasminewd2": "^2.0.8", "@types/node": "^24.5.2", "eslint": "^9.39.0", "ts-node": "~10.9.0", - "typescript": "~5.8.3", + "typescript": "~5.9.3", "typescript-eslint": "^8.46.2" } } diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html index 48762a0bf8..1b85beb82a 100644 --- a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.html @@ -14,172 +14,202 @@ -->
-
- - - - - Show Disabled KnoxSSO Cookies - - -
- -
- - - Show My Tokens Only - - -
- -
- - Search by Token ID, (Impersonated) User Name, Comment or Metadata... - - - - - - - - - - - - - - - - - Token ID - -
{{knoxToken.tokenId}}
-
{{knoxToken.tokenId}}
-
-
- - - Issued - {{formatDateTime(knoxToken.issueTimeLong)}} - - - - Expires - {{formatDateTime(knoxToken.expirationLong)}} - - - - User Name - {{knoxToken.metadata.userName}} - - - - Impersonated - -
- - -

{{knoxToken.metadata.createdBy}}

-
-
-
- - - Type - - - - - - - Comment - {{knoxToken.metadata.comment}} - - - - Additional - Metadata - -
    -
  • - {{metadata[0]}} = {{metadata[1]}} -
  • -
-
-
- - - Actions - - - - -

Previously Disabled SSO Cookie! -

-
-
- - - - -
- -
- -
- - - -
- -
- Expired tokens cannot be disabled in batches - (nor individually). -
-
- Expired tokens cannot be enabed in batches - (nor individually). -
-
- KnoxSSO Cookies cannot be revoked in batches - (nor individually). -
+
+ + + + + Show Disabled KnoxSSO Cookies + + +
+ + @if (userCanSeeAllTokens()) { +
+ + + Show My Tokens Only + + +
+ } + +
+ + Search by Token ID, (Impersonated) User Name, Comment or Metadata... + + + + + + + + + + + @if (!isDisabledKnoxSSoCookie(knoxToken)) { + + + } + + + + + Token ID + + @if (knoxToken.metadata.enabled) { +
{{knoxToken.tokenId}}
+ } + @if (!knoxToken.metadata.enabled) { +
{{knoxToken.tokenId}}
+ } +
+
+ + + Issued + {{formatDateTime(knoxToken.issueTimeLong)}} + + + + Expires + {{formatDateTime(knoxToken.expirationLong)}} + + + + User Name + {{knoxToken.metadata.userName}} + + + + Impersonated + +
+ @if (!knoxToken.metadata.createdBy) { + + } + @if (knoxToken.metadata.createdBy) { + + } + @if (knoxToken.metadata.createdBy) { +

{{knoxToken.metadata.createdBy}}

+ } +
+
+
+ + + Type + + + + + + + Comment + {{knoxToken.metadata.comment}} + + + + Additional + Metadata + +
    + @for (metadata of getCustomMetadataArray(knoxToken); track metadata) { +
  • + {{metadata[0]}} = {{metadata[1]}} +
  • + } +
+
+
+ + + Actions + + @if (knoxToken.metadata.enabled && !isTokenExpired(knoxToken.expirationLong)) { + + } + @if (!isKnoxSsoCookie(knoxToken) && !knoxToken.metadata.enabled && !isTokenExpired(knoxToken.expirationLong)) + { + + } + @if (!isKnoxSsoCookie(knoxToken)) { + + } + @if (isDisabledKnoxSsoCookie(knoxToken)) { +

Previously Disabled SSO Cookie! +

+ } +
+
+ + + + +
+ +
+ +
+ @if (showDisableSelectedTokensButton) { + + } + @if (showEnableSelectedTokensButton) { + + } + @if (showRevokeSelectedTokensButton) { + + } +
+ + @if (!selection.isEmpty() && !showDisableSelectedTokensButton) { +
+ Expired tokens cannot be disabled in batches + (nor individually). +
+ } + @if (!selection.isEmpty() && !showEnableSelectedTokensButton) { +
+ Expired tokens cannot be enabed in batches + (nor individually). +
+ } + @if (!selection.isEmpty() && !showRevokeSelectedTokensButton) { +
+ KnoxSSO Cookies cannot be revoked in batches + (nor individually). +
+ }
\ No newline at end of file diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts index 48fc4ab4d8..ce870c60f5 100644 --- a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts @@ -27,7 +27,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSortModule } from '@angular/material/sort'; import { MatPaginatorModule } from '@angular/material/paginator'; -import { CommonModule } from '@angular/common'; + import { FormsModule } from '@angular/forms'; import { MatTableModule } from '@angular/material/table'; import { MatInputModule } from '@angular/material/input'; @@ -40,8 +40,8 @@ import { MatButtonModule } from '@angular/material/button'; templateUrl: './token.management.component.html', styleUrls: ['./token.management.component.css'], providers: [TokenManagementService], - imports: [CommonModule, MatSlideToggleModule, MatFormFieldModule, MatSortModule, MatPaginatorModule, FormsModule, - MatTableModule, MatInputModule, MatCheckboxModule, MatIconModule, MatButtonModule], + imports: [MatSlideToggleModule, MatFormFieldModule, MatSortModule, MatPaginatorModule, FormsModule, MatTableModule, MatInputModule, + MatCheckboxModule, MatIconModule, MatButtonModule], standalone: true }) @@ -175,7 +175,7 @@ export class TokenManagementComponent implements OnInit { } private actualizeTokensToDisplay(): void { - if(!this.allKnoxTokens) { + if (!this.allKnoxTokens) { return; } let tokensToDisplay = this.allKnoxTokens; diff --git a/knox-token-management-ui/token-management/assets/sticky-footer.css b/knox-token-management-ui/token-management/assets/sticky-footer.css deleted file mode 100644 index 59b129bd78..0000000000 --- a/knox-token-management-ui/token-management/assets/sticky-footer.css +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF 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. - */ - -/* Sticky footer styles --------------------------------------------------- */ -html { - position: relative; - min-height: 100%; -} - -body { - /* Margin bottom by footer height */ - margin-bottom: 60px; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - /* Set the fixed height of the footer here */ - height: 60px; - background-color: #f5f5f5; -} - -.jumbotron { - padding: 0.5em 0.6em; -} diff --git a/knox-token-management-ui/token-management/main.ts b/knox-token-management-ui/token-management/main.ts index 797e447b92..c1e55feb8d 100644 --- a/knox-token-management-ui/token-management/main.ts +++ b/knox-token-management-ui/token-management/main.ts @@ -20,7 +20,7 @@ import { environment } from './environments/environment'; import { SessionInformationComponent } from './app/sessioninformation/session.information.component.js'; import { TokenManagementComponent } from './app/tokenmanagement/token.management.component.js'; import { bootstrapApplication } from '@angular/platform-browser'; -import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { enableProdMode, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; import { APP_BASE_HREF } from '@angular/common'; import { provideHttpClient } from '@angular/common/http'; @@ -37,7 +37,7 @@ const bootstrapComponents = [ bootstrapComponents.forEach(component => { bootstrapApplication(component, { providers: [ - importProvidersFrom(), + provideZoneChangeDetection(),importProvidersFrom(), provideHttpClient(), provideRouter([]), { diff --git a/knox-token-management-ui/token-management/tsconfig.json b/knox-token-management-ui/token-management/tsconfig.json index af90e6cbd0..543de1c19d 100644 --- a/knox-token-management-ui/token-management/tsconfig.json +++ b/knox-token-management-ui/token-management/tsconfig.json @@ -4,10 +4,6 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "lib": [ - "es2017", - "dom" - ], "module": "ES2022", "moduleResolution": "bundler", "outDir": "../dist/out-tsc", From 5ca9a9f8d0b122adac54890547c8120c2f90632a Mon Sep 17 00:00:00 2001 From: thanicz Date: Tue, 16 Dec 2025 08:57:03 +0100 Subject: [PATCH 8/9] KNOX-3224: Upgrade Homepage UI to angular v21 --- knox-homepage-ui/eslint.config.js | 2 +- .../apiservice-dialog.component.html | 47 ++-- .../apiservice-dialog.component.ts | 4 +- .../general.proxy.information.component.html | 182 +++++++------ .../general.proxy.information.component.ts | 4 +- .../session.information.component.html | 28 +- .../session.information.component.ts | 4 +- .../topology.information.component.html | 252 ++++++++++-------- .../topology.information.component.ts | 4 +- .../uiservice-dialog.component.html | 98 +++---- .../uiservice-dialog.component.ts | 4 +- knox-homepage-ui/home/main.ts | 4 +- knox-homepage-ui/home/tsconfig.json | 4 - knox-homepage-ui/package.json | 40 +-- knox-homepage-ui/tsconfig.json | 14 - 15 files changed, 372 insertions(+), 319 deletions(-) delete mode 100644 knox-homepage-ui/tsconfig.json diff --git a/knox-homepage-ui/eslint.config.js b/knox-homepage-ui/eslint.config.js index ed79a134c4..b75383502f 100644 --- a/knox-homepage-ui/eslint.config.js +++ b/knox-homepage-ui/eslint.config.js @@ -16,7 +16,7 @@ export default [ languageOptions: { parser: tsParser, parserOptions: { - project: ["./tsconfig.json"], + project: ["home/tsconfig.json"], tsconfigRootDir: import.meta.dirname, }, globals: { diff --git a/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.html b/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.html index 5dbab765cd..e157f811c5 100644 --- a/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.html +++ b/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.html @@ -1,16 +1,16 @@

{{ data?.shortDesc }} @@ -22,7 +22,9 @@

Knox Service Name
{{ data?.serviceName }} - (v{{ data?.version }}) + @if (data?.version) { + (v{{ data?.version }}) + }

@@ -34,16 +36,16 @@

Sample(s)
- + @if (data.samples?.sample?.length > 0) {
-
-
{{ sample.description }}
-
{{ sample.value }}
-
+ @for (sample of data.samples.sample; track sample) { +
+
{{ sample.description }}
+
{{ sample.value }}
+
+ }
-
- - + } @else {

No samples found in service metadata.

@@ -53,7 +55,8 @@

-
+ } +

diff --git a/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.ts b/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.ts index 3ad82fb6e0..c0ecb1055f 100644 --- a/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.ts +++ b/knox-homepage-ui/home/app/apiservice-dialog/apiservice-dialog.component.ts @@ -20,11 +20,11 @@ import { MatButtonModule } from '@angular/material/button'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatListModule } from '@angular/material/list'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-apiservice-dialog', - imports: [MatDialogModule, MatButtonModule, MatGridListModule, MatListModule, CommonModule], + imports: [MatDialogModule, MatButtonModule, MatGridListModule, MatListModule], templateUrl: './apiservice-dialog.component.html', styleUrl: './apiservice-dialog.component.css' }) diff --git a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.html b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.html index 2f0a4e979b..fb3b097ceb 100644 --- a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.html +++ b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.html @@ -1,85 +1,107 @@
-

- remove - add - General Proxy Information -

+

+ @if (this['showGeneralProxyInformation']) { + remove + } + @if (!this['showGeneralProxyInformation']) { + add + } + General Proxy Information +

-
+@if (this['showGeneralProxyInformation']) { +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Knox Version{{ getVersion() }}
Hostname{{ getHostname() }}
TLS Public Certificate - PEM -   |   - JKS -
Admin UI URL{{ getAdminUiUrl() }}
- Admin API Details - - - {{ getAdminApiBookUrl() }} -
- Metadata API - - General Proxy Information -   |   - Topologies -
- Integration Tokens - - Token Management -   |   - Token Generation -
Web Shell{{ getWebShellUrl() }}
-
\ No newline at end of file + + + + + + @if (this['showKnoxVersion']) { + + Knox Version + {{ getVersion() }} + + } + @if (this['showKnoxHostname']) { + + Hostname + {{ getHostname() }} + + } + @if (this['showPublicCerts']) { + + TLS Public Certificate + + PEM +   |   + JKS + + + } + @if (this['showAdminUI']) { + + Admin UI URL + {{ getAdminUiUrl() }} + + } + @if (this['showAdminAPI']) { + + + Admin API Details + + + + {{ getAdminApiBookUrl() }} + + + } + @if (this['showMetadataAPI']) { + + + Metadata API + + + General Proxy Information +   |   + Topologies + + + } + @if (this.isTokenManagementEnabled() && this['showTokens']) { + + + Integration Tokens + + + Token Management +   |   + Token Generation + + + } + @if (this.isWebshellEnabled() && this['showWebShell']) { + + Web Shell + {{ getWebShellUrl() }} + + } + + +
+} \ No newline at end of file diff --git a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts index 4a5e9de7c5..9bba05fc00 100644 --- a/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts +++ b/knox-homepage-ui/home/app/generalProxyInformation/general.proxy.information.component.ts @@ -18,14 +18,14 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {HomepageService} from '../service/homepage.service'; import {GeneralProxyInformation} from '../model/general.proxy.information'; -import { CommonModule } from '@angular/common'; + import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'app-general-proxy-information', templateUrl: './general.proxy.information.component.html', providers: [HomepageService], - imports: [CommonModule, MatIconModule] + imports: [MatIconModule] }) export class GeneralProxyInformationComponent implements OnInit { diff --git a/knox-homepage-ui/home/app/sessionInformation/session.information.component.html b/knox-homepage-ui/home/app/sessionInformation/session.information.component.html index 2860a89e8f..5118f7697f 100644 --- a/knox-homepage-ui/home/app/sessionInformation/session.information.component.html +++ b/knox-homepage-ui/home/app/sessionInformation/session.information.component.html @@ -1,17 +1,19 @@
Welcome {{ getUser() }}
- +@if (logoutSupported) { + +}
diff --git a/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts b/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts index 3c148daed7..f450e8f623 100644 --- a/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts +++ b/knox-homepage-ui/home/app/sessionInformation/session.information.component.ts @@ -17,14 +17,14 @@ import {Component, OnInit} from '@angular/core'; import {HomepageService} from '../service/homepage.service'; import {SessionInformation} from '../model/session.information'; -import { CommonModule } from '@angular/common'; + import { SafeHtmlPipe } from '../util/safehtml'; @Component({ selector: 'app-session-information', templateUrl: './session.information.component.html', providers: [HomepageService], - imports: [CommonModule, SafeHtmlPipe] + imports: [SafeHtmlPipe] }) export class SessionInformationComponent implements OnInit { diff --git a/knox-homepage-ui/home/app/topologies/topology.information.component.html b/knox-homepage-ui/home/app/topologies/topology.information.component.html index 9293f22265..351f2d29dc 100644 --- a/knox-homepage-ui/home/app/topologies/topology.information.component.html +++ b/knox-homepage-ui/home/app/topologies/topology.information.component.html @@ -1,151 +1,187 @@
-

- remove - addTopologies +

+ @if (this['showTopologies']) { + remove + } + @if (!this['showTopologies']) { + add + }Topologies

-
-
- +
+ @if (this['showTopologies']) { +
+ @for (topology of topologies; track topology) {
- remove - add - {{topology.topology}} - - push_pin - settings + @if (this['showTopology_' + topology.topology]) { + remove + } + @if (!this['showTopology_' + topology.topology]) { + add + } + {{topology.topology}} + @if (topology.pinned) { + push_pin + } + @if (!topology.pinned) { + settings + }
- -
- -
UI Services
- + @if (this['showTopology_' + topology.topology]) { +
+ @if (topology.uiServices.service.length > 0) { +
UI Services
+ } - - + @for (service of topology.uiServices.service; track service) { + - -
- + @if (service.serviceUrls.length === 1) { +
+ @if (!this['enableServiceText_' + service.serviceName.toLowerCase()]) { + - - + (error)="enableServiceText('enableServiceText_' + service.serviceName.toLowerCase())" /> + + } + @if (this['enableServiceText_' + service.serviceName.toLowerCase()]) { + {{service.shortDesc}} - + + } -

{{service.shortDesc}} (v{{service.version}})

+

{{service.shortDesc}} @if (service.version) { + (v{{service.version}}) + }

-

{{service.description}}

+

{{service.description}}

-
- +
+ } -
+ @if (service.serviceUrls.length > 1) { +
+ (error)="enableServiceText('enableServiceText_' + service.serviceName.toLowerCase())" /> -

{{service.shortDesc}} ({{service.serviceUrls.length}})

+

{{service.shortDesc}} ({{service.serviceUrls.length}})

-
- - - - +
+ } +
+ } +
+ } - -
API Services
- -
- + @if (topology.apiServices.service.length > 0) { +
API Services
+ } + @if (topology.apiServicesViewVersion === 'v1') { +
- -
No API services found
-
- + @if (topology.apiServices.service.length === 0) { +
No API services found
+ } - - + @if (topology.apiServices.service.length > 0) { +
- - + + - - - + + - - -
Description -
- info - {{ service.shortDesc }} - (v{{ service.version }}) -
-
Description +
+ info + {{ service.shortDesc }} + @if (service.version) { + (v{{ service.version }}) + } +
+
URLs - - {{ url }} -
-
-
URLs + @for (url of service.serviceUrls; track url; let i = $index) { + {{ url }} + @if (service.serviceUrls.length > 1 && i < service.serviceUrls.length - 1) { +
+ } + } +
- + + } - 0) { + - -
- - - + + } +
+ } + @if (topology.apiServicesViewVersion === 'v2') { + + @for (service of topology.apiServices.service; track service) { + - + @if (!this['enableServiceText_' + service.serviceName.toLowerCase()]) { + - - + (error)="enableServiceText('enableServiceText_' + service.serviceName.toLowerCase())" /> + + } + @if (this['enableServiceText_' + service.serviceName.toLowerCase()]) { + {{service.shortDesc}} - + + } -

{{service.shortDesc}} (v{{service.version}})

+

{{service.shortDesc}} @if (service.version) { + (v{{service.version}}) + }

-

{{service.description}}

+

{{service.description}}

-
-
-
- -
-
\ No newline at end of file + + } + + } +
+ } + } +
+
+ } \ No newline at end of file diff --git a/knox-homepage-ui/home/app/topologies/topology.information.component.ts b/knox-homepage-ui/home/app/topologies/topology.information.component.ts index 4ede4b0a61..df8fa70dc7 100644 --- a/knox-homepage-ui/home/app/topologies/topology.information.component.ts +++ b/knox-homepage-ui/home/app/topologies/topology.information.component.ts @@ -24,7 +24,7 @@ import { ActivatedRoute } from '@angular/router'; import { HomepageService } from '../service/homepage.service'; import { TopologyInformation } from '../model/topology.information'; import { Service } from '../model/service'; -import { CommonModule } from '@angular/common'; + import { MatGridListModule } from '@angular/material/grid-list'; import { ApiserviceDialogComponent } from '../apiservice-dialog/apiservice-dialog.component'; import { UiserviceDialogComponent } from '../uiservice-dialog/uiservice-dialog.component'; @@ -33,7 +33,7 @@ import { UiserviceDialogComponent } from '../uiservice-dialog/uiservice-dialog.c templateUrl: './topology.information.component.html', styleUrls: ['./topology.information.component.css'], providers: [HomepageService], - imports: [CommonModule, MatGridListModule, MatTooltipModule, MatIconModule, MatTableModule, MatPaginatorModule] + imports: [MatGridListModule, MatTooltipModule, MatIconModule, MatTableModule, MatPaginatorModule] }) export class TopologyInformationsComponent implements OnInit { diff --git a/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.html b/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.html index 3600905810..6842560116 100644 --- a/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.html +++ b/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.html @@ -1,53 +1,61 @@ -

- {{ data.shortDesc }} - (v{{ data.version }}) -

+@if (data) { +

+ {{ data.shortDesc }} + @if (data.version) { + (v{{ data.version }}) + } +

+} - -

{{ data.description }}

- - - Search by hostname, port... - - - - - - - - - - - {{ data.shortDesc }} - - - -

{{ data.shortDesc }} {{ getServiceUrlHostAndPort(serviceUrl) }}

-
-
-
-
+@if (data) { + +

{{ data.description }}

+ + Search by hostname, port... + + + + @for (serviceUrl of filteredServiceUrls; track serviceUrl) { + + @if (!enableServiceText) { + + + + } + @if (enableServiceText) { + + {{ data.shortDesc }} + + } + +

{{ data.shortDesc }} {{ getServiceUrlHostAndPort(serviceUrl) }}

+
+
+ } +
+
+} - diff --git a/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.ts b/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.ts index 88042c2154..6e7d4c164e 100644 --- a/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.ts +++ b/knox-homepage-ui/home/app/uiservice-dialog/uiservice-dialog.component.ts @@ -21,11 +21,11 @@ import { MatButtonModule } from '@angular/material/button'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatGridListModule } from '@angular/material/grid-list'; -import { CommonModule } from '@angular/common'; + @Component({ selector: 'app-uiservice-dialog', - imports: [MatDialogModule, MatButtonModule, MatFormFieldModule, MatInputModule, MatGridListModule, CommonModule], + imports: [MatDialogModule, MatButtonModule, MatFormFieldModule, MatInputModule, MatGridListModule], templateUrl: './uiservice-dialog.component.html', styleUrl: './uiservice-dialog.component.css' }) diff --git a/knox-homepage-ui/home/main.ts b/knox-homepage-ui/home/main.ts index 170a265041..dd64815e13 100644 --- a/knox-homepage-ui/home/main.ts +++ b/knox-homepage-ui/home/main.ts @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { enableProdMode, importProvidersFrom } from '@angular/core'; +import { enableProdMode, importProvidersFrom, provideZoneChangeDetection } from '@angular/core'; import { environment } from './environments/environment'; import { bootstrapApplication } from '@angular/platform-browser'; import { provideRouter } from '@angular/router'; @@ -40,7 +40,7 @@ const bootstrapComponents = [ bootstrapComponents.forEach(component => { bootstrapApplication(component, { providers: [ - importProvidersFrom(MatGridListModule), + provideZoneChangeDetection(),importProvidersFrom(MatGridListModule), provideHttpClient(), provideRouter([]), { diff --git a/knox-homepage-ui/home/tsconfig.json b/knox-homepage-ui/home/tsconfig.json index 4e53c0b8fc..024e84180e 100644 --- a/knox-homepage-ui/home/tsconfig.json +++ b/knox-homepage-ui/home/tsconfig.json @@ -4,10 +4,6 @@ "declaration": false, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "lib": [ - "es2017", - "dom" - ], "module": "ES2022", "moduleResolution": "bundler", "outDir": "../dist/out-tsc", diff --git a/knox-homepage-ui/package.json b/knox-homepage-ui/package.json index 834b91c652..37508c3cbc 100644 --- a/knox-homepage-ui/package.json +++ b/knox-homepage-ui/package.json @@ -11,36 +11,36 @@ }, "private": true, "dependencies": { - "@angular/animations": "^20.3.2", - "@angular/cdk": "^20.2.5", - "@angular/common": "^20.3.2", - "@angular/compiler": "^20.3.2", - "@angular/core": "^20.3.2", - "@angular/forms": "^20.3.2", - "@angular/material": "^20.2.5", - "@angular/platform-browser": "^20.3.2", - "@angular/platform-browser-dynamic": "^20.3.2", - "@angular/router": "^20.3.2", + "@angular/animations": "^21.0.5", + "@angular/cdk": "^21.0.3", + "@angular/common": "^21.0.5", + "@angular/compiler": "^21.0.5", + "@angular/core": "^21.0.5", + "@angular/forms": "^21.0.5", + "@angular/material": "^21.0.3", + "@angular/platform-browser": "^21.0.5", + "@angular/platform-browser-dynamic": "^21.0.5", + "@angular/router": "^21.0.5", "bootstrap": "^5.3.8", "core-js": "^3.46.0", "sweetalert2": "^11.26.3", "zone.js": "^0.15.1" }, "devDependencies": { - "@angular-eslint/builder": "20.3.0", - "@angular-eslint/eslint-plugin": "20.3.0", - "@angular-eslint/eslint-plugin-template": "20.3.0", - "@angular-eslint/schematics": "20.3.0", - "@angular-eslint/template-parser": "20.3.0", - "@angular/build": "^20.3.3", - "@angular/cli": "^20.3.3", - "@angular/compiler-cli": "^20.3.2", - "@angular/language-service": "^20.3.2", + "@angular-eslint/builder": "21.1.0", + "@angular-eslint/eslint-plugin": "21.1.0", + "@angular-eslint/eslint-plugin-template": "21.1.0", + "@angular-eslint/schematics": "21.1.0", + "@angular-eslint/template-parser": "21.1.0", + "@angular/build": "^21.0.3", + "@angular/cli": "^21.0.3", + "@angular/compiler-cli": "^21.0.5", + "@angular/language-service": "^21.0.5", "@eslint/js": "^9.39.0", "@types/node": "^24.5.2", "eslint": "^9.39.0", "ts-node": "~10.9.0", - "typescript": "~5.8.3", + "typescript": "~5.9.3", "typescript-eslint": "^8.46.2" } } diff --git a/knox-homepage-ui/tsconfig.json b/knox-homepage-ui/tsconfig.json deleted file mode 100644 index c76b8b0119..0000000000 --- a/knox-homepage-ui/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "target": "es2020", - "module": "esnext", - "moduleResolution": "node", - "lib": ["es2020", "dom"], - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["home/**/*.ts", "home/**/*.d.ts"], - "exclude": ["node_modules", "dist"] -} From 94eeed443e154a4202543f852158af60319644b8 Mon Sep 17 00:00:00 2001 From: thanicz Date: Thu, 18 Dec 2025 16:44:59 +0100 Subject: [PATCH 9/9] KNOX-3224: On Token Management UI fixed a race condition that caused tokens to NOT load on page init. --- .../tokenmanagement/token.management.component.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts index ce870c60f5..b1f4012fd9 100644 --- a/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts +++ b/knox-token-management-ui/token-management/app/tokenmanagement/token.management.component.ts @@ -126,15 +126,15 @@ export class TokenManagementComponent implements OnInit { if (!tokenHashKeyPresent) { this.showMissingKnoxTokenHashKeyPopup(); } + + this.tokenManagementService.getSessionInformation() + .then(sessionInformation => { + this.canSeeAllTokens = sessionInformation.canSeeAllTokens; + this.currentKnoxSsoCookieTokenId = sessionInformation.currentKnoxSsoCookieTokenId; + this.setUserName(sessionInformation.user); + }); } ); - - this.tokenManagementService.getSessionInformation() - .then(sessionInformation => { - this.canSeeAllTokens = sessionInformation.canSeeAllTokens; - this.currentKnoxSsoCookieTokenId = sessionInformation.currentKnoxSsoCookieTokenId; - this.setUserName(sessionInformation.user); - }); } isTokenHashKeyPresent(): boolean {