Compare commits

...
5 Commits
6 changed files with 372 additions and 1 deletions
@@ -0,0 +1,12 @@
server {
listen 80;
server_name localhost;
client_max_body_size 500M;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
@@ -42,7 +42,7 @@ export class FileUploaderComponent implements ControlValueAccessor {
case 'audio': case 'audio':
return 'audio/*'; return 'audio/*';
case 'video': case 'video':
return 'video/*'; return 'video/*,video/mp4,video/x-m4v,video/webm,.mp4,.mkv,.avi,.mov';
default: default:
return '*/*'; return '*/*';
} }
@@ -0,0 +1,96 @@
import { Component, OnInit, Input, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-captcha',
template: `
<div class="clr-form-control" style="margin-top: 0;">
<label class="clr-control-label" *ngIf="label" style="font-weight: 500; margin-bottom: 4px;">{{ label }}</label>
<div class="clr-control-container">
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 6px;">
<div style="background: #eef3f7; border: 1px dashed #0072a3; padding: 6px 14px; border-radius: 4px; font-family: 'Courier New', monospace; font-size: 18px; font-weight: bold; letter-spacing: 4px; color: #004d73; user-select: none;">
{{ captchaCode }}
</div>
<button type="button" class="btn btn-icon btn-sm btn-primary" (click)="generateCaptcha()" title="Refresh Captcha" style="margin: 0;">
<clr-icon shape="refresh"></clr-icon>
</button>
</div>
<input
clrInput
type="text"
[(ngModel)]="enteredValue"
(input)="onInput()"
placeholder="Enter code shown above"
class="clr-input"
style="max-width: 220px;"
/>
<div *ngIf="enteredValue && !isValid" style="color: #c92100; font-size: 12px; margin-top: 4px;">
* Captcha code does not match.
</div>
<div *ngIf="enteredValue && isValid" style="color: #2e7d32; font-size: 12px; margin-top: 4px;">
✓ Captcha verified
</div>
</div>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CaptchaComponent),
multi: true
}
]
})
export class CaptchaComponent implements OnInit, ControlValueAccessor {
@Input() label: string = 'Verification Code';
captchaCode: string = '';
enteredValue: string = '';
isValid: boolean = false;
private onChange: (val: any) => void = () => {};
private onTouched: () => void = () => {};
ngOnInit(): void {
this.generateCaptcha();
}
generateCaptcha(): void {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
let code = '';
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
this.captchaCode = code;
this.enteredValue = '';
this.isValid = false;
this.onChange('');
}
onInput(): void {
this.onTouched();
if (this.enteredValue && this.enteredValue.trim() === this.captchaCode) {
this.isValid = true;
this.onChange(this.enteredValue.trim());
} else {
this.isValid = false;
this.onChange('');
}
}
writeValue(value: any): void {
if (!value) {
this.enteredValue = '';
this.isValid = false;
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
}
@@ -0,0 +1,30 @@
import { Directive, ElementRef, Input, OnChanges, SimpleChanges } from '@angular/core';
declare var JsBarcode: any;
@Directive({
selector: '[appBarcode]'
})
export class BarcodeDirective implements OnChanges {
@Input('appBarcode') value: string;
constructor(private el: ElementRef) {}
ngOnChanges(changes: SimpleChanges): void {
if (this.value && typeof JsBarcode !== 'undefined') {
try {
JsBarcode(this.el.nativeElement, String(this.value), {
format: 'CODE128',
height: 45,
width: 1.5,
displayValue: true
});
} catch (err) {
this.el.nativeElement.innerHTML = '';
}
} else {
this.el.nativeElement.innerHTML = '';
}
}
}
@@ -40,6 +40,8 @@ import { CKEditorModule } from 'ng2-ckeditor';
import { UserRegistrationComponent } from '../main/admin/user-registration/user-registration.component'; import { UserRegistrationComponent } from '../main/admin/user-registration/user-registration.component';
import { QRCodeModule } from 'angularx-qrcode'; import { QRCodeModule } from 'angularx-qrcode';
import { BarcodeDirective } from './directives/barcode.directive';
import { CaptchaComponent } from './components/captcha/captcha.component';
import { TagInputModule } from 'ngx-chips'; import { TagInputModule } from 'ngx-chips';
import { CookieService } from 'ngx-cookie-service'; import { CookieService } from 'ngx-cookie-service';
import { ImageCropperModule } from 'ngx-image-cropper'; import { ImageCropperModule } from 'ngx-image-cropper';
@@ -121,6 +123,8 @@ import { DynamicFormViewerComponent } from './superadmin/dynamicform/dynamic-for
@NgModule({ @NgModule({
declarations: [ declarations: [
BarcodeDirective,
CaptchaComponent,
MainPageComponent, PageNotFoundComponent, UserComponent, PasswordResetComponent, MainPageComponent, PageNotFoundComponent, UserComponent, PasswordResetComponent,
MyworkspaceComponent, MyworkspaceComponent,
ReportRunnerComponent, ReportrunnereditComponent, Reportrunneredit2Component, MenuGroupComponent, AllMenuGroupComponent, EditMenuGroupComponent, ReadOnlyMenuGroupComponent, UserRegistrationComponent, ReportRunnerComponent, ReportrunnereditComponent, Reportrunneredit2Component, MenuGroupComponent, AllMenuGroupComponent, EditMenuGroupComponent, ReadOnlyMenuGroupComponent, UserRegistrationComponent,
+229
View File
@@ -0,0 +1,229 @@
{
"tech": "angularnew",
"object_type": "form",
"sub_object_type": "only header",
"example_entity": "Product",
"git_repo": "http://157.66.191.31:3000/risadmin_prod/authsec_testangular.git",
"git_branch": "main",
"ref_folder": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref",
"targets": [
{
"profile": "route",
"file": "frontend/angular-clarity-master/src/app/modules/main/main-routing.module.ts",
"anchor": "// buildercomponents",
"dedup": "{{Table}}Component",
"import_tpl": "import { {{Table}}Component } from './BuilderComponents/{{repo}}/{{Table}}/{{Table}}.component';",
"body_tpl": " { path: '{{table_lower}}', component: {{Table}}Component },",
"add": "{ path: '{{table_lower}}', component: {{Table}}Component },"
},
{
"profile": "plain",
"file": "frontend/angular-clarity-master/src/app/modules/main/main.module.ts",
"anchor": "// buildercomponents",
"dedup": "{{Table}}Component",
"import_tpl": "import { {{Table}}Component } from './BuilderComponents/{{repo}}/{{Table}}/{{Table}}.component';",
"body_tpl": " {{Table}}Component,",
"add": " {{Table}}Component,"
}
],
"files": [
{
"source_ref": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.ts",
"path_tpl": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.ts",
"description": "Component TypeScript file",
"content_tpl": "import { Component, OnInit } from '@angular/core';\nimport { ToastrService } from 'ngx-toastr';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { {{TABLE}}Service } from './{{TABLE}}.service';\nimport { ApiRequestService } from 'src/app/services/api/api-request.service';\n\n@Component({\n selector: 'app-{{TABLE_LOWER}}',\n templateUrl: './{{TABLE}}.component.html',\n styleUrls: ['./{{TABLE}}.component.scss']\n})\nexport class {{TABLE}}Component implements OnInit {\n rowSelected: any = {};\n modaldelete = false;\n modalEdit = false;\n modalAdd = false;\n loading = false;\n items: any[] = [];\n selected: any[] = [];\n error: string;\n/* {{RELATION_DECLARATIONS}} */\n\n constructor(\n private mainService: {{TABLE}}Service,\n private apiRequest: ApiRequestService,\n private toastr: ToastrService,\n private router: Router,\n private route: ActivatedRoute\n ) { }\n\n ngOnInit(): void {\n this.getData();\n/* {{RELATION_LOADERS}} */\n }\n\n getColumns(): string[] {\n if (!this.items || this.items.length === 0) {\n return [];\n }\n return Object.keys(this.items[0]).filter(k => k !== 'id');\n }\n\n getData() {\n this.loading = true;\n this.mainService.getAll().subscribe((data) => {\n this.loading = false;\n this.items = data || [];\n if (this.items.length === 0) {\n this.error = 'No Data Available';\n }\n }, (error) => {\n this.loading = false;\n this.error = 'Server Error';\n });\n }\n\n goToAdd() {\n this.rowSelected = {};\n this.modalAdd = true;\n }\n\n onEdit(row: any) {\n this.rowSelected = Object.assign({}, row);\n this.modalEdit = true;\n }\n\n onDelete(row: any) {\n this.rowSelected = row;\n this.modaldelete = true;\n }\n\n delete(id: number) {\n this.modaldelete = false;\n this.mainService.delete(id).subscribe(() => {\n this.toastr.success('Deleted successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to delete');\n });\n }\n\n onCreate() {\n this.modalAdd = false;\n this.mainService.create(this.rowSelected).subscribe(() => {\n this.toastr.success('Added successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to add');\n });\n }\n\n onUpdate(id: number) {\n this.modalEdit = false;\n this.mainService.update(id, this.rowSelected).subscribe(() => {\n this.toastr.success('Updated successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to update');\n });\n }\n}\n"
},
{
"source_ref": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.html",
"path_tpl": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.html",
"description": "Component HTML template",
"content_tpl": "<ol class=\"breadcrumb breadcrumb-arrow font-trirong\">\n <li><a href=\"javascript://\"><clr-icon shape=\"home\"></clr-icon></a></li>\n <li><a href=\"javascript://\"> {{TABLE}}</a></li>\n</ol>\n\n<div class=\"dg-wrapper\">\n <div class=\"clr-row\">\n <div class=\"clr-col-8\">\n <h3>{{TABLE}} Management</h3>\n </div>\n <div class=\"clr-col-4\" style=\"text-align: right;\">\n <button id=\"add\" class=\"btn btn-primary\" (click)=\"goToAdd()\">\n <clr-icon shape=\"plus\"></clr-icon> ADD\n </button>\n </div>\n </div>\n\n <!-- CLARITY DATAGRID -->\n <clr-datagrid [clrDgLoading]=\"loading\" [(clrDgSelected)]=\"selected\">\n <clr-dg-placeholder>\n <ng-template #loadingSpinner>\n <clr-spinner>Loading ...</clr-spinner>\n </ng-template>\n <div *ngIf=\"error; else loadingSpinner\">{{error}}</div>\n </clr-dg-placeholder>\n\n <!-- DYNAMIC COLUMN HEADERS -->\n <clr-dg-column *ngFor=\"let col of getColumns()\" [clrDgField]=\"col\">\n <ng-container *clrDgHideableColumn=\"{hidden: false}\">{{ col | titlecase }}</ng-container>\n </clr-dg-column>\n\n <clr-dg-column>\n <ng-container *clrDgHideableColumn=\"{hidden: false}\">\n <clr-icon shape=\"bars\"></clr-icon> Action\n </ng-container>\n </clr-dg-column>\n\n <!-- DYNAMIC DATA ROWS -->\n <clr-dg-row *clrDgItems=\"let item of items\" [clrDgItem]=\"item\">\n{{LIST_ITEMS}}\n <clr-dg-cell>\n <span style=\"cursor: pointer; margin-right: 10px;\" (click)=\"onEdit(item)\" title=\"Edit\">\n <clr-icon shape=\"pencil\"></clr-icon>\n </span>\n <span style=\"cursor: pointer; color: red;\" (click)=\"onDelete(item)\" title=\"Delete\">\n <clr-icon shape=\"trash\" class=\"is-error\"></clr-icon>\n </span>\n </clr-dg-cell>\n\n <clr-dg-action-overflow>\n <button class=\"action-item\" (click)=\"onEdit(item)\">Edit</button>\n <button class=\"action-item\" (click)=\"onDelete(item)\">Delete</button>\n </clr-dg-action-overflow>\n </clr-dg-row>\n\n <clr-dg-footer>\n <clr-dg-pagination #pagination [clrDgPageSize]=\"10\">\n <clr-dg-page-size [clrPageSizeOptions]=\"[10,20,50,100]\">Items per page</clr-dg-page-size>\n {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} of {{pagination.totalItems}} items\n </clr-dg-pagination>\n </clr-dg-footer>\n </clr-datagrid>\n</div>\n\n<!-- ADD MODAL -->\n<clr-modal [(clrModalOpen)]=\"modalAdd\" [clrModalSize]=\"'lg'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Add {{TABLE}}</h3>\n <div class=\"modal-body\">\n <form #addForm=\"ngForm\">\n <div class=\"clr-row\">\n{{FORM_FIELDS}}\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modalAdd = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onCreate()\">Submit</button>\n </div>\n</clr-modal>\n\n<!-- EDIT MODAL -->\n<clr-modal [(clrModalOpen)]=\"modalEdit\" [clrModalSize]=\"'lg'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Edit {{TABLE}} (ID: {{rowSelected.id}})</h3>\n <div class=\"modal-body\" *ngIf=\"rowSelected\">\n <form #editForm=\"ngForm\">\n <div class=\"clr-row\">\n{{FORM_FIELDS}}\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modalEdit = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onUpdate(rowSelected.id)\">Update</button>\n </div>\n</clr-modal>\n\n<!-- DELETE MODAL -->\n<clr-modal [(clrModalOpen)]=\"modaldelete\" [clrModalSize]=\"'md'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Confirm Delete</h3>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete this record (ID: <b>{{rowSelected.id}}</b>)?</p>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modaldelete = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"delete(rowSelected.id)\">Delete</button>\n </div>\n</clr-modal>\n"
},
{
"source_ref": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.scss",
"path_tpl": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.scss",
"description": "Component stylesheet",
"content_tpl": ".dg-wrapper {\n margin-top: 15px;\n}\n.heading {\n font-weight: 500;\n margin-bottom: 12px;\n}\n"
},
{
"source_ref": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.service.ts",
"path_tpl": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.service.ts",
"description": "Component Service file",
"content_tpl": "import { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { HttpClient } from '@angular/common/http';\nimport { ApiRequestService } from 'src/app/services/api/api-request.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class {{TABLE}}Service {\n private baseURL = '{{REPO}}/{{TABLE}}';\n\n constructor(\n private http: HttpClient,\n private apiRequest: ApiRequestService\n ) { }\n\n getAll(page?: number, size?: number): Observable<any> {\n return this.apiRequest.get(this.baseURL);\n }\n\n getById(id: number): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.get(_http);\n }\n\n create(data: any): Observable<any> {\n return this.apiRequest.post(this.baseURL, data);\n }\n\n update(id: number, data: any): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.put(_http, data);\n }\n\n delete(id: number): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.delete(_http);\n }\n}\n"
}
],
"datatypes": [
{
"key": "textfield",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"text\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "number",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"number\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "phone",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"tel\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" placeholder=\"e.g. +1 555-0199\" />\n </clr-input-container>\n</div>"
},
{
"key": "paragraph",
"your_code": "<div class=\"clr-col-12\">\n <clr-textarea-container>\n <label>{{label}}</label>\n <textarea clrTextarea name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" rows=\"3\"></textarea>\n </clr-textarea-container>\n</div>"
},
{
"key": "password",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-password-container>\n <label>{{label}}</label>\n <input clrPassword type=\"password\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-password-container>\n</div>"
},
{
"key": "textarea",
"your_code": "<div class=\"clr-col-12\">\n <clr-textarea-container>\n <label>{{label}}</label>\n <textarea clrTextarea name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" rows=\"3\"></textarea>\n </clr-textarea-container>\n</div>"
},
{
"key": "date",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-date-container>\n <label>{{label}}</label>\n <input clrDate type=\"date\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-date-container>\n</div>"
},
{
"key": "datetime",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"datetime-local\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "email",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"email\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "toggle_switch",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-toggle-wrapper>\n <input clrToggle type=\"checkbox\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n <label>{{label}}</label>\n </clr-toggle-wrapper>\n</div>"
},
{
"key": "url_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"url\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" placeholder=\"https://\" />\n </clr-input-container>\n</div>"
},
{
"key": "decimal",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"number\" step=\"0.01\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "percentage",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (%)</label>\n <input clrInput type=\"number\" min=\"0\" max=\"100\" step=\"0.01\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "recaptcha",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <div class=\"recaptcha-placeholder\">\n <span>[reCAPTCHA Verification: {{label}}]</span>\n </div>\n</div>"
},
{
"key": "document_seq",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (Auto Sequence)</label>\n <input clrInput type=\"text\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" [readonly]=\"true\" />\n </clr-input-container>\n</div>"
},
{
"key": "userid",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}}</label>\n <input clrInput type=\"number\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" [readonly]=\"true\" />\n </clr-input-container>\n</div>"
},
{
"key": "header_field",
"your_code": "<div class=\"clr-col-12\">\n <h4 class=\"header-field\">{{label}}</h4>\n</div>"
},
{
"key": "select_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-select-container>\n <label>{{label}}</label>\n <select clrSelect name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\">\n <option value=\"\">Select {{label}}</option>\n </select>\n </clr-select-container>\n</div>"
},
{
"key": "radio_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-radio-container clrInline>\n <label>{{label}}</label>\n <clr-radio-wrapper>\n <input clrRadio type=\"radio\" value=\"option1\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n <label>Option 1</label>\n </clr-radio-wrapper>\n </clr-radio-container>\n</div>"
},
{
"key": "checkbox",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-checkbox-wrapper>\n <input clrCheckbox type=\"checkbox\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n <label>{{label}}</label>\n </clr-checkbox-wrapper>\n</div>"
},
{
"key": "fileupload",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <app-file-uploader label=\"{{label}}\" type=\"file\" [(ngModel)]=\"rowSelected.{{fieldName}}\" name=\"{{fieldName}}\"></app-file-uploader>\n</div>"
},
{
"key": "imageupload",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <app-file-uploader label=\"{{label}}\" type=\"image\" [(ngModel)]=\"rowSelected.{{fieldName}}\" name=\"{{fieldName}}\"></app-file-uploader>\n</div>"
},
{
"key": "audio_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <app-file-uploader label=\"{{label}}\" type=\"audio\" [(ngModel)]=\"rowSelected.{{fieldName}}\" name=\"{{fieldName}}\"></app-file-uploader>\n</div>"
},
{
"key": "video_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <app-file-uploader label=\"{{label}}\" type=\"video\" [(ngModel)]=\"rowSelected.{{fieldName}}\" name=\"{{fieldName}}\"></app-file-uploader>\n</div>"
},
{
"key": "button_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"onButtonClick('{{fieldName}}')\">{{label}}</button>\n</div>"
},
{
"key": "survey_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (Rating 1-5)</label>\n <input clrInput type=\"number\" min=\"1\" max=\"5\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "field_group",
"your_code": "<div class=\"clr-col-12 field-group-section\">\n <div class=\"card card-block\">\n <h5 class=\"card-title\">{{label}}</h5>\n </div>\n</div>"
},
{
"key": "relationship",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-select-container>\n <label>{{label}}</label>\n <select clrSelect name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\">\n <option value=\"\">Select {{label}}</option>\n <option *ngFor=\"let opt of {{to_wireframe_lower}}Options\" [value]=\"opt.id\">{{opt.name || opt.id}}</option>\n </select>\n </clr-select-container>\n</div>"
},
{
"key": "currency",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} ($)</label>\n <input clrInput type=\"number\" step=\"0.01\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" />\n </clr-input-container>\n</div>"
},
{
"key": "value_list",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-select-container>\n <label>{{label}}</label>\n <select clrSelect name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\">\n <option value=\"\">Choose {{label}}</option>\n </select>\n </clr-select-container>\n</div>"
},
{
"key": "qr_code",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (QR Code)</label>\n <input clrInput type=\"text\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" placeholder=\"Enter text or URL\" />\n </clr-input-container>\n <div style=\"margin-top: 10px;\" *ngIf=\"rowSelected.{{fieldName}}\">\n <qrcode [qrdata]=\"rowSelected.{{fieldName}}\" [width]=\"130\" [errorCorrectionLevel]=\"'M'\"></qrcode>\n </div>\n</div>"
},
{
"key": "bar_code",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (Barcode)</label>\n <input clrInput type=\"text\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" placeholder=\"Enter code for Barcode\" />\n </clr-input-container>\n <div style=\"margin-top: 10px;\" *ngIf=\"rowSelected.{{fieldName}}\">\n <svg [appBarcode]=\"rowSelected.{{fieldName}}\"></svg>\n </div>\n</div>"
},
{
"key": "calculated_field",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-input-container>\n <label>{{label}} (Calculated)</label>\n <input clrInput type=\"text\" name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\" [readonly]=\"true\" />\n </clr-input-container>\n</div>"
},
{
"key": "data_grid",
"your_code": "<div class=\"clr-col-12\">\n <label class=\"clr-control-label\">{{label}} Items</label>\n <clr-datagrid>\n <clr-dg-column>Name</clr-dg-column>\n <clr-dg-placeholder>No {{label}} records added</clr-dg-placeholder>\n </clr-datagrid>\n</div>"
},
{
"key": "dependent_dropdown",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-select-container>\n <label>{{label}}</label>\n <select clrSelect name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\">\n <option value=\"\">Select {{label}}</option>\n <option *ngFor=\"let opt of {{fieldName}}FilteredOptions\" [value]=\"opt.id\">{{opt.name}}</option>\n </select>\n </clr-select-container>\n</div>"
},
{
"key": "relation",
"your_code": "<div class=\"clr-col-12 clr-col-md-6\">\n <clr-select-container>\n <label>{{label}}</label>\n <select clrSelect name=\"{{fieldName}}\" [(ngModel)]=\"rowSelected.{{fieldName}}\">\n <option value=\"\">Select {{label}}</option>\n <option *ngFor=\"let opt of {{to_wireframe_lower}}Options\" [value]=\"opt.id\">{{opt.name || opt.id}}</option>\n </select>\n </clr-select-container>\n</div>"
}
],
"list_item_tpl": " <clr-dg-cell>{{item.{{fieldName}}}}</clr-dg-cell>\n",
"ref_files": [
{
"name": "Product.component.scss",
"path": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.scss",
"default_target": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.scss",
"content": ".dg-wrapper {\n margin-top: 15px;\n}\n.heading {\n font-weight: 500;\n margin-bottom: 12px;\n}\n"
},
{
"name": "Product.component.html",
"path": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.html",
"default_target": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.html",
"content": "<ol class=\"breadcrumb breadcrumb-arrow font-trirong\">\n <li><a href=\"javascript://\"><clr-icon shape=\"home\"></clr-icon></a></li>\n <li><a href=\"javascript://\"> {{TABLE}}</a></li>\n</ol>\n\n<div class=\"dg-wrapper\">\n <div class=\"clr-row\">\n <div class=\"clr-col-8\">\n <h3>{{TABLE}} Management</h3>\n </div>\n <div class=\"clr-col-4\" style=\"text-align: right;\">\n <button id=\"add\" class=\"btn btn-primary\" (click)=\"goToAdd()\">\n <clr-icon shape=\"plus\"></clr-icon> ADD\n </button>\n </div>\n </div>\n\n <!-- CLARITY DATAGRID -->\n <clr-datagrid [clrDgLoading]=\"loading\" [(clrDgSelected)]=\"selected\">\n <clr-dg-placeholder>\n <ng-template #loadingSpinner>\n <clr-spinner>Loading ...</clr-spinner>\n </ng-template>\n <div *ngIf=\"error; else loadingSpinner\">{{error}}</div>\n </clr-dg-placeholder>\n\n <!-- DYNAMIC COLUMN HEADERS -->\n <clr-dg-column *ngFor=\"let col of getColumns()\" [clrDgField]=\"col\">\n <ng-container *clrDgHideableColumn=\"{hidden: false}\">{{ col | titlecase }}</ng-container>\n </clr-dg-column>\n\n <clr-dg-column>\n <ng-container *clrDgHideableColumn=\"{hidden: false}\">\n <clr-icon shape=\"bars\"></clr-icon> Action\n </ng-container>\n </clr-dg-column>\n\n <!-- DYNAMIC DATA ROWS -->\n <clr-dg-row *clrDgItems=\"let item of items\" [clrDgItem]=\"item\">\n{{LIST_ITEMS}}\n <clr-dg-cell>\n <span style=\"cursor: pointer; margin-right: 10px;\" (click)=\"onEdit(item)\" title=\"Edit\">\n <clr-icon shape=\"pencil\"></clr-icon>\n </span>\n <span style=\"cursor: pointer; color: red;\" (click)=\"onDelete(item)\" title=\"Delete\">\n <clr-icon shape=\"trash\" class=\"is-error\"></clr-icon>\n </span>\n </clr-dg-cell>\n\n <clr-dg-action-overflow>\n <button class=\"action-item\" (click)=\"onEdit(item)\">Edit</button>\n <button class=\"action-item\" (click)=\"onDelete(item)\">Delete</button>\n </clr-dg-action-overflow>\n </clr-dg-row>\n\n <clr-dg-footer>\n <clr-dg-pagination #pagination [clrDgPageSize]=\"10\">\n <clr-dg-page-size [clrPageSizeOptions]=\"[10,20,50,100]\">Items per page</clr-dg-page-size>\n {{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} of {{pagination.totalItems}} items\n </clr-dg-pagination>\n </clr-dg-footer>\n </clr-datagrid>\n</div>\n\n<!-- ADD MODAL -->\n<clr-modal [(clrModalOpen)]=\"modalAdd\" [clrModalSize]=\"'lg'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Add {{TABLE}}</h3>\n <div class=\"modal-body\">\n <form #addForm=\"ngForm\">\n <div class=\"clr-row\">\n{{FORM_FIELDS}}\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modalAdd = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onCreate()\">Submit</button>\n </div>\n</clr-modal>\n\n<!-- EDIT MODAL -->\n<clr-modal [(clrModalOpen)]=\"modalEdit\" [clrModalSize]=\"'lg'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Edit {{TABLE}} (ID: {{rowSelected.id}})</h3>\n <div class=\"modal-body\" *ngIf=\"rowSelected\">\n <form #editForm=\"ngForm\">\n <div class=\"clr-row\">\n{{FORM_FIELDS}}\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modalEdit = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"onUpdate(rowSelected.id)\">Update</button>\n </div>\n</clr-modal>\n\n<!-- DELETE MODAL -->\n<clr-modal [(clrModalOpen)]=\"modaldelete\" [clrModalSize]=\"'md'\" [clrModalStaticBackdrop]=\"true\">\n <h3 class=\"modal-title\">Confirm Delete</h3>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete this record (ID: <b>{{rowSelected.id}}</b>)?</p>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline\" (click)=\"modaldelete = false\">Cancel</button>\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"delete(rowSelected.id)\">Delete</button>\n </div>\n</clr-modal>\n"
},
{
"name": "Product.service.ts",
"path": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.service.ts",
"default_target": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.service.ts",
"content": "import { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { HttpClient } from '@angular/common/http';\nimport { ApiRequestService } from 'src/app/services/api/api-request.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class {{TABLE}}Service {\n private baseURL = '{{REPO}}/{{TABLE}}';\n\n constructor(\n private http: HttpClient,\n private apiRequest: ApiRequestService\n ) { }\n\n getAll(page?: number, size?: number): Observable<any> {\n return this.apiRequest.get(this.baseURL);\n }\n\n getById(id: number): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.get(_http);\n }\n\n create(data: any): Observable<any> {\n return this.apiRequest.post(this.baseURL, data);\n }\n\n update(id: number, data: any): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.put(_http, data);\n }\n\n delete(id: number): Observable<any> {\n const _http = this.baseURL + '/' + id;\n return this.apiRequest.delete(_http);\n }\n}\n"
},
{
"name": "Product.component.ts",
"path": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/io8.ref/product/Product.component.ts",
"default_target": "frontend/angular-clarity-master/src/app/modules/main/BuilderComponents/{{REPO}}/{{TABLE}}/{{TABLE}}.component.ts",
"content": "import { Component, OnInit } from '@angular/core';\nimport { ToastrService } from 'ngx-toastr';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { {{TABLE}}Service } from './{{TABLE}}.service';\nimport { ApiRequestService } from 'src/app/services/api/api-request.service';\n\n@Component({\n selector: 'app-{{TABLE_LOWER}}',\n templateUrl: './{{TABLE}}.component.html',\n styleUrls: ['./{{TABLE}}.component.scss']\n})\nexport class {{TABLE}}Component implements OnInit {\n rowSelected: any = {};\n modaldelete = false;\n modalEdit = false;\n modalAdd = false;\n loading = false;\n items: any[] = [];\n selected: any[] = [];\n error: string;\n/* {{RELATION_DECLARATIONS}} */\n\n constructor(\n private mainService: {{TABLE}}Service,\n private apiRequest: ApiRequestService,\n private toastr: ToastrService,\n private router: Router,\n private route: ActivatedRoute\n ) { }\n\n ngOnInit(): void {\n this.getData();\n/* {{RELATION_LOADERS}} */\n }\n\n getColumns(): string[] {\n if (!this.items || this.items.length === 0) {\n return [];\n }\n return Object.keys(this.items[0]).filter(k => k !== 'id');\n }\n\n getData() {\n this.loading = true;\n this.mainService.getAll().subscribe((data) => {\n this.loading = false;\n this.items = data || [];\n if (this.items.length === 0) {\n this.error = 'No Data Available';\n }\n }, (error) => {\n this.loading = false;\n this.error = 'Server Error';\n });\n }\n\n goToAdd() {\n this.rowSelected = {};\n this.modalAdd = true;\n }\n\n onEdit(row: any) {\n this.rowSelected = Object.assign({}, row);\n this.modalEdit = true;\n }\n\n onDelete(row: any) {\n this.rowSelected = row;\n this.modaldelete = true;\n }\n\n delete(id: number) {\n this.modaldelete = false;\n this.mainService.delete(id).subscribe(() => {\n this.toastr.success('Deleted successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to delete');\n });\n }\n\n onCreate() {\n this.modalAdd = false;\n this.mainService.create(this.rowSelected).subscribe(() => {\n this.toastr.success('Added successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to add');\n });\n }\n\n onUpdate(id: number) {\n this.modalEdit = false;\n this.mainService.update(id, this.rowSelected).subscribe(() => {\n this.toastr.success('Updated successfully');\n this.getData();\n }, (error) => {\n this.toastr.error('Failed to update');\n });\n }\n}\n"
}
],
"check_command": ""
}