devonthesofa_obsidian-note-.../components/SettingsUI/CustomStatusSettings.tsx
Aleix Soler f97bca5fa9 feat: implement granular selective synchronization and non-Markdown status sync
- Expand sync categories to include templates, custom statuses, colors, UI, workflow, storage, and features
- Add support for syncing non-Markdown status data to a vault-based JSON file
- Update NonMarkdownStatusStore to handle vault-based storage and real-time updates
- Enhance Synchronization UI with granular group selection and data sync options
- Add safety checks to prevent TypeErrors during settings initialization and migration
2026-03-18 12:35:49 +01:00

127 lines
3.4 KiB
TypeScript

import { PluginSettings } from "@/types/pluginSettings";
import React from "react";
import {
CustomStatusItem,
Props as CustomStatusItemProps,
} from "./CustomStatusItem";
import { SettingItem } from "./SettingItem";
export type Props = {
settings: PluginSettings;
onChange: (key: keyof PluginSettings, value: unknown) => void;
};
export const CustomStatusSettings: React.FC<Props> = ({
settings,
onChange,
}) => {
const addNewCustomStatus = () => {
const currentStatuses = [...(settings.customStatuses || [])];
currentStatuses.push({
name: "",
icon: "",
lucideIcon: "",
});
onChange("customStatuses", currentStatuses);
};
const removeCustomStatus: CustomStatusItemProps["onCustomStatusRemove"] = (
index,
) => {
const currentStatuses = [...(settings.customStatuses || [])];
currentStatuses.splice(index, 1);
onChange("customStatuses", currentStatuses);
};
const updateCustomStatus: CustomStatusItemProps["onCustomStatusChange"] = (
index,
column,
value,
) => {
const currentStatuses = [...(settings.customStatuses || [])];
const target = currentStatuses[index];
if (target) {
target[column] = value;
onChange("customStatuses", currentStatuses);
}
};
const moveCustomStatusUp = (index: number) => {
if (index <= 0) return;
const currentStatuses = [...(settings.customStatuses || [])];
[currentStatuses[index - 1], currentStatuses[index]] = [
currentStatuses[index],
currentStatuses[index - 1],
];
onChange("customStatuses", currentStatuses);
};
const moveCustomStatusDown = (index: number) => {
const currentStatuses = [...(settings.customStatuses || [])];
if (index >= currentStatuses.length - 1) return;
[currentStatuses[index], currentStatuses[index + 1]] = [
currentStatuses[index + 1],
currentStatuses[index],
];
onChange("customStatuses", currentStatuses);
};
return (
<div>
<h3>Custom Statuses</h3>
<SettingItem
name="Use only custom statuses"
description="Hide default template statuses and use only your custom statuses"
>
<input
type="checkbox"
checked={settings.useCustomStatusesOnly || false}
onChange={(e) =>
onChange("useCustomStatusesOnly", e.target.checked)
}
/>
</SettingItem>
<SettingItem
name="Custom statuses"
description="Create custom statuses with emoji icons and optional Lucide icon names plus colors. All statuses require a name."
vertical
>
<div className="custom-status-list">
{(settings.customStatuses || []).length === 0 ? (
<div className="custom-status-list__empty">
<p>
No custom statuses yet. Click "Add Status" below
to create your first one.
</p>
</div>
) : (
(settings.customStatuses || []).map((status, index) => (
<CustomStatusItem
key={index}
status={status}
index={index}
onCustomStatusChange={updateCustomStatus}
onCustomStatusRemove={removeCustomStatus}
onMoveUp={moveCustomStatusUp}
onMoveDown={moveCustomStatusDown}
canMoveUp={index > 0}
canMoveDown={
index <
(settings.customStatuses || []).length - 1
}
/>
))
)}
</div>
</SettingItem>
<SettingItem name="Add status" description="Create a new status">
<button className="mod-cta" onClick={addNewCustomStatus}>
+ Add Status
</button>
</SettingItem>
</div>
);
};