Skip to content

Commit

Permalink
chore(web): Consolidate all web code into a single app (#5716)
Browse files Browse the repository at this point in the history
* chore(web): Consolidate all web code into a single app

- Simplify development experience, simplify imports, fix live reload issues, and reduce package dependencies
- Enforce TS strict mode that wasn't previously enforced in EE code, although tsconfig.json had strict: true.
- Add the necessary Novu license under the apps/web/ee folder

* Update License files
SokratisVidros authored Jun 13, 2024
1 parent c67df9c commit cc23b1e
Showing 407 changed files with 15,850 additions and 2,879 deletions.
3 changes: 3 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -19,3 +19,6 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

This license applies to the entire repo except for subfolders that have their own license file.
In such cases, the license file in the subfolder takes precedence.
16 changes: 8 additions & 8 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@
"@babel/plugin-transform-runtime": "^7.23.2",
"@editorjs/editorjs": "^2.19.3",
"@editorjs/paragraph": "^2.8.0",
"@emotion/css": "^11.10.5",
"@emotion/babel-plugin": "^11.7.2",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
@@ -56,16 +57,20 @@
"@novu/design-system": "workspace:*",
"@novu/notification-center": "workspace:*",
"@novu/novui": "workspace:*",
"@novu/shared": "workspace:*",
"@novu/shared-web": "workspace:*",
"@novu/shared": "workspace:*",
"@rive-app/react-canvas": "^4.8.1",
"@rjsf/core": "^5.17.1",
"@rjsf/validator-ajv8": "^5.17.1",
"@segment/analytics-next": "^1.48.0",
"@sentry/react": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@storybook/addon-docs": "^7.4.2",
"@storybook/theming": "^7.4.2",
"@tanstack/react-query": "^4.20.4",
"@stripe/react-stripe-js": "^2.5.0",
"@stripe/stripe-js": "^2.4.0",
"@tanstack/react-query-devtools": "^4.20.4",
"@tanstack/react-query": "^4.20.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^29.5.0",
@@ -94,7 +99,6 @@
"lodash.set": "^4.3.2",
"monaco-editor": "^0.45.0",
"polished": "^4.1.3",
"react": "^18.3.1",
"react-ace": "^9.4.3",
"react-chartjs-2": "^4.0.1",
"react-color": "^2.19.3",
@@ -114,6 +118,7 @@
"react-syntax-highlighter": "^15.4.3",
"react-table": "^7.8.0",
"react-use-intercom": "^2.0.0",
"react": "^18.3.1",
"rimraf": "^3.0.2",
"slugify": "^1.4.6",
"storybook-dark-mode": "^3.0.1",
@@ -125,11 +130,6 @@
"highlight.js": "11.9.0",
"mdx-bundler": "10.0.2"
},
"optionalDependencies": {
"@novu/ee-billing-web": "workspace:*",
"@novu/ee-echo-web": "workspace:*",
"@novu/ee-translation-web": "workspace:*"
},
"devDependencies": {
"@babel/polyfill": "^7.12.1",
"@babel/preset-env": "^7.23.2",
10 changes: 2 additions & 8 deletions apps/web/src/components/layout/components/FreeTrialBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { IS_DOCKER_HOSTED } from '@novu/shared-web';
import { FreeTrialBanner as Component } from '../../../ee/billing';

export function FreeTrialBanner() {
if (IS_DOCKER_HOSTED) {
return null;
}

try {
const module = require('@novu/ee-billing-web');
const Component = module.FreeTrialBanner;

return <Component />;
} catch (e) {}

return null;
return <Component />;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { IS_DOCKER_HOSTED } from '@novu/shared-web';
import { FreeTrialSidebarWidget as Component } from '../../../ee/billing';

export const FreeTrialSidebarWidget = () => {
if (IS_DOCKER_HOSTED) {
return null;
}

try {
const module = require('@novu/ee-billing-web');
const Component = module.FreeTrialSidebarWidget;

return <Component />;
} catch (e) {}

return null;
return <Component />;
};
12 changes: 3 additions & 9 deletions apps/web/src/components/layout/components/UpgradePlanBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import { IS_DOCKER_HOSTED } from '@novu/shared-web';
import { FC } from 'react';
import { IS_DOCKER_HOSTED } from '@novu/shared-web';
import { UpgradePlanBanner as Component } from '../../../ee/billing';

export function UpgradePlanBanner({ FeatureActivatedBanner }: { FeatureActivatedBanner: FC }) {
if (IS_DOCKER_HOSTED) {
return null;
}

try {
const module = require('@novu/ee-billing-web');
const Component = module.UpgradePlanBanner;

return <Component FeatureActivatedBanner={FeatureActivatedBanner} />;
} catch (e) {}

return null;
return <Component FeatureActivatedBanner={FeatureActivatedBanner} />;
}
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ export const FlagIcon = ({ locale }) => {
}

try {
const module = require('@novu/ee-translation-web');
const module = require('../../../../ee/translations');

return module.FlagIcon({ locale });
} catch (e) {}
Original file line number Diff line number Diff line change
@@ -912,7 +912,7 @@ export const AndroidKeyboard = ({ isDarkMode, ...rest }: AndroidKeyboardProps) =
d="M74.76 13.5a2.967 2.967 0 0 0-2.974 2.975v11.05A2.967 2.967 0 0 0 74.76 30.5h8.925l5.1-5.1v-8.925A2.967 2.967 0 0 0 85.81 13.5H74.76Zm.213 1.7h10.625a1.487 1.487 0 0 1 1.488 1.488v7.862H85.81a2.967 2.967 0 0 0-2.975 2.975V28.8h-7.863a1.487 1.487 0 0 1-1.487-1.488V16.688a1.488 1.488 0 0 1 1.487-1.487Zm7.387 2.355a1.56 1.56 0 0 0-.4.05c-.799.221-1.25 1.037-1.045 1.845.042.128.102.255.178.374l2.746-.748c0-.145-.017-.289-.051-.434a1.492 1.492 0 0 0-1.428-1.087Zm-5.33 1.47c-.144 0-.272 0-.4.043a1.497 1.497 0 0 0-1.045 1.827c.026.136.102.255.179.391l2.745-.748a1.462 1.462 0 0 0-1.479-1.513Zm7.268 2.346-7.76 2.134a4.476 4.476 0 0 0 4.555 1.393 4.482 4.482 0 0 0 3.205-3.527Z"
opacity=".4"
/>
<g clip-path="url(#b)" opacity=".4">
<g clipPath="url(#b)" opacity=".4">
<path
fill="#5D5E5F"
d="M132.714 17h2.572v10h-2.572V17Zm-4.285 0h-5.143a1.693 1.693 0 0 0-1.714 1.667v6.666c0 .834.685 1.667 1.714 1.667h5.143a1.694 1.694 0 0 0 1.714-1.667V22h-2.571v2.5h-3.429v-5h6v-.833c0-.834-.686-1.667-1.714-1.667Zm17.143 2.5V17h-7.715v10h2.572v-3.333h3.428v-2.5h-3.428V19.5h5.143Z"
25 changes: 25 additions & 0 deletions apps/web/src/ee/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Novu Proprietary Software License

IMPORTANT – READ CAREFULLY: This License Agreement ("Agreement") is a legal agreement between you (either an individual or a single entity) and Novu Corporation ("Novu") for the software product identified below, which includes computer software and associated media, printed materials, and "online" or electronic documentation (collectively, the "Software").

By installing, copying, or otherwise using these files, you agree to be bound by the terms of this Agreement.
If you do not agree to the terms of this Agreement, do not install or use the Software.

Grant of License: Subject to the terms of this Agreement, Novu hereby grants you a non-exclusive, non-transferable license to use the Software solely for your internal operations.
You may not rent, lease, lend, sell, redistribute, sublicense or provide commercial hosting services with the Software.

- Use Restrictions: Use of the Software is conditional upon your compliance with the terms set forth below:
- Approval Required: You may not use the Software without obtaining prior written approval from Novu. To request approval, you must contact Novu at [contact information].
- No Modification: You may not modify, adapt, or translate the Software. You may not reverse engineer, decompile, disassemble, or otherwise attempt to discover the source code of the Software, except to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.

Intellectual Property Rights: The Software is the property of Novu and is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The Software is licensed, not sold.

Termination: This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically without notice from Novu if you fail to comply with any of the terms and conditions of this Agreement. Upon termination, you must cease all use of the Software and destroy all copies, full or partial, of the Software.

No Warranties: Novu expressly disclaims any warranty for the Software. The Software is provided 'As Is' without any express or implied warranty of any kind, including but not limited to any warranties of merchantability, noninfringement, or fitness for a particular purpose. Novu does not warrant or assume responsibility for the accuracy or completeness of any information, text, graphics, links, or other items contained within the Software.

Limitation of Liability: In no event shall Novu be liable for any damages whatsoever (including, without limitation, damages for loss of profits, business interruption, loss of information, or any other pecuniary loss) arising out of the use of or inability to use this Software, even if Novu has been advised of the possibility of such damages.

By installing, copying, or otherwise using the Software, you acknowledge that you have read this Agreement, understand it, and agree to be bound by its terms and conditions.

You also agree that this Agreement is the complete and exclusive statement of agreement between the parties and supersedes all proposals or prior agreements, oral or written, and any other communications between the parties relating to the subject matter of this Agreement.
60 changes: 60 additions & 0 deletions apps/web/src/ee/billing/components/BillingIntervalControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Box, SegmentedControl, useMantineTheme } from '@mantine/core';
import { colors, getGradient, shadows } from '@novu/design-system';
import React from 'react';

export const BillingIntervalControl = ({
onChange,
value,
}: {
onChange: (value: 'month' | 'year') => void;
value: 'month' | 'year';
}) => {
const { colorScheme, ...theme } = useMantineTheme();
const isDark = colorScheme === 'dark';

return (
<SegmentedControl
data-test-id="billing-interval-control"
value={value}
data={[
{
label: <Box data-test-id="billing-interval-control-monthly">Monthly</Box>,
value: 'month',
},
{
label: (
<Box data-test-id="billing-interval-control-annually">
Annually<span style={{ marginLeft: 4, color: colors.success }}>10% off</span>
</Box>
),
value: 'year',
},
]}
onChange={(changeValue) => onChange(changeValue as 'month' | 'year')}
radius="xl"
styles={{
root: {
width: '100%',
background: isDark ? theme.colors.dark[7] : theme.white,
padding: '5px',
boxShadow: isDark ? shadows.dark : shadows.light,
},
active: {
background: `${isDark ? getGradient(colors.B20) : getGradient(colors.white)} padding-box, ${
colors.horizontal
} border-box`,
border: '2px solid transparent',
},
label: {
fontSize: '14px',
fontWeight: 700,
padding: `10px 8px`,
color: theme.colors.gray[8],
},
labelActive: {
color: isDark ? theme.white : theme.colors.gray[8],
},
}}
/>
);
};
25 changes: 25 additions & 0 deletions apps/web/src/ee/billing/components/ContactSalesButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { colors, Text } from '@novu/design-system';
import { Group, useMantineTheme } from '@mantine/core';

export const ContactSalesButton = ({ onContactSales, label }: { onContactSales: () => void; label?: string }) => {
const { colorScheme } = useMantineTheme();
const isDark = colorScheme === 'dark';
const salesLabel = label || 'Contact sales';

return (
<Group position="center" spacing={4}>
<Text color={isDark ? colors.B60 : colors.B40}>Questions?</Text>
<Text gradient>
<a
onClick={onContactSales}
style={{
cursor: 'pointer',
}}
>
{salesLabel}
</a>
</Text>
</Group>
);
};
57 changes: 57 additions & 0 deletions apps/web/src/ee/billing/components/ContactSalesModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import { Modal, Title, successMessage } from '@novu/design-system';
import { HubspotForm } from './HubspotForm';
import { HUBSPOT_FORM_IDS } from '../utils/hubspot.constants';
import { useAuth } from '@novu/shared-web';
import { ApiServiceLevelEnum } from '@novu/shared';

type ContactSalesModalProps = {
isOpen: boolean;
onClose: () => void;
intendedApiServiceLevel: ApiServiceLevelEnum;
};

export const ContactSalesModal = ({ isOpen, onClose, intendedApiServiceLevel }: ContactSalesModalProps) => {
const { currentUser, currentOrganization } = useAuth();
if (!isOpen) {
return null;
}

return (
<Modal
styles={{
body: {
paddingTop: '0px !important',
},
modal: {
width: 840,
},
}}
padding={40}
withCloseButton={false}
size="xl"
opened={isOpen}
title={undefined}
onClose={onClose}
>
<Title mb={8}>Contact sales</Title>
<HubspotForm
formId={HUBSPOT_FORM_IDS.UPGRADE_CONTACT_SALES}
properties={{
firstname: currentUser.firstName || '',
lastname: currentUser.lastName || '',
email: currentUser.email || '',
app_organizationid: currentOrganization._id,
'TICKET.subject': `Contact Sales - ${intendedApiServiceLevel}`,
'TICKET.content': '',
}}
readonlyProperties={['email']}
focussedProperty="TICKET.content"
onFormSubmitted={() => {
successMessage('Thank you for contacting us! We will be in touch soon.');
onClose();
}}
/>
</Modal>
);
};
Loading

0 comments on commit cc23b1e

Please sign in to comment.