mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 12:30:24 +00:00
Merge pull request #81 from devonthesofa/feature/experiments-beta-check
[feature] Gate dashboard and grouped status view behind experimental settings
This commit is contained in:
commit
3cfd46b848
7 changed files with 149 additions and 17 deletions
|
|
@ -322,6 +322,43 @@ export const UISettings: React.FC<Props> = ({ settings, onChange }) => {
|
|||
/>
|
||||
</SettingItem>
|
||||
|
||||
<h3>Experimental features</h3>
|
||||
|
||||
<SettingItem
|
||||
name="Enable experimental features"
|
||||
description="Unlock beta views that are still under development."
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={settings.enableExperimentalFeatures || false}
|
||||
onChange={handleChange("enableExperimentalFeatures")}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Enable status dashboard"
|
||||
description="Show the ribbon shortcut to open the status dashboard view."
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
disabled={!settings.enableExperimentalFeatures}
|
||||
checked={settings.enableStatusDashboard || false}
|
||||
onChange={handleChange("enableStatusDashboard")}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Enable grouped status view"
|
||||
description="Show the ribbon shortcut to open the grouped status view."
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
disabled={!settings.enableExperimentalFeatures}
|
||||
checked={settings.enableGroupedStatusView || false}
|
||||
onChange={handleChange("enableGroupedStatusView")}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<h3>Behavior & Other</h3>
|
||||
|
||||
<SettingItem
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ export const DEFAULT_PLUGIN_SETTINGS: PluginSettings = {
|
|||
fileExplorerLeftBorder: false,
|
||||
fileExplorerStatusDot: false,
|
||||
fileExplorerUnderlineFileName: false,
|
||||
enableExperimentalFeatures: true,
|
||||
enableStatusDashboard: true,
|
||||
enableGroupedStatusView: true,
|
||||
enabledTemplates: DEFAULT_ENABLED_TEMPLATES,
|
||||
useCustomStatusesOnly: false,
|
||||
useMultipleStatuses: true,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { NoteStatusService, BaseNoteStatusService } from "./noteStatusService";
|
|||
import settingsService from "./settingsService";
|
||||
import eventBus from "./eventBus";
|
||||
import { VIEW_TYPE_EXAMPLE } from "../integrations/views/grouped-status-view";
|
||||
import { isExperimentalFeatureEnabled } from "@/utils/experimentalFeatures";
|
||||
|
||||
export class CommandsService {
|
||||
private plugin: Plugin;
|
||||
|
|
@ -229,15 +230,17 @@ export class CommandsService {
|
|||
});
|
||||
this.registeredCommands.add("search-by-status");
|
||||
|
||||
// Open Status Pane command
|
||||
this.plugin.addCommand({
|
||||
id: "open-status-pane",
|
||||
name: "Open status pane",
|
||||
callback: async () => {
|
||||
await this.openStatusPane();
|
||||
},
|
||||
});
|
||||
this.registeredCommands.add("open-status-pane");
|
||||
// Open Status Pane command (experimental)
|
||||
if (this.shouldEnableGroupedView()) {
|
||||
this.plugin.addCommand({
|
||||
id: "open-status-pane",
|
||||
name: "Open status pane",
|
||||
callback: async () => {
|
||||
await this.openStatusPane();
|
||||
},
|
||||
});
|
||||
this.registeredCommands.add("open-status-pane");
|
||||
}
|
||||
}
|
||||
|
||||
private async openStatusPane(): Promise<void> {
|
||||
|
|
@ -356,6 +359,10 @@ export class CommandsService {
|
|||
this.registeredCommands.clear();
|
||||
}
|
||||
|
||||
private shouldEnableGroupedView(): boolean {
|
||||
return isExperimentalFeatureEnabled("groupedStatusView");
|
||||
}
|
||||
|
||||
public destroy(): void {
|
||||
// Remove all registered commands properly
|
||||
this.removeRegisteredCommands();
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ export class CommandsIntegration {
|
|||
if (
|
||||
key === "quickStatusCommands" ||
|
||||
key === "useMultipleStatuses" ||
|
||||
key === "templates"
|
||||
key === "templates" ||
|
||||
key === "enableExperimentalFeatures" ||
|
||||
key === "enableGroupedStatusView"
|
||||
) {
|
||||
this.commandsService.destroy();
|
||||
/// BUG: if removed a command will persist because is not removed, you need the oldStates to send it to be disabled // const oldValue = this.settings[key]; // TODO: Send the old value
|
||||
|
|
|
|||
71
main.tsx
71
main.tsx
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from "./integrations/views/status-dashboard-view";
|
||||
import { StatusesInfoPopup } from "./integrations/popups/statusesInfoPopupIntegration";
|
||||
import statusStoreManager from "./core/statusStoreManager";
|
||||
import { isExperimentalFeatureEnabled } from "@/utils/experimentalFeatures";
|
||||
|
||||
export default class NoteStatusPlugin extends Plugin {
|
||||
private statusBarIntegration: StatusBarIntegration;
|
||||
|
|
@ -27,6 +28,7 @@ export default class NoteStatusPlugin extends Plugin {
|
|||
private fileExplorerIntegration: FileExplorerIntegration;
|
||||
private commandsIntegration: CommandsIntegration;
|
||||
private editorToolbarIntegration: EditorToolbarIntegration;
|
||||
private experimentalRibbonShortcuts: Map<string, HTMLElement> = new Map();
|
||||
|
||||
async onload() {
|
||||
BaseNoteStatusService.initialize(this.app);
|
||||
|
|
@ -53,13 +55,7 @@ export default class NoteStatusPlugin extends Plugin {
|
|||
(leaf) => new StatusDashboardView(leaf),
|
||||
);
|
||||
|
||||
this.addRibbonIcon("list-tree", "Open grouped status view", () => {
|
||||
this.activateView();
|
||||
});
|
||||
|
||||
this.addRibbonIcon("activity", "Open status dashboard", () => {
|
||||
this.activateDashboard();
|
||||
});
|
||||
this.syncExperimentalFeatureShortcuts();
|
||||
}
|
||||
|
||||
async onunload() {
|
||||
|
|
@ -70,6 +66,8 @@ export default class NoteStatusPlugin extends Plugin {
|
|||
this.commandsIntegration?.destroy();
|
||||
this.editorToolbarIntegration?.destroy();
|
||||
this.pluginSettingsIntegration?.destroy();
|
||||
this.experimentalRibbonShortcuts.forEach((el) => el.remove());
|
||||
this.experimentalRibbonShortcuts.clear();
|
||||
|
||||
// Clean up event subscriptions
|
||||
eventBus.unsubscribe(
|
||||
|
|
@ -148,6 +146,58 @@ export default class NoteStatusPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
private syncExperimentalFeatureShortcuts(): void {
|
||||
const shortcuts = this.getExperimentalShortcuts();
|
||||
Object.entries(shortcuts).forEach(([key, config]) => {
|
||||
this.toggleExperimentalRibbon(key, config);
|
||||
});
|
||||
}
|
||||
|
||||
private getExperimentalShortcuts() {
|
||||
return {
|
||||
groupedStatusView: {
|
||||
feature: "groupedStatusView" as const,
|
||||
icon: "list-tree",
|
||||
title: "Open grouped status view",
|
||||
handler: () => this.activateView(),
|
||||
},
|
||||
statusDashboard: {
|
||||
feature: "statusDashboard" as const,
|
||||
icon: "activity",
|
||||
title: "Open status dashboard",
|
||||
handler: () => this.activateDashboard(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private toggleExperimentalRibbon(
|
||||
key: string,
|
||||
config: {
|
||||
feature: Parameters<typeof isExperimentalFeatureEnabled>[0];
|
||||
icon: string;
|
||||
title: string;
|
||||
handler: () => void;
|
||||
},
|
||||
): void {
|
||||
const isEnabled = isExperimentalFeatureEnabled(config.feature);
|
||||
const existingIcon = this.experimentalRibbonShortcuts.get(key);
|
||||
|
||||
if (isEnabled && !existingIcon) {
|
||||
const ribbonEl = this.addRibbonIcon(
|
||||
config.icon,
|
||||
config.title,
|
||||
config.handler,
|
||||
);
|
||||
this.experimentalRibbonShortcuts.set(key, ribbonEl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled && existingIcon) {
|
||||
existingIcon.remove();
|
||||
this.experimentalRibbonShortcuts.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
private async loadEventBus() {
|
||||
// Propagate to custom event bus the new active file
|
||||
this.app.workspace.on(
|
||||
|
|
@ -179,6 +229,13 @@ export default class NoteStatusPlugin extends Plugin {
|
|||
if (key === "enableStatusOverviewPopup" && value === false) {
|
||||
StatusesInfoPopup.close();
|
||||
}
|
||||
if (
|
||||
key === "enableExperimentalFeatures" ||
|
||||
key === "enableStatusDashboard" ||
|
||||
key === "enableGroupedStatusView"
|
||||
) {
|
||||
this.syncExperimentalFeatureShortcuts();
|
||||
}
|
||||
},
|
||||
"main-status-popup-setting-subscriptor",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ export type PluginSettings = {
|
|||
fileExplorerLeftBorder: boolean; // Whether to display a colored border on the explorer item
|
||||
fileExplorerStatusDot: boolean; // Whether to append a small colored dot next to the filename
|
||||
fileExplorerUnderlineFileName: boolean; // Whether to underline the filename using the status color
|
||||
enableExperimentalFeatures: boolean; // Gate for experimental features
|
||||
enableStatusDashboard: boolean; // Toggle for the status dashboard experiment
|
||||
enableGroupedStatusView: boolean; // Toggle for the grouped status view experiment
|
||||
enabledTemplates: string[]; // IDs of enabled templates
|
||||
useCustomStatusesOnly: boolean; // Whether to use only custom statuses or include templates
|
||||
useMultipleStatuses: boolean; // Whether to allow multiple statuses per note
|
||||
|
|
|
|||
23
utils/experimentalFeatures.ts
Normal file
23
utils/experimentalFeatures.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import settingsService from "@/core/settingsService";
|
||||
|
||||
export type ExperimentalFeature = "statusDashboard" | "groupedStatusView";
|
||||
|
||||
const FEATURE_SETTING_MAP: Record<
|
||||
ExperimentalFeature,
|
||||
keyof typeof settingsService.settings
|
||||
> = {
|
||||
statusDashboard: "enableStatusDashboard",
|
||||
groupedStatusView: "enableGroupedStatusView",
|
||||
};
|
||||
|
||||
export function isExperimentalFeatureEnabled(
|
||||
feature: ExperimentalFeature,
|
||||
): boolean {
|
||||
const settings = settingsService.settings;
|
||||
if (!settings.enableExperimentalFeatures) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const flagKey = FEATURE_SETTING_MAP[feature];
|
||||
return Boolean(settings[flagKey]);
|
||||
}
|
||||
Loading…
Reference in a new issue