Skip to content

Commit

Permalink
Merge branch 'master' of github.com:AlexTatiyants/pev
Browse files Browse the repository at this point in the history
  • Loading branch information
mcginleyr1 committed Jun 4, 2016
2 parents ffec797 + d7bac26 commit 8dc7986
Show file tree
Hide file tree
Showing 20 changed files with 219 additions and 69 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ You may also need to install tsd and compass:
npm install tsd -g
gem install compass
```

## Build
To build, run the build command for a specific environment. For example, the following will create a production distribution:

```
npm start build.prod
```
2 changes: 1 addition & 1 deletion app/assets/css/styles.css

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion app/assets/sass/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ body, input, a, button, textarea {
color: $text-color-light;
}

.text-warning {
color: $alert-color;
}

.hero-container {
margin: $padding-lg * 3;
font-size: $font-size-xl;
Expand Down Expand Up @@ -52,7 +56,7 @@ a {
cursor: pointer;
}

code {
code, .code {
font-family: $font-family-mono;
font-weight: 600;
}
Expand All @@ -65,6 +69,10 @@ code {
margin-top: $padding-lg;
}

.pad-bottom {
margin-bottom: $padding-lg;
}

[tooltip]:before {
width: 150px;
text-transform: none;
Expand Down
7 changes: 6 additions & 1 deletion app/assets/sass/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@

&-lg {
width: 98%;
height: 280px;
height: 210px;
margin-bottom: $padding-base;
margin-bottom: $padding-lg;
border-radius: $border-radius-base;
border: 1px solid $line-color;
padding: $padding-lg;
}
}

.error-message {
background-color: $alert-color;
padding: $padding-base;
color: #fff;
}
7 changes: 6 additions & 1 deletion app/assets/sass/_menu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ $menu-toggle-height: 45px;

.menu {
width: 190px;
height: 240px;
height: 260px;
position: absolute;
font-size: $font-size-sm;
top: $menu-offset - 5;
Expand Down Expand Up @@ -53,4 +53,9 @@ $menu-toggle-height: 45px;
visibility: hidden;
}
}

.button-group {
display: flex;
margin-bottom: $padding-base;
}
}
10 changes: 7 additions & 3 deletions app/assets/sass/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
left: 0;
z-index: 1040;
background-color: #000;
opacity: 0.7;
opacity: 0.1;
}

.modal {
Expand All @@ -16,11 +16,12 @@
bottom: 0;
left: 0;
z-index: 1050;
transition: all 1s;

.modal-dialog {
position: relative;
transform: translate(0);
margin: 30px auto;
margin: 100px auto;
width: 500px;
opacity: 1;

Expand All @@ -33,11 +34,14 @@
border: 1px solid rgba(0,0,0,.2);
border-radius: 6px;
outline: 0;
box-shadow: 0 3px 9px rgba(0,0,0,.5);
box-shadow: 0 2px 2px rgba(0,0,0,.5);
display: block;

.modal-body {
padding: $padding-sm;
margin-bottom: $padding-xl;
text-align: left;
line-height: 1.5;
}

.modal-footer {
Expand Down
19 changes: 19 additions & 0 deletions app/assets/sass/_plan-node.scss
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,27 @@

.expanded {
width: 400px !important;
overflow: visible !important;
padding: $padding-base $padding-lg !important;
.tags span {
margin-right: $padding-sm !important;
}
}

.compact {
width: 140px;
}

.dot {
width: 30px;
overflow: hidden;
padding: $padding-sm;

.tags span {
margin-right: 1px;
}

.node-bar-container {
margin-top: $padding-sm;
}
}
7 changes: 1 addition & 6 deletions app/assets/sass/_plan.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ $connector-line: 2px solid darken($line-color, 10%);

.plan {
padding-bottom: $padding-lg * 3;
overflow: auto;
height: 100%;
min-height: 550px;
margin-left: 50px;
margin-right: 50px;
width: 100%;
margin-left: 100px;

ul {
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion app/assets/styles.css

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions app/components/plan-list/plan-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@
Welcome to PEV! Please <a [routerLink]="['/PlanNew']">submit</a> a plan for visualization
</div>

<table class="table">
<table class="table pad-bottom">
<tr *ngFor="#plan of plans">
<!-- this is a hack that should be converted to a proper dialog once that is available in angular 2-->
<div *ngIf="openDialog">
<div class="modal-backdrop"></div>
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">You're about to delete plan "{{planToDelete.name}}". Are you sure?</div>
<div class="modal-footer">
<button class="btn btn-primary" (click)="deletePlan()">Yes</button>
<button class="btn btn-default" (click)="cancelDelete()">No</button>
</div>
</div>
</div>
</div>
</div>

<td width="30%"><a [routerLink]="['/PlanView', {id: plan.id}]">{{plan.name}}</a></td>
<td>created on {{plan.createdOn | momentDate }}</td>
<td class="align-right"><button class="btn btn-danger" (click)="requestDelete()">
<td class="align-right"><button class="btn btn-danger" (click)="requestDelete(plan)">
<i class="fa fa-trash"></i>delete</button>
<!-- this is a hack that should be converted to a proper dialog once that is available in angular 2-->
<div *ngIf="openDialog">
<div class="modal-backdrop"></div>

<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">You're about to delete this plan. Are you sure?</div>
<div class="modal-footer">
<button class="btn btn-primary" (click)="deletePlan(plan)">Yes</button>
<button class="btn btn-default" (click)="cancelDelete()">No</button>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
Expand Down
7 changes: 5 additions & 2 deletions app/components/plan-list/plan-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ export class PlanList {
newPlanContent: any;
newPlanId: string;
openDialog: boolean = false;
planToDelete: IPlan;

constructor(private _planService: PlanService) { }

ngOnInit() {
this.plans = this._planService.getPlans();
}

requestDelete() {
requestDelete(plan) {
this.openDialog = true;
this.planToDelete = plan;
}

deletePlan(plan) {
this.openDialog = false;
this._planService.deletePlan(plan);
console.log(this.planToDelete);
this._planService.deletePlan(this.planToDelete);
this.plans = this._planService.getPlans();
}

Expand Down
12 changes: 8 additions & 4 deletions app/components/plan-new/plan-new.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<div class="page">
<span class="text-muted">For best results, use EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)</span>
<button class="btn btn-link" (click)="prefill()">create a sample plan</button>
<button class="pull-right btn btn-link" (click)="prefill()">create a sample plan</button>

<span class="text-muted">For best results, use <code>EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)</code><br>
Psql users can export the plan to a file using <code>psql -qAt -f explain.sql > analyze.json</code></span>
<p class="pad-top">DISCLAIMER: Pev stores your plans locally (localStorage) and will not send them anywhere.</p>
<div>
<input placeholder="name (optional)" class="input-box input-box-main" type="text" [(ngModel)]="newPlanName">
<button class="btn btn-default btn-lg pad-top pull-right" (click)="submitPlan()">submit</button>
</div>

<textarea placeholder="paste execution plan" class="input-box input-box-lg" [(ngModel)]="newPlanContent"></textarea>
<textarea placeholder="paste corresponding SQL query" class="input-box input-box-lg" [(ngModel)]="newPlanQuery"></textarea>
<p *ngIf="validationMessage" class="error-message">{{validationMessage}}</p>
<textarea placeholder="paste execution plan" class="input-box input-box-lg code" [(ngModel)]="newPlanContent"></textarea>
<textarea placeholder="paste corresponding SQL query" class="input-box input-box-lg code" [(ngModel)]="newPlanQuery"></textarea>
</div>
21 changes: 15 additions & 6 deletions app/components/plan-new/plan-new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ export class PlanNew {
newPlanContent: string;
newPlanQuery: string;
newPlan: IPlan;
validationMessage: string;

constructor( private _router: Router, private _planService: PlanService) { }
constructor(private _router: Router, private _planService: PlanService) { }

submitPlan() {
// remove psql generated header
this.newPlanContent = this.newPlanContent.replace('QUERY PLAN', '');

if (!this._planService.isJsonString(this.newPlanContent)) {
this.validationMessage = 'The string you submitted is not valid JSON'
return;
}

this.newPlan = this._planService.createPlan(this.newPlanName, this.newPlanContent, this.newPlanQuery);
this._router.navigate( ['PlanView', { id: this.newPlan.id }] );
this._router.navigate(['PlanView', { id: this.newPlan.id }]);
}

prefill() {
this.newPlanName = 'Sample plan';
this.newPlanContent = SAMPLE_JSON;
this.newPlanQuery = SAMPLE_QUERY;
}
this.newPlanName = 'Sample plan';
this.newPlanContent = SAMPLE_JSON;
this.newPlanQuery = SAMPLE_QUERY;
}
}
export var SAMPLE_JSON = `[
{
Expand Down
25 changes: 16 additions & 9 deletions app/components/plan-node/plan-node.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
<div class="plan-node" [class.expanded]="showDetails" [class.compact]="viewOptions.showCompactView">
<div class="plan-node"
[class.expanded]="showDetails"
[class.compact]="viewOptions.viewMode === viewModes.COMPACT"
[class.dot]="viewOptions.viewMode === viewModes.DOT">

<header (click)="showDetails = !showDetails" tooltip="view node details">
<h4>{{node[_planService.NODE_TYPE_PROP] | uppercase}}
</h4>
<span *ngIf="!viewOptions.showCompactView">
<h4>{{getNodeName()}}</h4>
<span *ngIf="viewOptions.viewMode === viewModes.FULL || showDetails">
<span class="node-duration">{{node[_planService.ACTUAL_DURATION_PROP] | duration}}<span class="text-muted">{{node[_planService.ACTUAL_DURATION_PROP] | durationUnit}}
| </span><strong>{{executionTimePercent}}</strong>
<span class="text-muted">%</span>
</span>
</span>
</header>

<button *ngIf="plan.query && !viewOptions.showCompactView" tooltip="view corresponding query"
<button *ngIf="plan.query && viewOptions.viewMode === viewModes.FULL" tooltip="view corresponding query"
class="btn btn-sm btn-default btn-slim pull-right" (click)="showQuery = !showQuery">
<i class="fa fa-database"></i>
</button>

<div *ngIf="!viewOptions.showCompactView">
<div *ngIf="viewOptions.viewMode === viewModes.FULL">
<div class="relation-name" *ngIf="node[_planService.RELATION_NAME_PROP]">
<span class="text-muted">on </span>
<span *ngIf="node[_planService.SCHEMA_PROP]">{{node[_planService.SCHEMA_PROP]}}.</span>{{node[_planService.RELATION_NAME_PROP]}}
Expand All @@ -32,21 +35,25 @@ <h4>{{node[_planService.NODE_TYPE_PROP] | uppercase}}
using</span> {{node[_planService.INDEX_NAME_PROP]}}</div>
<div class="relation-name" *ngIf="node[_planService.HASH_CONDITION_PROP]"><span class="text-muted">
on</span> {{node[_planService.HASH_CONDITION_PROP]}}</div>
<div class="relation-name" *ngIf="node[_planService.CTE_NAME_PROP]">
<span class="text-muted">CTE</span> {{node[_planService.CTE_NAME_PROP]}}
</div>
</div>

<div class="tags" *ngIf="viewOptions.showTags && tags.length > 0">
<span *ngFor="#tag of tags">{{tag}}</span>
<span *ngFor="#tag of tags">{{getTagName(tag)}}</span>
</div>

<div *ngIf="currentHighlightType !== highlightTypes.NONE">
<div class="node-bar-container">
<span class="node-bar" [style.width]="barWidth+'px'" [style.backgroundColor]="backgroundColor"></span>
</div>
<span class="node-bar-label">
<span class="node-bar-label" *ngIf="shouldShowNodeBarLabel()">
<span class="text-muted">{{viewOptions.highlightType}}:</span> {{highlightValue | number:'.0-2'}}
</span>
</div>

<div class="planner-estimate" *ngIf="viewOptions.showPlannerEstimate">
<div class="planner-estimate" *ngIf="shouldShowPlannerEstimate()">
<span *ngIf="plannerRowEstimateDirection === estimateDirections.over"><strong>over</strong> estimated rows</span>
<span *ngIf="plannerRowEstimateDirection === estimateDirections.under"><strong>under</strong> estimated rows</span>
<span> by <strong>{{plannerRowEstimateValue | number}}</strong>x</span>
Expand Down
Loading

0 comments on commit 8dc7986

Please sign in to comment.