PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | build/modules/connectors/index.js +225 -87 23.5.0 → trunk View file →
@@ -164,9 +164,9 @@
164 164 actionArea,
165 165 children
166 166 }) {
167 167 const headingId = (0, import_element.useId)();
168 - return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItem, { className, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 4, role: "group", "aria-labelledby": headingId, children: [
168 + return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItem, { className, role: "listitem", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 4, role: "group", "aria-labelledby": headingId, children: [
169 169 /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalHStack, { alignment: "center", spacing: 4, wrap: true, children: [
170 170 logo,
171 171 /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.FlexBlock, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 0, children: [
172 172 /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -171,9 +171,9 @@
171 171 /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.FlexBlock, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 0, children: [
172 172 /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173 173 import_components.__experimentalText,
174 174 {
175 - weight: 600,
175 + weight: "var(--wpds-typography-font-weight-emphasis, 600)",
176 176 size: 15,
177 177 id: headingId,
178 178 as: "h2",
179 179 children: name
@@ -185,8 +185,97 @@
185 185 ] }),
186 186 children
187 187 ] }) });
188 188 }
189 +function getHelpLinkLabel(helpUrl, helpLabel) {
190 + if (helpLabel) {
191 + return helpLabel;
192 + }
193 + if (!helpUrl) {
194 + return void 0;
195 + }
196 + try {
197 + return new URL(helpUrl).hostname;
198 + } catch {
199 + return helpUrl;
200 + }
201 +}
202 +function createConnectorHelpLink(helpUrl, helpLabel, message) {
203 + if (!helpUrl) {
204 + return void 0;
205 + }
206 + return (0, import_element.createInterpolateElement)(
207 + (0, import_i18n.sprintf)(message, "<a></a>"),
208 + {
209 + a: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.ExternalLink, { href: helpUrl, children: getHelpLinkLabel(helpUrl, helpLabel) })
210 + }
211 + );
212 +}
213 +function useConnectorSettingsSave(onSave, fallbackErrorMessage) {
214 + const [isSaving, setIsSaving] = (0, import_element.useState)(false);
215 + const [saveError, setSaveError] = (0, import_element.useState)(null);
216 + const handleSave = async (value) => {
217 + setSaveError(null);
218 + setIsSaving(true);
219 + try {
220 + await onSave?.(value);
221 + } catch (error) {
222 + setSaveError(
223 + error instanceof Error ? error.message : fallbackErrorMessage
224 + );
225 + } finally {
226 + setIsSaving(false);
227 + }
228 + };
229 + return {
230 + isSaving,
231 + saveError,
232 + setSaveError,
233 + handleSave
234 + };
235 +}
236 +function ConnectorSettingsFrame({
237 + readOnly,
238 + children
239 +}) {
240 + return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
241 + import_components.__experimentalVStack,
242 + {
243 + spacing: 4,
244 + className: "connector-settings",
245 + style: readOnly ? {
246 + "--wp-components-color-background": "#f0f0f0"
247 + } : void 0,
248 + children
249 + }
250 + );
251 +}
252 +function ConnectorSettingsFooter({
253 + readOnly,
254 + onRemove,
255 + canSave,
256 + isSaving,
257 + onSave
258 +}) {
259 + if (readOnly) {
260 + if (!onRemove) {
261 + return null;
262 + }
263 + return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalHStack, { justify: "flex-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Button, { variant: "link", isDestructive: true, onClick: onRemove, children: (0, import_i18n.__)("Remove and replace") }) });
264 + }
265 + return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalHStack, { justify: "flex-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
266 + import_components.Button,
267 + {
268 + __next40pxDefaultSize: true,
269 + variant: "primary",
270 + disabled: !canSave || isSaving,
271 + accessibleWhenDisabled: true,
272 + isBusy: isSaving,
273 + onClick: onSave,
274 + children: (0, import_i18n.__)("Save")
275 + }
276 + ) });
277 +}
189 278 function DefaultConnectorSettings({
190 279 onSave,
191 280 onRemove,
192 281 initialValue = "",
@@ -195,21 +284,20 @@
195 284 readOnly = false,
196 285 keySource
197 286 }) {
198 287 const [apiKey, setApiKey] = (0, import_element.useState)(initialValue);
199 - const [isSaving, setIsSaving] = (0, import_element.useState)(false);
200 - const [saveError, setSaveError] = (0, import_element.useState)(null);
201 - const helpLinkLabel = helpLabel || helpUrl?.replace(/^https?:\/\//, "");
202 - const helpLink = helpUrl ? (0, import_element.createInterpolateElement)(
203 - (0, import_i18n.sprintf)(
204 - /* translators: %s: Link to provider settings. */
205 - (0, import_i18n.__)("Get your API key at %s"),
206 - "<a></a>"
207 - ),
208 - {
209 - a: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.ExternalLink, { href: helpUrl, children: helpLinkLabel })
210 - }
211 - ) : void 0;
288 + const { isSaving, saveError, setSaveError, handleSave } = useConnectorSettingsSave(
289 + onSave,
290 + (0, import_i18n.__)(
291 + "It was not possible to connect to the provider using this key."
292 + )
293 + );
294 + const helpLink = createConnectorHelpLink(
295 + helpUrl,
296 + helpLabel,
297 + /* translators: %s: Link to provider settings. */
298 + (0, import_i18n.__)("Get your API key at %s")
299 + );
212 300 const isExternallyConfigured = keySource === "env" || keySource === "constant";
213 301 const getHelp = () => {
214 302 if (isExternallyConfigured) {
215 303 if (keySource === "env") {
@@ -221,19 +309,15 @@
221 309 return (0, import_i18n.__)("This API key is configured as a constant.");
222 310 }
223 311 }
224 312 if (readOnly) {
225 - return helpUrl ? (0, import_element.createInterpolateElement)(
226 - (0, import_i18n.sprintf)(
227 - /* translators: %s: Link to provider settings. */
228 - (0, import_i18n.__)(
229 - "Your API key is stored securely. You can manage it at %s"
230 - ),
231 - "<a></a>"
232 - ),
233 - {
234 - a: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.ExternalLink, { href: helpUrl, children: helpLinkLabel })
235 - }
313 + return helpUrl ? createConnectorHelpLink(
314 + helpUrl,
315 + helpLabel,
316 + /* translators: %s: Link to provider settings. */
317 + (0, import_i18n.__)(
318 + "Your API key is stored securely. You can manage it at %s"
319 + )
236 320 ) : (0, import_i18n.__)("Your API key is stored securely.");
237 321 }
238 322 if (saveError) {
239 323 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "connector-settings__error", children: saveError });
@@ -239,72 +323,125 @@
239 323 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "connector-settings__error", children: saveError });
240 324 }
241 325 return helpLink;
242 326 };
243 - const handleSave = async () => {
244 - setSaveError(null);
245 - setIsSaving(true);
246 - try {
247 - await onSave?.(apiKey);
248 - } catch (error) {
249 - setSaveError(
250 - error instanceof Error ? error.message : (0, import_i18n.__)(
251 - "It was not possible to connect to the provider using this key."
252 - )
253 - );
254 - } finally {
255 - setIsSaving(false);
256 - }
257 - };
258 - return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
259 - import_components.__experimentalVStack,
260 - {
261 - spacing: 4,
262 - className: "connector-settings",
263 - style: readOnly ? {
264 - "--wp-components-color-background": "#f0f0f0"
265 - } : void 0,
266 - children: [
267 - /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
268 - import_components.TextControl,
269 - {
270 - label: (0, import_i18n.__)("API Key"),
271 - value: apiKey,
272 - onChange: (value) => {
273 - if (!readOnly) {
274 - setSaveError(null);
275 - setApiKey(value);
276 - }
277 - },
278 - placeholder: (0, import_i18n.__)("Enter your API key"),
279 - disabled: readOnly || isSaving,
280 - autoComplete: "off",
281 - help: getHelp()
327 + return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ConnectorSettingsFrame, { readOnly, children: [
328 + /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
329 + import_components.TextControl,
330 + {
331 + label: (0, import_i18n.__)("API Key"),
332 + value: apiKey,
333 + onChange: (value) => {
334 + if (!readOnly) {
335 + setSaveError(null);
336 + setApiKey(value);
282 337 }
283 - ),
284 - readOnly ? onRemove && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalHStack, { justify: "flex-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
285 - import_components.Button,
286 - {
287 - variant: "link",
288 - isDestructive: true,
289 - onClick: onRemove,
290 - children: (0, import_i18n.__)("Remove and replace")
338 + },
339 + placeholder: (0, import_i18n.__)("Enter your API key"),
340 + disabled: readOnly || isSaving,
341 + autoComplete: "off",
342 + help: getHelp()
343 + }
344 + ),
345 + /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
346 + ConnectorSettingsFooter,
347 + {
348 + readOnly,
349 + onRemove,
350 + canSave: !!apiKey,
351 + isSaving,
352 + onSave: () => handleSave(apiKey)
353 + }
354 + )
355 + ] });
356 +}
357 +function ApplicationPasswordConnectorSettings({
358 + onSave,
359 + onRemove,
360 + initialUsername = "",
361 + helpUrl,
362 + helpLabel,
363 + readOnly = false,
364 + keySource
365 +}) {
366 + const [username, setUsername] = (0, import_element.useState)(initialUsername);
367 + const [applicationPassword, setApplicationPassword] = (0, import_element.useState)("");
368 + const { isSaving, saveError, setSaveError, handleSave } = useConnectorSettingsSave(
369 + onSave,
370 + (0, import_i18n.__)("It was not possible to save these credentials.")
371 + );
372 + const help = createConnectorHelpLink(
373 + helpUrl,
374 + helpLabel,
375 + /* translators: %s: Link to the remote site's application passwords screen. */
376 + (0, import_i18n.__)("Create an application password at %s")
377 + );
378 + let applicationPasswordHelp = help;
379 + if (keySource === "env") {
380 + applicationPasswordHelp = (0, import_i18n.__)(
381 + "These credentials are configured using an environment variable."
382 + );
383 + } else if (keySource === "constant") {
384 + applicationPasswordHelp = (0, import_i18n.__)(
385 + "These credentials are configured as a constant."
386 + );
387 + } else if (readOnly) {
388 + applicationPasswordHelp = (0, import_i18n.__)(
389 + "Your application password is stored securely."
390 + );
391 + }
392 + if (saveError) {
393 + applicationPasswordHelp = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "connector-settings__error", children: saveError });
394 + }
395 + return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ConnectorSettingsFrame, { readOnly, children: [
396 + /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
397 + import_components.TextControl,
398 + {
399 + label: (0, import_i18n.__)("Username"),
400 + value: username,
401 + onChange: (value) => {
402 + if (!readOnly) {
403 + setSaveError(null);
404 + setUsername(value);
291 405 }
292 - ) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalHStack, { justify: "flex-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
293 - import_components.Button,
294 - {
295 - __next40pxDefaultSize: true,
296 - variant: "primary",
297 - disabled: !apiKey || isSaving,
298 - accessibleWhenDisabled: true,
299 - isBusy: isSaving,
300 - onClick: handleSave,
301 - children: (0, import_i18n.__)("Save")
406 + },
407 + placeholder: (0, import_i18n.__)("Enter your username"),
408 + disabled: readOnly || isSaving,
409 + autoComplete: "username"
410 + }
411 + ),
412 + /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
413 + import_components.TextControl,
414 + {
415 + label: (0, import_i18n.__)("Application password"),
416 + value: readOnly ? "••••••••••••••••" : applicationPassword,
417 + onChange: (value) => {
418 + if (!readOnly) {
419 + setSaveError(null);
420 + setApplicationPassword(value);
302 421 }
303 - ) })
304 - ]
305 - }
306 - );
422 + },
423 + type: "password",
424 + placeholder: (0, import_i18n.__)("Enter your application password"),
425 + disabled: readOnly || isSaving,
426 + autoComplete: "new-password",
427 + help: applicationPasswordHelp
428 + }
429 + ),
430 + /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
431 + ConnectorSettingsFooter,
432 + {
433 + readOnly,
434 + onRemove,
435 + canSave: !!username.trim() && !!applicationPassword,
436 + isSaving,
437 + onSave: () => handleSave({
438 + username: username.trim(),
439 + applicationPassword
440 + })
441 + }
442 + )
443 + ] });
307 444 }
308 445
309 446 // packages/connectors/build-module/private-apis.mjs
310 447 var privateApis = {};
@@ -309,8 +446,9 @@
309 446 // packages/connectors/build-module/private-apis.mjs
310 447 var privateApis = {};
311 448 lock(privateApis, { store, STORE_NAME });
312 449 export {
450 + ApplicationPasswordConnectorSettings as __experimentalApplicationPasswordConnectorSettings,
313 451 ConnectorItem as __experimentalConnectorItem,
314 452 DefaultConnectorSettings as __experimentalDefaultConnectorSettings,
315 453 registerConnector as __experimentalRegisterConnector,
316 454 unregisterConnector as __experimentalUnregisterConnector,