@saasquatch/mint-components 2.1.8-27 → 2.1.8-28
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/dist/cjs/{ShadowViewAddon-e1e20b3a.js → ShadowViewAddon-363fcb59.js} +4 -3
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/mint-components.cjs.js +1 -1
- package/dist/cjs/sqm-big-stat_45.cjs.entry.js +10 -2
- package/dist/cjs/sqm-stencilbook.cjs.entry.js +2 -1
- package/dist/cjs/useShareLink-94e077a4.js +454 -0
- package/dist/collection/components/sqm-share-link/ShareLink.stories.js +1 -0
- package/dist/collection/components/sqm-share-link/sqm-share-link-view.js +3 -2
- package/dist/collection/components/sqm-share-link/sqm-share-link.js +41 -3
- package/dist/collection/components/sqm-share-link/useShareLink.js +1 -1
- package/dist/esm/{ShadowViewAddon-abfb02b8.js → ShadowViewAddon-667b4e9b.js} +4 -3
- package/dist/esm/loader.js +1 -1
- package/dist/esm/mint-components.js +1 -1
- package/dist/esm/sqm-big-stat_45.entry.js +10 -2
- package/dist/esm/sqm-stencilbook.entry.js +2 -1
- package/dist/esm/useShareLink-416a856a.js +451 -0
- package/dist/esm-es5/{ShadowViewAddon-abfb02b8.js → ShadowViewAddon-667b4e9b.js} +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/mint-components.js +1 -1
- package/dist/esm-es5/sqm-big-stat_45.entry.js +1 -1
- package/dist/esm-es5/sqm-stencilbook.entry.js +1 -1
- package/dist/esm-es5/useShareLink-416a856a.js +1 -0
- package/dist/mint-components/mint-components.esm.js +1 -1
- package/dist/mint-components/{p-5167f62c.entry.js → p-154642b1.entry.js} +2 -2
- package/dist/mint-components/{p-97b2aabc.js → p-17ebb16a.js} +2 -2
- package/dist/mint-components/{p-608be5f4.system.entry.js → p-33caf964.system.entry.js} +1 -1
- package/dist/mint-components/p-4b365f1f.system.js +1 -1
- package/dist/mint-components/{p-95304aa0.system.js → p-609d0fc4.system.js} +1 -1
- package/dist/mint-components/{p-d36f7dcf.system.entry.js → p-627789fa.system.entry.js} +1 -1
- package/dist/mint-components/{p-38491d20.entry.js → p-7db028eb.entry.js} +2 -2
- package/dist/mint-components/useShareLink-416a856a.js +451 -0
- package/dist/mint-components/useShareLink-af6ede83.system.js +1 -0
- package/dist/types/components/sqm-share-link/sqm-share-link-view.d.ts +1 -0
- package/dist/types/components/sqm-share-link/sqm-share-link.d.ts +7 -0
- package/dist/types/components/sqm-share-link/useShareLink.d.ts +1 -0
- package/dist/types/components.d.ts +14 -0
- package/docs/docs.docx +0 -0
- package/docs/raisins.json +1 -1
- package/grapesjs/grapesjs.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const index = require('./index-fd67d7bc.js');
|
|
4
|
+
const global = require('./global-746daf93.js');
|
|
5
|
+
const domContextHooks_module = require('./dom-context-hooks.module-224e09d4.js');
|
|
6
|
+
const index_module = require('./index.module-c79bd5b0.js');
|
|
7
|
+
const JSS = require('./JSS-518e9b4d.js');
|
|
8
|
+
const useReferralCodes = require('./useReferralCodes-4304f68f.js');
|
|
9
|
+
const copyTextView = require('./copy-text-view-fd17b89a.js');
|
|
10
|
+
|
|
11
|
+
const vanillaStyle = `
|
|
12
|
+
:host {
|
|
13
|
+
display: block;
|
|
14
|
+
width: 100%;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
function ShareLinkView(props) {
|
|
18
|
+
const { copyTextViewProps, allowCustomization, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, minCharactersText, } = props;
|
|
19
|
+
const style = {
|
|
20
|
+
Container: {
|
|
21
|
+
display: "flex",
|
|
22
|
+
flexDirection: "column",
|
|
23
|
+
gap: "var(--sl-spacing-xx-small)",
|
|
24
|
+
width: "100%",
|
|
25
|
+
},
|
|
26
|
+
CustomizeLinkText: {
|
|
27
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
28
|
+
margin: "0",
|
|
29
|
+
fontSize: "var(--sl-font-size-small)",
|
|
30
|
+
fontWeight: "600",
|
|
31
|
+
cursor: "pointer",
|
|
32
|
+
color: "var(--sl-color-neutral-900)",
|
|
33
|
+
textAlign: "left",
|
|
34
|
+
"&:hover": {
|
|
35
|
+
textDecoration: "underline",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
CustomizeLinkDisabled: {
|
|
39
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
40
|
+
margin: "0",
|
|
41
|
+
fontSize: "var(--sl-font-size-small)",
|
|
42
|
+
fontWeight: "600",
|
|
43
|
+
color: "var(--sl-color-neutral-400)",
|
|
44
|
+
cursor: "default",
|
|
45
|
+
textAlign: "left",
|
|
46
|
+
},
|
|
47
|
+
EditContainer: {
|
|
48
|
+
display: "flex",
|
|
49
|
+
flexDirection: "column",
|
|
50
|
+
gap: "var(--sl-spacing-x-small)",
|
|
51
|
+
width: "100%",
|
|
52
|
+
},
|
|
53
|
+
EditInputWrapper: {
|
|
54
|
+
display: "flex",
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
width: "100%",
|
|
57
|
+
border: "var(--sqm-border-thickness, 1px) solid var(--sqm-input-border-color, #d1d5db)",
|
|
58
|
+
borderRadius: "var(--sqm-border-radius-normal, 4px)",
|
|
59
|
+
background: "var(--sqm-input-background, #fff)",
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
"&:focus-within": {
|
|
62
|
+
borderColor: "#999999",
|
|
63
|
+
boxShadow: "0 0 0 var(--sl-focus-ring-width) var(--sl-input-focus-ring-color)",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
DomainPrefix: {
|
|
67
|
+
padding: "0 0 0 var(--sl-spacing-medium)",
|
|
68
|
+
fontSize: "var(--sl-font-size-medium)",
|
|
69
|
+
color: "var(--sl-color-neutral-500)",
|
|
70
|
+
whiteSpace: "nowrap",
|
|
71
|
+
userSelect: "none",
|
|
72
|
+
lineHeight: "var(--sl-input-height-medium)",
|
|
73
|
+
},
|
|
74
|
+
EditInput: {
|
|
75
|
+
flex: "1",
|
|
76
|
+
border: "none",
|
|
77
|
+
outline: "none",
|
|
78
|
+
padding: "0 var(--sl-spacing-medium) 0 0",
|
|
79
|
+
fontSize: "var(--sl-font-size-medium)",
|
|
80
|
+
fontFamily: "var(--sl-font-sans)",
|
|
81
|
+
color: "var(--sl-input-color)",
|
|
82
|
+
background: "transparent",
|
|
83
|
+
lineHeight: "var(--sl-input-height-medium)",
|
|
84
|
+
minWidth: "0",
|
|
85
|
+
},
|
|
86
|
+
EditLabel: {
|
|
87
|
+
margin: "0",
|
|
88
|
+
fontSize: "var(--sl-font-size-small)",
|
|
89
|
+
color: "var(--sl-color-neutral-500)",
|
|
90
|
+
},
|
|
91
|
+
HelperText: {
|
|
92
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
93
|
+
margin: "0",
|
|
94
|
+
fontSize: "var(--sl-font-size-small)",
|
|
95
|
+
color: "var(--sl-color-neutral-500)",
|
|
96
|
+
},
|
|
97
|
+
ErrorText: {
|
|
98
|
+
margin: "0",
|
|
99
|
+
fontSize: "var(--sl-font-size-small)",
|
|
100
|
+
color: "var(--sqm-danger-color-text, #dc2626)",
|
|
101
|
+
},
|
|
102
|
+
ActionRow: {
|
|
103
|
+
display: "flex",
|
|
104
|
+
gap: "var(--sl-spacing-medium)",
|
|
105
|
+
alignItems: "center",
|
|
106
|
+
},
|
|
107
|
+
SaveButton: {
|
|
108
|
+
cursor: "pointer",
|
|
109
|
+
fontFamily: "var(--sl-font-sans)",
|
|
110
|
+
fontSize: "var(--sl-font-size-small)",
|
|
111
|
+
fontWeight: "600",
|
|
112
|
+
padding: "var(--sl-spacing-x-small) var(--sl-spacing-medium)",
|
|
113
|
+
borderRadius: "var(--sqm-border-radius-normal, 4px)",
|
|
114
|
+
border: "1px solid var(--sl-color-neutral-900)",
|
|
115
|
+
background: "var(--sl-color-neutral-900)",
|
|
116
|
+
color: "#fff",
|
|
117
|
+
"&:disabled": {
|
|
118
|
+
opacity: "0.5",
|
|
119
|
+
cursor: "default",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
CancelButton: {
|
|
123
|
+
margin: "0",
|
|
124
|
+
fontSize: "var(--sl-font-size-small)",
|
|
125
|
+
fontWeight: "600",
|
|
126
|
+
cursor: "pointer",
|
|
127
|
+
background: "none",
|
|
128
|
+
border: "none",
|
|
129
|
+
fontFamily: "var(--sl-font-sans)",
|
|
130
|
+
color: "var(--sl-color-neutral-500)",
|
|
131
|
+
"&::part(label)": {
|
|
132
|
+
padding: "0",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
LimitReachedContainer: {
|
|
136
|
+
display: "flex",
|
|
137
|
+
alignItems: "center",
|
|
138
|
+
gap: "var(--sl-spacing-x-small)",
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
const sheet = JSS.createStyleSheet(style);
|
|
142
|
+
const styleString = sheet.toString();
|
|
143
|
+
const errorMessageType = (validationError === null || validationError === void 0 ? void 0 : validationError.code) === "EXISTING_CODE_CONFLICT" ? "info" : "warning";
|
|
144
|
+
const showCharactersRemaining = charactersRemaining <= 14;
|
|
145
|
+
const editLimitMessage = global.intl.formatMessage({
|
|
146
|
+
id: "editLimitText",
|
|
147
|
+
defaultMessage: editLimitText,
|
|
148
|
+
}, { editsRemaining });
|
|
149
|
+
// Editing state
|
|
150
|
+
if (isEditing) {
|
|
151
|
+
return (index.h("div", { class: sheet.classes.Container },
|
|
152
|
+
index.h("style", { type: "text/css" },
|
|
153
|
+
styleString,
|
|
154
|
+
vanillaStyle),
|
|
155
|
+
index.h("p", { class: sheet.classes.EditLabel }, "Enter your link"),
|
|
156
|
+
index.h("div", { class: sheet.classes.EditInputWrapper },
|
|
157
|
+
index.h("span", { class: sheet.classes.DomainPrefix }, domainPrefix),
|
|
158
|
+
index.h("input", { class: sheet.classes.EditInput, type: "text", value: editValue, onInput: (e) => onEditValueChange(e.target.value), onKeyDown: (e) => {
|
|
159
|
+
if (e.key === "/" || e.key === "@")
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
}, disabled: isSaving, maxLength: characterLimit })),
|
|
162
|
+
index.h("p", { class: sheet.classes.HelperText },
|
|
163
|
+
editLimitMessage,
|
|
164
|
+
" ",
|
|
165
|
+
charactersRemaining > 12 && minCharactersText,
|
|
166
|
+
showCharactersRemaining &&
|
|
167
|
+
` Characters remaining: ${charactersRemaining}`),
|
|
168
|
+
validationError && (index.h("sqm-form-message", { type: errorMessageType, style: { paddingBottom: "var(--sl-spacing-xx-small)" } },
|
|
169
|
+
index.h("p", { part: "alert-title" }, validationError.title),
|
|
170
|
+
validationError.description)),
|
|
171
|
+
isValidating && index.h("p", { class: sheet.classes.HelperText }, "Validating..."),
|
|
172
|
+
index.h("div", { class: sheet.classes.ActionRow },
|
|
173
|
+
index.h("button", { class: sheet.classes.SaveButton, onClick: onSave, disabled: isSaving ||
|
|
174
|
+
isValidating ||
|
|
175
|
+
!!validationError ||
|
|
176
|
+
!editValue ||
|
|
177
|
+
editValue.length < minCharacters }, isSaving ? "Saving..." : saveLabelText),
|
|
178
|
+
index.h("sl-button", { type: "text", class: sheet.classes.CancelButton, onClick: onCancel, disabled: isSaving }, cancelLabelText))));
|
|
179
|
+
}
|
|
180
|
+
// Default / Customized / Limit reached states
|
|
181
|
+
return (index.h("div", { class: sheet.classes.Container },
|
|
182
|
+
index.h("style", { type: "text/css" },
|
|
183
|
+
styleString,
|
|
184
|
+
vanillaStyle),
|
|
185
|
+
index.h(copyTextView.CopyTextView, Object.assign({}, copyTextViewProps)),
|
|
186
|
+
allowCustomization &&
|
|
187
|
+
(customizeDisabled ? (index.h("sl-tooltip", { content: customizeDisabledTooltip, placement: "top", style: { display: "inline-block", width: "fit-content" } },
|
|
188
|
+
index.h("p", { class: sheet.classes.CustomizeLinkDisabled }, customizeLinkLabel))) : (index.h("div", { class: sheet.classes.LimitReachedContainer },
|
|
189
|
+
index.h("p", { class: limitReached
|
|
190
|
+
? sheet.classes.CustomizeLinkDisabled
|
|
191
|
+
: sheet.classes.CustomizeLinkText, onClick: limitReached ? undefined : onCustomizeClick }, customizeLinkLabel),
|
|
192
|
+
allowCustomization && limitReached && (index.h("p", { class: sheet.classes.HelperText }, global.intl.formatMessage({
|
|
193
|
+
id: "editLimitReached",
|
|
194
|
+
defaultMessage: editLimitReachedText,
|
|
195
|
+
}, {
|
|
196
|
+
supportLink: (index.h("a", { target: "_blank", href: "https://help.impact.com/other/readme/get-help-and-support" }, supportLinkText)),
|
|
197
|
+
}))))))));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const MAX_EDITS = 5;
|
|
201
|
+
const CHARACTER_LIMIT = 15;
|
|
202
|
+
const MIN_CHARACTERS = 3;
|
|
203
|
+
const MessageLinkQuery = index_module.dist.gql `
|
|
204
|
+
query ($programId: ID) {
|
|
205
|
+
user: viewer {
|
|
206
|
+
... on User {
|
|
207
|
+
shareLink(programId: $programId)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
`;
|
|
212
|
+
const WIDGET_ENGAGEMENT_EVENT = index_module.dist.gql `
|
|
213
|
+
mutation loadEvent($eventMeta: UserAnalyticsEvent!) {
|
|
214
|
+
createUserAnalyticsEvent(eventMeta: $eventMeta)
|
|
215
|
+
}
|
|
216
|
+
`;
|
|
217
|
+
const ADD_SHARE_LINK_CODE = index_module.dist.gql `
|
|
218
|
+
mutation ($addShareLinkCodeInput: AddShareLinkCodeInput!) {
|
|
219
|
+
addShareLinkCode(addShareLinkCodeInput: $addShareLinkCodeInput) {
|
|
220
|
+
linkCode {
|
|
221
|
+
linkCode
|
|
222
|
+
shortUrl
|
|
223
|
+
referralCode {
|
|
224
|
+
code
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
`;
|
|
230
|
+
const VALIDATE_LINK_CODE = index_module.dist.gql `
|
|
231
|
+
query validateLinkCode($linkCode: String!) {
|
|
232
|
+
validateLinkCode(linkCode: $linkCode) {
|
|
233
|
+
valid
|
|
234
|
+
invalidReason
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
`;
|
|
238
|
+
const GET_LINK_DOMAIN = index_module.dist.gql `
|
|
239
|
+
query getLinkDomain {
|
|
240
|
+
tenantSettings {
|
|
241
|
+
primaryLinkDomain {
|
|
242
|
+
host
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
`;
|
|
247
|
+
const SHARE_LINK_EDIT_COUNT = index_module.dist.gql `
|
|
248
|
+
query shareLinkEditCount {
|
|
249
|
+
viewer {
|
|
250
|
+
... on User {
|
|
251
|
+
shareLinkCodes {
|
|
252
|
+
totalCount
|
|
253
|
+
data {
|
|
254
|
+
isVanity
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
`;
|
|
261
|
+
function parseShareUrl(url) {
|
|
262
|
+
try {
|
|
263
|
+
const parsed = new URL(url);
|
|
264
|
+
return {
|
|
265
|
+
url: parsed.origin + parsed.pathname,
|
|
266
|
+
domain: parsed.origin + "/",
|
|
267
|
+
path: parsed.pathname.slice(1),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return { url, domain: url, path: "" };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function useShareLink(props) {
|
|
275
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
276
|
+
const { programId = index_module.H() } = props;
|
|
277
|
+
const user = index_module.J();
|
|
278
|
+
const engagementMedium = index_module.B();
|
|
279
|
+
const contextData = index_module.Fn(useReferralCodes.REFERRAL_CODES_NAMESPACE);
|
|
280
|
+
const { data, refetch } = index_module.wn(MessageLinkQuery, { programId }, !(user === null || user === void 0 ? void 0 : user.jwt) || !!props.linkOverride || (contextData === null || contextData === void 0 ? void 0 : contextData.shareLink) !== undefined);
|
|
281
|
+
const [sendLoadEvent] = index_module.$e(WIDGET_ENGAGEMENT_EVENT);
|
|
282
|
+
const [setCopied] = index_module.$e(useReferralCodes.SET_CODE_COPIED);
|
|
283
|
+
const [addShareLinkCode, { loading: isSaving }] = index_module.$e(ADD_SHARE_LINK_CODE);
|
|
284
|
+
const [validateLinkCode] = index_module.Xe(VALIDATE_LINK_CODE);
|
|
285
|
+
const { refresh } = index_module.Qe();
|
|
286
|
+
const { data: linkDomainData } = index_module.wn(GET_LINK_DOMAIN, {}, !(user === null || user === void 0 ? void 0 : user.jwt) || !props.allowCustomization);
|
|
287
|
+
const { data: editCountData, refetch: refetchEditCount } = index_module.wn(SHARE_LINK_EDIT_COUNT, {}, !(user === null || user === void 0 ? void 0 : user.jwt) || !props.allowCustomization);
|
|
288
|
+
const { url: copyString, domain: domainPrefix, path: pathSuffix, } = parseShareUrl((_b = ((contextData === null || contextData === void 0 ? void 0 : contextData.shareLink) || ((_a = data === null || data === void 0 ? void 0 : data.user) === null || _a === void 0 ? void 0 : _a.shareLink))) !== null && _b !== void 0 ? _b :
|
|
289
|
+
// Shown during loading
|
|
290
|
+
"...");
|
|
291
|
+
const [open, setOpen] = domContextHooks_module.useState(false);
|
|
292
|
+
const [isEditing, setIsEditing] = domContextHooks_module.useState(false);
|
|
293
|
+
const [editValue, setEditValue] = domContextHooks_module.useState("");
|
|
294
|
+
const [validationError, setValidationError] = domContextHooks_module.useState(null);
|
|
295
|
+
const [isValidating, setIsValidating] = domContextHooks_module.useState(false);
|
|
296
|
+
const debounceTimerRef = domContextHooks_module.useRef(undefined);
|
|
297
|
+
const hasPrimaryLinkDomain = ((_c = linkDomainData === null || linkDomainData === void 0 ? void 0 : linkDomainData.tenantSettings) === null || _c === void 0 ? void 0 : _c.primaryLinkDomain) != null;
|
|
298
|
+
const customizeDisabled = !hasPrimaryLinkDomain;
|
|
299
|
+
const vanityCount = (_g = (_f = (_e = (_d = editCountData === null || editCountData === void 0 ? void 0 : editCountData.viewer) === null || _d === void 0 ? void 0 : _d.shareLinkCodes) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.filter((code) => code.isVanity).length) !== null && _g !== void 0 ? _g : 0;
|
|
300
|
+
const editCount = vanityCount;
|
|
301
|
+
const editsRemaining = Math.max(0, MAX_EDITS - editCount);
|
|
302
|
+
const limitReached = editsRemaining <= 0;
|
|
303
|
+
function mapErrorCodeToInfo(errorCode) {
|
|
304
|
+
if (!errorCode)
|
|
305
|
+
return null;
|
|
306
|
+
const errorMap = {
|
|
307
|
+
EXISTING_CODE_CONFLICT: {
|
|
308
|
+
code: "EXISTING_CODE_CONFLICT",
|
|
309
|
+
title: props.linkTakenErrorTitle,
|
|
310
|
+
description: props.linkTakenErrorDescription,
|
|
311
|
+
},
|
|
312
|
+
INVALID_CHARACTER: {
|
|
313
|
+
code: "INVALID_CHARACTER",
|
|
314
|
+
title: props.invalidCharactersErrorTitle,
|
|
315
|
+
description: props.invalidCharactersErrorDescription,
|
|
316
|
+
},
|
|
317
|
+
BLOCKED_WORD: {
|
|
318
|
+
code: "BLOCKED_WORD",
|
|
319
|
+
title: props.restrictedWordsErrorTitle,
|
|
320
|
+
description: props.restrictedWordsErrorDescription,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
return errorMap[errorCode];
|
|
324
|
+
}
|
|
325
|
+
async function onClick() {
|
|
326
|
+
if (contextData) {
|
|
327
|
+
await setCopied({ referralCode: contextData.referralCode });
|
|
328
|
+
contextData.refresh();
|
|
329
|
+
}
|
|
330
|
+
// Should well supported: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard#browser_compatibility
|
|
331
|
+
// Only if called from a user-initiated event
|
|
332
|
+
navigator.clipboard.writeText(copyString);
|
|
333
|
+
setOpen(true);
|
|
334
|
+
setTimeout(() => setOpen(false), props.tooltiplifespan);
|
|
335
|
+
sendLoadEvent({
|
|
336
|
+
eventMeta: {
|
|
337
|
+
programId,
|
|
338
|
+
id: user === null || user === void 0 ? void 0 : user.id,
|
|
339
|
+
accountId: user === null || user === void 0 ? void 0 : user.accountId,
|
|
340
|
+
type: "USER_REFERRAL_PROGRAM_ENGAGEMENT_EVENT",
|
|
341
|
+
meta: {
|
|
342
|
+
engagementMedium,
|
|
343
|
+
shareMedium: "DIRECT",
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
function onCustomizeClick() {
|
|
349
|
+
if (limitReached || customizeDisabled)
|
|
350
|
+
return;
|
|
351
|
+
setIsEditing(true);
|
|
352
|
+
setEditValue(editCount === 0 ? "" : pathSuffix);
|
|
353
|
+
setValidationError(null);
|
|
354
|
+
}
|
|
355
|
+
function onEditValueChange(value) {
|
|
356
|
+
const trimmed = value.slice(0, CHARACTER_LIMIT);
|
|
357
|
+
setEditValue(trimmed);
|
|
358
|
+
setValidationError(null);
|
|
359
|
+
if (debounceTimerRef.current)
|
|
360
|
+
clearTimeout(debounceTimerRef.current);
|
|
361
|
+
if (!trimmed || trimmed.length < MIN_CHARACTERS) {
|
|
362
|
+
setIsValidating(false);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
setIsValidating(true);
|
|
366
|
+
debounceTimerRef.current = setTimeout(async () => {
|
|
367
|
+
var _a, _b;
|
|
368
|
+
try {
|
|
369
|
+
const result = await validateLinkCode({ linkCode: trimmed });
|
|
370
|
+
if (!((_a = result === null || result === void 0 ? void 0 : result.validateLinkCode) === null || _a === void 0 ? void 0 : _a.valid)) {
|
|
371
|
+
const reason = (_b = result === null || result === void 0 ? void 0 : result.validateLinkCode) === null || _b === void 0 ? void 0 : _b.invalidReason;
|
|
372
|
+
setValidationError(mapErrorCodeToInfo(reason));
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Validation query failed — don't block the user
|
|
377
|
+
}
|
|
378
|
+
setIsValidating(false);
|
|
379
|
+
}, 2000);
|
|
380
|
+
}
|
|
381
|
+
async function onSave() {
|
|
382
|
+
var _a, _b;
|
|
383
|
+
if (!editValue ||
|
|
384
|
+
editValue.length < MIN_CHARACTERS ||
|
|
385
|
+
validationError ||
|
|
386
|
+
isValidating)
|
|
387
|
+
return;
|
|
388
|
+
try {
|
|
389
|
+
await addShareLinkCode({
|
|
390
|
+
addShareLinkCodeInput: {
|
|
391
|
+
userId: user === null || user === void 0 ? void 0 : user.id,
|
|
392
|
+
accountId: user === null || user === void 0 ? void 0 : user.accountId,
|
|
393
|
+
programId,
|
|
394
|
+
linkCode: editValue,
|
|
395
|
+
makeShareLinkCodePrimaryForReferralCode: true,
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
setIsEditing(false);
|
|
399
|
+
await Promise.all([refetch(), refetchEditCount()]);
|
|
400
|
+
refresh();
|
|
401
|
+
}
|
|
402
|
+
catch (e) {
|
|
403
|
+
const errorCode = (_a = e === null || e === void 0 ? void 0 : e.extensions) === null || _a === void 0 ? void 0 : _a.code;
|
|
404
|
+
setValidationError((_b = mapErrorCodeToInfo(errorCode)) !== null && _b !== void 0 ? _b : {
|
|
405
|
+
code: null,
|
|
406
|
+
title: "Error",
|
|
407
|
+
description: (e === null || e === void 0 ? void 0 : e.message) || "Failed to save custom link. Please try again.",
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function onCancel() {
|
|
412
|
+
setIsEditing(false);
|
|
413
|
+
setEditValue("");
|
|
414
|
+
setValidationError(null);
|
|
415
|
+
setIsValidating(false);
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
copyTextViewProps: {
|
|
419
|
+
...props,
|
|
420
|
+
onClick,
|
|
421
|
+
open,
|
|
422
|
+
copyString,
|
|
423
|
+
},
|
|
424
|
+
minCharactersText: props.minCharactersText,
|
|
425
|
+
allowCustomization: props.allowCustomization,
|
|
426
|
+
customizeLinkLabel: props.customizeLinkButtonLabel,
|
|
427
|
+
saveLabelText: props.saveLabelText,
|
|
428
|
+
cancelLabelText: props.cancelLabelText,
|
|
429
|
+
isEditing,
|
|
430
|
+
editValue,
|
|
431
|
+
domainPrefix,
|
|
432
|
+
editsRemaining,
|
|
433
|
+
maxEdits: MAX_EDITS,
|
|
434
|
+
limitReached,
|
|
435
|
+
validationError,
|
|
436
|
+
isValidating,
|
|
437
|
+
isSaving,
|
|
438
|
+
characterLimit: CHARACTER_LIMIT,
|
|
439
|
+
minCharacters: MIN_CHARACTERS,
|
|
440
|
+
charactersRemaining: CHARACTER_LIMIT - editValue.length,
|
|
441
|
+
editLimitText: props.editLimitText,
|
|
442
|
+
editLimitReachedText: props.editLimitReachedText,
|
|
443
|
+
supportLinkText: props.supportLinkText,
|
|
444
|
+
customizeDisabled,
|
|
445
|
+
customizeDisabledTooltip: props.customizeDisabledTooltip,
|
|
446
|
+
onCustomizeClick,
|
|
447
|
+
onEditValueChange,
|
|
448
|
+
onSave,
|
|
449
|
+
onCancel,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
exports.ShareLinkView = ShareLinkView;
|
|
454
|
+
exports.useShareLink = useShareLink;
|
|
@@ -123,6 +123,7 @@ const defaultCustomizeProps = {
|
|
|
123
123
|
supportLinkText: "Support",
|
|
124
124
|
customizeDisabled: false,
|
|
125
125
|
customizeDisabledTooltip: "Link customization is not available.",
|
|
126
|
+
minCharactersText: "Minimum 3 characters",
|
|
126
127
|
onCustomizeClick: noopFn,
|
|
127
128
|
onEditValueChange: noopFn,
|
|
128
129
|
onSave: noopFn,
|
|
@@ -9,7 +9,7 @@ const vanillaStyle = `
|
|
|
9
9
|
}
|
|
10
10
|
`;
|
|
11
11
|
export function ShareLinkView(props) {
|
|
12
|
-
const { copyTextViewProps, allowCustomization, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, } = props;
|
|
12
|
+
const { copyTextViewProps, allowCustomization, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, minCharactersText, } = props;
|
|
13
13
|
const style = {
|
|
14
14
|
Container: {
|
|
15
15
|
display: "flex",
|
|
@@ -140,7 +140,6 @@ export function ShareLinkView(props) {
|
|
|
140
140
|
id: "editLimitText",
|
|
141
141
|
defaultMessage: editLimitText,
|
|
142
142
|
}, { editsRemaining });
|
|
143
|
-
console.log(domainPrefix, "domain prefix");
|
|
144
143
|
// Editing state
|
|
145
144
|
if (isEditing) {
|
|
146
145
|
return (h("div", { class: sheet.classes.Container },
|
|
@@ -156,6 +155,8 @@ export function ShareLinkView(props) {
|
|
|
156
155
|
}, disabled: isSaving, maxLength: characterLimit })),
|
|
157
156
|
h("p", { class: sheet.classes.HelperText },
|
|
158
157
|
editLimitMessage,
|
|
158
|
+
" ",
|
|
159
|
+
charactersRemaining > 12 && minCharactersText,
|
|
159
160
|
showCharactersRemaining &&
|
|
160
161
|
` Characters remaining: ${charactersRemaining}`),
|
|
161
162
|
validationError && (h("sqm-form-message", { type: errorMessageType, style: { paddingBottom: "var(--sl-spacing-xx-small)" } },
|
|
@@ -112,7 +112,7 @@ export class ShareLink {
|
|
|
112
112
|
* @uiGroup Customizable Vanity Link
|
|
113
113
|
* @requiredFlavor impact
|
|
114
114
|
*/
|
|
115
|
-
this.editLimitText = "You can edit your link up to {editsRemaining} more
|
|
115
|
+
this.editLimitText = "You can edit your link up to {editsRemaining} more time(s).";
|
|
116
116
|
/**
|
|
117
117
|
* Description text shown when the link contains invalid special characters.
|
|
118
118
|
*
|
|
@@ -179,6 +179,13 @@ export class ShareLink {
|
|
|
179
179
|
* @requiredFlavor impact
|
|
180
180
|
*/
|
|
181
181
|
this.saveLabelText = "Save";
|
|
182
|
+
/**
|
|
183
|
+
* @uiName Min characters text
|
|
184
|
+
* @uiType string
|
|
185
|
+
* @uiGroup Customizable Vanity Link
|
|
186
|
+
* @requiredFlavor impact
|
|
187
|
+
*/
|
|
188
|
+
this.minCharactersText = "Minimum 3 characters.";
|
|
182
189
|
/**
|
|
183
190
|
* Display text for the support link in the edit limit reached message
|
|
184
191
|
*
|
|
@@ -680,7 +687,7 @@ export class ShareLink {
|
|
|
680
687
|
},
|
|
681
688
|
"attribute": "edit-limit-text",
|
|
682
689
|
"reflect": false,
|
|
683
|
-
"defaultValue": "\"You can edit your link up to {editsRemaining} more
|
|
690
|
+
"defaultValue": "\"You can edit your link up to {editsRemaining} more time(s).\""
|
|
684
691
|
},
|
|
685
692
|
"invalidCharactersErrorDescription": {
|
|
686
693
|
"type": "string",
|
|
@@ -901,6 +908,36 @@ export class ShareLink {
|
|
|
901
908
|
"reflect": false,
|
|
902
909
|
"defaultValue": "\"Save\""
|
|
903
910
|
},
|
|
911
|
+
"minCharactersText": {
|
|
912
|
+
"type": "string",
|
|
913
|
+
"mutable": false,
|
|
914
|
+
"complexType": {
|
|
915
|
+
"original": "string",
|
|
916
|
+
"resolved": "string",
|
|
917
|
+
"references": {}
|
|
918
|
+
},
|
|
919
|
+
"required": false,
|
|
920
|
+
"optional": true,
|
|
921
|
+
"docs": {
|
|
922
|
+
"tags": [{
|
|
923
|
+
"text": "Min characters text",
|
|
924
|
+
"name": "uiName"
|
|
925
|
+
}, {
|
|
926
|
+
"text": "string",
|
|
927
|
+
"name": "uiType"
|
|
928
|
+
}, {
|
|
929
|
+
"text": "Customizable Vanity Link",
|
|
930
|
+
"name": "uiGroup"
|
|
931
|
+
}, {
|
|
932
|
+
"text": "impact",
|
|
933
|
+
"name": "requiredFlavor"
|
|
934
|
+
}],
|
|
935
|
+
"text": ""
|
|
936
|
+
},
|
|
937
|
+
"attribute": "min-characters-text",
|
|
938
|
+
"reflect": false,
|
|
939
|
+
"defaultValue": "\"Minimum 3 characters.\""
|
|
940
|
+
},
|
|
904
941
|
"supportLinkText": {
|
|
905
942
|
"type": "string",
|
|
906
943
|
"mutable": false,
|
|
@@ -936,7 +973,7 @@ export class ShareLink {
|
|
|
936
973
|
"mutable": false,
|
|
937
974
|
"complexType": {
|
|
938
975
|
"original": "DemoData<ShareLinkViewProps>",
|
|
939
|
-
"resolved": "{ copyTextViewProps?: CopyTextViewProps; allowCustomization?: boolean; customizeLinkLabel?: string; saveLabelText?: string; cancelLabelText?: string; isEditing?: boolean; editValue?: string; domainPrefix?: string; editsRemaining?: number; maxEdits?: number; limitReached?: boolean; validationError?: ValidationErrorInfo; isValidating?: boolean; isSaving?: boolean; characterLimit?: number; minCharacters?: number; charactersRemaining?: number; editLimitText?: string; editLimitReachedText?: string; supportLinkText?: string; customizeDisabled?: boolean; customizeDisabledTooltip?: string; onCustomizeClick?: () => void; onEditValueChange?: (value: string) => void; onSave?: () => void; onCancel?: () => void; }",
|
|
976
|
+
"resolved": "{ copyTextViewProps?: CopyTextViewProps; allowCustomization?: boolean; customizeLinkLabel?: string; saveLabelText?: string; cancelLabelText?: string; isEditing?: boolean; editValue?: string; domainPrefix?: string; editsRemaining?: number; maxEdits?: number; limitReached?: boolean; validationError?: ValidationErrorInfo; isValidating?: boolean; isSaving?: boolean; characterLimit?: number; minCharacters?: number; charactersRemaining?: number; editLimitText?: string; editLimitReachedText?: string; minCharactersText?: string; supportLinkText?: string; customizeDisabled?: boolean; customizeDisabledTooltip?: string; onCustomizeClick?: () => void; onEditValueChange?: (value: string) => void; onSave?: () => void; onCancel?: () => void; }",
|
|
940
977
|
"references": {
|
|
941
978
|
"DemoData": {
|
|
942
979
|
"location": "import",
|
|
@@ -1025,6 +1062,7 @@ function useDemoShareLink(props) {
|
|
|
1025
1062
|
editLimitText: props.editLimitText,
|
|
1026
1063
|
editLimitReachedText: props.editLimitReachedText,
|
|
1027
1064
|
supportLinkText: props.supportLinkText,
|
|
1065
|
+
minCharactersText: props.minCharactersText,
|
|
1028
1066
|
customizeDisabled: false,
|
|
1029
1067
|
customizeDisabledTooltip: (_a = props.customizeDisabledTooltip) !== null && _a !== void 0 ? _a : "Link customization is not available.",
|
|
1030
1068
|
onCustomizeClick: () => {
|
|
@@ -221,7 +221,6 @@ export function useShareLink(props) {
|
|
|
221
221
|
setValidationError(null);
|
|
222
222
|
setIsValidating(false);
|
|
223
223
|
}
|
|
224
|
-
console.log(validationError, "validation error state"); // TEMP --- IGNORE ---
|
|
225
224
|
return {
|
|
226
225
|
copyTextViewProps: {
|
|
227
226
|
...props,
|
|
@@ -229,6 +228,7 @@ export function useShareLink(props) {
|
|
|
229
228
|
open,
|
|
230
229
|
copyString,
|
|
231
230
|
},
|
|
231
|
+
minCharactersText: props.minCharactersText,
|
|
232
232
|
allowCustomization: props.allowCustomization,
|
|
233
233
|
customizeLinkLabel: props.customizeLinkButtonLabel,
|
|
234
234
|
saveLabelText: props.saveLabelText,
|
|
@@ -4234,7 +4234,7 @@ const vanillaStyle$6 = `
|
|
|
4234
4234
|
}
|
|
4235
4235
|
`;
|
|
4236
4236
|
function ShareLinkView(props) {
|
|
4237
|
-
const { copyTextViewProps, allowCustomization, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, } = props;
|
|
4237
|
+
const { copyTextViewProps, allowCustomization, customizeLinkLabel, saveLabelText, cancelLabelText, isEditing, editValue, domainPrefix, editsRemaining, maxEdits, limitReached, validationError, isValidating, isSaving, characterLimit, minCharacters, charactersRemaining, editLimitText, editLimitReachedText, supportLinkText, customizeDisabled, customizeDisabledTooltip, onCustomizeClick, onEditValueChange, onSave, onCancel, minCharactersText, } = props;
|
|
4238
4238
|
const style = {
|
|
4239
4239
|
Container: {
|
|
4240
4240
|
display: "flex",
|
|
@@ -4365,7 +4365,6 @@ function ShareLinkView(props) {
|
|
|
4365
4365
|
id: "editLimitText",
|
|
4366
4366
|
defaultMessage: editLimitText,
|
|
4367
4367
|
}, { editsRemaining });
|
|
4368
|
-
console.log(domainPrefix, "domain prefix");
|
|
4369
4368
|
// Editing state
|
|
4370
4369
|
if (isEditing) {
|
|
4371
4370
|
return (h("div", { class: sheet.classes.Container },
|
|
@@ -4381,6 +4380,8 @@ function ShareLinkView(props) {
|
|
|
4381
4380
|
}, disabled: isSaving, maxLength: characterLimit })),
|
|
4382
4381
|
h("p", { class: sheet.classes.HelperText },
|
|
4383
4382
|
editLimitMessage,
|
|
4383
|
+
" ",
|
|
4384
|
+
charactersRemaining > 12 && minCharactersText,
|
|
4384
4385
|
showCharactersRemaining &&
|
|
4385
4386
|
` Characters remaining: ${charactersRemaining}`),
|
|
4386
4387
|
validationError && (h("sqm-form-message", { type: errorMessageType, style: { paddingBottom: "var(--sl-spacing-xx-small)" } },
|
|
@@ -4634,7 +4635,6 @@ function useShareLink(props) {
|
|
|
4634
4635
|
setValidationError(null);
|
|
4635
4636
|
setIsValidating(false);
|
|
4636
4637
|
}
|
|
4637
|
-
console.log(validationError, "validation error state"); // TEMP --- IGNORE ---
|
|
4638
4638
|
return {
|
|
4639
4639
|
copyTextViewProps: {
|
|
4640
4640
|
...props,
|
|
@@ -4642,6 +4642,7 @@ function useShareLink(props) {
|
|
|
4642
4642
|
open,
|
|
4643
4643
|
copyString,
|
|
4644
4644
|
},
|
|
4645
|
+
minCharactersText: props.minCharactersText,
|
|
4645
4646
|
allowCustomization: props.allowCustomization,
|
|
4646
4647
|
customizeLinkLabel: props.customizeLinkButtonLabel,
|
|
4647
4648
|
saveLabelText: props.saveLabelText,
|