@iann29/rastro 0.9.0 → 0.10.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/README.md +9 -1
- package/agent/integration.md +23 -1
- package/agent/manifest.json +4 -4
- package/dist/client/federation.d.ts +114 -9
- package/dist/client/federation.d.ts.map +1 -1
- package/dist/client/federation.js +54 -2
- package/dist/client/federation.js.map +1 -1
- package/dist/client/index.d.ts +642 -8
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +391 -9
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +14 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +278 -1
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/server.d.ts +4 -0
- package/dist/component/_generated/server.d.ts.map +1 -1
- package/dist/component/_generated/server.js.map +1 -1
- package/dist/component/constants.d.ts +5 -0
- package/dist/component/constants.d.ts.map +1 -1
- package/dist/component/constants.js +10 -0
- package/dist/component/constants.js.map +1 -1
- package/dist/component/convex.config.d.ts +4 -0
- package/dist/component/convex.config.js +9 -0
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/errors.d.ts +1 -1
- package/dist/component/errors.d.ts.map +1 -1
- package/dist/component/errors.js.map +1 -1
- package/dist/component/leads.d.ts +69 -3
- package/dist/component/leads.d.ts.map +1 -1
- package/dist/component/leads.js +419 -16
- package/dist/component/leads.js.map +1 -1
- package/dist/component/meta.d.ts +358 -0
- package/dist/component/meta.d.ts.map +1 -0
- package/dist/component/meta.js +1295 -0
- package/dist/component/meta.js.map +1 -0
- package/dist/component/metaCapi.d.ts +162 -0
- package/dist/component/metaCapi.d.ts.map +1 -0
- package/dist/component/metaCapi.js +754 -0
- package/dist/component/metaCapi.js.map +1 -0
- package/dist/component/metaFake.d.ts +5 -0
- package/dist/component/metaFake.d.ts.map +1 -0
- package/dist/component/metaFake.js +225 -0
- package/dist/component/metaFake.js.map +1 -0
- package/dist/component/metaGraph.d.ts +165 -0
- package/dist/component/metaGraph.d.ts.map +1 -0
- package/dist/component/metaGraph.js +507 -0
- package/dist/component/metaGraph.js.map +1 -0
- package/dist/component/metaSync.d.ts +186 -0
- package/dist/component/metaSync.d.ts.map +1 -0
- package/dist/component/metaSync.js +961 -0
- package/dist/component/metaSync.js.map +1 -0
- package/dist/component/pipeline.d.ts +99 -0
- package/dist/component/pipeline.d.ts.map +1 -0
- package/dist/component/pipeline.js +337 -0
- package/dist/component/pipeline.js.map +1 -0
- package/dist/component/schema.d.ts +404 -2
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +168 -2
- package/dist/component/schema.js.map +1 -1
- package/dist/component/secrets.d.ts +15 -0
- package/dist/component/secrets.d.ts.map +1 -0
- package/dist/component/secrets.js +67 -0
- package/dist/component/secrets.js.map +1 -0
- package/dist/component/validators.d.ts +1052 -15
- package/dist/component/validators.d.ts.map +1 -1
- package/dist/component/validators.js +307 -3
- package/dist/component/validators.js.map +1 -1
- package/dist/tracker/generated.d.ts +1 -1
- package/dist/tracker/generated.d.ts.map +1 -1
- package/dist/tracker/generated.js +1 -1
- package/dist/tracker/generated.js.map +1 -1
- package/dist/ui/campaigns/CampaignsView.d.ts +48 -0
- package/dist/ui/campaigns/CampaignsView.d.ts.map +1 -0
- package/dist/ui/campaigns/CampaignsView.js +47 -0
- package/dist/ui/campaigns/CampaignsView.js.map +1 -0
- package/dist/ui/campaigns/Conversions.d.ts +16 -0
- package/dist/ui/campaigns/Conversions.d.ts.map +1 -0
- package/dist/ui/campaigns/Conversions.js +40 -0
- package/dist/ui/campaigns/Conversions.js.map +1 -0
- package/dist/ui/campaigns/Drawer.d.ts +24 -0
- package/dist/ui/campaigns/Drawer.d.ts.map +1 -0
- package/dist/ui/campaigns/Drawer.js +120 -0
- package/dist/ui/campaigns/Drawer.js.map +1 -0
- package/dist/ui/campaigns/Icons.d.ts +35 -0
- package/dist/ui/campaigns/Icons.d.ts.map +1 -0
- package/dist/ui/campaigns/Icons.js +41 -0
- package/dist/ui/campaigns/Icons.js.map +1 -0
- package/dist/ui/campaigns/Summary.d.ts +21 -0
- package/dist/ui/campaigns/Summary.d.ts.map +1 -0
- package/dist/ui/campaigns/Summary.js +56 -0
- package/dist/ui/campaigns/Summary.js.map +1 -0
- package/dist/ui/campaigns/Thumbnail.d.ts +11 -0
- package/dist/ui/campaigns/Thumbnail.d.ts.map +1 -0
- package/dist/ui/campaigns/Thumbnail.js +23 -0
- package/dist/ui/campaigns/Thumbnail.js.map +1 -0
- package/dist/ui/campaigns/Tree.d.ts +12 -0
- package/dist/ui/campaigns/Tree.d.ts.map +1 -0
- package/dist/ui/campaigns/Tree.js +105 -0
- package/dist/ui/campaigns/Tree.js.map +1 -0
- package/dist/ui/campaigns/glyphs.d.ts +20 -0
- package/dist/ui/campaigns/glyphs.d.ts.map +1 -0
- package/dist/ui/campaigns/glyphs.js +19 -0
- package/dist/ui/campaigns/glyphs.js.map +1 -0
- package/dist/ui/campaigns/index.d.ts +4 -0
- package/dist/ui/campaigns/index.d.ts.map +1 -0
- package/dist/ui/campaigns/index.js +3 -0
- package/dist/ui/campaigns/index.js.map +1 -0
- package/dist/ui/campaigns/labels.d.ts +53 -0
- package/dist/ui/campaigns/labels.d.ts.map +1 -0
- package/dist/ui/campaigns/labels.js +169 -0
- package/dist/ui/campaigns/labels.js.map +1 -0
- package/dist/ui/campaigns/model.d.ts +99 -0
- package/dist/ui/campaigns/model.d.ts.map +1 -0
- package/dist/ui/campaigns/model.js +230 -0
- package/dist/ui/campaigns/model.js.map +1 -0
- package/dist/ui/campaigns/modes.d.ts +18 -0
- package/dist/ui/campaigns/modes.d.ts.map +1 -0
- package/dist/ui/campaigns/modes.js +7 -0
- package/dist/ui/campaigns/modes.js.map +1 -0
- package/dist/ui/index.d.ts +21 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +20 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/integrations/AccountPicker.d.ts +26 -0
- package/dist/ui/integrations/AccountPicker.d.ts.map +1 -0
- package/dist/ui/integrations/AccountPicker.js +101 -0
- package/dist/ui/integrations/AccountPicker.js.map +1 -0
- package/dist/ui/integrations/ClientCards.d.ts +17 -0
- package/dist/ui/integrations/ClientCards.d.ts.map +1 -0
- package/dist/ui/integrations/ClientCards.js +42 -0
- package/dist/ui/integrations/ClientCards.js.map +1 -0
- package/dist/ui/integrations/ClientsTable.d.ts +36 -0
- package/dist/ui/integrations/ClientsTable.d.ts.map +1 -0
- package/dist/ui/integrations/ClientsTable.js +143 -0
- package/dist/ui/integrations/ClientsTable.js.map +1 -0
- package/dist/ui/integrations/Connect.d.ts +35 -0
- package/dist/ui/integrations/Connect.d.ts.map +1 -0
- package/dist/ui/integrations/Connect.js +62 -0
- package/dist/ui/integrations/Connect.js.map +1 -0
- package/dist/ui/integrations/Connection.d.ts +37 -0
- package/dist/ui/integrations/Connection.d.ts.map +1 -0
- package/dist/ui/integrations/Connection.js +108 -0
- package/dist/ui/integrations/Connection.js.map +1 -0
- package/dist/ui/integrations/Dialogs.d.ts +21 -0
- package/dist/ui/integrations/Dialogs.d.ts.map +1 -0
- package/dist/ui/integrations/Dialogs.js +34 -0
- package/dist/ui/integrations/Dialogs.js.map +1 -0
- package/dist/ui/integrations/EventsFeed.d.ts +15 -0
- package/dist/ui/integrations/EventsFeed.d.ts.map +1 -0
- package/dist/ui/integrations/EventsFeed.js +61 -0
- package/dist/ui/integrations/EventsFeed.js.map +1 -0
- package/dist/ui/integrations/EventsSheet.d.ts +34 -0
- package/dist/ui/integrations/EventsSheet.d.ts.map +1 -0
- package/dist/ui/integrations/EventsSheet.js +136 -0
- package/dist/ui/integrations/EventsSheet.js.map +1 -0
- package/dist/ui/integrations/Icons.d.ts +38 -0
- package/dist/ui/integrations/Icons.d.ts.map +1 -0
- package/dist/ui/integrations/Icons.js +40 -0
- package/dist/ui/integrations/Icons.js.map +1 -0
- package/dist/ui/integrations/IntegrationsView.d.ts +15 -0
- package/dist/ui/integrations/IntegrationsView.d.ts.map +1 -0
- package/dist/ui/integrations/IntegrationsView.js +141 -0
- package/dist/ui/integrations/IntegrationsView.js.map +1 -0
- package/dist/ui/integrations/Overlay.d.ts +18 -0
- package/dist/ui/integrations/Overlay.d.ts.map +1 -0
- package/dist/ui/integrations/Overlay.js +36 -0
- package/dist/ui/integrations/Overlay.js.map +1 -0
- package/dist/ui/integrations/Partner.d.ts +14 -0
- package/dist/ui/integrations/Partner.d.ts.map +1 -0
- package/dist/ui/integrations/Partner.js +38 -0
- package/dist/ui/integrations/Partner.js.map +1 -0
- package/dist/ui/integrations/RowMenu.d.ts +15 -0
- package/dist/ui/integrations/RowMenu.d.ts.map +1 -0
- package/dist/ui/integrations/RowMenu.js +47 -0
- package/dist/ui/integrations/RowMenu.js.map +1 -0
- package/dist/ui/integrations/UnlinkDialog.d.ts +18 -0
- package/dist/ui/integrations/UnlinkDialog.d.ts.map +1 -0
- package/dist/ui/integrations/UnlinkDialog.js +29 -0
- package/dist/ui/integrations/UnlinkDialog.js.map +1 -0
- package/dist/ui/integrations/audience.d.ts +12 -0
- package/dist/ui/integrations/audience.d.ts.map +1 -0
- package/dist/ui/integrations/audience.js +12 -0
- package/dist/ui/integrations/audience.js.map +1 -0
- package/dist/ui/integrations/format.d.ts +28 -0
- package/dist/ui/integrations/format.d.ts.map +1 -0
- package/dist/ui/integrations/format.js +101 -0
- package/dist/ui/integrations/format.js.map +1 -0
- package/dist/ui/integrations/index.d.ts +5 -0
- package/dist/ui/integrations/index.d.ts.map +1 -0
- package/dist/ui/integrations/index.js +3 -0
- package/dist/ui/integrations/index.js.map +1 -0
- package/dist/ui/integrations/modal.d.ts +10 -0
- package/dist/ui/integrations/modal.d.ts.map +1 -0
- package/dist/ui/integrations/modal.js +77 -0
- package/dist/ui/integrations/modal.js.map +1 -0
- package/dist/ui/integrations/model.d.ts +99 -0
- package/dist/ui/integrations/model.d.ts.map +1 -0
- package/dist/ui/integrations/model.js +164 -0
- package/dist/ui/integrations/model.js.map +1 -0
- package/dist/ui/integrations/parts.d.ts +36 -0
- package/dist/ui/integrations/parts.d.ts.map +1 -0
- package/dist/ui/integrations/parts.js +85 -0
- package/dist/ui/integrations/parts.js.map +1 -0
- package/dist/ui/integrations/types.d.ts +146 -0
- package/dist/ui/integrations/types.d.ts.map +1 -0
- package/dist/ui/integrations/types.js +2 -0
- package/dist/ui/integrations/types.js.map +1 -0
- package/dist/ui/metrics.d.ts +106 -0
- package/dist/ui/metrics.d.ts.map +1 -0
- package/dist/ui/metrics.js +166 -0
- package/dist/ui/metrics.js.map +1 -0
- package/dist/ui/portfolio/PortfolioView.d.ts +26 -0
- package/dist/ui/portfolio/PortfolioView.d.ts.map +1 -0
- package/dist/ui/portfolio/PortfolioView.js +216 -0
- package/dist/ui/portfolio/PortfolioView.js.map +1 -0
- package/dist/ui/portfolio/SpendChart.d.ts +10 -0
- package/dist/ui/portfolio/SpendChart.d.ts.map +1 -0
- package/dist/ui/portfolio/SpendChart.js +196 -0
- package/dist/ui/portfolio/SpendChart.js.map +1 -0
- package/dist/ui/portfolio/alerts.d.ts +74 -0
- package/dist/ui/portfolio/alerts.d.ts.map +1 -0
- package/dist/ui/portfolio/alerts.js +291 -0
- package/dist/ui/portfolio/alerts.js.map +1 -0
- package/dist/ui/portfolio/figures.d.ts +79 -0
- package/dist/ui/portfolio/figures.d.ts.map +1 -0
- package/dist/ui/portfolio/figures.js +103 -0
- package/dist/ui/portfolio/figures.js.map +1 -0
- package/dist/ui/portfolio/format.d.ts +8 -0
- package/dist/ui/portfolio/format.d.ts.map +1 -0
- package/dist/ui/portfolio/format.js +28 -0
- package/dist/ui/portfolio/format.js.map +1 -0
- package/dist/ui/sample.d.ts +536 -0
- package/dist/ui/sample.d.ts.map +1 -0
- package/dist/ui/sample.js +574 -0
- package/dist/ui/sample.js.map +1 -0
- package/dist/ui/seed.d.ts +188 -0
- package/dist/ui/seed.d.ts.map +1 -0
- package/dist/ui/seed.js +563 -0
- package/dist/ui/seed.js.map +1 -0
- package/dist/ui/ui.css +3424 -0
- package/docs/federation.md +46 -1
- package/docs/meta-ads.md +795 -0
- package/docs/upgrading.md +116 -0
- package/llms.txt +3 -0
- package/package.json +15 -3
- package/src/component/_generated/api.ts +14 -0
- package/src/component/_generated/component.ts +324 -1
- package/src/component/_generated/server.ts +4 -0
- package/src/component/constants.ts +10 -0
- package/src/component/convex.config.ts +9 -0
- package/src/component/errors.ts +5 -1
- package/src/component/leads.ts +517 -17
- package/src/component/meta.ts +1525 -0
- package/src/component/metaCapi.ts +921 -0
- package/src/component/metaFake.ts +277 -0
- package/src/component/metaGraph.ts +722 -0
- package/src/component/metaSync.ts +1164 -0
- package/src/component/pipeline.ts +410 -0
- package/src/component/schema.ts +197 -1
- package/src/component/secrets.ts +98 -0
- package/src/component/validators.ts +376 -3
- package/src/tracker/generated.ts +1 -1
- package/src/ui/seed.ts +755 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agency view's numbers, derived once from a multi-site report: one row
|
|
3
|
+
* per client from `bySite[].paid` (what the ads bought) and its spend, the
|
|
4
|
+
* portfolio's paid funnel over the clients whose spend is known (what the
|
|
5
|
+
* totals, costs, return and averages use), and each client's ads and
|
|
6
|
+
* campaigns found through the ad rows' `siteId`.
|
|
7
|
+
*/
|
|
8
|
+
import type { LeadsReport, MetaStatus } from "../../client/index.js";
|
|
9
|
+
import { type PaidFunnel, type RowMetrics } from "../metrics.js";
|
|
10
|
+
export interface PortfolioSite {
|
|
11
|
+
siteId: string;
|
|
12
|
+
name: string;
|
|
13
|
+
segment?: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface ClientAd {
|
|
16
|
+
adId: string;
|
|
17
|
+
name: string;
|
|
18
|
+
campaignName: string | null;
|
|
19
|
+
won: number;
|
|
20
|
+
revenueCents: number;
|
|
21
|
+
spendCents: number | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ClientCampaign {
|
|
24
|
+
name: string;
|
|
25
|
+
won: number;
|
|
26
|
+
}
|
|
27
|
+
export interface ClientFigures {
|
|
28
|
+
site: PortfolioSite;
|
|
29
|
+
leads: number;
|
|
30
|
+
qualified: number;
|
|
31
|
+
won: number;
|
|
32
|
+
revenueCents: number;
|
|
33
|
+
/** Null when no linked ad account covers the client. */
|
|
34
|
+
spendCents: number | null;
|
|
35
|
+
/** The currency the client's ad account bills in. */
|
|
36
|
+
spendCurrency: string;
|
|
37
|
+
/** The account bills in another currency than the client sells in. */
|
|
38
|
+
currencyMismatch: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Cost per lead/sale in `spendCurrency`; the return is null when the
|
|
41
|
+
* account bills in another currency than the revenue.
|
|
42
|
+
*/
|
|
43
|
+
metrics: RowMetrics;
|
|
44
|
+
/** Average sale value (revenue ÷ sales), in cents. */
|
|
45
|
+
ticketCents: number | null;
|
|
46
|
+
ads: ClientAd[];
|
|
47
|
+
campaigns: ClientCampaign[];
|
|
48
|
+
/** The client's linked ad accounts, from `meta.status`. */
|
|
49
|
+
accounts: MetaStatus[number]["adAccounts"];
|
|
50
|
+
}
|
|
51
|
+
export interface PortfolioFigures {
|
|
52
|
+
clients: ClientFigures[];
|
|
53
|
+
paid: PaidFunnel;
|
|
54
|
+
/** Costs and return of `paid`; null where currencies make them meaningless. */
|
|
55
|
+
metrics: RowMetrics;
|
|
56
|
+
/** Average sale over every client's paid sales, in `currency`. */
|
|
57
|
+
ticketCents: number | null;
|
|
58
|
+
/** Revenue currency (the sites'). */
|
|
59
|
+
currency: string;
|
|
60
|
+
/** The one currency the accounts bill in, or null when they differ. */
|
|
61
|
+
spendCurrency: string | null;
|
|
62
|
+
/** Some account bills in another currency than the revenue. */
|
|
63
|
+
currencyMismatch: boolean;
|
|
64
|
+
/** The ad tree has no spend (too many rows); the per-client spend holds. */
|
|
65
|
+
spendIncomplete: boolean;
|
|
66
|
+
}
|
|
67
|
+
export declare function portfolioFigures({ sites, report, status, }: {
|
|
68
|
+
sites: readonly PortfolioSite[];
|
|
69
|
+
report: LeadsReport;
|
|
70
|
+
status?: MetaStatus | undefined;
|
|
71
|
+
}): PortfolioFigures;
|
|
72
|
+
/**
|
|
73
|
+
* Why a client's spend is or is not in the totals: counted, still on the
|
|
74
|
+
* first Meta sync (a linked account, no spend yet), not connected, or billed
|
|
75
|
+
* in another currency than the one the totals sum.
|
|
76
|
+
*/
|
|
77
|
+
export type SpendState = "counted" | "syncing" | "notConnected" | "otherCurrency";
|
|
78
|
+
export declare function spendState(client: ClientFigures, portfolio: Pick<PortfolioFigures, "paid">): SpendState;
|
|
79
|
+
//# sourceMappingURL=figures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figures.d.ts","sourceRoot":"","sources":["../../../src/ui/portfolio/figures.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAKD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,OAAO,EAAE,UAAU,CAAC;IACpB,sDAAsD;IACtD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,QAAQ,EAAE,CAAC;IAChB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,+EAA+E;IAC/E,OAAO,EAAE,UAAU,CAAC;IACpB,kEAAkE;IAClE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;CAC1B;AA0CD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE;IACD,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC,GAAG,gBAAgB,CAkEnB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GACpB,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,eAAe,CAAC;AAE3D,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GACxC,UAAU,CAOZ"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { paidFunnel, rowMetrics, } from "../metrics.js";
|
|
2
|
+
const perSale = (revenueCents, won) => won > 0 ? Math.round(revenueCents / won) : null;
|
|
3
|
+
/** Spend-based figures; the return is dropped when currencies differ. */
|
|
4
|
+
function metricsOf(row, sameCurrency) {
|
|
5
|
+
const metrics = rowMetrics(row);
|
|
6
|
+
return sameCurrency ? metrics : { ...metrics, returnOnSpend: null };
|
|
7
|
+
}
|
|
8
|
+
function adsBySite(campaigns) {
|
|
9
|
+
const ads = new Map();
|
|
10
|
+
const byCampaign = new Map();
|
|
11
|
+
for (const campaign of campaigns) {
|
|
12
|
+
for (const adset of campaign.adsets) {
|
|
13
|
+
for (const ad of adset.ads) {
|
|
14
|
+
if (!ad.siteId)
|
|
15
|
+
continue;
|
|
16
|
+
const list = ads.get(ad.siteId) ?? [];
|
|
17
|
+
list.push({
|
|
18
|
+
adId: ad.adId,
|
|
19
|
+
name: ad.adName ?? ad.title ?? ad.adId,
|
|
20
|
+
campaignName: campaign.campaignName,
|
|
21
|
+
won: ad.won,
|
|
22
|
+
revenueCents: ad.revenueCents,
|
|
23
|
+
spendCents: ad.spendCents ?? null,
|
|
24
|
+
});
|
|
25
|
+
ads.set(ad.siteId, list);
|
|
26
|
+
if (campaign.campaignName) {
|
|
27
|
+
const sold = byCampaign.get(ad.siteId) ?? new Map();
|
|
28
|
+
sold.set(campaign.campaignName, (sold.get(campaign.campaignName) ?? 0) + ad.won);
|
|
29
|
+
byCampaign.set(ad.siteId, sold);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { ads, byCampaign };
|
|
35
|
+
}
|
|
36
|
+
export function portfolioFigures({ sites, report, status, }) {
|
|
37
|
+
const currency = report.currency ?? "BRL";
|
|
38
|
+
const accountsBySite = new Map((status ?? []).map((site) => [site.siteId, site.adAccounts]));
|
|
39
|
+
// Read as `SitePaidRow`: hosts from 0.10 say each site's spend currency.
|
|
40
|
+
const rows = new Map((report.bySite ?? []).map((row) => [
|
|
41
|
+
row.siteId,
|
|
42
|
+
row,
|
|
43
|
+
]));
|
|
44
|
+
const { ads, byCampaign } = adsBySite(report.campaigns);
|
|
45
|
+
const clients = [];
|
|
46
|
+
const siteRows = [];
|
|
47
|
+
for (const site of sites) {
|
|
48
|
+
const row = rows.get(site.siteId);
|
|
49
|
+
if (!row)
|
|
50
|
+
continue;
|
|
51
|
+
const spendCents = row.spendCents ?? null;
|
|
52
|
+
const spendCurrency = row.spendCurrency ?? report.spendCurrency ?? currency;
|
|
53
|
+
const currencyMismatch = row.currencyMismatch ?? spendCurrency !== currency;
|
|
54
|
+
siteRows.push({ ...row, spendCurrency, currencyMismatch });
|
|
55
|
+
clients.push({
|
|
56
|
+
site,
|
|
57
|
+
...row.paid,
|
|
58
|
+
spendCents,
|
|
59
|
+
spendCurrency,
|
|
60
|
+
currencyMismatch,
|
|
61
|
+
metrics: metricsOf({ ...row.paid, spendCents }, !currencyMismatch),
|
|
62
|
+
ticketCents: perSale(row.paid.revenueCents, row.paid.won),
|
|
63
|
+
ads: (ads.get(site.siteId) ?? []).sort((a, b) => b.won - a.won),
|
|
64
|
+
campaigns: [...(byCampaign.get(site.siteId) ?? new Map())]
|
|
65
|
+
.map(([name, won]) => ({ name, won }))
|
|
66
|
+
.sort((a, b) => b.won - a.won),
|
|
67
|
+
accounts: accountsBySite.get(site.siteId) ?? [],
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const paid = paidFunnel({ ...report, bySite: siteRows });
|
|
71
|
+
const spent = clients.filter((client) => client.spendCents !== null);
|
|
72
|
+
// Spend in several currencies does not add up: no total, no cost, no return.
|
|
73
|
+
const mixed = new Set(spent.map((client) => client.spendCurrency)).size > 1 &&
|
|
74
|
+
paid.row.spendCents === null;
|
|
75
|
+
const spendCurrency = mixed
|
|
76
|
+
? null
|
|
77
|
+
: (paid.spendCurrency ?? report.spendCurrency ?? currency);
|
|
78
|
+
const allPaid = clients.reduce((sum, client) => ({
|
|
79
|
+
won: sum.won + client.won,
|
|
80
|
+
revenueCents: sum.revenueCents + client.revenueCents,
|
|
81
|
+
}), { won: 0, revenueCents: 0 });
|
|
82
|
+
return {
|
|
83
|
+
clients,
|
|
84
|
+
paid,
|
|
85
|
+
metrics: metricsOf(paid.row, !mixed && !paid.currencyMismatch),
|
|
86
|
+
ticketCents: perSale(allPaid.revenueCents, allPaid.won),
|
|
87
|
+
currency,
|
|
88
|
+
spendCurrency,
|
|
89
|
+
currencyMismatch: mixed ||
|
|
90
|
+
paid.currencyMismatch ||
|
|
91
|
+
spent.some((client) => client.currencyMismatch),
|
|
92
|
+
spendIncomplete: report.spendIncomplete === true,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export function spendState(client, portfolio) {
|
|
96
|
+
if (client.spendCents === null) {
|
|
97
|
+
return client.accounts.length > 0 ? "syncing" : "notConnected";
|
|
98
|
+
}
|
|
99
|
+
return portfolio.paid.sitesWithoutSpend.includes(client.site.siteId)
|
|
100
|
+
? "otherCurrency"
|
|
101
|
+
: "counted";
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=figures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figures.js","sourceRoot":"","sources":["../../../src/ui/portfolio/figures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Formatting only the agency view needs, on top of `../metrics.ts`. */
|
|
2
|
+
/** "R$ 13 mil", "R$ 2,5 mil": round money for tickets and chart axes. */
|
|
3
|
+
export declare function compactMoney(cents: number, currency?: string, locale?: string): string;
|
|
4
|
+
/** "Clínica Sorriso" → "CS", "Loja X" → "LX". */
|
|
5
|
+
export declare function initials(name: string): string;
|
|
6
|
+
/** A stable 0–5 hue slot per client, so its avatar keeps its color. */
|
|
7
|
+
export declare function hueSlot(key: string): number;
|
|
8
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/ui/portfolio/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,yEAAyE;AACzE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,SAAQ,EAChB,MAAM,SAAU,UAUjB;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,UAMpC;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAIlC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Formatting only the agency view needs, on top of `../metrics.ts`. */
|
|
2
|
+
/** "R$ 13 mil", "R$ 2,5 mil": round money for tickets and chart axes. */
|
|
3
|
+
export function compactMoney(cents, currency = "BRL", locale = "pt-BR") {
|
|
4
|
+
return new Intl.NumberFormat(locale, {
|
|
5
|
+
style: "currency",
|
|
6
|
+
currency,
|
|
7
|
+
notation: "compact",
|
|
8
|
+
maximumFractionDigits: 1,
|
|
9
|
+
})
|
|
10
|
+
.format(cents / 100)
|
|
11
|
+
.replace(/[\u00a0\u202f]/g, " ");
|
|
12
|
+
}
|
|
13
|
+
/** "Clínica Sorriso" → "CS", "Loja X" → "LX". */
|
|
14
|
+
export function initials(name) {
|
|
15
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
16
|
+
const letters = (words.length > 1 ? [words[0], words[1]] : [name.trim()])
|
|
17
|
+
.map((word) => (words.length > 1 ? word[0] : word.slice(0, 2)))
|
|
18
|
+
.join("");
|
|
19
|
+
return letters.toLocaleUpperCase("pt-BR");
|
|
20
|
+
}
|
|
21
|
+
/** A stable 0–5 hue slot per client, so its avatar keeps its color. */
|
|
22
|
+
export function hueSlot(key) {
|
|
23
|
+
let hash = 0;
|
|
24
|
+
for (const char of key)
|
|
25
|
+
hash = (hash * 31 + char.charCodeAt(0)) >>> 0;
|
|
26
|
+
return hash % 6;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/ui/portfolio/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,yEAAyE;AACzE,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,OAAO;IAEhB,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;QACnC,KAAK,EAAE,UAAU;QACjB,QAAQ;QACR,QAAQ,EAAE,SAAS;QACnB,qBAAqB,EAAE,CAAC;KACzB,CAAC;SACC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC;SACnB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;SACtE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SAChE,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,GAAG;QAAE,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,OAAO,IAAI,GAAG,CAAC,CAAC;AAClB,CAAC"}
|