help page
This commit is contained in:
parent
e9f4934bf0
commit
a99c39c5a4
Binary file not shown.
Binary file not shown.
@ -71,6 +71,18 @@ const appRoutes: Routes = [
|
||||
icon: 'user-cog'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'help',
|
||||
loadChildren: () => import('./help/help.module').then(x => x.HelpModule),
|
||||
canActivate: [AuthGuardService],
|
||||
canLoad: [AuthGuardService],
|
||||
data:
|
||||
{
|
||||
title: 'help.title',
|
||||
subTitle: 'help.subTitle',
|
||||
icon: 'question-circle'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'unauthorized',
|
||||
component: UnauthorizedComponent
|
||||
|
@ -31,13 +31,6 @@
|
||||
{{ 'navbar.menu.security' | translate }}
|
||||
</a>
|
||||
</li>
|
||||
<!--<li class="dropdown-divider"></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" [routerLink]="['./file-manager']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<fa-icon [fixedWidth]="true" icon="folder"></fa-icon>
|
||||
{{ 'navbar.menu.fileManager' | translate }}
|
||||
</a>
|
||||
</li>-->
|
||||
<li class="dropdown-divider"></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" [routerLink]="['./catalog/images']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
@ -45,24 +38,12 @@
|
||||
{{ 'navbar.menu.images' | translate }}
|
||||
</a>
|
||||
</li>
|
||||
<!--<li class="nav-item">
|
||||
<a class="nav-link" [routerLink]="['./catalog/docker-images']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<fa-icon [fixedWidth]="true" [icon]="['fab', 'docker']"></fa-icon>
|
||||
{{ 'navbar.menu.dockerImages' | translate }}
|
||||
</a>
|
||||
</li>-->
|
||||
<!--<li class="nav-item">
|
||||
<a class="nav-link" [routerLink]="['./catalog/docker-registry']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<fa-icon [fixedWidth]="true" [icon]="['fab', 'docker']"></fa-icon>
|
||||
{{ 'navbar.menu.dockerRegistry' | translate }}
|
||||
</a>
|
||||
</li>-->
|
||||
<!--<li class="dropdown-divider"></li>
|
||||
<li class="dropdown-divider"></li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" [routerLink]="['./account']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<fa-icon [fixedWidth]="true" icon="user-cog"></fa-icon>
|
||||
{{ 'navbar.menu.account' | translate }}
|
||||
<a class="nav-link" [routerLink]="['./help']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<fa-icon [fixedWidth]="true" icon="question-circle"></fa-icon>
|
||||
{{ 'navbar.menu.help' | translate }}
|
||||
</a>
|
||||
</li>-->
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
49
app/src/app/help/help.module.ts
Normal file
49
app/src/app/help/help.module.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { SharedModule } from '../shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { WebpackTranslateLoader } from '../helpers/webpack-translate-loader.service';
|
||||
import { LangChangeEvent, TranslateCompiler, TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
|
||||
import { HelpComponent } from './help/help.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [HelpComponent],
|
||||
imports: [
|
||||
SharedModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: HelpComponent,
|
||||
data:
|
||||
{
|
||||
title: 'help.title',
|
||||
subTitle: 'help.subTitle',
|
||||
icon: 'help-circle'
|
||||
}
|
||||
}
|
||||
]),
|
||||
TranslateModule.forChild({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
//useClass: WebpackTranslateLoader
|
||||
useFactory: () => new WebpackTranslateLoader('help')
|
||||
},
|
||||
compiler: {
|
||||
provide: TranslateCompiler,
|
||||
useFactory: () => new TranslateMessageFormatCompiler()
|
||||
},
|
||||
isolate: true
|
||||
})
|
||||
]
|
||||
})
|
||||
export class HelpModule
|
||||
{
|
||||
constructor(private readonly translate: TranslateService)
|
||||
{
|
||||
translate.use(translate.store.currentLang);
|
||||
|
||||
translate.store.onLangChange.subscribe((event: LangChangeEvent) => translate.use(event.lang));
|
||||
}
|
||||
}
|
32
app/src/app/help/help/help.component.html
Normal file
32
app/src/app/help/help/help.component.html
Normal file
@ -0,0 +1,32 @@
|
||||
<div class="d-flex flex-column h-100">
|
||||
<div class="container text-center mt-1">
|
||||
|
||||
<div class="spinner-border text-center text-info text-faded" role="status" *ngIf="loadingIndicator">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overflow-auto flex-grow-1 my-3">
|
||||
<div class="container my-2">
|
||||
|
||||
<accordion [closeOthers]="true">
|
||||
<accordion-group *ngFor="let helpTopic of helpTopics" (isOpenChange)="getHelpTopicContent($event, helpTopic)">
|
||||
<div class="d-flex justify-content-between align-items-center sticky-top" accordion-heading>
|
||||
<h4 class="mb-0 text-info">{{ helpTopic.title }}</h4>
|
||||
|
||||
<fa-icon icon="angle-right" [fixedWidth]="true" [rotate]="helpTopic.expanded ? 90 : 0" class="text-info"></fa-icon>
|
||||
</div>
|
||||
|
||||
<div class="p-3">
|
||||
<div class="spinner-border text-center text-info text-faded" role="status" *ngIf="helpTopic.loading">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
|
||||
<article [innerHtml]="helpTopic.content"></article>
|
||||
</div>
|
||||
</accordion-group>
|
||||
</accordion>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
0
app/src/app/help/help/help.component.scss
Normal file
0
app/src/app/help/help/help.component.scss
Normal file
25
app/src/app/help/help/help.component.spec.ts
Normal file
25
app/src/app/help/help/help.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HelpComponent } from './help.component';
|
||||
|
||||
describe('HelpComponent', () => {
|
||||
let component: HelpComponent;
|
||||
let fixture: ComponentFixture<HelpComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HelpComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HelpComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
60
app/src/app/help/help/help.component.ts
Normal file
60
app/src/app/help/help/help.component.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { StaticHtmlService } from '../../helpers/static-html.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-help',
|
||||
templateUrl: './help.component.html',
|
||||
styleUrls: ['./help.component.scss']
|
||||
})
|
||||
export class HelpComponent implements OnInit
|
||||
{
|
||||
helpTopics = [
|
||||
{
|
||||
title: 'Completing account information',
|
||||
contentUrl: './assets/help/account-info.html'
|
||||
},
|
||||
{
|
||||
title: 'Provisioning compute instance',
|
||||
contentUrl: ''
|
||||
},
|
||||
{
|
||||
title: 'Managing instances with Triton CLI',
|
||||
contentUrl: ''
|
||||
}
|
||||
];
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
constructor(private readonly staticHtmlService: StaticHtmlService,
|
||||
private readonly domSanitizer: DomSanitizer)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
getHelpTopicContent(isOpen, helpTopic)
|
||||
{
|
||||
helpTopic.expanded = isOpen;
|
||||
|
||||
if (!isOpen || !helpTopic.contentUrl || helpTopic.content) return;
|
||||
|
||||
helpTopic.loading = true;
|
||||
|
||||
this.staticHtmlService
|
||||
.getStaticHtml(helpTopic.contentUrl, helpTopic.contentUrl.startsWith(window.location.origin))
|
||||
.subscribe(response =>
|
||||
{
|
||||
helpTopic.content = this.domSanitizer.bypassSecurityTrustHtml(response);
|
||||
helpTopic.loading = false;
|
||||
}, err =>
|
||||
{
|
||||
helpTopic.content = err.error?.message;
|
||||
helpTopic.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
ngOnInit(): void
|
||||
{
|
||||
|
||||
}
|
||||
}
|
16
app/src/app/helpers/static-html.service.spec.ts
Normal file
16
app/src/app/helpers/static-html.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StaticHtmlService } from './static-html.service';
|
||||
|
||||
describe('StaticHtmlService', () => {
|
||||
let service: StaticHtmlService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(StaticHtmlService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
30
app/src/app/helpers/static-html.service.ts
Normal file
30
app/src/app/helpers/static-html.service.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { Injectable, SecurityContext } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class StaticHtmlService
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
constructor(
|
||||
private readonly httpClient: HttpClient,
|
||||
private readonly domSanitizer: DomSanitizer,
|
||||
) { }
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
getStaticHtml(url: string, isTrusted: boolean): Observable<string>
|
||||
{
|
||||
return this.httpClient.get(url, { responseType: 'text' })
|
||||
.pipe(map(response => this.mapStaticHtml(response, isTrusted)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
private mapStaticHtml(htmlString: string, isTrusted: boolean): string
|
||||
{
|
||||
return isTrusted ? htmlString : this.domSanitizer.sanitize(SecurityContext.HTML, htmlString);
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ import
|
||||
faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner,
|
||||
faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask,
|
||||
faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent,
|
||||
faUndo
|
||||
faUndo, faQuestionCircle
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { faDocker } from '@fortawesome/free-brands-svg-icons';
|
||||
|
||||
@ -149,7 +149,7 @@ export class SharedModule
|
||||
faArrowsAlt, faTags, faEllipsisV, faHatWizard, faUserCog, faCircle, faAngleLeft, faExternalLinkAlt, faCheck, faPowerOff, faBars, faSpinner,
|
||||
faStop, faPlay, faRedo, faMicrochip, faDesktop, faCopy, faSquare, faCheckSquare, faSave, faDatabase, faClone, faSearch, faHistory, faMask,
|
||||
faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent,
|
||||
faUndo
|
||||
faUndo, faQuestionCircle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
1
app/src/assets/help/account-info.html
Normal file
1
app/src/assets/help/account-info.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>Title goes here...</h1>
|
@ -11,7 +11,8 @@
|
||||
"virtualNetworks": "Virtual Networks",
|
||||
"firewallRules": "Firewall rules",
|
||||
"security": "Security",
|
||||
"account": "Account"
|
||||
"account": "Account",
|
||||
"help": "Help"
|
||||
}
|
||||
},
|
||||
"account":
|
||||
@ -61,5 +62,9 @@
|
||||
{
|
||||
"title": "Security",
|
||||
"subTitle": "Manage your users, roles and security policies"
|
||||
},
|
||||
"help":
|
||||
{
|
||||
"title": "Help"
|
||||
}
|
||||
}
|
||||
|
7
app/src/assets/i18n/help/en.json
Normal file
7
app/src/assets/i18n/help/en.json
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
{
|
||||
"help":
|
||||
{
|
||||
"title": "Help"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user