mirror of
https://github.com/taskgenius/taskgenius-plugin.git
synced 2026-07-22 06:40:25 +00:00
feat(settings): enhance index settings with tabbed source configuration
- Add tabbed interface for Checkbox Tasks and File Tasks configuration - Introduce FileFilterScopeControls to manage inline vs file task sources - Create ViewComponent base class for unified view component behaviors - Improve settings UI with clearer separation of task source types - Add scope controls to FileFilterManager for granular source management - Update calendar component formatting and add configOverride support - Enhance CSS styling for tabbed settings interface
This commit is contained in:
parent
af31b39f30
commit
0ae3957144
13 changed files with 1010 additions and 519 deletions
|
|
@ -649,10 +649,16 @@ export enum FilterMode {
|
|||
BLACKLIST = "blacklist",
|
||||
}
|
||||
|
||||
export interface FileFilterScopeControls {
|
||||
inlineTasksEnabled: boolean;
|
||||
fileTasksEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface FileFilterSettings {
|
||||
enabled: boolean;
|
||||
mode: FilterMode;
|
||||
rules: FileFilterRule[];
|
||||
scopeControls?: FileFilterScopeControls;
|
||||
}
|
||||
|
||||
/** MCP Server Configuration */
|
||||
|
|
@ -1522,6 +1528,10 @@ export const DEFAULT_SETTINGS: TaskProgressBarSettings = {
|
|||
rules: [
|
||||
// No default rules - let users explicitly choose via preset templates
|
||||
],
|
||||
scopeControls: {
|
||||
inlineTasksEnabled: true,
|
||||
fileTasksEnabled: true,
|
||||
},
|
||||
},
|
||||
|
||||
// OnCompletion Defaults
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ export class CalendarComponent extends Component {
|
|||
private badgeEventsCacheVersion: number = 0;
|
||||
|
||||
|
||||
// Per-view override from Bases (firstDayOfWeek, hideWeekends, ...)
|
||||
private configOverride: Partial<import("@/common/setting-definition").CalendarSpecificConfig> | null = null;
|
||||
// Per-view override from Bases (firstDayOfWeek, hideWeekends, ...)
|
||||
private configOverride: Partial<import("@/common/setting-definition").CalendarSpecificConfig> | null = null;
|
||||
|
||||
constructor(
|
||||
app: App,
|
||||
|
|
@ -162,8 +162,6 @@ export class CalendarComponent extends Component {
|
|||
this.app.saveLocalStorage(
|
||||
"task-genius:calendar-view",
|
||||
this.currentViewMode
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -703,7 +701,8 @@ export class CalendarComponent extends Component {
|
|||
let endDate: Date;
|
||||
|
||||
switch (this.currentViewMode) {
|
||||
case "month":
|
||||
case "month": {
|
||||
|
||||
// For month view, compute for the entire grid (including previous/next month days)
|
||||
const startOfMonth = this.currentDate.clone().startOf("month");
|
||||
const endOfMonth = this.currentDate.clone().endOf("month");
|
||||
|
|
@ -715,7 +714,7 @@ export class CalendarComponent extends Component {
|
|||
const gridStart = startOfMonth
|
||||
.clone()
|
||||
.weekday(firstDayOfWeek - 7);
|
||||
let gridEnd = endOfMonth.clone().weekday(firstDayOfWeek + 6);
|
||||
const gridEnd = endOfMonth.clone().weekday(firstDayOfWeek + 6);
|
||||
|
||||
// Ensure at least 42 days (6 weeks)
|
||||
if (gridEnd.diff(gridStart, "days") + 1 < 42) {
|
||||
|
|
@ -727,13 +726,16 @@ export class CalendarComponent extends Component {
|
|||
startDate = gridStart.toDate();
|
||||
endDate = gridEnd.toDate();
|
||||
break;
|
||||
}
|
||||
|
||||
case "week": {
|
||||
|
||||
case "week":
|
||||
const startOfWeek = this.currentDate.clone().startOf("week");
|
||||
const endOfWeek = this.currentDate.clone().endOf("week");
|
||||
startDate = startOfWeek.toDate();
|
||||
endDate = endOfWeek.toDate();
|
||||
break;
|
||||
}
|
||||
|
||||
case "day":
|
||||
startDate = this.currentDate.clone().startOf("day").toDate();
|
||||
|
|
@ -887,7 +889,7 @@ export class CalendarComponent extends Component {
|
|||
new QuickCaptureModal(
|
||||
this.app,
|
||||
this.plugin,
|
||||
{ dueDate: moment(day).toDate() },
|
||||
{dueDate: moment(day).toDate()},
|
||||
true
|
||||
).open();
|
||||
} else if (options.behavior === "open-task-view") {
|
||||
|
|
@ -934,19 +936,19 @@ export class CalendarComponent extends Component {
|
|||
this.params?.onTaskCompleted?.(event);
|
||||
};
|
||||
|
||||
// Allow external overrides (e.g., from Bases) and compute effective config
|
||||
public setConfigOverride(
|
||||
override: Partial<import("@/common/setting-definition").CalendarSpecificConfig> | null
|
||||
): void {
|
||||
this.configOverride = override ?? null;
|
||||
// Re-render to apply new config
|
||||
this.render();
|
||||
}
|
||||
// Allow external overrides (e.g., from Bases) and compute effective config
|
||||
public setConfigOverride(
|
||||
override: Partial<import("@/common/setting-definition").CalendarSpecificConfig> | null
|
||||
): void {
|
||||
this.configOverride = override ?? null;
|
||||
// Re-render to apply new config
|
||||
this.render();
|
||||
}
|
||||
|
||||
private getEffectiveCalendarConfig(): Partial<import("@/common/setting-definition").CalendarSpecificConfig> {
|
||||
const baseCfg = this.plugin.settings.viewConfiguration.find((v) => v.id === this.viewId)?.specificConfig as Partial<import("@/common/setting-definition").CalendarSpecificConfig> | undefined;
|
||||
return { ...(baseCfg ?? {}), ...(this.configOverride ?? {}) };
|
||||
}
|
||||
private getEffectiveCalendarConfig(): Partial<import("@/common/setting-definition").CalendarSpecificConfig> {
|
||||
const baseCfg = this.plugin.settings.viewConfiguration.find((v) => v.id === this.viewId)?.specificConfig as Partial<import("@/common/setting-definition").CalendarSpecificConfig> | undefined;
|
||||
return {...(baseCfg ?? {}), ...(this.configOverride ?? {})};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
protected taskMetadata: TaskMetadata = {};
|
||||
protected currentMode: QuickCaptureMode;
|
||||
protected suggestManager: SuggestManager;
|
||||
protected inlineModeAvailable: boolean = true;
|
||||
protected fileModeAvailable: boolean = false;
|
||||
|
||||
// UI Elements
|
||||
protected headerContainer: HTMLElement | null = null;
|
||||
|
|
@ -78,6 +80,22 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
this.plugin = plugin;
|
||||
this.currentMode = initialMode;
|
||||
|
||||
const scopeControls =
|
||||
this.plugin.settings.fileFilter?.scopeControls;
|
||||
this.inlineModeAvailable =
|
||||
scopeControls?.inlineTasksEnabled !== false;
|
||||
this.fileModeAvailable =
|
||||
(this.plugin.settings.fileSource?.enabled ?? false) &&
|
||||
scopeControls?.fileTasksEnabled !== false;
|
||||
if (!scopeControls) {
|
||||
this.inlineModeAvailable = true;
|
||||
this.fileModeAvailable =
|
||||
this.plugin.settings.fileSource?.enabled ?? false;
|
||||
}
|
||||
if (!this.inlineModeAvailable && !this.fileModeAvailable) {
|
||||
this.inlineModeAvailable = true;
|
||||
}
|
||||
|
||||
// Initialize suggest manager
|
||||
this.suggestManager = new SuggestManager(app, plugin);
|
||||
|
||||
|
|
@ -91,11 +109,14 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
}
|
||||
|
||||
// If FileSource is disabled, force mode to checkbox
|
||||
if (
|
||||
this.currentMode === "file" &&
|
||||
!this.plugin.settings?.fileSource?.enabled
|
||||
) {
|
||||
if (this.currentMode === "file" && !this.fileModeAvailable) {
|
||||
this.currentMode = "checkbox";
|
||||
} else if (
|
||||
this.currentMode === "checkbox" &&
|
||||
!this.inlineModeAvailable &&
|
||||
this.fileModeAvailable
|
||||
) {
|
||||
this.currentMode = "file";
|
||||
}
|
||||
|
||||
// Initialize settings
|
||||
|
|
@ -187,38 +208,43 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
});
|
||||
|
||||
// Checkbox mode button (save as checkbox task)
|
||||
const checkboxButton = new ButtonComponent(tabContainer)
|
||||
.setClass("quick-capture-tab")
|
||||
.onClick(() => this.switchMode("checkbox"));
|
||||
if (this.inlineModeAvailable) {
|
||||
const checkboxButton = new ButtonComponent(tabContainer)
|
||||
.setClass("quick-capture-tab")
|
||||
.onClick(() => this.switchMode("checkbox"));
|
||||
|
||||
checkboxButton.buttonEl.toggleClass("clickable-icon", true);
|
||||
checkboxButton.buttonEl.toggleClass("clickable-icon", true);
|
||||
|
||||
const checkboxButtonEl = checkboxButton.buttonEl;
|
||||
checkboxButtonEl.setAttribute("role", "tab");
|
||||
checkboxButtonEl.setAttribute(
|
||||
"aria-selected",
|
||||
String(this.currentMode === "checkbox")
|
||||
);
|
||||
checkboxButtonEl.setAttribute("aria-controls", "quick-capture-content");
|
||||
checkboxButtonEl.setAttribute("data-mode", "checkbox");
|
||||
const checkboxButtonEl = checkboxButton.buttonEl;
|
||||
checkboxButtonEl.setAttribute("role", "tab");
|
||||
checkboxButtonEl.setAttribute(
|
||||
"aria-selected",
|
||||
String(this.currentMode === "checkbox")
|
||||
);
|
||||
checkboxButtonEl.setAttribute(
|
||||
"aria-controls",
|
||||
"quick-capture-content"
|
||||
);
|
||||
checkboxButtonEl.setAttribute("data-mode", "checkbox");
|
||||
|
||||
if (this.currentMode === "checkbox") {
|
||||
checkboxButton.setClass("active");
|
||||
if (this.currentMode === "checkbox") {
|
||||
checkboxButton.setClass("active");
|
||||
}
|
||||
|
||||
// Manually create spans for icon and text
|
||||
checkboxButtonEl.empty();
|
||||
const checkboxIconSpan = checkboxButtonEl.createSpan({
|
||||
cls: "quick-capture-tab-icon",
|
||||
});
|
||||
setIcon(checkboxIconSpan, "check-square");
|
||||
checkboxButtonEl.createSpan({
|
||||
text: t("Checkbox"),
|
||||
cls: "quick-capture-tab-text",
|
||||
});
|
||||
}
|
||||
|
||||
// Manually create spans for icon and text
|
||||
checkboxButtonEl.empty();
|
||||
const checkboxIconSpan = checkboxButtonEl.createSpan({
|
||||
cls: "quick-capture-tab-icon",
|
||||
});
|
||||
setIcon(checkboxIconSpan, "check-square");
|
||||
checkboxButtonEl.createSpan({
|
||||
text: t("Checkbox"),
|
||||
cls: "quick-capture-tab-text",
|
||||
});
|
||||
|
||||
// File mode button (save as file) - only when FileSource is enabled
|
||||
if (this.plugin.settings?.fileSource?.enabled) {
|
||||
if (this.fileModeAvailable) {
|
||||
const fileButton = new ButtonComponent(tabContainer)
|
||||
.setClass("quick-capture-tab")
|
||||
.onClick(() => this.switchMode("file"));
|
||||
|
|
@ -249,6 +275,10 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
});
|
||||
}
|
||||
|
||||
if (!(this.fileModeAvailable && this.inlineModeAvailable)) {
|
||||
tabContainer.classList.add("is-hidden");
|
||||
}
|
||||
|
||||
// Right side: Clear button with improved styling
|
||||
const clearButton = this.headerContainer.createEl("button", {
|
||||
text: t("Clear"),
|
||||
|
|
@ -305,8 +335,8 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
*/
|
||||
protected async switchMode(mode: QuickCaptureMode): Promise<void> {
|
||||
if (mode === this.currentMode) return;
|
||||
// Prevent switching to file mode when FileSource is disabled
|
||||
if (mode === "file" && !this.plugin.settings?.fileSource?.enabled) {
|
||||
// Prevent switching to unsupported modes
|
||||
if (mode === "file" && !this.fileModeAvailable) {
|
||||
new Notice(
|
||||
t(
|
||||
"File Task is disabled. Enable FileSource in Settings to use File mode."
|
||||
|
|
@ -314,6 +344,9 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
);
|
||||
return;
|
||||
}
|
||||
if (mode === "checkbox" && !this.inlineModeAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save current state
|
||||
const savedContent = this.capturedContent;
|
||||
|
|
@ -334,14 +367,13 @@ export abstract class BaseQuickCaptureModal extends Modal {
|
|||
// Update tab active states
|
||||
const tabs =
|
||||
this.headerContainer?.querySelectorAll(".quick-capture-tab");
|
||||
tabs?.forEach((tab, index) => {
|
||||
tabs?.forEach((tab) => {
|
||||
tab.removeClass("active");
|
||||
if (
|
||||
(index === 0 && mode === "checkbox") ||
|
||||
(index === 1 && mode === "file")
|
||||
) {
|
||||
const tabMode = tab.getAttribute("data-mode");
|
||||
if (tabMode === mode) {
|
||||
tab.addClass("active");
|
||||
}
|
||||
tab.setAttribute("aria-selected", String(tabMode === mode));
|
||||
});
|
||||
|
||||
// Update only the target display instead of recreating everything
|
||||
|
|
|
|||
|
|
@ -14,14 +14,28 @@ import { ListConfigModal } from "@/components/ui/modals/ListConfigModal";
|
|||
/**
|
||||
* Create File Task settings UI
|
||||
*/
|
||||
export interface FileSourceSettingsOptions {
|
||||
showEnableToggle?: boolean;
|
||||
}
|
||||
|
||||
export function createFileSourceSettings(
|
||||
containerEl: HTMLElement,
|
||||
plugin: TaskProgressBarPlugin
|
||||
plugin: TaskProgressBarPlugin,
|
||||
options: FileSourceSettingsOptions = {}
|
||||
): void {
|
||||
const config = plugin.settings?.fileSource;
|
||||
|
||||
if (!config) {
|
||||
console.warn(
|
||||
"[FileSourceSettings] Missing fileSource configuration on plugin settings"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Main FileSource enable/disable toggle
|
||||
createEnableToggle(containerEl, plugin, config);
|
||||
if (options.showEnableToggle !== false) {
|
||||
createEnableToggle(containerEl, plugin, config);
|
||||
}
|
||||
|
||||
if (config.enabled) {
|
||||
// Recognition strategies section
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
44
src/components/ui/base/ViewComponent.ts
Normal file
44
src/components/ui/base/ViewComponent.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import { App, Component } from "obsidian";
|
||||
import TaskProgressBarPlugin from "@/index";
|
||||
import { Task } from "@/types/task";
|
||||
import { ViewMode } from "@/common/setting-definition";
|
||||
|
||||
/**
|
||||
* Base class for view components to unify common behaviors across special views
|
||||
* (kanban, calendar, gantt, forecast, quadrant, table, twocolumn, ...)
|
||||
*
|
||||
* Note: Intentionally minimal and non-invasive so existing components can
|
||||
* progressively migrate to extend this class without large refactors.
|
||||
*/
|
||||
export abstract class ViewComponent<TOverride = any> extends Component {
|
||||
protected app: App;
|
||||
protected plugin: TaskProgressBarPlugin;
|
||||
protected currentViewId: string;
|
||||
protected configOverride: Partial<TOverride> | null = null;
|
||||
|
||||
constructor(app: App, plugin: TaskProgressBarPlugin, viewId: string) {
|
||||
super();
|
||||
this.app = app;
|
||||
this.plugin = plugin;
|
||||
this.currentViewId = viewId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject per-view override configuration (e.g., from Bases view config)
|
||||
* Subclasses should merge this with their own config and refresh UI if needed.
|
||||
*/
|
||||
public setConfigOverride(override: Partial<TOverride> | null): void {
|
||||
this.configOverride = override ?? null;
|
||||
}
|
||||
|
||||
/** Optional hooks for specific view components to implement */
|
||||
// Provide tasks to the component (filteredTasks, allTasks, forceRefresh?)
|
||||
public setTasks(_tasks: Task[], _allTasks?: Task[], _forceRefresh?: boolean): void {}
|
||||
|
||||
// Update tasks incrementally (some components expose this instead of setTasks)
|
||||
public updateTasks(_tasks: Task[]): void {}
|
||||
|
||||
// Switch internal mode (some views support different modes within the same component)
|
||||
public setViewMode(_viewMode: ViewMode, _project?: string | null): void {}
|
||||
}
|
||||
|
||||
|
|
@ -5,7 +5,7 @@ import "@/styles/modal.css";
|
|||
|
||||
export interface ListConfigModalParams {
|
||||
title: string;
|
||||
description: string;
|
||||
description: string | DocumentFragment;
|
||||
placeholder?: string;
|
||||
values: string[];
|
||||
onSave: (values: string[]) => void;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
*/
|
||||
|
||||
import { normalizePath, TFile, TFolder } from "obsidian";
|
||||
import { FilterMode } from "../common/setting-definition";
|
||||
import {
|
||||
FilterMode,
|
||||
type FileFilterScopeControls,
|
||||
} from "../common/setting-definition";
|
||||
|
||||
/**
|
||||
* Filter rule types
|
||||
|
|
@ -25,6 +28,7 @@ export interface FileFilterConfig {
|
|||
enabled: boolean;
|
||||
mode: FilterMode;
|
||||
rules: FilterRule[];
|
||||
scopeControls?: FileFilterScopeControls;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -109,6 +113,10 @@ export class FileFilterManager {
|
|||
private fileSet: Set<string> = new Set(); // global (legacy)
|
||||
private patternRegexes: RegExp[] = []; // global (legacy)
|
||||
private cache: Map<string, boolean> = new Map();
|
||||
private scopeControls: FileFilterScopeControls = {
|
||||
inlineTasksEnabled: true,
|
||||
fileTasksEnabled: true,
|
||||
};
|
||||
|
||||
// Scoped indexes for per-rule scope control
|
||||
private folderTrieInline: PathTrie = new PathTrie();
|
||||
|
|
@ -120,6 +128,9 @@ export class FileFilterManager {
|
|||
|
||||
constructor(config: FileFilterConfig) {
|
||||
this.config = config;
|
||||
this.scopeControls = this.normalizeScopeControls(
|
||||
config.scopeControls
|
||||
);
|
||||
this.rebuildIndexes();
|
||||
}
|
||||
|
||||
|
|
@ -128,10 +139,37 @@ export class FileFilterManager {
|
|||
*/
|
||||
updateConfig(config: FileFilterConfig): void {
|
||||
this.config = config;
|
||||
this.scopeControls = this.normalizeScopeControls(
|
||||
config.scopeControls
|
||||
);
|
||||
this.rebuildIndexes();
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
private normalizeScopeControls(
|
||||
scopeControls?: FileFilterScopeControls
|
||||
): FileFilterScopeControls {
|
||||
return {
|
||||
inlineTasksEnabled:
|
||||
scopeControls?.inlineTasksEnabled !== false,
|
||||
fileTasksEnabled:
|
||||
scopeControls?.fileTasksEnabled !== false,
|
||||
};
|
||||
}
|
||||
|
||||
private isScopeEnabled(scope: "both" | "inline" | "file"): boolean {
|
||||
if (scope === "inline") {
|
||||
return this.scopeControls.inlineTasksEnabled !== false;
|
||||
}
|
||||
if (scope === "file") {
|
||||
return this.scopeControls.fileTasksEnabled !== false;
|
||||
}
|
||||
return (
|
||||
this.scopeControls.inlineTasksEnabled !== false ||
|
||||
this.scopeControls.fileTasksEnabled !== false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file should be included in indexing
|
||||
*/
|
||||
|
|
@ -139,6 +177,9 @@ export class FileFilterManager {
|
|||
file: TFile,
|
||||
scope: "both" | "inline" | "file" = "both"
|
||||
): boolean {
|
||||
if (!this.isScopeEnabled(scope)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.config.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -162,6 +203,9 @@ export class FileFilterManager {
|
|||
folder: TFolder,
|
||||
scope: "both" | "inline" | "file" = "both"
|
||||
): boolean {
|
||||
if (!this.isScopeEnabled(scope)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.config.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -185,6 +229,9 @@ export class FileFilterManager {
|
|||
path: string,
|
||||
scope: "both" | "inline" | "file" = "both"
|
||||
): boolean {
|
||||
if (!this.isScopeEnabled(scope)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.config.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@
|
|||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 4px 6px -1px rgb(0 0 0 / 0.1),
|
||||
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--shadow-xl: 0 10px 15px -3px rgb(0 0 0 / 0.1),
|
||||
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
/* Modal specific styles */
|
||||
|
|
@ -51,8 +51,7 @@
|
|||
|
||||
/* Header section */
|
||||
.onboarding-view .onboarding-header {
|
||||
padding: calc(var(--onboarding-spacing) * 4) var(--onboarding-spacing)
|
||||
var(--size-4-2) var(--onboarding-spacing);
|
||||
padding: calc(var(--onboarding-spacing) * 4) var(--onboarding-spacing) var(--size-4-2) var(--onboarding-spacing);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +265,7 @@
|
|||
var(--background-primary) 100%
|
||||
);
|
||||
box-shadow: var(--shadow-md),
|
||||
0 0 0 3px rgba(var(--interactive-accent-rgb), 0.1);
|
||||
0 0 0 3px rgba(var(--interactive-accent-rgb), 0.1);
|
||||
}
|
||||
|
||||
.onboarding-view .settings-check-action-card:hover {
|
||||
|
|
@ -1524,8 +1523,8 @@
|
|||
filter: blur(4px);
|
||||
transform: translateY(-2px);
|
||||
transition: opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
filter 0.4s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
filter 0.4s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
@ -1759,7 +1758,7 @@
|
|||
|
||||
.selectable-card {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--onboarding-border-radius);
|
||||
border-radius: var(--onboarding-border-radius, var(--radius-m));
|
||||
padding: var(--size-4-4);
|
||||
cursor: pointer;
|
||||
transition: var(--onboarding-transition);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,10 @@
|
|||
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
.quick-capture-tabs.is-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Quick Capture Tab Button Icon and Text - shadcn style */
|
||||
.quick-capture-tab-icon {
|
||||
margin-right: 6px;
|
||||
|
|
|
|||
|
|
@ -221,3 +221,56 @@
|
|||
border-top: 1px solid var(--background-modifier-border);
|
||||
padding-top: var(--size-4-4);
|
||||
}
|
||||
|
||||
|
||||
.fluent-view-tabs.tg-index-task-source-switcher {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
gap: var(--size-2-2);
|
||||
background-color: var(--background-secondary);
|
||||
border-radius: var(--size-2-3);
|
||||
padding: var(--size-2-1);
|
||||
margin-bottom: var(--size-4-4);
|
||||
width: fit-content;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.tg-index-task-source-switcher .fluent-view-tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.tg-index-task-source-switcher .fluent-view-tab:hover {
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.tg-index-task-source-switcher .fluent-view-tab.is-active {
|
||||
background-color: var(--background-primary);
|
||||
color: var(--text-normal);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.tg-index-task-source-switcher .fluent-view-tab-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tg-index-task-source-switcher .fluent-view-tab-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@
|
|||
.task-genius-settings:has(
|
||||
.settings-tab-section-active:not([data-tab-id="general"])
|
||||
)
|
||||
.settings-tabs-categorized-container {
|
||||
.settings-tabs-categorized-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
@ -444,7 +444,7 @@
|
|||
|
||||
/* Show legacy tabs when general tab is active (fallback behavior) */
|
||||
.task-genius-settings:has(.settings-tab-active[data-tab-id="general"])
|
||||
.settings-tabs-container {
|
||||
.settings-tabs-container {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +456,7 @@
|
|||
.task-genius-settings:has(
|
||||
.settings-tab-section-active:not([data-tab-id="general"])
|
||||
)
|
||||
.task-genius-settings-header {
|
||||
.task-genius-settings-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
@ -1294,8 +1294,7 @@
|
|||
var(--accent-l),
|
||||
0.5
|
||||
);
|
||||
border: 1px solid
|
||||
hsl(var(--accent-h), var(--accent-s), var(--accent-l), 0.5);
|
||||
border: 1px solid hsl(var(--accent-h), var(--accent-s), var(--accent-l), 0.5);
|
||||
border-radius: var(--radius-m);
|
||||
color: var(--text-on-accent);
|
||||
}
|
||||
|
|
@ -1578,3 +1577,24 @@
|
|||
.task-genius-date-examples-table tr:hover td {
|
||||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.tg-index-task-source-wrapper {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.tg-index-task-source-panels {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tg-source-settings-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.tg-source-settings-body.tg-source-disabled {
|
||||
opacity: 0.55;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
|
|||
70
styles.css
70
styles.css
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue