mirror of
https://github.com/taskgenius/taskgenius-plugin.git
synced 2026-07-22 06:40:25 +00:00
feat(kanban): add column visibility toggle with hide/unhide functionality
This commit is contained in:
parent
e0b6d079b5
commit
6ce9671511
8 changed files with 197 additions and 66 deletions
|
|
@ -104,6 +104,7 @@ export interface KanbanSpecificConfig {
|
|||
| "context"
|
||||
| "filePath";
|
||||
customColumns?: KanbanColumnConfig[]; // Custom column definitions when not using status
|
||||
hiddenColumns?: string[]; // List of hidden column titles
|
||||
}
|
||||
|
||||
export interface KanbanColumnConfig {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { App, Component, setIcon } from "obsidian";
|
||||
import { App, Component, setIcon, Menu } from "obsidian";
|
||||
import { Task } from "@/types/task"; // Adjust path
|
||||
import { KanbanCardComponent } from "./kanban-card";
|
||||
import TaskProgressBarPlugin from "@/index"; // Adjust path
|
||||
|
|
@ -38,6 +38,7 @@ export class KanbanColumnComponent extends Component {
|
|||
filterType: string,
|
||||
value: string | number | string[],
|
||||
) => void;
|
||||
onColumnHide?: (columnTitle: string) => void;
|
||||
},
|
||||
) {
|
||||
super();
|
||||
|
|
@ -88,6 +89,25 @@ export class KanbanColumnComponent extends Component {
|
|||
text: `(${this.tasks.length})`,
|
||||
});
|
||||
|
||||
// Add context menu for "Hide this column"
|
||||
this.registerDomEvent(
|
||||
this.headerEl,
|
||||
"contextmenu",
|
||||
(event: MouseEvent) => {
|
||||
if (this.params.onColumnHide) {
|
||||
const menu = new Menu();
|
||||
menu.addItem((item) => {
|
||||
item.setTitle(t("Hide this column"))
|
||||
.setIcon("eye-off")
|
||||
.onClick(() => {
|
||||
this.params.onColumnHide?.(this.statusName);
|
||||
});
|
||||
});
|
||||
menu.showAtMouseEvent(event);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Column Content (Scrollable Area for Cards, and Drop Zone)
|
||||
this.contentEl = this.element.createDiv({
|
||||
cls: "tg-kanban-column-content",
|
||||
|
|
|
|||
|
|
@ -602,6 +602,24 @@ export class KanbanComponent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
private handleColumnHide(title: string): void {
|
||||
const viewConfig = this.plugin.settings.viewConfiguration.find(
|
||||
(v) => v.id === this.currentViewId,
|
||||
);
|
||||
if (viewConfig && viewConfig.specificConfig?.viewType === "kanban") {
|
||||
const kanbanConfig =
|
||||
viewConfig.specificConfig as KanbanSpecificConfig;
|
||||
if (!kanbanConfig.hiddenColumns) {
|
||||
kanbanConfig.hiddenColumns = [];
|
||||
}
|
||||
if (!kanbanConfig.hiddenColumns.includes(title)) {
|
||||
kanbanConfig.hiddenColumns.push(title);
|
||||
this.plugin.saveSettings();
|
||||
this.renderColumns();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private renderColumns() {
|
||||
this.columnContainerEl?.empty();
|
||||
this.columns.forEach((col) => this.removeChild(col));
|
||||
|
|
@ -696,7 +714,13 @@ export class KanbanComponent extends Component {
|
|||
// Apply saved column order to status names
|
||||
const statusColumns = statusNames.map((name) => ({ title: name }));
|
||||
const orderedStatusColumns = this.applyColumnOrder(statusColumns);
|
||||
const orderedStatusNames = orderedStatusColumns.map((col) => col.title);
|
||||
|
||||
// Filter hidden columns
|
||||
const hiddenColumns =
|
||||
this.getEffectiveKanbanConfig()?.hiddenColumns || [];
|
||||
const orderedStatusNames = orderedStatusColumns
|
||||
.map((col) => col.title)
|
||||
.filter((title) => !hiddenColumns.includes(title));
|
||||
|
||||
orderedStatusNames.forEach((statusName) => {
|
||||
const tasksForStatus = this.getTasksForStatus(statusName);
|
||||
|
|
@ -714,6 +738,7 @@ export class KanbanComponent extends Component {
|
|||
newStatusMark: string,
|
||||
) => this.handleStatusUpdate(taskId, newStatusMark),
|
||||
onFilterApply: this.handleFilterApply,
|
||||
onColumnHide: (title) => this.handleColumnHide(title),
|
||||
},
|
||||
);
|
||||
this.addChild(column);
|
||||
|
|
@ -737,6 +762,7 @@ export class KanbanComponent extends Component {
|
|||
newStatusMark: string,
|
||||
) => this.handleStatusUpdate(taskId, newStatusMark),
|
||||
onFilterApply: this.handleFilterApply,
|
||||
onColumnHide: (title) => this.handleColumnHide(title),
|
||||
},
|
||||
);
|
||||
this.addChild(otherColumn); // Must call addChild first to trigger onload()
|
||||
|
|
@ -790,7 +816,14 @@ export class KanbanComponent extends Component {
|
|||
// Apply saved column order to column configurations
|
||||
const orderedColumnConfigs = this.applyColumnOrder(columnConfigs);
|
||||
|
||||
// Filter hidden columns
|
||||
const hiddenColumns =
|
||||
this.getEffectiveKanbanConfig()?.hiddenColumns || [];
|
||||
|
||||
orderedColumnConfigs.forEach((config) => {
|
||||
// Skip hidden columns
|
||||
if (hiddenColumns.includes(config.title)) return;
|
||||
|
||||
const tasksForColumn = this.getTasksForProperty(
|
||||
groupBy,
|
||||
config.value,
|
||||
|
|
@ -812,6 +845,7 @@ export class KanbanComponent extends Component {
|
|||
newValue,
|
||||
),
|
||||
onFilterApply: this.handleFilterApply,
|
||||
onColumnHide: (title) => this.handleColumnHide(title),
|
||||
},
|
||||
);
|
||||
this.addChild(column);
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ import "@/styles/view-setting-tab.css";
|
|||
|
||||
export function renderViewSettingsTab(
|
||||
settingTab: TaskProgressBarSettingTab,
|
||||
containerEl: HTMLElement
|
||||
containerEl: HTMLElement,
|
||||
) {
|
||||
new Setting(containerEl)
|
||||
.setName(t("View Configuration"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Configure the Task Genius sidebar views, visibility, order, and create custom views."
|
||||
)
|
||||
"Configure the Task Genius sidebar views, visibility, order, and create custom views.",
|
||||
),
|
||||
)
|
||||
.setHeading();
|
||||
|
||||
|
|
@ -24,8 +24,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Enable Task Genius Views"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Enable Task Genius sidebar views to display and manage tasks. Requires the indexer to be enabled."
|
||||
)
|
||||
"Enable Task Genius sidebar views to display and manage tasks. Requires the indexer to be enabled.",
|
||||
),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(settingTab.plugin.settings.enableView);
|
||||
|
|
@ -34,8 +34,8 @@ export function renderViewSettingsTab(
|
|||
// If trying to enable views but indexer is disabled, show warning
|
||||
new Notice(
|
||||
t(
|
||||
"Cannot enable views without indexer. Please enable the indexer first in Index & Sources settings."
|
||||
)
|
||||
"Cannot enable views without indexer. Please enable the indexer first in Index & Sources settings.",
|
||||
),
|
||||
);
|
||||
toggle.setValue(false);
|
||||
return;
|
||||
|
|
@ -51,7 +51,7 @@ export function renderViewSettingsTab(
|
|||
new Setting(containerEl)
|
||||
.setName(t("Views are disabled"))
|
||||
.setDesc(
|
||||
t("Enable Task Genius Views above to configure view settings.")
|
||||
t("Enable Task Genius Views above to configure view settings."),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Default view mode"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Choose the default display mode for all views. This affects how tasks are displayed when you first open a view or create a new view."
|
||||
)
|
||||
"Choose the default display mode for all views. This affects how tasks are displayed when you first open a view or create a new view.",
|
||||
),
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
|
|
@ -86,8 +86,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Default project view mode"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Choose whether to display projects as a flat list or hierarchical tree by default."
|
||||
)
|
||||
"Choose whether to display projects as a flat list or hierarchical tree by default.",
|
||||
),
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
|
|
@ -105,8 +105,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Auto-expand project tree"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Automatically expand all project nodes when opening the project view in tree mode."
|
||||
)
|
||||
"Automatically expand all project nodes when opening the project view in tree mode.",
|
||||
),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
|
|
@ -120,12 +120,12 @@ export function renderViewSettingsTab(
|
|||
new Setting(containerEl)
|
||||
.setName(t("Show empty project folders"))
|
||||
.setDesc(
|
||||
t("Display project folders even if they don't contain any tasks.")
|
||||
t("Display project folders even if they don't contain any tasks."),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(
|
||||
settingTab.plugin.settings.projectTreeShowEmptyFolders
|
||||
settingTab.plugin.settings.projectTreeShowEmptyFolders,
|
||||
)
|
||||
.onChange((value) => {
|
||||
settingTab.plugin.settings.projectTreeShowEmptyFolders =
|
||||
|
|
@ -138,8 +138,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Project path separator"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Character used to separate project hierarchy levels (e.g., '/' in 'Project/SubProject')."
|
||||
)
|
||||
"Character used to separate project hierarchy levels (e.g., '/' in 'Project/SubProject').",
|
||||
),
|
||||
)
|
||||
.addText((text) => {
|
||||
text.setPlaceholder("/")
|
||||
|
|
@ -161,8 +161,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Use relative time for date"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Use relative time for date in task list item, e.g. 'yesterday', 'today', 'tomorrow', 'in 2 days', '3 months ago', etc."
|
||||
)
|
||||
"Use relative time for date in task list item, e.g. 'yesterday', 'today', 'tomorrow', 'in 2 days', '3 months ago', etc.",
|
||||
),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(settingTab.plugin.settings.useRelativeTimeForDate);
|
||||
|
|
@ -182,8 +182,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Enable inline editor"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Enable inline editing of task content and metadata directly in task views. When disabled, tasks can only be edited in the source file."
|
||||
)
|
||||
"Enable inline editing of task content and metadata directly in task views. When disabled, tasks can only be edited in the source file.",
|
||||
),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(settingTab.plugin.settings.enableInlineEditor);
|
||||
|
|
@ -197,12 +197,12 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Enable dynamic metadata positioning"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Intelligently position task metadata. When enabled, metadata appears on the same line as short tasks and below long tasks. When disabled, metadata always appears below the task content."
|
||||
)
|
||||
"Intelligently position task metadata. When enabled, metadata appears on the same line as short tasks and below long tasks. When disabled, metadata always appears below the task content.",
|
||||
),
|
||||
)
|
||||
.addToggle((toggle) => {
|
||||
toggle.setValue(
|
||||
settingTab.plugin.settings.enableDynamicMetadataPositioning
|
||||
settingTab.plugin.settings.enableDynamicMetadataPositioning,
|
||||
);
|
||||
toggle.onChange((value) => {
|
||||
settingTab.plugin.settings.enableDynamicMetadataPositioning =
|
||||
|
|
@ -216,8 +216,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Global Filter Configuration"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Configure global filter rules that apply to all Views by default. Individual Views can override these settings."
|
||||
)
|
||||
"Configure global filter rules that apply to all Views by default. Individual Views can override these settings.",
|
||||
),
|
||||
)
|
||||
.setHeading();
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ export function renderViewSettingsTab(
|
|||
if (settingTab.plugin.settings.globalFilterRules.advancedFilter) {
|
||||
settingTab.app.saveLocalStorage(
|
||||
"task-genius-view-filter-global-filter",
|
||||
settingTab.plugin.settings.globalFilterRules.advancedFilter
|
||||
settingTab.plugin.settings.globalFilterRules.advancedFilter,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ export function renderViewSettingsTab(
|
|||
globalFilterContainer,
|
||||
settingTab.app,
|
||||
"global-filter", // Use a special leafId for global filter
|
||||
settingTab.plugin
|
||||
settingTab.plugin,
|
||||
);
|
||||
|
||||
// Load the component
|
||||
|
|
@ -281,8 +281,8 @@ export function renderViewSettingsTab(
|
|||
if (leafId === "global-filter") {
|
||||
handleGlobalFilterChange(filterState);
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -311,8 +311,8 @@ export function renderViewSettingsTab(
|
|||
.setName(t("Manage Views"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Drag views between sections or within sections to reorder them. Toggle visibility with the eye icon."
|
||||
)
|
||||
"Drag views between sections or within sections to reorder them. Toggle visibility with the eye icon.",
|
||||
),
|
||||
)
|
||||
.setHeading();
|
||||
|
||||
|
|
@ -418,7 +418,7 @@ export function renderViewSettingsTab(
|
|||
// Emit event to notify TaskView sidebar to update without full view refresh
|
||||
(settingTab.app.workspace as any).trigger(
|
||||
"task-genius:view-config-changed",
|
||||
{ reason: "visibility-changed", viewId: view.id }
|
||||
{ reason: "visibility-changed", viewId: view.id },
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -443,7 +443,7 @@ export function renderViewSettingsTab(
|
|||
(updatedView: ViewConfig, updatedRules: ViewFilterRule) => {
|
||||
const currentIndex =
|
||||
settingTab.plugin.settings.viewConfiguration.findIndex(
|
||||
(v) => v.id === updatedView.id
|
||||
(v) => v.id === updatedView.id,
|
||||
);
|
||||
if (currentIndex !== -1) {
|
||||
settingTab.plugin.settings.viewConfiguration[
|
||||
|
|
@ -459,10 +459,10 @@ export function renderViewSettingsTab(
|
|||
{
|
||||
reason: "view-updated",
|
||||
viewId: updatedView.id,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
).open();
|
||||
};
|
||||
|
||||
|
|
@ -483,7 +483,7 @@ export function renderViewSettingsTab(
|
|||
(createdView: ViewConfig, createdRules: ViewFilterRule) => {
|
||||
if (
|
||||
!settingTab.plugin.settings.viewConfiguration.some(
|
||||
(v) => v.id === createdView.id
|
||||
(v) => v.id === createdView.id,
|
||||
)
|
||||
) {
|
||||
settingTab.plugin.settings.viewConfiguration.push({
|
||||
|
|
@ -497,18 +497,18 @@ export function renderViewSettingsTab(
|
|||
{
|
||||
reason: "view-copied",
|
||||
viewId: createdView.id,
|
||||
}
|
||||
},
|
||||
);
|
||||
new Notice(
|
||||
t("View copied successfully: ") +
|
||||
createdView.name
|
||||
createdView.name,
|
||||
);
|
||||
} else {
|
||||
new Notice(t("Error: View ID already exists."));
|
||||
}
|
||||
},
|
||||
view,
|
||||
view.id
|
||||
view.id,
|
||||
).open();
|
||||
};
|
||||
|
||||
|
|
@ -528,12 +528,12 @@ export function renderViewSettingsTab(
|
|||
deleteBtn.onclick = () => {
|
||||
const index =
|
||||
settingTab.plugin.settings.viewConfiguration.findIndex(
|
||||
(v) => v.id === view.id
|
||||
(v) => v.id === view.id,
|
||||
);
|
||||
if (index !== -1) {
|
||||
settingTab.plugin.settings.viewConfiguration.splice(
|
||||
index,
|
||||
1
|
||||
1,
|
||||
);
|
||||
settingTab.applySettingsUpdate();
|
||||
renderViewList();
|
||||
|
|
@ -547,7 +547,7 @@ export function renderViewSettingsTab(
|
|||
// Render views in their respective containers
|
||||
topViews.forEach((view) => createViewItem(view, topViewsContainer));
|
||||
bottomViews.forEach((view) =>
|
||||
createViewItem(view, bottomViewsContainer)
|
||||
createViewItem(view, bottomViewsContainer),
|
||||
);
|
||||
|
||||
// Setup sortable for both containers
|
||||
|
|
@ -561,7 +561,7 @@ export function renderViewSettingsTab(
|
|||
const viewId = el.getAttribute("data-view-id");
|
||||
const view =
|
||||
settingTab.plugin.settings.viewConfiguration.find(
|
||||
(v) => v.id === viewId
|
||||
(v) => v.id === viewId,
|
||||
);
|
||||
if (view) {
|
||||
view.region = "top";
|
||||
|
|
@ -576,7 +576,7 @@ export function renderViewSettingsTab(
|
|||
const viewId = el.getAttribute("data-view-id");
|
||||
const view =
|
||||
settingTab.plugin.settings.viewConfiguration.find(
|
||||
(v) => v.id === viewId
|
||||
(v) => v.id === viewId,
|
||||
);
|
||||
if (view) {
|
||||
view.region = "bottom";
|
||||
|
|
@ -589,7 +589,7 @@ export function renderViewSettingsTab(
|
|||
settingTab.plugin.saveSettings();
|
||||
(settingTab.app.workspace as any).trigger(
|
||||
"task-genius:view-config-changed",
|
||||
{ reason: "order-changed" }
|
||||
{ reason: "order-changed" },
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -621,6 +621,19 @@ export function renderViewSettingsTab(
|
|||
|
||||
renderViewList(); // Initial render
|
||||
|
||||
// Listen for view config changes from FluentSidebar or other sources
|
||||
settingTab.plugin.registerEvent(
|
||||
settingTab.app.workspace.on(
|
||||
"task-genius:view-config-changed",
|
||||
(payload: { reason: string }) => {
|
||||
// Only refresh if the change came from sidebar reorder
|
||||
if (payload?.reason === "sidebar-reorder") {
|
||||
renderViewList();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// Add New Custom View Button (Logic unchanged)
|
||||
const addBtnContainer = containerEl.createDiv();
|
||||
new Setting(addBtnContainer).addButton((button) => {
|
||||
|
|
@ -636,7 +649,7 @@ export function renderViewSettingsTab(
|
|||
(createdView: ViewConfig, createdRules: ViewFilterRule) => {
|
||||
if (
|
||||
!settingTab.plugin.settings.viewConfiguration.some(
|
||||
(v) => v.id === createdView.id
|
||||
(v) => v.id === createdView.id,
|
||||
)
|
||||
) {
|
||||
// Save with filter rules embedded
|
||||
|
|
@ -648,12 +661,15 @@ export function renderViewSettingsTab(
|
|||
renderViewList();
|
||||
(settingTab.app.workspace as any).trigger(
|
||||
"task-genius:view-config-changed",
|
||||
{ reason: "view-added", viewId: createdView.id }
|
||||
{
|
||||
reason: "view-added",
|
||||
viewId: createdView.id,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
new Notice(t("Error: View ID already exists."));
|
||||
}
|
||||
}
|
||||
},
|
||||
).open();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -175,9 +175,7 @@ export class ViewConfigModal extends Modal {
|
|||
this.onSave = onSave;
|
||||
}
|
||||
|
||||
private applyTwoColumnPresetIfNeeded(
|
||||
sourceConfig?: ViewConfig,
|
||||
): void {
|
||||
private applyTwoColumnPresetIfNeeded(sourceConfig?: ViewConfig): void {
|
||||
if (!this.isCopyMode) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -196,8 +194,8 @@ export class ViewConfigModal extends Modal {
|
|||
|
||||
if (hasTwoColumnConfig) {
|
||||
// Already a two column view; ensure task property aligns with preset if missing
|
||||
const currentConfig =
|
||||
this.viewConfig.specificConfig as TwoColumnSpecificConfig;
|
||||
const currentConfig = this.viewConfig
|
||||
.specificConfig as TwoColumnSpecificConfig;
|
||||
if (!currentConfig.taskPropertyKey) {
|
||||
currentConfig.taskPropertyKey = preset.taskPropertyKey;
|
||||
}
|
||||
|
|
@ -216,10 +214,7 @@ export class ViewConfigModal extends Modal {
|
|||
}
|
||||
|
||||
const identifier =
|
||||
sourceIdentifier ??
|
||||
sourceConfig?.id ??
|
||||
sourceConfig?.name ??
|
||||
null;
|
||||
sourceIdentifier ?? sourceConfig?.id ?? sourceConfig?.name ?? null;
|
||||
|
||||
if (!identifier) {
|
||||
return null;
|
||||
|
|
@ -281,9 +276,7 @@ export class ViewConfigModal extends Modal {
|
|||
case "project":
|
||||
multiSelectText = t("projects selected");
|
||||
if (normalized.includes("review")) {
|
||||
emptyStateText = t(
|
||||
"Select a project to review its tasks.",
|
||||
);
|
||||
emptyStateText = t("Select a project to review its tasks.");
|
||||
leftColumnTitle = t("Review Projects");
|
||||
} else {
|
||||
emptyStateText = t("Select a project to see related tasks");
|
||||
|
|
@ -333,7 +326,10 @@ export class ViewConfigModal extends Modal {
|
|||
normalizedIdentifier: string,
|
||||
sourceConfig?: ViewConfig,
|
||||
): string {
|
||||
if (propertyKey === "project" && normalizedIdentifier.includes("review")) {
|
||||
if (
|
||||
propertyKey === "project" &&
|
||||
normalizedIdentifier.includes("review")
|
||||
) {
|
||||
return t("Review Projects");
|
||||
}
|
||||
|
||||
|
|
@ -833,6 +829,40 @@ export class ViewConfigModal extends Modal {
|
|||
});
|
||||
});
|
||||
|
||||
// Hidden Columns Management
|
||||
const kanbanConfigForHidden = this.viewConfig
|
||||
.specificConfig as KanbanSpecificConfig;
|
||||
const hiddenColumns = kanbanConfigForHidden?.hiddenColumns || [];
|
||||
if (hiddenColumns.length > 0) {
|
||||
new Setting(contentEl)
|
||||
.setName(t("Hidden Columns"))
|
||||
.setDesc(
|
||||
t(
|
||||
"Columns that are currently hidden from view. Click the eye icon to show them again.",
|
||||
),
|
||||
)
|
||||
.setHeading();
|
||||
|
||||
hiddenColumns.forEach((colTitle, index) => {
|
||||
new Setting(contentEl)
|
||||
.setName(colTitle)
|
||||
.addButton((button) => {
|
||||
button
|
||||
.setIcon("eye")
|
||||
.setTooltip(t("Unhide column"))
|
||||
.onClick(() => {
|
||||
const config = this.viewConfig
|
||||
.specificConfig as KanbanSpecificConfig;
|
||||
if (config.hiddenColumns) {
|
||||
config.hiddenColumns.splice(index, 1);
|
||||
this.checkForChanges();
|
||||
this.display(); // Refresh to update list
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Custom columns configuration for non-status grouping
|
||||
const kanbanConfig = this.viewConfig
|
||||
.specificConfig as KanbanSpecificConfig;
|
||||
|
|
|
|||
|
|
@ -2583,6 +2583,13 @@ const translations = {
|
|||
"kanban.allCycles": "All Cycles",
|
||||
"kanban.otherColumn": "Other",
|
||||
"kanban.noCyclesAvailable": "No cycles available",
|
||||
|
||||
// Kanban Column Visibility
|
||||
"Hide this column": "Hide this column",
|
||||
"Hidden Columns": "Hidden Columns",
|
||||
"Columns that are currently hidden from view. Click the eye icon to show them again.":
|
||||
"Columns that are currently hidden from view. Click the eye icon to show them again.",
|
||||
"Unhide column": "Unhide column",
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
|
|||
|
|
@ -2374,6 +2374,13 @@ const translations = {
|
|||
"kanban.allCycles": "所有周期",
|
||||
"kanban.otherColumn": "其他",
|
||||
"kanban.noCyclesAvailable": "无可用周期",
|
||||
|
||||
// Kanban Column Visibility
|
||||
"Hide this column": "隐藏此列",
|
||||
"Hidden Columns": "已隐藏的列",
|
||||
"Columns that are currently hidden from view. Click the eye icon to show them again.":
|
||||
"当前隐藏的列。点击眼睛图标可重新显示。",
|
||||
"Unhide column": "显示列",
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
|
|||
18
styles.css
18
styles.css
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue