@rolatech/angular-billing 20.3.2-beta.2 → 20.3.2-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, Component, ViewEncapsulation, inject, signal, computed, model, Injectable } from '@angular/core';
2
+ import { input, output, Component, ViewEncapsulation, inject, signal, computed, model, Injectable, effect, ChangeDetectionStrategy } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule, DatePipe, KeyValuePipe } from '@angular/common';
5
5
  import * as i1$2 from '@angular/forms';
6
- import { FormsModule } from '@angular/forms';
6
+ import { FormsModule, Validators, FormBuilder, ReactiveFormsModule } from '@angular/forms';
7
7
  import * as i2 from '@angular/material/button';
8
8
  import { MatButtonModule } from '@angular/material/button';
9
9
  import * as i4 from '@angular/material/form-field';
@@ -16,7 +16,7 @@ import * as i1$1 from '@angular/router';
16
16
  import { RouterModule, RouterLink } from '@angular/router';
17
17
  import { Skeleton, BaseComponent, PageCollectionShellComponent, ToolbarComponent, TabsComponent, TabComponent, EnumSelect, ConfirmationDialogComponent, MaterialModule } from '@rolatech/angular-components';
18
18
  import { PricePipe } from '@rolatech/angular-common';
19
- import { InvoiceService, PaymentService, EnumApiClient } from '@rolatech/angular-services';
19
+ import { InvoiceService, PaymentService, EnumApiClient, BillingProfileService } from '@rolatech/angular-services';
20
20
  import * as i6 from '@angular/material/paginator';
21
21
  import { MatPaginatorModule } from '@angular/material/paginator';
22
22
  import { map, distinctUntilChanged, switchMap, finalize } from 'rxjs';
@@ -24,7 +24,7 @@ import * as i8 from '@angular/material/card';
24
24
  import { MatCardModule } from '@angular/material/card';
25
25
  import * as i7 from '@angular/material/divider';
26
26
  import { MatDividerModule } from '@angular/material/divider';
27
- import * as i5$1 from '@angular/material/input';
27
+ import * as i4$1 from '@angular/material/input';
28
28
  import { MatInputModule } from '@angular/material/input';
29
29
  import * as i3$1 from '@angular/material/menu';
30
30
  import { MatMenuModule } from '@angular/material/menu';
@@ -35,6 +35,8 @@ import { finalize as finalize$1 } from 'rxjs/operators';
35
35
  import * as i1$3 from '@angular/cdk/drag-drop';
36
36
  import { DragDropModule } from '@angular/cdk/drag-drop';
37
37
  import { MatDialog } from '@angular/material/dialog';
38
+ import * as i5$1 from '@angular/material/slide-toggle';
39
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
38
40
 
39
41
  const billingRoutes = [];
40
42
 
@@ -715,7 +717,7 @@ class InvoiceManageCreate {
715
717
  return new Date().toISOString().slice(0, 10);
716
718
  }
717
719
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: InvoiceManageCreate, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
718
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: InvoiceManageCreate, isStandalone: true, selector: "rolatech-invoice-manage-create", ngImport: i0, template: "<rolatech-toolbar title=\"Create Invoice\">\n <button\n mat-flat-button\n color=\"primary\"\n (click)=\"save(invoiceForm)\"\n [disabled]=\"!invoiceForm.form.valid || invoice.lines.length === 0\"\n >\n Save\n </button>\n</rolatech-toolbar>\n<div class=\"p-4 space-y-6\">\n <form #invoiceForm=\"ngForm\" novalidate>\n <mat-card appearance=\"outlined\" class=\"p-4\">\n <div class=\"grid lg:grid-cols-2 gap-4\">\n <mat-form-field appearance=\"fill\">\n <mat-label>Customer name</mat-label>\n <input matInput name=\"customerName\" [(ngModel)]=\"invoice.customerName\" required />\n @if (invoiceForm.submitted && !invoice.customerName) {<mat-error>Name is required</mat-error>}\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Customer email</mat-label>\n <input matInput type=\"email\" name=\"customerEmail\" [(ngModel)]=\"invoice.customerEmail\" #email=\"ngModel\" email />\n @if (email.invalid && (email.dirty || email.touched)) {<mat-error>Invalid email</mat-error>}\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\" class=\"lg:col-span-2\">\n <mat-label>Customer address</mat-label>\n <textarea matInput rows=\"2\" name=\"customerAddress\" [(ngModel)]=\"invoice.customerAddress\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Currency</mat-label>\n <mat-select name=\"currency\" [(ngModel)]=\"invoice.currency\" required>\n <mat-option value=\"GBP\">GBP</mat-option>\n <mat-option value=\"USD\">USD</mat-option>\n <mat-option value=\"EUR\">EUR</mat-option>\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Issue date</mat-label>\n <input matInput type=\"date\" name=\"issueDate\" [(ngModel)]=\"invoice.issueDate\" required />\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Due date</mat-label>\n <input matInput type=\"date\" name=\"dueDate\" [(ngModel)]=\"invoice.dueDate\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\" class=\"lg:col-span-2\">\n <mat-label>Notes</mat-label>\n <textarea\n matInput\n rows=\"2\"\n name=\"notes\"\n [(ngModel)]=\"invoice.notes\"\n placeholder=\"Optional notes shown on the invoice\"\n ></textarea>\n </mat-form-field>\n </div>\n </mat-card>\n\n <mat-card appearance=\"outlined\" class=\"p-4 space-y-4 mt-4\">\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-xl font-medium\">Line items</h2>\n <button mat-stroked-button type=\"button\" (click)=\"addLine()\">\n <mat-icon>add</mat-icon>\n Add line\n </button>\n </div>\n\n <div class=\"hidden lg:grid grid-cols-12 gap-2 text-sm font-medium px-2\">\n <div class=\"col-span-3\">Type</div>\n <div class=\"col-span-3\">Description</div>\n <div class=\"col-span-1 text-right\">Qty</div>\n <div class=\"col-span-2 text-right\">Unit Price</div>\n <div class=\"col-span-2 text-right\">Tax %</div>\n <div class=\"col-span-1\"></div>\n </div>\n\n <div class=\"space-y-3\">\n @for ( line of invoice.lines; track line; let i = $index) {\n <div class=\"grid grid-cols-1 lg:grid-cols-12 gap-2 items-start\">\n <rolatech-enum-select\n class=\"lg:col-span-3\"\n [resource]=\"'billing'\"\n [enumName]=\"'InvoiceLineType'\"\n [label]=\"'Line type'\"\n [placeholder]=\"'Select\u2026'\"\n [(value)]=\"line.type\"\n ></rolatech-enum-select>\n <mat-form-field class=\"lg:col-span-3\" appearance=\"fill\">\n <mat-label>Description</mat-label>\n <input\n matInput\n [name]=\"'desc'+i\"\n [(ngModel)]=\"line.description\"\n required\n placeholder=\"e.g. Photo editing package\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-1\" appearance=\"fill\">\n <mat-label>Quantity</mat-label>\n <input matInput type=\"number\" min=\"1\" step=\"1\" [name]=\"'qty'+i\" [(ngModel)]=\"line.quantity\" required />\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-2\" appearance=\"fill\">\n <mat-label>Unit Price</mat-label>\n <input matInput type=\"number\" min=\"0\" step=\"0.01\" [name]=\"'unit'+i\" [(ngModel)]=\"line.unitPrice\" required />\n <mat-hint>e.g. 99.99</mat-hint>\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-2\" appearance=\"fill\">\n <mat-label>Tax %</mat-label>\n <input matInput type=\"number\" min=\"0\" step=\"0.01\" [name]=\"'tax'+i\" [(ngModel)]=\"line.taxRate\" />\n </mat-form-field>\n\n <div class=\"lg:col-span-1 flex items-center justify-end\">\n <button mat-icon-button color=\"warn\" type=\"button\" (click)=\"removeLine(i)\" aria-label=\"Remove line\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n <mat-divider></mat-divider>\n }\n </div>\n\n <div class=\"flex flex-col items-end space-y-1\">\n <div class=\"text-sm\">\n Subtotal: <span class=\"font-medium\">{{ subtotalMajor() | number:'1.2-2' }} {{ invoice.currency }}</span>\n </div>\n <div class=\"text-sm\">\n Tax: <span class=\"font-medium\">{{ taxMajor() | number:'1.2-2' }} {{ invoice.currency }}</span>\n </div>\n <div class=\"text-lg font-semibold\">Total: {{ totalMajor() | number:'1.2-2' }} {{ invoice.currency }}</div>\n </div>\n </mat-card>\n </form>\n\n @if (lastResponse) {\n <mat-card appearance=\"outlined\" class=\"p-4 flex items-center justify-between\">\n <div>\n <div class=\"font-medium\">Created invoice #{{ lastResponse.data.id }}</div>\n <div class=\"text-sm opacity-70\">\n Total: {{ penceToMajor(lastResponse.data.total) | number:'1.2-2' }} {{ invoice.currency }}\n </div>\n </div>\n <div class=\"space-x-2\">\n <button mat-stroked-button (click)=\"resetForm()\">Create another</button>\n <button mat-flat-button color=\"primary\">Download PDF</button>\n </div>\n </mat-card>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i1$2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: EnumSelect, selector: "rolatech-enum-select", inputs: ["resource", "enumName", "label", "placeholder", "disabled", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] }); }
720
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: InvoiceManageCreate, isStandalone: true, selector: "rolatech-invoice-manage-create", ngImport: i0, template: "<rolatech-toolbar title=\"Create Invoice\">\n <button\n mat-flat-button\n color=\"primary\"\n (click)=\"save(invoiceForm)\"\n [disabled]=\"!invoiceForm.form.valid || invoice.lines.length === 0\"\n >\n Save\n </button>\n</rolatech-toolbar>\n<div class=\"p-4 space-y-6\">\n <form #invoiceForm=\"ngForm\" novalidate>\n <mat-card appearance=\"outlined\" class=\"p-4\">\n <div class=\"grid lg:grid-cols-2 gap-4\">\n <mat-form-field appearance=\"fill\">\n <mat-label>Customer name</mat-label>\n <input matInput name=\"customerName\" [(ngModel)]=\"invoice.customerName\" required />\n @if (invoiceForm.submitted && !invoice.customerName) {<mat-error>Name is required</mat-error>}\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Customer email</mat-label>\n <input matInput type=\"email\" name=\"customerEmail\" [(ngModel)]=\"invoice.customerEmail\" #email=\"ngModel\" email />\n @if (email.invalid && (email.dirty || email.touched)) {<mat-error>Invalid email</mat-error>}\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\" class=\"lg:col-span-2\">\n <mat-label>Customer address</mat-label>\n <textarea matInput rows=\"2\" name=\"customerAddress\" [(ngModel)]=\"invoice.customerAddress\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Currency</mat-label>\n <mat-select name=\"currency\" [(ngModel)]=\"invoice.currency\" required>\n <mat-option value=\"GBP\">GBP</mat-option>\n <mat-option value=\"USD\">USD</mat-option>\n <mat-option value=\"EUR\">EUR</mat-option>\n </mat-select>\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Issue date</mat-label>\n <input matInput type=\"date\" name=\"issueDate\" [(ngModel)]=\"invoice.issueDate\" required />\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\">\n <mat-label>Due date</mat-label>\n <input matInput type=\"date\" name=\"dueDate\" [(ngModel)]=\"invoice.dueDate\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"fill\" class=\"lg:col-span-2\">\n <mat-label>Notes</mat-label>\n <textarea\n matInput\n rows=\"2\"\n name=\"notes\"\n [(ngModel)]=\"invoice.notes\"\n placeholder=\"Optional notes shown on the invoice\"\n ></textarea>\n </mat-form-field>\n </div>\n </mat-card>\n\n <mat-card appearance=\"outlined\" class=\"p-4 space-y-4 mt-4\">\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-xl font-medium\">Line items</h2>\n <button mat-stroked-button type=\"button\" (click)=\"addLine()\">\n <mat-icon>add</mat-icon>\n Add line\n </button>\n </div>\n\n <div class=\"hidden lg:grid grid-cols-12 gap-2 text-sm font-medium px-2\">\n <div class=\"col-span-3\">Type</div>\n <div class=\"col-span-3\">Description</div>\n <div class=\"col-span-1 text-right\">Qty</div>\n <div class=\"col-span-2 text-right\">Unit Price</div>\n <div class=\"col-span-2 text-right\">Tax %</div>\n <div class=\"col-span-1\"></div>\n </div>\n\n <div class=\"space-y-3\">\n @for ( line of invoice.lines; track line; let i = $index) {\n <div class=\"grid grid-cols-1 lg:grid-cols-12 gap-2 items-start\">\n <rolatech-enum-select\n class=\"lg:col-span-3\"\n [resource]=\"'billing'\"\n [enumName]=\"'InvoiceLineType'\"\n [label]=\"'Line type'\"\n [placeholder]=\"'Select\u2026'\"\n [(value)]=\"line.type\"\n ></rolatech-enum-select>\n <mat-form-field class=\"lg:col-span-3\" appearance=\"fill\">\n <mat-label>Description</mat-label>\n <input\n matInput\n [name]=\"'desc'+i\"\n [(ngModel)]=\"line.description\"\n required\n placeholder=\"e.g. Photo editing package\"\n />\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-1\" appearance=\"fill\">\n <mat-label>Quantity</mat-label>\n <input matInput type=\"number\" min=\"1\" step=\"1\" [name]=\"'qty'+i\" [(ngModel)]=\"line.quantity\" required />\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-2\" appearance=\"fill\">\n <mat-label>Unit Price</mat-label>\n <input matInput type=\"number\" min=\"0\" step=\"0.01\" [name]=\"'unit'+i\" [(ngModel)]=\"line.unitPrice\" required />\n <mat-hint>e.g. 99.99</mat-hint>\n </mat-form-field>\n\n <mat-form-field class=\"lg:col-span-2\" appearance=\"fill\">\n <mat-label>Tax %</mat-label>\n <input matInput type=\"number\" min=\"0\" step=\"0.01\" [name]=\"'tax'+i\" [(ngModel)]=\"line.taxRate\" />\n </mat-form-field>\n\n <div class=\"lg:col-span-1 flex items-center justify-end\">\n <button mat-icon-button color=\"warn\" type=\"button\" (click)=\"removeLine(i)\" aria-label=\"Remove line\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n <mat-divider></mat-divider>\n }\n </div>\n\n <div class=\"flex flex-col items-end space-y-1\">\n <div class=\"text-sm\">\n Subtotal: <span class=\"font-medium\">{{ subtotalMajor() | number:'1.2-2' }} {{ invoice.currency }}</span>\n </div>\n <div class=\"text-sm\">\n Tax: <span class=\"font-medium\">{{ taxMajor() | number:'1.2-2' }} {{ invoice.currency }}</span>\n </div>\n <div class=\"text-lg font-semibold\">Total: {{ totalMajor() | number:'1.2-2' }} {{ invoice.currency }}</div>\n </div>\n </mat-card>\n </form>\n\n @if (lastResponse) {\n <mat-card appearance=\"outlined\" class=\"p-4 flex items-center justify-between\">\n <div>\n <div class=\"font-medium\">Created invoice #{{ lastResponse.data.id }}</div>\n <div class=\"text-sm opacity-70\">\n Total: {{ penceToMajor(lastResponse.data.total) | number:'1.2-2' }} {{ invoice.currency }}\n </div>\n </div>\n <div class=\"space-x-2\">\n <button mat-stroked-button (click)=\"resetForm()\">Create another</button>\n <button mat-flat-button color=\"primary\">Download PDF</button>\n </div>\n </mat-card>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i1$2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: EnumSelect, selector: "rolatech-enum-select", inputs: ["resource", "enumName", "label", "placeholder", "disabled", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] }); }
719
721
  }
720
722
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: InvoiceManageCreate, decorators: [{
721
723
  type: Component,
@@ -763,7 +765,7 @@ class InvoiceEdit extends BaseComponent {
763
765
  deps: [MAT_DATE_LOCALE],
764
766
  },
765
767
  { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
766
- ], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-between gap-3\">\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Firstname</mat-label>\n <input matInput [(ngModel)]=\"invoice().firstName\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Lastname</mat-label>\n <input matInput [(ngModel)]=\"invoice().lastName\" />\n </mat-form-field>\n </div>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Email</mat-label>\n <input matInput [(ngModel)]=\"invoice().email\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Phone</mat-label>\n <input matInput [(ngModel)]=\"invoice().phone\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Discount total</mat-label>\n <input matInput [(ngModel)]=\"invoice().discountAmount\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Total</mat-label>\n <input matInput [(ngModel)]=\"invoice().total\" />\n </mat-form-field>\n <!-- <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label i18n>Move-in date</mat-label>\n <input\n matInput\n placeholder=\"Move-in date\"\n [min]=\"minDate\"\n [matDatepicker]=\"startDatePicker\"\n (focus)=\"startDatePicker.open()\"\n [(ngModel)]=\"invoice().startDate\"\n (dateInput)=\"invoice().startDate = $event.value.format('YYYY-MM-DD')\"\n required\n readonly\n />\n <mat-datepicker-toggle matIconPrefix [for]=\"startDatePicker\"></mat-datepicker-toggle>\n <mat-datepicker #startDatePicker></mat-datepicker>\n </mat-form-field> -->\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatOptionModule }] }); }
768
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col gap-2\">\n <div class=\"flex justify-between gap-3\">\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Firstname</mat-label>\n <input matInput [(ngModel)]=\"invoice().firstName\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Lastname</mat-label>\n <input matInput [(ngModel)]=\"invoice().lastName\" />\n </mat-form-field>\n </div>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Email</mat-label>\n <input matInput [(ngModel)]=\"invoice().email\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Phone</mat-label>\n <input matInput [(ngModel)]=\"invoice().phone\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Discount total</mat-label>\n <input matInput [(ngModel)]=\"invoice().discountAmount\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label>Total</mat-label>\n <input matInput [(ngModel)]=\"invoice().total\" />\n </mat-form-field>\n <!-- <mat-form-field appearance=\"fill\" subscriptSizing=\"dynamic\">\n <mat-label i18n>Move-in date</mat-label>\n <input\n matInput\n placeholder=\"Move-in date\"\n [min]=\"minDate\"\n [matDatepicker]=\"startDatePicker\"\n (focus)=\"startDatePicker.open()\"\n [(ngModel)]=\"invoice().startDate\"\n (dateInput)=\"invoice().startDate = $event.value.format('YYYY-MM-DD')\"\n required\n readonly\n />\n <mat-datepicker-toggle matIconPrefix [for]=\"startDatePicker\"></mat-datepicker-toggle>\n <mat-datepicker #startDatePicker></mat-datepicker>\n </mat-form-field> -->\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatOptionModule }] }); }
767
769
  }
768
770
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: InvoiceEdit, decorators: [{
769
771
  type: Component,
@@ -1136,7 +1138,7 @@ class InvoiceManageLine {
1136
1138
  }
1137
1139
  saveLines() { }
1138
1140
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: InvoiceManageLine, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1139
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: InvoiceManageLine, isStandalone: true, selector: "rolatech-invoice-manage-line", ngImport: i0, template: "<!-- invoice-lines.html -->\n<div class=\"rounded-xl border border-(--rt-border-color) p-4 grid space-y-3\">\n <!-- Header -->\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-sm font-semibold\">Invoice lines</h2>\n\n <div class=\"flex items-center gap-2\">\n <button mat-icon-button type=\"button\" aria-label=\"Toggle edit\" (click)=\"toggleEdit()\">\n <mat-icon> {{ editMode() ? 'done' : 'edit' }} </mat-icon>\n </button>\n <button mat-stroked-button type=\"button\" [disabled]=\"store.dirty() || store.status() === 'saving'\" (click)=\"saveLines()\">\n @if (store.status() === 'saving') { Saving\u2026 } @else { Save lines }\n </button>\n </div>\n </div>\n\n <!-- Column labels (desktop only) -->\n <div class=\"hidden lg:grid grid-cols-12 gap-2 text-sm font-medium px-2 text-(--rt-text-secondary)\">\n <!-- Drag column -->\n @if (editMode()) {\n <div class=\"col-span-1\"></div>\n }\n\n <!-- Type -->\n <div [class]=\"editMode() ? 'col-span-3' : 'col-span-3'\">Type</div>\n\n <!-- Description (take extra space when not editing) -->\n <div [class]=\"editMode() ? 'col-span-4' : 'col-span-5'\">Title</div>\n\n <!-- Unit Price -->\n <div class=\"col-span-2 text-right\">Unit Price</div>\n\n <!-- Tax % (optional) -->\n @if (!isVatExclusive()) {\n <div class=\"col-span-1 text-right\">Tax %</div>\n }\n\n <!-- Amount (take extra space when not editing) -->\n <div [class]=\"editMode() ? 'col-span-1' : 'col-span-2'\" class=\"text-right\">Amount</div>\n\n <!-- Delete column -->\n @if (editMode()) {\n <div class=\"col-span-1\"></div>\n }\n </div>\n\n <!-- invoice-lines.html (rows section) -->\n\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" [cdkDropListDisabled]=\"!editMode()\" class=\"space-y-2\">\n @if (lines().length > 0) { @for (line of lines(); track line.id; let i = $index) {\n\n <div\n cdkDrag\n class=\"grid grid-cols-12 gap-2 items-start rounded-xl border border-(--rt-border-color) bg-(--rt-background) p-2 hover:bg-(--rt-raised-background)\"\n [class.opacity-70]=\"!editMode()\"\n >\n <!-- Drag handle column (only in edit mode) -->\n @if (editMode()) {\n <div class=\"col-span-1 flex items-center justify-center\">\n <button mat-icon-button type=\"button\" cdkDragHandle aria-label=\"Reorder line\" (click)=\"$event.stopPropagation()\">\n <mat-icon>drag_indicator</mat-icon>\n </button>\n </div>\n }\n\n <!-- Type -->\n <div class=\"col-span-12 lg:col-span-3\">\n <rolatech-enum-select\n [resource]=\"'billing'\"\n [enumName]=\"'InvoiceLineType'\"\n [label]=\"'Line type'\"\n [placeholder]=\"'Select\u2026'\"\n [value]=\"line.type\"\n (valueChange)=\"editMode() && update(line.id!, { type: $event })\"\n ></rolatech-enum-select>\n </div>\n\n <!-- Title (expands when NOT editMode) -->\n <div [class]=\"editMode() ? 'col-span-12 lg:col-span-4' : 'col-span-12 lg:col-span-5'\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Title</mat-label>\n <input\n matInput\n placeholder=\"e.g. Photo editing package\"\n [readonly]=\"!editMode()\"\n [readonly]=\"isPropertyLine(line.type)\"\n (focus)=\"onTitleFocus(line)\"\n (click)=\"onTitleFocus(line)\"\n (keydown)=\"onTitleKeydown($event, line)\"\n [value]=\"line.title\"\n (input)=\"editMode() && update(line.id!, { title: $any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Unit Price -->\n <div class=\"col-span-6 lg:col-span-2\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Unit</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n class=\"text-right\"\n [readonly]=\"!editMode()\"\n [value]=\"line.unitPrice\"\n (input)=\"editMode() && update(line.id!, { unitPrice: +$any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Tax % (optional, hidden if VAT exclusive) -->\n @if (!isVatExclusive()) {\n <div class=\"col-span-6 lg:col-span-1\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Tax %</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n class=\"text-right\"\n [readonly]=\"!editMode()\"\n [value]=\"line.vatRate\"\n (input)=\"editMode() && update(line.id!, { vatRate: +$any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n }\n\n <!-- Amount (expands when NOT editMode) -->\n <div\n [class]=\"editMode() ? 'col-span-6 lg:col-span-1' : 'col-span-6 lg:col-span-2'\"\n class=\"flex items-center justify-end px-1 lg:pt-3\"\n >\n <div class=\"text-right font-semibold text-(--rt-text-secondary)\">{{ line.lineTotal | price }}</div>\n </div>\n\n <!-- Delete column (only in edit mode) -->\n @if (editMode()) {\n <div class=\"col-span-6 lg:col-span-1 flex items-center justify-end lg:pt-1\">\n <button mat-icon-button color=\"warn\" type=\"button\" aria-label=\"Delete line\" (click)=\"remove(line.id!)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n </div>\n } } @else {\n <div class=\"py-8 text-center text-sm text-(--rt-text-secondary)\">No invoice lines</div>\n }\n </div>\n\n <!-- Footer -->\n <div>\n <button mat-stroked-button (click)=\"add()\">Add item</button>\n </div>\n</div>\n", styles: [".cdk-drag-preview{box-shadow:0 10px 20px #00000026;border-radius:12px}.cdk-drag-placeholder{opacity:.3}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: EnumSelect, selector: "rolatech-enum-select", inputs: ["resource", "enumName", "label", "placeholder", "disabled", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: PricePipe, name: "price" }], encapsulation: i0.ViewEncapsulation.None }); }
1141
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: InvoiceManageLine, isStandalone: true, selector: "rolatech-invoice-manage-line", ngImport: i0, template: "<!-- invoice-lines.html -->\n<div class=\"rounded-xl border border-(--rt-border-color) p-4 grid space-y-3\">\n <!-- Header -->\n <div class=\"flex items-center justify-between\">\n <h2 class=\"text-sm font-semibold\">Invoice lines</h2>\n\n <div class=\"flex items-center gap-2\">\n <button mat-icon-button type=\"button\" aria-label=\"Toggle edit\" (click)=\"toggleEdit()\">\n <mat-icon> {{ editMode() ? 'done' : 'edit' }} </mat-icon>\n </button>\n <button mat-stroked-button type=\"button\" [disabled]=\"store.dirty() || store.status() === 'saving'\" (click)=\"saveLines()\">\n @if (store.status() === 'saving') { Saving\u2026 } @else { Save lines }\n </button>\n </div>\n </div>\n\n <!-- Column labels (desktop only) -->\n <div class=\"hidden lg:grid grid-cols-12 gap-2 text-sm font-medium px-2 text-(--rt-text-secondary)\">\n <!-- Drag column -->\n @if (editMode()) {\n <div class=\"col-span-1\"></div>\n }\n\n <!-- Type -->\n <div [class]=\"editMode() ? 'col-span-3' : 'col-span-3'\">Type</div>\n\n <!-- Description (take extra space when not editing) -->\n <div [class]=\"editMode() ? 'col-span-4' : 'col-span-5'\">Title</div>\n\n <!-- Unit Price -->\n <div class=\"col-span-2 text-right\">Unit Price</div>\n\n <!-- Tax % (optional) -->\n @if (!isVatExclusive()) {\n <div class=\"col-span-1 text-right\">Tax %</div>\n }\n\n <!-- Amount (take extra space when not editing) -->\n <div [class]=\"editMode() ? 'col-span-1' : 'col-span-2'\" class=\"text-right\">Amount</div>\n\n <!-- Delete column -->\n @if (editMode()) {\n <div class=\"col-span-1\"></div>\n }\n </div>\n\n <!-- invoice-lines.html (rows section) -->\n\n <div cdkDropList (cdkDropListDropped)=\"drop($event)\" [cdkDropListDisabled]=\"!editMode()\" class=\"space-y-2\">\n @if (lines().length > 0) { @for (line of lines(); track line.id; let i = $index) {\n\n <div\n cdkDrag\n class=\"grid grid-cols-12 gap-2 items-start rounded-xl border border-(--rt-border-color) bg-(--rt-background) p-2 hover:bg-(--rt-raised-background)\"\n [class.opacity-70]=\"!editMode()\"\n >\n <!-- Drag handle column (only in edit mode) -->\n @if (editMode()) {\n <div class=\"col-span-1 flex items-center justify-center\">\n <button mat-icon-button type=\"button\" cdkDragHandle aria-label=\"Reorder line\" (click)=\"$event.stopPropagation()\">\n <mat-icon>drag_indicator</mat-icon>\n </button>\n </div>\n }\n\n <!-- Type -->\n <div class=\"col-span-12 lg:col-span-3\">\n <rolatech-enum-select\n [resource]=\"'billing'\"\n [enumName]=\"'InvoiceLineType'\"\n [label]=\"'Line type'\"\n [placeholder]=\"'Select\u2026'\"\n [value]=\"line.type\"\n (valueChange)=\"editMode() && update(line.id!, { type: $event })\"\n ></rolatech-enum-select>\n </div>\n\n <!-- Title (expands when NOT editMode) -->\n <div [class]=\"editMode() ? 'col-span-12 lg:col-span-4' : 'col-span-12 lg:col-span-5'\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Title</mat-label>\n <input\n matInput\n placeholder=\"e.g. Photo editing package\"\n [readonly]=\"!editMode()\"\n [readonly]=\"isPropertyLine(line.type)\"\n (focus)=\"onTitleFocus(line)\"\n (click)=\"onTitleFocus(line)\"\n (keydown)=\"onTitleKeydown($event, line)\"\n [value]=\"line.title\"\n (input)=\"editMode() && update(line.id!, { title: $any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Unit Price -->\n <div class=\"col-span-6 lg:col-span-2\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Unit</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n class=\"text-right\"\n [readonly]=\"!editMode()\"\n [value]=\"line.unitPrice\"\n (input)=\"editMode() && update(line.id!, { unitPrice: +$any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n\n <!-- Tax % (optional, hidden if VAT exclusive) -->\n @if (!isVatExclusive()) {\n <div class=\"col-span-6 lg:col-span-1\">\n <mat-form-field appearance=\"fill\" class=\"w-full\" subscriptSizing=\"dynamic\">\n <mat-label>Tax %</mat-label>\n <input\n matInput\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n class=\"text-right\"\n [readonly]=\"!editMode()\"\n [value]=\"line.vatRate\"\n (input)=\"editMode() && update(line.id!, { vatRate: +$any($event.target).value })\"\n />\n </mat-form-field>\n </div>\n }\n\n <!-- Amount (expands when NOT editMode) -->\n <div\n [class]=\"editMode() ? 'col-span-6 lg:col-span-1' : 'col-span-6 lg:col-span-2'\"\n class=\"flex items-center justify-end px-1 lg:pt-3\"\n >\n <div class=\"text-right font-semibold text-(--rt-text-secondary)\">{{ line.lineTotal | price }}</div>\n </div>\n\n <!-- Delete column (only in edit mode) -->\n @if (editMode()) {\n <div class=\"col-span-6 lg:col-span-1 flex items-center justify-end lg:pt-1\">\n <button mat-icon-button color=\"warn\" type=\"button\" aria-label=\"Delete line\" (click)=\"remove(line.id!)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n }\n </div>\n } } @else {\n <div class=\"py-8 text-center text-sm text-(--rt-text-secondary)\">No invoice lines</div>\n }\n </div>\n\n <!-- Footer -->\n <div>\n <button mat-stroked-button (click)=\"add()\">Add item</button>\n </div>\n</div>\n", styles: [".cdk-drag-preview{box-shadow:0 10px 20px #00000026;border-radius:12px}.cdk-drag-placeholder{opacity:.3}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: EnumSelect, selector: "rolatech-enum-select", inputs: ["resource", "enumName", "label", "placeholder", "disabled", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: PricePipe, name: "price" }], encapsulation: i0.ViewEncapsulation.None }); }
1140
1142
  }
1141
1143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: InvoiceManageLine, decorators: [{
1142
1144
  type: Component,
@@ -1566,9 +1568,170 @@ const agentInvoiceRoutes = [
1566
1568
  },
1567
1569
  ];
1568
1570
 
1571
+ class BillingProfileFacade {
1572
+ constructor() {
1573
+ this.billingProfileService = inject(BillingProfileService);
1574
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1575
+ this.saving = signal(false, ...(ngDevMode ? [{ debugName: "saving" }] : []));
1576
+ this.profile = signal(null, ...(ngDevMode ? [{ debugName: "profile" }] : []));
1577
+ this.error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
1578
+ this.saveMessage = signal(null, ...(ngDevMode ? [{ debugName: "saveMessage" }] : []));
1579
+ this.enabled = computed(() => this.profile()?.enabled ?? false, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
1580
+ }
1581
+ load() {
1582
+ this.loading.set(true);
1583
+ this.error.set(null);
1584
+ this.billingProfileService
1585
+ .getOrCreate()
1586
+ .pipe(finalize(() => this.loading.set(false)))
1587
+ .subscribe({
1588
+ next: (response) => {
1589
+ this.profile.set(response.data);
1590
+ },
1591
+ error: (error) => {
1592
+ this.error.set(error?.error?.message ?? 'Failed to load billing profile.');
1593
+ },
1594
+ });
1595
+ }
1596
+ save(body, done) {
1597
+ this.saving.set(true);
1598
+ this.error.set(null);
1599
+ this.saveMessage.set(null);
1600
+ this.billingProfileService
1601
+ .updateProfile(body)
1602
+ .pipe(finalize(() => this.saving.set(false)))
1603
+ .subscribe({
1604
+ next: (response) => {
1605
+ this.profile.set(response.data);
1606
+ this.saveMessage.set('Billing profile saved successfully.');
1607
+ done?.(response.data);
1608
+ },
1609
+ error: (error) => {
1610
+ this.error.set(error?.error?.message ?? 'Failed to save billing profile.');
1611
+ },
1612
+ });
1613
+ }
1614
+ setEnabled(enabled) {
1615
+ this.saving.set(true);
1616
+ this.error.set(null);
1617
+ this.saveMessage.set(null);
1618
+ this.billingProfileService
1619
+ .patch({ enabled })
1620
+ .pipe(finalize(() => this.saving.set(false)))
1621
+ .subscribe({
1622
+ next: (response) => {
1623
+ this.profile.set(response.data);
1624
+ this.saveMessage.set(enabled ? 'Billing profile enabled.' : 'Billing profile disabled.');
1625
+ },
1626
+ error: (error) => {
1627
+ this.error.set(error?.error?.message ?? 'Failed to update billing profile status.');
1628
+ },
1629
+ });
1630
+ }
1631
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BillingProfileFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1632
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BillingProfileFacade }); }
1633
+ }
1634
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BillingProfileFacade, decorators: [{
1635
+ type: Injectable
1636
+ }] });
1637
+
1638
+ function createBillingProfileForm(formBuilder) {
1639
+ return formBuilder.nonNullable.group({
1640
+ displayName: [''],
1641
+ companyName: [''],
1642
+ companyWebsite: [''],
1643
+ companyRegistrationNo: [''],
1644
+ companyVatNo: [''],
1645
+ companyAddressLine: [''],
1646
+ companyEmail: ['', [Validators.email]],
1647
+ companyPhone: [''],
1648
+ bankInstitution: [''],
1649
+ bankAccountName: [''],
1650
+ bankSortCode: [''],
1651
+ bankAccountNo: [''],
1652
+ bankSwift: [''],
1653
+ bankIban: [''],
1654
+ bankPaymentRef: [''],
1655
+ invoiceFooter: [''],
1656
+ paymentInstructions: [''],
1657
+ logoUrl: [''],
1658
+ enabled: [true],
1659
+ });
1660
+ }
1661
+ function patchBillingProfileForm(form, value) {
1662
+ if (!value) {
1663
+ return;
1664
+ }
1665
+ form.patchValue({
1666
+ displayName: value.displayName ?? '',
1667
+ companyName: value.companyName ?? '',
1668
+ companyWebsite: value.companyWebsite ?? '',
1669
+ companyRegistrationNo: value.companyRegistrationNo ?? '',
1670
+ companyVatNo: value.companyVatNo ?? '',
1671
+ companyAddressLine: value.companyAddressLine ?? '',
1672
+ companyEmail: value.companyEmail ?? '',
1673
+ companyPhone: value.companyPhone ?? '',
1674
+ bankInstitution: value.bankInstitution ?? '',
1675
+ bankAccountName: value.bankAccountName ?? '',
1676
+ bankSortCode: value.bankSortCode ?? '',
1677
+ bankAccountNo: value.bankAccountNo ?? '',
1678
+ bankSwift: value.bankSwift ?? '',
1679
+ bankIban: value.bankIban ?? '',
1680
+ bankPaymentRef: value.bankPaymentRef ?? '',
1681
+ invoiceFooter: value.invoiceFooter ?? '',
1682
+ paymentInstructions: value.paymentInstructions ?? '',
1683
+ logoUrl: value.logoUrl ?? '',
1684
+ enabled: value.enabled ?? true,
1685
+ });
1686
+ }
1687
+
1688
+ class BillingProfileSettingPage {
1689
+ constructor() {
1690
+ this.formBuilder = inject(FormBuilder);
1691
+ this.facade = inject(BillingProfileFacade);
1692
+ this.form = createBillingProfileForm(this.formBuilder);
1693
+ this.canSubmit = computed(() => !this.facade.loading() && !this.facade.saving(), ...(ngDevMode ? [{ debugName: "canSubmit" }] : []));
1694
+ effect(() => {
1695
+ const profile = this.facade.profile();
1696
+ patchBillingProfileForm(this.form, profile);
1697
+ });
1698
+ this.facade.load();
1699
+ }
1700
+ submit() {
1701
+ if (!this.canSubmit()) {
1702
+ return;
1703
+ }
1704
+ this.facade.save(this.form.getRawValue());
1705
+ }
1706
+ toggleEnabled(enabled) {
1707
+ this.facade.setEnabled(enabled);
1708
+ }
1709
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BillingProfileSettingPage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1710
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: BillingProfileSettingPage, isStandalone: true, selector: "rolatech-billing-profile-setting-page", providers: [BillingProfileFacade], ngImport: i0, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\n <header class=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div class=\"min-w-0\">\n <div class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">Member Management</h1>\n <p class=\"text-sm text-muted-foreground\">\n Review organization members, invitation state, and current role assignments from one workspace.\n </p>\n </div>\n </div>\n </header>\n <section class=\"grid gap-4\">\n @if (facade.error()) {\n <div class=\"mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\">{{ facade.error() }}</div>\n } @if (facade.saveMessage()) {\n <div class=\"mb-4 rounded-xl border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-700\">\n {{ facade.saveMessage() }}\n </div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"space-y-6\">\n <mat-card class=\"rounded-2xl\">\n <div class=\"grid gap-4 p-4 md:grid-cols-2\">\n <div class=\"md:col-span-2 flex items-center justify-between\">\n <div>\n <div class=\"text-base font-medium\">Billing Profile Status</div>\n <div class=\"text-sm text-gray-500\">Enable this profile for invoice generation and payment instructions.</div>\n </div>\n\n <mat-slide-toggle formControlName=\"enabled\" (change)=\"toggleEnabled($event.checked)\"> Enabled </mat-slide-toggle>\n </div>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Display Name</mat-label>\n <input matInput formControlName=\"displayName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Logo URL</mat-label>\n <input matInput formControlName=\"logoUrl\" />\n </mat-form-field>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Company Information</h2>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Name</mat-label>\n <input matInput formControlName=\"companyName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Website</mat-label>\n <input matInput formControlName=\"companyWebsite\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Registration No</mat-label>\n <input matInput formControlName=\"companyRegistrationNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>VAT No</mat-label>\n <input matInput formControlName=\"companyVatNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"md:col-span-2\">\n <mat-label>Address</mat-label>\n <textarea matInput rows=\"3\" formControlName=\"companyAddressLine\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Email</mat-label>\n <input matInput formControlName=\"companyEmail\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Phone</mat-label>\n <input matInput formControlName=\"companyPhone\" />\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Bank Information</h2>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Bank Institution</mat-label>\n <input matInput formControlName=\"bankInstitution\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Account Name</mat-label>\n <input matInput formControlName=\"bankAccountName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Sort Code</mat-label>\n <input matInput formControlName=\"bankSortCode\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Account No</mat-label>\n <input matInput formControlName=\"bankAccountNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>SWIFT</mat-label>\n <input matInput formControlName=\"bankSwift\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>IBAN</mat-label>\n <input matInput formControlName=\"bankIban\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"md:col-span-2\">\n <mat-label>Payment Reference</mat-label>\n <input matInput formControlName=\"bankPaymentRef\" />\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Invoice & Payment Content</h2>\n\n <div class=\"grid gap-4\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Invoice Footer</mat-label>\n <textarea matInput rows=\"4\" formControlName=\"invoiceFooter\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Payment Instructions</mat-label>\n <textarea matInput rows=\"5\" formControlName=\"paymentInstructions\"></textarea>\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <div class=\"flex justify-end\">\n <button mat-flat-button color=\"primary\" type=\"submit\" [disabled]=\"facade.saving() || facade.loading()\">\n {{ facade.saving() ? 'Saving...' : 'Save Billing Profile' }}\n </button>\n </div>\n </form>\n </section>\n</section>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i5$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1711
+ }
1712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BillingProfileSettingPage, decorators: [{
1713
+ type: Component,
1714
+ args: [{ selector: 'rolatech-billing-profile-setting-page', imports: [
1715
+ CommonModule,
1716
+ ReactiveFormsModule,
1717
+ MatButtonModule,
1718
+ MatFormFieldModule,
1719
+ MatInputModule,
1720
+ MatSlideToggleModule,
1721
+ MatCardModule,
1722
+ ], providers: [BillingProfileFacade], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"rt-platform-theme flex flex-col gap-6 bg-(--rt-base-background) p-6 text-(--rt-text-primary)\">\n <header class=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div class=\"min-w-0\">\n <div class=\"space-y-1\">\n <h1 class=\"text-2xl font-semibold tracking-tight\">Member Management</h1>\n <p class=\"text-sm text-muted-foreground\">\n Review organization members, invitation state, and current role assignments from one workspace.\n </p>\n </div>\n </div>\n </header>\n <section class=\"grid gap-4\">\n @if (facade.error()) {\n <div class=\"mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700\">{{ facade.error() }}</div>\n } @if (facade.saveMessage()) {\n <div class=\"mb-4 rounded-xl border border-green-200 bg-green-50 px-4 py-3 text-sm text-green-700\">\n {{ facade.saveMessage() }}\n </div>\n }\n\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\" class=\"space-y-6\">\n <mat-card class=\"rounded-2xl\">\n <div class=\"grid gap-4 p-4 md:grid-cols-2\">\n <div class=\"md:col-span-2 flex items-center justify-between\">\n <div>\n <div class=\"text-base font-medium\">Billing Profile Status</div>\n <div class=\"text-sm text-gray-500\">Enable this profile for invoice generation and payment instructions.</div>\n </div>\n\n <mat-slide-toggle formControlName=\"enabled\" (change)=\"toggleEnabled($event.checked)\"> Enabled </mat-slide-toggle>\n </div>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Display Name</mat-label>\n <input matInput formControlName=\"displayName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Logo URL</mat-label>\n <input matInput formControlName=\"logoUrl\" />\n </mat-form-field>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Company Information</h2>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Name</mat-label>\n <input matInput formControlName=\"companyName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Website</mat-label>\n <input matInput formControlName=\"companyWebsite\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Registration No</mat-label>\n <input matInput formControlName=\"companyRegistrationNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>VAT No</mat-label>\n <input matInput formControlName=\"companyVatNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"md:col-span-2\">\n <mat-label>Address</mat-label>\n <textarea matInput rows=\"3\" formControlName=\"companyAddressLine\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Email</mat-label>\n <input matInput formControlName=\"companyEmail\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Company Phone</mat-label>\n <input matInput formControlName=\"companyPhone\" />\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Bank Information</h2>\n\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Bank Institution</mat-label>\n <input matInput formControlName=\"bankInstitution\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Account Name</mat-label>\n <input matInput formControlName=\"bankAccountName\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Sort Code</mat-label>\n <input matInput formControlName=\"bankSortCode\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Account No</mat-label>\n <input matInput formControlName=\"bankAccountNo\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>SWIFT</mat-label>\n <input matInput formControlName=\"bankSwift\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>IBAN</mat-label>\n <input matInput formControlName=\"bankIban\" />\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\" class=\"md:col-span-2\">\n <mat-label>Payment Reference</mat-label>\n <input matInput formControlName=\"bankPaymentRef\" />\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <mat-card class=\"rounded-2xl\">\n <div class=\"p-4\">\n <h2 class=\"mb-4 text-lg font-medium\">Invoice & Payment Content</h2>\n\n <div class=\"grid gap-4\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Invoice Footer</mat-label>\n <textarea matInput rows=\"4\" formControlName=\"invoiceFooter\"></textarea>\n </mat-form-field>\n\n <mat-form-field appearance=\"outline\">\n <mat-label>Payment Instructions</mat-label>\n <textarea matInput rows=\"5\" formControlName=\"paymentInstructions\"></textarea>\n </mat-form-field>\n </div>\n </div>\n </mat-card>\n\n <div class=\"flex justify-end\">\n <button mat-flat-button color=\"primary\" type=\"submit\" [disabled]=\"facade.saving() || facade.loading()\">\n {{ facade.saving() ? 'Saving...' : 'Save Billing Profile' }}\n </button>\n </div>\n </form>\n </section>\n</section>\n", styles: [":host{display:block}\n"] }]
1723
+ }], ctorParameters: () => [] });
1724
+
1725
+ const BILLING_PROFILE_ROUTES = [
1726
+ {
1727
+ path: '',
1728
+ component: BillingProfileSettingPage,
1729
+ },
1730
+ ];
1731
+
1569
1732
  /**
1570
1733
  * Generated bundle index. Do not edit.
1571
1734
  */
1572
1735
 
1573
- export { agentInvoiceRoutes, billingRoutes, invoiceManageRoutes, invoiceRoutes };
1736
+ export { BILLING_PROFILE_ROUTES, BillingProfileFacade, agentInvoiceRoutes, billingRoutes, invoiceManageRoutes, invoiceRoutes };
1574
1737
  //# sourceMappingURL=rolatech-angular-billing.mjs.map