Skip to content

Commit b375169

Browse files
authored
Merge pull request #62 from rubberduck-vba/webhook
Online indenter tweaks
2 parents 3e70aff + 961e736 commit b375169

File tree

2 files changed

+174
-31
lines changed

2 files changed

+174
-31
lines changed

rubberduckvba.client/src/app/routes/indenter/indenter.component.html

+24-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
<section *ngIf="model" class="row text-center my-3">
32
<div>
43
<h1>Online Indenter</h1>
@@ -14,7 +13,7 @@ <h1>Online Indenter</h1>
1413
</section>
1514

1615
<section *ngIf="model" class="row my-3">
17-
<div class="col-lg-6 accordion">
16+
<div class="col-lg-6 my-1 accordion">
1817

1918
<!-- Indent Options -->
2019
<div class="card my-2">
@@ -411,24 +410,24 @@ <h4 class="card-title">Looking for a programmatic approach?</h4>
411410
<div class="card-body">
412411
Try the API:
413412
<ol>
414-
<li>Request (GET) <code>api.rubberduckvba.com/indenter/defaults</code> to get a JSON object for the model (or copy it from below);</li>
413+
<li>Request (GET) <code>{{apiBaseUrl}}indenter/defaults</code> to get a JSON object for the model (or copy it from below);</li>
415414
<li>Provide the code to be indented in the 'Code' property; use <code>\n</code> for newline characters;</li>
416-
<li>Post (POST) the JSON object to <code>api.rubberduckvba.com/indenter/indent</code> to get the indented code back as an array of strings.</li>
415+
<li>Post (POST) the JSON object to <code>{{apiBaseUrl}}indenter/indent</code> to get the indented code back as an array of strings.</li>
417416
</ol>
418417
<textarea id="template-json" class="code-area form-control font-monospace" rows="15" readonly [innerHTML]="asJson"></textarea>
419418
</div>
420419

421420
<div class="card-footer">
422-
<button id="copy-template" class="btn btn-secondary mx-1" type="button">
423-
<span><i class="fa fa-clipboard"></i>&nbsp;Copy</span>
421+
<button id="copy-template" class="btn mx-1" [ngClass]="wasTemplateCopied ? 'btn-success' : 'btn-secondary'" type="button" (click)="copyTemplate()">
422+
<span><fa-icon [icon]="wasTemplateCopied ? 'check' : 'clipboard'"></fa-icon>&nbsp;{{wasTemplateCopied ? 'Copied!' : 'Copy'}}</span>
424423
</button>
425424
</div>
426425
</div>
427426
</div>
428427

429428
</div>
430429

431-
<div class="col-lg-6">
430+
<div class="col-lg-6 my-1">
432431
<div class="card">
433432
<div class="card-header">
434433
<h4>Try it right here!</h4>
@@ -444,20 +443,30 @@ <h4>Try it right here!</h4>
444443
<span id="indent-button-text">Indent</span>
445444
</button>
446445
<button id="copy-code" class="btn mx-1" [ngClass]="wasCopied ? 'btn-success' : 'btn-secondary'" type="button" [disabled]="model.code.length == 0" (click)="copy()">
447-
<span><fa-icon [icon]="'clipboard'"></fa-icon>&nbsp;{{wasCopied ? 'Copied!' : 'Copy'}}</span>
446+
<span><fa-icon [icon]="wasCopied ? 'check' : 'clipboard'"></fa-icon>&nbsp;{{wasCopied ? 'Copied!' : 'Copy'}}</span>
448447
</button>
449448
</div>
450449
</div>
451450
</div>
452451

453-
<!-- <div class="row"> -->
454-
<!-- <div class="col-12"> -->
455-
<!-- <img class="ducky my-2 w-10 hover-enlarge" alt="Rubberduck logo" src="../../assets/vector-ducky-dark.svg" /> -->
456-
<!-- </div> -->
457-
<!-- </div> -->
458-
452+
<hr />
459453
<div class="row">
460-
<!-- TODO -->
454+
<div class="form-group col-6">
455+
<div role="button" class="btn btn-primary" (click)="getDefaults()"><fa-icon [icon]="'rotate-left'"></fa-icon>&nbsp;Reset to defaults</div>
456+
</div>
457+
<div class="form-group col-6">
458+
<div class="form-check">
459+
<label class="form-check-label" for="vspaceBox">
460+
<input id="localstorageBox" type="checkbox" [(ngModel)]="isLocalStorageOK" />
461+
Remember configuration
462+
</label>
463+
</div>
464+
</div>
461465
</div>
466+
</section>
462467

468+
<section class="row my-3 text-center">
469+
<div class="col-12">
470+
<img class="ducky my-2 w-10 hover-enlarge" alt="Rubberduck logo" src="../../assets/vector-ducky-dark.svg" />
471+
</div>
463472
</section>
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,165 @@
11
import { Component, OnInit } from "@angular/core";
22
import { FaIconLibrary } from "@fortawesome/angular-fontawesome";
33
import { fas } from "@fortawesome/free-solid-svg-icons";
4-
import { IndenterViewModel } from "../../model/indenter.model";
4+
import { IndenterViewModel, IndenterViewModelClass } from "../../model/indenter.model";
55
import { ApiClientService } from "../../services/api-client.service";
6+
import { environment } from "../../../environments/environment";
7+
8+
export interface IndenterOptionGroups {
9+
isExpanded: boolean;
10+
isIndentOptionsExpanded: boolean;
11+
isOutdentOptionsExpanded: boolean;
12+
isAlignmentOptionsExpanded: boolean;
13+
isCommentOptionsExpanded: boolean;
14+
isVerticalOptionsExpanded: boolean;
15+
isApiAboutBoxExpanded: boolean;
16+
}
617

718
@Component({
819
selector: 'app-indenter',
920
templateUrl: './indenter.component.html',
1021
})
11-
export class IndenterComponent implements OnInit {
22+
export class IndenterComponent implements OnInit, IndenterOptionGroups {
1223
private _model!: IndenterViewModel;
1324
public wasCopied: boolean = false;
25+
public wasTemplateCopied: boolean = false;
1426

1527

1628
constructor(fa: FaIconLibrary, private service: ApiClientService) {
1729
fa.addIconPacks(fas);
1830
}
1931

2032
ngOnInit(): void {
33+
const localModel = localStorage.getItem('indenter.model');
34+
if (localModel) {
35+
this.model = <IndenterViewModel>JSON.parse(localModel);
36+
}
37+
38+
const localOptionGroups = localStorage.getItem('indenter.options');
39+
if (localOptionGroups) {
40+
const optionGroups = <IndenterOptionGroups>JSON.parse(localOptionGroups);
41+
this.isExpanded = optionGroups.isExpanded;
42+
this.isIndentOptionsExpanded = optionGroups.isIndentOptionsExpanded;
43+
this.isOutdentOptionsExpanded = optionGroups.isOutdentOptionsExpanded;
44+
this.isAlignmentOptionsExpanded = optionGroups.isAlignmentOptionsExpanded;
45+
this.isCommentOptionsExpanded = optionGroups.isCommentOptionsExpanded;
46+
this.isVerticalOptionsExpanded = optionGroups.isVerticalOptionsExpanded;
47+
this.isApiAboutBoxExpanded = optionGroups.isApiAboutBoxExpanded;
48+
}
49+
50+
this.isLocalStorageOK = localModel != null || localOptionGroups != null;
51+
if (!this.isLocalStorageOK) {
52+
this.getDefaults();
53+
}
54+
}
55+
56+
public getDefaults(): void {
2157
this.service.getIndenterDefaults().subscribe(model => {
22-
this._model = model;
58+
this.model = model;
2359
});
2460
}
2561

26-
public isExpanded: boolean = false;
27-
public isIndentOptionsExpanded: boolean = true;
28-
public isOutdentOptionsExpanded: boolean = false;
29-
public isAlignmentOptionsExpanded: boolean = false;
30-
public isCommentOptionsExpanded: boolean = false;
31-
public isVerticalOptionsExpanded: boolean = false;
32-
public isApiAboutBoxExpanded: boolean = true;
62+
private _isExpanded: boolean = false;
63+
private _isIndentOptionsExpanded: boolean = true;
64+
private _isOutdentOptionsExpanded: boolean = false;
65+
private _isAlignmentOptionsExpanded: boolean = false;
66+
private _isCommentOptionsExpanded: boolean = false;
67+
private _isVerticalOptionsExpanded: boolean = false;
68+
private _isApiAboutBoxExpanded: boolean = false;
3369

3470
public isIndenterBusy: boolean = false;
71+
public isLocalStorageOK: boolean = false;
3572

3673
public get model(): IndenterViewModel {
3774
return this._model;
3875
}
3976

77+
private set model(value: IndenterViewModel) {
78+
this._model = value;
79+
this.invalidateClipboard();
80+
if (this.isLocalStorageOK) {
81+
localStorage.setItem('indenter.model', JSON.stringify(this.model))
82+
};
83+
}
84+
4085
public get asJson(): string {
41-
return JSON.stringify(this._model);
86+
const copy = new IndenterViewModelClass(this._model);
87+
copy.indentedCode = '';
88+
return JSON.stringify(copy);
89+
}
90+
91+
public get isExpanded(): boolean {
92+
return this._isExpanded;
93+
}
94+
public set isExpanded(value: boolean) {
95+
this._isExpanded = value;
96+
this.saveOptions();
97+
}
98+
public get isIndentOptionsExpanded(): boolean {
99+
return this._isIndentOptionsExpanded;
100+
}
101+
102+
public set isIndentOptionsExpanded(value: boolean) {
103+
this._isIndentOptionsExpanded = value;
104+
this.saveOptions();
105+
}
106+
public get isCommentOptionsExpanded(): boolean {
107+
return this._isCommentOptionsExpanded;
108+
}
109+
public set isCommentOptionsExpanded(value: boolean) {
110+
this._isCommentOptionsExpanded = value;
111+
this.saveOptions();
112+
}
113+
public get isVerticalOptionsExpanded(): boolean {
114+
return this._isVerticalOptionsExpanded;
115+
}
116+
public set isVerticalOptionsExpanded(value: boolean) {
117+
this._isVerticalOptionsExpanded = value;
118+
this.saveOptions();
119+
}
120+
121+
public get isApiAboutBoxExpanded(): boolean {
122+
return this._isApiAboutBoxExpanded;
123+
}
124+
public set isApiAboutBoxExpanded(value: boolean) {
125+
this._isApiAboutBoxExpanded = value;
126+
this.saveOptions();
127+
}
128+
129+
public get isOutdentOptionsExpanded(): boolean {
130+
return this._isOutdentOptionsExpanded;
131+
}
132+
public set isOutdentOptionsExpanded(value: boolean) {
133+
this._isOutdentOptionsExpanded = value;
134+
this.saveOptions();
135+
}
136+
public get isAlignmentOptionsExpanded(): boolean {
137+
return this._isAlignmentOptionsExpanded;
138+
}
139+
public set isAlignmentOptionsExpanded(value: boolean) {
140+
this._isAlignmentOptionsExpanded = value;
141+
this.saveOptions();
142+
}
143+
144+
private get asOptionGroups(): IndenterOptionGroups {
145+
return {
146+
isExpanded: this.isExpanded,
147+
isIndentOptionsExpanded: this.isIndentOptionsExpanded,
148+
isAlignmentOptionsExpanded: this.isAlignmentOptionsExpanded,
149+
isApiAboutBoxExpanded: this.isApiAboutBoxExpanded,
150+
isCommentOptionsExpanded: this.isCommentOptionsExpanded,
151+
isOutdentOptionsExpanded: this.isOutdentOptionsExpanded,
152+
isVerticalOptionsExpanded: this.isVerticalOptionsExpanded
153+
};
154+
}
155+
156+
private saveModel(): void {
157+
if (this.isLocalStorageOK) {
158+
localStorage.setItem('indenter.model', JSON.stringify(this.model));
159+
}
160+
}
161+
private saveOptions(): void {
162+
localStorage.setItem('indenter.options', JSON.stringify(this.asOptionGroups));
42163
}
43164

44165
public indent(): void {
@@ -47,19 +168,32 @@ export class IndenterComponent implements OnInit {
47168
this.model.indentedCode = vm.indentedCode;
48169
this.model.code = vm.indentedCode;
49170
this.isIndenterBusy = false;
50-
});
51-
}
52171

53-
public clear(): void {
54-
this.model.code = '';
172+
this.invalidateClipboard();
173+
this.saveModel();
174+
this.saveOptions();
175+
});
55176
}
56177

57178
public copy(): void {
58179
navigator.clipboard.writeText(this.model.code).then(e => this.wasCopied = true);
59180
}
181+
public copyTemplate(): void {
182+
navigator.clipboard.writeText(this.asJson).then(e => this.wasTemplateCopied = true);
183+
}
184+
185+
private invalidateClipboard(): void {
186+
this.wasCopied = false;
187+
this.wasTemplateCopied = false;
188+
}
189+
190+
public get apiBaseUrl(): string {
191+
return environment.apiBaseUrl.replace('https://', '');
192+
}
60193

61194
public onModelChanged(code: string): void {
62195
this.model.code = code;
63-
this.wasCopied = false;
196+
this.invalidateClipboard();
197+
this.saveModel();
64198
}
65199
}

0 commit comments

Comments
 (0)