diff --git a/src/app/core/component/cardrenderer/card-renderer.component.ts b/src/app/core/component/cardrenderer/card-renderer.component.ts index bf27865a..df582f13 100644 --- a/src/app/core/component/cardrenderer/card-renderer.component.ts +++ b/src/app/core/component/cardrenderer/card-renderer.component.ts @@ -32,7 +32,7 @@ export class CardRendererComponent { navigate(pattern: UriEntity): void { this.zone.run(() => { - this.router.navigate([UriConverter.doubleEncodeUri(pattern.uri)], { relativeTo: this.activatedRoute }); + this.router.navigate([pattern.id], { relativeTo: this.activatedRoute }); }); } diff --git a/src/app/core/component/delete-confirmation-dialog/delete-confirmation-dialog.component.html b/src/app/core/component/delete-confirmation-dialog/delete-confirmation-dialog.component.html index d6520076..05b27da8 100644 --- a/src/app/core/component/delete-confirmation-dialog/delete-confirmation-dialog.component.html +++ b/src/app/core/component/delete-confirmation-dialog/delete-confirmation-dialog.component.html @@ -1,8 +1,8 @@

Do you really want to delete {{data.name}}?

Do you really want to delete this item?

- - + diff --git a/src/app/core/component/edit-url-dialog/edit-url-dialog.component.html b/src/app/core/component/edit-url-dialog/edit-url-dialog.component.html index d9effe84..b48bf7f0 100644 --- a/src/app/core/component/edit-url-dialog/edit-url-dialog.component.html +++ b/src/app/core/component/edit-url-dialog/edit-url-dialog.component.html @@ -2,14 +2,14 @@

Edit Title or Icon for {{data.pattern.name}}

Adjust Pattern Name - + Adjust Icon URL - +
- + diff --git a/src/app/core/component/markdown-content-container/discuss-dialog/discuss-dialog.component.html b/src/app/core/component/markdown-content-container/discuss-dialog/discuss-dialog.component.html index 7cf083ca..78dbce18 100644 --- a/src/app/core/component/markdown-content-container/discuss-dialog/discuss-dialog.component.html +++ b/src/app/core/component/markdown-content-container/discuss-dialog/discuss-dialog.component.html @@ -13,6 +13,6 @@

{{data.title}}

- +
diff --git a/src/app/core/component/markdown-content-container/markdown-pattern-sectioncontent/markdown-pattern-section-content.component.ts b/src/app/core/component/markdown-content-container/markdown-pattern-sectioncontent/markdown-pattern-section-content.component.ts index 70ed197a..13f0e0f8 100644 --- a/src/app/core/component/markdown-content-container/markdown-pattern-sectioncontent/markdown-pattern-section-content.component.ts +++ b/src/app/core/component/markdown-content-container/markdown-pattern-sectioncontent/markdown-pattern-section-content.component.ts @@ -26,6 +26,7 @@ import * as QuantumCircuit from 'quantum-circuit'; export class MarkdownPatternSectionContentComponent extends DataRenderingComponent implements AfterViewInit { data: string; renderedData: string; + patternLanguageId: string; title = ''; imageModels: ImageModel[] = []; svg: Selection; @@ -107,7 +108,7 @@ export class MarkdownPatternSectionContentComponent extends DataRenderingCompone openEditor(): void { const dialogRef = this.dialog.open(MdEditorComponent, - { data: { content: this.data, field: this.title } }); + { data: { content: this.data, field: this.title, patternLanguageId: this.patternLanguageId } }); dialogRef.afterClosed().subscribe(async (result: DialogData) => { const previousValue = this.data; diff --git a/src/app/core/component/md-editor/md-editor.component.html b/src/app/core/component/md-editor/md-editor.component.html index 9c57844d..557a404c 100644 --- a/src/app/core/component/md-editor/md-editor.component.html +++ b/src/app/core/component/md-editor/md-editor.component.html @@ -4,8 +4,22 @@

Edit '{{data.label}}'

close
-
- +
+
+ + Pattern + + + {{pattern.name}} + + + + +
+
+ + diff --git a/src/app/core/component/select-pattern-dialog/select-pattern-dialog.component.scss b/src/app/core/component/select-pattern-dialog/select-pattern-dialog.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/core/component/select-pattern-dialog/select-pattern-dialog.component.ts b/src/app/core/component/select-pattern-dialog/select-pattern-dialog.component.ts new file mode 100644 index 00000000..b616053f --- /dev/null +++ b/src/app/core/component/select-pattern-dialog/select-pattern-dialog.component.ts @@ -0,0 +1,31 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +@Component({ + selector: 'pp-select-pattern-dialog', + templateUrl: './select-pattern-dialog.component.html', + styleUrls: ['./select-pattern-dialog.component.scss'] +}) +export class SelectPatternDialogComponent implements OnInit { + + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, private _fb: FormBuilder) { + } + + selectedPatternForm: FormGroup; + + onNoClick(): void { + this.dialogRef.close(); + } + + + ngOnInit(): void { + this.selectedPatternForm = this._fb.group({ + selectedPattern: ['', [Validators.required]] + }); + } + +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 257bc6cc..ecaa9180 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -77,6 +77,7 @@ import { CandidateManagementService } from './candidate-management/_services/can import { CandidateManagementStore } from './candidate-management'; import { MatTreeModule } from '@angular/material/tree'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { SelectPatternDialogComponent } from './component/select-pattern-dialog/select-pattern-dialog.component'; import { DeleteConfirmationDialogComponent } from './component/delete-confirmation-dialog/delete-confirmation-dialog.component'; import { EditUrlDialogComponent } from './component/edit-url-dialog/edit-url-dialog.component'; import { FeatureToggleDialogComponent } from './component/feature-toggle-dialog/feature-toggle-dialog.component'; @@ -167,6 +168,7 @@ import { PatternAtlasUiFeatureToggleModule } from './directives/pattern-atlas-ui CreativeLicenseFooterComponent, CommentDialogComponent, DiscussDialogComponent, + SelectPatternDialogComponent, DeleteConfirmationDialogComponent, EditUrlDialogComponent, FeatureToggleDialogComponent diff --git a/src/app/core/default-pattern-renderer/default-pattern-renderer.component.ts b/src/app/core/default-pattern-renderer/default-pattern-renderer.component.ts index 376934ad..bafbe8e5 100644 --- a/src/app/core/default-pattern-renderer/default-pattern-renderer.component.ts +++ b/src/app/core/default-pattern-renderer/default-pattern-renderer.component.ts @@ -33,7 +33,7 @@ import { EditUrlDialogComponent } from '../component/edit-url-dialog/edit-url-di @Component({ selector: 'pp-default-pattern-renderer', templateUrl: './default-pattern-renderer.component.html', - styleUrls: [ './default-pattern-renderer.component.scss' ] + styleUrls: ['./default-pattern-renderer.component.scss'] }) export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy { @ViewChild(PatternPropertyDirective) ppPatternProperty: PatternPropertyDirective; @@ -105,7 +105,7 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy getPatternSectionContent(): Observable { const content = this.patternService.getPatternContentByPattern(this.pattern); const renderedContent = this.patternService.getPatternRenderedContentByPattern(this.pattern); - return forkJoin([ content, renderedContent ]).pipe( + return forkJoin([content, renderedContent]).pipe( map((patternContent) => { this.pattern.renderedContent = patternContent[1].renderedContent; return this.pattern.content = patternContent[0].content; @@ -115,7 +115,7 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy getPatternLanguageLinks(): Observable { const $getDirectedEdges = this.getDirectedEdges(); const $getUndirectedEdges = this.getUndirectedEdges(); - return forkJoin([ $getDirectedEdges, $getUndirectedEdges ]).pipe(tap(() => this.isLoadingLinks = false)); + return forkJoin([$getDirectedEdges, $getUndirectedEdges]).pipe(tap(() => this.isLoadingLinks = false)); } getPatternByLink(edge: DirectedEdgeModel | UndirectedEdgeModel, res: any) { @@ -146,6 +146,7 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy instance.renderedData = renderedContent; instance.data = content; instance.title = section; + instance.patternLanguageId = this.patternLanguageId; instance.isEditingEnabled = this.isEditingEnabled; const changeSubscription = instance.changeContent.subscribe((dataChange: DataChange) => { this.pattern.content[section] = dataChange.currentValue; @@ -162,8 +163,8 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy return this.patternLanguageService.getDirectedEdges(this.patternLanguage).pipe( tap((edges) => { this.directedPatternRelations = edges && edges._embedded ? - edges._embedded.directedEdgeModels.filter(edge => edge.sourcePatternId === this.pattern.id || - edge.targetPatternId === this.pattern.id) : []; + edges._embedded.directedEdgeModels.filter(edge => edge.sourcePatternId === this.patternId || + edge.targetPatternId === this.patternId) : []; })); } @@ -174,7 +175,7 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy return this.patternLanguageService.getUndirectedEdges(this.patternLanguage).pipe( tap((edges) => { this.undirectedPatternRelations = edges && edges._embedded ? - edges._embedded.undirectedEdgeModels.filter(edge => edge.pattern1Id === this.pattern.id || edge.pattern2Id === this.pattern.id) : []; + edges._embedded.undirectedEdgeModels.filter(edge => edge.pattern1Id === this.patternId || edge.pattern2Id === this.patternId) : []; })); } @@ -196,34 +197,21 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy } private getData(): void { - //initialize pattern to get ID etc for future requests - let getPatternObservable; - if (UriConverter.isUUID(this.patternId)) { - getPatternObservable = this.patternService.getPatternById(this.patternLanguage, this.patternId).pipe( - tap(pattern => this.pattern = pattern)); - } else { - getPatternObservable = this.patternService.getPatternByEncodedUri(this.patternId).pipe(tap(pattern => this.pattern = pattern)); - } - // get pattern language object with all the hal links that we need - let dataObservable; - if (UriConverter.isUUID(this.patternLanguageId)) { - dataObservable = this.patternLanguageService.getPatternLanguageByID(this.patternLanguageId).pipe( - tap((patternLanguage) => this.patternLanguage = patternLanguage), - // get our individual pattern and the links in parallel - switchMap(() => forkJoin([ this.fillPatternSectionData(), this.getPatternLanguageLinks() ]))); - } else { - this.patternLanguageService.getPatternLanguageByEncodedUri(this.patternLanguageId).pipe( - tap((patternLanguage) => this.patternLanguage = patternLanguage), - // get our individual pattern and the links in parallel - switchMap(() => forkJoin([ this.fillPatternSectionData(), this.getPatternLanguageLinks() ]))); - } - const dataSubscription = forkJoin([getPatternObservable, dataObservable]).subscribe(() => this.cdr.detectChanges()); - this.subscriptions.add(dataSubscription); + // first load pattern language object with all the hal links / ids that we may need + let dataObservable = UriConverter.isUUID(this.patternLanguageId) ? this.patternLanguageService.getPatternLanguageByID(this.patternLanguageId) + : this.patternLanguageService.getPatternLanguageByEncodedUri(this.patternLanguageId); + let subscription = dataObservable.pipe( + tap((patternLanguage) => this.patternLanguage = patternLanguage), + // load the rest: get our individual pattern and the links in parallel + switchMap(() => forkJoin([this.getPatternObservable(), this.fillPatternSectionData(), this.getPatternLanguageLinks()]))) + .subscribe(res => this.cdr.detectChanges()); + this.subscriptions.add(subscription); } + private fillPatternSectionData() { return this.getPatternData().pipe( tap(() => { @@ -273,4 +261,11 @@ export class DefaultPatternRendererComponent implements AfterViewInit, OnDestroy } }); } + + private getPatternObservable(): Observable { + return UriConverter.isUUID(this.patternId) ? + this.patternService.getPatternById(this.patternLanguage, this.patternId) : + this.patternService.getPatternByEncodedUri(this.patternId).pipe( + tap(pattern => this.pattern = pattern)); + } } diff --git a/src/app/core/default-pl-renderer/default-pl-renderer.component.ts b/src/app/core/default-pl-renderer/default-pl-renderer.component.ts index 76e15a9d..c1db85cb 100644 --- a/src/app/core/default-pl-renderer/default-pl-renderer.component.ts +++ b/src/app/core/default-pl-renderer/default-pl-renderer.component.ts @@ -288,7 +288,8 @@ export class DefaultPlRendererComponent implements OnInit, OnDestroy { } let loadDataObservable; - // check if patternlanguage is specified via UUIID or URI and load it accordingly + console.log(this.patternLanguageId) + // check if patternlanguage is specified via UUID or URI and load it accordingly if (UriConverter.isUUID(this.patternLanguageId)) { loadDataObservable = this.patternLanguageService.getPatternLanguageByID(this.patternLanguageId) .pipe( diff --git a/src/app/core/service/pattern.service.ts b/src/app/core/service/pattern.service.ts index 742af464..2f7e8ec5 100644 --- a/src/app/core/service/pattern.service.ts +++ b/src/app/core/service/pattern.service.ts @@ -71,6 +71,13 @@ export class PatternService { return this.http.get (this.repoEndpoint + '/patternLanguages/' + patternLanguage.id + '/patterns/' + patternId); } + getPatternsById(patternLanguageId: string): Observable> { + return this.http.get (this.repoEndpoint + '/patternLanguages/' + patternLanguageId + '/patterns/').pipe( + map(result => { + return >(result && result._embedded ? result._embedded.patternModels : []) + })); + } + getPatternByUrl(href: string): Observable { return this.http.get(href); } diff --git a/src/app/core/util/markdown-editor-utils.ts b/src/app/core/util/markdown-editor-utils.ts new file mode 100644 index 00000000..34374429 --- /dev/null +++ b/src/app/core/util/markdown-editor-utils.ts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018 University of Stuttgart. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache Software License 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + + +import Pattern from '../model/hal/pattern.model'; + +export class MarkdownEditorUtils { + + static standardMarkdownEditiorButtons = ['bold', 'italic', 'heading', '|', 'quote', 'unordered-list', 'ordered-list', + '|', // Separator + 'link', 'image', + '|', // Separator + 'code'] + + static helpButton = { + name: 'guide', + action: 'https://pattern-atlas-readthedocs.readthedocs.io/en/latest/user_guide/patterns/#pattern-creation', + className: 'fa fa-question-circle', + }; + + // this method is based on the private function _replaceSelection(cm, active, startEnd, url) + // of simpleMDE (see simplemde.debug.js) which our markdowneditor is based on + static insertTextAtCursor(editor: any, textBeforeCursor, textAfterCursor): void { + var cm = editor.codemirror; + var stat = editor.getState(cm); + var options = editor.options; + var url = 'http://'; + if (options.promptURLs) { + url = prompt(options.promptTexts.image); + if (!url) { + return; + } + } + var text; + var start = textBeforeCursor; // text to insert before cursor + var end = textAfterCursor; // text to insert after cursor + var startPoint = cm.getCursor('start'); + var endPoint = cm.getCursor('end'); + if (url) { + end = end.replace('#url#', url); + } + if (stat.link) { + text = cm.getLine(startPoint.line); + start = text.slice(0, startPoint.ch); + end = text.slice(startPoint.ch); + cm.replaceRange(start + end, { + line: startPoint.line, + ch: 0 + }); + } else { + text = cm.getSelection(); + cm.replaceSelection(start + text + end); + + startPoint.ch += start.length; + if (startPoint !== endPoint) { + endPoint.ch += start.length; + } + } + cm.setSelection(startPoint, endPoint); + cm.focus(); + } + + static getPatternHrefMarkdown(patternLanguageId: string, pattern: Pattern): string { + const patternReferenceUrl = `pattern-languages/${patternLanguageId}/${pattern.id}`; + return `[${pattern.name}](${patternReferenceUrl})`; + } +} diff --git a/src/app/core/util/uri-converter.ts b/src/app/core/util/uri-converter.ts index 2927a7b1..aa44b020 100644 --- a/src/app/core/util/uri-converter.ts +++ b/src/app/core/util/uri-converter.ts @@ -52,7 +52,7 @@ export class UriConverter { } // this function checks if a given urlParam is a UUID (otherwise the entity is specified via its URI) - static isUUID(urlParam) { + static isUUID(urlParam): boolean { const s = '' + urlParam; const match = s.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'); diff --git a/src/app/pattern-language-management/create-pattern/create-pattern.component.ts b/src/app/pattern-language-management/create-pattern/create-pattern.component.ts index 8d06333e..a2d006d2 100644 --- a/src/app/pattern-language-management/create-pattern/create-pattern.component.ts +++ b/src/app/pattern-language-management/create-pattern/create-pattern.component.ts @@ -3,7 +3,6 @@ import { TdTextEditorComponent } from '@covalent/text-editor'; import { ActivatedRoute, Router } from '@angular/router'; import * as marked from 'marked'; import { TokensList } from 'marked'; -import Pattern from '../../core/model/pattern.model'; import { ToasterService } from 'angular2-toaster'; import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms'; import { ValidationService } from '../../core/service/validation.service'; @@ -13,9 +12,14 @@ import PatternSectionSchema from '../../core/model/hal/pattern-section-schema.mo import * as MarkdownIt from 'markdown-it'; import * as markdownitKatex from 'markdown-it-katex'; import { PatternService } from '../../core/service/pattern.service'; -import { debounceTime, distinctUntilChanged } from 'rxjs/internal/operators'; +import { debounceTime, distinctUntilChanged, tap } from 'rxjs/internal/operators'; import { globals } from '../../globals'; import { UriConverter } from '../../core/util/uri-converter'; +import { SelectPatternDialogComponent } from '../../core/component/select-pattern-dialog/select-pattern-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { of } from 'rxjs'; +import Pattern from '../../core/model/hal/pattern.model'; +import { MarkdownEditorUtils } from '../../core/util/markdown-editor-utils'; @Component({ selector: 'pp-create-pattern', @@ -34,32 +38,24 @@ export class CreatePatternComponent implements OnInit { options: any = { autoDownloadFontAwesome: true, toolbar: - ['bold', 'italic', 'heading', '|', 'quote', 'unordered-list', 'ordered-list', - '|', // Separator - 'link', 'image', - '|', // Separator - 'code', + [...MarkdownEditorUtils.standardMarkdownEditiorButtons, { name: 'alert', action: (editor) => { - this.insertTextAtCursor(editor, '$', '$'); + MarkdownEditorUtils.insertTextAtCursor(editor, '$', '$'); }, className: 'fa fa-subscript', title: 'Add Formula', }, { name: 'pattern-link', action: (editor) => { - // TODO: after chosing a pattern in the dialog, insert a link to the chosen pattern in markdown syntax + this.addPatternReference(editor); }, className: 'fa fab fa-product-hunt', title: 'Reference Pattern', }, '|', // Separator - { - name: 'guide', - action: 'https://pattern-atlas-readthedocs.readthedocs.io/en/latest/user_guide/patterns/#pattern-creation', - className: 'fa fa-question-circle', - }, + MarkdownEditorUtils.helpButton ], }; errorMessages: Array; @@ -76,7 +72,8 @@ export class CreatePatternComponent implements OnInit { private patternService: PatternService, private router: Router, private zone: NgZone, - private _fb: FormBuilder) { + private _fb: FormBuilder, + private matDialog: MatDialog) { } get iconUrl(): AbstractControl { @@ -97,7 +94,10 @@ export class CreatePatternComponent implements OnInit { this.markdown = new MarkdownIt(); this.markdown.use(markdownitKatex); - this.patternLanguageService.getPatternLanguageById(this.patternLanguageId).subscribe((pl: PatternLanguage) => { + const patternLanguageObservable = UriConverter.isUUID(this.patternLanguageId) ? + this.patternLanguageService.getPatternLanguageById(this.patternLanguageId) + : this.patternLanguageService.getPatternLanguageByEncodedUri(this.patternLanguageId); + patternLanguageObservable.subscribe((pl) => { this.patternLanguage = pl; this.sections = this.patternLanguage.patternSchema ? this.patternLanguage.patternSchema.patternSectionSchemas.map((schema: PatternSectionSchema) => schema.label) : []; @@ -186,7 +186,7 @@ export class CreatePatternComponent implements OnInit { } //Format Input text so MAP Patterns can be directly copied into Pattern Atlas - reformatMapPatternInput(text: string){ + reformatMapPatternInput(text: string) { return text.replace(new RegExp('', 'g'), ' ') .replace(new RegExp('\{#sec:.*}', 'g'), ' ') .replace(new RegExp('#{3,}', 'g'), '##'); @@ -225,10 +225,10 @@ export class CreatePatternComponent implements OnInit { } this.errorMessages = []; Object.keys(this.patternValuesFormGroup.controls).forEach(key => { - const controlErrors: ValidationErrors = this.patternValuesFormGroup.controls[ key ].errors; + const controlErrors: ValidationErrors = this.patternValuesFormGroup.controls[key].errors; if (controlErrors != null) { Object.keys(controlErrors).forEach(keyError => { - this.errorMessages.push(ValidationService.getMessageForError(key, keyError, controlErrors[ keyError ])); + this.errorMessages.push(ValidationService.getMessageForError(key, keyError, controlErrors[keyError])); }); } }); @@ -259,7 +259,7 @@ export class CreatePatternComponent implements OnInit { private parsePatternInput(): void { const lines = this.parseMarkdownText(); const patternNameIndex = lines.findIndex((it) => it.type === 'heading' && it.depth === 1); - this.patternName = patternNameIndex !== -1 ? lines[ patternNameIndex ][ 'text' ] : ''; + this.patternName = patternNameIndex !== -1 ? lines[patternNameIndex]['text'] : ''; this.patternLanguage.patternSchema.patternSectionSchemas.forEach((schema: PatternSectionSchema) => { const sectionName = schema.name; const sectionIndex = lines.findIndex((sec) => sec.type === 'heading' && sec.depth === 2 && @@ -267,21 +267,21 @@ export class CreatePatternComponent implements OnInit { if (sectionIndex !== -1) { const sectionContent = []; for (let i = sectionIndex + 1; i < lines.length; i++) { - if (lines[ i ].type === 'heading') { + if (lines[i].type === 'heading') { break; } - if (lines[ i ].type === 'space') { + if (lines[i].type === 'space') { sectionContent.push('\n'); } - if (lines[ i ][ 'text' ]) { + if (lines[i]['text']) { // if a list item was parsed before, add it to the text - sectionContent.push(i > 0 && CreatePatternComponent.isListItem(i, sectionIndex, lines) ? '* ' + lines[ i ][ 'text' ] : lines[ i ][ 'text' ] ); + sectionContent.push(i > 0 && CreatePatternComponent.isListItem(i, sectionIndex, lines) ? '* ' + lines[i]['text'] : lines[i]['text']); } - console.log('sectioncontent:'+sectionContent) + console.log('sectioncontent:' + sectionContent) } if (this.patternValuesFormGroup) { - if (this.patternValuesFormGroup.controls[ sectionName ]) { - this.patternValuesFormGroup.controls[ sectionName ].setValue(sectionContent.join('\n')); + if (this.patternValuesFormGroup.controls[sectionName]) { + this.patternValuesFormGroup.controls[sectionName].setValue(sectionContent.join('\n')); } else { console.log('missing formcontrol:'); console.log(sectionName); @@ -311,4 +311,34 @@ export class CreatePatternComponent implements OnInit { this._textEditor.value = this.previousTextEditorValue; this.onChangeMarkdownText(); } + + private addPatternReference(editor: any) { + // get patterns to select from + let patternsObservable = !this.patterns ? + this.patternService.getPatternsByUrl(this.patternLanguage._links.patterns.href) : of(this.patterns); + patternsObservable.pipe( + tap((res) => { + this.patterns = res; + // let the user choose which pattern to reference + this.showAndHandlePatternSelectionDialog(this.patterns, editor); + })).subscribe((res) => { + console.log('show dialog for pattern selection') + }); + } + + private showAndHandlePatternSelectionDialog(patterns: Array, editor: any) { + const dialogRef = this.matDialog.open(SelectPatternDialogComponent, { + data: { + patterns: this.patterns + } + }); + + dialogRef.afterClosed().subscribe((selectedPattern) => { + const patternReferenceUrl = `pattern-languages/${this.patternLanguage.id}/${selectedPattern.id}`; + if (selectedPattern) { // if user did not cancel + MarkdownEditorUtils.insertTextAtCursor(editor, `[${selectedPattern.name}](${patternReferenceUrl})`, ''); + this.onChangeMarkdownText(); + } + }); + } } diff --git a/src/app/pattern-view-management/pattern-view-renderer/pattern-view-renderer.component.ts b/src/app/pattern-view-management/pattern-view-renderer/pattern-view-renderer.component.ts index 53aa6850..17613494 100644 --- a/src/app/pattern-view-management/pattern-view-renderer/pattern-view-renderer.component.ts +++ b/src/app/pattern-view-management/pattern-view-renderer/pattern-view-renderer.component.ts @@ -30,7 +30,7 @@ import { UiFeatures } from '../../core/directives/pattern-atlas-ui-repository-co @Component({ selector: 'pp-pattern-view-renderer', templateUrl: './pattern-view-renderer.component.html', - styleUrls: ['./pattern-view-renderer.component.scss'] + styleUrls: [ './pattern-view-renderer.component.scss' ] }) export class PatternViewRendererComponent implements OnInit, AfterViewInit { diff --git a/yarn.lock b/yarn.lock index d35c9719..2f4c5ff8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2366,14 +2366,15 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.3, browserslist@^4.8.5, browserslist@^4.9.1: - version "4.12.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" - integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001043" - electron-to-chromium "^1.3.413" - node-releases "^1.1.53" - pkg-up "^2.0.0" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" browserstack@^1.5.1: version "1.6.0" @@ -2585,10 +2586,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001061: - version "1.0.30001066" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001066.tgz#0a8a58a10108f2b9bf38e7b65c237b12fd9c5f04" - integrity sha512-Gfj/WAastBtfxLws0RCh2sDbTK/8rJuSeZMecrSkNGYxPcv7EzblmDGfWQCFEQcSqYE2BRgQiJh8HOD07N5hIw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001061, caniuse-lite@^1.0.30001219: + version "1.0.30001228" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== canonical-path@1.0.0: version "1.0.0" @@ -2903,6 +2904,11 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + colors@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -3966,10 +3972,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.413: - version "1.3.453" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.453.tgz#758a8565a64b7889b27132a51d2abb8b135c9d01" - integrity sha512-IQbCfjJR0NDDn/+vojTlq7fPSREcALtF8M1n01gw7nQghCtfFYrJ2dfhsp8APr8bANoFC8vRTFVXMOGpT0eetw== +electron-to-chromium@^1.3.723: + version "1.3.736" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.736.tgz#f632d900a1f788dab22fec9c62ec5c9c8f0c4052" + integrity sha512-DY8dA7gR51MSo66DqitEQoUMQ0Z+A2DSXFi7tK304bdTVqczCAfUuyQw6Wdg8hIoo5zIxkU1L24RQtUce1Ioig== elliptic@^6.0.0, elliptic@^6.5.2: version "6.5.3" @@ -4139,6 +4145,11 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -4568,13 +4579,6 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -6255,14 +6259,6 @@ loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4 emojis-list "^3.0.0" json5 "^1.0.1" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -6968,10 +6964,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.53: - version "1.1.57" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.57.tgz#f6754ce225fad0611e61228df3e09232e017ea19" - integrity sha512-ZQmnWS7adi61A9JsllJ2gdj2PauElcjnOwTp2O011iGzoakTxUsDGSe+6vD7wXbKdqhSFymC0OSx35aAMhrSdw== +node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== normalize-package-data@^2.0.0, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: version "2.5.0" @@ -7345,13 +7341,6 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.2.2: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -7359,13 +7348,6 @@ p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.2.2: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -7399,11 +7381,6 @@ p-retry@^3.0.1: dependencies: retry "^0.12.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -7666,13 +7643,6 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - portfinder@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"