@peers-app/peers-ui 0.28.6 → 0.28.8

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.
@@ -47,6 +47,17 @@ const PackageVersionsList = (props) => {
47
47
  const [activating, setActivating] = (0, react_1.useState)(null);
48
48
  const [deleting, setDeleting] = (0, react_1.useState)(null);
49
49
  const [pinning, setPinning] = (0, react_1.useState)(false);
50
+ const [promotionNote, setPromotionNote] = (0, react_1.useState)();
51
+ const canSelectForGroup = (0, hooks_1.usePromise)(package_helpers_1.isGroupAdmin, false, [pkg.packageId]);
52
+ (0, react_1.useEffect)(() => {
53
+ const subscription = (0, peers_sdk_1.PackageVersions)().dataChanged.subscribe((event) => {
54
+ if (event.dataObject?.packageId === pkg.packageId)
55
+ refreshKey(refreshKey() + 1);
56
+ });
57
+ return () => {
58
+ subscription.unsubscribe();
59
+ };
60
+ }, [refreshKey, pkg.packageId]);
50
61
  const [devicePrefs] = (0, hooks_1.useObservable)((0, peers_sdk_1.packagePrefsVar)(pkg.packageId));
51
62
  const effective = (0, peers_sdk_1.getEffectivePackagePrefs)(pkg.toJS(), devicePrefs);
52
63
  const effectiveActiveVersionId = effective.activePackageVersionId;
@@ -78,6 +89,7 @@ const PackageVersionsList = (props) => {
78
89
  return { sorted, userMap };
79
90
  }, undefined, [pkg.packageId, refreshKey()]);
80
91
  async function activateVersion(pv) {
92
+ setPromotionNote(undefined);
81
93
  setActivating(pv.packageVersionId);
82
94
  try {
83
95
  await (0, package_helpers_1.activatePackageVersion)(pkg.packageId, pv);
@@ -92,6 +104,7 @@ const PackageVersionsList = (props) => {
92
104
  }
93
105
  }
94
106
  async function deleteVersion(pv) {
107
+ setPromotionNote(undefined);
95
108
  if (!confirm(`Delete version v${pv.version} (${pv.packageVersionHash?.substring(0, 8)})?`))
96
109
  return;
97
110
  setDeleting(pv.packageVersionId);
@@ -106,16 +119,17 @@ const PackageVersionsList = (props) => {
106
119
  setDeleting(null);
107
120
  }
108
121
  }
109
- async function promoteVersion(pv, newTag) {
122
+ async function promoteVersion(pv, newTag, activateForGroup) {
123
+ setPromotionNote(undefined);
110
124
  try {
111
125
  // The host re-tags, re-signs, records history, and activates the version when this
112
126
  // device was running it and the group follows the new tag.
113
127
  const result = await (await (0, packages_ipc_1.packagesTools)()).promotePackageVersion({
114
128
  packageVersionId: pv.packageVersionId,
115
129
  versionTag: newTag,
130
+ ...(activateForGroup ? { activateForGroup: true } : {}),
116
131
  });
117
- if (result.warning)
118
- alert(result.warning);
132
+ setPromotionNote([result.activationNote, result.warning].filter(Boolean).join(" "));
119
133
  if (result.activated)
120
134
  await pkg.load();
121
135
  refreshKey(refreshKey() + 1);
@@ -125,6 +139,7 @@ const PackageVersionsList = (props) => {
125
139
  }
126
140
  }
127
141
  async function pinVersion() {
142
+ setPromotionNote(undefined);
128
143
  setPinning(true);
129
144
  try {
130
145
  const pinsGroup = !(0, peers_sdk_1.hasDeviceFollowOverride)(devicePrefs) && (await (0, package_helpers_1.isGroupAdmin)());
@@ -151,10 +166,12 @@ const PackageVersionsList = (props) => {
151
166
  return ((0, jsx_runtime_1.jsx)("div", { className: "text-center p-3", children: (0, jsx_runtime_1.jsx)("div", { className: "spinner-border spinner-border-sm" }) }));
152
167
  }
153
168
  const { sorted, userMap } = versions;
154
- if (sorted.length === 0) {
155
- return ((0, jsx_runtime_1.jsxs)("div", { className: "text-muted text-center p-4", children: [(0, jsx_runtime_1.jsx)("i", { className: "bi bi-tag me-1" }), "No versions found for this package."] }));
156
- }
157
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("small", { className: "text-muted", children: [sorted.length, " version", sorted.length !== 1 ? "s" : ""] }), (0, jsx_runtime_1.jsx)("div", { className: "list-group mt-2", children: sorted.map((pv) => ((0, jsx_runtime_1.jsx)(VersionRow, { pv: pv, isActive: pv.packageVersionId === effectiveActiveVersionId, isPinned: isPinned, pinning: pinning, activating: activating, deleting: deleting, userMap: userMap, onActivate: activateVersion, onDelete: deleteVersion, onPin: pinVersion, onPromote: promoteVersion }, pv.packageVersionId))) })] }));
169
+ const groupWarning = (0, peers_sdk_1.packageGroupVersionWarning)(pkg.packageId, {
170
+ groupActivePackageVersionId: pkg.activePackageVersionId,
171
+ groupVersionMissing: !!pkg.activePackageVersionId &&
172
+ !sorted.some((pv) => pv.packageVersionId === pkg.activePackageVersionId),
173
+ });
174
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [groupWarning && ((0, jsx_runtime_1.jsx)("div", { role: "alert", className: "alert alert-warning", children: groupWarning })), promotionNote && ((0, jsx_runtime_1.jsx)("div", { role: "status", className: "alert alert-info", children: promotionNote })), sorted.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-muted text-center p-4", children: "No versions found for this package." })), (0, jsx_runtime_1.jsxs)("small", { className: "text-muted", children: [sorted.length, " version", sorted.length !== 1 ? "s" : ""] }), (0, jsx_runtime_1.jsx)("div", { className: "list-group mt-2", children: sorted.map((pv) => ((0, jsx_runtime_1.jsx)(VersionRow, { pv: pv, isActive: pv.packageVersionId === effectiveActiveVersionId, isPinned: isPinned, pinning: pinning, activating: activating, deleting: deleting, userMap: userMap, canSelectForGroup: !!canSelectForGroup, onActivate: activateVersion, onDelete: deleteVersion, onPin: pinVersion, onPromote: promoteVersion }, pv.packageVersionId))) })] }));
158
175
  };
159
176
  exports.PackageVersionsList = PackageVersionsList;
160
177
  function VersionRow(props) {
@@ -162,5 +179,5 @@ function VersionRow(props) {
162
179
  const creatorName = userMap.get(pv.createdBy);
163
180
  const currentTag = pv.versionTag || "dev";
164
181
  const promoteTargets = (0, peers_sdk_1.packageVersionPromotionTargets)(currentTag);
165
- return ((0, jsx_runtime_1.jsx)("div", { className: `list-group-item ${isActive ? "list-group-item-success" : ""}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center flex-wrap", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "me-2", children: ["v", pv.version] }), pv.versionTag && ((0, jsx_runtime_1.jsx)("span", { className: `badge ${tagBadgeClass(pv.versionTag)} me-2`, children: pv.versionTag })), (0, jsx_runtime_1.jsx)("code", { className: "text-muted small me-2", children: pv.packageVersionHash?.substring(0, 8) }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted me-2", children: formatDate(pv.createdAt) }), creatorName && (0, jsx_runtime_1.jsxs)("small", { className: "text-muted", children: ["by ", creatorName] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "d-flex gap-1 align-items-center", children: [promoteTargets.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "dropdown", children: [(0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-outline-info dropdown-toggle", "data-bs-toggle": "dropdown", "data-bs-popper-config": '{"strategy":"fixed"}', title: "Change version tag", children: "Promote" }), (0, jsx_runtime_1.jsx)("ul", { className: "dropdown-menu dropdown-menu-end", children: promoteTargets.map((tag) => ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => props.onPromote(pv, tag), children: [currentTag, " \u2192 ", tag] }) }, tag))) })] })), isActive ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { className: "btn btn-sm btn-outline-secondary", disabled: isPinned || pinning, onClick: () => props.onPin(), title: isPinned ? "Already pinned" : "Pin to this version (disable auto-updates)", children: [pinning ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-pin-fill" })), isPinned ? " Pinned" : " Pin"] }), (0, jsx_runtime_1.jsx)("span", { className: "badge text-bg-info align-self-center", children: "active" })] })) : ((0, jsx_runtime_1.jsxs)("button", { className: "btn btn-sm btn-outline-primary", disabled: activating === pv.packageVersionId, onClick: () => props.onActivate(pv), children: [activating === pv.packageVersionId ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm me-1" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-check2-circle me-1" })), "Activate"] })), !isActive && ((0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-outline-danger", disabled: deleting === pv.packageVersionId, onClick: () => props.onDelete(pv), children: deleting === pv.packageVersionId ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-trash" })) }))] })] }) }));
182
+ return ((0, jsx_runtime_1.jsx)("div", { className: `list-group-item ${isActive ? "list-group-item-success" : ""}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center justify-content-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center flex-wrap", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "me-2", children: ["v", pv.version] }), pv.versionTag && ((0, jsx_runtime_1.jsx)("span", { className: `badge ${tagBadgeClass(pv.versionTag)} me-2`, children: pv.versionTag })), (0, jsx_runtime_1.jsx)("code", { className: "text-muted small me-2", children: pv.packageVersionHash?.substring(0, 8) }), (0, jsx_runtime_1.jsx)("small", { className: "text-muted me-2", children: formatDate(pv.createdAt) }), creatorName && (0, jsx_runtime_1.jsxs)("small", { className: "text-muted", children: ["by ", creatorName] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "d-flex gap-1 align-items-center", children: [promoteTargets.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "dropdown", children: [(0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-outline-info dropdown-toggle", "data-bs-toggle": "dropdown", "data-bs-popper-config": '{"strategy":"fixed"}', title: "Change version tag", children: "Promote" }), (0, jsx_runtime_1.jsx)("ul", { className: "dropdown-menu dropdown-menu-end", children: promoteTargets.map((tag) => ((0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => props.onPromote(pv, tag), children: [currentTag, " \u2192 ", tag] }), props.canSelectForGroup && ((0, jsx_runtime_1.jsxs)("button", { className: "dropdown-item", onClick: () => props.onPromote(pv, tag, true), children: [currentTag, " \u2192 ", tag, " and use for group"] }))] }, tag))) })] })), isActive ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("button", { className: "btn btn-sm btn-outline-secondary", disabled: isPinned || pinning, onClick: () => props.onPin(), title: isPinned ? "Already pinned" : "Pin to this version (disable auto-updates)", children: [pinning ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-pin-fill" })), isPinned ? " Pinned" : " Pin"] }), (0, jsx_runtime_1.jsx)("span", { className: "badge text-bg-info align-self-center", children: "active" })] })) : ((0, jsx_runtime_1.jsxs)("button", { className: "btn btn-sm btn-outline-primary", disabled: activating === pv.packageVersionId, onClick: () => props.onActivate(pv), children: [activating === pv.packageVersionId ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm me-1" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-check2-circle me-1" })), "Activate"] })), !isActive && ((0, jsx_runtime_1.jsx)("button", { className: "btn btn-sm btn-outline-danger", disabled: deleting === pv.packageVersionId, onClick: () => props.onDelete(pv), children: deleting === pv.packageVersionId ? ((0, jsx_runtime_1.jsx)("span", { className: "spinner-border spinner-border-sm" })) : ((0, jsx_runtime_1.jsx)("i", { className: "bi bi-trash" })) }))] })] }) }));
166
183
  }
package/dist/theme.css CHANGED
@@ -1,30 +1,31 @@
1
- /* Shared light palette. Import after Bootstrap in every platform host. */
1
+ /* Shared light palette. Import after Bootstrap in every platform host.
2
+ The grays lean only slightly cool; the blues are the link and accent colors. */
2
3
  [data-bs-theme="light"] {
3
- --bs-body-bg: #e5e9ed;
4
- --bs-body-bg-rgb: 229, 233, 237;
5
- --bs-body-color: #242a31;
6
- --bs-body-color-rgb: 36, 42, 49;
7
- --bs-secondary-color: #5f6974;
8
- --bs-secondary-color-rgb: 95, 105, 116;
9
- --bs-border-color: #c7ced6;
4
+ --bs-body-bg: #e6e9eb;
5
+ --bs-body-bg-rgb: 230, 233, 235;
6
+ --bs-body-color: #262a2e;
7
+ --bs-body-color-rgb: 38, 42, 46;
8
+ --bs-secondary-color: #626970;
9
+ --bs-secondary-color-rgb: 98, 105, 112;
10
+ --bs-border-color: #c9ced3;
10
11
  --bs-link-color: #2a63cb;
11
12
  --bs-link-color-rgb: 42, 99, 203;
12
13
  --bs-link-hover-color: var(--bs-link-color);
13
14
  --bs-link-hover-color-rgb: var(--bs-link-color-rgb);
14
15
 
15
16
  --peers-surface-bg: #fbfcfd;
16
- --peers-surface-border: #d0d7de;
17
- --peers-tab-strip-bg: #d0d6dd;
18
- --peers-tab-edge: #b8c1ca;
19
- --peers-tab-strip-color: #283037;
20
- --peers-tab-icon-color: #56616d;
21
- --peers-tab-color: #4f5a66;
17
+ --peers-surface-border: #d2d7db;
18
+ --peers-tab-strip-bg: #d2d6da;
19
+ --peers-tab-edge: #bbc1c6;
20
+ --peers-tab-strip-color: #2a3034;
21
+ --peers-tab-icon-color: #596068;
22
+ --peers-tab-color: #525961;
22
23
  --peers-tab-hover-bg: rgba(255, 255, 255, 0.42);
23
- --peers-tab-divider: #bcc5ce;
24
- --peers-tab-active-color: #1e242a;
24
+ --peers-tab-divider: #bfc5ca;
25
+ --peers-tab-active-color: #202428;
25
26
  --peers-tab-accent: #2f6fde;
26
- --peers-tab-active-shadow: 0 -1px 3px rgba(30, 40, 55, 0.09);
27
- --peers-graph-overlay-color: rgba(36, 42, 49, 0.32);
27
+ --peers-tab-active-shadow: 0 -1px 3px rgba(33, 40, 49, 0.09);
28
+ --peers-graph-overlay-color: rgba(38, 42, 46, 0.32);
28
29
  }
29
30
 
30
31
  /* Bootstrap declares these variables locally, so override them on each component. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peers-app/peers-ui",
3
- "version": "0.28.6",
3
+ "version": "0.28.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/peers-app/peers-ui.git"
@@ -36,7 +36,7 @@
36
36
  "lint:fix": "biome check --write ."
37
37
  },
38
38
  "peerDependencies": {
39
- "@peers-app/peers-sdk": "^0.28.6",
39
+ "@peers-app/peers-sdk": "^0.28.8",
40
40
  "bootstrap": "^5.3.3",
41
41
  "react": "^18.0.0",
42
42
  "react-dom": "^18.0.0"
@@ -47,7 +47,7 @@
47
47
  "@babel/preset-react": "^7.24.1",
48
48
  "@babel/preset-typescript": "^7.27.1",
49
49
  "@biomejs/biome": "2.3.11",
50
- "@peers-app/peers-sdk": "0.28.6",
50
+ "@peers-app/peers-sdk": "0.28.8",
51
51
  "@testing-library/dom": "^10.4.0",
52
52
  "@testing-library/jest-dom": "^6.6.3",
53
53
  "@testing-library/react": "^16.3.0",