diff --git a/.gitignore b/.gitignore index adb4979..36478d2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,17 @@ /dist /tmp /out-tsc + # Only exists if Bazel was run /bazel-out + # dependencies /node_modules + # profiling files chrome-profiler-events.json speed-measure-plugin.json + # IDEs and editors /.idea .project @@ -18,6 +22,7 @@ speed-measure-plugin.json *.launch .settings/ *.sublime-workspace + # IDE - VSCode .vscode/* !.vscode/settings.json @@ -25,6 +30,7 @@ speed-measure-plugin.json !.vscode/launch.json !.vscode/extensions.json .history/* + # misc /.sass-cache /connect.lock @@ -34,6 +40,8 @@ npm-debug.log yarn-error.log testem.log /typings +environment.local.ts + # System Files .DS_Store Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md index b6becf2..e48bc1b 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,11 @@ _Redis Patterns Console_ is an interactive (and reactive) console, written in An - _Step by Step_ Patterns panel, with integrated command execution and detection of contextual official [Redis doc](https://github.com/antirez/redis-doc); - Command-line and history of Redis Server responses; - Command list (divided by categories) and detection of contextual official [Redis doc](https://github.com/antirez/redis-doc); +- Interactive Command suggestion; - Isolated Client sessions. +![redis-patterns-console](https://acadevmy.it/redis-patterns-console.gif "Redis Patterns Console") + _Redis Patterns Console_ is inspired by [Try-Redis](https://try.redis.io/) project. ### Development server @@ -28,6 +31,7 @@ Thanks for your future contributions! - Stateless Components refactoring and improvements; - Continuous refactoring; - Blacklist Enum; [TBD] +- Increase GitHub API calls (with GitHub login) to 5000 (per token); - Everythings you notice! 🙏   diff --git a/package-lock.json b/package-lock.json index 0c78a7c..1d9fe50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3314,6 +3314,12 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true } } }, @@ -4740,7 +4746,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4761,12 +4768,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4781,17 +4790,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4908,7 +4920,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4920,6 +4933,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4934,6 +4948,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4941,12 +4956,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4965,6 +4982,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5045,7 +5063,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5057,6 +5076,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5142,7 +5162,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5178,6 +5199,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5197,6 +5219,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5240,12 +5263,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -9102,10 +9127,9 @@ } }, "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", - "dev": true + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==" }, "serve-index": { "version": "1.9.1", @@ -10143,6 +10167,12 @@ "pkg-dir": "^3.0.0" } }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/package.json b/package.json index 6c2b341..5d5512f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redis-patterns-app", - "version": "0.0.0", + "version": "1.0.0", "scripts": { "ng": "ng", "start": "ng serve", @@ -23,6 +23,7 @@ "bootstrap": "^4.3.1", "markdown": "^0.5.0", "rxjs": "~6.5.3", + "serialize-javascript": "^2.1.2", "tslib": "^1.9.0", "uuid": "^3.3.3", "zone.js": "~0.9.1" diff --git a/src/app/app.component.html b/src/app/app.component.html index 15f42b9..9ba317c 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,6 +1,6 @@
- +
@@ -37,7 +37,7 @@
- +
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2a48950..d6b0e3f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,29 +1,41 @@ -import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; +import {Component} from '@angular/core'; -import { Output } from '@app/shared/models/response.interface'; -import { Pattern } from '@app/shared/models/pattern.interface'; -import { CommandService } from '@app/core/services/command.service'; -import { PatternService } from '@app/core/services/pattern.service'; -import { RedisConnectService } from '@app/core/services/redis-connect.service'; +import {Output} from '@app/shared/models/response.interface'; +import {Pattern} from '@app/shared/models/pattern.interface'; +import { GithubDataService } from '@app/core/services/github-data.service'; +import {CommandService} from '@app/core/services/command.service'; +import {PatternService} from '@app/core/services/pattern.service'; +import {RedisConnectService} from '@app/core/services/redis-connect.service'; + +import {Observable, BehaviorSubject, merge} from 'rxjs'; +import {scan} from 'rxjs/operators'; @Component({ selector: 'tr-root', templateUrl: './app.component.html' }) export class AppComponent { - responses: Output[] = []; + + readonly responses$: Observable; + private currentResponseBs: BehaviorSubject = new BehaviorSubject(null); + selectedDoc: string; activePattern: Pattern; newCommandForInput: string; resetCommand$: Observable = this.redisConnectService.execCommandTime$; + isAuth$: Observable = this.githubDataService.isAuth; constructor( + private githubDataService: GithubDataService, public commandService: CommandService, public patternService: PatternService, private redisConnectService: RedisConnectService) { - this.redisConnectService.response$.subscribe((response: Output) => this.updateResponses(response)); - } + + /** when currentResponse$ is null reset responses$ */ + this.responses$ = merge(this.currentResponseBs.asObservable(), this.redisConnectService.response$).pipe( + scan((previous, current) => (current != null) ? [...previous, current] : [], []) + ); + } /** * Set current command as the active one @@ -57,15 +69,17 @@ export class AppComponent { */ runCommand(commandString: string) { const newCommand: Output = {valid: true, output: commandString.toUpperCase(), type: 'command'}; - this.updateResponses(newCommand); + this.currentResponseBs.next(newCommand); this.redisConnectService.send(commandString); const [first, ...second] = commandString.split(' '); this.selectActiveCommand(first); } - private updateResponses(command: Output) { - const commands = []; - Object.assign(commands, [...this.responses, command]); - this.responses = commands; + /** + * reset responses + * + */ + clearOutput(): void { + this.currentResponseBs.next(null); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 91094c6..cdd2cb0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; import { CoreModule } from './core/core.module'; import { SharedModule } from './shared/shared.module'; @@ -17,7 +18,8 @@ import { AppComponent } from '@app/app.component'; CoreModule, SharedModule, CommandModule, - PatternModule + PatternModule, + RouterModule.forRoot([]), ], bootstrap: [AppComponent] }) diff --git a/src/app/core/components/header/header.component.html b/src/app/core/components/header/header.component.html index 5526b9d..3a10626 100644 --- a/src/app/core/components/header/header.component.html +++ b/src/app/core/components/header/header.component.html @@ -1,13 +1,16 @@
-

{{title}}

+

{{title}} {{version}}

diff --git a/src/app/core/components/header/header.component.ts b/src/app/core/components/header/header.component.ts index ad48b88..9124cb4 100644 --- a/src/app/core/components/header/header.component.ts +++ b/src/app/core/components/header/header.component.ts @@ -1,4 +1,5 @@ -import { Component, ChangeDetectorRef, AfterViewInit } from '@angular/core'; +import { Component, ChangeDetectorRef, AfterViewInit, Input } from '@angular/core'; +import { environment } from '@app/../environments/environment'; @Component({ selector: 'tr-header', @@ -18,7 +19,14 @@ import { Component, ChangeDetectorRef, AfterViewInit } from '@angular/core'; ] }) export class HeaderComponent implements AfterViewInit { - title = 'Redis Patterns'; + title = 'Redis Patterns Console'; + version = environment.version; + loginUrl = environment.loginFlowStart + environment.githubAppClientId; + isLogged: boolean; + @Input('isAuth') set islogged(data: boolean) { + this.isLogged = data; + this.changeDetectorRef.detectChanges(); + } constructor(private changeDetectorRef: ChangeDetectorRef) {} diff --git a/src/app/core/interceptors/cache-interceptor.ts b/src/app/core/interceptors/cache-interceptor.ts index fdf35d0..a21073d 100644 --- a/src/app/core/interceptors/cache-interceptor.ts +++ b/src/app/core/interceptors/cache-interceptor.ts @@ -11,17 +11,18 @@ import { tap } from 'rxjs/operators'; ​ import { environment } from '@app/../environments/environment'; import { CachingService } from '@app/core/services/caching.service'; +import { GithubDataService } from '@app/core/services/github-data.service'; ​ @Injectable({ providedIn: 'root' }) export class CacheInterceptor implements HttpInterceptor { ​ - constructor(private cachingService: CachingService) { } + constructor(private cachingService: CachingService, private githubDataService: GithubDataService) { } ​ intercept(request: HttpRequest, next: HttpHandler ): Observable> { - if (environment.basicAuth && environment.basicAuth.length) { - request = request.clone({ setHeaders: { Authorization: `Basic ${btoa(environment.basicAuth)}` } }); + if (this.githubDataService.accessToken && this.githubDataService.accessToken.length) { + request = request.clone({ setHeaders: { Authorization: `token ${this.githubDataService.accessToken}` } }); } ​ if (!request.headers.has(environment.cacheableHeaderKey)) { diff --git a/src/app/core/services/config.service.ts b/src/app/core/services/config.service.ts index 2f994f2..ece821a 100644 --- a/src/app/core/services/config.service.ts +++ b/src/app/core/services/config.service.ts @@ -1,4 +1,7 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Injector } from '@angular/core'; +import { NavigationEnd, Router } from '@angular/router'; +import { filter, finalize, map, switchMap, take, tap } from 'rxjs/operators'; +import { iif, of } from 'rxjs'; import { CommandService } from '@app/core/services/command.service'; import { GithubDataService } from '@app/core/services/github-data.service'; @@ -10,12 +13,28 @@ import { PatternService } from '@app/core/services/pattern.service'; export class ConfigService { constructor( + private injector: Injector, private githubDataService: GithubDataService, private commandService: CommandService, private patternService: PatternService) { } init() { - this.commandService.setCommands(); - this.patternService.patterns$ = this.githubDataService.fetchPatterns(); + const router = this.injector.get(Router); + + router.events.pipe( + filter((event) => (event instanceof NavigationEnd && event.id <= 1)), // filter only first navigation end event + map((event: NavigationEnd) => new URLSearchParams(event.url.slice(1)).get('code')), // parse url to get the 'code' query param + switchMap((code) => iif(() => !code, of(null), // if code exists get access token else emits null value + this.githubDataService.setAccessToken(code).pipe( + tap(() => router.navigate(['/'])) + ) + )), + take(1), + finalize(() => { + this.commandService.setCommands(); + this.patternService.patterns$ = this.githubDataService.fetchPatterns(); + }) + ).subscribe(); + } } diff --git a/src/app/core/services/github-data.service.ts b/src/app/core/services/github-data.service.ts index 121b737..7f6f21a 100644 --- a/src/app/core/services/github-data.service.ts +++ b/src/app/core/services/github-data.service.ts @@ -1,23 +1,27 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable, of } from 'rxjs'; -import { catchError, map } from 'rxjs/operators'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { catchError, map, switchMap } from 'rxjs/operators'; import { environment } from '@app/../environments/environment'; import { Command } from '@app/shared/models/command.interface'; import { Pattern } from '@app/shared/models/pattern.interface'; import { CachingService } from '@app/core/services/caching.service'; -import { GithubContent } from '@app/shared/models/github-content.interface'; +import { GithubContent, ITokenResponse } from '@app/shared/models/github-content.interface'; @Injectable({ providedIn: 'root' }) export class GithubDataService { + authorized = new BehaviorSubject(false); + accessToken: string; private redisDocPath = environment.redisDocRepo.path; private patternsPath = environment.patternsRepo.path; - constructor(private http: HttpClient, private cachingService: CachingService) { } + constructor( + private http: HttpClient, + private cachingService: CachingService) { } /** * Fetch all available commands from remote git repo @@ -90,4 +94,23 @@ export class GithubDataService { private getEndpoint(repo: string, file: string): string { return environment.githubEndpoint.replace('_repo_', repo).replace('_file_', file); } + + setAccessToken(code?: string): Observable { + return this.http.get(environment.accessTokenRequestUrl + code).pipe( + switchMap((res: ITokenResponse) => { + const isToken = (res.data.access_token) ? true : false; + this.authorized.next(isToken); + this.accessToken = res.data && res.data.access_token; + return this.isAuth; + }), + catchError(() => { + this.authorized.next(false); + return this.isAuth; + }) + ); + } + + get isAuth() { + return this.authorized.asObservable(); + } } diff --git a/src/app/core/services/redis-connect.service.ts b/src/app/core/services/redis-connect.service.ts index 87fc07b..612d1cf 100644 --- a/src/app/core/services/redis-connect.service.ts +++ b/src/app/core/services/redis-connect.service.ts @@ -1,8 +1,8 @@ import * as uuid from 'uuid'; import { Injectable } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; import { webSocket } from 'rxjs/webSocket'; import { environment } from '@app/../environments/environment'; @@ -21,6 +21,11 @@ export class RedisConnectService { map((response: any): Output => { const valid = response.status === 'ok'; return { valid, type: 'response', output: response.output }; + }), + catchError(() => { + /** return connection error response to not clear the output response box */ + const valid = false; + return of({ valid, type: 'response', output: 'Connection error' }); }) ); diff --git a/src/app/features/command/command-output/command-output.component.html b/src/app/features/command/command-output/command-output.component.html index 1301173..7f100a9 100644 --- a/src/app/features/command/command-output/command-output.component.html +++ b/src/app/features/command/command-output/command-output.component.html @@ -1,4 +1,12 @@ -

Redis Responses

+

+ Redis Responses + +

+
    @@ -9,4 +17,4 @@

    Redis Responses

-
+
\ No newline at end of file diff --git a/src/app/features/command/command-output/command-output.component.scss b/src/app/features/command/command-output/command-output.component.scss index 68f9d09..84db1e9 100644 --- a/src/app/features/command/command-output/command-output.component.scss +++ b/src/app/features/command/command-output/command-output.component.scss @@ -1,12 +1,12 @@ ul { list-style: none; - padding: .5rem; + padding: 0.5rem; li { &.command { color: #736767; - font-size: .7rem; - padding-top: .6rem; + font-size: 0.7rem; + padding-top: 0.6rem; span { font-style: italic; @@ -14,7 +14,7 @@ ul { } &.response { - padding-bottom: .6rem; + padding-bottom: 0.6rem; border-bottom: 1px solid #ccc; .run-command { @@ -24,7 +24,7 @@ ul { span { display: inline-block; - padding: 0 .25rem; + padding: 0 0.25rem; margin-bottom: 0; } } @@ -41,3 +41,18 @@ ul { } } +.flex-box { + display: flex; + justify-content: space-between; + align-items: center; + + .flex-button { + background-color: transparent; + border-color: transparent; + padding: 0; + } + + button:focus { + outline: 0; + } +} diff --git a/src/app/features/command/command-output/command-output.component.ts b/src/app/features/command/command-output/command-output.component.ts index 1486ad7..d4adf0c 100644 --- a/src/app/features/command/command-output/command-output.component.ts +++ b/src/app/features/command/command-output/command-output.component.ts @@ -1,6 +1,6 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import {ChangeDetectionStrategy, Component, Input, EventEmitter, Output} from '@angular/core'; -import { Output } from '@app/shared/models/response.interface'; +import {Output as OutputItf} from '@app/shared/models/response.interface'; @Component({ selector: 'tr-command-output', @@ -9,5 +9,11 @@ import { Output } from '@app/shared/models/response.interface'; changeDetection: ChangeDetectionStrategy.OnPush }) export class CommandOutputComponent { - @Input() commandsOutput: Array = []; + @Input() commandsOutput: Array = []; + @Output() + clearEvt: EventEmitter = new EventEmitter(); + + clear(): void { + this.clearEvt.emit(); + } } diff --git a/src/app/shared/models/github-content.interface.ts b/src/app/shared/models/github-content.interface.ts index 4e8c89e..ac16916 100644 --- a/src/app/shared/models/github-content.interface.ts +++ b/src/app/shared/models/github-content.interface.ts @@ -5,3 +5,15 @@ export interface GithubContent { download_url: string; encoding: string; } + +export interface ITokenResponse { + query: { code: string }; + data: { + error?: string; + error_description?: string; + error_uri?: string; + access_token?: string; + token_type?: string; + scope?: string; + }; +} \ No newline at end of file diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 99f89f1..749f431 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,7 +1,11 @@ +import { version } from 'package.json'; + export const environment = { production: true, redisServer: '', // ADD HERE YOUR WS SERVER URL - basicAuth: '', // ADD HERE YOUR GITHUB "user:token" to prevent API rate limit + githubAppClientId: '', // ADD HERE YOUR GITHUB APP CLIENT ID + accessTokenRequestUrl: '', // ADD HERE BACKEND OAUTH IMPLEMENTATION + loginFlowStart: 'https://github.com/login/oauth/authorize?client_id=', githubEndpoint: 'https://api.github.com/repos/_repo_/contents/_file_', redisDocRepo: { path: 'antirez/redis-doc', @@ -12,5 +16,6 @@ export const environment = { path: 'acadevmy/redis-patterns-cookbook', json: 'patterns.json' }, - cacheableHeaderKey: 'cacheable-request' + cacheableHeaderKey: 'cacheable-request', + version }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index fe00646..2881b7b 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,11 +1,15 @@ // This file can be replaced during build by using the `fileReplacements` array. // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. + +import { version } from 'package.json'; ​ export const environment = { production: false, redisServer: 'ws://127.0.0.1:8080', - basicAuth: '', // ADD HERE YOUR GITHUB "user:token" to prevent API rate limit + githubAppClientId: '', + accessTokenRequestUrl: '', + loginFlowStart: 'https://github.com/login/oauth/authorize?client_id=', githubEndpoint: 'https://api.github.com/repos/_repo_/contents/_file_', redisDocRepo: { path: 'antirez/redis-doc', @@ -16,7 +20,8 @@ export const environment = { path: 'acadevmy/redis-patterns-cookbook', json: 'patterns.json' }, - cacheableHeaderKey: 'cacheable-request' + cacheableHeaderKey: 'cacheable-request', + version }; ​ /* diff --git a/src/styles/styles.scss b/src/styles/styles.scss index bca2811..8fb3772 100644 --- a/src/styles/styles.scss +++ b/src/styles/styles.scss @@ -1,12 +1,13 @@ @import "./variables"; @import "./../../node_modules/bootstrap/scss/bootstrap.scss"; -@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap'); +@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap"); -html,body{ - height:100%; - font-size: .9rem; - font-family: 'Open Sans', sans-serif; +html, +body { + height: 100%; + font-size: 0.9rem; + font-family: "Open Sans", sans-serif; } .scroll-box-container { @@ -28,7 +29,7 @@ html,body{ .col-center { background: #ebebeb; - border-color: #ccc!important; + border-color: #ccc !important; } code { @@ -39,26 +40,29 @@ code { font-size: 0.8rem; text-transform: uppercase; border-bottom: 1px solid #ccc; - padding-bottom: .5rem; + padding-bottom: 0.5rem; } +.h7, h3.h4 { color: #7a0c00; font-weight: bolder; } - +.h7 { + font-size: 1rem; +} tr-pattern-content h1 { - font-size: 1.3rem!important; + font-size: 1.3rem !important; font-weight: bold; } tr-pattern-content h2 { - font-size: 1.1rem!important; + font-size: 1.1rem !important; font-weight: bold; } tr-command-documentation h2 { - font-size: 1.1rem!important; + font-size: 1.1rem !important; font-weight: bold; } @@ -73,7 +77,6 @@ tr-pattern-content { box-shadow: 0; } - .scroll-box::-webkit-scrollbar { -webkit-appearance: none; } @@ -89,7 +92,7 @@ tr-pattern-content { .scroll-box::-webkit-scrollbar-thumb { border-radius: 8px; border: 2px solid white; /* should match background, can't be transparent */ - background-color: rgba(0, 0, 0, .5); + background-color: rgba(0, 0, 0, 0.5); } .scroll-box::-webkit-scrollbar-track { @@ -107,6 +110,10 @@ tr-pattern-content { } @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } } diff --git a/tsconfig.json b/tsconfig.json index 6e14098..6272915 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, + "resolveJsonModule": true, "target": "es2015", "typeRoots": [ "node_modules/@types"