@streamoid/settings 0.10.1 → 0.11.0
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 +168 -184
- package/dist/index.d.ts +168 -184
- package/dist/index.js +365 -514
- package/dist/index.mjs +366 -515
- 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,20 @@ __export(index_exports, {
|
|
|
98
92
|
loadWorkspaceOrganization: () => loadWorkspaceOrganization,
|
|
99
93
|
memberRoleUpdate: () => memberRoleUpdate,
|
|
100
94
|
minimumCreditLimit: () => minimumCreditLimit,
|
|
95
|
+
poolErrorMessage: () => poolErrorMessage,
|
|
96
|
+
poolWorkspaceName: () => poolWorkspaceName,
|
|
101
97
|
resolveSettingsTabFromPath: () => resolveSettingsTabFromPath,
|
|
102
98
|
roundCredits: () => roundCredits,
|
|
99
|
+
sharedPoolBannerText: () => sharedPoolBannerText,
|
|
103
100
|
useSettingsAdapters: () => useSettingsAdapters,
|
|
104
101
|
useWorkspaceOrganization: () => useWorkspaceOrganization,
|
|
102
|
+
usedByNamesFrom: () => usedByNamesFrom,
|
|
103
|
+
usedByWorkspaceKey: () => usedByWorkspaceKey,
|
|
105
104
|
userLanguageLabel: () => userLanguageLabel,
|
|
106
|
-
validateAllocationText: () => validateAllocationText,
|
|
107
|
-
validateAllocationValue: () => validateAllocationValue,
|
|
108
105
|
validateCreditLimitInput: () => validateCreditLimitInput,
|
|
109
|
-
validateDefaultCreditLimitInput: () => validateDefaultCreditLimitInput
|
|
106
|
+
validateDefaultCreditLimitInput: () => validateDefaultCreditLimitInput,
|
|
107
|
+
validatePoolText: () => validatePoolText,
|
|
108
|
+
validatePoolValue: () => validatePoolValue
|
|
110
109
|
});
|
|
111
110
|
module.exports = __toCommonJS(index_exports);
|
|
112
111
|
|
|
@@ -8032,14 +8031,14 @@ function BuyCreditsModal({
|
|
|
8032
8031
|
const maxCredits = Math.round(
|
|
8033
8032
|
topupConfig.maxAmount / topupConfig.pricePerCredit
|
|
8034
8033
|
);
|
|
8035
|
-
const [
|
|
8034
|
+
const [credits2, setCredits] = (0, import_react15.useState)(minCredits);
|
|
8036
8035
|
const [creditsInput, setCreditsInput] = (0, import_react15.useState)(String(minCredits));
|
|
8037
8036
|
const [priceInput, setPriceInput] = (0, import_react15.useState)(
|
|
8038
8037
|
String(minCredits * topupConfig.pricePerCredit)
|
|
8039
8038
|
);
|
|
8040
8039
|
const [activeField, setActiveField] = (0, import_react15.useState)("credits");
|
|
8041
|
-
const parsedCredits = creditsInput.length ? Number(creditsInput) :
|
|
8042
|
-
const previewCredits = Number.isFinite(parsedCredits) ? parsedCredits :
|
|
8040
|
+
const parsedCredits = creditsInput.length ? Number(creditsInput) : credits2;
|
|
8041
|
+
const previewCredits = Number.isFinite(parsedCredits) ? parsedCredits : credits2;
|
|
8043
8042
|
const pricedCredits = previewCredits > 0 ? previewCredits : 0;
|
|
8044
8043
|
const price = Number(
|
|
8045
8044
|
(pricedCredits * topupConfig.pricePerCredit).toFixed(2)
|
|
@@ -8061,8 +8060,8 @@ function BuyCreditsModal({
|
|
|
8061
8060
|
setCreditsInput(String(derived));
|
|
8062
8061
|
setPriceInput(String(amount));
|
|
8063
8062
|
};
|
|
8064
|
-
const handleDecrement = () => syncFromCredits(Math.max(minCredits,
|
|
8065
|
-
const handleIncrement = () => syncFromCredits(Math.min(maxCredits,
|
|
8063
|
+
const handleDecrement = () => syncFromCredits(Math.max(minCredits, credits2 - STEP));
|
|
8064
|
+
const handleIncrement = () => syncFromCredits(Math.min(maxCredits, credits2 + STEP));
|
|
8066
8065
|
const handleCreditsChange = (value) => {
|
|
8067
8066
|
const raw = value.replace(/[^\d]/g, "");
|
|
8068
8067
|
setCreditsInput(raw);
|
|
@@ -8196,7 +8195,7 @@ function BuyCreditsModal({
|
|
|
8196
8195
|
style: {
|
|
8197
8196
|
width: 24,
|
|
8198
8197
|
height: 24,
|
|
8199
|
-
opacity:
|
|
8198
|
+
opacity: credits2 <= minCredits ? 0.3 : 1,
|
|
8200
8199
|
transition: "opacity 0.15s ease"
|
|
8201
8200
|
},
|
|
8202
8201
|
onClick: handleDecrement,
|
|
@@ -8254,7 +8253,7 @@ function BuyCreditsModal({
|
|
|
8254
8253
|
style: {
|
|
8255
8254
|
width: 24,
|
|
8256
8255
|
height: 24,
|
|
8257
|
-
opacity:
|
|
8256
|
+
opacity: credits2 >= maxCredits ? 0.3 : 1,
|
|
8258
8257
|
transition: "opacity 0.15s ease"
|
|
8259
8258
|
},
|
|
8260
8259
|
onClick: handleIncrement,
|
|
@@ -8386,7 +8385,7 @@ function BuyCreditsModal({
|
|
|
8386
8385
|
pointerEvents: isInvalid ? "none" : "auto",
|
|
8387
8386
|
transition: "opacity 0.2s ease"
|
|
8388
8387
|
},
|
|
8389
|
-
onClick: () => onBuy(
|
|
8388
|
+
onClick: () => onBuy(credits2, price),
|
|
8390
8389
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8391
8390
|
"span",
|
|
8392
8391
|
{
|
|
@@ -9126,7 +9125,7 @@ function PerUserLimitsView() {
|
|
|
9126
9125
|
] });
|
|
9127
9126
|
}
|
|
9128
9127
|
|
|
9129
|
-
// src/
|
|
9128
|
+
// src/shared-credits-view.tsx
|
|
9130
9129
|
var import_react21 = require("react");
|
|
9131
9130
|
var import_ui15 = require("@streamoid/ui");
|
|
9132
9131
|
|
|
@@ -9375,23 +9374,23 @@ function ConfirmActionModal({
|
|
|
9375
9374
|
);
|
|
9376
9375
|
}
|
|
9377
9376
|
|
|
9378
|
-
// src/credit-
|
|
9377
|
+
// src/credit-pool-modal.tsx
|
|
9379
9378
|
var import_react19 = require("react");
|
|
9380
9379
|
var import_ui13 = require("@streamoid/ui");
|
|
9381
9380
|
var import_icons13 = require("@streamoid/icons");
|
|
9382
9381
|
|
|
9383
|
-
// src/credit-
|
|
9384
|
-
var
|
|
9385
|
-
var
|
|
9386
|
-
function
|
|
9387
|
-
return Boolean(api.
|
|
9382
|
+
// src/credit-pool.ts
|
|
9383
|
+
var POOL_NOTE_MAX_LENGTH = 500;
|
|
9384
|
+
var REMOVE_REASON_MAX_LENGTH = 500;
|
|
9385
|
+
function canShowSharedCredits(api, workspace, organization) {
|
|
9386
|
+
return Boolean(api.fetchCreditPool) && Boolean(workspace?.organizationId || organization?.id);
|
|
9388
9387
|
}
|
|
9389
|
-
function
|
|
9388
|
+
function cleanPoolValueInput(raw) {
|
|
9390
9389
|
const kept = raw.replace(/[^\d.]/g, "");
|
|
9391
9390
|
const dot = kept.indexOf(".");
|
|
9392
9391
|
return dot === -1 ? kept : kept.slice(0, dot + 1) + kept.slice(dot + 1).replace(/\./g, "");
|
|
9393
9392
|
}
|
|
9394
|
-
function
|
|
9393
|
+
function validatePoolValue(mode, raw) {
|
|
9395
9394
|
const trimmed = raw.trim();
|
|
9396
9395
|
if (!trimmed) return { ok: false, reason: mode === "percent" ? "Enter a percentage" : "Enter a number of credits" };
|
|
9397
9396
|
if (!/^\d+(\.\d{1,2})?$/.test(trimmed)) {
|
|
@@ -9400,64 +9399,61 @@ function validateAllocationValue(mode, raw, balance) {
|
|
|
9400
9399
|
const value = Number(trimmed);
|
|
9401
9400
|
if (!(value > 0)) return { ok: false, reason: "Enter a number greater than 0" };
|
|
9402
9401
|
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
9402
|
return { ok: true, value };
|
|
9410
9403
|
}
|
|
9411
|
-
function
|
|
9404
|
+
function validatePoolText(raw, max) {
|
|
9412
9405
|
const value = raw.trim();
|
|
9413
9406
|
if (!value) return { ok: false, reason: "Required" };
|
|
9414
9407
|
if (value.length > max) return { ok: false, reason: `At most ${max} characters` };
|
|
9415
9408
|
return { ok: true, value };
|
|
9416
9409
|
}
|
|
9417
|
-
|
|
9410
|
+
var credits = (value) => `${formatCredits(value)} ${value === 1 ? "credit" : "credits"}`;
|
|
9411
|
+
function formatPoolSplit(split) {
|
|
9418
9412
|
if (split.mode === "percent") return `${formatCredits(split.value)}%`;
|
|
9419
|
-
return
|
|
9413
|
+
return credits(split.value);
|
|
9420
9414
|
}
|
|
9421
|
-
function
|
|
9422
|
-
|
|
9415
|
+
function describeAllowance(member) {
|
|
9416
|
+
const allowance = `${credits(member.allowance)} this cycle`;
|
|
9417
|
+
return member.mode === "percent" ? `${formatPoolSplit(member)} \xB7 ${allowance}` : allowance;
|
|
9423
9418
|
}
|
|
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) {
|
|
9419
|
+
function poolWorkspaceName(name) {
|
|
9430
9420
|
return name?.trim() || "Unknown workspace";
|
|
9431
9421
|
}
|
|
9432
|
-
function
|
|
9433
|
-
const
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
"
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
]
|
|
9459
|
-
|
|
9460
|
-
|
|
9422
|
+
function sharedPoolBannerText(pool) {
|
|
9423
|
+
const sponsor = pool.sponsorName?.trim() || "another workspace";
|
|
9424
|
+
return `Credits shared by ${sponsor}: ${formatCredits(pool.remaining)} of ${formatCredits(pool.allowance)} left this cycle`;
|
|
9425
|
+
}
|
|
9426
|
+
function creditsMeter({
|
|
9427
|
+
availableCredits,
|
|
9428
|
+
totalCredits,
|
|
9429
|
+
sharedPool
|
|
9430
|
+
}) {
|
|
9431
|
+
if (sharedPool) {
|
|
9432
|
+
const used2 = Math.max(0, sharedPool.used);
|
|
9433
|
+
const remaining = Math.max(0, sharedPool.remaining);
|
|
9434
|
+
const progressPct2 = sharedPool.allowance > 0 ? Math.min(100, Math.round(used2 / sharedPool.allowance * 100)) : 100;
|
|
9435
|
+
return { used: used2, remaining, progressPct: progressPct2, remainingPct: 100 - progressPct2 };
|
|
9436
|
+
}
|
|
9437
|
+
const used = availableCredits != null && totalCredits != null ? Math.max(0, totalCredits - availableCredits) : null;
|
|
9438
|
+
const progressPct = used != null && totalCredits != null && totalCredits > 0 ? Math.min(100, Math.round(used / totalCredits * 100)) : 0;
|
|
9439
|
+
return { used, remaining: availableCredits, progressPct, remainingPct: 100 - progressPct };
|
|
9440
|
+
}
|
|
9441
|
+
function usedByWorkspaceKey(log, currentWorkspaceId) {
|
|
9442
|
+
const usedBy = log.meta?.usedBy;
|
|
9443
|
+
if (typeof usedBy !== "string" || !usedBy) return null;
|
|
9444
|
+
return usedBy.toLowerCase() === String(currentWorkspaceId ?? "").toLowerCase() ? null : usedBy;
|
|
9445
|
+
}
|
|
9446
|
+
function usedByNamesFrom(pool) {
|
|
9447
|
+
const names = {};
|
|
9448
|
+
for (const member of [...pool?.formerMembers ?? [], ...pool?.members ?? []]) {
|
|
9449
|
+
const name = member.memberWorkspaceName?.trim();
|
|
9450
|
+
if (name && member.memberWorkspaceKey) names[member.memberWorkspaceKey.toLowerCase()] = name;
|
|
9451
|
+
}
|
|
9452
|
+
return names;
|
|
9453
|
+
}
|
|
9454
|
+
var POOL_ERROR_CODES = ["SPONSOR_ON_FREE_PLAN", "POOL_NOT_ALLOWED"];
|
|
9455
|
+
function findPoolError(failure) {
|
|
9456
|
+
const error = findBillingError(failure, POOL_ERROR_CODES);
|
|
9461
9457
|
if (!error) return null;
|
|
9462
9458
|
const status = error.status;
|
|
9463
9459
|
const message = [status?.message, error.error, error.message].find(
|
|
@@ -9466,29 +9462,18 @@ function findAllocationError(failure) {
|
|
|
9466
9462
|
const details = error.details && typeof error.details === "object" ? error.details : {};
|
|
9467
9463
|
return { code: error.code, details, message: message ?? null };
|
|
9468
9464
|
}
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
const found = findAllocationError(failure);
|
|
9465
|
+
function poolErrorMessage(failure) {
|
|
9466
|
+
const found = findPoolError(failure);
|
|
9472
9467
|
if (!found) return null;
|
|
9473
9468
|
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":
|
|
9469
|
+
case "SPONSOR_ON_FREE_PLAN":
|
|
9483
9470
|
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.";
|
|
9471
|
+
case "POOL_NOT_ALLOWED":
|
|
9472
|
+
return found.message ? found.message.replace(/\.?$/, ".") : "Credits can't be shared with that workspace.";
|
|
9488
9473
|
}
|
|
9489
9474
|
}
|
|
9490
9475
|
|
|
9491
|
-
// src/credit-
|
|
9476
|
+
// src/credit-pool-modal.tsx
|
|
9492
9477
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
9493
9478
|
var MODAL_T = {
|
|
9494
9479
|
primary: "var(--alias-text---icons-primary)",
|
|
@@ -9521,7 +9506,7 @@ var modalBodyText = {
|
|
|
9521
9506
|
fontSize: T16.fsSm,
|
|
9522
9507
|
lineHeight: T16.lhSm
|
|
9523
9508
|
};
|
|
9524
|
-
function
|
|
9509
|
+
function PoolModalShell({
|
|
9525
9510
|
title,
|
|
9526
9511
|
busy,
|
|
9527
9512
|
onClose,
|
|
@@ -9622,7 +9607,7 @@ function AllocationModalShell({
|
|
|
9622
9607
|
}
|
|
9623
9608
|
);
|
|
9624
9609
|
}
|
|
9625
|
-
function
|
|
9610
|
+
function PoolWarning({ children }) {
|
|
9626
9611
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9627
9612
|
"div",
|
|
9628
9613
|
{
|
|
@@ -9641,68 +9626,55 @@ function AllocationWarning({ children }) {
|
|
|
9641
9626
|
);
|
|
9642
9627
|
}
|
|
9643
9628
|
var fieldLabel = { ...modalBodyText, fontWeight: 500, color: T16.primary };
|
|
9644
|
-
function
|
|
9629
|
+
function CreditPoolMemberModal(props) {
|
|
9645
9630
|
const { toast } = useSettingsAdapters();
|
|
9646
|
-
const editing = props.kind === "edit" ? props.
|
|
9647
|
-
const [
|
|
9648
|
-
const [mode, setMode] = (0, import_react19.useState)(editing?.mode ?? "
|
|
9631
|
+
const editing = props.kind === "edit" ? props.member : null;
|
|
9632
|
+
const [memberId, setMemberId] = (0, import_react19.useState)("");
|
|
9633
|
+
const [mode, setMode] = (0, import_react19.useState)(editing?.mode ?? "percent");
|
|
9649
9634
|
const [raw, setRaw] = (0, import_react19.useState)(editing ? String(editing.value) : "");
|
|
9650
|
-
const [recurring, setRecurring] = (0, import_react19.useState)(editing?.recurring ?? true);
|
|
9651
9635
|
const [note, setNote] = (0, import_react19.useState)("");
|
|
9652
9636
|
const [touched, setTouched] = (0, import_react19.useState)(false);
|
|
9653
9637
|
const [saving, setSaving] = (0, import_react19.useState)(false);
|
|
9654
9638
|
const [serverError, setServerError] = (0, import_react19.useState)(null);
|
|
9655
9639
|
(0, import_react19.useEffect)(() => {
|
|
9656
9640
|
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);
|
|
9641
|
+
}, [memberId, mode, raw, note]);
|
|
9642
|
+
const value = validatePoolValue(mode, raw);
|
|
9643
|
+
const noteCheck = validatePoolText(note, POOL_NOTE_MAX_LENGTH);
|
|
9644
|
+
const changed = !editing || mode !== editing.mode || !value.ok || value.value !== editing.value;
|
|
9645
|
+
const valid = value.ok && (props.kind === "edit" || Boolean(memberId) && noteCheck.ok);
|
|
9664
9646
|
const canSave = !saving && changed && valid;
|
|
9665
9647
|
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
9648
|
const handleSave = async () => {
|
|
9668
9649
|
if (!canSave || !value.ok) return;
|
|
9669
9650
|
setSaving(true);
|
|
9670
9651
|
try {
|
|
9671
|
-
if (props.kind === "
|
|
9672
|
-
const
|
|
9673
|
-
|
|
9652
|
+
if (props.kind === "add") {
|
|
9653
|
+
const added = await props.onSave({
|
|
9654
|
+
memberWorkspaceId: memberId,
|
|
9674
9655
|
mode,
|
|
9675
9656
|
value: value.value,
|
|
9676
|
-
recurring,
|
|
9677
9657
|
note: noteCheck.ok ? noteCheck.value : ""
|
|
9678
9658
|
});
|
|
9679
|
-
|
|
9680
|
-
if (warning) toast.error(warning);
|
|
9681
|
-
else {
|
|
9682
|
-
const sent = initialTransferSummary(created);
|
|
9683
|
-
toast.success(sent ? `Allocation created. ${sent}.` : "Allocation created");
|
|
9684
|
-
}
|
|
9659
|
+
toast.success(`Credits shared. ${describeAllowance(added)}.`);
|
|
9685
9660
|
} else {
|
|
9686
|
-
await props.onSave(
|
|
9687
|
-
|
|
9688
|
-
);
|
|
9689
|
-
toast.success("Allocation updated. Applies from the next renewal.");
|
|
9661
|
+
const updated = await props.onSave({ mode, value: value.value });
|
|
9662
|
+
toast.success(`Share updated. ${describeAllowance(updated)}.`);
|
|
9690
9663
|
}
|
|
9691
9664
|
props.onSaved();
|
|
9692
9665
|
props.onClose();
|
|
9693
9666
|
} catch (err) {
|
|
9694
|
-
const message =
|
|
9667
|
+
const message = poolErrorMessage(err);
|
|
9695
9668
|
if (message) setServerError(message);
|
|
9696
|
-
else toast.error(errorMessage(err, { method: props.kind === "
|
|
9697
|
-
if (findAllocationError(err)?.details.allocationId) props.onSaved();
|
|
9669
|
+
else toast.error(errorMessage(err, { method: props.kind === "add" ? "POST" : "PATCH" }));
|
|
9698
9670
|
setSaving(false);
|
|
9699
9671
|
}
|
|
9700
9672
|
};
|
|
9701
|
-
const
|
|
9673
|
+
const candidateOptions = props.kind === "add" ? props.candidates.map((candidate) => ({ id: candidate.id, label: candidate.name })) : [];
|
|
9702
9674
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
9703
|
-
|
|
9675
|
+
PoolModalShell,
|
|
9704
9676
|
{
|
|
9705
|
-
title: props.kind === "
|
|
9677
|
+
title: props.kind === "add" ? "Share credits" : "Edit shared credits",
|
|
9706
9678
|
busy: saving,
|
|
9707
9679
|
onClose: props.onClose,
|
|
9708
9680
|
footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
@@ -9719,7 +9691,7 @@ function CreditAllocationModal(props) {
|
|
|
9719
9691
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9720
9692
|
import_ui13.ScButton,
|
|
9721
9693
|
{
|
|
9722
|
-
text: props.kind === "
|
|
9694
|
+
text: props.kind === "add" ? "Share credits" : "Save",
|
|
9723
9695
|
variant: "primary",
|
|
9724
9696
|
size: "md",
|
|
9725
9697
|
state: canSave ? "default" : "disabled",
|
|
@@ -9729,29 +9701,29 @@ function CreditAllocationModal(props) {
|
|
|
9729
9701
|
] }),
|
|
9730
9702
|
children: [
|
|
9731
9703
|
/* @__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 === "
|
|
9704
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "Share with" }),
|
|
9705
|
+
props.kind === "add" ? candidateOptions.length ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9734
9706
|
import_ui13.ScSelect,
|
|
9735
9707
|
{
|
|
9736
|
-
value:
|
|
9737
|
-
onChange:
|
|
9738
|
-
options:
|
|
9708
|
+
value: memberId,
|
|
9709
|
+
onChange: setMemberId,
|
|
9710
|
+
options: candidateOptions,
|
|
9739
9711
|
placeholder: "Choose a workspace",
|
|
9740
9712
|
disabled: saving
|
|
9741
9713
|
}
|
|
9742
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { ...modalBodyText, color: T16.muted }, children: "There are no other workspaces in this organization to
|
|
9714
|
+
) : /* @__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
9715
|
] }),
|
|
9744
9716
|
/* @__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" }),
|
|
9717
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "How much, each billing cycle" }),
|
|
9746
9718
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center", style: { gap: T16.sp3xl }, children: [
|
|
9747
9719
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9748
9720
|
import_ui13.ScPairtext,
|
|
9749
9721
|
{
|
|
9750
9722
|
type: "radio",
|
|
9751
|
-
content: "
|
|
9752
|
-
checked: mode === "
|
|
9723
|
+
content: "Percentage",
|
|
9724
|
+
checked: mode === "percent",
|
|
9753
9725
|
onChange: () => {
|
|
9754
|
-
if (!saving) setMode("
|
|
9726
|
+
if (!saving) setMode("percent");
|
|
9755
9727
|
}
|
|
9756
9728
|
}
|
|
9757
9729
|
),
|
|
@@ -9759,10 +9731,10 @@ function CreditAllocationModal(props) {
|
|
|
9759
9731
|
import_ui13.ScPairtext,
|
|
9760
9732
|
{
|
|
9761
9733
|
type: "radio",
|
|
9762
|
-
content: "
|
|
9763
|
-
checked: mode === "
|
|
9734
|
+
content: "Fixed credits",
|
|
9735
|
+
checked: mode === "fixed",
|
|
9764
9736
|
onChange: () => {
|
|
9765
|
-
if (!saving) setMode("
|
|
9737
|
+
if (!saving) setMode("fixed");
|
|
9766
9738
|
}
|
|
9767
9739
|
}
|
|
9768
9740
|
)
|
|
@@ -9790,7 +9762,7 @@ function CreditAllocationModal(props) {
|
|
|
9790
9762
|
value: raw,
|
|
9791
9763
|
disabled: saving,
|
|
9792
9764
|
onChange: (e) => {
|
|
9793
|
-
setRaw(
|
|
9765
|
+
setRaw(cleanPoolValueInput(e.target.value));
|
|
9794
9766
|
setTouched(true);
|
|
9795
9767
|
},
|
|
9796
9768
|
className: "flex-1 min-w-0",
|
|
@@ -9808,39 +9780,18 @@ function CreditAllocationModal(props) {
|
|
|
9808
9780
|
]
|
|
9809
9781
|
}
|
|
9810
9782
|
),
|
|
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
|
-
) })
|
|
9783
|
+
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: [
|
|
9784
|
+
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.",
|
|
9785
|
+
editing ? " Applies immediately." : ""
|
|
9786
|
+
] })
|
|
9836
9787
|
] }),
|
|
9837
|
-
props.kind === "
|
|
9788
|
+
props.kind === "add" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col w-full", style: { gap: T16.spXs }, children: [
|
|
9838
9789
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: fieldLabel, children: "Note" }),
|
|
9839
9790
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
9840
9791
|
import_ui13.ScTextArea,
|
|
9841
9792
|
{
|
|
9842
9793
|
value: note,
|
|
9843
|
-
maxLength:
|
|
9794
|
+
maxLength: POOL_NOTE_MAX_LENGTH,
|
|
9844
9795
|
placeholder: "Why are these credits being shared?",
|
|
9845
9796
|
disabled: saving,
|
|
9846
9797
|
onChange: (e) => setNote(e.target.value),
|
|
@@ -9852,117 +9803,57 @@ function CreditAllocationModal(props) {
|
|
|
9852
9803
|
"Required. ",
|
|
9853
9804
|
note.trim().length,
|
|
9854
9805
|
"/",
|
|
9855
|
-
|
|
9806
|
+
POOL_NOTE_MAX_LENGTH
|
|
9856
9807
|
] })
|
|
9857
9808
|
] }),
|
|
9858
|
-
props.kind === "
|
|
9809
|
+
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
9810
|
serverError && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { role: "alert", style: { ...modalBodyText, color: T16.error }, children: serverError })
|
|
9860
9811
|
]
|
|
9861
9812
|
}
|
|
9862
9813
|
);
|
|
9863
9814
|
}
|
|
9864
9815
|
|
|
9865
|
-
// src/
|
|
9816
|
+
// src/remove-pool-member-modal.tsx
|
|
9866
9817
|
var import_react20 = require("react");
|
|
9867
9818
|
var import_ui14 = require("@streamoid/ui");
|
|
9868
9819
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
9869
|
-
function
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9820
|
+
function RemovePoolMemberModal({
|
|
9821
|
+
member,
|
|
9822
|
+
memberName,
|
|
9823
|
+
sponsorName,
|
|
9824
|
+
onRemove,
|
|
9873
9825
|
onClose,
|
|
9874
|
-
|
|
9826
|
+
onRemoved
|
|
9875
9827
|
}) {
|
|
9876
9828
|
const { toast } = useSettingsAdapters();
|
|
9877
9829
|
const [reason, setReason] = (0, import_react20.useState)("");
|
|
9878
9830
|
const [saving, setSaving] = (0, import_react20.useState)(false);
|
|
9879
|
-
const
|
|
9880
|
-
const check = validateAllocationText(reason, CANCEL_REASON_MAX_LENGTH);
|
|
9831
|
+
const check = validatePoolText(reason, REMOVE_REASON_MAX_LENGTH);
|
|
9881
9832
|
const canConfirm = !saving && check.ok;
|
|
9882
9833
|
const handleConfirm = async () => {
|
|
9883
9834
|
if (!canConfirm || !check.ok) return;
|
|
9884
9835
|
setSaving(true);
|
|
9885
9836
|
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));
|
|
9837
|
+
await onRemove(check.value);
|
|
9838
|
+
toast.success(`${memberName} can no longer spend ${sponsorName}'s credits`);
|
|
9839
|
+
onRemoved();
|
|
9898
9840
|
onClose();
|
|
9899
9841
|
} catch (err) {
|
|
9900
9842
|
toast.error(errorMessage(err, { method: "DELETE" }));
|
|
9901
9843
|
setSaving(false);
|
|
9902
9844
|
}
|
|
9903
9845
|
};
|
|
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
9846
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
9956
|
-
|
|
9847
|
+
PoolModalShell,
|
|
9957
9848
|
{
|
|
9958
|
-
title: "
|
|
9849
|
+
title: "Stop sharing credits",
|
|
9959
9850
|
busy: saving,
|
|
9960
9851
|
onClose,
|
|
9961
9852
|
footer: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
9962
9853
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
9963
9854
|
import_ui14.ScButton,
|
|
9964
9855
|
{
|
|
9965
|
-
text: "Keep
|
|
9856
|
+
text: "Keep sharing",
|
|
9966
9857
|
variant: "secondary",
|
|
9967
9858
|
size: "md",
|
|
9968
9859
|
state: saving ? "disabled" : "default",
|
|
@@ -9972,7 +9863,7 @@ function CancelCreditAllocationModal({
|
|
|
9972
9863
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
9973
9864
|
import_ui14.ScButton,
|
|
9974
9865
|
{
|
|
9975
|
-
text: "
|
|
9866
|
+
text: "Stop sharing",
|
|
9976
9867
|
variant: "error",
|
|
9977
9868
|
size: "md",
|
|
9978
9869
|
state: canConfirm ? "default" : "disabled",
|
|
@@ -9982,16 +9873,18 @@ function CancelCreditAllocationModal({
|
|
|
9982
9873
|
] }),
|
|
9983
9874
|
children: [
|
|
9984
9875
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { ...modalBodyText, color: MODAL_T.primary }, children: [
|
|
9985
|
-
"
|
|
9986
|
-
|
|
9987
|
-
"
|
|
9988
|
-
|
|
9989
|
-
"
|
|
9876
|
+
"This stops ",
|
|
9877
|
+
memberName,
|
|
9878
|
+
" spending ",
|
|
9879
|
+
sponsorName,
|
|
9880
|
+
"'s credits immediately."
|
|
9990
9881
|
] }),
|
|
9991
9882
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { ...modalBodyText, color: MODAL_T.tertiary }, children: [
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9883
|
+
"It had ",
|
|
9884
|
+
describeAllowance(member),
|
|
9885
|
+
" and has used ",
|
|
9886
|
+
formatCredits(member.used),
|
|
9887
|
+
". Credits it already spent are not returned; anything it runs from now uses its own credits."
|
|
9995
9888
|
] }),
|
|
9996
9889
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col w-full", style: { gap: MODAL_T.spXs }, children: [
|
|
9997
9890
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { style: { ...modalBodyText, fontWeight: 500, color: MODAL_T.primary }, children: "Reason" }),
|
|
@@ -9999,8 +9892,8 @@ function CancelCreditAllocationModal({
|
|
|
9999
9892
|
import_ui14.ScTextArea,
|
|
10000
9893
|
{
|
|
10001
9894
|
value: reason,
|
|
10002
|
-
maxLength:
|
|
10003
|
-
placeholder: "Why is this
|
|
9895
|
+
maxLength: REMOVE_REASON_MAX_LENGTH,
|
|
9896
|
+
placeholder: "Why is this workspace no longer sharing these credits?",
|
|
10004
9897
|
disabled: saving,
|
|
10005
9898
|
onChange: (e) => setReason(e.target.value),
|
|
10006
9899
|
rows: 3,
|
|
@@ -10014,16 +9907,13 @@ function CancelCreditAllocationModal({
|
|
|
10014
9907
|
);
|
|
10015
9908
|
}
|
|
10016
9909
|
|
|
10017
|
-
// src/
|
|
9910
|
+
// src/shared-credits-view.tsx
|
|
10018
9911
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
10019
9912
|
var T17 = {
|
|
10020
9913
|
primary: "var(--alias-text---icons-primary)",
|
|
10021
9914
|
muted: "var(--alias-text---icons-muted)",
|
|
10022
9915
|
tertiary: "var(--alias-text---icons-tertiary)",
|
|
10023
9916
|
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
9917
|
fillPlus: "var(--alias-fill-neutral-neutralplus)",
|
|
10028
9918
|
surfaceBase: "var(--alias-surface-base)",
|
|
10029
9919
|
borderSubtle: "var(--alias-border-subtle)",
|
|
@@ -10037,9 +9927,7 @@ var T17 = {
|
|
|
10037
9927
|
r3xl: "var(--radius-3xl)",
|
|
10038
9928
|
rFull: "var(--radius-full)"
|
|
10039
9929
|
};
|
|
10040
|
-
var
|
|
10041
|
-
var TRANSFER_COLUMNS = "120px 170px minmax(200px, 1fr) 120px";
|
|
10042
|
-
var TRANSFERS_PAGE = 20;
|
|
9930
|
+
var MEMBER_COLUMNS2 = "minmax(220px, 1fr) 220px 110px 110px 150px";
|
|
10043
9931
|
var cellText2 = {
|
|
10044
9932
|
fontFamily: T17.font,
|
|
10045
9933
|
fontSize: T17.fsSm,
|
|
@@ -10061,138 +9949,67 @@ var tableHeader = (columns, labels) => /* @__PURE__ */ (0, import_jsx_runtime27.
|
|
|
10061
9949
|
children: labels.map((label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: label }, label))
|
|
10062
9950
|
}
|
|
10063
9951
|
);
|
|
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,
|
|
9952
|
+
function MemberRow2({
|
|
9953
|
+
member,
|
|
10086
9954
|
onEdit,
|
|
10087
|
-
|
|
9955
|
+
onRemove
|
|
10088
9956
|
}) {
|
|
10089
|
-
const
|
|
10090
|
-
const sent = initialTransferSummary(allocation);
|
|
10091
|
-
const active = allocation.status === "active";
|
|
9957
|
+
const spent = member.remaining <= 0;
|
|
10092
9958
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
10093
9959
|
"div",
|
|
10094
9960
|
{
|
|
10095
9961
|
style: {
|
|
10096
9962
|
borderBottom: `1px solid ${T17.borderSubtle}`,
|
|
10097
9963
|
display: "grid",
|
|
10098
|
-
gridTemplateColumns:
|
|
9964
|
+
gridTemplateColumns: MEMBER_COLUMNS2,
|
|
10099
9965
|
alignItems: "center",
|
|
10100
9966
|
padding: `10px ${T17.sp3xl}`,
|
|
10101
9967
|
gap: 24
|
|
10102
9968
|
},
|
|
10103
9969
|
children: [
|
|
10104
9970
|
/* @__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" })
|
|
9971
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", style: { ...cellText2, fontWeight: 500 }, children: poolWorkspaceName(member.memberWorkspaceName) }),
|
|
9972
|
+
member.note && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", title: member.note, style: { ...cellText2, color: T17.tertiary }, children: member.note })
|
|
10117
9973
|
] }),
|
|
10118
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style:
|
|
9974
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: describeAllowance(member) }),
|
|
9975
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: cellText2, children: formatCredits(member.used) }),
|
|
9976
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: spent ? T17.warning : T17.primary }, children: formatCredits(member.remaining) }),
|
|
10119
9977
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center", style: { gap: 8 }, children: [
|
|
10120
|
-
|
|
10121
|
-
|
|
9978
|
+
onEdit && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Edit", variant: "secondary", size: "sm", onClick: onEdit }),
|
|
9979
|
+
onRemove && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Remove", variant: "secondary", size: "sm", onClick: onRemove })
|
|
10122
9980
|
] })
|
|
10123
9981
|
]
|
|
10124
9982
|
}
|
|
10125
9983
|
);
|
|
10126
9984
|
}
|
|
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() {
|
|
9985
|
+
function SharedCreditsView() {
|
|
10157
9986
|
const { api, workspace, toast } = useSettingsAdapters();
|
|
10158
9987
|
const workspaceId = workspace.current?.id ?? null;
|
|
9988
|
+
const workspaceName = workspace.current?.name?.trim() || "this workspace";
|
|
10159
9989
|
const [data, setData] = (0, import_react21.useState)(null);
|
|
10160
9990
|
const [loading, setLoading] = (0, import_react21.useState)(true);
|
|
10161
9991
|
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);
|
|
9992
|
+
const [candidates, setCandidates] = (0, import_react21.useState)([]);
|
|
9993
|
+
const [adding, setAdding] = (0, import_react21.useState)(false);
|
|
10169
9994
|
const [editing, setEditing] = (0, import_react21.useState)(null);
|
|
10170
|
-
const [
|
|
10171
|
-
const [planNotRestored, setPlanNotRestored] = (0, import_react21.useState)(() => /* @__PURE__ */ new Set());
|
|
9995
|
+
const [removing, setRemoving] = (0, import_react21.useState)(null);
|
|
10172
9996
|
const latestLoad = (0, import_react21.useRef)(0);
|
|
10173
9997
|
const load = (0, import_react21.useCallback)(
|
|
10174
9998
|
async ({ refresh = false } = {}) => {
|
|
10175
9999
|
const loadId = ++latestLoad.current;
|
|
10176
|
-
if (!api.
|
|
10000
|
+
if (!api.fetchCreditPool) {
|
|
10177
10001
|
setLoading(false);
|
|
10178
10002
|
setFailed(true);
|
|
10179
10003
|
return;
|
|
10180
10004
|
}
|
|
10181
|
-
const
|
|
10182
|
-
api.fetchCreditAllocations().catch(() => null),
|
|
10183
|
-
api.fetchCreditTransfers ? api.fetchCreditTransfers({ page: 1, limit: TRANSFERS_PAGE }).catch(() => null) : Promise.resolve(null)
|
|
10184
|
-
]);
|
|
10005
|
+
const next = await api.fetchCreditPool().catch(() => null);
|
|
10185
10006
|
if (loadId !== latestLoad.current) return;
|
|
10186
10007
|
if (refresh && !next) {
|
|
10187
|
-
toast.error("Couldn't refresh
|
|
10008
|
+
toast.error("Couldn't refresh shared credits. Reopen this page to see the latest.");
|
|
10188
10009
|
return;
|
|
10189
10010
|
}
|
|
10190
10011
|
setFailed(!next);
|
|
10191
10012
|
setData(next);
|
|
10192
|
-
setTransfersFailed(Boolean(api.fetchCreditTransfers) && !page);
|
|
10193
|
-
setTransfers(page?.transfers ?? []);
|
|
10194
|
-
setTransfersTotal(page?.total ?? 0);
|
|
10195
|
-
setTransfersPage(page ? 1 : 0);
|
|
10196
10013
|
setLoading(false);
|
|
10197
10014
|
},
|
|
10198
10015
|
[api, toast]
|
|
@@ -10201,11 +10018,9 @@ function CreditAllocationsView() {
|
|
|
10201
10018
|
setLoading(true);
|
|
10202
10019
|
setFailed(false);
|
|
10203
10020
|
setData(null);
|
|
10204
|
-
|
|
10205
|
-
setCreating(false);
|
|
10021
|
+
setAdding(false);
|
|
10206
10022
|
setEditing(null);
|
|
10207
|
-
|
|
10208
|
-
setPlanNotRestored(/* @__PURE__ */ new Set());
|
|
10023
|
+
setRemoving(null);
|
|
10209
10024
|
void load();
|
|
10210
10025
|
}, [workspaceId]);
|
|
10211
10026
|
(0, import_react21.useEffect)(
|
|
@@ -10215,36 +10030,21 @@ function CreditAllocationsView() {
|
|
|
10215
10030
|
[]
|
|
10216
10031
|
);
|
|
10217
10032
|
const canManage = Boolean(data?.canManage);
|
|
10218
|
-
const
|
|
10219
|
-
const
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10033
|
+
const sponsor = data?.sponsor ?? null;
|
|
10034
|
+
const canAdd = canManage && !sponsor && Boolean(api.addCreditPoolMember);
|
|
10035
|
+
const openAdd = async () => {
|
|
10036
|
+
if (!api.fetchCreditPoolCandidates) {
|
|
10037
|
+
setCandidates([]);
|
|
10038
|
+
setAdding(true);
|
|
10223
10039
|
return;
|
|
10224
10040
|
}
|
|
10225
10041
|
try {
|
|
10226
|
-
|
|
10227
|
-
|
|
10042
|
+
setCandidates(await api.fetchCreditPoolCandidates());
|
|
10043
|
+
setAdding(true);
|
|
10228
10044
|
} catch {
|
|
10229
10045
|
toast.error("Couldn't load this organization's workspaces. Try again.");
|
|
10230
10046
|
}
|
|
10231
10047
|
};
|
|
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
10048
|
if (loading) {
|
|
10249
10049
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10250
10050
|
"div",
|
|
@@ -10267,9 +10067,7 @@ function CreditAllocationsView() {
|
|
|
10267
10067
|
}
|
|
10268
10068
|
);
|
|
10269
10069
|
}
|
|
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;
|
|
10070
|
+
const members = data?.members ?? [];
|
|
10273
10071
|
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
10072
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start justify-between shrink-0 w-full", style: { gap: 12 }, children: [
|
|
10275
10073
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col min-w-0", style: { gap: 4 }, children: [
|
|
@@ -10277,12 +10075,12 @@ function CreditAllocationsView() {
|
|
|
10277
10075
|
"span",
|
|
10278
10076
|
{
|
|
10279
10077
|
style: { fontFamily: T17.font, fontSize: T17.fsXl, fontWeight: 500, lineHeight: T17.lhXl, color: T17.primary },
|
|
10280
|
-
children: "
|
|
10078
|
+
children: "Shared credits"
|
|
10281
10079
|
}
|
|
10282
10080
|
),
|
|
10283
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, color: T17.muted }, children: canManage ? "
|
|
10081
|
+
/* @__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
10082
|
] }),
|
|
10285
|
-
|
|
10083
|
+
canAdd && !failed && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_ui15.ScButton, { text: "Share credits", variant: "primary", size: "md", onClick: () => void openAdd() })
|
|
10286
10084
|
] }),
|
|
10287
10085
|
sponsor && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
10288
10086
|
"div",
|
|
@@ -10296,103 +10094,74 @@ function CreditAllocationsView() {
|
|
|
10296
10094
|
borderRadius: T17.r3xl
|
|
10297
10095
|
},
|
|
10298
10096
|
children: [
|
|
10299
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10097
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, fontWeight: 500 }, children: sharedPoolBannerText({
|
|
10098
|
+
sponsorName: poolWorkspaceName(sponsor.sponsorWorkspaceName),
|
|
10099
|
+
allowance: sponsor.allowance,
|
|
10100
|
+
remaining: sponsor.remaining
|
|
10101
|
+
}) }),
|
|
10303
10102
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { style: { ...cellText2, color: T17.muted }, children: [
|
|
10304
|
-
"
|
|
10305
|
-
|
|
10103
|
+
"This workspace spends ",
|
|
10104
|
+
poolWorkspaceName(sponsor.sponsorWorkspaceName),
|
|
10105
|
+
"'s credits, not its own",
|
|
10106
|
+
sponsor.cycle?.end ? `, until its allowance starts again on ${formatDate2(sponsor.cycle.end)}` : "",
|
|
10306
10107
|
"."
|
|
10307
10108
|
] })
|
|
10308
10109
|
]
|
|
10309
10110
|
}
|
|
10310
10111
|
),
|
|
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: "
|
|
10112
|
+
!sponsor && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col shrink-0 w-full", style: { gap: 8 }, children: [
|
|
10113
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { ...cellText2, fontWeight: 500 }, children: "Shared with" }),
|
|
10313
10114
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10314
10115
|
MemberListFrame,
|
|
10315
10116
|
{
|
|
10316
10117
|
grow: "cap",
|
|
10317
10118
|
maxHeight: 420,
|
|
10318
|
-
contentMinWidth:
|
|
10319
|
-
header: tableHeader(
|
|
10320
|
-
isEmpty: failed ||
|
|
10321
|
-
emptyText: failed ? "Couldn't load
|
|
10322
|
-
children:
|
|
10323
|
-
|
|
10119
|
+
contentMinWidth: 860,
|
|
10120
|
+
header: tableHeader(MEMBER_COLUMNS2, ["Workspace", "Allowance", "Used", "Remaining", "Actions"]),
|
|
10121
|
+
isEmpty: failed || members.length === 0,
|
|
10122
|
+
emptyText: failed ? "Couldn't load shared credits. Try again later." : "This workspace doesn't share its credits with any other workspace.",
|
|
10123
|
+
children: members.map((member) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10124
|
+
MemberRow2,
|
|
10324
10125
|
{
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
onCancel: canManage && api.cancelCreditAllocation ? () => setCanceling(allocation) : void 0
|
|
10126
|
+
member,
|
|
10127
|
+
onEdit: canManage && api.updateCreditPoolMember ? () => setEditing(member) : void 0,
|
|
10128
|
+
onRemove: canManage && api.removeCreditPoolMember ? () => setRemoving(member) : void 0
|
|
10329
10129
|
},
|
|
10330
|
-
|
|
10130
|
+
member._id
|
|
10331
10131
|
))
|
|
10332
10132
|
}
|
|
10333
10133
|
)
|
|
10334
10134
|
] }),
|
|
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,
|
|
10135
|
+
adding && api.addCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10136
|
+
CreditPoolMemberModal,
|
|
10362
10137
|
{
|
|
10363
|
-
kind: "
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
onClose: () => setCreating(false),
|
|
10138
|
+
kind: "add",
|
|
10139
|
+
candidates,
|
|
10140
|
+
onSave: (input) => api.addCreditPoolMember(input),
|
|
10141
|
+
onClose: () => setAdding(false),
|
|
10368
10142
|
onSaved: () => void load({ refresh: true })
|
|
10369
10143
|
}
|
|
10370
10144
|
),
|
|
10371
|
-
editing && api.
|
|
10372
|
-
|
|
10145
|
+
editing && api.updateCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10146
|
+
CreditPoolMemberModal,
|
|
10373
10147
|
{
|
|
10374
10148
|
kind: "edit",
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
onSave: (patch) => api.
|
|
10149
|
+
member: editing,
|
|
10150
|
+
memberName: poolWorkspaceName(editing.memberWorkspaceName),
|
|
10151
|
+
onSave: (patch) => api.updateCreditPoolMember(editing._id, patch),
|
|
10378
10152
|
onClose: () => setEditing(null),
|
|
10379
10153
|
onSaved: () => void load({ refresh: true })
|
|
10380
10154
|
}
|
|
10381
10155
|
),
|
|
10382
|
-
|
|
10383
|
-
|
|
10156
|
+
removing && api.removeCreditPoolMember && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
10157
|
+
RemovePoolMemberModal,
|
|
10384
10158
|
{
|
|
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
|
-
}
|
|
10159
|
+
member: removing,
|
|
10160
|
+
memberName: poolWorkspaceName(removing.memberWorkspaceName),
|
|
10161
|
+
sponsorName: workspaceName,
|
|
10162
|
+
onRemove: (reason) => api.removeCreditPoolMember(removing._id, reason),
|
|
10163
|
+
onClose: () => setRemoving(null),
|
|
10164
|
+
onRemoved: () => void load({ refresh: true })
|
|
10396
10165
|
}
|
|
10397
10166
|
)
|
|
10398
10167
|
] });
|
|
@@ -11282,8 +11051,11 @@ function InvoiceHistoryTable({
|
|
|
11282
11051
|
function UsageLogsTable({
|
|
11283
11052
|
logs,
|
|
11284
11053
|
userMap,
|
|
11285
|
-
loading
|
|
11054
|
+
loading,
|
|
11055
|
+
currentWorkspaceId = null,
|
|
11056
|
+
usedByNames = {}
|
|
11286
11057
|
}) {
|
|
11058
|
+
const showWorkspace = logs.some((log) => usedByWorkspaceKey(log, currentWorkspaceId));
|
|
11287
11059
|
if (loading) {
|
|
11288
11060
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11289
11061
|
"div",
|
|
@@ -11360,6 +11132,14 @@ function UsageLogsTable({
|
|
|
11360
11132
|
style: { flexShrink: 0, width: "7.5rem" }
|
|
11361
11133
|
}
|
|
11362
11134
|
),
|
|
11135
|
+
showWorkspace && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11136
|
+
import_ui16.ScHeader,
|
|
11137
|
+
{
|
|
11138
|
+
text: "Workspace",
|
|
11139
|
+
state: "none",
|
|
11140
|
+
style: { flexShrink: 0, width: "9rem" }
|
|
11141
|
+
}
|
|
11142
|
+
),
|
|
11363
11143
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11364
11144
|
import_ui16.ScHeader,
|
|
11365
11145
|
{
|
|
@@ -11406,6 +11186,8 @@ function UsageLogsTable({
|
|
|
11406
11186
|
logs.map((log) => {
|
|
11407
11187
|
const userName = log.triggeredByUserId ? userMap[log.triggeredByUserId] || "Unknown" : "System";
|
|
11408
11188
|
const app = log.service?.serviceGroupName || "\u2014";
|
|
11189
|
+
const usedBy = usedByWorkspaceKey(log, currentWorkspaceId);
|
|
11190
|
+
const workspaceLabel2 = usedBy ? `Used by ${usedByNames[usedBy.toLowerCase()] ?? "another workspace"}` : "This workspace";
|
|
11409
11191
|
const activity = log.type === "return" ? "Returned Credits" : log.meta?.info || "Credit usage";
|
|
11410
11192
|
const isPositive = log.type === "return" || log.type === "add";
|
|
11411
11193
|
const signedAmount = `${isPositive ? "+" : "-"}${log.amount}`;
|
|
@@ -11435,6 +11217,18 @@ function UsageLogsTable({
|
|
|
11435
11217
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, flex: 1 }, children: app }),
|
|
11436
11218
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, flex: 1 }, children: activity }),
|
|
11437
11219
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, width: "7.5rem" }, children: userName }),
|
|
11220
|
+
showWorkspace && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11221
|
+
"div",
|
|
11222
|
+
{
|
|
11223
|
+
style: {
|
|
11224
|
+
...rowCellRegular,
|
|
11225
|
+
width: "9rem",
|
|
11226
|
+
color: usedBy ? "var(--alias-text---icons-primary, #f5f5f5)" : "var(--alias-text---icons-muted)"
|
|
11227
|
+
},
|
|
11228
|
+
title: workspaceLabel2,
|
|
11229
|
+
children: workspaceLabel2
|
|
11230
|
+
}
|
|
11231
|
+
),
|
|
11438
11232
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { style: { ...rowCellRegular, width: "7.5rem" }, children: formatDate3(log.createdAt) }),
|
|
11439
11233
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11440
11234
|
"div",
|
|
@@ -11503,8 +11297,8 @@ function BillingContent({
|
|
|
11503
11297
|
onShowPlansChange,
|
|
11504
11298
|
showPerUserLimits: showPerUserLimitsProp,
|
|
11505
11299
|
onShowPerUserLimitsChange,
|
|
11506
|
-
|
|
11507
|
-
|
|
11300
|
+
showSharedCredits: showSharedCreditsProp,
|
|
11301
|
+
onShowSharedCreditsChange
|
|
11508
11302
|
} = {}) {
|
|
11509
11303
|
const { auth, workspace, organization, api, toast, navigation } = useSettingsAdapters();
|
|
11510
11304
|
const user = auth.user;
|
|
@@ -11529,21 +11323,23 @@ function BillingContent({
|
|
|
11529
11323
|
if (onShowPerUserLimitsChange) onShowPerUserLimitsChange(next);
|
|
11530
11324
|
else setShowPerUserLimitsInternal(next);
|
|
11531
11325
|
};
|
|
11532
|
-
const
|
|
11326
|
+
const canShareCredits = canShowSharedCredits(
|
|
11533
11327
|
api,
|
|
11534
11328
|
workspace.current,
|
|
11535
11329
|
organization?.current
|
|
11536
11330
|
);
|
|
11537
|
-
const [
|
|
11538
|
-
const
|
|
11539
|
-
const
|
|
11540
|
-
if (
|
|
11541
|
-
else
|
|
11331
|
+
const [showSharedCreditsInternal, setShowSharedCreditsInternal] = (0, import_react22.useState)(false);
|
|
11332
|
+
const showSharedCredits = (showSharedCreditsProp ?? showSharedCreditsInternal) && canShareCredits;
|
|
11333
|
+
const setShowSharedCredits = (next) => {
|
|
11334
|
+
if (onShowSharedCreditsChange) onShowSharedCreditsChange(next);
|
|
11335
|
+
else setShowSharedCreditsInternal(next);
|
|
11542
11336
|
};
|
|
11543
11337
|
const [showExportModal, setShowExportModal] = (0, import_react22.useState)(false);
|
|
11544
11338
|
const [showBuyCreditsModal, setShowBuyCreditsModal] = (0, import_react22.useState)(false);
|
|
11545
11339
|
const [subscription, setSubscription] = (0, import_react22.useState)(null);
|
|
11546
11340
|
const [availableCredits, setAvailableCredits] = (0, import_react22.useState)(null);
|
|
11341
|
+
const [sharedPool, setSharedPool] = (0, import_react22.useState)(null);
|
|
11342
|
+
const [usedByNames, setUsedByNames] = (0, import_react22.useState)({});
|
|
11547
11343
|
const [products, setProducts] = (0, import_react22.useState)([]);
|
|
11548
11344
|
const [invoices, setInvoices] = (0, import_react22.useState)([]);
|
|
11549
11345
|
const [totalCredits, setTotalCredits] = (0, import_react22.useState)(null);
|
|
@@ -11594,6 +11390,7 @@ function BillingContent({
|
|
|
11594
11390
|
if (subRes?.data) setSubscription(subRes.data);
|
|
11595
11391
|
if (creditsRes?.availableCredits != null)
|
|
11596
11392
|
setAvailableCredits(creditsRes.availableCredits);
|
|
11393
|
+
setSharedPool(creditsRes?.sharedPool ?? null);
|
|
11597
11394
|
if (productsRes?.data) {
|
|
11598
11395
|
const normalizedWorkspaceCountry = workspace.current?.country?.trim().toUpperCase();
|
|
11599
11396
|
const targetCurrency = normalizedWorkspaceCountry === "IN" ? "inr" : "usd";
|
|
@@ -11642,7 +11439,12 @@ function BillingContent({
|
|
|
11642
11439
|
);
|
|
11643
11440
|
} else if (api.fetchUsageLogs) {
|
|
11644
11441
|
const res = await api.fetchUsageLogs();
|
|
11645
|
-
|
|
11442
|
+
const logs = res.data?.length ? res.data : [];
|
|
11443
|
+
setUsageLogs(logs);
|
|
11444
|
+
if (api.fetchCreditPool && logs.some((log) => usedByWorkspaceKey(log, workspaceId))) {
|
|
11445
|
+
const pool = await api.fetchCreditPool().catch(() => null);
|
|
11446
|
+
setUsedByNames(usedByNamesFrom(pool));
|
|
11447
|
+
}
|
|
11646
11448
|
} else {
|
|
11647
11449
|
setUsageLogs([]);
|
|
11648
11450
|
}
|
|
@@ -11653,7 +11455,7 @@ function BillingContent({
|
|
|
11653
11455
|
setLoadingTable(false);
|
|
11654
11456
|
}
|
|
11655
11457
|
},
|
|
11656
|
-
[api]
|
|
11458
|
+
[api, workspaceId]
|
|
11657
11459
|
);
|
|
11658
11460
|
const handlePlanAction = (0, import_react22.useCallback)(
|
|
11659
11461
|
async ({ productId, priceId, planName: planName2 }) => {
|
|
@@ -11811,10 +11613,13 @@ function BillingContent({
|
|
|
11811
11613
|
);
|
|
11812
11614
|
const scheduledDowngradeText = subscription?.downgradeScheduled && subscription.plan?.name ? `Downgrades to ${subscription.plan.name}${scheduledDowngradeDateLabel ? ` ${scheduledDowngradeDateLabel}` : ""}` : void 0;
|
|
11813
11615
|
const isPlanDetailsLoading = !billingOverviewLoaded || loadingBilling || subscription?.plan == null || !planName || planName === "-" || !planAmount || currentPlanCredits == null;
|
|
11814
|
-
const
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11616
|
+
const {
|
|
11617
|
+
used: usedCredits,
|
|
11618
|
+
remaining: remainingCredits,
|
|
11619
|
+
progressPct,
|
|
11620
|
+
remainingPct
|
|
11621
|
+
} = creditsMeter({ availableCredits, totalCredits, sharedPool });
|
|
11622
|
+
const usageText = usedCredits != null ? formatCredits2(usedCredits) : remainingCredits != null ? `${formatCredits2(remainingCredits)} available` : customPlanCredits != null ? `${formatCredits2(customPlanCredits)} credits` : "\u2014";
|
|
11818
11623
|
const handleExport = async (startDate, endDate) => {
|
|
11819
11624
|
const end = new Date(endDate);
|
|
11820
11625
|
end.setHours(23, 59, 59, 999);
|
|
@@ -11891,7 +11696,7 @@ function BillingContent({
|
|
|
11891
11696
|
function fmtFilename(d) {
|
|
11892
11697
|
return d.toISOString().slice(0, 10);
|
|
11893
11698
|
}
|
|
11894
|
-
async function handleBuyCredits(
|
|
11699
|
+
async function handleBuyCredits(credits2, price) {
|
|
11895
11700
|
if (!workspaceId) {
|
|
11896
11701
|
toast.error("Missing workspace details for credit top-up");
|
|
11897
11702
|
return;
|
|
@@ -11903,14 +11708,14 @@ function BillingContent({
|
|
|
11903
11708
|
"Buy credits confirmed",
|
|
11904
11709
|
{
|
|
11905
11710
|
action: "confirm_buy_credits",
|
|
11906
|
-
additionalInfo: `${
|
|
11711
|
+
additionalInfo: `${credits2}:${price}`
|
|
11907
11712
|
}
|
|
11908
11713
|
);
|
|
11909
11714
|
try {
|
|
11910
11715
|
const topupCurrency = workspace.current?.country?.trim().toUpperCase() === "IN" ? "inr" : "usd";
|
|
11911
11716
|
const res = await api.buyCredits({
|
|
11912
11717
|
serviceName: DEFAULT_TOPUP_SERVICE,
|
|
11913
|
-
credits,
|
|
11718
|
+
credits: credits2,
|
|
11914
11719
|
unitAmount: price,
|
|
11915
11720
|
itemCount: 1,
|
|
11916
11721
|
currency: topupCurrency,
|
|
@@ -11928,7 +11733,7 @@ function BillingContent({
|
|
|
11928
11733
|
setAvailableCredits(payloadData.availableCredits);
|
|
11929
11734
|
} else {
|
|
11930
11735
|
setAvailableCredits(
|
|
11931
|
-
(prev) => typeof prev === "number" ? prev +
|
|
11736
|
+
(prev) => typeof prev === "number" ? prev + credits2 : prev
|
|
11932
11737
|
);
|
|
11933
11738
|
}
|
|
11934
11739
|
toast.success("Top-up created");
|
|
@@ -11998,13 +11803,13 @@ function BillingContent({
|
|
|
11998
11803
|
}
|
|
11999
11804
|
) });
|
|
12000
11805
|
}
|
|
12001
|
-
if (
|
|
12002
|
-
const
|
|
12003
|
-
!
|
|
12004
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11806
|
+
if (showSharedCredits) {
|
|
11807
|
+
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: [
|
|
11808
|
+
!onShowSharedCreditsChange && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(BackToBilling, { onClick: () => setShowSharedCredits(false) }),
|
|
11809
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SharedCreditsView, {})
|
|
12005
11810
|
] });
|
|
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:
|
|
11811
|
+
if (embedded) return sharedCreditsView;
|
|
11812
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex-1 h-full min-h-0 min-w-0 relative", children: sharedCreditsView });
|
|
12008
11813
|
}
|
|
12009
11814
|
if (showPerUserLimits) {
|
|
12010
11815
|
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 +11876,7 @@ function BillingContent({
|
|
|
12071
11876
|
{
|
|
12072
11877
|
usageLabel: "Credits used",
|
|
12073
11878
|
usageText,
|
|
12074
|
-
remainingText:
|
|
11879
|
+
remainingText: remainingCredits != null ? `${formatCredits2(remainingCredits)} (${remainingPct}%) Remaining` : `${remainingPct}% Remaining`,
|
|
12075
11880
|
buyButtonText: "Buy credits",
|
|
12076
11881
|
buyButtonState: isFreePlan ? "disabled" : "default",
|
|
12077
11882
|
buyButtonHoverText: isFreePlan ? "Pro plan required" : void 0,
|
|
@@ -12091,6 +11896,50 @@ function BillingContent({
|
|
|
12091
11896
|
]
|
|
12092
11897
|
}
|
|
12093
11898
|
),
|
|
11899
|
+
sharedPool ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
11900
|
+
"div",
|
|
11901
|
+
{
|
|
11902
|
+
role: "status",
|
|
11903
|
+
className: "flex flex-col shrink-0 w-full",
|
|
11904
|
+
style: {
|
|
11905
|
+
gap: 4,
|
|
11906
|
+
padding: 16,
|
|
11907
|
+
backgroundColor: "var(--alias-surface-base)",
|
|
11908
|
+
border: "1px solid var(--alias-border-subtle)",
|
|
11909
|
+
borderRadius: "var(--radius-3xl)"
|
|
11910
|
+
},
|
|
11911
|
+
children: [
|
|
11912
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11913
|
+
"span",
|
|
11914
|
+
{
|
|
11915
|
+
style: {
|
|
11916
|
+
fontFamily: "var(--font-family-font-family-body)",
|
|
11917
|
+
fontSize: "var(--font-size-font-size-sm)",
|
|
11918
|
+
fontWeight: 500,
|
|
11919
|
+
lineHeight: "var(--line-height-line-height-sm)",
|
|
11920
|
+
color: "var(--alias-text---icons-primary)"
|
|
11921
|
+
},
|
|
11922
|
+
children: sharedPoolBannerText(sharedPool)
|
|
11923
|
+
}
|
|
11924
|
+
),
|
|
11925
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
11926
|
+
"span",
|
|
11927
|
+
{
|
|
11928
|
+
style: {
|
|
11929
|
+
fontFamily: "var(--font-family-font-family-body)",
|
|
11930
|
+
fontSize: "var(--font-size-font-size-sm)",
|
|
11931
|
+
lineHeight: "var(--line-height-line-height-sm)",
|
|
11932
|
+
color: "var(--alias-text---icons-muted)"
|
|
11933
|
+
},
|
|
11934
|
+
children: [
|
|
11935
|
+
"This workspace spends these shared credits, not its own; credits bought here can't be used while it does.",
|
|
11936
|
+
sharedPool.cycleEnd ? ` The allowance starts again on ${formatDate3(sharedPool.cycleEnd)}.` : ""
|
|
11937
|
+
]
|
|
11938
|
+
}
|
|
11939
|
+
)
|
|
11940
|
+
]
|
|
11941
|
+
}
|
|
11942
|
+
) : null,
|
|
12094
11943
|
usage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
12095
11944
|
"div",
|
|
12096
11945
|
{
|
|
@@ -12164,7 +12013,7 @@ function BillingContent({
|
|
|
12164
12013
|
]
|
|
12165
12014
|
}
|
|
12166
12015
|
) : null,
|
|
12167
|
-
|
|
12016
|
+
canShareCredits ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
12168
12017
|
"div",
|
|
12169
12018
|
{
|
|
12170
12019
|
className: "flex items-center justify-between shrink-0 w-full",
|
|
@@ -12187,7 +12036,7 @@ function BillingContent({
|
|
|
12187
12036
|
lineHeight: "var(--line-height-line-height-sm)",
|
|
12188
12037
|
color: "var(--alias-text---icons-primary)"
|
|
12189
12038
|
},
|
|
12190
|
-
children: "
|
|
12039
|
+
children: "Shared credits"
|
|
12191
12040
|
}
|
|
12192
12041
|
),
|
|
12193
12042
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -12199,7 +12048,7 @@ function BillingContent({
|
|
|
12199
12048
|
lineHeight: "var(--line-height-line-height-sm)",
|
|
12200
12049
|
color: "var(--alias-text---icons-muted)"
|
|
12201
12050
|
},
|
|
12202
|
-
children: "
|
|
12051
|
+
children: "Let other workspaces in your organization spend this workspace's credits"
|
|
12203
12052
|
}
|
|
12204
12053
|
)
|
|
12205
12054
|
] }),
|
|
@@ -12209,7 +12058,7 @@ function BillingContent({
|
|
|
12209
12058
|
text: "Manage",
|
|
12210
12059
|
variant: "secondary",
|
|
12211
12060
|
size: "md",
|
|
12212
|
-
onClick: () =>
|
|
12061
|
+
onClick: () => setShowSharedCredits(true)
|
|
12213
12062
|
}
|
|
12214
12063
|
)
|
|
12215
12064
|
]
|
|
@@ -12259,7 +12108,9 @@ function BillingContent({
|
|
|
12259
12108
|
{
|
|
12260
12109
|
logs: usageLogs,
|
|
12261
12110
|
userMap,
|
|
12262
|
-
loading: loadingTable
|
|
12111
|
+
loading: loadingTable,
|
|
12112
|
+
currentWorkspaceId: workspaceId,
|
|
12113
|
+
usedByNames
|
|
12263
12114
|
}
|
|
12264
12115
|
),
|
|
12265
12116
|
showExportModal && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -12278,8 +12129,8 @@ function BillingContent({
|
|
|
12278
12129
|
workspace.current?.country
|
|
12279
12130
|
),
|
|
12280
12131
|
onClose: () => setShowBuyCreditsModal(false),
|
|
12281
|
-
onBuy: (
|
|
12282
|
-
handleBuyCredits(
|
|
12132
|
+
onBuy: (credits2, price) => {
|
|
12133
|
+
handleBuyCredits(credits2, price);
|
|
12283
12134
|
}
|
|
12284
12135
|
}
|
|
12285
12136
|
)
|
|
@@ -14927,20 +14778,20 @@ function SettingsContentInner({
|
|
|
14927
14778
|
const isBillingPlans = activeTab === "billing" && isWorkspaceAdmin && billingShowPlans;
|
|
14928
14779
|
const [billingShowPerUserLimits, setBillingShowPerUserLimits] = (0, import_react26.useState)(false);
|
|
14929
14780
|
const isBillingPerUserLimits = activeTab === "billing" && isWorkspaceAdmin && billingShowPerUserLimits && !billingShowPlans;
|
|
14930
|
-
const [
|
|
14931
|
-
const
|
|
14932
|
-
const isBillingSubView = isBillingPlans || isBillingPerUserLimits ||
|
|
14781
|
+
const [billingShowSharedCredits, setBillingShowSharedCredits] = (0, import_react26.useState)(false);
|
|
14782
|
+
const isBillingSharedCredits = activeTab === "billing" && isWorkspaceAdmin && billingShowSharedCredits && !billingShowPlans && !billingShowPerUserLimits;
|
|
14783
|
+
const isBillingSubView = isBillingPlans || isBillingPerUserLimits || isBillingSharedCredits;
|
|
14933
14784
|
(0, import_react26.useEffect)(() => {
|
|
14934
14785
|
if (activeTab !== "billing" || !isWorkspaceAdmin) {
|
|
14935
14786
|
setBillingShowPlans(false);
|
|
14936
14787
|
setBillingShowPerUserLimits(false);
|
|
14937
|
-
|
|
14788
|
+
setBillingShowSharedCredits(false);
|
|
14938
14789
|
}
|
|
14939
14790
|
}, [activeTab, isWorkspaceAdmin]);
|
|
14940
14791
|
(0, import_react26.useEffect)(() => {
|
|
14941
14792
|
setBillingShowPlans(false);
|
|
14942
14793
|
setBillingShowPerUserLimits(false);
|
|
14943
|
-
|
|
14794
|
+
setBillingShowSharedCredits(false);
|
|
14944
14795
|
}, [workspaceId]);
|
|
14945
14796
|
(0, import_react26.useEffect)(() => {
|
|
14946
14797
|
if (!onClose) return;
|
|
@@ -14955,15 +14806,15 @@ function SettingsContentInner({
|
|
|
14955
14806
|
setBillingShowPerUserLimits(false);
|
|
14956
14807
|
return;
|
|
14957
14808
|
}
|
|
14958
|
-
if (
|
|
14959
|
-
|
|
14809
|
+
if (billingShowSharedCredits) {
|
|
14810
|
+
setBillingShowSharedCredits(false);
|
|
14960
14811
|
return;
|
|
14961
14812
|
}
|
|
14962
14813
|
onClose();
|
|
14963
14814
|
};
|
|
14964
14815
|
document.addEventListener("keydown", handleKeyDown);
|
|
14965
14816
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
14966
|
-
}, [onClose, billingShowPlans, billingShowPerUserLimits,
|
|
14817
|
+
}, [onClose, billingShowPlans, billingShowPerUserLimits, billingShowSharedCredits]);
|
|
14967
14818
|
const [localWorkspaces, setLocalWorkspaces] = (0, import_react26.useState)(null);
|
|
14968
14819
|
const [wsModalOpen, setWsModalOpen] = (0, import_react26.useState)(false);
|
|
14969
14820
|
const [wsModalMode, setWsModalMode] = (0, import_react26.useState)("create");
|
|
@@ -15284,7 +15135,7 @@ function SettingsContentInner({
|
|
|
15284
15135
|
if (isBillingSubView) {
|
|
15285
15136
|
setBillingShowPlans(false);
|
|
15286
15137
|
setBillingShowPerUserLimits(false);
|
|
15287
|
-
|
|
15138
|
+
setBillingShowSharedCredits(false);
|
|
15288
15139
|
return;
|
|
15289
15140
|
}
|
|
15290
15141
|
if (onBack) onBack();
|
|
@@ -15387,7 +15238,7 @@ function SettingsContentInner({
|
|
|
15387
15238
|
}
|
|
15388
15239
|
)
|
|
15389
15240
|
] }),
|
|
15390
|
-
|
|
15241
|
+
isBillingSharedCredits && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
15391
15242
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_icons17.SiconRight, { className: "w-6 h-6 shrink-0", color: "var(--alias-text---icons-primary)" }),
|
|
15392
15243
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
15393
15244
|
"span",
|
|
@@ -15399,7 +15250,7 @@ function SettingsContentInner({
|
|
|
15399
15250
|
lineHeight: "var(--line-height-line-height-xl)",
|
|
15400
15251
|
color: "var(--alias-text---icons-primary)"
|
|
15401
15252
|
},
|
|
15402
|
-
children: "
|
|
15253
|
+
children: "Shared credits"
|
|
15403
15254
|
}
|
|
15404
15255
|
)
|
|
15405
15256
|
] })
|
|
@@ -15612,7 +15463,7 @@ function SettingsContentInner({
|
|
|
15612
15463
|
setBillingShowPlans(open);
|
|
15613
15464
|
if (open) {
|
|
15614
15465
|
setBillingShowPerUserLimits(false);
|
|
15615
|
-
|
|
15466
|
+
setBillingShowSharedCredits(false);
|
|
15616
15467
|
}
|
|
15617
15468
|
},
|
|
15618
15469
|
showPerUserLimits: billingShowPerUserLimits,
|
|
@@ -15620,12 +15471,12 @@ function SettingsContentInner({
|
|
|
15620
15471
|
setBillingShowPerUserLimits(open);
|
|
15621
15472
|
if (open) {
|
|
15622
15473
|
setBillingShowPlans(false);
|
|
15623
|
-
|
|
15474
|
+
setBillingShowSharedCredits(false);
|
|
15624
15475
|
}
|
|
15625
15476
|
},
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15477
|
+
showSharedCredits: billingShowSharedCredits,
|
|
15478
|
+
onShowSharedCreditsChange: (open) => {
|
|
15479
|
+
setBillingShowSharedCredits(open);
|
|
15629
15480
|
if (open) {
|
|
15630
15481
|
setBillingShowPlans(false);
|
|
15631
15482
|
setBillingShowPerUserLimits(false);
|