diff --git a/angular.json b/angular.json index 812f38eaab..ab1dac87d1 100644 --- a/angular.json +++ b/angular.json @@ -20,11 +20,18 @@ "framework": "express" }, "@nrwl/angular:application": { + "style": "scss", + "linter": "eslint", "unitTestRunner": "jest", "e2eTestRunner": "cypress" }, "@nrwl/angular:library": { - "unitTestRunner": "none" + "style": "scss", + "linter": "eslint", + "unitTestRunner": "jest" + }, + "@nrwl/angular:component": { + "style": "scss" } }, "projects": { @@ -272,6 +279,31 @@ }, "schematics": {} }, + "vscode-ui-argument-list": { + "projectType": "library", + "root": "libs/vscode-ui/argument-list", + "sourceRoot": "libs/vscode-ui/argument-list/src", + "prefix": "nx-console", + "architect": { + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "libs/vscode-ui/argument-list/src/**/*.ts", + "libs/vscode-ui/argument-list/src/**/*.html" + ] + } + }, + "test": { + "builder": "@nrwl/jest:jest", + "outputs": ["coverage/libs/vscode-ui/argument-list"], + "options": { + "jestConfig": "libs/vscode-ui/argument-list/jest.config.js", + "passWithNoTests": true + } + } + } + }, "vscode-ui-components": { "projectType": "library", "root": "libs/vscode-ui/components", @@ -294,11 +326,6 @@ }, "outputs": ["coverage/libs/vscode-ui/components"] } - }, - "schematics": { - "@nrwl/angular:component": { - "styleext": "scss" - } } }, "vscode-ui-styles": { diff --git a/apps/vscode-ui/src/styles.scss b/apps/vscode-ui/src/styles.scss index 262e5eba49..bc9c27907a 100644 --- a/apps/vscode-ui/src/styles.scss +++ b/apps/vscode-ui/src/styles.scss @@ -1,5 +1,6 @@ @import 'flex'; @import 'variables'; +@import '~vscode-codicons/dist/codicon'; html, body { diff --git a/jest.config.js b/jest.config.js index 1068d10a7e..dff135dc12 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,6 +2,7 @@ module.exports = { projects: [ '/apps/vscode-ui', '/libs/server', + '/libs/vscode-ui/argument-list', '/libs/vscode-ui/components', '/libs/vscode-ui/feature-task-execution-form', '/libs/vscode/nx-project-view', diff --git a/libs/vscode-ui/argument-list/.eslintrc.json b/libs/vscode-ui/argument-list/.eslintrc.json new file mode 100644 index 0000000000..a8f03f4386 --- /dev/null +++ b/libs/vscode-ui/argument-list/.eslintrc.json @@ -0,0 +1,31 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nrwl/nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "parserOptions": { + "project": ["libs/vscode-ui/argument-list/tsconfig.*?.json"] + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { "type": "attribute", "prefix": "nx-console", "style": "camelCase" } + ], + "@angular-eslint/component-selector": [ + "error", + { "type": "element", "prefix": "nx-console", "style": "kebab-case" } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/libs/vscode-ui/argument-list/jest.config.js b/libs/vscode-ui/argument-list/jest.config.js new file mode 100644 index 0000000000..1409af71cc --- /dev/null +++ b/libs/vscode-ui/argument-list/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + displayName: 'vscode-ui-argument-list', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsConfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + astTransformers: { + before: [ + 'jest-preset-angular/build/InlineFilesTransformer', + 'jest-preset-angular/build/StripStylesTransformer', + ], + }, + }, + }, + coverageDirectory: '../../../coverage/libs/vscode-ui/argument-list', + snapshotSerializers: [ + 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', + 'jest-preset-angular/build/AngularSnapshotSerializer.js', + 'jest-preset-angular/build/HTMLCommentSerializer.js', + ], +}; diff --git a/libs/vscode-ui/argument-list/src/index.ts b/libs/vscode-ui/argument-list/src/index.ts new file mode 100644 index 0000000000..a294fb67aa --- /dev/null +++ b/libs/vscode-ui/argument-list/src/index.ts @@ -0,0 +1 @@ +export * from './lib/argument-list.module'; diff --git a/libs/vscode-ui/argument-list/src/lib/argument-list.component.html b/libs/vscode-ui/argument-list/src/lib/argument-list.component.html new file mode 100644 index 0000000000..77e85b021b --- /dev/null +++ b/libs/vscode-ui/argument-list/src/lib/argument-list.component.html @@ -0,0 +1 @@ +
diff --git a/libs/vscode-ui/argument-list/src/lib/argument-list.component.scss b/libs/vscode-ui/argument-list/src/lib/argument-list.component.scss new file mode 100644 index 0000000000..80b5290b7a --- /dev/null +++ b/libs/vscode-ui/argument-list/src/lib/argument-list.component.scss @@ -0,0 +1,5 @@ +div { + overflow-wrap: break-word; + margin-left: 1em; + text-indent: -1em; +} diff --git a/libs/vscode-ui/argument-list/src/lib/argument-list.component.spec.ts b/libs/vscode-ui/argument-list/src/lib/argument-list.component.spec.ts new file mode 100644 index 0000000000..66e9036491 --- /dev/null +++ b/libs/vscode-ui/argument-list/src/lib/argument-list.component.spec.ts @@ -0,0 +1,34 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ArgumentListComponent } from './argument-list.component'; + +describe('ArgumentListComponent', () => { + let component: ArgumentListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ArgumentListComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ArgumentListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should format arguments for multiline break-word', () => { + component.args = [ + '--some-arg=withalistofoptions,that-may-not-fit-on-a-single-line', + ]; + fixture.detectChanges(); + expect(component.args).toEqual([ + '--some-arg=withalistofoptions,that-may-not-fit-on-a-single-line', + ]); + }); +}); diff --git a/libs/vscode-ui/argument-list/src/lib/argument-list.component.ts b/libs/vscode-ui/argument-list/src/lib/argument-list.component.ts new file mode 100644 index 0000000000..21a2e3d792 --- /dev/null +++ b/libs/vscode-ui/argument-list/src/lib/argument-list.component.ts @@ -0,0 +1,36 @@ +import { + Component, + Input, + ChangeDetectionStrategy, + SecurityContext, +} from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; + +@Component({ + selector: 'nx-console-argument-list', + templateUrl: './argument-list.component.html', + styleUrls: ['./argument-list.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ArgumentListComponent { + private _formattedArgs: string[]; + @Input() + get args(): string[] { + return this._formattedArgs; + } + set args(values: string[]) { + this._formattedArgs = + values && + values.map( + (value) => + this.domSanitizer.sanitize( + SecurityContext.HTML, + this.domSanitizer.bypassSecurityTrustHtml( + value.replace('=', '=') + ) + ) || '' + ); + } + + constructor(private readonly domSanitizer: DomSanitizer) {} +} diff --git a/libs/vscode-ui/argument-list/src/lib/argument-list.module.ts b/libs/vscode-ui/argument-list/src/lib/argument-list.module.ts new file mode 100644 index 0000000000..1d4bc3ff47 --- /dev/null +++ b/libs/vscode-ui/argument-list/src/lib/argument-list.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ArgumentListComponent } from './argument-list.component'; + +@NgModule({ + imports: [CommonModule], + declarations: [ArgumentListComponent], + exports: [ArgumentListComponent], +}) +export class ArgumentListModule {} diff --git a/libs/vscode-ui/argument-list/src/test-setup.ts b/libs/vscode-ui/argument-list/src/test-setup.ts new file mode 100644 index 0000000000..8d88704e8f --- /dev/null +++ b/libs/vscode-ui/argument-list/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular'; diff --git a/libs/vscode-ui/argument-list/tsconfig.json b/libs/vscode-ui/argument-list/tsconfig.json new file mode 100644 index 0000000000..667a3463d1 --- /dev/null +++ b/libs/vscode-ui/argument-list/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/vscode-ui/argument-list/tsconfig.lib.json b/libs/vscode-ui/argument-list/tsconfig.lib.json new file mode 100644 index 0000000000..890aaeb555 --- /dev/null +++ b/libs/vscode-ui/argument-list/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "target": "es2015", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [], + "lib": ["dom", "es2018"] + }, + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "enableResourceInlining": true + }, + "exclude": ["src/test-setup.ts", "**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/libs/vscode-ui/argument-list/tsconfig.spec.json b/libs/vscode-ui/argument-list/tsconfig.spec.json new file mode 100644 index 0000000000..fd405a65ef --- /dev/null +++ b/libs/vscode-ui/argument-list/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.html b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.html index 56a3525b56..d1cdef359f 100644 --- a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.html +++ b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.html @@ -3,6 +3,8 @@ *ngFor="let field of fields" (click)="scrollToField(field.name)" [class.active]="activeFieldName === field.name" + [class.valid]="isFieldValid(field.name)" + [class.error]="isFieldInvalid(field.name)" [id]="field.name + '-field-tree-item'" [style.display]="filteredFields.has(field.name) ? 'block' : 'none'" > diff --git a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.scss b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.scss index 8b92433be4..999f89c5c2 100644 --- a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.scss +++ b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.scss @@ -36,4 +36,11 @@ font-weight: 700; opacity: 1; } + + &.valid { + color: $modified-text-color; + } + &.error { + color: $error-text-color; + } } diff --git a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.ts b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.ts index 77c7cacc95..bf8413ce3e 100644 --- a/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.ts +++ b/libs/vscode-ui/components/src/lib/field-tree/field-tree.component.ts @@ -19,6 +19,8 @@ export class FieldTreeComponent implements OnChanges { @Input() fields: Array