Skip to content

feat(workspace): copy as command #3544

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

Merged
merged 8 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
8 changes: 8 additions & 0 deletions packages/plugin-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@
"command": "dendron.copyCodespaceURL",
"title": "Dendron: Copy Codespace URL"
},
{
"command": "dendron.copyAs",
"title": "Dendron: Copy As"
},
{
"command": "dendron.delete",
"title": "Dendron: Delete"
Expand Down Expand Up @@ -660,6 +664,10 @@
"command": "dendron.copyCodespaceURL",
"when": "dendron:pluginActive && shellExecutionSupported"
},
{
"command": "dendron.copyAs",
"when": "dendron:pluginActive && shellExecutionSupported"
},
{
"command": "dendron.delete",
"when": "dendron:pluginActive && shellExecutionSupported"
Expand Down
9 changes: 9 additions & 0 deletions packages/plugin-core/src/ExtensionProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { DendronError } from "@dendronhq/common-all";
import { PodUtils } from "@dendronhq/pods-core";
import { ensureDirSync } from "fs-extra";
import _ from "lodash";
import { IDendronExtension } from "./dendronExtensionInterface";
import { IWSUtilsV2 } from "./WSUtilsV2Interface";
Expand Down Expand Up @@ -51,4 +53,11 @@ export class ExtensionProvider {
static register(extension: IDendronExtension) {
ExtensionProvider.extension = extension;
}

static getPodsDir() {
const { wsRoot } = ExtensionProvider.getDWorkspace();
const podsDir = PodUtils.getPodDir({ wsRoot });
ensureDirSync(podsDir);
return podsDir;
}
}
78 changes: 78 additions & 0 deletions packages/plugin-core/src/commands/CopyAsCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { assertUnreachable } from "@dendronhq/common-all";
import {
CopyAsFormat,
getAllCopyAsFormat,
JSONV2PodConfig,
MarkdownV2PodConfig,
PodExportScope,
PodV2Types,
} from "@dendronhq/pods-core";
import _ from "lodash";
import { PodCommandFactory } from "../components/pods/PodCommandFactory";
import { PodUIControls } from "../components/pods/PodControls";
import { DENDRON_COMMANDS } from "../constants";
import { VSCodeUtils } from "../vsCodeUtils";
import { BasicCommand, CodeCommandInstance } from "./base";

type CommandOutput = void;
type CommandInput = CodeCommandInstance;
type CommandOpts = CodeCommandInstance;

/**
* Command that will find the appropriate export command to run, and then run
* it. This is the UI entry point for all export pod functionality.
*/
export class CopyAsCommand extends BasicCommand<
CommandOpts,
CommandOutput,
CommandInput
> {
public format: CopyAsFormat[];
key = DENDRON_COMMANDS.COPY_AS.key;

constructor(_name?: string) {
super(_name);
this.format = getAllCopyAsFormat();
}

async sanityCheck(_opts?: Partial<CodeCommandInstance> | undefined) {
if (_.isUndefined(VSCodeUtils.getActiveTextEditor())) {
return "you must have a note open to execute this command";
}
return;
}

async gatherInputs() {
const format = await PodUIControls.promtToSelectCopyAsFormat();

if (!format) {
return;
}
switch (format) {
case CopyAsFormat.JSON: {
const config: JSONV2PodConfig = {
destination: "clipboard",
exportScope: PodExportScope.Note,
podType: PodV2Types.JSONExportV2,
podId: "copyAs.json", // dummy value, required property
};
return PodCommandFactory.createPodCommandForStoredConfig({ config });
}
case CopyAsFormat.MARKDOWN: {
const config: MarkdownV2PodConfig = {
destination: "clipboard",
exportScope: PodExportScope.Note,
podType: PodV2Types.MarkdownExportV2,
podId: "copyAs.markdown", // dummy value, required property
};
return PodCommandFactory.createPodCommandForStoredConfig({ config });
}
default:
assertUnreachable(format);
}
}

async execute(opts: CommandOpts) {
opts.run();
}
}
2 changes: 2 additions & 0 deletions packages/plugin-core/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import { CreateNoteCommand } from "./CreateNoteCommand";
import { MergeNoteCommand } from "./MergeNoteCommand";
import { CopyCodespaceURL } from "./CopyCodespaceURL";
import { MoveSelectionToCommand } from "./MoveSelectionToCommand";
import { CopyAsCommand } from "./CopyAsCommand";

/**
* Note: this does not contain commands that have parametered constructors, as
Expand Down Expand Up @@ -181,6 +182,7 @@ const ALL_COMMANDS = [
MergeNoteCommand,
CreateNoteCommand,
CopyCodespaceURL,
CopyAsCommand,
] as CodeCommandConstructor[];

export { ALL_COMMANDS };
12 changes: 7 additions & 5 deletions packages/plugin-core/src/commands/pods/ExportPodV2Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ export class ExportPodV2Command extends BaseCommand<

// If a podId is passed in, use this instead of prompting the user
if (args?.podId) {
return PodCommandFactory.createPodCommandForStoredConfig(
{ podId: args.podId },
args.exportScope
);
return PodCommandFactory.createPodCommandForStoredConfig({
configId: { podId: args.podId },
exportScope: args.exportScope,
});
}

const exportChoice = await PodUIControls.promptForExportConfigOrNewExport();
Expand All @@ -66,7 +66,9 @@ export class ExportPodV2Command extends BaseCommand<
}
return PodCommandFactory.createPodCommandForPodType(podType);
} else {
return PodCommandFactory.createPodCommandForStoredConfig(exportChoice);
return PodCommandFactory.createPodCommandForStoredConfig({
configId: exportChoice,
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,19 @@ export class JSONExportPodCommand extends BaseExportPodCommand<
exportReturnValue: JSONExportReturnType;
config: RunnableJSONV2PodConfig;
}) {
let successMessage = "Finished running JSON export pod.";
const data = exportReturnValue.data?.exportedNotes;
if (_.isString(data) && config.destination === "clipboard") {
vscode.env.clipboard.writeText(data);
successMessage += " Content is copied to the clipboard";
}
if (ResponseUtil.hasError(exportReturnValue)) {
const errorMsg = `Finished JSON Export. Error encountered: ${ErrorFactory.safeStringify(
exportReturnValue.error
)}`;
this.L.error(errorMsg);
} else {
vscode.window.showInformationMessage("Finished running JSON export pod.");
vscode.window.showInformationMessage(successMessage);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,10 @@ export class MarkdownExportPodCommand extends BaseExportPodCommand<
config: RunnableMarkdownV2PodConfig;
}) {
const data = exportReturnValue.data?.exportedNotes;
let successMessage = "Finished running Markdown export pod.";
if (_.isString(data) && config.destination === "clipboard") {
vscode.env.clipboard.writeText(data);
successMessage += " Content is copied to the clipboard";
}
const count = data?.length ?? 0;
if (ResponseUtil.hasError(exportReturnValue)) {
Expand All @@ -133,9 +135,7 @@ export class MarkdownExportPodCommand extends BaseExportPodCommand<
)}`;
this.L.error(errorMsg);
} else {
vscode.window.showInformationMessage(
"Finished running Markdown export pod."
);
vscode.window.showInformationMessage(successMessage);
}
}

Expand Down
56 changes: 40 additions & 16 deletions packages/plugin-core/src/components/pods/PodCommandFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { JSONExportPodCommand } from "../../commands/pods/JSONExportPodCommand";
import { MarkdownExportPodCommand } from "../../commands/pods/MarkdownExportPodCommand";
import { NotionExportPodCommand } from "../../commands/pods/NotionExportPodCommand";
import { ExtensionProvider } from "../../ExtensionProvider";
import { getExtension } from "../../workspace";

export class PodCommandFactory {
/**
Expand All @@ -22,27 +21,52 @@ export class PodCommandFactory {
* @param configId
* @returns A pod command configured with the found configuration
*/
public static createPodCommandForStoredConfig(
configId: Pick<ExportPodConfigurationV2, "podId">,
exportScope?: PodExportScope
): CodeCommandInstance {
const storedConfig = PodV2ConfigManager.getPodConfigById({
podsDir: path.join(getExtension().podsDir, "custom"),
opts: configId,
});

if (!storedConfig) {
public static createPodCommandForStoredConfig({
configId,
exportScope,
config,
}: {
configId?: Pick<ExportPodConfigurationV2, "podId">;
exportScope?: PodExportScope;
config?: ExportPodConfigurationV2 & { destination?: string };
}): CodeCommandInstance {
// configId is a required param for all cases except when called from CopyAsCommand. It sends a predefined config
if (!configId && !config) {
throw new DendronError({
message: `No pod config with id ${configId.podId} found.`,
message: `Please provide a config id to continue.`,
});
}
// overrides the exportScope of stored config with the exportScope passed in args
if (exportScope) {
storedConfig.exportScope = exportScope;
let podType: PodV2Types;
let storedConfig: ExportPodConfigurationV2 | undefined;
if (config) {
podType = config.podType;
storedConfig = config;
} else {
if (!configId) {
throw new DendronError({
message: `Please provide a config id`,
});
}

storedConfig = PodV2ConfigManager.getPodConfigById({
podsDir: path.join(ExtensionProvider.getPodsDir(), "custom"),
opts: configId,
});

if (!storedConfig) {
throw new DendronError({
message: `No pod config with id ${configId.podId} found.`,
});
}
// overrides the exportScope of stored config with the exportScope passed in args
if (exportScope) {
storedConfig.exportScope = exportScope;
}
podType = storedConfig.podType;
}
let cmdWithArgs: CodeCommandInstance;
const extension = ExtensionProvider.getExtension();
switch (storedConfig.podType) {
switch (podType) {
case PodV2Types.AirtableExportV2: {
const airtableCmd = new AirtableExportPodCommand(extension);
cmdWithArgs = {
Expand Down
23 changes: 22 additions & 1 deletion packages/plugin-core/src/components/pods/PodControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { assertUnreachable, DVault, VaultUtils } from "@dendronhq/common-all";
import { DLogger } from "@dendronhq/common-server";
import { HistoryEvent } from "@dendronhq/engine-server";
import {
CopyAsFormat,
ExportPodConfigurationV2,
ExternalConnectionManager,
ExternalService,
ExternalTarget,
getAllCopyAsFormat,
PodExportScope,
PodUtils,
PodV2ConfigManager,
Expand All @@ -28,7 +30,7 @@ import { NoteLookupProviderUtils } from "../lookup/NoteLookupProviderUtils";
*/
export class PodUIControls {
/**
* Prompts the user with a quick-pick to select a {@link PodConfigurationV2}
* Prompts the user with a quick-pick to select a {@link ExportPodConfigurationV2}
* by its podId. Furthermore, there is an option to create a new export
* configuration intead.
* @returns
Expand Down Expand Up @@ -552,4 +554,23 @@ export class PodUIControls {
});
return podIdQuickPick?.label;
}

/**
* Prompt user to select the copy as format
*/
public static async promtToSelectCopyAsFormat(): Promise<
CopyAsFormat | undefined
> {
const items = getAllCopyAsFormat().map<QuickPickItem>((value) => {
return {
label: value,
detail: `Format Dendron note to ${value} and copy it to the clipboard`,
};
});
const formatQuickPick = await VSCodeUtils.showQuickPick(items, {
title: "Pick the format to convert",
ignoreFocusOut: true,
});
return formatQuickPick?.label as CopyAsFormat;
}
}
5 changes: 5 additions & 0 deletions packages/plugin-core/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ export const DENDRON_COMMANDS: { [key: string]: CommandEntry } = {
title: `${CMD_PREFIX} Copy Codespace URL`,
when: `${DendronContext.PLUGIN_ACTIVE} && shellExecutionSupported`,
},
COPY_AS: {
key: "dendron.copyAs",
title: `${CMD_PREFIX} Copy As`,
when: `${DendronContext.PLUGIN_ACTIVE} && shellExecutionSupported`,
},
DELETE: {
key: "dendron.delete",
title: `${CMD_PREFIX} Delete`,
Expand Down
Loading