Skip to content

Commit

Permalink
connect measured used storage to frontend organization page
Browse files Browse the repository at this point in the history
  • Loading branch information
fm3 committed Jan 10, 2023
1 parent b459dba commit cd80b77
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 48 deletions.
4 changes: 2 additions & 2 deletions app/models/organization/Organization.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ case class Organization(
pricingPlan: PricingPlan,
paidUntil: Option[Instant],
includedUsers: Option[Int], // None means unlimited
includedStorage: Option[Long], // None means unlimited
includedStorageBytes: Option[Long], // None means unlimited
_rootFolder: ObjectId,
newUserMailingList: String = "",
overTimeMailingList: String = "",
Expand Down Expand Up @@ -102,7 +102,7 @@ class OrganizationDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionCont
VALUES
(${o._id.id}, ${o.name}, ${o.additionalInformation}, ${o.logoUrl}, ${o.displayName}, ${o._rootFolder},
${o.newUserMailingList}, ${o.overTimeMailingList}, ${o.enableAutoVerify},
'#${o.pricingPlan}', ${o.paidUntil}, ${o.includedUsers}, ${o.includedStorage}, ${o.lastTermsOfServiceAcceptanceTime},
'#${o.pricingPlan}', ${o.paidUntil}, ${o.includedUsers}, ${o.includedStorageBytes}, ${o.lastTermsOfServiceAcceptanceTime},
${o.lastTermsOfServiceAcceptanceVersion}, ${o.created}, ${o.isDeleted})
""")
} yield ()
Expand Down
2 changes: 1 addition & 1 deletion app/models/organization/OrganizationService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OrganizationService @Inject()(organizationDAO: OrganizationDAO,
"pricingPlan" -> organization.pricingPlan,
"paidUntil" -> organization.paidUntil,
"includedUsers" -> organization.includedUsers,
"includedStorage" -> organization.includedStorage.map(bytes => bytes / 1000000),
"includedStorageBytes" -> organization.includedStorageBytes,
"usedStorageBytes" -> usedStorageBytes
) ++ adminOnlyInfo
}
Expand Down
11 changes: 1 addition & 10 deletions frontend/javascripts/admin/admin_rest_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ import type {
VoxelyticsWorkflowReport,
VoxelyticsChunkStatistics,
ShortLink,
APIOrganizationStorageInfo,
APIPricingPlanStatus,
} from "types/api_flow_types";
import { APIAnnotationTypeEnum } from "types/api_flow_types";
Expand Down Expand Up @@ -1935,7 +1934,7 @@ export async function getOrganization(organizationName: string): Promise<APIOrga
return {
...organization,
paidUntil: organization.paidUntil ?? Constants.MAXIMUM_DATE_TIMESTAMP,
includedStorage: organization.includedStorage ?? Number.POSITIVE_INFINITY,
includedStorageBytes: organization.includedStorageBytes ?? Number.POSITIVE_INFINITY,
includedUsers: organization.includedUsers ?? Number.POSITIVE_INFINITY,
};
}
Expand Down Expand Up @@ -1990,14 +1989,6 @@ export async function isWorkflowAccessibleBySwitching(
return Request.receiveJSON(`/api/auth/accessibleBySwitching?workflowHash=${workflowHash}`);
}

export async function getOrganizationStorageSpace(
_organizationName: string,
): Promise<APIOrganizationStorageInfo> {
// TODO switch to a real API. See PR #6614
const usedStorageMB = 0;
return Promise.resolve({ usedStorageSpace: usedStorageMB });
}

export async function sendUpgradePricingPlanEmail(requestedPlan: string): Promise<void> {
return Request.receiveJSON(`/api/pricing/requestUpgrade?requestedPlan=${requestedPlan}`, {
method: "POST",
Expand Down
17 changes: 8 additions & 9 deletions frontend/javascripts/admin/organization/organization_cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,32 +173,31 @@ export function PlanExpirationCard({ organization }: { organization: APIOrganiza
export function PlanDashboardCard({
organization,
activeUsersCount,
usedStorageSpace,
}: {
organization: APIOrganization;
activeUsersCount: number;
usedStorageSpace: number;
}) {
const usedUsersPercentage = (activeUsersCount / organization.includedUsers) * 100;
const usedStoragePercentage = (usedStorageSpace / organization.includedStorage) * 100;
const usedStoragePercentage =
(organization.usedStorageBytes / organization.includedStorageBytes) * 100;

const hasExceededUserLimit = hasPricingPlanExceededUsers(organization, activeUsersCount);
const hasExceededStorageLimit = hasPricingPlanExceededStorage(organization, usedStorageSpace);
const hasExceededStorageLimit = hasPricingPlanExceededStorage(organization);

const maxUsersCountLabel =
organization.includedUsers === Number.POSITIVE_INFINITY ? "∞" : organization.includedUsers;

let includedStorageLabel =
organization.pricingPlan === PricingPlanEnum.Basic
? `${(organization.includedStorage / 1000).toFixed(0)}GB`
: `${(organization.includedStorage / 1000 ** 2).toFixed(0)}TB`;
? `${(organization.includedStorageBytes / 10 ** 9).toFixed(0)}GB`
: `${(organization.includedStorageBytes / 10 ** 12).toFixed(0)}TB`;
includedStorageLabel =
organization.includedStorage === Number.POSITIVE_INFINITY ? "∞" : includedStorageLabel;
organization.includedStorageBytes === Number.POSITIVE_INFINITY ? "∞" : includedStorageLabel;

const usedStorageLabel =
organization.pricingPlan === PricingPlanEnum.Basic
? `${(usedStorageSpace / 1000).toFixed(1)}`
: `${(usedStorageSpace / 1000 ** 2).toFixed(1)}`;
? `${(organization.usedStorageBytes / 10 ** 9).toFixed(1)}`
: `${(organization.usedStorageBytes / 10 ** 12).toFixed(1)}`;

const storageLabel = `${usedStorageLabel}/${includedStorageLabel}`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
updateOrganization,
getUsers,
getPricingPlanStatus,
getOrganizationStorageSpace,
} from "admin/admin_rest_api";
import Toast from "libs/toast";
import { coalesce } from "libs/utils";
Expand Down Expand Up @@ -50,7 +49,6 @@ type State = {
organization: APIOrganization | null;
activeUsersCount: number;
pricingPlanStatus: APIPricingPlanStatus | null;
usedStorageSpace: number | null;
};

class OrganizationEditView extends React.PureComponent<Props, State> {
Expand All @@ -63,7 +61,6 @@ class OrganizationEditView extends React.PureComponent<Props, State> {
organization: null,
activeUsersCount: 1,
pricingPlanStatus: null,
usedStorageSpace: null,
};
formRef = React.createRef<FormInstance>();

Expand Down Expand Up @@ -101,11 +98,10 @@ class OrganizationEditView extends React.PureComponent<Props, State> {
this.setState({
isFetchingData: true,
});
const [organization, users, pricingPlanStatus, usedStorageSpace] = await Promise.all([
const [organization, users, pricingPlanStatus] = await Promise.all([
getOrganization(this.props.organizationName),
getUsers(),
getPricingPlanStatus(),
getOrganizationStorageSpace(this.props.organizationName),
]);

const { displayName, newUserMailingList, pricingPlan } = organization;
Expand All @@ -117,7 +113,6 @@ class OrganizationEditView extends React.PureComponent<Props, State> {
organization,
pricingPlanStatus,
activeUsersCount: getActiveUserCount(users),
usedStorageSpace: usedStorageSpace.usedStorageSpace,
});
}

Expand Down Expand Up @@ -165,8 +160,7 @@ class OrganizationEditView extends React.PureComponent<Props, State> {
this.state.isFetchingData ||
!this.state.organization ||
!this.state.pricingPlan ||
!this.state.pricingPlanStatus ||
this.state.usedStorageSpace === null
!this.state.pricingPlanStatus
)
return (
<div
Expand Down Expand Up @@ -206,7 +200,6 @@ class OrganizationEditView extends React.PureComponent<Props, State> {
<PlanDashboardCard
organization={this.state.organization}
activeUsersCount={this.state.activeUsersCount}
usedStorageSpace={this.state.usedStorageSpace}
/>
<PlanExpirationCard organization={this.state.organization} />
<PlanUpgradeCard organization={this.state.organization} />
Expand Down
9 changes: 3 additions & 6 deletions frontend/javascripts/admin/organization/pricing_plan_utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { APIOrganization, APIOrganizationStorageInfo, APIUser } from "types/api_flow_types";
import { APIOrganization, APIUser } from "types/api_flow_types";
import { PricingPlanEnum } from "./organization_edit_view";

export const teamPlanFeatures = [
Expand Down Expand Up @@ -34,11 +34,8 @@ export function hasPricingPlanExceededUsers(
return activeUserCount > organization.includedUsers;
}

export function hasPricingPlanExceededStorage(
organization: APIOrganization,
usedStorageSpaceMB: number,
): boolean {
return usedStorageSpaceMB > organization.includedStorage;
export function hasPricingPlanExceededStorage(organization: APIOrganization): boolean {
return organization.usedStorageBytes > organization.includedStorageBytes;
}

export function isUserAllowedToRequestUpgrades(user: APIUser): boolean {
Expand Down
8 changes: 1 addition & 7 deletions frontend/javascripts/dashboard/dashboard_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,11 @@ import React, { PureComponent, useContext } from "react";
import _ from "lodash";
import { setActiveUserAction } from "oxalis/model/actions/user_actions";
import { WhatsNextHeader } from "admin/welcome_ui";
import type {
APIOrganization,
APIOrganizationStorageInfo,
APIPricingPlanStatus,
APIUser,
} from "types/api_flow_types";
import type { APIOrganization, APIPricingPlanStatus, APIUser } from "types/api_flow_types";
import type { OxalisState } from "oxalis/store";
import { enforceActiveUser } from "oxalis/model/accessors/user_accessor";
import {
getOrganization,
getOrganizationStorageSpace,
getPricingPlanStatus,
getUser,
updateNovelUserExperienceInfos,
Expand Down
6 changes: 2 additions & 4 deletions frontend/javascripts/types/api_flow_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,10 +516,8 @@ export type APIOrganization = {
readonly newUserMailingList: string;
readonly paidUntil: number;
readonly includedUsers: number;
readonly includedStorage: number; // megabytes
};
export type APIOrganizationStorageInfo = {
readonly usedStorageSpace: number;
readonly includedStorageBytes: number;
readonly usedStorageBytes: number;
};
export type APIPricingPlanStatus = {
readonly pricingPlan: PricingPlanEnum;
Expand Down

0 comments on commit cd80b77

Please sign in to comment.