Compare commits

...

11 Commits

Author SHA1 Message Date
Elio Struyf
d2ae94df34 Merge pull request #177 from estruyf/dev 2021-11-15 10:42:15 +01:00
Elio Struyf
f799613b1a Update changelog 2021-11-15 10:38:46 +01:00
Elio Struyf
3f057a01d8 Removed char 2021-11-12 15:36:51 +01:00
Elio Struyf
3ad5136735 #173 - Persistent sorting 2021-11-12 12:11:46 +01:00
Elio Struyf
e201ce6f83 updated changelog 2021-11-12 10:55:26 +01:00
Elio Struyf
383a3a7d4c Updated changelog 2021-11-10 15:19:12 +01:00
Elio Struyf
8261f1de1b #173 - Allow to specify your own sorting 2021-11-10 15:18:35 +01:00
Elio Struyf
5b38e6fa56 Updated changelog 2021-11-10 11:55:33 +01:00
Elio Struyf
717f34bc85 #174 - Enhancement for excluding sub-directories 2021-11-10 11:54:39 +01:00
Elio Struyf
47fb2a90a9 5.5.0 2021-11-10 11:16:24 +01:00
Elio Struyf
85a7221895 Updated flows 2021-11-09 10:02:38 +01:00
27 changed files with 254 additions and 60 deletions

View File

@@ -25,3 +25,6 @@ jobs:
- name: Publish
run: npx vsce publish -p ${{ secrets.VSCE_PAT }} --baseImagesUrl https://raw.githubusercontent.com/estruyf/vscode-front-matter/dev
- name: Publish to open-vsx.org
run: npx ovsx publish -p ${{ secrets.OPEN_VSX_PAT }}

View File

@@ -26,3 +26,5 @@ jobs:
- name: Publish
run: npx vsce publish -p ${{ secrets.VSCE_PAT }}
- name: Publish to open-vsx.org
run: npx ovsx publish -p ${{ secrets.OPEN_VSX_PAT }}

View File

@@ -1,5 +1,14 @@
# Change Log
## [5.5.0] - 2021-11-15
As from this version onwards, the extension will be published to [open-vsx.org](https://open-vsx.org/).
### 🎨 Enhancements
- [#173](https://github.com/estruyf/vscode-front-matter/issues/173): Allow to specify your own sorting for the content dashboard
- [#174](https://github.com/estruyf/vscode-front-matter/issues/174): Added option to exclude sub-directories from page/markdown content retrieval
## [5.4.0] - 2021-11-05
### 🎨 Enhancements

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "vscode-front-matter-beta",
"version": "5.4.0",
"version": "5.5.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -3,7 +3,7 @@
"displayName": "Front Matter",
"description": "An essential Visual Studio Code extension when you want to manage the markdown pages of your static site like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...",
"icon": "assets/frontmatter-teal-128x128.png",
"version": "5.4.0",
"version": "5.5.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
@@ -154,6 +154,11 @@
"path": {
"type": "string",
"description": "Path of the folder"
},
"excludeSubdir": {
"type": "boolean",
"default": false,
"description": "Exclude sub-directories"
}
},
"additionalProperties": false,
@@ -170,6 +175,48 @@
"markdownDescription": "Specify the folder name where all your assets are located. For instance in Hugo this is the `static` folder. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.content.publicfolder)",
"scope": "Content"
},
"frontMatter.content.sorting": {
"type": "object",
"default": [],
"markdownDescription": "Define the sorting options for your dashboard content. [Check in the docs](https://frontmatter.codes/docs/settings#frontMatter.content.sorting)",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Name of the sorting label"
},
"name": {
"type": "string",
"description": "Name of the metadata field to sort by"
},
"order": {
"type": "string",
"enum": [
"asc",
"desc"
],
"description": "Order of the sorting"
},
"type": {
"type": "string",
"default": "string",
"enum": [
"string",
"date"
],
"description": "Type of the field value"
}
},
"additionalProperties": false,
"required": [
"title",
"name",
"order"
]
},
"scope": "Content"
},
"frontMatter.custom.scripts": {
"type": "array",
"default": [],
@@ -792,4 +839,4 @@
"dependencies": {
"@docsearch/js": "^3.0.0-alpha.40"
}
}
}

View File

@@ -1,10 +1,10 @@
import { SETTINGS_CONTENT_STATIC_FOLDER, SETTING_DATE_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTING_TAXONOMY_CONTENT_TYPES, DefaultFields, HOME_PAGE_NAVIGATION_ID, ExtensionState, COMMAND_NAME, SETTINGS_FRAMEWORK_ID, SETTINGS_CONTENT_DRAFT_FIELD } from '../constants';
import { SETTINGS_CONTENT_STATIC_FOLDER, SETTING_DATE_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTING_TAXONOMY_CONTENT_TYPES, DefaultFields, HOME_PAGE_NAVIGATION_ID, ExtensionState, COMMAND_NAME, SETTINGS_FRAMEWORK_ID, SETTINGS_CONTENT_DRAFT_FIELD, SETTINGS_CONTENT_SORTING } from '../constants';
import { ArticleHelper } from './../helpers/ArticleHelper';
import { basename, dirname, extname, join, parse } from "path";
import { existsSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
import { commands, Uri, ViewColumn, Webview, WebviewPanel, window, workspace, env, Position } from "vscode";
import { Settings as SettingsHelper } from '../helpers';
import { DraftField, Framework, TaxonomyType } from '../models';
import { DraftField, Framework, SortingSetting, TaxonomyType } from '../models';
import { Folders } from './Folders';
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { DashboardMessage } from '../dashboardWebView/DashboardMessage';
@@ -39,7 +39,7 @@ export class Dashboard {
return Dashboard._viewData;
}
/** 
/**
* Init the dashboard
*/
public static async init() {
@@ -192,6 +192,11 @@ export class Dashboard {
case DashboardMessage.setFramework:
Dashboard.setFramework(msg?.data);
break;
case DashboardMessage.setState:
if (msg?.data?.key && msg?.data?.value) {
Extension.getInstance().setState(msg?.data?.key, msg?.data?.value, "workspace");
}
break;
}
});
}
@@ -280,9 +285,13 @@ export class Dashboard {
mediaSnippet: SettingsHelper.get<string[]>(SETTINGS_DASHBOARD_MEDIA_SNIPPET) || [],
contentTypes: SettingsHelper.get(SETTING_TAXONOMY_CONTENT_TYPES) || [],
draftField: SettingsHelper.get<DraftField>(SETTINGS_CONTENT_DRAFT_FIELD),
contentFolders: Folders.get().map(f => f.path),
customSorting: SettingsHelper.get<SortingSetting[]>(SETTINGS_CONTENT_SORTING),
contentFolders: Folders.get(),
crntFramework: SettingsHelper.get<string>(SETTINGS_FRAMEWORK_ID),
framework: (!isInitialized && wsFolder) ? FrameworkDetector.get(wsFolder.fsPath) : null,
dashboardState: {
sorting: await ext.getState<ViewType | undefined>(ExtensionState.Dashboard.Sorting, "workspace")
}
} as Settings
});
}

View File

@@ -210,8 +210,8 @@ export class Folders {
if (projectStart) {
projectStart = projectStart.replace(/\\/g, '/');
projectStart = projectStart.startsWith('/') ? projectStart.substr(1) : projectStart;
const mdFiles = await workspace.findFiles(join(projectStart, '**/*.md'));
const mdxFiles = await workspace.findFiles(join(projectStart, '**/*.mdx'));
const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md'));
const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx'));
let files = [...mdFiles, ...mdxFiles];
if (files) {
let fileStats: FileInfo[] = [];
@@ -263,7 +263,7 @@ export class Folders {
const folders: ContentFolder[] = Settings.get(SETTINGS_CONTENT_PAGE_FOLDERS) as ContentFolder[];
return folders.map(folder => ({
title: folder.title,
...folder,
path: Folders.absWsFolder(folder, wsFolder)
}));
}
@@ -274,10 +274,12 @@ export class Folders {
*/
private static async update(folders: ContentFolder[]) {
const wsFolder = Folders.getWorkspaceFolder();
let folderDetails = folders.map(folder => ({
title: folder.title,
...folder,
path: Folders.relWsFolder(folder, wsFolder)
}));
await Settings.update(SETTINGS_CONTENT_PAGE_FOLDERS, folderDetails, true);
}

View File

@@ -5,4 +5,8 @@ export const ExtensionState = {
Version: `frontMatter:Version`,
SettingPromoted: `frontMatter:Settings:Promoted`,
MoveTemplatesFolder: `frontMatter:Templates:Move`,
Dashboard: {
Sorting: `frontMatter:Dashboard:Sorting`,
}
};

View File

@@ -40,6 +40,7 @@ export const SETTINGS_CONTENT_PAGE_FOLDERS = "content.pageFolders";
export const SETTINGS_CONTENT_STATIC_FOLDER = "content.publicFolder";
export const SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT = "content.fmHighlight";
export const SETTINGS_CONTENT_DRAFT_FIELD = "content.draftField";
export const SETTINGS_CONTENT_SORTING = "content.sorting";
export const SETTINGS_DASHBOARD_OPENONSTART = "dashboard.openOnStart";
export const SETTINGS_DASHBOARD_MEDIA_SNIPPET = "dashboard.mediaSnippet";

View File

@@ -19,4 +19,5 @@ export enum DashboardMessage {
updateMediaMetadata = 'updateMediaMetadata',
createMediaFolder = 'createMediaFolder',
setFramework = 'setFramework',
setState = 'setState',
}

View File

@@ -31,9 +31,10 @@ export const Breadcrumb: React.FunctionComponent<IBreadcrumbProps> = (props: Rea
return false;
}
}
1
for (let i = 0; i < contentFolders.length; i++) {
const contentFolder = parseWinPath(contentFolders[i]) as string;
const folder = contentFolders[i];
const contentFolder = parseWinPath(folder.path) as string;
const relContentPath = folderPath.replace(contentFolder, '');
return relContentPath.length > 1 && folderPath.startsWith(contentFolder);
}

View File

@@ -1,7 +1,7 @@
import { XCircleIcon } from '@heroicons/react/solid';
import * as React from 'react';
import { useRecoilValue, useResetRecoilState } from 'recoil';
import { SortingSelector, FolderSelector, TagSelector, CategorySelector, SortingAtom, DEFAULT_SORTING_OPTION, FolderAtom, DEFAULT_FOLDER_STATE, TagAtom, CategoryAtom, DEFAULT_TAG_STATE, DEFAULT_CATEGORY_STATE } from '../../state';
import { FolderSelector, TagSelector, CategorySelector, SortingAtom, FolderAtom, DEFAULT_FOLDER_STATE, TagAtom, CategoryAtom, DEFAULT_TAG_STATE, DEFAULT_CATEGORY_STATE } from '../../state';
import { DefaultValue } from 'recoil';
@@ -17,7 +17,6 @@ export interface IClearFiltersProps {}
export const ClearFilters: React.FunctionComponent<IClearFiltersProps> = (props: React.PropsWithChildren<IClearFiltersProps>) => {
const [ show, setShow ] = React.useState(false);
const sorting = useRecoilValue(SortingSelector);
const folder = useRecoilValue(FolderSelector);
const tag = useRecoilValue(TagSelector);
const category = useRecoilValue(CategorySelector);
@@ -36,19 +35,19 @@ export const ClearFilters: React.FunctionComponent<IClearFiltersProps> = (props:
};
React.useEffect(() => {
if (sorting !== DEFAULT_SORTING_OPTION || folder !== DEFAULT_FOLDER_STATE || tag !== DEFAULT_TAG_STATE || category !== DEFAULT_CATEGORY_STATE) {
if (folder !== DEFAULT_FOLDER_STATE || tag !== DEFAULT_TAG_STATE || category !== DEFAULT_CATEGORY_STATE) {
setShow(true);
} else {
setShow(false);
}
}, [sorting, folder, tag, category]);
}, [folder, tag, category]);
if (!show) return null;
return (
<button className="flex items-center hover:text-teal-600" onClick={reset} title={`Clear filters, grouping, and sorting`}>
<XCircleIcon className={`inline-block w-5 h-5 mr-1`} /><span>Clear</span>
<span className={`sr-only`}> filters, grouping, and sorting</span>
<span className={`sr-only`}> filters and grouping</span>
</button>
);
};

View File

@@ -1,19 +1,19 @@
import { Menu } from '@headlessui/react';
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { FolderAtom } from '../../state';
import { useRecoilState, useRecoilValue } from 'recoil';
import { FolderAtom, SettingsSelector } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
export interface IFoldersProps {
folders: string[];
}
export interface IFoldersProps {}
const DEFAULT_TYPE = "All types";
export const Folders: React.FunctionComponent<IFoldersProps> = ({folders}: React.PropsWithChildren<IFoldersProps>) => {
export const Folders: React.FunctionComponent<IFoldersProps> = ({}: React.PropsWithChildren<IFoldersProps>) => {
const [ crntFolder, setCrntFolder ] = useRecoilState(FolderAtom);
const settings = useRecoilValue(SettingsSelector);
const contentFolders = settings?.contentFolders || [];
if (folders.length <= 1) {
if (contentFolders.length <= 1) {
return null;
}
@@ -29,12 +29,12 @@ export const Folders: React.FunctionComponent<IFoldersProps> = ({folders}: React
isCurrent={!crntFolder}
onClick={(value) => setCrntFolder(value)} />
{folders.map((option) => (
{contentFolders.map((option) => (
<MenuItem
key={option}
title={option}
value={option}
isCurrent={option === crntFolder}
key={option.title}
title={option.title}
value={option.title}
isCurrent={option.title === crntFolder}
onClick={(value) => setCrntFolder(value)} />
))}
</MenuItems>

View File

@@ -98,7 +98,7 @@ export const Header: React.FunctionComponent<IHeaderProps> = ({totalPages, folde
<div className={`py-4 px-5 w-full flex items-center justify-between lg:justify-end space-x-4 lg:space-x-6 xl:space-x-8 bg-gray-200 border-b border-gray-300 dark:bg-vulcan-400 dark:border-vulcan-100`}>
<ClearFilters />
<Folders folders={folders || []} />
<Folders />
<Filter label={`Tag`} activeItem={crntTag} items={settings?.tags || []} onClick={(value) => setCrntTag(value)} />

View File

@@ -1,37 +1,64 @@
import { Messenger } from '@estruyf/vscode/dist/client';
import { Menu } from '@headlessui/react';
import * as React from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { ExtensionState } from '../../../constants';
import { SortOrder, SortType } from '../../../models';
import { SortOption } from '../../constants/SortOption';
import { SearchSelector, SortingAtom } from '../../state';
import { DashboardMessage } from '../../DashboardMessage';
import { SortingOption } from '../../models/SortingOption';
import { SearchSelector, SettingsSelector, SortingAtom } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
export interface ISortingProps {}
export const sortOptions = [
{ name: "Last modified", id: SortOption.LastModified },
{ name: "By filename (asc)", id: SortOption.FileNameAsc },
{ name: "By filename (desc)", id: SortOption.FileNameDesc },
export const sortOptions: SortingOption[] = [
{ name: "Last modified", id: SortOption.LastModified, order: SortOrder.desc, type: SortType.string },
{ name: "By filename (asc)", id: SortOption.FileNameAsc, order: SortOrder.asc, type: SortType.string },
{ name: "By filename (desc)", id: SortOption.FileNameDesc, order: SortOrder.desc, type: SortType.string },
];
export const Sorting: React.FunctionComponent<ISortingProps> = ({}: React.PropsWithChildren<ISortingProps>) => {
const [ crntSorting, setCrntSorting ] = useRecoilState(SortingAtom);
const searchValue = useRecoilValue(SearchSelector);
const settings = useRecoilValue(SettingsSelector);
const crntSort = sortOptions.find(x => x.id === crntSorting);
const updateSorting = (value: SortingOption) => {
Messenger.send(DashboardMessage.setState, {
key: ExtensionState.Dashboard.Sorting,
value: value
})
setCrntSorting(value)
};
let allOptions = [...sortOptions];
if (settings?.customSorting) {
allOptions = [...allOptions, ...settings.customSorting.map((s) => ({
title: s.title || s.name,
name: s.name,
id: `${s.name}-${s.order}`,
order: s.order,
type: s.type
}))];
}
let crntSort = allOptions.find(x => x.id === crntSorting?.id) || sortOptions[0];
return (
<div className="flex items-center">
<Menu as="div" className="relative z-10 inline-block text-left">
<MenuButton label={`Sort by`} title={crntSort?.name || ""} disabled={!!searchValue} />
<MenuButton label={`Sort by`} title={crntSort?.title || crntSort?.name || ""} disabled={!!searchValue} />
<MenuItems>
{sortOptions.map((option) => (
{allOptions.map((option) => (
<MenuItem
key={option.id}
title={option.name}
value={option.id}
isCurrent={option.id === crntSorting}
onClick={(value) => setCrntSorting(value)} />
title={option.title || option.name}
value={option}
isCurrent={option.id === crntSorting?.id}
onClick={(value) => updateSorting(value)} />
))}
</MenuItems>
</Menu>

View File

@@ -1,5 +1,5 @@
export enum SortOption {
LastModified = 1,
FileNameAsc,
FileNameDesc
LastModified = "LastModified",
FileNameAsc = "FileNameAsc",
FileNameDesc = "FileNameDesc"
}

View File

@@ -3,8 +3,10 @@ import { SortOption } from '../constants/SortOption';
import { Tab } from '../constants/Tab';
import { Page } from '../models/Page';
import Fuse from 'fuse.js';
import { useRecoilValue } from 'recoil';
import { CategorySelector, FolderSelector, SearchSelector, SettingsSelector, SortingSelector, TabSelector, TagSelector } from '../state';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CategorySelector, FolderSelector, SearchSelector, SettingsSelector, SortingAtom, TabSelector, TagSelector } from '../state';
import { SortOrder, SortType } from '../../models';
import { DateHelper } from '../../helpers/DateHelper';
const fuseOptions: Fuse.IFuseOptions<Page> = {
keys: [
@@ -16,16 +18,48 @@ const fuseOptions: Fuse.IFuseOptions<Page> = {
export default function usePages(pages: Page[]) {
const [ pageItems, setPageItems ] = useState<Page[]>([]);
const [ sorting, setSorting ] = useRecoilState(SortingAtom);
const settings = useRecoilValue(SettingsSelector);
const tab = useRecoilValue(TabSelector);
const sorting = useRecoilValue(SortingSelector);
const folder = useRecoilValue(FolderSelector);
const search = useRecoilValue(SearchSelector);
const tag = useRecoilValue(TagSelector);
const category = useRecoilValue(CategorySelector);
// Sort field value alphabetically
const sortAlphabetically = (property: string) => {
return (a: Page, b: Page) => {
if (a[property] < b[property]) {
return -1;
}
if (a[property] > b[property]) {
return 1;
}
return 0;
};
};
// Sort by date
const sortByDate = (property: string) => {
return (a: Page, b: Page) => {
const dateA = DateHelper.tryParse(a[property]);
const dateB = DateHelper.tryParse(b[property]);
return (dateA || new Date(0)).getTime() - (dateB || new Date(0)).getTime();
};
};
useEffect(() => {
const draftField = settings?.draftField;
let usedSorting = sorting;
if (!usedSorting) {
const lastSort = settings?.dashboardState.sorting;
if (lastSort) {
setSorting(lastSort);
return;
}
}
// Check if search needs to be performed
let searchedPages = pages;
@@ -58,12 +92,26 @@ export default function usePages(pages: Page[]) {
// Sort the pages
let pagesSorted: Page[] = Object.assign([], pagesToShow);
if (!search) {
if (sorting === SortOption.FileNameAsc) {
pagesSorted = pagesToShow.sort((a, b) => a.fmFileName.toLowerCase().localeCompare(b.fmFileName.toLowerCase()));
} else if (sorting === SortOption.FileNameDesc) {
pagesSorted = pagesToShow.sort((a, b) => b.fmFileName.toLowerCase().localeCompare(a.fmFileName.toLowerCase()));
if (sorting && sorting.id === SortOption.FileNameAsc) {
pagesSorted = pagesSorted.sort(sortAlphabetically("fmFileName"));
} else if (sorting && sorting.id === SortOption.FileNameDesc) {
pagesSorted = pagesSorted.sort(sortAlphabetically("fmFileName")).reverse();
} else if (sorting && sorting.id === SortOption.LastModified) {
pagesSorted = pagesSorted.sort((a, b) => b.fmModified - a.fmModified);
} else if (sorting && sorting.id && sorting.name) {
const { order, name, type } = sorting;
if (type === SortType.string) {
pagesSorted = pagesSorted.sort(sortAlphabetically(name));
} else if (type === SortType.date) {
pagesSorted = pagesSorted.sort(sortByDate(name));
}
if (order === SortOrder.desc) {
pagesSorted = pagesSorted.reverse();
}
} else {
pagesSorted = pagesToShow.sort((a, b) => b.fmModified - a.fmModified);
pagesSorted = pagesSorted.sort((a, b) => b.fmModified - a.fmModified);
}
}

View File

@@ -1,7 +1,8 @@
import { VersionInfo } from '../../models/VersionInfo';
import { ViewType } from '../state';
import { ContentFolder } from '../../models/ContentFolder';
import { ContentType, DraftField, Framework } from '../../models';
import { ContentType, DraftField, Framework, SortingSetting } from '../../models';
import { SortingOption } from './SortingOption';
export interface Settings {
beta: boolean;
@@ -16,8 +17,14 @@ export interface Settings {
pageViewType: ViewType | undefined;
mediaSnippet: string[];
contentTypes: ContentType[];
contentFolders: string[];
contentFolders: ContentFolder[];
crntFramework: string;
framework: Framework | null | undefined;
draftField: DraftField | null | undefined;
customSorting: SortingSetting[] | undefined;
dashboardState: DashboardState;
}
export interface DashboardState {
sorting: SortingOption | null | undefined;
}

View File

@@ -0,0 +1,10 @@
import { SortOrder, SortType } from "../../models";
import { SortOption } from "../constants/SortOption";
export interface SortingOption {
title?: string;
name: string;
id: SortOption | string;
order: SortOrder,
type: SortType;
}

View File

@@ -1,9 +1,10 @@
import { atom } from 'recoil';
import { SortOption } from '../../constants/SortOption';
import { SortingOption } from '../../models/SortingOption';
export const DEFAULT_SORTING_OPTION = SortOption.LastModified;
export const SortingAtom = atom<SortOption>({
export const SortingAtom = atom<SortingOption | null>({
key: 'SortingAtom',
default: DEFAULT_SORTING_OPTION
default: null
});

View File

@@ -91,11 +91,13 @@ export class ArticleHelper {
}
}
}
return matter.stringify(content, data, ({
...TomlEngine,
...langOpts,
noArrayIndent: !indentArray,
skipInvalid: true,
noCompatMode: true,
lineWidth: 500,
indent: spaces || 2
} as DumpOptions as any));

View File

@@ -115,7 +115,7 @@ export class Extension {
const projectFolder = basename(workspace?.fsPath || "");
const paths = folders.map((folder: any) => ({
title: folder.title,
...folder,
path: `${WORKSPACE_PLACEHOLDER}${folder.fsPath.split(projectFolder).slice(1).join('')}`.split('\\').join('/')
}));

View File

@@ -1,4 +1,6 @@
export interface ContentFolder {
title: string;
path: string;
excludeSubdir?: boolean;
}

4
src/models/SortOrder.ts Normal file
View File

@@ -0,0 +1,4 @@
export enum SortOrder {
asc = 'asc',
desc = 'desc'
}

4
src/models/SortType.ts Normal file
View File

@@ -0,0 +1,4 @@
export enum SortType {
string = 'string',
date = 'date'
}

View File

@@ -0,0 +1,8 @@
import { SortOrder, SortType } from ".";
export interface SortingSetting {
title: string;
name: string;
order: SortOrder;
type: SortType;
}

View File

@@ -5,5 +5,8 @@ export * from './DraftField';
export * from './Framework';
export * from './MediaPaths';
export * from './PanelSettings';
export * from './SortOrder';
export * from './SortType';
export * from './SortingSetting';
export * from './TaxonomyType';
export * from './VersionInfo';