sitetree
This commit is contained in:
parent
0ced644864
commit
5e70585afc
Binary file not shown.
Binary file not shown.
@ -62,6 +62,9 @@
|
||||
<clr-dg-column [clrDgField]="'Java Code'"> <ng-container *clrDgHideableColumn="{hidden: false}"> javacode
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
<!-- <clr-dg-column [clrDgField]="'tag'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Tag
|
||||
</ng-container></clr-dg-column> -->
|
||||
|
||||
<clr-dg-column [clrDgField]="'Active'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Active
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
@ -107,6 +110,9 @@
|
||||
style="cursor: pointer; align-items: center;"><clr-icon shape="details"></clr-icon>
|
||||
</clr-dg-cell>
|
||||
|
||||
<!-- <clr-dg-cell>{{user.tag }}</clr-dg-cell> -->
|
||||
|
||||
|
||||
<clr-dg-cell>{{user. active }}</clr-dg-cell>
|
||||
|
||||
|
||||
@ -377,6 +383,14 @@
|
||||
placeholder="Textarea"> </textarea>
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label>Tag</label>
|
||||
<select name="tag" [(ngModel)]="rowSelected.tag">
|
||||
<option [value]="null">Choose Tag</option>
|
||||
<option *ngFor=" let item of selectTagdata" [value]="item.id">{{item.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -497,6 +511,14 @@
|
||||
<textarea cols="10" rows="2" formControlName="javacode" placeholder="Textarea"> </textarea>
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Tag</label>
|
||||
<select formControlName="tag">
|
||||
<option [value]="null">Choose Tag</option>
|
||||
<option *ngFor="let item of selectTagdata " [value]="item.id">{{item.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import { UserInfoService } from 'src/app/services/user-info.service';
|
||||
import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
|
||||
import { COMMON_CSS } from '../WireframesUi/common-css';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Tagservice } from '../Tag/Tag.service';
|
||||
declare var JsBarcode: any;
|
||||
@Component({
|
||||
selector: 'app-Design_lbrary',
|
||||
@ -44,6 +45,7 @@ export class Design_lbraryComponent implements OnInit {
|
||||
modaldelete = false;
|
||||
modalEdit = false;
|
||||
modalAdd = false;
|
||||
selectTagdata;
|
||||
public entryForm: FormGroup;
|
||||
loading = false;
|
||||
product;
|
||||
@ -61,6 +63,7 @@ export class Design_lbraryComponent implements OnInit {
|
||||
private _fb: FormBuilder,
|
||||
private siteTreeService: SiteTreeservice,
|
||||
private route: ActivatedRoute,
|
||||
private tagService: Tagservice,
|
||||
|
||||
) { }
|
||||
// component button
|
||||
@ -74,6 +77,7 @@ export class Design_lbraryComponent implements OnInit {
|
||||
}
|
||||
this.userrole = this.userInfoService.getRoles();
|
||||
this.getData();
|
||||
this.getallTags();
|
||||
this.entryForm = this._fb.group({
|
||||
name: [null],
|
||||
|
||||
@ -82,6 +86,8 @@ export class Design_lbraryComponent implements OnInit {
|
||||
active: [false],
|
||||
|
||||
htmljson: [null],
|
||||
tag: [null],
|
||||
|
||||
|
||||
css: [null],
|
||||
templatetype: [null],
|
||||
@ -247,6 +253,14 @@ export class Design_lbraryComponent implements OnInit {
|
||||
this.rowSelected = row; this.rsModaljavacode = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
getallTags() {
|
||||
this.tagService.getAll().subscribe(data => {
|
||||
this.selectTagdata = data;
|
||||
console.log('tag data ', data);
|
||||
}, (error) => { console.log(error); });
|
||||
}
|
||||
// updateaction
|
||||
|
||||
public htmlContent: string = '';
|
||||
|
||||
@ -31,15 +31,5 @@ export class Design_lbraryservice {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// updateaction
|
||||
}
|
||||
@ -15,11 +15,9 @@
|
||||
<button id="add" class="btn btn-primary" (click)="goToAdd(product)">
|
||||
<clr-icon shape="plus"></clr-icon>ADD
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="!isCardview"> <!-- GET ALL --> <clr-datagrid [clrDgLoading]="loading"
|
||||
[(clrDgSelected)]="selected">
|
||||
<clr-dg-placeholder>
|
||||
@ -29,7 +27,7 @@
|
||||
<div *ngIf="error;else loadingSpinner">{{error}}</div>
|
||||
</clr-dg-placeholder>
|
||||
|
||||
<clr-dg-column [clrDgField]="' name'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Name
|
||||
<clr-dg-column [clrDgField]="' name'"> <ng-container *clrDgHideableColumn="{hidden: false}">Website Name
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
|
||||
@ -49,7 +47,7 @@
|
||||
|
||||
<clr-dg-row *clrDgItems="let user of product?.slice()?.reverse()" [clrDgItem]="user">
|
||||
|
||||
<clr-dg-cell>{{user. name }}</clr-dg-cell>
|
||||
<clr-dg-cell>{{user.name }}</clr-dg-cell>
|
||||
|
||||
|
||||
<clr-dg-cell (click)="goToReplaceStringdescription (user.description)"
|
||||
@ -57,7 +55,7 @@
|
||||
</clr-dg-cell>
|
||||
|
||||
|
||||
<clr-dg-cell>{{user. active }}</clr-dg-cell>
|
||||
<clr-dg-cell>{{user.active }}</clr-dg-cell>
|
||||
|
||||
|
||||
<!-- who column -->
|
||||
@ -98,6 +96,9 @@
|
||||
</clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid> </ng-container>
|
||||
|
||||
|
||||
|
||||
<ng-template #showInfo>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<div class="alert-items">
|
||||
@ -110,13 +111,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</ng-template><ng-container *ngIf="isCardview">
|
||||
|
||||
<div *ngIf="product; else showInfo" class="clr-row clr-align-items-start clr-justify-content-start">
|
||||
<div *ngFor="let app of product| filter:search; let index = i" class="clr-col-auto">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-lg-12 clr-col-md-4 clr-col-sm-4 clr-col-12" style="width: 410px;">
|
||||
<div class="card" style="padding: 10px; "
|
||||
[style.background-color]="cardmodal.cardColor !== '' ? cardmodal.cardColor : 'white'">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="card-body"
|
||||
style="display: grid; grid-template-columns: repeat(13, 1fr); grid-template-rows: repeat(7, 1fr); gap: 5px;">
|
||||
<ng-container *ngFor="let item of dashboardArray">
|
||||
@ -224,20 +232,107 @@
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<!-- card view start -->
|
||||
<!-- <div *ngIf="isCardview" class="project-container" style="height: 600px; overflow-y: scroll;">
|
||||
<div *ngIf="product else showInfo" class="clr-row clr-align-items-start clr-justify-content-start"
|
||||
style="margin: 0px;">
|
||||
<div *ngFor="let app of product | filter:search; let index = i" class="clr-col-auto">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-lg-12 clr-col-md-4 clr-col-sm-4 clr-col-12" style="width: 410px;">
|
||||
<div class="card" (click)="gotositebuilder(app.id)">
|
||||
<div class="card-header">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-5">
|
||||
<b style="font-size: 15px; display: inline-block;
|
||||
width: 180px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis;" [title]="app.name"> {{app.name}}</b>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-title1" id="word">
|
||||
<b class="word" style="font-size: 15px; " [title]="app.projectName">{{app.projectName}}</b>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-9">
|
||||
<div class="card-title1" id="word">
|
||||
<b style="font-size: 15px;" class="p2" [title]="app.description">{{app.description}}</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clr-col-3"
|
||||
style="text-align: right; display: flex; align-items: center; justify-content: flex-end; padding:0;">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 0 10px;cursor: pointer;position:relative; "
|
||||
(click)="openModal(app.id);$event.stopPropagation();">
|
||||
|
||||
<clr-progress-bar [clrValue]="app.progressValue" clrLabeled></clr-progress-bar>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-block" style="padding: 10px 10px 0px 10px;">
|
||||
|
||||
<div class="card-text">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-7">
|
||||
<span *ngFor="let tech of app?.technology?.slice(0, 6); let i = index">
|
||||
<span class="label label-light-blue p7 wordwrap" style="margin-top: .4em;" [title]="tech">
|
||||
{{tech}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="clr-col-5" (click)="stopRedirection($event)" style="-ms-flex-align: end;">
|
||||
<div class="profile-pics">
|
||||
<ng-container *ngFor="let imageitem of app?.images; let i = index">
|
||||
<img (click)="openprofile(app.id); $event.stopPropagation();"
|
||||
[src]="imageitem?.image ? imageitem?.image : '../../../../../assets/images/images.png'"
|
||||
[title]="imageitem?.user_name" [style.z-index]="i + 2" [style.left.rem]="i * 0.9"
|
||||
[style.display]="i < 5 ? 'block' : 'none'" />
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" style="padding: 0px 10px 6px 10px">
|
||||
<button class="btn btn-sm btn-link"> Last Updated On: {{app.updatedAt|date}}</button> <span
|
||||
style="margin: 0 0 0 10px; padding: 5px;" class="label p7"><clr-icon
|
||||
shape="calendar"></clr-icon> {{app.createdAt | timePipe}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div> -->
|
||||
<!-- card view end -->
|
||||
|
||||
|
||||
|
||||
<clr-modal [(clrModalOpen)]="rsModaldescription" [clrModalSize]="'xl'" [clrModalStaticBackdrop]="true">
|
||||
<clr-modal [(clrModalOpen)]="rsModaldescription" [clrModalSize]="'xl'" [clrModalStaticBackdrop]="true">
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" style="width:100%; height: 400px;" readonly>{{rowSelected}}</textarea>
|
||||
</div>
|
||||
</clr-modal>
|
||||
</clr-modal>
|
||||
|
||||
|
||||
|
||||
<!-- // EDIT DATA......... -->
|
||||
<clr-modal [(clrModalOpen)]="modalEdit" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<!-- // EDIT DATA......... -->
|
||||
<clr-modal [(clrModalOpen)]="modalEdit" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<h3 class="modal-title">Update Site Builder <!--update button -->
|
||||
|
||||
|
||||
@ -251,7 +346,7 @@
|
||||
<form>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-sm-12">
|
||||
<label>Name</label>
|
||||
<label>Website Name</label>
|
||||
<input class="clr-input" type="text" [(ngModel)]="rowSelected.name" name="name" />
|
||||
</div>
|
||||
|
||||
@ -270,8 +365,51 @@
|
||||
|
||||
|
||||
|
||||
<h6> List of logoupload</h6>
|
||||
|
||||
<div class="clr-row" style="margin-top: 10px;">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th> File</th>
|
||||
<th>File Name</th>
|
||||
<th>Preview</th>
|
||||
<th>Cancel</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let attach of FileDatalogoupload; let i=index">
|
||||
<td style="width: 70px;"><input type="text" class="clr-input" value={{i+1}} [readonly]="true"> </td>
|
||||
<td><input type="file" (change)="onFileChangedlogoupload($event, i)" accept="image/*" />
|
||||
</td>
|
||||
<td>{{attach.uploadedfile_name}}</td>
|
||||
<td> <img [src]="attach.filePreview" alt="File Preview" [ngModelOptions]="{standalone: true}"
|
||||
name="filePreview" width="100px" height="100px"></td>
|
||||
<td>
|
||||
<clr-signpost style="padding-right: 10px;">
|
||||
<clr-icon shape="trash" class="is-error" aria-label="Icon Button Trigger"
|
||||
clrSignpostTrigger></clr-icon>
|
||||
|
||||
<clr-signpost-content [clrPosition]="'bottom-middle'" *clrIfOpen>
|
||||
<div style="text-align: center;"><b>Are you sure?</b></div>
|
||||
<button class="btn btn-outline" [clrSignpostTrigger]="false">cancel</button>
|
||||
<button class="btn btn-primary" (click)="deleteRowlogoupload(i,attach.id)">Delete</button>
|
||||
</clr-signpost-content>
|
||||
</clr-signpost>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
<button type="button" class="btn btn-primary button1" style="margin-left: 20px;"
|
||||
(click)="onAddLineslogoupload()">
|
||||
<clr-icon shape="plus"></clr-icon>
|
||||
</button>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- form code start -->
|
||||
<div *ngIf="checkFormCode">
|
||||
@ -290,8 +428,8 @@
|
||||
[(ngModel)]="rowSelected[field.extValue]" class="clr-input" />
|
||||
|
||||
<!-- Textarea --> <label *ngSwitchCase="'textarea'">{{ field.fieldName }}</label>
|
||||
<textarea *ngSwitchCase="'textarea'" name="{{ field.extValue }}" [(ngModel)]="rowSelected[field.extValue]"
|
||||
col="10" row="2"></textarea>
|
||||
<textarea *ngSwitchCase="'textarea'" name="{{ field.extValue }}"
|
||||
[(ngModel)]="rowSelected[field.extValue]" col="10" row="2"></textarea>
|
||||
|
||||
<!-- Checkbox --> <label *ngSwitchCase="'checkbox'">{{ field.fieldName }}</label><br>
|
||||
<input *ngSwitchCase="'checkbox'" [type]="field.fieldType" name="{{ field.extValue }}"
|
||||
@ -308,8 +446,8 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</clr-modal>
|
||||
<clr-modal [(clrModalOpen)]="modaldelete" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
</clr-modal>
|
||||
<clr-modal [(clrModalOpen)]="modaldelete" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<div class="modal-body" *ngIf="rowSelected.id">
|
||||
<h1 class="delete">Are You Sure Want to delete?</h1>
|
||||
<h2 class="heading">{{rowSelected.id}}</h2>
|
||||
@ -318,16 +456,17 @@
|
||||
<button type="button" (click)="delete(rowSelected.id)" class="btn btn-primary">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</clr-modal>
|
||||
<!-- ADD FORM ..... -->
|
||||
<clr-modal [(clrModalOpen)]="modalAdd" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
</clr-modal>
|
||||
<!-- ADD FORM ..... -->
|
||||
<clr-modal [(clrModalOpen)]="modalAdd" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<h3 class="modal-title">Add Site Builder
|
||||
|
||||
<!-- aeroplane icon -->
|
||||
|
||||
<a *ngIf="userrole.includes('ROLE_ADMIN')" style="float: right;" href="javascript:void(0)" role="tooltip"
|
||||
<a *ngIf="userrole?.includes('ROLE_ADMIN')" style="float: right;" href="javascript:void(0)" role="tooltip"
|
||||
aria-haspopup="true" class="tooltip tooltip-sm tooltip-bottom-left">
|
||||
<a id="build_extension" [routerLink]="['../extension/all']" [queryParams]="{ formCode: 'Visa_status_formCode' }">
|
||||
<a id="build_extension" [routerLink]="['../extension/all']"
|
||||
[queryParams]="{ formCode: 'Visa_status_formCode' }">
|
||||
<clr-icon shape="airplane" size="32"></clr-icon>
|
||||
</a>
|
||||
<span class="tooltip-content">Form Extension</span>
|
||||
@ -338,7 +477,7 @@
|
||||
<div class="clr-row" style="height: fit-content;">
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Name</label>
|
||||
<label>Website Name</label>
|
||||
<input class="clr-input" type="text" formControlName="name" />
|
||||
</div>
|
||||
|
||||
@ -351,16 +490,47 @@
|
||||
<label> Active</label>
|
||||
<input type="checkbox" formControlName="active" clrToggle />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h6> List of logoupload</h6>
|
||||
|
||||
<div class="clr-row" style="margin-top: 10px;">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th> File</th>
|
||||
<th>File Name</th>
|
||||
<th>Preview</th>
|
||||
<th>Cancel</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let attach of FileDatalogoupload; let i=index">
|
||||
<td style="width: 70px;"><input type="text" class="clr-input" value={{i+1}} [readonly]="true"> </td>
|
||||
<td><input type="file" (change)="onFileChangedlogoupload($event, i)"
|
||||
accept="image/*" /><!--accept=".pdf,.doc,.docx,.jpg,.msg"-->
|
||||
</td>
|
||||
<td>{{attach.uploadedfile_name}}</td>
|
||||
<td> <img [src]="attach.filePreview" alt="File Preview" [ngModelOptions]="{standalone: true}"
|
||||
name="filePreview" width="100px" height="100px"></td>
|
||||
<td>
|
||||
<a (click)="deleteRowlogoupload(i)">
|
||||
<clr-icon shape="trash" class="is-error"></clr-icon>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
<button type="button" class="btn btn-primary button1" style="margin-left: 20px;"
|
||||
(click)="onAddLineslogoupload()">
|
||||
<clr-icon shape="plus"></clr-icon>
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- form code start -->
|
||||
<div *ngIf="checkFormCode">
|
||||
@ -392,11 +562,6 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</clr-modal>
|
||||
</clr-modal>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- htmlpopup -->
|
||||
<!-- htmlpopup -->
|
||||
@ -59,19 +59,21 @@ export class SiteTreeComponent implements OnInit {
|
||||
) { }
|
||||
// component button
|
||||
ngOnInit(): void {
|
||||
|
||||
this.getData();
|
||||
|
||||
if (this.cardmodeldata !== '') {
|
||||
this.cardmodal = JSON.parse(this.cardmodeldata);
|
||||
this.dashboardArray = this.cardmodal.dashboard.slice();
|
||||
console.log(this.dashboardArray)
|
||||
console.log('card data ', this.dashboardArray)
|
||||
}
|
||||
this.userrole = this.userInfoService.getRoles();
|
||||
this.getData();
|
||||
this.entryForm = this._fb.group({
|
||||
name: [null],
|
||||
|
||||
description: [null],
|
||||
|
||||
active: [false],
|
||||
active: [true],
|
||||
|
||||
}); // component_button200
|
||||
// form code start
|
||||
@ -99,11 +101,15 @@ export class SiteTreeComponent implements OnInit {
|
||||
}
|
||||
|
||||
|
||||
FileDataLogoupload: any[];
|
||||
selectedLogoupload: any[];
|
||||
|
||||
error;
|
||||
getData() {
|
||||
this.mainService.getAll().subscribe((data) => {
|
||||
console.log(data);
|
||||
this.product = data;
|
||||
console.log('site data ', this.product);
|
||||
if (this.product.length == 0) {
|
||||
this.error = "No Data Available"
|
||||
}
|
||||
@ -116,6 +122,15 @@ export class SiteTreeComponent implements OnInit {
|
||||
}
|
||||
onEdit(row) {
|
||||
this.rowSelected = row;
|
||||
|
||||
|
||||
|
||||
this.selectedlogoupload = [];
|
||||
this.mainService.uploadLogouploadgetById(row.id, this.tableName).subscribe(uploaddata => {
|
||||
console.log(uploaddata);
|
||||
this.FileDatalogoupload = uploaddata;
|
||||
|
||||
})
|
||||
this.modalEdit = true;
|
||||
}
|
||||
onDelete(row) {
|
||||
@ -149,6 +164,13 @@ export class SiteTreeComponent implements OnInit {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
|
||||
|
||||
for (let i = 0; i < this.selectedlogoupload.length; i++) {
|
||||
|
||||
this.mainService.uploadLogoupload(data.id, this.tableName, this.selectedlogoupload[i]).subscribe(uploaddata => {
|
||||
console.log(uploaddata);
|
||||
})
|
||||
}
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error.status >= 200 && error.status <= 299) {
|
||||
@ -178,6 +200,13 @@ export class SiteTreeComponent implements OnInit {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
|
||||
|
||||
for (let i = 0; i < this.selectedlogoupload.length; i++) {
|
||||
|
||||
this.mainService.uploadLogoupload(data.id, this.tableName, this.selectedlogoupload[i]).subscribe(uploaddata => {
|
||||
console.log(uploaddata);
|
||||
})
|
||||
}
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error.status >= 200 && error.status <= 299) {
|
||||
@ -195,7 +224,9 @@ export class SiteTreeComponent implements OnInit {
|
||||
}, 500);
|
||||
}
|
||||
goToAdd(row) {
|
||||
this.modalAdd = true; this.submitted = false;
|
||||
console.log('go to add ')
|
||||
this.modalAdd = true;
|
||||
this.submitted = false;
|
||||
|
||||
}
|
||||
|
||||
@ -218,6 +249,47 @@ export class SiteTreeComponent implements OnInit {
|
||||
|
||||
|
||||
|
||||
filePreviewlogoupload: string | ArrayBuffer | null = null;
|
||||
FileDatalogoupload: { uploadedfile_name?: any, filePreview: string | ArrayBuffer | null }[] = []; // Initialize the array
|
||||
selectedlogoupload: File[] = [];
|
||||
public onFileChangedlogoupload(event, index) {
|
||||
const files = event.target.files;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
this.FileDatalogoupload[index].uploadedfile_name = files[i].name;
|
||||
this.selectedlogoupload.push(files[i]);
|
||||
if (file.type.startsWith('image/')) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
// Set the file preview source
|
||||
const filePreview = e.target?.result as string;
|
||||
this.FileDatalogoupload[index] = {
|
||||
...this.FileDatalogoupload[index], // Preserve existing properties
|
||||
filePreview: filePreview // Update only the filePreview property
|
||||
};
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
onAddLineslogoupload() {
|
||||
this.FileDatalogoupload.push({
|
||||
uploadedfile_name: "",
|
||||
filePreview: "",
|
||||
// f3: "",
|
||||
});
|
||||
}
|
||||
deleteRowlogoupload(index, id) {
|
||||
this.FileDatalogoupload.splice(index, 1);
|
||||
|
||||
if (id) {
|
||||
this.mainService.uploadLogouploaddelete(id).subscribe(data => {
|
||||
console.log(data);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// updateaction
|
||||
|
||||
gotositebuilder(id) {
|
||||
|
||||
@ -10,6 +10,7 @@ export class SiteTreeservice {
|
||||
private baseURL = "SiteTree/SiteTree";
|
||||
private dlfbaseURL = environment.nodeUrl + "/entityBuilder";
|
||||
private llmURL = environment.nodeUrl + "/llm";
|
||||
private geminiURL = environment.ollamaUrl;
|
||||
|
||||
|
||||
constructor(
|
||||
@ -72,20 +73,20 @@ export class SiteTreeservice {
|
||||
const formattedSiteName = this.formatSiteName(siteName);
|
||||
const _http = `${this.baseURL}/deploy?siteId=${siteId}&siteBuilderName=${formattedSiteName}`;
|
||||
return this.apiRequest.post(_http, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
createHtmlfile(siteId: number, siteName: string, data: any): Observable<any> {
|
||||
const formattedSiteName = this.formatSiteName(siteName);
|
||||
const _http = `${this.baseURL}/createFile?siteId=${siteId}&siteBuilderName=${formattedSiteName}`;
|
||||
return this.apiRequest.post(_http, data);
|
||||
}
|
||||
}
|
||||
|
||||
readPages( siteName: string, pageName: string): Observable<any> {
|
||||
readPages(siteName: string, pageName: string): Observable<any> {
|
||||
const formattedSite = this.formatSiteName(siteName);
|
||||
const _http = `${this.baseURL}/read?siteBuilderName=${formattedSite}&filename=${pageName}`;
|
||||
return this.apiRequest.get(_http, undefined, 'text');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -98,7 +99,7 @@ readPages( siteName: string, pageName: string): Observable<any> {
|
||||
.replace(/([a-z])([A-Z])/g, '$1_$2') // Convert camelCase to snake_case
|
||||
.replace(/\s+/g, '_') // Replace spaces with underscores
|
||||
.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
// readPages(siteNmae: String, pageNmae: String): Observable<any> {
|
||||
|
||||
@ -110,5 +111,22 @@ readPages( siteName: string, pageName: string): Observable<any> {
|
||||
return this.http.post(`${this.llmURL}/api/gemini`, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uploadLogoupload(ref: any, Sitebuilder: any, file: any): Observable<any> {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return this.apiRequest.postFormData(`FileUpload/Uploadeddocs/${ref}/${Sitebuilder}`, formData);
|
||||
}
|
||||
|
||||
uploadLogouploadgetById(ref: any, Sitebuilder: any,): Observable<any> {
|
||||
return this.apiRequest.get(`FileUpload/Uploadeddocs/${ref}/${Sitebuilder}`);
|
||||
}
|
||||
|
||||
|
||||
uploadLogouploaddelete(id: number): Observable<any> {
|
||||
return this.apiRequest.delete(`FileUpload/Uploadeddocs/${id}`);
|
||||
}
|
||||
// updateactionƒ
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
export const SiteTreecardvariable = {
|
||||
"cardButton": false,
|
||||
// "cardmodeldata": ``
|
||||
"cardmodeldata": ``
|
||||
|
||||
}
|
||||
@ -0,0 +1,376 @@
|
||||
<ol class="breadcrumb breadcrumb-arrow font-trirong">
|
||||
<li><a href="javascript://"> Tag</a></li>
|
||||
</ol>
|
||||
<div class="dg-wrapper">
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-8">
|
||||
<h3>Tag </h3>
|
||||
</div>
|
||||
<div class="clr-col-4" style="text-align: right;">
|
||||
<button *ngIf="cardButton" id="add" class="btn btn-primary btn-icon" (click)="changeView()" >
|
||||
<clr-icon *ngIf="!isCardview" shape="grid-view"></clr-icon> <clr-icon *ngIf="isCardview" shape="bars"></clr-icon>
|
||||
</button>
|
||||
<!-- button -->
|
||||
<button id="add" class="btn btn-primary" (click)="goToAdd(product)" >
|
||||
<clr-icon shape="plus"></clr-icon>ADD
|
||||
</button>
|
||||
</div></div>
|
||||
<ng-container *ngIf="!isCardview"> <!-- GET ALL --> <clr-datagrid [clrDgLoading]="loading" [(clrDgSelected)]="selected">
|
||||
<clr-dg-placeholder>
|
||||
<ng-template #loadingSpinner>
|
||||
<clr-spinner>Loading ... </clr-spinner>
|
||||
</ng-template>
|
||||
<div *ngIf="error;else loadingSpinner">{{error}}</div>
|
||||
</clr-dg-placeholder>
|
||||
|
||||
<clr-dg-column [clrDgField]="' name'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Name
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
|
||||
<clr-dg-column [clrDgField]="' description'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Description
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
|
||||
<clr-dg-column [clrDgField]="' active'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Active
|
||||
</ng-container></clr-dg-column>
|
||||
|
||||
|
||||
<!-- who column -->
|
||||
<clr-dg-column> <ng-container *clrDgHideableColumn="{hidden: false}">
|
||||
<clr-icon shape="bars"></clr-icon> Action
|
||||
</ng-container></clr-dg-column>
|
||||
<!-- end -->
|
||||
|
||||
<clr-dg-row *clrDgItems="let user of product" [clrDgItem]="user">
|
||||
|
||||
<clr-dg-cell>{{user. name }}</clr-dg-cell>
|
||||
|
||||
|
||||
<clr-dg-cell (click)="goToReplaceStringdescription (user.description)" style="cursor: pointer; align-items: center;"><clr-icon shape="details"></clr-icon>
|
||||
</clr-dg-cell>
|
||||
|
||||
|
||||
<clr-dg-cell>{{user. active }}</clr-dg-cell>
|
||||
|
||||
|
||||
<!-- who column -->
|
||||
<clr-dg-cell>
|
||||
<clr-signpost>
|
||||
<span style="cursor: pointer;" clrSignpostTrigger><clr-icon shape="help" class="success" style="color: rgb(0, 130, 236);"></clr-icon></span>
|
||||
<clr-signpost-content [clrPosition]="'left-middle'" *clrIfOpen>
|
||||
<h5 style="margin-top: 0">Who Column</h5>
|
||||
<div>Account ID: <code class="clr-code">{{user.accountId}}</code></div>
|
||||
<div>Created At: <code class="clr-code">{{user.createdAt| date}}</code></div>
|
||||
<div>Created By: <code class="clr-code">{{user.createdBy}}</code></div>
|
||||
<div>Updated At: <code class="clr-code">{{user.updatedAt | date}}</code></div>
|
||||
<div>Updated By: <code class="clr-code">{{user.updatedBy}}</code></div>
|
||||
</clr-signpost-content>
|
||||
</clr-signpost>
|
||||
</clr-dg-cell>
|
||||
|
||||
<!-- who colmn -->
|
||||
|
||||
<clr-dg-action-overflow>
|
||||
<button class="action-item" (click)="onEdit(user)">Edit</button>
|
||||
<button class="action-item" (click)="onDelete(user)">Delete</button>
|
||||
</clr-dg-action-overflow>
|
||||
</clr-dg-row>
|
||||
<clr-dg-footer>
|
||||
<clr-dg-pagination #pagination [clrDgPageSize]="10">
|
||||
<clr-dg-page-size [clrPageSizeOptions]="[10,20,50,100]">Users per page</clr-dg-page-size>
|
||||
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}}
|
||||
of {{pagination.totalItems}} users
|
||||
</clr-dg-pagination>
|
||||
</clr-dg-footer>
|
||||
</clr-datagrid> </ng-container>
|
||||
<ng-template #showInfo>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<div class="alert-items">
|
||||
<div class="alert-item static">
|
||||
<span class="alert-text">
|
||||
<clr-icon class="alert-icon" shape="info-circle"></clr-icon>
|
||||
Data could be found. Loading..
|
||||
<clr-spinner [clrMedium]="true">Loading ...</clr-spinner>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template><ng-container *ngIf="isCardview">
|
||||
<div *ngIf="product; else showInfo" class="clr-row clr-align-items-start clr-justify-content-start">
|
||||
<div *ngFor="let app of product| filter:search; let index = i" class="clr-col-auto" >
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-lg-12 clr-col-md-4 clr-col-sm-4 clr-col-12" style="width: 410px;">
|
||||
<div class="card" style="padding: 10px; "[style.background-color]="cardmodal.cardColor !== '' ? cardmodal.cardColor : 'white'">
|
||||
<div class="card-body" style="display: grid; grid-template-columns: repeat(13, 1fr); grid-template-rows: repeat(7, 1fr); gap: 5px;">
|
||||
<ng-container *ngFor="let item of dashboardArray">
|
||||
<div [style.gridColumn]="item.x + 1" [style.gridRow]="item.y + 1" [style.gridColumnEnd]="item.x + item.cols + 1"
|
||||
[style.gridRowEnd]="item.y + item.rows + 1">
|
||||
<div *ngIf="item.name === 'textField'" class="title-card card-title"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'" [style.background-color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditionbackgroundcolor : item.backgroundcolor"
|
||||
[style.color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditiontextcolor : item.textcolor">
|
||||
{{beforeText(item.fieldtext)}}
|
||||
{{ app[transform(item.fieldtext) ] }}
|
||||
{{afterText(item.fieldtext)}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="item.name === 'dateField'" class="title-card card-title"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'" [style.background-color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditionbackgroundcolor : item.backgroundcolor"
|
||||
[style.color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditiontextcolor : item.textcolor">
|
||||
{{beforeText(item.fieldtext)}}
|
||||
{{ app[transform(item.fieldtext) ] | date}}
|
||||
{{afterText(item.fieldtext)}}
|
||||
</div>
|
||||
<div *ngIf="item.name === 'numberField'" class="title-card card-title"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'" [style.background-color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditionbackgroundcolor : item.backgroundcolor"
|
||||
[style.color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditiontextcolor : item.textcolor">
|
||||
{{beforeText(item.fieldtext)}}
|
||||
{{ app[transform(item.fieldtext) ]}}
|
||||
{{afterText(item.fieldtext)}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="item.name === 'Line'" class="title-card card-title"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'">
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
|
||||
<div *ngIf="item.name === 'Icon'" class="icon-card"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'"
|
||||
>
|
||||
<clr-icon [attr.shape]="item.iconName"></clr-icon>
|
||||
</div>
|
||||
|
||||
<div *ngIf="item.name == 'Image'"
|
||||
[style.text-align]="item.alignment !== '' ? item.alignment : 'left'"
|
||||
[style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'"
|
||||
[style.font-family]="item.fontName !== '' ? item.fontName : 'Metropolis'"
|
||||
[style.font-size]="item.fontSize !== '' ? item.fontSize : '100%'"
|
||||
[style.font-style]="item.italic == true ? 'Italic' : 'normal'"
|
||||
[style.font-weight]="item.bold == true ? 'bold' : 'normal'" [style.text-decoration]="(item.underline && item.strikethough) ? 'underline line-through' :
|
||||
(item.underline ? 'underline' : (item.strikethough ? 'line-through' : 'none'))"
|
||||
[style.background-color]="item.backgroundcolor !== '' ? item.backgroundcolor : 'white'"
|
||||
[style.color]="item.textcolor !== '' ? item.textcolor : 'black'"
|
||||
[style.background-color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditionbackgroundcolor : item.backgroundcolor"
|
||||
[style.color]="item.conditionValue == app[transform(item.fieldtext) ] ? item.conditiontextcolor : item.textcolor"> <img id="filePreview" [src]="item.imageURL" alt="File Preview"
|
||||
[style.width]="item.imagewidth !== '' ? item.imagewidth + 'px' : '100px'"
|
||||
[style.height]="item.imagewidth !== '' ? item.imagewidth + 'px' : '100px'"></div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<clr-modal [(clrModalOpen)]="rsModaldescription" [clrModalSize]="'xl'" [clrModalStaticBackdrop]="true">
|
||||
<div class="modal-body">
|
||||
<textarea class="form-control" style="width:100%; height: 400px;" readonly>{{rowSelected}}</textarea>
|
||||
</div></clr-modal>
|
||||
|
||||
|
||||
|
||||
<!-- // EDIT DATA......... -->
|
||||
<clr-modal [(clrModalOpen)]="modalEdit" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<h3 class="modal-title">Update Tag
|
||||
<!--update button -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</h3>
|
||||
<div class="modal-body" *ngIf="rowSelected.id">
|
||||
<h2 class="heading">{{rowSelected.id}}</h2>
|
||||
<!-- button -->
|
||||
<form >
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-sm-12">
|
||||
<label>Name</label>
|
||||
<input class="clr-input" type="text" [(ngModel)]="rowSelected.name" name="name" />
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Description</label>
|
||||
<textarea cols="10" rows="2"[(ngModel)]="rowSelected.description" name="description " placeholder="Textarea"> </textarea>
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Active</label>
|
||||
<input type="checkbox" name="active" clrToggle [(ngModel)]="rowSelected.active" /> </div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- form code start -->
|
||||
<div *ngIf="checkFormCode">
|
||||
<h4 style="font-weight: 300;display: inline;">Extension</h4>
|
||||
<br>
|
||||
<hr>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4" *ngFor="let field of additionalFieldsFromBackend">
|
||||
<ng-container *ngIf="field.formCode === formcode" [ngSwitch]="field.fieldType">
|
||||
<!-- Text Input --> <label *ngSwitchCase="'text'">{{ field.fieldName }}</label>
|
||||
<input *ngSwitchCase="'text'" [type]="field.fieldType" name="{{ field.extValue }}" [(ngModel)]="rowSelected[field.extValue]" class="clr-input" />
|
||||
|
||||
<!-- Date Input --> <label *ngSwitchCase="'date'">{{ field.fieldName }}</label>
|
||||
<input *ngSwitchCase="'date'" [type]="field.fieldType" name="{{ field.extValue }}" [(ngModel)]="rowSelected[field.extValue]" class="clr-input" />
|
||||
|
||||
<!-- Textarea --> <label *ngSwitchCase="'textarea'">{{ field.fieldName }}</label>
|
||||
<textarea *ngSwitchCase="'textarea'" name="{{ field.extValue }}" [(ngModel)]="rowSelected[field.extValue]" col="10" row="2"></textarea>
|
||||
|
||||
<!-- Checkbox --> <label *ngSwitchCase="'checkbox'">{{ field.fieldName }}</label><br>
|
||||
<input *ngSwitchCase="'checkbox'" [type]="field.fieldType" name="{{ field.extValue }}" [(ngModel)]="rowSelected[field.extValue]" class="clr-checkbox" />
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- form code end --> <div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="modalEdit = false">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" (click)="onUpdate(rowSelected.id)">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</clr-modal>
|
||||
<clr-modal [(clrModalOpen)]="modaldelete" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<div class="modal-body" *ngIf="rowSelected.id">
|
||||
<h1 class="delete">Are You Sure Want to delete?</h1>
|
||||
<h2 class="heading">{{rowSelected.id}}</h2>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="modaldelete = false">Cancel</button>
|
||||
<button type="button" (click)="delete(rowSelected.id)" class="btn btn-primary" >Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</clr-modal>
|
||||
<!-- ADD FORM ..... -->
|
||||
<clr-modal [(clrModalOpen)]="modalAdd" [clrModalSize]="'lg'" [clrModalStaticBackdrop]="true">
|
||||
<h3 class="modal-title">Add Tag
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- aeroplane icon -->
|
||||
|
||||
<a *ngIf="userrole.includes('ADMIN')" style="float: right;" href="javascript:void(0)" role="tooltip" aria-haspopup="true"
|
||||
class="tooltip tooltip-sm tooltip-bottom-left">
|
||||
<a id="build_extension" [routerLink]="['../extension/all']" [queryParams]="{ formCode: 'Tag_formCode' }">
|
||||
<clr-icon shape="airplane" size="32"></clr-icon>
|
||||
</a>
|
||||
<span class="tooltip-content">Form Extension</span>
|
||||
</a> </h3>
|
||||
<div class="modal-body">
|
||||
<form [formGroup]="entryForm" >
|
||||
<div class="clr-row" style="height: fit-content;">
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Name</label>
|
||||
<input class="clr-input" type="text" formControlName="name" />
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Description</label>
|
||||
<textarea cols="10" rows="2" formControlName="description" placeholder="Textarea"> </textarea>
|
||||
</div>
|
||||
|
||||
<div class="clr-col-sm-12">
|
||||
<label> Active</label>
|
||||
<input type="checkbox" formControlName="active" clrToggle/> </div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- form code start -->
|
||||
<div *ngIf="checkFormCode">
|
||||
<h4 style="font-weight: 300;display: inline;">Extension</h4>
|
||||
<br>
|
||||
<hr>
|
||||
<div class="clr-row">
|
||||
<div class="clr-col-4" *ngFor="let field of additionalFieldsFromBackend">
|
||||
<ng-container *ngIf="field.formCode === formcode" [ngSwitch]="field.fieldType">
|
||||
<!-- Text Input --> <label *ngSwitchCase="'text'">{{ field.fieldName }}</label>
|
||||
<input *ngSwitchCase="'text'" [type]="field.fieldType" [formControlName]="field.extValue"
|
||||
class="clr-input" />
|
||||
<!-- Date Input --> <label *ngSwitchCase="'date'">{{ field.fieldName }}</label>
|
||||
<input *ngSwitchCase="'date'" [type]="field.fieldType" [formControlName]="field.extValue"
|
||||
class="clr-input" />
|
||||
<!-- Textarea --> <label *ngSwitchCase="'textarea'">{{ field.fieldName }}</label>
|
||||
<textarea *ngSwitchCase="'textarea'" [formControlName]="field.extValue" col="10" row="2"></textarea>
|
||||
<!-- Checkbox --> <label *ngSwitchCase="'checkbox'">{{ field.fieldName }}</label><br>
|
||||
<input *ngSwitchCase="'checkbox'" [type]="field.fieldType" [formControlName]="field.extValue"
|
||||
class="clr-checkbox" />
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- form code end --> <div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline" (click)="modalAdd = false">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary" (click)="onSubmit()">ADD</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</clr-modal>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- htmlpopup -->
|
||||
@ -0,0 +1,78 @@
|
||||
//@import "../../../../assets/scss/var";
|
||||
.s-info-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
button {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.delete,.heading{
|
||||
text-align: center;
|
||||
color: red;
|
||||
}
|
||||
.entry-pg {
|
||||
width: 750px;
|
||||
}
|
||||
|
||||
.button1::after {
|
||||
content: none;
|
||||
}
|
||||
.button1:hover::after {
|
||||
content: "ADD ROWS";
|
||||
}
|
||||
|
||||
.section {
|
||||
background-color: #dddddd;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.section p {
|
||||
//color: white;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.clr-input {
|
||||
color: #212529;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.75rem 0.75rem;
|
||||
margin-top: 3px;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.clr-file {
|
||||
color: #212529;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
//padding: 0.6rem 0.75rem;
|
||||
margin-top: 3px;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
select{
|
||||
width: 100%;
|
||||
margin-top: 3px;
|
||||
padding: 5px 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
input[type=text],[type=date],[type=number],textarea {
|
||||
width: 100%;
|
||||
padding: 15px 15px;
|
||||
background-color:rgb(255, 255, 255);
|
||||
// margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.error_mess {
|
||||
color: red;
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { AlertService } from 'src/app/services/alert.service';
|
||||
import { Tagservice } from './Tag.service';
|
||||
import { AbstractControl, FormArray, FormBuilder, FormGroup, Validators, ValidationErrors } from '@angular/forms';
|
||||
import { ExtensionService } from 'src/app/services/fnd/extension.service';
|
||||
import { DashboardContentModel2 } from 'src/app/models/builder/dashboard';
|
||||
import { Tagcardvariable } from './Tag_cardvariable';
|
||||
import { UserInfoService } from 'src/app/services/user-info.service';
|
||||
declare var JsBarcode: any;
|
||||
@Component({
|
||||
selector: 'app-Tag',
|
||||
templateUrl: './Tag.component.html',
|
||||
styleUrls: ['./Tag.component.scss']
|
||||
})
|
||||
export class TagComponent implements OnInit {
|
||||
cardButton = Tagcardvariable.cardButton;
|
||||
cardmodeldata = Tagcardvariable.cardmodeldata;
|
||||
public dashboardArray: DashboardContentModel2[];
|
||||
isCardview = Tagcardvariable.cardButton;
|
||||
cardmodal; changeView() {
|
||||
this.isCardview = !this.isCardview;
|
||||
}
|
||||
beforeText(fieldtext: string): string { // Extract the text before the first '<'
|
||||
const index = fieldtext.indexOf('<');
|
||||
return index !== -1 ? fieldtext.substring(0, index) : fieldtext;
|
||||
}
|
||||
afterText(fieldtext: string): string { // Extract the text after the last '>'
|
||||
const index = fieldtext.lastIndexOf('>');
|
||||
return index !== -1 ? fieldtext.substring(index + 1) : '';
|
||||
}
|
||||
transform(fieldtext: string): string {
|
||||
const match = fieldtext.match(/<([^>]*)>/);
|
||||
return match ? match[1] : ''; // Extract the text between '<' and '>'
|
||||
}
|
||||
userrole;
|
||||
rowSelected: any = {};
|
||||
modaldelete = false;
|
||||
modalEdit = false;
|
||||
modalAdd = false;
|
||||
public entryForm: FormGroup;
|
||||
loading = false;
|
||||
product;
|
||||
modalOpenedforNewLine = false;
|
||||
newLine: any;
|
||||
additionalFieldsFromBackend: any[] = [];
|
||||
formcode = 'Tag_formCode'
|
||||
tableName = 'Tag'; checkFormCode; selected: any[] = []; constructor(
|
||||
private extensionService: ExtensionService,
|
||||
private userInfoService: UserInfoService,
|
||||
private mainService: Tagservice,
|
||||
private alertService: AlertService,
|
||||
private toastr: ToastrService,
|
||||
private _fb: FormBuilder,
|
||||
) { }
|
||||
// component button
|
||||
ngOnInit(): void {
|
||||
if (this.cardmodeldata !== '') {
|
||||
this.cardmodal = JSON.parse(this.cardmodeldata);
|
||||
this.dashboardArray = this.cardmodal.dashboard.slice();
|
||||
console.log(this.dashboardArray)
|
||||
}
|
||||
this.userrole = this.userInfoService.getRoles();
|
||||
this.getData();
|
||||
this.entryForm = this._fb.group({
|
||||
name: [null],
|
||||
|
||||
description: [null],
|
||||
|
||||
active: [false],
|
||||
|
||||
}); // component_button200
|
||||
// form code start
|
||||
this.extensionService.getJsonObjectsByFormCodeList(this.formcode).subscribe(data => {
|
||||
console.log(data);
|
||||
const jsonArray = data.map((str) => JSON.parse(str));
|
||||
this.additionalFieldsFromBackend = jsonArray;
|
||||
this.checkFormCode = this.additionalFieldsFromBackend.some(field => field.formCode === "Tag_formCode");
|
||||
console.log(this.checkFormCode);
|
||||
console.log(this.additionalFieldsFromBackend);
|
||||
if (this.additionalFieldsFromBackend && this.additionalFieldsFromBackend.length > 0) {
|
||||
this.additionalFieldsFromBackend.forEach(field => {
|
||||
if (field.formCode === this.formcode) {
|
||||
if (!this.entryForm.contains(field.extValue)) {
|
||||
// Add the control only if it doesn't exist in the form
|
||||
this.entryForm.addControl(field.extValue, this._fb.control(field.fieldValue));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
console.log(this.entryForm.value);
|
||||
// form code end
|
||||
|
||||
}
|
||||
error;
|
||||
getData() {
|
||||
this.mainService.getAll().subscribe((data) => {
|
||||
console.log(data);
|
||||
this.product = data;
|
||||
if (this.product.length == 0) {
|
||||
this.error = "No Data Available"
|
||||
}
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error) {
|
||||
this.error = "Server Error";
|
||||
}
|
||||
});
|
||||
}
|
||||
onEdit(row) {
|
||||
this.rowSelected = row;
|
||||
this.modalEdit = true;
|
||||
}
|
||||
onDelete(row) {
|
||||
this.rowSelected = row;
|
||||
this.modaldelete = true;
|
||||
}
|
||||
delete(id) {
|
||||
this.modaldelete = false;
|
||||
console.log("in delete " + id);
|
||||
this.mainService.delete(id).subscribe(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
this.ngOnInit();
|
||||
if (data) { this.toastr.success('Deleted successfully'); }
|
||||
});
|
||||
}
|
||||
onUpdate(id) {
|
||||
this.modalEdit = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//console.log("in update");
|
||||
console.log("id " + id);
|
||||
console.log(this.rowSelected);
|
||||
//console.log("out update");
|
||||
this.mainService.update(id, this.rowSelected).subscribe(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
if (data || data.status >= 200 && data.status <= 299) {
|
||||
this.toastr.success("Update Successfully");
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error.status >= 200 && error.status <= 299) {
|
||||
// this.toastr.success("update Succesfully");
|
||||
}
|
||||
if (error.status >= 400 && error.status <= 499) {
|
||||
this.toastr.error("Not Updated");
|
||||
}
|
||||
if (error.status >= 500 && error.status <= 599) {
|
||||
this.toastr.error("Not Updated");
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
}
|
||||
onCreate() {
|
||||
this.modalAdd = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.mainService.create(this.entryForm.value).subscribe(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
if (data || data.status >= 200 && data.status <= 299) {
|
||||
this.toastr.success("Added Successfully");
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error.status >= 200 && error.status <= 299) {
|
||||
// this.toastr.success("Added Succesfully");
|
||||
}
|
||||
if (error.status >= 400 && error.status <= 499) {
|
||||
this.toastr.error("Not Added");
|
||||
}
|
||||
if (error.status >= 500 && error.status <= 599) {
|
||||
this.toastr.error("Not Added");
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.ngOnInit();
|
||||
}, 500);
|
||||
}
|
||||
goToAdd(row) {
|
||||
this.modalAdd = true; this.submitted = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
submitted = false;
|
||||
onSubmit() {
|
||||
console.log(this.entryForm.value);
|
||||
this.submitted = true;
|
||||
if (this.entryForm.invalid) {
|
||||
return;
|
||||
} this.onCreate();
|
||||
|
||||
}
|
||||
|
||||
|
||||
rsModaldescription = false;
|
||||
goToReplaceStringdescription(row) {
|
||||
this.rowSelected = row; this.rsModaldescription = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// updateaction
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from "rxjs";
|
||||
import { HttpClient, HttpHeaders, HttpParams, } from "@angular/common/http";
|
||||
import { ApiRequestService } from "src/app/services/api/api-request.service";
|
||||
import { environment } from 'src/environments/environment';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class Tagservice{
|
||||
private baseURL = "Tag/Tag" ; constructor(
|
||||
private http: HttpClient,
|
||||
private apiRequest: ApiRequestService,
|
||||
) { }
|
||||
getAll(page?: number, size?: number): Observable<any> {
|
||||
return this.apiRequest.get(this.baseURL);
|
||||
}
|
||||
getById(id: number): Observable<any> {
|
||||
const _http = this.baseURL + "/" + id;
|
||||
return this.apiRequest.get(_http);
|
||||
}
|
||||
create(data: any): Observable<any> {
|
||||
return this.apiRequest.post(this.baseURL, data);
|
||||
}
|
||||
update(id: number, data: any): Observable<any> {
|
||||
const _http = this.baseURL + "/" + id;
|
||||
return this.apiRequest.put(_http, data);
|
||||
}
|
||||
delete(id: number): Observable<any> {
|
||||
const _http = this.baseURL + "/" + id;
|
||||
return this.apiRequest.delete(_http);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// updateaction
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
export const Tagcardvariable = {
|
||||
"cardButton": false,
|
||||
"cardmodeldata": ``
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -132,9 +132,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Fixed Right Sidebar -->
|
||||
<div class="wireframe-controls-sidebar"
|
||||
[class.collapsed]="sidebarCollapsed"
|
||||
[class.mobile-open]="sidebarOpen"
|
||||
<div class="wireframe-controls-sidebar" [class.collapsed]="sidebarCollapsed" [class.mobile-open]="sidebarOpen"
|
||||
[class.visible]="sidebarOpen || !isMobile">
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
@ -145,10 +143,7 @@
|
||||
|
||||
<!-- Updated Close Button -->
|
||||
<div class="sidebar-header">
|
||||
<button
|
||||
(click)="toggleSidebar()"
|
||||
class="close-btn"
|
||||
style="
|
||||
<button (click)="toggleSidebar()" class="close-btn" style="
|
||||
background: none;
|
||||
border: none;
|
||||
color: #060606;
|
||||
@ -157,8 +152,7 @@
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease-in-out;
|
||||
font-size: 16px;
|
||||
"
|
||||
>
|
||||
">
|
||||
<i class="fas" [ngClass]="sidebarCollapsed ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
||||
</button>
|
||||
<h2>Wireframe Controls</h2>
|
||||
@ -174,14 +168,10 @@
|
||||
</h3>
|
||||
|
||||
<div class="search-container">
|
||||
<input
|
||||
type="text"
|
||||
class="search-input"
|
||||
[(ngModel)]="searchTerm"
|
||||
(input)="onSearchChange()"
|
||||
placeholder="Search sections..."
|
||||
> </div>
|
||||
</div>
|
||||
<input type="text" class="search-input" [(ngModel)]="searchTerm" (input)="onSearchChange()"
|
||||
placeholder="Search sections...">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -196,8 +186,7 @@
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(globalSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(globalSections)"
|
||||
<div class="wf-section-item" *ngFor="let section of getFilteredSections(globalSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
@ -211,15 +200,14 @@
|
||||
</div>
|
||||
|
||||
<!-- Standard Sections -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-th-large" style="margin-right: 6px; color: #fd7e14;"></i>
|
||||
Standard Sections
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(standardSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(standardSections)"
|
||||
<div class="wf-section-item" *ngFor="let section of getFilteredSections(standardSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
@ -233,15 +221,14 @@
|
||||
</div>
|
||||
|
||||
<!-- Custom Sections -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-puzzle-piece" style="margin-right: 6px; color: #e83e8c;"></i>
|
||||
Custom Sections
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(customSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(customSections)"
|
||||
<div class="wf-section-item" *ngFor="let section of getFilteredSections(customSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
@ -293,6 +280,11 @@
|
||||
Build Wireframe
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="buildSiteBuilder()" [@buttonHover]>
|
||||
<i class="fas fa-hammer"></i>
|
||||
Build Site Builder
|
||||
</button>
|
||||
|
||||
<button class="action-btn primary" (click)="goToWireFrameEdit()">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
Edit WireFrame
|
||||
@ -410,15 +402,13 @@
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Canvas Area -->
|
||||
<div class="canvas-main-area" [class.sidebar-collapsed]="sidebarCollapsed">
|
||||
<div class="wireframe-controls-sidebar-overlay"
|
||||
*ngIf="sidebarOpen && !isMobile"
|
||||
(click)="sidebarOpen = false">
|
||||
<div class="canvas-main-area" [class.sidebar-collapsed]="sidebarCollapsed">
|
||||
<div class="wireframe-controls-sidebar-overlay" *ngIf="sidebarOpen && !isMobile" (click)="sidebarOpen = false">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Infinite Grid Background -->
|
||||
@ -427,17 +417,12 @@
|
||||
<!-- Zoom Controls -->
|
||||
|
||||
<!-- Canvas Container -->
|
||||
<div class="canvas-container"
|
||||
[class.panning]="isPanning"
|
||||
(mousedown)="startPan($event)"
|
||||
(mousemove)="doPan($event)"
|
||||
(mouseup)="endPan()"
|
||||
(mouseleave)="endPan()"
|
||||
(wheel)="onWheel($event)">
|
||||
<div class="canvas-container" [class.panning]="isPanning" (mousedown)="startPan($event)" (mousemove)="doPan($event)"
|
||||
(mouseup)="endPan()" (mouseleave)="endPan()" (wheel)="onWheel($event)">
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
<!-- Updated Loading Overlay -->
|
||||
<div *ngIf="isLoading" class="loading-overlay" [@fadeIn]>
|
||||
<div *ngIf="isLoading" class="loading-overlay" [@fadeIn]>
|
||||
<div class="loading-container">
|
||||
<mat-spinner diameter="50" color="accent"></mat-spinner>
|
||||
<div class="loading-text">Building Interface...</div>
|
||||
@ -446,33 +431,27 @@
|
||||
<div class="progress-fill" [style.width.%]="loadProgress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Updated single page container with minimal header and full height -->
|
||||
<!-- Replace your current "all-pages-grid-container" section with this -->
|
||||
<div *ngIf="!isLoading" class="single-page-container" [style.transform]="getPageTransform()">
|
||||
<!-- Updated single page container with minimal header and full height -->
|
||||
<!-- Replace your current "all-pages-grid-container" section with this -->
|
||||
<div *ngIf="!isLoading" class="single-page-container" [style.transform]="getPageTransform()">
|
||||
<div class="page-info">
|
||||
<h2 class="current-page-title">{{ getCurrentPageName() }}</h2>
|
||||
<span class="page-counter">Page {{ currentPageIndex + 1 }} of {{ pageRenderOrder.length }}</span>
|
||||
</div>
|
||||
<div class="single-page-wrapper">
|
||||
<div *ngIf="pageRenderOrder.length > 0"
|
||||
class="current-page-card">
|
||||
<div *ngIf="pageRenderOrder.length > 0" class="current-page-card">
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="page-content-area">
|
||||
<!-- Sections for current page -->
|
||||
<div class="connected-sections"
|
||||
cdkDropList
|
||||
[cdkDropListData]="getPageSections(getCurrentPageName())"
|
||||
<div class="connected-sections" cdkDropList [cdkDropListData]="getPageSections(getCurrentPageName())"
|
||||
[cdkDropListConnectedTo]="allConnectedLists"
|
||||
(cdkDropListDropped)="onSectionDrop($event, getCurrentPageName())">
|
||||
|
||||
<div *ngFor="let sectionKey of getPageSections(getCurrentPageName())"
|
||||
cdkDrag
|
||||
[cdkDragData]="sectionKey"
|
||||
class="section-container"
|
||||
[class.editing]="isCurrentSectionEditing(sectionKey)">
|
||||
<div *ngFor="let sectionKey of getPageSections(getCurrentPageName())" cdkDrag [cdkDragData]="sectionKey"
|
||||
class="section-container" [class.editing]="isCurrentSectionEditing(sectionKey)">
|
||||
|
||||
<!-- Drag Handle -->
|
||||
<div class="drag-handle" cdkDragHandle>
|
||||
@ -480,8 +459,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Section Content -->
|
||||
<div class="section-content"
|
||||
[innerHTML]="getSectionHtml(getCurrentPageName(), sectionKey)"
|
||||
<div class="section-content" [innerHTML]="getSectionHtml(getCurrentPageName(), sectionKey)"
|
||||
[attr.contenteditable]="isCurrentSectionEditing(sectionKey)"
|
||||
(blur)="handleDirectContentEdit($event, getCurrentPageName(), sectionKey)">
|
||||
</div>
|
||||
@ -517,13 +495,16 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="page-actions">
|
||||
|
||||
<!-- Show Code Button -->
|
||||
<button class="action-btn-modern copy-btn" (click)="showCode()">
|
||||
<i class="fas fa-code"></i>
|
||||
Show Code
|
||||
</button>
|
||||
|
||||
<button class="action-btn-modern copy-btn" (click)="copyPageToClipboard()">
|
||||
<i class="fas fa-copy"></i>
|
||||
Copy Page
|
||||
@ -533,15 +514,30 @@
|
||||
<i class="fas fa-download"></i>
|
||||
Download Page
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Show Code Modal -->
|
||||
|
||||
<!-- Code Edit Modal -->
|
||||
<div *ngIf="showCodeModal" class="code-modal-overlay">
|
||||
<div class="code-modal">
|
||||
<div class="code-modal-header">
|
||||
<h3>Edit Code – {{ currentEditingPage }}</h3>
|
||||
<button class="close-btn" (click)="cancelEdit()">×</button>
|
||||
</div>
|
||||
|
||||
<textarea [(ngModel)]="editableHtml" class="code-textarea"></textarea>
|
||||
|
||||
<div class="code-modal-footer">
|
||||
<button class="action-btn-modern" (click)="saveEditedCode()">Save</button>
|
||||
<button class="action-btn-modern" (click)="cancelEdit()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Page Navigation Controls -->
|
||||
<div *ngIf="!isLoading && pageRenderOrder.length > 0" class="page-navigation">
|
||||
<button class="nav-btn"
|
||||
(click)="previousPage()"
|
||||
[disabled]="currentPageIndex <= 0"
|
||||
title="Previous Page">
|
||||
<button class="nav-btn" (click)="previousPage()" [disabled]="currentPageIndex <= 0" title="Previous Page">
|
||||
<i class="fas fa-chevron-left"></i>
|
||||
Previous
|
||||
</button>
|
||||
@ -553,9 +549,7 @@
|
||||
<div class="page-title">{{ getCurrentPageName() }}</div>
|
||||
</div>
|
||||
|
||||
<button class="nav-btn"
|
||||
(click)="nextPage()"
|
||||
[disabled]="currentPageIndex >= pageRenderOrder.length - 1"
|
||||
<button class="nav-btn" (click)="nextPage()" [disabled]="currentPageIndex >= pageRenderOrder.length - 1"
|
||||
title="Next Page">
|
||||
Next
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
@ -564,9 +558,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Mobile Sidebar Toggle (Hidden on Desktop) -->
|
||||
<button class="mobile-sidebar-toggle"
|
||||
(click)="toggleMobileSidebar()"
|
||||
[class.active]="sidebarOpen"
|
||||
<button class="mobile-sidebar-toggle" (click)="toggleMobileSidebar()" [class.active]="sidebarOpen"
|
||||
style="display: none; position: fixed; top: 20px; right: 20px; z-index: 1600; background: #212529; color: white; border: none; padding: 12px; border-radius: 50%; font-size: 16px;"
|
||||
*ngIf="isMobile">
|
||||
<i class="fas" [ngClass]="sidebarOpen ? 'fa-times' : 'fa-bars'"></i>
|
||||
@ -574,8 +566,8 @@
|
||||
|
||||
<!-- Navbar Editor Modal -->
|
||||
|
||||
<!-- Updated Navbar Editor Modal -->
|
||||
<div class="modal-overlay" *ngIf="showNavbarEditorModal" [@fadeIn] (click)="closeNavbarEditorModal()">
|
||||
<!-- Updated Navbar Editor Modal -->
|
||||
<div class="modal-overlay" *ngIf="showNavbarEditorModal" [@fadeIn] (click)="closeNavbarEditorModal()">
|
||||
<div class="modal-content navbar-editor-modal" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
@ -593,8 +585,7 @@
|
||||
<div class="form-group">
|
||||
<label for="navbarPageSelect">Select Page:</label>
|
||||
<select id="navbarPageSelect" class="form-control" [(ngModel)]="selectedNavbarPage"
|
||||
(change)="onNavbarPageChange()"
|
||||
[@focusBorder]>
|
||||
(change)="onNavbarPageChange()" [@focusBorder]>
|
||||
<option value="">Choose a page...</option>
|
||||
<option *ngFor="let page of pageRenderOrder" [value]="page">
|
||||
<i class="fas fa-file-alt"></i> {{ page }}
|
||||
@ -645,10 +636,10 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Custom Section Modal -->
|
||||
<div class="modal-overlay" *ngIf="showAddCustomModal" [@fadeIn] (click)="closeAddCustomModal()">
|
||||
<!-- Add Custom Section Modal -->
|
||||
<div class="modal-overlay" *ngIf="showAddCustomModal" [@fadeIn] (click)="closeAddCustomModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
@ -667,11 +658,8 @@
|
||||
<i class="fas fa-tag" style="margin-right: 4px;"></i>
|
||||
Section Name:
|
||||
</label>
|
||||
<input id="customSectionName"
|
||||
type="text"
|
||||
[(ngModel)]="newCustomSectionName"
|
||||
placeholder="Enter section name (e.g., Custom Header, Special CTA)"
|
||||
class="form-control">
|
||||
<input id="customSectionName" type="text" [(ngModel)]="newCustomSectionName"
|
||||
placeholder="Enter section name (e.g., Custom Header, Special CTA)" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@ -679,11 +667,8 @@
|
||||
<i class="fas fa-align-left" style="margin-right: 4px;"></i>
|
||||
Section Description:
|
||||
</label>
|
||||
<textarea id="customSectionDesc"
|
||||
[(ngModel)]="newCustomSectionDesc"
|
||||
rows="4"
|
||||
placeholder="Describe the content and purpose of this custom section..."
|
||||
class="form-control"></textarea>
|
||||
<textarea id="customSectionDesc" [(ngModel)]="newCustomSectionDesc" rows="4"
|
||||
placeholder="Describe the content and purpose of this custom section..." class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@ -691,11 +676,8 @@
|
||||
<i class="fas fa-icons" style="margin-right: 4px;"></i>
|
||||
Icon Class:
|
||||
</label>
|
||||
<input id="customSectionIcon"
|
||||
type="text"
|
||||
[(ngModel)]="newCustomSectionIcon"
|
||||
placeholder="e.g., fas fa-star, fas fa-rocket"
|
||||
class="form-control">
|
||||
<input id="customSectionIcon" type="text" [(ngModel)]="newCustomSectionIcon"
|
||||
placeholder="e.g., fas fa-star, fas fa-rocket" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -704,15 +686,14 @@
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary"
|
||||
[disabled]="!newCustomSectionName || !newCustomSectionDesc"
|
||||
<button class="action-btn primary" [disabled]="!newCustomSectionName || !newCustomSectionDesc"
|
||||
(click)="confirmAddCustomSection()">
|
||||
<i class="fas fa-plus" style="margin-right: 5px;"></i>
|
||||
Add Custom Section
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal for Adding New Page -->
|
||||
<div class="modal-overlay" *ngIf="showNewPageModal" [@fadeIn] (click)="closeNewPageModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
@ -733,11 +714,8 @@
|
||||
<i class="fas fa-file-alt" style="margin-right: 4px;"></i>
|
||||
Page Name:
|
||||
</label>
|
||||
<input id="pageName"
|
||||
type="text"
|
||||
[(ngModel)]="newPageName"
|
||||
placeholder="Enter page name (e.g., Home, About, Contact)"
|
||||
class="form-control">
|
||||
<input id="pageName" type="text" [(ngModel)]="newPageName"
|
||||
placeholder="Enter page name (e.g., Home, About, Contact)" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@ -745,11 +723,8 @@
|
||||
<i class="fas fa-align-left" style="margin-right: 4px;"></i>
|
||||
Page Description:
|
||||
</label>
|
||||
<textarea id="pageDescription"
|
||||
[(ngModel)]="newPageDescription"
|
||||
rows="3"
|
||||
placeholder="Describe the purpose and content of this page..."
|
||||
class="form-control"></textarea>
|
||||
<textarea id="pageDescription" [(ngModel)]="newPageDescription" rows="3"
|
||||
placeholder="Describe the purpose and content of this page..." class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -758,9 +733,7 @@
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary"
|
||||
[disabled]="!newPageName.trim()"
|
||||
(click)="confirmAddPage()">
|
||||
<button class="action-btn primary" [disabled]="!newPageName.trim()" (click)="confirmAddPage()">
|
||||
<i class="fas fa-plus" style="margin-right: 5px;"></i>
|
||||
Add Page
|
||||
</button>
|
||||
@ -768,4 +741,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,12 @@ import * as sha256 from 'crypto-js/sha256';
|
||||
import SHA256 from 'crypto-js/sha256';
|
||||
import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
|
||||
import { trigger, transition, style, animate, state } from '@angular/animations';
|
||||
import * as e from 'express';
|
||||
import { json } from 'stream/consumers';
|
||||
|
||||
|
||||
interface GeneratedSectionContent {
|
||||
json: string;
|
||||
css: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-wireframe-renderer',
|
||||
@ -50,6 +54,8 @@ import { json } from 'stream/consumers';
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
|
||||
export class WireframeRendererComponent implements OnInit {
|
||||
|
||||
globalSections = [
|
||||
@ -177,6 +183,8 @@ export class WireframeRendererComponent implements OnInit {
|
||||
initialPrompt = '';
|
||||
id: number;
|
||||
allPagePrompts: Record<string, Record<string, string>> = {};
|
||||
allPageCss: Record<string, Record<string, string>> = {};
|
||||
|
||||
initialGeneratedPrompts: Record<string, Record<string, string>> = {};
|
||||
promptHashCache: Record<string, string> = {};
|
||||
pageSections: Record<string, { FullPage: SafeHtml }> = {};
|
||||
@ -186,12 +194,14 @@ export class WireframeRendererComponent implements OnInit {
|
||||
|
||||
sidebarCollapsed: boolean = false;
|
||||
|
||||
newlyGeneratedPages: string[] = [];
|
||||
newlyGeneratedPages: string[] = [];
|
||||
|
||||
// Add toggle method
|
||||
|
||||
processedCssSections: string[] = [];
|
||||
finalCssBundle: string = '';
|
||||
|
||||
deployedUrl: string | null = null;
|
||||
deployedUrl: string | null = null;
|
||||
// Added properties for grid and drag functionality
|
||||
hoveredPage: string | null = null;
|
||||
hoveredSection: string | null = null;
|
||||
@ -202,7 +212,7 @@ deployedUrl: string | null = null;
|
||||
lastX: number = 0;
|
||||
lastY: number = 0;
|
||||
isDragging = false;
|
||||
startPanPosition = { x: 0, y: 0 };
|
||||
startPanPosition = { x: 0, y: 0 };
|
||||
// Edit mode properties
|
||||
editMode: boolean = false;
|
||||
editingSection: { page: string, section: string } | null = null;
|
||||
@ -320,6 +330,7 @@ private async checkAllExistingFilesEnhanced(siteName: string, expectedPages: str
|
||||
|
||||
// Only create new HTML structure if the original doesn't have proper HTML tags
|
||||
if (!rawHtml.includes('<!DOCTYPE') || !rawHtml.includes('<html')) {
|
||||
|
||||
completeHtml = this.createCompleteHtml(pageName, parsed.css, parsed.bodyHtml);
|
||||
}
|
||||
|
||||
@ -867,7 +878,9 @@ fetchTreeById(id: number) {
|
||||
this.dividePagesToExistingOrNew(this.jsonInput, this.sitename);
|
||||
this.updateLoadingProgress(20, 'Model data loaded successfully');
|
||||
await this.generateMissingPagesWithAI(this.missingPages, this.jsonInput);
|
||||
console.log("Printing Final Map of Html ", this.missingHtmlPages)
|
||||
console.log("Printing Final Map of Html ", this.mapofPageAndHtmlBody)
|
||||
|
||||
|
||||
// Start the enhanced processing flow
|
||||
// await this.processAllPagesWithExistingCheck(this.jsonInput);
|
||||
} catch (err) {
|
||||
@ -887,11 +900,11 @@ fetchTreeById(id: number) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
goToWireFrameEdit(){
|
||||
let mapOfHtml:any;
|
||||
this.router.navigate(["../WireFrameEdit/",{ mapOfHtml: this.mapofPageAndHtmlBody }])
|
||||
goToWireFrameEdit() {
|
||||
localStorage.setItem('mapOfHtml',JSON.stringify(this.mapofPageAndHtmlBody));
|
||||
this.router.navigate(['/cns-portal/WireFrameEdit']);
|
||||
}
|
||||
|
||||
/* Step 2: Process all pages with existing file checking
|
||||
*/
|
||||
async processAllPagesWithExistingCheck(treeJsonString: string) {
|
||||
@ -1037,8 +1050,25 @@ private async generatePromptsForMissingPage(pageName: string, sections: any) {
|
||||
|
||||
this.sectionOrderMap[pageName].push(sectionName);
|
||||
const prompt = await this.generatePromptFromSection(sectionName, sectionDescription as string);
|
||||
sectionPrompts[sectionName] = prompt;
|
||||
sectionPrompts[sectionName] = prompt.json;
|
||||
|
||||
// ✅ Store section-wise CSS externally
|
||||
if (!this.allPageCss[pageName]) {
|
||||
this.allPageCss[pageName] = {};
|
||||
}
|
||||
this.allPageCss[pageName][sectionName] = prompt.css;
|
||||
|
||||
// store for unique css
|
||||
|
||||
const templateKey = sectionName.toLowerCase().replace(/section$/, '').trim();
|
||||
|
||||
if (!this.processedCssSections.includes(templateKey)) {
|
||||
this.processedCssSections.push(templateKey);
|
||||
this.finalCssBundle += prompt.css + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.allPagePrompts[pageName] = sectionPrompts;
|
||||
this.initialGeneratedPrompts[pageName] = { ...sectionPrompts };
|
||||
@ -1449,8 +1479,26 @@ private async processMissingPagesEnhanced(treeJson: any, missingPages: string[])
|
||||
|
||||
this.sectionOrderMap[pageName].push(sectionName);
|
||||
const prompt = await this.generatePromptFromSection(sectionName, sectionDescription as string);
|
||||
sectionPrompts[sectionName] = prompt;
|
||||
sectionPrompts[sectionName] = prompt.json;
|
||||
|
||||
|
||||
// ✅ Store section-wise CSS externally
|
||||
if (!this.allPageCss[pageName]) {
|
||||
this.allPageCss[pageName] = {};
|
||||
}
|
||||
this.allPageCss[pageName][sectionName] = prompt.css;
|
||||
|
||||
// store for unique css
|
||||
|
||||
const templateKey = sectionName.toLowerCase().replace(/section$/, '').trim();
|
||||
|
||||
if (!this.processedCssSections.includes(templateKey)) {
|
||||
this.processedCssSections.push(templateKey);
|
||||
this.finalCssBundle += prompt.css + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.allPagePrompts[pageName] = sectionPrompts;
|
||||
this.initialGeneratedPrompts[pageName] = { ...sectionPrompts };
|
||||
@ -1501,7 +1549,21 @@ private async processAllPagesEnhanced(treeJson: any) {
|
||||
|
||||
this.sectionOrderMap[pageName].push(sectionName);
|
||||
const prompt = await this.generatePromptFromSection(sectionName, sectionDescription);
|
||||
sectionPrompts[sectionName] = prompt;
|
||||
sectionPrompts[sectionName] = prompt.json;
|
||||
// ✅ Store section-wise CSS externally
|
||||
if (!this.allPageCss[pageName]) {
|
||||
this.allPageCss[pageName] = {};
|
||||
}
|
||||
this.allPageCss[pageName][sectionName] = prompt.css;
|
||||
// store for unique css
|
||||
|
||||
const templateKey = sectionName.toLowerCase().replace(/section$/, '').trim();
|
||||
|
||||
if (!this.processedCssSections.includes(templateKey)) {
|
||||
this.processedCssSections.push(templateKey);
|
||||
this.finalCssBundle += prompt.css + '\n';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.allPagePrompts[pageName] = sectionPrompts;
|
||||
@ -1579,7 +1641,10 @@ async processPageSectionsEnhanced(pageName: string, sectionMap: Record<string, s
|
||||
await Promise.all(htmlTasks);
|
||||
|
||||
// Create complete HTML structure for the page
|
||||
const completeHtml = this.createCompleteHtml(pageName, COMMON_CSS, sectionHtmls.join('\n'));
|
||||
|
||||
const css = this.getCombinedSectionCss(pageName);
|
||||
|
||||
const completeHtml = this.createCompleteHtml(pageName, css, sectionHtmls.join('\n'));
|
||||
|
||||
const safeHtml = completeHtml;
|
||||
this.pageSections[pageName] = { FullPage: safeHtml };
|
||||
@ -1622,13 +1687,14 @@ HTML Only. No CSS.
|
||||
✅ Focus on layout that matches a modern UI — semantic, responsive, and readable.
|
||||
✅ Use placeholders for image/icon blocks where appropriate (e.g., <div style="width:100px;height:30px;background:#ccc;"></div>)`;
|
||||
|
||||
|
||||
// Generate prompt from section
|
||||
async generatePromptFromSection(
|
||||
sectionName: string,
|
||||
sectionDescription: string,
|
||||
headerId: number = 35,
|
||||
operationType: string = 'template 1'
|
||||
): Promise<string> {
|
||||
): Promise<GeneratedSectionContent> {
|
||||
return new Promise((resolve) => {
|
||||
const fieldType = sectionName.toLowerCase().replace(/section$/i, '').trim();
|
||||
|
||||
@ -1639,8 +1705,11 @@ HTML Only. No CSS.
|
||||
try {
|
||||
// const jsonBlock = res?.javacode;
|
||||
const jsonBlock = res?.htmljson;
|
||||
const sectionCss = res?.css || '';
|
||||
|
||||
// if (!jsonBlock) return resolve('{}');
|
||||
if (!jsonBlock) return resolve({ json: '{}', css: '' });
|
||||
|
||||
if (!jsonBlock) return resolve('{}');
|
||||
|
||||
console.log(' base json is ...',jsonBlock);
|
||||
const baseJson = typeof jsonBlock === 'string' ? JSON.parse(jsonBlock) : jsonBlock;
|
||||
@ -1673,7 +1742,9 @@ HTML Only. No CSS.
|
||||
const hash = sha256(enhancedPrompt).toString();
|
||||
|
||||
if (this.promptHashCache[hash]) {
|
||||
return resolve(this.promptHashCache[hash]);
|
||||
// return resolve(this.promptHashCache[hash]);
|
||||
return resolve({ json: this.promptHashCache[hash], css: sectionCss });
|
||||
|
||||
}
|
||||
|
||||
const enhanced = await this.callAi(enhancedPrompt);
|
||||
@ -1682,16 +1753,27 @@ HTML Only. No CSS.
|
||||
this.promptHashCache[hash] = enhanced;
|
||||
|
||||
// resolve(baseJsonString);
|
||||
resolve(this.promptHashCache[hash]);
|
||||
// resolve(this.promptHashCache[hash]);
|
||||
resolve({ json: this.promptHashCache[hash], css: sectionCss });
|
||||
} catch (err) {
|
||||
console.error('❌ JSON parse error:', err);
|
||||
resolve('{}');
|
||||
// resolve('{}');
|
||||
resolve({ json: '{}', css: '' });
|
||||
|
||||
}
|
||||
},
|
||||
error: () => resolve('{}')
|
||||
error: () => resolve({ json: '{}', css: '' })
|
||||
|
||||
// error: () => resolve('{}')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private getCombinedSectionCss(pageName: string): string {
|
||||
const sectionCssMap = this.allPageCss[pageName] || {};
|
||||
return Object.values(sectionCssMap).join('\n');
|
||||
}
|
||||
|
||||
// Process all pages live update
|
||||
async processAllPagesLiveUpdate() {
|
||||
const htmlGenerationTasks: Promise<void>[] = [];
|
||||
@ -1828,8 +1910,6 @@ private createCompleteHtml(pageName: string, css: string, bodyHtml: string): str
|
||||
<style>
|
||||
${css}
|
||||
|
||||
/* Additional common styles */
|
||||
${COMMON_CSS}
|
||||
|
||||
html, body {
|
||||
margin: 0 !important;
|
||||
@ -1905,7 +1985,8 @@ createHtmlFiles() {
|
||||
// Ensure we have valid HTML
|
||||
if (!html.includes('<!DOCTYPE') && !html.includes('<html')) {
|
||||
// If it's just body content, wrap it properly
|
||||
html = this.createCompleteHtml(pageName, COMMON_CSS, html);
|
||||
const css = this.getCombinedSectionCss(pageName);
|
||||
html = this.createCompleteHtml(pageName, css, html);
|
||||
}
|
||||
|
||||
const sanitizedPageName = this.sanitizeFilename(pageName);
|
||||
@ -1933,9 +2014,9 @@ async generateJson(data: { jsonStructure: any, sectionType: string }): Promise<s
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
const parsedJson =
|
||||
typeof data.jsonStructure === 'string'
|
||||
? JSON.parse(data.jsonStructure)
|
||||
: data.jsonStructure;
|
||||
typeof data.jsonStructure.json === 'string'
|
||||
? JSON.parse(data.jsonStructure.json)
|
||||
: data.jsonStructure.json;
|
||||
|
||||
// Check for empty or invalid parsed JSON
|
||||
const isEmpty = !parsedJson || Object.keys(parsedJson).length === 0;
|
||||
@ -2060,6 +2141,64 @@ downloadHtml(pageName: string) {
|
||||
}
|
||||
|
||||
|
||||
buildSiteBuilder() {
|
||||
const pageHtmlMap: Record<string, string> = {};
|
||||
|
||||
for (const [pageName, section] of Object.entries(this.pageSections)) {
|
||||
const html = section.FullPage?.toString() || '';
|
||||
pageHtmlMap[pageName] = html;
|
||||
}
|
||||
const payload = {
|
||||
css: this.finalCssBundle,
|
||||
pageHtmlMap: pageHtmlMap
|
||||
};
|
||||
|
||||
|
||||
this.siteTreeService.deploySiteBuilder(this.siteId,this.sitename,payload).subscribe(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
if (data || data.status >= 200 && data.status <= 299) {
|
||||
|
||||
|
||||
|
||||
this.siteTreeService.getById(this.siteId).subscribe({
|
||||
next: async (res) => {
|
||||
console.log('📥 Fetched from getById again :', res);
|
||||
|
||||
if (res ) {
|
||||
this.deployedUrl = res.deployedUrl;
|
||||
|
||||
console.log('deployed url is ', this.deployedUrl)
|
||||
|
||||
|
||||
} else {
|
||||
console.warn('⚠️ Deployed Url Not found');
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('❌ Error in getById:', err);
|
||||
}
|
||||
});
|
||||
this.toastr.success("Site builder Deploying Start..");
|
||||
}
|
||||
// setTimeout(() => {
|
||||
// this.ngOnInit();
|
||||
// }, 500);
|
||||
}, (error) => {
|
||||
console.log(error);
|
||||
if (error.status >= 200 && error.status <= 299) {
|
||||
this.toastr.success("deployed Files Created Successfully");
|
||||
}
|
||||
if (error.status >= 400 && error.status <= 499) {
|
||||
this.toastr.error(" deployed Files Not Created");
|
||||
}
|
||||
if (error.status >= 500 && error.status <= 599) {
|
||||
this.toastr.error("deployed Server Error");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Update your helper methods
|
||||
@ -2568,6 +2707,42 @@ copyPageToClipboard(pageName?: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
// this is for show code
|
||||
showCodeModal = false;
|
||||
editableHtml = '';
|
||||
currentEditingPage = '';
|
||||
|
||||
showCode(pageName?: string): void {
|
||||
const pageToSelect = pageName || this.getCurrentPageName();
|
||||
const html = this.mapofPageAndHtmlBody[pageToSelect];
|
||||
|
||||
if (html) {
|
||||
this.currentEditingPage = pageToSelect;
|
||||
this.editableHtml = html;
|
||||
this.showCodeModal = true;
|
||||
} else {
|
||||
this.toastr.error('No code found for this page');
|
||||
}
|
||||
}
|
||||
|
||||
saveEditedCode(): void {
|
||||
if (this.currentEditingPage && this.editableHtml) {
|
||||
this.mapofPageAndHtmlBody[this.currentEditingPage] = this.editableHtml;
|
||||
this.toastr.success(`${this.currentEditingPage} HTML updated`);
|
||||
this.showCodeModal = false;
|
||||
} else {
|
||||
this.toastr.error('Failed to save. Missing page or HTML.');
|
||||
}
|
||||
}
|
||||
|
||||
cancelEdit(): void {
|
||||
this.showCodeModal = false;
|
||||
this.editableHtml = '';
|
||||
this.currentEditingPage = '';
|
||||
}
|
||||
|
||||
// show code end
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2899,9 +3074,9 @@ downloadCurrentPage(): void {
|
||||
// Add this to initialize the current page
|
||||
|
||||
|
||||
getPageTransform(): string {
|
||||
getPageTransform(): string {
|
||||
return `scale(${this.scale})`;
|
||||
}
|
||||
}
|
||||
|
||||
refreshAllSectionCSS(): void {
|
||||
// Refresh CSS in all section previews
|
||||
@ -3363,6 +3538,8 @@ async mapOfExistingPagesWithHtmlCss(existingPages: string[]): Promise<void> {
|
||||
try {
|
||||
await Promise.all(pagePromises);
|
||||
console.log('All existing pages loaded:', this.mapofPageAndHtmlBody);
|
||||
console.log("Start The Deployment! ")
|
||||
await this.deployAllPages()
|
||||
} catch (error) {
|
||||
console.error('Error loading some pages:', error);
|
||||
}
|
||||
@ -3393,7 +3570,9 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
this.sectionHtmls[pageName]['FullPage'] = this.sanitizer.bypassSecurityTrustHtml(htmlContent);
|
||||
}
|
||||
}
|
||||
async generateMissingPagesWithAI(missingPages: string[], jsonInput: string): Promise<void> {
|
||||
|
||||
|
||||
async generateMissingPagesWithAI(missingPages: string[], jsonInput: string): Promise<void> {
|
||||
if (!missingPages.length) {
|
||||
this.toastr.info('No missing pages to generate');
|
||||
return;
|
||||
@ -3447,7 +3626,22 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
for (const [sectionName, sectionDescription] of sectionEntries) {
|
||||
// Generate prompt for section, passing the full jsonInput as context
|
||||
const prompt = await this.generatePromptFromSection(sectionName, sectionDescription as string);
|
||||
this.allPagePrompts[pageName][sectionName] = prompt;
|
||||
this.allPagePrompts[pageName][sectionName] = prompt.json;
|
||||
|
||||
// ✅ Store section-wise CSS externally
|
||||
if (!this.allPageCss[pageName]) {
|
||||
this.allPageCss[pageName] = {};
|
||||
}
|
||||
this.allPageCss[pageName][sectionName] = prompt.css;
|
||||
|
||||
// store for unique css
|
||||
|
||||
const templateKey = sectionName.toLowerCase().replace(/section$/, '').trim();
|
||||
|
||||
if (!this.processedCssSections.includes(templateKey)) {
|
||||
this.processedCssSections.push(templateKey);
|
||||
this.finalCssBundle += prompt.css + '\n';
|
||||
}
|
||||
|
||||
// Generate HTML for section
|
||||
const html = await this.generateJson({ sectionType: sectionName, jsonStructure: prompt });
|
||||
@ -3458,7 +3652,9 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
sanitizedPageName = this.sanitizeFilename(pageName);
|
||||
|
||||
// Combine all section HTMLs and CSS for the page
|
||||
const finalHtml = this.createCompleteHtml(sanitizedPageName, COMMON_CSS, sectionHtmls.join('\n'));
|
||||
const css = this.getCombinedSectionCss(pageName);
|
||||
|
||||
const finalHtml = this.createCompleteHtml(sanitizedPageName, css, sectionHtmls.join('\n'));
|
||||
|
||||
this.pageSections[pageName] = { FullPage: finalHtml };
|
||||
this.mapofPageAndHtmlBody[pageName] = finalHtml;
|
||||
@ -3472,17 +3668,22 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
for (const [pageName, html] of pagesToSave.entries()) {
|
||||
|
||||
const pageObj: Record<string, string> = { [pageName]: html };
|
||||
|
||||
const payload = {
|
||||
css: this.finalCssBundle,
|
||||
pageHtmlMap: pageObj
|
||||
};
|
||||
// Ensure the page name is sanitized
|
||||
await new Promise<void>((resolve) => {
|
||||
this.siteTreeService.createHtmlfile(this.siteId, this.sitename, pageObj).subscribe({
|
||||
this.siteTreeService.createHtmlfile(this.siteId, this.sitename, payload).subscribe({
|
||||
next: (response) => {
|
||||
console.log(`Page "${pageName}" created successfully.`);
|
||||
this.toastr.success(`Generated and saved page: ${pageName}`);
|
||||
// this.toastr.success(`Generated and saved page: ${pageName}`);
|
||||
resolve();
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(`Error creating page "${pageName}":`, error);
|
||||
this.toastr.error(`Failed to save generated page: ${pageName}`);
|
||||
// this.toastr.error(`Failed to save generated page: ${pageName}`);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
@ -3506,7 +3707,9 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
// }
|
||||
|
||||
console.log('Map of All Pages with HTML:', this.mapofPageAndHtmlBody);
|
||||
this.toastr.success('Generated all missing pages with AI.');
|
||||
console.log('Generated all missing pages with AI...');
|
||||
|
||||
// this.toastr.success('Generated all missing pages with AI.');
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
@ -3519,6 +3722,26 @@ calculateSectionHtmlsForExistingPage(pageName: string, htmlContent: string): voi
|
||||
// Add this property to your component
|
||||
isGridView: boolean = false; // Set to true for grid, false for single page
|
||||
|
||||
async deployAllPages() {
|
||||
// this.toastr.info("Deploying all pages...");
|
||||
|
||||
try {
|
||||
console.log("SITE ID ",this.siteId)
|
||||
console.log("SITE NAME FORMATTED ",this.formatSiteName(this.sitename));
|
||||
this.siteTreeService.deploySiteBuilder(+this.siteId,
|
||||
this.formatSiteName(this.sitename).trim(),
|
||||
this.mapofPageAndHtmlBody
|
||||
)
|
||||
// this.toastr.success("All pages deployed successfully!");
|
||||
} catch (error) {
|
||||
console.error(`Error deploy}:`, error);
|
||||
this.toastr.error(`Failed to deploy page: `);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.75);
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -155,17 +155,27 @@
|
||||
animation: fadeIn 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* Main Popup Content */
|
||||
/* Main Popup Content */
|
||||
.popup-content {
|
||||
width: 600px;
|
||||
max-height: none;
|
||||
width: 900px;
|
||||
/* ⬅️ Increased from 600px to 900px */
|
||||
max-width: 95vw;
|
||||
/* ⬅️ Prevent overflow on smaller screens */
|
||||
max-height: 90vh;
|
||||
/* ⬅️ Avoid overflowing vertically */
|
||||
padding: 24px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.25);
|
||||
border-radius: 8px;
|
||||
/* ⬅️ More spacing */
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
border-radius: 12px;
|
||||
/* ⬅️ Slightly larger corners */
|
||||
background-color: snow;
|
||||
animation: slideIn 0.4s ease-out;
|
||||
overflow-y: auto;
|
||||
/* ⬅️ Scroll if content overflows vertically */
|
||||
}
|
||||
|
||||
|
||||
.close-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
@ -193,7 +203,7 @@
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
transition: border 0.3s ease;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
@ -240,13 +250,13 @@
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.generate-btn:hover {
|
||||
background: #1565c0;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Loading Container */
|
||||
@ -255,7 +265,7 @@
|
||||
padding: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@ -269,13 +279,11 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
opacity: 0.1;
|
||||
background-image: repeating-linear-gradient(
|
||||
45deg,
|
||||
background-image: repeating-linear-gradient(45deg,
|
||||
transparent,
|
||||
transparent 10px,
|
||||
rgba(255,255,255,0.1) 10px,
|
||||
rgba(255,255,255,0.1) 20px
|
||||
);
|
||||
rgba(255, 255, 255, 0.1) 10px,
|
||||
rgba(255, 255, 255, 0.1) 20px);
|
||||
}
|
||||
|
||||
.loader-content {
|
||||
@ -287,12 +295,12 @@
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto 24px;
|
||||
background: rgba(255,255,255,0.15);
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
animation: spinPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@ -306,7 +314,7 @@
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dots {
|
||||
@ -314,7 +322,7 @@
|
||||
}
|
||||
|
||||
.thinking-subtitle {
|
||||
color: rgba(255,255,255,0.9);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 16px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
@ -330,15 +338,29 @@
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.4);
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
animation: dotPulse 1.4s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.dot-1 { animation-delay: 0s; }
|
||||
.dot-2 { animation-delay: 0.2s; }
|
||||
.dot-3 { animation-delay: 0.4s; }
|
||||
.dot-4 { animation-delay: 0.6s; }
|
||||
.dot-5 { animation-delay: 0.8s; }
|
||||
.dot-1 {
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.dot-2 {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.dot-3 {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.dot-4 {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
.dot-5 {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
.particles {
|
||||
position: absolute;
|
||||
@ -352,7 +374,7 @@
|
||||
.particle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.6);
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
animation: float 3s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@ -367,7 +389,7 @@
|
||||
.particle-2 {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: rgba(255,255,255,0.4);
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
top: 60%;
|
||||
right: 20%;
|
||||
animation-duration: 4s;
|
||||
@ -377,7 +399,7 @@
|
||||
.particle-3 {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
background: rgba(255,255,255,0.7);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
bottom: 30%;
|
||||
left: 25%;
|
||||
animation-duration: 2.5s;
|
||||
@ -386,7 +408,7 @@
|
||||
.particle-4 {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: rgba(255,255,255,0.5);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
top: 40%;
|
||||
right: 15%;
|
||||
animation-duration: 3.5s;
|
||||
@ -399,7 +421,7 @@
|
||||
padding: 32px;
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
animation: slideIn 0.4s ease-out;
|
||||
@ -409,7 +431,7 @@
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto 24px;
|
||||
background: rgba(255,255,255,0.15);
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -422,11 +444,11 @@
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.3);
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: rgba(255,255,255,0.9);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 16px;
|
||||
margin-bottom: 32px;
|
||||
line-height: 1.5;
|
||||
@ -434,9 +456,9 @@
|
||||
|
||||
.retry-btn {
|
||||
padding: 12px 20px;
|
||||
background: rgba(255,255,255,0.2);
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border: 1px solid rgba(255,255,255,0.3);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
@ -444,7 +466,7 @@
|
||||
}
|
||||
|
||||
.retry-btn:hover {
|
||||
background: rgba(255,255,255,0.3);
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
@ -469,6 +491,7 @@
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
@ -479,6 +502,7 @@
|
||||
opacity: 0;
|
||||
transform: translateY(30px) scale(0.95);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
@ -486,44 +510,76 @@
|
||||
}
|
||||
|
||||
@keyframes spinPulse {
|
||||
0%, 100% {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0deg) scale(1);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: rotate(180deg) scale(1.1);
|
||||
box-shadow: 0 12px 48px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes brainThink {
|
||||
0%, 100% { transform: scale(1) rotate(0deg); }
|
||||
25% { transform: scale(1.1) rotate(-5deg); }
|
||||
75% { transform: scale(0.95) rotate(5deg); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: scale(1.1) rotate(-5deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: scale(0.95) rotate(5deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes typewriter {
|
||||
0%, 20% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
80%, 100% { opacity: 1; }
|
||||
|
||||
0%,
|
||||
20% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
80%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dotPulse {
|
||||
0%, 20%, 80%, 100% {
|
||||
|
||||
0%,
|
||||
20%,
|
||||
80%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
background: rgba(255,255,255,0.4);
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scale(1.5);
|
||||
background: rgba(255,255,255,0.9);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translateY(0px) rotate(0deg);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-20px) rotate(180deg);
|
||||
opacity: 1;
|
||||
@ -531,14 +587,27 @@
|
||||
}
|
||||
|
||||
@keyframes errorShake {
|
||||
0%, 100% { transform: translateX(0); }
|
||||
25% { transform: translateX(-10px); }
|
||||
75% { transform: translateX(10px); }
|
||||
|
||||
0%,
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: translateX(-10px);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translateX(10px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.popup-content, .loading-container, .error-container {
|
||||
|
||||
.popup-content,
|
||||
.loading-container,
|
||||
.error-container {
|
||||
width: 90%;
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
@ -145,11 +145,11 @@ export class TreeVisualizerComponent {
|
||||
}
|
||||
|
||||
|
||||
// Add these properties to your component class
|
||||
isLoading = false;
|
||||
showError = false;
|
||||
// Add these properties to your component class
|
||||
isLoading = false;
|
||||
showError = false;
|
||||
|
||||
// Method to handle the enhanced generate flow
|
||||
// Method to handle the enhanced generate flow
|
||||
generateJsonWithLoading() {
|
||||
this.isLoading = true;
|
||||
this.showError = false;
|
||||
@ -157,6 +157,7 @@ showError = false;
|
||||
console.log('🔄 Starting generateJsonWithLoading...');
|
||||
|
||||
// Call the actual generateJson method
|
||||
const [minPages, maxPages] = this.selectedPageRange.split("-").map(Number);
|
||||
|
||||
const prompt = `
|
||||
You are a JSON structure generator for website UI and sitemap hierarchy.
|
||||
@ -165,19 +166,20 @@ showError = false;
|
||||
|
||||
Each page must contain:
|
||||
|
||||
- 4 to 5 meaningful UI sections (e.g., "Header Section", "Form Section", "Feature Section", etc.)
|
||||
- Each page MUST contain at least 6 meaningful UI sections (including "Navbar" and "Footer"). These sections should be clearly named and described (e.g., "Header Section", "Hero Section", "Testimonial Section", etc.). You are NOT allowed to include fewer than 6 sections on any page.
|
||||
- A "Navbar" and a "Footer" section (always included on every page)
|
||||
- A short, clear description for each section (to support frontend development)
|
||||
|
||||
Constraints:
|
||||
- Total number of pages (including nested children) must be between ${this.selectedPageRange}
|
||||
- Do NOT create unnecessary or generic pages (e.g., no "Blog", "FAQ", etc.) unless explicitly present in the user flow
|
||||
- Pages that appear after user actions (e.g., clicking a card or after login) must be nested under the relevant parent using a "Children" key
|
||||
- DO NOT include any standalone section like "FAQ" or "Blog" as top-level pages unless mentioned
|
||||
|
||||
📘 Website Context:
|
||||
${this.rawInputText}
|
||||
|
||||
🔒 Strict Constraints:
|
||||
- You MUST generate at least ${minPages} and not more than ${maxPages} unique pages in total (including nested children), be strict on this
|
||||
- Each page MUST contain at least 6 meaningful UI sections (including "Navbar" and "Footer")
|
||||
- Do NOT create unnecessary or generic pages (e.g., no "Blog", "FAQ", etc.) unless explicitly present in the user flow
|
||||
- Pages that appear after user actions (e.g., clicking a card or after login) must be nested under the relevant parent using a "Children" key
|
||||
- DO NOT include any standalone section like "FAQ" or "Blog" as top-level pages unless mentioned
|
||||
|
||||
|
||||
--- Reference Format (DO NOT COPY; for structure only) ---
|
||||
@ -202,7 +204,6 @@ showError = false;
|
||||
}
|
||||
}
|
||||
---
|
||||
|
||||
🚫 DO NOT:
|
||||
- Include any explanation, notes, comments, or formatting (like \`\`\` or \`json\`)
|
||||
- Do NOT return escaped or markdown-formatted JSON
|
||||
@ -290,15 +291,15 @@ showError = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Helper method to check if all calls are complete
|
||||
private checkAndCompleteGeneration(parsedJson: any, pendingCalls: number) {
|
||||
// Helper method to check if all calls are complete
|
||||
private checkAndCompleteGeneration(parsedJson: any, pendingCalls: number) {
|
||||
if (pendingCalls === 0) {
|
||||
this.completeGeneration(parsedJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to complete the generation process
|
||||
private completeGeneration(parsedJson: any) {
|
||||
// Helper method to complete the generation process
|
||||
private completeGeneration(parsedJson: any) {
|
||||
this.inputJson = JSON.stringify(parsedJson);
|
||||
|
||||
const updatePayload = {
|
||||
@ -327,29 +328,29 @@ private completeGeneration(parsedJson: any) {
|
||||
this.handleGenerationError('Failed to save site structure');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to handle errors
|
||||
private handleGenerationError(message: string) {
|
||||
// Helper method to handle errors
|
||||
private handleGenerationError(message: string) {
|
||||
console.error('❌ Generation failed:', message);
|
||||
this.isLoading = false;
|
||||
this.showError = true;
|
||||
// Don't close popup so user can retry
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Enhanced close method
|
||||
closePopup() {
|
||||
// Enhanced close method
|
||||
closePopup() {
|
||||
this.showPopup = false;
|
||||
this.isLoading = false;
|
||||
this.showError = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Retry method for error state
|
||||
retryGeneration() {
|
||||
// Retry method for error state
|
||||
retryGeneration() {
|
||||
this.showError = false;
|
||||
this.generateJsonWithLoading();
|
||||
}
|
||||
}
|
||||
convertJson() {
|
||||
try {
|
||||
const parsed = JSON.parse(this.inputJson);
|
||||
@ -645,6 +646,7 @@ retryGeneration() {
|
||||
alert('Model data is not valid JSON format');
|
||||
}
|
||||
} else {
|
||||
this.openPopup();
|
||||
console.warn('⚠️ Model key not found or empty, keeping inputJson as is.');
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +1,34 @@
|
||||
<p>wire-frame-edit works!</p>
|
||||
<div class="wireframe-container">
|
||||
<!-- GrapesJS Editor + Sidebar -->
|
||||
<div class="app-container" *ngIf="currentPageHtml">
|
||||
<div class="canvas-container">
|
||||
<div #gjsContainer class="page-canvas"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- No content message -->
|
||||
<div class="no-content" *ngIf="!currentPageHtml">
|
||||
<p *ngIf="totalPages === 0">No HTML pages found in localStorage.</p>
|
||||
<p *ngIf="totalPages > 0 && !currentPageHtml">Current page has no HTML content.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Sticky Navigation buttons at bottom center -->
|
||||
<div class="sticky-navigation" *ngIf="totalPages > 1">
|
||||
<button
|
||||
class="nav-btn prev-btn"
|
||||
[disabled]="!hasPrevPage()"
|
||||
(click)="prevPage()">
|
||||
← Previous
|
||||
</button>
|
||||
<span class="page-indicator">
|
||||
{{ getCurrentPageNumber() }} / {{ totalPages }}
|
||||
</span>
|
||||
<button
|
||||
class="nav-btn next-btn"
|
||||
[disabled]="!hasNextPage()"
|
||||
(click)="nextPage()">
|
||||
Next →
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,161 @@
|
||||
// Hide GrapesJS outlines/highlights - IMPORTANT: This must be global
|
||||
:host ::ng-deep .gjs-dashed *[data-gjs-highlightable] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .gjs-cv-canvas {
|
||||
.gjs-dashed *[data-gjs-highlightable] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Hide any other GrapesJS visual indicators
|
||||
.gjs-hovered,
|
||||
.gjs-selected {
|
||||
outline: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.wireframe-container {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
|
||||
.app-container {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
|
||||
.canvas-container {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.page-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.no-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background-color: #f9f9f9;
|
||||
color: #666;
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.page-list {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 999;
|
||||
|
||||
h4 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.page-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.page-btn {
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border-color: #007bff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sticky navigation at bottom center
|
||||
.sticky-navigation {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
padding: 15px 25px;
|
||||
border-radius: 50px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
z-index: 1000;
|
||||
|
||||
.nav-btn {
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: #1976D2;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: #cccccc;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
&.prev-btn {
|
||||
background-color: #FF9800;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: #F57C00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-indicator {
|
||||
padding: 8px 16px;
|
||||
background-color: rgba(33, 150, 243, 0.1);
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
border: 2px solid #2196F3;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,142 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit, ViewChild, ElementRef, OnDestroy } from '@angular/core';
|
||||
import grapesjs from 'grapesjs';
|
||||
import presetWebpage from 'grapesjs-preset-webpage';
|
||||
|
||||
const editor = grapesjs.init({
|
||||
container: '#editor',
|
||||
plugins: [presetWebpage],
|
||||
});
|
||||
|
||||
|
||||
import { COMMON_CSS } from './common-css';
|
||||
|
||||
@Component({
|
||||
selector: 'app-wire-frame-edit',
|
||||
templateUrl: './wire-frame-edit.component.html',
|
||||
styleUrls: ['./wire-frame-edit.component.scss']
|
||||
styleUrls: ['./wire-frame-edit.component.scss'] // use your CSS here
|
||||
})
|
||||
export class WireFrameEditComponent {
|
||||
export class WireFrameEditComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('gjsContainer', { static: false }) gjsContainer!: ElementRef<HTMLDivElement>;
|
||||
|
||||
mapOfAllHtmlPages: { [key: string]: string } = {};
|
||||
pageKeys: string[] = [];
|
||||
currentPageIndex: number = 0;
|
||||
currentPageName: string = '';
|
||||
currentPageHtml: string = '';
|
||||
totalPages: number = 0;
|
||||
|
||||
sidebarOpen = true;
|
||||
private editor: any = null;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.mapOfAllHtmlPages = JSON.parse(localStorage.getItem('mapOfHtml') || '{}');
|
||||
this.pageKeys = Object.keys(this.mapOfAllHtmlPages);
|
||||
this.totalPages = this.pageKeys.length;
|
||||
if (this.totalPages > 0) {
|
||||
this.loadPage(0);
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
// Initialize GrapesJS after view is ready
|
||||
if (this.gjsContainer && this.currentPageHtml) {
|
||||
this.initGrapesJs();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.editor?.destroy();
|
||||
}
|
||||
|
||||
loadPage(index: number): void {
|
||||
if (index >= 0 && index < this.totalPages) {
|
||||
this.currentPageIndex = index;
|
||||
this.currentPageName = this.pageKeys[index];
|
||||
this.currentPageHtml = this.mapOfAllHtmlPages[this.currentPageName];
|
||||
// If GrapesJS already initialized, update its content
|
||||
if (this.editor) {
|
||||
this.editor.setComponents(this.currentPageHtml, { keepScripts: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextPage(): void {
|
||||
if (this.currentPageIndex < this.totalPages - 1) {
|
||||
this.loadPage(this.currentPageIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
prevPage(): void {
|
||||
if (this.currentPageIndex > 0) {
|
||||
this.loadPage(this.currentPageIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
hasNextPage(): boolean {
|
||||
return this.currentPageIndex < this.totalPages - 1;
|
||||
}
|
||||
|
||||
hasPrevPage(): boolean {
|
||||
return this.currentPageIndex > 0;
|
||||
}
|
||||
|
||||
getCurrentPageNumber(): number {
|
||||
return this.currentPageIndex + 1;
|
||||
}
|
||||
|
||||
toggleSidebar() {
|
||||
this.sidebarOpen = !this.sidebarOpen;
|
||||
}
|
||||
|
||||
downloadHtml() {
|
||||
const blob = new Blob([this.currentPageHtml], { type: 'text/html' });
|
||||
const a = document.createElement('a');
|
||||
a.href = URL.createObjectURL(blob);
|
||||
a.download = `${this.currentPageName || 'exported-page'}.html`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(a.href);
|
||||
}
|
||||
|
||||
private initGrapesJs() {
|
||||
// If already initialized, destroy and re-init
|
||||
if (this.editor) {
|
||||
this.editor.destroy();
|
||||
}
|
||||
this.editor = grapesjs.init({
|
||||
container: this.gjsContainer.nativeElement,
|
||||
fromElement: false,
|
||||
storageManager: false,
|
||||
plugins: ['gjs-preset-webpage'],
|
||||
allowScripts: 1,
|
||||
} as any);
|
||||
|
||||
this.editor.setComponents(this.currentPageHtml, { keepScripts: true });
|
||||
|
||||
this.editor.on('component:update', this.updateCurrentPageHtml.bind(this));
|
||||
this.editor.on('style:change', this.updateCurrentPageHtml.bind(this));
|
||||
}
|
||||
|
||||
private updateCurrentPageHtml() {
|
||||
if (!this.editor) return;
|
||||
const html = this.editor.getHtml();
|
||||
const css = this.editor.getCss();
|
||||
this.currentPageHtml = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${this.currentPageName}</title>
|
||||
<style>${css }</style>
|
||||
<style>${COMMON_CSS }</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
${html}
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
// Optionally, update your map and localStorage here if you want autosave
|
||||
// this.mapOfAllHtmlPages[this.currentPageName] = this.currentPageHtml;
|
||||
// localStorage.setItem('mapOfHtml', JSON.stringify(this.mapOfAllHtmlPages));
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +101,7 @@ import { EditstepperComponent } from './BuilderComponents/vpspack/Visa_applicati
|
||||
import { Design_lbraryComponent } from './fnd/SiteTreeBuilder/Design_lbrary/Design_lbrary.component';
|
||||
import { Dlf_headerComponent } from './fnd/SiteTreeBuilder/Dlf_header/Dlf_header.component';
|
||||
import { WireFrameEditComponent } from './fnd/SiteTreeBuilder/wire-frame-edit/wire-frame-edit.component';
|
||||
import { TagComponent } from './fnd/SiteTreeBuilder/Tag/Tag.component';
|
||||
|
||||
|
||||
|
||||
@ -272,10 +273,14 @@ const routes: Routes = [
|
||||
|
||||
|
||||
// buildercomponents
|
||||
|
||||
{ path: 'Tag', component: TagComponent },
|
||||
{ path: 'Dlf_header', component: Dlf_headerComponent },
|
||||
|
||||
// { path: 'Design_lbrary', component: Design_lbraryComponent },
|
||||
{ path: 'Design_lbrary/:id', component: Design_lbraryComponent },
|
||||
{ path: 'WireFrameEdit', component: WireFrameEditComponent },
|
||||
|
||||
|
||||
|
||||
{ path: 'sitetree', component: SiteTreeComponent, },
|
||||
|
||||
@ -129,6 +129,7 @@ import { Design_lbraryComponent } from './fnd/SiteTreeBuilder/Design_lbrary/Desi
|
||||
import { Dlf_headerComponent } from './fnd/SiteTreeBuilder/Dlf_header/Dlf_header.component';
|
||||
import { EditstepperTfComponent } from './fnd/Visa_application/VisaOrderWorkflow/editstepperTf.component';
|
||||
import { WireFrameEditComponent } from './fnd/SiteTreeBuilder/wire-frame-edit/wire-frame-edit.component';
|
||||
import { TagComponent } from './fnd/SiteTreeBuilder/Tag/Tag.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -152,6 +153,8 @@ import { WireFrameEditComponent } from './fnd/SiteTreeBuilder/wire-frame-edit/wi
|
||||
|
||||
|
||||
// buildercomponents
|
||||
WireFrameEditComponent,
|
||||
TagComponent,
|
||||
EditstepperTfComponent,
|
||||
Dlf_headerComponent,
|
||||
Design_lbraryComponent,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user