Skip to content

Commit

Permalink
Can Export Preview Record (grouparoo#3000)
Browse files Browse the repository at this point in the history
* Lots of moving parts, 181358373 is also fixed here

* Removing more unused code

* Builds

* Removing tests for removed endpoint

* Removing route

* RecordType -> Models.GrouparooRecordType

* Test fixed

* Restoring original functionality

* Fetch record always returns the data we want

* Cleanup

* Code review

* weird apostrophe
  • Loading branch information
Krishna Glick authored Feb 28, 2022
1 parent 4662412 commit b26d0bd
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 30 deletions.
31 changes: 24 additions & 7 deletions core/src/actions/destinations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ConfigWriter } from "../modules/configWriter";
import { APIData } from "../modules/apiData";
import { ActionPermission } from "../models/Permission";
import { WhereAttributeHash } from "sequelize/types";
import { DestinationOps } from "../modules/ops/destination";

export class DestinationsList extends AuthenticatedAction {
name = "destinations:list";
Expand Down Expand Up @@ -325,10 +326,12 @@ export class DestinationView extends AuthenticatedAction {

export class DestinationExport extends AuthenticatedAction {
name = "destination:export";
description = "export the members of the groups tracked by this destination";
description =
"export the member or members of the groups tracked by this destination";
permission: ActionPermission = { topic: "destination", mode: "write" };
inputs = {
id: { required: true },
id: { required: true, inPath: true },
recordId: { required: false },
} as const;

async runWithinTransaction({
Expand All @@ -337,7 +340,12 @@ export class DestinationExport extends AuthenticatedAction {
params: ParamsFrom<DestinationExport>;
}) {
const destination = await Destination.findById(params.id);
await destination.exportMembers();
if (params.recordId) {
const record = await GrouparooRecord.findById(params.recordId);
await destination.exportRecord(record);
} else {
await destination.exportMembers();
}
return { success: true };
}
}
Expand Down Expand Up @@ -413,11 +421,20 @@ export class DestinationRecordPreview extends AuthenticatedAction {
await destination.checkRecordWillBeExported(record);
}

const recordPreview = await destination.recordPreview(
record,
mapping,
destinationGroupMemberships
);

const groups = await record.$get("groups");
const destinations = await DestinationOps.relevantFor(record, groups);

return {
record: await destination.recordPreview(
record,
mapping,
destinationGroupMemberships
record: recordPreview,
groups: await Promise.all(groups.map((group) => group.apiData())),
destinations: await Promise.all(
destinations.map((destination) => destination.apiData(false, false))
),
};
}
Expand Down
10 changes: 10 additions & 0 deletions ui/ui-components/__tests__/components/record/SampleRecordCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import SampleRecordCard, {
import { Models } from "../../../utils/apiData";
import { asyncRenderWithContext } from "../../__utils__/renderWithContext";

jest.mock("next/router", () => {
return {
useRouter: () => ({
query: { destinationId: "asdf" },
asPath: "",
pathname: "",
}),
};
});

describe("SampleRecordCard", () => {
let cardProps: SampleRecordCardProps;
const modelId = "test-model";
Expand Down
79 changes: 58 additions & 21 deletions ui/ui-components/components/record/SampleRecordCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { useApi } from "../../contexts/api";
import Cookies from "universal-cookie";
import { isBrowser } from "../../utils/isBrowser";
import { useGrouparooModel } from "../../contexts/grouparooModel";
import { useRouter } from "next/router";

export type RecordType =
| Models.GrouparooRecordType
Expand All @@ -48,7 +49,6 @@ export interface SampleRecordCardProps {
reloadKey?: string;
warning?: string;
groupId?: string;

record?: RecordType;
groups?: Models.GroupType[];
destinations?: Models.DestinationType[];
Expand Down Expand Up @@ -121,9 +121,12 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
const {
model: { id: modelId },
} = useGrouparooModel();
const router = useRouter();
const { destinationId } = router.query;

const [loading, setLoading] = useState(false);
const [importing, setImporting] = useState(false);
const [exporting, setExporting] = useState(false);
const [addingRecord, setAddingRecord] = useState(false);
const [hasRecords, setHasRecords] = useState(true);
const [totalRecords, setTotalRecords] = useState(0);
Expand All @@ -136,6 +139,11 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
() => props.record?.id || getCachedSampleRecordId(modelId)
);

const canExportRecord = useMemo(
() => destinations?.find(({ id }) => id === destinationId),
[destinationId, destinations]
);

const saveRecord = useCallback(
(
record: RecordType,
Expand Down Expand Up @@ -327,6 +335,37 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
return result;
}, [record, hideViewAllRecords, totalRecords, modelId, disabled]);

const importRecord = useCallback(async () => {
setImporting(true);
const response = await client.request<Actions.RecordImport>(
"post",
`/record/${record.id}/import`
);
if (response?.record) {
setRecord(response.record);
setGroups(response.groups);
successHandler.set({ message: "Import Complete!" });
} else {
loadRecord(); // we may have done a partial import
}
setImporting(false);
}, [client, loadRecord, record?.id]);

const exportRecord = useCallback(async () => {
setExporting(true);
const response = await client.request<Actions.DestinationExport>(
"post",
`/destination/${destinationId}/export`,
{ recordId: record.id }
);
if (response?.success) {
successHandler.set({ message: "Export Complete!" });
} else {
errorHandler.set({ message: "Export Failed" });
}
setExporting(false);
}, [client, destinationId, record?.id]);

if (!sortedPropertyKeys?.length && !properties.length) {
return (
<ManagedCard title="Sample Record">
Expand All @@ -343,22 +382,6 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
);
}

const importRecord = async () => {
setImporting(true);
const response = await client.request<Actions.RecordImport>(
"post",
`/record/${record.id}/import`
);
if (response?.record) {
setRecord(response.record);
setGroups(response.groups);
successHandler.set({ message: "Import Complete!" });
} else {
loadRecord(); // we may have done a partial import
}
setImporting(false);
};

const actions = [
<LoadingButton
key="clear-record-id"
Expand All @@ -381,9 +404,7 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
<LoadingButton
disabled={disabled || !record || loading}
loading={importing}
onClick={() => {
importRecord();
}}
onClick={importRecord}
size="sm"
variant="outline-success"
>
Expand All @@ -392,6 +413,20 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
);
}

if (canExportRecord) {
actions.push(
<LoadingButton
disabled={disabled || !record || loading || !!warning}
loading={exporting}
onClick={exportRecord}
size="sm"
variant="outline-success"
>
Export Record Data
</LoadingButton>
);
}

if (isConfigUI) {
actions.push(
<LoadingButton
Expand Down Expand Up @@ -569,7 +604,9 @@ const SampleRecordCard: React.FC<SampleRecordCardProps> = ({
<AddSampleRecordModal
properties={properties}
show={addingRecord}
onRecordCreated={saveRecord}
onRecordCreated={(record) => {
setRecordId(record?.id);
}}
onHide={() => {
setAddingRecord(false);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const Page: NextPageWithInferredProps<typeof getServerSideProps> = ({
async function exportRecord() {
setLoading(true);
successHandler.set({ message: "enqueued for export..." });
const response: Actions.RecordExport = await client.request(
const response = await client.request<Actions.RecordExport>(
"post",
`/record/${record.id}/export`
);
Expand Down
1 change: 0 additions & 1 deletion ui/ui-components/utils/apiData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ export namespace Actions {
export type DestinationView = AsyncReturnType<
typeof DestinationView.prototype.runWithinTransaction
>;

export type ExportView = AsyncReturnType<
typeof ExportView.prototype.runWithinTransaction
>;
Expand Down

0 comments on commit b26d0bd

Please sign in to comment.