Created
January 15, 2024 04:53
-
-
Save anandadake/e65e38258705d5b72986446120f1d700 to your computer and use it in GitHub Desktop.
Component Code structure style
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="container mt-5"> | |
| <div class="row"> | |
| <div class="col-md-12"> | |
| <div class="row mb-2"> | |
| <div class="col-md-8"> | |
| <h1>{{project_info.project_name}}</h1> | |
| </div> | |
| <div class="col-md-2"><div class="d-grid"><button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#makeACopyModal" (click)="onPreCopy($event)">Make a Copy</button></div></div> | |
| <div class="col-md-2"><div class="d-grid"><button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">Delete project</button></div></div> | |
| </div> | |
| <div class="modal-content"> | |
| <div class="modal-header"> | |
| <h5 class="modal-title">Project Details</h5> | |
| </div> | |
| <div class="modal-body"> | |
| <form [formGroup]="projectInfo"> | |
| <div class="mb-3"> | |
| <label for="projectTitle" class="form-label">Project Title</label> | |
| <input type="text" class="form-control" maxlength="50" formControlName="project_name" (input)="removeSpecialCharAndFirstCharIfNumber($event)" #wordForName> | |
| <div class="form-text">Title for your Project (Min 5 Character to Max 50 Characters)</div> | |
| <div class="form-text alert-info">{{maxWordsForName - wordForName.value.length}} Characters Remaining..</div> | |
| <div class="alert alert-danger" *ngIf="projectInfo.controls['project_name'].touched && projectInfo.controls['project_name'].invalid"> | |
| <strong>Project Title Can't be Empty!</strong> Please fill Project Title. | |
| </div> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="projectDescription" class="form-label">Project Description</label> | |
| <textarea type="text" class="form-control" rows="5" maxlength="500" formControlName="description" #wordForDescription></textarea> | |
| <div class="form-text">Description for your Project (Min 1 Character to Max 500 Characters)</div> | |
| <div class="form-text alert-info">{{maxWordsForDescription - wordForDescription.value.length}} Characters Remaining..</div> | |
| </div> | |
| <div class="mb-3"> | |
| <label class="form-label">Unit System</label> | |
| <select class="form-select" formControlName="unit_system"> | |
| <option disabled [value]="null">Select Unit System</option> | |
| <option *ngFor="let unit of unit_systems" [value]="unit">{{ unit }}</option> | |
| </select> | |
| </div> | |
| </form> | |
| </div> | |
| <div class="modal-footer"> | |
| <button type="submit" class="btn btn-primary" (click)="onSave($event)" [disabled]="!projectInfo.valid">Update project</button> | |
| <button class="btn " data-bs-toggle="modal" data-bs-target="#shareProject" (click)="fetchPermissions($event)" > Permissions </button> | |
| <button class="btn btn-outline-primary" (click)="onMakeTemplateProject($event)">Make Template Project</button> | |
| <button class="btn btn-secondary" routerLink="/dashboard">Cancel</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Modal --> | |
| <div class="modal fade" id="makeACopyModal" tabindex="-1" aria-labelledby="makeACopyModalLabel" aria-hidden="true"> | |
| <div class="modal-dialog"> | |
| <div class="modal-content"> | |
| <div class="modal-header"> | |
| <h5 class="modal-title" id="makeACopyModalLabel">Copy Project</h5> | |
| <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | |
| </div> | |
| <div class="modal-body"> | |
| <form [formGroup]="projectInfo"> | |
| <div class="mb-3"> | |
| <label for="projectTitle" class="form-label">New Project Title</label> | |
| <input type="text" class="form-control" maxlength="50" formControlName="project_name" (input)="removeSpecialCharAndFirstCharIfNumber($event)"> | |
| <div class="form-text">Title for your Project (Min 5 Character to Max 50 Characters)</div> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="projectDescription" class="form-label">New Project Description</label> | |
| <textarea type="text" class="form-control" rows="5" maxlength="500" formControlName="description"></textarea> | |
| <div class="form-text">Description for your Project (Min 1 Character to Max 500 Characters)</div> | |
| </div> | |
| </form> | |
| </div> | |
| <div class="modal-footer"> | |
| <button class="btn btn-secondary" data-bs-dismiss="modal" (click)="onPreCopClose($event)">Cancel</button> | |
| <button class="btn btn-primary" (click)="onCopy($event)">Copy</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Modal --> | |
| <div class="modal fade" id="shareProject" tabindex="-1" aria-labelledby="shareProject" aria-hidden="true"> | |
| <div class="modal-dialog"> | |
| <div class="modal-content"> | |
| <div class="modal-header"> | |
| <h5 class="modal-title" id="shareProject">Share - Project</h5> | |
| <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | |
| </div> | |
| <div class="modal-body"> | |
| <form class="form" [formGroup]="sharedWithOther" > | |
| <label for="inputShareWith" class="visually-hidden"><b>Share with</b></label> | |
| <div class="d-flex flex-row justify-space-between mb-3 g-3"> | |
| <div class="p-2"><input type="text" class="form-control" id="inputShareWith" placeholder="Username" formControlName="username" #username></div> | |
| <div class="p-2"><button class="btn btn-info" (click)="addSharedWith(username.value)"><i class='bx bx-user-plus' ></i></button></div> | |
| </div> | |
| <ng-container formArrayName="shared_with"> | |
| <ng-container *ngFor="let skill of sharedWith.controls; let i=index"> | |
| <ng-container [formGroupName]="i" class="mb-5"> | |
| <div class="row g-3 mb-3"> | |
| <div class="col-5"> | |
| <label for="username" class="visually-hidden">Username</label> | |
| <input type="text" class="form-control form-control-sm" id="username" formControlName="username" readonly> | |
| </div> | |
| <div class="col-5"> | |
| <label for="permission" class="visually-hidden">permission</label> | |
| <select class="form-select form-select-sm" id="permission" formControlName="permission"> | |
| <option disabled [value]="null" [selected]="null==sharedWithOther.value.permission">Select permission</option> | |
| <!-- <option [value]="'OWNER'">OWNER</option> --> | |
| <option [value]="'EDIT'">EDIT</option> | |
| <option [value]="'COPY'">COPY</option> | |
| </select> | |
| </div> | |
| <div class="col-2"> | |
| <button class="btn btn-danger" (click)="removeSharedWith(i)"><i class="bx bx-trash"></i></button> | |
| </div> | |
| </div> | |
| </ng-container> | |
| </ng-container> | |
| </ng-container> | |
| </form> | |
| </div> | |
| <div class="modal-footer"> | |
| <!-- <button class="btn btn-secondary" data-bs-dismiss="modal" (click)="onPreCopClose($event)">Cancel</button> --> | |
| <button class="btn btn-primary" (click)="permissionSave($event)">Apply</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Modal HTML --> | |
| <div id="deleteModal" class="modal fade"> | |
| <div class="modal-dialog modal-confirm"> | |
| <div class="modal-content"> | |
| <div class="modal-header flex-column"> | |
| <div class="icon-box"> | |
| <i class='bx bx-x bx-size'></i> | |
| </div> | |
| <h4 class="modal-title">Are you sure?</h4> | |
| </div> | |
| <div class="modal-body"> | |
| <p>Do you really want to delete this Project? <br> This process cannot be undone.</p> | |
| </div> | |
| <div class="modal-footer justify-content-center"> | |
| <button class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> | |
| <button class="btn btn-danger" (click)="onDelete($event)">Delete</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { ToastrService } from 'ngx-toastr'; | |
| import { catchError, finalize, of } from 'rxjs'; | |
| import { HttpParams } from '@angular/common/http'; | |
| import { Component, OnInit } from '@angular/core'; | |
| import { ActivatedRoute, Router } from '@angular/router'; | |
| import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms'; | |
| import { removeSpecialCharAndFirstCharIfNumber } from '../shared/util/util'; | |
| import { WorkspaceApiService } from '../workspace/service/workspace-api.service'; | |
| import { WorkspaceStateService } from '../workspace/state/workspace-state.service'; | |
| declare var $: any; | |
| @Component({ | |
| selector: 'app-project-view', | |
| templateUrl: './project-view.component.html', | |
| styleUrls: ['./project-view.component.css'] | |
| }) | |
| export class ProjectViewComponent implements OnInit { | |
| private subscriptions$:any = []; | |
| public unit_systems:any[] = ["SI"]; | |
| public maxWordsForName:number = 50; | |
| public maxWordsForDescription:number = 500; | |
| public project_info:any = {}; | |
| public project_data:any = {}; | |
| public projectInfo: FormGroup = this.fb.group({ | |
| pid:[undefined], | |
| project_name: [null, [Validators.required, Validators.min(5), Validators.maxLength(50),]], | |
| description: [undefined, [Validators.maxLength(500)]], | |
| unit_system: [{value: undefined}, Validators.required,], | |
| }); | |
| public sharedWithOther: FormGroup = this.fb.group({ | |
| pid:[undefined], | |
| username:[undefined], | |
| shared_with: this.fb.array([]), | |
| }); | |
| get sharedWith() : FormArray { return this.sharedWithOther.get("shared_with") as FormArray } | |
| addSharedWith(username:any=undefined, permission:any='COPY') { | |
| this.sharedWith.push(this.fb.group({username,permission,})); | |
| } | |
| removeSharedWith(i:number) { this.sharedWith.removeAt(i); } | |
| clearPermissions = () => { while (this.sharedWith.length !== 0) { this.sharedWith.removeAt(0); } } | |
| permissionSave(event:any){ | |
| this.sharedWithOther.patchValue({pid: this.project_info.pid}); | |
| this.subscriptions$.push(this.apiService.save_project_permissions_api(this.sharedWithOther.value).pipe( | |
| finalize(()=>{$('#shareProject')?.modal('hide');}), | |
| catchError((err)=>{this.toastr.error(err?.error?.msg, "API Error!");return (err)}), | |
| ).subscribe( | |
| (resp:any) => { | |
| this.clearPermissions(); | |
| resp?.data?.forEach((item: any) => this.addSharedWith(item.username, item.permission,)); | |
| this.toastr.success(resp.msg, "Successful"); | |
| } | |
| )); | |
| } | |
| fetchPermissions(event:any){ | |
| this.subscriptions$.push(this.apiService.get_project_permissions_api(this.project_info.pid).subscribe( | |
| (resp:any) => { | |
| this.clearPermissions(); | |
| resp.data.forEach((item: any) => this.addSharedWith(item.username, item.permission,)); | |
| } | |
| )); | |
| } | |
| constructor( | |
| private router: Router, | |
| private fb: FormBuilder, | |
| private toastr: ToastrService, | |
| private activatedRoute: ActivatedRoute, | |
| public apiService:WorkspaceApiService, | |
| public stateService:WorkspaceStateService, | |
| ) { } | |
| ngOnInit(): void { | |
| // ---------------------------------------------------------------------------- | |
| // fetch Project data via api | |
| // ---------------------------------------------------------------------------- | |
| this.activatedRoute.queryParamMap.subscribe((queryParamMap:any)=>{ | |
| if(queryParamMap.params.pid!=undefined && queryParamMap.params.pid != 0){ | |
| let params = new HttpParams().set('only_info', true); | |
| this.subscriptions$.push(this.apiService.get_project_api(queryParamMap.params.pid,params).subscribe( | |
| (resp:any) => { | |
| this.project_info = resp.data.project_info; | |
| this.project_data = resp.data.project_data; | |
| this.patchValue(resp.data.project_info); | |
| } | |
| )); | |
| } | |
| }); | |
| } | |
| ngOnDestroy(): void { | |
| this.subscriptions$.forEach((subscription:any)=>subscription.unsubscribe()); | |
| } | |
| patchValue(values:any) { | |
| this.projectInfo.patchValue(values); | |
| } | |
| onSave(event:any) { | |
| // this.project_info.project_name = this.projectInfo.value.project_name; | |
| // alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.projectInfo.value, null, 4)); | |
| this.subscriptions$.push(this.apiService.update_project_api(this.projectInfo.value).subscribe( | |
| (resp:any) => { | |
| this.toastr.success("Your changes have been saved successfully!", "Successful"); | |
| this.project_info = resp.data.project_info; | |
| this.patchValue(resp.data.project_info); | |
| this.router.navigate(['/dashboard']); | |
| }, | |
| (error: any) => { | |
| this.toastr.error(error.error.msg, "API Error!"); | |
| } | |
| )); | |
| } | |
| onMakeTemplateProject(event?:any) { | |
| // this.project_info.project_name = this.projectInfo.value.project_name; | |
| // alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.projectInfo.value, null, 4)); | |
| // return; | |
| this.subscriptions$.push(this.apiService.make_project_template_api(this.projectInfo.value).subscribe( | |
| (resp:any) => { | |
| this.toastr.success(resp.msg, "Successful"); | |
| }, | |
| (error: any) => { | |
| this.toastr.error(error.error.msg, "API Error!"); | |
| } | |
| )); | |
| } | |
| onPreCopy(event?:any) { | |
| const project_name = this.projectInfo.getRawValue()?.project_name + "_copy"; | |
| this.projectInfo.patchValue({project_name}); | |
| } | |
| onPreCopClose(event?:any) { | |
| const project_name = this.projectInfo.getRawValue()?.project_name.replace("_copy", ""); | |
| this.projectInfo.patchValue({project_name}); | |
| } | |
| onCopy(event?:any) { | |
| this.stateService.clear(); | |
| this.subscriptions$.push(this.apiService.copy_project_api(this.projectInfo.value).subscribe( | |
| (resp:any) => { | |
| $('#makeACopyModal').modal('hide'); | |
| this.router.navigate(['/dashboard'], { queryParams: { pid: resp.data.pid } }); | |
| }, | |
| (e:any) => {console.error(e)} | |
| )); | |
| } | |
| onDelete(event:any) { | |
| this.subscriptions$.push(this.apiService.delete_project_api(this.projectInfo.value).pipe( | |
| finalize(()=>{$('#deleteModal').modal('hide');}), | |
| catchError((err)=>{ | |
| this.toastr.error(err.error.msg, "API Error!"); | |
| return err; | |
| }) | |
| ).subscribe( | |
| (resp:any) => { | |
| this.toastr.success("Deleted Successfully", "Successful"); | |
| this.router.navigate(['/dashboard']); | |
| })); | |
| } | |
| removeSpecialCharAndFirstCharIfNumber(event:any){ | |
| // const str = removeSpecialCharAndFirstCharIfNumber(event.target.value); | |
| let str = event.target.value.replace(/[^A-Z0-9_ ]/ig, ""); | |
| str = str.replace(/^[0-9_]+/, ""); | |
| this.projectInfo.patchValue({project_name:str}); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment