@streamoid/settings 0.10.1 → 0.11.1
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/README.md +7 -5
- package/dist/index.d.mts +175 -184
- package/dist/index.d.ts +175 -184
- package/dist/index.js +373 -514
- package/dist/index.mjs +373 -514
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,18 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
ALLOCATION_ERROR_CODES: () => ALLOCATION_ERROR_CODES,
|
|
24
|
-
ALLOCATION_NOTE_MAX_LENGTH: () => ALLOCATION_NOTE_MAX_LENGTH,
|
|
25
23
|
APP_KEYS: () => APP_KEYS,
|
|
26
24
|
BillingContent: () => BillingContent,
|
|
27
25
|
BuyCreditsModal: () => BuyCreditsModal,
|
|
28
|
-
CANCEL_REASON_MAX_LENGTH: () => CANCEL_REASON_MAX_LENGTH,
|
|
29
|
-
CancelCreditAllocationModal: () => CancelCreditAllocationModal,
|
|
30
26
|
ConfirmDeleteModal: () => ConfirmDeleteModal,
|
|
31
27
|
ConfirmLeaveModal: () => ConfirmLeaveModal,
|
|
32
28
|
ConnectedAppsContent: () => ConnectedAppsContent,
|
|
33
|
-
|
|
34
|
-
CreditAllocationsView: () => CreditAllocationsView,
|
|
29
|
+
CreditPoolMemberModal: () => CreditPoolMemberModal,
|
|
35
30
|
DEFAULT_PERMISSIONS: () => DEFAULT_PERMISSIONS,
|
|
36
31
|
DEFAULT_USER_LANGUAGE: () => DEFAULT_USER_LANGUAGE,
|
|
37
32
|
ExportDateModal: () => ExportDateModal,
|
|
@@ -44,15 +39,20 @@ __export(index_exports, {
|
|
|
44
39
|
OrganizationMemberModal: () => OrganizationMemberModal,
|
|
45
40
|
OrganizationModal: () => OrganizationModal,
|
|
46
41
|
OrganizationPicker: () => OrganizationPicker,
|
|
42
|
+
POOL_ERROR_CODES: () => POOL_ERROR_CODES,
|
|
43
|
+
POOL_NOTE_MAX_LENGTH: () => POOL_NOTE_MAX_LENGTH,
|
|
47
44
|
PerUserLimitsView: () => PerUserLimitsView,
|
|
48
45
|
ProfileAvatar: () => ProfileAvatar,
|
|
49
46
|
ProfileTab: () => ProfileTab,
|
|
47
|
+
REMOVE_REASON_MAX_LENGTH: () => REMOVE_REASON_MAX_LENGTH,
|
|
50
48
|
ReferralTab: () => ReferralTab,
|
|
49
|
+
RemovePoolMemberModal: () => RemovePoolMemberModal,
|
|
51
50
|
SCOPE_LABELS: () => SCOPE_LABELS,
|
|
52
51
|
ScopeHeader: () => ScopeHeader,
|
|
53
52
|
SettingsAdaptersProvider: () => SettingsAdaptersProvider,
|
|
54
53
|
SettingsContent: () => SettingsContent,
|
|
55
54
|
SettingsTooltip: () => SettingsTooltip,
|
|
55
|
+
SharedCreditsView: () => SharedCreditsView,
|
|
56
56
|
SiconKey: () => SiconKey_default,
|
|
57
57
|
TAB_DESCRIPTIONS: () => TAB_DESCRIPTIONS,
|
|
58
58
|
TAB_LABELS: () => TAB_LABELS,
|
|
@@ -68,28 +68,22 @@ __export(index_exports, {
|
|
|
68
68
|
WorkspaceModal: () => WorkspaceModal,
|
|
69
69
|
WorkspacePicker: () => WorkspacePicker,
|
|
70
70
|
WorkspaceTab: () => WorkspaceTab,
|
|
71
|
-
allocationErrorMessage: () => allocationErrorMessage,
|
|
72
|
-
allocationWorkspaceName: () => allocationWorkspaceName,
|
|
73
71
|
belowUsageReason: () => belowUsageReason,
|
|
74
|
-
|
|
75
|
-
cancelOutcomeSummary: () => cancelOutcomeSummary,
|
|
76
|
-
cancelOutcomeWarning: () => cancelOutcomeWarning,
|
|
77
|
-
cleanAllocationValueInput: () => cleanAllocationValueInput,
|
|
72
|
+
canShowSharedCredits: () => canShowSharedCredits,
|
|
78
73
|
cleanCreditLimitInput: () => cleanCreditLimitInput,
|
|
74
|
+
cleanPoolValueInput: () => cleanPoolValueInput,
|
|
79
75
|
countLabel: () => countLabel,
|
|
80
76
|
creditCycleUnit: () => creditCycleUnit,
|
|
81
|
-
|
|
77
|
+
creditsMeter: () => creditsMeter,
|
|
78
|
+
describeAllowance: () => describeAllowance,
|
|
82
79
|
describeDefaultLimit: () => describeDefaultLimit,
|
|
83
80
|
describeMemberLimit: () => describeMemberLimit,
|
|
84
|
-
findAllocationError: () => findAllocationError,
|
|
85
81
|
findBillingError: () => findBillingError,
|
|
86
|
-
|
|
87
|
-
formatAllocationSplit: () => formatAllocationSplit,
|
|
82
|
+
findPoolError: () => findPoolError,
|
|
88
83
|
formatCreditLimit: () => formatCreditLimit,
|
|
89
84
|
formatCredits: () => formatCredits,
|
|
85
|
+
formatPoolSplit: () => formatPoolSplit,
|
|
90
86
|
groupWorkspaceList: () => groupWorkspaceList,
|
|
91
|
-
initialTransferSummary: () => initialTransferSummary,
|
|
92
|
-
initialTransferWarning: () => initialTransferWarning,
|
|
93
87
|
isLimitBelowUsage: () => isLimitBelowUsage,
|
|
94
88
|
joinMembersWithLimits: () => joinMembersWithLimits,
|
|
95
89
|
lastUsedLabel: () => lastUsedLabel,
|
|
@@ -98,15 +92,21 @@ __export(index_exports, {
|
|
|
98
92
|
loadWorkspaceOrganization: () => loadWorkspaceOrganization,
|
|
99
93
|
memberRoleUpdate: () => memberRoleUpdate,
|
|
100
94
|
minimumCreditLimit: () => minimumCreditLimit,
|
|
95
|
+
pausedOwnCreditsText: () => pausedOwnCreditsText,
|
|
96
|
+
poolErrorMessage: () => poolErrorMessage,
|
|
97
|
+
poolWorkspaceName: () => poolWorkspaceName,
|
|
101
98
|
resolveSettingsTabFromPath: () => resolveSettingsTabFromPath,
|
|
102
99
|
roundCredits: () => roundCredits,
|
|
100
|
+
sharedPoolBannerText: () => sharedPoolBannerText,
|
|
103
101
|
useSettingsAdapters: () => useSettingsAdapters,
|
|
104
102
|
useWorkspaceOrganization: () => useWorkspaceOrganization,
|
|
103
|
+
usedByNamesFrom: () => usedByNamesFrom,
|
|
104
|
+
usedByWorkspaceKey: () => usedByWorkspaceKey,
|
|
105
105
|
userLanguageLabel: () => userLanguageLabel,
|
|
106
|
-
validateAllocationText: () => validateAllocationText,
|
|
107
|
-
validateAllocationValue: () => validateAllocationValue,
|
|
108
106
|
validateCreditLimitInput: () => validateCreditLimitInput,
|
|
109
|
-
validateDefaultCreditLimitInput: () => validateDefaultCreditLimitInput
|
|
107
|
+
validateDefaultCreditLimitInput: () => validateDefaultCreditLimitInput,
|
|
108
|
+
validatePoolText: () => validatePoolText,
|
|
109
|
+
validatePoolValue: () => validatePoolValue
|
|
110
110
|
});
|
|
111
111
|
module.exports = __toCommonJS(index_exports);
|
|
112
112
|
|
|
@@ -8032,14 +8032,14 @@ function BuyCreditsModal({
|
|
|
8032
8032
|
const maxCredits = Math.round(
|
|
8033
8033
|
topupConfig.maxAmount / topupConfig.pricePerCredit
|
|
8034
8034
|
);
|
|
8035
|
-
const [
|
|
8035
|
+
const [credits2, setCredits] = (0, import_react15.useState)(minCredits);
|
|
8036
8036
|
const [creditsInput, setCreditsInput] = (0, import_react15.useState)(String(minCredits));
|
|
8037
8037
|
const [priceInput, setPriceInput] = (0, import_react15.useState)(
|
|
8038
8038
|
String(minCredits * topupConfig.pricePerCredit)
|
|
8039
8039
|
);
|
|
8040
8040
|
const [activeField, setActiveField] = (0, import_react15.useState)("credits");
|
|
8041
|
-
const parsedCredits = creditsInput.length ? Number(creditsInput) :
|
|
8042
|
-
const previewCredits = Number.isFinite(parsedCredits) ? parsedCredits :
|
|
8041
|
+
const parsedCredits = creditsInput.length ? Number(creditsInput) : credits2;
|
|
8042
|
+
const previewCredits = Number.isFinite(parsedCredits) ? parsedCredits : credits2;
|
|
8043
8043
|
const pricedCredits = previewCredits > 0 ? previewCredits : 0;
|
|
8044
8044
|
const price = Number(
|
|
8045
8045
|
(pricedCredits * topupConfig.pricePerCredit).toFixed(2)
|
|
@@ -8061,8 +8061,8 @@ function BuyCreditsModal({
|
|
|
8061
8061
|
setCreditsInput(String(derived));
|
|
8062
8062
|
setPriceInput(String(amount));
|
|
8063
8063
|
};
|
|
8064
|
-
const handleDecrement = () => syncFromCredits(Math.max(minCredits,
|
|
8065
|
-
const handleIncrement = () => syncFromCredits(Math.min(maxCredits,
|
|
8064
|
+
const handleDecrement = () => syncFromCredits(Math.max(minCredits, credits2 - STEP));
|
|
8065
|
+
const handleIncrement = () => syncFromCredits(Math.min(maxCredits, credits2 + STEP));
|
|
8066
8066
|
const handleCreditsChange = (value) => {
|
|
8067
8067
|
const raw = value.replace(/[^\d]/g, "");
|
|
8068
8068
|
setCreditsInput(raw);
|
|
@@ -8196,7 +8196,7 @@ function BuyCreditsModal({
|
|
|
8196
8196
|
style: {
|
|
8197
8197
|
width: 24,
|
|
8198
8198
|
height: 24,
|
|
8199
|
-
opacity:
|
|
8199
|
+
opacity: credits2 <= minCredits ? 0.3 : 1,
|
|
8200
8200
|
transition: "opacity 0.15s ease"
|
|
8201
8201
|
},
|
|
8202
8202
|
onClick: handleDecrement,
|
|
@@ -8254,7 +8254,7 @@ function BuyCreditsModal({
|
|
|
8254
8254
|
style: {
|
|
8255
8255
|
width: 24,
|
|
8256
8256
|
height: 24,
|
|
8257
|
-
opacity:
|
|
8257
|
+
opacity: credits2 >= maxCredits ? 0.3 : 1,
|
|
8258
8258
|
transition: "opacity 0.15s ease"
|
|
8259
8259
|
},
|
|
8260
8260
|
onClick: handleIncrement,
|
|
@@ -8386,7 +8386,7 @@ function BuyCreditsModal({
|
|
|
8386
8386
|
pointerEvents: isInvalid ? "none" : "auto",
|
|
8387
8387
|
transition: "opacity 0.2s ease"
|
|
8388
8388
|
},
|
|
8389
|
-
onClick: () => onBuy(
|
|
8389
|
+
onClick: () => onBuy(credits2, price),
|
|
8390
8390
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8391
8391
|
"span",
|
|
8392
8392
|
{
|
|
@@ -9126,7 +9126,7 @@ function PerUserLimitsView() {
|
|
|
9126
9126
|
] });
|
|
9127
9127
|
}
|
|
9128
9128
|
|
|
9129
|
-
// src/
|
|
9129
|
+
// src/shared-credits-view.tsx
|
|
9130
9130
|
var import_react21 = require("react");
|
|
9131
9131
|
var import_ui15 = require("@streamoid/ui");
|
|
9132
9132
|
|
|
@@ -9375,23 +9375,23 @@ function ConfirmActionModal({
|
|
|
9375
9375
|
);
|
|
9376
9376
|
}
|
|
9377
9377
|
|
|
9378
|
-
// src/credit-
|
|
9378
|
+
// src/credit-pool-modal.tsx
|
|
9379
9379
|
var import_react19 = require("react");
|
|
9380
9380
|
var import_ui13 = require("@streamoid/ui");
|
|
9381
9381
|
var import_icons13 = require("@streamoid/icons");
|
|
9382
9382
|
|
|
9383
|
-
// src/credit-
|
|
9384
|
-
var
|
|
9385
|
-
var
|
|
9386
|
-
function
|
|
9387
|
-
return Boolean(api.
|
|
9383
|
+
// src/credit-pool.ts
|
|
9384
|
+
var POOL_NOTE_MAX_LENGTH = 500;
|
|
9385
|
+
var REMOVE_REASON_MAX_LENGTH = 500;
|
|
9386
|
+
function canShowSharedCredits(api, workspace, organization) {
|
|
9387
|
+
return Boolean(api.fetchCreditPool) && Boolean(workspace?.organizationId || organization?.id);
|
|
9388
9388
|
}
|
|
9389
|
-
function
|
|
9389
|
+
function cleanPoolValueInput(raw) {
|
|
9390
9390
|
const kept = raw.replace(/[^\d.]/g, "");
|
|
9391
9391
|
const dot = kept.indexOf(".");
|
|
9392
9392
|
return dot === -1 ? kept : kept.slice(0, dot + 1) + kept.slice(dot + 1).replace(/\./g, "");
|
|
9393
9393
|
}
|
|
9394
|
-
function
|
|
9394
|
+
function validatePoolValue(mode, raw) {
|
|
9395
9395
|
const trimmed = raw.trim();
|
|
9396
9396
|
if (!trimmed) return { ok: false, reason: mode === "percent" ? "Enter a percentage" : "Enter a number of credits" };
|
|
9397
9397
|
if (!/^\d+(\.\d{1,2})?$/.test(trimmed)) {
|
|
@@ -9400,64 +9400,68 @@ function validateAllocationValue(mode, raw, balance) {
|
|
|
9400
9400
|
const value = Number(trimmed);
|
|
9401
9401
|
if (!(value > 0)) return { ok: false, reason: "Enter a number greater than 0" };
|
|
9402
9402
|
if (mode === "percent" && value > 100) return { ok: false, reason: "A percentage can be at most 100" };
|
|
9403
|
-
if (mode === "fixed" && typeof balance === "number" && Number.isFinite(balance) && value > balance) {
|
|
9404
|
-
return {
|
|
9405
|
-
ok: false,
|
|
9406
|
-
reason: `This workspace has ${formatCredits(balance)} credits available`
|
|
9407
|
-
};
|
|
9408
|
-
}
|
|
9409
9403
|
return { ok: true, value };
|
|
9410
9404
|
}
|
|
9411
|
-
function
|
|
9405
|
+
function validatePoolText(raw, max) {
|
|
9412
9406
|
const value = raw.trim();
|
|
9413
9407
|
if (!value) return { ok: false, reason: "Required" };
|
|
9414
9408
|
if (value.length > max) return { ok: false, reason: `At most ${max} characters` };
|
|
9415
9409
|
return { ok: true, value };
|
|
9416
9410
|
}
|
|
9417
|
-
|
|
9411
|
+
var credits = (value) => `${formatCredits(value)} ${value === 1 ? "credit" : "credits"}`;
|
|
9412
|
+
function formatPoolSplit(split) {
|
|
9418
9413
|
if (split.mode === "percent") return `${formatCredits(split.value)}%`;
|
|
9419
|
-
return
|
|
9414
|
+
return credits(split.value);
|
|
9420
9415
|
}
|
|
9421
|
-
function
|
|
9422
|
-
|
|
9416
|
+
function describeAllowance(member) {
|
|
9417
|
+
const allowance = `${credits(member.allowance)} this cycle`;
|
|
9418
|
+
return member.mode === "percent" ? `${formatPoolSplit(member)} \xB7 ${allowance}` : allowance;
|
|
9423
9419
|
}
|
|
9424
|
-
function
|
|
9425
|
-
const split = formatAllocationSplit(allocation);
|
|
9426
|
-
if (!allocation.recurring) return `${split} once`;
|
|
9427
|
-
return allocation.mode === "percent" ? `${split} of each renewal` : `${split} every renewal`;
|
|
9428
|
-
}
|
|
9429
|
-
function allocationWorkspaceName(name) {
|
|
9420
|
+
function poolWorkspaceName(name) {
|
|
9430
9421
|
return name?.trim() || "Unknown workspace";
|
|
9431
9422
|
}
|
|
9432
|
-
function
|
|
9433
|
-
const
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
return `
|
|
9442
|
-
}
|
|
9443
|
-
function
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
}
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
}
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9423
|
+
function sharedPoolBannerText(pool) {
|
|
9424
|
+
const sponsor = pool.sponsorName?.trim() || "another workspace";
|
|
9425
|
+
return `Credits shared by ${sponsor}: ${formatCredits(pool.remaining)} of ${formatCredits(pool.allowance)} left this cycle`;
|
|
9426
|
+
}
|
|
9427
|
+
function pausedOwnCreditsText(pool) {
|
|
9428
|
+
const own = pool.ownCredits;
|
|
9429
|
+
if (typeof own !== "number" || !Number.isFinite(own)) {
|
|
9430
|
+
return "This workspace spends these shared credits, not its own; credits bought here can't be used while it does.";
|
|
9431
|
+
}
|
|
9432
|
+
return `This workspace's own ${credits(own)} ${own === 1 ? "is" : "are"} paused while it uses shared credits. They stay with it and can be used again once sharing stops.`;
|
|
9433
|
+
}
|
|
9434
|
+
function creditsMeter({
|
|
9435
|
+
availableCredits,
|
|
9436
|
+
totalCredits,
|
|
9437
|
+
sharedPool
|
|
9438
|
+
}) {
|
|
9439
|
+
if (sharedPool) {
|
|
9440
|
+
const used2 = Math.max(0, sharedPool.used);
|
|
9441
|
+
const remaining = Math.max(0, sharedPool.remaining);
|
|
9442
|
+
const progressPct2 = sharedPool.allowance > 0 ? Math.min(100, Math.round(used2 / sharedPool.allowance * 100)) : 100;
|
|
9443
|
+
return { used: used2, remaining, progressPct: progressPct2, remainingPct: 100 - progressPct2 };
|
|
9444
|
+
}
|
|
9445
|
+
const used = availableCredits != null && totalCredits != null ? Math.max(0, totalCredits - availableCredits) : null;
|
|
9446
|
+
const progressPct = used != null && totalCredits != null && totalCredits > 0 ? Math.min(100, Math.round(used / totalCredits * 100)) : 0;
|
|
9447
|
+
return { used, remaining: availableCredits, progressPct, remainingPct: 100 - progressPct };
|
|
9448
|
+
}
|
|
9449
|
+
function usedByWorkspaceKey(log, currentWorkspaceId) {
|
|
9450
|
+
const usedBy = log.meta?.usedBy;
|
|
9451
|
+
if (typeof usedBy !== "string" || !usedBy) return null;
|
|
9452
|
+
return usedBy.toLowerCase() === String(currentWorkspaceId ?? "").toLowerCase() ? null : usedBy;
|
|
9453
|
+
}
|
|
9454
|
+
function usedByNamesFrom(pool) {
|
|
9455
|
+
const names = {};
|
|
9456
|
+
for (const member of [...pool?.formerMembers ?? [], ...pool?.members ?? []]) {
|
|
9457
|
+
const name = member.memberWorkspaceName?.trim();
|
|
9458
|
+
if (name && member.memberWorkspaceKey) names[member.memberWorkspaceKey.toLowerCase()] = name;
|
|
9459
|
+
}
|
|
9460
|
+
return names;
|
|
9461
|
+
}
|
|
9462
|
+
var POOL_ERROR_CODES = ["SPONSOR_ON_FREE_PLAN", "POOL_NOT_ALLOWED"];
|
|
9463
|
+
function findPoolError(failure) {
|
|
9464
|
+
const error = findBillingError(failure, POOL_ERROR_CODES);
|
|
9461
9465
|
if (!error) return null;
|
|
9462
9466
|
const status = error.status;
|
|
9463
9467
|
const message = [status?.message, error.error, error.message].find(
|
|
@@ -9466,29 +9470,18 @@ function findAllocationError(failure) {
|
|
|
9466
9470
|
const details = error.details && typeof error.details === "object" ? error.details : {};
|
|
9467
9471
|
return { code: error.code, details, message: message ?? null };
|
|
9468
9472
|
}
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
const found = findAllocationError(failure);
|
|
9473
|
+
function poolErrorMessage(failure) {
|
|
9474
|
+
const found = findPoolError(failure);
|
|
9472
9475
|
if (!found) return null;
|
|
9473
9476
|
switch (found.code) {
|
|
9474
|
-
case "
|
|
9475
|
-
const balance = num(found.details.currentBalance);
|
|
9476
|
-
const required = num(found.details.requiredCredits);
|
|
9477
|
-
if (balance !== null && required !== null) {
|
|
9478
|
-
return `Not enough credits: this would send ${formatCredits(required)} now, but the workspace has ${formatCredits(balance)}.`;
|
|
9479
|
-
}
|
|
9480
|
-
return "This workspace doesn't have enough credits to send that now.";
|
|
9481
|
-
}
|
|
9482
|
-
case "SOURCE_ON_FREE_PLAN":
|
|
9477
|
+
case "SPONSOR_ON_FREE_PLAN":
|
|
9483
9478
|
return "A workspace on the free plan can't share credits. Upgrade this workspace's plan first.";
|
|
9484
|
-
case "
|
|
9485
|
-
return found.message ? found.message.replace(/\.?$/, ".") : "
|
|
9486
|
-
case "TARGET_PLAN_CHANGE_FAILED":
|
|
9487
|
-
return found.details.allocationId ? "The target workspace moved to the Custom plan, but its plan details weren't saved. Cancel this allocation to move it back to free." : "Couldn't move the target workspace to the Custom plan, so nothing was transferred. Try again.";
|
|
9479
|
+
case "POOL_NOT_ALLOWED":
|
|
9480
|
+
return found.message ? found.message.replace(/\.?$/, ".") : "Credits can't be shared with that workspace.";
|
|
9488
9481
|
}
|
|
9489
9482
|
}
|
|
9490
9483
|
|
|
9491
|
-
// src/credit-
|
|
9484
|
+
// src/credit-pool-modal.tsx
|
|
9492
9485
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
9493
9486
|
var MODAL_T = {
|
|
9494
9487
|
primary: "var(--alias-text---icons-primary)",
|
|
@@ -9521,7 +9514,7 @@ var modalBodyText = {
|
|
|
9521
9514
|
fontSize: T16.fsSm,
|
|
9522
9515
|
lineHeight: T16.lhSm
|
|
9523
9516
|
};
|
|
9524
|
-
function
|
|
9517
|
+
function PoolModalShell({
|
|
9525
9518
|
title,
|
|
9526
9519
|
busy,
|
|
9527
9520
|
onClose,
|
|
@@ -9622,7 +9615,7 @@ function AllocationModalShell({
|
|
|
9622
9615
|
}
|
|
9623
9616
|
);
|
|
9624
9617
|
}
|
|
9625
|
-
function
|
|
9618
|
+
function PoolWarning({ children }) {
|
|
9626
9619
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9627
9620
|
"div",
|
|
9628
9621
|
{
|
|
@@ -9641,68 +9634,55 @@ function AllocationWarning({ children }) {
|
|
|
9641
9634
|
);
|
|
9642
9635
|
}
|
|
9643
9636
|
var fieldLabel = { ...modalBodyText, fontWeight: 500, color: T16.primary };
|
|
9644
|
-
function
|
|
9637
|
+
function CreditPoolMemberModal(props) {
|
|
9645
9638
|
const { toast } = useSettingsAdapters();
|
|
9646
|
-
const editing = props.kind === "edit" ? props.
|
|
9647
|
-
const [
|
|
9648
|
-
const [mode, setMode] = (0, import_react19.useState)(editing?.mode ?? "
|
|
9639
|
+
const editing = props.kind === "edit" ? props.member : null;
|
|
9640
|
+
const [memberId, setMemberId] = (0, import_react19.useState)("");
|
|
9641
|
+
const [mode, setMode] = (0, import_react19.useState)(editing?.mode ?? "percent");
|
|
9649
9642
|
const [raw, setRaw] = (0, import_react19.useState)(editing ? String(editing.value) : "");
|
|
9650
|
-
const [recurring, setRecurring] = (0, import_react19.useState)(editing?.recurring ?? true);
|
|
9651
9643
|
const [note, setNote] = (0, import_react19.useState)("");
|
|
9652
9644
|
const [touched, setTouched] = (0, import_react19.useState)(false);
|
|
9653
9645
|
const [saving, setSaving] = (0, import_react19.useState)(false);
|
|
9654
9646
|
const [serverError, setServerError] = (0, import_react19.useState)(null);
|
|
9655
9647
|
(0, import_react19.useEffect)(() => {
|
|
9656
9648
|
setServerError(null);
|
|
9657
|
-
}, [
|
|
9658
|
-
const
|
|
9659
|
-
const
|
|
9660
|
-
const
|
|
9661
|
-
const
|
|
9662
|
-
const changed = !editing || splitChanged || recurring !== editing.recurring;
|
|
9663
|
-
const valid = value.ok && (props.kind === "edit" || Boolean(targetId) && noteCheck.ok);
|
|
9649
|
+
}, [memberId, mode, raw, note]);
|
|
9650
|
+
const value = validatePoolValue(mode, raw);
|
|
9651
|
+
const noteCheck = validatePoolText(note, POOL_NOTE_MAX_LENGTH);
|
|
9652
|
+
const changed = !editing || mode !== editing.mode || !value.ok || value.value !== editing.value;
|
|
9653
|
+
const valid = value.ok && (props.kind === "edit" || Boolean(memberId) && noteCheck.ok);
|
|
9664
9654
|
const canSave = !saving && changed && valid;
|
|
9665
9655
|
const valueHint = touched && !value.ok ? value.reason : null;
|
|
9666
|
-
const percentNow = props.kind === "create" && mode === "percent" && value.ok && balance !== null ? Math.floor(roundCredits(balance * value.value / 100) * 100) / 100 : null;
|
|
9667
9656
|
const handleSave = async () => {
|
|
9668
9657
|
if (!canSave || !value.ok) return;
|
|
9669
9658
|
setSaving(true);
|
|
9670
9659
|
try {
|
|
9671
|
-
if (props.kind === "
|
|
9672
|
-
const
|
|
9673
|
-
|
|
9660
|
+
if (props.kind === "add") {
|
|
9661
|
+
const added = await props.onSave({
|
|
9662
|
+
memberWorkspaceId: memberId,
|
|
9674
9663
|
mode,
|
|
9675
9664
|
value: value.value,
|
|
9676
|
-
recurring,
|
|
9677
9665
|
note: noteCheck.ok ? noteCheck.value : ""
|
|
9678
9666
|
});
|
|
9679
|
-
|
|
9680
|
-
if (warning) toast.error(warning);
|
|
9681
|
-
else {
|
|
9682
|
-
const sent = initialTransferSummary(created);
|
|
9683
|
-
toast.success(sent ? `Allocation created. ${sent}.` : "Allocation created");
|
|
9684
|
-
}
|
|
9667
|
+
toast.success(`Credits shared. ${describeAllowance(added)}.`);
|
|
9685
9668
|
} else {
|
|
9686
|
-
await props.onSave(
|
|
9687
|
-
|
|
9688
|
-
);
|
|
9689
|
-
toast.success("Allocation updated. Applies from the next renewal.");
|
|
9669
|
+
const updated = await props.onSave({ mode, value: value.value });
|
|
9670
|
+
toast.success(`Share updated. ${describeAllowance(updated)}.`);
|
|
9690
9671
|
}
|
|
9691
9672
|
props.onSaved();
|
|
9692
9673
|
props.onClose();
|
|
9693
9674
|
} catch (err) {
|
|
9694
|
-
const message =
|
|
9675
|
+
const message = poolErrorMessage(err);
|
|
9695
9676
|
if (message) setServerError(message);
|
|
9696
|
-
else toast.error(errorMessage(err, { method: props.kind === "
|
|
9697
|
-
if (findAllocationError(err)?.details.allocationId) props.onSaved();
|
|
9677
|
+
else toast.error(errorMessage(err, { method: props.kind === "add" ? "POST" : "PATCH" }));
|
|
9698
9678
|
setSaving(false);
|
|
9699
9679
|
}
|
|
9700
9680
|
};
|
|
9701
|
-
const
|
|
9681
|
+
const candidateOptions = props.kind === "add" ? props.candidates.map((candidate) => ({ id: candidate.id, label: candidate.name })) : [];
|
|
9702
9682
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
9703
|
-
|
|
9683
|
+
PoolModalShell,
|
|
9704
9684
|
{
|
|
9705
|
-
title: props.kind === "
|
|
9685
|
+
title: props.kind === "add" ? "Share credits" : "Edit shared credits",
|
|
9706
9686
|
busy: saving,
|
|
9707
9687
|
onClose: props.onClose,
|
|
9708
9688
|
footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
@@ -9719,7 +9699,7 @@ function CreditAllocationModal(props) {
|
|
|
9719
9699
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9720
9700
|
import_ui13.ScButton,
|
|
9721
9701
|
{
|
|
9722
|
-
text: props.kind === "
|
|
9702
|
+
text: props.kind === "add" ? "Share credits" : "Save",
|
|
9723
9703
|
variant: "primary",
|
|
9724
9704
|
size: "md",
|
|
9725
9705
|
state: canSave ? "default" : "disabled",
|
|
@@ -9729,29 +9709,29 @@ function CreditAllocationModal(props) {
|
|
|
9729
9709
|
] }),
|
|
9730
9710
|
children: [
|
|
9731
9711
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col w-full", style: { gap: T16.spXs }, children: [
|
|
9732
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "
|
|
9733
|
-
props.kind === "
|
|
9712
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "Share with" }),
|
|
9713
|
+
props.kind === "add" ? candidateOptions.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9734
9714
|
import_ui13.ScSelect,
|
|
9735
9715
|
{
|
|
9736
|
-
value:
|
|
9737
|
-
onChange:
|
|
9738
|
-
options:
|
|
9716
|
+
value: memberId,
|
|
9717
|
+
onChange: setMemberId,
|
|
9718
|
+
options: candidateOptions,
|
|
9739
9719
|
placeholder: "Choose a workspace",
|
|
9740
9720
|
disabled: saving
|
|
9741
9721
|
}
|
|
9742
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { ...modalBodyText, color: T16.muted }, children: "There are no other workspaces in this organization to
|
|
9722
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { ...modalBodyText, color: T16.muted }, children: "There are no other workspaces in this organization to share credits with." }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { ...modalBodyText, color: T16.primary }, children: props.memberName })
|
|
9743
9723
|
] }),
|
|
9744
9724
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col w-full", style: { gap: T16.spMd }, children: [
|
|
9745
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "How much" }),
|
|
9725
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "How much, each billing cycle" }),
|
|
9746
9726
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center", style: { gap: T16.sp3xl }, children: [
|
|
9747
9727
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9748
9728
|
import_ui13.ScPairtext,
|
|
9749
9729
|
{
|
|
9750
9730
|
type: "radio",
|
|
9751
|
-
content: "
|
|
9752
|
-
checked: mode === "
|
|
9731
|
+
content: "Percentage",
|
|
9732
|
+
checked: mode === "percent",
|
|
9753
9733
|
onChange: () => {
|
|
9754
|
-
if (!saving) setMode("
|
|
9734
|
+
if (!saving) setMode("percent");
|
|
9755
9735
|
}
|
|
9756
9736
|
}
|
|
9757
9737
|
),
|
|
@@ -9759,10 +9739,10 @@ function CreditAllocationModal(props) {
|
|
|
9759
9739
|
import_ui13.ScPairtext,
|
|
9760
9740
|
{
|
|
9761
9741
|
type: "radio",
|
|
9762
|
-
content: "
|
|
9763
|
-
checked: mode === "
|
|
9742
|
+
content: "Fixed credits",
|
|
9743
|
+
checked: mode === "fixed",
|
|
9764
9744
|
onChange: () => {
|
|
9765
|
-
if (!saving) setMode("
|
|
9745
|
+
if (!saving) setMode("fixed");
|
|
9766
9746
|
}
|
|
9767
9747
|
}
|
|
9768
9748
|
)
|
|
@@ -9790,7 +9770,7 @@ function CreditAllocationModal(props) {
|
|
|
9790
9770
|
value: raw,
|
|
9791
9771
|
disabled: saving,
|
|
9792
9772
|
onChange: (e) => {
|
|
9793
|
-
setRaw(
|
|
9773
|
+
setRaw(cleanPoolValueInput(e.target.value));
|
|
9794
9774
|
setTouched(true);
|
|
9795
9775
|
},
|
|
9796
9776
|
className: "flex-1 min-w-0",
|
|
@@ -9808,39 +9788,18 @@ function CreditAllocationModal(props) {
|
|
|
9808
9788
|
]
|
|
9809
9789
|
}
|
|
9810
9790
|
),
|
|
9811
|
-
valueHint ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { role: "alert", style: { ...modalBodyText, color: T16.error }, children: valueHint }) :
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "Repeat on every renewal" }),
|
|
9816
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { ...modalBodyText, color: T16.muted }, children: mode === "percent" ? "Also send this share of each renewal grant this workspace receives." : "Also send these credits out of each renewal grant this workspace receives." })
|
|
9817
|
-
] }),
|
|
9818
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { display: "inline-flex", width: 41, height: 25, alignItems: "center", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9819
|
-
import_ui13.ScToggleSwitch,
|
|
9820
|
-
{
|
|
9821
|
-
checked: recurring,
|
|
9822
|
-
disabled: saving,
|
|
9823
|
-
onToggle: (next) => setRecurring(next),
|
|
9824
|
-
role: "switch",
|
|
9825
|
-
"aria-checked": recurring,
|
|
9826
|
-
"aria-label": "Repeat on every renewal",
|
|
9827
|
-
tabIndex: 0,
|
|
9828
|
-
onKeyDown: (event) => {
|
|
9829
|
-
if ((event.key === " " || event.key === "Enter") && !saving) {
|
|
9830
|
-
event.preventDefault();
|
|
9831
|
-
setRecurring(!recurring);
|
|
9832
|
-
}
|
|
9833
|
-
}
|
|
9834
|
-
}
|
|
9835
|
-
) })
|
|
9791
|
+
valueHint ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { role: "alert", style: { ...modalBodyText, color: T16.error }, children: valueHint }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { style: { ...modalBodyText, color: T16.tertiary }, children: [
|
|
9792
|
+
mode === "percent" ? "A share of this workspace's plan credits for each billing cycle. Credits stay with this workspace; the other workspace spends them up to this share." : "Credits the other workspace may spend each billing cycle. Credits stay with this workspace until spent.",
|
|
9793
|
+
editing ? " Applies immediately." : ""
|
|
9794
|
+
] })
|
|
9836
9795
|
] }),
|
|
9837
|
-
props.kind === "
|
|
9796
|
+
props.kind === "add" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col w-full", style: { gap: T16.spXs }, children: [
|
|
9838
9797
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "Note" }),
|
|
9839
9798
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9840
9799
|
import_ui13.ScTextArea,
|
|
9841
9800
|
{
|
|
9842
9801
|
value: note,
|
|
9843
|
-
maxLength:
|
|
9802
|
+
maxLength: POOL_NOTE_MAX_LENGTH,
|
|
9844
9803
|
placeholder: "Why are these credits being shared?",
|
|
9845
9804
|
disabled: saving,
|
|
9846
9805
|
onChange: (e) => setNote(e.target.value),
|
|
@@ -9852,117 +9811,57 @@ function CreditAllocationModal(props) {
|
|
|
9852
9811
|
"Required. ",
|
|
9853
9812
|
note.trim().length,
|
|
9854
9813
|
"/",
|
|
9855
|
-
|
|
9814
|
+
POOL_NOTE_MAX_LENGTH
|
|
9856
9815
|
] })
|
|
9857
9816
|
] }),
|
|
9858
|
-
props.kind === "
|
|
9817
|
+
props.kind === "add" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PoolWarning, { children: "While it spends shared credits, the other workspace uses only this workspace's credits, not its own." }),
|
|
9859
9818
|
serverError && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { role: "alert", style: { ...modalBodyText, color: T16.error }, children: serverError })
|
|
9860
9819
|
]
|
|
9861
9820
|
}
|
|
9862
9821
|
);
|
|
9863
9822
|
}
|
|
9864
9823
|
|
|
9865
|
-
// src/
|
|
9824
|
+
// src/remove-pool-member-modal.tsx
|
|
9866
9825
|
var import_react20 = require("react");
|
|
9867
9826
|
var import_ui14 = require("@streamoid/ui");
|
|
9868
9827
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
9869
|
-
function
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9828
|
+
function RemovePoolMemberModal({
|
|
9829
|
+
member,
|
|
9830
|
+
memberName,
|
|
9831
|
+
sponsorName,
|
|
9832
|
+
onRemove,
|
|
9873
9833
|
onClose,
|
|
9874
|
-
|
|
9834
|
+
onRemoved
|
|
9875
9835
|
}) {
|
|
9876
9836
|
const { toast } = useSettingsAdapters();
|
|
9877
9837
|
const [reason, setReason] = (0, import_react20.useState)("");
|
|
9878
9838
|
const [saving, setSaving] = (0, import_react20.useState)(false);
|
|
9879
|
-
const
|
|
9880
|
-
const check = validateAllocationText(reason, CANCEL_REASON_MAX_LENGTH);
|
|
9839
|
+
const check = validatePoolText(reason, REMOVE_REASON_MAX_LENGTH);
|
|
9881
9840
|
const canConfirm = !saving && check.ok;
|
|
9882
9841
|
const handleConfirm = async () => {
|
|
9883
9842
|
if (!canConfirm || !check.ok) return;
|
|
9884
9843
|
setSaving(true);
|
|
9885
9844
|
try {
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
targetName
|
|
9890
|
-
);
|
|
9891
|
-
onCanceled({ planNotRestored: Boolean(warning) });
|
|
9892
|
-
if (warning) {
|
|
9893
|
-
setOutcome({ warning, error: result.error });
|
|
9894
|
-
setSaving(false);
|
|
9895
|
-
return;
|
|
9896
|
-
}
|
|
9897
|
-
toast.success(cancelOutcomeSummary(result, targetName));
|
|
9845
|
+
await onRemove(check.value);
|
|
9846
|
+
toast.success(`${memberName} can no longer spend ${sponsorName}'s credits`);
|
|
9847
|
+
onRemoved();
|
|
9898
9848
|
onClose();
|
|
9899
9849
|
} catch (err) {
|
|
9900
9850
|
toast.error(errorMessage(err, { method: "DELETE" }));
|
|
9901
9851
|
setSaving(false);
|
|
9902
9852
|
}
|
|
9903
9853
|
};
|
|
9904
|
-
const copyId = () => {
|
|
9905
|
-
const id = allocation.targetWorkspaceKey;
|
|
9906
|
-
const clipboard = typeof navigator !== "undefined" ? navigator.clipboard : void 0;
|
|
9907
|
-
if (!clipboard) {
|
|
9908
|
-
toast.error("Couldn't copy. Select the ID and copy it instead.");
|
|
9909
|
-
return;
|
|
9910
|
-
}
|
|
9911
|
-
clipboard.writeText(id).then(
|
|
9912
|
-
() => toast.success("Workspace ID copied"),
|
|
9913
|
-
() => toast.error("Couldn't copy. Select the ID and copy it instead.")
|
|
9914
|
-
);
|
|
9915
|
-
};
|
|
9916
|
-
if (outcome) {
|
|
9917
|
-
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
9918
|
-
AllocationModalShell,
|
|
9919
|
-
{
|
|
9920
|
-
title: "Target plan not restored",
|
|
9921
|
-
busy: false,
|
|
9922
|
-
onClose,
|
|
9923
|
-
footer: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ui14.ScButton, { text: "Got it", variant: "primary", size: "md", onClick: onClose }),
|
|
9924
|
-
children: [
|
|
9925
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AllocationWarning, { children: outcome.warning }),
|
|
9926
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col w-full", style: { gap: MODAL_T.spXs }, children: [
|
|
9927
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { style: { ...modalBodyText, fontWeight: 500, color: MODAL_T.primary }, children: "Workspace ID" }),
|
|
9928
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center w-full", style: { gap: MODAL_T.spXl }, children: [
|
|
9929
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
9930
|
-
"code",
|
|
9931
|
-
{
|
|
9932
|
-
className: "flex-1 min-w-0 truncate",
|
|
9933
|
-
style: {
|
|
9934
|
-
...modalBodyText,
|
|
9935
|
-
color: MODAL_T.primary,
|
|
9936
|
-
background: MODAL_T.fillPlus,
|
|
9937
|
-
borderRadius: MODAL_T.r3xl,
|
|
9938
|
-
padding: `${MODAL_T.spXl} ${MODAL_T.sp3xl}`,
|
|
9939
|
-
userSelect: "all"
|
|
9940
|
-
},
|
|
9941
|
-
children: allocation.targetWorkspaceKey
|
|
9942
|
-
}
|
|
9943
|
-
),
|
|
9944
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_ui14.ScButton, { text: "Copy", variant: "secondary", size: "sm", onClick: copyId })
|
|
9945
|
-
] })
|
|
9946
|
-
] }),
|
|
9947
|
-
outcome.error && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { ...modalBodyText, color: MODAL_T.muted }, children: [
|
|
9948
|
-
"Details: ",
|
|
9949
|
-
outcome.error
|
|
9950
|
-
] })
|
|
9951
|
-
]
|
|
9952
|
-
}
|
|
9953
|
-
);
|
|
9954
|
-
}
|
|
9955
9854
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
9956
|
-
|
|
9855
|
+
PoolModalShell,
|
|
9957
9856
|
{
|
|
9958
|
-
title: "
|
|
9857
|
+
title: "Stop sharing credits",
|
|
9959
9858
|
busy: saving,
|
|
9960
9859
|
onClose,
|
|
9961
9860
|
footer: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
9962
9861
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
9963
9862
|
import_ui14.ScButton,
|
|
9964
9863
|
{
|
|
9965
|
-
text: "Keep
|
|
9864
|
+
text: "Keep sharing",
|
|
9966
9865
|
variant: "secondary",
|
|
9967
9866
|
size: "md",
|
|
9968
9867
|
state: saving ? "disabled" : "default",
|
|
@@ -9972,7 +9871,7 @@ function CancelCreditAllocationModal({
|
|
|
9972
9871
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
9973
9872
|
import_ui14.ScButton,
|
|
9974
9873
|
{
|
|
9975
|
-
text: "
|
|
9874
|
+
text: "Stop sharing",
|
|
9976
9875
|
variant: "error",
|
|
9977
9876
|
size: "md",
|
|
9978
9877
|
state: canConfirm ? "default" : "disabled",
|
|
@@ -9982,16 +9881,18 @@ function CancelCreditAllocationModal({
|
|
|
9982
9881
|
] }),
|
|
9983
9882
|
children: [
|
|
9984
9883
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { ...modalBodyText, color: MODAL_T.primary }, children: [
|
|
9985
|
-
"
|
|
9986
|
-
|
|
9987
|
-
"
|
|
9988
|
-
|
|
9989
|
-
"
|
|
9884
|
+
"This stops ",
|
|
9885
|
+
memberName,
|
|
9886
|
+
" spending ",
|
|
9887
|
+
sponsorName,
|
|
9888
|
+
"'s credits immediately."
|
|
9990
9889
|
] }),
|
|
9991
9890
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { ...modalBodyText, color: MODAL_T.tertiary }, children: [
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9891
|
+
"It had ",
|
|
9892
|
+
describeAllowance(member),
|
|
9893
|
+
" and has used ",
|
|
9894
|
+
formatCredits(member.used),
|
|
9895
|
+
". Credits it already spent are not returned; anything it runs from now uses its own credits."
|
|
9995
9896
|
] }),
|
|
9996
9897
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col w-full", style: { gap: MODAL_T.spXs }, children: [
|
|
9997
9898
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { style: { ...modalBodyText, fontWeight: 500, color: MODAL_T.primary }, children: "Reason" }),
|
|
@@ -9999,8 +9900,8 @@ function CancelCreditAllocationModal({
|
|
|
9999
9900
|
import_ui14.ScTextArea,
|
|
10000
9901
|
{
|
|
10001
9902
|
value: reason,
|
|
10002
|
-
maxLength:
|
|
10003
|
-
placeholder: "Why is this
|
|
9903
|
+
maxLength: REMOVE_REASON_MAX_LENGTH,
|
|
9904
|
+
placeholder: "Why is this workspace no longer sharing these credits?",
|
|
10004
9905
|
disabled: saving,
|
|
10005
9906
|
onChange: (e) => setReason(e.target.value),
|
|
10006
9907
|
rows: 3,
|
|
@@ -10014,16 +9915,13 @@ function CancelCreditAllocationModal({
|
|
|
10014
9915
|
);
|
|
10015
9916
|
}
|
|
10016
9917
|
|
|
10017
|
-
// src/
|
|
9918
|
+
// src/shared-credits-view.tsx
|
|
10018
9919
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
10019
9920
|
var T17 = {
|
|
10020
9921
|
primary: "var(--alias-text---icons-primary)",
|
|
10021
9922
|
muted: "var(--alias-text---icons-muted)",
|
|
10022
9923
|
tertiary: "var(--alias-text---icons-tertiary)",
|
|
10023
9924
|
warning: "var(--alias-text---icons-warning)",
|
|
10024
|
-
success: "var(--alias-text---icons-success)",
|
|
10025
|
-
warningFill: "var(--alias-fill-warning-soft)",
|
|
10026
|
-
warningBorder: "var(--alias-border-warning)",
|
|
10027
9925
|
fillPlus: "var(--alias-fill-neutral-neutralplus)",
|
|
10028
9926
|
surfaceBase: "var(--alias-surface-base)",
|
|
10029
9927
|
borderSubtle: "var(--alias-border-subtle)",
|
|
@@ -10037,9 +9935,7 @@ var T17 = {
|
|
|
10037
9935
|
r3xl: "var(--radius-3xl)",
|
|
10038
9936
|
rFull: "var(--radius-full)"
|
|
10039
9937
|
};
|
|
10040
|
-
var
|
|
10041
|
-
var TRANSFER_COLUMNS = "120px 170px minmax(200px, 1fr) 120px";
|
|
10042
|
-
var TRANSFERS_PAGE = 20;
|
|
9938
|
+
var MEMBER_COLUMNS2 = "minmax(220px, 1fr) 220px 110px 110px 150px";
|
|
10043
9939
|
var cellText2 = {
|
|
10044
9940
|
fontFamily: T17.font,
|
|
10045
9941
|
fontSize: T17.fsSm,
|
|
@@ -10061,138 +9957,67 @@ var tableHeader = (columns, labels) => /* @__PURE__ */ (0, import_jsx_runtime27.
|
|
|
10061
9957
|
children: labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: label }, label))
|
|
10062
9958
|
}
|
|
10063
9959
|
);
|
|
10064
|
-
function
|
|
10065
|
-
|
|
10066
|
-
"span",
|
|
10067
|
-
{
|
|
10068
|
-
className: "inline-flex items-center shrink-0",
|
|
10069
|
-
style: {
|
|
10070
|
-
...cellText2,
|
|
10071
|
-
fontSize: 12,
|
|
10072
|
-
padding: "0 8px",
|
|
10073
|
-
height: 22,
|
|
10074
|
-
borderRadius: T17.rFull,
|
|
10075
|
-
color: tone === "warning" ? T17.primary : T17.muted,
|
|
10076
|
-
background: tone === "warning" ? T17.warningFill : T17.fillPlus,
|
|
10077
|
-
border: tone === "warning" ? `1px solid ${T17.warningBorder}` : "1px solid transparent"
|
|
10078
|
-
},
|
|
10079
|
-
children: text2
|
|
10080
|
-
}
|
|
10081
|
-
);
|
|
10082
|
-
}
|
|
10083
|
-
function GivingRow({
|
|
10084
|
-
allocation,
|
|
10085
|
-
planNotRestored,
|
|
9960
|
+
function MemberRow2({
|
|
9961
|
+
member,
|
|
10086
9962
|
onEdit,
|
|
10087
|
-
|
|
9963
|
+
onRemove
|
|
10088
9964
|
}) {
|
|
10089
|
-
const
|
|
10090
|
-
const sent = initialTransferSummary(allocation);
|
|
10091
|
-
const active = allocation.status === "active";
|
|
9965
|
+
const spent = member.remaining <= 0;
|
|
10092
9966
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
10093
9967
|
"div",
|
|
10094
9968
|
{
|
|
10095
9969
|
style: {
|
|
10096
9970
|
borderBottom: `1px solid ${T17.borderSubtle}`,
|
|
10097
9971
|
display: "grid",
|
|
10098
|
-
gridTemplateColumns:
|
|
9972
|
+
gridTemplateColumns: MEMBER_COLUMNS2,
|
|
10099
9973
|
alignItems: "center",
|
|
10100
9974
|
padding: `10px ${T17.sp3xl}`,
|
|
10101
9975
|
gap: 24
|
|
10102
9976
|
},
|
|
10103
9977
|
children: [
|
|
10104
9978
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col min-w-0", style: { gap: 2 }, children: [
|
|
10105
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", style: { ...cellText2, fontWeight: 500 }, children:
|
|
10106
|
-
|
|
10107
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { text: "First transfer failed", tone: "warning" }) }),
|
|
10108
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: failed })
|
|
10109
|
-
] }) : sent ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: sent }) : null,
|
|
10110
|
-
allocation.note && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", title: allocation.note, style: { ...cellText2, color: T17.tertiary }, children: allocation.note })
|
|
10111
|
-
] }),
|
|
10112
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: formatAllocationSplit(allocation) }),
|
|
10113
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: formatAllocationRepeat(allocation.recurring) }),
|
|
10114
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center", style: { gap: 6 }, children: [
|
|
10115
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { text: active ? "Active" : "Canceled", tone: "neutral" }),
|
|
10116
|
-
planNotRestored && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Badge, { text: "Plan not restored", tone: "warning" })
|
|
9979
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", style: { ...cellText2, fontWeight: 500 }, children: poolWorkspaceName(member.memberWorkspaceName) }),
|
|
9980
|
+
member.note && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", title: member.note, style: { ...cellText2, color: T17.tertiary }, children: member.note })
|
|
10117
9981
|
] }),
|
|
10118
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style:
|
|
9982
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: describeAllowance(member) }),
|
|
9983
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: formatCredits(member.used) }),
|
|
9984
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: spent ? T17.warning : T17.primary }, children: formatCredits(member.remaining) }),
|
|
10119
9985
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center", style: { gap: 8 }, children: [
|
|
10120
|
-
|
|
10121
|
-
|
|
9986
|
+
onEdit && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Edit", variant: "secondary", size: "sm", onClick: onEdit }),
|
|
9987
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Remove", variant: "secondary", size: "sm", onClick: onRemove })
|
|
10122
9988
|
] })
|
|
10123
9989
|
]
|
|
10124
9990
|
}
|
|
10125
9991
|
);
|
|
10126
9992
|
}
|
|
10127
|
-
function
|
|
10128
|
-
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
10129
|
-
"div",
|
|
10130
|
-
{
|
|
10131
|
-
style: {
|
|
10132
|
-
borderBottom: `1px solid ${T17.borderSubtle}`,
|
|
10133
|
-
display: "grid",
|
|
10134
|
-
gridTemplateColumns: TRANSFER_COLUMNS,
|
|
10135
|
-
alignItems: "center",
|
|
10136
|
-
padding: `8px ${T17.sp3xl}`,
|
|
10137
|
-
gap: 24
|
|
10138
|
-
},
|
|
10139
|
-
children: [
|
|
10140
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: formatDate2(transfer.createdAt) }),
|
|
10141
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { style: cellText2, children: [
|
|
10142
|
-
transfer.direction === "sent" ? "Sent" : "Received",
|
|
10143
|
-
" \xB7",
|
|
10144
|
-
" ",
|
|
10145
|
-
transfer.kind === "initial" ? "Initial" : "Renewal"
|
|
10146
|
-
] }),
|
|
10147
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", style: cellText2, children: transfer.counterpartWorkspaceName ?? (transfer.counterpartWorkspaceId ? "Unknown workspace" : "\u2014") }),
|
|
10148
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { style: { ...cellText2, color: transfer.direction === "received" ? T17.success : T17.primary }, children: [
|
|
10149
|
-
transfer.direction === "received" ? "+" : "\u2212",
|
|
10150
|
-
formatCredits(transfer.credits)
|
|
10151
|
-
] })
|
|
10152
|
-
]
|
|
10153
|
-
}
|
|
10154
|
-
);
|
|
10155
|
-
}
|
|
10156
|
-
function CreditAllocationsView() {
|
|
9993
|
+
function SharedCreditsView() {
|
|
10157
9994
|
const { api, workspace, toast } = useSettingsAdapters();
|
|
10158
9995
|
const workspaceId = workspace.current?.id ?? null;
|
|
9996
|
+
const workspaceName = workspace.current?.name?.trim() || "this workspace";
|
|
10159
9997
|
const [data, setData] = (0, import_react21.useState)(null);
|
|
10160
9998
|
const [loading, setLoading] = (0, import_react21.useState)(true);
|
|
10161
9999
|
const [failed, setFailed] = (0, import_react21.useState)(false);
|
|
10162
|
-
const [
|
|
10163
|
-
const [
|
|
10164
|
-
const [transfersTotal, setTransfersTotal] = (0, import_react21.useState)(0);
|
|
10165
|
-
const [transfersPage, setTransfersPage] = (0, import_react21.useState)(0);
|
|
10166
|
-
const [transfersFailed, setTransfersFailed] = (0, import_react21.useState)(false);
|
|
10167
|
-
const [loadingMore, setLoadingMore] = (0, import_react21.useState)(false);
|
|
10168
|
-
const [creating, setCreating] = (0, import_react21.useState)(false);
|
|
10000
|
+
const [candidates, setCandidates] = (0, import_react21.useState)([]);
|
|
10001
|
+
const [adding, setAdding] = (0, import_react21.useState)(false);
|
|
10169
10002
|
const [editing, setEditing] = (0, import_react21.useState)(null);
|
|
10170
|
-
const [
|
|
10171
|
-
const [planNotRestored, setPlanNotRestored] = (0, import_react21.useState)(() => /* @__PURE__ */ new Set());
|
|
10003
|
+
const [removing, setRemoving] = (0, import_react21.useState)(null);
|
|
10172
10004
|
const latestLoad = (0, import_react21.useRef)(0);
|
|
10173
10005
|
const load = (0, import_react21.useCallback)(
|
|
10174
10006
|
async ({ refresh = false } = {}) => {
|
|
10175
10007
|
const loadId = ++latestLoad.current;
|
|
10176
|
-
if (!api.
|
|
10008
|
+
if (!api.fetchCreditPool) {
|
|
10177
10009
|
setLoading(false);
|
|
10178
10010
|
setFailed(true);
|
|
10179
10011
|
return;
|
|
10180
10012
|
}
|
|
10181
|
-
const
|
|
10182
|
-
api.fetchCreditAllocations().catch(() => null),
|
|
10183
|
-
api.fetchCreditTransfers ? api.fetchCreditTransfers({ page: 1, limit: TRANSFERS_PAGE }).catch(() => null) : Promise.resolve(null)
|
|
10184
|
-
]);
|
|
10013
|
+
const next = await api.fetchCreditPool().catch(() => null);
|
|
10185
10014
|
if (loadId !== latestLoad.current) return;
|
|
10186
10015
|
if (refresh && !next) {
|
|
10187
|
-
toast.error("Couldn't refresh
|
|
10016
|
+
toast.error("Couldn't refresh shared credits. Reopen this page to see the latest.");
|
|
10188
10017
|
return;
|
|
10189
10018
|
}
|
|
10190
10019
|
setFailed(!next);
|
|
10191
10020
|
setData(next);
|
|
10192
|
-
setTransfersFailed(Boolean(api.fetchCreditTransfers) && !page);
|
|
10193
|
-
setTransfers(page?.transfers ?? []);
|
|
10194
|
-
setTransfersTotal(page?.total ?? 0);
|
|
10195
|
-
setTransfersPage(page ? 1 : 0);
|
|
10196
10021
|
setLoading(false);
|
|
10197
10022
|
},
|
|
10198
10023
|
[api, toast]
|
|
@@ -10201,11 +10026,9 @@ function CreditAllocationsView() {
|
|
|
10201
10026
|
setLoading(true);
|
|
10202
10027
|
setFailed(false);
|
|
10203
10028
|
setData(null);
|
|
10204
|
-
|
|
10205
|
-
setCreating(false);
|
|
10029
|
+
setAdding(false);
|
|
10206
10030
|
setEditing(null);
|
|
10207
|
-
|
|
10208
|
-
setPlanNotRestored(/* @__PURE__ */ new Set());
|
|
10031
|
+
setRemoving(null);
|
|
10209
10032
|
void load();
|
|
10210
10033
|
}, [workspaceId]);
|
|
10211
10034
|
(0, import_react21.useEffect)(
|
|
@@ -10215,36 +10038,21 @@ function CreditAllocationsView() {
|
|
|
10215
10038
|
[]
|
|
10216
10039
|
);
|
|
10217
10040
|
const canManage = Boolean(data?.canManage);
|
|
10218
|
-
const
|
|
10219
|
-
const
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10041
|
+
const sponsor = data?.sponsor ?? null;
|
|
10042
|
+
const canAdd = canManage && !sponsor && Boolean(api.addCreditPoolMember);
|
|
10043
|
+
const openAdd = async () => {
|
|
10044
|
+
if (!api.fetchCreditPoolCandidates) {
|
|
10045
|
+
setCandidates([]);
|
|
10046
|
+
setAdding(true);
|
|
10223
10047
|
return;
|
|
10224
10048
|
}
|
|
10225
10049
|
try {
|
|
10226
|
-
|
|
10227
|
-
|
|
10050
|
+
setCandidates(await api.fetchCreditPoolCandidates());
|
|
10051
|
+
setAdding(true);
|
|
10228
10052
|
} catch {
|
|
10229
10053
|
toast.error("Couldn't load this organization's workspaces. Try again.");
|
|
10230
10054
|
}
|
|
10231
10055
|
};
|
|
10232
|
-
const loadMoreTransfers = async () => {
|
|
10233
|
-
if (!api.fetchCreditTransfers || loadingMore) return;
|
|
10234
|
-
const loadId = latestLoad.current;
|
|
10235
|
-
setLoadingMore(true);
|
|
10236
|
-
try {
|
|
10237
|
-
const page = await api.fetchCreditTransfers({ page: transfersPage + 1, limit: TRANSFERS_PAGE });
|
|
10238
|
-
if (loadId !== latestLoad.current) return;
|
|
10239
|
-
setTransfers((prev) => [...prev, ...page.transfers]);
|
|
10240
|
-
setTransfersTotal(page.total);
|
|
10241
|
-
setTransfersPage(transfersPage + 1);
|
|
10242
|
-
} catch {
|
|
10243
|
-
toast.error("Couldn't load more transfers. Try again.");
|
|
10244
|
-
} finally {
|
|
10245
|
-
setLoadingMore(false);
|
|
10246
|
-
}
|
|
10247
|
-
};
|
|
10248
10056
|
if (loading) {
|
|
10249
10057
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10250
10058
|
"div",
|
|
@@ -10267,9 +10075,7 @@ function CreditAllocationsView() {
|
|
|
10267
10075
|
}
|
|
10268
10076
|
);
|
|
10269
10077
|
}
|
|
10270
|
-
const
|
|
10271
|
-
const sponsor = data?.receiving.find((a) => a.status === "active") ?? null;
|
|
10272
|
-
const balance = typeof workspace.current?.availableCredits === "number" ? workspace.current.availableCredits : null;
|
|
10078
|
+
const members = data?.members ?? [];
|
|
10273
10079
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col flex-1 min-h-0 w-full overflow-y-auto", style: { gap: 16 }, children: [
|
|
10274
10080
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start justify-between shrink-0 w-full", style: { gap: 12 }, children: [
|
|
10275
10081
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col min-w-0", style: { gap: 4 }, children: [
|
|
@@ -10277,12 +10083,12 @@ function CreditAllocationsView() {
|
|
|
10277
10083
|
"span",
|
|
10278
10084
|
{
|
|
10279
10085
|
style: { fontFamily: T17.font, fontSize: T17.fsXl, fontWeight: 500, lineHeight: T17.lhXl, color: T17.primary },
|
|
10280
|
-
children: "
|
|
10086
|
+
children: "Shared credits"
|
|
10281
10087
|
}
|
|
10282
10088
|
),
|
|
10283
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: canManage ? "
|
|
10089
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: canManage ? "Let other workspaces in your organization spend this workspace's credits, up to a share each billing cycle. The credits stay here." : "Workspaces in this organization that spend this workspace's credits. Only organization admins can change them." })
|
|
10284
10090
|
] }),
|
|
10285
|
-
|
|
10091
|
+
canAdd && !failed && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Share credits", variant: "primary", size: "md", onClick: () => void openAdd() })
|
|
10286
10092
|
] }),
|
|
10287
10093
|
sponsor && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
10288
10094
|
"div",
|
|
@@ -10296,103 +10102,74 @@ function CreditAllocationsView() {
|
|
|
10296
10102
|
borderRadius: T17.r3xl
|
|
10297
10103
|
},
|
|
10298
10104
|
children: [
|
|
10299
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10105
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, fontWeight: 500 }, children: sharedPoolBannerText({
|
|
10106
|
+
sponsorName: poolWorkspaceName(sponsor.sponsorWorkspaceName),
|
|
10107
|
+
allowance: sponsor.allowance,
|
|
10108
|
+
remaining: sponsor.remaining
|
|
10109
|
+
}) }),
|
|
10303
10110
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { style: { ...cellText2, color: T17.muted }, children: [
|
|
10304
|
-
"
|
|
10305
|
-
|
|
10111
|
+
"This workspace spends ",
|
|
10112
|
+
poolWorkspaceName(sponsor.sponsorWorkspaceName),
|
|
10113
|
+
"'s credits, not its own",
|
|
10114
|
+
sponsor.cycle?.end ? `, until its allowance starts again on ${formatDate2(sponsor.cycle.end)}` : "",
|
|
10306
10115
|
"."
|
|
10307
10116
|
] })
|
|
10308
10117
|
]
|
|
10309
10118
|
}
|
|
10310
10119
|
),
|
|
10311
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col shrink-0 w-full", style: { gap: 8 }, children: [
|
|
10312
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, fontWeight: 500 }, children: "
|
|
10120
|
+
!sponsor && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col shrink-0 w-full", style: { gap: 8 }, children: [
|
|
10121
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, fontWeight: 500 }, children: "Shared with" }),
|
|
10313
10122
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10314
10123
|
MemberListFrame,
|
|
10315
10124
|
{
|
|
10316
10125
|
grow: "cap",
|
|
10317
10126
|
maxHeight: 420,
|
|
10318
|
-
contentMinWidth:
|
|
10319
|
-
header: tableHeader(
|
|
10320
|
-
isEmpty: failed ||
|
|
10321
|
-
emptyText: failed ? "Couldn't load
|
|
10322
|
-
children:
|
|
10323
|
-
|
|
10127
|
+
contentMinWidth: 860,
|
|
10128
|
+
header: tableHeader(MEMBER_COLUMNS2, ["Workspace", "Allowance", "Used", "Remaining", "Actions"]),
|
|
10129
|
+
isEmpty: failed || members.length === 0,
|
|
10130
|
+
emptyText: failed ? "Couldn't load shared credits. Try again later." : "This workspace doesn't share its credits with any other workspace.",
|
|
10131
|
+
children: members.map((member) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10132
|
+
MemberRow2,
|
|
10324
10133
|
{
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
onCancel: canManage && api.cancelCreditAllocation ? () => setCanceling(allocation) : void 0
|
|
10134
|
+
member,
|
|
10135
|
+
onEdit: canManage && api.updateCreditPoolMember ? () => setEditing(member) : void 0,
|
|
10136
|
+
onRemove: canManage && api.removeCreditPoolMember ? () => setRemoving(member) : void 0
|
|
10329
10137
|
},
|
|
10330
|
-
|
|
10138
|
+
member._id
|
|
10331
10139
|
))
|
|
10332
10140
|
}
|
|
10333
10141
|
)
|
|
10334
10142
|
] }),
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10338
|
-
MemberListFrame,
|
|
10339
|
-
{
|
|
10340
|
-
grow: "cap",
|
|
10341
|
-
maxHeight: 420,
|
|
10342
|
-
contentMinWidth: 680,
|
|
10343
|
-
header: tableHeader(TRANSFER_COLUMNS, ["Date", "Type", "Workspace", "Credits"]),
|
|
10344
|
-
isEmpty: transfersFailed || transfers.length === 0,
|
|
10345
|
-
emptyText: transfersFailed ? "Couldn't load transfers. Try again later." : "No transfers yet",
|
|
10346
|
-
children: transfers.map((transfer) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TransferRow, { transfer }, transfer.id))
|
|
10347
|
-
}
|
|
10348
|
-
),
|
|
10349
|
-
transfers.length < transfersTotal && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10350
|
-
import_ui15.ScButton,
|
|
10351
|
-
{
|
|
10352
|
-
text: loadingMore ? "Loading\u2026" : "Load more",
|
|
10353
|
-
variant: "secondary",
|
|
10354
|
-
size: "sm",
|
|
10355
|
-
state: loadingMore ? "disabled" : "default",
|
|
10356
|
-
onClick: loadingMore ? void 0 : () => void loadMoreTransfers()
|
|
10357
|
-
}
|
|
10358
|
-
) })
|
|
10359
|
-
] }),
|
|
10360
|
-
creating && api.createCreditAllocation && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10361
|
-
CreditAllocationModal,
|
|
10143
|
+
adding && api.addCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10144
|
+
CreditPoolMemberModal,
|
|
10362
10145
|
{
|
|
10363
|
-
kind: "
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
onClose: () => setCreating(false),
|
|
10146
|
+
kind: "add",
|
|
10147
|
+
candidates,
|
|
10148
|
+
onSave: (input) => api.addCreditPoolMember(input),
|
|
10149
|
+
onClose: () => setAdding(false),
|
|
10368
10150
|
onSaved: () => void load({ refresh: true })
|
|
10369
10151
|
}
|
|
10370
10152
|
),
|
|
10371
|
-
editing && api.
|
|
10372
|
-
|
|
10153
|
+
editing && api.updateCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10154
|
+
CreditPoolMemberModal,
|
|
10373
10155
|
{
|
|
10374
10156
|
kind: "edit",
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
onSave: (patch) => api.
|
|
10157
|
+
member: editing,
|
|
10158
|
+
memberName: poolWorkspaceName(editing.memberWorkspaceName),
|
|
10159
|
+
onSave: (patch) => api.updateCreditPoolMember(editing._id, patch),
|
|
10378
10160
|
onClose: () => setEditing(null),
|
|
10379
10161
|
onSaved: () => void load({ refresh: true })
|
|
10380
10162
|
}
|
|
10381
10163
|
),
|
|
10382
|
-
|
|
10383
|
-
|
|
10164
|
+
removing && api.removeCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10165
|
+
RemovePoolMemberModal,
|
|
10384
10166
|
{
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
const id = canceling._id;
|
|
10392
|
-
setPlanNotRestored((prev) => new Set(prev).add(id));
|
|
10393
|
-
}
|
|
10394
|
-
void load({ refresh: true });
|
|
10395
|
-
}
|
|
10167
|
+
member: removing,
|
|
10168
|
+
memberName: poolWorkspaceName(removing.memberWorkspaceName),
|
|
10169
|
+
sponsorName: workspaceName,
|
|
10170
|
+
onRemove: (reason) => api.removeCreditPoolMember(removing._id, reason),
|
|
10171
|
+
onClose: () => setRemoving(null),
|
|
10172
|
+
onRemoved: () => void load({ refresh: true })
|
|
10396
10173
|
}
|
|
10397
10174
|
)
|
|
10398
10175
|
] });
|
|
@@ -11282,8 +11059,11 @@ function InvoiceHistoryTable({
|
|
|
11282
11059
|
function UsageLogsTable({
|
|
11283
11060
|
logs,
|
|
11284
11061
|
userMap,
|
|
11285
|
-
loading
|
|
11062
|
+
loading,
|
|
11063
|
+
currentWorkspaceId = null,
|
|
11064
|
+
usedByNames = {}
|
|
11286
11065
|
}) {
|
|
11066
|
+
const showWorkspace = logs.some((log) => usedByWorkspaceKey(log, currentWorkspaceId));
|
|
11287
11067
|
if (loading) {
|
|
11288
11068
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11289
11069
|
"div",
|
|
@@ -11360,6 +11140,14 @@ function UsageLogsTable({
|
|
|
11360
11140
|
style: { flexShrink: 0, width: "7.5rem" }
|
|
11361
11141
|
}
|
|
11362
11142
|
),
|
|
11143
|
+
showWorkspace && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11144
|
+
import_ui16.ScHeader,
|
|
11145
|
+
{
|
|
11146
|
+
text: "Workspace",
|
|
11147
|
+
state: "none",
|
|
11148
|
+
style: { flexShrink: 0, width: "9rem" }
|
|
11149
|
+
}
|
|
11150
|
+
),
|
|
11363
11151
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11364
11152
|
import_ui16.ScHeader,
|
|
11365
11153
|
{
|
|
@@ -11406,6 +11194,8 @@ function UsageLogsTable({
|
|
|
11406
11194
|
logs.map((log) => {
|
|
11407
11195
|
const userName = log.triggeredByUserId ? userMap[log.triggeredByUserId] || "Unknown" : "System";
|
|
11408
11196
|
const app = log.service?.serviceGroupName || "\u2014";
|
|
11197
|
+
const usedBy = usedByWorkspaceKey(log, currentWorkspaceId);
|
|
11198
|
+
const workspaceLabel2 = usedBy ? `Used by ${usedByNames[usedBy.toLowerCase()] ?? "another workspace"}` : "This workspace";
|
|
11409
11199
|
const activity = log.type === "return" ? "Returned Credits" : log.meta?.info || "Credit usage";
|
|
11410
11200
|
const isPositive = log.type === "return" || log.type === "add";
|
|
11411
11201
|
const signedAmount = `${isPositive ? "+" : "-"}${log.amount}`;
|
|
@@ -11435,6 +11225,18 @@ function UsageLogsTable({
|
|
|
11435
11225
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, flex: 1 }, children: app }),
|
|
11436
11226
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, flex: 1 }, children: activity }),
|
|
11437
11227
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, width: "7.5rem" }, children: userName }),
|
|
11228
|
+
showWorkspace && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11229
|
+
"div",
|
|
11230
|
+
{
|
|
11231
|
+
style: {
|
|
11232
|
+
...rowCellRegular,
|
|
11233
|
+
width: "9rem",
|
|
11234
|
+
color: usedBy ? "var(--alias-text---icons-primary, #f5f5f5)" : "var(--alias-text---icons-muted)"
|
|
11235
|
+
},
|
|
11236
|
+
title: workspaceLabel2,
|
|
11237
|
+
children: workspaceLabel2
|
|
11238
|
+
}
|
|
11239
|
+
),
|
|
11438
11240
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, width: "7.5rem" }, children: formatDate3(log.createdAt) }),
|
|
11439
11241
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11440
11242
|
"div",
|
|
@@ -11503,8 +11305,8 @@ function BillingContent({
|
|
|
11503
11305
|
onShowPlansChange,
|
|
11504
11306
|
showPerUserLimits: showPerUserLimitsProp,
|
|
11505
11307
|
onShowPerUserLimitsChange,
|
|
11506
|
-
|
|
11507
|
-
|
|
11308
|
+
showSharedCredits: showSharedCreditsProp,
|
|
11309
|
+
onShowSharedCreditsChange
|
|
11508
11310
|
} = {}) {
|
|
11509
11311
|
const { auth, workspace, organization, api, toast, navigation } = useSettingsAdapters();
|
|
11510
11312
|
const user = auth.user;
|
|
@@ -11529,21 +11331,23 @@ function BillingContent({
|
|
|
11529
11331
|
if (onShowPerUserLimitsChange) onShowPerUserLimitsChange(next);
|
|
11530
11332
|
else setShowPerUserLimitsInternal(next);
|
|
11531
11333
|
};
|
|
11532
|
-
const
|
|
11334
|
+
const canShareCredits = canShowSharedCredits(
|
|
11533
11335
|
api,
|
|
11534
11336
|
workspace.current,
|
|
11535
11337
|
organization?.current
|
|
11536
11338
|
);
|
|
11537
|
-
const [
|
|
11538
|
-
const
|
|
11539
|
-
const
|
|
11540
|
-
if (
|
|
11541
|
-
else
|
|
11339
|
+
const [showSharedCreditsInternal, setShowSharedCreditsInternal] = (0, import_react22.useState)(false);
|
|
11340
|
+
const showSharedCredits = (showSharedCreditsProp ?? showSharedCreditsInternal) && canShareCredits;
|
|
11341
|
+
const setShowSharedCredits = (next) => {
|
|
11342
|
+
if (onShowSharedCreditsChange) onShowSharedCreditsChange(next);
|
|
11343
|
+
else setShowSharedCreditsInternal(next);
|
|
11542
11344
|
};
|
|
11543
11345
|
const [showExportModal, setShowExportModal] = (0, import_react22.useState)(false);
|
|
11544
11346
|
const [showBuyCreditsModal, setShowBuyCreditsModal] = (0, import_react22.useState)(false);
|
|
11545
11347
|
const [subscription, setSubscription] = (0, import_react22.useState)(null);
|
|
11546
11348
|
const [availableCredits, setAvailableCredits] = (0, import_react22.useState)(null);
|
|
11349
|
+
const [sharedPool, setSharedPool] = (0, import_react22.useState)(null);
|
|
11350
|
+
const [usedByNames, setUsedByNames] = (0, import_react22.useState)({});
|
|
11547
11351
|
const [products, setProducts] = (0, import_react22.useState)([]);
|
|
11548
11352
|
const [invoices, setInvoices] = (0, import_react22.useState)([]);
|
|
11549
11353
|
const [totalCredits, setTotalCredits] = (0, import_react22.useState)(null);
|
|
@@ -11594,6 +11398,7 @@ function BillingContent({
|
|
|
11594
11398
|
if (subRes?.data) setSubscription(subRes.data);
|
|
11595
11399
|
if (creditsRes?.availableCredits != null)
|
|
11596
11400
|
setAvailableCredits(creditsRes.availableCredits);
|
|
11401
|
+
setSharedPool(creditsRes?.sharedPool ?? null);
|
|
11597
11402
|
if (productsRes?.data) {
|
|
11598
11403
|
const normalizedWorkspaceCountry = workspace.current?.country?.trim().toUpperCase();
|
|
11599
11404
|
const targetCurrency = normalizedWorkspaceCountry === "IN" ? "inr" : "usd";
|
|
@@ -11642,7 +11447,12 @@ function BillingContent({
|
|
|
11642
11447
|
);
|
|
11643
11448
|
} else if (api.fetchUsageLogs) {
|
|
11644
11449
|
const res = await api.fetchUsageLogs();
|
|
11645
|
-
|
|
11450
|
+
const logs = res.data?.length ? res.data : [];
|
|
11451
|
+
setUsageLogs(logs);
|
|
11452
|
+
if (api.fetchCreditPool && logs.some((log) => usedByWorkspaceKey(log, workspaceId))) {
|
|
11453
|
+
const pool = await api.fetchCreditPool().catch(() => null);
|
|
11454
|
+
setUsedByNames(usedByNamesFrom(pool));
|
|
11455
|
+
}
|
|
11646
11456
|
} else {
|
|
11647
11457
|
setUsageLogs([]);
|
|
11648
11458
|
}
|
|
@@ -11653,7 +11463,7 @@ function BillingContent({
|
|
|
11653
11463
|
setLoadingTable(false);
|
|
11654
11464
|
}
|
|
11655
11465
|
},
|
|
11656
|
-
[api]
|
|
11466
|
+
[api, workspaceId]
|
|
11657
11467
|
);
|
|
11658
11468
|
const handlePlanAction = (0, import_react22.useCallback)(
|
|
11659
11469
|
async ({ productId, priceId, planName: planName2 }) => {
|
|
@@ -11811,10 +11621,13 @@ function BillingContent({
|
|
|
11811
11621
|
);
|
|
11812
11622
|
const scheduledDowngradeText = subscription?.downgradeScheduled && subscription.plan?.name ? `Downgrades to ${subscription.plan.name}${scheduledDowngradeDateLabel ? ` ${scheduledDowngradeDateLabel}` : ""}` : void 0;
|
|
11813
11623
|
const isPlanDetailsLoading = !billingOverviewLoaded || loadingBilling || subscription?.plan == null || !planName || planName === "-" || !planAmount || currentPlanCredits == null;
|
|
11814
|
-
const
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11624
|
+
const {
|
|
11625
|
+
used: usedCredits,
|
|
11626
|
+
remaining: remainingCredits,
|
|
11627
|
+
progressPct,
|
|
11628
|
+
remainingPct
|
|
11629
|
+
} = creditsMeter({ availableCredits, totalCredits, sharedPool });
|
|
11630
|
+
const usageText = usedCredits != null ? formatCredits2(usedCredits) : remainingCredits != null ? `${formatCredits2(remainingCredits)} available` : customPlanCredits != null ? `${formatCredits2(customPlanCredits)} credits` : "\u2014";
|
|
11818
11631
|
const handleExport = async (startDate, endDate) => {
|
|
11819
11632
|
const end = new Date(endDate);
|
|
11820
11633
|
end.setHours(23, 59, 59, 999);
|
|
@@ -11891,7 +11704,7 @@ function BillingContent({
|
|
|
11891
11704
|
function fmtFilename(d) {
|
|
11892
11705
|
return d.toISOString().slice(0, 10);
|
|
11893
11706
|
}
|
|
11894
|
-
async function handleBuyCredits(
|
|
11707
|
+
async function handleBuyCredits(credits2, price) {
|
|
11895
11708
|
if (!workspaceId) {
|
|
11896
11709
|
toast.error("Missing workspace details for credit top-up");
|
|
11897
11710
|
return;
|
|
@@ -11903,14 +11716,14 @@ function BillingContent({
|
|
|
11903
11716
|
"Buy credits confirmed",
|
|
11904
11717
|
{
|
|
11905
11718
|
action: "confirm_buy_credits",
|
|
11906
|
-
additionalInfo: `${
|
|
11719
|
+
additionalInfo: `${credits2}:${price}`
|
|
11907
11720
|
}
|
|
11908
11721
|
);
|
|
11909
11722
|
try {
|
|
11910
11723
|
const topupCurrency = workspace.current?.country?.trim().toUpperCase() === "IN" ? "inr" : "usd";
|
|
11911
11724
|
const res = await api.buyCredits({
|
|
11912
11725
|
serviceName: DEFAULT_TOPUP_SERVICE,
|
|
11913
|
-
credits,
|
|
11726
|
+
credits: credits2,
|
|
11914
11727
|
unitAmount: price,
|
|
11915
11728
|
itemCount: 1,
|
|
11916
11729
|
currency: topupCurrency,
|
|
@@ -11928,7 +11741,7 @@ function BillingContent({
|
|
|
11928
11741
|
setAvailableCredits(payloadData.availableCredits);
|
|
11929
11742
|
} else {
|
|
11930
11743
|
setAvailableCredits(
|
|
11931
|
-
(prev) => typeof prev === "number" ? prev +
|
|
11744
|
+
(prev) => typeof prev === "number" ? prev + credits2 : prev
|
|
11932
11745
|
);
|
|
11933
11746
|
}
|
|
11934
11747
|
toast.success("Top-up created");
|
|
@@ -11998,13 +11811,13 @@ function BillingContent({
|
|
|
11998
11811
|
}
|
|
11999
11812
|
) });
|
|
12000
11813
|
}
|
|
12001
|
-
if (
|
|
12002
|
-
const
|
|
12003
|
-
!
|
|
12004
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11814
|
+
if (showSharedCredits) {
|
|
11815
|
+
const sharedCreditsView = /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col flex-1 h-full min-h-0 min-w-0 w-full", style: { gap: 16 }, children: [
|
|
11816
|
+
!onShowSharedCreditsChange && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(BackToBilling, { onClick: () => setShowSharedCredits(false) }),
|
|
11817
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SharedCreditsView, {})
|
|
12005
11818
|
] });
|
|
12006
|
-
if (embedded) return
|
|
12007
|
-
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex-1 h-full min-h-0 min-w-0 relative", children:
|
|
11819
|
+
if (embedded) return sharedCreditsView;
|
|
11820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex-1 h-full min-h-0 min-w-0 relative", children: sharedCreditsView });
|
|
12008
11821
|
}
|
|
12009
11822
|
if (showPerUserLimits) {
|
|
12010
11823
|
const limitsView = /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col flex-1 h-full min-h-0 min-w-0 w-full", style: { gap: 16 }, children: [
|
|
@@ -12071,7 +11884,7 @@ function BillingContent({
|
|
|
12071
11884
|
{
|
|
12072
11885
|
usageLabel: "Credits used",
|
|
12073
11886
|
usageText,
|
|
12074
|
-
remainingText:
|
|
11887
|
+
remainingText: remainingCredits != null ? `${formatCredits2(remainingCredits)} (${remainingPct}%) Remaining` : `${remainingPct}% Remaining`,
|
|
12075
11888
|
buyButtonText: "Buy credits",
|
|
12076
11889
|
buyButtonState: isFreePlan ? "disabled" : "default",
|
|
12077
11890
|
buyButtonHoverText: isFreePlan ? "Pro plan required" : void 0,
|
|
@@ -12091,6 +11904,50 @@ function BillingContent({
|
|
|
12091
11904
|
]
|
|
12092
11905
|
}
|
|
12093
11906
|
),
|
|
11907
|
+
sharedPool ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
11908
|
+
"div",
|
|
11909
|
+
{
|
|
11910
|
+
role: "status",
|
|
11911
|
+
className: "flex flex-col shrink-0 w-full",
|
|
11912
|
+
style: {
|
|
11913
|
+
gap: 4,
|
|
11914
|
+
padding: 16,
|
|
11915
|
+
backgroundColor: "var(--alias-surface-base)",
|
|
11916
|
+
border: "1px solid var(--alias-border-subtle)",
|
|
11917
|
+
borderRadius: "var(--radius-3xl)"
|
|
11918
|
+
},
|
|
11919
|
+
children: [
|
|
11920
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11921
|
+
"span",
|
|
11922
|
+
{
|
|
11923
|
+
style: {
|
|
11924
|
+
fontFamily: "var(--font-family-font-family-body)",
|
|
11925
|
+
fontSize: "var(--font-size-font-size-sm)",
|
|
11926
|
+
fontWeight: 500,
|
|
11927
|
+
lineHeight: "var(--line-height-line-height-sm)",
|
|
11928
|
+
color: "var(--alias-text---icons-primary)"
|
|
11929
|
+
},
|
|
11930
|
+
children: sharedPoolBannerText(sharedPool)
|
|
11931
|
+
}
|
|
11932
|
+
),
|
|
11933
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
11934
|
+
"span",
|
|
11935
|
+
{
|
|
11936
|
+
style: {
|
|
11937
|
+
fontFamily: "var(--font-family-font-family-body)",
|
|
11938
|
+
fontSize: "var(--font-size-font-size-sm)",
|
|
11939
|
+
lineHeight: "var(--line-height-line-height-sm)",
|
|
11940
|
+
color: "var(--alias-text---icons-muted)"
|
|
11941
|
+
},
|
|
11942
|
+
children: [
|
|
11943
|
+
pausedOwnCreditsText(sharedPool),
|
|
11944
|
+
sharedPool.cycleEnd ? ` The allowance starts again on ${formatDate3(sharedPool.cycleEnd)}.` : ""
|
|
11945
|
+
]
|
|
11946
|
+
}
|
|
11947
|
+
)
|
|
11948
|
+
]
|
|
11949
|
+
}
|
|
11950
|
+
) : null,
|
|
12094
11951
|
usage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
12095
11952
|
"div",
|
|
12096
11953
|
{
|
|
@@ -12164,7 +12021,7 @@ function BillingContent({
|
|
|
12164
12021
|
]
|
|
12165
12022
|
}
|
|
12166
12023
|
) : null,
|
|
12167
|
-
|
|
12024
|
+
canShareCredits ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
12168
12025
|
"div",
|
|
12169
12026
|
{
|
|
12170
12027
|
className: "flex items-center justify-between shrink-0 w-full",
|
|
@@ -12187,7 +12044,7 @@ function BillingContent({
|
|
|
12187
12044
|
lineHeight: "var(--line-height-line-height-sm)",
|
|
12188
12045
|
color: "var(--alias-text---icons-primary)"
|
|
12189
12046
|
},
|
|
12190
|
-
children: "
|
|
12047
|
+
children: "Shared credits"
|
|
12191
12048
|
}
|
|
12192
12049
|
),
|
|
12193
12050
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -12199,7 +12056,7 @@ function BillingContent({
|
|
|
12199
12056
|
lineHeight: "var(--line-height-line-height-sm)",
|
|
12200
12057
|
color: "var(--alias-text---icons-muted)"
|
|
12201
12058
|
},
|
|
12202
|
-
children: "
|
|
12059
|
+
children: "Let other workspaces in your organization spend this workspace's credits"
|
|
12203
12060
|
}
|
|
12204
12061
|
)
|
|
12205
12062
|
] }),
|
|
@@ -12209,7 +12066,7 @@ function BillingContent({
|
|
|
12209
12066
|
text: "Manage",
|
|
12210
12067
|
variant: "secondary",
|
|
12211
12068
|
size: "md",
|
|
12212
|
-
onClick: () =>
|
|
12069
|
+
onClick: () => setShowSharedCredits(true)
|
|
12213
12070
|
}
|
|
12214
12071
|
)
|
|
12215
12072
|
]
|
|
@@ -12259,7 +12116,9 @@ function BillingContent({
|
|
|
12259
12116
|
{
|
|
12260
12117
|
logs: usageLogs,
|
|
12261
12118
|
userMap,
|
|
12262
|
-
loading: loadingTable
|
|
12119
|
+
loading: loadingTable,
|
|
12120
|
+
currentWorkspaceId: workspaceId,
|
|
12121
|
+
usedByNames
|
|
12263
12122
|
}
|
|
12264
12123
|
),
|
|
12265
12124
|
showExportModal && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -12278,8 +12137,8 @@ function BillingContent({
|
|
|
12278
12137
|
workspace.current?.country
|
|
12279
12138
|
),
|
|
12280
12139
|
onClose: () => setShowBuyCreditsModal(false),
|
|
12281
|
-
onBuy: (
|
|
12282
|
-
handleBuyCredits(
|
|
12140
|
+
onBuy: (credits2, price) => {
|
|
12141
|
+
handleBuyCredits(credits2, price);
|
|
12283
12142
|
}
|
|
12284
12143
|
}
|
|
12285
12144
|
)
|
|
@@ -14927,20 +14786,20 @@ function SettingsContentInner({
|
|
|
14927
14786
|
const isBillingPlans = activeTab === "billing" && isWorkspaceAdmin && billingShowPlans;
|
|
14928
14787
|
const [billingShowPerUserLimits, setBillingShowPerUserLimits] = (0, import_react26.useState)(false);
|
|
14929
14788
|
const isBillingPerUserLimits = activeTab === "billing" && isWorkspaceAdmin && billingShowPerUserLimits && !billingShowPlans;
|
|
14930
|
-
const [
|
|
14931
|
-
const
|
|
14932
|
-
const isBillingSubView = isBillingPlans || isBillingPerUserLimits ||
|
|
14789
|
+
const [billingShowSharedCredits, setBillingShowSharedCredits] = (0, import_react26.useState)(false);
|
|
14790
|
+
const isBillingSharedCredits = activeTab === "billing" && isWorkspaceAdmin && billingShowSharedCredits && !billingShowPlans && !billingShowPerUserLimits;
|
|
14791
|
+
const isBillingSubView = isBillingPlans || isBillingPerUserLimits || isBillingSharedCredits;
|
|
14933
14792
|
(0, import_react26.useEffect)(() => {
|
|
14934
14793
|
if (activeTab !== "billing" || !isWorkspaceAdmin) {
|
|
14935
14794
|
setBillingShowPlans(false);
|
|
14936
14795
|
setBillingShowPerUserLimits(false);
|
|
14937
|
-
|
|
14796
|
+
setBillingShowSharedCredits(false);
|
|
14938
14797
|
}
|
|
14939
14798
|
}, [activeTab, isWorkspaceAdmin]);
|
|
14940
14799
|
(0, import_react26.useEffect)(() => {
|
|
14941
14800
|
setBillingShowPlans(false);
|
|
14942
14801
|
setBillingShowPerUserLimits(false);
|
|
14943
|
-
|
|
14802
|
+
setBillingShowSharedCredits(false);
|
|
14944
14803
|
}, [workspaceId]);
|
|
14945
14804
|
(0, import_react26.useEffect)(() => {
|
|
14946
14805
|
if (!onClose) return;
|
|
@@ -14955,15 +14814,15 @@ function SettingsContentInner({
|
|
|
14955
14814
|
setBillingShowPerUserLimits(false);
|
|
14956
14815
|
return;
|
|
14957
14816
|
}
|
|
14958
|
-
if (
|
|
14959
|
-
|
|
14817
|
+
if (billingShowSharedCredits) {
|
|
14818
|
+
setBillingShowSharedCredits(false);
|
|
14960
14819
|
return;
|
|
14961
14820
|
}
|
|
14962
14821
|
onClose();
|
|
14963
14822
|
};
|
|
14964
14823
|
document.addEventListener("keydown", handleKeyDown);
|
|
14965
14824
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
14966
|
-
}, [onClose, billingShowPlans, billingShowPerUserLimits,
|
|
14825
|
+
}, [onClose, billingShowPlans, billingShowPerUserLimits, billingShowSharedCredits]);
|
|
14967
14826
|
const [localWorkspaces, setLocalWorkspaces] = (0, import_react26.useState)(null);
|
|
14968
14827
|
const [wsModalOpen, setWsModalOpen] = (0, import_react26.useState)(false);
|
|
14969
14828
|
const [wsModalMode, setWsModalMode] = (0, import_react26.useState)("create");
|
|
@@ -15284,7 +15143,7 @@ function SettingsContentInner({
|
|
|
15284
15143
|
if (isBillingSubView) {
|
|
15285
15144
|
setBillingShowPlans(false);
|
|
15286
15145
|
setBillingShowPerUserLimits(false);
|
|
15287
|
-
|
|
15146
|
+
setBillingShowSharedCredits(false);
|
|
15288
15147
|
return;
|
|
15289
15148
|
}
|
|
15290
15149
|
if (onBack) onBack();
|
|
@@ -15387,7 +15246,7 @@ function SettingsContentInner({
|
|
|
15387
15246
|
}
|
|
15388
15247
|
)
|
|
15389
15248
|
] }),
|
|
15390
|
-
|
|
15249
|
+
isBillingSharedCredits && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
15391
15250
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons17.SiconRight, { className: "w-6 h-6 shrink-0", color: "var(--alias-text---icons-primary)" }),
|
|
15392
15251
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
15393
15252
|
"span",
|
|
@@ -15399,7 +15258,7 @@ function SettingsContentInner({
|
|
|
15399
15258
|
lineHeight: "var(--line-height-line-height-xl)",
|
|
15400
15259
|
color: "var(--alias-text---icons-primary)"
|
|
15401
15260
|
},
|
|
15402
|
-
children: "
|
|
15261
|
+
children: "Shared credits"
|
|
15403
15262
|
}
|
|
15404
15263
|
)
|
|
15405
15264
|
] })
|
|
@@ -15612,7 +15471,7 @@ function SettingsContentInner({
|
|
|
15612
15471
|
setBillingShowPlans(open);
|
|
15613
15472
|
if (open) {
|
|
15614
15473
|
setBillingShowPerUserLimits(false);
|
|
15615
|
-
|
|
15474
|
+
setBillingShowSharedCredits(false);
|
|
15616
15475
|
}
|
|
15617
15476
|
},
|
|
15618
15477
|
showPerUserLimits: billingShowPerUserLimits,
|
|
@@ -15620,12 +15479,12 @@ function SettingsContentInner({
|
|
|
15620
15479
|
setBillingShowPerUserLimits(open);
|
|
15621
15480
|
if (open) {
|
|
15622
15481
|
setBillingShowPlans(false);
|
|
15623
|
-
|
|
15482
|
+
setBillingShowSharedCredits(false);
|
|
15624
15483
|
}
|
|
15625
15484
|
},
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15485
|
+
showSharedCredits: billingShowSharedCredits,
|
|
15486
|
+
onShowSharedCreditsChange: (open) => {
|
|
15487
|
+
setBillingShowSharedCredits(open);
|
|
15629
15488
|
if (open) {
|
|
15630
15489
|
setBillingShowPlans(false);
|
|
15631
15490
|
setBillingShowPerUserLimits(false);
|