Skip to content

Commit f3ec9c3

Browse files
Update API and add observables
1 parent 092a4ca commit f3ec9c3

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

.changeset/wet-cycles-punch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/ui-extensions': minor
3+
---
4+
5+
Added subscribable discounts api

packages/ui-extensions/src/surfaces/admin/api/discount-function-settings/discount-function-settings.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import type {BlockExtensionApi} from '../block/block';
22
import type {ExtensionTarget as AnyExtensionTarget} from '../../extension-targets';
33

44
import {ApplyMetafieldChange} from './metafields';
5-
import {DiscountFunctionSettingsData} from './launch-options';
5+
import {
6+
DiscountFunctionSettingsData,
7+
SubscribableDiscountFields,
8+
} from './launch-options';
69

710
export interface DiscountFunctionSettingsApi<
811
ExtensionTarget extends AnyExtensionTarget,
@@ -12,4 +15,5 @@ export interface DiscountFunctionSettingsApi<
1215
*/
1316
applyMetafieldChange: ApplyMetafieldChange;
1417
data: DiscountFunctionSettingsData;
18+
discounts: SubscribableDiscountFields;
1519
}

packages/ui-extensions/src/surfaces/admin/api/discount-function-settings/launch-options.ts

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,57 @@ interface Metafield {
77
type: string;
88
}
99

10-
export enum DiscountClass {
11-
Product = 'PRODUCT',
12-
Order = 'ORDER',
13-
Shipping = 'SHIPPING',
14-
}
10+
type DiscountClass = 'product' | 'order' | 'shipping';
1511

16-
interface Discount {
17-
/**
18-
* the discount's gid
19-
*/
20-
id: string;
12+
type DiscountMethod = 'automatic' | 'code';
13+
14+
type PurchaseType = 'one_time_purchase' | 'subscription' | 'both';
15+
16+
type Result<T> =
17+
| {success: true; value: T}
18+
| {success: false; errors: ValidationError[]};
19+
20+
interface ValidationError {
21+
type: 'error';
22+
message: string;
23+
code: string;
24+
issues?: {
25+
message: string;
26+
path: string[];
27+
}[];
2128
}
2229

2330
/**
2431
* The object that exposes the validation with its settings.
2532
*/
2633
export interface DiscountFunctionSettingsData {
27-
id: Discount;
34+
id: string;
2835
metafields: Metafield[];
2936
}
37+
38+
/**
39+
* Represents a reactive signal interface that provides both immediate value access and subscription-based updates. Enables real-time synchronization with changing data through the observer pattern.
40+
*/
41+
export interface ReadonlySignalLike<T> {
42+
/**
43+
* The current value of the field.
44+
*/
45+
readonly value: T;
46+
/**
47+
* Subscribes to field changes and calls the provided function whenever the field updates. Returns an unsubscribe function to clean up the subscription.
48+
*/
49+
subscribe(fn: (value: T) => void): () => void;
50+
}
51+
52+
type UpdateFunction<T> = (value: T) => Result<T>;
53+
54+
export interface SubscribableDiscountFields {
55+
discountClasses: ReadonlySignalLike<DiscountClass[]>;
56+
updateDiscountClasses: UpdateFunction<DiscountClass[]>;
57+
method: ReadonlySignalLike<DiscountMethod>;
58+
updateMethod: UpdateFunction<DiscountMethod>;
59+
purchaseType: ReadonlySignalLike<PurchaseType>;
60+
updatePurchaseType: UpdateFunction<PurchaseType>;
61+
recurringCycleLimit: ReadonlySignalLike<number | null | undefined>;
62+
updateRecurringCycleLimit: UpdateFunction<number | null | undefined>;
63+
}

0 commit comments

Comments
 (0)