@columenlabs/lumen-ui 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/NOTICE +12 -0
- package/README.md +4 -2
- package/dist/add-column.d.ts +23 -0
- package/dist/add-column.js +62 -0
- package/dist/api-fetch.d.ts +9 -0
- package/dist/api-fetch.js +60 -0
- package/dist/app-switcher.d.ts +21 -0
- package/dist/app-switcher.js +12 -0
- package/dist/app-views.d.ts +18 -0
- package/dist/app-views.js +41 -0
- package/dist/assistant-context.d.ts +72 -0
- package/dist/assistant-context.js +30 -0
- package/dist/assistant-panel.d.ts +58 -0
- package/dist/assistant-panel.js +244 -0
- package/dist/assistant-screen.d.ts +124 -0
- package/dist/assistant-screen.js +252 -0
- package/dist/card-switch.d.ts +16 -0
- package/dist/card-switch.js +16 -0
- package/dist/color-dot.d.ts +14 -0
- package/dist/color-dot.js +19 -0
- package/dist/confirm.d.ts +18 -0
- package/dist/confirm.js +5 -0
- package/dist/connections.d.ts +45 -0
- package/dist/connections.js +275 -0
- package/dist/coverage-calendar-map.d.ts +27 -0
- package/dist/coverage-calendar-map.js +84 -0
- package/dist/coverage-cells.d.ts +55 -0
- package/dist/coverage-cells.js +85 -0
- package/dist/coverage-map.d.ts +112 -0
- package/dist/coverage-map.js +434 -0
- package/dist/details-table.d.ts +20 -0
- package/dist/details-table.js +17 -0
- package/dist/drawer-section.d.ts +27 -0
- package/dist/drawer-section.js +23 -0
- package/dist/floating-head.d.ts +2 -0
- package/dist/floating-head.js +57 -0
- package/dist/fold.d.ts +16 -0
- package/dist/fold.js +70 -0
- package/dist/form-issues.d.ts +32 -0
- package/dist/form-issues.js +60 -0
- package/dist/formula-input.d.ts +17 -0
- package/dist/formula-input.js +104 -0
- package/dist/frame-script.d.ts +7 -0
- package/dist/frame-script.js +103 -0
- package/dist/freshness.d.ts +24 -0
- package/dist/freshness.js +99 -0
- package/dist/group-button.d.ts +33 -0
- package/dist/group-button.js +67 -0
- package/dist/growth-chart.d.ts +77 -0
- package/dist/growth-chart.js +195 -0
- package/dist/hooks/use-keyboard-fit.d.ts +15 -0
- package/dist/hooks/use-keyboard-fit.js +29 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/icon-button.d.ts +21 -0
- package/dist/icon-button.js +22 -0
- package/dist/icon-picker.d.ts +14 -0
- package/dist/icon-picker.js +36 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.js +90 -0
- package/dist/integrations.d.ts +57 -0
- package/dist/integrations.js +73 -0
- package/dist/joins.d.ts +127 -0
- package/dist/joins.js +767 -0
- package/dist/kit-config.d.ts +13 -0
- package/dist/kit-config.js +15 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/lumen-boundary.d.ts +7 -0
- package/dist/lumen-boundary.js +10 -0
- package/dist/lumen-code-editor-impl.d.ts +2 -0
- package/dist/lumen-code-editor-impl.js +16 -0
- package/dist/lumen-code-editor.d.ts +11 -0
- package/dist/lumen-code-editor.js +11 -0
- package/dist/lumen-code.d.ts +22 -0
- package/dist/lumen-code.js +79 -0
- package/dist/lumen-drawer.d.ts +30 -0
- package/dist/lumen-drawer.js +29 -0
- package/dist/lumen-echart.d.ts +58 -0
- package/dist/lumen-echart.js +129 -0
- package/dist/lumen-filter.d.ts +75 -0
- package/dist/lumen-filter.js +554 -0
- package/dist/lumen-finder.d.ts +62 -0
- package/dist/lumen-finder.js +275 -0
- package/dist/lumen-form.d.ts +34 -0
- package/dist/lumen-form.js +81 -0
- package/dist/lumen-geo-map.d.ts +9 -0
- package/dist/lumen-geo-map.js +135 -0
- package/dist/lumen-grid.d.ts +49 -0
- package/dist/lumen-grid.js +205 -0
- package/dist/lumen-layout.d.ts +150 -0
- package/dist/lumen-layout.js +658 -0
- package/dist/lumen-links.d.ts +96 -0
- package/dist/lumen-links.js +213 -0
- package/dist/lumen-page-state.d.ts +20 -0
- package/dist/lumen-page-state.js +15 -0
- package/dist/lumen-selector.d.ts +139 -0
- package/dist/lumen-selector.js +308 -0
- package/dist/lumen-source.d.ts +137 -0
- package/dist/lumen-source.js +329 -0
- package/dist/lumen-tab-drawer.d.ts +27 -0
- package/dist/lumen-tab-drawer.js +26 -0
- package/dist/lumen-tabs.d.ts +21 -0
- package/dist/lumen-tabs.js +6 -0
- package/dist/lumen-toast.d.ts +11 -0
- package/dist/lumen-toast.js +16 -0
- package/dist/lumen-trend.d.ts +18 -0
- package/dist/lumen-trend.js +157 -0
- package/dist/lumen-view-card.d.ts +35 -0
- package/dist/lumen-view-card.js +50 -0
- package/dist/lumen-view.d.ts +172 -0
- package/dist/lumen-view.js +647 -0
- package/dist/lumen-widget-charts.d.ts +57 -0
- package/dist/lumen-widget-charts.js +69 -0
- package/dist/lumen-widget.d.ts +614 -0
- package/dist/lumen-widget.js +598 -0
- package/dist/market/compare-chart.d.ts +34 -0
- package/dist/market/compare-chart.js +292 -0
- package/dist/market/indicator-picker.d.ts +29 -0
- package/dist/market/indicator-picker.js +125 -0
- package/dist/market/indicators.d.ts +63 -0
- package/dist/market/indicators.js +314 -0
- package/dist/market/live.d.ts +120 -0
- package/dist/market/live.js +444 -0
- package/dist/market/lumen-chart.d.ts +88 -0
- package/dist/market/lumen-chart.js +645 -0
- package/dist/market/market-widget.d.ts +45 -0
- package/dist/market/market-widget.js +346 -0
- package/dist/market/option-chain.d.ts +19 -0
- package/dist/market/option-chain.js +53 -0
- package/dist/market/price-chart.d.ts +128 -0
- package/dist/market/price-chart.js +619 -0
- package/dist/mcp-settings.d.ts +20 -0
- package/dist/mcp-settings.js +65 -0
- package/dist/nav.d.ts +77 -0
- package/dist/nav.js +73 -0
- package/dist/note-line.d.ts +13 -0
- package/dist/note-line.js +5 -0
- package/dist/notifications.d.ts +9 -0
- package/dist/notifications.js +168 -0
- package/dist/origin-legend.d.ts +14 -0
- package/dist/origin-legend.js +38 -0
- package/dist/overview.d.ts +84 -0
- package/dist/overview.js +105 -0
- package/dist/page-inputs.d.ts +14 -0
- package/dist/page-inputs.js +16 -0
- package/dist/page.d.ts +32 -0
- package/dist/page.js +45 -0
- package/dist/pager.d.ts +10 -0
- package/dist/pager.js +14 -0
- package/dist/prefs.d.ts +71 -0
- package/dist/prefs.js +126 -0
- package/dist/query-client.d.ts +7 -0
- package/dist/query-client.js +19 -0
- package/dist/refresh.d.ts +4 -0
- package/dist/refresh.js +19 -0
- package/dist/rename-field.d.ts +11 -0
- package/dist/rename-field.js +26 -0
- package/dist/reset-button.d.ts +9 -0
- package/dist/reset-button.js +10 -0
- package/dist/route-error.d.ts +42 -0
- package/dist/route-error.js +229 -0
- package/dist/schedules.d.ts +88 -0
- package/dist/schedules.js +221 -0
- package/dist/settings.d.ts +51 -0
- package/dist/settings.js +183 -0
- package/dist/shell.d.ts +99 -0
- package/dist/shell.js +137 -0
- package/dist/source-health.d.ts +12 -0
- package/dist/source-health.js +58 -0
- package/dist/spotlight.d.ts +23 -0
- package/dist/spotlight.js +138 -0
- package/dist/status-health.d.ts +16 -0
- package/dist/status-health.js +41 -0
- package/dist/status.d.ts +9 -0
- package/dist/status.js +12 -0
- package/dist/summary-cards.d.ts +56 -0
- package/dist/summary-cards.js +274 -0
- package/dist/symbol-sheet-context.d.ts +4 -0
- package/dist/symbol-sheet-context.js +5 -0
- package/dist/symbol-sheet.d.ts +9 -0
- package/dist/symbol-sheet.js +24 -0
- package/dist/tasks.d.ts +29 -0
- package/dist/tasks.js +278 -0
- package/dist/theme.css +606 -0
- package/dist/tile.d.ts +37 -0
- package/dist/tile.js +25 -0
- package/dist/ui/alert-dialog.d.ts +18 -0
- package/dist/ui/alert-dialog.js +41 -0
- package/dist/ui/alert.d.ts +10 -0
- package/dist/ui/alert.js +27 -0
- package/dist/ui/avatar.d.ts +11 -0
- package/dist/ui/avatar.js +22 -0
- package/dist/ui/badge.d.ts +9 -0
- package/dist/ui/badge.js +27 -0
- package/dist/ui/breadcrumb.d.ts +11 -0
- package/dist/ui/breadcrumb.js +27 -0
- package/dist/ui/button-group.d.ts +11 -0
- package/dist/ui/button-group.js +27 -0
- package/dist/ui/button.d.ts +10 -0
- package/dist/ui/button.js +38 -0
- package/dist/ui/card.d.ts +11 -0
- package/dist/ui/card.js +24 -0
- package/dist/ui/chart.d.ts +44 -0
- package/dist/ui/chart.js +120 -0
- package/dist/ui/checkbox.d.ts +4 -0
- package/dist/ui/checkbox.js +8 -0
- package/dist/ui/collapsible.d.ts +5 -0
- package/dist/ui/collapsible.js +12 -0
- package/dist/ui/combobox.d.ts +24 -0
- package/dist/ui/combobox.js +60 -0
- package/dist/ui/command.d.ts +18 -0
- package/dist/ui/command.js +34 -0
- package/dist/ui/dialog.d.ts +23 -0
- package/dist/ui/dialog.js +50 -0
- package/dist/ui/dropdown-menu.d.ts +29 -0
- package/dist/ui/dropdown-menu.js +50 -0
- package/dist/ui/emoji-picker.d.ts +6 -0
- package/dist/ui/emoji-picker.js +28 -0
- package/dist/ui/empty.d.ts +11 -0
- package/dist/ui/empty.js +33 -0
- package/dist/ui/field.d.ts +24 -0
- package/dist/ui/field.js +65 -0
- package/dist/ui/hover-card.d.ts +6 -0
- package/dist/ui/hover-card.js +13 -0
- package/dist/ui/input-group.d.ts +16 -0
- package/dist/ui/input-group.js +56 -0
- package/dist/ui/input.d.ts +3 -0
- package/dist/ui/input.js +6 -0
- package/dist/ui/item.d.ts +23 -0
- package/dist/ui/item.js +67 -0
- package/dist/ui/kbd.d.ts +3 -0
- package/dist/ui/kbd.js +9 -0
- package/dist/ui/label.d.ts +4 -0
- package/dist/ui/label.js +7 -0
- package/dist/ui/popover.d.ts +10 -0
- package/dist/ui/popover.js +25 -0
- package/dist/ui/progress.d.ts +4 -0
- package/dist/ui/progress.js +9 -0
- package/dist/ui/resizable.d.ts +7 -0
- package/dist/ui/resizable.js +13 -0
- package/dist/ui/scroll-area.d.ts +5 -0
- package/dist/ui/scroll-area.js +10 -0
- package/dist/ui/select.d.ts +15 -0
- package/dist/ui/select.js +36 -0
- package/dist/ui/separator.d.ts +4 -0
- package/dist/ui/separator.js +7 -0
- package/dist/ui/sheet.d.ts +14 -0
- package/dist/ui/sheet.js +54 -0
- package/dist/ui/sidebar.d.ts +69 -0
- package/dist/ui/sidebar.js +206 -0
- package/dist/ui/skeleton.d.ts +2 -0
- package/dist/ui/skeleton.js +6 -0
- package/dist/ui/slider.d.ts +4 -0
- package/dist/ui/slider.js +9 -0
- package/dist/ui/sonner.d.ts +3 -0
- package/dist/ui/sonner.js +24 -0
- package/dist/ui/spinner.d.ts +2 -0
- package/dist/ui/spinner.js +7 -0
- package/dist/ui/switch.d.ts +6 -0
- package/dist/ui/switch.js +7 -0
- package/dist/ui/table.d.ts +10 -0
- package/dist/ui/table.js +31 -0
- package/dist/ui/tabs.d.ts +7 -0
- package/dist/ui/tabs.js +22 -0
- package/dist/ui/textarea.d.ts +3 -0
- package/dist/ui/textarea.js +6 -0
- package/dist/ui/toggle-group.d.ts +10 -0
- package/dist/ui/toggle-group.js +22 -0
- package/dist/ui/toggle.d.ts +9 -0
- package/dist/ui/toggle.js +25 -0
- package/dist/ui/tooltip.d.ts +7 -0
- package/dist/ui/tooltip.js +16 -0
- package/dist/view-edit-cell.d.ts +49 -0
- package/dist/view-edit-cell.js +201 -0
- package/dist/view-editor.d.ts +52 -0
- package/dist/view-editor.js +940 -0
- package/dist/view-formulas.d.ts +61 -0
- package/dist/view-formulas.js +247 -0
- package/dist/view-icons.d.ts +20 -0
- package/dist/view-icons.js +70 -0
- package/dist/view-model.d.ts +390 -0
- package/dist/view-model.js +316 -0
- package/dist/whats-new.d.ts +3 -0
- package/dist/whats-new.js +53 -0
- package/dist/widget-controls.d.ts +9 -0
- package/dist/widget-controls.js +26 -0
- package/dist/widget-settings.d.ts +436 -0
- package/dist/widget-settings.js +290 -0
- package/dist/widget-thumbs.d.ts +3 -0
- package/dist/widget-thumbs.js +29 -0
- package/dist/workspace-keys.d.ts +12 -0
- package/dist/workspace-keys.js +13 -0
- package/dist/workspaces.d.ts +57 -0
- package/dist/workspaces.js +473 -0
- package/package.json +82 -4
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import type { JoinKey } from '@columenlabs/lumen-ui-types/domains';
|
|
2
|
+
import { type CustomViewConfig, type ViewAgg, type ViewChip, type ViewFormat, type ViewTotalAgg } from '@columenlabs/lumen-ui-types/views';
|
|
3
|
+
import type { LucideIcon } from 'lucide-react';
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
|
+
import type { ChartBand, ChartMarker, Series } from './growth-chart.js';
|
|
6
|
+
export type ViewCellValue = number | string | null;
|
|
7
|
+
/** One field of a data domain: how to read it, show it, filter, group and roll it up. */
|
|
8
|
+
export interface ViewField<T> {
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
icon: LucideIcon;
|
|
12
|
+
value: (row: T) => ViewCellValue;
|
|
13
|
+
/**
|
|
14
|
+
* Its name in formulas when not `<domain>.<key>`: a join field's
|
|
15
|
+
* `symbol.price`, a frame column's `frame.<frame>.<column>`, a linked domain's `tax_lots.count`.
|
|
16
|
+
*/
|
|
17
|
+
name?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Where the field comes from: one of the domain's `groups` (Holding, Symbol,
|
|
20
|
+
* Account). The editor's tree and the table's column-group headers follow it; formulas are their
|
|
21
|
+
* own group. Left out: the domain's first group.
|
|
22
|
+
*/
|
|
23
|
+
group?: string;
|
|
24
|
+
/** The sub-heading within its group in the editor's tree (Valuation, Analysts, Technicals). */
|
|
25
|
+
topic?: string;
|
|
26
|
+
/** Every value a row has for filtering, when it has several (a symbol in Holdings and Watchlist). */
|
|
27
|
+
values?: (row: T) => string[];
|
|
28
|
+
format: ViewFormat;
|
|
29
|
+
/** How the value is made, shown under the field in the Edit dialog. */
|
|
30
|
+
formula?: string;
|
|
31
|
+
/** A holding amount (dollars or size) that Hide amounts masks. */
|
|
32
|
+
amount?: boolean;
|
|
33
|
+
/** Large numbers in short form, $283.1B or 6.1M (13F funds). */
|
|
34
|
+
compact?: boolean;
|
|
35
|
+
/** What an empty cell says (`N/A` where the source has no value for it); left out: a dash. */
|
|
36
|
+
empty?: string;
|
|
37
|
+
/** A short note beside the field in the Edit dialog, e.g. `per ticker`. */
|
|
38
|
+
note?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Makes the cell editable: a click picks a value in use or takes a new one,
|
|
41
|
+
* saved through `save`; `note` says what an edit covers for that row. `options` lists every
|
|
42
|
+
* value the field has, in use or not, so the picker offers them whatever the filter shows
|
|
43
|
+
*; without it the picker offers the values in the shown rows.
|
|
44
|
+
*/
|
|
45
|
+
edit?: {
|
|
46
|
+
/** Saves one value (null clears it). A field with `many` leaves it out. */
|
|
47
|
+
save?: (row: T, value: string | null) => Promise<unknown>;
|
|
48
|
+
/**
|
|
49
|
+
* Several values a row (labels): the cell shows each of `values` as a chip
|
|
50
|
+
* and its picker ticks any number, typed names added, saved together when it closes.
|
|
51
|
+
*/
|
|
52
|
+
many?: (row: T, values: string[]) => Promise<unknown>;
|
|
53
|
+
note?: (row: T) => string;
|
|
54
|
+
options?: () => {
|
|
55
|
+
inUse: string[];
|
|
56
|
+
unused: string[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Typed in place (Edits in place): the cell is a number or text box, as in
|
|
60
|
+
* a sheet (click or tap and type; Enter saves, Esc leaves, Tab moves right), not a picker.
|
|
61
|
+
*/
|
|
62
|
+
input?: 'number' | 'text';
|
|
63
|
+
/** The picker offers only `options`, with no typed new value (an app, an area). */
|
|
64
|
+
fixed?: boolean;
|
|
65
|
+
/** This row's cell was typed by hand: a small ✎ marks it. */
|
|
66
|
+
edited?: (row: T) => boolean;
|
|
67
|
+
};
|
|
68
|
+
/** Offered as `field:value` tokens in the filter box. */
|
|
69
|
+
filterable?: boolean;
|
|
70
|
+
/** Offered in the Group switcher and as pivot rows or columns. */
|
|
71
|
+
groupable?: boolean;
|
|
72
|
+
/** Why a field is not groupable, shown on its greyed Group box in Edit view, e.g. `One per holding. Group by Underlying.` */
|
|
73
|
+
groupNote?: string;
|
|
74
|
+
/** How group, pivot and Total rows roll the field up; no roll-up when left out. */
|
|
75
|
+
aggregate?: ViewAgg;
|
|
76
|
+
/** A formula column with no `aggregate`: group and Total rows run `compute` over the rows' roll-ups of its inputs. */
|
|
77
|
+
rollFormula?: boolean;
|
|
78
|
+
/** Group and Total rows leave it blank (the view picked None for it). */
|
|
79
|
+
noRollup?: boolean;
|
|
80
|
+
/** A value the page works out from the row and the shown rows (a formula column). */
|
|
81
|
+
compute?: (row: T, scope: {
|
|
82
|
+
value: (key: string) => ViewCellValue;
|
|
83
|
+
groupSum: (key: string) => number;
|
|
84
|
+
totalSum: (key: string) => number;
|
|
85
|
+
}) => ViewCellValue;
|
|
86
|
+
/**
|
|
87
|
+
* A share the page works out, in %: the row's `of` field over its sum in the row's group
|
|
88
|
+
* (`group`; every shown row when not grouped) or in every shown row (`total`). A group row shows
|
|
89
|
+
* its group's share of the total. `value` is unused for it.
|
|
90
|
+
*/
|
|
91
|
+
share?: {
|
|
92
|
+
of: string;
|
|
93
|
+
within: 'group' | 'total';
|
|
94
|
+
};
|
|
95
|
+
/** Draws the cell instead of its formatted value (a sparkline); sorting and filters still use
|
|
96
|
+
* `value` (strategy lab). */
|
|
97
|
+
render?: (row: T) => ReactNode;
|
|
98
|
+
/** The ticker a click on the cell charts in the app's chart dialog (an option charts its
|
|
99
|
+
* underlying); null leaves the row's cell plain. */
|
|
100
|
+
chart?: (row: T) => string | null;
|
|
101
|
+
/** The chip's colour when the field shows as a chip: `gain` green, `muted` grey (Open and
|
|
102
|
+
* Closed lots), `loss` red and `info` blue (a run's Failed and Running;
|
|
103
|
+
* `RUN_STATE_TONE`). Left out: the plain chip. */
|
|
104
|
+
tone?: (row: T) => ViewChipTone | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* A text value's colour (a category's, a label's): a dot before it in the
|
|
107
|
+
* cell, its chip and the edit picker. A CSS colour; a theme token reads in light and dark.
|
|
108
|
+
*/
|
|
109
|
+
color?: (value: string) => string | undefined;
|
|
110
|
+
/** The cell's background, a theme colour mix (a P/L heat grid). */
|
|
111
|
+
tint?: (row: T) => string | undefined;
|
|
112
|
+
/** Left out on phones, where the table has no room for it (a returns table's longer windows). */
|
|
113
|
+
hideOnPhone?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* How the value updates (live domains): `live` moves with the market while it
|
|
116
|
+
* trades (a quote), `asof` is a daily or snapshot value (a close, a fact, the assistant frame's column).
|
|
117
|
+
* `calc` is worked out from live values the domain has no field for (an account's value).
|
|
118
|
+
* Left out it is fixed (a quantity, a cost), unless `from` names a live field.
|
|
119
|
+
*/
|
|
120
|
+
updates?: 'live' | 'calc' | 'asof';
|
|
121
|
+
/** The fields it is worked out from, so a value made from a live one marks as Live calc. */
|
|
122
|
+
from?: string[];
|
|
123
|
+
}
|
|
124
|
+
export type ViewChipTone = 'gain' | 'loss' | 'info' | 'muted' | 'sky' | 'amber';
|
|
125
|
+
/** A chip's classes per tone, on the theme's tokens so light and dark both read. */
|
|
126
|
+
export declare const CHIP_TONE: Record<ViewChipTone, string>;
|
|
127
|
+
/** A run's state as a chip, the same on every app: done green, failed
|
|
128
|
+
* red, running blue, queued, waiting and canceled grey. */
|
|
129
|
+
export declare const RUN_STATE_TONE: {
|
|
130
|
+
readonly done: "gain";
|
|
131
|
+
readonly failed: "loss";
|
|
132
|
+
readonly running: "info";
|
|
133
|
+
readonly queued: "muted";
|
|
134
|
+
readonly waiting: "muted";
|
|
135
|
+
readonly canceled: "muted";
|
|
136
|
+
};
|
|
137
|
+
/** A group of fields by where they come from: their colour and, per topic, the source line. */
|
|
138
|
+
export interface ViewFieldGroup {
|
|
139
|
+
id: string;
|
|
140
|
+
label: string;
|
|
141
|
+
/** A theme colour (`var(--chart-3)`) for the group's dot and column-group header. */
|
|
142
|
+
color?: string;
|
|
143
|
+
/** What the group's fields are looked up by, e.g. `by symbol · an option by its underlying`. */
|
|
144
|
+
note?: string;
|
|
145
|
+
/** Each topic's source, e.g. Feed, live (`JOIN_SOURCES`). */
|
|
146
|
+
sources?: Record<string, ViewSource & {
|
|
147
|
+
detail?: string;
|
|
148
|
+
}>;
|
|
149
|
+
}
|
|
150
|
+
/** Where a topic's fields come from; its colour marks the topic in the field tree. */
|
|
151
|
+
export interface ViewSource {
|
|
152
|
+
name: string;
|
|
153
|
+
/** A theme colour (`var(--chart-2)`), one per source across every app. */
|
|
154
|
+
color: string;
|
|
155
|
+
}
|
|
156
|
+
/** The formulas group: a view's own formula columns. */
|
|
157
|
+
export declare const FORMULAS_GROUP = "_formulas";
|
|
158
|
+
/** A data domain: registered once, any app can open views on it. */
|
|
159
|
+
export interface ViewDomain<T> {
|
|
160
|
+
id: string;
|
|
161
|
+
fields: ViewField<T>[];
|
|
162
|
+
/** Field groups in order; without them every field is one group. */
|
|
163
|
+
groups?: ViewFieldGroup[];
|
|
164
|
+
/**
|
|
165
|
+
* The keys its rows carry (views from data domains): a reader per key, null
|
|
166
|
+
* for a row without one (cash). The shell's `useJoins` attaches the registry's join fields for
|
|
167
|
+
* each key (symbol: Price, Valuation, Technicals, Change...; account: Brokerage, Trading, Cash)
|
|
168
|
+
* on any card of any app, after the domain's own fields; an own field of the same key wins.
|
|
169
|
+
*/
|
|
170
|
+
keys?: Partial<Record<JoinKey, (row: T) => string | string[] | null>>;
|
|
171
|
+
/** A stable id per row (React keys, the details drawer). */
|
|
172
|
+
rowKey: (row: T) => string;
|
|
173
|
+
/** Free text the filter box matches besides field values (a name, an id). */
|
|
174
|
+
text?: (row: T) => string[];
|
|
175
|
+
/** False keeps views from adding their own formula columns (`config.formulas`); every other
|
|
176
|
+
* domain takes them (formulas everywhere, `takesFormulas`). */
|
|
177
|
+
formulas?: false;
|
|
178
|
+
/** The domain's own summary tiles a view can show, in the order offered;
|
|
179
|
+
* the app draws them (LumenLayout's `tile`). */
|
|
180
|
+
tiles?: {
|
|
181
|
+
key: string;
|
|
182
|
+
label: string;
|
|
183
|
+
icon: LucideIcon;
|
|
184
|
+
}[];
|
|
185
|
+
/**
|
|
186
|
+
* Row-tap filtering (the assistant drafts step 1): in a card with a link colour, a row
|
|
187
|
+
* tap picks the row's value of this field as a temporary linked chip, so every card of that
|
|
188
|
+
* colour narrows to it (tap a lot, see its swaps); a second tap lets go. Unlinked, a tap opens the
|
|
189
|
+
* row as usual.
|
|
190
|
+
*/
|
|
191
|
+
rowLink?: string;
|
|
192
|
+
/** The details drawer: collapsible sections (the shell's DrawerSection), each with its icon.
|
|
193
|
+
* A section starts collapsed unless `open` says so; a function opens it only for rows it
|
|
194
|
+
* holds something for. `count` and `hint` fill the header's chip and note. */
|
|
195
|
+
details?: {
|
|
196
|
+
id: string;
|
|
197
|
+
label: string;
|
|
198
|
+
icon: LucideIcon;
|
|
199
|
+
open?: boolean | ((row: T) => boolean);
|
|
200
|
+
count?: (row: T) => number | null;
|
|
201
|
+
hint?: (row: T) => string | null;
|
|
202
|
+
render: (row: T) => ReactNode;
|
|
203
|
+
}[];
|
|
204
|
+
/** While grouped, rows of one group sharing `key` show as one line, made by `rows`. */
|
|
205
|
+
merge?: {
|
|
206
|
+
key: (row: T) => string;
|
|
207
|
+
rows: (rows: T[]) => T;
|
|
208
|
+
};
|
|
209
|
+
/** A folded row's own rows, shown as a table at the top of its details drawer, first column
|
|
210
|
+
* `by` (the field they differ on), then the view's columns. */
|
|
211
|
+
parts?: {
|
|
212
|
+
label: string;
|
|
213
|
+
by: string;
|
|
214
|
+
rows: (row: T) => T[];
|
|
215
|
+
/** `rows` are the other rows only, not the row itself, so one is enough to open (a post's repeats). By default they include it and need two. */
|
|
216
|
+
others?: boolean;
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* A row with more to read opens it in a panel inside the table, right under the row, from the
|
|
220
|
+
* chevron in its first cell (an outlook's write-up, an article's summary).
|
|
221
|
+
* `render` returns null for rows with nothing more: they get no chevron. Takes the chevron over
|
|
222
|
+
* from the sub-group.
|
|
223
|
+
*/
|
|
224
|
+
panel?: {
|
|
225
|
+
label: string;
|
|
226
|
+
render: (row: T) => ReactNode | null;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* What a row can open under it, one level: the view's "Each row opens"
|
|
230
|
+
* picks one, or none; a view that says nothing opens the first. Either `rows`, a row's own
|
|
231
|
+
* children (tax lots, accounts, variants), or `under`, where rows sharing that key fold into one
|
|
232
|
+
* rolled-up line that opens them (holdings by underlying: Shares, then each option). `name`
|
|
233
|
+
* labels each child in the first column.
|
|
234
|
+
*/
|
|
235
|
+
subgroups?: ViewSubgroup<T>[];
|
|
236
|
+
/**
|
|
237
|
+
* Curves for the Growth of $1 widget: the shown rows' lines (rows with no
|
|
238
|
+
* curve yet drop out) and anything drawn beside them (benchmarks), the bands (an OOS window, its
|
|
239
|
+
* line draggable) and markers, the card's header tools and a note. Only domains with it offer
|
|
240
|
+
* the widget.
|
|
241
|
+
*/
|
|
242
|
+
growth?: {
|
|
243
|
+
lines: (rows: T[]) => Series[];
|
|
244
|
+
bands?: (rows: T[]) => ChartBand[];
|
|
245
|
+
markers?: ChartMarker[];
|
|
246
|
+
tools?: ReactNode;
|
|
247
|
+
note?: string;
|
|
248
|
+
/** The curves' own loading (the tapes), when they load apart from the rows. */
|
|
249
|
+
loading?: boolean;
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* The tiles card's own header from the shown rows: say whose numbers the
|
|
253
|
+
* tiles show and how that row was picked, e.g. "Best variant: Daily close" / "highest CAGR", and
|
|
254
|
+
* its own tools (a Rank by picker).
|
|
255
|
+
*/
|
|
256
|
+
tilesHead?: (rows: T[]) => {
|
|
257
|
+
title?: string;
|
|
258
|
+
note?: string;
|
|
259
|
+
tools?: ReactNode;
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* The domain's cash rows (an account's cash line), when it has them: each
|
|
263
|
+
* Summary then offers Include cash in Edit widget (`summaryCash`).
|
|
264
|
+
*/
|
|
265
|
+
cash?: (row: T) => boolean;
|
|
266
|
+
}
|
|
267
|
+
/** Whether a Summary counts the domain's cash rows: its own choice, else only when it covers
|
|
268
|
+
* every row (no filter of its own, no linked chips). */
|
|
269
|
+
export declare const summaryCash: (card: {
|
|
270
|
+
cash?: boolean;
|
|
271
|
+
}, narrowed: boolean) => boolean;
|
|
272
|
+
/** One choice of a domain's "Each row opens". */
|
|
273
|
+
export interface ViewSubgroup<T> {
|
|
274
|
+
key: string;
|
|
275
|
+
label: string;
|
|
276
|
+
icon: LucideIcon;
|
|
277
|
+
rows?: (row: T) => T[];
|
|
278
|
+
under?: (row: T) => string;
|
|
279
|
+
name?: (row: T) => string;
|
|
280
|
+
/** `under` folds a key even when one row has it (a field's second level of grouping). */
|
|
281
|
+
always?: boolean;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* What a row can open: the domain's own sub-groups, else every groupable field as a second level
|
|
285
|
+
* of grouping (the assistant frame tab groups by class, then by unit). The field's
|
|
286
|
+
* rows sharing a value fold into one rolled-up line that opens them.
|
|
287
|
+
*/
|
|
288
|
+
/** The picker's name: a domain's own sub-groups open rows, field ones group a second level. */
|
|
289
|
+
export declare function subgroupLabel<T>(domain: ViewDomain<T>): string;
|
|
290
|
+
export declare function subgroupsOf<T>(domain: ViewDomain<T>): ViewSubgroup<T>[];
|
|
291
|
+
/** The sub-group a view opens: its own pick, else the domain's first; null for none. */
|
|
292
|
+
export declare function subgroupOf<T>(domain: ViewDomain<T>, key: string | null | undefined): ViewSubgroup<T> | null;
|
|
293
|
+
/** Rolls values up; nulls are skipped and an empty set is null (count is 0). */
|
|
294
|
+
export declare function rollUp(values: ViewCellValue[], agg: ViewAgg): ViewCellValue;
|
|
295
|
+
/** A view's chip fields and where each shows; views saved before chips existed have none. */
|
|
296
|
+
export declare const chipsOf: (c: CustomViewConfig) => ViewChip[];
|
|
297
|
+
/** Whether views over the domain may add formula columns: every domain but one that opts out. */
|
|
298
|
+
export declare const takesFormulas: (domain: {
|
|
299
|
+
formulas?: false;
|
|
300
|
+
}) => boolean;
|
|
301
|
+
/** A view's formula columns; views saved before formulas existed have none. */
|
|
302
|
+
export declare const formulasOf: (c: CustomViewConfig) => {
|
|
303
|
+
key: string;
|
|
304
|
+
label: string;
|
|
305
|
+
expr: string;
|
|
306
|
+
format: "number" | "text" | "weight" | "compact" | "rounded" | "price" | "price_rounded" | "price_signed" | "percent" | "signed" | "integer";
|
|
307
|
+
agg: "none" | "max" | "min" | "first" | "last" | "sum" | "count" | "mean" | "distinct" | null;
|
|
308
|
+
}[];
|
|
309
|
+
/** Fields listed under Columns but not shown, for their Filter and Group ticks; views saved before it have none. */
|
|
310
|
+
export declare const hiddenOf: (c: CustomViewConfig) => string[];
|
|
311
|
+
/** A view's own tiles; views saved before tiles existed have none. */
|
|
312
|
+
export declare const tilesOf: (c: CustomViewConfig) => ({
|
|
313
|
+
key: string;
|
|
314
|
+
label: string;
|
|
315
|
+
field: string;
|
|
316
|
+
agg: "max" | "min" | "first" | "last" | "sum" | "count" | "mean" | "distinct";
|
|
317
|
+
filter: {
|
|
318
|
+
key: string;
|
|
319
|
+
value: string;
|
|
320
|
+
not?: boolean | undefined;
|
|
321
|
+
op?: "gt" | "lt" | "eq" | "between" | undefined;
|
|
322
|
+
link?: "blue" | "lime" | "pink" | "teal" | "amber" | undefined;
|
|
323
|
+
}[];
|
|
324
|
+
sign: boolean;
|
|
325
|
+
suffix: string;
|
|
326
|
+
lines: ({
|
|
327
|
+
kind: "value";
|
|
328
|
+
field: string;
|
|
329
|
+
agg: "max" | "min" | "first" | "last" | "sum" | "count" | "mean" | "distinct";
|
|
330
|
+
filter: {
|
|
331
|
+
key: string;
|
|
332
|
+
value: string;
|
|
333
|
+
not?: boolean | undefined;
|
|
334
|
+
op?: "gt" | "lt" | "eq" | "between" | undefined;
|
|
335
|
+
link?: "blue" | "lime" | "pink" | "teal" | "amber" | undefined;
|
|
336
|
+
}[];
|
|
337
|
+
suffix: string;
|
|
338
|
+
} | {
|
|
339
|
+
kind: "pct";
|
|
340
|
+
field: string;
|
|
341
|
+
agg: "max" | "min" | "first" | "last" | "sum" | "count" | "mean" | "distinct";
|
|
342
|
+
} | {
|
|
343
|
+
kind: "text";
|
|
344
|
+
text: string;
|
|
345
|
+
})[];
|
|
346
|
+
} | {
|
|
347
|
+
key: string;
|
|
348
|
+
})[];
|
|
349
|
+
/**
|
|
350
|
+
* The fields a view shows: the domain's plus its formula columns (where the domain takes formulas),
|
|
351
|
+
* each number field in the format the view picked for it (`formats`).
|
|
352
|
+
*/
|
|
353
|
+
export declare function withViewFields<T>(domain: ViewDomain<T>, c: CustomViewConfig): ViewDomain<T>;
|
|
354
|
+
/** Whether group and Total rows show a value for the field. */
|
|
355
|
+
export declare const rollsUp: <T>(f: ViewField<T>) => boolean;
|
|
356
|
+
/** A number field's Total pick as Edit view shows it: the view's, else the field's own. */
|
|
357
|
+
export declare function totalAggOf<T>(f: ViewField<T>): ViewTotalAgg | 'own';
|
|
358
|
+
export declare const pick: <T>(fields: ViewField<T>[], keys: string[]) => ViewField<T>[];
|
|
359
|
+
/** A field the filter box can offer: one marked filterable, or any number field. */
|
|
360
|
+
export declare const canFilter: <T>(f: ViewField<T>) => boolean;
|
|
361
|
+
/** The fields a view's filter box offers: the ones it lists, else every field marked filterable. */
|
|
362
|
+
export declare const filterFieldsOf: <T>(fields: ViewField<T>[], keys: string[]) => ViewField<T>[];
|
|
363
|
+
/** A view's filters with `tokens` as the ones it opens with, offering every field they use. */
|
|
364
|
+
export declare function withSavedFilters<T>(fields: ViewField<T>[], filters: CustomViewConfig['filters'], tokens: CustomViewConfig['filters']['default']): CustomViewConfig['filters'];
|
|
365
|
+
export declare const label: (v: ViewCellValue) => string;
|
|
366
|
+
/**
|
|
367
|
+
* Values over the shown rows: plain fields as read, share fields and formula columns worked out
|
|
368
|
+
* against the row's group (every shown row when not grouped) and every shown row.
|
|
369
|
+
*/
|
|
370
|
+
export declare function computedOf<T>(domain: ViewDomain<T>, rows: T[], groupBy: ViewField<T> | null): {
|
|
371
|
+
value: (f: ViewField<T>, r: T) => ViewCellValue;
|
|
372
|
+
roll: (f: ViewField<T>, rs: T[]) => ViewCellValue;
|
|
373
|
+
};
|
|
374
|
+
/**
|
|
375
|
+
* Each formula column that is blank on some of the rows, and why (a blank
|
|
376
|
+
* column said nothing): `blank on 24 of 24 rows: dew_point_f is empty`. The editor shows it under
|
|
377
|
+
* the formula, and the assistant reads it after each card move.
|
|
378
|
+
*/
|
|
379
|
+
export declare function formulaBlanks<T>(domain: ViewDomain<T>, rows: T[]): Map<string, string>;
|
|
380
|
+
export declare const num: (v: ViewCellValue) => number;
|
|
381
|
+
/** A field's group id: its own, else the domain's first group ('' when the domain has none). */
|
|
382
|
+
export declare const groupOf: <T>(domain: ViewDomain<T>, f: ViewField<T>) => string;
|
|
383
|
+
/**
|
|
384
|
+
* A field's name in formulas: the one it was made with (a join's
|
|
385
|
+
* `symbol.price`, a frame's `frame.<frame>.<column>`, a linked domain's `tax_lots.count`), a
|
|
386
|
+
* formula's bare key, else `<domain>.<key>` for the domain's own.
|
|
387
|
+
*/
|
|
388
|
+
export declare const fieldName: <T>(domain: ViewDomain<T>, f: ViewField<T>) => string;
|
|
389
|
+
/** Each field by its name in formulas. */
|
|
390
|
+
export declare const nameIndex: <T>(domain: ViewDomain<T>) => Map<string, ViewField<T>>;
|