mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
Add clock updates setting (#106)
* feat: add enable clock updates setting * feat: add event handler for clock updates change * refactor: update description * chore: bump version
This commit is contained in:
parent
8543d800aa
commit
f4f5471ad7
10 changed files with 419 additions and 138 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "vault-explorer",
|
||||
"name": "Vault Explorer",
|
||||
"version": "1.12.1",
|
||||
"version": "1.13.0",
|
||||
"minAppVersion": "1.4.13",
|
||||
"description": "Explore your vault in visual format",
|
||||
"author": "DecafDev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-vault-explorer",
|
||||
"version": "1.12.1",
|
||||
"version": "1.13.0",
|
||||
"description": "Explore your vault in visual format",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
|||
views: {
|
||||
currentView: ViewType.GRID,
|
||||
order: [ViewType.GRID, ViewType.LIST],
|
||||
titleWrapping: "normal"
|
||||
titleWrapping: "normal",
|
||||
enableClockUpdates: true
|
||||
},
|
||||
pageSize: 50,
|
||||
pluginVersion: null
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export type PluginEvent = "file-rename" | "file-create" | "file-delete" | "file-modify" | "metadata-change" | "properties-filter-update" | "folder-rename" | "folder-delete" | "folder-create" | "page-size-setting-change" | "title-wrapping-setting-change" | "property-setting-change" | "device-registration-change";
|
||||
export type PluginEvent = "file-rename" | "file-create" | "file-delete" | "file-modify" | "metadata-change" | "properties-filter-update" | "folder-rename" | "folder-delete" | "folder-create" | "page-size-setting-change" | "title-wrapping-setting-change" | "property-setting-change" | "device-registration-change" | "clock-updates-setting-change"
|
||||
|
||||
export type EventCallback = (...data: unknown[]) => void;
|
||||
|
|
|
|||
16
src/main.ts
16
src/main.ts
|
|
@ -23,6 +23,7 @@ import { loadDeviceId } from './svelte/shared/services/device-id-utils';
|
|||
import License from './svelte/shared/services/license';
|
||||
import { VaultExplorerPluginSettings_1_8_1 } from './types/types-1.8.1';
|
||||
import { VaultExplorerPluginSettings_1_9_1 } from './types/types-1.9.1';
|
||||
import { VaultExplorerPluginSettings_1_12_1 } from './types/types-1.12.1';
|
||||
|
||||
export default class VaultExplorerPlugin extends Plugin {
|
||||
settings: VaultExplorerPluginSettings = DEFAULT_SETTINGS;
|
||||
|
|
@ -292,7 +293,7 @@ export default class VaultExplorerPlugin extends Plugin {
|
|||
if (isVersionLessThan(settingsVersion, "1.10.0")) {
|
||||
console.log("Upgrading settings from version 1.9.1 to 1.10.0");
|
||||
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_9_1;
|
||||
const newData: VaultExplorerPluginSettings = {
|
||||
const newData: VaultExplorerPluginSettings_1_12_1 = {
|
||||
...typedData,
|
||||
filters: {
|
||||
...typedData.filters,
|
||||
|
|
@ -321,6 +322,19 @@ export default class VaultExplorerPlugin extends Plugin {
|
|||
}
|
||||
data = newData as unknown as Record<string, unknown>;
|
||||
}
|
||||
|
||||
if (isVersionLessThan(settingsVersion, "1.13.0")) {
|
||||
console.log("Upgrading settings from version 1.12.1 to 1.13.0");
|
||||
const typedData = (data as unknown) as VaultExplorerPluginSettings_1_12_1;
|
||||
const newData: VaultExplorerPluginSettings = {
|
||||
...typedData,
|
||||
views: {
|
||||
...typedData.views,
|
||||
enableClockUpdates: true
|
||||
}
|
||||
}
|
||||
data = newData as unknown as Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
||||
//Apply default settings. This will make it so we don't need to do migrations for just adding new settings
|
||||
|
|
|
|||
|
|
@ -162,6 +162,19 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
EventManager.getInstance().emit("property-setting-change");
|
||||
}));
|
||||
|
||||
new Setting(containerEl).setName("Updates").setHeading();
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Enable clock updates")
|
||||
.setDesc("When enabled, time values will update every minute. This will cause a refresh of the Vault Explorer view. When disabled, time values will only update when the view is opened.")
|
||||
.addToggle(toggle => toggle
|
||||
.setValue(this.plugin.settings.views.enableClockUpdates)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.views.enableClockUpdates = value;
|
||||
await this.plugin.saveSettings();
|
||||
EventManager.getInstance().emit("clock-updates-setting-change");
|
||||
}));
|
||||
|
||||
new Setting(containerEl).setName("Premium").setHeading();
|
||||
|
||||
this.component = new Component({
|
||||
|
|
@ -193,16 +206,6 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab {
|
|||
});
|
||||
}
|
||||
|
||||
private getSettingMessageClassName(type: "success" | "failure" | "default" = "default") {
|
||||
let className = "vault-explorer-setting-message";
|
||||
if (type === "success") {
|
||||
className += " vault-explorer-setting-message--success";
|
||||
} else if (type === "failure") {
|
||||
className += " vault-explorer-setting-message--failure";
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.component?.$destroy();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
<script lang="ts">
|
||||
// ============================================
|
||||
// Imports
|
||||
// ============================================
|
||||
import Stack from "../shared/components/stack.svelte";
|
||||
import Flex from "../shared/components/flex.svelte";
|
||||
import IconButton from "../shared/components/icon-button.svelte";
|
||||
import Checkbox from "../shared/components/checkbox.svelte";
|
||||
import TabList from "../shared/components/tab-list.svelte";
|
||||
import Tab from "../shared/components/tab.svelte";
|
||||
import { Menu, TFile, TFolder } from "obsidian";
|
||||
import { Menu, TFile } from "obsidian";
|
||||
import PropertiesFilterModal from "src/obsidian/properties-filter-modal";
|
||||
import {
|
||||
FilterGroup,
|
||||
|
|
@ -35,30 +38,16 @@
|
|||
import { FileRenderData } from "./types";
|
||||
import Logger from "js-logger";
|
||||
|
||||
// ============================================
|
||||
// Variables
|
||||
// ============================================
|
||||
let plugin: VaultExplorerPlugin;
|
||||
|
||||
let startOfTodayMillis: number;
|
||||
let startOfThisWeekMillis: number;
|
||||
let startOfLastWeekMillis: number;
|
||||
|
||||
function updateTimeValues() {
|
||||
startOfTodayMillis = getStartOfTodayMillis();
|
||||
startOfThisWeekMillis = getStartOfThisWeekMillis();
|
||||
startOfLastWeekMillis = getStartOfLastWeekMillis();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
updateTimeValues();
|
||||
const interval = setInterval(updateTimeValues, 60000); // Update every minute
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
});
|
||||
|
||||
let folders: string[] = [];
|
||||
let pageSize: number = 0;
|
||||
|
||||
let searchFilter: string = "";
|
||||
let sortFilter: SortFilter = "file-name-asc";
|
||||
let timestampFilter: TimestampFilter = "all";
|
||||
|
|
@ -67,52 +56,69 @@
|
|||
let currentView: ViewType = ViewType.GRID;
|
||||
let filterGroups: FilterGroup[] = [];
|
||||
let selectedFilterGroupId: string = "";
|
||||
|
||||
let frontmatterCacheTime: number = Date.now();
|
||||
let propertySettingTime: number = Date.now();
|
||||
|
||||
let files: TFile[] = [];
|
||||
let timeValuesUpdateInterval: NodeJS.Timer | null = null;
|
||||
|
||||
const debounceSearchFilter = _.debounce((e) => {
|
||||
searchFilter = e.target.value;
|
||||
}, 300);
|
||||
|
||||
const debounceFavoriteFilter = _.debounce((value) => {
|
||||
onlyFavorites = value;
|
||||
}, 300);
|
||||
|
||||
function updateFrontmatterCacheTime() {
|
||||
Logger.trace({
|
||||
fileName: "app/index.ts",
|
||||
functionName: "updateFrontmatterCacheTime",
|
||||
message: "called",
|
||||
});
|
||||
frontmatterCacheTime = Date.now();
|
||||
}
|
||||
|
||||
function updatePropertySettingTime() {
|
||||
propertySettingTime = Date.now();
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Lifecycle hooks
|
||||
// ============================================
|
||||
store.plugin.subscribe((p) => {
|
||||
plugin = p;
|
||||
|
||||
const allFiles = plugin.app.vault.getAllLoadedFiles();
|
||||
folders = allFiles
|
||||
.filter((file) => file instanceof TFolder)
|
||||
.map((folder) => folder.path);
|
||||
const { app, settings } = plugin;
|
||||
files = app.vault.getFiles();
|
||||
pageSize = settings.pageSize;
|
||||
searchFilter = settings.filters.search;
|
||||
sortFilter = settings.filters.sort;
|
||||
timestampFilter = settings.filters.timestamp;
|
||||
onlyFavorites = settings.filters.onlyFavorites;
|
||||
currentView = settings.views.currentView;
|
||||
viewOrder = settings.views.order;
|
||||
filterGroups = settings.filters.custom.groups;
|
||||
selectedFilterGroupId = settings.filters.custom.selectedGroupId;
|
||||
|
||||
files = plugin.app.vault.getFiles();
|
||||
if (settings.views.enableClockUpdates) {
|
||||
setTimeValuesUpdateInterval();
|
||||
}
|
||||
});
|
||||
|
||||
pageSize = plugin.settings.pageSize;
|
||||
onMount(() => {
|
||||
function handleClockUpdatesSettingChange() {
|
||||
Logger.trace({
|
||||
fileName: "app/index.ts",
|
||||
functionName: "handleClockUpdatesSettingChange",
|
||||
message: "called",
|
||||
});
|
||||
|
||||
searchFilter = plugin.settings.filters.search;
|
||||
sortFilter = plugin.settings.filters.sort;
|
||||
timestampFilter = plugin.settings.filters.timestamp;
|
||||
onlyFavorites = plugin.settings.filters.onlyFavorites;
|
||||
currentView = plugin.settings.views.currentView;
|
||||
viewOrder = plugin.settings.views.order;
|
||||
filterGroups = plugin.settings.filters.custom.groups;
|
||||
selectedFilterGroupId = plugin.settings.filters.custom.selectedGroupId;
|
||||
const isEnabled = plugin.settings.views.enableClockUpdates;
|
||||
if (isEnabled) {
|
||||
updateTimeValues();
|
||||
setTimeValuesUpdateInterval();
|
||||
} else if (timeValuesUpdateInterval != null) {
|
||||
clearInterval(timeValuesUpdateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
updateTimeValues();
|
||||
|
||||
EventManager.getInstance().on(
|
||||
"clock-updates-setting-change",
|
||||
handleClockUpdatesSettingChange,
|
||||
);
|
||||
|
||||
return () => {
|
||||
if (timeValuesUpdateInterval != null)
|
||||
clearInterval(timeValuesUpdateInterval);
|
||||
|
||||
EventManager.getInstance().off(
|
||||
"clock-updates-setting-change",
|
||||
handleClockUpdatesSettingChange,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
|
|
@ -275,6 +281,46 @@
|
|||
};
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Functions
|
||||
// ============================================
|
||||
const debounceSearchFilter = _.debounce((e) => {
|
||||
searchFilter = e.target.value;
|
||||
}, 300);
|
||||
|
||||
const debounceFavoriteFilter = _.debounce((value) => {
|
||||
onlyFavorites = value;
|
||||
}, 300);
|
||||
|
||||
function updateTimeValues() {
|
||||
Logger.trace({
|
||||
fileName: "app/index.ts",
|
||||
functionName: "updateTimeValues",
|
||||
message: "called",
|
||||
});
|
||||
startOfTodayMillis = getStartOfTodayMillis();
|
||||
startOfThisWeekMillis = getStartOfThisWeekMillis();
|
||||
startOfLastWeekMillis = getStartOfLastWeekMillis();
|
||||
}
|
||||
|
||||
function setTimeValuesUpdateInterval() {
|
||||
const MILLIS_MINUTE = 60000;
|
||||
timeValuesUpdateInterval = setInterval(updateTimeValues, MILLIS_MINUTE);
|
||||
}
|
||||
|
||||
function updateFrontmatterCacheTime() {
|
||||
Logger.trace({
|
||||
fileName: "app/index.ts",
|
||||
functionName: "updateFrontmatterCacheTime",
|
||||
message: "called",
|
||||
});
|
||||
frontmatterCacheTime = Date.now();
|
||||
}
|
||||
|
||||
function updatePropertySettingTime() {
|
||||
propertySettingTime = Date.now();
|
||||
}
|
||||
|
||||
async function filterByCustomFilter() {
|
||||
const promises: Promise<TFile | null>[] = [];
|
||||
|
||||
|
|
@ -312,66 +358,6 @@
|
|||
return results.filter((file) => file !== null) as TFile[];
|
||||
}
|
||||
|
||||
let filteredCustom: TFile[] = [];
|
||||
|
||||
$: if (frontmatterCacheTime && filterGroups) {
|
||||
filterByCustomFilter().then((files) => {
|
||||
filteredCustom = files;
|
||||
});
|
||||
}
|
||||
|
||||
let formatted: FileRenderData[] = [];
|
||||
$: if (propertySettingTime) {
|
||||
formatted = filteredCustom.map((file) => {
|
||||
const frontmatter =
|
||||
plugin.app.metadataCache.getFileCache(file)?.frontmatter;
|
||||
return formatFileDataForRender(plugin.settings, file, frontmatter);
|
||||
});
|
||||
}
|
||||
|
||||
$: filteredSearch = formatted.filter((file) =>
|
||||
filterBySearch(file, searchFilter),
|
||||
);
|
||||
|
||||
$: filteredFavorites = filteredSearch.filter((file) =>
|
||||
filterByFavorites(file, onlyFavorites),
|
||||
);
|
||||
|
||||
$: filteredTimestamp = filteredFavorites.filter((file) => {
|
||||
const { modifiedMillis, createdMillis } = file;
|
||||
return filterByTimestamp({
|
||||
createdMillis,
|
||||
modifiedMillis,
|
||||
timestampFilter,
|
||||
startOfTodayMillis,
|
||||
startOfThisWeekMillis,
|
||||
startOfLastWeekMillis,
|
||||
});
|
||||
});
|
||||
|
||||
$: renderData = [...filteredTimestamp].sort((a, b) => {
|
||||
if (sortFilter === "file-name-asc") {
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
} else if (sortFilter === "file-name-desc") {
|
||||
return b.name.toLowerCase().localeCompare(a.name.toLowerCase());
|
||||
} else if (sortFilter === "modified-asc") {
|
||||
return a.modifiedMillis - b.modifiedMillis;
|
||||
} else if (sortFilter === "modified-desc") {
|
||||
return b.modifiedMillis - a.modifiedMillis;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
$: searchFilter,
|
||||
sortFilter,
|
||||
timestampFilter,
|
||||
onlyFavorites,
|
||||
currentView,
|
||||
viewOrder,
|
||||
filterGroups,
|
||||
selectedFilterGroupId,
|
||||
saveSettings();
|
||||
|
||||
async function saveSettings() {
|
||||
plugin.settings.filters.search = searchFilter;
|
||||
plugin.settings.filters.sort = sortFilter;
|
||||
|
|
@ -493,6 +479,10 @@
|
|||
});
|
||||
}
|
||||
|
||||
function handlePageChange(newPage: number) {
|
||||
currentPage = newPage;
|
||||
}
|
||||
|
||||
function openPropertiesFilterModal() {
|
||||
new PropertiesFilterModal(plugin).open();
|
||||
}
|
||||
|
|
@ -578,17 +568,75 @@
|
|||
debounceFavoriteFilter(value);
|
||||
}
|
||||
|
||||
let currentPage = 1;
|
||||
// ============================================
|
||||
// Reactive statements and computed data
|
||||
// ============================================
|
||||
let filteredCustom: TFile[] = [];
|
||||
$: if (frontmatterCacheTime && filterGroups) {
|
||||
filterByCustomFilter().then((files) => {
|
||||
filteredCustom = files;
|
||||
});
|
||||
}
|
||||
|
||||
let formatted: FileRenderData[] = [];
|
||||
$: if (propertySettingTime) {
|
||||
formatted = filteredCustom.map((file) => {
|
||||
const frontmatter =
|
||||
plugin.app.metadataCache.getFileCache(file)?.frontmatter;
|
||||
return formatFileDataForRender(plugin.settings, file, frontmatter);
|
||||
});
|
||||
}
|
||||
|
||||
$: filteredSearch = formatted.filter((file) =>
|
||||
filterBySearch(file, searchFilter),
|
||||
);
|
||||
|
||||
$: filteredFavorites = filteredSearch.filter((file) =>
|
||||
filterByFavorites(file, onlyFavorites),
|
||||
);
|
||||
|
||||
$: filteredTimestamp = filteredFavorites.filter((file) => {
|
||||
const { modifiedMillis, createdMillis } = file;
|
||||
return filterByTimestamp({
|
||||
createdMillis,
|
||||
modifiedMillis,
|
||||
timestampFilter,
|
||||
startOfTodayMillis,
|
||||
startOfThisWeekMillis,
|
||||
startOfLastWeekMillis,
|
||||
});
|
||||
});
|
||||
|
||||
$: renderData = [...filteredTimestamp].sort((a, b) => {
|
||||
if (sortFilter === "file-name-asc") {
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
} else if (sortFilter === "file-name-desc") {
|
||||
return b.name.toLowerCase().localeCompare(a.name.toLowerCase());
|
||||
} else if (sortFilter === "modified-asc") {
|
||||
return a.modifiedMillis - b.modifiedMillis;
|
||||
} else if (sortFilter === "modified-desc") {
|
||||
return b.modifiedMillis - a.modifiedMillis;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
$: searchFilter,
|
||||
sortFilter,
|
||||
timestampFilter,
|
||||
onlyFavorites,
|
||||
currentView,
|
||||
viewOrder,
|
||||
filterGroups,
|
||||
selectedFilterGroupId,
|
||||
saveSettings();
|
||||
|
||||
$: totalItems = renderData.length;
|
||||
$: totalPages = Math.ceil(totalItems / pageSize);
|
||||
|
||||
let currentPage = 1;
|
||||
$: startIndex = (currentPage - 1) * pageSize;
|
||||
$: pageLength = Math.min(pageSize, renderData.length - startIndex);
|
||||
$: endIndex = startIndex + pageLength;
|
||||
|
||||
function changePage(newPage: number) {
|
||||
currentPage = newPage;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="vault-explorer">
|
||||
|
|
@ -691,24 +739,24 @@
|
|||
<IconButton
|
||||
iconId="chevrons-left"
|
||||
ariaLabel="First page"
|
||||
on:click={() => changePage(1)}
|
||||
on:click={() => handlePageChange(1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-left"
|
||||
ariaLabel="Previous page"
|
||||
disabled={currentPage === 1}
|
||||
on:click={() => changePage(currentPage - 1)}
|
||||
on:click={() => handlePageChange(currentPage - 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevron-right"
|
||||
ariaLabel="Next page"
|
||||
disabled={currentPage === totalPages}
|
||||
on:click={() => changePage(currentPage + 1)}
|
||||
on:click={() => handlePageChange(currentPage + 1)}
|
||||
/>
|
||||
<IconButton
|
||||
iconId="chevrons-right"
|
||||
ariaLabel="Last page"
|
||||
on:click={() => changePage(totalPages)}
|
||||
on:click={() => handlePageChange(totalPages)}
|
||||
/>
|
||||
</Flex>
|
||||
</Stack>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export interface VaultExplorerPluginSettings {
|
|||
currentView: ViewType;
|
||||
order: ViewType[];
|
||||
titleWrapping: WordBreak;
|
||||
enableClockUpdates: boolean;
|
||||
}
|
||||
pageSize: number;
|
||||
pluginVersion: string | null;
|
||||
|
|
|
|||
213
src/types/types-1.12.1.ts
Normal file
213
src/types/types-1.12.1.ts
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
export interface VaultExplorerPluginSettings_1_12_1 {
|
||||
logLevel: string;
|
||||
properties: {
|
||||
favorite: string;
|
||||
url: string;
|
||||
createdDate: string;
|
||||
modifiedDate: string;
|
||||
custom1: string;
|
||||
custom2: string;
|
||||
custom3: string;
|
||||
},
|
||||
filters: {
|
||||
search: string;
|
||||
onlyFavorites: boolean;
|
||||
sort: SortFilter;
|
||||
timestamp: TimestampFilter;
|
||||
custom: {
|
||||
selectedGroupId: string;
|
||||
groups: FilterGroup[];
|
||||
}
|
||||
},
|
||||
views: {
|
||||
currentView: ViewType;
|
||||
order: ViewType[];
|
||||
titleWrapping: WordBreak;
|
||||
}
|
||||
pageSize: number;
|
||||
pluginVersion: string | null;
|
||||
}
|
||||
|
||||
export type WordBreak = "normal" | "break-word";
|
||||
|
||||
export enum ViewType {
|
||||
GRID = "grid",
|
||||
LIST = "list",
|
||||
}
|
||||
|
||||
export type FilterOperator = "and" | "or";
|
||||
|
||||
export enum TextFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
STARTS_WITH = "starts-with",
|
||||
ENDS_WITH = "ends-with",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
export enum ListFilterCondition {
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
export enum NumberFilterCondition {
|
||||
IS_EQUAL = "is-equal",
|
||||
IS_NOT_EQUAL = "is-not-equal",
|
||||
IS_GREATER = "is-greater",
|
||||
IS_LESS = "is-less",
|
||||
IS_GREATER_OR_EQUAL = "is-greater-or-equal",
|
||||
IS_LESS_OR_EQUAL = "is-less-or-equal",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
export enum CheckboxFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
//TODO: add is between
|
||||
export enum DateFilterCondition {
|
||||
IS = "is",
|
||||
IS_BEFORE = "is-before",
|
||||
IS_AFTER = "is-after",
|
||||
IS_ON_OR_BEFORE = "is-on-or-before",
|
||||
IS_ON_OR_AFTER = "is-on-or-after",
|
||||
EXISTS = "exists",
|
||||
DOES_NOT_EXIST = "does-not-exist",
|
||||
}
|
||||
|
||||
export enum ContentFilterCondition {
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
IS_EMPTY = "is-empty",
|
||||
IS_NOT_EMPTY = "is-not-empty",
|
||||
}
|
||||
|
||||
//TODO add is child of and is parent of?
|
||||
export enum FolderFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
}
|
||||
|
||||
export enum FileNameFilterCondition {
|
||||
IS = "is",
|
||||
IS_NOT = "is-not",
|
||||
CONTAINS = "contains",
|
||||
DOES_NOT_CONTAIN = "does-not-contain",
|
||||
STARTS_WITH = "starts-with",
|
||||
ENDS_WITH = "ends-with",
|
||||
}
|
||||
|
||||
export type FilterCondition = TextFilterCondition | NumberFilterCondition | DateFilterCondition | CheckboxFilterCondition | ListFilterCondition | ContentFilterCondition | FolderFilterCondition | FileNameFilterCondition;
|
||||
|
||||
//This matches the Obsidian property types
|
||||
export enum PropertyType {
|
||||
TEXT = "text",
|
||||
NUMBER = "number",
|
||||
LIST = "list",
|
||||
CHECKBOX = "checkbox",
|
||||
DATE = "date",
|
||||
DATETIME = "datetime",
|
||||
}
|
||||
|
||||
export enum FilterRuleType {
|
||||
PROPERTY = "property",
|
||||
FOLDER = "folder",
|
||||
FILE_NAME = "file-name",
|
||||
CONTENT = "content",
|
||||
}
|
||||
|
||||
export enum DatePropertyFilterValue {
|
||||
TODAY = "today",
|
||||
TOMORROW = "tomorrow",
|
||||
YESTERDAY = "yesterday",
|
||||
ONE_WEEK_FROM_NOW = "one-week-from-now",
|
||||
ONE_WEEK_AGO = "one-week-ago",
|
||||
ONE_MONTH_FROM_NOW = "one-month-from-now",
|
||||
ONE_MONTH_AGO = "one-month-ago",
|
||||
CUSTOM = "custom"
|
||||
}
|
||||
|
||||
interface BaseFilterRule {
|
||||
id: string;
|
||||
operator: FilterOperator;
|
||||
type: FilterRuleType;
|
||||
condition: FilterCondition;
|
||||
isEnabled: boolean;
|
||||
value: string;
|
||||
matchWhenPropertyDNE: boolean;
|
||||
}
|
||||
|
||||
export interface TextPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.TEXT;
|
||||
propertyName: string;
|
||||
condition: TextFilterCondition;
|
||||
}
|
||||
|
||||
export interface NumberPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.NUMBER;
|
||||
propertyName: string;
|
||||
condition: NumberFilterCondition;
|
||||
}
|
||||
|
||||
export interface ListPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.LIST;
|
||||
propertyName: string;
|
||||
condition: ListFilterCondition;
|
||||
}
|
||||
|
||||
export interface CheckboxPropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.CHECKBOX;
|
||||
propertyName: string;
|
||||
condition: CheckboxFilterCondition;
|
||||
}
|
||||
|
||||
export interface DatePropertyFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.PROPERTY;
|
||||
propertyType: PropertyType.DATE | PropertyType.DATETIME;
|
||||
propertyName: string;
|
||||
condition: DateFilterCondition;
|
||||
valueData: string;
|
||||
}
|
||||
|
||||
export interface FolderFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.FOLDER;
|
||||
condition: FolderFilterCondition;
|
||||
includeSubfolders: boolean;
|
||||
}
|
||||
|
||||
export interface FileNameFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.FILE_NAME;
|
||||
condition: FileNameFilterCondition;
|
||||
}
|
||||
|
||||
export interface ContentFilterRule extends BaseFilterRule {
|
||||
type: FilterRuleType.CONTENT;
|
||||
condition: ContentFilterCondition;
|
||||
}
|
||||
|
||||
export type FilterRule = PropertyFilterRule | FolderFilterRule | FileNameFilterRule | ContentFilterRule;
|
||||
export type PropertyFilterRule = TextPropertyFilterRule | NumberPropertyFilterRule | ListPropertyFilterRule | CheckboxPropertyFilterRule | DatePropertyFilterRule;
|
||||
|
||||
export interface FilterGroup {
|
||||
id: string;
|
||||
name: string;
|
||||
rules: FilterRule[];
|
||||
isEnabled: boolean;
|
||||
}
|
||||
|
||||
export type SortFilter = "file-name-asc" | "file-name-desc" | "modified-asc" | "modified-desc";
|
||||
|
||||
export type TimestampFilter = "created-today" | "modified-today" | "created-this-week" | "modified-this-week" | "created-2-weeks" | "modified-2-weeks" | "all";
|
||||
|
|
@ -65,5 +65,6 @@
|
|||
"1.10.0": "1.4.13",
|
||||
"1.11.0": "1.4.13",
|
||||
"1.12.0": "1.4.13",
|
||||
"1.12.1": "1.4.13"
|
||||
"1.12.1": "1.4.13",
|
||||
"1.13.0": "1.4.13"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue