diff --git a/satellite/accounting/projectlimitcache.go b/satellite/accounting/projectlimitcache.go
index 61aab5908..98a7e9cc5 100644
--- a/satellite/accounting/projectlimitcache.go
+++ b/satellite/accounting/projectlimitcache.go
@@ -78,6 +78,14 @@ func (c *ProjectLimitCache) GetProjectLimits(ctx context.Context, projectID uuid
defaultUsage := c.defaultMaxUsage.Int64()
projectLimits.Usage = &defaultUsage
}
+ if projectLimits.Segments == nil {
+ defaultSegments := c.defaultMaxSegments
+ projectLimits.Segments = &defaultSegments
+ }
+ if projectLimits.Segments == nil {
+ defaultSegments := c.defaultMaxSegments
+ projectLimits.Segments = &defaultSegments
+ }
return projectLimits, nil
}
diff --git a/satellite/accounting/projectusage.go b/satellite/accounting/projectusage.go
index 1a74913ee..ac2da5c8a 100644
--- a/satellite/accounting/projectusage.go
+++ b/satellite/accounting/projectusage.go
@@ -218,6 +218,18 @@ func (usage *Service) GetProjectBandwidthTotals(ctx context.Context, projectID u
return total, ErrProjectUsage.Wrap(err)
}
+// GetProjectSegmentTotals returns total amount of allocated segments used for past 30 days.
+func (usage *Service) GetProjectSegmentTotals(ctx context.Context, projectID uuid.UUID) (total int64, err error) {
+ defer mon.Task()(&ctx, projectID)(&err)
+
+ total, err = usage.liveAccounting.GetProjectSegmentUsage(ctx, projectID)
+ if ErrKeyNotFound.Has(err) {
+ return 0, nil
+ }
+
+ return total, ErrProjectUsage.Wrap(err)
+}
+
// GetProjectBandwidth returns project allocated bandwidth for the specified year, month and day.
func (usage *Service) GetProjectBandwidth(ctx context.Context, projectID uuid.UUID, year int, month time.Month, day int) (_ int64, err error) {
defer mon.Task()(&ctx, projectID)(&err)
@@ -243,6 +255,17 @@ func (usage *Service) GetProjectBandwidthLimit(ctx context.Context, projectID uu
return usage.projectLimitCache.GetProjectBandwidthLimit(ctx, projectID)
}
+// GetProjectSegmentLimit returns current project segment limit.
+func (usage *Service) GetProjectSegmentLimit(ctx context.Context, projectID uuid.UUID) (_ memory.Size, err error) {
+ defer mon.Task()(&ctx, projectID)(&err)
+ limits, err := usage.projectLimitCache.GetProjectLimits(ctx, projectID)
+ if err != nil {
+ return 0, ErrProjectUsage.Wrap(err)
+ }
+
+ return memory.Size(*limits.Usage), nil
+}
+
// UpdateProjectLimits sets new value for project's bandwidth and storage limit.
// TODO remove because it's not used.
func (usage *Service) UpdateProjectLimits(ctx context.Context, projectID uuid.UUID, limit memory.Size) (err error) {
diff --git a/satellite/console/projectusagelimits.go b/satellite/console/projectusagelimits.go
index 0f89ab4ce..b404bde59 100644
--- a/satellite/console/projectusagelimits.go
+++ b/satellite/console/projectusagelimits.go
@@ -11,6 +11,10 @@ type ProjectUsageLimits struct {
BandwidthUsed int64 `json:"bandwidthUsed"`
ObjectCount int64 `json:"objectCount"`
SegmentCount int64 `json:"segmentCount"`
+ RateLimit int64 `json:"rateLimit"`
+ SegmentLimit int64 `json:"segmentLimit"`
+ RateUsed int64 `json:"rateUsed"`
+ SegmentUsed int64 `json:"segmentUsed"`
}
// UsageLimits represents storage, bandwidth, and segment limits imposed on an entity.
diff --git a/satellite/console/service.go b/satellite/console/service.go
index f246cd0cb..2f0ffc5e8 100644
--- a/satellite/console/service.go
+++ b/satellite/console/service.go
@@ -2642,6 +2642,8 @@ func (s *Service) GetProjectUsageLimits(ctx context.Context, projectID uuid.UUID
BandwidthUsed: prUsageLimits.BandwidthUsed,
ObjectCount: prObjectsSegments.ObjectCount,
SegmentCount: prObjectsSegments.SegmentCount,
+ SegmentLimit: prUsageLimits.SegmentLimit,
+ SegmentUsed: prUsageLimits.SegmentUsed,
}, nil
}
@@ -2695,6 +2697,10 @@ func (s *Service) getProjectUsageLimits(ctx context.Context, projectID uuid.UUID
if err != nil {
return nil, err
}
+ segmentLimit, err := s.projectUsage.GetProjectSegmentLimit(ctx, projectID)
+ if err != nil {
+ return nil, err
+ }
storageUsed, err := s.projectUsage.GetProjectStorageTotals(ctx, projectID)
if err != nil {
@@ -2704,12 +2710,18 @@ func (s *Service) getProjectUsageLimits(ctx context.Context, projectID uuid.UUID
if err != nil {
return nil, err
}
+ segmentUsed, err := s.projectUsage.GetProjectSegmentTotals(ctx, projectID)
+ if err != nil {
+ return nil, err
+ }
return &ProjectUsageLimits{
StorageLimit: storageLimit.Int64(),
BandwidthLimit: bandwidthLimit.Int64(),
StorageUsed: storageUsed,
BandwidthUsed: bandwidthUsed,
+ SegmentLimit: segmentLimit.Int64(),
+ SegmentUsed: segmentUsed,
}, nil
}
diff --git a/web/satellite/src/api/projects.ts b/web/satellite/src/api/projects.ts
index 3a9a2f3bb..91e9e8102 100644
--- a/web/satellite/src/api/projects.ts
+++ b/web/satellite/src/api/projects.ts
@@ -153,9 +153,11 @@ export class ProjectsApiGql extends BaseGql implements ProjectsApi {
limits.bandwidthLimit,
limits.bandwidthUsed,
limits.storageLimit,
- limits.storageUsed,
+ limits.storageUsed,
limits.objectCount,
limits.segmentCount,
+ limits.segmentLimit,
+ limits.segmentUsed,
);
}
diff --git a/web/satellite/src/components/modals/LimitWarningModal.vue b/web/satellite/src/components/modals/LimitWarningModal.vue
index 5ce87e5f8..78c284fa4 100644
--- a/web/satellite/src/components/modals/LimitWarningModal.vue
+++ b/web/satellite/src/components/modals/LimitWarningModal.vue
@@ -7,7 +7,7 @@
{{ title }}
-
To get more storage and bandwidth, upgrade to a Pro Account. You will still get 150GB free storage and bandwidth per month, and only pay what you use beyond that.
+
To get more {{ limitType }} limit, upgrade to a Pro Account. You will still get 150GB free storage and bandwidth per month, and only pay what you use beyond that.
@@ -54,6 +54,8 @@ export default class LimitWarningModal extends Vue {
private readonly severity: 'warning' | 'critical';
@Prop({ default: '' })
private readonly title: string;
+ @Prop({ default: '' })
+ private readonly limitType: string;
@Prop({ default: () => {} })
private readonly onUpgrade: () => Promise;
@Prop({ default: () => {} })
diff --git a/web/satellite/src/types/projects.ts b/web/satellite/src/types/projects.ts
index 616f31d8c..36180bc05 100644
--- a/web/satellite/src/types/projects.ts
+++ b/web/satellite/src/types/projects.ts
@@ -153,6 +153,8 @@ export class ProjectLimits {
public storageUsed: number = 0,
public objectCount: number = 0,
public segmentCount: number = 0,
+ public segmentLimit: number = 0,
+ public segmentUsed: number = 0,
) {}
}
diff --git a/web/satellite/src/views/DashboardArea.vue b/web/satellite/src/views/DashboardArea.vue
index b1df9b665..522bf6566 100644
--- a/web/satellite/src/views/DashboardArea.vue
+++ b/web/satellite/src/views/DashboardArea.vue
@@ -38,13 +38,24 @@
- {{ limitState.label }}
+ {{ limitState.hundredLabel }}
+ Upgrade now
+
+
+
+
+ {{ limitState.eightyLabel }}
Upgrade now
@@ -66,10 +77,19 @@
:initial-seconds="inactivityModalTime / 1000"
/>
+
@@ -147,7 +167,8 @@ const debugTimerId = ref | null>();
const inactivityModalShown = ref(false);
const isSessionActive = ref(false);
const isSessionRefreshing = ref(false);
-const isLimitModalShown = ref(false);
+const isHundredLimitModalShown = ref(false);
+const isEightyLimitModalShown = ref(false);
const debugTimerText = ref('');
const dashboardContent = ref(null);
@@ -162,41 +183,61 @@ const isAccountFrozen = computed((): boolean => {
/**
* Returns all needed information for limit banner and modal when bandwidth or storage close to limits.
*/
-const limitState = computed((): { isShown: boolean, severity?: 'info' | 'warning' | 'critical', label?: string, modalTitle?: string } => {
- if (store.state.usersModule.user.paidTier || isAccountFrozen.value) return { isShown: false };
+const limitState = computed((): { eightyIsShown: boolean, hundredIsShown: boolean, eightyLabel?: string, eightyModalTitle?: string, eightyModalLimitType?: string, hundredLabel?: string, hundredModalTitle?: string, hundredModalLimitType?: string } => {
+ if (store.state.usersModule.user.paidTier || isAccountFrozen.value) return { eightyIsShown: false, hundredIsShown: false };
- const EIGHTY_PERCENT = 80;
- const HUNDRED_PERCENT = 100;
+ const result:
+ {
+ eightyIsShown: boolean,
+ hundredIsShown: boolean,
+ eightyLabel?: string,
+ eightyModalTitle?: string,
+ eightyModalLimitType?: string,
+ hundredLabel?: string,
+ hundredModalTitle?: string,
+ hundredModalLimitType?: string
+
+ } = { eightyIsShown: false, hundredIsShown: false, eightyLabel: '', hundredLabel: '' };
- const result: { isShown: boolean, severity?: 'info' | 'warning' | 'critical', label?: string, modalTitle?: string } = { isShown: false, label: '' };
const { currentLimits } = store.state.projectsModule;
+
+ const limitTypeArr = [
+ { name: 'bandwidth', usedPercent: Math.round(currentLimits.bandwidthUsed * 100 / currentLimits.bandwidthLimit) },
+ { name: 'storage', usedPercent: Math.round(currentLimits.storageUsed * 100 / currentLimits.storageLimit) },
+ { name: 'segment', usedPercent: Math.round(currentLimits.segmentUsed * 100 / currentLimits.segmentLimit) },
+ ];
- const bandwidthUsedPercent = Math.round(currentLimits.bandwidthUsed * HUNDRED_PERCENT / currentLimits.bandwidthLimit);
- const storageUsedPercent = Math.round(currentLimits.storageUsed * HUNDRED_PERCENT / currentLimits.storageLimit);
+ const hundredPercent = [] as string[];
+ const eightyPercent = [] as string[];
- const isLimitHigh = bandwidthUsedPercent >= EIGHTY_PERCENT || storageUsedPercent >= EIGHTY_PERCENT;
- const isLimitCritical = bandwidthUsedPercent === HUNDRED_PERCENT || storageUsedPercent === HUNDRED_PERCENT;
+ limitTypeArr.forEach((limitType) => {
+ if (limitType.usedPercent >= 80) {
+ if (limitType.usedPercent >= 100) {
+ hundredPercent.push(limitType.name);
+ } else {
+ eightyPercent.push(limitType.name);
+ }
+ }
+ });
- if (isLimitHigh) {
- result.isShown = true;
- result.severity = isLimitCritical ? 'critical' : 'warning';
+ if (eightyPercent.length !== 0) {
+ result.eightyIsShown = true;
- if (bandwidthUsedPercent > storageUsedPercent) {
- result.label = bandwidthUsedPercent === HUNDRED_PERCENT ?
- 'URGENT: You’ve reached the bandwidth limit for your project. Avoid any service interruptions.'
- : `You’ve used ${bandwidthUsedPercent}% of your bandwidth limit. Avoid interrupting your usage by upgrading account.`;
- result.modalTitle = `You’ve used ${bandwidthUsedPercent}% of your free account bandwidth`;
- } else if (bandwidthUsedPercent < storageUsedPercent) {
- result.label = storageUsedPercent === HUNDRED_PERCENT ?
- 'URGENT: You’ve reached the storage limit for your project. Avoid any service interruptions.'
- : `You’ve used ${storageUsedPercent}% of your storage limit. Avoid interrupting your usage by upgrading account.`;
- result.modalTitle = `You’ve used ${storageUsedPercent}% of your free account storage`;
- } else {
- result.label = storageUsedPercent === HUNDRED_PERCENT && bandwidthUsedPercent === HUNDRED_PERCENT ?
- 'URGENT: You’ve reached the storage and bandwidth limits for your project. Avoid any service interruptions.'
- : `You’ve used ${storageUsedPercent}% of your storage and ${bandwidthUsedPercent}% of bandwidth limit. Avoid interrupting your usage by upgrading account.`;
- result.modalTitle = `You’ve used ${storageUsedPercent}% storage and ${bandwidthUsedPercent}% of your free account bandwidth`;
- }
+ const eightyPercentString = eightyPercent.join(' and ');
+
+ result.eightyLabel = `You've used 80% of your ${eightyPercentString} limit. Avoid interrupting your usage by upgrading your account.`;
+ result.eightyModalTitle = `80% ${eightyPercentString} limit used`;
+ result.eightyModalLimitType = eightyPercentString;
+ }
+
+ if (hundredPercent.length !== 0) {
+ result.hundredIsShown = true;
+
+ const hundredPercentString = hundredPercent.join(' and ');
+
+ result.hundredLabel = `URGENT: You’ve reached the ${hundredPercentString} limit for your project. Upgrade to avoid any service interruptions.`;
+ result.hundredModalTitle = `URGENT: You’ve reached the ${hundredPercentString} limit for your project.`;
+ result.hundredModalLimitType = hundredPercentString;
}
return result;
@@ -469,8 +510,12 @@ async function handleInactive(): Promise {
}
}
-function setIsLimitModalShown(value: boolean): void {
- isLimitModalShown.value = value;
+function setIsEightyLimitModalShown(value: boolean): void {
+ isEightyLimitModalShown.value = value;
+}
+
+function setIsHundredLimitModalShown(value: boolean): void {
+ isHundredLimitModalShown.value = value;
}
/**
@@ -496,7 +541,8 @@ async function generateNewMFARecoveryCodes(): Promise {
* Opens add payment method modal.
*/
function togglePMModal(): void {
- isLimitModalShown.value = false;
+ isHundredLimitModalShown.value = false;
+ isEightyLimitModalShown.value = false;
store.commit(APP_STATE_MUTATIONS.UPDATE_ACTIVE_MODAL, MODALS.addPaymentMethod);
}