Skip to content
Snippets Groups Projects
Commit 5a231ef1 authored by Kawtar Laariche's avatar Kawtar Laariche
Browse files

#19: create custom rich text editor dialog

parent c182b694
No related branches found
Tags v0.2.0
1 merge request!12Features/user auth manage my models
...@@ -38,15 +38,10 @@ ...@@ -38,15 +38,10 @@
</mat-form-field> </mat-form-field>
<div> <div>
<span>Model description</span> <span>Model description</span>
@if (showDescriptionEditor) {
<quill-editor <button color="primary" (click)="addEditDescription()">
[styles]="{ height: '200px' }" <mat-icon>add</mat-icon>
(onFocus)="focus($event)" </button>
(onBlur)="blur($event)"
(onEditorCreated)="created($event)"
formControlName="description"
></quill-editor>
}
</div> </div>
<div style="display: flex; gap: 20px; width: 100%"> <div style="display: flex; gap: 20px; width: 100%">
<mat-form-field style="width: 100%"> <mat-form-field style="width: 100%">
...@@ -127,10 +122,29 @@ ...@@ -127,10 +122,29 @@
</button> </button>
</div> </div>
<!--upload documents end--> <!--upload documents end-->
<mat-form-field> <!--tags starts-->
<mat-label>Model tags</mat-label> <div style="display: flex; align-items: center">
<input matInput formControlName="tags" /> <mat-form-field class="example-chip-list" style="flex-grow: 1">
</mat-form-field> <mat-label>Add tags</mat-label>
<mat-chip-grid #chipGrid formControlName="tags">
@for (tag of tags; track tag) {
<mat-chip-row (removed)="remove(tag)">
{{ tag.tag }}
<button matChipRemove [attr.aria-label]="'remove ' + tag">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
</mat-chip-grid>
<input
#userInput
[matChipInputFor]="chipGrid"
(matChipInputTokenEnd)="addTag($event)"
/>
</mat-form-field>
<button mat-raised-button color="primary">Add tags</button>
</div>
<!--tags ends-->
<!--upload image start--> <!--upload image start-->
<div <div
style=" style="
......
import { Component, OnInit } from '@angular/core'; import { Component, inject, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service'; import { PublicSolutionsService } from 'src/app/core/services/public-solutions.service';
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
Filter, Filter,
LicenseProfileModel, LicenseProfileModel,
PublicSolutionDetailsModel, PublicSolutionDetailsModel,
Tag,
ToolkitTypeCode, ToolkitTypeCode,
toolkitTypeCodeMap, toolkitTypeCodeMap,
} from '../../models'; } from '../../models';
...@@ -32,6 +33,11 @@ import { SharedDataService } from 'src/app/core/services/shared-data/shared-data ...@@ -32,6 +33,11 @@ import { SharedDataService } from 'src/app/core/services/shared-data/shared-data
import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { AlertService } from 'src/app/core/services/alert.service'; import { AlertService } from 'src/app/core/services/alert.service';
import { ModelDetailsLicenseProfileComponent } from '../model-details-license-profile/model-details-license-profile.component'; import { ModelDetailsLicenseProfileComponent } from '../model-details-license-profile/model-details-license-profile.component';
import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips';
import { MatIconModule } from '@angular/material/icon';
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { RichTextEditorDialogComponent } from '../rich-text-editor-dialog/rich-text-editor-dialog.component';
@Component({ @Component({
selector: 'gp-publish-to-marketplace-page', selector: 'gp-publish-to-marketplace-page',
...@@ -48,6 +54,8 @@ import { ModelDetailsLicenseProfileComponent } from '../model-details-license-pr ...@@ -48,6 +54,8 @@ import { ModelDetailsLicenseProfileComponent } from '../model-details-license-pr
MatInputModule, MatInputModule,
QuillModule, QuillModule,
ModelDetailsLicenseProfileComponent, ModelDetailsLicenseProfileComponent,
MatChipsModule,
MatIconModule,
], ],
templateUrl: './publish-to-marketplace-page.component.html', templateUrl: './publish-to-marketplace-page.component.html',
styleUrl: './publish-to-marketplace-page.component.scss', styleUrl: './publish-to-marketplace-page.component.scss',
...@@ -65,13 +73,15 @@ export class PublishToMarketplacePageComponent implements OnInit { ...@@ -65,13 +73,15 @@ export class PublishToMarketplacePageComponent implements OnInit {
imageFile!: { content: File; name: string }; imageFile!: { content: File; name: string };
documentFile!: { content: File; name: string }; documentFile!: { content: File; name: string };
licenseProfile!: { content: File; name: string }; licenseProfile!: { content: File; name: string };
tags: Tag[] = [];
blured = false; blured = false;
focused = false; focused = false;
showDescriptionEditor: boolean = false;
addEditLicenseProfile: boolean = false; addEditLicenseProfile: boolean = false;
announcer = inject(LiveAnnouncer);
constructor( constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private privateCatalogsService: PrivateCatalogsService, private privateCatalogsService: PrivateCatalogsService,
...@@ -273,4 +283,46 @@ export class PublishToMarketplacePageComponent implements OnInit { ...@@ -273,4 +283,46 @@ export class PublishToMarketplacePageComponent implements OnInit {
onLicenseProfileClick() { onLicenseProfileClick() {
this.addEditLicenseProfile = true; this.addEditLicenseProfile = true;
} }
remove(tag: Tag) {
const index = this.tags.indexOf(tag);
if (index >= 0) {
this.tags.splice(index, 1);
this.announcer.announce(`Removed ${tag}`);
}
}
addTag(event: MatChipInputEvent): void {
// console.log()
const value = { tag: (event.value || '').trim() };
// Add our keyword
if (value) {
this.tags.push(value);
}
// Clear the input value
event.chipInput!.clear();
}
addEditDescription() {
const dialogRef: MatDialogRef<RichTextEditorDialogComponent> =
this.dialog.open(RichTextEditorDialogComponent, {
data: {
dataKey: {
title: 'Add model description',
isEditMode: false,
isCheckExtension: false,
action: (file: File) => {},
},
},
});
dialogRef.afterClosed().subscribe((result) => {
// This will be executed when the dialog is closed
// Reload data to fetch the updated license profile
});
}
} }
<mat-toolbar class="dialog-header">
<div style="display: flex; align-items: center; padding: 0; flex: 1 1 auto">
<h2>{{ title }}</h2>
</div>
<button
type="button"
mat-icon-button
[mat-dialog-close]="true"
class="close"
tabindex="-1"
>
<mat-icon aria-hidden="false" aria-label="Close icon">close</mat-icon>
</button>
</mat-toolbar>
<mat-dialog-content>
<div class="star-rating-container">
<p>
{{ content }}
</p>
<quill-editor [styles]="{ height: '200px' }"></quill-editor></div
></mat-dialog-content>
<mat-toolbar class="form-footer">
<button mat-dialog-close mat-raised-button style="margin-right: auto">
Cancel
</button>
<button color="primary" mat-raised-button (click)="confirm()">Confirm</button>
</mat-toolbar>
@use "@angular/material" as mat;
@import "../../../../styles.scss";
.form-container {
width: 100%;
}
.asterix--after:after {
content: "*";
color: red;
}
.login-form {
display: flex;
flex-direction: column;
padding: 10px;
}
.mat-mdc-dialog-content {
max-height: 75vh;
min-width: 800px;
}
.dialog-header {
background-color: mat.get-color-from-palette($graphene-ui-primary);
height: 39px;
color: #fff;
h2 {
color: #fff;
font-size: 16px;
font-weight: 600;
margin: 0;
}
}
.version {
font-size: 12px;
color: #bbb;
padding-left: 5px;
}
.legend {
width: 100%;
max-width: 100%;
white-space: normal;
font-size: 16px !important;
font-weight: 600;
line-height: 30px !important;
border-bottom: 1px solid #e5e5e5;
margin-bottom: 8px !important;
padding: 5px 8px 5px 0 !important;
color: #671c9d !important;
text-transform: uppercase;
font-family: "Open Sans", sans-serif;
}
.font600 {
font-weight: 600;
}
.md-txtarea {
border: 1px solid #d5d5d5;
padding: 7px;
height: 82px;
font-size: 14px;
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RichTextEditorDialogComponent } from './rich-text-editor-dialog.component';
describe('RichTextEditorDialogComponent', () => {
let component: RichTextEditorDialogComponent;
let fixture: ComponentFixture<RichTextEditorDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RichTextEditorDialogComponent]
})
.compileComponents();
fixture = TestBed.createComponent(RichTextEditorDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Inject, OnInit } from '@angular/core';
import {
MAT_DIALOG_DATA,
MatDialog,
MatDialogModule,
MatDialogRef,
} from '@angular/material/dialog';
import { AlertService } from 'src/app/core/services/alert.service';
import { AlertType } from '../../models';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { QuillModule } from 'ngx-quill';
@Component({
selector: 'gp-rich-text-editor-dialog',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
MatButtonModule,
MatToolbarModule,
MatIconModule,
QuillModule,
],
templateUrl: './rich-text-editor-dialog.component.html',
styleUrl: './rich-text-editor-dialog.component.scss',
})
export class RichTextEditorDialogComponent implements OnInit {
title!: string;
content!: string;
alertMessage!: string;
constructor(
public dialogRef: MatDialogRef<RichTextEditorDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
private alertService: AlertService,
) {}
ngOnInit(): void {
this.title = this.data.dataKey.title;
this.content = this.data.dataKey.content;
this.alertMessage = this.data.dataKey.alertMessage;
}
confirm() {
this.data.dataKey.action().subscribe({
next: (res: any) => {
this.alertService.notify(
{ message: this.alertMessage, type: AlertType.Success },
3000,
);
this.dialogRef.close(true);
},
error: (err: any) => {
this.alertService.notify(
{ message: 'Operation failed', type: AlertType.Error },
3000,
);
this.dialogRef.close(false);
},
});
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment