Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
52f8806
feat(fleet-management-sample): build master-detail grid with scoped d…
Zneeky Jun 8, 2026
f199427
feat(fleet-management-sample): match Angular detail layout and add in…
Zneeky Jun 8, 2026
5af74dc
feat(fleet-management-sample): compact grid sizing, toolbar layout an…
Zneeky Jun 9, 2026
bef53d2
feat(fleet-management-sample): native cell templates, detail refactor…
Zneeky Jun 9, 2026
2bda74d
feat(fleet-management-sample): give the utilization chart the same bo…
Zneeky Jun 10, 2026
ad3949b
feat(fleet-management-sample): restructure the utilization chart as a…
Zneeky Jun 10, 2026
500f9c6
feat(fleet-management-sample): mark the current trip with a Current b…
Zneeky Jun 10, 2026
c6a96a7
feat(sales-dashboard-sample): pivot grid dashboard with data selector…
Zneeky Jun 10, 2026
46e2c6a
feat(sales-dashboard-sample): web-components-aligned layout; temporar…
Zneeky Jun 10, 2026
f50f52e
feat(financial-portfolio-sample): live portfolio grid with templated …
Zneeky Jun 10, 2026
68786f3
feat(financial-portfolio-sample): web-components toolbar with filter …
Zneeky Jun 10, 2026
5b69c6c
feat(financial-portfolio-sample): apply the full Bootstrap grid theme…
Zneeky Jun 10, 2026
3da544e
feat(financial-portfolio-sample): per-keystroke search, bootstrap inp…
Zneeky Jun 10, 2026
bc71eb9
feat(financial-portfolio-sample): fit all columns and thicken the all…
Zneeky Jun 10, 2026
f12570a
fix(financial-portfolio-sample): thicken the allocation bar track and…
Zneeky Jun 10, 2026
6720444
fix(fleet-management-sample): remove column filtering, fix shell tab/…
Zneeky Jun 11, 2026
19c6e65
Merge branch 'aahmedov/fleet-managment-sample-blazor' into aahmedov/s…
Zneeky Jun 11, 2026
750c54e
feat(sales-dashboard-sample): WC-accurate pivot dashboard with bundle…
Zneeky Jun 11, 2026
ca8757f
chore(sales-dashboard-sample): remove comments
Zneeky Jun 11, 2026
aee969e
fix(routing): match the WC route structure with /home sample endpoints
Zneeky Jun 11, 2026
f60f2d2
fix(fleet-management-sample): remove 2px page scroll by correcting gr…
Zneeky Jun 11, 2026
6ee84b9
Merge remote-tracking branch 'origin/aahmedov/fleet-managment-sample-…
Zneeky Jun 11, 2026
fc5b34f
Merge remote-tracking branch 'origin/aahmedov/fleet-managment-sample-…
Zneeky Jun 11, 2026
66e0a47
feat(shell): hide the sample tab strip in fullscreen and sync state v…
Zneeky Jun 12, 2026
8edd04f
Merge remote-tracking branch 'origin/aahmedov/fleet-managment-sample-…
Zneeky Jun 12, 2026
6e6f04f
Merge remote-tracking branch 'origin/aahmedov/fleet-managment-sample-…
Zneeky Jun 12, 2026
cf63527
feat(shell): replace the Unicode toolbar icons with the WC SVGs rende…
Zneeky Jun 12, 2026
8ecd5e6
Merge pull request #21 from IgniteUI/aahmedov/sales-dashboard-sample-…
Zneeky Jun 18, 2026
b766b50
fix(theming): replace fleet-dark.css with runtime scopeThemeToElement…
Zneeky Jun 18, 2026
2b268be
Merge branch 'aahmedov/fleet-managment-sample-blazor' of https://gith…
Zneeky Jun 18, 2026
f54e7b8
fix(theming): replace sales static CSS dumps with runtime scopeThemeT…
Zneeky Jun 18, 2026
998225d
Merge branch 'aahmedov/fleet-managment-sample-blazor' of https://gith…
Jun 18, 2026
838ec4b
fix(financial grid): unifying currency formatting
Jun 18, 2026
febbc7e
chore(*): exclude e2e testing for now
Zneeky Jun 18, 2026
2af2408
Merge branch 'aahmedov/fleet-managment-sample-blazor' into aahmedov/f…
Zneeky Jun 18, 2026
69750f0
fix(theming): migrate Finance to runtime scopeThemeToElement (Bootstrap)
Zneeky Jun 18, 2026
3ace80b
Merge remote-tracking branch 'origin/aahmedov/financial-portfolio-sam…
Zneeky Jun 22, 2026
f75d496
fix(financial-portfolio): match WC typography for title, filter input…
Zneeky Jun 22, 2026
3bfd465
fix(financial-portfolio): fill the viewport with no page scroll (WC p…
Zneeky Jun 22, 2026
bf717f5
fix(financial-portfolio): blue toolbar buttons, bold headers, row-sel…
Zneeky Jun 22, 2026
9da62ce
fix(financial-portfolio): tint outlined toolbar button borders blue
Zneeky Jun 22, 2026
b922ef2
feat(shell): add opt-in full-theme scoping to scope-css.js; bump Igni…
Zneeky Jun 22, 2026
66acc46
Merge branch 'aahmedov/fleet-managment-sample-blazor' into aahmedov/f…
Zneeky Jun 22, 2026
a029821
fix(financial-portfolio): use full-theme scoping for the Bootstrap se…
Zneeky Jun 22, 2026
361cf07
fix(shell): fill the viewport with no page scroll
Zneeky Jun 22, 2026
edf57a5
fix(fleet-management): show the toolbar title in white (WC parity)
Zneeky Jun 22, 2026
b48d7ba
fix(sales-dashboard): match the WC sample 1:1
Zneeky Jun 22, 2026
43f45bc
Merge branch 'aahmedov/fleet-managment-sample-blazor' into aahmedov/f…
Zneeky Jun 22, 2026
d811248
Merge branch 'master' into aahmedov/financial-portfolio-sample-blazor
Zneeky Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions BlazorGridExamples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
typeof(IgbCategoryChartModule),
typeof(IgbPieChartModule),
typeof(IgbSelectModule),
typeof(IgbLinearProgressModule),
typeof(IgbInputModule),
typeof(IgbDropdownModule),
typeof(IgbPivotGridModule),
typeof(IgbPivotDataSelectorModule));
Expand Down
1 change: 1 addition & 0 deletions BlazorGridExamples/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<script src="scripts/scope-css.js"></script>
<script src="scripts/shell-interop.js"></script>
<script src="_content/FleetManagement/scripts/fleet-grid-templates.js"></script>
<script src="_content/FinanceGrid/scripts/finance-grid-templates.js"></script>
</head>

<body>
Expand Down
32 changes: 0 additions & 32 deletions samples/FinanceGrid/ExampleJsInterop.cs

This file was deleted.

155 changes: 93 additions & 62 deletions samples/FinanceGrid/FinanceGridComponent.razor
Original file line number Diff line number Diff line change
@@ -1,97 +1,128 @@
@using FinanceGrid.Services
@using FinanceGrid.Services
@using FinanceGrid.Models
@using IgniteUI.Blazor.Controls
@using Microsoft.JSInterop
@inject FinancialService FinancialService
@inject IJSRuntime JS
@implements IDisposable

<div class="container-fluid p-4">
@if (isLoading)
{
<div class="text-center my-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-3">Loading financial data...</p>
</div>
}
else if (!FinancialService.Data.Any())
{
<div class="alert alert-warning" role="alert">
No data available. Please check your connection.
</div>
}
else
{
<IgbGrid Data="FinancialService.Data"
AutoGenerate="false"
AllowFiltering="true"
Height="calc(100vh - 200px)"
@ref="grid">
<IgbColumn Field="Id" Header="Symbol" Width="7%" MinWidth="68px"></IgbColumn>
<IgbColumn Field="HoldingName" Header="Asset" Width="15%" MinWidth="100px" Sortable="true"></IgbColumn>
<IgbColumn Field="Value.CurrentPrice" Header="Last Price" DataType="GridColumnDataType.Number" Width="10%" MinWidth="80px"></IgbColumn>
<IgbColumn Field="DailyPercentageChange" Header="Change %" DataType="GridColumnDataType.Number" Width="10%" MinWidth="85px"></IgbColumn>
<IgbColumn Field="MarketValue" Header="Market Value" DataType="GridColumnDataType.Number" Width="10%" MinWidth="100px"></IgbColumn>
<IgbColumn Field="ProfitLossValue" Header="NET Profit" DataType="GridColumnDataType.Number" Width="10%" MinWidth="90px"></IgbColumn>
<IgbColumn Field="ProfitLossPercentage" Header="NET Profit %" DataType="GridColumnDataType.Number" Width="12%" MinWidth="95px"></IgbColumn>
<IgbColumn Field="Allocation" Header="Allocation" DataType="GridColumnDataType.Number" Width="10%" MinWidth="85px"></IgbColumn>
</IgbGrid>
<div class="mt-3">
<small class="text-muted">
<i class="bi bi-info-circle"></i> Data updates every 3 seconds to simulate live market data
</small>
</div>
}
</div>
<link href="_content/FinanceGrid/styles/finance.css" rel="stylesheet" />

<style>
.profit-condition {
color: #28a745;
font-weight: 600;
}
<div id="finance-section" class="ig-typography ig-scrollbar">
<div class="finance-container">
@if (isLoading)
{
<div class="text-center my-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-3">Loading financial data...</p>
</div>
}
else if (!FinancialService.Data.Any())
{
<div class="alert alert-warning" role="alert">
No data available. Please check your connection.
</div>
}
else
{
<IgbGrid Data="FilteredData"
PrimaryKey="Id"
AutoGenerate="false"
RowSelection="GridSelectionMode.Multiple"
Height="100%"
Width="100%"
class="finance-grid"
@ref="grid">
<IgbGridToolbar>
<IgbGridToolbarTitle>Financial Portfolio</IgbGridToolbarTitle>
<input type="search"
placeholder="Filter by Asset"
class="finance-search"
@bind="searchTerm"
@bind:event="oninput" />
<IgbGridToolbarActions>
<IgbGridToolbarHiding />
<IgbGridToolbarPinning />
<IgbGridToolbarExporter />
</IgbGridToolbarActions>
</IgbGridToolbar>

.loss-condition {
color: #dc3545;
font-weight: 600;
}
</style>
<IgbColumn Field="Id" Header="Symbol" Sortable="true" Width="6%" MinWidth="68px"></IgbColumn>
<IgbColumn Field="HoldingName" Header="Asset" Sortable="true" Width="16.5%" MinWidth="110px" BodyTemplateScript="financeAssetCell"></IgbColumn>
<IgbColumn Field="Positions" Header="Position" DataType="GridColumnDataType.Number" Sortable="true" Width="6%" MinWidth="70px"></IgbColumn>
<IgbColumn Field="Value.BoughtPrice" Header="Average Cost/Share" DataType="GridColumnDataType.Currency" Sortable="true" Width="10%" MinWidth="100px" PipeArgs="@currencyDigitsFormat"></IgbColumn>
<IgbColumn Field="Value.CurrentPrice" Header="Last Price" DataType="GridColumnDataType.Currency" Sortable="true" Width="7%" MinWidth="75px" PipeArgs="@currencyDigitsFormat"></IgbColumn>
<IgbColumn Field="DailyPercentageChange" Header="Daily Change %" Sortable="true" Width="9%" MinWidth="105px" BodyTemplateScript="financePercentCell"></IgbColumn>
<IgbColumn Field="MarketValue" Header="Market Value" DataType="GridColumnDataType.Currency" Sortable="true" Width="9%" MinWidth="95px" PipeArgs="@currencyDigitsFormat"></IgbColumn>
<IgbColumn Field="ProfitLossValue" Header="NET Profit/Loss" Sortable="true" Width="9%" MinWidth="105px" BodyTemplateScript="financeProfitValueCell"></IgbColumn>
<IgbColumn Field="ProfitLossPercentage" Header="NET Profit/Loss %" Sortable="true" Width="9%" MinWidth="115px" BodyTemplateScript="financePercentCell"></IgbColumn>
<IgbColumn Field="Allocation" Header="Allocation" Sortable="true" Width="10%" MinWidth="100px" BodyTemplateScript="financeAllocationCell"></IgbColumn>
<IgbColumn Field="HoldingPeriod" Header="Holding Period" Sortable="true" MinWidth="50px" BodyTemplateScript="financeHoldingPeriodCell"></IgbColumn>
</IgbGrid>
}
</div>
</div>

@code {
private bool isLoading = true;
private System.Timers.Timer? updateTimer;
private PeriodicTimer? updateTimer;
private IgbGrid? grid;
private string searchTerm = "";
private IgbColumnPipeArgs currencyDigitsFormat = new IgbColumnPipeArgs { DigitsInfo = "1.2-2" };

private List<FinancialData> FilteredData =>
string.IsNullOrWhiteSpace(searchTerm)
? FinancialService.Data
: FinancialService.Data.Where(d =>
(d.Id != null && d.Id.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)) ||
(d.HoldingName != null && d.HoldingName.Contains(searchTerm, StringComparison.OrdinalIgnoreCase)))
.ToList();


protected override async Task OnInitializedAsync()
{
FinancialService.OnDataChanged += OnDataChanged;
await FinancialService.LoadDataAsync();
isLoading = false;
_ = RunLiveUpdatesAsync();
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// Re-theme this sample to Bootstrap at the component level (full=true) by re-scoping
// the whole stock theme under #finance-section, so buttons/checkboxes/headers match
// Bootstrap exactly. The scopeThemeToElement helper dedupes, so remounts won't re-inject.
await JS.InvokeVoidAsync("scopeThemeToElement",
"_content/IgniteUI.Blazor/themes/light/bootstrap.css", "#finance-section", true);
await JS.InvokeVoidAsync("scopeThemeToElement",
"_content/IgniteUI.Blazor/themes/grid/light/bootstrap.css", "#finance-section", true);
}
}

// Start auto-update timer (every 3 seconds)
updateTimer = new System.Timers.Timer(3000);
updateTimer.Elapsed += (sender, args) =>
private async Task RunLiveUpdatesAsync()
{
updateTimer = new PeriodicTimer(TimeSpan.FromSeconds(3));
while (await updateTimer.WaitForNextTickAsync())
{
FinancialService.UpdateAllPrices();
};
updateTimer.Start();
}
}

private void OnDataChanged()
{
InvokeAsync(() =>
{
StateHasChanged();
// Trigger grid change detection to refresh with updated data
if (grid != null)
{
grid.MarkForCheck();
}
grid?.MarkForCheck();
});
}

public void Dispose()
{
updateTimer?.Stop();
updateTimer?.Dispose();
FinancialService.OnDataChanged -= OnDataChanged;
}
Expand Down
6 changes: 0 additions & 6 deletions samples/FinanceGrid/FinanceGridComponent.razor.css

This file was deleted.

3 changes: 3 additions & 0 deletions samples/FinanceGrid/Models/FinancialData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public class FinancialData

[JsonPropertyName("dailyPercentageChange")]
public double DailyPercentageChange { get; set; }

[JsonPropertyName("holdingPeriod")]
public int HoldingPeriod { get; set; }
}

public class PriceValue
Expand Down
5 changes: 3 additions & 2 deletions samples/FinanceGrid/Services/FinancialService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public void UpdateAllPrices()
dataRow.DailyPercentageChange = randomizedData.DailyPercentageChange;
}

// New list reference so the Blazor grid re-syncs the mutated rows to the web component.
Data = new List<FinancialData>(Data);
OnDataChanged?.Invoke();
}

Expand All @@ -93,8 +95,7 @@ private double CalculateProfitLossPercentage(double profitLossValue, double boug

private double CalculateDailyPercentageChange(double initialPrice, double finalPrice)
{
var priceDifference = finalPrice - initialPrice;
return (priceDifference / initialPrice) * 100;
return (finalPrice - initialPrice) / initialPrice;
}

private (double NewPrice, double ProfitLossValue, double ProfitLossPercentage, double MarketValue, double DailyPercentageChange)
Expand Down
Binary file removed samples/FinanceGrid/wwwroot/background.png
Binary file not shown.
Binary file added samples/FinanceGrid/wwwroot/companies/3M.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Adobe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Alibaba.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Bitcoin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Boeing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Booking.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Cisco.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Costco.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Dominos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Exxon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/FedEx.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/Ford.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/General.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/FinanceGrid/wwwroot/companies/IBM.png
Binary file added samples/FinanceGrid/wwwroot/companies/Intel.png
Binary file added samples/FinanceGrid/wwwroot/companies/Johnson.png
Binary file added samples/FinanceGrid/wwwroot/companies/Kellogg.png
Binary file added samples/FinanceGrid/wwwroot/companies/Morgan.png
Binary file added samples/FinanceGrid/wwwroot/companies/NVIDIA.png
Binary file added samples/FinanceGrid/wwwroot/companies/Netflix.png
Binary file added samples/FinanceGrid/wwwroot/companies/PayPal.png
Binary file added samples/FinanceGrid/wwwroot/companies/PepsiCo.png
Binary file added samples/FinanceGrid/wwwroot/companies/Pfizer.png
Binary file added samples/FinanceGrid/wwwroot/companies/Procter.png
Binary file added samples/FinanceGrid/wwwroot/companies/Spotify.png
Binary file added samples/FinanceGrid/wwwroot/companies/Tesla.png
Binary file added samples/FinanceGrid/wwwroot/companies/The.png
Binary file added samples/FinanceGrid/wwwroot/companies/Uber.png
Binary file added samples/FinanceGrid/wwwroot/companies/Visa.png
Binary file added samples/FinanceGrid/wwwroot/companies/Walmart.png
Binary file added samples/FinanceGrid/wwwroot/companies/Walt.png
Binary file added samples/FinanceGrid/wwwroot/companies/Zoom.png
6 changes: 0 additions & 6 deletions samples/FinanceGrid/wwwroot/exampleJsInterop.js

This file was deleted.

39 changes: 39 additions & 0 deletions samples/FinanceGrid/wwwroot/scripts/finance-grid-templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
(function registerFinanceGridTemplates() {
if (!window.igRegisterScript || !window.igTemplating || !window.igTemplating.html) {
setTimeout(registerFinanceGridTemplates, 50);
return;
}
const html = window.igTemplating.html;
const icons = {
up: html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor"><path d="m136-240-56-56 296-298 160 160 208-206H640v-80h240v240h-80v-104L536-320 376-480 136-240Z"/></svg>`,
down: html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor"><path d="M640-240v-80h104L536-526 376-366 80-664l56-56 240 240 160-160 264 264v-104h80v240H640Z"/></svg>`
};
const trend = (v) => (v >= 0 ? icons.up : icons.down);
const sign = (v) => (v >= 0 ? "profit" : "loss");

window.igRegisterScript("financeAssetCell", (ctx) => {
const name = ctx.cell.value || "";
const logo = "_content/FinanceGrid/companies/" + name.split(" ")[0] + ".png";
return html`<div class="cell-flex"><igc-avatar shape="rounded" class="asset-avatar" src="${logo}"></igc-avatar><span>${name}</span></div>`;
}, false);

window.igRegisterScript("financePercentCell", (ctx) => {
const v = ctx.cell.value || 0;
return html`<div class="cell-flex ${sign(v)}"><span>${(v * 100).toFixed(2)}%</span>${trend(v)}</div>`;
}, false);

window.igRegisterScript("financeProfitValueCell", (ctx) => {
const v = ctx.cell.value || 0;
const formatted = (v < 0 ? "-$" : "$") + Math.abs(v).toFixed(2);
return html`<div class="cell-flex ${sign(v)}"><span>${formatted}</span>${trend(v)}</div>`;
}, false);

window.igRegisterScript("financeAllocationCell", (ctx) => {
const pct = ((ctx.cell.value || 0) * 100).toFixed(2);
return html`<div class="alloc-cell"><span style="width: 42px">${pct}%</span><igc-linear-progress value="${pct}" animation-duration="0" hide-label></igc-linear-progress></div>`;
}, false);

window.igRegisterScript("financeHoldingPeriodCell", (ctx) => {
return html`<span>${ctx.cell.value} days</span>`;
}, false);
})();
Loading