@sparkelf/dsh-dataops-managed 0.3.5 → 0.3.7

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/lib/client.js CHANGED
@@ -97,34 +97,34 @@ window.__ModuleLoader__.load({
97
97
  }
98
98
  //#endregion
99
99
  //#region \0dsh-css:/root/projects/dsh-plugins-plus/packages/dataops-managed/src/client/ManagedDataOpsSection.module.css.mjs
100
- const css$1 = "._2dqzjG_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}._2dqzjG_title{margin:0;font-size:16px;font-weight:500;line-height:24px}._2dqzjG_statusRow{align-items:center;gap:8px;min-height:24px;font-size:14px;line-height:22px;display:flex}._2dqzjG_description{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}._2dqzjG_details{border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0 0}._2dqzjG_detailRow{border-bottom:1px solid var(--dsw-alias-border-l2);grid-template-columns:minmax(140px,2fr) minmax(0,3fr);gap:20px;padding:12px 0;display:grid}._2dqzjG_detailRow dt,._2dqzjG_detailRow dd{margin:0;font-size:14px;line-height:22px}._2dqzjG_detailRow dt{color:var(--dsw-alias-label-secondary)}._2dqzjG_detailRow dd{color:var(--dsw-alias-label-primary)}._2dqzjG_brandingRow{border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:20px;padding:12px 0;display:flex}._2dqzjG_brandingCopy{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}._2dqzjG_brandingCopy strong{font-size:14px;font-weight:500;line-height:22px}._2dqzjG_brandingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._2dqzjG_switch{background:var(--dsw-alias-border-l1);cursor:pointer;border:0;border-radius:10px;flex:none;width:34px;height:20px;padding:0;transition:background-color .12s;position:relative}._2dqzjG_switch>span{background:var(--dsw-alias-bg-base);border-radius:50%;width:14px;height:14px;transition:transform .12s;position:absolute;top:3px;left:3px;box-shadow:0 1px 2px #0003}._2dqzjG_switch[data-checked=true]{background:var(--dsw-alias-state-business-primary)}._2dqzjG_switch[data-checked=true]>span{transform:translate(14px)}._2dqzjG_switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}@media (prefers-reduced-motion:reduce){._2dqzjG_switch,._2dqzjG_switch>span{transition:none}}._2dqzjG_modelPanel{border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:12px 0;display:flex}._2dqzjG_modelTitle{margin:0;font-size:14px;font-weight:500;line-height:22px}._2dqzjG_modelDescription{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._2dqzjG_modelList{flex-direction:column;gap:8px;padding-top:4px;display:flex}._2dqzjG_modelListTitle{font-size:13px;font-weight:500;line-height:20px}._2dqzjG_modelListDescription{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._2dqzjG_modelRow{align-items:center;gap:16px;min-height:28px;display:flex}._2dqzjG_modelId{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;line-height:20px;overflow:hidden}._2dqzjG_modelAction{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:5px 12px;font-size:13px;line-height:20px}._2dqzjG_modelAction:hover:not(:disabled){background:var(--dsw-alias-bg-hover)}._2dqzjG_modelAction:disabled,._2dqzjG_switch:disabled{cursor:default;opacity:.5}";
101
- const tagId$1 = "@sparkelf/dsh-dataops-managed/ManagedDataOpsSection.module.css";
102
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
100
+ const css$2 = "._2dqzjG_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}._2dqzjG_title{margin:0;font-size:16px;font-weight:500;line-height:24px}._2dqzjG_statusRow{align-items:center;gap:8px;min-height:24px;font-size:14px;line-height:22px;display:flex}._2dqzjG_description{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}._2dqzjG_details{border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0 0}._2dqzjG_detailRow{border-bottom:1px solid var(--dsw-alias-border-l2);grid-template-columns:minmax(140px,2fr) minmax(0,3fr);gap:20px;padding:12px 0;display:grid}._2dqzjG_detailRow dt,._2dqzjG_detailRow dd{margin:0;font-size:14px;line-height:22px}._2dqzjG_detailRow dt{color:var(--dsw-alias-label-secondary)}._2dqzjG_detailRow dd{color:var(--dsw-alias-label-primary)}._2dqzjG_brandingRow{border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:20px;padding:12px 0;display:flex}._2dqzjG_brandingCopy{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}._2dqzjG_brandingCopy strong{font-size:14px;font-weight:500;line-height:22px}._2dqzjG_brandingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._2dqzjG_switch{background:var(--dsw-alias-border-l1);cursor:pointer;border:0;border-radius:10px;flex:none;width:34px;height:20px;padding:0;transition:background-color .12s;position:relative}._2dqzjG_switch>span{background:var(--dsw-alias-bg-base);border-radius:50%;width:14px;height:14px;transition:transform .12s;position:absolute;top:3px;left:3px;box-shadow:0 1px 2px #0003}._2dqzjG_switch[data-checked=true]{background:var(--dsw-alias-state-business-primary)}._2dqzjG_switch[data-checked=true]>span{transform:translate(14px)}._2dqzjG_switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}@media (prefers-reduced-motion:reduce){._2dqzjG_switch,._2dqzjG_switch>span{transition:none}}._2dqzjG_modelPanel{border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:12px 0;display:flex}._2dqzjG_modelTitle{margin:0;font-size:14px;font-weight:500;line-height:22px}._2dqzjG_modelDescription{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._2dqzjG_modelList{flex-direction:column;gap:8px;padding-top:4px;display:flex}._2dqzjG_modelListTitle{font-size:13px;font-weight:500;line-height:20px}._2dqzjG_modelListDescription{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._2dqzjG_modelRow{align-items:center;gap:16px;min-height:28px;display:flex}._2dqzjG_modelId{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;line-height:20px;overflow:hidden}._2dqzjG_modelAction{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:5px 12px;font-size:13px;line-height:20px}._2dqzjG_modelAction:hover:not(:disabled){background:var(--dsw-alias-bg-hover)}._2dqzjG_modelAction:disabled,._2dqzjG_switch:disabled{cursor:default;opacity:.5}";
101
+ const tagId$2 = "@sparkelf/dsh-dataops-managed/ManagedDataOpsSection.module.css";
102
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
103
103
  const tag = document.createElement("style");
104
104
  tag.dataset.plugin = "@sparkelf/dsh-dataops-managed";
105
- tag.dataset.pluginCss = tagId$1;
106
- tag.textContent = css$1;
105
+ tag.dataset.pluginCss = tagId$2;
106
+ tag.textContent = css$2;
107
107
  document.head.appendChild(tag);
108
108
  }
109
109
  var ManagedDataOpsSection_module_css_default = {
110
- "modelRow": "_2dqzjG_modelRow",
111
110
  "modelList": "_2dqzjG_modelList",
112
- "brandingCopy": "_2dqzjG_brandingCopy",
113
- "detailRow": "_2dqzjG_detailRow",
114
- "title": "_2dqzjG_title",
115
- "modelPanel": "_2dqzjG_modelPanel",
116
- "brandingRow": "_2dqzjG_brandingRow",
117
- "description": "_2dqzjG_description",
118
- "modelDescription": "_2dqzjG_modelDescription",
119
- "section": "_2dqzjG_section",
120
111
  "modelId": "_2dqzjG_modelId",
112
+ "modelDescription": "_2dqzjG_modelDescription",
113
+ "detailRow": "_2dqzjG_detailRow",
121
114
  "modelAction": "_2dqzjG_modelAction",
122
- "details": "_2dqzjG_details",
123
- "modelListDescription": "_2dqzjG_modelListDescription",
124
- "statusRow": "_2dqzjG_statusRow",
115
+ "section": "_2dqzjG_section",
116
+ "modelTitle": "_2dqzjG_modelTitle",
125
117
  "modelListTitle": "_2dqzjG_modelListTitle",
118
+ "details": "_2dqzjG_details",
126
119
  "switch": "_2dqzjG_switch",
127
- "modelTitle": "_2dqzjG_modelTitle"
120
+ "statusRow": "_2dqzjG_statusRow",
121
+ "title": "_2dqzjG_title",
122
+ "modelListDescription": "_2dqzjG_modelListDescription",
123
+ "modelPanel": "_2dqzjG_modelPanel",
124
+ "description": "_2dqzjG_description",
125
+ "brandingRow": "_2dqzjG_brandingRow",
126
+ "modelRow": "_2dqzjG_modelRow",
127
+ "brandingCopy": "_2dqzjG_brandingCopy"
128
128
  };
129
129
  //#endregion
130
130
  //#region src/client/ManagedDataOpsSection.tsx
@@ -342,6 +342,279 @@ window.__ModuleLoader__.load({
342
342
  });
343
343
  }
344
344
  //#endregion
345
+ //#region src/client/skill-plaza-client.ts
346
+ /** Same-origin skill plaza calls from the DataOps skill center section. */
347
+ /** Route the plugin's Host half serves for the plaza. */
348
+ const SKILL_PLAZA_PATH = "/integrations/dataops/skill-plaza";
349
+ /** Narrow an unknown value to a plaza entry. */
350
+ function asSkill(value) {
351
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
352
+ const row = value;
353
+ if (typeof row.id !== "number" || typeof row.name !== "string") return null;
354
+ return {
355
+ id: row.id,
356
+ name: row.name,
357
+ description: typeof row.description === "string" ? row.description : void 0,
358
+ instruction: typeof row.instruction === "string" ? row.instruction : "",
359
+ tags: Array.isArray(row.tags) ? row.tags.filter((tag) => typeof tag === "string") : [],
360
+ sharedByMe: row.sharedByMe === true,
361
+ updatedAt: typeof row.updatedAt === "string" ? row.updatedAt : ""
362
+ };
363
+ }
364
+ /** Narrow an unknown value to the listing. */
365
+ function asListing(value) {
366
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
367
+ const row = value;
368
+ return {
369
+ skills: Array.isArray(row.skills) ? row.skills.flatMap((entry) => asSkill(entry) ?? []) : [],
370
+ tags: Array.isArray(row.tags) ? row.tags.filter((tag) => typeof tag === "string") : []
371
+ };
372
+ }
373
+ /**
374
+ * Read the plaza.
375
+ * @param filter - Optional tag and text filters.
376
+ * @returns The listing, or null when this workspace is not connected to DataOps.
377
+ */
378
+ async function fetchPlaza(filter = {}) {
379
+ const params = new URLSearchParams();
380
+ if (filter.tag !== void 0 && filter.tag !== "") params.set("tag", filter.tag);
381
+ if (filter.query !== void 0 && filter.query !== "") params.set("q", filter.query);
382
+ const suffix = params.size === 0 ? "" : "?" + params.toString();
383
+ const response = await fetch(SKILL_PLAZA_PATH + suffix, { headers: { accept: "application/json" } });
384
+ if (response.status === 503) return null;
385
+ if (!response.ok) throw new Error("skill plaza read failed with HTTP " + String(response.status));
386
+ return asListing(await response.json());
387
+ }
388
+ /**
389
+ * Change the plaza.
390
+ * @param body - Action and its parameters.
391
+ * @returns The parsed reply, or null when the plugin is not active.
392
+ */
393
+ async function postPlazaAction(body) {
394
+ const response = await fetch(SKILL_PLAZA_PATH, {
395
+ method: "POST",
396
+ headers: {
397
+ "content-type": "application/json",
398
+ accept: "application/json"
399
+ },
400
+ body: JSON.stringify(body)
401
+ });
402
+ if (response.status === 503) return null;
403
+ if (!response.ok) throw new Error("skill plaza action failed with HTTP " + String(response.status));
404
+ return await response.json();
405
+ }
406
+ //#endregion
407
+ //#region \0dsh-css:/root/projects/dsh-plugins-plus/packages/dataops-managed/src/client/SkillPlazaSection.module.css.mjs
408
+ const css$1 = "._9FdZvq_section{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;margin-top:20px;padding-top:16px;display:flex}._9FdZvq_title{margin:0;font-size:16px;font-weight:500;line-height:24px}._9FdZvq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px;line-height:20px}._9FdZvq_filters{gap:10px;display:flex}._9FdZvq_search{border:1px solid var(--dsw-alias-border-l1);min-width:0;color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}._9FdZvq_tagSelect{border:1px solid var(--dsw-alias-border-l1);max-width:180px;color:inherit;background:0 0;border-radius:6px;flex:none;padding:6px 10px;font-size:13px}._9FdZvq_notice{color:var(--dsw-alias-state-business-primary);margin:0;font-size:12px;line-height:18px}._9FdZvq_cards{flex-direction:column;gap:10px;margin:0;padding:0;list-style:none;display:flex}._9FdZvq_card{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:6px;padding:12px;display:flex}._9FdZvq_cardHead{align-items:center;gap:8px;display:flex}._9FdZvq_cardName{font-size:14px;font-weight:500;line-height:22px}._9FdZvq_mine{background:var(--dsw-alias-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:1px 6px;font-size:11px;line-height:16px}._9FdZvq_cardDesc{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._9FdZvq_tags{flex-wrap:wrap;gap:6px;display:flex}._9FdZvq_tag{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);border-radius:10px;padding:1px 7px;font-size:11px;line-height:16px}._9FdZvq_cardActions{gap:8px;padding-top:2px;display:flex}";
409
+ const tagId$1 = "@sparkelf/dsh-dataops-managed/SkillPlazaSection.module.css";
410
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
411
+ const tag = document.createElement("style");
412
+ tag.dataset.plugin = "@sparkelf/dsh-dataops-managed";
413
+ tag.dataset.pluginCss = tagId$1;
414
+ tag.textContent = css$1;
415
+ document.head.appendChild(tag);
416
+ }
417
+ var SkillPlazaSection_module_css_default = {
418
+ "cardDesc": "_9FdZvq_cardDesc",
419
+ "tags": "_9FdZvq_tags",
420
+ "title": "_9FdZvq_title",
421
+ "cardHead": "_9FdZvq_cardHead",
422
+ "cardActions": "_9FdZvq_cardActions",
423
+ "tag": "_9FdZvq_tag",
424
+ "section": "_9FdZvq_section",
425
+ "card": "_9FdZvq_card",
426
+ "cardName": "_9FdZvq_cardName",
427
+ "search": "_9FdZvq_search",
428
+ "intro": "_9FdZvq_intro",
429
+ "notice": "_9FdZvq_notice",
430
+ "cards": "_9FdZvq_cards",
431
+ "tagSelect": "_9FdZvq_tagSelect",
432
+ "mine": "_9FdZvq_mine",
433
+ "filters": "_9FdZvq_filters"
434
+ };
435
+ //#endregion
436
+ //#region src/client/SkillPlazaSection.tsx
437
+ /**
438
+ * Browse, share, and install skills other users published.
439
+ *
440
+ * The section appears only where this plugin is installed: the skill center renders the slot,
441
+ * and an empty slot renders nothing. Every action goes through this plugin's Host route, so a
442
+ * workspace without DataOps never reaches these calls.
443
+ * @param props - Skill center injection values.
444
+ * @returns The plaza section, or nothing before injection.
445
+ */
446
+ function SkillPlazaSection(props) {
447
+ const { t } = props;
448
+ const [state, setState] = (0, react.useState)({ kind: "loading" });
449
+ const [tag, setTag] = (0, react.useState)("");
450
+ const [query, setQuery] = (0, react.useState)("");
451
+ const [busy, setBusy] = (0, react.useState)(false);
452
+ const [notice, setNotice] = (0, react.useState)(null);
453
+ const load = (0, react.useCallback)(async (filter) => {
454
+ try {
455
+ const listing = await fetchPlaza(filter);
456
+ setState(listing === null ? { kind: "unavailable" } : {
457
+ kind: "ready",
458
+ listing
459
+ });
460
+ } catch {
461
+ setState({ kind: "failed" });
462
+ }
463
+ }, []);
464
+ (0, react.useEffect)(() => {
465
+ load({});
466
+ }, [load]);
467
+ const refresh = (0, react.useCallback)(async (nextTag = tag, nextQuery = query) => {
468
+ await load({
469
+ tag: nextTag,
470
+ query: nextQuery
471
+ });
472
+ }, [
473
+ load,
474
+ tag,
475
+ query
476
+ ]);
477
+ const act = (0, react.useCallback)(async (body, message) => {
478
+ setBusy(true);
479
+ setNotice(null);
480
+ try {
481
+ await postPlazaAction(body);
482
+ setNotice(message);
483
+ await refresh();
484
+ } catch {
485
+ setNotice(t === void 0 ? null : t("plazaActionFailed"));
486
+ } finally {
487
+ setBusy(false);
488
+ }
489
+ }, [refresh, t]);
490
+ if (t === void 0) return null;
491
+ if (state.kind === "loading") return null;
492
+ if (state.kind === "unavailable") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
493
+ className: SkillPlazaSection_module_css_default.section,
494
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
495
+ className: SkillPlazaSection_module_css_default.title,
496
+ children: t("plazaTitle")
497
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
498
+ className: SkillPlazaSection_module_css_default.intro,
499
+ children: t("plazaUnavailable")
500
+ })]
501
+ });
502
+ if (state.kind === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
503
+ className: SkillPlazaSection_module_css_default.section,
504
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
505
+ className: SkillPlazaSection_module_css_default.title,
506
+ children: t("plazaTitle")
507
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
508
+ className: SkillPlazaSection_module_css_default.intro,
509
+ role: "alert",
510
+ children: t("plazaLoadFailed")
511
+ })]
512
+ });
513
+ const { listing } = state;
514
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
515
+ className: SkillPlazaSection_module_css_default.section,
516
+ children: [
517
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
518
+ className: SkillPlazaSection_module_css_default.title,
519
+ children: t("plazaTitle")
520
+ }),
521
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
522
+ className: SkillPlazaSection_module_css_default.intro,
523
+ children: t("plazaIntro")
524
+ }),
525
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
526
+ className: SkillPlazaSection_module_css_default.filters,
527
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
528
+ className: SkillPlazaSection_module_css_default.search,
529
+ placeholder: t("plazaSearch"),
530
+ value: query,
531
+ onChange: (event) => {
532
+ setQuery(event.target.value);
533
+ }
534
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
535
+ className: SkillPlazaSection_module_css_default.tagSelect,
536
+ "aria-label": t("plazaTagFilter"),
537
+ value: tag,
538
+ onChange: (event) => {
539
+ setTag(event.target.value);
540
+ refresh(event.target.value, query);
541
+ },
542
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
543
+ value: "",
544
+ children: t("plazaAllTags")
545
+ }), listing.tags.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
546
+ value: item,
547
+ children: item
548
+ }, item))]
549
+ })]
550
+ }),
551
+ notice === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
552
+ className: SkillPlazaSection_module_css_default.notice,
553
+ children: notice
554
+ }),
555
+ listing.skills.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
556
+ className: SkillPlazaSection_module_css_default.intro,
557
+ children: t("plazaEmpty")
558
+ }) : null,
559
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
560
+ className: SkillPlazaSection_module_css_default.cards,
561
+ children: listing.skills.map((skill) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
562
+ className: SkillPlazaSection_module_css_default.card,
563
+ children: [
564
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
565
+ className: SkillPlazaSection_module_css_default.cardHead,
566
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
567
+ className: SkillPlazaSection_module_css_default.cardName,
568
+ children: skill.name
569
+ }), skill.sharedByMe ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
570
+ className: SkillPlazaSection_module_css_default.mine,
571
+ children: t("plazaMine")
572
+ }) : null]
573
+ }),
574
+ skill.description === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
575
+ className: SkillPlazaSection_module_css_default.cardDesc,
576
+ children: skill.description
577
+ }),
578
+ skill.tags.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
579
+ className: SkillPlazaSection_module_css_default.tags,
580
+ children: skill.tags.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
581
+ className: SkillPlazaSection_module_css_default.tag,
582
+ children: item
583
+ }, item))
584
+ }),
585
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
586
+ className: SkillPlazaSection_module_css_default.cardActions,
587
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
588
+ variant: "primary",
589
+ size: "sm",
590
+ disabled: busy,
591
+ onClick: () => {
592
+ act({
593
+ action: "install",
594
+ id: skill.id
595
+ }, t("plazaInstalled"));
596
+ },
597
+ children: t("plazaInstall")
598
+ }), skill.sharedByMe ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
599
+ variant: "outline",
600
+ size: "sm",
601
+ disabled: busy,
602
+ onClick: () => {
603
+ act({
604
+ action: "unshare",
605
+ id: skill.id
606
+ }, t("plazaUnshared"));
607
+ },
608
+ children: t("plazaUnshare")
609
+ }) : null]
610
+ })
611
+ ]
612
+ }, skill.id))
613
+ })
614
+ ]
615
+ });
616
+ }
617
+ //#endregion
345
618
  //#region \0dsh-css:/root/projects/dsh-plugins-plus/packages/dataops-managed/src/client/WanxiangBrand.module.css.mjs
346
619
  const css = ".s0HPxG_mark{color:inherit;flex:none;display:block;overflow:visible}.s0HPxG_animatedMark{cursor:pointer}.s0HPxG_mark g{transform-box:fill-box;transform-origin:50%}.s0HPxG_sidebarName{min-width:0;height:24px;color:inherit;align-items:center;gap:6px;display:inline-flex}.s0HPxG_sidebarName>svg:first-child{flex:0 auto;min-width:0;max-width:102px}.s0HPxG_harness{flex:none;display:block;overflow:visible}@keyframes s0HPxG_unit-top{0%,to{transform:translate(0)}50%{transform:translateY(-2px)}}@keyframes s0HPxG_unit-left{0%,to{transform:translate(0)}50%{transform:translate(-2px,1px)}}@keyframes s0HPxG_unit-right{0%,to{transform:translate(0)}50%{transform:translate(2px,1px)}}@keyframes s0HPxG_unit-core{0%,to{transform:translate(0)}50%{transform:translateY(2px)}}@media (hover:hover) and (prefers-reduced-motion:no-preference){.s0HPxG_animatedMark:hover .s0HPxG_unitTop{animation:1.6s ease-in-out infinite s0HPxG_unit-top}.s0HPxG_animatedMark:hover .s0HPxG_unitLeft{animation:1.6s ease-in-out infinite s0HPxG_unit-left}.s0HPxG_animatedMark:hover .s0HPxG_unitRight{animation:1.6s ease-in-out infinite s0HPxG_unit-right}.s0HPxG_animatedMark:hover .s0HPxG_unitCore{animation:1.6s ease-in-out infinite s0HPxG_unit-core}}@media (prefers-reduced-motion:reduce){.s0HPxG_animatedMark,.s0HPxG_animatedMark g{animation:none!important;transform:none!important}}";
347
620
  const tagId = "@sparkelf/dsh-dataops-managed/WanxiangBrand.module.css";
@@ -353,18 +626,18 @@ window.__ModuleLoader__.load({
353
626
  document.head.appendChild(tag);
354
627
  }
355
628
  var WanxiangBrand_module_css_default = {
356
- "sidebarName": "s0HPxG_sidebarName",
357
- "harness": "s0HPxG_harness",
629
+ "unit-left": "s0HPxG_unit-left",
358
630
  "animatedMark": "s0HPxG_animatedMark",
359
- "unit-top": "s0HPxG_unit-top",
631
+ "harness": "s0HPxG_harness",
360
632
  "unit-right": "s0HPxG_unit-right",
361
- "unitLeft": "s0HPxG_unitLeft",
362
- "unitCore": "s0HPxG_unitCore",
363
- "mark": "s0HPxG_mark",
364
- "unit-left": "s0HPxG_unit-left",
365
633
  "unit-core": "s0HPxG_unit-core",
634
+ "unitLeft": "s0HPxG_unitLeft",
635
+ "unitRight": "s0HPxG_unitRight",
636
+ "sidebarName": "s0HPxG_sidebarName",
366
637
  "unitTop": "s0HPxG_unitTop",
367
- "unitRight": "s0HPxG_unitRight"
638
+ "mark": "s0HPxG_mark",
639
+ "unitCore": "s0HPxG_unitCore",
640
+ "unit-top": "s0HPxG_unit-top"
368
641
  };
369
642
  //#endregion
370
643
  //#region src/client/WanxiangBrand.tsx
@@ -666,7 +939,21 @@ window.__ModuleLoader__.load({
666
939
  modelsListDescription: "A model turned off here stays available in this workspace and is not offered to other users.",
667
940
  modelShareLabel: "Available to other users",
668
941
  modelsEmpty: "No models are configured in this workspace yet. Add them in Models settings first.",
669
- loadFailed: "The model configuration could not be loaded. Try again."
942
+ loadFailed: "The model configuration could not be loaded. Try again.",
943
+ plazaTitle: "Skill plaza",
944
+ plazaIntro: "Skills other users shared. Install one to use it in this workspace, or share a skill of your own.",
945
+ plazaSearch: "Search skills",
946
+ plazaTagFilter: "Filter by tag",
947
+ plazaAllTags: "All tags",
948
+ plazaMine: "Shared by me",
949
+ plazaInstall: "Install",
950
+ plazaInstalled: "Installed. It is now in your skill list.",
951
+ plazaUnshare: "Stop sharing",
952
+ plazaUnshared: "Removed from the plaza. Users who installed it keep their copy.",
953
+ plazaEmpty: "No skills have been shared yet.",
954
+ plazaUnavailable: "The skill plaza is available once this workspace is connected to DataOps.",
955
+ plazaLoadFailed: "The skill plaza could not be loaded. Try again.",
956
+ plazaActionFailed: "The action could not be completed. Try again."
670
957
  };
671
958
  /** Chinese managed DataOps Settings copy. */
672
959
  const zh = {
@@ -698,7 +985,21 @@ window.__ModuleLoader__.load({
698
985
  modelsListDescription: "在这里关闭的模型,本工作区仍可使用,只是不提供给其他用户。",
699
986
  modelShareLabel: "提供给其他用户使用",
700
987
  modelsEmpty: "本工作区还没有配置模型,请先在模型设置中添加。",
701
- loadFailed: "模型配置加载失败,请重试。"
988
+ loadFailed: "模型配置加载失败,请重试。",
989
+ plazaTitle: "技能广场",
990
+ plazaIntro: "其他用户共享的技能。装载后即可在本工作区使用,也可以把自己的技能共享出去。",
991
+ plazaSearch: "搜索技能",
992
+ plazaTagFilter: "按标签筛选",
993
+ plazaAllTags: "全部标签",
994
+ plazaMine: "我共享的",
995
+ plazaInstall: "装载",
996
+ plazaInstalled: "已装载,可在技能列表中使用。",
997
+ plazaUnshare: "取消共享",
998
+ plazaUnshared: "已从广场移除;已装载的用户保留其副本。",
999
+ plazaEmpty: "还没有人共享技能。",
1000
+ plazaUnavailable: "工作区接入 DataOps 后即可使用技能广场。",
1001
+ plazaLoadFailed: "技能广场加载失败,请重试。",
1002
+ plazaActionFailed: "操作未完成,请重试。"
702
1003
  };
703
1004
  //#endregion
704
1005
  //#region src/client/index.ts
@@ -725,6 +1026,19 @@ window.__ModuleLoader__.load({
725
1026
  label: () => t("nav"),
726
1027
  inject: () => ({ t })
727
1028
  }, ManagedDataOpsSection));
1029
+ /**
1030
+ * The skill plaza, contributed to the skill center page.
1031
+ *
1032
+ * The skill center declares the slot and renders whatever it holds; a profile without this
1033
+ * plugin leaves it empty, which is what keeps the plaza out of a deployment that never
1034
+ * installed DataOps.
1035
+ */
1036
+ ctx.slots.inject("skill-center.section", () => ctx.slots.register({
1037
+ name: "skill-center.section",
1038
+ id: "dataops-plaza",
1039
+ order: 10,
1040
+ inject: () => ({ t })
1041
+ }, SkillPlazaSection));
728
1042
  const synchronizeJwt = async () => {
729
1043
  const response = await fetch(new URL(MANAGED_AUTH_PATH, window.location.origin), {
730
1044
  method: "POST",