Skip to content

Commit 8e10051

Browse files
Merge branch 'next' into self-hosted-auth
2 parents 14a245e + 94c9c83 commit 8e10051

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2432
-3223
lines changed

apps/api/src/app/inbox/usecases/notifications-count/notifications-count.spec.ts

+34-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ describe('NotificationsCount', () => {
1515
let notificationsCount: NotificationsCount;
1616
let messageRepository: sinon.SinonStubbedInstance<MessageRepository>;
1717
let subscriberRepository: sinon.SinonStubbedInstance<SubscriberRepository>;
18-
let organizationRepository: sinon.SinonStubbedInstance<OrganizationRepository>;
1918

2019
beforeEach(() => {
2120
messageRepository = sinon.createStubInstance(MessageRepository);
@@ -177,6 +176,40 @@ describe('NotificationsCount', () => {
177176
)
178177
).to.be.true;
179178

179+
await notificationsCount.execute({
180+
organizationId: 'organizationId',
181+
environmentId,
182+
subscriberId: 'subscriber-id',
183+
filters: [{ snoozed: true }],
184+
});
185+
186+
expect(
187+
messageRepository.getCount.calledWith(
188+
environmentId,
189+
subscriber._id,
190+
ChannelTypeEnum.IN_APP,
191+
{ snoozed: true },
192+
{ limit: 99 }
193+
)
194+
).to.be.true;
195+
196+
await notificationsCount.execute({
197+
organizationId: 'organizationId',
198+
environmentId,
199+
subscriberId: 'subscriber-id',
200+
filters: [{ snoozed: false }],
201+
});
202+
203+
expect(
204+
messageRepository.getCount.calledWith(
205+
environmentId,
206+
subscriber._id,
207+
ChannelTypeEnum.IN_APP,
208+
{ snoozed: false },
209+
{ limit: 99 }
210+
)
211+
).to.be.true;
212+
180213
await notificationsCount.execute({
181214
organizationId: 'organizationId',
182215
environmentId,

apps/dashboard/src/components/integrations/components/integration-card.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ function InAppPremiumFeaturesIcon() {
158158
<TooltipContent>
159159
<div className="flex flex-col gap-2">
160160
<div>
161-
Upgrade to remove the 'Inbox by Novu' badge and enable notification reminders in your{' '}
161+
Upgrade to remove the 'Inbox by Novu' badge and extend notification snooze beyond 24 hours in your{' '}
162162
<span className="font-mono">{`<Inbox />`}</span> component.
163163
</div>
164164
<button onClick={handleUpgradeClick} className="flex items-center gap-1 text-xs font-medium hover:underline">

apps/dashboard/src/components/integrations/components/integration-general-settings.tsx

+1-84
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ import { Input } from '@/components/primitives/input';
44
import { Popover, PopoverContent, PopoverTrigger } from '@/components/primitives/popover';
55
import { Separator } from '@/components/primitives/separator';
66
import { Switch } from '@/components/primitives/switch';
7-
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/primitives/tooltip';
8-
import { useFeatureFlag } from '@/hooks/use-feature-flag';
97
import { useFetchSubscription } from '@/hooks/use-fetch-subscription';
108
import { ROUTES } from '@/utils/routes';
11-
import { ApiServiceLevelEnum, FeatureFlagsKeysEnum } from '@novu/shared';
9+
import { ApiServiceLevelEnum } from '@novu/shared';
1210
import { Control } from 'react-hook-form';
1311
import { useNavigate } from 'react-router-dom';
1412
import { IS_SELF_HOSTED, SELF_HOSTED_UPGRADE_REDIRECT_URL } from '../../../config';
@@ -23,7 +21,6 @@ type IntegrationFormData = {
2321
primary: boolean;
2422
environmentId: string;
2523
removeNovuBranding?: boolean;
26-
enableSnooze?: boolean;
2724
};
2825

2926
type GeneralSettingsProps = {
@@ -34,62 +31,6 @@ type GeneralSettingsProps = {
3431
isForInAppStep?: boolean;
3532
};
3633

37-
/**
38-
* This switch doesn't actually set any value, it serves as an indicator
39-
* informing if the feature is enabled or not.
40-
*/
41-
function EnableSnoozeSwitch({ id }: { id: string }) {
42-
const { subscription, isLoading } = useFetchSubscription();
43-
const navigate = useNavigate();
44-
const isFreePlan = subscription?.apiServiceLevel === ApiServiceLevelEnum.FREE;
45-
const disabled = isFreePlan || IS_SELF_HOSTED || isLoading;
46-
const checked = disabled ? false : true; // Always checked for paid plans
47-
48-
const popoverContent = IS_SELF_HOSTED
49-
? 'Enable "Remind me later" functionality by upgrading to Cloud plans'
50-
: 'Enable "Remind me later" functionality by upgrading to our paid plans';
51-
52-
const handleLinkClick = () => {
53-
if (IS_SELF_HOSTED) {
54-
openInNewTab(SELF_HOSTED_UPGRADE_REDIRECT_URL + '?utm_campaign=enable_snooze_prompt');
55-
} else {
56-
navigate(ROUTES.SETTINGS_BILLING + '?utm_source=enable_snooze_prompt');
57-
}
58-
};
59-
60-
return (
61-
<div className="flex items-center">
62-
{isFreePlan || IS_SELF_HOSTED ? (
63-
<Popover modal>
64-
<PopoverTrigger asChild>
65-
<Switch id={id} checked={checked} />
66-
</PopoverTrigger>
67-
<PopoverContent className="w-72" align="end" sideOffset={4}>
68-
<div className="flex flex-col gap-2 p-1">
69-
<div className="flex flex-col gap-1">
70-
<h4 className="text-xs font-semibold">Premium Feature</h4>
71-
<p className="text-muted-foreground text-xs">{popoverContent}</p>
72-
</div>
73-
<div className="flex justify-end">
74-
<LinkButton size="sm" variant="primary" onClick={handleLinkClick}>
75-
Upgrade Plan
76-
</LinkButton>
77-
</div>
78-
</div>
79-
</PopoverContent>
80-
</Popover>
81-
) : (
82-
<Tooltip>
83-
<TooltipTrigger asChild>
84-
<Switch id={id} checked={true} disabled={true} />
85-
</TooltipTrigger>
86-
<TooltipContent>This feature is automatically enabled with your plan and stays active.</TooltipContent>
87-
</Tooltip>
88-
)}
89-
</div>
90-
);
91-
}
92-
9334
function NovuBrandingSwitch({
9435
id,
9536
value,
@@ -153,8 +94,6 @@ export function GeneralSettings({
15394
disabledPrimary,
15495
isForInAppStep,
15596
}: GeneralSettingsProps) {
156-
const isSnoozeEnabled = useFeatureFlag(FeatureFlagsKeysEnum.IS_SNOOZE_ENABLED);
157-
15897
return (
15998
<div className="border-neutral-alpha-200 bg-background text-foreground-600 mx-0 mt-0 flex flex-col gap-2 rounded-lg border p-3">
16099
<FormField
@@ -197,28 +136,6 @@ export function GeneralSettings({
197136
);
198137
}}
199138
/>
200-
{isSnoozeEnabled && (
201-
<FormField
202-
control={control}
203-
name="enableSnooze"
204-
render={() => {
205-
return (
206-
<FormItem className="flex items-center justify-between gap-2">
207-
<FormLabel
208-
className="text-xs"
209-
htmlFor="enableSnooze"
210-
tooltip="Enables users to postpone notifications and get reminded at a later time"
211-
>
212-
Enable "Remind me later" functionality
213-
</FormLabel>
214-
<FormControl>
215-
<EnableSnoozeSwitch id="enableSnooze" />
216-
</FormControl>
217-
</FormItem>
218-
);
219-
}}
220-
/>
221-
)}
222139
</>
223140
)}
224141

libs/dal/src/repositories/message/message.repository.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ export class MessageRepository extends BaseRepository<MessageDBModel, MessageEnt
9696
}
9797

9898
if (query.snoozed != null) {
99-
requestQuery.snoozedUntil = { $exists: true, $ne: null };
100-
} else {
101-
requestQuery.snoozedUntil = { $exists: false };
99+
if (query.snoozed) {
100+
requestQuery.snoozedUntil = { $ne: null };
101+
} else {
102+
requestQuery.$or = [{ snoozedUntil: { $exists: false } }, { snoozedUntil: null }];
103+
}
102104
}
103105

104106
if (createdAt != null) {

packages/js/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"build": "pnpm run clean && NODE_ENV=production tsup",
7373
"postbuild": "rm ./src/ui/index.directcss && ./scripts/copy-package-json.sh && node scripts/size-limit.mjs && pnpm run check-exports",
7474
"build:umd": "webpack --config webpack.config.cjs",
75-
"build:watch": "concurrently \"NODE_ENV=development pnpm run tsup:watch\" \"pnpm run start:server\"",
75+
"build:watch": "concurrently \"pnpm run prebuild\" \"NODE_ENV=development pnpm run tsup:watch\" \"pnpm run start:server\"",
7676
"tsup:watch": "tsup --watch",
7777
"check-exports": "attw --pack .",
7878
"lint": "eslint src",
@@ -132,7 +132,7 @@
132132
"mitt": "^3.0.1",
133133
"socket.io-client": "4.7.2",
134134
"solid-floating-ui": "^0.3.1",
135-
"solid-js": "^1.8.11",
135+
"solid-js": "^1.9.4",
136136
"solid-motionone": "^1.0.3",
137137
"tailwind-merge": "^2.4.0"
138138
},

packages/js/src/ui/components/Inbox.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { useInboxContext } from '../context';
44
import { useStyle } from '../helpers';
55
import type {
66
BellRenderer,
7+
BodyRenderer,
78
NotificationActionClickHandler,
89
NotificationClickHandler,
910
NotificationRenderer,
1011
SubjectRenderer,
11-
BodyRenderer,
1212
} from '../types';
1313
import { Bell, Footer, Header, Preferences } from './elements';
1414
import { PreferencesHeader } from './elements/Preferences/PreferencesHeader';

packages/js/src/ui/components/InboxTabs/InboxTabs.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import { useTabsDropdown } from '../../helpers/useTabsDropdown';
66
import { Check } from '../../icons';
77
import { ArrowDown } from '../../icons/ArrowDown';
88
import {
9+
BodyRenderer,
910
NotificationActionClickHandler,
1011
NotificationClickHandler,
1112
NotificationRenderer,
1213
NotificationStatus,
1314
SubjectRenderer,
14-
BodyRenderer,
1515
Tab,
1616
} from '../../types';
1717
import { NotificationList } from '../Notification';

0 commit comments

Comments
 (0)