diff --git a/angular.json b/angular.json index d565b6d7..d8a5e1da 100644 --- a/angular.json +++ b/angular.json @@ -131,7 +131,8 @@ } }, "cli": { - "schematicCollections": ["@angular-eslint/schematics"] + "schematicCollections": ["@angular-eslint/schematics"], + "analytics": false }, "schematics": { "@angular-eslint/schematics:application": { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 727c5801..fa9f7fc9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -43,6 +43,10 @@ import { GuacTerminalComponent } from './scenario/guacTerminal.component'; import { IdeWindowComponent } from './scenario/ideWindow.component'; import { ContextService } from './services/context.service'; import { TypedSettingsService } from './services/typedSettings.service'; +import { VerificationService } from './services/verification.service'; +import { TaskProgressComponent } from './scenario/task-progress/task-progress.component'; +import { TaskModalComponent } from './scenario/task-modal/task-modal.component'; +import { SingleTaskVerificationMarkdownComponent } from './hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component'; import '@cds/core/icon/register.js'; import { ClarityIcons, @@ -69,6 +73,7 @@ import { windowCloseIcon, arrowIcon, hostIcon, + syncIcon, eyeIcon, eyeHideIcon, clockIcon, @@ -99,6 +104,7 @@ ClarityIcons.addIcons( windowCloseIcon, arrowIcon, hostIcon, + syncIcon, eyeIcon, eyeHideIcon, clockIcon, @@ -114,10 +120,21 @@ const appInitializerFn = (appConfig: AppConfigService) => { }; }; +export const jwtAllowedDomains = [ + environment.server.replace(/(^\w+:|^)\/\//, ''), +]; + +export function addJwtAllowedDomain(domain: string) { + const newDomain = domain.replace(/(^\w+:|^)\/\//, ''); + if (!jwtAllowedDomains.includes(newDomain)) { + jwtAllowedDomains.push(newDomain); + } +} + export function jwtOptionsFactory() { return { tokenGetter: tokenGetter, - allowedDomains: [environment.server.replace(/(^\w+:|^)\/\//, '')], + allowedDomains: jwtAllowedDomains, disallowedRoutes: [ environment.server.replace(/(^\w+:|^)\/\//, '') + '/auth/authenticate', ], @@ -147,6 +164,9 @@ export function jwtOptionsFactory() { HfMarkdownComponent, PrintableComponent, IdeWindowComponent, + TaskProgressComponent, + TaskModalComponent, + SingleTaskVerificationMarkdownComponent, ], imports: [ BrowserModule, @@ -167,6 +187,7 @@ export function jwtOptionsFactory() { }, globalParsers: [ { component: CtrComponent }, + { component: SingleTaskVerificationMarkdownComponent }, { component: QuizComponent }, ], }), @@ -193,6 +214,7 @@ export function jwtOptionsFactory() { ProgressService, ContextService, TypedSettingsService, + VerificationService, { provide: APP_INITIALIZER, useFactory: appInitializerFn, diff --git a/src/app/hf-markdown/hf-markdown.component.ts b/src/app/hf-markdown/hf-markdown.component.ts index 35d61faa..6660c365 100644 --- a/src/app/hf-markdown/hf-markdown.component.ts +++ b/src/app/hf-markdown/hf-markdown.component.ts @@ -148,6 +148,14 @@ ${token}`; >${this.renderHighlightedCode(code, language, filename)}`; }, + verifyTask(code: string, target: string, taskName: string) { + return ``; + }, + mermaid(code: string) { const n = 5; const containerId = `mermaid-${this.uniqueString(n)}`; diff --git a/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.html b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.html new file mode 100644 index 00000000..0176dd62 --- /dev/null +++ b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.html @@ -0,0 +1,130 @@ +
+ +
+ + Verify: {{ taskName }} on {{ target }} +
+
+ +
+ +
+
+ +
+
+
+ + +
diff --git a/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.scss b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.scss new file mode 100644 index 00000000..ca47ddec --- /dev/null +++ b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.scss @@ -0,0 +1,75 @@ +.task-verification-box { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-left: 3px solid; + border-radius: 5px; +} + +.down { + transform: rotate(180deg); +} + +.sideways { + transform: rotate(90deg); +} + +.flex-container { + display: flex !important; + flex-direction: row; + justify-content: space-between; +} + +.label-container { + display: flex !important; + flex-direction: row; + justify-content: space-between; + width: fit-content; +} + +.label-status { + margin: auto; + margin-left: 4px; + margin-bottom: 7%; +} + +.label:hover { + cursor: default; +} + +#refreshButton:hover { + cursor: pointer !important; +} + +.list-group { + width: 100%; +} + +.greenBorder { + border-left-color: var(--clr-color-success-500, green) !important; +} + +.redBorder { + border-left-color: #f0ad4e !important; +} + +details { + border: 1px solid var(--clr-color-neutral-400, #cccccc); + border-left: 3px solid; + border-radius: 4px; + padding: 0.5em 0.5em 0; + &[open] { + padding: 0.5em; + summary { + margin-bottom: 0.5em; + } + } +} + +summary { + font-weight: bold; + margin: -0.5em -0.5em 0; + padding: 0.5em; + display: list-item; + cursor: pointer; +} diff --git a/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.ts b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.ts new file mode 100644 index 00000000..fde54f24 --- /dev/null +++ b/src/app/hf-markdown/single-task-verification-markdown/single-task-verification-markdown.component.ts @@ -0,0 +1,65 @@ +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; +import { Component, Input, OnInit } from '@angular/core'; +import { Task } from 'src/app/scenario/taskVerification.type'; +import { VerificationService } from 'src/app/services/verification.service'; + +@Component({ + selector: 'app-single-task-verification-markdown', + templateUrl: './single-task-verification-markdown.component.html', + animations: [ + trigger('rotatedState', [ + state('default', style({ transform: 'rotate(0)' })), + state('rotating', style({ transform: 'rotate(360deg)' })), + transition('default => rotating', animate('1500ms')), + ]), + ], + styleUrls: ['./single-task-verification-markdown.component.scss'], +}) +export class SingleTaskVerificationMarkdownComponent implements OnInit { + @Input() target: string; + @Input() message: string; + @Input() taskName: string; + + detailsOpen = false; + + rotationState = 'default'; + + task?: Task; + + constructor(private verificationService: VerificationService) {} + + ngOnInit(): void { + this.verificationService.currentVerifications.subscribe( + (verificationMap) => { + const temp = verificationMap.get(this.target); + this.task = temp?.tasks?.filter( + (task) => task.name == this.taskName, + )[0]; + }, + ); + } + + isOfReturnType(task: Task, returnTypes: string[]): boolean { + return returnTypes.includes(task.return_type); + } + + elementClicked() { + this.rotationState = 'rotating'; + setTimeout(() => { + this.rotationState = 'default'; + }, 1500); + this.verificationService + .verifyTask(this.target, this.taskName) + ?.subscribe(); + } + + taskUnset(): boolean { + return this.task == undefined || this.task.success == undefined; + } +} diff --git a/src/app/scenario/Scenario.ts b/src/app/scenario/Scenario.ts index 2569d43a..d491f520 100644 --- a/src/app/scenario/Scenario.ts +++ b/src/app/scenario/Scenario.ts @@ -1,3 +1,5 @@ +import { TaskVerification } from './taskVerification.type'; + export class Scenario { id: string; name: string; @@ -6,4 +8,5 @@ export class Scenario { virtualmachines: Map[]; pauseable: boolean; printable: boolean; + vm_tasks: TaskVerification[]; } diff --git a/src/app/scenario/step.component.html b/src/app/scenario/step.component.html index ab8c449c..b4aa16e6 100644 --- a/src/app/scenario/step.component.html +++ b/src/app/scenario/step.component.html @@ -8,7 +8,14 @@