From 2bf5c1302cd9d4599928aac24ea2dfd47a45e999 Mon Sep 17 00:00:00 2001 From: DecafDev <40307803+decaf-dev@users.noreply.github.com> Date: Tue, 6 Aug 2024 22:00:40 -0600 Subject: [PATCH] Add cover image fit (#310) * chore: bump version * feat: add cover image fit setting * feat: render cover image * feat: add cover image to context menu * refactor: add default fit into description * fix: only show cover image options for markdown files --- manifest.json | 2 +- package.json | 2 +- src/constants.ts | 2 + src/event/types.ts | 1 + src/migrations/index.ts | 6 + src/migrations/migrate_1_40_0.ts | 4 +- src/migrations/migrate_1_41_0.ts | 25 ++ src/obsidian/vault-explorer-settings-tab.ts | 44 ++- src/svelte/app/components/grid-card.svelte | 17 +- src/svelte/app/components/grid-view.svelte | 2 + src/svelte/app/index.svelte | 72 ++++- src/svelte/app/services/context-menu.ts | 21 ++ src/svelte/app/services/render-data.ts | 17 +- src/svelte/app/types.ts | 3 + src/types/index.guard.ts | 5 + src/types/index.ts | 4 + src/types/types-1.40.2.ts | 328 ++++++++++++++++++++ versions.json | 3 +- 18 files changed, 545 insertions(+), 13 deletions(-) create mode 100644 src/migrations/migrate_1_41_0.ts create mode 100644 src/types/types-1.40.2.ts diff --git a/manifest.json b/manifest.json index a4884da..c739319 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "vault-explorer", "name": "Vault Explorer", - "version": "1.40.2", + "version": "1.41.0", "minAppVersion": "1.4.13", "description": "Explore your vault in visual format", "author": "DecafDev", diff --git a/package.json b/package.json index d1d6bbe..fbd593c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-vault-explorer", - "version": "1.40.2", + "version": "1.41.0", "description": "Explore your vault in visual format", "main": "main.js", "scripts": { diff --git a/src/constants.ts b/src/constants.ts index 2363a46..218f30a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -10,6 +10,7 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = { favorite: "", url: "", image: "", + coverImageFit: "", createdDate: "", modifiedDate: "", custom1: "", @@ -45,6 +46,7 @@ export const DEFAULT_SETTINGS: VaultExplorerPluginSettings = { }, grid: { isEnabled: true, + coverImageFit: "cover", coverImageSources: [ { type: "image-property", diff --git a/src/event/types.ts b/src/event/types.ts index bf66264..64a5ebe 100644 --- a/src/event/types.ts +++ b/src/event/types.ts @@ -10,6 +10,7 @@ export enum PluginEvent { FOLDER_DELETE = "folder-delete", FOLDER_CREATE = "folder-create", PAGE_SIZE_SETTING_CHANGE = "page-size-setting-change", + COVER_IMAGE_FIT_SETTING_CHANGE = "cover-image-fit-setting-change", FEED_CONTENT_SETTING_CHANGE = "feed-content-setting-change", COVER_IMAGE_SOURCE_SETTING_CHANGE = "cover-image-source-setting-change", PROPERTY_SETTING_CHANGE = "property-setting-change", diff --git a/src/migrations/index.ts b/src/migrations/index.ts index f86694f..9dd64c3 100644 --- a/src/migrations/index.ts +++ b/src/migrations/index.ts @@ -30,6 +30,7 @@ import Migrate_1_37_0 from "./migrate_1_37_0"; import Migrate_1_38_0 from "./migrate_1_38_0"; import Migrate_1_39_0 from "./migrate_1_39_0"; import Migrate_1_40_0 from "./migrate_1_40_0"; +import Migrate_1_41_0 from "./migrate_1_41_0"; const migrations: TMigration[] = [ { @@ -177,6 +178,11 @@ const migrations: TMigration[] = [ to: "1.40.0", migrate: Migrate_1_40_0, }, + { + from: "1.40.2", + to: "1.41.0", + migrate: Migrate_1_41_0, + }, ]; export const preformMigrations = ( diff --git a/src/migrations/migrate_1_40_0.ts b/src/migrations/migrate_1_40_0.ts index 32bd5fe..1c4c26e 100644 --- a/src/migrations/migrate_1_40_0.ts +++ b/src/migrations/migrate_1_40_0.ts @@ -1,11 +1,11 @@ import MigrationInterface from "./migration_interface"; import { VaultExplorerPluginSettings_1_39_0 } from "src/types/types-1.39.0"; -import { VaultExplorerPluginSettings } from "src/types"; +import { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2"; export default class Migrate_1_40_0 implements MigrationInterface { migrate(data: Record) { const typedData = data as unknown as VaultExplorerPluginSettings_1_39_0; - const newData: VaultExplorerPluginSettings = { + const newData: VaultExplorerPluginSettings_1_40_2 = { ...typedData, shouldCollapseFilters: false, }; diff --git a/src/migrations/migrate_1_41_0.ts b/src/migrations/migrate_1_41_0.ts new file mode 100644 index 0000000..2ad34f2 --- /dev/null +++ b/src/migrations/migrate_1_41_0.ts @@ -0,0 +1,25 @@ +import { VaultExplorerPluginSettings } from "src/types"; +import MigrationInterface from "./migration_interface"; +import { VaultExplorerPluginSettings_1_40_2 } from "src/types/types-1.40.2"; + +export default class Migrate_1_41_0 implements MigrationInterface { + migrate(data: Record) { + const typedData = data as unknown as VaultExplorerPluginSettings_1_40_2; + const newData: VaultExplorerPluginSettings = { + ...typedData, + properties: { + ...typedData.properties, + coverImageFit: "", + }, + views: { + ...typedData.views, + grid: { + ...typedData.views.grid, + coverImageFit: "cover", + }, + }, + }; + + return newData as unknown as Record; + } +} diff --git a/src/obsidian/vault-explorer-settings-tab.ts b/src/obsidian/vault-explorer-settings-tab.ts index 9d1c070..8b779c2 100644 --- a/src/obsidian/vault-explorer-settings-tab.ts +++ b/src/obsidian/vault-explorer-settings-tab.ts @@ -14,7 +14,7 @@ import { } from "src/logger/constants"; import Logger from "js-logger"; import { stringToLogLevel } from "src/logger"; -import { CollapseStyle, TExplorerView } from "src/types"; +import { CollapseStyle, CoverImageFit, TExplorerView } from "src/types"; import EventManager from "src/event/event-manager"; import LicenseKeyApp from "../svelte/license-key-app/index.svelte"; import ImageSourceApp from "../svelte/image-source-app/index.svelte"; @@ -312,6 +312,26 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { }) ); + new Setting(containerEl) + .setName("Cover image fit") + .setDesc("Set the default cover image fit") + .addDropdown((cb) => + cb + .addOptions({ + cover: "Cover", + contain: "Contain", + }) + .setValue(this.plugin.settings.views.grid.coverImageFit) + .onChange(async (value) => { + this.plugin.settings.views.grid.coverImageFit = + value as CoverImageFit; + await this.plugin.saveSettings(); + EventManager.getInstance().emit( + PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE + ); + }) + ); + new Setting(containerEl).setName("List view").setHeading(); new Setting(containerEl) @@ -443,9 +463,9 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { ); new Setting(containerEl) - .setName("Image property") + .setName("Cover image property") .setDesc( - "Property used to store an image. This must be a text property." + "Property used to store a cover image. This must be a text property." ) .addDropdown((dropdown) => dropdown @@ -460,6 +480,24 @@ export default class VaultExplorerSettingsTab extends PluginSettingTab { }) ); + new Setting(containerEl) + .setName("Cover image fit property") + .setDesc( + "Property used to store the cover image fit. This must be a text property." + ) + .addDropdown((dropdown) => + dropdown + .addOptions(getDropdownOptionsForProperties(textProperties)) + .setValue(this.plugin.settings.properties.coverImageFit) + .onChange(async (value) => { + this.plugin.settings.properties.coverImageFit = value; + await this.plugin.saveSettings(); + EventManager.getInstance().emit( + PluginEvent.PROPERTY_SETTING_CHANGE + ); + }) + ); + new Setting(containerEl) .setName("URL property") .setDesc( diff --git a/src/svelte/app/components/grid-card.svelte b/src/svelte/app/components/grid-card.svelte index 252dc94..7533f67 100644 --- a/src/svelte/app/components/grid-card.svelte +++ b/src/svelte/app/components/grid-card.svelte @@ -23,6 +23,7 @@ isSocialMediaImageEntryExpired, putSocialMediaImageUrl, } from "../services/social-media-image-cache"; + import { CoverImageFit } from "src/types"; export let displayName: string; export let path: string; @@ -35,6 +36,7 @@ export let custom2: string | null; export let custom3: string | null; export let isFavorite: boolean | null; + export let coverImageFit: CoverImageFit; let plugin: VaultExplorerPlugin; let enableFileIcons: boolean = false; @@ -136,11 +138,21 @@ dispatch("favoritePropertyChange", { filePath, value }); } + function handleCoverImageFitChange(filePath: string, value: CoverImageFit) { + dispatch("coverImageFitChange", { filePath, value }); + } + function handleCardContextMenu(e: Event) { const nativeEvent = e as MouseEvent; + + const showCoverImageOptions = path.endsWith(".md"); openContextMenu(plugin, path, nativeEvent, { isFavorite, + coverImageFit: showCoverImageOptions ? coverImageFit : undefined, onFavoriteChange: handleFavoriteChange, + onCoverImageFitChange: showCoverImageOptions + ? handleCoverImageFitChange + : undefined, }); } @@ -208,7 +220,9 @@ @@ -335,7 +349,6 @@ .vault-explorer-grid-card__image { width: 100%; height: 150px; - object-fit: cover; border-top-left-radius: var(--radius-m); border-top-right-radius: var(--radius-m); } diff --git a/src/svelte/app/components/grid-view.svelte b/src/svelte/app/components/grid-view.svelte index e4fdd76..eda929b 100644 --- a/src/svelte/app/components/grid-view.svelte +++ b/src/svelte/app/components/grid-view.svelte @@ -26,6 +26,7 @@ {/each} diff --git a/src/svelte/app/index.svelte b/src/svelte/app/index.svelte index 2a1f8c9..23118d6 100644 --- a/src/svelte/app/index.svelte +++ b/src/svelte/app/index.svelte @@ -15,6 +15,7 @@ TSortFilter, TTimestampFilter, TExplorerView, + CoverImageFit, } from "src/types"; import store from "../shared/services/store"; import VaultExplorerPlugin from "src/main"; @@ -104,6 +105,7 @@ let frontmatterCacheTime: number = Date.now(); let propertySettingsTime: number = Date.now(); let coverImageSourcesTime: number = Date.now(); + let coverImageFitTime: number = Date.now(); let loadBodyTagsTime: number = Date.now(); let loadedFiles: LoadedFile[] = []; @@ -471,6 +473,29 @@ }; }); + onMount(() => { + function handleCoverImageFitSettingChange() { + Logger.trace({ + fileName: "app/index.svelte", + functionName: "handleCoverImageFitSettingChange", + message: "called", + }); + + coverImageFitTime = Date.now(); + } + + EventManager.getInstance().on( + PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE, + handleCoverImageFitSettingChange, + ); + return () => { + EventManager.getInstance().off( + PluginEvent.COVER_IMAGE_FIT_SETTING_CHANGE, + handleCoverImageFitSettingChange, + ); + }; + }); + onMount(() => { function handleCoverImageSourceSettingChange() { Logger.trace({ @@ -759,6 +784,43 @@ debounceFavoriteFilterChange(value); } + function handleCoverImageFitChange(e: CustomEvent) { + const { filePath, value } = e.detail as { + filePath: string; + value: CoverImageFit; + }; + + console.log(filePath, value); + + const { properties } = plugin.settings; + const { coverImageFit: coverImageFitProperty } = properties; + + //If the favorite property is not set, return + if (coverImageFitProperty === "") { + new Notice( + "Vault Explorer: Please set a cover image fit property in the plugin settings to use this feature", + ); + return; + } + + const file = plugin.app.vault.getFileByPath(filePath); + if (!file) { + Logger.error({ + fileName: "app/index.svelte", + functionName: "handleCoverImageFitChange", + message: "file not found. returning...", + }); + return; + } + + if (file.extension === "md") { + plugin.app.fileManager.processFrontMatter(file, (frontmatter) => { + frontmatter[coverImageFitProperty] = value; + return frontmatter; + }); + } + } + function handleFavoritePropertyChange(e: CustomEvent) { const { filePath, value } = e.detail as { filePath: string; @@ -771,7 +833,7 @@ //If the favorite property is not set, return if (favoritePropertyName === "") { new Notice( - "Please select a favorite property in the Vault Explorer settings to use this feature", + "Vault Explorer: Please set a favorite property in the plugin settings to use this feature", ); return; } @@ -827,7 +889,12 @@ } let formatted: FileRenderData[] = []; - $: if (propertySettingsTime || coverImageSourcesTime || loadBodyTagsTime) { + $: if ( + propertySettingsTime || + coverImageSourcesTime || + loadBodyTagsTime || + coverImageFitTime + ) { formatted = filteredCustom.map((loadedFile) => { const { id, file } = loadedFile; const frontmatter = @@ -1047,6 +1114,7 @@ {startIndex} {pageLength} on:favoritePropertyChange={handleFavoritePropertyChange} + on:coverImageFitChange={handleCoverImageFitChange} /> {:else if currentView === "list"} void; + onCoverImageFitChange?: ( + filePath: string, + value: CoverImageFit + ) => void; } ) => { const menu = new Menu(); @@ -37,6 +45,19 @@ export const openContextMenu = ( onFavoriteChange(filePath, newValue); }); }); + if (coverImageFit !== undefined && onCoverImageFitChange !== undefined) { + menu.addSeparator(); + menu.addItem((item) => { + item.setTitle("Cover image fit: cover"); + item.setChecked(coverImageFit === "cover"); + item.onClick(() => onCoverImageFitChange(filePath, "cover")); + }); + menu.addItem((item) => { + item.setTitle("Cover image fit: contain"); + item.setChecked(coverImageFit === "contain"); + item.onClick(() => onCoverImageFitChange(filePath, "contain")); + }); + } menu.showAtMouseEvent(e); }; diff --git a/src/svelte/app/services/render-data.ts b/src/svelte/app/services/render-data.ts index 45bb024..2cb015f 100644 --- a/src/svelte/app/services/render-data.ts +++ b/src/svelte/app/services/render-data.ts @@ -1,5 +1,9 @@ import { App, FrontMatterCache, TFile } from "obsidian"; -import { PropertyType, VaultExplorerPluginSettings } from "src/types"; +import { + CoverImageFit, + PropertyType, + VaultExplorerPluginSettings, +} from "src/types"; import { FileRenderData } from "../types"; import Logger from "js-logger"; import { @@ -62,6 +66,7 @@ export const formatFileDataForRender = ({ modifiedDate: modifiedDateProp, url: urlProp, image: imageProp, + coverImageFit: coverImageFitProp, favorite: favoriteProp, custom1: custom1Prop, custom2: custom2Prop, @@ -103,6 +108,15 @@ export const formatFileDataForRender = ({ isFavorite = fileFavorite; } + let coverImageFit: CoverImageFit | null = loadPropertyValue( + fileFrontmatter, + coverImageFitProp, + PropertyType.TEXT + ) as CoverImageFit | null; + if (coverImageFit === null) { + coverImageFit = settings.views.grid.coverImageFit; + } + const creationDate: string | null = loadPropertyValue( fileFrontmatter, createdDateProp, @@ -230,6 +244,7 @@ export const formatFileDataForRender = ({ displayName, path, baseName: basename, + coverImageFit, basePath, extension, url, diff --git a/src/svelte/app/types.ts b/src/svelte/app/types.ts index c5e03e9..b0b16cb 100644 --- a/src/svelte/app/types.ts +++ b/src/svelte/app/types.ts @@ -1,3 +1,5 @@ +import { CoverImageFit } from "src/types"; + export interface FileRenderData { id: string; displayName: string; @@ -5,6 +7,7 @@ export interface FileRenderData { basePath: string; extension: string; baseName: string; + coverImageFit: CoverImageFit; content: string | null; url: string | null; imageUrl: string | null; diff --git a/src/types/index.guard.ts b/src/types/index.guard.ts index b86ec16..bb54582 100644 --- a/src/types/index.guard.ts +++ b/src/types/index.guard.ts @@ -16,6 +16,7 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore typeof typedObj["properties"]["favorite"] === "string" && typeof typedObj["properties"]["url"] === "string" && typeof typedObj["properties"]["image"] === "string" && + typeof typedObj["properties"]["coverImageFit"] === "string" && typeof typedObj["properties"]["createdDate"] === "string" && typeof typedObj["properties"]["modifiedDate"] === "string" && typeof typedObj["properties"]["custom1"] === "string" && @@ -606,6 +607,10 @@ export function isVaultExplorerPluginSettings(obj: unknown): obj is VaultExplore e["type"] === "body") && typeof e["isEnabled"] === "boolean" ) && + (typedObj["views"]["grid"]["coverImageFit"] === "cover" || + typedObj["views"]["grid"]["coverImageFit"] === "contain" || + typedObj["views"]["grid"]["coverImageFit"] === "scale-down" || + typedObj["views"]["grid"]["coverImageFit"] === "none") && typeof typedObj["views"]["grid"]["loadSocialMediaImage"] === "boolean" && (typedObj["views"]["list"] !== null && typeof typedObj["views"]["list"] === "object" || diff --git a/src/types/index.ts b/src/types/index.ts index 90d5fbd..2e0ca16 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -4,6 +4,7 @@ export interface VaultExplorerPluginSettings { favorite: string; url: string; image: string; + coverImageFit: string; createdDate: string; modifiedDate: string; custom1: string; @@ -55,6 +56,7 @@ export interface TListView extends BaseView { export interface TGridView extends BaseView { coverImageSources: CoverImageSource[]; + coverImageFit: CoverImageFit; loadSocialMediaImage: boolean; } @@ -63,6 +65,8 @@ export interface CoverImageSource { isEnabled: boolean; } +export type CoverImageFit = "cover" | "contain"; + export type CoverImageSourceType = | "image-property" | "url-property" diff --git a/src/types/types-1.40.2.ts b/src/types/types-1.40.2.ts new file mode 100644 index 0000000..9a3fcf7 --- /dev/null +++ b/src/types/types-1.40.2.ts @@ -0,0 +1,328 @@ +export interface VaultExplorerPluginSettings_1_40_2 { + properties: { + favorite: string; + url: string; + image: string; + createdDate: string; + modifiedDate: string; + custom1: string; + custom2: string; + custom3: string; + }; + filters: { + search: TSearchFilter; + favorites: TFavoritesFilter; + sort: TSortFilter; + timestamp: TTimestampFilter; + custom: TCustomFilter; + }; + views: { + dashboard: TDashboardView; + grid: TGridView; + list: TListView; + table: TTableView; + feed: TFeedView; + recommended: TRecommendedView; + related: TRelatedView; + }; + titleWrapping: WordBreak; + enableClockUpdates: boolean; + enableFileIcons: boolean; + loadBodyTags: boolean; + currentView: TExplorerView | null; + pageSize: number; + filterGroupsWidth: string; + shouldWrapFilterGroups: boolean; + shouldCollapseFilters: boolean; + viewOrder: TExplorerView[]; + configDir: string; + pluginVersion: string | null; + logLevel: string; +} + +type FileInteractionStyle = "title" | "content"; + +interface BaseView { + isEnabled: boolean; +} + +interface TTableView extends BaseView {} + +interface TListView extends BaseView { + showTags: boolean; +} + +interface TGridView extends BaseView { + coverImageSources: CoverImageSource[]; + loadSocialMediaImage: boolean; +} + +interface CoverImageSource { + type: CoverImageSourceType; + isEnabled: boolean; +} + +type CoverImageSourceType = + | "image-property" + | "url-property" + | "frontmatter" + | "body"; + +interface TDashboardView extends BaseView {} + +type CollapseStyle = "no-new-lines" | "no-extra-new-lines"; + +interface TFeedView extends BaseView { + collapseStyle: CollapseStyle; + removeH1: boolean; + lineClampSmall: number; + lineClampMedium: number; + lineClampLarge: number; +} + +interface TRecommendedView extends BaseView {} + +interface TRelatedView extends BaseView {} + +interface BaseFilter { + isEnabled: boolean; +} + +interface TSearchFilter extends BaseFilter { + value: string; +} + +interface TFavoritesFilter extends BaseFilter { + value: boolean; +} + +interface TSortFilter extends BaseFilter { + value: SortFilterOption; +} + +interface TTimestampFilter extends BaseFilter { + value: TimestampFilterOption; +} + +interface TCustomFilter extends BaseFilter { + selectedGroupId: string; + groups: TFilterGroup[]; +} + +type TimestampFilterOption = + | "created-today" + | "modified-today" + | "created-this-week" + | "modified-this-week" + | "created-2-weeks" + | "modified-2-weeks" + | "all"; + +type SortFilterOption = + | "file-name-asc" + | "file-name-desc" + | "modified-asc" + | "modified-desc" + | "random"; + +type WordBreak = "normal" | "break-word"; + +enum TExplorerView { + DASHBOARD = "dashboard", + GRID = "grid", + LIST = "list", + FEED = "feed", + TABLE = "table", + RECOMMENDED = "recommended", + RELATED = "related", +} + +type FilterOperator = "and" | "or"; + +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", +} + +enum ListFilterCondition { + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +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", +} + +enum CheckboxFilterCondition { + IS = "is", + IS_NOT = "is-not", + EXISTS = "exists", + DOES_NOT_EXIST = "does-not-exist", +} + +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", +} + +enum ContentFilterCondition { + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + IS_EMPTY = "is-empty", + IS_NOT_EMPTY = "is-not-empty", +} + +enum FolderFilterCondition { + IS = "is", + IS_NOT = "is-not", +} + +enum FileNameFilterCondition { + IS = "is", + IS_NOT = "is-not", + CONTAINS = "contains", + DOES_NOT_CONTAIN = "does-not-contain", + STARTS_WITH = "starts-with", + ENDS_WITH = "ends-with", +} + +type FilterCondition = + | TextFilterCondition + | NumberFilterCondition + | DateFilterCondition + | CheckboxFilterCondition + | ListFilterCondition + | ContentFilterCondition + | FolderFilterCondition + | FileNameFilterCondition; + +//This matches the Obsidian property types +enum PropertyType { + TEXT = "text", + NUMBER = "number", + LIST = "list", + CHECKBOX = "checkbox", + DATE = "date", + DATETIME = "datetime", +} + +enum FilterRuleType { + PROPERTY = "property", + FOLDER = "folder", + FILE_NAME = "file-name", + CONTENT = "content", +} + +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; +} + +interface TextPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.TEXT; + propertyName: string; + condition: TextFilterCondition; +} + +interface NumberPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.NUMBER; + propertyName: string; + condition: NumberFilterCondition; +} + +interface ListPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.LIST; + propertyName: string; + condition: ListFilterCondition; +} + +interface CheckboxPropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.CHECKBOX; + propertyName: string; + condition: CheckboxFilterCondition; +} + +interface DatePropertyFilterRule extends BaseFilterRule { + type: FilterRuleType.PROPERTY; + propertyType: PropertyType.DATE | PropertyType.DATETIME; + propertyName: string; + condition: DateFilterCondition; + valueData: string; +} + +interface FolderFilterRule extends BaseFilterRule { + type: FilterRuleType.FOLDER; + condition: FolderFilterCondition; + includeSubfolders: boolean; +} + +interface FileNameFilterRule extends BaseFilterRule { + type: FilterRuleType.FILE_NAME; + condition: FileNameFilterCondition; +} + +interface ContentFilterRule extends BaseFilterRule { + type: FilterRuleType.CONTENT; + condition: ContentFilterCondition; +} + +type TFilterRule = + | PropertyFilterRule + | FolderFilterRule + | FileNameFilterRule + | ContentFilterRule; + +type PropertyFilterRule = + | TextPropertyFilterRule + | NumberPropertyFilterRule + | ListPropertyFilterRule + | CheckboxPropertyFilterRule + | DatePropertyFilterRule; + +interface TFilterGroup { + id: string; + name: string; + rules: TFilterRule[]; + isEnabled: boolean; + isSticky: boolean; +} diff --git a/versions.json b/versions.json index e4baa2d..44ff2df 100644 --- a/versions.json +++ b/versions.json @@ -134,5 +134,6 @@ "1.39.0": "1.4.13", "1.40.0": "1.4.13", "1.40.1": "1.4.13", - "1.40.2": "1.4.13" + "1.40.2": "1.4.13", + "1.41.0": "1.4.13" }