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(admin): add download logs action #221

Merged
merged 5 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ exports[`exports > exports from index.ts 1`] = `
"defineAction",
"deleteAccountAction",
"doMutate",
"downloadLogsAction",
"executeAction",
"executeAdminComponentTest",
"executeAfterHandle",
Expand Down Expand Up @@ -116,6 +117,7 @@ exports[`exports > exports from index.ts 1`] = `
"useDeleteAccountMutation",
"useDeleteShipmentsMutation",
"useDeleteWebhooksMutation",
"useDownloadLogsMutation",
"useDropOffInputContext",
"useDropdownData",
"useElement",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ exports[`exports > exports from index.ts 1`] = `
"defineAction",
"deleteAccountAction",
"doMutate",
"downloadLogsAction",
"executeAction",
"executeAfterHandle",
"executeBeforeHandle",
Expand Down Expand Up @@ -113,6 +114,7 @@ exports[`exports > exports from index.ts 1`] = `
"useDeleteAccountMutation",
"useDeleteShipmentsMutation",
"useDeleteWebhooksMutation",
"useDownloadLogsMutation",
"useDropOffInputContext",
"useDropdownData",
"useElement",
Expand Down
2 changes: 2 additions & 0 deletions apps/admin/src/__tests__/__snapshots__/exports.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ exports[`exports > exports from index.ts 1`] = `
"defineAction",
"deleteAccountAction",
"doMutate",
"downloadLogsAction",
"executeAction",
"executeAfterHandle",
"executeBeforeHandle",
Expand Down Expand Up @@ -113,6 +114,7 @@ exports[`exports > exports from index.ts 1`] = `
"useDeleteAccountMutation",
"useDeleteShipmentsMutation",
"useDeleteWebhooksMutation",
"useDownloadLogsMutation",
"useDropOffInputContext",
"useDropdownData",
"useElement",
Expand Down
20 changes: 12 additions & 8 deletions apps/admin/src/__tests__/mocks/mockDefaultPlatform.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import {vi} from 'vitest';
import {type GlobalAdminContext} from '../../types';

export const mockDefaultPlatform = vi.fn(() => ({
backofficeUrl: 'https://backoffice.test.myparcel.nl',
defaultCarrier: 'postnl',
defaultCarrierId: 1,
human: 'Test',
localCountry: 'NL',
name: 'test',
}));
export const mockDefaultPlatform = vi.fn((): GlobalAdminContext['platform'] => {
return {
backofficeUrl: 'https://backoffice.test.myparcel.nl',
defaultCarrier: 'postnl',
defaultCarrierId: 1,
human: 'Test',
localCountry: 'NL',
name: 'test',
supportUrl: 'https://developer.myparcel.nl/contact',
};
});
20 changes: 20 additions & 0 deletions apps/admin/src/__tests__/utils/mockLinkElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {vi} from 'vitest';

export const mockLinkElement = () => {
const createElementSpy = vi.spyOn(document, 'createElement');
const appendChildSpy = vi.spyOn(document.body, 'appendChild');

const mockElement = document.createElement('a');

mockElement.setAttribute = vi.fn();
mockElement.click = vi.fn();
mockElement.remove = vi.fn();

createElementSpy.mockReturnValue(mockElement);

return {
createElementSpy,
appendChildSpy,
mockElement,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useDownloadLogsMutation';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {BackendEndpoint} from '@myparcel-pdk/common';
import {usePdkMutation} from '../usePdkMutation';
import {type ResolvedQuery} from '../../../../stores';
import {usePdkAdminApi} from '../../../../sdk';

export const useDownloadLogsMutation = (): ResolvedQuery<BackendEndpoint.DownloadLogs> => {
return usePdkMutation(BackendEndpoint.DownloadLogs, () => usePdkAdminApi().downloadLogs());
};

Check warning on line 8 in apps/admin/src/actions/composables/mutations/debug/useDownloadLogsMutation.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/actions/composables/mutations/debug/useDownloadLogsMutation.ts#L7-L8

Added lines #L7 - L8 were not covered by tests
1 change: 1 addition & 0 deletions apps/admin/src/actions/composables/mutations/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './account';
export * from './debug';
export * from './orders';
export * from './settings';
export * from './shipments';
Expand Down
19 changes: 19 additions & 0 deletions apps/admin/src/actions/definitions/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {BackendEndpoint} from '@myparcel-pdk/common';
import {createMutationHandler} from '../executors';
import {defineAction} from '../defineAction';
import {downloadBlob} from '../../utils/downloadBlob';
import {AdminAction, AdminIcon} from '../../data';

/**
* Download zip with logs.
*/
export const downloadLogsAction = defineAction({
name: AdminAction.DownloadLogs,
icon: AdminIcon.Download,
label: 'action_download_logs',
handler: createMutationHandler(BackendEndpoint.DownloadLogs),
// @ts-expect-error todo
afterHandle(response) {
downloadBlob(response.response, 'logs.zip');
},

Check warning on line 18 in apps/admin/src/actions/definitions/debug.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/actions/definitions/debug.ts#L17-L18

Added lines #L17 - L18 were not covered by tests
});
1 change: 1 addition & 0 deletions apps/admin/src/actions/definitions/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './account';
export * from './context';
export * from './debug';
export * from './modal';
export * from './orders';
export * from './settings';
Expand Down
4 changes: 2 additions & 2 deletions apps/admin/src/actions/print/openOrPrintPdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {type ActionContextWithResponse} from '../executors';
import {generateLabelFilename} from '../../utils';
import {type PdfDataResponse, type PrintAction} from '../../types';
import {downloadPdf, openPdfInNewWindow} from '../../services';
import {downloadFile, openPdfInNewWindow} from '../../services';

export const openOrPrintPdf = async <A extends PrintAction>({
response,
Expand All @@ -12,5 +12,5 @@
return openPdfInNewWindow(response.data);
}

await downloadPdf(response.url, generateLabelFilename(parameters));
await downloadFile(response.url, generateLabelFilename(parameters));

Check warning on line 15 in apps/admin/src/actions/print/openOrPrintPdf.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/actions/print/openOrPrintPdf.ts#L15

Added line #L15 was not covered by tests
};
26 changes: 10 additions & 16 deletions apps/admin/src/components/PluginSettings/AccountSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,29 @@
:button-wrapper="prefixComponent(AdminComponent.ButtonGroup)"
:closeable="hasAccount"
:initial-tab="!hasAccount"
:tabs="tabs">
<template
v-if="refreshAction"
#button-wrapper>
<ActionButton
:action="refreshAction"
:size="Size.Small"
:variant="Variant.Secondary" />
</template>
</TabNavigation>
:tabs="tabs" />
</PdkBox>
</template>

<script lang="ts" setup>
import {computed} from 'vue';
import {get} from '@vueuse/core';
import {Size, Status, Variant} from '@myparcel-pdk/common';
import {ActionButton, StatusIndicator, TabNavigation} from '../common';
import {Status} from '@myparcel-pdk/common';
import {StatusIndicator, TabNavigation} from '../common';
import {prefixComponent} from '../../utils';
import {type TabDefinition} from '../../types';
import {useActionStore} from '../../stores';
import {instantiateAction} from '../../services';
import {AdminComponent} from '../../data';
import {useLanguage, useStoreContextQuery} from '../../composables';
import {
deleteAccountAction,
refreshAccountAction,
updateAccountAction,
useDeleteAccountMutation,
useUpdateAccountMutation,
} from '../../actions';
import WebhooksStatus from './WebhooksStatus.vue';
import EditApiKeyForm from './EditApiKeyForm.vue';
import DebugOptions from './DebugOptions.vue';

const actionStore = useActionStore();

Expand All @@ -61,8 +51,6 @@ const hasApiKey = computed(() => Boolean(get(contextQuery.data)?.pluginSettings.

const hasAccount = computed(() => !get(loading) && hasApiKey.value && Boolean(get(contextQuery.data)?.account));

const refreshAction = instantiateAction(refreshAccountAction);

const {translate} = useLanguage();

const tabs = computed(() => {
Expand All @@ -82,6 +70,12 @@ const tabs = computed(() => {
});
}

array.push({
name: 'debug',
component: DebugOptions,
label: 'button_debug',
});

return array;
});
</script>
37 changes: 37 additions & 0 deletions apps/admin/src/components/PluginSettings/DebugOptions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<div>
<PdkHeading level="2">{{ translate('settings_debug_title') }}</PdkHeading>

<div>
<p v-text="translate('debug_refresh_description')" />

<ActionButton :action="refreshAccountInstance" />
</div>

<div>
<p v-text="translate('debug_download_logs_description')" />

<ActionButton :action="downloadLogsInstance" />
</div>
</div>
</template>

<script lang="ts" setup>
import {BackendEndpoint} from '@myparcel-pdk/common';
import {ActionButton} from '../common';
import {useActionStore, useQueryStore} from '../../stores';
import {instantiateAction} from '../../services';
import {useLanguage} from '../../composables';
import {downloadLogsAction, refreshAccountAction, updateAccountAction, useDownloadLogsMutation} from '../../actions';

const {translate} = useLanguage();

const queryStore = useQueryStore();
const actionStore = useActionStore();

queryStore.register(BackendEndpoint.DownloadLogs, useDownloadLogsMutation());
actionStore.register([updateAccountAction, downloadLogsAction]);

const refreshAccountInstance = instantiateAction(refreshAccountAction);
const downloadLogsInstance = instantiateAction(downloadLogsAction);
</script>
2 changes: 2 additions & 0 deletions apps/admin/src/data/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ export enum AdminAction {
WebhooksCreate = 'webhooksCreate',
WebhooksDelete = 'webhooksDelete',
WebhooksFetch = 'webhooksFetch',

DownloadLogs = 'downloadLogs',
}
2 changes: 2 additions & 0 deletions apps/admin/src/data/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export const BACKEND_ENDPOINTS_WEBHOOKS = [
BackendEndpoint.DeleteWebhooks,
BackendEndpoint.FetchWebhooks,
] as const;

export const BACKEND_ENDPOINTS_DEBUG = [BackendEndpoint.DownloadLogs] as const;
16 changes: 16 additions & 0 deletions apps/admin/src/services/actions/downloadFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {downloadFileFromUrl} from '../../utils';

/**
* Try to get a file from an url. An error means the file is not ready yet. Retry until it is.
*/
export async function downloadFile(url: string, filename: string): Promise<void> {
try {
downloadFileFromUrl(url, filename);
} catch (e) {
await new Promise((resolve) => {
setTimeout(resolve, 100);
});

return downloadFile(url, filename);
}
}

Check warning on line 16 in apps/admin/src/services/actions/downloadFile.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/services/actions/downloadFile.ts#L6-L16

Added lines #L6 - L16 were not covered by tests
16 changes: 0 additions & 16 deletions apps/admin/src/services/actions/downloadPdf.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/admin/src/services/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './createAction';
export * from './createActionContext';
export * from './downloadPdf';
export * from './downloadFile';
export * from './getActionIdentifier';
5 changes: 3 additions & 2 deletions apps/admin/src/services/print/openPdfInNewWindow.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {openUrl} from '../../utils';
import {openUrlInNewTab} from '../../utils';

/**
* Opens a new window with the given base64 encoded pdf.
*/
export const openPdfInNewWindow = async (pdf: string): Promise<void> => {
const blob = await (await fetch(`data:application/pdf;base64,${pdf}`)).blob();
const url = URL.createObjectURL(blob);

Check warning on line 8 in apps/admin/src/services/print/openPdfInNewWindow.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/services/print/openPdfInNewWindow.ts#L8

Added line #L8 was not covered by tests

openUrl(URL.createObjectURL(blob));
openUrlInNewTab(url);

Check warning on line 10 in apps/admin/src/services/print/openPdfInNewWindow.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/services/print/openPdfInNewWindow.ts#L10

Added line #L10 was not covered by tests
};
1 change: 1 addition & 0 deletions apps/admin/src/types/actions/actions.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface AdminActionEndpointMap extends Record<AdminAction, BackendEndpo
[AdminAction.AccountDelete]: BackendEndpoint.DeleteAccount;
[AdminAction.AccountUpdate]: BackendEndpoint.UpdateAccount;
[AdminAction.ContextFetch]: BackendEndpoint.FetchContext;
[AdminAction.DownloadLogs]: BackendEndpoint.DownloadLogs;
[AdminAction.OrdersEdit]: BackendEndpoint.UpdateOrders;
[AdminAction.OrdersExportPrint]: BackendEndpoint.ExportOrders;
[AdminAction.OrdersExport]: BackendEndpoint.ExportOrders;
Expand Down
1 change: 1 addition & 0 deletions apps/admin/src/types/actions/endpoints.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {type BackendEndpoint} from '@myparcel-pdk/common';
*/
export type BackendMutationEndpoints =
| BackendEndpoint.CreateWebhooks
| BackendEndpoint.DownloadLogs
| BackendEndpoint.DeleteAccount
| BackendEndpoint.DeleteShipments
| BackendEndpoint.DeleteWebhooks
Expand Down
3 changes: 3 additions & 0 deletions apps/admin/src/types/endpoints.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {type BackendEndpoint, type EndpointObject} from '@myparcel-pdk/common';
import {
type BACKEND_ENDPOINTS_DEBUG,
type BACKEND_ENDPOINTS_ORDERS,
type BACKEND_ENDPOINTS_SHIPMENTS,
type BACKEND_ENDPOINTS_WEBHOOKS,
Expand All @@ -12,3 +13,5 @@ export type BackendShipmentEndpoint = (typeof BACKEND_ENDPOINTS_SHIPMENTS)[numbe
export type BackendOrderEndpoint = (typeof BACKEND_ENDPOINTS_ORDERS)[number];

export type BackendWebhookEndpoint = (typeof BACKEND_ENDPOINTS_WEBHOOKS)[number];

export type BackendDebugEndpoint = (typeof BACKEND_ENDPOINTS_DEBUG)[number];
6 changes: 6 additions & 0 deletions apps/admin/src/types/sdk.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,14 @@ interface DeleteWebhooksDefinition extends PdkEndpointDefinition {
response: WebhookDefinition[];
}

interface DebugDownloadLogsDefinition extends PdkEndpointDefinition {
name: BackendEndpoint.DownloadLogs;
response: Blob;
}

export type BackendEndpointDefinition =
| CreateWebhooksDefinition
| DebugDownloadLogsDefinition
| DeleteAccountDefinition
| DeleteShipmentsDefinition
| DeleteWebhooksDefinition
Expand Down
9 changes: 9 additions & 0 deletions apps/admin/src/utils/downloadBlob.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {downloadFileFromUrl} from './downloadFileFromUrl';

export const downloadBlob = (blob: Blob, filename: string): void => {
const url = URL.createObjectURL(blob);

downloadFileFromUrl(url, filename);

URL.revokeObjectURL(url);
};

Check warning on line 9 in apps/admin/src/utils/downloadBlob.ts

View check run for this annotation

Codecov / codecov/patch

apps/admin/src/utils/downloadBlob.ts#L4-L9

Added lines #L4 - L9 were not covered by tests
Loading
Loading