Simple User Quota (#367)

* Simple User Quota
* 👷Fix build with OpenSearch
This commit is contained in:
Anton Shepilov
2024-02-22 10:17:25 +01:00
committed by GitHub
parent df0809ec48
commit 63f2c281c0
34 changed files with 10549 additions and 5836 deletions
@@ -7,6 +7,7 @@ import { DriveItemAtom, DriveItemChildrenAtom } from '../state/store';
import { BrowseFilter, DriveItem, DriveItemVersion } from '../types';
import { SharedWithMeFilterState } from '../state/shared-with-me-filter';
import Languages from 'features/global/services/languages-service';
import { useUserQuota } from "features/users/hooks/use-user-quota";
/**
* Returns the children of a drive item
@@ -15,6 +16,7 @@ import Languages from 'features/global/services/languages-service';
export const useDriveActions = () => {
const companyId = useRouterCompany();
const sharedFilter = useRecoilValue(SharedWithMeFilterState);
const { getQuota } = useUserQuota();
const refresh = useRecoilCallback(
({ set, snapshot }) =>
@@ -52,6 +54,7 @@ export const useDriveActions = () => {
try {
driveFile = await DriveApiClient.create(companyId, { item, version });
await refresh(driveFile.parent_id!);
await getQuota();
} catch (e) {
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_create_file'));
}
@@ -89,6 +92,7 @@ export const useDriveActions = () => {
try {
await DriveApiClient.remove(companyId, id);
await refresh(parentId || '');
await getQuota();
} catch (e) {
ToasterService.error(Languages.t('hooks.use-drive-actions.unable_remove_file'));
}
@@ -9,3 +9,15 @@ export const formatBytes = (bytes: number, decimals = 2) => {
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
};
export const formatBytesToInt = (bytes: number, decimals = 2) => {
if (!+bytes) return '0 KB';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseInt((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
};
@@ -11,6 +11,7 @@ export enum FeatureNames {
COMPANY_SEARCH_USERS = 'company:search_users',
COMPANY_SHARED_DRIVE = 'company:shared_drive',
COMPANY_DISPLAY_EMAIL = 'company:display_email',
COMPANY_USER_QUOTA = 'company:user_quota',
}
export type FeatureValueType = boolean | number;
@@ -29,6 +30,7 @@ availableFeaturesWithDefaults.set(FeatureNames.COMPANY_INVITE_MEMBER, true);
availableFeaturesWithDefaults.set(FeatureNames.COMPANY_SEARCH_USERS, true);
availableFeaturesWithDefaults.set(FeatureNames.COMPANY_SHARED_DRIVE, true);
availableFeaturesWithDefaults.set(FeatureNames.COMPANY_DISPLAY_EMAIL, true);
availableFeaturesWithDefaults.set(FeatureNames.COMPANY_USER_QUOTA, false);
/**
* ChannelServiceImpl that allow you to manage feature flipping in Tdrive using react feature toggles
@@ -70,7 +72,6 @@ class FeatureTogglesService {
}
public isActiveFeatureName(featureName: FeatureNames) {
console.debug(this.activeFeatureNames)
const b = this.activeFeatureNames.includes(featureName);
console.debug(`Feature ${featureName} is ${b}`);
return b;
@@ -7,6 +7,7 @@ import WorkspaceAPIClient from '../../workspaces/api/workspace-api-client';
import CurrentUser from '../../../deprecated/user/CurrentUser';
import { setUserList } from '../hooks/use-user-list';
import Logger from 'features/global/framework/logger-service';
import { UserQuota } from "features/users/types/user-quota";
export type SearchContextType = {
scope: 'company' | 'workspace' | 'all';
@@ -141,6 +142,19 @@ class UserAPIClientService {
});
}
async getQuota(userId: string): Promise<UserQuota> {
return Api.get<UserQuota>(
`/internal/services/users/v1/users/${userId}/quota`,
undefined,
false
).then(result => {
return result;
}).catch(e => {
console.log(`Error getting quota:: ${e.message}`)
return { } as UserQuota;
});
}
async getCompany(companyId: string): Promise<CompanyType> {
return Api.get<{ resource: CompanyType }>(
`/internal/services/users/v1/companies/${companyId}`,
@@ -0,0 +1,41 @@
import { useCallback, useEffect } from "react";
import { UserQuota } from '@features/users/types/user-quota';
import UserAPIClient from '@features/users/api/user-api-client';
import { useCurrentUser } from "features/users/hooks/use-current-user";
import { atom, useRecoilState } from "recoil";
export const QuotaState = atom<UserQuota>({
key: 'QuotaState',
default: {
used: 0,
remaining: 1,
total: 1
},
});
export const useUserQuota = () => {
const nullQuota = {
used: 0,
remaining: 1,
total: 1
}
const {user } = useCurrentUser();
const [quota, setQuota] = useRecoilState(QuotaState);
const getQuota = useCallback(async () => {
let data: UserQuota = nullQuota;
if (user?.id) {
data = await UserAPIClient.getQuota(user.id);
} else {
data = nullQuota;
}
setQuota(data)
}, []);
useEffect(() => {
getQuota();
}, []);
return { quota, getQuota };
};
@@ -0,0 +1,5 @@
export type UserQuota = {
used: number;
remaining: number;
total: number;
}