mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-05 09:21:39 +02:00
Move taxonomy value
This commit is contained in:
@@ -49,6 +49,7 @@ export enum DashboardMessage {
|
||||
addToTaxonomy = "addToTaxonomy",
|
||||
createTaxonomy = "createTaxonomy",
|
||||
importTaxonomy = "importTaxonomy",
|
||||
moveTaxonomy = "moveTaxonomy",
|
||||
|
||||
// Other
|
||||
getTheme = 'getTheme',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/outline';
|
||||
import { ArrowCircleUpIcon, ArrowUpIcon, PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { MergeIcon } from '../../../components/icons/MergeIcon';
|
||||
@@ -34,6 +34,13 @@ export const TaxonomyActions: React.FunctionComponent<ITaxonomyActionsProps> = (
|
||||
});
|
||||
}, [field, value]);
|
||||
|
||||
const onMove = useCallback(() => {
|
||||
Messenger.send(DashboardMessage.moveTaxonomy, {
|
||||
type: field,
|
||||
value
|
||||
});
|
||||
}, [field, value]);
|
||||
|
||||
const onDelete = useCallback(() => {
|
||||
Messenger.send(DashboardMessage.deleteTaxonomy, {
|
||||
type: field,
|
||||
@@ -46,7 +53,7 @@ export const TaxonomyActions: React.FunctionComponent<ITaxonomyActionsProps> = (
|
||||
{
|
||||
unmapped && (
|
||||
<button
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-800 dark:hover:text-whisper-600'
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600'
|
||||
type={`button`}
|
||||
title={`Add ${value} to taxonomy settings`}
|
||||
onClick={onAdd}>
|
||||
@@ -55,24 +62,36 @@ export const TaxonomyActions: React.FunctionComponent<ITaxonomyActionsProps> = (
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
<button
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-800 dark:hover:text-whisper-600'
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600'
|
||||
type={`button`}
|
||||
title={`Edit ${value}`}
|
||||
onClick={onEdit}>
|
||||
<PencilIcon className={`w-4 h-4`} aria-hidden={true} />
|
||||
<span className='sr-only'>Edit</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-800 dark:hover:text-whisper-600'
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600'
|
||||
type={`button`}
|
||||
title={`Merge ${value}`}
|
||||
onClick={onMerge}>
|
||||
<MergeIcon className={`w-4 h-4`} aria-hidden={true} />
|
||||
<span className='sr-only'>Merge</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-800 dark:hover:text-whisper-600'
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600'
|
||||
type={`button`}
|
||||
title={`Move to another taxonomy type`}
|
||||
onClick={onMove}>
|
||||
<ArrowCircleUpIcon className={`w-4 h-4`} aria-hidden={true} />
|
||||
<span className='sr-only'>Move to another taxonomy type</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
className='text-gray-500 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600'
|
||||
type={`button`}
|
||||
title={`Delete ${value}`}
|
||||
onClick={onDelete}>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
||||
import { Page } from '../../models';
|
||||
import { SettingsSelector } from '../../state';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { getTaxonomyField } from '../../utils';
|
||||
import { getTaxonomyField } from '../../../helpers/getTaxonomyField';
|
||||
|
||||
export interface ITaxonomyLookupProps {
|
||||
taxonomy: string | null;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TaxonomyData } from '../../../models';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
import { Page } from '../../models';
|
||||
import { SettingsSelector } from '../../state';
|
||||
import { getTaxonomyField } from '../../utils';
|
||||
import { getTaxonomyField } from '../../../helpers/getTaxonomyField';
|
||||
import { TaxonomyActions } from './TaxonomyActions';
|
||||
import { TaxonomyLookup } from './TaxonomyLookup';
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './getTaxonomyField';
|
||||
@@ -1,5 +1,6 @@
|
||||
import { EXTENSION_NAME } from "../constants";
|
||||
import { TaxonomyType } from "../models";
|
||||
import { getTaxonomyField } from './getTaxonomyField';
|
||||
import { EXTENSION_NAME, SETTING_TAXONOMY_CUSTOM } from "../constants";
|
||||
import { CustomTaxonomy, TaxonomyType } from "../models";
|
||||
import { FilesHelper } from "./FilesHelper";
|
||||
import { ProgressLocation, window } from "vscode";
|
||||
import { parseWinPath } from "./parseWinPath";
|
||||
@@ -242,6 +243,101 @@ export class TaxonomyHelper {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a taxonomy value to another taxonomy type
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
public static async move(data: { type: string, value: string }) {
|
||||
const { type, value } = data;
|
||||
|
||||
const customTaxs = Settings.get<CustomTaxonomy[]>(SETTING_TAXONOMY_CUSTOM, true) || [];
|
||||
|
||||
let options = [
|
||||
"tags",
|
||||
"categories",
|
||||
...customTaxs.map(t => t.id)
|
||||
];
|
||||
|
||||
options = options.filter(o => o !== type);
|
||||
|
||||
const answer = await window.showQuickPick(options, {
|
||||
title: `Move the "${value}" to another type`,
|
||||
placeHolder: `Select the type to move to`,
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
|
||||
if (!answer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldType = this.getTypeFromString(type);
|
||||
const newType = this.getTypeFromString(answer);
|
||||
|
||||
window.withProgress({
|
||||
location: ProgressLocation.Notification,
|
||||
title: `${EXTENSION_NAME}: Moving "${value}" from ${type} to "${answer}".`,
|
||||
cancellable: false
|
||||
}, async (progress) => {
|
||||
// Retrieve all the markdown files
|
||||
const allFiles = await FilesHelper.getAllFiles();
|
||||
if (!allFiles) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the initial progress
|
||||
const progressNr = allFiles.length/100;
|
||||
progress.report({ increment: 0});
|
||||
|
||||
let i = 0;
|
||||
for (const file of allFiles) {
|
||||
progress.report({ increment: (++i/progressNr) });
|
||||
|
||||
const mdFile = readFileSync(parseWinPath(file.fsPath), { encoding: "utf8" });
|
||||
|
||||
if (mdFile) {
|
||||
try {
|
||||
const article = FrontMatterParser.fromFile(mdFile);
|
||||
const contentType = ArticleHelper.getContentType(article.data);
|
||||
|
||||
let oldFieldName: string | undefined = getTaxonomyField(type, contentType);
|
||||
let newFieldName: string | undefined = getTaxonomyField(answer, contentType);
|
||||
|
||||
if (oldFieldName && newFieldName && article && article.data) {
|
||||
const { data } = article;
|
||||
let oldTaxonomies: string[] = data[oldFieldName];
|
||||
let newTaxonomies: string[] = data[newFieldName] || [];
|
||||
|
||||
if (oldTaxonomies && oldTaxonomies.length > 0) {
|
||||
const idx = oldTaxonomies.findIndex(o => o === value);
|
||||
|
||||
if (idx !== -1) {
|
||||
newTaxonomies.push(value);
|
||||
|
||||
data[newFieldName] = [...new Set(newTaxonomies)].sort();
|
||||
|
||||
const spaces = window.activeTextEditor?.options?.tabSize;
|
||||
// Update the file
|
||||
writeFileSync(parseWinPath(file.fsPath), FrontMatterParser.toFile(article.content, article.data, mdFile, {
|
||||
indent: spaces || 2
|
||||
} as DumpOptions as any), { encoding: "utf8" });
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Continue with the next file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await this.addToSettings(newType, value, value);
|
||||
|
||||
await this.process("delete", oldType, value);
|
||||
|
||||
Notifications.info(`Move completed.`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the taxonomy value to the settings
|
||||
* @param taxonomyType
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ContentType } from '../../models';
|
||||
import { ContentType } from '../models';
|
||||
|
||||
|
||||
export const getTaxonomyField = (taxonomyType: string, contentType: ContentType): string | undefined => {
|
||||
@@ -27,6 +27,7 @@ export * from './TaxonomyHelper';
|
||||
export * from './Telemetry';
|
||||
export * from './decodeBase64Image';
|
||||
export * from './getNonce';
|
||||
export * from './getTaxonomyField';
|
||||
export * from './isValidFile';
|
||||
export * from './openFileInEditor';
|
||||
export * from './parseWinPath';
|
||||
|
||||
@@ -29,6 +29,9 @@ export class TaxonomyListener extends BaseListener {
|
||||
case DashboardMessage.deleteTaxonomy:
|
||||
TaxonomyHelper.delete(msg.data);
|
||||
break;
|
||||
case DashboardMessage.moveTaxonomy:
|
||||
TaxonomyHelper.move(msg.data);
|
||||
break;
|
||||
case DashboardMessage.addToTaxonomy:
|
||||
TaxonomyHelper.addTaxonomy(msg.data);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user