Skip to content

Commit

Permalink
feat: add name to query param for setting (#223)
Browse files Browse the repository at this point in the history
fix: do not stringify app messages (resizing bug)
  • Loading branch information
spaenleh authored Dec 19, 2023
1 parent de3e239 commit 483e37c
Show file tree
Hide file tree
Showing 22 changed files with 200 additions and 143 deletions.
13 changes: 8 additions & 5 deletions src/api/appData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppData, UUID } from '@graasp/sdk';
import { AppData, UUID, appendQueryParamToUrl } from '@graasp/sdk';

import { ApiData } from '../types';
import { ApiData, Data } from '../types';
import configureAxios from './axios';
import {
buildDeleteAppDataRoute,
Expand All @@ -12,10 +12,13 @@ import {

const axios = configureAxios();

export const getAppData = async (args: ApiData) => {
const { token, itemId, apiHost } = args;
export const getAppData = async <DataType extends Data = Data>(
args: ApiData & { filters?: { [key: string]: string } },
) => {
const { token, itemId, apiHost, filters } = args;
const url = appendQueryParamToUrl(`${apiHost}/${buildGetAppDataRoute(itemId)}`, filters ?? {});
return axios
.get<AppData[]>(`${apiHost}/${buildGetAppDataRoute(itemId)}`, {
.get<AppData<DataType>[]>(url, {
headers: {
Authorization: `Bearer ${token}`,
},
Expand Down
16 changes: 11 additions & 5 deletions src/api/appSetting.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppSetting } from '@graasp/sdk';
import { AppSetting, appendQueryParamToUrl } from '@graasp/sdk';

import { ApiData } from '../types';
import { ApiData, Data } from '../types';
import configureAxios from './axios';
import {
buildDeleteAppSettingRoute,
Expand All @@ -12,10 +12,16 @@ import {

const axios = configureAxios();

export const getAppSettings = async (args: ApiData) => {
const { token, itemId, apiHost } = args;
export const getAppSettings = async <DataType extends Data = Data>(
args: ApiData & { filters?: { name: string } },
) => {
const { token, itemId, apiHost, filters } = args;
const url = appendQueryParamToUrl(
`${apiHost}/${buildGetAppSettingsRoute(itemId)}`,
filters ?? {},
);
return axios
.get<AppSetting[]>(`${apiHost}/${buildGetAppSettingsRoute(itemId)}`, {
.get<AppSetting<DataType>[]>(url, {
headers: {
Authorization: `Bearer ${token}`,
},
Expand Down
2 changes: 1 addition & 1 deletion src/api/chatBot.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChatBotMessage } from '@graasp/sdk';

import { ApiData, ChatBotCompletion } from 'src/types';
import { ApiData, ChatBotCompletion } from 'types';

import configureAxios from './axios';
import { buildPostChatBotRoute } from './routes';
Expand Down
2 changes: 2 additions & 0 deletions src/api/routes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { appendQueryParamToUrl } from '@graasp/sdk';

export const APP_DATA_ENDPOINT = 'app-data';
export const ITEMS_ROUTE = 'items';
export const APP_ITEMS_ROUTE = 'app-items';
Expand Down
43 changes: 33 additions & 10 deletions src/config/keys.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { UUID } from '@graasp/sdk';

export const buildAppDataKey = (id?: UUID) => ['app-data', id] as const;
export const buildAppActionsKey = (id?: UUID) => ['app-action', id] as const;
export const buildAppSettingsKey = (id?: UUID) => ['app-setting', id] as const;
export const buildAppContextKey = (id?: UUID) => ['context', id] as const;
const APP_SETTING_KEY = 'app-setting';
const APP_DATA_KEY = 'app-setting';
const APP_ACTION_KEY = 'app-action';

export const appSettingKeys = {
all: [APP_SETTING_KEY] as const,
allSingles: () => [...appSettingKeys.all, 'single'] as const,
single: (id?: UUID, filters?: { [key: string]: unknown }) =>
[...appSettingKeys.allSingles(), id, filters] as const,
allFileContents: () => [...appSettingKeys.all, 'file-content'] as const,
fileContent: (id?: UUID) => [...appSettingKeys.allFileContents(), id] as const,
};

export const appDataKeys = {
all: [APP_DATA_KEY] as const,
allSingles: () => [...appDataKeys.all, 'single'] as const,
single: (id?: UUID, filters?: { [key: string]: unknown }) =>
[...appDataKeys.allSingles(), id, filters] as const,
allFileContents: () => [...appDataKeys.all, 'file-content'] as const,
fileContent: (id?: UUID) => [...appDataKeys.allFileContents(), id] as const,
};

export const appActionKeys = {
all: [APP_ACTION_KEY] as const,
allSingles: () => [...appActionKeys.all, 'single'] as const,
single: (id?: UUID) => [...appActionKeys.allSingles(), id] as const,
};

export const AUTH_TOKEN_KEY = ['AUTH_TOKEN_KEY'];
export const LOCAL_CONTEXT_KEY = ['LOCAL_CONTEXT_KEY'];
export const buildFileContentKey = (id?: UUID) => ['app-data', 'files', 'content', id] as const;
export const buildAppSettingFileContentKey = (id?: UUID) =>
['app-setting', 'files', 'content', id] as const;

export const buildAppContextKey = (id?: UUID) => ['context', id] as const;

export const buildPostMessageKeys = (itemId: UUID) =>
({
Expand All @@ -22,8 +45,8 @@ export const buildPostMessageKeys = (itemId: UUID) =>
}) as const;

export const QUERY_KEYS = {
buildAppDataKey,
buildAppContextKey,
buildAppActionsKey,
buildAppSettingsKey,
appSettingKeys,
appDataKeys,
appActionKeys,
};
4 changes: 2 additions & 2 deletions src/hooks/appAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PermissionLevel } from '@graasp/sdk';
import { useQuery, useQueryClient } from '@tanstack/react-query';

import * as Api from '../api';
import { buildAppActionsKey } from '../config/keys';
import { appActionKeys } from '../config/keys';
import { getApiHost, getData, getDataOrThrow, getPermissionLevel } from '../config/utils';
import { QueryClientConfig } from '../types';
import { configureWsAppActionsHooks } from '../ws/hooks/app';
Expand Down Expand Up @@ -32,7 +32,7 @@ export default (queryConfig: QueryClientConfig, websocketClient?: WebsocketClien
useAppActionsUpdates(enableWs && permissionLevel === PermissionLevel.Admin ? itemId : null);

return useQuery({
queryKey: buildAppActionsKey(itemId),
queryKey: appActionKeys.single(itemId),
queryFn: () => {
const { token } = getDataOrThrow(queryClient);

Expand Down
11 changes: 3 additions & 8 deletions src/hooks/appData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import {
import { Endpoint, mockHook, setUpTest } from '../../test/utils';
import { buildDownloadAppDataFileRoute, buildGetAppDataRoute } from '../api/routes';
import { MOCK_TOKEN } from '../config/constants';
import {
AUTH_TOKEN_KEY,
LOCAL_CONTEXT_KEY,
buildAppDataKey,
buildFileContentKey,
} from '../config/keys';
import { AUTH_TOKEN_KEY, LOCAL_CONTEXT_KEY, appDataKeys } from '../config/keys';
import { MissingApiHostError } from '../config/utils';

const { hooks, wrapper, queryClient } = setUpTest();
Expand All @@ -34,7 +29,7 @@ describe('App Data Hooks', () => {
});

describe('useAppData', () => {
const key = buildAppDataKey(itemId);
const key = appDataKeys.single(itemId);
const route = `/${buildGetAppDataRoute(itemId)}`;
const hook = () => hooks.useAppData();

Expand Down Expand Up @@ -125,7 +120,7 @@ describe('App Data Hooks', () => {
const id = 'some-id';
const route = `/${buildDownloadAppDataFileRoute(id)}`;
const hook = () => hooks.useAppDataFile({ fileId: id });
const key = buildFileContentKey(id);
const key = appDataKeys.fileContent(id);

it('Receive file content', async () => {
const endpoints = [
Expand Down
21 changes: 15 additions & 6 deletions src/hooks/appData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';

import * as Api from '../api';
import { MissingFileIdError } from '../config/errors';
import { buildAppDataKey, buildFileContentKey } from '../config/keys';
import { appDataKeys } from '../config/keys';
import { getApiHost, getData, getDataOrThrow } from '../config/utils';
import { QueryClientConfig } from '../types';
import { Data, QueryClientConfig } from '../types';
import { configureWsAppDataHooks } from '../ws/hooks/app';
import { WebsocketClient } from '../ws/ws-client';

Expand All @@ -22,8 +22,16 @@ export default (
};
const { useAppDataUpdates } = configureWsAppDataHooks(websocketClient);
return {
useAppData: (options?: { refetchInterval?: number; getUpdates?: boolean }) => {
useAppData: <DataType extends Data = Data>(
filters?: { type: string },
options?: {
refetchInterval?: number;
enabled?: boolean;
getUpdates?: boolean;
},
) => {
const refetchInterval = options?.refetchInterval ?? false;
const enabled = options?.enabled ?? true;
const getUpdates = options?.getUpdates ?? true;
const queryClient = useQueryClient();

Expand All @@ -35,12 +43,13 @@ export default (
useAppDataUpdates(enableWs ? itemId : null);

return useQuery({
queryKey: buildAppDataKey(itemId),
queryKey: appDataKeys.single(itemId),
queryFn: () => {
const { token } = getDataOrThrow(queryClient);
return Api.getAppData({ itemId, token, apiHost });
return Api.getAppData<DataType>({ itemId, token, apiHost, filters });
},
...defaultOptions,
enabled,
refetchInterval,
});
},
Expand All @@ -53,7 +62,7 @@ export default (
const apiHost = getApiHost(queryClient);

return useQuery({
queryKey: buildFileContentKey(payload?.fileId),
queryKey: appDataKeys.fileContent(payload?.fileId),
queryFn: () => {
const { token } = getDataOrThrow(queryClient);

Expand Down
11 changes: 3 additions & 8 deletions src/hooks/appSetting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import {
import { Endpoint, mockHook, setUpTest } from '../../test/utils';
import { buildDownloadAppSettingFileRoute, buildGetAppSettingsRoute } from '../api/routes';
import { MOCK_TOKEN } from '../config/constants';
import {
AUTH_TOKEN_KEY,
LOCAL_CONTEXT_KEY,
buildAppSettingFileContentKey,
buildAppSettingsKey,
} from '../config/keys';
import { AUTH_TOKEN_KEY, LOCAL_CONTEXT_KEY, appSettingKeys } from '../config/keys';
import { MissingApiHostError } from '../config/utils';

const { hooks, wrapper, queryClient } = setUpTest();
Expand All @@ -34,7 +29,7 @@ describe('App Settings Hooks', () => {
});

describe('useAppSettings', () => {
const key = buildAppSettingsKey(itemId);
const key = appSettingKeys.single(itemId);
const route = `/${buildGetAppSettingsRoute(itemId)}`;
const hook = () => hooks.useAppSettings();

Expand Down Expand Up @@ -120,7 +115,7 @@ describe('App Settings Hooks', () => {
const id = 'some-id';
const route = `/${buildDownloadAppSettingFileRoute(id)}`;
const hook = () => hooks.useAppSettingFile({ appSettingId: id });
const key = buildAppSettingFileContentKey(id);
const key = appSettingKeys.fileContent(id);

it('Receive file content', async () => {
const endpoints = [
Expand Down
16 changes: 10 additions & 6 deletions src/hooks/appSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';

import * as Api from '../api';
import { MissingFileIdError } from '../config/errors';
import { buildAppSettingFileContentKey, buildAppSettingsKey } from '../config/keys';
import { appSettingKeys } from '../config/keys';
import { getApiHost, getData, getDataOrThrow } from '../config/utils';
import { QueryClientConfig } from '../types';
import { Data, QueryClientConfig } from '../types';
import { configureWsAppSettingHooks } from '../ws/hooks/app';
import { WebsocketClient } from '../ws/ws-client';

Expand All @@ -18,7 +18,10 @@ export default (queryConfig: QueryClientConfig, websocketClient?: WebsocketClien
};
const { useAppSettingsUpdates } = configureWsAppSettingHooks(websocketClient);
return {
useAppSettings: (options?: { getUpdates: boolean }) => {
useAppSettings: <DataType extends Data = Data>(
filters?: { name: string },
options?: { getUpdates: boolean },
) => {
const getUpdates = options?.getUpdates ?? true;
const queryClient = useQueryClient();
const apiHost = getApiHost(queryClient);
Expand All @@ -29,16 +32,17 @@ export default (queryConfig: QueryClientConfig, websocketClient?: WebsocketClien
useAppSettingsUpdates(enableWs ? itemId : null);

return useQuery({
queryKey: buildAppSettingsKey(itemId),
queryKey: appSettingKeys.single(itemId, filters),
queryFn: () => {
const { token: localToken, itemId: localItemId } = getDataOrThrow(queryClient, {
shouldMemberExist: false,
});

return Api.getAppSettings({
return Api.getAppSettings<DataType>({
itemId: localItemId,
token: localToken,
apiHost,
filters,
});
},
...defaultOptions,
Expand All @@ -56,7 +60,7 @@ export default (queryConfig: QueryClientConfig, websocketClient?: WebsocketClien
const { token } = getData(queryClient, { shouldMemberExist: false });

return useQuery({
queryKey: buildAppSettingFileContentKey(payload?.appSettingId),
queryKey: appSettingKeys.fileContent(payload?.appSettingId),
queryFn: (): Promise<Blob> => {
const { token: localToken } = getDataOrThrow(queryClient, {
shouldMemberExist: false,
Expand Down
13 changes: 7 additions & 6 deletions src/hooks/postMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class CommunicationChannel {
if (this.isMobile) {
window.parent.postMessage(JSON.stringify(data));
} else {
console.debug('this.messagePort is', this.messagePort);
this.messagePort?.postMessage(JSON.stringify(data));
}
}
Expand Down Expand Up @@ -302,12 +303,12 @@ const configurePostMessageHooks = (queryConfig: QueryClientConfig) => {
useEffect(() => {
if (!queryConfig.isStandalone) {
const sendHeight = (height: number): void => {
communicationChannel?.postMessage(
JSON.stringify({
type: POST_MESSAGE_KEYS.POST_AUTO_RESIZE,
payload: height,
}),
);
console.debug('[app-postMessage] Sending height', height);
console.debug('communication channel is', communicationChannel);
communicationChannel?.postMessage({
type: POST_MESSAGE_KEYS.POST_AUTO_RESIZE,
payload: height,
});
};
if (!communicationChannel) {
const error = new MissingMessageChannelPortError();
Expand Down
21 changes: 13 additions & 8 deletions src/mockServer/mirage/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,12 @@ export const mockMirageServer = ({
},
routes() {
// app data
this.get(
`/${buildGetAppDataRoute(currentItem.id)}`,
(schema) => schema.all('appDataResource') ?? [],
);
this.get(`/${buildGetAppDataRoute(currentItem.id)}`, (schema, request) => {
const dataType = new URL(request.url).searchParams.get('type');
return (
schema.all('appDataResource').filter((x) => (dataType ? x.type === dataType : true)) ?? []
);
});
this.post(`/${buildPostAppDataRoute({ itemId: currentItem.id })}`, (schema, request) => {
if (!currentMember) {
return new Response(401, {}, { errors: ['user not authenticated'] });
Expand Down Expand Up @@ -232,10 +234,13 @@ export const mockMirageServer = ({
});

// app settings
this.get(
`/${buildGetAppSettingsRoute(currentItem.id)}`,
(schema) => schema.all('appSetting') ?? [],
);
this.get(`/${buildGetAppSettingsRoute(currentItem.id)}`, (schema, request) => {
const settingName = new URL(request.url).searchParams.get('name');
return (
schema.all('appSetting').filter((x) => (settingName ? x.name === settingName : true)) ??
[]
);
});

this.post(`/${buildPostAppSettingRoute({ itemId: currentItem.id })}`, (schema, request) => {
if (!currentMember) {
Expand Down
Loading

0 comments on commit 483e37c

Please sign in to comment.