Skip to content
Snippets Groups Projects
Unverified Commit 53cf083f authored by Nemanja Glumac's avatar Nemanja Glumac Committed by GitHub
Browse files

Re-wire the `Pulses` entity to use RTK Query under the hood (#41775)

* Throw on `Pulse.api.delete`

* Add boilerplate `subscriptionApi`

* Add `unsubscribe` endpoint

* Add types

* Delete unused `Pulses.objectActions`

* Re-wire `Pulses` entity to use RTK Query for `objectActions`

* Re-wire `Pulses.api` to use RTK Query under the hood

* Add cache invalidation

* Fix `setArchived` objectAction

* Update DELETE response type

* Fix `params`
parent cac42f21
No related merge requests found
......@@ -33,6 +33,7 @@ export * from "./setup";
export * from "./slack";
export * from "./snippets";
export * from "./store";
export * from "./subscription";
export * from "./table";
export * from "./task";
export * from "./timeline";
......
import type { Card } from "./card";
import type { RegularCollectionId } from "./collection";
import type { DashboardId } from "./dashboard";
import type { Channel } from "./notifications";
import type { Parameter } from "./parameters";
import type { User } from "./user";
export interface ListSubscriptionsRequest {
archived?: boolean;
dashboard_id?: DashboardId;
creator_or_recipient?: boolean;
}
export interface DashboardSubscription {
archived: boolean;
cards: Card[];
channels: Channel[];
collection_id: RegularCollectionId | null;
collection_position: number | null;
created_at: string;
creator: User;
creator_id: number;
dashboard_id: DashboardId;
entity_id: string;
id: number;
name: string;
parameters: Parameter[];
skip_if_empty: boolean;
updated_at: string;
}
export interface CreateSubscriptionRequest {
name: string;
cards: Card[];
channels: Channel[];
skip_if_empty?: boolean;
collection_id?: RegularCollectionId | null;
collection_position?: number | null;
dashboard_id?: DashboardId;
parameters?: Parameter[];
}
export interface UpdateSubscriptionRequest {
id: number;
name?: string;
cards?: Card[];
channels?: Channel[];
skip_if_empty?: boolean;
collection_id?: RegularCollectionId | null;
collection_position?: number | null;
dashboard_id?: DashboardId;
parameters?: Parameter[];
archived?: boolean;
can_write?: boolean;
}
......@@ -19,6 +19,7 @@ export * from "./search";
export * from "./segment";
export * from "./session";
export * from "./snippet";
export * from "./subscription";
export * from "./table";
export * from "./task";
export * from "./timeline";
......
import type {
ListSubscriptionsRequest,
DashboardSubscription,
CreateSubscriptionRequest,
UpdateSubscriptionRequest,
} from "metabase-types/api";
import { Api } from "./api";
import {
idTag,
invalidateTags,
listTag,
provideSubscriptionListTags,
provideSubscriptionTags,
} from "./tags";
export const subscriptionApi = Api.injectEndpoints({
endpoints: builder => ({
listSubscriptions: builder.query<
DashboardSubscription[],
ListSubscriptionsRequest
>({
query: params => ({
method: "GET",
url: "/api/pulse",
params,
}),
providesTags: (subscriptions = []) =>
provideSubscriptionListTags(subscriptions),
}),
getSubscription: builder.query<DashboardSubscription, number>({
query: id => ({
method: "GET",
url: `/api/pulse/${id}`,
}),
providesTags: subscription =>
subscription ? provideSubscriptionTags(subscription) : [],
}),
createSubscription: builder.mutation<
DashboardSubscription,
CreateSubscriptionRequest
>({
query: body => ({
method: "POST",
url: "/api/pulse",
body,
}),
invalidatesTags: (_, error) =>
invalidateTags(error, [listTag("subscription")]),
}),
updateSubscription: builder.mutation<
DashboardSubscription,
UpdateSubscriptionRequest
>({
query: ({ id, ...body }) => ({
method: "PUT",
url: `/api/pulse/${id}`,
body,
}),
invalidatesTags: (_, error, { id }) =>
invalidateTags(error, [
listTag("subscription"),
idTag("subscription", id),
]),
}),
unsubscribe: builder.mutation<void, number>({
query: id => ({
method: "DELETE",
url: `/api/pulse/${id}/subscription`,
}),
invalidatesTags: (_, error, id) =>
invalidateTags(error, [
listTag("subscription"),
idTag("subscription", id),
]),
}),
}),
});
export const {
useListSubscriptionsQuery,
useGetSubscriptionQuery,
useCreateSubscriptionMutation,
useUpdateSubscriptionMutation,
useUnsubscribeMutation,
} = subscriptionApi;
......@@ -18,8 +18,9 @@ export const TAG_TYPES = [
"persisted-model",
"revision",
"schema",
"snippet",
"segment",
"snippet",
"subscription",
"table",
"task",
"timeline",
......
......@@ -10,6 +10,7 @@ import type {
CollectionItem,
CollectionItemModel,
Dashboard,
DashboardSubscription,
Database,
DatabaseCandidate,
Field,
......@@ -375,6 +376,21 @@ export function provideSnippetTags(
return [idTag("snippet", snippet.id)];
}
export function provideSubscriptionListTags(
subscriptions: DashboardSubscription[],
): TagDescription<TagType>[] {
return [
listTag("subscription"),
...subscriptions.flatMap(provideSubscriptionTags),
];
}
export function provideSubscriptionTags(
subscription: DashboardSubscription,
): TagDescription<TagType>[] {
return [idTag("subscription", subscription.id)];
}
export function provideTableListTags(
tables: Table[],
): TagDescription<TagType>[] {
......
import { t } from "ttag";
import { canonicalCollectionId } from "metabase/collections/utils";
import { subscriptionApi } from "metabase/api";
import { getCollectionType } from "metabase/entities/collections";
import { color } from "metabase/lib/colors";
import { createEntity, undo } from "metabase/lib/entities";
import {
createEntity,
undo,
entityCompatibleQuery,
} from "metabase/lib/entities";
import * as Urls from "metabase/lib/urls";
import { addUndo } from "metabase/redux/undo";
import { PulseApi } from "metabase/services";
export const UNSUBSCRIBE = "metabase/entities/pulses/unsubscribe";
......@@ -22,6 +25,36 @@ const Pulses = createEntity({
UNSUBSCRIBE,
},
api: {
list: (entityQuery, dispatch) =>
entityCompatibleQuery(
entityQuery,
dispatch,
subscriptionApi.endpoints.listSubscriptions,
),
get: (entityQuery, options, dispatch) =>
entityCompatibleQuery(
entityQuery.id,
dispatch,
subscriptionApi.endpoints.getSubscription,
),
create: (entityQuery, dispatch) =>
entityCompatibleQuery(
entityQuery,
dispatch,
subscriptionApi.endpoints.createSubscription,
),
update: (entityQuery, dispatch) =>
entityCompatibleQuery(
entityQuery,
dispatch,
subscriptionApi.endpoints.updateSubscription,
),
delete: () => {
throw new TypeError("Pulses.api.delete is not supported");
},
},
objectActions: {
setArchived: ({ id }, archived, opts) => {
return Pulses.actions.update(
......@@ -31,37 +64,14 @@ const Pulses = createEntity({
);
},
setChannels: ({ id }, channels, opts) => {
return Pulses.actions.update(
{ id },
{ channels },
undo(opts, t`subscription`, t`updated`),
);
},
setCollection: ({ id }, collection, opts) => {
return Pulses.actions.update(
{ id },
{ collection_id: canonicalCollectionId(collection && collection.id) },
undo(opts, t`subscription`, t`moved`),
);
},
setPinned: ({ id }, pinned, opts) => {
return Pulses.actions.update(
{ id },
{
collection_position:
typeof pinned === "number" ? pinned : pinned ? 1 : null,
},
opts,
);
},
unsubscribe:
({ id }) =>
async dispatch => {
await PulseApi.unsubscribe({ id });
await entityCompatibleQuery(
id,
dispatch,
subscriptionApi.endpoints.unsubscribe,
);
dispatch(addUndo({ message: t`Successfully unsubscribed` }));
dispatch({ type: UNSUBSCRIBE, payload: { id } });
dispatch({ type: Pulses.actionTypes.INVALIDATE_LISTS_ACTION });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment