diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/vpspack/Visa_application/VisaOrderWorkflow/editstepper.component.ts b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/vpspack/Visa_application/VisaOrderWorkflow/editstepper.component.ts index e269bdc..566b937 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/vpspack/Visa_application/VisaOrderWorkflow/editstepper.component.ts +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/vpspack/Visa_application/VisaOrderWorkflow/editstepper.component.ts @@ -52,13 +52,13 @@ export class EditstepperComponent implements OnInit { public entryForm: FormGroup; - + submitted = false; rowSelected: any = {}; modalcomplete = false; - constructor(private mainService: Visa_applicationservice, - + constructor( + private mainService: Visa_applicationservice, private _fb: FormBuilder, private router: Router, private route: ActivatedRoute, diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder 8.zip b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder 8.zip new file mode 100644 index 0000000..96a28e5 Binary files /dev/null and b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder 8.zip differ diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.html b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.html index c49add8..8cdd74d 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.html +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.html @@ -73,7 +73,7 @@
-
+

Default Sections

{{ template.type }}
{{ template.description }}
- +

Custom Sections

{{ customSection.type }}
{{ customSection.description }}
- + -
+
No custom sections created yet. Create one below!
@@ -115,31 +115,38 @@
-
-
-
Edit Section: {{ selectedSection?.type }}
- -
-
-
- - +
+
+
Edit Section: {{ selectedSection?.type }}
+
-
- - - -
-
- - +
+
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + +
-
- - -
- - -
- -
-
- - {{ page.name }} + + +
+ + +
- -
- - -
-

No sections added yet

- +
+ + +
+
{{ section.type }}
+
+
+ + +
+
+ +
+
+ + +
+ Add Section +
+
+ +
+ +
- - -
-
{{ section.type }}
-
-
- - -
-
- -
-
- - -
- Add Section -
-
- -
- - +
-
- + + +
+ +
+
+ + +
+
+ + +
+ + +
- - -
- -
- - -
-
- - -
- - - -
-
- \ No newline at end of file + \ No newline at end of file diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.ts b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.ts index 94ccc7f..62b80d7 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.ts +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/TreeNode/tree-node.component.ts @@ -9,6 +9,8 @@ import { ToastrService } from 'ngx-toastr'; interface Section { type: string; content: string; + keywords?: string; // <-- Add this line + } interface Page { @@ -140,17 +142,17 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit { customSections = [ - { - type: 'Visa Application', - description: 'Visa application form and process', - content: 'Complete visa application with required documents and processing information.' - }, - { - type: 'Visa Application 2', - description: 'Alternative visa application layout', - content: 'Alternative visa application design with step-by-step guidance.' - } -]; + { + type: 'Visa Application', + description: 'Visa application form and process', + content: 'Complete visa application with required documents and processing information.' + }, + { + type: 'Visa Application 2', + description: 'Alternative visa application layout', + content: 'Alternative visa application design with step-by-step guidance.' + } + ]; constructor( @@ -538,6 +540,18 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit { // If parsing fails, use the raw content pageObj[section.type] = section.content; } + + // ✅ Save keywords if present + if (section.keywords) { + if (typeof pageObj[section.type] === 'object') { + pageObj[section.type].keywords = section.keywords; + } else { + pageObj[section.type] = { + text: pageObj[section.type], + keywords: section.keywords + }; + } + } }); // Add children @@ -709,19 +723,19 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit { // Save section changes saveSection(): void { - if (this.selectedSection && this.currentParentPage) { - // Find the original section in the parent page by reference - const originalSection = this.currentParentPage.sections.find(s => s === this.selectedSection); - - if (originalSection) { - // Update the original section directly - originalSection.type = this.selectedSection.type; - originalSection.content = this.selectedSection.content; - this.hasUnsavedChanges = true; + if (this.selectedSection && this.currentParentPage) { + // Find the original section in the parent page by reference + const originalSection = this.currentParentPage.sections.find(s => s === this.selectedSection); + + if (originalSection) { + // Update the original section directly + originalSection.type = this.selectedSection.type; + originalSection.content = this.selectedSection.content; + this.hasUnsavedChanges = true; + } } + this.closeEditSectionOffcanvas(); } - this.closeEditSectionOffcanvas(); -} // Add section from a template addSectionFromTemplate(template: any): void { @@ -751,79 +765,79 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit { // Similar update for addCustomSection addCustomSection(): void { - if (this.currentParentPage && this.customSectionType) { - const newSection: Section = { - type: this.customSectionType, - content: this.customSectionContent || '' - }; - - // Add to current page - if (this.currentSectionIndex >= 0) { - this.currentParentPage.sections.splice(this.currentSectionIndex + 1, 0, newSection); - } else { - this.currentParentPage.sections.push(newSection); - } - - // Add to custom sections list if it doesn't exist - const existingCustomSection = this.customSections.find(cs => cs.type === this.customSectionType); - if (!existingCustomSection) { - this.customSections.push({ + if (this.currentParentPage && this.customSectionType) { + const newSection: Section = { type: this.customSectionType, - description: 'Custom section', content: this.customSectionContent || '' - }); + }; + + // Add to current page + if (this.currentSectionIndex >= 0) { + this.currentParentPage.sections.splice(this.currentSectionIndex + 1, 0, newSection); + } else { + this.currentParentPage.sections.push(newSection); + } + + // Add to custom sections list if it doesn't exist + const existingCustomSection = this.customSections.find(cs => cs.type === this.customSectionType); + if (!existingCustomSection) { + this.customSections.push({ + type: this.customSectionType, + description: 'Custom section', + content: this.customSectionContent || '' + }); + } + + // Add to available section types + if (!this.availableSectionTypes.includes(this.customSectionType)) { + this.availableSectionTypes.push(this.customSectionType); + } + + this.hasUnsavedChanges = true; + this.closeAddSectionOffcanvas(); } - // Add to available section types - if (!this.availableSectionTypes.includes(this.customSectionType)) { - this.availableSectionTypes.push(this.customSectionType); - } - this.hasUnsavedChanges = true; - this.closeAddSectionOffcanvas(); } + addCustomSectionFromList(customSection: any): void { + if (this.currentParentPage) { + const newSection: Section = { + type: customSection.type, + content: customSection.content + }; -} + // Insert at specific position if provided, otherwise add to end + if (this.currentSectionIndex >= 0) { + this.currentParentPage.sections.splice(this.currentSectionIndex + 1, 0, newSection); + } else { + this.currentParentPage.sections.push(newSection); + } -addCustomSectionFromList(customSection: any): void { - if (this.currentParentPage) { - const newSection: Section = { - type: customSection.type, - content: customSection.content - }; + if (!this.availableSectionTypes.includes(customSection.type)) { + this.availableSectionTypes.push(customSection.type); + } - // Insert at specific position if provided, otherwise add to end - if (this.currentSectionIndex >= 0) { - this.currentParentPage.sections.splice(this.currentSectionIndex + 1, 0, newSection); - } else { - this.currentParentPage.sections.push(newSection); + this.hasUnsavedChanges = true; + this.closeAddSectionOffcanvas(); } - - if (!this.availableSectionTypes.includes(customSection.type)) { - this.availableSectionTypes.push(customSection.type); - } - - this.hasUnsavedChanges = true; - this.closeAddSectionOffcanvas(); } -} // Edit section // Edit section - modify this function editSection(section: Section, event: Event): void { - event.stopPropagation(); - // Store reference to the original section - this.selectedSection = section; // Don't clone, use direct reference - this.currentParentPage = this.selectedPage; - this.editMode = 'section'; - this.showEditSectionOffcanvas = true; + event.stopPropagation(); + // Store reference to the original section + this.selectedSection = section; // Don't clone, use direct reference + this.currentParentPage = this.selectedPage; + this.editMode = 'section'; + this.showEditSectionOffcanvas = true; - // Listen for clicks outside offcanvas - setTimeout(() => { - document.addEventListener('click', this.handleOutsideClick); - }, 10); -} + // Listen for clicks outside offcanvas + setTimeout(() => { + document.addEventListener('click', this.handleOutsideClick); + }, 10); + } // Cancel edit cancelEdit(): void { @@ -860,112 +874,112 @@ addCustomSectionFromList(customSection: any): void { // Handle page drag start onPageDragStart(page: Page, event: DragEvent): void { - this.draggedPage = page; - if (event.dataTransfer) { - event.dataTransfer.effectAllowed = 'move'; - event.dataTransfer.setData('text/html', page.name); - } - - // Add visual feedback - setTimeout(() => { - const draggedElement = event.target as HTMLElement; - if (draggedElement) { - draggedElement.classList.add('dragging'); + this.draggedPage = page; + if (event.dataTransfer) { + event.dataTransfer.effectAllowed = 'move'; + event.dataTransfer.setData('text/html', page.name); } - }, 0); -} -onPageDragOver(event: DragEvent): void { - event.preventDefault(); - event.stopPropagation(); - - if (event.dataTransfer) { - event.dataTransfer.dropEffect = 'move'; + // Add visual feedback + setTimeout(() => { + const draggedElement = event.target as HTMLElement; + if (draggedElement) { + draggedElement.classList.add('dragging'); + } + }, 0); } - - // Add visual feedback - const dropZone = event.currentTarget as HTMLElement; - if (dropZone) { - dropZone.classList.add('drag-over'); - } -} -onPageDragLeave(event: DragEvent): void { - const dropZone = event.currentTarget as HTMLElement; - if (dropZone) { - dropZone.classList.remove('drag-over'); + onPageDragOver(event: DragEvent): void { + event.preventDefault(); + event.stopPropagation(); + + if (event.dataTransfer) { + event.dataTransfer.dropEffect = 'move'; + } + + // Add visual feedback + const dropZone = event.currentTarget as HTMLElement; + if (dropZone) { + dropZone.classList.add('drag-over'); + } + } + + onPageDragLeave(event: DragEvent): void { + const dropZone = event.currentTarget as HTMLElement; + if (dropZone) { + dropZone.classList.remove('drag-over'); + } } -} // Handle page drag end onPageDragEnd(event: DragEvent): void { - // Remove visual feedback - const draggedElement = event.target as HTMLElement; - if (draggedElement) { - draggedElement.classList.remove('dragging'); + // Remove visual feedback + const draggedElement = event.target as HTMLElement; + if (draggedElement) { + draggedElement.classList.remove('dragging'); + } + + // Remove all drop zone highlights + document.querySelectorAll('.drop-zone').forEach(el => { + el.classList.remove('drag-over'); + }); + + this.draggedPage = null; + this.dropTargetPage = null; } - - // Remove all drop zone highlights - document.querySelectorAll('.drop-zone').forEach(el => { - el.classList.remove('drag-over'); - }); - - this.draggedPage = null; - this.dropTargetPage = null; -} // Handle page drop -onPageDrop(targetPage: Page, event: DragEvent): void { - event.preventDefault(); - event.stopPropagation(); - - // Remove visual feedback - const dropZone = event.currentTarget as HTMLElement; - if (dropZone) { - dropZone.classList.remove('drag-over'); - } - - if (!this.draggedPage || this.draggedPage === targetPage) { - return; - } - - // Prevent dropping a parent into its own child - if (this.isDescendant(targetPage, this.draggedPage)) { - console.warn('Cannot drop a parent into its own descendant'); - return; - } - - // Remove from current parent - if (this.draggedPage.parent && this.draggedPage.parent.children) { - const sourceIndex = this.draggedPage.parent.children.indexOf(this.draggedPage); - if (sourceIndex > -1) { - this.draggedPage.parent.children.splice(sourceIndex, 1); - } - } - - // Add to new parent - if (!targetPage.children) { - targetPage.children = []; - } - - // Update parent reference - this.draggedPage.parent = targetPage; - targetPage.children.push(this.draggedPage); - - this.hasUnsavedChanges = true; - console.log(`Moved "${this.draggedPage.name}" to "${targetPage.name}"`); -} + onPageDrop(targetPage: Page, event: DragEvent): void { + event.preventDefault(); + event.stopPropagation(); -private isDescendant(possibleDescendant: Page, ancestor: Page): boolean { - if (!ancestor.children) return false; - - for (const child of ancestor.children) { - if (child === possibleDescendant) return true; - if (this.isDescendant(possibleDescendant, child)) return true; + // Remove visual feedback + const dropZone = event.currentTarget as HTMLElement; + if (dropZone) { + dropZone.classList.remove('drag-over'); + } + + if (!this.draggedPage || this.draggedPage === targetPage) { + return; + } + + // Prevent dropping a parent into its own child + if (this.isDescendant(targetPage, this.draggedPage)) { + console.warn('Cannot drop a parent into its own descendant'); + return; + } + + // Remove from current parent + if (this.draggedPage.parent && this.draggedPage.parent.children) { + const sourceIndex = this.draggedPage.parent.children.indexOf(this.draggedPage); + if (sourceIndex > -1) { + this.draggedPage.parent.children.splice(sourceIndex, 1); + } + } + + // Add to new parent + if (!targetPage.children) { + targetPage.children = []; + } + + // Update parent reference + this.draggedPage.parent = targetPage; + targetPage.children.push(this.draggedPage); + + this.hasUnsavedChanges = true; + console.log(`Moved "${this.draggedPage.name}" to "${targetPage.name}"`); + } + + private isDescendant(possibleDescendant: Page, ancestor: Page): boolean { + if (!ancestor.children) return false; + + for (const child of ancestor.children) { + if (child === possibleDescendant) return true; + if (this.isDescendant(possibleDescendant, child)) return true; + } + + return false; } - - return false; -} // Handle section drag drop onSectionDrop(event: CdkDragDrop): void { if (event.previousContainer === event.container) { @@ -999,26 +1013,26 @@ private isDescendant(possibleDescendant: Page, ancestor: Page): boolean { } showAddSectionForEmptyPage(page: Page, event: Event): void { - event.stopPropagation(); - this.openAddSectionOffcanvas(page, -1, event); -} + event.stopPropagation(); + this.openAddSectionOffcanvas(page, -1, event); + } -// Add these helper methods to your component for proper connector positioning + // Add these helper methods to your component for proper connector positioning -getHorizontalConnectorLeft(childrenCount: number): number { - // Calculate left position for horizontal connector - const nodeWidth = 250; // Approximate node width - const gap = 40; // Gap between nodes - const totalWidth = (childrenCount * nodeWidth) + ((childrenCount - 1) * gap); - return (totalWidth / 2) - (totalWidth / childrenCount / 2); -} + getHorizontalConnectorLeft(childrenCount: number): number { + // Calculate left position for horizontal connector + const nodeWidth = 250; // Approximate node width + const gap = 40; // Gap between nodes + const totalWidth = (childrenCount * nodeWidth) + ((childrenCount - 1) * gap); + return (totalWidth / 2) - (totalWidth / childrenCount / 2); + } -getHorizontalConnectorWidth(childrenCount: number): number { - // Calculate width of horizontal connector - const nodeWidth = 250; // Approximate node width - const gap = 40; // Gap between nodes - return (childrenCount - 1) * (nodeWidth + gap); -} + getHorizontalConnectorWidth(childrenCount: number): number { + // Calculate width of horizontal connector + const nodeWidth = 250; // Approximate node width + const gap = 40; // Gap between nodes + return (childrenCount - 1) * (nodeWidth + gap); + } // Save tree data saveTreeData(silent: boolean = false): void { diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.html b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.html index 0cd2f9c..0332af5 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.html +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.html @@ -451,7 +451,8 @@ (cdkDropListDropped)="onSectionDrop($event, getCurrentPageName())">
+ class="section-container" [class.editing]="isCurrentSectionEditing(sectionKey)" + (click)="openCssEditor(getCurrentPageName(), sectionKey)">
@@ -483,6 +484,27 @@
+ +
+

Edit CSS for Section: {{ selectedSection?.section }}

+ +
+

.{{ className }}

+
+ + + +
+ +
+ + + +
+ + + +
diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.scss b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.scss index 96051d8..5551daf 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.scss +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.scss @@ -1920,6 +1920,73 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15); margin-left: 10px; } + .css-editor-modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.3); + z-index: 1000; + display: flex; + justify-content: center; + align-items: center; + } + + // css editor + .css-editor-modal-overlay { + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + background: rgba(0, 0, 0, 0.4); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + } + + .css-editor-modal { + background: white; + padding: 20px; + width: 600px; + max-height: 80vh; + overflow-y: auto; + border-radius: 8px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + z-index: 1001; + } + + .css-editor-modal input { + width: 100%; + padding: 6px 8px; + margin-bottom: 8px; + border: 1px solid #ccc; + border-radius: 4px; + } + + .css-editor-header { + display: flex; + justify-content: space-between; + align-items: center; + } + + .css-editor-header .close-btn { + background: transparent; + border: none; + font-size: 18px; + cursor: pointer; + } + + .css-editor-footer { + margin-top: 20px; + display: flex; + gap: 10px; + justify-content: flex-end; + } + + // chow code css end } \ No newline at end of file diff --git a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.ts b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.ts index d9bdfd0..872bcfc 100644 --- a/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.ts +++ b/visaproject-front-f/authsec_angular/frontend/angular-clarity-master/src/app/modules/main/fnd/SiteTreeBuilder/WireframesUi/wireframe-renderer.component.ts @@ -3741,9 +3741,105 @@ async deployAllPages() { } +// css editor +showCssEditorModal = false; +cssEditorStyles: any = {}; +selectedSection: { page: string; section: string } | null = null; + +closeCssEditor(): void { + this.showCssEditorModal = false; + this.selectedSection = null; + this.cssEditorStyles = {}; +} - + +// new + +openCssEditor(page: string, section: string): void { + const rawHtml = this.sectionHtmls[page]?.[section]?.toString() || ''; + + // ✅ Step 1: Parse all class names recursively + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = rawHtml; + + const classSet = new Set(); + + // Traverse all elements recursively and extract classList + const elements = tempDiv.querySelectorAll('*'); + elements.forEach(el => { + const classList = Array.from(el.classList); + classList.forEach(cls => classSet.add(cls)); + }); + + const allClasses = Array.from(classSet); + + // ✅ Step 2: Extract CSS rules for all these classes + const cssMap: Record> = {}; + allClasses.forEach(cls => { + const rules = this.extractCssForClass(cls, this.finalCssBundle); // use your full css bundle + cssMap[cls] = rules; + }); + + // ✅ Step 3: Store in modal + this.selectedSection = { page, section }; + this.classCssMap = cssMap; + this.showCssEditorModal = true; +} + + + +extractClassesFromHtml(html: string): string[] { + const match = html.match(/class=["']([^"']+)["']/); + if (!match) return []; + return match[1].split(/\s+/).filter(cls => cls.trim()); +} + +extractCssForClass(className: string, cssText: string): Record { + const result: Record = {}; + const regex = new RegExp(`\\.${className}\\s*{([^}]*)}`, 'g'); + let match; + + while ((match = regex.exec(cssText)) !== null) { + const props = match[1].split(';').map(p => p.trim()).filter(Boolean); + props.forEach(prop => { + const [key, val] = prop.split(':'); + if (key && val) result[key.trim()] = val.trim(); + }); + } + + return result; +} + + classCssMap: Record> = {}; + +saveClassCss(): void { + let cssBundle = ''; + + for (const [className, props] of Object.entries(this.classCssMap)) { + const block = Object.entries(props) + .map(([k, v]) => ` ${k}: ${v};`) + .join('\n'); + cssBundle += `.${className} {\n${block}\n}\n\n`; + } + + const { page, section } = this.selectedSection!; + this.allPageCss[page] = this.allPageCss[page] || {}; + this.allPageCss[page][section] = cssBundle; + + this.updateFullPageHtml(page); + this.toastr.success(`CSS updated for ${section}`); + this.closeCssEditor(); +} + +addCssProp(className: string): void { + this.classCssMap[className]['new-property'] = ''; +} + +removeCssProp(className: string, prop: string): void { + delete this.classCssMap[className][prop]; +} + }