feat(webapp): deprecate the subscription from webapp.

This commit is contained in:
a.bouhuolia
2023-03-05 13:21:06 +02:00
parent 0c1bf302e5
commit f26ced97fe
15 changed files with 118 additions and 228 deletions

View File

@@ -14,19 +14,16 @@ import GlobalHotkeys from './GlobalHotkeys';
import DashboardProvider from './DashboardProvider'; import DashboardProvider from './DashboardProvider';
import DrawersContainer from '@/components/DrawersContainer'; import DrawersContainer from '@/components/DrawersContainer';
import AlertsContainer from '@/containers/AlertsContainer'; import AlertsContainer from '@/containers/AlertsContainer';
import EnsureSubscriptionIsActive from '../Guards/EnsureSubscriptionIsActive';
/** /**
* Dashboard preferences. * Dashboard preferences.
*/ */
function DashboardPreferences() { function DashboardPreferences() {
return ( return (
<EnsureSubscriptionIsActive> <DashboardSplitPane>
<DashboardSplitPane> <Sidebar />
<Sidebar /> <PreferencesPage />
<PreferencesPage /> </DashboardSplitPane>
</DashboardSplitPane>
</EnsureSubscriptionIsActive>
); );
} }

View File

@@ -7,26 +7,20 @@ import {
} from '@/hooks/query'; } from '@/hooks/query';
import { useSplashLoading } from '@/hooks/state'; import { useSplashLoading } from '@/hooks/state';
import { useWatch, useWatchImmediate, useWhen } from '@/hooks'; import { useWatch, useWatchImmediate, useWhen } from '@/hooks';
import { useSubscription } from '@/hooks/state';
import { setCookie, getCookie } from '@/utils'; import { setCookie, getCookie } from '@/utils';
/** /**
* Dashboard meta async booting. * Dashboard meta async booting.
* - Fetches the dashboard meta only if the organization subscribe is active. * - Fetches the dashboard meta in booting state.
* - Once the dashboard meta query is loading display dashboard splash screen. * - Once the dashboard meta query started loading display dashboard splash screen.
*/ */
export function useDashboardMetaBoot() { export function useDashboardMetaBoot() {
const { isSubscriptionActive } = useSubscription();
const { const {
data: dashboardMeta, data: dashboardMeta,
isLoading: isDashboardMetaLoading, isLoading: isDashboardMetaLoading,
isSuccess: isDashboardMetaSuccess, isSuccess: isDashboardMetaSuccess,
} = useDashboardMeta({ } = useDashboardMeta({
keepPreviousData: true, keepPreviousData: true,
// Avoid run the query if the organization subscription is not active.
enabled: isSubscriptionActive,
}); });
const [startLoading, stopLoading] = useSplashLoading(); const [startLoading, stopLoading] = useSplashLoading();

View File

@@ -1,5 +1,6 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { useHistory } from 'react-router-dom';
import { import {
CollapsibleList, CollapsibleList,
MenuItem, MenuItem,
@@ -7,29 +8,29 @@ import {
Boundary, Boundary,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import withBreadcrumbs from 'react-router-breadcrumbs-hoc'; import withBreadcrumbs from 'react-router-breadcrumbs-hoc';
import { getDashboardRoutes } from '@/routes/dashboard';
import { useHistory } from 'react-router-dom';
function DashboardBreadcrumbs({ breadcrumbs }){ function DashboardBreadcrumbs({ breadcrumbs }) {
const history = useHistory(); const history = useHistory();
return( return (
<CollapsibleList <CollapsibleList
className={Classes.BREADCRUMBS} className={Classes.BREADCRUMBS}
dropdownTarget={<span className={Classes.BREADCRUMBS_COLLAPSED} />} dropdownTarget={<span className={Classes.BREADCRUMBS_COLLAPSED} />}
collapseFrom={Boundary.START} collapseFrom={Boundary.START}
visibleItemCount={0}> visibleItemCount={0}
{ >
breadcrumbs.map(({ breadcrumb,match })=>{ {breadcrumbs.map(({ breadcrumb, match }) => {
return (<MenuItem return (
key={match.url} <MenuItem
icon={'folder-close'} key={match.url}
text={breadcrumb} icon={'folder-close'}
onClick={() => history.push(match.url) } />) text={breadcrumb}
}) onClick={() => history.push(match.url)}
} />
);
})}
</CollapsibleList> </CollapsibleList>
) );
} }
export default withBreadcrumbs([])(DashboardBreadcrumbs) export default withBreadcrumbs([])(DashboardBreadcrumbs);

View File

@@ -1,7 +1,7 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { ErrorBoundary } from 'react-error-boundary'; import { ErrorBoundary } from 'react-error-boundary';
import DashboardTopbar from '@/components/Dashboard/DashboardTopbar'; import DashboardTopbar from '@/components/Dashboard/DashboardTopbar/DashboardTopbar';
import DashboardContentRoutes from '@/components/Dashboard/DashboardContentRoute'; import DashboardContentRoutes from '@/components/Dashboard/DashboardContentRoute';
import DashboardErrorBoundary from './DashboardErrorBoundary'; import DashboardErrorBoundary from './DashboardErrorBoundary';

View File

@@ -3,15 +3,13 @@ import React from 'react';
import { Route, Switch } from 'react-router-dom'; import { Route, Switch } from 'react-router-dom';
import { getDashboardRoutes } from '@/routes/dashboard'; import { getDashboardRoutes } from '@/routes/dashboard';
import EnsureSubscriptionsIsActive from '../Guards/EnsureSubscriptionsIsActive';
import EnsureSubscriptionsIsInactive from '../Guards/EnsureSubscriptionsIsInactive';
import DashboardPage from './DashboardPage'; import DashboardPage from './DashboardPage';
/** /**
* Dashboard inner route content. * Dashboard inner route content.
*/ */
function DashboardContentRouteContent({ route }) { function DashboardContentRouteContent({ route }) {
const content = ( return (
<DashboardPage <DashboardPage
name={route.name} name={route.name}
Component={route.component} Component={route.component}
@@ -23,21 +21,6 @@ function DashboardContentRouteContent({ route }) {
defaultSearchResource={route.defaultSearchResource} defaultSearchResource={route.defaultSearchResource}
/> />
); );
return route.subscriptionActive ? (
<EnsureSubscriptionsIsInactive
subscriptionTypes={route.subscriptionActive}
children={content}
redirectTo={'/billing'}
/>
) : route.subscriptionInactive ? (
<EnsureSubscriptionsIsActive
subscriptionTypes={route.subscriptionInactive}
children={content}
redirectTo={'/'}
/>
) : (
content
);
} }
/** /**

View File

@@ -10,57 +10,19 @@ import {
Tooltip, Tooltip,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from '@/components'; import { FormattedMessage as T, Icon, Hint, If } from '@/components';
import DashboardTopbarUser from '@/components/Dashboard/TopbarUser'; import DashboardTopbarUser from '@/components/Dashboard/TopbarUser';
import DashboardBreadcrumbs from '@/components/Dashboard/DashboardBreadcrumbs'; import DashboardBreadcrumbs from '@/components/Dashboard/DashboardBreadcrumbs';
import DashboardBackLink from '@/components/Dashboard/DashboardBackLink'; import DashboardBackLink from '@/components/Dashboard/DashboardBackLink';
import { Icon, Hint, If } from '@/components';
import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions'; import withUniversalSearchActions from '@/containers/UniversalSearch/withUniversalSearchActions';
import withDashboardActions from '@/containers/Dashboard/withDashboardActions'; import withDashboardActions from '@/containers/Dashboard/withDashboardActions';
import withDashboard from '@/containers/Dashboard/withDashboard'; import withDashboard from '@/containers/Dashboard/withDashboard';
import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown'; import QuickNewDropdown from '@/containers/QuickNewDropdown/QuickNewDropdown';
import { DashboardHamburgerButton, DashboardQuickSearchButton } from './_components';
import { compose } from '@/utils'; import { compose } from '@/utils';
import withSubscriptions from '@/containers/Subscriptions/withSubscriptions';
import { useGetUniversalSearchTypeOptions } from '@/containers/UniversalSearch/utils';
function DashboardTopbarSubscriptionMessage() {
return (
<div class="dashboard__topbar-subscription-msg">
<span>
<T id={'dashboard.subscription_msg.period_over'} />
</span>
</div>
);
}
function DashboardHamburgerButton({ ...props }) {
return (
<Button minimal={true} {...props}>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
role="img"
focusable="false"
>
<title>
<T id={'menu'} />
</title>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-miterlimit="5"
stroke-width="2"
d="M4 7h15M4 12h15M4 17h15"
></path>
</svg>
</Button>
);
}
/** /**
* Dashboard topbar. * Dashboard topbar.
@@ -79,10 +41,6 @@ function DashboardTopbar({
// #withGlobalSearch // #withGlobalSearch
openGlobalSearch, openGlobalSearch,
// #withSubscriptions
isSubscriptionActive,
isSubscriptionInactive,
}) { }) {
const history = useHistory(); const history = useHistory();
@@ -137,28 +95,22 @@ function DashboardTopbar({
</div> </div>
<div class="dashboard__topbar-right"> <div class="dashboard__topbar-right">
<If condition={isSubscriptionInactive}>
<DashboardTopbarSubscriptionMessage />
</If>
<Navbar class="dashboard__topbar-navbar"> <Navbar class="dashboard__topbar-navbar">
<NavbarGroup> <NavbarGroup>
<If condition={isSubscriptionActive}> <DashboardQuickSearchButton
<DashboardQuickSearchButton onClick={() => openGlobalSearch(true)}
onClick={() => openGlobalSearch(true)} />
/> <QuickNewDropdown />
<QuickNewDropdown />
<Tooltip <Tooltip
content={<T id={'notifications'} />} content={<T id={'notifications'} />}
position={Position.BOTTOM} position={Position.BOTTOM}
> >
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon={'notification-24'} iconSize={20} />} icon={<Icon icon={'notification-24'} iconSize={20} />}
/> />
</Tooltip> </Tooltip>
</If>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}
@@ -186,31 +138,4 @@ export default compose(
pageHint, pageHint,
})), })),
withDashboardActions, withDashboardActions,
withSubscriptions(
({ isSubscriptionActive, isSubscriptionInactive }) => ({
isSubscriptionActive,
isSubscriptionInactive,
}),
'main',
),
)(DashboardTopbar); )(DashboardTopbar);
/**
* Dashboard quick search button.
*/
function DashboardQuickSearchButton({ ...rest }) {
const searchTypeOptions = useGetUniversalSearchTypeOptions();
// Can't continue if there is no any search type option.
if (searchTypeOptions.length <= 0) {
return null;
}
return (
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'search-24'} iconSize={20} />}
text={<T id={'quick_find'} />}
{...rest}
/>
);
}

View File

@@ -0,0 +1,61 @@
// @ts-nocheck
import React from 'react';
import { Button, Classes } from '@blueprintjs/core';
import { useGetUniversalSearchTypeOptions } from '@/containers/UniversalSearch/utils';
import { Icon, FormattedMessage as T } from '@/components';
export function DashboardTopbarSubscriptionMessage() {
return (
<div class="dashboard__topbar-subscription-msg">
<span>
<T id={'dashboard.subscription_msg.period_over'} />
</span>
</div>
);
}
export function DashboardHamburgerButton({ ...props }) {
return (
<Button minimal={true} {...props}>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
role="img"
focusable="false"
>
<title>
<T id={'menu'} />
</title>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-miterlimit="5"
stroke-width="2"
d="M4 7h15M4 12h15M4 17h15"
></path>
</svg>
</Button>
);
}
/**
* Dashboard quick search button.
*/
export function DashboardQuickSearchButton({ ...rest }) {
const searchTypeOptions = useGetUniversalSearchTypeOptions();
// Can't continue if there is no any search type option.
if (searchTypeOptions.length <= 0) {
return null;
}
return (
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'search-24'} iconSize={20} />}
text={<T id={'quick_find'} />}
{...rest}
/>
);
}

View File

@@ -0,0 +1 @@
export * from './DashboardTopbar';

View File

@@ -9,25 +9,21 @@ import {
Popover, Popover,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { If, FormattedMessage as T } from '@/components'; import { FormattedMessage as T } from '@/components';
import { firstLettersArgs } from '@/utils';
import { useAuthActions } from '@/hooks/state'; import { useAuthActions } from '@/hooks/state';
import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDialogActions from '@/containers/Dialog/withDialogActions';
import withSubscriptions from '@/containers/Subscriptions/withSubscriptions';
import { useAuthenticatedAccount } from '@/hooks/query'; import { useAuthenticatedAccount } from '@/hooks/query';
import { compose } from '@/utils'; import { firstLettersArgs, compose } from '@/utils';
/** /**
* Dashboard topbar user. * Dashboard topbar user.
*/ */
function DashboardTopbarUser({ function DashboardTopbarUser({
// #withDialogActions
openDialog, openDialog,
// #withSubscriptions
isSubscriptionActive,
}) { }) {
const history = useHistory(); const history = useHistory();
const { setLogout } = useAuthActions(); const { setLogout } = useAuthActions();
@@ -62,16 +58,14 @@ function DashboardTopbarUser({
} }
/> />
<MenuDivider /> <MenuDivider />
<If condition={isSubscriptionActive}> <MenuItem
<MenuItem text={<T id={'keyboard_shortcuts'} />}
text={<T id={'keyboard_shortcuts'} />} onClick={onKeyboardShortcut}
onClick={onKeyboardShortcut} />
/> <MenuItem
<MenuItem text={<T id={'preferences'} />}
text={<T id={'preferences'} />} onClick={() => history.push('/preferences')}
onClick={() => history.push('/preferences')} />
/>
</If>
<MenuItem text={<T id={'logout'} />} onClick={onClickLogout} /> <MenuItem text={<T id={'logout'} />} onClick={onClickLogout} />
</Menu> </Menu>
} }
@@ -87,8 +81,4 @@ function DashboardTopbarUser({
} }
export default compose( export default compose(
withDialogActions, withDialogActions,
withSubscriptions(
({ isSubscriptionActive }) => ({ isSubscriptionActive }),
'main',
),
)(DashboardTopbarUser); )(DashboardTopbarUser);

View File

@@ -5,7 +5,6 @@ import { Features } from '@/constants/features';
import { import {
ISidebarMenuItemType, ISidebarMenuItemType,
ISidebarMenuOverlayIds, ISidebarMenuOverlayIds,
ISidebarSubscriptionAbility,
} from '@/containers/Dashboard/Sidebar/interfaces'; } from '@/containers/Dashboard/Sidebar/interfaces';
import { import {
ReportsAction, ReportsAction,
@@ -24,9 +23,7 @@ import {
ManualJournalAction, ManualJournalAction,
ExpenseAction, ExpenseAction,
CashflowAction, CashflowAction,
ProjectAction,
PreferencesAbility, PreferencesAbility,
SubscriptionBillingAbility,
} from '@/constants/abilityOption'; } from '@/constants/abilityOption';
export const SidebarMenu = [ export const SidebarMenu = [
@@ -781,19 +778,6 @@ export const SidebarMenu = [
ability: PreferencesAbility.Mutate, ability: PreferencesAbility.Mutate,
}, },
}, },
{
text: <T id={'billing'} />,
href: '/billing',
type: ISidebarMenuItemType.Link,
subscription: [
ISidebarSubscriptionAbility.Expired,
ISidebarSubscriptionAbility.Active,
],
permission: {
subject: AbilitySubject.SubscriptionBilling,
ability: SubscriptionBillingAbility.View,
},
},
], ],
}, },
]; ];

View File

@@ -4,7 +4,6 @@ import { Scrollbar } from 'react-scrollbars-custom';
import classNames from 'classnames'; import classNames from 'classnames';
import withDashboard from '@/containers/Dashboard/withDashboard'; import withDashboard from '@/containers/Dashboard/withDashboard';
import withSubscriptions from '@/containers/Subscriptions/withSubscriptions';
import { useObserveSidebarExpendedBodyclass } from './hooks'; import { useObserveSidebarExpendedBodyclass } from './hooks';
import { compose } from '@/utils'; import { compose } from '@/utils';
@@ -19,9 +18,6 @@ function SidebarContainerJSX({
// #withDashboard // #withDashboard
sidebarExpended, sidebarExpended,
// #withSubscription
isSubscriptionActive,
}) { }) {
const sidebarScrollerRef = React.useRef(); const sidebarScrollerRef = React.useRef();
@@ -51,7 +47,6 @@ function SidebarContainerJSX({
<div <div
className={classNames('sidebar', { className={classNames('sidebar', {
'sidebar--mini-sidebar': !sidebarExpended, 'sidebar--mini-sidebar': !sidebarExpended,
'is-subscription-inactive': !isSubscriptionActive,
})} })}
id="sidebar" id="sidebar"
onMouseLeave={handleSidebarMouseLeave} onMouseLeave={handleSidebarMouseLeave}
@@ -72,8 +67,4 @@ export const SidebarContainer = compose(
withDashboard(({ sidebarExpended }) => ({ withDashboard(({ sidebarExpended }) => ({
sidebarExpended, sidebarExpended,
})), })),
withSubscriptions(
({ isSubscriptionActive }) => ({ isSubscriptionActive }),
'main',
),
)(SidebarContainerJSX); )(SidebarContainerJSX);

View File

@@ -1,14 +1,11 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { Menu } from '@blueprintjs/core'; import { Menu } from '@blueprintjs/core';
import * as R from 'ramda';
import { MenuItem, MenuItemLabel } from '@/components'; import { MenuItem, MenuItemLabel } from '@/components';
import { ISidebarMenuItemType } from '@/containers/Dashboard/Sidebar/interfaces'; import { ISidebarMenuItemType } from '@/containers/Dashboard/Sidebar/interfaces';
import { useIsSidebarMenuItemActive } from './hooks'; import { useIsSidebarMenuItemActive } from './hooks';
import withSubscriptions from '@/containers/Subscriptions/withSubscriptions';
/** /**
* Sidebar menu item. * Sidebar menu item.
* @returns {JSX.Element} * @returns {JSX.Element}
@@ -55,7 +52,7 @@ function SidebarMenuItemComposer({ item, index }) {
* Sidebar menu. * Sidebar menu.
* @returns {JSX.Element} * @returns {JSX.Element}
*/ */
function SidebarMenuJSX({ menu }) { export function SidebarMenu({ menu }) {
return ( return (
<div> <div>
<Menu className="sidebar-menu"> <Menu className="sidebar-menu">
@@ -66,10 +63,3 @@ function SidebarMenuJSX({ menu }) {
</div> </div>
); );
} }
export const SidebarMenu = R.compose(
withSubscriptions(
({ isSubscriptionActive }) => ({ isSubscriptionActive }),
'main',
),
)(SidebarMenuJSX);

View File

@@ -19,7 +19,6 @@ import {
} from './interfaces'; } from './interfaces';
import { filterValuesDeep, deepdash } from '@/utils'; import { filterValuesDeep, deepdash } from '@/utils';
const deepDashConfig = { const deepDashConfig = {
childrenPath: 'children', childrenPath: 'children',
pathFormat: 'array', pathFormat: 'array',
@@ -136,9 +135,7 @@ function useFilterSidebarMenuAbility(menu) {
return deepdash.filterDeep( return deepdash.filterDeep(
menu, menu,
(item) => { (item) => predFeature(item) && predAbility(item),
return predFeature(item) && predAbility(item) && predSubscription(item);
},
deepDashConfig, deepDashConfig,
); );
} }

View File

@@ -4,7 +4,6 @@ import React from 'react';
import SetupDialogs from './SetupDialogs'; import SetupDialogs from './SetupDialogs';
import SetupWizardContent from './SetupWizardContent'; import SetupWizardContent from './SetupWizardContent';
import withSubscriptions from '@/containers/Subscriptions/withSubscriptions';
import withOrganization from '@/containers/Organization/withOrganization'; import withOrganization from '@/containers/Organization/withOrganization';
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization'; import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
import withSetupWizard from '@/store/organizations/withSetupWizard'; import withSetupWizard from '@/store/organizations/withSetupWizard';

View File

@@ -1,23 +0,0 @@
// @ts-nocheck
import LazyLoader from '@/components/LazyLoader';
export default [
{
path: '/register/subscription',
component: LazyLoader({
loader: () => import('@/containers/Authentication/Register/RegisterSubscriptionForm'),
}),
},
{
path: '/register/organization',
component: LazyLoader({
loader: () => import('@/containers/Authentication/Register/RegisterOrganizationForm'),
}),
},
{
path: `/`,
component: LazyLoader({
loader: () => import('@/containers/Authentication/Register/RegisterUserForm'),
}),
},
];