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_ 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
\ 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"