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'
|
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',
|
path: 'unauthorized',
|
||||||
component: UnauthorizedComponent
|
component: UnauthorizedComponent
|
||||||
|
@ -31,13 +31,6 @@
|
|||||||
{{ 'navbar.menu.security' | translate }}
|
{{ 'navbar.menu.security' | translate }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</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="dropdown-divider"></li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" [routerLink]="['./catalog/images']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
<a class="nav-link" [routerLink]="['./catalog/images']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||||
@ -45,24 +38,12 @@
|
|||||||
{{ 'navbar.menu.images' | translate }}
|
{{ 'navbar.menu.images' | translate }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<!--<li class="nav-item">
|
<li class="dropdown-divider"></li>
|
||||||
<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="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" [routerLink]="['./account']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
<a class="nav-link" [routerLink]="['./help']" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">
|
||||||
<fa-icon [fixedWidth]="true" icon="user-cog"></fa-icon>
|
<fa-icon [fixedWidth]="true" icon="question-circle"></fa-icon>
|
||||||
{{ 'navbar.menu.account' | translate }}
|
{{ 'navbar.menu.help' | translate }}
|
||||||
</a>
|
</a>
|
||||||
</li>-->
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</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,
|
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,
|
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,
|
faCloud, faCloudUploadAlt, faEye, faFingerprint, faLink, faClipboard, faCoins, faArrowRight, faEllipsisH, faStar, faCommentAlt, faOutdent,
|
||||||
faUndo
|
faUndo, faQuestionCircle
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faDocker } from '@fortawesome/free-brands-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,
|
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,
|
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,
|
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",
|
"virtualNetworks": "Virtual Networks",
|
||||||
"firewallRules": "Firewall rules",
|
"firewallRules": "Firewall rules",
|
||||||
"security": "Security",
|
"security": "Security",
|
||||||
"account": "Account"
|
"account": "Account",
|
||||||
|
"help": "Help"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"account":
|
"account":
|
||||||
@ -61,5 +62,9 @@
|
|||||||
{
|
{
|
||||||
"title": "Security",
|
"title": "Security",
|
||||||
"subTitle": "Manage your users, roles and security policies"
|
"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