Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Delete subscriber channel preference when updating global channel #6767

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5e77371
refactor(preferences): enhance validation and structure
rifont Oct 23, 2024
cda73b9
refactor(preferences): remove default values from schema
rifont Oct 23, 2024
856a947
fix(sync): handle undefined workflow preferences
rifont Oct 24, 2024
22346b8
refactor(base.command): improve error mapping logic
rifont Oct 24, 2024
18523d5
refactor(upsert-preferences): remove unused import
rifont Oct 24, 2024
8ba826f
refactor(sync): extract getWorkflowPreferences method
rifont Oct 24, 2024
eaf6080
refactor(inbox): rename GetPreferences to GetInboxPreferences
rifont Oct 24, 2024
3e3ff65
refactor(inbox): rename GetPreferences to GetInboxPreferences
rifont Oct 24, 2024
f5c8d98
refactor(upsert-preferences): simplify preferences handling
rifont Oct 24, 2024
0c41453
`feat(preferences): add unset logic for channel types`
rifont Oct 24, 2024
150e302
refactor(preferences): simplify channel handling
rifont Oct 24, 2024
6a66a12
refactor(sync): update WorkflowPreferences type usage
rifont Oct 24, 2024
5d99857
refactor(inbox): simplify preference retrieval logic
rifont Oct 24, 2024
0fa489a
refactor(preference): simplify global preference logic
rifont Oct 24, 2024
86b5bc6
refactor(get-subscriber): improve preference handling
rifont Oct 24, 2024
56f0d09
refactor(workflows): add default workflow preferences
rifont Oct 24, 2024
70f22b6
refactor(preferences): update storePreferences method
rifont Oct 24, 2024
7aab8b7
refactor(preferences): extract method for clarity
rifont Oct 24, 2024
49b8683
refactor(subscriber): merge fetch and get methods
rifont Oct 24, 2024
a4d5c47
fix: correct enabled flag in preference return object
rifont Oct 24, 2024
1739863
fix: handle undefined enabled property safely
rifont Oct 24, 2024
ae7a520
fix(preference): default enable to true if undefined
rifont Oct 24, 2024
b1abd25
test(get-inbox-preferences): revise test structure
rifont Oct 24, 2024
26c0ffc
test(update-preferences): remove unused channel fields
rifont Oct 24, 2024
4d7479d
test(inbox): update preferences e2e test logic
rifont Oct 24, 2024
a51539c
refactor(get-subscriber-preference): rename variable
rifont Oct 24, 2024
85addb9
refactor(get-preferences): simplify preference mapping
rifont Oct 24, 2024
73fe8bf
feat(upsert-preferences): enhance preferences handling
rifont Oct 24, 2024
7177ae2
refactor(get-preferences): use partial preferences type
rifont Oct 24, 2024
a5ce239
test(inbox): update e2e test for preferences
rifont Oct 24, 2024
8ca830f
refactor(get-preferences): improve preference mapping logic
rifont Oct 24, 2024
3c09ccc
refactor(update-preferences): reorganize preference logic
rifont Oct 24, 2024
c783e5d
test(inbox): add test for updating preferences
rifont Oct 24, 2024
32f7ec6
refactor(upsert-preferences): rename method for clarity
rifont Oct 25, 2024
093365d
refactor: rename method for clarity
rifont Oct 25, 2024
26891fc
refactor(upsert-preferences): simplify update query
rifont Oct 26, 2024
6afe9da
refactor(preferences): use WorkflowPreferencesPartial type
rifont Oct 26, 2024
4b54490
ci(setup-project): update MongoDB to v5.0.29
rifont Oct 26, 2024
a5c0b9b
ci(setup-project): update MongoDB version and action tag
rifont Oct 26, 2024
2ee421d
ci: Update MongoDB version in setup action
rifont Oct 26, 2024
e383ae2
style: Adjust div height in preferences page
rifont Oct 26, 2024
09107f8
refactor(get-preferences): update preferences handling
rifont Oct 27, 2024
33c0d8e
refactor(get-preferences): update source type definitions
rifont Oct 27, 2024
a53724a
refactor(preferences): add caching to preference update
rifont Oct 28, 2024
2137bc3
test: simplify global preference channel assertions
rifont Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 61 additions & 6 deletions packages/js/src/preferences/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { InboxService } from '../api';
import type { NovuEventEmitter } from '../event-emitter';
import type { Result } from '../types';
import type { ChannelPreference, Result } from '../types';
import { ChannelType, PreferenceLevel } from '../types';
import { Preference } from './preference';
import type { UpdatePreferencesArgs } from './types';
import { NovuError } from '../utils/errors';
import { PreferencesCache } from '../cache/preferences-cache';

type UpdatePreferenceParams = {
emitter: NovuEventEmitter;
apiService: InboxService;
cache: PreferencesCache;
useCache: boolean;
args: UpdatePreferencesArgs;
};

export const updatePreference = async ({
emitter,
apiService,
cache,
useCache,
args,
}: {
emitter: NovuEventEmitter;
apiService: InboxService;
args: UpdatePreferencesArgs;
}): Result<Preference> => {
}: UpdatePreferenceParams): Result<Preference> => {
const { workflowId, channelPreferences } = args;
try {
emitter.emit('preference.update.pending', {
Expand All @@ -30,6 +38,8 @@ export const updatePreference = async ({
{
emitterInstance: emitter,
inboxServiceInstance: apiService,
cache,
useCache,
}
)
: undefined,
Expand All @@ -39,12 +49,15 @@ export const updatePreference = async ({
if (workflowId) {
response = await apiService.updateWorkflowPreferences({ workflowId, channelPreferences });
} else {
optimisticUpdateWorkflowPreferences({ emitter, apiService, cache, useCache, args });
response = await apiService.updateGlobalPreferences(channelPreferences);
}

const preference = new Preference(response, {
emitterInstance: emitter,
inboxServiceInstance: apiService,
cache,
useCache,
});
emitter.emit('preference.update.resolved', { args, data: preference });

Expand All @@ -55,3 +68,45 @@ export const updatePreference = async ({
return { error: new NovuError('Failed to fetch notifications', error) };
}
};

const optimisticUpdateWorkflowPreferences = ({
emitter,
apiService,
cache,
useCache,
args,
}: UpdatePreferenceParams): void => {
const allPreferences = useCache ? cache?.getAll({}) : undefined;

allPreferences?.forEach((el) => {
if (el.level === PreferenceLevel.TEMPLATE) {
const mergedPreference = {
...el,
channels: Object.entries(el.channels).reduce((acc, [key, value]) => {
const channelType = key as ChannelType;
acc[channelType] = args.channelPreferences[channelType] ?? value;

return acc;
}, {} as ChannelPreference),
};
const updatedPreference = args.preference
? new Preference(mergedPreference, {
emitterInstance: emitter,
inboxServiceInstance: apiService,
cache,
useCache,
})
: undefined;

if (updatedPreference) {
emitter.emit('preference.update.pending', {
args: {
workflowId: el.workflow?.id,
channelPreferences: updatedPreference.channels,
},
data: updatedPreference,
});
}
}
});
};
20 changes: 18 additions & 2 deletions packages/js/src/preferences/preference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { InboxService } from '../api';
import { NovuEventEmitter } from '../event-emitter';
import { ChannelPreference, PreferenceLevel, Result, Workflow } from '../types';
import { updatePreference } from './helpers';
import { PreferencesCache } from '../cache/preferences-cache';

type PreferenceLike = Pick<Preference, 'level' | 'enabled' | 'channels' | 'workflow'>;

export class Preference {
#emitter: NovuEventEmitter;
#apiService: InboxService;
#cache: PreferencesCache;
#useCache: boolean;

readonly level: PreferenceLevel;
readonly enabled: boolean;
Expand All @@ -17,11 +20,22 @@ export class Preference {

constructor(
preference: PreferenceLike,
{ emitterInstance, inboxServiceInstance }: { emitterInstance: NovuEventEmitter; inboxServiceInstance: InboxService }
{
emitterInstance,
inboxServiceInstance,
cache,
useCache,
}: {
emitterInstance: NovuEventEmitter;
inboxServiceInstance: InboxService;
cache: PreferencesCache;
useCache: boolean;
}
) {
this.#emitter = emitterInstance;
this.#apiService = inboxServiceInstance;

this.#cache = cache;
this.#useCache = useCache;
this.level = preference.level;
this.enabled = preference.enabled;
this.channels = preference.channels;
Expand All @@ -32,6 +46,8 @@ export class Preference {
return updatePreference({
emitter: this.#emitter,
apiService: this.#apiService,
cache: this.#cache,
useCache: this.#useCache,
args: {
workflowId: this.workflow?.id,
channelPreferences,
Expand Down
8 changes: 2 additions & 6 deletions packages/js/src/preferences/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class Preferences extends BaseModule {
new Preference(el, {
emitterInstance: this._emitter,
inboxServiceInstance: this._inboxService,
cache: this.cache,
useCache: this.#useCache,
})
);

Expand All @@ -62,10 +64,4 @@ export class Preferences extends BaseModule {
}
});
}

async update(args: UpdatePreferencesArgs): Result<Preference> {
return this.callWithSession(async () =>
updatePreference({ emitter: this._emitter, apiService: this._inboxService, args })
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This update method on the full Preferences resource was never used, so I'm deleting it.

}
Loading