Skip to content

Commit

Permalink
feat: otter training - components (#2173)
Browse files Browse the repository at this point in the history
## Proposed change

Creation of components that will be used in the Otter training (such as
a code editor, etc)

## Related issues

- 🐛 Fixes #(issue)
- 🚀 Feature #(issue)

<!-- Please make sure to follow the contributing guidelines on
https://github.com/amadeus-digital/Otter/blob/main/CONTRIBUTING.md -->
  • Loading branch information
sdo-1A authored Oct 2, 2024
2 parents ce1fa8c + 63b5bc1 commit 9a62adb
Show file tree
Hide file tree
Showing 40 changed files with 866 additions and 88 deletions.
1 change: 1 addition & 0 deletions apps/showcase/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
dist-e2e-playwright
playwright-reports
test-results
training-assets
2 changes: 1 addition & 1 deletion apps/showcase/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"test:playwright:scenario": "USE_MOCKS=true playwright test --config=e2e-playwright/playwright-config.ts",
"test:playwright:sanity": "USE_MOCKS=true playwright test --config=e2e-playwright/playwright-config.sanity.ts",
"update-screenshots": "node scripts/update-screenshots/index.cjs",
"copy-training-assets": "node scripts/copy-training-assets/index.cjs",
"postbuild:patch": "yarn patch:package",
"patch:package": "cpy 'package.json' 'dist' && patch-package-json-main"
},
Expand Down Expand Up @@ -112,7 +113,6 @@
"@typescript-eslint/parser": "^7.14.1",
"@typescript-eslint/types": "^7.14.1",
"@typescript-eslint/utils": "^7.14.1",
"@webcontainer/api": "~1.2.4",
"concurrently": "^8.0.0",
"eslint": "^8.57.0",
"eslint-import-resolver-node": "^0.3.9",
Expand Down
48 changes: 46 additions & 2 deletions apps/showcase/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@
},
"compile": {
"executor": "@angular-devkit/build-angular:application",
"inputs": [
"source",
"^source",
"{projectRoot}/dev-resources",
"{projectRoot}/training-assets",
"{projectRoot}/*.metadata.json",
"packages/@o3r/training-sdk/dist/*-structure.json"
],
"options": {
"outputPath": "apps/showcase/dist",
"index": "apps/showcase/src/index.html",
Expand All @@ -70,13 +78,30 @@
"output": "/localizations"
},
{
"glob": "**/*.metadata.json",
"glob": "*.metadata.json",
"input": "apps/showcase",
"output": "/metadata"
},
{
"glob": "**/*",
"input": "apps/showcase/training-assets/monaco-editor",
"output": "/assets/monaco/"
},
{
"glob": "**/*",
"input": "apps/showcase/training-assets/ngx-monaco-tree/assets",
"output": "/assets/"
},
{
"glob": "*-structure.json",
"input": "packages/@o3r/training-sdk/dist",
"output": "/assets/@o3r/training-sdk"
}
],
"styles": [
"apps/showcase/src/styles.scss",
"apps/showcase/training-assets/@vscode/codicons/dist/codicon.css",
"apps/showcase/training-assets/@xterm/xterm/css/xterm.css",
{
"inject": false,
"input": "apps/showcase/src/style/dark-theme/dark-theme.scss",
Expand Down Expand Up @@ -119,7 +144,8 @@
"generate-translations",
"generate-theme",
"generate-dark-theme",
"generate-horizon-theme"
"generate-horizon-theme",
"copy-training-assets"
]
},
"serve": {
Expand All @@ -140,6 +166,12 @@
},
"serve-app": {
"executor": "@angular-devkit/build-angular:dev-server",
"options": {
"headers": {
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp"
}
},
"configurations": {
"production": {
"buildTarget": "showcase:compile:production"
Expand Down Expand Up @@ -347,6 +379,18 @@
]
},
"dependsOn": ["^build-builders"]
},
"copy-training-assets": {
"executor": "nx:run-script",
"inputs": [
"global",
"{projectRoot}/package.json",
"{projectRoot}/scripts/copy-training-assets/*.cjs"
],
"outputs": ["{projectRoot}/training-assets"],
"options": {
"script": "copy-training-assets"
}
}
},
"tags": ["showcase"]
Expand Down
32 changes: 32 additions & 0 deletions apps/showcase/scripts/copy-training-assets/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copy necessary assets for the Otter training
*/
const fs = require('node:fs');
const path = require('node:path');

const temporaryAssetsDirectory = path.resolve( __dirname, '..', '..', 'training-assets');

function getAbsolutePath(packageName) {
const packageJsonPath = require.resolve(`${packageName}/package.json`);
return path.dirname(packageJsonPath);
}

// @vscode/codicons
const vscodePath = path.join(getAbsolutePath('@vscode/codicons'), 'dist');
const vscodeDestinationPath = `${temporaryAssetsDirectory}/@vscode/codicons/dist`;
fs.cpSync(vscodePath, vscodeDestinationPath, {recursive: true});

// @xterm/xterm
const xtermPath = path.join(getAbsolutePath('@xterm/xterm'), 'css/xterm.css');
const xtermDestinationPath = `${temporaryAssetsDirectory}/@xterm/xterm/css/xterm.css`;
fs.cpSync(xtermPath, xtermDestinationPath, {recursive: true});

// monaco-editor
const monacoEditorPath = path.join(getAbsolutePath('monaco-editor'));
const monacoEditorDestinationPath = `${temporaryAssetsDirectory}/monaco-editor`;
fs.cpSync(monacoEditorPath, monacoEditorDestinationPath, {recursive: true});

// ngx-monaco-tree
const ngxMonacoTreePath = path.join(getAbsolutePath('ngx-monaco-tree'), 'assets');
const ngxMonacoTreeDestinationPath = `${temporaryAssetsDirectory}/ngx-monaco-tree/assets`;
fs.cpSync(ngxMonacoTreePath, ngxMonacoTreeDestinationPath, {recursive: true});
2 changes: 1 addition & 1 deletion apps/showcase/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NavigationEnd, Router } from '@angular/router';
import { NgbOffcanvas, NgbOffcanvasRef } from '@ng-bootstrap/ng-bootstrap';
import { O3rComponent } from '@o3r/core';
import { filter, map, Observable, share, shareReplay, Subscription } from 'rxjs';
import { SideNavLinksGroup } from '../components/index';
import { SideNavLinksGroup } from '../components/utilities/sidenav';

@O3rComponent({ componentType: 'Component' })
@Component({
Expand Down
3 changes: 1 addition & 2 deletions apps/showcase/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ import { ConsoleLogger, Logger, LOGGER_CLIENT_TOKEN, LoggerService } from '@o3r/
import { OTTER_RULES_ENGINE_DEVTOOLS_OPTIONS, RulesEngineRunnerModule } from '@o3r/rules-engine';
import { OTTER_STYLING_DEVTOOLS_OPTIONS, StylingDevtoolsModule } from '@o3r/styling';
import { HIGHLIGHT_OPTIONS } from 'ngx-highlightjs';
import { ScrollBackTopPresComponent, SidenavPresComponent } from '../components/index';
import { DatePickerHebrewInputPresComponent } from '../components/utilities/date-picker-input-hebrew';
import { DatePickerHebrewInputPresComponent, ScrollBackTopPresComponent, SidenavPresComponent } from '../components/utilities';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, inject, QueryList, V
import { RouterModule } from '@angular/router';
import { O3rComponent } from '@o3r/core';
import { DynamicContentModule } from '@o3r/dynamic-content';
import { CopyTextPresComponent, DynamicContentPresComponent, IN_PAGE_NAV_PRES_DIRECTIVES, InPageNavLink, InPageNavLinkDirective, InPageNavPresService } from '../../components/index';
import { DynamicContentPresComponent } from '../../components/showcase/dynamic-content';
import { CopyTextPresComponent, IN_PAGE_NAV_PRES_DIRECTIVES, InPageNavLink, InPageNavLinkDirective, InPageNavPresService } from '../../components/utilities';

@O3rComponent({ componentType: 'Page' })
@Component({
Expand Down
3 changes: 2 additions & 1 deletion apps/showcase/src/app/rules-engine/rules-engine.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import {
UnaryOperator
} from '@o3r/rules-engine';
import { firstValueFrom } from 'rxjs';
import { CopyTextPresComponent, IN_PAGE_NAV_PRES_DIRECTIVES, InPageNavLink, InPageNavLinkDirective, InPageNavPresService, RulesEnginePresComponent } from '../../components/index';
import { RulesEnginePresComponent } from '../../components/showcase/rules-engine';
import { CopyTextPresComponent, IN_PAGE_NAV_PRES_DIRECTIVES, InPageNavLink, InPageNavLinkDirective, InPageNavPresService } from '../../components/utilities';
import { environment } from '../../environments/environment.development';
import { TripFactsService } from '../../facts/index';
import { duringSummer } from '../../operators/index';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';
import { O3rComponent } from '@o3r/core';
import { CopyTextPresComponent } from '../../components/index';
import { CopyTextPresComponent } from '../../components/utilities/copy-text';

@O3rComponent({ componentType: 'Page' })
@Component({
Expand Down
1 change: 1 addition & 0 deletions apps/showcase/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './showcase/index';
export * from './training/index';
export * from './utilities/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<ul ngbNav #nav="ngbNav" class="nav nav-tabs">
<li ngbNavItem class="nav-item" role="presentation" [destroyOnHide]="false">
<a ngbNavLink class="nav-link" [class.active]="activeTab === 'preview'" (click)="activeTab = 'preview'">Preview</a>
<ng-template ngbNavContent>
<iframe class="w-100 h-100" #iframe allow="cross-origin-isolated" [srcdoc]="'Loading...'"></iframe>
</ng-template>
</li>
<li ngbNavItem class="nav-item" role="presentation" [destroyOnHide]="false">
<a ngbNavLink class="nav-link" [class.active]="activeTab === 'output'" (click)="activeTab = 'output'">Output</a>
<ng-template ngbNavContent>
<code-editor-terminal id="tab-content2" class="d-block h-100"
(disposed)="webContainerService.runner.disposeCommandOutputTerminal()"
(terminalUpdated)="webContainerService.runner.registerCommandOutputTerminal($event)">
</code-editor-terminal>
</ng-template>
</li>
<li ngbNavItem class="nav-item" role="presentation" [destroyOnHide]="false">
<a ngbNavLink class="nav-link" [class.active]="activeTab === 'terminal'" (click)="activeTab = 'terminal'">Terminal</a>
<ng-template ngbNavContent>
<code-editor-terminal id="tab-content3" class="d-block h-100"
(disposed)="webContainerService.runner.disposeShell()"
(terminalUpdated)="webContainerService.runner.registerShell($event)">
</code-editor-terminal>
</ng-template>
</li>
<button type="button" class="btn btn-outline-secondary df-btn-icononly align-self-center ms-auto"
[class.fa-chevron-down]="!show"
[class.fa-chevron-up]="show"
(click)="show = !show">
<span class="visually-hidden">{{show ? 'Hide' : 'Show'}}</span>
</button>
</ul>
<div class="h-100 command-panel" [class.d-none]="!show" [ngbNavOutlet]="nav"></div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
code-editor-control {

&:has(.command-panel.d-none) {
min-height: 3rem;
}

.tab-content {
--df-tabs-content-tab-pane-padding: 0;
overflow: hidden;
}

.tab-pane {
border: 1px solid black;
height: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';

import {CodeEditorControlComponent} from './code-editor-control.component';

describe('ViewComponent', () => {
let component: CodeEditorControlComponent;
let fixture: ComponentFixture<CodeEditorControlComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CodeEditorControlComponent]
}).compileComponents();

fixture = TestBed.createComponent(CodeEditorControlComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
inject,
Input,
OnDestroy,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {NgbNav, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavOutlet} from '@ng-bootstrap/ng-bootstrap';
import {WebContainerService} from '../../../services';
import {CodeEditorTerminalComponent} from '../code-editor-terminal';

@Component({
selector: 'code-editor-control',
standalone: true,
imports: [
CodeEditorTerminalComponent,
NgbNav,
NgbNavContent,
NgbNavItem,
NgbNavLink,
NgbNavOutlet
],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
templateUrl: './code-editor-control.component.html',
styleUrl: './code-editor-control.component.scss'
})
export class CodeEditorControlComponent implements OnDestroy, AfterViewInit {
/**
* Show the terminal used as output for the command process
*/
@Input() public showOutput = true;

/**
* Reference to the iframe used to display the content of the application served in the web container
*/
@ViewChild('iframe')
public iframeEl!: ElementRef<HTMLIFrameElement>;

/**
* Manage the web-container commands and outputs.
*/
public readonly webContainerService = inject(WebContainerService);

/**
* Whether to show the panels - if set to false, hide all the panels and only display the tab bar
*/
public show = true;

/**
* Current tab displayed
*/
public activeTab: 'preview' | 'output' | 'terminal' = 'preview';

/**
* @inheritDoc
*/
public ngAfterViewInit() {
this.webContainerService.runner.registerIframe(this.iframeEl.nativeElement);
}

/**
* @inheritDoc
*/
public ngOnDestroy() {
this.webContainerService.runner.registerIframe(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './code-editor-control.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { CodeEditorTerminalComponent } from './code-editor-terminal.component';

describe('ViewComponent', () => {
let component: CodeEditorTerminalComponent;
let fixture: ComponentFixture<CodeEditorTerminalComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CodeEditorTerminalComponent]
}).compileComponents();

fixture = TestBed.createComponent(CodeEditorTerminalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading

0 comments on commit 9a62adb

Please sign in to comment.