tin-spa 20.4.6 → 20.4.7
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.
- package/fesm2022/tin-spa.mjs +898 -183
- package/fesm2022/tin-spa.mjs.map +1 -1
- package/index.d.ts +40 -13
- package/package.json +1 -1
package/fesm2022/tin-spa.mjs
CHANGED
|
@@ -47,7 +47,7 @@ import { MatPaginatorModule } from '@angular/material/paginator';
|
|
|
47
47
|
import * as i18$1 from '@angular/material/progress-spinner';
|
|
48
48
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
49
49
|
import { MatRadioModule } from '@angular/material/radio';
|
|
50
|
-
import * as i7
|
|
50
|
+
import * as i7 from '@angular/material/select';
|
|
51
51
|
import { MatSelectModule } from '@angular/material/select';
|
|
52
52
|
import { MatSliderModule } from '@angular/material/slider';
|
|
53
53
|
import { MatSortModule } from '@angular/material/sort';
|
|
@@ -59,7 +59,7 @@ import * as i4$5 from '@angular/material/tabs';
|
|
|
59
59
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
60
60
|
import * as i14$1 from '@angular/material/progress-bar';
|
|
61
61
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
62
|
-
import * as
|
|
62
|
+
import * as i8 from '@angular/material/tooltip';
|
|
63
63
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
64
64
|
import * as i2$3 from '@angular/forms';
|
|
65
65
|
import { FormsModule, ReactiveFormsModule, FormControl, Validators, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
@@ -69,7 +69,7 @@ import * as i17 from '@angular/material/toolbar';
|
|
|
69
69
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
70
70
|
import * as i18 from '@angular/material/expansion';
|
|
71
71
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
72
|
-
import * as
|
|
72
|
+
import * as i9 from 'ng2-charts';
|
|
73
73
|
import { BaseChartDirective, provideCharts, withDefaultRegisterables } from 'ng2-charts';
|
|
74
74
|
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
|
|
75
75
|
import imageCompression from 'browser-image-compression';
|
|
@@ -1133,7 +1133,7 @@ class AppConfig {
|
|
|
1133
1133
|
this.loginStyle = 'default';
|
|
1134
1134
|
this.termsUrl = "";
|
|
1135
1135
|
this.privacyUrl = "";
|
|
1136
|
-
this.siteUrl = "https://
|
|
1136
|
+
this.siteUrl = "https://alsquaretech.net/";
|
|
1137
1137
|
this.navWidth = '200px';
|
|
1138
1138
|
this.navColor = 'rgba(0,0,0,0.78)'; // Changed: Default dark overlay for side-modern sidebar
|
|
1139
1139
|
this.navImage = ''; // Changed: Default no background image for side-modern sidebar
|
|
@@ -1891,6 +1891,7 @@ class DataServiceLib {
|
|
|
1891
1891
|
this.capStandingOrders = new CapItem; // Changed: Capability for standing orders management
|
|
1892
1892
|
this.capFixedAssets = new CapItem; // Added: Capability for fixed assets management
|
|
1893
1893
|
this.capFixedAssetCategories = new CapItem; // Added: Capability for fixed asset categories management
|
|
1894
|
+
this.capCurrencies = new CapItem; // Changed: Capability for currencies management
|
|
1894
1895
|
this.capTransactionTypes = new CapItem;
|
|
1895
1896
|
this.capTransactions = new CapItem;
|
|
1896
1897
|
this.capAccountingInvoices = new CapItem;
|
|
@@ -1923,6 +1924,8 @@ class DataServiceLib {
|
|
|
1923
1924
|
this.capSalesDashboard = new CapItem; // Changed: Sales dashboard menu item
|
|
1924
1925
|
this.capPurchasingDashboard = new CapItem; // Changed: Purchasing dashboard menu item
|
|
1925
1926
|
this.capSupplierAging = new CapItem; // Changed: AP Aging capability property
|
|
1927
|
+
this.capInvoiceDashboard = new CapItem; // Changed: Invoice dashboard menu item
|
|
1928
|
+
this.capPayrollDashboard = new CapItem; // Changed: Payroll dashboard menu item
|
|
1926
1929
|
this.tmpProfileuserName = "";
|
|
1927
1930
|
this.isProcessing = false;
|
|
1928
1931
|
//--------------------------Departmemts Form-------------------------
|
|
@@ -2647,7 +2650,7 @@ class DataServiceLib {
|
|
|
2647
2650
|
this.capAdmin.name = "cap2";
|
|
2648
2651
|
this.capAdmin.display = "Admin";
|
|
2649
2652
|
this.capAdmin.icon = "security";
|
|
2650
|
-
this.capAdmin.capSubItems = [this.capUsers, this.capRoles, this.capLogs, this.
|
|
2653
|
+
this.capAdmin.capSubItems = [this.capUsers, this.capRoles, this.capLogs, this.capSettings, this.capSubscription, this.capBilling]; // Changed: Added Subscription & Billing — tenant-specific settings belong under Admin
|
|
2651
2654
|
this.capUsers.name = "cap3";
|
|
2652
2655
|
this.capUsers.display = "Users";
|
|
2653
2656
|
this.capUsers.link = "home/admin/users";
|
|
@@ -2667,7 +2670,7 @@ class DataServiceLib {
|
|
|
2667
2670
|
this.capMultitenant.name = "cap7";
|
|
2668
2671
|
this.capMultitenant.display = "Multitenant";
|
|
2669
2672
|
this.capMultitenant.icon = "apartment";
|
|
2670
|
-
this.capMultitenant.capSubItems = [this.capTenants, this.capMembership, this.capPlans, this.capFeatures, this.capPlanFeatures
|
|
2673
|
+
this.capMultitenant.capSubItems = [this.capTenants, this.capMembership, this.capPlans, this.capFeatures, this.capPlanFeatures]; // Changed: Moved Subscription & Billing to Admin — they are tenant-specific settings
|
|
2671
2674
|
this.capTenants.name = "cap8";
|
|
2672
2675
|
this.capTenants.display = "Tenants";
|
|
2673
2676
|
this.capTenants.link = "home/admin/tenants";
|
|
@@ -2755,7 +2758,11 @@ class DataServiceLib {
|
|
|
2755
2758
|
this.capPayroll.name = "cap72"; // Changed: Moved from cap110 to cap72 — library range consolidation
|
|
2756
2759
|
this.capPayroll.display = "Payroll";
|
|
2757
2760
|
this.capPayroll.icon = "payments";
|
|
2758
|
-
this.capPayroll.capSubItems = [this.capSalaryStructures, this.capStatutoryDeductions, this.capPayrollRuns, this.capCommissionConfigs, this.capCommissionEntries, this.capSalaryAdvances, this.capOvertimeEntries]; // Changed: Added
|
|
2761
|
+
this.capPayroll.capSubItems = [this.capPayrollDashboard, this.capSalaryStructures, this.capStatutoryDeductions, this.capPayrollRuns, this.capCommissionConfigs, this.capCommissionEntries, this.capSalaryAdvances, this.capOvertimeEntries]; // Changed: Added payroll dashboard as first item
|
|
2762
|
+
this.capPayrollDashboard.name = "cap72"; // Changed: Reuses module cap number for dashboard visibility
|
|
2763
|
+
this.capPayrollDashboard.display = "Dashboard";
|
|
2764
|
+
this.capPayrollDashboard.link = "home/admin/payroll-dashboard";
|
|
2765
|
+
this.capPayrollDashboard.icon = "dashboard";
|
|
2759
2766
|
this.capSalaryStructures.name = "cap73"; // Changed: Moved from cap111 to cap73 — library range consolidation
|
|
2760
2767
|
this.capSalaryStructures.display = "Salary Structures";
|
|
2761
2768
|
this.capSalaryStructures.link = "home/admin/payroll-salary-structures";
|
|
@@ -2814,7 +2821,7 @@ class DataServiceLib {
|
|
|
2814
2821
|
this.capAccounting.name = "cap27";
|
|
2815
2822
|
this.capAccounting.display = "Accounting";
|
|
2816
2823
|
this.capAccounting.icon = "account_balance";
|
|
2817
|
-
this.capAccounting.capSubItems = [this.capAccountingDashboard, this.capAccounts, this.capTransactions, this.capAggregates, this.capReports, this.capTransactionTypes, this.capTaxRates, this.capStandingOrders, this.capFixedAssets, this.capFixedAssetCategories]; // Changed: Added Dashboard to Accounting submenu
|
|
2824
|
+
this.capAccounting.capSubItems = [this.capAccountingDashboard, this.capAccounts, this.capTransactions, this.capAggregates, this.capReports, this.capTransactionTypes, this.capTaxRates, this.capCurrencies, this.capStandingOrders, this.capFixedAssets, this.capFixedAssetCategories]; // Changed: Added Dashboard and Currencies to Accounting submenu
|
|
2818
2825
|
this.capAccountingDashboard.name = "cap27"; // Changed: Reuses module cap number for dashboard visibility
|
|
2819
2826
|
this.capAccountingDashboard.display = "Dashboard";
|
|
2820
2827
|
this.capAccountingDashboard.link = "home/admin/accounting-dashboard";
|
|
@@ -2835,6 +2842,11 @@ class DataServiceLib {
|
|
|
2835
2842
|
this.capTaxRates.display = "Tax Rates";
|
|
2836
2843
|
this.capTaxRates.link = "home/admin/accounting-tax-rates";
|
|
2837
2844
|
this.capTaxRates.icon = "percent";
|
|
2845
|
+
// Changed: Added Currencies to Accounting menu — feature exists but was missing from nav
|
|
2846
|
+
this.capCurrencies.name = "cap84";
|
|
2847
|
+
this.capCurrencies.display = "Currencies";
|
|
2848
|
+
this.capCurrencies.link = "home/admin/accounting-currencies";
|
|
2849
|
+
this.capCurrencies.icon = "currency_exchange";
|
|
2838
2850
|
this.capStandingOrders.name = "cap64"; // Changed: Standing orders capability
|
|
2839
2851
|
this.capStandingOrders.display = "Standing Orders";
|
|
2840
2852
|
this.capStandingOrders.link = "home/admin/accounting-standing-orders";
|
|
@@ -2858,7 +2870,11 @@ class DataServiceLib {
|
|
|
2858
2870
|
this.capInvoicing.name = "cap53";
|
|
2859
2871
|
this.capInvoicing.display = "Invoicing";
|
|
2860
2872
|
this.capInvoicing.icon = "receipt_long";
|
|
2861
|
-
this.capInvoicing.capSubItems = [this.capAccountingInvoices, this.capAging, this.capAccountingOutstandingInvoices];
|
|
2873
|
+
this.capInvoicing.capSubItems = [this.capInvoiceDashboard, this.capAccountingInvoices, this.capAging, this.capAccountingOutstandingInvoices]; // Changed: Added invoice dashboard as first item
|
|
2874
|
+
this.capInvoiceDashboard.name = "cap53"; // Changed: Reuses module cap number for dashboard visibility
|
|
2875
|
+
this.capInvoiceDashboard.display = "Dashboard";
|
|
2876
|
+
this.capInvoiceDashboard.link = "home/admin/invoice-dashboard";
|
|
2877
|
+
this.capInvoiceDashboard.icon = "dashboard";
|
|
2862
2878
|
this.capAccountingInvoices.name = "cap53";
|
|
2863
2879
|
this.capAccountingInvoices.display = "Invoices";
|
|
2864
2880
|
this.capAccountingInvoices.link = "home/admin/accounting-invoices";
|
|
@@ -3414,6 +3430,7 @@ class AccountingService {
|
|
|
3414
3430
|
{ name: 'invoiceID', type: 'number', hidden: true },
|
|
3415
3431
|
{ name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true },
|
|
3416
3432
|
{ name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue: 1, loadAction: { url: 'invoicepayments/list/methods' } },
|
|
3433
|
+
{ name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: Added currency select for multi-currency payments
|
|
3417
3434
|
{ name: 'outstandingAmount', type: 'label', alias: 'Outstanding', readonly: true },
|
|
3418
3435
|
{ name: 'amount', type: 'money', alias: 'Amount', required: true, span: true },
|
|
3419
3436
|
{ name: 'reference', type: 'text', alias: 'Reference', span: true }
|
|
@@ -3612,9 +3629,9 @@ class AccountingService {
|
|
|
3612
3629
|
this.invoicesTileConfig = {
|
|
3613
3630
|
clickable: true,
|
|
3614
3631
|
tiles: [
|
|
3615
|
-
{ name: 'drafts', alias: 'Draft Invoices', color: '#FFC107', info: 'Invoices in draft stage', action: { url: 'invoices/drafts/x' } },
|
|
3616
|
-
{ name: 'submitted', alias: 'Pending Payment', color: '#2196F3', info: 'Submitted invoices awaiting payment', action: { url: 'invoices/submitted/x' } },
|
|
3617
|
-
{ name: 'pendingPayments', alias: 'Outstanding', color: '#F44336', info: 'Total amount pending payment' }
|
|
3632
|
+
{ name: 'drafts', alias: 'Draft Invoices', color: '#FFC107', icon: 'edit_note', info: 'Invoices in draft stage', action: { url: 'invoices/drafts/x' } }, // Changed: Added icon
|
|
3633
|
+
{ name: 'submitted', alias: 'Pending Payment', color: '#2196F3', icon: 'send', info: 'Submitted invoices awaiting payment', action: { url: 'invoices/submitted/x' } }, // Changed: Added icon
|
|
3634
|
+
{ name: 'pendingPayments', alias: 'Outstanding', color: '#F44336', icon: 'payments', info: 'Total amount pending payment' } // Changed: Added icon
|
|
3618
3635
|
],
|
|
3619
3636
|
loadAction: { url: 'invoices/summary/x' }
|
|
3620
3637
|
};
|
|
@@ -3669,12 +3686,12 @@ class AccountingService {
|
|
|
3669
3686
|
this.agingTileConfig = {
|
|
3670
3687
|
// clickable: true,
|
|
3671
3688
|
tiles: [
|
|
3672
|
-
{ name: 'current', alias: 'Current', color: '#4CAF50', info: 'Not yet due'
|
|
3673
|
-
{ name: 'days30', alias: '1-30 Days', color: '#FFC107', info: '1-30 days overdue'
|
|
3674
|
-
{ name: 'days60', alias: '31-60 Days', color: '#FF9800', info: '31-60 days overdue'
|
|
3675
|
-
{ name: 'days90', alias: '61-90 Days', color: '#F44336', info: '61-90 days overdue'
|
|
3676
|
-
{ name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', info: 'Over 90 days overdue'
|
|
3677
|
-
{ name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', info: 'Total outstanding amount' }
|
|
3689
|
+
{ name: 'current', alias: 'Current', color: '#4CAF50', icon: 'check_circle', info: 'Not yet due' }, // Changed: Added icon
|
|
3690
|
+
{ name: 'days30', alias: '1-30 Days', color: '#FFC107', icon: 'schedule', info: '1-30 days overdue' }, // Changed: Added icon
|
|
3691
|
+
{ name: 'days60', alias: '31-60 Days', color: '#FF9800', icon: 'warning', info: '31-60 days overdue' }, // Changed: Added icon
|
|
3692
|
+
{ name: 'days90', alias: '61-90 Days', color: '#F44336', icon: 'error', info: '61-90 days overdue' }, // Changed: Added icon
|
|
3693
|
+
{ name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', icon: 'dangerous', info: 'Over 90 days overdue' }, // Changed: Added icon
|
|
3694
|
+
{ name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', icon: 'account_balance_wallet', info: 'Total outstanding amount' } // Changed: Added icon
|
|
3678
3695
|
],
|
|
3679
3696
|
// loadAction: { url: 'invoices/aging-summary/x' }
|
|
3680
3697
|
};
|
|
@@ -4043,8 +4060,7 @@ class AccountingService {
|
|
|
4043
4060
|
},
|
|
4044
4061
|
{ name: 'description', type: 'text', required: true, span: true },
|
|
4045
4062
|
{ name: 'amount', type: 'money', required: true, span: true },
|
|
4046
|
-
|
|
4047
|
-
{ name: 'foreignAmount', type: 'number', alias: 'Foreign Amount', hiddenCondition: (x) => !x.currencyID }, // Changed: Added foreign amount field, hidden when no currency selected
|
|
4063
|
+
// Changed: Removed currencyID and foreignAmount fields — backend auto-detects currency from accounts
|
|
4048
4064
|
],
|
|
4049
4065
|
};
|
|
4050
4066
|
this.transactionEditButton = { name: 'edit', dialog: true,
|
|
@@ -4066,7 +4082,7 @@ class AccountingService {
|
|
|
4066
4082
|
this.transactionsTableConfig = {
|
|
4067
4083
|
showFilter: true,
|
|
4068
4084
|
greyOut: x => x.isReversal || x.status == 1,
|
|
4069
|
-
minColumns: ['date', 'description', '
|
|
4085
|
+
minColumns: ['date', 'description', 'amountDisplay'],
|
|
4070
4086
|
flatButtons: true,
|
|
4071
4087
|
columns: [
|
|
4072
4088
|
{ name: 'date', type: 'date' },
|
|
@@ -4079,11 +4095,9 @@ class AccountingService {
|
|
|
4079
4095
|
{ name: 'typeName', type: 'text', alias: 'Type' },
|
|
4080
4096
|
{ name: 'debitAccountName', type: 'text', alias: 'Debit Account' },
|
|
4081
4097
|
{ name: 'creditAccountName', type: 'text', alias: 'Credit Account' },
|
|
4082
|
-
{ name: '
|
|
4083
|
-
{ name: 'amount', type: 'money',
|
|
4098
|
+
{ name: 'amountDisplay', type: 'text', alias: 'Amount', // Changed: Single formatted column replacing CCY, Amount, Foreign Amount
|
|
4084
4099
|
color: { name: 'red', condition: x => x.reducesBalance && !x.isAggregate },
|
|
4085
4100
|
},
|
|
4086
|
-
{ name: 'foreignAmountDisplay', type: 'number', alias: 'Foreign Amount', hiddenCondition: (x) => !x.currencyCode }, // Changed: Added foreign amount column, hidden when no currency
|
|
4087
4101
|
],
|
|
4088
4102
|
buttons: [
|
|
4089
4103
|
{ name: 'create', display: 'Create Transaction', dialog: true, action: { url: 'transactions/dto?action=create', method: 'post' } },
|
|
@@ -4098,7 +4112,7 @@ class AccountingService {
|
|
|
4098
4112
|
this.accountTransactionsTableConfig = {
|
|
4099
4113
|
...this.transactionsTableConfig,
|
|
4100
4114
|
causeFormRefresh: true,
|
|
4101
|
-
minColumns: ['date', 'description', '
|
|
4115
|
+
minColumns: ['date', 'description', 'amountDisplay', 'runningBalance'], // Changed: Use amountDisplay instead of amount
|
|
4102
4116
|
tabTitle: 'Account Transactions',
|
|
4103
4117
|
loadAction: { url: 'transactions/account/x' }, loadCriteria: 'account', loadIDField: 'accountID',
|
|
4104
4118
|
columns: [
|
|
@@ -4543,10 +4557,10 @@ class AccountingService {
|
|
|
4543
4557
|
this.assetTileConfig = {
|
|
4544
4558
|
clickable: true,
|
|
4545
4559
|
tiles: [
|
|
4546
|
-
{ name: 'draft', alias: 'Draft', color: '#FFC107', action: { url: 'fixedassets/draft/x' } },
|
|
4547
|
-
{ name: 'active', alias: 'Active', color: '#4CAF50', action: { url: 'fixedassets/active/x' } },
|
|
4548
|
-
{ name: 'fullyDepreciated', alias: 'Fully Depreciated', color: '#2196F3' },
|
|
4549
|
-
{ name: 'disposed', alias: 'Disposed', color: '#9E9E9E' },
|
|
4560
|
+
{ name: 'draft', alias: 'Draft', color: '#FFC107', icon: 'edit_note', action: { url: 'fixedassets/draft/x' } }, // Changed: Added icon
|
|
4561
|
+
{ name: 'active', alias: 'Active', color: '#4CAF50', icon: 'check_circle', action: { url: 'fixedassets/active/x' } }, // Changed: Added icon
|
|
4562
|
+
{ name: 'fullyDepreciated', alias: 'Fully Depreciated', color: '#2196F3', icon: 'trending_down' }, // Changed: Added icon
|
|
4563
|
+
{ name: 'disposed', alias: 'Disposed', color: '#9E9E9E', icon: 'delete_forever' }, // Changed: Added icon
|
|
4550
4564
|
],
|
|
4551
4565
|
loadAction: { url: 'fixedassets/summary/x' }
|
|
4552
4566
|
};
|
|
@@ -4723,10 +4737,10 @@ class AccountingService {
|
|
|
4723
4737
|
// Budget summary tiles for report page
|
|
4724
4738
|
this.budgetSummaryTileConfig = {
|
|
4725
4739
|
tiles: [
|
|
4726
|
-
{ name: 'totalBudgeted', alias: 'Total Budgeted', color: '#2196F3', info: 'Sum of all budget line amounts' },
|
|
4727
|
-
{ name: 'totalActual', alias: 'Total Actual', color: '#4CAF50', info: 'Sum of actual amounts from ledger' },
|
|
4728
|
-
{ name: 'totalVariance', alias: 'Total Variance', color: '#FF9800', info: 'Difference between budgeted and actual' },
|
|
4729
|
-
{ name: 'overBudgetLines', alias: 'Over Budget', color: '#F44336', info: 'Number of lines over budget' }
|
|
4740
|
+
{ name: 'totalBudgeted', alias: 'Total Budgeted', color: '#2196F3', icon: 'request_quote', info: 'Sum of all budget line amounts' }, // Changed: Added icon
|
|
4741
|
+
{ name: 'totalActual', alias: 'Total Actual', color: '#4CAF50', icon: 'receipt', info: 'Sum of actual amounts from ledger' }, // Changed: Added icon
|
|
4742
|
+
{ name: 'totalVariance', alias: 'Total Variance', color: '#FF9800', icon: 'compare_arrows', info: 'Difference between budgeted and actual' }, // Changed: Added icon
|
|
4743
|
+
{ name: 'overBudgetLines', alias: 'Over Budget', color: '#F44336', icon: 'warning', info: 'Number of lines over budget' } // Changed: Added icon
|
|
4730
4744
|
]
|
|
4731
4745
|
};
|
|
4732
4746
|
}
|
|
@@ -5672,10 +5686,10 @@ class InventoryService {
|
|
|
5672
5686
|
clickable: true,
|
|
5673
5687
|
headerPosition: 'top',
|
|
5674
5688
|
tiles: [
|
|
5675
|
-
{ name: 'totalProducts', alias: 'Total Products', color: '#2196F3', info: 'Total number of products in inventory', action: { url: 'inventoryitems/stock/all' } },
|
|
5676
|
-
{ name: 'lowStockProducts', alias: 'Low Stock', color: '#FFC107', info: 'Products below minimum quantity', action: { url: 'inventoryitems/stock/lowstock' } },
|
|
5677
|
-
{ name: 'outOfStockProducts', alias: 'Out of Stock', color: '#F44336', info: 'Products with zero quantity', action: { url: 'inventoryitems/stock/outofstock' } },
|
|
5678
|
-
{ name: 'serializedProducts', alias: 'Serialized Products', color: '#9C27B0', info: 'Number of products with serial tracking', action: { url: 'inventoryitems/stock/serialized' } },
|
|
5689
|
+
{ name: 'totalProducts', alias: 'Total Products', color: '#2196F3', icon: 'category', info: 'Total number of products in inventory', action: { url: 'inventoryitems/stock/all' } }, // Changed: Added icon
|
|
5690
|
+
{ name: 'lowStockProducts', alias: 'Low Stock', color: '#FFC107', icon: 'warning', info: 'Products below minimum quantity', action: { url: 'inventoryitems/stock/lowstock' } }, // Changed: Added icon
|
|
5691
|
+
{ name: 'outOfStockProducts', alias: 'Out of Stock', color: '#F44336', icon: 'remove_shopping_cart', info: 'Products with zero quantity', action: { url: 'inventoryitems/stock/outofstock' } }, // Changed: Added icon
|
|
5692
|
+
{ name: 'serializedProducts', alias: 'Serialized Products', color: '#9C27B0', icon: 'qr_code_2', info: 'Number of products with serial tracking', action: { url: 'inventoryitems/stock/serialized' } }, // Changed: Added icon
|
|
5679
5693
|
],
|
|
5680
5694
|
loadAction: { url: 'inventoryitems/stock/summary' }
|
|
5681
5695
|
};
|
|
@@ -6408,7 +6422,7 @@ class SuffixComponent {
|
|
|
6408
6422
|
this.clearClick.emit();
|
|
6409
6423
|
}
|
|
6410
6424
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SuffixComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6411
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SuffixComponent, isStandalone: false, selector: "spa-suffix", inputs: { label: "label", infoMessage: "infoMessage", copyContent: "copyContent", isHovered: "isHovered", clearContent: "clearContent", value: "value" }, outputs: { infoClick: "infoClick", copyClick: "copyClick", clearClick: "clearClick", valueChange: "valueChange" }, ngImport: i0, template: "<label *ngIf=\"label\"> {{label}}</label>\r\n<button mat-icon-button *ngIf=\"copyContent && isHovered\" (click)=\"onCopyClick($event)\" matTooltip=\"Copy Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\">content_copy</mat-icon>\r\n</button>\r\n<button mat-icon-button *ngIf=\"clearContent && isHovered\" (click)=\"onClearClick($event)\" matTooltip=\"Clear Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\">close</mat-icon>\r\n</button>\r\n<button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" [matTooltip]=\"infoMessage\" matTooltipPosition=\"above\" style=\"opacity: 1;margin-right: 2px;\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\r\n</button>\r\n", styles: [".smallIcon{font-size:14px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
6425
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SuffixComponent, isStandalone: false, selector: "spa-suffix", inputs: { label: "label", infoMessage: "infoMessage", copyContent: "copyContent", isHovered: "isHovered", clearContent: "clearContent", value: "value" }, outputs: { infoClick: "infoClick", copyClick: "copyClick", clearClick: "clearClick", valueChange: "valueChange" }, ngImport: i0, template: "<label *ngIf=\"label\"> {{label}}</label>\r\n<button mat-icon-button *ngIf=\"copyContent && isHovered\" (click)=\"onCopyClick($event)\" matTooltip=\"Copy Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\">content_copy</mat-icon>\r\n</button>\r\n<button mat-icon-button *ngIf=\"clearContent && isHovered\" (click)=\"onClearClick($event)\" matTooltip=\"Clear Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\">close</mat-icon>\r\n</button>\r\n<button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" [matTooltip]=\"infoMessage\" matTooltipPosition=\"above\" style=\"opacity: 1;margin-right: 2px;\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\r\n</button>\r\n", styles: [".smallIcon{font-size:14px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
6412
6426
|
}
|
|
6413
6427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SuffixComponent, decorators: [{
|
|
6414
6428
|
type: Component,
|
|
@@ -7233,7 +7247,7 @@ class TextSingleComponent {
|
|
|
7233
7247
|
}
|
|
7234
7248
|
}
|
|
7235
7249
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TextSingleComponent, deps: [{ token: DataServiceLib }, { token: DialogService }, { token: ButtonService }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7236
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TextSingleComponent, isStandalone: false, selector: "spa-text-single", inputs: { appearance: "appearance", readonly: "readonly", hint: "hint", display: "display", placeholder: "placeholder", value: "value", width: "width", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", loadAction: "loadAction", required: "required", min: "min", max: "max", regex: "regex", suffix: "suffix", infoMessage: "infoMessage", field: "field", data: "data", detailsConfig: "detailsConfig", masterField: "masterField" }, outputs: { valueChange: "valueChange", leave: "leave", enterPress: "enterPress" }, usesOnChanges: true, ngImport: i0, template: "<!-- Autocomplete text input -->\r\n<mat-form-field [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [appearance]=\"appearance ?? 'fill'\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <input [placeholder]=\"placeholder\" [formControl]=\"myControl\" matInput [matAutocomplete]=\"auto\" [required]=\"required\" [readonly]=\"readonly\">\r\n <mat-error *ngIf=\"myControl.invalid && (myControl.dirty || myControl.touched)\">{{validate(myControl)}}</mat-error>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"changed()\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"multiDimension ? option[optionDisplay] : option\">\r\n {{multiDimension ? option[optionDisplay] : option}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <div matSuffix class=\"suffix-icons\">\r\n <!-- Changed: Added Add button for creating new items via detailsConfig -->\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <!-- Changed: Added View button for viewing selected item via detailsConfig -->\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4$2.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: i7
|
|
7250
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TextSingleComponent, isStandalone: false, selector: "spa-text-single", inputs: { appearance: "appearance", readonly: "readonly", hint: "hint", display: "display", placeholder: "placeholder", value: "value", width: "width", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", loadAction: "loadAction", required: "required", min: "min", max: "max", regex: "regex", suffix: "suffix", infoMessage: "infoMessage", field: "field", data: "data", detailsConfig: "detailsConfig", masterField: "masterField" }, outputs: { valueChange: "valueChange", leave: "leave", enterPress: "enterPress" }, usesOnChanges: true, ngImport: i0, template: "<!-- Autocomplete text input -->\r\n<mat-form-field [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [appearance]=\"appearance ?? 'fill'\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <input [placeholder]=\"placeholder\" [formControl]=\"myControl\" matInput [matAutocomplete]=\"auto\" [required]=\"required\" [readonly]=\"readonly\">\r\n <mat-error *ngIf=\"myControl.invalid && (myControl.dirty || myControl.touched)\">{{validate(myControl)}}</mat-error>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"changed()\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"multiDimension ? option[optionDisplay] : option\">\r\n {{multiDimension ? option[optionDisplay] : option}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <div matSuffix class=\"suffix-icons\">\r\n <!-- Changed: Added Add button for creating new items via detailsConfig -->\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <!-- Changed: Added View button for viewing selected item via detailsConfig -->\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4$2.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: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i12.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] }); }
|
|
7237
7251
|
}
|
|
7238
7252
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TextSingleComponent, decorators: [{
|
|
7239
7253
|
type: Component,
|
|
@@ -7727,7 +7741,7 @@ class SelectCommonComponent {
|
|
|
7727
7741
|
}
|
|
7728
7742
|
}
|
|
7729
7743
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectCommonComponent, deps: [{ token: MessageService }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7730
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectCommonComponent, isStandalone: false, selector: "spa-select-common", inputs: { width: "width", readonly: "readonly", required: "required", defaultFirstValue: "defaultFirstValue", readonlyMode: "readonlyMode", hint: "hint", placeholder: "placeholder", display: "display", value: "value", options: "options", masterOptions: "masterOptions", masterField: "masterField", optionValue: "optionValue", optionDisplay: "optionDisplay", optionDisplayExtra: "optionDisplayExtra", nullable: "nullable", infoMessage: "infoMessage", copyContent: "copyContent", loadAction: "loadAction", loadIDField: "loadIDField", field: "field", data: "data" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, usesOnChanges: true, ngImport: i0, template: "<mat-form-field *ngIf=\"readonlyMode==''\" floatLabel=\"always\" [hintLabel]=\"computedHint\" [ngStyle]=\"{'width':width ?? '100%'}\" [hideRequiredMarker]=\"false\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n\r\n <mat-label>{{display}}</mat-label>\r\n <!-- Removed: [multiple]=\"multiple\" binding - component now only supports single selection -->\r\n <mat-select [(value)]=\"value\" (selectionChange)=\"changed()\" [disabled]=\"readonly\" [placeholder]=\"placeholder\" [required]=\"required\">\r\n <mat-option *ngFor=\"let row of options\" [value]=\"row[optionValue]\">\r\n {{row[optionDisplay]}} <label *ngIf=\"optionDisplayExtra!='' && row[optionDisplayExtra] && row[optionDisplayExtra] != ''\">({{row[optionDisplayExtra]}})</label>\r\n </mat-option>\r\n </mat-select>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n <ng-content select=\"[additionalButtons]\"></ng-content>\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered && !masterField\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7
|
|
7744
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectCommonComponent, isStandalone: false, selector: "spa-select-common", inputs: { width: "width", readonly: "readonly", required: "required", defaultFirstValue: "defaultFirstValue", readonlyMode: "readonlyMode", hint: "hint", placeholder: "placeholder", display: "display", value: "value", options: "options", masterOptions: "masterOptions", masterField: "masterField", optionValue: "optionValue", optionDisplay: "optionDisplay", optionDisplayExtra: "optionDisplayExtra", nullable: "nullable", infoMessage: "infoMessage", copyContent: "copyContent", loadAction: "loadAction", loadIDField: "loadIDField", field: "field", data: "data" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, usesOnChanges: true, ngImport: i0, template: "<mat-form-field *ngIf=\"readonlyMode==''\" floatLabel=\"always\" [hintLabel]=\"computedHint\" [ngStyle]=\"{'width':width ?? '100%'}\" [hideRequiredMarker]=\"false\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n\r\n <mat-label>{{display}}</mat-label>\r\n <!-- Removed: [multiple]=\"multiple\" binding - component now only supports single selection -->\r\n <mat-select [(value)]=\"value\" (selectionChange)=\"changed()\" [disabled]=\"readonly\" [placeholder]=\"placeholder\" [required]=\"required\">\r\n <mat-option *ngFor=\"let row of options\" [value]=\"row[optionValue]\">\r\n {{row[optionDisplay]}} <label *ngIf=\"optionDisplayExtra!='' && row[optionDisplayExtra] && row[optionDisplayExtra] != ''\">({{row[optionDisplayExtra]}})</label>\r\n </mat-option>\r\n </mat-select>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n <ng-content select=\"[additionalButtons]\"></ng-content>\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered && !masterField\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7.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: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }] }); }
|
|
7731
7745
|
}
|
|
7732
7746
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectCommonComponent, decorators: [{
|
|
7733
7747
|
type: Component,
|
|
@@ -7835,7 +7849,7 @@ class SelectComponent extends SelectCommonComponent {
|
|
|
7835
7849
|
}
|
|
7836
7850
|
}
|
|
7837
7851
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectComponent, deps: [{ token: MessageService }, { token: DataServiceLib }, { token: DialogService }, { token: ButtonService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7838
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectComponent, isStandalone: false, selector: "spa-select", inputs: { detailsConfig: "detailsConfig" }, usesInheritance: true, ngImport: i0, template: "<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\r\n [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\r\n [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\r\n [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\r\n [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\r\n (valueChange)=\"valueChange.emit($event)\"\r\n (hoverChange)=\"onHoverChange($event)\">\r\n <ng-container additionalButtons>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\r\n </button>\r\n\r\n </ng-container>\r\n</spa-select-common>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
7852
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectComponent, isStandalone: false, selector: "spa-select", inputs: { detailsConfig: "detailsConfig" }, usesInheritance: true, ngImport: i0, template: "<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\r\n [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\r\n [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\r\n [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\r\n [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\r\n (valueChange)=\"valueChange.emit($event)\"\r\n (hoverChange)=\"onHoverChange($event)\">\r\n <ng-container additionalButtons>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\r\n </button>\r\n\r\n </ng-container>\r\n</spa-select-common>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SelectCommonComponent, selector: "spa-select-common", inputs: ["width", "readonly", "required", "defaultFirstValue", "readonlyMode", "hint", "placeholder", "display", "value", "options", "masterOptions", "masterField", "optionValue", "optionDisplay", "optionDisplayExtra", "nullable", "infoMessage", "copyContent", "loadAction", "loadIDField", "field", "data"], outputs: ["valueChange", "hoverChange"] }] }); }
|
|
7839
7853
|
}
|
|
7840
7854
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectComponent, decorators: [{
|
|
7841
7855
|
type: Component,
|
|
@@ -7896,7 +7910,7 @@ class FilterComponent {
|
|
|
7896
7910
|
this.applyFilter(this._filterText);
|
|
7897
7911
|
}
|
|
7898
7912
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7899
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: FilterComponent, isStandalone: false, selector: "spa-filter", inputs: { flatButtons: "flatButtons", showText: "showText", showButton: "showButton", smallScreen: "smallScreen", data: "data" }, outputs: { refreshClick: "refreshClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Changed: Added flex container div to align filter textbox and button -->\r\n<div class=\"filter-container\">\r\n <mat-form-field *ngIf=\"showText\" [ngClass]=\"{'filter-compact': smallScreen}\"> <!-- Changed: Apply compact class on small screens -->\r\n <mat-label>Filter</mat-label>\r\n <input id=\"txtFilter\" matInput [(ngModel)]=\"_filterText\" (keyup)=\"keyUp($event)\" placeholder=\"Enter Filter text\" autocomplete=\"off\">\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"_filterText\" (click)=\"clear()\" matTooltip=\"Clear\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: black;\">close</mat-icon>\r\n </button>\r\n\r\n </div>\r\n </mat-form-field>\r\n\r\n <!-- <button *ngIf=\"showButton && !flatButtons\" id=\"btnFilter\" mat-mini-fab color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\" style=\"margin-right:1em;margin-top:5px\">\r\n <mat-icon class=\"refreshIcon\">cached</mat-icon>\r\n </button> -->\r\n\r\n <!-- Changed: Removed inline margin-top style as alignment is now handled by flex container -->\r\n <button *ngIf=\"showButton\" id=\"btnFilter\" mat-icon-button color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\">\r\n <mat-icon class=\"refreshIcon\">cached</mat-icon>\r\n </button>\r\n</div>\r\n", styles: [".filter-container{display:flex;align-items:center;gap:.25em}.filter-container mat-form-field{margin-bottom:0;flex:0 1 auto}.filter-container ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-container ::ng-deep .mat-mdc-text-field-wrapper{padding-bottom:0}.filter-container button{margin-top:0;align-self:center}.filter-compact{width:80px!important;min-width:80px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4$2.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: "directive", type:
|
|
7913
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: FilterComponent, isStandalone: false, selector: "spa-filter", inputs: { flatButtons: "flatButtons", showText: "showText", showButton: "showButton", smallScreen: "smallScreen", data: "data" }, outputs: { refreshClick: "refreshClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Changed: Added flex container div to align filter textbox and button -->\r\n<div class=\"filter-container\">\r\n <mat-form-field *ngIf=\"showText\" [ngClass]=\"{'filter-compact': smallScreen}\"> <!-- Changed: Apply compact class on small screens -->\r\n <mat-label>Filter</mat-label>\r\n <input id=\"txtFilter\" matInput [(ngModel)]=\"_filterText\" (keyup)=\"keyUp($event)\" placeholder=\"Enter Filter text\" autocomplete=\"off\">\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"_filterText\" (click)=\"clear()\" matTooltip=\"Clear\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: black;\">close</mat-icon>\r\n </button>\r\n\r\n </div>\r\n </mat-form-field>\r\n\r\n <!-- <button *ngIf=\"showButton && !flatButtons\" id=\"btnFilter\" mat-mini-fab color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\" style=\"margin-right:1em;margin-top:5px\">\r\n <mat-icon class=\"refreshIcon\">cached</mat-icon>\r\n </button> -->\r\n\r\n <!-- Changed: Removed inline margin-top style as alignment is now handled by flex container -->\r\n <button *ngIf=\"showButton\" id=\"btnFilter\" mat-icon-button color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\">\r\n <mat-icon class=\"refreshIcon\">cached</mat-icon>\r\n </button>\r\n</div>\r\n", styles: [".filter-container{display:flex;align-items:center;gap:.25em}.filter-container mat-form-field{margin-bottom:0;flex:0 1 auto}.filter-container ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-container ::ng-deep .mat-mdc-text-field-wrapper{padding-bottom:0}.filter-container button{margin-top:0;align-self:center}.filter-compact{width:80px!important;min-width:80px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4$2.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: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
7900
7914
|
}
|
|
7901
7915
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: FilterComponent, decorators: [{
|
|
7902
7916
|
type: Component,
|
|
@@ -8409,7 +8423,7 @@ class TextMultiComponent {
|
|
|
8409
8423
|
});
|
|
8410
8424
|
}
|
|
8411
8425
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TextMultiComponent, deps: [{ token: MessageService }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8412
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TextMultiComponent, isStandalone: false, selector: "spa-text-multi", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", strict: "strict", suffix: "suffix", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-form-field style=\"width: 100%;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-chip-grid #chipList>\r\n <mat-chip-row *ngFor=\"let value of values\" [removable]=\"!readonly\" (removed)=\"remove(value)\">\r\n {{getDisplayValue(value)}}\r\n <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\r\n </mat-chip-row>\r\n <input #textInput autocomplete=\"off\" [placeholder]=\"readonly ? '' : display\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"add($event)\" [formControl]=\"control\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\r\n </mat-chip-grid>\r\n\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"option\">\r\n {{option[optionDisplay]}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n\r\n <mat-error *ngIf=\"errorState\">{{hint}}</mat-error>\r\n <mat-hint *ngIf=\"hint && !errorState\">{{hint}}</mat-hint>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i7
|
|
8426
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TextMultiComponent, isStandalone: false, selector: "spa-text-multi", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", strict: "strict", suffix: "suffix", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-form-field style=\"width: 100%;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-chip-grid #chipList>\r\n <mat-chip-row *ngFor=\"let value of values\" [removable]=\"!readonly\" (removed)=\"remove(value)\">\r\n {{getDisplayValue(value)}}\r\n <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\r\n </mat-chip-row>\r\n <input #textInput autocomplete=\"off\" [placeholder]=\"readonly ? '' : display\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"add($event)\" [formControl]=\"control\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\r\n </mat-chip-grid>\r\n\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"option\">\r\n {{option[optionDisplay]}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n\r\n <mat-error *ngIf=\"errorState\">{{hint}}</mat-error>\r\n <mat-hint *ngIf=\"hint && !errorState\">{{hint}}</mat-hint>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i12.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] }); }
|
|
8413
8427
|
}
|
|
8414
8428
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TextMultiComponent, decorators: [{
|
|
8415
8429
|
type: Component,
|
|
@@ -8569,7 +8583,7 @@ class SelectMultiComponent {
|
|
|
8569
8583
|
});
|
|
8570
8584
|
}
|
|
8571
8585
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectMultiComponent, deps: [{ token: MessageService }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8572
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectMultiComponent, isStandalone: false, selector: "spa-select-multi", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", nullable: "nullable", placeholder: "placeholder", width: "width", suffix: "suffix", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, usesOnChanges: true, ngImport: i0, template: "<mat-form-field [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-select [formControl]=\"control\" [required]=\"required\" multiple [placeholder]=\"placeholder\" [compareWith]=\"compareWith\" (selectionChange)=\"selectionChange($event)\">\r\n <mat-option *ngIf=\"nullable\" [value]=\"null\">None</mat-option>\r\n <mat-option *ngFor=\"let option of options\" [value]=\"option[optionValue]\">\r\n {{option[optionDisplay]}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\">\r\n </spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7
|
|
8586
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectMultiComponent, isStandalone: false, selector: "spa-select-multi", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", nullable: "nullable", placeholder: "placeholder", width: "width", suffix: "suffix", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", hoverChange: "hoverChange" }, usesOnChanges: true, ngImport: i0, template: "<mat-form-field [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-select [formControl]=\"control\" [required]=\"required\" multiple [placeholder]=\"placeholder\" [compareWith]=\"compareWith\" (selectionChange)=\"selectionChange($event)\">\r\n <mat-option *ngIf=\"nullable\" [value]=\"null\">None</mat-option>\r\n <mat-option *ngFor=\"let option of options\" [value]=\"option[optionValue]\">\r\n {{option[optionDisplay]}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n <div matSuffix class=\"suffix-icons\">\r\n <button mat-icon-button *ngIf=\"loadAction && isHovered\" (click)=\"refresh($event)\" matTooltip=\"Refresh\" matTooltipPosition=\"above\">\r\n <mat-icon class=\"tinyIcon\" color=\"primary\">cached</mat-icon>\r\n </button>\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\">\r\n </spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7.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: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }] }); }
|
|
8573
8587
|
}
|
|
8574
8588
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectMultiComponent, decorators: [{
|
|
8575
8589
|
type: Component,
|
|
@@ -8651,7 +8665,7 @@ class OptionComponent {
|
|
|
8651
8665
|
}
|
|
8652
8666
|
}
|
|
8653
8667
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: OptionComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8654
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: OptionComponent, isStandalone: false, selector: "spa-option", inputs: { options: "options", optionValue: "optionValue", optionDisplay: "optionDisplay", readonly: "readonly", type: "type", value: "value", display: "display", show: "show", required: "required", infoMessage: "infoMessage", copyContent: "copyContent", suffix: "suffix", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", enterPress: "enterPress" }, ngImport: i0, template: "\r\n<div class=\"tin-row gap-0\" style=\"align-items: center;\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"margin-right: 2px;\" [(ngModel)]=\"show\" (change)=\"resetValue()\" labelPosition=\"after\" [disabled]=\"required\" >{{display}}</mat-checkbox>\r\n\r\n <ng-container *ngIf=\"show\" [ngSwitch]=\"type\">\r\n\r\n <spa-date class=\"opt\" *ngSwitchCase=\"'date'\" [display]=\"display\" width=\"120px\" [(value)]=\"value\" [display]=\"display\" (valueChange)=\"dateChanged($event)\" [infoMessage]=\"infoMessage\"\r\n ></spa-date>\r\n\r\n <spa-select-multi class=\"opt\" *ngSwitchCase=\"'select-multi'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-select-multi>\r\n\r\n <spa-text-multi class=\"opt\" *ngSwitchCase=\"'text-multi'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-text-multi>\r\n\r\n <spa-select-lite class=\"opt\" *ngSwitchCase=\"'select'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-select-lite>\r\n\r\n <spa-text-single class=\"opt\" *ngSwitchDefault [display]=\"display\" (enterPress)=\"enterPressed()\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [suffix]=\"suffix\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-text-single>\r\n\r\n </ng-container>\r\n\r\n <button mat-icon-button *ngIf=\"infoMessage && !show\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\r\n </button>\r\n\r\n</div>\r\n", styles: [".opt{margin-left:0;align-self:center}.opt ::ng-deep mat-form-field{margin-bottom:-1.25em}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
8668
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: OptionComponent, isStandalone: false, selector: "spa-option", inputs: { options: "options", optionValue: "optionValue", optionDisplay: "optionDisplay", readonly: "readonly", type: "type", value: "value", display: "display", show: "show", required: "required", infoMessage: "infoMessage", copyContent: "copyContent", suffix: "suffix", loadAction: "loadAction" }, outputs: { valueChange: "valueChange", enterPress: "enterPress" }, ngImport: i0, template: "\r\n<div class=\"tin-row gap-0\" style=\"align-items: center;\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"margin-right: 2px;\" [(ngModel)]=\"show\" (change)=\"resetValue()\" labelPosition=\"after\" [disabled]=\"required\" >{{display}}</mat-checkbox>\r\n\r\n <ng-container *ngIf=\"show\" [ngSwitch]=\"type\">\r\n\r\n <spa-date class=\"opt\" *ngSwitchCase=\"'date'\" [display]=\"display\" width=\"120px\" [(value)]=\"value\" [display]=\"display\" (valueChange)=\"dateChanged($event)\" [infoMessage]=\"infoMessage\"\r\n ></spa-date>\r\n\r\n <spa-select-multi class=\"opt\" *ngSwitchCase=\"'select-multi'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-select-multi>\r\n\r\n <spa-text-multi class=\"opt\" *ngSwitchCase=\"'text-multi'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-text-multi>\r\n\r\n <spa-select-lite class=\"opt\" *ngSwitchCase=\"'select'\" [display]=\"display\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-select-lite>\r\n\r\n <spa-text-single class=\"opt\" *ngSwitchDefault [display]=\"display\" (enterPress)=\"enterPressed()\" [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\r\n [suffix]=\"suffix\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\r\n ></spa-text-single>\r\n\r\n </ng-container>\r\n\r\n <button mat-icon-button *ngIf=\"infoMessage && !show\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\r\n <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\r\n </button>\r\n\r\n</div>\r\n", styles: [".opt{margin-left:0;align-self:center}.opt ::ng-deep mat-form-field{margin-bottom:-1.25em}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: TextSingleComponent, selector: "spa-text-single", inputs: ["appearance", "readonly", "hint", "display", "placeholder", "value", "width", "copyContent", "clearContent", "options", "optionDisplay", "optionValue", "loadAction", "required", "min", "max", "regex", "suffix", "infoMessage", "field", "data", "detailsConfig", "masterField"], outputs: ["valueChange", "leave", "enterPress"] }, { kind: "component", type: DateComponent, selector: "spa-date", inputs: ["required", "min", "max", "readonly", "hint", "value", "display", "placeholder", "width", "suffix", "infoMessage", "copyContent", "clearContent"], outputs: ["valueChange"] }, { kind: "component", type: SelectLiteComponent, selector: "spa-select-lite" }, { kind: "component", type: TextMultiComponent, selector: "spa-text-multi", inputs: ["display", "value", "readonly", "required", "hint", "strict", "suffix", "infoMessage", "copyContent", "clearContent", "options", "optionDisplay", "optionValue", "loadAction"], outputs: ["valueChange", "hoverChange"] }, { kind: "component", type: SelectMultiComponent, selector: "spa-select-multi", inputs: ["display", "value", "readonly", "required", "hint", "options", "optionDisplay", "optionValue", "infoMessage", "copyContent", "clearContent", "nullable", "placeholder", "width", "suffix", "loadAction"], outputs: ["valueChange", "hoverChange"] }] }); }
|
|
8655
8669
|
}
|
|
8656
8670
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: OptionComponent, decorators: [{
|
|
8657
8671
|
type: Component,
|
|
@@ -8703,6 +8717,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
8703
8717
|
}]
|
|
8704
8718
|
}] });
|
|
8705
8719
|
|
|
8720
|
+
// Changed: Compact callout plugin — projects labels strictly left/right to maximize pie vertical space
|
|
8721
|
+
const TileCalloutPlugin = {
|
|
8722
|
+
id: 'tileCallout',
|
|
8723
|
+
afterDraw: (chart) => {
|
|
8724
|
+
const { ctx, canvas } = chart;
|
|
8725
|
+
const meta = chart.getDatasetMeta(0);
|
|
8726
|
+
if (!meta?.data?.length)
|
|
8727
|
+
return;
|
|
8728
|
+
const dataset = chart.data.datasets[0];
|
|
8729
|
+
const total = dataset.data.reduce((a, b) => a + b, 0);
|
|
8730
|
+
if (total === 0)
|
|
8731
|
+
return;
|
|
8732
|
+
const labels = chart.data.labels || [];
|
|
8733
|
+
const colors = dataset.backgroundColor || [];
|
|
8734
|
+
// Changed: Reset clip region so we can draw in the padding area outside chartArea
|
|
8735
|
+
ctx.save();
|
|
8736
|
+
ctx.resetTransform();
|
|
8737
|
+
ctx.beginPath();
|
|
8738
|
+
ctx.rect(0, 0, canvas.width, canvas.height);
|
|
8739
|
+
ctx.clip();
|
|
8740
|
+
const dpr = window.devicePixelRatio || 1;
|
|
8741
|
+
ctx.scale(dpr, dpr);
|
|
8742
|
+
// Changed: Collect callout positions per side, then space them vertically to avoid overlap
|
|
8743
|
+
const leftItems = [];
|
|
8744
|
+
const rightItems = [];
|
|
8745
|
+
meta.data.forEach((arc, i) => {
|
|
8746
|
+
const value = dataset.data[i];
|
|
8747
|
+
const pct = Math.round((value / total) * 100);
|
|
8748
|
+
if (pct < 8)
|
|
8749
|
+
return; // Changed: Skip small segments for tile readability
|
|
8750
|
+
const midAngle = (arc.startAngle + arc.endAngle) / 2;
|
|
8751
|
+
const outerRadius = arc.outerRadius;
|
|
8752
|
+
const cx = arc.x;
|
|
8753
|
+
const cy = arc.y;
|
|
8754
|
+
// Changed: Edge point on arc circumference
|
|
8755
|
+
const edgeX = cx + Math.cos(midAngle) * outerRadius;
|
|
8756
|
+
const edgeY = cy + Math.sin(midAngle) * outerRadius;
|
|
8757
|
+
// Changed: Determine left/right side based on segment position
|
|
8758
|
+
const isRight = Math.cos(midAngle) >= 0;
|
|
8759
|
+
const color = Array.isArray(colors) ? colors[i % colors.length] : '#333';
|
|
8760
|
+
const item = { edgeX, edgeY, cx, cy, outerRadius, pct, label: labels[i] ? String(labels[i]) : '', color, isRight };
|
|
8761
|
+
if (isRight)
|
|
8762
|
+
rightItems.push(item);
|
|
8763
|
+
else
|
|
8764
|
+
leftItems.push(item);
|
|
8765
|
+
});
|
|
8766
|
+
// Changed: Sort items by edgeY so vertical spacing works top-to-bottom
|
|
8767
|
+
leftItems.sort((a, b) => a.edgeY - b.edgeY);
|
|
8768
|
+
rightItems.sort((a, b) => a.edgeY - b.edgeY);
|
|
8769
|
+
// Changed: Space labels vertically — minimum 12px apart (single row needs less gap)
|
|
8770
|
+
const spaceLabels = (items) => {
|
|
8771
|
+
const minGap = 12;
|
|
8772
|
+
for (let j = 1; j < items.length; j++) {
|
|
8773
|
+
if (items[j].edgeY - items[j - 1].edgeY < minGap) {
|
|
8774
|
+
items[j].edgeY = items[j - 1].edgeY + minGap;
|
|
8775
|
+
}
|
|
8776
|
+
}
|
|
8777
|
+
};
|
|
8778
|
+
spaceLabels(leftItems);
|
|
8779
|
+
spaceLabels(rightItems);
|
|
8780
|
+
// Changed: Get canvas logical width for margin calculations
|
|
8781
|
+
const cw = canvas.width / (window.devicePixelRatio || 1);
|
|
8782
|
+
// Changed: Draw callouts — label name and percentage on the SAME row, side by side
|
|
8783
|
+
const drawSide = (items) => {
|
|
8784
|
+
items.forEach((item) => {
|
|
8785
|
+
const { edgeX, edgeY, cx, outerRadius, pct, label, color, isRight } = item;
|
|
8786
|
+
// Changed: Connector endpoint near the pie edge
|
|
8787
|
+
const tailX = isRight ? cx + outerRadius + 10 : cx - outerRadius - 10;
|
|
8788
|
+
const tailY = edgeY;
|
|
8789
|
+
// Changed: Draw connector line from arc edge to label area
|
|
8790
|
+
ctx.beginPath();
|
|
8791
|
+
ctx.moveTo(edgeX, edgeY);
|
|
8792
|
+
ctx.lineTo(tailX, tailY);
|
|
8793
|
+
ctx.strokeStyle = '#bbb';
|
|
8794
|
+
ctx.lineWidth = 0.8;
|
|
8795
|
+
ctx.stroke();
|
|
8796
|
+
// Changed: Same row layout — percentage near pie, label name at the margin edge
|
|
8797
|
+
ctx.textBaseline = 'middle';
|
|
8798
|
+
const textX = tailX + (isRight ? 3 : -3);
|
|
8799
|
+
// Changed: Percentage closest to pie — bold, segment-colored
|
|
8800
|
+
ctx.font = 'bold 9px Arial';
|
|
8801
|
+
ctx.fillStyle = color;
|
|
8802
|
+
ctx.textAlign = isRight ? 'left' : 'right';
|
|
8803
|
+
ctx.fillText(pct + '%', textX, tailY);
|
|
8804
|
+
// Changed: Label name further from pie — muted, at the outer margin edge
|
|
8805
|
+
if (label) {
|
|
8806
|
+
ctx.font = '8px Arial';
|
|
8807
|
+
ctx.fillStyle = '#666';
|
|
8808
|
+
if (isRight) {
|
|
8809
|
+
const pctWidth = ctx.measureText(pct + '%').width;
|
|
8810
|
+
ctx.textAlign = 'left';
|
|
8811
|
+
ctx.fillText(label, textX + pctWidth + 3, tailY); // Changed: Right of percentage
|
|
8812
|
+
}
|
|
8813
|
+
else {
|
|
8814
|
+
const pctWidth = ctx.measureText(pct + '%').width;
|
|
8815
|
+
ctx.textAlign = 'right';
|
|
8816
|
+
ctx.fillText(label, textX - pctWidth - 3, tailY); // Changed: Left of percentage
|
|
8817
|
+
}
|
|
8818
|
+
}
|
|
8819
|
+
});
|
|
8820
|
+
};
|
|
8821
|
+
drawSide(leftItems);
|
|
8822
|
+
drawSide(rightItems);
|
|
8823
|
+
ctx.restore();
|
|
8824
|
+
}
|
|
8825
|
+
};
|
|
8706
8826
|
class TilesComponent {
|
|
8707
8827
|
constructor(dataService, messageService) {
|
|
8708
8828
|
this.dataService = dataService;
|
|
@@ -8711,21 +8831,6 @@ class TilesComponent {
|
|
|
8711
8831
|
this.tileClick = new EventEmitter();
|
|
8712
8832
|
this.tileUnClick = new EventEmitter();
|
|
8713
8833
|
this.selectedTile = "";
|
|
8714
|
-
// Changed: Added mini chart options — minimal sparkline with no axes, grid, or labels
|
|
8715
|
-
this.miniChartOptions = {
|
|
8716
|
-
responsive: true,
|
|
8717
|
-
maintainAspectRatio: false,
|
|
8718
|
-
plugins: { legend: { display: false }, tooltip: { enabled: false } },
|
|
8719
|
-
scales: { x: { display: false }, y: { display: false } },
|
|
8720
|
-
elements: { line: { tension: 0.4 }, point: { radius: 0 } }
|
|
8721
|
-
};
|
|
8722
|
-
// Changed: Added gauge chart options for doughnut mini charts
|
|
8723
|
-
this.miniGaugeOptions = {
|
|
8724
|
-
responsive: true,
|
|
8725
|
-
maintainAspectRatio: false,
|
|
8726
|
-
plugins: { legend: { display: false }, tooltip: { enabled: false } },
|
|
8727
|
-
cutout: '70%'
|
|
8728
|
-
};
|
|
8729
8834
|
}
|
|
8730
8835
|
ngOnInit() {
|
|
8731
8836
|
if (this.config) {
|
|
@@ -8788,53 +8893,169 @@ class TilesComponent {
|
|
|
8788
8893
|
}
|
|
8789
8894
|
return false;
|
|
8790
8895
|
}
|
|
8791
|
-
// Changed:
|
|
8896
|
+
// Changed: Returns true only when data[tile.name] is a displayable primitive and not already shown by the chart
|
|
8897
|
+
isTileValuePrimitive(tile) {
|
|
8898
|
+
if (tile.chart)
|
|
8899
|
+
return false; // Changed: Chart tiles display values via chart plugins (gauge center text, callouts), not as text below
|
|
8900
|
+
const val = this.data?.[tile.name];
|
|
8901
|
+
return val != null && typeof val !== 'object';
|
|
8902
|
+
}
|
|
8903
|
+
// Changed: Helper to check if tile chart has data to render — supports dynamic gauge values via dataField
|
|
8904
|
+
hasTileChartData(tile) {
|
|
8905
|
+
const chart = tile.chart;
|
|
8906
|
+
if (!chart)
|
|
8907
|
+
return false;
|
|
8908
|
+
if (chart.gaugeValue != null)
|
|
8909
|
+
return true;
|
|
8910
|
+
if (chart.data != null)
|
|
8911
|
+
return true;
|
|
8912
|
+
if (chart.dataField && this.data?.[chart.dataField] != null)
|
|
8913
|
+
return true; // Changed: Use != null to support zero values
|
|
8914
|
+
return false;
|
|
8915
|
+
}
|
|
8916
|
+
// Changed: Enhanced mini chart data builder — better colors, gradient fills, proper segment colors
|
|
8792
8917
|
getTileMiniChartData(tile) {
|
|
8793
8918
|
const chartConfig = tile.chart;
|
|
8794
8919
|
if (!chartConfig)
|
|
8795
8920
|
return { labels: [], datasets: [] };
|
|
8796
|
-
// Gauge mode
|
|
8797
|
-
|
|
8921
|
+
// Changed: Gauge mode — supports static gaugeValue OR dynamic value via dataField
|
|
8922
|
+
const gaugeVal = chartConfig.gaugeValue ?? (chartConfig.type === 'doughnut' && chartConfig.dataField ? this.data?.[chartConfig.dataField] : null);
|
|
8923
|
+
if (chartConfig.type === 'doughnut' && gaugeVal != null && typeof gaugeVal === 'number' && !chartConfig.data) {
|
|
8798
8924
|
return {
|
|
8799
8925
|
datasets: [{
|
|
8800
|
-
data: [
|
|
8801
|
-
backgroundColor: [chartConfig.gaugeColor ?? '#4acccd', '#
|
|
8802
|
-
borderWidth: 0
|
|
8926
|
+
data: [gaugeVal, 100 - gaugeVal],
|
|
8927
|
+
backgroundColor: [chartConfig.gaugeColor ?? '#4acccd', '#f0f0f0'],
|
|
8928
|
+
borderWidth: 0,
|
|
8929
|
+
hoverOffset: 4
|
|
8803
8930
|
}]
|
|
8804
8931
|
};
|
|
8805
8932
|
}
|
|
8806
|
-
//
|
|
8807
|
-
const chartData = this.data?.[chartConfig.dataField];
|
|
8933
|
+
// Changed: Get data from API response via dataField, or from inline data property
|
|
8934
|
+
const chartData = this.data?.[chartConfig.dataField] ?? chartConfig.data;
|
|
8808
8935
|
if (!chartData)
|
|
8809
8936
|
return { labels: [], datasets: [] };
|
|
8810
|
-
// If data is already Chart.js format (has datasets),
|
|
8811
|
-
if (chartData.datasets)
|
|
8937
|
+
// If data is already Chart.js format (has datasets), apply colors if needed
|
|
8938
|
+
if (chartData.datasets) {
|
|
8939
|
+
// Changed: Apply configured colors to datasets that lack backgroundColor
|
|
8940
|
+
if (chartConfig.colors?.length) {
|
|
8941
|
+
chartData.datasets.forEach((ds) => {
|
|
8942
|
+
if (!ds.backgroundColor)
|
|
8943
|
+
ds.backgroundColor = chartConfig.colors;
|
|
8944
|
+
});
|
|
8945
|
+
}
|
|
8812
8946
|
return chartData;
|
|
8813
|
-
|
|
8947
|
+
}
|
|
8948
|
+
// Changed: Plain array data — wrap with appropriate styling per chart type
|
|
8949
|
+
const color = chartConfig.color ?? '#4acccd';
|
|
8950
|
+
if (chartConfig.type === 'line') {
|
|
8951
|
+
return {
|
|
8952
|
+
labels: chartData.map((_, i) => ''),
|
|
8953
|
+
datasets: [{ data: chartData, borderColor: color, backgroundColor: color + '20', borderWidth: 2.5, fill: true, pointRadius: 0 }] // Changed: Gradient fill for sparklines
|
|
8954
|
+
};
|
|
8955
|
+
}
|
|
8956
|
+
if (chartConfig.type === 'bar') {
|
|
8957
|
+
return {
|
|
8958
|
+
labels: chartData.map((_, i) => ''),
|
|
8959
|
+
datasets: [{ data: chartData, backgroundColor: chartConfig.colors ?? [color], borderRadius: 3, borderWidth: 0 }] // Changed: Rounded bars, no border
|
|
8960
|
+
};
|
|
8961
|
+
}
|
|
8962
|
+
// Changed: Pie/doughnut plain array
|
|
8814
8963
|
return {
|
|
8815
|
-
labels: chartData.map((_, i) =>
|
|
8816
|
-
datasets: [{
|
|
8817
|
-
data: chartData,
|
|
8818
|
-
borderColor: chartConfig.color ?? '#4acccd',
|
|
8819
|
-
backgroundColor: chartConfig.type === 'bar' ? (chartConfig.color ?? '#4acccd') : 'transparent',
|
|
8820
|
-
borderWidth: 2,
|
|
8821
|
-
fill: false,
|
|
8822
|
-
pointRadius: 0
|
|
8823
|
-
}]
|
|
8964
|
+
labels: chartData.map((_, i) => `Segment ${i + 1}`),
|
|
8965
|
+
datasets: [{ data: chartData, backgroundColor: chartConfig.colors ?? [color, '#e8e8e8'], borderWidth: 1, hoverOffset: 4 }]
|
|
8824
8966
|
};
|
|
8825
8967
|
}
|
|
8826
|
-
// Changed:
|
|
8968
|
+
// Changed: Enhanced mini chart options for sparklines — clean, no axes
|
|
8827
8969
|
getMiniChartOptions(tile) {
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8970
|
+
const chart = tile.chart;
|
|
8971
|
+
if (!chart)
|
|
8972
|
+
return {};
|
|
8973
|
+
if (chart.type === 'doughnut') {
|
|
8974
|
+
// Changed: Detect gauge mode — static gaugeValue OR dynamic value via dataField
|
|
8975
|
+
const gaugeVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);
|
|
8976
|
+
const isGauge = gaugeVal != null && typeof gaugeVal === 'number' && !chart.data;
|
|
8977
|
+
return {
|
|
8978
|
+
responsive: true,
|
|
8979
|
+
maintainAspectRatio: false,
|
|
8980
|
+
plugins: {
|
|
8981
|
+
legend: { display: false },
|
|
8982
|
+
tooltip: { enabled: !isGauge },
|
|
8983
|
+
datalabels: { display: false }
|
|
8984
|
+
},
|
|
8985
|
+
cutout: isGauge ? '70%' : '45%',
|
|
8986
|
+
layout: { padding: isGauge ? 4 : { top: 4, bottom: 4, left: 55, right: 55 } }
|
|
8987
|
+
};
|
|
8988
|
+
}
|
|
8989
|
+
if (chart.type === 'pie') {
|
|
8990
|
+
return {
|
|
8991
|
+
responsive: true,
|
|
8992
|
+
maintainAspectRatio: false,
|
|
8993
|
+
plugins: {
|
|
8994
|
+
legend: { display: false },
|
|
8995
|
+
tooltip: { enabled: true, backgroundColor: 'rgba(0,0,0,0.8)', padding: 8, cornerRadius: 4 },
|
|
8996
|
+
datalabels: { display: false }
|
|
8997
|
+
},
|
|
8998
|
+
layout: { padding: { top: 4, bottom: 4, left: 55, right: 55 } } // Changed: Minimal top/bottom — callouts project left/right only
|
|
8999
|
+
};
|
|
9000
|
+
}
|
|
9001
|
+
if (chart.type === 'bar') {
|
|
9002
|
+
return {
|
|
9003
|
+
responsive: true,
|
|
9004
|
+
maintainAspectRatio: false,
|
|
9005
|
+
plugins: { legend: { display: false }, tooltip: { enabled: false }, datalabels: { display: false } },
|
|
9006
|
+
scales: { x: { display: false }, y: { display: false } },
|
|
9007
|
+
elements: { bar: { borderRadius: 2 } } // Changed: Subtle rounded bars
|
|
9008
|
+
};
|
|
9009
|
+
}
|
|
9010
|
+
// Changed: Line sparkline — smooth, no axes, gradient fill
|
|
9011
|
+
return {
|
|
9012
|
+
responsive: true,
|
|
9013
|
+
maintainAspectRatio: false,
|
|
9014
|
+
plugins: { legend: { display: false }, tooltip: { enabled: false }, datalabels: { display: false } },
|
|
9015
|
+
scales: { x: { display: false }, y: { display: false } },
|
|
9016
|
+
elements: { line: { tension: 0.4, borderWidth: 2.5 }, point: { radius: 0 } }
|
|
9017
|
+
};
|
|
9018
|
+
}
|
|
9019
|
+
// Changed: Returns plugins array for tile mini charts — callout labels for pie/doughnut, center text for gauges
|
|
9020
|
+
getTileChartPlugins(tile) {
|
|
9021
|
+
const chart = tile.chart;
|
|
9022
|
+
if (!chart)
|
|
9023
|
+
return [];
|
|
9024
|
+
// Changed: Detect gauge mode — static gaugeValue OR dynamic value via dataField
|
|
9025
|
+
const gaugeVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);
|
|
9026
|
+
const isGauge = chart.type === 'doughnut' && gaugeVal != null && typeof gaugeVal === 'number' && !chart.data;
|
|
9027
|
+
// Changed: Add compact callout plugin for non-gauge pie/doughnut tiles
|
|
9028
|
+
if (chart.type === 'pie' || (chart.type === 'doughnut' && !isGauge)) {
|
|
9029
|
+
return [TileCalloutPlugin];
|
|
9030
|
+
}
|
|
9031
|
+
// Changed: Gauge center text — supports both static and dynamic gauge values
|
|
9032
|
+
if (isGauge) {
|
|
9033
|
+
return [{
|
|
9034
|
+
id: 'tileCenterText',
|
|
9035
|
+
afterDraw: (chartInstance) => {
|
|
9036
|
+
const ctx = chartInstance.ctx;
|
|
9037
|
+
const { width, height } = chartInstance;
|
|
9038
|
+
ctx.save();
|
|
9039
|
+
// Changed: Re-read dynamic gauge value from data on each draw cycle
|
|
9040
|
+
const currentVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);
|
|
9041
|
+
const text = (currentVal ?? 0) + '%';
|
|
9042
|
+
ctx.font = 'bold 18px Arial';
|
|
9043
|
+
ctx.fillStyle = chart.gaugeColor ?? '#4acccd';
|
|
9044
|
+
ctx.textAlign = 'center';
|
|
9045
|
+
ctx.textBaseline = 'middle';
|
|
9046
|
+
ctx.fillText(text, width / 2, height / 2);
|
|
9047
|
+
ctx.restore();
|
|
9048
|
+
}
|
|
9049
|
+
}];
|
|
9050
|
+
}
|
|
9051
|
+
return [];
|
|
8831
9052
|
}
|
|
8832
9053
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TilesComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8833
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TilesComponent, isStandalone: false, selector: "spa-tiles", inputs: { config: "config", lastSearch: "lastSearch", data: "data", reload: "reload" }, outputs: { tileActionSelected: "tileActionSelected", tileClick: "tileClick", tileUnClick: "tileUnClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Changed: align-items-
|
|
9054
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TilesComponent, isStandalone: false, selector: "spa-tiles", inputs: { config: "config", lastSearch: "lastSearch", data: "data", reload: "reload" }, outputs: { tileActionSelected: "tileActionSelected", tileClick: "tileClick", tileUnClick: "tileUnClick" }, usesOnChanges: true, ngImport: i0, template: "<!-- Changed: align-items-center vertically centers tiles of different heights for clean alignment -->\r\n<div class=\"d-flex row align-items-center justify-content-between\">\r\n <ng-container *ngFor=\"let tile of tiles\">\r\n <mat-card *ngIf=\"!isHidden(tile)\" class=\"col\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\r\n\r\n <!-- Changed: Chart-style tile \u2014 header, prominent chart, optional value, footer -->\r\n <ng-container *ngIf=\"tile.chart; else standardTile\">\r\n <!-- Changed: Header with tile name \u2014 left-aligned for better hierarchy -->\r\n <div class=\"tile-chart-header\">\r\n <span>{{tile.alias ?? tile.name | camelToWords}}</span>\r\n </div>\r\n\r\n <!-- Changed: Chart fills tile \u2014 uses helper method for reliable data detection -->\r\n <div class=\"tile-chart\" *ngIf=\"hasTileChartData(tile)\" [style.height.px]=\"tile.chart.height ?? 120\">\r\n <canvas baseChart\r\n [type]=\"tile.chart.type\"\r\n [data]=\"getTileMiniChartData(tile)\"\r\n [options]=\"getMiniChartOptions(tile)\"\r\n [plugins]=\"getTileChartPlugins(tile)\">\r\n </canvas>\r\n </div>\r\n\r\n <!-- Changed: Optional value display below chart \u2014 only show primitive values, skip chart data objects -->\r\n <div class=\"tile-chart-value\" *ngIf=\"tile.name && isTileValuePrimitive(tile)\">\r\n <span class=\"tile-chart-value-text\" [style.color]=\"tile.color\">{{tile.prefix ?? ''}}{{data?.[tile.name]}}<span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span></span>\r\n </div>\r\n\r\n <!-- Changed: Footer with divider for chart tiles -->\r\n <div class=\"tile-footer\" *ngIf=\"tile.footer || tile.info\">\r\n <mat-divider></mat-divider>\r\n <div class=\"d-flex align-items-center\" style=\"gap: 4px; color: #9a9a9a; font-size: 12px; margin-top: 6px;\">\r\n <mat-icon *ngIf=\"tile.footerIcon\" style=\"font-size: 16px; width: 16px; height: 16px;\">{{tile.footerIcon}}</mat-icon>\r\n <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" style=\"font-size: 16px; width: 16px; height: 16px; color: steelblue;\">info</mat-icon>\r\n <span>{{tile.footer ?? tile.info}}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Changed: Standard tile \u2014 Paper Dashboard style: icon left, label+value right, optional footer -->\r\n <ng-template #standardTile>\r\n <!-- Changed: Icon-style tile \u2014 icon left, label top-right, large value below -->\r\n <ng-container *ngIf=\"tile.icon; else basicTile\">\r\n <div class=\"tile-icon-row\">\r\n <div class=\"tile-icon-wrap\" [style.color]=\"tile.color ?? '#2196f3'\">\r\n <mat-icon>{{tile.icon}}</mat-icon>\r\n </div>\r\n <div class=\"tile-icon-content\">\r\n <div class=\"tile-icon-label\">{{tile.alias ?? tile.name | camelToWords}}</div>\r\n <div class=\"tile-icon-value\" [style.color]=\"tile.color\">\r\n <span *ngIf=\"tile.prefix\">{{tile.prefix}}</span>{{data?.[tile.name] ?? 0}}<span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span>\r\n <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Changed: Footer with divider \u2014 info tooltip or custom footer text -->\r\n <div class=\"tile-icon-footer\" *ngIf=\"tile.info || tile.footer\">\r\n <mat-divider></mat-divider>\r\n <div class=\"tile-icon-footer-content\">\r\n <mat-icon *ngIf=\"tile.footerIcon\" class=\"tile-icon-footer-icon\">{{tile.footerIcon}}</mat-icon>\r\n <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" class=\"tile-icon-footer-icon\" style=\"color: steelblue;\">info</mat-icon>\r\n <span>{{tile.footer ?? tile.info}}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Basic tile fallback \u2014 centered number display (no icon) -->\r\n <ng-template #basicTile>\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div style=\"text-align: center;font-size: 30px;\">\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> \r\n <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tile.color }\">{{data?.[tile.name] ?? 0}}</mat-label> \r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\r\n <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\r\n </div>\r\n </div>\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\r\n <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\r\n <mat-icon *ngIf=\"tile.info\" [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-template>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".card{min-width:200px;max-width:200px;display:flex;flex-direction:column;align-items:center;padding:5px 10px}.tiles{gap:1;row-gap:5px}.col{transition:all .3s ease;cursor:pointer}.selected-tile{background-color:#e0e0e0;box-shadow:0 4px 8px #0003;transform:translateY(-2px);border:2px solid #3f51b5}.selected-tile mat-label{font-weight:700}.col:hover{background-color:#f5f5f5}.selected-tile:hover{background-color:#e0e0e0}.tile-chart-header{display:flex;justify-content:flex-start;font-size:11px;font-weight:500;color:#999;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px}.tile-chart{width:100%;position:relative;margin-top:4px;display:flex;align-items:center;justify-content:center}.tile-chart canvas{width:100%!important;height:100%!important;max-height:inherit}.tile-chart-value{text-align:center;margin-top:6px}.tile-chart-value-text{font-size:22px;font-weight:600;letter-spacing:-.5px}.tile-badge{display:inline-block;font-size:12px;font-weight:500;color:#fff;padding:2px 8px;border-radius:12px;vertical-align:middle;margin-left:4px}.tile-footer{margin-top:8px}.tile-icon-row{display:flex;align-items:flex-start;gap:12px;padding:4px 0}.tile-icon-wrap{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:48px;height:48px}.tile-icon-wrap mat-icon{font-size:36px;width:36px;height:36px;opacity:.85}.tile-icon-content{flex:1;text-align:right;min-width:0}.tile-icon-label{font-size:12px;color:#999;text-transform:uppercase;letter-spacing:.3px;line-height:1.4}.tile-icon-value{font-size:26px;font-weight:600;line-height:1.2;letter-spacing:-.5px}.tile-icon-footer{margin-top:8px}.tile-icon-footer mat-divider{margin-bottom:6px}.tile-icon-footer-content{display:flex;align-items:center;gap:4px;font-size:12px;color:#999}.tile-icon-footer-icon{font-size:16px;width:16px;height:16px;color:#bbb}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i14.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i9.BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
8834
9055
|
}
|
|
8835
9056
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TilesComponent, decorators: [{
|
|
8836
9057
|
type: Component,
|
|
8837
|
-
args: [{ selector: 'spa-tiles', standalone: false, template: "<!-- Changed: align-items-
|
|
9058
|
+
args: [{ selector: 'spa-tiles', standalone: false, template: "<!-- Changed: align-items-center vertically centers tiles of different heights for clean alignment -->\r\n<div class=\"d-flex row align-items-center justify-content-between\">\r\n <ng-container *ngFor=\"let tile of tiles\">\r\n <mat-card *ngIf=\"!isHidden(tile)\" class=\"col\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\r\n\r\n <!-- Changed: Chart-style tile \u2014 header, prominent chart, optional value, footer -->\r\n <ng-container *ngIf=\"tile.chart; else standardTile\">\r\n <!-- Changed: Header with tile name \u2014 left-aligned for better hierarchy -->\r\n <div class=\"tile-chart-header\">\r\n <span>{{tile.alias ?? tile.name | camelToWords}}</span>\r\n </div>\r\n\r\n <!-- Changed: Chart fills tile \u2014 uses helper method for reliable data detection -->\r\n <div class=\"tile-chart\" *ngIf=\"hasTileChartData(tile)\" [style.height.px]=\"tile.chart.height ?? 120\">\r\n <canvas baseChart\r\n [type]=\"tile.chart.type\"\r\n [data]=\"getTileMiniChartData(tile)\"\r\n [options]=\"getMiniChartOptions(tile)\"\r\n [plugins]=\"getTileChartPlugins(tile)\">\r\n </canvas>\r\n </div>\r\n\r\n <!-- Changed: Optional value display below chart \u2014 only show primitive values, skip chart data objects -->\r\n <div class=\"tile-chart-value\" *ngIf=\"tile.name && isTileValuePrimitive(tile)\">\r\n <span class=\"tile-chart-value-text\" [style.color]=\"tile.color\">{{tile.prefix ?? ''}}{{data?.[tile.name]}}<span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span></span>\r\n </div>\r\n\r\n <!-- Changed: Footer with divider for chart tiles -->\r\n <div class=\"tile-footer\" *ngIf=\"tile.footer || tile.info\">\r\n <mat-divider></mat-divider>\r\n <div class=\"d-flex align-items-center\" style=\"gap: 4px; color: #9a9a9a; font-size: 12px; margin-top: 6px;\">\r\n <mat-icon *ngIf=\"tile.footerIcon\" style=\"font-size: 16px; width: 16px; height: 16px;\">{{tile.footerIcon}}</mat-icon>\r\n <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" style=\"font-size: 16px; width: 16px; height: 16px; color: steelblue;\">info</mat-icon>\r\n <span>{{tile.footer ?? tile.info}}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Changed: Standard tile \u2014 Paper Dashboard style: icon left, label+value right, optional footer -->\r\n <ng-template #standardTile>\r\n <!-- Changed: Icon-style tile \u2014 icon left, label top-right, large value below -->\r\n <ng-container *ngIf=\"tile.icon; else basicTile\">\r\n <div class=\"tile-icon-row\">\r\n <div class=\"tile-icon-wrap\" [style.color]=\"tile.color ?? '#2196f3'\">\r\n <mat-icon>{{tile.icon}}</mat-icon>\r\n </div>\r\n <div class=\"tile-icon-content\">\r\n <div class=\"tile-icon-label\">{{tile.alias ?? tile.name | camelToWords}}</div>\r\n <div class=\"tile-icon-value\" [style.color]=\"tile.color\">\r\n <span *ngIf=\"tile.prefix\">{{tile.prefix}}</span>{{data?.[tile.name] ?? 0}}<span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span>\r\n <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Changed: Footer with divider \u2014 info tooltip or custom footer text -->\r\n <div class=\"tile-icon-footer\" *ngIf=\"tile.info || tile.footer\">\r\n <mat-divider></mat-divider>\r\n <div class=\"tile-icon-footer-content\">\r\n <mat-icon *ngIf=\"tile.footerIcon\" class=\"tile-icon-footer-icon\">{{tile.footerIcon}}</mat-icon>\r\n <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" class=\"tile-icon-footer-icon\" style=\"color: steelblue;\">info</mat-icon>\r\n <span>{{tile.footer ?? tile.info}}</span>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Basic tile fallback \u2014 centered number display (no icon) -->\r\n <ng-template #basicTile>\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div style=\"text-align: center;font-size: 30px;\">\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> \r\n <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tile.color }\">{{data?.[tile.name] ?? 0}}</mat-label> \r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\r\n <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\r\n </div>\r\n </div>\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\r\n <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\r\n <mat-icon *ngIf=\"tile.info\" [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-template>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".card{min-width:200px;max-width:200px;display:flex;flex-direction:column;align-items:center;padding:5px 10px}.tiles{gap:1;row-gap:5px}.col{transition:all .3s ease;cursor:pointer}.selected-tile{background-color:#e0e0e0;box-shadow:0 4px 8px #0003;transform:translateY(-2px);border:2px solid #3f51b5}.selected-tile mat-label{font-weight:700}.col:hover{background-color:#f5f5f5}.selected-tile:hover{background-color:#e0e0e0}.tile-chart-header{display:flex;justify-content:flex-start;font-size:11px;font-weight:500;color:#999;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px}.tile-chart{width:100%;position:relative;margin-top:4px;display:flex;align-items:center;justify-content:center}.tile-chart canvas{width:100%!important;height:100%!important;max-height:inherit}.tile-chart-value{text-align:center;margin-top:6px}.tile-chart-value-text{font-size:22px;font-weight:600;letter-spacing:-.5px}.tile-badge{display:inline-block;font-size:12px;font-weight:500;color:#fff;padding:2px 8px;border-radius:12px;vertical-align:middle;margin-left:4px}.tile-footer{margin-top:8px}.tile-icon-row{display:flex;align-items:flex-start;gap:12px;padding:4px 0}.tile-icon-wrap{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:48px;height:48px}.tile-icon-wrap mat-icon{font-size:36px;width:36px;height:36px;opacity:.85}.tile-icon-content{flex:1;text-align:right;min-width:0}.tile-icon-label{font-size:12px;color:#999;text-transform:uppercase;letter-spacing:.3px;line-height:1.4}.tile-icon-value{font-size:26px;font-weight:600;line-height:1.2;letter-spacing:-.5px}.tile-icon-footer{margin-top:8px}.tile-icon-footer mat-divider{margin-bottom:6px}.tile-icon-footer-content{display:flex;align-items:center;gap:4px;font-size:12px;color:#999}.tile-icon-footer-icon{font-size:16px;width:16px;height:16px;color:#bbb}\n"] }]
|
|
8838
9059
|
}], ctorParameters: () => [{ type: DataServiceLib }, { type: MessageService }], propDecorators: { config: [{
|
|
8839
9060
|
type: Input
|
|
8840
9061
|
}], tileActionSelected: [{
|
|
@@ -9031,7 +9252,7 @@ class AttachComponent {
|
|
|
9031
9252
|
this.filesChange.emit(this.files);
|
|
9032
9253
|
}
|
|
9033
9254
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AttachComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9034
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: AttachComponent, isStandalone: false, selector: "spa-attach", inputs: { fileOptions: "fileOptions", message: "message", files: "files", enableUpload: "enableUpload" }, outputs: { filesChange: "filesChange", upload: "upload" }, ngImport: i0, template: "<div class=\"tin-input-row\" style=\"width: 100%;\">\r\n\r\n <div class=\"col\">\r\n <div class=\"container\" appDnd (fileDropped)=\"onFileDropped($event)\">\r\n <input type=\"file\" #fileDropRef id=\"fileDropRef\" multiple (change)=\"fileBrowseHandler($event)\" />\r\n <h4>{{message}}</h4>\r\n\r\n <label for=\"fileDropRef\">Click to Browse</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col\">\r\n <div class=\"files-list \">\r\n <div class=\"single-file \" style=\"width: 100%;\" *ngFor=\"let file of files; let i = index\">\r\n\r\n <div class=\"tin-input-row info\" >\r\n <h4 class=\"name\">\r\n {{ file?.name }}\r\n </h4>\r\n <p class=\"size\">\r\n {{ formatBytes(file?.size, 2) }}\r\n </p>\r\n </div>\r\n\r\n <div class=\"delete\" (click)=\"deleteFile(i)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"18\" viewBox=\"0 0 14 18\">\r\n <path fill=\"#B1B1B1\" fill-rule=\"nonzero\"\r\n d=\"M1 16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v10zm3.17-7.83a.996.996 0 0 1 1.41 0L7 9.59l1.42-1.42a.996.996 0 1 1 1.41 1.41L8.41 11l1.42 1.42a.996.996 0 1 1-1.41 1.41L7 12.41l-1.42 1.42a.996.996 0 1 1-1.41-1.41L5.59 11 4.17 9.58a.996.996 0 0 1 0-1.41zM10.5 1L9.79.29C9.61.11 9.35 0 9.09 0H4.91c-.26 0-.52.11-.7.29L3.5 1H1c-.55 0-1 .45-1 1s.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1h-2.5z\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"files.length > 0 && enableUpload\" class=\"tin-input-row d-flex justify-content-center\" style=\"width: 100%;\" >\r\n <button mat-button color=\"primary\" (click)=\"uploaded()\" matTooltip=\"Upload New Documents\" matTooltipPosition=\"above\" ><mat-icon>file_upload</mat-icon> Upload</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: [".container{width:100%;height:100px;padding-top:5px;text-align:center;border:dashed 2px #2a7b94;position:relative;margin:0 auto}.container input{opacity:0;position:absolute;z-index:2;width:100%;height:100%;top:0;left:0}.container label{color:#fff;width:183px;height:44px;border-radius:21.5px;background-color:#db202f;padding:8px 16px}.container h3{font-size:20px;font-weight:600;color:#38424c}.fileover{animation:shake 1s;animation-iteration-count:infinite}.files-list{margin-top:1.5rem}.files-list .single-file{padding:.5rem;justify-content:space-between;align-items:center;border:dashed 1px #1c824d;margin-bottom:1rem;margin-right:1rem;display:flex;flex-grow:1}.files-list .single-file .delete{display:flex;margin-left:.5rem;cursor:pointer;align-self:flex-end}.files-list .single-file .name{font-size:14px;font-weight:500;color:#353f4a;margin:0}.files-list .single-file .size{font-size:12px;font-weight:500;color:#a4a4a4;margin:0;margin-left:1rem}.files-list .single-file .info{width:100%}@keyframes shake{0%{transform:translate(1px,1px) rotate(0)}10%{transform:translate(-1px,-2px) rotate(-1deg)}20%{transform:translate(-3px) rotate(1deg)}30%{transform:translate(3px,2px) rotate(0)}40%{transform:translate(1px,-1px) rotate(1deg)}50%{transform:translate(-1px,2px) rotate(-1deg)}60%{transform:translate(-3px,1px) rotate(0)}70%{transform:translate(3px,1px) rotate(-1deg)}80%{transform:translate(-1px,-1px) rotate(1deg)}90%{transform:translate(1px,2px) rotate(0)}to{transform:translate(1px,-2px) rotate(-1deg)}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.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: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
9255
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: AttachComponent, isStandalone: false, selector: "spa-attach", inputs: { fileOptions: "fileOptions", message: "message", files: "files", enableUpload: "enableUpload" }, outputs: { filesChange: "filesChange", upload: "upload" }, ngImport: i0, template: "<div class=\"tin-input-row\" style=\"width: 100%;\">\r\n\r\n <div class=\"col\">\r\n <div class=\"container\" appDnd (fileDropped)=\"onFileDropped($event)\">\r\n <input type=\"file\" #fileDropRef id=\"fileDropRef\" multiple (change)=\"fileBrowseHandler($event)\" />\r\n <h4>{{message}}</h4>\r\n\r\n <label for=\"fileDropRef\">Click to Browse</label>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col\">\r\n <div class=\"files-list \">\r\n <div class=\"single-file \" style=\"width: 100%;\" *ngFor=\"let file of files; let i = index\">\r\n\r\n <div class=\"tin-input-row info\" >\r\n <h4 class=\"name\">\r\n {{ file?.name }}\r\n </h4>\r\n <p class=\"size\">\r\n {{ formatBytes(file?.size, 2) }}\r\n </p>\r\n </div>\r\n\r\n <div class=\"delete\" (click)=\"deleteFile(i)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"18\" viewBox=\"0 0 14 18\">\r\n <path fill=\"#B1B1B1\" fill-rule=\"nonzero\"\r\n d=\"M1 16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v10zm3.17-7.83a.996.996 0 0 1 1.41 0L7 9.59l1.42-1.42a.996.996 0 1 1 1.41 1.41L8.41 11l1.42 1.42a.996.996 0 1 1-1.41 1.41L7 12.41l-1.42 1.42a.996.996 0 1 1-1.41-1.41L5.59 11 4.17 9.58a.996.996 0 0 1 0-1.41zM10.5 1L9.79.29C9.61.11 9.35 0 9.09 0H4.91c-.26 0-.52.11-.7.29L3.5 1H1c-.55 0-1 .45-1 1s.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1h-2.5z\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"files.length > 0 && enableUpload\" class=\"tin-input-row d-flex justify-content-center\" style=\"width: 100%;\" >\r\n <button mat-button color=\"primary\" (click)=\"uploaded()\" matTooltip=\"Upload New Documents\" matTooltipPosition=\"above\" ><mat-icon>file_upload</mat-icon> Upload</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: [".container{width:100%;height:100px;padding-top:5px;text-align:center;border:dashed 2px #2a7b94;position:relative;margin:0 auto}.container input{opacity:0;position:absolute;z-index:2;width:100%;height:100%;top:0;left:0}.container label{color:#fff;width:183px;height:44px;border-radius:21.5px;background-color:#db202f;padding:8px 16px}.container h3{font-size:20px;font-weight:600;color:#38424c}.fileover{animation:shake 1s;animation-iteration-count:infinite}.files-list{margin-top:1.5rem}.files-list .single-file{padding:.5rem;justify-content:space-between;align-items:center;border:dashed 1px #1c824d;margin-bottom:1rem;margin-right:1rem;display:flex;flex-grow:1}.files-list .single-file .delete{display:flex;margin-left:.5rem;cursor:pointer;align-self:flex-end}.files-list .single-file .name{font-size:14px;font-weight:500;color:#353f4a;margin:0}.files-list .single-file .size{font-size:12px;font-weight:500;color:#a4a4a4;margin:0;margin-left:1rem}.files-list .single-file .info{width:100%}@keyframes shake{0%{transform:translate(1px,1px) rotate(0)}10%{transform:translate(-1px,-2px) rotate(-1deg)}20%{transform:translate(-3px) rotate(1deg)}30%{transform:translate(3px,2px) rotate(0)}40%{transform:translate(1px,-1px) rotate(1deg)}50%{transform:translate(-1px,2px) rotate(-1deg)}60%{transform:translate(-3px,1px) rotate(0)}70%{transform:translate(3px,1px) rotate(-1deg)}80%{transform:translate(-1px,-1px) rotate(1deg)}90%{transform:translate(1px,2px) rotate(0)}to{transform:translate(1px,-2px) rotate(-1deg)}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.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: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
9035
9256
|
}
|
|
9036
9257
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AttachComponent, decorators: [{
|
|
9037
9258
|
type: Component,
|
|
@@ -9315,7 +9536,7 @@ class NavMenuComponent {
|
|
|
9315
9536
|
return !this.isMiniSidebar || this.isMiniHovered;
|
|
9316
9537
|
}
|
|
9317
9538
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: NavMenuComponent, deps: [{ token: i1$2.Router }, { token: AuthService }, { token: StorageService }, { token: NotificationsService }, { token: i1$3.BreakpointObserver }, { token: DataServiceLib }, { token: i1.MatDialog }, { token: SubscriptionService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9318
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: NavMenuComponent, isStandalone: false, selector: "spa-nav-menu", inputs: { appConfig: "appConfig", footer: "footer" }, host: { listeners: { "window:scroll": "onWindowScroll()" } }, ngImport: i0, template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <!-- Changed: Removed mb-3 class to eliminate gap between toolbar and content -->\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow\" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/notifications')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> {{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of reversedCapItems\">\r\n\r\n <!-- Menu Item \u2014 Added: isFeatureAllowed check for plan-based gating -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored \u2014 Added: isFeatureAllowed check -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display \u2014 Added: isFeatureAllowed check -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items \u2014 Added: isFeatureAllowed check on sub-items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu && isFeatureAllowed(subItem)\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<!-- Changed: Removed top/bottom padding to eliminate gaps, but kept left/right padding for content spacing -->\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\" style=\"padding: 12px 12px; margin: 0;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 22px; font-weight: 400;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <!-- <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div> -->\r\n\r\n <!-- <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\r\n\r\n <!-- <label style=\"font-size: 14px;\">Hi, {{loggedUserFullName}}</label> -->\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" matTooltip=\"Organisation Settings\">\r\n <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\r\n </button>\r\n <label style=\"font-size: 14px;margin-right: 20px;\">{{tenantName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\" matTooltip=\"Support\">\r\n <mat-icon >help</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n <label style=\"font-size: 14px;\">{{loggedUserFullName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\" matTooltip=\"Signout\">\r\n <mat-icon>logout</mat-icon>\r\n </button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'side'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\"\r\n [ngStyle]=\"{'width': dataService.appConfig.navWidth}\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item \u2014 Added: isFeatureAllowed check for plan-based gating -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\" style=\"height: 40px;font-size: 15px;\"\r\n (click)=\"smallScreen ? toggle() : null\">\r\n <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items \u2014 Added: isFeatureAllowed check -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items - Changed: Use ng-container to avoid blank spaces for hidden items -->\r\n <mat-nav-list>\r\n <ng-container *ngFor=\"let capSub of getSubItems(cap)\">\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px; padding-left: 4px; padding-right: 10px; margin-bottom: 5px;\" (click)=\"smallScreen ? toggle() : null\" *ngIf=\"myRole[capSub.name] && capSub.showMenu && isFeatureAllowed(capSub)\" [matTooltip]=\"capSub.display\" matTooltipPosition=\"right\">\r\n <mat-icon [ngStyle]=\"{'color': capSub.color}\" style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n </ng-container>\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"tin-bg-image\" style=\"padding: 0px 12px;\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">© {{nowDate | date : 'yyyy'}} <a color=\"primary\" class=\"terms-link\" [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openTerms()\">Terms</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openPrivacy()\">Privacy Policy</a></label>\r\n</div>\r\n\r\n\r\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n<!-- SIDE-MODERN -->\r\n\r\n<!-- Changed: Side-modern navigation layout -->\r\n<div class=\"sm-layout\"\r\n *ngIf=\"loggedin && dataService.appConfig.navigation == 'side-modern'\"\r\n [class.sm-mini]=\"isMiniSidebar && !isMiniHovered\"\r\n [class.sm-mini-hovered]=\"isMiniSidebar && isMiniHovered\"\r\n [class.sm-mobile-open]=\"smallScreen && isExpanded\">\r\n\r\n <!-- Sidebar -->\r\n <aside class=\"sm-sidebar\"\r\n (mouseenter)=\"onMiniMouseEnter()\"\r\n (mouseleave)=\"onMiniMouseLeave()\">\r\n\r\n <!-- Background layers -->\r\n <div class=\"sm-sidebar-bg\">\r\n <div class=\"sm-sidebar-bg-image\" *ngIf=\"appConfig.navImage\" [ngStyle]=\"{'background-image': 'url(' + appConfig.navImage + ')'}\"></div>\r\n <div class=\"sm-sidebar-bg-overlay\" [ngStyle]=\"{'background-color': appConfig.navColor}\"></div>\r\n </div>\r\n\r\n <!-- Sidebar content -->\r\n <div class=\"sm-sidebar-content\">\r\n\r\n <!-- Brand -->\r\n <div class=\"sm-brand\">\r\n <img *ngIf=\"appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" />\r\n <span class=\"sm-brand-name\">{{appConfig.appName}}</span>\r\n </div>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <!-- Profile -->\r\n <div class=\"sm-profile\">\r\n <mat-icon class=\"sm-profile-icon\">account_circle</mat-icon>\r\n <div class=\"sm-profile-info\">\r\n <div class=\"sm-profile-name\">{{loggedUserFullName}}</div>\r\n <div class=\"sm-profile-role\">{{tenantName || 'User'}}</div>\r\n </div>\r\n </div>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <!-- Scrollable menu -->\r\n <div class=\"sm-menu-scroll\">\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\">\r\n\r\n <!-- Simple menu item (no sub-items or ignoring sub display) \u2014 Added: isFeatureAllowed check -->\r\n <div *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\"\r\n class=\"sm-menu-item\"\r\n [class.sm-active]=\"isActiveRoute(cap.link)\"\r\n (click)=\"modernNavigate(cap.link)\">\r\n <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\r\n <span class=\"sm-menu-text\">{{cap.display}}</span>\r\n </div>\r\n\r\n <!-- Parent menu item with sub-items \u2014 Added: isFeatureAllowed check -->\r\n <ng-container *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\r\n\r\n <!-- Parent item (toggles sub-menu) -->\r\n <div class=\"sm-menu-item\"\r\n [class.sm-active]=\"isParentActive(cap) && !isMenuOpen(cap.name)\"\r\n (click)=\"toggleModernMenu(cap.name)\">\r\n <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\r\n <span class=\"sm-menu-text\">{{cap.display}}</span>\r\n <mat-icon class=\"sm-caret\" [class.sm-caret-open]=\"isMenuOpen(cap.name)\">expand_more</mat-icon>\r\n </div>\r\n\r\n <!-- Sub-menu container (animated) -->\r\n <div class=\"sm-submenu\" [class.sm-submenu-open]=\"isMenuOpen(cap.name)\">\r\n <ng-container *ngFor=\"let sub of getSubItems(cap)\">\r\n <div *ngIf=\"myRole[sub.name] && sub.showMenu && isFeatureAllowed(sub)\"\r\n class=\"sm-submenu-item\"\r\n [class.sm-active]=\"isActiveRoute(sub.link)\"\r\n (click)=\"modernNavigate(sub.link)\">\r\n <mat-icon *ngIf=\"sub.icon && sub.icon != 'navigate_next'\" class=\"sm-sub-icon\">{{sub.icon}}</mat-icon>\r\n <span *ngIf=\"!sub.icon || sub.icon == 'navigate_next'\" class=\"sm-initials\">{{getInitials(sub.display)}}</span>\r\n <span class=\"sm-menu-text\">{{sub.display}}</span>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n </div>\r\n </aside>\r\n\r\n <!-- Mobile backdrop -->\r\n <div class=\"sm-backdrop\" (click)=\"isExpanded = false\"></div>\r\n\r\n <!-- Main content -->\r\n <div class=\"sm-main\">\r\n\r\n <!-- Top bar - Changed: Added scroll class for frosted glass effect -->\r\n <div class=\"sm-topbar\" [class.sm-topbar-scrolled]=\"topbarScrolled\">\r\n <button mat-icon-button (click)=\"smallScreen ? toggle() : toggleMiniSidebar()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <!-- Changed: Mobile branding - show logo + app name when sidebar is hidden on small screens -->\r\n <img *ngIf=\"smallScreen && appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" class=\"sm-topbar-logo\" />\r\n <span *ngIf=\"smallScreen\" class=\"sm-topbar-brand\">{{appConfig.appName}}</span>\r\n\r\n <span class=\"sm-topbar-spacer\"></span>\r\n\r\n <!-- Multitenant buttons -->\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" matTooltip=\"Organisation Settings\">\r\n <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\r\n </button>\r\n <span class=\"sm-topbar-label\">{{tenantName}}</span>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\" matTooltip=\"Support\">\r\n <mat-icon>help</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Profile menu -->\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"smProfileMenu\">\r\n <mat-icon>account_circle</mat-icon>\r\n </button>\r\n <span class=\"sm-topbar-label\">{{loggedUserFullName}}</span>\r\n\r\n <mat-menu #smProfileMenu=\"matMenu\" [overlapTrigger]=\"false\" yPosition=\"below\">\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon><span>Help</span>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n </mat-menu>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\" matTooltip=\"Signout\">\r\n <mat-icon>logout</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Page content - Changed: Replaced tin-bg-image with sm-content modern texture -->\r\n <div class=\"sm-content\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"sm-footer\">\r\n © {{nowDate | date : 'yyyy'}} <a [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a (click)=\"openTerms()\">Terms</a> | <a (click)=\"openPrivacy()\">Privacy Policy</a>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n\r\n<!-- Not logged in fallback for side-modern -->\r\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side-modern'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar-item-spacer{flex:1 1 auto}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff;margin-bottom:0!important}.toolbar button,.toolbar .mat-mdc-button,.toolbar .mat-mdc-icon-button{color:#fff!important}.toolbar mat-icon{color:#fff!important}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.app-container{height:90%;margin:0}.app-sidenav{width:200px;border:1px solid rgb(192,190,199)}.side-color{background-color:#e6f4ff}.app-sidenav mat-list-item{display:flex!important;align-items:center!important}.app-sidenav mat-icon{display:inline-flex!important;align-items:center!important;vertical-align:middle!important}.app-sidenav mat-expansion-panel-header mat-icon{display:inline-flex!important;align-items:center!important;vertical-align:middle!important}::ng-deep .app-sidenav .mat-expansion-panel-body{padding-bottom:5px!important;padding-right:5px!important}::ng-deep .app-sidenav .mdc-list{padding-bottom:0!important}.sm-layout{display:flex;min-height:100vh;position:relative}.sm-sidebar{position:fixed;top:0;left:0;bottom:0;width:260px;z-index:1030;overflow:hidden;transition:width .3s cubic-bezier(.4,0,.2,1)}.sm-sidebar-bg{position:absolute;inset:0;z-index:0}.sm-sidebar-bg-image{position:absolute;inset:0;background-size:cover;background-position:center}.sm-sidebar-bg-overlay{position:absolute;inset:0}.sm-sidebar-content{position:relative;z-index:1;display:flex;flex-direction:column;height:100%;color:#fff}.sm-brand{display:flex;align-items:center;padding:18px 15px 10px;min-height:60px;text-decoration:none;white-space:nowrap;overflow:hidden}.sm-brand img{height:34px;width:34px;object-fit:contain;margin-right:12px;flex-shrink:0}.sm-brand-name{font-size:16px;font-weight:500;letter-spacing:.5px;color:#fff;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s ease}.sm-profile{display:flex;align-items:center;padding:12px 15px;white-space:nowrap;overflow:hidden}.sm-profile-icon{font-size:34px!important;width:34px!important;height:34px!important;margin-right:12px;flex-shrink:0;color:#fffc}.sm-profile-info{overflow:hidden;transition:opacity .2s ease}.sm-profile-name{font-size:14px;font-weight:500;color:#fff;line-height:1.3;overflow:hidden;text-overflow:ellipsis}.sm-profile-role{font-size:11px;color:#fff9;line-height:1.3;overflow:hidden;text-overflow:ellipsis}.sm-sidebar mat-divider{border-color:#ffffff26!important;margin:0 15px}.sm-menu-scroll{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px 0}.sm-menu-scroll::-webkit-scrollbar{width:4px}.sm-menu-scroll::-webkit-scrollbar-track{background:transparent}.sm-menu-scroll::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.sm-menu-item{display:flex;align-items:center;padding:10px 15px;margin:2px 15px;border-radius:4px;cursor:pointer;color:#fff;font-size:13px;font-weight:400;letter-spacing:.3px;transition:all .15s ease;text-decoration:none;white-space:nowrap;overflow:hidden}.sm-menu-item:hover{background:#ffffff1f}.sm-menu-item.sm-active{background-color:#fff;color:#3c4858;box-shadow:0 4px 20px #00000024,0 7px 10px -5px #0003;font-weight:500}.sm-menu-item.sm-active .sm-menu-icon{color:#3c4858}.sm-menu-icon{font-size:20px!important;width:24px!important;height:24px!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;flex-shrink:0;color:#fffc;transition:color .15s ease}.sm-menu-text{flex:1;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s ease}.sm-caret{font-size:18px!important;width:18px!important;height:18px!important;transition:transform .3s cubic-bezier(.4,0,.2,1);flex-shrink:0;color:#fff9}.sm-caret.sm-caret-open{transform:rotate(180deg)}.sm-active .sm-caret{color:#3c4858}.sm-submenu{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.sm-submenu.sm-submenu-open{max-height:1000px}.sm-submenu-item{display:flex;align-items:center;padding:8px 15px 8px 30px;margin:1px 15px;border-radius:4px;cursor:pointer;color:#fffc;font-size:12px;font-weight:400;transition:all .15s ease;white-space:nowrap;overflow:hidden}.sm-submenu-item:hover{background:#ffffff1f;color:#fff}.sm-submenu-item.sm-active{background-color:#fff;color:#3c4858;box-shadow:0 4px 20px #00000024,0 7px 10px -5px #0003;font-weight:500}.sm-submenu-item.sm-active .sm-sub-icon{color:#3c4858}.sm-sub-icon{font-size:16px!important;width:20px!important;height:20px!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:10px;flex-shrink:0;color:#fff9}.sm-initials{width:20px;height:20px;border-radius:50%;background:#ffffff26;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:600;margin-right:10px;flex-shrink:0;color:#fffc}.sm-active .sm-initials{background:#3c48581f;color:#3c4858}.sm-main{flex:1;margin-left:260px;min-height:100vh;display:flex;flex-direction:column;transition:margin-left .3s cubic-bezier(.4,0,.2,1);background-color:#eef2f7}.sm-topbar{display:flex;align-items:center;padding:8px 16px;min-height:56px;background-color:#eef2f7;background-image:radial-gradient(circle,#d5dbe3 1px,transparent 1px);background-size:16px 16px;border-bottom:1px solid rgba(0,0,0,.08);position:sticky;top:0;z-index:1020;transition:background .3s ease,backdrop-filter .3s ease}.sm-topbar-scrolled{background-color:#eef2f78c;background-image:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);box-shadow:0 1px 3px #0000000f}.sm-topbar-spacer{flex:1 1 auto}.sm-topbar-logo{height:32px;width:32px;object-fit:contain;margin-right:8px}.sm-topbar-brand{font-size:18px;font-weight:500;margin-right:8px;white-space:nowrap}.sm-topbar-label{font-size:14px;margin-right:4px;display:inline-flex;align-items:center;align-self:center;height:40px;line-height:1}.sm-topbar .mat-mdc-icon-button{display:inline-flex!important;align-items:center!important;justify-content:center!important}.sm-content{flex:1;padding:12px;background-color:#e5eaf2;background-image:radial-gradient(ellipse at 50% 45%,#fffffff2,#fff6 35%,#fff0 60%),radial-gradient(circle,#bec7d4 1px,transparent 1px);background-size:100% 100%,16px 16px;min-height:calc(100vh - 104px)}.sm-footer{padding:12px 16px;text-align:center;font-size:12px;color:#999;border-top:1px solid #e0e0e0;background:#fff}.sm-footer a{color:inherit;cursor:pointer}.sm-footer a:hover{text-decoration:underline}.sm-backdrop{display:none;position:fixed;inset:0;background:#00000080;z-index:1025}.sm-layout.sm-mini .sm-sidebar{width:80px}.sm-layout.sm-mini .sm-main{margin-left:80px}.sm-layout.sm-mini .sm-brand-name,.sm-layout.sm-mini .sm-profile-info,.sm-layout.sm-mini .sm-menu-text,.sm-layout.sm-mini .sm-caret,.sm-layout.sm-mini .sm-submenu{display:none}.sm-layout.sm-mini .sm-sidebar mat-divider{margin:0 10px}.sm-layout.sm-mini .sm-brand{justify-content:center;padding:18px 0 10px}.sm-layout.sm-mini .sm-brand img{margin-right:0}.sm-layout.sm-mini .sm-profile{justify-content:center;padding:12px 0}.sm-layout.sm-mini .sm-profile-icon{margin-right:0}.sm-layout.sm-mini .sm-menu-item{justify-content:center;padding:12px 0;margin:2px 0}.sm-layout.sm-mini .sm-menu-icon{margin-right:0;font-size:22px!important}.sm-layout.sm-mini-hovered .sm-sidebar{width:260px;box-shadow:4px 0 20px #0000004d}.sm-layout.sm-mini-hovered .sm-main{margin-left:80px}.sm-layout.sm-mini-hovered .sm-brand-name,.sm-layout.sm-mini-hovered .sm-profile-info,.sm-layout.sm-mini-hovered .sm-menu-text,.sm-layout.sm-mini-hovered .sm-caret{display:initial}.sm-layout.sm-mini-hovered .sm-submenu{display:block}.sm-layout.sm-mini-hovered .sm-sidebar mat-divider{margin:0 15px}.sm-layout.sm-mini-hovered .sm-brand{justify-content:flex-start;padding:18px 15px 10px}.sm-layout.sm-mini-hovered .sm-brand img{margin-right:12px}.sm-layout.sm-mini-hovered .sm-profile{justify-content:flex-start;padding:12px 15px}.sm-layout.sm-mini-hovered .sm-profile-icon{margin-right:12px}.sm-layout.sm-mini-hovered .sm-menu-item{justify-content:flex-start;padding:10px 15px;margin:2px 15px}.sm-layout.sm-mini-hovered .sm-menu-icon{margin-right:12px;font-size:20px!important}@media (max-width: 600px){.sm-sidebar{transform:translate(-100%);transition:transform .3s cubic-bezier(.4,0,.2,1);width:260px!important}.sm-layout.sm-mobile-open .sm-sidebar{transform:translate(0)}.sm-layout.sm-mobile-open .sm-backdrop{display:block}.sm-main{margin-left:0!important}.sm-layout.sm-mini .sm-sidebar{width:260px!important}.sm-layout.sm-mini .sm-brand-name,.sm-layout.sm-mini .sm-profile-info,.sm-layout.sm-mini .sm-menu-text,.sm-layout.sm-mini .sm-caret{display:initial}.sm-layout.sm-mini .sm-submenu{display:block}.sm-layout.sm-mini .sm-sidebar mat-divider{margin:0 15px}.sm-layout.sm-mini .sm-menu-item{justify-content:flex-start;padding:10px 15px;margin:2px 15px}.sm-layout.sm-mini .sm-menu-icon{margin-right:12px;font-size:20px!important}.sm-layout.sm-mini .sm-brand{justify-content:flex-start;padding:18px 15px 10px}.sm-layout.sm-mini .sm-brand img{margin-right:12px}.sm-layout.sm-mini .sm-profile{justify-content:flex-start;padding:12px 15px}.sm-layout.sm-mini .sm-profile-icon{margin-right:12px}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i3$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i14.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i14.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i16.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i16.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i16.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: i17.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i1$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i18.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i18.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "component", type: LoaderComponent, selector: "spa-loader", inputs: ["logo"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
9539
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: NavMenuComponent, isStandalone: false, selector: "spa-nav-menu", inputs: { appConfig: "appConfig", footer: "footer" }, host: { listeners: { "window:scroll": "onWindowScroll()" } }, ngImport: i0, template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <!-- Changed: Removed mb-3 class to eliminate gap between toolbar and content -->\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow\" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/notifications')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> {{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of reversedCapItems\">\r\n\r\n <!-- Menu Item \u2014 Added: isFeatureAllowed check for plan-based gating -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored \u2014 Added: isFeatureAllowed check -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display \u2014 Added: isFeatureAllowed check -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items \u2014 Added: isFeatureAllowed check on sub-items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu && isFeatureAllowed(subItem)\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<!-- Changed: Removed top/bottom padding to eliminate gaps, but kept left/right padding for content spacing -->\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\" style=\"padding: 12px 12px; margin: 0;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 22px; font-weight: 400;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <!-- <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div> -->\r\n\r\n <!-- <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\r\n\r\n <!-- <label style=\"font-size: 14px;\">Hi, {{loggedUserFullName}}</label> -->\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" matTooltip=\"Organisation Settings\">\r\n <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\r\n </button>\r\n <label style=\"font-size: 14px;margin-right: 20px;\">{{tenantName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\" matTooltip=\"Support\">\r\n <mat-icon >help</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n <label style=\"font-size: 14px;\">{{loggedUserFullName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\" matTooltip=\"Signout\">\r\n <mat-icon>logout</mat-icon>\r\n </button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'side'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\"\r\n [ngStyle]=\"{'width': dataService.appConfig.navWidth}\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item \u2014 Added: isFeatureAllowed check for plan-based gating -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\" style=\"height: 40px;font-size: 15px;\"\r\n (click)=\"smallScreen ? toggle() : null\">\r\n <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items \u2014 Added: isFeatureAllowed check -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items - Changed: Use ng-container to avoid blank spaces for hidden items -->\r\n <mat-nav-list>\r\n <ng-container *ngFor=\"let capSub of getSubItems(cap)\">\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px; padding-left: 4px; padding-right: 10px; margin-bottom: 5px;\" (click)=\"smallScreen ? toggle() : null\" *ngIf=\"myRole[capSub.name] && capSub.showMenu && isFeatureAllowed(capSub)\" [matTooltip]=\"capSub.display\" matTooltipPosition=\"right\">\r\n <mat-icon [ngStyle]=\"{'color': capSub.color}\" style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n </ng-container>\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"tin-bg-image\" style=\"padding: 0px 12px;\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">© {{nowDate | date : 'yyyy'}} <a color=\"primary\" class=\"terms-link\" [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openTerms()\">Terms</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openPrivacy()\">Privacy Policy</a></label>\r\n</div>\r\n\r\n\r\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n<!-- SIDE-MODERN -->\r\n\r\n<!-- Changed: Side-modern navigation layout -->\r\n<div class=\"sm-layout\"\r\n *ngIf=\"loggedin && dataService.appConfig.navigation == 'side-modern'\"\r\n [class.sm-mini]=\"isMiniSidebar && !isMiniHovered\"\r\n [class.sm-mini-hovered]=\"isMiniSidebar && isMiniHovered\"\r\n [class.sm-mobile-open]=\"smallScreen && isExpanded\">\r\n\r\n <!-- Sidebar -->\r\n <aside class=\"sm-sidebar\"\r\n (mouseenter)=\"onMiniMouseEnter()\"\r\n (mouseleave)=\"onMiniMouseLeave()\">\r\n\r\n <!-- Background layers -->\r\n <div class=\"sm-sidebar-bg\">\r\n <div class=\"sm-sidebar-bg-image\" *ngIf=\"appConfig.navImage\" [ngStyle]=\"{'background-image': 'url(' + appConfig.navImage + ')'}\"></div>\r\n <div class=\"sm-sidebar-bg-overlay\" [ngStyle]=\"{'background-color': appConfig.navColor}\"></div>\r\n </div>\r\n\r\n <!-- Sidebar content -->\r\n <div class=\"sm-sidebar-content\">\r\n\r\n <!-- Brand -->\r\n <div class=\"sm-brand\">\r\n <img *ngIf=\"appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" />\r\n <span class=\"sm-brand-name\">{{appConfig.appName}}</span>\r\n </div>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <!-- Profile -->\r\n <div class=\"sm-profile\">\r\n <mat-icon class=\"sm-profile-icon\">account_circle</mat-icon>\r\n <div class=\"sm-profile-info\">\r\n <div class=\"sm-profile-name\">{{loggedUserFullName}}</div>\r\n <div class=\"sm-profile-role\">{{tenantName || 'User'}}</div>\r\n </div>\r\n </div>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <!-- Scrollable menu -->\r\n <div class=\"sm-menu-scroll\">\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\">\r\n\r\n <!-- Simple menu item (no sub-items or ignoring sub display) \u2014 Added: isFeatureAllowed check -->\r\n <div *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\"\r\n class=\"sm-menu-item\"\r\n [class.sm-active]=\"isActiveRoute(cap.link)\"\r\n (click)=\"modernNavigate(cap.link)\">\r\n <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\r\n <span class=\"sm-menu-text\">{{cap.display}}</span>\r\n </div>\r\n\r\n <!-- Parent menu item with sub-items \u2014 Added: isFeatureAllowed check -->\r\n <ng-container *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\r\n\r\n <!-- Parent item (toggles sub-menu) -->\r\n <div class=\"sm-menu-item\"\r\n [class.sm-active]=\"isParentActive(cap) && !isMenuOpen(cap.name)\"\r\n (click)=\"toggleModernMenu(cap.name)\">\r\n <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\r\n <span class=\"sm-menu-text\">{{cap.display}}</span>\r\n <mat-icon class=\"sm-caret\" [class.sm-caret-open]=\"isMenuOpen(cap.name)\">expand_more</mat-icon>\r\n </div>\r\n\r\n <!-- Sub-menu container (animated) -->\r\n <div class=\"sm-submenu\" [class.sm-submenu-open]=\"isMenuOpen(cap.name)\">\r\n <ng-container *ngFor=\"let sub of getSubItems(cap)\">\r\n <div *ngIf=\"myRole[sub.name] && sub.showMenu && isFeatureAllowed(sub)\"\r\n class=\"sm-submenu-item\"\r\n [class.sm-active]=\"isActiveRoute(sub.link)\"\r\n (click)=\"modernNavigate(sub.link)\">\r\n <mat-icon *ngIf=\"sub.icon && sub.icon != 'navigate_next'\" class=\"sm-sub-icon\">{{sub.icon}}</mat-icon>\r\n <span *ngIf=\"!sub.icon || sub.icon == 'navigate_next'\" class=\"sm-initials\">{{getInitials(sub.display)}}</span>\r\n <span class=\"sm-menu-text\">{{sub.display}}</span>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n </div>\r\n </aside>\r\n\r\n <!-- Mobile backdrop -->\r\n <div class=\"sm-backdrop\" (click)=\"isExpanded = false\"></div>\r\n\r\n <!-- Main content -->\r\n <div class=\"sm-main\">\r\n\r\n <!-- Top bar - Changed: Added scroll class for frosted glass effect -->\r\n <div class=\"sm-topbar\" [class.sm-topbar-scrolled]=\"topbarScrolled\">\r\n <button mat-icon-button (click)=\"smallScreen ? toggle() : toggleMiniSidebar()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <!-- Changed: Mobile branding - show logo + app name when sidebar is hidden on small screens -->\r\n <img *ngIf=\"smallScreen && appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" class=\"sm-topbar-logo\" />\r\n <span *ngIf=\"smallScreen\" class=\"sm-topbar-brand\">{{appConfig.appName}}</span>\r\n\r\n <span class=\"sm-topbar-spacer\"></span>\r\n\r\n <!-- Multitenant buttons -->\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" matTooltip=\"Organisation Settings\">\r\n <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\r\n </button>\r\n <span class=\"sm-topbar-label\">{{tenantName}}</span>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\" matTooltip=\"Support\">\r\n <mat-icon>help</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Profile menu -->\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"smProfileMenu\">\r\n <mat-icon>account_circle</mat-icon>\r\n </button>\r\n <span class=\"sm-topbar-label\">{{loggedUserFullName}}</span>\r\n\r\n <mat-menu #smProfileMenu=\"matMenu\" [overlapTrigger]=\"false\" yPosition=\"below\">\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon><span>Help</span>\r\n </button>\r\n <mat-divider></mat-divider>\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n </mat-menu>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\" matTooltip=\"Signout\">\r\n <mat-icon>logout</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <!-- Page content - Changed: Replaced tin-bg-image with sm-content modern texture -->\r\n <div class=\"sm-content\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"sm-footer\">\r\n © {{nowDate | date : 'yyyy'}} <a [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a (click)=\"openTerms()\">Terms</a> | <a (click)=\"openPrivacy()\">Privacy Policy</a>\r\n </div>\r\n\r\n </div>\r\n\r\n</div>\r\n\r\n<!-- Not logged in fallback for side-modern -->\r\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side-modern'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar-item-spacer{flex:1 1 auto}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff;margin-bottom:0!important}.toolbar button,.toolbar .mat-mdc-button,.toolbar .mat-mdc-icon-button{color:#fff!important}.toolbar mat-icon{color:#fff!important}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.app-container{height:90%;margin:0}.app-sidenav{width:200px;border:1px solid rgb(192,190,199)}.side-color{background-color:#e6f4ff}.app-sidenav mat-list-item{display:flex!important;align-items:center!important}.app-sidenav mat-icon{display:inline-flex!important;align-items:center!important;vertical-align:middle!important}.app-sidenav mat-expansion-panel-header mat-icon{display:inline-flex!important;align-items:center!important;vertical-align:middle!important}::ng-deep .app-sidenav .mat-expansion-panel-body{padding-bottom:5px!important;padding-right:5px!important}::ng-deep .app-sidenav .mdc-list{padding-bottom:0!important}.sm-layout{display:flex;min-height:100vh;position:relative}.sm-sidebar{position:fixed;top:0;left:0;bottom:0;width:260px;z-index:1030;overflow:hidden;transition:width .3s cubic-bezier(.4,0,.2,1)}.sm-sidebar-bg{position:absolute;inset:0;z-index:0}.sm-sidebar-bg-image{position:absolute;inset:0;background-size:cover;background-position:center}.sm-sidebar-bg-overlay{position:absolute;inset:0}.sm-sidebar-content{position:relative;z-index:1;display:flex;flex-direction:column;height:100%;color:#fff}.sm-brand{display:flex;align-items:center;padding:18px 15px 10px;min-height:60px;text-decoration:none;white-space:nowrap;overflow:hidden}.sm-brand img{height:34px;width:34px;object-fit:contain;margin-right:12px;flex-shrink:0}.sm-brand-name{font-size:16px;font-weight:500;letter-spacing:.5px;color:#fff;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s ease}.sm-profile{display:flex;align-items:center;padding:12px 15px;white-space:nowrap;overflow:hidden}.sm-profile-icon{font-size:34px!important;width:34px!important;height:34px!important;margin-right:12px;flex-shrink:0;color:#fffc}.sm-profile-info{overflow:hidden;transition:opacity .2s ease}.sm-profile-name{font-size:14px;font-weight:500;color:#fff;line-height:1.3;overflow:hidden;text-overflow:ellipsis}.sm-profile-role{font-size:11px;color:#fff9;line-height:1.3;overflow:hidden;text-overflow:ellipsis}.sm-sidebar mat-divider{border-color:#ffffff26!important;margin:0 15px}.sm-menu-scroll{flex:1;overflow-y:auto;overflow-x:hidden;padding:8px 0}.sm-menu-scroll::-webkit-scrollbar{width:4px}.sm-menu-scroll::-webkit-scrollbar-track{background:transparent}.sm-menu-scroll::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.sm-menu-item{display:flex;align-items:center;padding:10px 15px;margin:2px 15px;border-radius:4px;cursor:pointer;color:#fff;font-size:13px;font-weight:400;letter-spacing:.3px;transition:all .15s ease;text-decoration:none;white-space:nowrap;overflow:hidden}.sm-menu-item:hover{background:#ffffff1f}.sm-menu-item.sm-active{background-color:#fff;color:#3c4858;box-shadow:0 4px 20px #00000024,0 7px 10px -5px #0003;font-weight:500}.sm-menu-item.sm-active .sm-menu-icon{color:#3c4858}.sm-menu-icon{font-size:20px!important;width:24px!important;height:24px!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:12px;flex-shrink:0;color:#fffc;transition:color .15s ease}.sm-menu-text{flex:1;overflow:hidden;text-overflow:ellipsis;transition:opacity .2s ease}.sm-caret{font-size:18px!important;width:18px!important;height:18px!important;transition:transform .3s cubic-bezier(.4,0,.2,1);flex-shrink:0;color:#fff9}.sm-caret.sm-caret-open{transform:rotate(180deg)}.sm-active .sm-caret{color:#3c4858}.sm-submenu{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1)}.sm-submenu.sm-submenu-open{max-height:1000px}.sm-submenu-item{display:flex;align-items:center;padding:8px 15px 8px 30px;margin:1px 15px;border-radius:4px;cursor:pointer;color:#fffc;font-size:12px;font-weight:400;transition:all .15s ease;white-space:nowrap;overflow:hidden}.sm-submenu-item:hover{background:#ffffff1f;color:#fff}.sm-submenu-item.sm-active{background-color:#fff;color:#3c4858;box-shadow:0 4px 20px #00000024,0 7px 10px -5px #0003;font-weight:500}.sm-submenu-item.sm-active .sm-sub-icon{color:#3c4858}.sm-sub-icon{font-size:16px!important;width:20px!important;height:20px!important;display:inline-flex!important;align-items:center;justify-content:center;margin-right:10px;flex-shrink:0;color:#fff9}.sm-initials{width:20px;height:20px;border-radius:50%;background:#ffffff26;display:inline-flex;align-items:center;justify-content:center;font-size:9px;font-weight:600;margin-right:10px;flex-shrink:0;color:#fffc}.sm-active .sm-initials{background:#3c48581f;color:#3c4858}.sm-main{flex:1;margin-left:260px;min-height:100vh;display:flex;flex-direction:column;transition:margin-left .3s cubic-bezier(.4,0,.2,1);background-color:#eef2f7}.sm-topbar{display:flex;align-items:center;padding:8px 16px;min-height:56px;background-color:#eef2f7;background-image:radial-gradient(circle,#d5dbe3 1px,transparent 1px);background-size:16px 16px;border-bottom:1px solid rgba(0,0,0,.08);position:sticky;top:0;z-index:1020;transition:background .3s ease,backdrop-filter .3s ease}.sm-topbar-scrolled{background-color:#eef2f78c;background-image:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);box-shadow:0 1px 3px #0000000f}.sm-topbar-spacer{flex:1 1 auto}.sm-topbar-logo{height:32px;width:32px;object-fit:contain;margin-right:8px}.sm-topbar-brand{font-size:18px;font-weight:500;margin-right:8px;white-space:nowrap}.sm-topbar-label{font-size:14px;margin-right:4px;display:inline-flex;align-items:center;align-self:center;height:40px;line-height:1}.sm-topbar .mat-mdc-icon-button{display:inline-flex!important;align-items:center!important;justify-content:center!important}.sm-content{flex:1;padding:12px;background-color:#e5eaf2;background-image:radial-gradient(ellipse at 50% 45%,#fffffff2,#fff6 35%,#fff0 60%),radial-gradient(circle,#bec7d4 1px,transparent 1px);background-size:100% 100%,16px 16px;min-height:calc(100vh - 104px)}.sm-footer{padding:12px 16px;text-align:center;font-size:12px;color:#999;border-top:1px solid #e0e0e0;background:#fff}.sm-footer a{color:inherit;cursor:pointer}.sm-footer a:hover{text-decoration:underline}.sm-backdrop{display:none;position:fixed;inset:0;background:#00000080;z-index:1025}.sm-layout.sm-mini .sm-sidebar{width:80px}.sm-layout.sm-mini .sm-main{margin-left:80px}.sm-layout.sm-mini .sm-brand-name,.sm-layout.sm-mini .sm-profile-info,.sm-layout.sm-mini .sm-menu-text,.sm-layout.sm-mini .sm-caret,.sm-layout.sm-mini .sm-submenu{display:none}.sm-layout.sm-mini .sm-sidebar mat-divider{margin:0 10px}.sm-layout.sm-mini .sm-brand{justify-content:center;padding:18px 0 10px}.sm-layout.sm-mini .sm-brand img{margin-right:0}.sm-layout.sm-mini .sm-profile{justify-content:center;padding:12px 0}.sm-layout.sm-mini .sm-profile-icon{margin-right:0}.sm-layout.sm-mini .sm-menu-item{justify-content:center;padding:12px 0;margin:2px 0}.sm-layout.sm-mini .sm-menu-icon{margin-right:0;font-size:22px!important}.sm-layout.sm-mini-hovered .sm-sidebar{width:260px;box-shadow:4px 0 20px #0000004d}.sm-layout.sm-mini-hovered .sm-main{margin-left:80px}.sm-layout.sm-mini-hovered .sm-brand-name,.sm-layout.sm-mini-hovered .sm-profile-info,.sm-layout.sm-mini-hovered .sm-menu-text,.sm-layout.sm-mini-hovered .sm-caret{display:initial}.sm-layout.sm-mini-hovered .sm-submenu{display:block}.sm-layout.sm-mini-hovered .sm-sidebar mat-divider{margin:0 15px}.sm-layout.sm-mini-hovered .sm-brand{justify-content:flex-start;padding:18px 15px 10px}.sm-layout.sm-mini-hovered .sm-brand img{margin-right:12px}.sm-layout.sm-mini-hovered .sm-profile{justify-content:flex-start;padding:12px 15px}.sm-layout.sm-mini-hovered .sm-profile-icon{margin-right:12px}.sm-layout.sm-mini-hovered .sm-menu-item{justify-content:flex-start;padding:10px 15px;margin:2px 15px}.sm-layout.sm-mini-hovered .sm-menu-icon{margin-right:12px;font-size:20px!important}@media (max-width: 600px){.sm-sidebar{transform:translate(-100%);transition:transform .3s cubic-bezier(.4,0,.2,1);width:260px!important}.sm-layout.sm-mobile-open .sm-sidebar{transform:translate(0)}.sm-layout.sm-mobile-open .sm-backdrop{display:block}.sm-main{margin-left:0!important}.sm-layout.sm-mini .sm-sidebar{width:260px!important}.sm-layout.sm-mini .sm-brand-name,.sm-layout.sm-mini .sm-profile-info,.sm-layout.sm-mini .sm-menu-text,.sm-layout.sm-mini .sm-caret{display:initial}.sm-layout.sm-mini .sm-submenu{display:block}.sm-layout.sm-mini .sm-sidebar mat-divider{margin:0 15px}.sm-layout.sm-mini .sm-menu-item{justify-content:flex-start;padding:10px 15px;margin:2px 15px}.sm-layout.sm-mini .sm-menu-icon{margin-right:12px;font-size:20px!important}.sm-layout.sm-mini .sm-brand{justify-content:flex-start;padding:18px 15px 10px}.sm-layout.sm-mini .sm-brand img{margin-right:12px}.sm-layout.sm-mini .sm-profile{justify-content:flex-start;padding:12px 15px}.sm-layout.sm-mini .sm-profile-icon{margin-right:12px}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i3$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i14.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i14.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "component", type: i14.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i16.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i16.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i16.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: i17.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i1$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i18.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i18.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "component", type: LoaderComponent, selector: "spa-loader", inputs: ["logo"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
9319
9540
|
}
|
|
9320
9541
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: NavMenuComponent, decorators: [{
|
|
9321
9542
|
type: Component,
|
|
@@ -9877,7 +10098,7 @@ class EmailComponent {
|
|
|
9877
10098
|
});
|
|
9878
10099
|
}
|
|
9879
10100
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: EmailComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9880
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: EmailComponent, isStandalone: false, selector: "spa-email", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", suffix: "suffix", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionValue: "optionValue" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<mat-form-field style=\"width: 100%;\" subscriptSizing=\"dynamic\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-chip-grid #chipList>\r\n <mat-chip-row *ngFor=\"let email of emails\" [removable]=\"!readonly\" (removed)=\"removeEmail(email)\">\r\n {{email}}\r\n <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\r\n </mat-chip-row>\r\n <input autocomplete=\"off\" #emailInput [placeholder]=\"readonly ? '' : 'Enter email addresses'\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"addEmail($event)\" [formControl]=\"emailControl\" (paste)=\"handlePaste($event)\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\r\n </mat-chip-grid>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"optionValue ? option[optionValue] : option\">\r\n {{optionValue ? option[optionValue] : option}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"emailControl.invalid && emailControl.touched\">Invalid email format</mat-error>\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n <div matSuffix class=\"suffix-icons\">\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clearEmails()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", styles: [":host ::ng-deep .mat-form-field-flex{align-items:flex-start}:host ::ng-deep .mat-form-field-infix{max-height:170px;overflow-y:auto;padding-top:.25em;padding-bottom:.25em;overflow-x:hidden}:host ::ng-deep mat-chip{flex:0 0 auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i7
|
|
10101
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: EmailComponent, isStandalone: false, selector: "spa-email", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", suffix: "suffix", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionValue: "optionValue" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<mat-form-field style=\"width: 100%;\" subscriptSizing=\"dynamic\">\r\n <mat-label>{{display}}</mat-label>\r\n <mat-chip-grid #chipList>\r\n <mat-chip-row *ngFor=\"let email of emails\" [removable]=\"!readonly\" (removed)=\"removeEmail(email)\">\r\n {{email}}\r\n <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\r\n </mat-chip-row>\r\n <input autocomplete=\"off\" #emailInput [placeholder]=\"readonly ? '' : 'Enter email addresses'\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"addEmail($event)\" [formControl]=\"emailControl\" (paste)=\"handlePaste($event)\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\r\n </mat-chip-grid>\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\r\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"optionValue ? option[optionValue] : option\">\r\n {{optionValue ? option[optionValue] : option}}\r\n </mat-option>\r\n </mat-autocomplete>\r\n <mat-error *ngIf=\"emailControl.invalid && emailControl.touched\">Invalid email format</mat-error>\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n <div matSuffix class=\"suffix-icons\">\r\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clearEmails()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\r\n </div>\r\n</mat-form-field>\r\n", styles: [":host ::ng-deep .mat-form-field-flex{align-items:flex-start}:host ::ng-deep .mat-form-field-infix{max-height:170px;overflow-y:auto;padding-top:.25em;padding-bottom:.25em;overflow-x:hidden}:host ::ng-deep mat-chip{flex:0 0 auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i6.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i6.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i12.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i12.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] }); }
|
|
9881
10102
|
}
|
|
9882
10103
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: EmailComponent, decorators: [{
|
|
9883
10104
|
type: Component,
|
|
@@ -10757,7 +10978,7 @@ class DetailsDialogLite {
|
|
|
10757
10978
|
}
|
|
10758
10979
|
}
|
|
10759
10980
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialogLite, deps: [{ token: i1$3.BreakpointObserver }, { token: LoaderService }, { token: DataServiceLib }, { token: MessageService }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: ButtonService }, { token: DialogService }, { token: AuthService }, { token: TableConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10760
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialogLite, isStandalone: false, selector: "spa-detailsDialog-lite", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select-lite\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n \r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select-lite>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- \r\n Lite Dialog should not implement tabs \r\n PlaceHolder\r\n \r\n \r\n \r\n \r\n \r\n -->\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions>\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\" \r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\" \r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: SelectLiteComponent, selector: "spa-select-lite" }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
10981
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialogLite, isStandalone: false, selector: "spa-detailsDialog-lite", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select-lite\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n \r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select-lite>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- \r\n Lite Dialog should not implement tabs \r\n PlaceHolder\r\n \r\n \r\n \r\n \r\n \r\n -->\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions>\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\" \r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\" \r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: SelectLiteComponent, selector: "spa-select-lite" }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
10761
10982
|
}
|
|
10762
10983
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialogLite, decorators: [{
|
|
10763
10984
|
type: Component,
|
|
@@ -10824,7 +11045,7 @@ class SelectInternalComponent extends SelectCommonComponent {
|
|
|
10824
11045
|
}
|
|
10825
11046
|
}
|
|
10826
11047
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectInternalComponent, deps: [{ token: MessageService }, { token: DataServiceLib }, { token: DialogService }, { token: ButtonService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10827
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectInternalComponent, isStandalone: false, selector: "spa-select-internal", inputs: { detailsConfig: "detailsConfig" }, usesInheritance: true, ngImport: i0, template: "<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\r\n [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\r\n [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\r\n [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\r\n [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\r\n (valueChange)=\"valueChange.emit($event)\"\r\n (hoverChange)=\"onHoverChange($event)\">\r\n <ng-container additionalButtons>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon color=\"primary\">launch</mat-icon>\r\n </button>\r\n\r\n </ng-container>\r\n</spa-select-common>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
11048
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectInternalComponent, isStandalone: false, selector: "spa-select-internal", inputs: { detailsConfig: "detailsConfig" }, usesInheritance: true, ngImport: i0, template: "<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\r\n [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\r\n [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\r\n [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\r\n [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\r\n (valueChange)=\"valueChange.emit($event)\"\r\n (hoverChange)=\"onHoverChange($event)\">\r\n <ng-container additionalButtons>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: green;\">add</mat-icon>\r\n </button>\r\n <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\r\n <mat-icon color=\"primary\">launch</mat-icon>\r\n </button>\r\n\r\n </ng-container>\r\n</spa-select-common>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SelectCommonComponent, selector: "spa-select-common", inputs: ["width", "readonly", "required", "defaultFirstValue", "readonlyMode", "hint", "placeholder", "display", "value", "options", "masterOptions", "masterField", "optionValue", "optionDisplay", "optionDisplayExtra", "nullable", "infoMessage", "copyContent", "loadAction", "loadIDField", "field", "data"], outputs: ["valueChange", "hoverChange"] }] }); }
|
|
10828
11049
|
}
|
|
10829
11050
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectInternalComponent, decorators: [{
|
|
10830
11051
|
type: Component,
|
|
@@ -10874,7 +11095,7 @@ class SearchComponent {
|
|
|
10874
11095
|
this.searchClick.emit(this.data);
|
|
10875
11096
|
}
|
|
10876
11097
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10877
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SearchComponent, isStandalone: false, selector: "spa-search", inputs: { config: "config", smallScreen: "smallScreen", tableDataSource: "tableDataSource" }, outputs: { searchClick: "searchClick" }, ngImport: i0, template: "\r\n<div class=\"tin-between\">\r\n\r\n <div class=\"col tin-row\">\r\n\r\n <div *ngFor=\"let field of config.fields\">\r\n\r\n <spa-option \r\n [type]=\"field.type\" \r\n [required]=\"field.required\" \r\n [show]=\"field.show\" \r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [options]=\"field.options\" \r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\" \r\n [optionValue]=\"field.optionValue ?? 'value'\" \r\n [(value)]=\"data[field.name]\" (enterPress)=\"search()\"\r\n [infoMessage]=\"field.infoMessage\" \r\n [suffix]=\"field.suffix\" \r\n [copyContent]=\"field.copyContent\" \r\n [loadAction]=\"field.loadAction\"\r\n ></spa-option>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"col-2 tin-end\">\r\n <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.length > 10)\" [showButton]=\"false\" [data]=\"tableDataSource\" ></spa-filter>\r\n <button mat-icon-button color=\"primary\" (click)=\"search()\" matTooltip=\"Search\" matTooltipPosition=\"right\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".tin-row{column-gap:30px;row-gap:0px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
11098
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SearchComponent, isStandalone: false, selector: "spa-search", inputs: { config: "config", smallScreen: "smallScreen", tableDataSource: "tableDataSource" }, outputs: { searchClick: "searchClick" }, ngImport: i0, template: "\r\n<div class=\"tin-between\">\r\n\r\n <div class=\"col tin-row\">\r\n\r\n <div *ngFor=\"let field of config.fields\">\r\n\r\n <spa-option \r\n [type]=\"field.type\" \r\n [required]=\"field.required\" \r\n [show]=\"field.show\" \r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [options]=\"field.options\" \r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\" \r\n [optionValue]=\"field.optionValue ?? 'value'\" \r\n [(value)]=\"data[field.name]\" (enterPress)=\"search()\"\r\n [infoMessage]=\"field.infoMessage\" \r\n [suffix]=\"field.suffix\" \r\n [copyContent]=\"field.copyContent\" \r\n [loadAction]=\"field.loadAction\"\r\n ></spa-option>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"col-2 tin-end\">\r\n <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.length > 10)\" [showButton]=\"false\" [data]=\"tableDataSource\" ></spa-filter>\r\n <button mat-icon-button color=\"primary\" (click)=\"search()\" matTooltip=\"Search\" matTooltipPosition=\"right\">\r\n <mat-icon>search</mat-icon>\r\n </button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".tin-row{column-gap:30px;row-gap:0px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FilterComponent, selector: "spa-filter", inputs: ["flatButtons", "showText", "showButton", "smallScreen", "data"], outputs: ["refreshClick"] }, { kind: "component", type: OptionComponent, selector: "spa-option", inputs: ["options", "optionValue", "optionDisplay", "readonly", "type", "value", "display", "show", "required", "infoMessage", "copyContent", "suffix", "loadAction"], outputs: ["valueChange", "enterPress"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
10878
11099
|
}
|
|
10879
11100
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SearchComponent, decorators: [{
|
|
10880
11101
|
type: Component,
|
|
@@ -11033,7 +11254,7 @@ class TableHeaderComponent {
|
|
|
11033
11254
|
return this.buttonService.getButtonColor(button, row);
|
|
11034
11255
|
}
|
|
11035
11256
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableHeaderComponent, deps: [{ token: ButtonService }, { token: DialogService }, { token: MessageService }, { token: CsvService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11036
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableHeaderComponent, isStandalone: false, selector: "app-table-header", inputs: { lastSearch: "lastSearch", config: "config", hideTitle: "hideTitle", tableDataSource: "tableDataSource", tileConfig: "tileConfig", smallScreen: "smallScreen", tileReload: "tileReload", showFilterButton: "showFilterButton", data: "data", tileData: "tileData" }, outputs: { createClick: "createClick", customClick: "customClick", refreshClick: "refreshClick", tileClick: "tileClick", tileUnClick: "tileUnClick" }, ngImport: i0, template: "<!--Tiles Top Position -->\r\n<ng-container *ngIf=\"config.tileConfig && !smallScreen && config.tileConfig.headerPosition == 'top'\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n</ng-container>\r\n\r\n<div class=\"top\">\r\n\r\n <!-- buttons -->\r\n <div class=\"tin-row\" style=\"margin-right: 10px;\" *ngIf=\"getHeaderButtons().length > 0\" >\r\n\r\n <ng-container *ngFor=\"let button of getHeaderButtons()\">\r\n <ng-container *ngIf=\"testVisible(button)\" >\r\n <button *ngIf=\"!config.flatButtons\" mat-raised-button color=\"primary\" [disabled]=\"testDisabled(button)\" (click)=\"onButtonClick(button)\" >\r\n {{button.display}}\r\n </button>\r\n <button *ngIf=\"config.flatButtons\" mat-stroked-button [disabled]=\"testDisabled(button)\" (click)=\"onButtonClick(button)\" [ngStyle]=\"{'color': getButtonColor(button, config.parentData)}\">\r\n {{button.display}}\r\n </button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </div>\r\n <div *ngIf=\"getHeaderButtons().length == 0 && config.holdHeaderButtonSpace || getHeaderButtons().length == 0 && !config.tileConfig\"></div>\r\n\r\n <!-- tiles -->\r\n <div *ngIf=\"config.tileConfig && !smallScreen && (!config.tileConfig.headerPosition || config.tileConfig.headerPosition == 'middle')\" style=\"min-width: 75%;\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n </div>\r\n\r\n <!-- filter -->\r\n <div class=\"tin-row d-flex justify-content-end\" >\r\n\r\n <button *ngIf=\"config.download && testVisibleHeaderButton(config.download)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Download\" matTooltipPosition=\"above\" color=\"primary\" (click)=\"onDownloadClick()\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"config.upload && testVisibleHeaderButton(config.upload)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Upload\" matTooltipPosition=\"above\" color=\"primary\" (click)=\"onUploadClick()\">\r\n <mat-icon>upload</mat-icon>\r\n </button>\r\n\r\n <div *ngIf=\"config.showFilter\" >\r\n <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.data?.length > 10)\" [showButton]=\"showFilterButton\" [data]=\"tableDataSource\" [flatButtons]=\"config.flatButtons\" [smallScreen]=\"smallScreen\" (refreshClick)=\"onRefreshClick()\"></spa-filter> <!-- Changed: Use .data.length for MatTableDataSource, pass smallScreen for compact width -->\r\n </div>\r\n <div *ngIf=\"!config.showFilter && config.holdFilterSpace\"></div>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<div *ngIf=\"config.tileConfig && smallScreen\" style=\"width: 100%;\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\"[lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n</div>\r\n\r\n<!-- <div *ngIf=\"config.title && !hideTitle\" class=\"title\">\r\n {{config.title | camelToWords}}\r\n</div> -->\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;row-gap:8px;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.header-action-btn{width:20px!important;height:20px!important}.header-action-btn mat-icon{font-size:18px!important;margin-top:0!important}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.tin-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
11257
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableHeaderComponent, isStandalone: false, selector: "app-table-header", inputs: { lastSearch: "lastSearch", config: "config", hideTitle: "hideTitle", tableDataSource: "tableDataSource", tileConfig: "tileConfig", smallScreen: "smallScreen", tileReload: "tileReload", showFilterButton: "showFilterButton", data: "data", tileData: "tileData" }, outputs: { createClick: "createClick", customClick: "customClick", refreshClick: "refreshClick", tileClick: "tileClick", tileUnClick: "tileUnClick" }, ngImport: i0, template: "<!--Tiles Top Position -->\r\n<ng-container *ngIf=\"config.tileConfig && !smallScreen && config.tileConfig.headerPosition == 'top'\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n</ng-container>\r\n\r\n<div class=\"top\">\r\n\r\n <!-- buttons -->\r\n <div class=\"tin-row\" style=\"margin-right: 10px;\" *ngIf=\"getHeaderButtons().length > 0\" >\r\n\r\n <ng-container *ngFor=\"let button of getHeaderButtons()\">\r\n <ng-container *ngIf=\"testVisible(button)\" >\r\n <button *ngIf=\"!config.flatButtons\" mat-raised-button color=\"primary\" [disabled]=\"testDisabled(button)\" (click)=\"onButtonClick(button)\" >\r\n {{button.display}}\r\n </button>\r\n <button *ngIf=\"config.flatButtons\" mat-stroked-button [disabled]=\"testDisabled(button)\" (click)=\"onButtonClick(button)\" [ngStyle]=\"{'color': getButtonColor(button, config.parentData)}\">\r\n {{button.display}}\r\n </button>\r\n </ng-container>\r\n </ng-container>\r\n\r\n </div>\r\n <div *ngIf=\"getHeaderButtons().length == 0 && config.holdHeaderButtonSpace || getHeaderButtons().length == 0 && !config.tileConfig\"></div>\r\n\r\n <!-- tiles -->\r\n <div *ngIf=\"config.tileConfig && !smallScreen && (!config.tileConfig.headerPosition || config.tileConfig.headerPosition == 'middle')\" style=\"min-width: 75%;\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n </div>\r\n\r\n <!-- filter -->\r\n <div class=\"tin-row d-flex justify-content-end\" >\r\n\r\n <button *ngIf=\"config.download && testVisibleHeaderButton(config.download)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Download\" matTooltipPosition=\"above\" color=\"primary\" (click)=\"onDownloadClick()\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n\r\n <button *ngIf=\"config.upload && testVisibleHeaderButton(config.upload)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Upload\" matTooltipPosition=\"above\" color=\"primary\" (click)=\"onUploadClick()\">\r\n <mat-icon>upload</mat-icon>\r\n </button>\r\n\r\n <div *ngIf=\"config.showFilter\" >\r\n <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.data?.length > 10)\" [showButton]=\"showFilterButton\" [data]=\"tableDataSource\" [flatButtons]=\"config.flatButtons\" [smallScreen]=\"smallScreen\" (refreshClick)=\"onRefreshClick()\"></spa-filter> <!-- Changed: Use .data.length for MatTableDataSource, pass smallScreen for compact width -->\r\n </div>\r\n <div *ngIf=\"!config.showFilter && config.holdFilterSpace\"></div>\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n<div *ngIf=\"config.tileConfig && smallScreen\" style=\"width: 100%;\">\r\n <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\"[lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\r\n</div>\r\n\r\n<!-- <div *ngIf=\"config.title && !hideTitle\" class=\"title\">\r\n {{config.title | camelToWords}}\r\n</div> -->\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;row-gap:8px;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.header-action-btn{width:20px!important;height:20px!important}.header-action-btn mat-icon{font-size:18px!important;margin-top:0!important}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.tin-row{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: FilterComponent, selector: "spa-filter", inputs: ["flatButtons", "showText", "showButton", "smallScreen", "data"], outputs: ["refreshClick"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }] }); }
|
|
11037
11258
|
}
|
|
11038
11259
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableHeaderComponent, decorators: [{
|
|
11039
11260
|
type: Component,
|
|
@@ -11132,7 +11353,7 @@ class TableRowComponent {
|
|
|
11132
11353
|
return false;
|
|
11133
11354
|
}
|
|
11134
11355
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableRowComponent, deps: [{ token: ButtonService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11135
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableRowComponent, isStandalone: false, selector: "app-table-row", inputs: { column: "column", row: "row", config: "config", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick", columnClick: "columnClick", showBannerEvent: "showBannerEvent" }, ngImport: i0, template: "<ng-container [ngSwitch]=\"column.type\">\r\n <ng-container *ngSwitchCase=\"'checkbox'\">\r\n <spa-check [value]=\"row[column.name]\" [readonly]=\"true\"></spa-check>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <spa-select-lite [options]=\"column.options\" [optionDisplay]=\"column.optionDisplay\" [optionValue]=\"column.optionValue\" [(value)]=\"row[column.name]\" width=\"90%\"></spa-select-lite>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'chip'\">\r\n <button mat-stroked-button (click)=\"onColumnClick(column, row)\" [ngStyle]=\"{'background-color': getColorOnCondition(row, column), 'color': 'rgba(0, 0, 0, 0.87)', 'border': 'none'}\">{{row[column.name]}}</button>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'icon'\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy HH:mm'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'datetimesec'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy HH:mm:ss'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'money'\">\r\n <label [ngStyle]=\"{'color': getColorOnCondition(row, column) }\">{{row[column.name] | currency:'':''}}</label>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'button'\">\r\n <button mat-stroked-button (click)=\"onColumnClick(column, row)\" [ngStyle]=\"{'color': getColorOnCondition(row, column)}\" >{{row[column.name]}}</button>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchDefault>\r\n <label [ngStyle]=\"{'color': getColorOnCondition(row, column) }\">\r\n <ng-container *ngIf=\"column.type === 'number'\">\r\n {{row[column.name] | number:'1.0-2'}}\r\n </ng-container>\r\n <ng-container *ngIf=\"column.type !== 'number'\">\r\n {{textDisplayed(row, column)}}\r\n </ng-container>\r\n </label>\r\n <mat-icon class=\"col-icon\" *ngIf=\"textTruncated(row, column)\" matTooltip='Show more' matTooltipPosition=\"above\" (click)=\"showBanner(row[column.name])\">more_horiz</mat-icon>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n</ng-container>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px;vertical-align:middle}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.table-chip{font-size:14px!important;font-weight:500!important;letter-spacing:.25px!important;padding:8px 20px!important;min-height:36px!important;height:auto!important;border-radius:24px!important;cursor:pointer!important;transition:all .2s ease!important;color:#000000de!important;box-shadow:none!important;border:1.5px solid rgba(0,0,0,.2)!important;text-transform:none!important;white-space:nowrap!important;background-clip:padding-box!important}.table-chip:hover{transform:none!important;box-shadow:none!important;filter:brightness(.96)!important;border-color:#0000004d!important}.table-chip:active{transform:scale(.98)!important;box-shadow:none!important;transition-duration:.1s!important;filter:brightness(.92)!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i4.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: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: SelectLiteComponent, selector: "spa-select-lite" }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
11356
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableRowComponent, isStandalone: false, selector: "app-table-row", inputs: { column: "column", row: "row", config: "config", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick", columnClick: "columnClick", showBannerEvent: "showBannerEvent" }, ngImport: i0, template: "<ng-container [ngSwitch]=\"column.type\">\r\n <ng-container *ngSwitchCase=\"'checkbox'\">\r\n <spa-check [value]=\"row[column.name]\" [readonly]=\"true\"></spa-check>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <spa-select-lite [options]=\"column.options\" [optionDisplay]=\"column.optionDisplay\" [optionValue]=\"column.optionValue\" [(value)]=\"row[column.name]\" width=\"90%\"></spa-select-lite>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'chip'\">\r\n <button mat-stroked-button (click)=\"onColumnClick(column, row)\" [ngStyle]=\"{'background-color': getColorOnCondition(row, column), 'color': 'rgba(0, 0, 0, 0.87)', 'border': 'none'}\">{{row[column.name]}}</button>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'icon'\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy HH:mm'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'datetimesec'\">\r\n {{row[column.name] | date : 'dd/MM/yyyy HH:mm:ss'}}\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'money'\">\r\n <label [ngStyle]=\"{'color': getColorOnCondition(row, column) }\">{{row[column.name] | currency:'':''}}</label>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'button'\">\r\n <button mat-stroked-button (click)=\"onColumnClick(column, row)\" [ngStyle]=\"{'color': getColorOnCondition(row, column)}\" >{{row[column.name]}}</button>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchDefault>\r\n <label [ngStyle]=\"{'color': getColorOnCondition(row, column) }\">\r\n <ng-container *ngIf=\"column.type === 'number'\">\r\n {{row[column.name] | number:'1.0-2'}}\r\n </ng-container>\r\n <ng-container *ngIf=\"column.type !== 'number'\">\r\n {{textDisplayed(row, column)}}\r\n </ng-container>\r\n </label>\r\n <mat-icon class=\"col-icon\" *ngIf=\"textTruncated(row, column)\" matTooltip='Show more' matTooltipPosition=\"above\" (click)=\"showBanner(row[column.name])\">more_horiz</mat-icon>\r\n <mat-icon class=\"col-icon\" *ngIf=\"column.icon && testIconCondition(row, column.icon)\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [ngStyle]=\"{'color':column.icon?.color}\">{{column.icon.name }}</mat-icon>\r\n <ng-container *ngFor=\"let icon of column.icons\">\r\n <mat-icon class=\"col-icon\" *ngIf=\"testIconCondition(row, icon)\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [ngStyle]=\"{'color':icon?.color}\">{{icon.name }}</mat-icon>\r\n </ng-container>\r\n </ng-container>\r\n</ng-container>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px;vertical-align:middle}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.table-chip{font-size:14px!important;font-weight:500!important;letter-spacing:.25px!important;padding:8px 20px!important;min-height:36px!important;height:auto!important;border-radius:24px!important;cursor:pointer!important;transition:all .2s ease!important;color:#000000de!important;box-shadow:none!important;border:1.5px solid rgba(0,0,0,.2)!important;text-transform:none!important;white-space:nowrap!important;background-clip:padding-box!important}.table-chip:hover{transform:none!important;box-shadow:none!important;filter:brightness(.96)!important;border-color:#0000004d!important}.table-chip:active{transform:scale(.98)!important;box-shadow:none!important;transition-duration:.1s!important;filter:brightness(.92)!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i4.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: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: SelectLiteComponent, selector: "spa-select-lite" }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
11136
11357
|
}
|
|
11137
11358
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableRowComponent, decorators: [{
|
|
11138
11359
|
type: Component,
|
|
@@ -11230,7 +11451,7 @@ class TableActionComponent {
|
|
|
11230
11451
|
: [];
|
|
11231
11452
|
}
|
|
11232
11453
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableActionComponent, deps: [{ token: ButtonService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11233
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableActionComponent, isStandalone: false, selector: "app-table-action", inputs: { displayedButtons: "displayedButtons", config: "config", row: "row", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick" }, ngImport: i0, template: "<ng-container *ngFor=\"let button of visibleButtons\">\r\n\r\n <ng-container *ngIf=\"button.name != 'create' && testVisible(row, button.name)\">\r\n <!-- <button *ngIf=\"!config.flatButtons\" mat-mini-fab [matTooltip]=\"button.tip ?? button.name | titlecase\" matTooltipPosition=\"above\" style=\"margin-right:5px\" [ngStyle]=\"{'background-color': getButtonColor(button, row)}\" [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon>{{getIcon(button.name)}}</mat-icon>\r\n </button> -->\r\n\r\n <button mat-icon-button [matTooltip]=\"button.tip ?? button.name | titlecase\" matTooltipPosition=\"above\" style=\"margin-right:5px\" [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"button.name != 'create' && !testVisible(row, button.name) && config?.collapseButtons === false\">\r\n <label style=\"margin-right: 35px;\"></label>\r\n </ng-container>\r\n\r\n</ng-container>\r\n\r\n<button *ngIf=\"overflowButtons.length > 0\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'More actions'\" matTooltipPosition=\"above\">\r\n <mat-icon>more_vert</mat-icon>\r\n</button>\r\n\r\n<mat-menu #menu=\"matMenu\">\r\n <ng-container *ngFor=\"let button of overflowButtons\">\r\n <button *ngIf=\"testVisible(row, button.name)\" mat-menu-item [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">\r\n {{getIcon(button.name)}}\r\n </mat-icon>\r\n <span>{{button.tip ?? button.name | titlecase}}</span>\r\n </button>\r\n </ng-container>\r\n</mat-menu>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
11454
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TableActionComponent, isStandalone: false, selector: "app-table-action", inputs: { displayedButtons: "displayedButtons", config: "config", row: "row", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick" }, ngImport: i0, template: "<ng-container *ngFor=\"let button of visibleButtons\">\r\n\r\n <ng-container *ngIf=\"button.name != 'create' && testVisible(row, button.name)\">\r\n <!-- <button *ngIf=\"!config.flatButtons\" mat-mini-fab [matTooltip]=\"button.tip ?? button.name | titlecase\" matTooltipPosition=\"above\" style=\"margin-right:5px\" [ngStyle]=\"{'background-color': getButtonColor(button, row)}\" [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon>{{getIcon(button.name)}}</mat-icon>\r\n </button> -->\r\n\r\n <button mat-icon-button [matTooltip]=\"button.tip ?? button.name | titlecase\" matTooltipPosition=\"above\" style=\"margin-right:5px\" [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"button.name != 'create' && !testVisible(row, button.name) && config?.collapseButtons === false\">\r\n <label style=\"margin-right: 35px;\"></label>\r\n </ng-container>\r\n\r\n</ng-container>\r\n\r\n<button *ngIf=\"overflowButtons.length > 0\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'More actions'\" matTooltipPosition=\"above\">\r\n <mat-icon>more_vert</mat-icon>\r\n</button>\r\n\r\n<mat-menu #menu=\"matMenu\">\r\n <ng-container *ngFor=\"let button of overflowButtons\">\r\n <button *ngIf=\"testVisible(row, button.name)\" mat-menu-item [disabled]=\"testDisabled(row, button.name)\" (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">\r\n {{getIcon(button.name)}}\r\n </mat-icon>\r\n <span>{{button.tip ?? button.name | titlecase}}</span>\r\n </button>\r\n </ng-container>\r\n</mat-menu>\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#e5e5e5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }] }); }
|
|
11234
11455
|
}
|
|
11235
11456
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TableActionComponent, decorators: [{
|
|
11236
11457
|
type: Component,
|
|
@@ -11375,7 +11596,7 @@ class CardsComponent {
|
|
|
11375
11596
|
return this.displayedButtons?.find(x => x.name === name) || null;
|
|
11376
11597
|
}
|
|
11377
11598
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: CardsComponent, deps: [{ token: ButtonService }, { token: ConditionService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11378
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: CardsComponent, isStandalone: false, selector: "spa-cards", inputs: { config: "config", dataSource: "dataSource", displayedButtons: "displayedButtons", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick", columnClick: "columnClick", showBannerEvent: "showBannerEvent" }, ngImport: i0, template: "<div class=\"cards-container\" [style.grid-template-columns]=\"'repeat(' + getColumnCount() + ', 1fr)'\">\r\n <mat-card *ngFor=\"let row of dataSource\" [class]=\"getElevationClass()\" class=\"card-item\">\r\n <mat-card-header>\r\n <mat-card-title>{{getTitleValue(row)}}</mat-card-title>\r\n <mat-card-subtitle *ngIf=\"getSubtitleValue(row)\">{{getSubtitleValue(row)}}</mat-card-subtitle>\r\n </mat-card-header>\r\n \r\n <mat-card-content>\r\n <div class=\"content-item\" *ngFor=\"let content of getContentValues(row)\">\r\n <span class=\"label\">{{content.label}}:</span>\r\n <span class=\"value\">{{content.value}}</span>\r\n </div>\r\n </mat-card-content>\r\n \r\n <mat-card-actions align=\"end\">\r\n <ng-container *ngFor=\"let button of displayedButtons\">\r\n <button *ngIf=\"!config.flatButtons && testVisible(row, button.name)\" \r\n mat-mini-fab\r\n [matTooltip]=\"button.tip ?? button.name | titlecase\"\r\n matTooltipPosition=\"above\"\r\n [ngStyle]=\"{'background-color': getButtonColor(button, row)}\"\r\n [disabled]=\"testDisabled(row, button.name)\"\r\n (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon>{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n \r\n <button *ngIf=\"config.flatButtons && testVisible(row, button.name)\"\r\n mat-icon-button \r\n [matTooltip]=\"button.tip ?? button.name | titlecase\"\r\n matTooltipPosition=\"above\"\r\n [disabled]=\"testDisabled(row, button.name)\"\r\n (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </mat-card-actions>\r\n </mat-card>\r\n </div>", styles: [".cards-container{display:grid;gap:20px;padding:20px}.card-item{height:100%;transition:transform .2s}.card-item:hover{transform:translateY(-5px)}.content-item{margin:8px 0;display:grid;grid-template-columns:minmax(33%,1fr) minmax(67%,2fr);gap:8px;align-items:baseline}.label{font-weight:500;color:#000000b3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.value{text-align:left;word-break:break-word}mat-card-actions{padding:16px;display:flex;gap:8px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i6$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i6$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i6$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type:
|
|
11599
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: CardsComponent, isStandalone: false, selector: "spa-cards", inputs: { config: "config", dataSource: "dataSource", displayedButtons: "displayedButtons", smallScreen: "smallScreen" }, outputs: { actionClick: "actionClick", columnClick: "columnClick", showBannerEvent: "showBannerEvent" }, ngImport: i0, template: "<div class=\"cards-container\" [style.grid-template-columns]=\"'repeat(' + getColumnCount() + ', 1fr)'\">\r\n <mat-card *ngFor=\"let row of dataSource\" [class]=\"getElevationClass()\" class=\"card-item\">\r\n <mat-card-header>\r\n <mat-card-title>{{getTitleValue(row)}}</mat-card-title>\r\n <mat-card-subtitle *ngIf=\"getSubtitleValue(row)\">{{getSubtitleValue(row)}}</mat-card-subtitle>\r\n </mat-card-header>\r\n \r\n <mat-card-content>\r\n <div class=\"content-item\" *ngFor=\"let content of getContentValues(row)\">\r\n <span class=\"label\">{{content.label}}:</span>\r\n <span class=\"value\">{{content.value}}</span>\r\n </div>\r\n </mat-card-content>\r\n \r\n <mat-card-actions align=\"end\">\r\n <ng-container *ngFor=\"let button of displayedButtons\">\r\n <button *ngIf=\"!config.flatButtons && testVisible(row, button.name)\" \r\n mat-mini-fab\r\n [matTooltip]=\"button.tip ?? button.name | titlecase\"\r\n matTooltipPosition=\"above\"\r\n [ngStyle]=\"{'background-color': getButtonColor(button, row)}\"\r\n [disabled]=\"testDisabled(row, button.name)\"\r\n (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon>{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n \r\n <button *ngIf=\"config.flatButtons && testVisible(row, button.name)\"\r\n mat-icon-button \r\n [matTooltip]=\"button.tip ?? button.name | titlecase\"\r\n matTooltipPosition=\"above\"\r\n [disabled]=\"testDisabled(row, button.name)\"\r\n (click)=\"onActionClick(button.name, row)\">\r\n <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">{{getIcon(button.name)}}</mat-icon>\r\n </button>\r\n </ng-container>\r\n </mat-card-actions>\r\n </mat-card>\r\n </div>", styles: [".cards-container{display:grid;gap:20px;padding:20px}.card-item{height:100%;transition:transform .2s}.card-item:hover{transform:translateY(-5px)}.content-item{margin:8px 0;display:grid;grid-template-columns:minmax(33%,1fr) minmax(67%,2fr);gap:8px;align-items:baseline}.label{font-weight:500;color:#000000b3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.value{text-align:left;word-break:break-word}mat-card-actions{padding:16px;display:flex;gap:8px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i6$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i6$1.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i6$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }] }); }
|
|
11379
11600
|
}
|
|
11380
11601
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: CardsComponent, decorators: [{
|
|
11381
11602
|
type: Component,
|
|
@@ -11591,7 +11812,7 @@ class GroupsComponent {
|
|
|
11591
11812
|
});
|
|
11592
11813
|
}
|
|
11593
11814
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: GroupsComponent, deps: [{ token: ConditionService }, { token: ButtonService }, { token: DataServiceLib }, { token: i2$1.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11594
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: GroupsComponent, isStandalone: false, selector: "spa-groups", inputs: { config: "config", dataSource: "dataSource", displayedButtons: "displayedButtons" }, outputs: { actionClick: "actionClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"groups-container\" cdkDropListGroup>\r\n\r\n <mat-card *ngFor=\"let group of groupedData\" class=\"group-card\">\r\n\r\n <div class=\"group-header\">\r\n <div class=\"header-left\">\r\n <mat-icon *ngIf=\"group.icon\" [style.color]=\"group.color\" class=\"group-icon\">{{group.icon}}</mat-icon>\r\n <label class=\"group-title\">{{group.displayName}}</label>\r\n <label *ngIf=\"config.groupConfig.showGroupCount !== false\" class=\"group-count\">({{group.items.length}})</label>\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n <button\r\n *ngFor=\"let button of getVisibleHeaderButtons(group)\"\r\n mat-icon-button\r\n [matTooltip]=\"getHeaderButtonTooltip(button)\"\r\n matTooltipPosition=\"above\"\r\n [style.color]=\"getHeaderButtonColor(button, group)\"\r\n [disabled]=\"isHeaderButtonDisabled(button, group)\"\r\n (click)=\"headerButtonClicked(button, group)\">\r\n <mat-icon>{{getHeaderButtonIcon(button)}}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"group-divider\" />\r\n\r\n <!-- Empty state: show when no items and drag is disabled -->\r\n <div *ngIf=\"group.items.length === 0 && !config.groupConfig.dragEnabled\" class=\"empty-state\">\r\n <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\r\n </div>\r\n\r\n <!-- Chip set with CDK drop list for drag-drop support -->\r\n <mat-chip-set\r\n *ngIf=\"group.items.length > 0 || config.groupConfig.dragEnabled\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.items\"\r\n [cdkDropListDisabled]=\"!config.groupConfig.dragEnabled\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"drop-list\">\r\n\r\n <!-- Empty state inside drop list when drag is enabled -->\r\n <div *ngIf=\"group.items.length === 0\" class=\"empty-state drop-empty\">\r\n <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\r\n </div>\r\n\r\n <mat-chip\r\n *ngFor=\"let item of group.items\"\r\n cdkDrag [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!config.groupConfig.dragEnabled\"\r\n [matMenuTriggerFor]=\"config.groupConfig.contextMenuEnabled !== false ? itemMenu : null\"\r\n [matMenuTriggerData]=\"{item: item, group: group}\"\r\n #chipTrigger=\"matMenuTrigger\">\r\n\r\n <!-- Drag placeholder -->\r\n <div *cdkDragPlaceholder class=\"drag-placeholder\"></div>\r\n\r\n <mat-icon\r\n *ngIf=\"getItemIcon(item)\"\r\n [style.color]=\"getItemIconColor(item)\"\r\n class=\"chip-icon\">\r\n {{getItemIcon(item)}}\r\n </mat-icon>\r\n\r\n <label class=\"chip-text\">{{getItemText(item)}}</label>\r\n\r\n <ng-container *ngFor=\"let additionalIcon of getVisibleAdditionalIcons(item)\">\r\n <mat-icon\r\n [style.color]=\"additionalIcon.color\"\r\n [matTooltip]=\"getIconTooltip(additionalIcon, item)\"\r\n matTooltipPosition=\"above\"\r\n class=\"chip-additional-icon\">\r\n {{additionalIcon.name}}\r\n </mat-icon>\r\n </ng-container>\r\n\r\n </mat-chip>\r\n </mat-chip-set>\r\n\r\n </mat-card>\r\n\r\n</div>\r\n\r\n<mat-menu #itemMenu=\"matMenu\">\r\n <ng-template matMenuContent let-item=\"item\" let-group=\"group\">\r\n <button\r\n *ngFor=\"let button of getVisibleButtons(item)\"\r\n mat-menu-item\r\n [disabled]=\"isButtonDisabled(button, item)\"\r\n (click)=\"itemActionClicked(button.name, item, group)\">\r\n <mat-icon [style.color]=\"getButtonIconColor(button, item)\">{{getButtonIcon(button)}}</mat-icon>\r\n <span>{{button.display ?? button.tip ?? (button.name | titlecase)}}</span>\r\n </button>\r\n </ng-template>\r\n</mat-menu>\r\n", styles: [".groups-container{display:flex;flex-direction:column;gap:20px;padding-right:10px;margin-left:0}.group-card{width:100%;margin-bottom:0;padding:16px}.group-header{display:flex;justify-content:space-between;align-items:center;padding:5px 0}.header-left{display:flex;align-items:center;gap:5px}.header-right{display:flex;align-items:center;gap:4px}.group-icon{padding-top:5px;margin-right:5px;font-size:24px;width:24px;height:24px}.group-title{font-size:24px;font-weight:300}.group-count{font-size:12px;font-weight:300;margin-left:5px}.group-divider{margin-top:5px;margin-bottom:10px}.empty-state{display:flex;justify-content:center;align-items:center;padding:10px}.empty-state label{color:#757575;font-style:italic}mat-chip-list{margin-top:0}mat-chip{cursor:pointer;margin:4px}.chip-text{margin-right:5px;margin-bottom:5px}button[mat-icon-button]{width:32px;height:32px}button[mat-icon-button] mat-icon{font-size:18px;margin-top:-3px}.drop-list{min-height:40px}.drop-empty{padding:5px 10px}.drag-placeholder{display:inline-block;min-width:80px;height:32px;border:2px dashed #ccc;border-radius:16px;background:#f5f5f5;margin:4px;transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;opacity:.9;border-radius:16px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-receiving{border:2px dashed #90caf9;border-radius:8px;background:#90caf90d}.cdk-drop-list-dragging mat-chip:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i6.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "directive", type:
|
|
11815
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: GroupsComponent, isStandalone: false, selector: "spa-groups", inputs: { config: "config", dataSource: "dataSource", displayedButtons: "displayedButtons" }, outputs: { actionClick: "actionClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"groups-container\" cdkDropListGroup>\r\n\r\n <mat-card *ngFor=\"let group of groupedData\" class=\"group-card\">\r\n\r\n <div class=\"group-header\">\r\n <div class=\"header-left\">\r\n <mat-icon *ngIf=\"group.icon\" [style.color]=\"group.color\" class=\"group-icon\">{{group.icon}}</mat-icon>\r\n <label class=\"group-title\">{{group.displayName}}</label>\r\n <label *ngIf=\"config.groupConfig.showGroupCount !== false\" class=\"group-count\">({{group.items.length}})</label>\r\n </div>\r\n\r\n <div class=\"header-right\">\r\n <button\r\n *ngFor=\"let button of getVisibleHeaderButtons(group)\"\r\n mat-icon-button\r\n [matTooltip]=\"getHeaderButtonTooltip(button)\"\r\n matTooltipPosition=\"above\"\r\n [style.color]=\"getHeaderButtonColor(button, group)\"\r\n [disabled]=\"isHeaderButtonDisabled(button, group)\"\r\n (click)=\"headerButtonClicked(button, group)\">\r\n <mat-icon>{{getHeaderButtonIcon(button)}}</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <hr class=\"group-divider\" />\r\n\r\n <!-- Empty state: show when no items and drag is disabled -->\r\n <div *ngIf=\"group.items.length === 0 && !config.groupConfig.dragEnabled\" class=\"empty-state\">\r\n <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\r\n </div>\r\n\r\n <!-- Chip set with CDK drop list for drag-drop support -->\r\n <mat-chip-set\r\n *ngIf=\"group.items.length > 0 || config.groupConfig.dragEnabled\"\r\n cdkDropList\r\n [cdkDropListData]=\"group.items\"\r\n [cdkDropListDisabled]=\"!config.groupConfig.dragEnabled\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"drop-list\">\r\n\r\n <!-- Empty state inside drop list when drag is enabled -->\r\n <div *ngIf=\"group.items.length === 0\" class=\"empty-state drop-empty\">\r\n <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\r\n </div>\r\n\r\n <mat-chip\r\n *ngFor=\"let item of group.items\"\r\n cdkDrag [cdkDragData]=\"item\"\r\n [cdkDragDisabled]=\"!config.groupConfig.dragEnabled\"\r\n [matMenuTriggerFor]=\"config.groupConfig.contextMenuEnabled !== false ? itemMenu : null\"\r\n [matMenuTriggerData]=\"{item: item, group: group}\"\r\n #chipTrigger=\"matMenuTrigger\">\r\n\r\n <!-- Drag placeholder -->\r\n <div *cdkDragPlaceholder class=\"drag-placeholder\"></div>\r\n\r\n <mat-icon\r\n *ngIf=\"getItemIcon(item)\"\r\n [style.color]=\"getItemIconColor(item)\"\r\n class=\"chip-icon\">\r\n {{getItemIcon(item)}}\r\n </mat-icon>\r\n\r\n <label class=\"chip-text\">{{getItemText(item)}}</label>\r\n\r\n <ng-container *ngFor=\"let additionalIcon of getVisibleAdditionalIcons(item)\">\r\n <mat-icon\r\n [style.color]=\"additionalIcon.color\"\r\n [matTooltip]=\"getIconTooltip(additionalIcon, item)\"\r\n matTooltipPosition=\"above\"\r\n class=\"chip-additional-icon\">\r\n {{additionalIcon.name}}\r\n </mat-icon>\r\n </ng-container>\r\n\r\n </mat-chip>\r\n </mat-chip-set>\r\n\r\n </mat-card>\r\n\r\n</div>\r\n\r\n<mat-menu #itemMenu=\"matMenu\">\r\n <ng-template matMenuContent let-item=\"item\" let-group=\"group\">\r\n <button\r\n *ngFor=\"let button of getVisibleButtons(item)\"\r\n mat-menu-item\r\n [disabled]=\"isButtonDisabled(button, item)\"\r\n (click)=\"itemActionClicked(button.name, item, group)\">\r\n <mat-icon [style.color]=\"getButtonIconColor(button, item)\">{{getButtonIcon(button)}}</mat-icon>\r\n <span>{{button.display ?? button.tip ?? (button.name | titlecase)}}</span>\r\n </button>\r\n </ng-template>\r\n</mat-menu>\r\n", styles: [".groups-container{display:flex;flex-direction:column;gap:20px;padding-right:10px;margin-left:0}.group-card{width:100%;margin-bottom:0;padding:16px}.group-header{display:flex;justify-content:space-between;align-items:center;padding:5px 0}.header-left{display:flex;align-items:center;gap:5px}.header-right{display:flex;align-items:center;gap:4px}.group-icon{padding-top:5px;margin-right:5px;font-size:24px;width:24px;height:24px}.group-title{font-size:24px;font-weight:300}.group-count{font-size:12px;font-weight:300;margin-left:5px}.group-divider{margin-top:5px;margin-bottom:10px}.empty-state{display:flex;justify-content:center;align-items:center;padding:10px}.empty-state label{color:#757575;font-style:italic}mat-chip-list{margin-top:0}mat-chip{cursor:pointer;margin:4px}.chip-text{margin-right:5px;margin-bottom:5px}button[mat-icon-button]{width:32px;height:32px}button[mat-icon-button] mat-icon{font-size:18px;margin-top:-3px}.drop-list{min-height:40px}.drop-empty{padding:5px 10px}.drag-placeholder{display:inline-block;min-width:80px;height:32px;border:2px dashed #ccc;border-radius:16px;background:#f5f5f5;margin:4px;transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-preview{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;opacity:.9;border-radius:16px}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drop-list-receiving{border:2px dashed #90caf9;border-radius:8px;background:#90caf90d}.cdk-drop-list-dragging mat-chip:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$4.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i4$4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i6.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i12$1.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: i12$1.CdkDropListGroup, selector: "[cdkDropListGroup]", inputs: ["cdkDropListGroupDisabled"], exportAs: ["cdkDropListGroup"] }, { kind: "directive", type: i12$1.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: i12$1.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }] }); }
|
|
11595
11816
|
}
|
|
11596
11817
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: GroupsComponent, decorators: [{
|
|
11597
11818
|
type: Component,
|
|
@@ -12501,7 +12722,7 @@ class DetailsDialogInternal {
|
|
|
12501
12722
|
}
|
|
12502
12723
|
}
|
|
12503
12724
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialogInternal, deps: [{ token: i1$3.BreakpointObserver }, { token: LoaderService }, { token: DataServiceLib }, { token: MessageService }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: ButtonService }, { token: DialogService }, { token: AuthService }, { token: TableConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12504
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialogInternal, isStandalone: false, selector: "spa-detailsDialog-internal", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select-internal\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n [detailsConfig]=\"field.detailsConfig\"\r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select-internal>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- Changed: Replace mat-tab-group with spa-tabs-lite component -->\r\n <spa-tabs-lite \r\n *ngIf=\"tableConfigs\"\r\n [tableConfigs]=\"tableConfigs\"\r\n [reload]=\"tableReload\"\r\n [parentDetails]=\"details\"\r\n (formRefresh)=\"loadData(formConfig.loadAction, false)\">\r\n </spa-tabs-lite>\r\n\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions>\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\" \r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\" \r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: SelectInternalComponent, selector: "spa-select-internal", inputs: ["detailsConfig"] }, { kind: "component", type: TabsLiteComponent, selector: "spa-tabs-lite", inputs: ["tableConfigs", "reload", "parentDetails"], outputs: ["formRefresh"] }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
12725
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialogInternal, isStandalone: false, selector: "spa-detailsDialog-internal", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select-internal\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n [detailsConfig]=\"field.detailsConfig\"\r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select-internal>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- Changed: Replace mat-tab-group with spa-tabs-lite component -->\r\n <spa-tabs-lite \r\n *ngIf=\"tableConfigs\"\r\n [tableConfigs]=\"tableConfigs\"\r\n [reload]=\"tableReload\"\r\n [parentDetails]=\"details\"\r\n (formRefresh)=\"loadData(formConfig.loadAction, false)\">\r\n </spa-tabs-lite>\r\n\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions>\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\" \r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\" \r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: SelectInternalComponent, selector: "spa-select-internal", inputs: ["detailsConfig"] }, { kind: "component", type: TabsLiteComponent, selector: "spa-tabs-lite", inputs: ["tableConfigs", "reload", "parentDetails"], outputs: ["formRefresh"] }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
12505
12726
|
}
|
|
12506
12727
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialogInternal, decorators: [{
|
|
12507
12728
|
type: Component,
|
|
@@ -13449,7 +13670,7 @@ class DetailsDialog {
|
|
|
13449
13670
|
}
|
|
13450
13671
|
}
|
|
13451
13672
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialog, deps: [{ token: i1$3.BreakpointObserver }, { token: LoaderService }, { token: DataServiceLib }, { token: MessageService }, { token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: ButtonService }, { token: DialogService }, { token: AuthService }, { token: TableConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
13452
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialog, isStandalone: false, selector: "spa-detailsDialog", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n [detailsConfig]=\"field.detailsConfig\"\r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- Changed: Replace mat-tab-group with spa-tabs-internal component -->\r\n <spa-tabs-internal\r\n *ngIf=\"tableConfigs && !(detailsConfig.hideTablesInCreateMode && formConfig?.mode === 'create')\"\r\n [tableConfigs]=\"tableConfigs\"\r\n [reload]=\"tableReload\"\r\n [parentDetails]=\"details\"\r\n (formRefresh)=\"loadData(formConfig.loadAction, false)\">\r\n </spa-tabs-internal>\r\n\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions >\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\"\r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\"\r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["detailsConfig"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: TabsInternalComponent, selector: "spa-tabs-internal", inputs: ["tableConfigs", "reload", "parentDetails"], outputs: ["formRefresh"] }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
13673
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: DetailsDialog, isStandalone: false, selector: "spa-detailsDialog", outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"dialog-container\">\r\n\r\n <div class=\"dialog-content\">\r\n\r\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isProcessing && dataService.appConfig.progressLine\"></mat-progress-bar>\r\n\r\n <div class=\"d-flex justify-content-between align-items-center mt-2\" style=\"padding-left: 24px; padding-right: 24px;\">\r\n\r\n <div>\r\n <label style=\"font-size: 20px; font-weight:500;margin-top: 10px;margin-bottom: 5px;\" >{{titleAction | titlecase}} {{formConfig?.title}}</label>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\r\n\r\n <spa-check *ngIf=\"detailsConfig.autoRefreshConfig\" display=\"Auto Refresh\" [(value)]=\"autoRefreshEnabled\" (valueChange)=\"toggleAutoRefresh()\"></spa-check>\r\n\r\n <div *ngIf=\"formConfig.mode=='view' && editButton && testVisible(details,editButton.name)\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"testDisabled(details,editButton.name)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <button [disabled]=\"isProcessing\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\">cached</mat-icon></button>\r\n \r\n <!-- Added: Top close button when position is 'top' -->\r\n <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"padding-left: 24px; padding-right: 24px;\">\r\n <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n </div>\r\n\r\n <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\r\n\r\n <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\r\n <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\r\n <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\r\n\r\n <div class=\"tin-input\" style=\"font-size:14px\">\r\n\r\n <p *ngIf=\"formConfig && !details\"><em>Loading...</em></p>\r\n\r\n <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\r\n <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\">\r\n <spa-select\r\n [display]=\"field.alias ?? field.name | camelToWords\"\r\n [width]=\"field.width\"\r\n [nullable]=\"field.nullable\"\r\n [options]=\"field.options\"\r\n [masterOptions]=\"field.masterOptions\"\r\n [masterField]=\"field.masterField\"\r\n [optionDisplay]=\"field.optionDisplay ?? 'name'\"\r\n [optionValue]=\"field.optionValue ?? 'value'\"\r\n [(value)]=\"data[field.name]\"\r\n [defaultFirstValue]=\"field.defaultFirstValue\"\r\n [required]=\"testRequired(field)\"\r\n [readonly]=\"testReadOnly(field)\"\r\n [hint]=\"field.hint\"\r\n [detailsConfig]=\"field.detailsConfig\"\r\n [loadAction]=\"field.loadAction\"\r\n [loadIDField]=\"field.loadIDField\"\r\n [field]=\"field\"\r\n [data]=\"data\"\r\n [infoMessage]=\"field.infoMessage\"\r\n [copyContent]=\"field.copyContent\"\r\n (valueChange)=\"selectChanged(field)\"\r\n ></spa-select>\r\n </ng-template>\r\n </spa-form>\r\n\r\n <!-- Changed: Replace mat-tab-group with spa-tabs-internal component -->\r\n <spa-tabs-internal\r\n *ngIf=\"tableConfigs && !(detailsConfig.hideTablesInCreateMode && formConfig?.mode === 'create')\"\r\n [tableConfigs]=\"tableConfigs\"\r\n [reload]=\"tableReload\"\r\n [parentDetails]=\"details\"\r\n (formRefresh)=\"loadData(formConfig.loadAction, false)\">\r\n </spa-tabs-internal>\r\n\r\n </div>\r\n\r\n </mat-dialog-content>\r\n\r\n\r\n </div>\r\n\r\n <mat-dialog-actions >\r\n\r\n <div>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\"\r\n (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <button mat-raised-button [disabled]=\"isProcessing\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\"\r\n (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\r\n </button>\r\n\r\n <ng-container *ngFor=\"let btn of extraButtons\">\r\n <button *ngIf=\"formConfig.mode !== 'create' && testVisible(details,btn.name)\" mat-stroked-button [disabled]=\"isProcessing || testDisabled(details,btn.name)\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\" (click)=\"custom(btn)\" cdkFocusInitial>\r\n <mat-icon *ngIf=\"btn.icon\" [ngStyle]=\"{'color': getButtonColor(btn, details)}\">{{btn.icon.name}}</mat-icon>\r\n {{btn.display ?? btn.name | titlecase}}\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Changed: Bottom close button now uses conditional display and custom text -->\r\n <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\r\n\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\r\n <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create' && deleteButton\"><mat-icon>delete</mat-icon></button>\r\n </div>\r\n\r\n\r\n </mat-dialog-actions>\r\n\r\n\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n", styles: [".top{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:10px;margin-top:10px}.mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.mat-icon-button{width:32px;height:32px}.mat-icon-button mat-icon{font-size:20px;margin-top:-7px}.col-icon{margin-left:10px}.title{margin-top:10px;font-size:larger;font-weight:300}.make-gray{background-color:#f5f5f5}.right-padding{padding-right:10px}.action-buttons-container{display:flex;justify-content:flex-end;align-items:center}.refreshIcon{font-size:22px!important;margin-top:-7px!important}.dialog-container{display:flex;flex-direction:column;height:100%}.dialog-content{flex:1;overflow:hidden;display:flex;flex-direction:column}.dialog-scroll-content{flex:1;overflow-y:auto}mat-dialog-actions{flex-shrink:0;justify-content:flex-start}.paginator-hidden{display:none!important}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["detailsConfig"] }, { kind: "component", type: StepsComponent, selector: "spa-steps", inputs: ["value", "config", "data"] }, { kind: "component", type: FormComponent, selector: "spa-form", inputs: ["files", "data", "config"], outputs: ["buttonClick", "inputChange"] }, { kind: "component", type: AlertComponent, selector: "spa-alert", inputs: ["config", "data"] }, { kind: "component", type: TabsInternalComponent, selector: "spa-tabs-internal", inputs: ["tableConfigs", "reload", "parentDetails"], outputs: ["formRefresh"] }, { kind: "component", type: StatusesComponent, selector: "spa-statuses", inputs: ["config", "data"] }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
13453
13674
|
}
|
|
13454
13675
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DetailsDialog, decorators: [{
|
|
13455
13676
|
type: Component,
|
|
@@ -14287,7 +14508,7 @@ class TitleActionsComponent {
|
|
|
14287
14508
|
this.actionValues[action.name] = value;
|
|
14288
14509
|
}
|
|
14289
14510
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TitleActionsComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
14290
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TitleActionsComponent, isStandalone: false, selector: "spa-title-actions", inputs: { titleActions: "titleActions" }, outputs: { actionChange: "actionChange" }, ngImport: i0, template: "<div class=\"title-actions-container\" *ngIf=\"titleActions && titleActions.length > 0\">\r\n \r\n <ng-container *ngFor=\"let action of titleActions\">\r\n \r\n <!-- Date Field -->\r\n <spa-date \r\n *ngIf=\"action.type === 'date' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-date>\r\n\r\n <!-- DateTime Field -->\r\n <spa-datetime \r\n *ngIf=\"action.type === 'datetime' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [readonly]=\"isReadonly(action)\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-datetime>\r\n\r\n <!-- Select Field -->\r\n <spa-select \r\n *ngIf=\"action.type === 'select' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [nullable]=\"action.nullable\"\r\n [options]=\"action.options\"\r\n [optionDisplay]=\"getOptionDisplay(action)\"\r\n [optionValue]=\"getOptionValue(action)\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [defaultFirstValue]=\"action.defaultFirstValue\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-select>\r\n\r\n <!-- Multi-Select Field -->\r\n <spa-select-multi \r\n *ngIf=\"action.type === 'select-multi' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [options]=\"action.options\"\r\n [optionDisplay]=\"getOptionDisplay(action)\"\r\n [optionValue]=\"getOptionValue(action)\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-select-multi>\r\n\r\n <!-- Checkbox Field -->\r\n <spa-check \r\n *ngIf=\"action.type === 'checkbox' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [readonly]=\"isReadonly(action)\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-check>\r\n\r\n <!-- Button Field -->\r\n <button \r\n *ngIf=\"action.type === 'button' && !isHidden(action)\"\r\n mat-icon-button\r\n [disabled]=\"isReadonly(action)\"\r\n [matTooltip]=\"action.hint ?? (action.alias ?? action.name | camelToWords)\"\r\n matTooltipPosition=\"above\"\r\n [color]=\"action.color ?? 'primary'\"\r\n (click)=\"onButtonClick(action)\">\r\n <mat-icon *ngIf=\"action.icon\">{{action.icon.name}}</mat-icon>\r\n <span *ngIf=\"!action.icon\">{{action.alias ?? action.name | camelToWords}}</span>\r\n </button>\r\n\r\n </ng-container>\r\n\r\n</div>\r\n", styles: [".title-actions-container{display:flex;align-items:flex-start;gap:15px;flex-wrap:wrap}.title-actions-container spa-date,.title-actions-container spa-datetime,.title-actions-container spa-select,.title-actions-container spa-multi-select{min-width:150px}.title-actions-container button{margin:0}@media (max-width: 600px){.title-actions-container{gap:10px}.title-actions-container spa-date,.title-actions-container spa-datetime,.title-actions-container spa-select,.title-actions-container spa-multi-select{min-width:120px}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
14511
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TitleActionsComponent, isStandalone: false, selector: "spa-title-actions", inputs: { titleActions: "titleActions" }, outputs: { actionChange: "actionChange" }, ngImport: i0, template: "<div class=\"title-actions-container\" *ngIf=\"titleActions && titleActions.length > 0\">\r\n \r\n <ng-container *ngFor=\"let action of titleActions\">\r\n \r\n <!-- Date Field -->\r\n <spa-date \r\n *ngIf=\"action.type === 'date' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-date>\r\n\r\n <!-- DateTime Field -->\r\n <spa-datetime \r\n *ngIf=\"action.type === 'datetime' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [readonly]=\"isReadonly(action)\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-datetime>\r\n\r\n <!-- Select Field -->\r\n <spa-select \r\n *ngIf=\"action.type === 'select' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [nullable]=\"action.nullable\"\r\n [options]=\"action.options\"\r\n [optionDisplay]=\"getOptionDisplay(action)\"\r\n [optionValue]=\"getOptionValue(action)\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [defaultFirstValue]=\"action.defaultFirstValue\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-select>\r\n\r\n <!-- Multi-Select Field -->\r\n <spa-select-multi \r\n *ngIf=\"action.type === 'select-multi' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [width]=\"action.width\"\r\n [options]=\"action.options\"\r\n [optionDisplay]=\"getOptionDisplay(action)\"\r\n [optionValue]=\"getOptionValue(action)\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [required]=\"action.required\"\r\n [readonly]=\"isReadonly(action)\"\r\n [hint]=\"action.hint\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-select-multi>\r\n\r\n <!-- Checkbox Field -->\r\n <spa-check \r\n *ngIf=\"action.type === 'checkbox' && !isHidden(action)\"\r\n [display]=\"action.alias ?? action.name | camelToWords\"\r\n [(value)]=\"actionValues[action.name]\"\r\n [readonly]=\"isReadonly(action)\"\r\n (valueChange)=\"onActionChange(action, actionValues[action.name])\">\r\n </spa-check>\r\n\r\n <!-- Button Field -->\r\n <button \r\n *ngIf=\"action.type === 'button' && !isHidden(action)\"\r\n mat-icon-button\r\n [disabled]=\"isReadonly(action)\"\r\n [matTooltip]=\"action.hint ?? (action.alias ?? action.name | camelToWords)\"\r\n matTooltipPosition=\"above\"\r\n [color]=\"action.color ?? 'primary'\"\r\n (click)=\"onButtonClick(action)\">\r\n <mat-icon *ngIf=\"action.icon\">{{action.icon.name}}</mat-icon>\r\n <span *ngIf=\"!action.icon\">{{action.alias ?? action.name | camelToWords}}</span>\r\n </button>\r\n\r\n </ng-container>\r\n\r\n</div>\r\n", styles: [".title-actions-container{display:flex;align-items:flex-start;gap:15px;flex-wrap:wrap}.title-actions-container spa-date,.title-actions-container spa-datetime,.title-actions-container spa-select,.title-actions-container spa-multi-select{min-width:150px}.title-actions-container button{margin:0}@media (max-width: 600px){.title-actions-container{gap:10px}.title-actions-container spa-date,.title-actions-container spa-datetime,.title-actions-container spa-select,.title-actions-container spa-multi-select{min-width:120px}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: DateComponent, selector: "spa-date", inputs: ["required", "min", "max", "readonly", "hint", "value", "display", "placeholder", "width", "suffix", "infoMessage", "copyContent", "clearContent"], outputs: ["valueChange"] }, { kind: "component", type: DatetimeComponent, selector: "spa-datetime", inputs: ["display", "value", "readonly", "width", "min", "max", "suffix", "infoMessage", "copyContent", "clearContent"], outputs: ["valueChange"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["detailsConfig"] }, { kind: "component", type: SelectMultiComponent, selector: "spa-select-multi", inputs: ["display", "value", "readonly", "required", "hint", "options", "optionDisplay", "optionValue", "infoMessage", "copyContent", "clearContent", "nullable", "placeholder", "width", "suffix", "loadAction"], outputs: ["valueChange", "hoverChange"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] }); }
|
|
14291
14512
|
}
|
|
14292
14513
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TitleActionsComponent, decorators: [{
|
|
14293
14514
|
type: Component,
|
|
@@ -14726,7 +14947,7 @@ class TasksComponent {
|
|
|
14726
14947
|
});
|
|
14727
14948
|
}
|
|
14728
14949
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TasksComponent, deps: [{ token: DataServiceLib }, { token: MessageService }, { token: AuthService }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
14729
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TasksComponent, isStandalone: false, selector: "spa-tasks", ngImport: i0, template: "<div class=\"d-flex align-items-center justify-content-between mt-0\" style=\"margin-left: 10px\">\r\n\r\n <label style=\"font-size: 16px;\">Tasks</label>\r\n\r\n <div>\r\n <button mat-mini-fab color=\"primary\" style=\"margin-right:1em;\" (click)=\"cats()\" matTooltip=\"Categories\" matTooltipPosition=\"above\"><mat-icon>category</mat-icon></button>\r\n </div>\r\n\r\n</div>\r\n<hr>\r\n\r\n<div class=\"mt-3\" style=\" font-size: 14px;\">\r\n <spa-table [config]=\"tasksTableConfig\" [reload]=\"reload\"></spa-table>\r\n</div>\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type:
|
|
14950
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TasksComponent, isStandalone: false, selector: "spa-tasks", ngImport: i0, template: "<div class=\"d-flex align-items-center justify-content-between mt-0\" style=\"margin-left: 10px\">\r\n\r\n <label style=\"font-size: 16px;\">Tasks</label>\r\n\r\n <div>\r\n <button mat-mini-fab color=\"primary\" style=\"margin-right:1em;\" (click)=\"cats()\" matTooltip=\"Categories\" matTooltipPosition=\"above\"><mat-icon>category</mat-icon></button>\r\n </div>\r\n\r\n</div>\r\n<hr>\r\n\r\n<div class=\"mt-3\" style=\" font-size: 14px;\">\r\n <spa-table [config]=\"tasksTableConfig\" [reload]=\"reload\"></spa-table>\r\n</div>\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: TableComponent, selector: "spa-table", inputs: ["data", "tileData", "config", "reload", "activeTab", "inTab"], outputs: ["dataLoad", "actionSuccess", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }] }); }
|
|
14730
14951
|
}
|
|
14731
14952
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TasksComponent, decorators: [{
|
|
14732
14953
|
type: Component,
|
|
@@ -15224,7 +15445,7 @@ class SelectBitwiseComponent {
|
|
|
15224
15445
|
this.infoClick.emit();
|
|
15225
15446
|
}
|
|
15226
15447
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectBitwiseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
15227
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectBitwiseComponent, isStandalone: false, selector: "spa-select-bitwise", inputs: { display: "display", hint: "hint", required: "required", readonly: "readonly", width: "width", infoMessage: "infoMessage", options: "options", value: "value" }, outputs: { valueChange: "valueChange", infoClick: "infoClick" }, ngImport: i0, template: "<mat-form-field [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\">\r\n <mat-label>{{display}}</mat-label>\r\n\r\n <mat-select multiple [(ngModel)]=\"selectedValues\" (selectionChange)=\"onSelectionChange($event)\" [required]=\"required\" [disabled]=\"readonly\">\r\n <mat-option *ngFor=\"let option of bitwiseOptions\" [value]=\"option.value\">\r\n\r\n <mat-icon *ngIf=\"option.icon && !hasNames\" [ngStyle]=\"{'color': option.icon.color}\" [matTooltip]=\"option.icon.tip\" >\r\n {{option.icon.name}}\r\n </mat-icon>\r\n\r\n <span *ngIf=\"hasNames\">\r\n {{option.name}}\r\n </span>\r\n\r\n </mat-option>\r\n </mat-select>\r\n\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n\r\n <ng-container *ngIf=\"!hasNames\">\r\n <mat-icon *ngFor=\"let option of selectedOptions\" [ngStyle]=\"{'color': option.icon?.color, 'margin-right': '4px'}\" style=\"font-size: 14px;\" [matTooltip]=\"option.icon?.tip\">\r\n {{option.icon?.name}}\r\n </mat-icon>\r\n </ng-container>\r\n\r\n <button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: steelblue;\">info</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7
|
|
15448
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: SelectBitwiseComponent, isStandalone: false, selector: "spa-select-bitwise", inputs: { display: "display", hint: "hint", required: "required", readonly: "readonly", width: "width", infoMessage: "infoMessage", options: "options", value: "value" }, outputs: { valueChange: "valueChange", infoClick: "infoClick" }, ngImport: i0, template: "<mat-form-field [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\">\r\n <mat-label>{{display}}</mat-label>\r\n\r\n <mat-select multiple [(ngModel)]=\"selectedValues\" (selectionChange)=\"onSelectionChange($event)\" [required]=\"required\" [disabled]=\"readonly\">\r\n <mat-option *ngFor=\"let option of bitwiseOptions\" [value]=\"option.value\">\r\n\r\n <mat-icon *ngIf=\"option.icon && !hasNames\" [ngStyle]=\"{'color': option.icon.color}\" [matTooltip]=\"option.icon.tip\" >\r\n {{option.icon.name}}\r\n </mat-icon>\r\n\r\n <span *ngIf=\"hasNames\">\r\n {{option.name}}\r\n </span>\r\n\r\n </mat-option>\r\n </mat-select>\r\n\r\n <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\r\n\r\n <div matSuffix class=\"suffix-icons\">\r\n\r\n <ng-container *ngIf=\"!hasNames\">\r\n <mat-icon *ngFor=\"let option of selectedOptions\" [ngStyle]=\"{'color': option.icon?.color, 'margin-right': '4px'}\" style=\"font-size: 14px;\" [matTooltip]=\"option.icon?.tip\">\r\n {{option.icon?.name}}\r\n </mat-icon>\r\n </ng-container>\r\n\r\n <button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\">\r\n <mat-icon style=\"color: steelblue;\">info</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n</mat-form-field>\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i7.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: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
15228
15449
|
}
|
|
15229
15450
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: SelectBitwiseComponent, decorators: [{
|
|
15230
15451
|
type: Component,
|
|
@@ -15725,6 +15946,108 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
15725
15946
|
args: [{ selector: 'spa-welcome', standalone: false, template: "<div class=\"welcome-container\">\r\n <div class=\"header-section\">\r\n <h2>Tin-SPA Business Framework</h2>\r\n <p class=\"subtitle\">Comprehensive enterprise modules for Accounting, Inventory, Loans, and HR Management</p>\r\n </div>\r\n\r\n <!-- Quick Navigation to Core Modules -->\r\n <div class=\"row mb-4\">\r\n <div class=\"col-md-12\">\r\n <h4>Quick Access</h4>\r\n <div class=\"navigation-grid\">\r\n <button mat-raised-button (click)=\"navigateTo(dataService.capAccounts.link)\" class=\"nav-button accounting\">\r\n <mat-icon>{{dataService.capAccounts.icon}}</mat-icon>\r\n Accounting\r\n </button>\r\n <button mat-raised-button (click)=\"navigateTo(dataService.capInventoryDashboard.link)\" class=\"nav-button inventory\">\r\n <mat-icon>{{dataService.capInventoryDashboard.icon}}</mat-icon>\r\n Inventory\r\n </button>\r\n <button mat-raised-button (click)=\"navigateTo(dataService.capLoanProducts.link)\" class=\"nav-button loans\">\r\n <mat-icon>{{dataService.capLoanProducts.icon}}</mat-icon>\r\n Loans\r\n </button>\r\n <button mat-raised-button (click)=\"navigateTo(dataService.capEmployees.link)\" class=\"nav-button hr\">\r\n <mat-icon>{{dataService.capEmployees.icon}}</mat-icon>\r\n Human Resources\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Core Business Modules -->\r\n <div class=\"row mb-4\">\r\n <div class=\"col-md-12\">\r\n <h4>Core Business Modules</h4>\r\n <div class=\"row\">\r\n <div class=\"col-md-6 mb-3\" *ngFor=\"let module of businessModules\">\r\n <div class=\"module-card\" (click)=\"navigateTo(module.demoUrl)\" [style.border-left]=\"'4px solid ' + module.color\">\r\n <div class=\"module-header\">\r\n <mat-icon [style.color]=\"module.color\" class=\"module-icon\">{{module.icon}}</mat-icon>\r\n <div class=\"module-title\">\r\n <h5>{{module.name}}</h5>\r\n <span class=\"component-count\">{{module.components}} Components</span>\r\n </div>\r\n </div>\r\n <div class=\"module-content\">\r\n <p class=\"module-description\">{{module.description}}</p>\r\n <div class=\"features-list\">\r\n <span class=\"feature-tag\" *ngFor=\"let feature of module.features\">\r\n <mat-icon class=\"feature-icon\">check_circle</mat-icon>\r\n {{feature}}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Quick Navigation to Core Modules -->\r\n <div class=\"row mb-4\">\r\n <div class=\"col-md-12\">\r\n <h4>Advanced Features Across Modules</h4>\r\n <div class=\"features-grid\">\r\n <div class=\"feature-item\" *ngFor=\"let feature of advancedFeatures\">\r\n <div class=\"feature-name\">{{feature.name}}</div>\r\n <div class=\"feature-modules\">\r\n <mat-icon class=\"small-icon\">widgets</mat-icon>\r\n {{feature.modules}}\r\n </div>\r\n <div class=\"feature-description\">{{feature.description}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Supporting Modules -->\r\n <div class=\"row mb-4\">\r\n <div class=\"col-md-12\">\r\n <h4>Supporting Modules</h4>\r\n <div class=\"supporting-grid\">\r\n <div class=\"support-item\" *ngFor=\"let support of supportingModules\" (click)=\"navigateTo(support.link)\">\r\n <mat-icon>{{support.icon}}</mat-icon>\r\n <div class=\"support-details\">\r\n <div class=\"support-name\">{{support.name}}</div>\r\n <div class=\"support-description\">{{support.description}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Module Details Sections -->\r\n <div class=\"row\">\r\n <div class=\"col-md-12\">\r\n <h4>Module Details</h4>\r\n \r\n <!-- Accounting Details -->\r\n <div class=\"detail-section\">\r\n <div class=\"detail-header\">\r\n <mat-icon style=\"color: #667eea\">account_balance</mat-icon>\r\n <h5>Accounting Module</h5>\r\n </div>\r\n <p>\r\n The Accounting module provides comprehensive financial management capabilities including:\r\n </p>\r\n <ul>\r\n <li><strong>Chart of Accounts:</strong> Hierarchical account structure with categories and types</li>\r\n <li><strong>Transactions:</strong> Record debits and credits with full audit trail</li>\r\n <li><strong>Invoicing:</strong> Create and track invoices with multiple status workflows</li>\r\n <li><strong>Outstanding Management:</strong> Monitor and manage outstanding payments</li>\r\n <li><strong>Financial Reporting:</strong> Real-time financial summaries and analytics</li>\r\n </ul>\r\n </div>\r\n\r\n <!-- Inventory Details -->\r\n <div class=\"detail-section\">\r\n <div class=\"detail-header\">\r\n <mat-icon style=\"color: #4CAF50\">inventory</mat-icon>\r\n <h5>Inventory Module</h5>\r\n </div>\r\n <p>\r\n The Inventory module covers the complete inventory lifecycle from procurement to sales:\r\n </p>\r\n <ul>\r\n <li><strong>Product Management:</strong> Catalog with categories, brands, and pricing</li>\r\n <li><strong>Stock Control:</strong> Real-time stock levels with location tracking</li>\r\n <li><strong>Purchase Orders:</strong> Supplier ordering with receipt management</li>\r\n <li><strong>Sales Orders:</strong> Customer orders with fulfillment tracking</li>\r\n <li><strong>Requisitions:</strong> Internal requests and transfers between locations</li>\r\n <li><strong>Adjustments & Returns:</strong> Stock adjustments and return processing</li>\r\n <li><strong>Dashboard:</strong> Visual analytics with tiles showing key metrics</li>\r\n </ul>\r\n </div>\r\n\r\n <!-- Loans Details -->\r\n <div class=\"detail-section\">\r\n <div class=\"detail-header\">\r\n <mat-icon style=\"color: #FF9800\">payments</mat-icon>\r\n <h5>Loans Module</h5>\r\n </div>\r\n <p>\r\n The Loans module enables loan origination and management for both customers and employees:\r\n </p>\r\n <ul>\r\n <li><strong>Loan Products:</strong> Define loan types with interest rates and terms</li>\r\n <li><strong>Loan Applications:</strong> Customer and employee loan processing</li>\r\n <li><strong>Payment Tracking:</strong> Record and monitor loan payments</li>\r\n <li><strong>Interest Calculations:</strong> Automated interest computation based on method</li>\r\n <li><strong>Outstanding Balances:</strong> Real-time balance and status monitoring</li>\r\n </ul>\r\n </div>\r\n\r\n <!-- HR Details -->\r\n <div class=\"detail-section\">\r\n <div class=\"detail-header\">\r\n <mat-icon style=\"color: #E91E63\">diversity_3</mat-icon>\r\n <h5>Human Resources Module</h5>\r\n </div>\r\n <p>\r\n The HR module manages employee information and organizational structure:\r\n </p>\r\n <ul>\r\n <li><strong>Employee Records:</strong> Comprehensive employee database with demographics</li>\r\n <li><strong>Department Management:</strong> Organizational department structure</li>\r\n <li><strong>Position Tracking:</strong> Job positions and hierarchies</li>\r\n <li><strong>Employment Status:</strong> Track employment and active status</li>\r\n <li><strong>User Integration:</strong> Link employees to system user accounts</li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"footer-section mt-5\">\r\n <p class=\"text-center\">\r\n <strong>Tin-SPA Business Framework</strong> - Enterprise-grade modules for complete business management\r\n <br>\r\n <small>Built with Angular Material and designed for scalability and extensibility</small>\r\n </p>\r\n </div>\r\n</div>\r\n", styles: [".welcome-container{padding:20px;max-width:1400px;margin:0 auto}.header-section{text-align:center;margin-bottom:30px}.header-section h2{color:#2c3e50;margin-bottom:10px;font-weight:600}.subtitle{color:#7f8c8d;font-size:16px;margin-bottom:0;font-weight:400}.stats-card{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;padding:25px;border-radius:12px;margin-bottom:20px;box-shadow:0 4px 15px #667eea4d}.stats-card h4{margin-bottom:20px;text-align:center;font-weight:500}.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:20px;text-align:center}.stat-item{background:#ffffff26;padding:20px;border-radius:8px;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);transition:transform .3s ease}.stat-item:hover{transform:translateY(-3px);background:#fff3}.stat-number{font-size:2.5em;font-weight:700;margin-bottom:8px}.stat-label{font-size:.9em;opacity:.95;font-weight:300}.module-card{background:#fff;border:1px solid #e0e0e0;border-radius:10px;padding:20px;cursor:pointer;transition:all .3s ease;height:100%;box-shadow:0 2px 8px #00000014}.module-card:hover{transform:translateY(-5px);box-shadow:0 10px 30px #00000026;border-color:transparent}.module-header{display:flex;align-items:center;gap:15px;margin-bottom:15px}.module-icon{font-size:36px;width:36px;height:36px}.module-title h5{margin:0 0 5px;color:#2c3e50;font-weight:600}.component-count{color:#7f8c8d;font-size:13px}.module-content{margin-top:15px}.module-description{color:#555;font-size:14px;margin-bottom:15px;line-height:1.5}.features-list{display:flex;flex-direction:column;gap:8px}.feature-tag{display:flex;align-items:center;gap:8px;background:#f8f9fa;color:#495057;padding:6px 10px;border-radius:6px;font-size:12px;transition:background .2s ease}.feature-tag:hover{background:#e9ecef}.feature-icon{font-size:16px;width:16px;height:16px;color:#28a745}.navigation-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:15px;margin-bottom:20px}.nav-button{display:flex;align-items:center;gap:10px;padding:15px 20px;justify-content:flex-start;font-size:15px;font-weight:500;border-radius:8px;transition:all .3s ease}.nav-button.accounting{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.nav-button.inventory{background:linear-gradient(135deg,#4caf50,#388e3c);color:#fff}.nav-button.loans{background:linear-gradient(135deg,#ff9800,#f57c00);color:#fff}.nav-button.hr{background:linear-gradient(135deg,#e91e63,#c2185b);color:#fff}.nav-button:hover{transform:translateY(-3px);box-shadow:0 6px 20px #00000026}.features-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:15px}.feature-item{background:#fff;border:1px solid #e0e0e0;border-radius:8px;padding:15px;transition:all .3s ease}.feature-item:hover{border-color:#667eea;box-shadow:0 4px 12px #667eea1a}.feature-name{font-weight:600;color:#667eea;margin-bottom:8px;font-size:15px}.feature-modules{color:#7f8c8d;font-size:12px;margin-bottom:8px;display:flex;align-items:center;gap:5px}.small-icon{font-size:14px;width:14px;height:14px}.feature-description{color:#495057;font-size:13px;line-height:1.5}.supporting-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:15px}.support-item{display:flex;align-items:center;gap:12px;background:#fff;border:1px solid #e0e0e0;border-radius:8px;padding:12px;cursor:pointer;transition:all .3s ease}.support-item:hover{border-color:#667eea;background:#f8f9fa;transform:translate(5px)}.support-item mat-icon{color:#667eea}.support-details{flex:1}.support-name{font-weight:500;color:#2c3e50;font-size:14px}.support-description{color:#7f8c8d;font-size:12px}.capability-card{background:#fff;border:1px solid #e0e0e0;border-radius:8px;padding:15px;text-align:center;transition:all .3s ease;height:100%}.capability-card:hover{border-color:#667eea;box-shadow:0 4px 12px #667eea1a}.capability-header{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:10px}.capability-count{font-size:24px;font-weight:700;color:#667eea}.capability-category{font-size:16px;font-weight:500;color:#2c3e50}.capability-items{color:#7f8c8d;font-size:12px;line-height:1.6}.detail-section{background:#fff;border-left:4px solid #667eea;border-radius:8px;padding:20px;margin-bottom:20px;box-shadow:0 2px 8px #00000014}.detail-header{display:flex;align-items:center;gap:12px;margin-bottom:15px}.detail-header mat-icon{font-size:28px;width:28px;height:28px}.detail-header h5{margin:0;color:#2c3e50;font-weight:600}.detail-section p{color:#555;margin-bottom:15px;line-height:1.6}.detail-section ul{margin:0;padding-left:20px}.detail-section li{color:#495057;margin-bottom:10px;line-height:1.6}.detail-section li strong{color:#2c3e50}.footer-section{border-top:2px solid #e0e0e0;padding-top:30px;color:#7f8c8d;margin-top:40px}.footer-section strong{color:#2c3e50}@media (max-width: 992px){.stats-grid,.navigation-grid{grid-template-columns:repeat(2,1fr)}}@media (max-width: 768px){.welcome-container{padding:15px}.stats-grid,.navigation-grid,.features-grid,.supporting-grid{grid-template-columns:1fr}.module-icon{font-size:28px;width:28px;height:28px}.stat-number{font-size:2em}}\n"] }]
|
|
15726
15947
|
}], ctorParameters: () => [{ type: i1$2.Router }, { type: DataServiceLib }] });
|
|
15727
15948
|
|
|
15949
|
+
// Changed: Callout plugin — projects labels strictly left/right to maximize pie vertical space
|
|
15950
|
+
const OuterCalloutPlugin = {
|
|
15951
|
+
id: 'outerCallout',
|
|
15952
|
+
afterDraw: (chart) => {
|
|
15953
|
+
const { ctx } = chart;
|
|
15954
|
+
const meta = chart.getDatasetMeta(0);
|
|
15955
|
+
if (!meta?.data?.length)
|
|
15956
|
+
return;
|
|
15957
|
+
const dataset = chart.data.datasets[0];
|
|
15958
|
+
const total = dataset.data.reduce((a, b) => a + b, 0);
|
|
15959
|
+
if (total === 0)
|
|
15960
|
+
return;
|
|
15961
|
+
const labels = chart.data.labels || [];
|
|
15962
|
+
const colors = dataset.backgroundColor || [];
|
|
15963
|
+
// Changed: Reset clip region so callout labels can draw in the padding area outside chartArea
|
|
15964
|
+
ctx.save();
|
|
15965
|
+
ctx.resetTransform();
|
|
15966
|
+
ctx.beginPath();
|
|
15967
|
+
ctx.rect(0, 0, chart.canvas.width, chart.canvas.height);
|
|
15968
|
+
ctx.clip();
|
|
15969
|
+
const dpr = window.devicePixelRatio || 1;
|
|
15970
|
+
ctx.scale(dpr, dpr);
|
|
15971
|
+
// Changed: Collect callout items per side, then space vertically to avoid overlap
|
|
15972
|
+
const leftItems = [];
|
|
15973
|
+
const rightItems = [];
|
|
15974
|
+
meta.data.forEach((arc, i) => {
|
|
15975
|
+
const value = dataset.data[i];
|
|
15976
|
+
const pct = Math.round((value / total) * 100);
|
|
15977
|
+
if (pct < 5)
|
|
15978
|
+
return; // Changed: Skip tiny segments
|
|
15979
|
+
const midAngle = (arc.startAngle + arc.endAngle) / 2;
|
|
15980
|
+
const outerRadius = arc.outerRadius;
|
|
15981
|
+
const cx = arc.x;
|
|
15982
|
+
const cy = arc.y;
|
|
15983
|
+
const edgeX = cx + Math.cos(midAngle) * outerRadius;
|
|
15984
|
+
const edgeY = cy + Math.sin(midAngle) * outerRadius;
|
|
15985
|
+
const isRight = Math.cos(midAngle) >= 0; // Changed: Use cos to determine left/right
|
|
15986
|
+
const color = Array.isArray(colors) ? colors[i % colors.length] : '#333';
|
|
15987
|
+
const item = { edgeX, edgeY, cx, cy, outerRadius, pct, label: labels[i] ? String(labels[i]) : '', color, isRight };
|
|
15988
|
+
if (isRight)
|
|
15989
|
+
rightItems.push(item);
|
|
15990
|
+
else
|
|
15991
|
+
leftItems.push(item);
|
|
15992
|
+
});
|
|
15993
|
+
// Changed: Sort by Y and enforce minimum vertical gap between labels
|
|
15994
|
+
leftItems.sort((a, b) => a.edgeY - b.edgeY);
|
|
15995
|
+
rightItems.sort((a, b) => a.edgeY - b.edgeY);
|
|
15996
|
+
// Changed: Space labels vertically — minimum 16px (single row needs less gap)
|
|
15997
|
+
const spaceLabels = (items) => {
|
|
15998
|
+
const minGap = 16;
|
|
15999
|
+
for (let j = 1; j < items.length; j++) {
|
|
16000
|
+
if (items[j].edgeY - items[j - 1].edgeY < minGap) {
|
|
16001
|
+
items[j].edgeY = items[j - 1].edgeY + minGap;
|
|
16002
|
+
}
|
|
16003
|
+
}
|
|
16004
|
+
};
|
|
16005
|
+
spaceLabels(leftItems);
|
|
16006
|
+
spaceLabels(rightItems);
|
|
16007
|
+
// Changed: Draw callouts — label name and percentage on the SAME row, side by side
|
|
16008
|
+
const drawSide = (items) => {
|
|
16009
|
+
items.forEach((item) => {
|
|
16010
|
+
const { edgeX, edgeY, cx, outerRadius, pct, label, color, isRight } = item;
|
|
16011
|
+
// Changed: Connector endpoint near the pie edge
|
|
16012
|
+
const tailX = isRight ? cx + outerRadius + 16 : cx - outerRadius - 16;
|
|
16013
|
+
const tailY = edgeY;
|
|
16014
|
+
// Changed: Draw connector line from arc edge to label area
|
|
16015
|
+
ctx.beginPath();
|
|
16016
|
+
ctx.moveTo(edgeX, edgeY);
|
|
16017
|
+
ctx.lineTo(tailX, tailY);
|
|
16018
|
+
ctx.strokeStyle = '#999';
|
|
16019
|
+
ctx.lineWidth = 1;
|
|
16020
|
+
ctx.stroke();
|
|
16021
|
+
// Changed: Same row — percentage near pie, label name further out
|
|
16022
|
+
ctx.textBaseline = 'middle';
|
|
16023
|
+
const textX = tailX + (isRight ? 4 : -4);
|
|
16024
|
+
// Changed: Percentage closest to pie — bold, segment-colored
|
|
16025
|
+
ctx.font = 'bold 12px Arial';
|
|
16026
|
+
ctx.fillStyle = color;
|
|
16027
|
+
ctx.textAlign = isRight ? 'left' : 'right';
|
|
16028
|
+
ctx.fillText(pct + '%', textX, tailY);
|
|
16029
|
+
// Changed: Label name next to percentage — muted
|
|
16030
|
+
if (label) {
|
|
16031
|
+
ctx.font = '11px Arial';
|
|
16032
|
+
ctx.fillStyle = '#888';
|
|
16033
|
+
if (isRight) {
|
|
16034
|
+
const pctWidth = ctx.measureText(pct + '%').width;
|
|
16035
|
+
ctx.textAlign = 'left';
|
|
16036
|
+
ctx.fillText(label, textX + pctWidth + 4, tailY); // Changed: Right of percentage
|
|
16037
|
+
}
|
|
16038
|
+
else {
|
|
16039
|
+
const pctWidth = ctx.measureText(pct + '%').width;
|
|
16040
|
+
ctx.textAlign = 'right';
|
|
16041
|
+
ctx.fillText(label, textX - pctWidth - 4, tailY); // Changed: Left of percentage
|
|
16042
|
+
}
|
|
16043
|
+
}
|
|
16044
|
+
});
|
|
16045
|
+
};
|
|
16046
|
+
drawSide(leftItems);
|
|
16047
|
+
drawSide(rightItems);
|
|
16048
|
+
ctx.restore();
|
|
16049
|
+
}
|
|
16050
|
+
};
|
|
15728
16051
|
class ChartsComponent {
|
|
15729
16052
|
constructor(dataService, messageService) {
|
|
15730
16053
|
this.dataService = dataService;
|
|
@@ -15772,67 +16095,103 @@ class ChartsComponent {
|
|
|
15772
16095
|
};
|
|
15773
16096
|
}
|
|
15774
16097
|
// Standard mode: resolve data from API response by chart name, or use pre-loaded data
|
|
15775
|
-
|
|
16098
|
+
const chartData = this.data?.[chart.name] ?? chart.data ?? { labels: [], datasets: [] };
|
|
16099
|
+
// Changed: Apply chart.colors to dataset backgroundColor if not already set (ensures pie/doughnut render correctly)
|
|
16100
|
+
if (chart.colors?.length && chartData.datasets?.length) {
|
|
16101
|
+
chartData.datasets.forEach((ds) => {
|
|
16102
|
+
if (!ds.backgroundColor) {
|
|
16103
|
+
ds.backgroundColor = chart.colors;
|
|
16104
|
+
}
|
|
16105
|
+
});
|
|
16106
|
+
}
|
|
16107
|
+
return chartData;
|
|
15776
16108
|
}
|
|
15777
|
-
//
|
|
16109
|
+
// Changed: Enhanced chart options for all chart types — better styling, datalabels for pie/doughnut
|
|
15778
16110
|
getChartOptions(chart) {
|
|
15779
|
-
// Start with passthrough options if provided
|
|
15780
16111
|
const options = chart.options ?? {};
|
|
15781
|
-
// Common responsive settings
|
|
15782
16112
|
options.responsive = true;
|
|
15783
16113
|
options.maintainAspectRatio = false;
|
|
15784
16114
|
if (chart.type === 'line') {
|
|
15785
|
-
// Line chart
|
|
16115
|
+
// Changed: Line chart — smooth curves, subtle grid
|
|
15786
16116
|
options.elements = options.elements ?? {};
|
|
15787
|
-
options.elements.line =
|
|
15788
|
-
options.elements.
|
|
15789
|
-
options.elements.point = options.elements.point ?? {};
|
|
15790
|
-
options.elements.point.radius = chart.showPoints ? 4 : 0; // Show/hide data points
|
|
16117
|
+
options.elements.line = { tension: chart.tension ?? 0.4, borderWidth: 2.5 };
|
|
16118
|
+
options.elements.point = { radius: chart.showPoints ? 4 : 0, hoverRadius: 6, hitRadius: 10 };
|
|
15791
16119
|
options.plugins = options.plugins ?? {};
|
|
15792
|
-
options.plugins.legend =
|
|
16120
|
+
options.plugins.legend = chart.showLegend ? { display: true, position: 'bottom', labels: { usePointStyle: true, pointStyle: 'circle', padding: 16, font: { size: 12 } } } : { display: false }; // Changed: Show Chart.js legend only when showLegend is true
|
|
16121
|
+
options.plugins.tooltip = options.plugins.tooltip ?? { mode: 'index', intersect: false, backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };
|
|
16122
|
+
options.plugins.datalabels = { display: false }; // Changed: No datalabels on line charts
|
|
16123
|
+
options.scales = options.scales ?? {};
|
|
16124
|
+
options.scales.x = options.scales.x ?? { grid: { display: false }, ticks: { font: { size: 11 }, color: '#999' } };
|
|
16125
|
+
options.scales.y = options.scales.y ?? { grid: { color: '#f0f0f0', drawBorder: false }, ticks: { font: { size: 11 }, color: '#999' }, border: { display: false } };
|
|
15793
16126
|
}
|
|
15794
16127
|
if (chart.type === 'bar') {
|
|
15795
|
-
// Bar chart
|
|
16128
|
+
// Changed: Bar chart — clean grid, rounded bars
|
|
15796
16129
|
options.plugins = options.plugins ?? {};
|
|
15797
|
-
options.plugins.legend =
|
|
16130
|
+
options.plugins.legend = chart.showLegend ? { display: true, position: 'bottom', labels: { usePointStyle: true, pointStyle: 'circle', padding: 16, font: { size: 12 } } } : { display: false }; // Changed: Show Chart.js legend only when showLegend is true
|
|
16131
|
+
options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };
|
|
16132
|
+
options.plugins.datalabels = { display: false }; // Changed: No datalabels on bar charts
|
|
16133
|
+
options.scales = options.scales ?? {};
|
|
16134
|
+
options.scales.x = options.scales.x ?? { grid: { display: false }, ticks: { font: { size: 11 }, color: '#999' } };
|
|
16135
|
+
options.scales.y = options.scales.y ?? { grid: { color: '#f0f0f0', drawBorder: false }, ticks: { font: { size: 11 }, color: '#999' }, border: { display: false }, beginAtZero: true };
|
|
16136
|
+
options.elements = options.elements ?? {};
|
|
16137
|
+
options.elements.bar = options.elements.bar ?? { borderRadius: 4 }; // Changed: Rounded bar corners
|
|
15798
16138
|
}
|
|
15799
16139
|
if (chart.type === 'pie') {
|
|
15800
|
-
// Pie chart
|
|
16140
|
+
// Changed: Pie chart — outer callout labels, legend always disabled (callout plugin handles labeling)
|
|
15801
16141
|
options.plugins = options.plugins ?? {};
|
|
15802
|
-
options.plugins.legend =
|
|
16142
|
+
options.plugins.legend = { display: false };
|
|
16143
|
+
options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };
|
|
16144
|
+
options.plugins.datalabels = { display: false }; // Changed: Disabled — outerCallout plugin draws labels instead
|
|
16145
|
+
options.layout = options.layout ?? { padding: { top: 10, bottom: 10, left: 70, right: 70 } }; // Changed: Minimal top/bottom — callouts project left/right only
|
|
15803
16146
|
}
|
|
15804
16147
|
if (chart.type === 'doughnut') {
|
|
15805
|
-
// Doughnut
|
|
16148
|
+
// Changed: Doughnut — outer callout labels
|
|
15806
16149
|
options.plugins = options.plugins ?? {};
|
|
15807
|
-
options.plugins.legend = options.plugins.legend ?? { display: false };
|
|
15808
16150
|
if (chart.gaugeValue != null) {
|
|
16151
|
+
// Changed: Gauge mode — no legend, no tooltip, center text via plugin
|
|
16152
|
+
options.plugins.legend = { display: false };
|
|
15809
16153
|
options.plugins.tooltip = { enabled: false };
|
|
15810
|
-
options.
|
|
16154
|
+
options.plugins.datalabels = { display: false };
|
|
16155
|
+
options.cutout = options.cutout ?? '70%';
|
|
16156
|
+
options.layout = options.layout ?? { padding: 10 };
|
|
16157
|
+
}
|
|
16158
|
+
else {
|
|
16159
|
+
// Changed: Standard doughnut — legend always disabled (callout plugin handles labeling)
|
|
16160
|
+
options.plugins.legend = { display: false };
|
|
16161
|
+
options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };
|
|
16162
|
+
options.plugins.datalabels = { display: false }; // Changed: Disabled — outerCallout plugin draws labels
|
|
16163
|
+
options.cutout = options.cutout ?? '50%';
|
|
16164
|
+
options.layout = options.layout ?? { padding: { top: 10, bottom: 10, left: 70, right: 70 } }; // Changed: Minimal top/bottom — callouts project left/right only
|
|
15811
16165
|
}
|
|
15812
16166
|
}
|
|
15813
16167
|
return options;
|
|
15814
16168
|
}
|
|
15815
|
-
// Return Chart.js plugins array for
|
|
16169
|
+
// Changed: Return Chart.js plugins array — outer callout for pie/doughnut, center text for gauges
|
|
15816
16170
|
getPlugins(chart) {
|
|
15817
|
-
|
|
16171
|
+
const plugins = [];
|
|
16172
|
+
// Changed: Add outer callout plugin for pie and doughnut (non-gauge) — draws labels with connector lines
|
|
16173
|
+
if (chart.type === 'pie' || (chart.type === 'doughnut' && chart.gaugeValue == null)) {
|
|
16174
|
+
plugins.push(OuterCalloutPlugin);
|
|
16175
|
+
}
|
|
16176
|
+
// Changed: Center text plugin for doughnut gauge — displays percentage inside the ring
|
|
15818
16177
|
if (chart.type === 'doughnut' && chart.gaugeValue != null) {
|
|
15819
|
-
|
|
15820
|
-
|
|
15821
|
-
|
|
15822
|
-
|
|
15823
|
-
|
|
15824
|
-
|
|
15825
|
-
|
|
15826
|
-
|
|
15827
|
-
|
|
15828
|
-
|
|
15829
|
-
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
|
|
15833
|
-
|
|
16178
|
+
plugins.push({
|
|
16179
|
+
id: 'centerText',
|
|
16180
|
+
afterDraw: (chartInstance) => {
|
|
16181
|
+
const ctx = chartInstance.ctx;
|
|
16182
|
+
const { width, height } = chartInstance;
|
|
16183
|
+
ctx.save();
|
|
16184
|
+
const text = chart.gaugeValue + '%';
|
|
16185
|
+
ctx.font = 'bold 28px Arial';
|
|
16186
|
+
ctx.fillStyle = chart.gaugeColor ?? '#4acccd';
|
|
16187
|
+
ctx.textAlign = 'center';
|
|
16188
|
+
ctx.textBaseline = 'middle';
|
|
16189
|
+
ctx.fillText(text, width / 2, height / 2);
|
|
16190
|
+
ctx.restore();
|
|
16191
|
+
}
|
|
16192
|
+
});
|
|
15834
16193
|
}
|
|
15835
|
-
return
|
|
16194
|
+
return plugins;
|
|
15836
16195
|
}
|
|
15837
16196
|
// Check if a chart should be hidden
|
|
15838
16197
|
isHidden(chart) {
|
|
@@ -15843,11 +16202,11 @@ class ChartsComponent {
|
|
|
15843
16202
|
return false;
|
|
15844
16203
|
}
|
|
15845
16204
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChartsComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
15846
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChartsComponent, isStandalone: false, selector: "spa-charts", inputs: { config: "config", data: "data", reload: "reload" }, ngImport: i0, template: "<div class=\"charts-grid\" [style.--columns]=\"config?.columns\">\r\n <ng-container *ngFor=\"let chart of config?.charts\">\r\n <mat-card *ngIf=\"!isHidden(chart)\" class=\"chart-card\">\r\n\r\n <!-- Header -->\r\n <div class=\"chart-header\" *ngIf=\"chart.title\">\r\n <h4 class=\"chart-title\">{{ chart.title }}</h4>\r\n <p class=\"chart-subtitle\" *ngIf=\"chart.subtitle\">{{ chart.subtitle }}</p>\r\n </div>\r\n\r\n <!-- Chart Area -->\r\n <div class=\"chart-body\" [style.height]=\"chart.height ?? '300px'\">\r\n <canvas baseChart\r\n [type]=\"chart.type\"\r\n [data]=\"getChartData(chart)\"\r\n [options]=\"getChartOptions(chart)\"\r\n [plugins]=\"getPlugins(chart)\">\r\n </canvas>\r\n </div>\r\n\r\n <!--
|
|
16205
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: ChartsComponent, isStandalone: false, selector: "spa-charts", inputs: { config: "config", data: "data", reload: "reload" }, ngImport: i0, template: "<div class=\"charts-grid\" [style.--columns]=\"config?.columns\">\r\n <ng-container *ngFor=\"let chart of config?.charts\">\r\n <mat-card *ngIf=\"!isHidden(chart)\" class=\"chart-card\">\r\n\r\n <!-- Header -->\r\n <div class=\"chart-header\" *ngIf=\"chart.title\">\r\n <h4 class=\"chart-title\">{{ chart.title }}</h4>\r\n <p class=\"chart-subtitle\" *ngIf=\"chart.subtitle\">{{ chart.subtitle }}</p>\r\n </div>\r\n\r\n <!-- Chart Area -->\r\n <div class=\"chart-body\" [style.height]=\"chart.height ?? '300px'\">\r\n <canvas baseChart\r\n [type]=\"chart.type\"\r\n [data]=\"getChartData(chart)\"\r\n [options]=\"getChartOptions(chart)\"\r\n [plugins]=\"getPlugins(chart)\">\r\n </canvas>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"chart-footer\" *ngIf=\"chart.footer\">\r\n <mat-divider></mat-divider>\r\n <div class=\"footer-content\">\r\n <mat-icon *ngIf=\"chart.footerIcon\">{{ chart.footerIcon }}</mat-icon>\r\n <span>{{ chart.footer }}</span>\r\n </div>\r\n </div>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".charts-grid{display:grid;grid-template-columns:repeat(var(--columns, auto-fit),minmax(380px,1fr));gap:10px;padding:12px 0;margin-left:-5px}.chart-card{padding:20px;display:flex;flex-direction:column;border-radius:12px;transition:box-shadow .3s ease}.chart-card:hover{box-shadow:0 6px 20px #00000014}.chart-header{margin-bottom:8px}.chart-title{font-size:16px;font-weight:500;margin:0;color:#333}.chart-subtitle{font-size:13px;color:#9a9a9a;margin:4px 0 0}.chart-body{flex:1;position:relative;padding:8px 4px}.chart-footer{padding-top:12px}.footer-content{display:flex;align-items:center;gap:8px;padding:8px 0 4px;color:#9a9a9a;font-size:13px}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i14.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i9.BaseChartDirective, selector: "canvas[baseChart]", inputs: ["type", "legend", "data", "options", "plugins", "labels", "datasets"], outputs: ["chartClick", "chartHover"], exportAs: ["base-chart"] }] }); }
|
|
15847
16206
|
}
|
|
15848
16207
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: ChartsComponent, decorators: [{
|
|
15849
16208
|
type: Component,
|
|
15850
|
-
args: [{ selector: 'spa-charts', standalone: false, template: "<div class=\"charts-grid\" [style.--columns]=\"config?.columns\">\r\n <ng-container *ngFor=\"let chart of config?.charts\">\r\n <mat-card *ngIf=\"!isHidden(chart)\" class=\"chart-card\">\r\n\r\n <!-- Header -->\r\n <div class=\"chart-header\" *ngIf=\"chart.title\">\r\n <h4 class=\"chart-title\">{{ chart.title }}</h4>\r\n <p class=\"chart-subtitle\" *ngIf=\"chart.subtitle\">{{ chart.subtitle }}</p>\r\n </div>\r\n\r\n <!-- Chart Area -->\r\n <div class=\"chart-body\" [style.height]=\"chart.height ?? '300px'\">\r\n <canvas baseChart\r\n [type]=\"chart.type\"\r\n [data]=\"getChartData(chart)\"\r\n [options]=\"getChartOptions(chart)\"\r\n [plugins]=\"getPlugins(chart)\">\r\n </canvas>\r\n </div>\r\n\r\n <!--
|
|
16209
|
+
args: [{ selector: 'spa-charts', standalone: false, template: "<div class=\"charts-grid\" [style.--columns]=\"config?.columns\">\r\n <ng-container *ngFor=\"let chart of config?.charts\">\r\n <mat-card *ngIf=\"!isHidden(chart)\" class=\"chart-card\">\r\n\r\n <!-- Header -->\r\n <div class=\"chart-header\" *ngIf=\"chart.title\">\r\n <h4 class=\"chart-title\">{{ chart.title }}</h4>\r\n <p class=\"chart-subtitle\" *ngIf=\"chart.subtitle\">{{ chart.subtitle }}</p>\r\n </div>\r\n\r\n <!-- Chart Area -->\r\n <div class=\"chart-body\" [style.height]=\"chart.height ?? '300px'\">\r\n <canvas baseChart\r\n [type]=\"chart.type\"\r\n [data]=\"getChartData(chart)\"\r\n [options]=\"getChartOptions(chart)\"\r\n [plugins]=\"getPlugins(chart)\">\r\n </canvas>\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"chart-footer\" *ngIf=\"chart.footer\">\r\n <mat-divider></mat-divider>\r\n <div class=\"footer-content\">\r\n <mat-icon *ngIf=\"chart.footerIcon\">{{ chart.footerIcon }}</mat-icon>\r\n <span>{{ chart.footer }}</span>\r\n </div>\r\n </div>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".charts-grid{display:grid;grid-template-columns:repeat(var(--columns, auto-fit),minmax(380px,1fr));gap:10px;padding:12px 0;margin-left:-5px}.chart-card{padding:20px;display:flex;flex-direction:column;border-radius:12px;transition:box-shadow .3s ease}.chart-card:hover{box-shadow:0 6px 20px #00000014}.chart-header{margin-bottom:8px}.chart-title{font-size:16px;font-weight:500;margin:0;color:#333}.chart-subtitle{font-size:13px;color:#9a9a9a;margin:4px 0 0}.chart-body{flex:1;position:relative;padding:8px 4px}.chart-footer{padding-top:12px}.footer-content{display:flex;align-items:center;gap:8px;padding:8px 0 4px;color:#9a9a9a;font-size:13px}\n"] }]
|
|
15851
16210
|
}], ctorParameters: () => [{ type: DataServiceLib }, { type: MessageService }], propDecorators: { config: [{
|
|
15852
16211
|
type: Input
|
|
15853
16212
|
}], data: [{
|
|
@@ -17068,7 +17427,7 @@ class RolesComponent {
|
|
|
17068
17427
|
});
|
|
17069
17428
|
}
|
|
17070
17429
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RolesComponent, deps: [{ token: HttpService }, { token: i1$2.Router }, { token: AuthService }, { token: DataServiceLib }, { token: DialogService }, { token: i1.MatDialog }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
17071
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: RolesComponent, isStandalone: false, selector: "spa-roles", ngImport: i0, template: "<h4> Roles </h4>\r\n<hr />\r\n\r\n<div class=\"container-fluid mb-5\">\r\n\r\n <div class=\"d-flex justify-content-between mb-2\">\r\n\r\n <div >\r\n <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end\">\r\n <button id=\"btnRefresh\" mat-icon-button color=\"primary\" (click)=\"refresh()\" matTooltip=\"refresh data\" matTooltipPosition=\"right\"><mat-icon >refresh</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\" *ngFor=\"let role of roles\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" style=\"width:100%\">\r\n\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n\r\n <label style=\"font-size: 16px;\">{{role.roleName}}</label>\r\n\r\n <button mat-icon-button color=\"primary\" matTooltip=\"Rename Role\" (click)=\"renameRole(role)\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <hr style=\"margin-top: 0px;\">\r\n\r\n <div class=\"tin-row\" style=\" font-size:12px;\">\r\n\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capItem of appConfig.capItems\">\r\n\r\n <!-- Main item-->\r\n <mat-checkbox *ngIf=\"capItem.isBool || capItem.capSubItems\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capItem.name]\" (ngModelChange)=\"onCapItemChange(capItem, $event, role)\">\r\n {{capItem.display}}\r\n <span *ngIf=\"!role[capItem.name] && hasSubItemsAccess(capItem, role)\" class=\"asterisk\" style=\"color: red;\">*</span>\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capItem.isBool && !capItem.capSubItems\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capItem.display\"\r\n [(value)]=\"role[capItem.name]\"\r\n width=\"150px\" \r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n\r\n <ng-container *ngIf=\"capItem.capSubItems && role[capItem.name]\">\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubItem of capItem.capSubItems\">\r\n\r\n\r\n <!-- Sub Item -->\r\n <mat-checkbox *ngIf=\"capSubItem.isBool\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubItem.name]\">\r\n {{capSubItem.display}}\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capSubItem.isBool\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capSubItem.display\"\r\n [(value)]=\"role[capSubItem.name]\"\r\n width=\"150px\"\r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n <ng-container *ngIf=\"capSubItem.capSubItems\">\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubSubItem of capSubItem.capSubItems\">\r\n\r\n <!-- Sub Sub Items -->\r\n <mat-checkbox *ngIf=\"capSubSubItem.isBool\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubSubItem.name]\">\r\n {{capSubSubItem.display}}\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capSubSubItem.isBool\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capSubSubItem.display\"\r\n [(value)]=\"role[capSubSubItem.name]\"\r\n width=\"150px\" \r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n </div>\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n </div>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <button mat-raised-button color=\"primary\" (click)=\"updateRole(role)\" style=\"margin-right:10px;\">\r\n <mat-icon>done_all</mat-icon>\r\n Update\r\n </button>\r\n\r\n <button mat-raised-button (click)=\"deleteRole(role)\" style=\"margin-right:10px\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n </div>\r\n\r\n <hr style=\"margin-top: 50px;\" />\r\n\r\n\r\n</div>\r\n\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type:
|
|
17430
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: RolesComponent, isStandalone: false, selector: "spa-roles", ngImport: i0, template: "<h4> Roles </h4>\r\n<hr />\r\n\r\n<div class=\"container-fluid mb-5\">\r\n\r\n <div class=\"d-flex justify-content-between mb-2\">\r\n\r\n <div >\r\n <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end\">\r\n <button id=\"btnRefresh\" mat-icon-button color=\"primary\" (click)=\"refresh()\" matTooltip=\"refresh data\" matTooltipPosition=\"right\"><mat-icon >refresh</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\" *ngFor=\"let role of roles\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" style=\"width:100%\">\r\n\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n\r\n <label style=\"font-size: 16px;\">{{role.roleName}}</label>\r\n\r\n <button mat-icon-button color=\"primary\" matTooltip=\"Rename Role\" (click)=\"renameRole(role)\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n </div>\r\n\r\n <hr style=\"margin-top: 0px;\">\r\n\r\n <div class=\"tin-row\" style=\" font-size:12px;\">\r\n\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capItem of appConfig.capItems\">\r\n\r\n <!-- Main item-->\r\n <mat-checkbox *ngIf=\"capItem.isBool || capItem.capSubItems\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capItem.name]\" (ngModelChange)=\"onCapItemChange(capItem, $event, role)\">\r\n {{capItem.display}}\r\n <span *ngIf=\"!role[capItem.name] && hasSubItemsAccess(capItem, role)\" class=\"asterisk\" style=\"color: red;\">*</span>\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capItem.isBool && !capItem.capSubItems\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capItem.display\"\r\n [(value)]=\"role[capItem.name]\"\r\n width=\"150px\" \r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n\r\n <ng-container *ngIf=\"capItem.capSubItems && role[capItem.name]\">\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubItem of capItem.capSubItems\">\r\n\r\n\r\n <!-- Sub Item -->\r\n <mat-checkbox *ngIf=\"capSubItem.isBool\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubItem.name]\">\r\n {{capSubItem.display}}\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capSubItem.isBool\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capSubItem.display\"\r\n [(value)]=\"role[capSubItem.name]\"\r\n width=\"150px\"\r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n <ng-container *ngIf=\"capSubItem.capSubItems\">\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubSubItem of capSubItem.capSubItems\">\r\n\r\n <!-- Sub Sub Items -->\r\n <mat-checkbox *ngIf=\"capSubSubItem.isBool\"\r\n color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubSubItem.name]\">\r\n {{capSubSubItem.display}}\r\n </mat-checkbox>\r\n\r\n <spa-select\r\n *ngIf=\"!capSubSubItem.isBool\"\r\n [options]=\"roleAccessOptions\"\r\n optionDisplay=\"name\"\r\n optionValue=\"value\"\r\n [display]=\"capSubSubItem.display\"\r\n [(value)]=\"role[capSubSubItem.name]\"\r\n width=\"150px\" \r\n style=\"font-size: 12px;\">\r\n </spa-select>\r\n\r\n </div>\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n </div>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <button mat-raised-button color=\"primary\" (click)=\"updateRole(role)\" style=\"margin-right:10px;\">\r\n <mat-icon>done_all</mat-icon>\r\n Update\r\n </button>\r\n\r\n <button mat-raised-button (click)=\"deleteRole(role)\" style=\"margin-right:10px\">\r\n <mat-icon>delete</mat-icon>\r\n Delete\r\n </button>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n </div>\r\n\r\n <hr style=\"margin-top: 50px;\" />\r\n\r\n\r\n</div>\r\n\r\n", styles: [""], dependencies: [{ kind: "directive", type: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["detailsConfig"] }] }); }
|
|
17072
17431
|
}
|
|
17073
17432
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: RolesComponent, decorators: [{
|
|
17074
17433
|
type: Component,
|
|
@@ -17455,11 +17814,11 @@ class AccountsComponent {
|
|
|
17455
17814
|
this.accountingService = accountingService;
|
|
17456
17815
|
this.accountTileConfig = {
|
|
17457
17816
|
tiles: [
|
|
17458
|
-
{ name: 'totalAssets', alias: 'Total Assets', color: '#2196F3', info: 'Total value of all asset accounts' },
|
|
17459
|
-
{ name: 'totalLiabilities', alias: 'Total Liabilities', color: '#F44336', info: 'Total value of all liability accounts' },
|
|
17460
|
-
{ name: 'totalRevenue', alias: 'Revenue', color: '#9C27B0', info: 'Total revenue from all sources' },
|
|
17461
|
-
{ name: 'totalExpense', alias: 'Expenses', color: '#FF9800', info: 'Total expenses across all accounts' },
|
|
17462
|
-
{ name: 'totalEquity', alias: 'Total Equity', color: '#4CAF50', info: 'Total value of all equity accounts' },
|
|
17817
|
+
{ name: 'totalAssets', alias: 'Total Assets', color: '#2196F3', icon: 'account_balance', info: 'Total value of all asset accounts' }, // Changed: Added icon
|
|
17818
|
+
{ name: 'totalLiabilities', alias: 'Total Liabilities', color: '#F44336', icon: 'credit_card', info: 'Total value of all liability accounts' }, // Changed: Added icon
|
|
17819
|
+
{ name: 'totalRevenue', alias: 'Revenue', color: '#9C27B0', icon: 'trending_up', info: 'Total revenue from all sources' }, // Changed: Added icon
|
|
17820
|
+
{ name: 'totalExpense', alias: 'Expenses', color: '#FF9800', icon: 'trending_down', info: 'Total expenses across all accounts' }, // Changed: Added icon
|
|
17821
|
+
{ name: 'totalEquity', alias: 'Total Equity', color: '#4CAF50', icon: 'savings', info: 'Total value of all equity accounts' }, // Changed: Added icon
|
|
17463
17822
|
]
|
|
17464
17823
|
};
|
|
17465
17824
|
this.accountTabConfigs = [
|
|
@@ -17869,6 +18228,7 @@ class PurchasingService {
|
|
|
17869
18228
|
loadAction: { url: 'inventoryreceipts/list/timing' }, defaultFirstValue: true,
|
|
17870
18229
|
infoMessage: 'Cash Purchase (pay now) or Credit Purchase (pay later)'
|
|
17871
18230
|
},
|
|
18231
|
+
{ name: 'currencyID', type: 'select', alias: 'Currency', section: 'receiptInfo', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this purchase (defaults to base currency)' }, // Changed: Added currency select for multi-currency purchases
|
|
17872
18232
|
{ name: 'paymentType', type: 'select', required: true, alias: 'Payment Method', section: 'receiptInfo', defaultFirstValue: true,
|
|
17873
18233
|
options: this.paymentTypeOptions, infoMessage: 'Payment method used for this purchase',
|
|
17874
18234
|
hiddenCondition: x => x.timing === 1,
|
|
@@ -17973,6 +18333,7 @@ class PurchasingService {
|
|
|
17973
18333
|
{ name: 'inventoryReceiptID', type: 'number', hidden: true },
|
|
17974
18334
|
{ name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true },
|
|
17975
18335
|
{ name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue: 2, loadAction: { url: 'supplierpayments/list/methods' } },
|
|
18336
|
+
{ name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: Added currency select for multi-currency supplier payments
|
|
17976
18337
|
{ name: 'outstandingAmount', type: 'label', alias: 'Outstanding', readonly: true },
|
|
17977
18338
|
{ name: 'amount', type: 'money', alias: 'Amount', required: true, span: true },
|
|
17978
18339
|
{ name: 'reference', type: 'text', alias: 'Reference', span: true }
|
|
@@ -18014,12 +18375,12 @@ class PurchasingService {
|
|
|
18014
18375
|
// Changed: AP aging summary tiles — mirrors AR aging pattern
|
|
18015
18376
|
this.apAgingTileConfig = {
|
|
18016
18377
|
tiles: [
|
|
18017
|
-
{ name: 'current', alias: 'Current', color: '#4CAF50', info: 'Not yet due' },
|
|
18018
|
-
{ name: 'days30', alias: '1-30 Days', color: '#FFC107', info: '1-30 days overdue' },
|
|
18019
|
-
{ name: 'days60', alias: '31-60 Days', color: '#FF9800', info: '31-60 days overdue' },
|
|
18020
|
-
{ name: 'days90', alias: '61-90 Days', color: '#F44336', info: '61-90 days overdue' },
|
|
18021
|
-
{ name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', info: 'Over 90 days overdue' },
|
|
18022
|
-
{ name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', info: 'Total outstanding amount' }
|
|
18378
|
+
{ name: 'current', alias: 'Current', color: '#4CAF50', icon: 'check_circle', info: 'Not yet due' }, // Changed: Added icon
|
|
18379
|
+
{ name: 'days30', alias: '1-30 Days', color: '#FFC107', icon: 'schedule', info: '1-30 days overdue' }, // Changed: Added icon
|
|
18380
|
+
{ name: 'days60', alias: '31-60 Days', color: '#FF9800', icon: 'warning', info: '31-60 days overdue' }, // Changed: Added icon
|
|
18381
|
+
{ name: 'days90', alias: '61-90 Days', color: '#F44336', icon: 'error', info: '61-90 days overdue' }, // Changed: Added icon
|
|
18382
|
+
{ name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', icon: 'dangerous', info: 'Over 90 days overdue' }, // Changed: Added icon
|
|
18383
|
+
{ name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', icon: 'account_balance_wallet', info: 'Total outstanding amount' } // Changed: Added icon
|
|
18023
18384
|
],
|
|
18024
18385
|
};
|
|
18025
18386
|
// Changed: AP aging base table config — common columns for all aging tabs
|
|
@@ -18525,6 +18886,7 @@ class SalesService {
|
|
|
18525
18886
|
{ name: 'saleDate', type: 'date', required: true, alias: 'Sale Date', section: 'saleInfo', infoMessage: 'Date when the sale was completed' },
|
|
18526
18887
|
{ name: 'customerID', type: 'select', required: true, alias: 'Customer', section: 'saleInfo', loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig },
|
|
18527
18888
|
{ name: 'timing', type: 'select', required: true, alias: 'Transaction Type', section: 'saleInfo', loadAction: { url: 'sales/list/timing' }, defaultFirstValue: true, infoMessage: 'Cash Sale (pay now) or Credit Sale (pay later)' },
|
|
18889
|
+
{ name: 'currencyID', type: 'select', alias: 'Currency', section: 'saleInfo', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this sale (defaults to base currency)' }, // Changed: Added currency select for multi-currency sales
|
|
18528
18890
|
{ name: 'paymentMethod', type: 'select', required: true, alias: 'Payment Method', section: 'saleInfo', defaultFirstValue: true, infoMessage: 'Method of payment used for this sale', requiredCondition: x => x.timing === 0, hiddenCondition: x => x.timing === 1,
|
|
18529
18891
|
options: [
|
|
18530
18892
|
{ name: 'Cash', value: 0 },
|
|
@@ -18575,6 +18937,7 @@ class SalesService {
|
|
|
18575
18937
|
{ name: 'saleID', type: 'number', hidden: true },
|
|
18576
18938
|
{ name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true },
|
|
18577
18939
|
{ name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue: 1, loadAction: { url: 'invoicepayments/list/methods' } },
|
|
18940
|
+
{ name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: Added currency select for multi-currency sale payments
|
|
18578
18941
|
{ name: 'totalAmount', type: 'label', alias: 'Total Amount', readonly: true },
|
|
18579
18942
|
{ name: 'amount', type: 'money', alias: 'Amount', required: true, span: true },
|
|
18580
18943
|
{ name: 'paymentReferenceTemp', type: 'text', alias: 'Reference', span: true }
|
|
@@ -18773,7 +19136,17 @@ class InventoryDashboardComponent {
|
|
|
18773
19136
|
{ name: 'itemsInStock', alias: 'Items In Stock', color: '#ff9800', icon: 'inventory', style: 'icon', info: 'Total inventory item count' },
|
|
18774
19137
|
{ name: 'adjustmentsThisMonth', alias: 'Adjustments (MTD)', color: '#9c27b0', icon: 'tune', style: 'icon', info: 'Inventory adjustments this month' },
|
|
18775
19138
|
],
|
|
18776
|
-
loadAction: { url: 'dashboard/
|
|
19139
|
+
loadAction: { url: 'products/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
19140
|
+
loadInit: true
|
|
19141
|
+
};
|
|
19142
|
+
// Changed: Chart-style tiles now use loadAction with dataField for dynamic data
|
|
19143
|
+
this.chartTiles = {
|
|
19144
|
+
tiles: [
|
|
19145
|
+
{ name: 'stockHealth', alias: 'Stock Health', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'stockHealth' }, footer: 'Items above reorder level', footerIcon: 'health_and_safety' }, // Changed: dataField replaces gaugeValue
|
|
19146
|
+
{ name: 'movementSpark', alias: 'Stock Movement', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 130, dataField: 'movementSpark' }, footer: 'Last 12 months', footerIcon: 'trending_up' }, // Changed: dataField replaces inline data
|
|
19147
|
+
{ name: 'categorySplit', alias: 'By Category', color: '#ff9800', chart: { type: 'pie', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'], height: 130, dataField: 'categorySplit' }, footer: 'Value distribution', footerIcon: 'donut_large' }, // Changed: dataField replaces inline data
|
|
19148
|
+
],
|
|
19149
|
+
loadAction: { url: 'products/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API
|
|
18777
19150
|
loadInit: true
|
|
18778
19151
|
};
|
|
18779
19152
|
this.chartConfig = {
|
|
@@ -18781,9 +19154,9 @@ class InventoryDashboardComponent {
|
|
|
18781
19154
|
{ name: 'stockByCategory', title: 'Stock Levels by Category', type: 'bar', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0', '#795548', '#607d8b'] },
|
|
18782
19155
|
{ name: 'lowStockProducts', title: 'Low Stock Products', type: 'bar', height: '300px', colors: ['#f44336'] },
|
|
18783
19156
|
{ name: 'valueByCategory', title: 'Value by Category', type: 'pie', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0', '#795548', '#607d8b'] },
|
|
18784
|
-
{ name: 'movementTrend', title: 'Stock Movement Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336', '#2196f3'] },
|
|
19157
|
+
{ name: 'movementTrend', title: 'Stock Movement Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336', '#2196f3'], showLegend: true }, // Changed: showLegend for line chart
|
|
18785
19158
|
],
|
|
18786
|
-
loadAction: { url: 'dashboard/
|
|
19159
|
+
loadAction: { url: 'products/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
18787
19160
|
loadInit: true,
|
|
18788
19161
|
columns: 2
|
|
18789
19162
|
};
|
|
@@ -18793,6 +19166,9 @@ class InventoryDashboardComponent {
|
|
|
18793
19166
|
<div class="dashboard-container">
|
|
18794
19167
|
<h4 class="dashboard-title"><mat-icon>inventory_2</mat-icon> Inventory Dashboard</h4>
|
|
18795
19168
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
19169
|
+
<!-- Changed: Spacer div ensures margin between summary and chart tiles -->
|
|
19170
|
+
<div style="margin-top: 16px;"></div>
|
|
19171
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
18796
19172
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
18797
19173
|
</div>
|
|
18798
19174
|
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }] }); }
|
|
@@ -18803,6 +19179,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
18803
19179
|
<div class="dashboard-container">
|
|
18804
19180
|
<h4 class="dashboard-title"><mat-icon>inventory_2</mat-icon> Inventory Dashboard</h4>
|
|
18805
19181
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
19182
|
+
<!-- Changed: Spacer div ensures margin between summary and chart tiles -->
|
|
19183
|
+
<div style="margin-top: 16px;"></div>
|
|
19184
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
18806
19185
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
18807
19186
|
</div>
|
|
18808
19187
|
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"] }]
|
|
@@ -19324,14 +19703,6 @@ class PreferencesComponent {
|
|
|
19324
19703
|
this.dataServiceLib = dataServiceLib;
|
|
19325
19704
|
this.messageService = messageService;
|
|
19326
19705
|
this.preference = {};
|
|
19327
|
-
this.currencyOptions = [
|
|
19328
|
-
{ name: "US Dollar (USD)", value: "USD" },
|
|
19329
|
-
{ name: "Euro (EUR)", value: "EUR" },
|
|
19330
|
-
{ name: "British Pound (GBP)", value: "GBP" },
|
|
19331
|
-
{ name: "South African Rand (ZAR)", value: "ZAR" },
|
|
19332
|
-
{ name: "Botswana Pula (BWP)", value: "BWP" },
|
|
19333
|
-
{ name: "Zimbabwe Gold (ZWG)", value: "ZWG" }
|
|
19334
|
-
];
|
|
19335
19706
|
this.monthOptions = [
|
|
19336
19707
|
{ name: "January", value: 1 },
|
|
19337
19708
|
{ name: "February", value: 2 },
|
|
@@ -19370,11 +19741,11 @@ class PreferencesComponent {
|
|
|
19370
19741
|
});
|
|
19371
19742
|
}
|
|
19372
19743
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PreferencesComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
19373
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: PreferencesComponent, isStandalone: false, selector: "spa-preferences", ngImport: i0, template: "<h4>Preferences</h4>\r\n<hr>\r\n\r\n<mat-card>\r\n <mat-card-content>\r\n <form (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"tin-col mt-3\">\r\n\r\n <div class=\"header-title\">General</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"Default Currency\" [(value)]=\"preference.
|
|
19744
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: PreferencesComponent, isStandalone: false, selector: "spa-preferences", ngImport: i0, template: "<h4>Preferences</h4>\r\n<hr>\r\n\r\n<mat-card>\r\n <mat-card-content>\r\n <form (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"tin-col mt-3\">\r\n\r\n <div class=\"header-title\">General</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"Default Currency\" [(value)]=\"preference.baseCurrencyID\" optionDisplay=\"name\" optionValue=\"value\" [loadAction]=\"{url: 'currencies/list'}\"></spa-select>\r\n </div>\r\n\r\n <div class=\"header-title\">Accounting</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"First Month of Year\" [(value)]=\"preference.firstMonthOfYear\" optionDisplay=\"name\" optionValue=\"value\" [options]=\"monthOptions\"></spa-select>\r\n <spa-select display=\"First Day of Month\" [(value)]=\"preference.firstDayOfMonth\" optionDisplay=\"name\" optionValue=\"value\" [options]=\"dayOptions\"></spa-select>\r\n </div>\r\n\r\n </div>\r\n\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\">Save Preferences</button>\r\n </mat-card-actions>\r\n </form>\r\n </mat-card-content>\r\n</mat-card>\r\n", styles: [".header-title{font-size:24px;font-weight:300}.header-line{margin-top:5px;margin-bottom:5px}.header{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px;margin-bottom:30px}\n"], dependencies: [{ kind: "directive", type: i2$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$3.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.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: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i6$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["detailsConfig"] }] }); }
|
|
19374
19745
|
}
|
|
19375
19746
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PreferencesComponent, decorators: [{
|
|
19376
19747
|
type: Component,
|
|
19377
|
-
args: [{ selector: 'spa-preferences', standalone: false, template: "<h4>Preferences</h4>\r\n<hr>\r\n\r\n<mat-card>\r\n <mat-card-content>\r\n <form (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"tin-col mt-3\">\r\n\r\n <div class=\"header-title\">General</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"Default Currency\" [(value)]=\"preference.
|
|
19748
|
+
args: [{ selector: 'spa-preferences', standalone: false, template: "<h4>Preferences</h4>\r\n<hr>\r\n\r\n<mat-card>\r\n <mat-card-content>\r\n <form (ngSubmit)=\"onSubmit()\">\r\n\r\n <div class=\"tin-col mt-3\">\r\n\r\n <div class=\"header-title\">General</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"Default Currency\" [(value)]=\"preference.baseCurrencyID\" optionDisplay=\"name\" optionValue=\"value\" [loadAction]=\"{url: 'currencies/list'}\"></spa-select>\r\n </div>\r\n\r\n <div class=\"header-title\">Accounting</div>\r\n <hr class=\"header-line\">\r\n <div class=\"ml-4 header\">\r\n <spa-select display=\"First Month of Year\" [(value)]=\"preference.firstMonthOfYear\" optionDisplay=\"name\" optionValue=\"value\" [options]=\"monthOptions\"></spa-select>\r\n <spa-select display=\"First Day of Month\" [(value)]=\"preference.firstDayOfMonth\" optionDisplay=\"name\" optionValue=\"value\" [options]=\"dayOptions\"></spa-select>\r\n </div>\r\n\r\n </div>\r\n\r\n <mat-card-actions>\r\n <button mat-raised-button color=\"primary\" type=\"submit\">Save Preferences</button>\r\n </mat-card-actions>\r\n </form>\r\n </mat-card-content>\r\n</mat-card>\r\n", styles: [".header-title{font-size:24px;font-weight:300}.header-line{margin-top:5px;margin-bottom:5px}.header{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px;margin-bottom:30px}\n"] }]
|
|
19378
19749
|
}], ctorParameters: () => [{ type: DataServiceLib }, { type: MessageService }] });
|
|
19379
19750
|
|
|
19380
19751
|
class PayrollService {
|
|
@@ -20185,17 +20556,28 @@ class AccountingDashboardComponent {
|
|
|
20185
20556
|
{ name: 'outstandingAP', alias: 'Outstanding AP', color: '#9c27b0', icon: 'payments', style: 'icon', info: 'Unpaid supplier amounts' }, // Changed: Removed prefix
|
|
20186
20557
|
{ name: 'overdueInvoices', alias: 'Overdue Invoices', color: '#f44336', icon: 'warning', style: 'icon', info: 'Invoices past due date' },
|
|
20187
20558
|
],
|
|
20188
|
-
loadAction: { url: 'dashboard/
|
|
20559
|
+
loadAction: { url: 'accounts/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20560
|
+
loadInit: true
|
|
20561
|
+
};
|
|
20562
|
+
// Changed: Chart-style tiles now use loadAction with dataField for dynamic data
|
|
20563
|
+
this.chartTiles = {
|
|
20564
|
+
tiles: [
|
|
20565
|
+
{ name: 'collectionRate', alias: 'Collection Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'collectionRate' }, footer: 'Invoice collection rate', footerIcon: 'check_circle' }, // Changed: dataField replaces gaugeValue
|
|
20566
|
+
{ name: 'revenueTrendSpark', alias: 'Revenue Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'revenueTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' }, // Changed: dataField replaces inline data
|
|
20567
|
+
{ name: 'invoiceStatusSplit', alias: 'Invoice Status', color: '#ff9800', chart: { type: 'pie', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'], height: 130, dataField: 'invoiceStatusSplit' }, footer: 'Current distribution', footerIcon: 'receipt' }, // Changed: dataField replaces inline data
|
|
20568
|
+
{ name: 'expenseTrendSpark', alias: 'Expense Trend', color: '#f44336', chart: { type: 'bar', colors: ['#f44336', '#ef5350', '#e57373', '#ef9a9a', '#ffcdd2', '#f44336'], height: 100, dataField: 'expenseTrendSpark' }, footer: 'Last 6 months', footerIcon: 'trending_down' }, // Changed: dataField replaces inline data
|
|
20569
|
+
],
|
|
20570
|
+
loadAction: { url: 'accounts/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API
|
|
20189
20571
|
loadInit: true
|
|
20190
20572
|
};
|
|
20191
20573
|
this.chartConfig = {
|
|
20192
20574
|
charts: [
|
|
20193
|
-
{ name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'] },
|
|
20575
|
+
{ name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: showLegend for line chart
|
|
20194
20576
|
{ name: 'arAging', title: 'AR Aging Breakdown', type: 'bar', height: '300px', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'] },
|
|
20195
20577
|
{ name: 'accountBalances', title: 'Account Balances by Type', type: 'bar', height: '300px', colors: ['#2196f3', '#f44336', '#4caf50', '#ff9800', '#9c27b0'] },
|
|
20196
20578
|
{ name: 'invoiceStatus', title: 'Invoice Status Distribution', type: 'doughnut', height: '300px', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'] },
|
|
20197
20579
|
],
|
|
20198
|
-
loadAction: { url: 'dashboard/
|
|
20580
|
+
loadAction: { url: 'accounts/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20199
20581
|
loadInit: true,
|
|
20200
20582
|
columns: 2
|
|
20201
20583
|
};
|
|
@@ -20205,6 +20587,9 @@ class AccountingDashboardComponent {
|
|
|
20205
20587
|
<div class="dashboard-container">
|
|
20206
20588
|
<h4 class="dashboard-title"><mat-icon>account_balance</mat-icon> Accounting Dashboard</h4>
|
|
20207
20589
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20590
|
+
<!-- Changed: Chart tiles for mini financial indicators -->
|
|
20591
|
+
<div style="margin-top: 16px;"></div>
|
|
20592
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20208
20593
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20209
20594
|
</div>
|
|
20210
20595
|
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }] }); }
|
|
@@ -20215,6 +20600,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
20215
20600
|
<div class="dashboard-container">
|
|
20216
20601
|
<h4 class="dashboard-title"><mat-icon>account_balance</mat-icon> Accounting Dashboard</h4>
|
|
20217
20602
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20603
|
+
<!-- Changed: Chart tiles for mini financial indicators -->
|
|
20604
|
+
<div style="margin-top: 16px;"></div>
|
|
20605
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20218
20606
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20219
20607
|
</div>
|
|
20220
20608
|
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"] }]
|
|
@@ -20231,17 +20619,27 @@ class SalesDashboardComponent {
|
|
|
20231
20619
|
{ name: 'creditSalesOutstanding', alias: 'Credit Outstanding', color: '#f44336', icon: 'credit_card', style: 'icon', info: 'Outstanding credit sale amounts' }, // Changed: Removed prefix
|
|
20232
20620
|
{ name: 'topProduct', alias: 'Top Product', color: '#9c27b0', icon: 'star', style: 'icon', info: 'Best selling product this month' },
|
|
20233
20621
|
],
|
|
20234
|
-
loadAction: { url: '
|
|
20622
|
+
loadAction: { url: 'sales/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20623
|
+
loadInit: true
|
|
20624
|
+
};
|
|
20625
|
+
// Changed: Chart-style tiles now use loadAction with dataField for dynamic data
|
|
20626
|
+
this.chartTiles = {
|
|
20627
|
+
tiles: [
|
|
20628
|
+
{ name: 'conversionRate', alias: 'Conversion Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'conversionRate' }, footer: 'Quote to sale conversion', footerIcon: 'swap_horiz' }, // Changed: dataField replaces gaugeValue
|
|
20629
|
+
{ name: 'salesTrendSpark', alias: 'Sales Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'salesTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' }, // Changed: dataField replaces inline data
|
|
20630
|
+
{ name: 'paymentSplit', alias: 'Payment Methods', color: '#9c27b0', chart: { type: 'doughnut', colors: ['#4caf50', '#2196f3', '#ff9800', '#9c27b0'], height: 130, dataField: 'paymentSplit' }, footer: 'Current distribution', footerIcon: 'payment' }, // Changed: dataField replaces inline data
|
|
20631
|
+
],
|
|
20632
|
+
loadAction: { url: 'sales/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API
|
|
20235
20633
|
loadInit: true
|
|
20236
20634
|
};
|
|
20237
20635
|
this.chartConfig = {
|
|
20238
20636
|
charts: [
|
|
20239
|
-
{ name: 'salesTrend', title: 'Sales Revenue Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#2196f3'] },
|
|
20637
|
+
{ name: 'salesTrend', title: 'Sales Revenue Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#2196f3'], showLegend: true }, // Changed: showLegend for line chart
|
|
20240
20638
|
{ name: 'paymentMethods', title: 'Payment Method Breakdown', type: 'doughnut', height: '300px', colors: ['#4caf50', '#2196f3', '#ff9800', '#9c27b0', '#f44336'] },
|
|
20241
20639
|
{ name: 'topProducts', title: 'Top Selling Products', type: 'bar', height: '300px', colors: ['#4caf50', '#66bb6a', '#81c784', '#a5d6a7', '#c8e6c9'] },
|
|
20242
20640
|
{ name: 'orderPipeline', title: 'Sales Order Pipeline', type: 'bar', height: '300px', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'] },
|
|
20243
20641
|
],
|
|
20244
|
-
loadAction: { url: '
|
|
20642
|
+
loadAction: { url: 'sales/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20245
20643
|
loadInit: true,
|
|
20246
20644
|
columns: 2
|
|
20247
20645
|
};
|
|
@@ -20251,6 +20649,9 @@ class SalesDashboardComponent {
|
|
|
20251
20649
|
<div class="dashboard-container">
|
|
20252
20650
|
<h4 class="dashboard-title"><mat-icon>point_of_sale</mat-icon> Sales Dashboard</h4>
|
|
20253
20651
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20652
|
+
<!-- Changed: Chart tiles for sales visual indicators -->
|
|
20653
|
+
<div style="margin-top: 16px;"></div>
|
|
20654
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20254
20655
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20255
20656
|
</div>
|
|
20256
20657
|
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }] }); }
|
|
@@ -20261,6 +20662,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
20261
20662
|
<div class="dashboard-container">
|
|
20262
20663
|
<h4 class="dashboard-title"><mat-icon>point_of_sale</mat-icon> Sales Dashboard</h4>
|
|
20263
20664
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20665
|
+
<!-- Changed: Chart tiles for sales visual indicators -->
|
|
20666
|
+
<div style="margin-top: 16px;"></div>
|
|
20667
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20264
20668
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20265
20669
|
</div>
|
|
20266
20670
|
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"] }]
|
|
@@ -20277,17 +20681,27 @@ class PurchasingDashboardComponent {
|
|
|
20277
20681
|
{ name: 'supplierPaymentsOutstanding', alias: 'AP Outstanding', color: '#f44336', icon: 'payments', style: 'icon', info: 'Outstanding supplier payment amounts' }, // Changed: Removed prefix
|
|
20278
20682
|
{ name: 'receiptsThisMonth', alias: 'Receipts (MTD)', color: '#4caf50', icon: 'receipt', style: 'icon', info: 'Inventory receipts processed this month' },
|
|
20279
20683
|
],
|
|
20280
|
-
loadAction: { url: 'dashboard/
|
|
20684
|
+
loadAction: { url: 'inventoryreceipts/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20685
|
+
loadInit: true
|
|
20686
|
+
};
|
|
20687
|
+
// Changed: Chart-style tiles now use loadAction with dataField for dynamic data
|
|
20688
|
+
this.chartTiles = {
|
|
20689
|
+
tiles: [
|
|
20690
|
+
{ name: 'fulfillmentRate', alias: 'Fulfillment Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'fulfillmentRate' }, footer: 'PO fulfillment rate', footerIcon: 'verified' }, // Changed: dataField replaces gaugeValue
|
|
20691
|
+
{ name: 'spendTrendSpark', alias: 'Spend Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'spendTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' }, // Changed: dataField replaces inline data
|
|
20692
|
+
{ name: 'poStatusSplit', alias: 'PO Status', color: '#ff9800', chart: { type: 'doughnut', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336'], height: 130, dataField: 'poStatusSplit' }, footer: 'Current distribution', footerIcon: 'assignment' }, // Changed: dataField replaces inline data
|
|
20693
|
+
],
|
|
20694
|
+
loadAction: { url: 'inventoryreceipts/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API
|
|
20281
20695
|
loadInit: true
|
|
20282
20696
|
};
|
|
20283
20697
|
this.chartConfig = {
|
|
20284
20698
|
charts: [
|
|
20285
|
-
{ name: 'purchaseTrend', title: 'Purchase Spend Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196f3', '#f44336'] },
|
|
20699
|
+
{ name: 'purchaseTrend', title: 'Purchase Spend Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196f3', '#f44336'], showLegend: true }, // Changed: showLegend for line chart
|
|
20286
20700
|
{ name: 'poStatus', title: 'PO Status Distribution', type: 'doughnut', height: '300px', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'] },
|
|
20287
20701
|
{ name: 'topSuppliers', title: 'Top Suppliers by Spend', type: 'bar', height: '300px', colors: ['#2196f3', '#42a5f5', '#64b5f6', '#90caf9', '#bbdefb'] },
|
|
20288
20702
|
{ name: 'apAging', title: 'AP Aging Breakdown', type: 'bar', height: '300px', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'] },
|
|
20289
20703
|
],
|
|
20290
|
-
loadAction: { url: 'dashboard/
|
|
20704
|
+
loadAction: { url: 'inventoryreceipts/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint
|
|
20291
20705
|
loadInit: true,
|
|
20292
20706
|
columns: 2
|
|
20293
20707
|
};
|
|
@@ -20297,6 +20711,9 @@ class PurchasingDashboardComponent {
|
|
|
20297
20711
|
<div class="dashboard-container">
|
|
20298
20712
|
<h4 class="dashboard-title"><mat-icon>local_shipping</mat-icon> Purchasing Dashboard</h4>
|
|
20299
20713
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20714
|
+
<!-- Changed: Chart tiles for purchasing visual indicators -->
|
|
20715
|
+
<div style="margin-top: 16px;"></div>
|
|
20716
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20300
20717
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20301
20718
|
</div>
|
|
20302
20719
|
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }] }); }
|
|
@@ -20307,6 +20724,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
20307
20724
|
<div class="dashboard-container">
|
|
20308
20725
|
<h4 class="dashboard-title"><mat-icon>local_shipping</mat-icon> Purchasing Dashboard</h4>
|
|
20309
20726
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20727
|
+
<!-- Changed: Chart tiles for purchasing visual indicators -->
|
|
20728
|
+
<div style="margin-top: 16px;"></div>
|
|
20729
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20310
20730
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20311
20731
|
</div>
|
|
20312
20732
|
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"] }]
|
|
@@ -20317,20 +20737,31 @@ class OverviewDashboardComponent {
|
|
|
20317
20737
|
constructor() {
|
|
20318
20738
|
this.summaryTiles = {
|
|
20319
20739
|
tiles: [
|
|
20320
|
-
{ name: 'revenue', alias: 'Revenue', color: '#4caf50', icon: 'trending_up', style: 'icon', info: 'Total revenue (all time)' },
|
|
20321
|
-
{ name: 'expenses', alias: 'Expenses', color: '#f44336', icon: 'trending_down', style: 'icon', info: 'Total expenses (all time)' },
|
|
20322
|
-
{ name: 'netProfit', alias: 'Net Profit', color: '#2196f3', icon: 'account_balance', style: 'icon', info: 'Revenue minus expenses' },
|
|
20323
|
-
{ name: 'stockValue', alias: 'Stock Value', color: '#ff9800', icon: 'inventory_2', style: 'icon', info: 'Total inventory value' },
|
|
20324
|
-
{ name: 'outstandingAR', alias: 'Outstanding AR', color: '#9c27b0', icon: 'receipt_long', style: 'icon', info: 'Unpaid invoice amounts' },
|
|
20325
|
-
{ name: 'outstandingAP', alias: 'Outstanding AP', color: '#e91e63', icon: 'payments', style: 'icon', info: 'Unpaid supplier amounts' },
|
|
20740
|
+
{ name: 'revenue', alias: 'Revenue', color: '#4caf50', icon: 'trending_up', style: 'icon', info: 'Total revenue (all time)' },
|
|
20741
|
+
{ name: 'expenses', alias: 'Expenses', color: '#f44336', icon: 'trending_down', style: 'icon', info: 'Total expenses (all time)' },
|
|
20742
|
+
{ name: 'netProfit', alias: 'Net Profit', color: '#2196f3', icon: 'account_balance', style: 'icon', info: 'Revenue minus expenses' },
|
|
20743
|
+
{ name: 'stockValue', alias: 'Stock Value', color: '#ff9800', icon: 'inventory_2', style: 'icon', info: 'Total inventory value' },
|
|
20744
|
+
{ name: 'outstandingAR', alias: 'Outstanding AR', color: '#9c27b0', icon: 'receipt_long', style: 'icon', info: 'Unpaid invoice amounts' },
|
|
20745
|
+
{ name: 'outstandingAP', alias: 'Outstanding AP', color: '#e91e63', icon: 'payments', style: 'icon', info: 'Unpaid supplier amounts' },
|
|
20326
20746
|
],
|
|
20327
20747
|
loadAction: { url: 'dashboard/overview/summary' },
|
|
20328
20748
|
loadInit: true
|
|
20329
20749
|
};
|
|
20750
|
+
// Changed: Chart-style tiles now use loadAction with dataField for dynamic data
|
|
20751
|
+
this.chartTiles = {
|
|
20752
|
+
tiles: [
|
|
20753
|
+
{ name: 'profitMarginValue', alias: 'Profit Margin', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'profitMarginValue' }, footer: 'Based on all-time revenue', footerIcon: 'info' }, // Changed: dataField replaces gaugeValue
|
|
20754
|
+
{ name: 'revenueSparkline', alias: 'Revenue Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'revenueSparkline' }, footer: 'Last 12 months', footerIcon: 'timeline' }, // Changed: dataField replaces inline data
|
|
20755
|
+
{ name: 'expenseBreakdown', alias: 'Expense Split', color: '#ff9800', chart: { type: 'doughnut', colors: ['#ff9800', '#f44336', '#9c27b0', '#2196f3', '#4caf50'], height: 130, dataField: 'expenseBreakdown' }, footer: 'By category', footerIcon: 'pie_chart' }, // Changed: dataField replaces inline data
|
|
20756
|
+
{ name: 'monthlyOrders', alias: 'Monthly Orders', color: '#9c27b0', chart: { type: 'bar', colors: ['#9c27b0', '#ba68c8', '#ce93d8', '#e1bee7', '#9c27b0', '#ba68c8'], height: 100, dataField: 'monthlyOrders' }, footer: 'Last 6 months', footerIcon: 'bar_chart' }, // Changed: dataField replaces inline data
|
|
20757
|
+
],
|
|
20758
|
+
loadAction: { url: 'dashboard/overview/chart-tiles' }, // Changed: Load chart tile data from API
|
|
20759
|
+
loadInit: true
|
|
20760
|
+
};
|
|
20330
20761
|
this.chartConfig = {
|
|
20331
20762
|
charts: [
|
|
20332
|
-
{ name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'] },
|
|
20333
|
-
{ name: 'cashFlow', title: 'Monthly Cash Flow', type: 'bar', height: '300px', colors: ['#4caf50', '#f44336'] },
|
|
20763
|
+
{ name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: showLegend for line chart
|
|
20764
|
+
{ name: 'cashFlow', title: 'Monthly Cash Flow', type: 'bar', height: '300px', colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: showLegend for multi-dataset bar chart
|
|
20334
20765
|
{ name: 'profitMargin', title: 'Profit Margin', type: 'doughnut', height: '300px', colors: ['#4caf50', '#e0e0e0'] },
|
|
20335
20766
|
{ name: 'healthIndicators', title: 'Business Health Indicators', type: 'doughnut', height: '300px', colors: ['#4caf50', '#e0e0e0', '#2196f3', '#e0e0e0', '#ff9800', '#e0e0e0'] },
|
|
20336
20767
|
],
|
|
@@ -20343,7 +20774,11 @@ class OverviewDashboardComponent {
|
|
|
20343
20774
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: OverviewDashboardComponent, isStandalone: false, selector: "spa-overview-dashboard", ngImport: i0, template: `
|
|
20344
20775
|
<div class="dashboard-container">
|
|
20345
20776
|
<h4 class="dashboard-title"><mat-icon>dashboard</mat-icon> Overview Dashboard</h4>
|
|
20777
|
+
<!-- Changed: Icon tiles for primary KPIs -->
|
|
20346
20778
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20779
|
+
<!-- Changed: Chart tiles for mini visual indicators -->
|
|
20780
|
+
<div style="margin-top: 16px;"></div>
|
|
20781
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20347
20782
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20348
20783
|
</div>
|
|
20349
20784
|
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"], dependencies: [{ kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }] }); }
|
|
@@ -20353,12 +20788,286 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
20353
20788
|
args: [{ selector: 'spa-overview-dashboard', template: `
|
|
20354
20789
|
<div class="dashboard-container">
|
|
20355
20790
|
<h4 class="dashboard-title"><mat-icon>dashboard</mat-icon> Overview Dashboard</h4>
|
|
20791
|
+
<!-- Changed: Icon tiles for primary KPIs -->
|
|
20356
20792
|
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20793
|
+
<!-- Changed: Chart tiles for mini visual indicators -->
|
|
20794
|
+
<div style="margin-top: 16px;"></div>
|
|
20795
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20357
20796
|
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20358
20797
|
</div>
|
|
20359
20798
|
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}\n"] }]
|
|
20360
20799
|
}] });
|
|
20361
20800
|
|
|
20801
|
+
// Invoice module dashboard with pipeline visibility, aging, and collection KPIs
|
|
20802
|
+
class InvoiceDashboardComponent {
|
|
20803
|
+
constructor(dataService) {
|
|
20804
|
+
this.dataService = dataService;
|
|
20805
|
+
this.attentionItems = [];
|
|
20806
|
+
// Changed: Summary tiles — invoice pipeline KPIs
|
|
20807
|
+
this.summaryTiles = {
|
|
20808
|
+
tiles: [
|
|
20809
|
+
{ name: 'totalInvoices', alias: 'Total Invoices', color: '#1565c0', icon: 'receipt_long', style: 'icon', info: 'All active invoices' },
|
|
20810
|
+
{ name: 'drafts', alias: 'Drafts', color: '#9e9e9e', icon: 'edit_note', style: 'icon', info: 'Invoices awaiting submission' },
|
|
20811
|
+
{ name: 'outstandingAmount', alias: 'Outstanding', color: '#ff9800', icon: 'pending', style: 'icon', prefix: '$', info: 'Total unpaid amount' },
|
|
20812
|
+
{ name: 'overdueCount', alias: 'Overdue', color: '#f44336', icon: 'warning', style: 'icon', info: 'Invoices past due date' },
|
|
20813
|
+
{ name: 'paidThisMonth', alias: 'Paid (Month)', color: '#4caf50', icon: 'check_circle', style: 'icon', info: 'Fully paid this month' },
|
|
20814
|
+
{ name: 'avgDaysToPay', alias: 'Avg Days to Pay', color: '#7b1fa2', icon: 'schedule', style: 'icon', suffix: ' days', info: 'Average payment turnaround' },
|
|
20815
|
+
],
|
|
20816
|
+
loadAction: { url: 'invoices/dashboard-summary/x' },
|
|
20817
|
+
loadInit: true
|
|
20818
|
+
};
|
|
20819
|
+
// Changed: Chart tiles — collection gauge, trend sparkline, status pie, aging bar
|
|
20820
|
+
this.chartTiles = {
|
|
20821
|
+
tiles: [
|
|
20822
|
+
{ name: 'collectionRate', alias: 'Collection Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'collectionRate' }, footer: 'Amount collected vs invoiced', footerIcon: 'check_circle' },
|
|
20823
|
+
{ name: 'invoiceTrend', alias: 'Invoice Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'invoiceTrend' }, footer: 'Last 12 months', footerIcon: 'timeline' },
|
|
20824
|
+
{ name: 'statusDistribution', alias: 'Status Split', color: '#ff9800', chart: { type: 'pie', colors: ['#9e9e9e', '#2196f3', '#ff9800', '#4caf50', '#f44336'], height: 130, dataField: 'statusDistribution' }, footer: 'Current distribution', footerIcon: 'pie_chart' },
|
|
20825
|
+
{ name: 'agingSnapshot', alias: 'Aging Snapshot', color: '#f44336', chart: { type: 'bar', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'], height: 100, dataField: 'agingSnapshot' }, footer: 'Outstanding by age', footerIcon: 'bar_chart' },
|
|
20826
|
+
],
|
|
20827
|
+
loadAction: { url: 'invoices/dashboard-chart-tiles/x' },
|
|
20828
|
+
loadInit: true
|
|
20829
|
+
};
|
|
20830
|
+
// Changed: Full charts — revenue pipeline, aging breakdown, top customers, payment trend
|
|
20831
|
+
this.chartConfig = {
|
|
20832
|
+
charts: [
|
|
20833
|
+
{ name: 'revenuePipeline', title: 'Invoiced vs Collected', type: 'bar', height: '300px', showLegend: true, colors: ['#2196f3', '#4caf50'] },
|
|
20834
|
+
{ name: 'agingBreakdown', title: 'AR Aging Breakdown', type: 'bar', height: '300px', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'] },
|
|
20835
|
+
{ name: 'topCustomers', title: 'Top Customers by Outstanding', type: 'bar', height: '300px', colors: ['#1565c0', '#1976d2', '#1e88e5', '#2196f3', '#42a5f5'] },
|
|
20836
|
+
{ name: 'paymentTrend', title: 'Payment Collection Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50'], showLegend: true },
|
|
20837
|
+
],
|
|
20838
|
+
loadAction: { url: 'invoices/dashboard-charts/x' },
|
|
20839
|
+
loadInit: true,
|
|
20840
|
+
columns: 2
|
|
20841
|
+
};
|
|
20842
|
+
}
|
|
20843
|
+
ngOnInit() {
|
|
20844
|
+
// Load attention items — top overdue invoices needing action
|
|
20845
|
+
this.dataService.CallApi({ url: 'invoices/dashboard-attention/x' }).subscribe((res) => {
|
|
20846
|
+
if (res.success)
|
|
20847
|
+
this.attentionItems = res.data || [];
|
|
20848
|
+
});
|
|
20849
|
+
}
|
|
20850
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: InvoiceDashboardComponent, deps: [{ token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20851
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: InvoiceDashboardComponent, isStandalone: false, selector: "spa-invoice-dashboard", ngImport: i0, template: `
|
|
20852
|
+
<div class="dashboard-container">
|
|
20853
|
+
<h4 class="dashboard-title"><mat-icon>receipt_long</mat-icon> Invoice Dashboard</h4>
|
|
20854
|
+
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20855
|
+
<div style="margin-top: 16px;"></div>
|
|
20856
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20857
|
+
|
|
20858
|
+
<!-- Attention Required sub-table -->
|
|
20859
|
+
<div *ngIf="attentionItems.length > 0" class="attention-section">
|
|
20860
|
+
<h5 class="section-title">
|
|
20861
|
+
<mat-icon style="vertical-align: middle; margin-right: 4px; color: #f44336;">warning</mat-icon>
|
|
20862
|
+
Needs Attention
|
|
20863
|
+
</h5>
|
|
20864
|
+
<table class="kpi-table">
|
|
20865
|
+
<thead>
|
|
20866
|
+
<tr>
|
|
20867
|
+
<th>Invoice</th>
|
|
20868
|
+
<th>Customer</th>
|
|
20869
|
+
<th>Due Date</th>
|
|
20870
|
+
<th>Days Overdue</th>
|
|
20871
|
+
<th>Outstanding</th>
|
|
20872
|
+
</tr>
|
|
20873
|
+
</thead>
|
|
20874
|
+
<tbody>
|
|
20875
|
+
<tr *ngFor="let item of attentionItems">
|
|
20876
|
+
<td>{{ item.invoiceNumber }}</td>
|
|
20877
|
+
<td>{{ item.customerName }}</td>
|
|
20878
|
+
<td>{{ item.dueDate | date:'mediumDate' }}</td>
|
|
20879
|
+
<td style="color: #f44336; font-weight: 500;">{{ item.daysOverdue }}</td>
|
|
20880
|
+
<td>{{ item.outstandingAmount | currency }}</td>
|
|
20881
|
+
</tr>
|
|
20882
|
+
</tbody>
|
|
20883
|
+
</table>
|
|
20884
|
+
</div>
|
|
20885
|
+
|
|
20886
|
+
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20887
|
+
</div>
|
|
20888
|
+
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.attention-section{margin-top:16px}.section-title{display:flex;align-items:center;margin-bottom:8px;color:#333;font-weight:500}.kpi-table{width:100%;border-collapse:collapse;font-size:13px}.kpi-table th{text-align:left;padding:8px 12px;background:#f5f5f5;border-bottom:2px solid #e0e0e0;font-weight:500}.kpi-table td{padding:8px 12px;border-bottom:1px solid #eee}.kpi-table tr:hover{background:#fafafa}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
20889
|
+
}
|
|
20890
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: InvoiceDashboardComponent, decorators: [{
|
|
20891
|
+
type: Component,
|
|
20892
|
+
args: [{ selector: 'spa-invoice-dashboard', template: `
|
|
20893
|
+
<div class="dashboard-container">
|
|
20894
|
+
<h4 class="dashboard-title"><mat-icon>receipt_long</mat-icon> Invoice Dashboard</h4>
|
|
20895
|
+
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20896
|
+
<div style="margin-top: 16px;"></div>
|
|
20897
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20898
|
+
|
|
20899
|
+
<!-- Attention Required sub-table -->
|
|
20900
|
+
<div *ngIf="attentionItems.length > 0" class="attention-section">
|
|
20901
|
+
<h5 class="section-title">
|
|
20902
|
+
<mat-icon style="vertical-align: middle; margin-right: 4px; color: #f44336;">warning</mat-icon>
|
|
20903
|
+
Needs Attention
|
|
20904
|
+
</h5>
|
|
20905
|
+
<table class="kpi-table">
|
|
20906
|
+
<thead>
|
|
20907
|
+
<tr>
|
|
20908
|
+
<th>Invoice</th>
|
|
20909
|
+
<th>Customer</th>
|
|
20910
|
+
<th>Due Date</th>
|
|
20911
|
+
<th>Days Overdue</th>
|
|
20912
|
+
<th>Outstanding</th>
|
|
20913
|
+
</tr>
|
|
20914
|
+
</thead>
|
|
20915
|
+
<tbody>
|
|
20916
|
+
<tr *ngFor="let item of attentionItems">
|
|
20917
|
+
<td>{{ item.invoiceNumber }}</td>
|
|
20918
|
+
<td>{{ item.customerName }}</td>
|
|
20919
|
+
<td>{{ item.dueDate | date:'mediumDate' }}</td>
|
|
20920
|
+
<td style="color: #f44336; font-weight: 500;">{{ item.daysOverdue }}</td>
|
|
20921
|
+
<td>{{ item.outstandingAmount | currency }}</td>
|
|
20922
|
+
</tr>
|
|
20923
|
+
</tbody>
|
|
20924
|
+
</table>
|
|
20925
|
+
</div>
|
|
20926
|
+
|
|
20927
|
+
<spa-charts [config]="chartConfig"></spa-charts>
|
|
20928
|
+
</div>
|
|
20929
|
+
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.attention-section{margin-top:16px}.section-title{display:flex;align-items:center;margin-bottom:8px;color:#333;font-weight:500}.kpi-table{width:100%;border-collapse:collapse;font-size:13px}.kpi-table th{text-align:left;padding:8px 12px;background:#f5f5f5;border-bottom:2px solid #e0e0e0;font-weight:500}.kpi-table td{padding:8px 12px;border-bottom:1px solid #eee}.kpi-table tr:hover{background:#fafafa}\n"] }]
|
|
20930
|
+
}], ctorParameters: () => [{ type: DataServiceLib }] });
|
|
20931
|
+
|
|
20932
|
+
// Payroll module dashboard with cost tracking, department analysis, and employee metrics
|
|
20933
|
+
class PayrollDashboardComponent {
|
|
20934
|
+
constructor(dataService) {
|
|
20935
|
+
this.dataService = dataService;
|
|
20936
|
+
this.recentRuns = [];
|
|
20937
|
+
// Changed: Summary tiles — payroll KPIs
|
|
20938
|
+
this.summaryTiles = {
|
|
20939
|
+
tiles: [
|
|
20940
|
+
{ name: 'eligibleEmployees', alias: 'Eligible Employees', color: '#1565c0', icon: 'group', style: 'icon', info: 'Active employees with salary structures' },
|
|
20941
|
+
{ name: 'lastPayrollNet', alias: 'Last Payroll (Net)', color: '#4caf50', icon: 'account_balance', style: 'icon', prefix: '$', info: 'Net pay of last completed run' },
|
|
20942
|
+
{ name: 'pendingAdvances', alias: 'Pending Advances', color: '#f44336', icon: 'money_off', style: 'icon', info: 'Undeducted salary advances' },
|
|
20943
|
+
{ name: 'overtimeMTD', alias: 'Overtime (MTD)', color: '#ff9800', icon: 'more_time', style: 'icon', prefix: '$', info: 'Total overtime this month' },
|
|
20944
|
+
{ name: 'payrollRunsYTD', alias: 'Runs (YTD)', color: '#7b1fa2', icon: 'play_circle', style: 'icon', info: 'Payroll runs this year' },
|
|
20945
|
+
{ name: 'totalPayrollCostYTD', alias: 'Payroll Cost (YTD)', color: '#00695c', icon: 'attach_money', style: 'icon', prefix: '$', info: 'Year-to-date gross payroll' },
|
|
20946
|
+
],
|
|
20947
|
+
loadAction: { url: 'payrollruns/dashboard-summary/x' },
|
|
20948
|
+
loadInit: true
|
|
20949
|
+
};
|
|
20950
|
+
// Changed: Chart tiles — cost ratio gauge, trend sparkline, department pie, run status bar
|
|
20951
|
+
this.chartTiles = {
|
|
20952
|
+
tiles: [
|
|
20953
|
+
{ name: 'payrollCostRatio', alias: 'Payroll Cost Ratio', color: '#ff9800', chart: { type: 'doughnut', gaugeColor: '#ff9800', height: 130, dataField: 'payrollCostRatio' }, footer: 'Payroll as % of expenses', footerIcon: 'info' },
|
|
20954
|
+
{ name: 'payrollTrend', alias: 'Payroll Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'payrollTrend' }, footer: 'Last 12 months gross', footerIcon: 'timeline' },
|
|
20955
|
+
{ name: 'departmentSplit', alias: 'By Department', color: '#4caf50', chart: { type: 'pie', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'], height: 130, dataField: 'departmentSplit' }, footer: 'Employee distribution', footerIcon: 'pie_chart' },
|
|
20956
|
+
{ name: 'runStatusSplit', alias: 'Run Status', color: '#9c27b0', chart: { type: 'bar', colors: ['#9e9e9e', '#2196f3', '#ff9800', '#4caf50'], height: 100, dataField: 'runStatusSplit' }, footer: 'All-time run status', footerIcon: 'bar_chart' },
|
|
20957
|
+
],
|
|
20958
|
+
loadAction: { url: 'payrollruns/dashboard-chart-tiles/x' },
|
|
20959
|
+
loadInit: true
|
|
20960
|
+
};
|
|
20961
|
+
// Changed: Full charts — cost trend, department breakdown, earnings vs deductions, commission & overtime
|
|
20962
|
+
this.chartConfig = {
|
|
20963
|
+
charts: [
|
|
20964
|
+
{ name: 'payrollCostTrend', title: 'Payroll Cost Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196f3', '#4caf50', '#f44336'], showLegend: true },
|
|
20965
|
+
{ name: 'departmentCosts', title: 'Cost by Department', type: 'bar', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'] },
|
|
20966
|
+
{ name: 'earningsVsDeductions', title: 'Earnings vs Deductions', type: 'doughnut', height: '300px', colors: ['#4caf50', '#f44336'] },
|
|
20967
|
+
{ name: 'variablePayTrend', title: 'Commission & Overtime', type: 'bar', height: '300px', showLegend: true, colors: ['#9c27b0', '#ff9800'] },
|
|
20968
|
+
],
|
|
20969
|
+
loadAction: { url: 'payrollruns/dashboard-charts/x' },
|
|
20970
|
+
loadInit: true,
|
|
20971
|
+
columns: 2
|
|
20972
|
+
};
|
|
20973
|
+
}
|
|
20974
|
+
ngOnInit() {
|
|
20975
|
+
// Load recent payroll runs for sub-table
|
|
20976
|
+
this.dataService.CallApi({ url: 'payrollruns/dashboard-recent/x' }).subscribe((res) => {
|
|
20977
|
+
if (res.success)
|
|
20978
|
+
this.recentRuns = res.data || [];
|
|
20979
|
+
});
|
|
20980
|
+
}
|
|
20981
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PayrollDashboardComponent, deps: [{ token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
20982
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: PayrollDashboardComponent, isStandalone: false, selector: "spa-payroll-dashboard", ngImport: i0, template: `
|
|
20983
|
+
<div class="dashboard-container">
|
|
20984
|
+
<h4 class="dashboard-title"><mat-icon>payments</mat-icon> Payroll Dashboard</h4>
|
|
20985
|
+
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
20986
|
+
<div style="margin-top: 16px;"></div>
|
|
20987
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
20988
|
+
|
|
20989
|
+
<!-- Recent Payroll Runs sub-table -->
|
|
20990
|
+
<div *ngIf="recentRuns.length > 0" class="runs-section">
|
|
20991
|
+
<h5 class="section-title">
|
|
20992
|
+
<mat-icon style="vertical-align: middle; margin-right: 4px;">play_circle</mat-icon>
|
|
20993
|
+
Recent Payroll Runs
|
|
20994
|
+
</h5>
|
|
20995
|
+
<table class="kpi-table">
|
|
20996
|
+
<thead>
|
|
20997
|
+
<tr>
|
|
20998
|
+
<th>Period</th>
|
|
20999
|
+
<th>Pay Date</th>
|
|
21000
|
+
<th>Status</th>
|
|
21001
|
+
<th>Employees</th>
|
|
21002
|
+
<th>Gross Pay</th>
|
|
21003
|
+
<th>Net Pay</th>
|
|
21004
|
+
</tr>
|
|
21005
|
+
</thead>
|
|
21006
|
+
<tbody>
|
|
21007
|
+
<tr *ngFor="let run of recentRuns">
|
|
21008
|
+
<td>{{ run.periodName }}</td>
|
|
21009
|
+
<td>{{ run.payDate | date:'mediumDate' }}</td>
|
|
21010
|
+
<td>
|
|
21011
|
+
<span class="status-chip" [style.background]="run.statusColor">{{ run.statusName }}</span>
|
|
21012
|
+
</td>
|
|
21013
|
+
<td>{{ run.payslipCount }}</td>
|
|
21014
|
+
<td>{{ run.totalGrossPay | currency }}</td>
|
|
21015
|
+
<td>{{ run.totalNetPay | currency }}</td>
|
|
21016
|
+
</tr>
|
|
21017
|
+
</tbody>
|
|
21018
|
+
</table>
|
|
21019
|
+
</div>
|
|
21020
|
+
|
|
21021
|
+
<spa-charts [config]="chartConfig"></spa-charts>
|
|
21022
|
+
</div>
|
|
21023
|
+
`, isInline: true, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.runs-section{margin-top:16px}.section-title{display:flex;align-items:center;margin-bottom:8px;color:#333;font-weight:500}.kpi-table{width:100%;border-collapse:collapse;font-size:13px}.kpi-table th{text-align:left;padding:8px 12px;background:#f5f5f5;border-bottom:2px solid #e0e0e0;font-weight:500}.kpi-table td{padding:8px 12px;border-bottom:1px solid #eee}.kpi-table tr:hover{background:#fafafa}.status-chip{padding:2px 8px;border-radius:12px;color:#fff;font-size:11px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: TilesComponent, selector: "spa-tiles", inputs: ["config", "lastSearch", "data", "reload"], outputs: ["tileActionSelected", "tileClick", "tileUnClick"] }, { kind: "component", type: ChartsComponent, selector: "spa-charts", inputs: ["config", "data", "reload"] }, { kind: "pipe", type: i2.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
21024
|
+
}
|
|
21025
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: PayrollDashboardComponent, decorators: [{
|
|
21026
|
+
type: Component,
|
|
21027
|
+
args: [{ selector: 'spa-payroll-dashboard', template: `
|
|
21028
|
+
<div class="dashboard-container">
|
|
21029
|
+
<h4 class="dashboard-title"><mat-icon>payments</mat-icon> Payroll Dashboard</h4>
|
|
21030
|
+
<spa-tiles [config]="summaryTiles"></spa-tiles>
|
|
21031
|
+
<div style="margin-top: 16px;"></div>
|
|
21032
|
+
<spa-tiles [config]="chartTiles"></spa-tiles>
|
|
21033
|
+
|
|
21034
|
+
<!-- Recent Payroll Runs sub-table -->
|
|
21035
|
+
<div *ngIf="recentRuns.length > 0" class="runs-section">
|
|
21036
|
+
<h5 class="section-title">
|
|
21037
|
+
<mat-icon style="vertical-align: middle; margin-right: 4px;">play_circle</mat-icon>
|
|
21038
|
+
Recent Payroll Runs
|
|
21039
|
+
</h5>
|
|
21040
|
+
<table class="kpi-table">
|
|
21041
|
+
<thead>
|
|
21042
|
+
<tr>
|
|
21043
|
+
<th>Period</th>
|
|
21044
|
+
<th>Pay Date</th>
|
|
21045
|
+
<th>Status</th>
|
|
21046
|
+
<th>Employees</th>
|
|
21047
|
+
<th>Gross Pay</th>
|
|
21048
|
+
<th>Net Pay</th>
|
|
21049
|
+
</tr>
|
|
21050
|
+
</thead>
|
|
21051
|
+
<tbody>
|
|
21052
|
+
<tr *ngFor="let run of recentRuns">
|
|
21053
|
+
<td>{{ run.periodName }}</td>
|
|
21054
|
+
<td>{{ run.payDate | date:'mediumDate' }}</td>
|
|
21055
|
+
<td>
|
|
21056
|
+
<span class="status-chip" [style.background]="run.statusColor">{{ run.statusName }}</span>
|
|
21057
|
+
</td>
|
|
21058
|
+
<td>{{ run.payslipCount }}</td>
|
|
21059
|
+
<td>{{ run.totalGrossPay | currency }}</td>
|
|
21060
|
+
<td>{{ run.totalNetPay | currency }}</td>
|
|
21061
|
+
</tr>
|
|
21062
|
+
</tbody>
|
|
21063
|
+
</table>
|
|
21064
|
+
</div>
|
|
21065
|
+
|
|
21066
|
+
<spa-charts [config]="chartConfig"></spa-charts>
|
|
21067
|
+
</div>
|
|
21068
|
+
`, standalone: false, styles: [".dashboard-container{padding:16px}.dashboard-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.runs-section{margin-top:16px}.section-title{display:flex;align-items:center;margin-bottom:8px;color:#333;font-weight:500}.kpi-table{width:100%;border-collapse:collapse;font-size:13px}.kpi-table th{text-align:left;padding:8px 12px;background:#f5f5f5;border-bottom:2px solid #e0e0e0;font-weight:500}.kpi-table td{padding:8px 12px;border-bottom:1px solid #eee}.kpi-table tr:hover{background:#fafafa}.status-chip{padding:2px 8px;border-radius:12px;color:#fff;font-size:11px;font-weight:500}\n"] }]
|
|
21069
|
+
}], ctorParameters: () => [{ type: DataServiceLib }] });
|
|
21070
|
+
|
|
20362
21071
|
// Subscription management page — current plan display, plan comparison, upgrade/downgrade
|
|
20363
21072
|
class SubscriptionPageComponent {
|
|
20364
21073
|
constructor(httpService, subscriptionService, snackBar) {
|
|
@@ -21007,7 +21716,7 @@ class BillingPageComponent {
|
|
|
21007
21716
|
</mat-card>
|
|
21008
21717
|
</div>
|
|
21009
21718
|
</div>
|
|
21010
|
-
`, isInline: true, styles: [".billing-container{padding:16px;max-width:1200px}.page-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.summary-card{margin-bottom:24px}.summary-row{display:flex;gap:32px;flex-wrap:wrap}.summary-item{display:flex;flex-direction:column}.summary-label{font-size:12px;color:#888;text-transform:uppercase}.summary-value{font-size:16px;font-weight:500}.status-badge{padding:2px 10px;border-radius:12px;font-size:12px;font-weight:500}.status-0{background:#e3f2fd;color:#1565c0}.status-1{background:#e8f5e9;color:#2e7d32}.status-2{background:#fff3e0;color:#e65100}.status-3{background:#fce4ec;color:#c62828}.status-4{background:#f5f5f5;color:#616161}.invoices-card{margin-bottom:24px}.table-container{overflow-x:auto}.invoice-table,.transaction-table{width:100%;border-collapse:collapse}.invoice-table th,.invoice-table td,.transaction-table th,.transaction-table td{padding:10px 12px;text-align:left;border-bottom:1px solid #e0e0e0;font-size:14px}.invoice-table th,.transaction-table th{font-weight:500;color:#666;font-size:12px;text-transform:uppercase}.invoice-table tbody tr:hover{background:#f5f5f5}.invoice-status{padding:2px 8px;border-radius:10px;font-size:12px;font-weight:500}.inv-status-0{background:#fff3e0;color:#e65100}.inv-status-1{background:#e8f5e9;color:#2e7d32}.inv-status-2{background:#fce4ec;color:#c62828}.inv-status-3{background:#f3e5f5;color:#6a1b9a}.txn-status{padding:2px 8px;border-radius:10px;font-size:12px;font-weight:500}.txn-status-0{background:#e3f2fd;color:#1565c0}.txn-status-1{background:#fff3e0;color:#e65100}.txn-status-2{background:#e8f5e9;color:#2e7d32}.txn-status-3{background:#fce4ec;color:#c62828}.txn-status-4{background:#f5f5f5;color:#616161}.empty-state,.loading-state{display:flex;flex-direction:column;align-items:center;padding:32px;color:#999}.empty-state mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:8px}.overlay{position:fixed;inset:0;background:#0006;display:flex;align-items:center;justify-content:center;z-index:1000}.detail-dialog{max-width:640px;width:90%;max-height:80vh;overflow-y:auto}.payment-dialog{max-width:440px;width:90%}.close-btn{position:absolute;top:8px;right:8px}.detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px}.detail-field{display:flex;flex-direction:column}.field-label{font-size:12px;color:#888;text-transform:uppercase}.field-value{font-size:14px;font-weight:500}.transactions-section{margin-top:16px}.transactions-section h5{margin:0 0 8px;color:#555}.no-transactions{color:#999;font-size:13px}.payment-summary{margin-bottom:16px}.payment-summary p{margin:4px 0;font-size:15px}.payment-state{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center}.result-icon{font-size:48px;width:48px;height:48px;margin-bottom:8px}.success-icon{color:#4caf50}.redirect-icon{color:#1976d2}.error-icon{color:#f44336}.payment-ref{font-size:12px;color:#888}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i6$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i6$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i18$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type:
|
|
21719
|
+
`, isInline: true, styles: [".billing-container{padding:16px;max-width:1200px}.page-title{display:flex;align-items:center;gap:8px;margin-bottom:16px;color:#333;font-weight:500}.summary-card{margin-bottom:24px}.summary-row{display:flex;gap:32px;flex-wrap:wrap}.summary-item{display:flex;flex-direction:column}.summary-label{font-size:12px;color:#888;text-transform:uppercase}.summary-value{font-size:16px;font-weight:500}.status-badge{padding:2px 10px;border-radius:12px;font-size:12px;font-weight:500}.status-0{background:#e3f2fd;color:#1565c0}.status-1{background:#e8f5e9;color:#2e7d32}.status-2{background:#fff3e0;color:#e65100}.status-3{background:#fce4ec;color:#c62828}.status-4{background:#f5f5f5;color:#616161}.invoices-card{margin-bottom:24px}.table-container{overflow-x:auto}.invoice-table,.transaction-table{width:100%;border-collapse:collapse}.invoice-table th,.invoice-table td,.transaction-table th,.transaction-table td{padding:10px 12px;text-align:left;border-bottom:1px solid #e0e0e0;font-size:14px}.invoice-table th,.transaction-table th{font-weight:500;color:#666;font-size:12px;text-transform:uppercase}.invoice-table tbody tr:hover{background:#f5f5f5}.invoice-status{padding:2px 8px;border-radius:10px;font-size:12px;font-weight:500}.inv-status-0{background:#fff3e0;color:#e65100}.inv-status-1{background:#e8f5e9;color:#2e7d32}.inv-status-2{background:#fce4ec;color:#c62828}.inv-status-3{background:#f3e5f5;color:#6a1b9a}.txn-status{padding:2px 8px;border-radius:10px;font-size:12px;font-weight:500}.txn-status-0{background:#e3f2fd;color:#1565c0}.txn-status-1{background:#fff3e0;color:#e65100}.txn-status-2{background:#e8f5e9;color:#2e7d32}.txn-status-3{background:#fce4ec;color:#c62828}.txn-status-4{background:#f5f5f5;color:#616161}.empty-state,.loading-state{display:flex;flex-direction:column;align-items:center;padding:32px;color:#999}.empty-state mat-icon{font-size:48px;width:48px;height:48px;margin-bottom:8px}.overlay{position:fixed;inset:0;background:#0006;display:flex;align-items:center;justify-content:center;z-index:1000}.detail-dialog{max-width:640px;width:90%;max-height:80vh;overflow-y:auto}.payment-dialog{max-width:440px;width:90%}.close-btn{position:absolute;top:8px;right:8px}.detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px}.detail-field{display:flex;flex-direction:column}.field-label{font-size:12px;color:#888;text-transform:uppercase}.field-value{font-size:14px;font-weight:500}.transactions-section{margin-top:16px}.transactions-section h5{margin:0 0 8px;color:#555}.no-transactions{color:#999;font-size:13px}.payment-summary{margin-bottom:16px}.payment-summary p{margin:4px 0;font-size:15px}.payment-state{display:flex;flex-direction:column;align-items:center;padding:24px;text-align:center}.result-icon{font-size:48px;width:48px;height:48px;margin-bottom:8px}.success-icon{color:#4caf50}.redirect-icon{color:#1976d2}.error-icon{color:#f44336}.payment-ref{font-size:12px;color:#888}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.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: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6$1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6$1.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i6$1.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i6$1.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i6$1.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i18$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i2.DecimalPipe, name: "number" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] }); }
|
|
21011
21720
|
}
|
|
21012
21721
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: BillingPageComponent, decorators: [{
|
|
21013
21722
|
type: Component,
|
|
@@ -21295,6 +22004,8 @@ const routes$1 = [
|
|
|
21295
22004
|
{ path: "sales-dashboard", component: SalesDashboardComponent }, // Changed: Added sales dashboard route
|
|
21296
22005
|
{ path: "purchasing-dashboard", component: PurchasingDashboardComponent }, // Changed: Added purchasing dashboard route
|
|
21297
22006
|
{ path: "overview-dashboard", component: OverviewDashboardComponent }, // Changed: Added overview dashboard route
|
|
22007
|
+
{ path: "invoice-dashboard", component: InvoiceDashboardComponent }, // Changed: Added invoice dashboard route
|
|
22008
|
+
{ path: "payroll-dashboard", component: PayrollDashboardComponent }, // Changed: Added payroll dashboard route
|
|
21298
22009
|
{ path: "subscription", component: SubscriptionPageComponent }, // Added: Subscription management route
|
|
21299
22010
|
{ path: "billing", component: BillingPageComponent } // Added: Billing & invoice history route
|
|
21300
22011
|
];
|
|
@@ -21355,6 +22066,8 @@ class AdminModule {
|
|
|
21355
22066
|
SalesDashboardComponent, // Changed: Added sales dashboard component
|
|
21356
22067
|
PurchasingDashboardComponent, // Changed: Added purchasing dashboard component
|
|
21357
22068
|
OverviewDashboardComponent, // Changed: Added overview dashboard component
|
|
22069
|
+
InvoiceDashboardComponent, // Changed: Added invoice dashboard component
|
|
22070
|
+
PayrollDashboardComponent, // Changed: Added payroll dashboard component
|
|
21358
22071
|
FeaturesComponent, // Added: Feature registry component
|
|
21359
22072
|
PlanFeaturesComponent, // Added: Plan-Feature mapping component
|
|
21360
22073
|
SubscriptionPageComponent, // Added: Subscription management component
|
|
@@ -21411,6 +22124,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
21411
22124
|
SalesDashboardComponent, // Changed: Added sales dashboard component
|
|
21412
22125
|
PurchasingDashboardComponent, // Changed: Added purchasing dashboard component
|
|
21413
22126
|
OverviewDashboardComponent, // Changed: Added overview dashboard component
|
|
22127
|
+
InvoiceDashboardComponent, // Changed: Added invoice dashboard component
|
|
22128
|
+
PayrollDashboardComponent, // Changed: Added payroll dashboard component
|
|
21414
22129
|
FeaturesComponent, // Added: Feature registry component
|
|
21415
22130
|
PlanFeaturesComponent, // Added: Plan-Feature mapping component
|
|
21416
22131
|
SubscriptionPageComponent, // Added: Subscription management component
|
|
@@ -21471,5 +22186,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
21471
22186
|
* Generated bundle index. Do not edit.
|
|
21472
22187
|
*/
|
|
21473
22188
|
|
|
21474
|
-
export { Account, AccountsComponent as AccountingAccountsComponent, AggregatesComponent as AccountingAggregatesComponent, AgingComponent as AccountingAgingComponent, CurrenciesComponent as AccountingCurrenciesComponent, AccountingDashboardComponent, InvoicesComponent as AccountingInvoicesComponent, ReportsComponent as AccountingReportsComponent, AccountingService, StatementComponent as AccountingStatementComponent, TransactionTypesComponent as AccountingTransactionTypesComponent, TransactionsComponent as AccountingTransactionsComponent, Action, ActivityComponent, AdminModule, AlertComponent, AlertConfig, AlertMessage, ApiResponse, AppConfig, AppModelsComponent, AssetStatus, AttachComponent, AuthService, BillingPageComponent, BrandsComponent, CacheConfig, CapItem, CapsulesComponent, CategoriesComponent, ChangePasswordComponent, ChangeUserPassword, ChartConfig, ChartsComponent, CheckComponent, ChipsComponent, Constants, Core, CreateAccountComponent, CustomersComponent, DataServiceLib, DateComponent, DatetimeComponent, DepartmentsComponent, DetailsDialog, DetailsDialogConfig, DetailsDialogProcessor, DetailsSource, DialogService, EmailComponent, EmployeesComponent, ExportService, FeatureDirective, FilterComponent, FormComponent, FormConfig, GeneralService, GradesComponent, GroupsComponent, HtmlComponent, HttpService, IndexModule, InventoryDashboardComponent, InventoryReceiptStatus, InventoryService, InvoiceItemType, InvoiceStatus, LabelComponent, ListDialogComponent, ListDialogConfig, LoaderComponent, LoaderService, LoanPaymentsComponent, LoanProductsComponent, LoansComponent, LoansService, LogLevel, LogService, LoginComponent, LogsComponent, MembershipComponent, MessageService, MoneyComponent, MovementType, NavMenuComponent, NotesComponent, NotesConfig, NotificationsService, NumberComponent, OnboardingComponent, OptionComponent, OverviewDashboardComponent, PageComponent, PageConfig, PlansComponent, PositionsComponent, PreferencesComponent, PrivacyDialogComponent, Profile, ProfileComponent, PurchasingDashboardComponent, PushNotificationService, RecoverAccountComponent, Register, Role, RoleAccess, RolesComponent, SalesDashboardComponent, SearchComponent, SearchConfig, SecurityConfig, SelectBitwiseComponent, SelectComponent, SelectLiteComponent, SelectMultiComponent, SettingsComponent, SignupComponent, SignupData, SpaAdminModule, SpaIndexModule, SpaMatModule, SpaUserModule, StatusesComponent, Step, StepConfig, StepsComponent, StorageService, SubCategoriesComponent, SubscriptionPageComponent, SubscriptionService, SuppliersComponent, TabService, TableComponent, TableConfig, TabsComponent, TabsInternalComponent, TabsLiteComponent, TasksComponent, TenantsComponent, TermsDialogComponent, TextAreaComponent, TextComponent, TextMaskComponent, TextMultiComponent, TextSingleComponent, TileConfig, TilesComponent, TinSpaComponent, TinSpaModule, TinSpaService, TitleActionsComponent, TransactionTiming, UnitOfMeasure, UpdateService, User, UserModule, UsersComponent, ViewerComponent, WelcomeComponent, authGuard, dialogOptions, featureGuard, loginConfig, messageDialog, viewerDialog };
|
|
22189
|
+
export { Account, AccountsComponent as AccountingAccountsComponent, AggregatesComponent as AccountingAggregatesComponent, AgingComponent as AccountingAgingComponent, CurrenciesComponent as AccountingCurrenciesComponent, AccountingDashboardComponent, InvoicesComponent as AccountingInvoicesComponent, ReportsComponent as AccountingReportsComponent, AccountingService, StatementComponent as AccountingStatementComponent, TransactionTypesComponent as AccountingTransactionTypesComponent, TransactionsComponent as AccountingTransactionsComponent, Action, ActivityComponent, AdminModule, AlertComponent, AlertConfig, AlertMessage, ApiResponse, AppConfig, AppModelsComponent, AssetStatus, AttachComponent, AuthService, BillingPageComponent, BrandsComponent, CacheConfig, CapItem, CapsulesComponent, CategoriesComponent, ChangePasswordComponent, ChangeUserPassword, ChartConfig, ChartsComponent, CheckComponent, ChipsComponent, Constants, Core, CreateAccountComponent, CustomersComponent, DataServiceLib, DateComponent, DatetimeComponent, DepartmentsComponent, DetailsDialog, DetailsDialogConfig, DetailsDialogProcessor, DetailsSource, DialogService, EmailComponent, EmployeesComponent, ExportService, FeatureDirective, FilterComponent, FormComponent, FormConfig, GeneralService, GradesComponent, GroupsComponent, HtmlComponent, HttpService, IndexModule, InventoryDashboardComponent, InventoryReceiptStatus, InventoryService, InvoiceDashboardComponent, InvoiceItemType, InvoiceStatus, LabelComponent, ListDialogComponent, ListDialogConfig, LoaderComponent, LoaderService, LoanPaymentsComponent, LoanProductsComponent, LoansComponent, LoansService, LogLevel, LogService, LoginComponent, LogsComponent, MembershipComponent, MessageService, MoneyComponent, MovementType, NavMenuComponent, NotesComponent, NotesConfig, NotificationsService, NumberComponent, OnboardingComponent, OptionComponent, OverviewDashboardComponent, PageComponent, PageConfig, PayrollDashboardComponent, PlansComponent, PositionsComponent, PreferencesComponent, PrivacyDialogComponent, Profile, ProfileComponent, PurchasingDashboardComponent, PushNotificationService, RecoverAccountComponent, Register, Role, RoleAccess, RolesComponent, SalesDashboardComponent, SearchComponent, SearchConfig, SecurityConfig, SelectBitwiseComponent, SelectComponent, SelectLiteComponent, SelectMultiComponent, SettingsComponent, SignupComponent, SignupData, SpaAdminModule, SpaIndexModule, SpaMatModule, SpaUserModule, StatusesComponent, Step, StepConfig, StepsComponent, StorageService, SubCategoriesComponent, SubscriptionPageComponent, SubscriptionService, SuppliersComponent, TabService, TableComponent, TableConfig, TabsComponent, TabsInternalComponent, TabsLiteComponent, TasksComponent, TenantsComponent, TermsDialogComponent, TextAreaComponent, TextComponent, TextMaskComponent, TextMultiComponent, TextSingleComponent, TileConfig, TilesComponent, TinSpaComponent, TinSpaModule, TinSpaService, TitleActionsComponent, TransactionTiming, UnitOfMeasure, UpdateService, User, UserModule, UsersComponent, ViewerComponent, WelcomeComponent, authGuard, dialogOptions, featureGuard, loginConfig, messageDialog, viewerDialog };
|
|
21475
22190
|
//# sourceMappingURL=tin-spa.mjs.map
|