diff --git a/packages/server/src/modules/ee/Workspaces/dtos/WorkspaceResponse.dto.ts b/packages/server/src/modules/ee/Workspaces/dtos/WorkspaceResponse.dto.ts index ae36cbbba..1219b7387 100644 --- a/packages/server/src/modules/ee/Workspaces/dtos/WorkspaceResponse.dto.ts +++ b/packages/server/src/modules/ee/Workspaces/dtos/WorkspaceResponse.dto.ts @@ -22,6 +22,10 @@ export class WorkspaceDto { metadata?: WorkspaceMetadataDto; @ApiPropertyOptional() totalIncome?: number; @ApiPropertyOptional() totalExpenses?: number; + @ApiPropertyOptional() totalAssets?: number; + @ApiPropertyOptional() totalLiabilities?: number; + @ApiPropertyOptional() formattedTotalAssets?: string; + @ApiPropertyOptional() formattedTotalLiabilities?: string; } export class CreateWorkspaceResponseDto { diff --git a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts b/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts index 3619e30f2..493f52425 100644 --- a/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts +++ b/packages/server/src/modules/ee/Workspaces/queries/GetWorkspacesFinancial.service.ts @@ -10,6 +10,8 @@ interface WorkspaceFinancialData { tenantId: number; totalIncome: number; totalExpenses: number; + totalAssets: number; + totalLiabilities: number; } interface AccountTransaction { @@ -19,6 +21,11 @@ interface AccountTransaction { accountRootType: string; } +interface AccountBalance { + accountRootType: string; + total: string; +} + /** * Service to retrieve financial data (income and expenses) for multiple workspaces. * This service creates dynamic connections to tenant databases to fetch aggregated data. @@ -96,10 +103,27 @@ export class GetWorkspacesFinancialService { const totalIncome = this.calculateIncome(transactions); const totalExpenses = this.calculateExpenses(transactions); + // Query account balances for assets and liabilities + const balances = (await knex('accounts') + .whereIn('root_type', [ACCOUNT_ROOT_TYPE.ASSET, ACCOUNT_ROOT_TYPE.LIABILITY]) + .select( + knex.raw('root_type as accountRootType'), + knex.raw('SUM(amount) as total'), + ) + .groupBy('root_type')) as AccountBalance[]; + + const assetsRow = balances.find((b) => b.accountRootType === ACCOUNT_ROOT_TYPE.ASSET); + const liabilitiesRow = balances.find((b) => b.accountRootType === ACCOUNT_ROOT_TYPE.LIABILITY); + + const totalAssets = assetsRow ? parseFloat(assetsRow.total) : 0; + const totalLiabilities = liabilitiesRow ? parseFloat(liabilitiesRow.total) : 0; + return { tenantId, totalIncome: Math.max(0, totalIncome), totalExpenses: Math.max(0, totalExpenses), + totalAssets, + totalLiabilities, }; } catch (error) { // If tenant database doesn't exist or other error, return zeros @@ -107,6 +131,8 @@ export class GetWorkspacesFinancialService { tenantId, totalIncome: 0, totalExpenses: 0, + totalAssets: 0, + totalLiabilities: 0, }; } finally { await knex.destroy(); @@ -150,6 +176,8 @@ export class GetWorkspacesFinancialService { tenantId: w.tenantId, totalIncome: 0, totalExpenses: 0, + totalAssets: 0, + totalLiabilities: 0, }); }); diff --git a/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts b/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts index 688d1a60d..d9bc67de0 100644 --- a/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts +++ b/packages/server/src/modules/ee/Workspaces/transformers/WorkspaceTransformer.ts @@ -1,11 +1,14 @@ import { Transformer } from '@/modules/Transformer/Transformer'; import { UserTenant } from '@/modules/System/models/UserTenant.model'; import { WorkspaceDto } from '../dtos/WorkspaceResponse.dto'; +import { formatNumber } from '@/utils/format-number'; interface FinancialData { tenantId: number; totalIncome: number; totalExpenses: number; + totalAssets: number; + totalLiabilities: number; } /** @@ -31,6 +34,10 @@ export class WorkspaceTransformer extends Transformer { 'isDefault', 'totalIncome', 'totalExpenses', + 'totalAssets', + 'totalLiabilities', + 'formattedTotalAssets', + 'formattedTotalLiabilities', ]; }; @@ -115,6 +122,42 @@ export class WorkspaceTransformer extends Transformer { return this.financialData?.totalExpenses ?? 0; }; + /** + * Get total assets from financial data. + */ + protected totalAssets = (): number => { + return this.financialData?.totalAssets ?? 0; + }; + + /** + * Get total liabilities from financial data. + */ + protected totalLiabilities = (): number => { + return this.financialData?.totalLiabilities ?? 0; + }; + + /** + * Get formatted total assets. + */ + protected formattedTotalAssets = (membership: UserTenant): string => { + const currencyCode = membership.tenant?.metadata?.baseCurrency; + return formatNumber(this.totalAssets(), { + currencyCode, + money: true, + }); + }; + + /** + * Get formatted total liabilities. + */ + protected formattedTotalLiabilities = (membership: UserTenant): string => { + const currencyCode = membership.tenant?.metadata?.baseCurrency; + return formatNumber(this.totalLiabilities(), { + currencyCode, + money: true, + }); + }; + /** * Transform single membership to WorkspaceDto. */ @@ -137,6 +180,10 @@ export class WorkspaceTransformer extends Transformer { metadata: this.metadata(membership), totalIncome: this.totalIncome(), totalExpenses: this.totalExpenses(), + totalAssets: this.totalAssets(), + totalLiabilities: this.totalLiabilities(), + formattedTotalAssets: this.formattedTotalAssets(membership), + formattedTotalLiabilities: this.formattedTotalLiabilities(membership), }; }; } diff --git a/packages/webapp/src/components/DialogsContainer.tsx b/packages/webapp/src/components/DialogsContainer.tsx index c9a8f8108..a3a065510 100644 --- a/packages/webapp/src/components/DialogsContainer.tsx +++ b/packages/webapp/src/components/DialogsContainer.tsx @@ -50,8 +50,8 @@ import { DisconnectBankAccountDialog } from '@/containers/CashFlow/AccountTransa import { SharePaymentLinkDialog } from '@/containers/PaymentLink/dialogs/SharePaymentLinkDialog/SharePaymentLinkDialog'; import { SelectPaymentMethodsDialog } from '@/containers/PaymentLink/dialogs/SelectPaymentMethodsDialog/SelectPaymentMethodsDialog'; import ApiKeysGenerateDialog from '@/containers/Dialogs/ApiKeysGenerateDialog'; -import WorkspaceDeleteDialog from '@/containers/Dialogs/Workspaces/WorkspaceDeleteDialog'; -import WorkspaceInactivateDialog from '@/containers/Dialogs/Workspaces/WorkspaceInactivateDialog'; +import WorkspaceDeleteDialog from '@/ee/workspaces/containers/Dialogs/WorkspaceDeleteDialog'; +import WorkspaceInactivateDialog from '@/ee/workspaces/containers/Dialogs/WorkspaceInactivateDialog'; import InvoiceBulkDeleteDialog from '@/containers/Dialogs/Invoices/InvoiceBulkDeleteDialog'; import EstimateBulkDeleteDialog from '@/containers/Dialogs/Estimates/EstimateBulkDeleteDialog'; import ReceiptBulkDeleteDialog from '@/containers/Dialogs/Receipts/ReceiptBulkDeleteDialog'; diff --git a/packages/webapp/src/components/DrawersContainer.tsx b/packages/webapp/src/components/DrawersContainer.tsx index b4c1385ff..f9145b6c6 100644 --- a/packages/webapp/src/components/DrawersContainer.tsx +++ b/packages/webapp/src/components/DrawersContainer.tsx @@ -34,8 +34,8 @@ import { InvoiceSendMailDrawer } from '@/containers/Sales/Invoices/InvoiceSendMa import { EstimateSendMailDrawer } from '@/containers/Sales/Estimates/EstimateSendMailDrawer'; import { ReceiptSendMailDrawer } from '@/containers/Sales/Receipts/ReceiptSendMailDrawer'; import { PaymentReceivedSendMailDrawer } from '@/containers/Sales/PaymentsReceived/PaymentReceivedMailDrawer'; -import { CreateWorkspaceDrawer } from '@/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceDrawer'; -import { OrganizationsListDrawer } from '@/containers/Workspaces/OrganizationsListDrawer'; +import { CreateWorkspaceDrawer } from '@/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceDrawer'; +import { OrganizationsListDrawer } from '@/ee/workspaces/containers/OrganizationsListDrawer'; /** * Drawers container of the dashboard. diff --git a/packages/webapp/src/components/index.tsx b/packages/webapp/src/components/index.tsx index 46dd8f3d7..3be16da23 100644 --- a/packages/webapp/src/components/index.tsx +++ b/packages/webapp/src/components/index.tsx @@ -62,6 +62,6 @@ export * from './EmptyStatus'; export * from './Postbox'; export * from './AppToaster'; export * from './Layout'; -export * from './WorkspaceSwitchingOverlay'; +export * from '@/ee/workspaces/components/WorkspaceSwitchingOverlay'; export { MODIFIER, ContextMenu, AvatarCell }; diff --git a/packages/webapp/src/containers/AlertsContainer/registered.tsx b/packages/webapp/src/containers/AlertsContainer/registered.tsx index 343cc0831..7a17e4cde 100644 --- a/packages/webapp/src/containers/AlertsContainer/registered.tsx +++ b/packages/webapp/src/containers/AlertsContainer/registered.tsx @@ -25,7 +25,7 @@ import WarehousesTransfersAlerts from '@/containers/WarehouseTransfers/Warehouse import BranchesAlerts from '@/containers/Preferences/Branches/BranchesAlerts'; import ProjectAlerts from '@/containers/Projects/containers/ProjectAlerts'; import TaxRatesAlerts from '@/containers/TaxRates/alerts'; -import WorkspacesAlerts from '@/containers/Alerts/Workspaces/WorkspacesAlerts'; +import WorkspacesAlerts from '@/ee/workspaces/containers/Alerts/WorkspacesAlerts'; import { CashflowAlerts } from '../CashFlow/CashflowAlerts'; import { BankRulesAlerts } from '../Banking/Rules/RulesList/BankRulesAlerts'; import { SubscriptionAlerts } from '../Subscriptions/alerts/alerts'; diff --git a/packages/webapp/src/containers/Dashboard/Sidebar/SidebarHead.tsx b/packages/webapp/src/containers/Dashboard/Sidebar/SidebarHead.tsx index bbb64755f..a27c313c0 100644 --- a/packages/webapp/src/containers/Dashboard/Sidebar/SidebarHead.tsx +++ b/packages/webapp/src/containers/Dashboard/Sidebar/SidebarHead.tsx @@ -12,9 +12,10 @@ import styled, { x } from '@xstyled/emotion'; import { Icon, FormattedMessage as T } from '@/components'; import { withCurrentOrganization } from '@/containers/Organization/withCurrentOrganization'; -import { useAuthenticatedAccount, useWorkspaces } from '@/hooks/query'; +import { useAuthenticatedAccount } from '@/hooks/query'; +import { useWorkspaces } from '@/ee/workspaces/hooks/query/workspaces'; import { useAuthOrganizationId, useAuthActions } from '@/hooks/state'; -import { useSwitchOrganization } from '@/hooks/useSwitchOrganization'; +import { useSwitchOrganization } from '@/ee/workspaces/hooks/useSwitchOrganization'; import { DRAWERS } from '@/constants/drawers'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { compose, firstLettersArgs } from '@/utils'; diff --git a/packages/webapp/src/components/WorkspaceSwitchingOverlay.tsx b/packages/webapp/src/ee/workspaces/components/WorkspaceSwitchingOverlay.tsx similarity index 92% rename from packages/webapp/src/components/WorkspaceSwitchingOverlay.tsx rename to packages/webapp/src/ee/workspaces/components/WorkspaceSwitchingOverlay.tsx index f22817cc7..721387d34 100644 --- a/packages/webapp/src/components/WorkspaceSwitchingOverlay.tsx +++ b/packages/webapp/src/ee/workspaces/components/WorkspaceSwitchingOverlay.tsx @@ -1,7 +1,7 @@ // @ts-nocheck import React from 'react'; import { firstLettersArgs } from '@/utils'; -import '@/style/components/WorkspaceSwitchingOverlay.scss'; +import '@/ee/workspaces/style/components/WorkspaceSwitchingOverlay.scss'; interface WorkspaceSwitchingOverlayProps { workspaceName: string; diff --git a/packages/webapp/src/containers/Alerts/Workspaces/WorkspacesAlerts.tsx b/packages/webapp/src/ee/workspaces/containers/Alerts/WorkspacesAlerts.tsx similarity index 100% rename from packages/webapp/src/containers/Alerts/Workspaces/WorkspacesAlerts.tsx rename to packages/webapp/src/ee/workspaces/containers/Alerts/WorkspacesAlerts.tsx diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/BuildingWorkspaceStep.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/BuildingWorkspaceStep.tsx similarity index 100% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/BuildingWorkspaceStep.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/BuildingWorkspaceStep.tsx diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceDrawer.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceDrawer.tsx similarity index 100% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceDrawer.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceDrawer.tsx diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceDrawerContent.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceDrawerContent.tsx similarity index 100% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceDrawerContent.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceDrawerContent.tsx diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx similarity index 98% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx index 1b3ea4d39..7f58e63bb 100644 --- a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx +++ b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceForm.tsx @@ -15,7 +15,7 @@ import { } from '@/components'; import { Col, Row } from '@/components'; import { useIsDarkMode } from '@/hooks/useDarkMode'; -import { useCreateWorkspace } from '@/hooks/query'; +import { useCreateWorkspace } from '@/ee/workspaces/hooks/query/workspaces'; import { getFiscalYear } from '@/constants/fiscalYearOptions'; import { getLanguages } from '@/constants/languagesOptions'; import { getAllCurrenciesOptions } from '@/constants/currencies'; diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceStepper.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceStepper.tsx similarity index 100% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/CreateWorkspaceStepper.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/CreateWorkspaceStepper.tsx diff --git a/packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/InviteUsersStep.tsx b/packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/InviteUsersStep.tsx similarity index 100% rename from packages/webapp/src/containers/Workspaces/CreateWorkspaceDrawer/InviteUsersStep.tsx rename to packages/webapp/src/ee/workspaces/containers/CreateWorkspaceDrawer/InviteUsersStep.tsx diff --git a/packages/webapp/src/containers/Dashboard/WorkspacesSidebar/WorkspacesSidebar.tsx b/packages/webapp/src/ee/workspaces/containers/Dashboard/WorkspacesSidebar.tsx similarity index 92% rename from packages/webapp/src/containers/Dashboard/WorkspacesSidebar/WorkspacesSidebar.tsx rename to packages/webapp/src/ee/workspaces/containers/Dashboard/WorkspacesSidebar.tsx index c04b3eb59..69d215098 100644 --- a/packages/webapp/src/containers/Dashboard/WorkspacesSidebar/WorkspacesSidebar.tsx +++ b/packages/webapp/src/ee/workspaces/containers/Dashboard/WorkspacesSidebar.tsx @@ -2,16 +2,16 @@ import React, { useState } from 'react'; import * as R from 'ramda'; import { Tooltip, Position, Spinner, Icon } from '@blueprintjs/core'; -import { useWorkspaces } from '@/hooks/query'; +import { useWorkspaces } from '@/ee/workspaces/hooks/query/workspaces'; import { useAuthOrganizationId } from '@/hooks/state'; -import { useSwitchOrganization } from '@/hooks/useSwitchOrganization'; +import { useSwitchOrganization } from '@/ee/workspaces/hooks/useSwitchOrganization'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { DRAWERS } from '@/constants/drawers'; import { firstLettersArgs } from '@/utils'; -import { WorkspaceSwitchingOverlay } from '@/components'; +import { WorkspaceSwitchingOverlay } from '@/ee/workspaces/components/WorkspaceSwitchingOverlay'; import classNames from 'classnames'; -import '@/style/containers/Dashboard/WorkspacesSidebar.scss'; +import '@/ee/workspaces/style/containers/Dashboard/WorkspacesSidebar.scss'; /** * Single workspace icon button. diff --git a/packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceDeleteDialog.tsx b/packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceDeleteDialog.tsx similarity index 80% rename from packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceDeleteDialog.tsx rename to packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceDeleteDialog.tsx index ac5916ff5..1e9508962 100644 --- a/packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceDeleteDialog.tsx +++ b/packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceDeleteDialog.tsx @@ -3,8 +3,8 @@ import React from 'react'; import { Button, Classes, Dialog, Intent, Callout } from '@blueprintjs/core'; import { FormattedMessage as T, AppToaster } from '@/components'; import intl from 'react-intl-universal'; - -import { useDeleteWorkspace } from '@/hooks/query'; +import { x } from '@xstyled/emotion'; +import { useDeleteWorkspace } from '@/ee/workspaces/hooks/query/workspaces'; import withDialogRedux from '@/components/DialogReduxConnect'; import { withDialogActions } from '@/containers/Dialog/withDialogActions'; import { compose } from '@/utils'; @@ -59,7 +59,7 @@ function WorkspaceDeleteDialog({ >
-

-

+

{intl.get('workspaces.delete_workspace_details', { fallback: 'Deleting this workspace will permanently remove:', })}

-
    -
  • {intl.get('workspaces.delete_workspace_all_data', { fallback: 'All organization data including transactions, accounts, and contacts' })}
  • -
  • {intl.get('workspaces.delete_workspace_all_users', { fallback: 'All user associations and permissions' })}
  • -
  • {intl.get('workspaces.delete_workspace_database', { fallback: 'The entire database for this workspace' })}
  • -
-

+ + + {intl.get('workspaces.delete_workspace_all_data', { fallback: 'All organization data including transactions, accounts, and contacts' })} + {intl.get('workspaces.delete_workspace_all_users', { fallback: 'All user associations and permissions' })} + {intl.get('workspaces.delete_workspace_database', { fallback: 'The entire database for this workspace' })} + + + {intl.get('workspaces.delete_workspace_irreversible', { fallback: 'This action is irreversible. Please make sure you have exported any important data before proceeding.', })} -

-
+
+
@@ -96,9 +98,8 @@ function WorkspaceDeleteDialog({ intent={Intent.DANGER} onClick={handleConfirmDelete} loading={isLoading} - icon="trash" > - + Delete Workspace
diff --git a/packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceInactivateDialog.tsx b/packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceInactivateDialog.tsx similarity index 88% rename from packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceInactivateDialog.tsx rename to packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceInactivateDialog.tsx index e3fc58d0b..84b3dad9b 100644 --- a/packages/webapp/src/containers/Dialogs/Workspaces/WorkspaceInactivateDialog.tsx +++ b/packages/webapp/src/ee/workspaces/containers/Dialogs/WorkspaceInactivateDialog.tsx @@ -3,8 +3,8 @@ import React from 'react'; import { Button, Classes, Dialog, Intent, Callout } from '@blueprintjs/core'; import { FormattedMessage as T, AppToaster } from '@/components'; import intl from 'react-intl-universal'; - -import { useInactivateWorkspace, useActivateWorkspace } from '@/hooks/query'; +import { x } from '@xstyled/emotion'; +import { useInactivateWorkspace, useActivateWorkspace } from '@/ee/workspaces/hooks/query/workspaces'; import withDialogRedux from '@/components/DialogReduxConnect'; import { withDialogActions } from '@/containers/Dialog/withDialogActions'; import { compose } from '@/utils'; @@ -89,7 +89,7 @@ function WorkspaceInactivateDialog({ >
-

{isInactivateAction && ( -

+

{intl.get('workspaces.inactivate_workspace_details', { fallback: 'Inactivating this workspace will:', })}

-
    -
  • {intl.get('workspaces.inactivate_workspace_effect_1', { fallback: 'Prevent all users from signing in' })}
  • -
  • {intl.get('workspaces.inactivate_workspace_effect_2', { fallback: 'Preserve all data and settings' })}
  • -
  • {intl.get('workspaces.inactivate_workspace_effect_3', { fallback: 'Allow reactivation at any time' })}
  • -
-
+ + {intl.get('workspaces.inactivate_workspace_effect_1', { fallback: 'Prevent all users from signing in' })} + {intl.get('workspaces.inactivate_workspace_effect_2', { fallback: 'Preserve all data and settings' })} + {intl.get('workspaces.inactivate_workspace_effect_3', { fallback: 'Allow reactivation at any time' })} + + )}
@@ -123,7 +123,6 @@ function WorkspaceInactivateDialog({ intent={intent} onClick={handleConfirm} loading={isLoading} - icon={isInactivateAction ? 'pause' : 'play'} > {isInactivateAction ? intl.get('workspaces.inactivate_workspace', { fallback: 'Inactivate' }) diff --git a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawer.tsx b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawer.tsx similarity index 76% rename from packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawer.tsx rename to packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawer.tsx index 04a71961e..2220d85c6 100644 --- a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawer.tsx +++ b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawer.tsx @@ -2,10 +2,18 @@ import React from 'react'; import * as R from 'ramda'; import { Position } from '@blueprintjs/core'; +import styled from '@xstyled/emotion'; import { Drawer, DrawerSuspense } from '@/components'; import { withDrawers } from '@/containers/Drawer/withDrawers'; import { OrganizationsListDrawerContent } from './OrganizationsListDrawerContent'; +const OrganizationsDrawer = styled(Drawer)` + &.bp4-drawer.bp4-dark, + .bp4-dark &.bp4-drawer { + background-color: var(--color-dark-gray1); + } +`; + /** * Organizations list drawer. */ @@ -16,7 +24,7 @@ function OrganizationsListDrawerRoot({ payload, }) { return ( - - + ); } diff --git a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx similarity index 96% rename from packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx rename to packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx index f97e88d3f..8a3a1582a 100644 --- a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx +++ b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerContent.tsx @@ -5,14 +5,14 @@ import { debounce } from 'lodash'; import { FormGroup, InputGroup, Button } from '@blueprintjs/core'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { DRAWERS } from '@/constants/drawers'; -import { useWorkspaces } from '@/hooks/query'; +import { useWorkspaces } from '@/ee/workspaces/hooks/query/workspaces'; import OrganizationsListTable from './OrganizationsListTable'; import { OrganizationsListDrawerHeader } from './OrganizationsListDrawerHeader'; import intl from 'react-intl-universal'; import { css } from '@emotion/css'; import { x } from '@xstyled/emotion'; -import '@/style/containers/Workspaces/OrganizationsListDrawer.scss'; +import '@/ee/workspaces/style/containers/Workspaces/OrganizationsListDrawer.scss'; const organizationsDrawerSearchFormGroupCss = css` margin: 0 !important; diff --git a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx similarity index 95% rename from packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx rename to packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx index 6a53ebdac..4ec9816fd 100644 --- a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx +++ b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListDrawerHeader.tsx @@ -5,7 +5,7 @@ import { x } from '@xstyled/emotion'; import { css } from '@emotion/css'; import intl from 'react-intl-universal'; -import '@/style/containers/Workspaces/OrganizationsListDrawer.scss'; +import '@/ee/workspaces/style/containers/Workspaces/OrganizationsListDrawer.scss'; const organizationsSwitchLabelBpCss = css` .bp4-control.bp4-switch { diff --git a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListTable.tsx b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListTable.tsx similarity index 82% rename from packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListTable.tsx rename to packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListTable.tsx index 46fbeee83..961d09721 100644 --- a/packages/webapp/src/containers/Workspaces/OrganizationsListDrawer/OrganizationsListTable.tsx +++ b/packages/webapp/src/ee/workspaces/containers/OrganizationsListDrawer/OrganizationsListTable.tsx @@ -10,31 +10,20 @@ import { Popover, Menu, MenuItem, + MenuDivider, } from '@blueprintjs/core'; import { x } from '@xstyled/emotion'; import styled from '@xstyled/emotion'; import { DataTable, TableSkeletonRows } from '@/components'; -import { useSetDefaultWorkspace } from '@/hooks/query'; +import { useSetDefaultWorkspace } from '@/ee/workspaces/hooks/query/workspaces'; import { useAuthOrganizationId } from '@/hooks/state'; -import { useSwitchOrganization } from '@/hooks/useSwitchOrganization'; +import { useSwitchOrganization } from '@/ee/workspaces/hooks/useSwitchOrganization'; import { compose } from '@/utils'; import { OrganizationsListWorkspaceCell } from './OrganizationsListWorkspaceCell'; -import { WorkspaceSwitchingOverlay } from '@/components'; +import { WorkspaceSwitchingOverlay } from '@/ee/workspaces/components/WorkspaceSwitchingOverlay'; import { withDialogActions } from '@/containers/Dialog/withDialogActions'; import { DialogsName } from '@/constants/dialogs'; -/** - * Format currency for display - */ -function formatCurrency(amount: number): string { - return new Intl.NumberFormat('en-US', { - style: 'currency', - currency: 'USD', - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }).format(amount); -} - /** * Organizations list table component. */ @@ -108,16 +97,16 @@ function OrganizationsListTable({ { id: 'assets', Header: intl.get('workspaces.column_assets', { fallback: 'Assets' }), - accessor: 'assets', - Cell: ({ value }) => formatCurrency(value ?? 1000000), + accessor: 'formattedTotalAssets', + Cell: ({ value }) => value || '-', align: 'right', width: 100, }, { id: 'liabilities', Header: intl.get('workspaces.column_liabilities', { fallback: 'Liabilities' }), - accessor: 'liabilities', - Cell: ({ value }) => formatCurrency(value ?? 1000000), + accessor: 'formattedTotalLiabilities', + Cell: ({ value }) => value || '-', align: 'right', width: 100, }, @@ -128,9 +117,11 @@ function OrganizationsListTable({ disableSortBy: true, Cell: ({ row }) => { const workspace = row.original; + const workspaceName = workspace.metadata?.name || workspace.organizationId; + const isCurrentOrganization = workspace.organizationId === activeOrganizationId; const isDisabled = !workspace.isReady || workspace.isBuildRunning || workspace.isDeleting; const isOwner = workspace.role === 'owner'; - const canSwitch = !isDisabled && workspace.isActive; + const canSwitch = !isCurrentOrganization && !isDisabled && workspace.isActive; const defaultDisabled = !workspace.isReady || workspace.isBuildRunning || !workspace.isActive || workspace.isDefault; const canSetDefaultInMenu = @@ -155,6 +146,7 @@ function OrganizationsListTable({ disabled={isDisabled} onClick={() => !isDisabled && handleInactivateWorkspace(workspace)} /> + } @@ -166,7 +158,21 @@ function OrganizationsListTable({ ) : null; return ( - + + {!isCurrentOrganization && ( + +