@base316/react 0.1.0 → 0.2.0
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/CHANGELOG.md +35 -0
- package/README.md +15 -15
- package/dist/index.cjs +4150 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4136 -165
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1161 -0
- package/dist/src/AcceptInvitation.d.ts +27 -0
- package/dist/src/AcceptInvitation.d.ts.map +1 -0
- package/dist/src/ActiveSessions.d.ts +21 -0
- package/dist/src/ActiveSessions.d.ts.map +1 -0
- package/dist/src/ApiKeyManager.d.ts +22 -0
- package/dist/src/ApiKeyManager.d.ts.map +1 -0
- package/dist/src/Chart.d.ts +42 -0
- package/dist/src/Chart.d.ts.map +1 -0
- package/dist/src/DataTable.d.ts +56 -0
- package/dist/src/DataTable.d.ts.map +1 -0
- package/dist/src/DeviceApproval.d.ts +30 -0
- package/dist/src/DeviceApproval.d.ts.map +1 -0
- package/dist/src/ForgotPassword.d.ts +24 -0
- package/dist/src/ForgotPassword.d.ts.map +1 -0
- package/dist/src/Invoices.d.ts.map +1 -1
- package/dist/src/Kanban.d.ts +40 -0
- package/dist/src/Kanban.d.ts.map +1 -0
- package/dist/src/PasskeyManager.d.ts.map +1 -1
- package/dist/src/PayInvoice.d.ts +41 -0
- package/dist/src/PayInvoice.d.ts.map +1 -0
- package/dist/src/PricingTable.d.ts +43 -11
- package/dist/src/PricingTable.d.ts.map +1 -1
- package/dist/src/PrivacyControls.d.ts +28 -0
- package/dist/src/PrivacyControls.d.ts.map +1 -0
- package/dist/src/RecordDetail.d.ts +31 -0
- package/dist/src/RecordDetail.d.ts.map +1 -0
- package/dist/src/RecordForm.d.ts +32 -0
- package/dist/src/RecordForm.d.ts.map +1 -0
- package/dist/src/RelationPicker.d.ts +23 -0
- package/dist/src/RelationPicker.d.ts.map +1 -0
- package/dist/src/ResetPassword.d.ts +24 -0
- package/dist/src/ResetPassword.d.ts.map +1 -0
- package/dist/src/SignIn.d.ts +11 -1
- package/dist/src/SignIn.d.ts.map +1 -1
- package/dist/src/SignUp.d.ts.map +1 -1
- package/dist/src/SubscriptionManager.d.ts.map +1 -1
- package/dist/src/TeamMembers.d.ts +49 -0
- package/dist/src/TeamMembers.d.ts.map +1 -0
- package/dist/src/TwoFactorManager.d.ts +29 -0
- package/dist/src/TwoFactorManager.d.ts.map +1 -0
- package/dist/src/VerifyEmail.d.ts +24 -0
- package/dist/src/VerifyEmail.d.ts.map +1 -0
- package/dist/src/appearance.d.ts +2 -2
- package/dist/src/appearance.d.ts.map +1 -1
- package/dist/src/confirm.d.ts +32 -0
- package/dist/src/confirm.d.ts.map +1 -0
- package/dist/src/fields.d.ts +44 -0
- package/dist/src/fields.d.ts.map +1 -0
- package/dist/src/manifest.d.ts +84 -0
- package/dist/src/manifest.d.ts.map +1 -0
- package/dist/src/test/harness.d.ts +204 -0
- package/dist/src/test/harness.d.ts.map +1 -0
- package/dist/src/test/setup.d.ts +2 -0
- package/dist/src/test/setup.d.ts.map +1 -0
- package/dist/src/useCollection.d.ts +79 -0
- package/dist/src/useCollection.d.ts.map +1 -0
- package/dist/src/usePaymentLink.d.ts +41 -0
- package/dist/src/usePaymentLink.d.ts.map +1 -0
- package/dist/src/usePlans.d.ts +66 -0
- package/dist/src/usePlans.d.ts.map +1 -0
- package/package.json +36 -28
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The other end of an invitation.
|
|
4
|
+
*
|
|
5
|
+
* Reads the token from the URL and says what it is for *before* asking anybody
|
|
6
|
+
* to sign in, because "join Acme as a Member" is a reason to create an account
|
|
7
|
+
* and "accept invitation" is not. That preview is the one call here that needs
|
|
8
|
+
* no session — the person holding the link may have no account at all, which is
|
|
9
|
+
* the entire reason invitations exist.
|
|
10
|
+
*
|
|
11
|
+
* The token is not scrubbed from the URL, unlike a password reset. It is
|
|
12
|
+
* useless to anybody but the address it was sent to, and leaving it in place
|
|
13
|
+
* means the page survives a sign-in round trip that navigates away and back —
|
|
14
|
+
* which is the normal path for somebody who has just created an account.
|
|
15
|
+
*/
|
|
16
|
+
export interface AcceptInvitationProps {
|
|
17
|
+
/** Supply the token directly. Read from `?invitation=` when omitted. */
|
|
18
|
+
token?: string;
|
|
19
|
+
onAccepted?: (organizationId: string) => void;
|
|
20
|
+
/** Where to send somebody who needs an account first. */
|
|
21
|
+
signUpUrl?: string;
|
|
22
|
+
signInUrl?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
style?: CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
export declare function AcceptInvitation({ token: supplied, onAccepted, signUpUrl, signInUrl, className, style, }: AcceptInvitationProps): import("react").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=AcceptInvitation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AcceptInvitation.d.ts","sourceRoot":"","sources":["../../src/AcceptInvitation.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKhE;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,qBAAqB;IACrC,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,EAChC,KAAK,EAAE,QAAQ,EACf,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE,qBAAqB,+BA0IvB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Where this account is signed in, and a way to end the rest.
|
|
4
|
+
*
|
|
5
|
+
* The panel somebody opens when they think they have been compromised, which
|
|
6
|
+
* is why the copy is plain and the button does not hedge. It shows where and
|
|
7
|
+
* when rather than anything identifying the session itself: the token digest is
|
|
8
|
+
* the value the database authenticates against and never reaches the browser.
|
|
9
|
+
*
|
|
10
|
+
* Revoking keeps the caller's own session. Signing somebody out of the device
|
|
11
|
+
* they are holding, in response to a button about their *other* devices, would
|
|
12
|
+
* be a surprise at the worst possible moment.
|
|
13
|
+
*/
|
|
14
|
+
export interface ActiveSessionsProps {
|
|
15
|
+
/** Called after other sessions are ended, with how many went. */
|
|
16
|
+
onRevoked?: (count: number) => void;
|
|
17
|
+
className?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
export declare function ActiveSessions({ onRevoked, className, style }: ActiveSessionsProps): import("react").JSX.Element | null;
|
|
21
|
+
//# sourceMappingURL=ActiveSessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActiveSessions.d.ts","sourceRoot":"","sources":["../../src/ActiveSessions.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK7E;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,mBAAmB;IACnC,iEAAiE;IACjE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AA+CD,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,mBAAmB,sCAkGlF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The signed-in user's credentials for this application's API.
|
|
4
|
+
*
|
|
5
|
+
* Drop this on an account or developer-settings page and the account manages
|
|
6
|
+
* its own keys: issue, rotate, revoke. Reads through the session, never a
|
|
7
|
+
* customer id from props — the account is whoever the session says it is, so
|
|
8
|
+
* one user cannot be pointed at another's keys by changing a prop.
|
|
9
|
+
*
|
|
10
|
+
* What it deliberately does *not* offer is changing the rate limit. A caller
|
|
11
|
+
* who can raise their own ceiling does not have one. The limit is shown, and so
|
|
12
|
+
* are the scopes the plan withholds, which is an upgrade prompt arriving at the
|
|
13
|
+
* moment somebody actually wants the capability.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ApiKeyManager({ className, style,
|
|
16
|
+
/** Restrict to one API. Omit to show every one the account can reach. */
|
|
17
|
+
audience, }: {
|
|
18
|
+
className?: string;
|
|
19
|
+
style?: CSSProperties;
|
|
20
|
+
audience?: string;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=ApiKeyManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiKeyManager.d.ts","sourceRoot":"","sources":["../../src/ApiKeyManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAmB7E;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAC7B,SAAS,EACT,KAAK;AACL,yEAAyE;AACzE,QAAQ,GACR,EAAE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,+BAqWA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type AggregateKind } from "@base316/sdk";
|
|
2
|
+
import { type CSSProperties } from "react";
|
|
3
|
+
import { type UseCollectionOptions } from "./useCollection";
|
|
4
|
+
/**
|
|
5
|
+
* A chart, over a collection that was never designed to have one.
|
|
6
|
+
*
|
|
7
|
+
* The second proof, and it asks the schema different questions from the board:
|
|
8
|
+
*
|
|
9
|
+
* fieldsFor(fields, "timeAxis") // "what can be an x-axis?"
|
|
10
|
+
* fieldsAggregatableBy(fields, "sum") // "what can be added up?"
|
|
11
|
+
*
|
|
12
|
+
* Neither question mentions a field type, and this file names none. That is the
|
|
13
|
+
* point: the board found a SELECT, this finds a date and a number, and both did
|
|
14
|
+
* it by describing what they needed rather than by being configured.
|
|
15
|
+
*
|
|
16
|
+
* Drawn as SVG rather than with a charting library. Artifacts and customer
|
|
17
|
+
* pages both restrict which scripts may load, a charting dependency is larger
|
|
18
|
+
* than everything else in this package put together, and bars with a baseline
|
|
19
|
+
* are not the hard part of charting.
|
|
20
|
+
*/
|
|
21
|
+
export interface ChartProps extends UseCollectionOptions {
|
|
22
|
+
collection: string;
|
|
23
|
+
/** The date field along the bottom. Discovered when omitted. */
|
|
24
|
+
x?: string;
|
|
25
|
+
/**
|
|
26
|
+
* What to measure.
|
|
27
|
+
*
|
|
28
|
+
* Omitted means count the records, which is the question that always has an
|
|
29
|
+
* answer: a collection may have no numeric field, but it always has rows.
|
|
30
|
+
*/
|
|
31
|
+
y?: string;
|
|
32
|
+
/** How to combine. Ignored when counting. */
|
|
33
|
+
aggregate?: Exclude<AggregateKind, "count">;
|
|
34
|
+
/** How wide a bar is in time. */
|
|
35
|
+
bucket?: "day" | "week" | "month";
|
|
36
|
+
title?: string;
|
|
37
|
+
height?: number;
|
|
38
|
+
className?: string;
|
|
39
|
+
style?: CSSProperties;
|
|
40
|
+
}
|
|
41
|
+
export declare function Chart({ collection, x, y, aggregate, bucket, title, height, className, style, ...options }: ChartProps): import("react").JSX.Element;
|
|
42
|
+
//# sourceMappingURL=Chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../src/Chart.tsx"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,aAAa,EAKlB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAGpD,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE3E;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,6CAA6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC5C,iCAAiC;IACjC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAQD,wBAAgB,KAAK,CAAC,EACrB,UAAU,EACV,CAAC,EACD,CAAC,EACD,SAAiB,EACjB,MAAc,EACd,KAAK,EACL,MAAY,EACZ,SAAS,EACT,KAAK,EACL,GAAG,OAAO,EACV,EAAE,UAAU,+BAiIZ"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type CollectionRecord, type FieldDescriptor } from "@base316/sdk";
|
|
2
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
3
|
+
import { type UseCollectionOptions } from "./useCollection";
|
|
4
|
+
/**
|
|
5
|
+
* A table of data nobody wrote a table for.
|
|
6
|
+
*
|
|
7
|
+
* Drop it in with a collection key and it works: it reads the schema, derives
|
|
8
|
+
* its columns from the field types, sorts on the fields that can be sorted,
|
|
9
|
+
* searches the ones that can be searched, and offers editing only if this
|
|
10
|
+
* viewer may write.
|
|
11
|
+
*
|
|
12
|
+
* <DataTable collection="jobs" />
|
|
13
|
+
*
|
|
14
|
+
* It never names a field type. Every cell goes through the renderer registry,
|
|
15
|
+
* so a type added later works here without this file being touched — which is
|
|
16
|
+
* the same reason a board or a calendar can be built against the same schema.
|
|
17
|
+
*
|
|
18
|
+
* Wants a different table? Call `useCollection()` and write one. You keep the
|
|
19
|
+
* schema loading, the paging, the permission handling and the write errors,
|
|
20
|
+
* and lose only the markup, which is the part worth replacing.
|
|
21
|
+
*/
|
|
22
|
+
export interface DataTableProps extends UseCollectionOptions {
|
|
23
|
+
/** The collection key, as the schema defines it. */
|
|
24
|
+
collection: string;
|
|
25
|
+
/**
|
|
26
|
+
* Which fields to show, in order.
|
|
27
|
+
*
|
|
28
|
+
* Defaults to every field in its declared position. Name them to trim a wide
|
|
29
|
+
* collection down to what this screen is about.
|
|
30
|
+
*/
|
|
31
|
+
columns?: string[];
|
|
32
|
+
/** Replace the cell for one field. Everything else keeps the default. */
|
|
33
|
+
renderCell?: (record: CollectionRecord, field: FieldDescriptor) => ReactNode | undefined;
|
|
34
|
+
/** Row click. Without it, rows are not interactive. */
|
|
35
|
+
onSelect?: (record: CollectionRecord) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Called after this table creates, edits or deletes a record.
|
|
38
|
+
*
|
|
39
|
+
* The table refreshes itself; this is for anything else on the page bound to
|
|
40
|
+
* the same collection. Each component holds its own data and they share no
|
|
41
|
+
* cache, so without this a `<Chart>` beside a table silently lags by every
|
|
42
|
+
* record added through it — which is exactly what an agent building against
|
|
43
|
+
* this hit, with no event to hook.
|
|
44
|
+
*/
|
|
45
|
+
onChanged?: () => void;
|
|
46
|
+
/** Hide the search box even when the collection has searchable fields. */
|
|
47
|
+
hideSearch?: boolean;
|
|
48
|
+
/** Hide New, Edit and Delete even for a viewer who may write. */
|
|
49
|
+
readOnly?: boolean;
|
|
50
|
+
/** Shown when there is nothing to list. */
|
|
51
|
+
emptyState?: ReactNode;
|
|
52
|
+
className?: string;
|
|
53
|
+
style?: CSSProperties;
|
|
54
|
+
}
|
|
55
|
+
export declare function DataTable({ collection, columns, renderCell, onSelect, onChanged, hideSearch, readOnly, emptyState, className, style, ...options }: DataTableProps): import("react").JSX.Element;
|
|
56
|
+
//# sourceMappingURL=DataTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../src/DataTable.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAW,MAAM,cAAc,CAAC;AACpF,OAAO,EAAY,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE3E;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC3D,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,KAAK,SAAS,GAAG,SAAS,CAAC;IACzF,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,EACzB,UAAU,EACV,OAAO,EACP,UAAU,EACV,QAAQ,EACR,SAAS,EACT,UAAU,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,KAAK,EACL,GAAG,OAAO,EACV,EAAE,cAAc,+BA+NhB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Approving a sign-in that started somewhere with no browser.
|
|
4
|
+
*
|
|
5
|
+
* Drop this on a page in your own application — `/device` is the convention —
|
|
6
|
+
* and point your device's verification URI at it. The person is already signed
|
|
7
|
+
* in here, which is the whole reason this belongs in your app rather than on a
|
|
8
|
+
* page of ours: there is nothing to log into, and the page looks like yours.
|
|
9
|
+
*
|
|
10
|
+
* Two steps, deliberately. The code is checked first so that what is being
|
|
11
|
+
* approved can be named before anybody presses Approve; a single button that
|
|
12
|
+
* takes a code and grants access in one motion is a button people press without
|
|
13
|
+
* reading.
|
|
14
|
+
*/
|
|
15
|
+
export interface DeviceApprovalProps {
|
|
16
|
+
/**
|
|
17
|
+
* The code, when your page already has it.
|
|
18
|
+
*
|
|
19
|
+
* A device that can show a link or a QR code puts the code in the URL, which
|
|
20
|
+
* saves exactly the typing this flow exists to avoid. Read it off your router
|
|
21
|
+
* and pass it here; the entry step is skipped.
|
|
22
|
+
*/
|
|
23
|
+
userCode?: string;
|
|
24
|
+
/** Called after the person answers, with what they chose. */
|
|
25
|
+
onDecided?: (approved: boolean) => void;
|
|
26
|
+
className?: string;
|
|
27
|
+
style?: CSSProperties;
|
|
28
|
+
}
|
|
29
|
+
export declare function DeviceApproval({ userCode, onDecided, className, style, }: DeviceApprovalProps): import("react").JSX.Element | null;
|
|
30
|
+
//# sourceMappingURL=DeviceApproval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceApproval.d.ts","sourceRoot":"","sources":["../../src/DeviceApproval.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKrE;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,mBAAmB;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,cAAc,CAAC,EAC9B,QAAa,EACb,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE,mBAAmB,sCAqIrB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Asking for a reset link.
|
|
4
|
+
*
|
|
5
|
+
* The screen always says the same thing afterwards, whether or not the address
|
|
6
|
+
* has an account. That is not politeness: a form that said "no account with
|
|
7
|
+
* that address" is a way to discover who has registered, one address at a time,
|
|
8
|
+
* and the API already refuses to distinguish them — so a component that showed
|
|
9
|
+
* a different message for each would be inventing information the server
|
|
10
|
+
* deliberately withheld.
|
|
11
|
+
*
|
|
12
|
+
* There is no prop for where the link lands. That URL is configured on the
|
|
13
|
+
* environment, for the same reason a checkout return URL is — a form that could
|
|
14
|
+
* name it would be a way to have a sign-in link emailed to somewhere else.
|
|
15
|
+
*/
|
|
16
|
+
export interface ForgotPasswordProps {
|
|
17
|
+
onSent?: (email: string) => void;
|
|
18
|
+
/** Back to sign-in. Rendered as a link when given. */
|
|
19
|
+
signInUrl?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
}
|
|
23
|
+
export declare function ForgotPassword({ onSent, signInUrl, className, style }: ForgotPasswordProps): import("react").JSX.Element;
|
|
24
|
+
//# sourceMappingURL=ForgotPassword.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgotPassword.d.ts","sourceRoot":"","sources":["../../src/ForgotPassword.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKrD;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,mBAAmB,+BA8E1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Invoices.d.ts","sourceRoot":"","sources":["../../src/Invoices.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAuB7E;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,+
|
|
1
|
+
{"version":3,"file":"Invoices.d.ts","sourceRoot":"","sources":["../../src/Invoices.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAuB7E;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,+BAgI3F"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type CollectionRecord } from "@base316/sdk";
|
|
2
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
3
|
+
import { type UseCollectionOptions } from "./useCollection";
|
|
4
|
+
/**
|
|
5
|
+
* A board, over a collection that was never designed to have one.
|
|
6
|
+
*
|
|
7
|
+
* This component is the proof of the whole design. It was written after the
|
|
8
|
+
* schema and the table, it knows nothing about jobs or tickets or deals, and it
|
|
9
|
+
* asks the schema one question:
|
|
10
|
+
*
|
|
11
|
+
* defaultGroupFieldOf(schema.fields) // "which field makes columns?"
|
|
12
|
+
*
|
|
13
|
+
* The registry answers with the SELECT field, because a status or a stage is
|
|
14
|
+
* what somebody means by grouping — and so `<Kanban collection="jobs" />`
|
|
15
|
+
* works with no props at all. Had fields been described in rendering terms
|
|
16
|
+
* ("this column is right-aligned"), there would have been nothing here to ask,
|
|
17
|
+
* and every board would need its own configuration naming its own columns.
|
|
18
|
+
*
|
|
19
|
+
* Moving a card writes the grouping field. That is the only mutation a board
|
|
20
|
+
* makes, and it is why the field has to be one with a fixed set of values: a
|
|
21
|
+
* column header has to be a value somebody can drop onto.
|
|
22
|
+
*/
|
|
23
|
+
export interface KanbanProps extends UseCollectionOptions {
|
|
24
|
+
collection: string;
|
|
25
|
+
/**
|
|
26
|
+
* Which field makes the columns.
|
|
27
|
+
*
|
|
28
|
+
* Discovered when omitted. Name it when a collection has several groupable
|
|
29
|
+
* fields and the first choice is not the one this board is about.
|
|
30
|
+
*/
|
|
31
|
+
groupBy?: string;
|
|
32
|
+
/** Fields to show on a card, in order. Defaults to the title and the next two. */
|
|
33
|
+
cardFields?: string[];
|
|
34
|
+
onSelect?: (record: CollectionRecord) => void;
|
|
35
|
+
emptyState?: ReactNode;
|
|
36
|
+
className?: string;
|
|
37
|
+
style?: CSSProperties;
|
|
38
|
+
}
|
|
39
|
+
export declare function Kanban({ collection, groupBy, cardFields, onSelect, emptyState, className, style, ...options }: KanbanProps): import("react").JSX.Element;
|
|
40
|
+
//# sourceMappingURL=Kanban.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kanban.d.ts","sourceRoot":"","sources":["../../src/Kanban.tsx"],"names":[],"mappings":"AAEA,OAAO,EACN,KAAK,gBAAgB,EAKrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAY,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIrE,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE3E;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,WAAY,SAAQ,oBAAoB;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,OAAO,EACP,UAAU,EACV,QAAQ,EACR,UAAU,EACV,SAAS,EACT,KAAK,EACL,GAAG,OAAO,EACV,EAAE,WAAW,+BAoMb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasskeyManager.d.ts","sourceRoot":"","sources":["../../src/PasskeyManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PasskeyManager.d.ts","sourceRoot":"","sources":["../../src/PasskeyManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAM7E;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAC9B,SAAS,EACT,KAAK,EACL,KAAkB,GAClB,EAAE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,sCAoJA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
interface StripeElements {
|
|
3
|
+
create(type: string): {
|
|
4
|
+
mount(selector: string | HTMLElement): void;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
interface StripeLike {
|
|
8
|
+
elements(options: {
|
|
9
|
+
clientSecret: string;
|
|
10
|
+
}): StripeElements;
|
|
11
|
+
confirmPayment(options: {
|
|
12
|
+
elements: StripeElements;
|
|
13
|
+
confirmParams: {
|
|
14
|
+
return_url: string;
|
|
15
|
+
};
|
|
16
|
+
redirect: "if_required";
|
|
17
|
+
}): Promise<{
|
|
18
|
+
error?: {
|
|
19
|
+
message?: string;
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
declare global {
|
|
24
|
+
interface Window {
|
|
25
|
+
Stripe?: (key: string, options?: {
|
|
26
|
+
stripeAccount: string;
|
|
27
|
+
}) => StripeLike;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export declare function PayInvoice({ token, environmentId, onPaid, className, style, }: {
|
|
31
|
+
/** From `invoices.createPaymentLink` on your server. */
|
|
32
|
+
token: string;
|
|
33
|
+
/** The environment the link belongs to; it is in the link URL too. */
|
|
34
|
+
environmentId: string;
|
|
35
|
+
/** Runs once the payment is complete. */
|
|
36
|
+
onPaid?: () => void;
|
|
37
|
+
className?: string;
|
|
38
|
+
style?: CSSProperties;
|
|
39
|
+
}): import("react").JSX.Element;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=PayInvoice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PayInvoice.d.ts","sourceRoot":"","sources":["../../src/PayInvoice.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AA0BxE,UAAU,cAAc;IACvB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC;CACtE;AAED,UAAU,UAAU;IACnB,QAAQ,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,CAAC;IAC5D,cAAc,CAAC,OAAO,EAAE;QACvB,QAAQ,EAAE,cAAc,CAAC;QACzB,aAAa,EAAE;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC;QACtC,QAAQ,EAAE,aAAa,CAAC;KACxB,GAAG,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CAC9C;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,KAAK,UAAU,CAAC;KAC1E;CACD;AAgCD,wBAAgB,UAAU,CAAC,EAC1B,KAAK,EACL,aAAa,EACb,MAAM,EACN,SAAS,EACT,KAAK,GACL,EAAE;IACF,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BA8GA"}
|
|
@@ -1,21 +1,53 @@
|
|
|
1
1
|
import type { PublicPlan } from "@base316/sdk";
|
|
2
|
-
import {
|
|
2
|
+
import type { CSSProperties } from "react";
|
|
3
3
|
/**
|
|
4
|
-
* The plans, as an end user picks
|
|
4
|
+
* The plans, as an end user picks them.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* Drop it in with no props and it works: it loads the published plans, marks
|
|
7
|
+
* the one the signed-in user is on, and completes the purchase.
|
|
8
|
+
*
|
|
9
|
+
* Choosing a plan used to be the caller's job, because minting a checkout
|
|
10
|
+
* session needs a secret key that cannot live in a browser. That is still
|
|
11
|
+
* true — but it is an argument about *key custody*, not about who names the
|
|
12
|
+
* plan. `POST /v1/me/checkout/sessions` resolves the customer from the session
|
|
13
|
+
* and reads the price from the database against the plan id, so a browser
|
|
14
|
+
* naming a cheaper plan subscribes to a cheaper plan rather than paying less
|
|
15
|
+
* for an expensive one. That is what makes this droppable.
|
|
16
|
+
*
|
|
17
|
+
* Two routes, because a subscriber and a newcomer need different things:
|
|
18
|
+
*
|
|
19
|
+
* - Already subscribed, card on file → change plan in place, prorated, no
|
|
20
|
+
* card re-entry and no second subscription beside the first.
|
|
21
|
+
* - Otherwise → a checkout session, which is the thing that collects a card.
|
|
22
|
+
*
|
|
23
|
+
* `onSelectPlan` remains as an override for an application that wants to run
|
|
24
|
+
* its own flow — a quote, an approval step, its own backend route.
|
|
12
25
|
*/
|
|
13
|
-
export declare function PricingTable({ onSelectPlan, currentPlanVersionId, featuredPlanKey, className, style, }: {
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
export declare function PricingTable({ onSelectPlan, currentPlanVersionId, featuredPlanKey, signInUrl, className, style, }: {
|
|
27
|
+
/**
|
|
28
|
+
* Take over what "Choose" does.
|
|
29
|
+
*
|
|
30
|
+
* Optional. Without it the component completes the purchase itself, which
|
|
31
|
+
* is what most applications want.
|
|
32
|
+
*/
|
|
33
|
+
onSelectPlan?: (planVersionId: string, plan: PublicPlan) => void | Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Marks the plan the viewer is already on.
|
|
36
|
+
*
|
|
37
|
+
* Discovered from the signed-in user's subscription when not given. Pass it
|
|
38
|
+
* to override — on a marketing page rendering someone else's plan, say.
|
|
39
|
+
*/
|
|
16
40
|
currentPlanVersionId?: string | null;
|
|
17
41
|
/** The plan to present as the default choice, by its key. */
|
|
18
42
|
featuredPlanKey?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Where to send a signed-out visitor who picks a plan.
|
|
45
|
+
*
|
|
46
|
+
* Checkout needs a session, so without a signed-in user there is nobody to
|
|
47
|
+
* bill. Given a URL the button goes there; without one it says so rather
|
|
48
|
+
* than failing on click.
|
|
49
|
+
*/
|
|
50
|
+
signInUrl?: string;
|
|
19
51
|
className?: string;
|
|
20
52
|
style?: CSSProperties;
|
|
21
53
|
}): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PricingTable.d.ts","sourceRoot":"","sources":["../../src/PricingTable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"PricingTable.d.ts","sourceRoot":"","sources":["../../src/PricingTable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AA4B3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,EAC5B,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE;IACF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAgJA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Download my data, and delete my account.
|
|
4
|
+
*
|
|
5
|
+
* The two things a privacy notice promises and most products never build, so
|
|
6
|
+
* the promise gets kept by an inbox and a person doing it by hand. Both here
|
|
7
|
+
* take the signed-in user's own session, so neither needs your server to be
|
|
8
|
+
* trusted with somebody else's account.
|
|
9
|
+
*
|
|
10
|
+
* Deletion asks twice, and the second time it asks the person to type. That is
|
|
11
|
+
* not friction for its own sake: this is the one control on the page that
|
|
12
|
+
* cannot be undone, and a misplaced click should not be able to reach it.
|
|
13
|
+
*/
|
|
14
|
+
export interface PrivacyControlsProps {
|
|
15
|
+
/**
|
|
16
|
+
* What must be typed to confirm deletion.
|
|
17
|
+
*
|
|
18
|
+
* Defaults to the English word, which is wrong in every other language —
|
|
19
|
+
* pass the one your interface is written in.
|
|
20
|
+
*/
|
|
21
|
+
confirmWord?: string;
|
|
22
|
+
/** Called after the account is gone. Sign them out and send them somewhere. */
|
|
23
|
+
onErased?: () => void;
|
|
24
|
+
className?: string;
|
|
25
|
+
style?: CSSProperties;
|
|
26
|
+
}
|
|
27
|
+
export declare function PrivacyControls({ confirmWord, onErased, className, style, }: PrivacyControlsProps): import("react").JSX.Element | null;
|
|
28
|
+
//# sourceMappingURL=PrivacyControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrivacyControls.d.ts","sourceRoot":"","sources":["../../src/PrivacyControls.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKrD;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAC/B,WAAsB,EACtB,QAAQ,EACR,SAAS,EACT,KAAK,GACL,EAAE,oBAAoB,sCAmItB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* One record, read.
|
|
4
|
+
*
|
|
5
|
+
* The other half of a table: a row shows what fits in a column, and this shows
|
|
6
|
+
* everything — including the fields a table deliberately truncates, like a
|
|
7
|
+
* paragraph of notes, and the derived ones a form leaves out because they
|
|
8
|
+
* cannot be typed.
|
|
9
|
+
*
|
|
10
|
+
* <RecordDetail collection="jobs" recordId={id} />
|
|
11
|
+
*
|
|
12
|
+
* Edit is offered only when the viewer may write, which the schema already
|
|
13
|
+
* says. There is no second permission check here and there should not be: the
|
|
14
|
+
* server decides, and a component that decided for itself would eventually
|
|
15
|
+
* disagree with it.
|
|
16
|
+
*/
|
|
17
|
+
export interface RecordDetailProps {
|
|
18
|
+
collection: string;
|
|
19
|
+
recordId: string;
|
|
20
|
+
tenant?: string;
|
|
21
|
+
/** Hide Edit and Delete even for a viewer who may write. */
|
|
22
|
+
readOnly?: boolean;
|
|
23
|
+
onDeleted?: () => void;
|
|
24
|
+
onClose?: () => void;
|
|
25
|
+
/** Rendered under the fields — related lists, actions, anything. */
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: CSSProperties;
|
|
29
|
+
}
|
|
30
|
+
export declare function RecordDetail({ collection, recordId, tenant, readOnly, onDeleted, onClose, children, className, style, }: RecordDetailProps): import("react").JSX.Element;
|
|
31
|
+
//# sourceMappingURL=RecordDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordDetail.d.ts","sourceRoot":"","sources":["../../src/RecordDetail.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQrE;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,EAC5B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAS,EACT,OAAO,EACP,QAAQ,EACR,SAAS,EACT,KAAK,GACL,EAAE,iBAAiB,+BAqHnB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type FieldValue } from "@base316/sdk";
|
|
2
|
+
import { type CSSProperties } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Creating or editing one record, with the form derived from the schema.
|
|
5
|
+
*
|
|
6
|
+
* Nobody writes the inputs. The field types decide which control each value
|
|
7
|
+
* gets, which ones are required, and which are not editable at all — an
|
|
8
|
+
* AUTONUMBER, a LOOKUP and a ROLLUP are produced by the server, so offering an
|
|
9
|
+
* input for one would invite somebody to type a value that is discarded.
|
|
10
|
+
*
|
|
11
|
+
* <RecordForm collection="jobs" /> // create
|
|
12
|
+
* <RecordForm collection="jobs" recordId={id} /> // edit
|
|
13
|
+
*
|
|
14
|
+
* Errors come back per field and land under the input that caused them.
|
|
15
|
+
* Validation is not repeated here: the same `validateRecord` the server uses
|
|
16
|
+
* would have to be kept in step, and a second implementation that drifts is
|
|
17
|
+
* worse than one round trip.
|
|
18
|
+
*/
|
|
19
|
+
export interface RecordFormProps {
|
|
20
|
+
collection: string;
|
|
21
|
+
/** Omit to create. */
|
|
22
|
+
recordId?: string;
|
|
23
|
+
tenant?: string;
|
|
24
|
+
onSaved?: (id: string) => void;
|
|
25
|
+
onCancel?: () => void;
|
|
26
|
+
/** Start with these values filled in. Ignored when editing. */
|
|
27
|
+
defaults?: Record<string, FieldValue>;
|
|
28
|
+
className?: string;
|
|
29
|
+
style?: CSSProperties;
|
|
30
|
+
}
|
|
31
|
+
export declare function RecordForm({ collection, recordId, tenant, onSaved, onCancel, defaults, className, style, }: RecordFormProps): import("react").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=RecordForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordForm.d.ts","sourceRoot":"","sources":["../../src/RecordForm.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAW,MAAM,cAAc,CAAC;AACxD,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAOhE;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,EAC1B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,KAAK,GACL,EAAE,eAAe,+BA+GjB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FieldDescriptor } from "@base316/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Choosing a record in another collection, by typing its name.
|
|
4
|
+
*
|
|
5
|
+
* The alternative is a text box holding an id, which nobody can fill in
|
|
6
|
+
* without going to look one up — so a relation field without this is a
|
|
7
|
+
* relation field nobody uses.
|
|
8
|
+
*
|
|
9
|
+
* Two fetches, and they answer different questions. The title of what is
|
|
10
|
+
* already chosen has to be known before anybody types, or an existing record
|
|
11
|
+
* opens showing an id. The search results are what typing produces. Conflating
|
|
12
|
+
* them means an edit form that looks empty until the user searches for the
|
|
13
|
+
* value it already has.
|
|
14
|
+
*/
|
|
15
|
+
export declare function RelationPicker({ field, value, onChange, error, disabled, tenant, }: {
|
|
16
|
+
field: FieldDescriptor;
|
|
17
|
+
value: string | null;
|
|
18
|
+
onChange: (value: string | null) => void;
|
|
19
|
+
error?: string | null;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
tenant?: string;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=RelationPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RelationPicker.d.ts","sourceRoot":"","sources":["../../src/RelationPicker.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD;;;;;;;;;;;;GAYG;AAEH,wBAAgB,cAAc,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,MAAM,GACN,EAAE;IACF,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,+BAqLA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Setting a new password from an emailed link.
|
|
4
|
+
*
|
|
5
|
+
* The page the link lands on renders this; the token comes from `?token=` and
|
|
6
|
+
* is removed from the address bar as soon as it is read. A reset token sitting
|
|
7
|
+
* in browser history, in a referrer header or in a shared screenshot is a way
|
|
8
|
+
* into the account for as long as it is unspent.
|
|
9
|
+
*
|
|
10
|
+
* The confirmation field is checked here rather than by the server, because it
|
|
11
|
+
* is the one thing the server cannot help with: two different strings are both
|
|
12
|
+
* valid passwords, and only the person typing knows which they meant.
|
|
13
|
+
*/
|
|
14
|
+
export interface ResetPasswordProps {
|
|
15
|
+
/** Supply the token directly. Read from `?token=` when omitted. */
|
|
16
|
+
token?: string;
|
|
17
|
+
onReset?: () => void;
|
|
18
|
+
/** Where to go afterwards. Rendered as a link when given. */
|
|
19
|
+
signInUrl?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
}
|
|
23
|
+
export declare function ResetPassword({ token: supplied, onReset, signInUrl, className, style, }: ResetPasswordProps): import("react").JSX.Element;
|
|
24
|
+
//# sourceMappingURL=ResetPassword.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPassword.d.ts","sourceRoot":"","sources":["../../src/ResetPassword.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKhE;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,kBAAkB;IAClC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,EAC7B,KAAK,EAAE,QAAQ,EACf,OAAO,EACP,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE,kBAAkB,+BA+HpB"}
|
package/dist/src/SignIn.d.ts
CHANGED
|
@@ -6,10 +6,20 @@ import { type CSSProperties } from "react";
|
|
|
6
6
|
* challenge instead of a session, and a form that ignores that case appears to
|
|
7
7
|
* fail for exactly the users who most need it to work.
|
|
8
8
|
*/
|
|
9
|
-
export declare function SignIn({ onSignedIn, passkeys, className, style, }: {
|
|
9
|
+
export declare function SignIn({ onSignedIn, passkeys, magicLinkRedirectUrl, className, style, }: {
|
|
10
10
|
onSignedIn?: () => void;
|
|
11
11
|
/** Offer passkeys alongside the password. On by default where supported. */
|
|
12
12
|
passkeys?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Where an emailed sign-in link lands. Offering magic link at all requires
|
|
15
|
+
* it, because the link has to point somewhere this application controls —
|
|
16
|
+
* and the URL must be registered on the environment's sign-in page, the same
|
|
17
|
+
* list that governs redirects.
|
|
18
|
+
*
|
|
19
|
+
* The page it names should render this component: arriving with `?token=`
|
|
20
|
+
* redeems it automatically.
|
|
21
|
+
*/
|
|
22
|
+
magicLinkRedirectUrl?: string;
|
|
13
23
|
className?: string;
|
|
14
24
|
style?: CSSProperties;
|
|
15
25
|
}): import("react").JSX.Element;
|
package/dist/src/SignIn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../src/SignIn.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../src/SignIn.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA+B,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKxF;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,QAAe,EACf,oBAAoB,EACpB,SAAS,EACT,KAAK,GACL,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BA0UA"}
|