@saasquatch/mint-components 2.1.8-26 → 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-1bc48666.js → ShadowViewAddon-363fcb59.js} +8 -5
- 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 +7 -4
- 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-10db3e11.js → ShadowViewAddon-667b4e9b.js} +8 -5
- 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-10db3e11.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-a4f44c57.entry.js → p-154642b1.entry.js} +2 -2
- package/dist/mint-components/{p-72055e41.js → p-17ebb16a.js} +2 -2
- package/dist/mint-components/{p-6d10c03c.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-0b5dd21b.system.js → p-609d0fc4.system.js} +1 -1
- package/dist/mint-components/{p-4df9c93e.system.entry.js → p-627789fa.system.entry.js} +1 -1
- package/dist/mint-components/{p-840157bd.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",
|
|
@@ -18,6 +18,7 @@ export function ShareLinkView(props) {
|
|
|
18
18
|
width: "100%",
|
|
19
19
|
},
|
|
20
20
|
CustomizeLinkText: {
|
|
21
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
21
22
|
margin: "0",
|
|
22
23
|
fontSize: "var(--sl-font-size-small)",
|
|
23
24
|
fontWeight: "600",
|
|
@@ -29,6 +30,7 @@ export function ShareLinkView(props) {
|
|
|
29
30
|
},
|
|
30
31
|
},
|
|
31
32
|
CustomizeLinkDisabled: {
|
|
33
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
32
34
|
margin: "0",
|
|
33
35
|
fontSize: "var(--sl-font-size-small)",
|
|
34
36
|
fontWeight: "600",
|
|
@@ -81,6 +83,7 @@ export function ShareLinkView(props) {
|
|
|
81
83
|
color: "var(--sl-color-neutral-500)",
|
|
82
84
|
},
|
|
83
85
|
HelperText: {
|
|
86
|
+
paddingTop: "var(--sl-spacing-xx-small)",
|
|
84
87
|
margin: "0",
|
|
85
88
|
fontSize: "var(--sl-font-size-small)",
|
|
86
89
|
color: "var(--sl-color-neutral-500)",
|
|
@@ -137,7 +140,6 @@ export function ShareLinkView(props) {
|
|
|
137
140
|
id: "editLimitText",
|
|
138
141
|
defaultMessage: editLimitText,
|
|
139
142
|
}, { editsRemaining });
|
|
140
|
-
console.log(domainPrefix, "domain prefix");
|
|
141
143
|
// Editing state
|
|
142
144
|
if (isEditing) {
|
|
143
145
|
return (h("div", { class: sheet.classes.Container },
|
|
@@ -153,6 +155,8 @@ export function ShareLinkView(props) {
|
|
|
153
155
|
}, disabled: isSaving, maxLength: characterLimit })),
|
|
154
156
|
h("p", { class: sheet.classes.HelperText },
|
|
155
157
|
editLimitMessage,
|
|
158
|
+
" ",
|
|
159
|
+
charactersRemaining > 12 && minCharactersText,
|
|
156
160
|
showCharactersRemaining &&
|
|
157
161
|
` Characters remaining: ${charactersRemaining}`),
|
|
158
162
|
validationError && (h("sqm-form-message", { type: errorMessageType, style: { paddingBottom: "var(--sl-spacing-xx-small)" } },
|
|
@@ -183,7 +187,6 @@ export function ShareLinkView(props) {
|
|
|
183
187
|
id: "editLimitReached",
|
|
184
188
|
defaultMessage: editLimitReachedText,
|
|
185
189
|
}, {
|
|
186
|
-
supportLink: (h("a", { target: "_blank", href: "https://help.impact.com/other/readme/get-help-and-support" },
|
|
187
|
-
h("p", null, supportLinkText))),
|
|
190
|
+
supportLink: (h("a", { target: "_blank", href: "https://help.impact.com/other/readme/get-help-and-support" }, supportLinkText)),
|
|
188
191
|
}))))))));
|
|
189
192
|
}
|
|
@@ -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,
|