mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 12:30:24 +00:00
Merge pull request #54 from devonthesofa/chore/fix-build
chore: remove unused components
This commit is contained in:
commit
45af700bc2
3 changed files with 0 additions and 455 deletions
|
|
@ -101,7 +101,6 @@ export const CustomStatusSettings: React.FC<Props> = ({
|
|||
key={index}
|
||||
status={status}
|
||||
index={index}
|
||||
settings={settings}
|
||||
onCustomStatusChange={updateCustomStatus}
|
||||
onCustomStatusRemove={removeCustomStatus}
|
||||
onMoveUp={moveCustomStatusUp}
|
||||
|
|
|
|||
|
|
@ -1,156 +0,0 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { StatusTemplate, PluginSettings } from "../../types/pluginSettings";
|
||||
import { NoteStatus } from "../../types/noteStatus";
|
||||
import { Input } from "../atoms/Input";
|
||||
import { TemplateStatusSelector } from "./TemplateStatusSelector";
|
||||
|
||||
interface TemplateEditorProps {
|
||||
template: StatusTemplate | null;
|
||||
onSave: (template: StatusTemplate) => void | Promise<void>;
|
||||
onCancel: () => void;
|
||||
existingTemplateNames: string[];
|
||||
settings: PluginSettings;
|
||||
}
|
||||
|
||||
export const TemplateEditor: React.FC<TemplateEditorProps> = ({
|
||||
template,
|
||||
onSave,
|
||||
onCancel,
|
||||
existingTemplateNames,
|
||||
settings,
|
||||
}) => {
|
||||
const [templateName, setTemplateName] = useState(template?.name || "");
|
||||
const [templateDescription, setTemplateDescription] = useState(
|
||||
template?.description || "",
|
||||
);
|
||||
const [statuses, setStatuses] = useState<NoteStatus[]>(
|
||||
template?.statuses || [],
|
||||
);
|
||||
const [errors, setErrors] = useState<string[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (template) {
|
||||
setTemplateName(template.name);
|
||||
setTemplateDescription(template.description);
|
||||
setStatuses(template.statuses);
|
||||
}
|
||||
}, [template]);
|
||||
|
||||
const validateForm = (): boolean => {
|
||||
const newErrors: string[] = [];
|
||||
|
||||
if (!templateName.trim()) {
|
||||
newErrors.push("Template name is required");
|
||||
} else if (
|
||||
existingTemplateNames.includes(templateName.trim().toLowerCase())
|
||||
) {
|
||||
newErrors.push("Template name must be unique");
|
||||
}
|
||||
|
||||
if (!templateDescription.trim()) {
|
||||
newErrors.push("Template description is required");
|
||||
}
|
||||
|
||||
if (statuses.length === 0) {
|
||||
newErrors.push("At least one status is required");
|
||||
}
|
||||
|
||||
const statusNames = statuses.map((s) => s.name.toLowerCase());
|
||||
const duplicateNames = statusNames.filter(
|
||||
(name, index) => statusNames.indexOf(name) !== index,
|
||||
);
|
||||
if (duplicateNames.length > 0) {
|
||||
newErrors.push("Status names must be unique within template");
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
return newErrors.length === 0;
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
if (!validateForm()) return;
|
||||
|
||||
const templateToSave: StatusTemplate = {
|
||||
id: template?.id || "", // Will be generated in integration
|
||||
name: templateName.trim(),
|
||||
description: templateDescription.trim(),
|
||||
statuses: statuses,
|
||||
};
|
||||
|
||||
onSave(templateToSave);
|
||||
};
|
||||
|
||||
const handleStatusesChange = (newStatuses: NoteStatus[]) => {
|
||||
setStatuses(newStatuses);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="template-editor">
|
||||
<div className="template-editor__header">
|
||||
<h4>{template ? "Edit Template" : "Create New Template"}</h4>
|
||||
</div>
|
||||
|
||||
{errors.length > 0 && (
|
||||
<div className="template-editor__errors">
|
||||
{errors.map((error, index) => (
|
||||
<div key={index} className="template-editor__error">
|
||||
{error}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="template-editor__basic-info">
|
||||
<div className="template-editor__field">
|
||||
<label className="template-editor__label">
|
||||
Template Name
|
||||
</label>
|
||||
<Input
|
||||
variant="text"
|
||||
value={templateName}
|
||||
onChange={setTemplateName}
|
||||
placeholder="Enter template name"
|
||||
className="template-editor__input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="template-editor__field">
|
||||
<label className="template-editor__label">
|
||||
Description
|
||||
</label>
|
||||
<textarea
|
||||
value={templateDescription}
|
||||
onChange={(e) => setTemplateDescription(e.target.value)}
|
||||
placeholder="Describe this template's purpose"
|
||||
className="template-editor__textarea"
|
||||
rows={2}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="template-editor__statuses-section">
|
||||
<h5 className="template-editor__section-title">
|
||||
Template Statuses
|
||||
</h5>
|
||||
<p className="template-editor__section-description">
|
||||
Select existing statuses or create new ones for this
|
||||
template
|
||||
</p>
|
||||
|
||||
<TemplateStatusSelector
|
||||
selectedStatuses={statuses}
|
||||
onStatusesChange={handleStatusesChange}
|
||||
templateId={template?.id}
|
||||
settings={settings}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="template-editor__actions">
|
||||
<button onClick={handleSave} className="mod-cta">
|
||||
{template ? "Update Template" : "Create Template"}
|
||||
</button>
|
||||
<button onClick={onCancel}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,298 +0,0 @@
|
|||
import React, { useState, useCallback, useMemo } from "react";
|
||||
import { NoteStatus } from "../../types/noteStatus";
|
||||
import { StatusSelector } from "../atoms/StatusSelector";
|
||||
import { SearchFilter } from "../atoms/SearchFilter";
|
||||
import { CustomStatusItem } from "./CustomStatusItem";
|
||||
import { CustomStatusIntegration } from "../../integrations/customStatus/customStatusIntegration";
|
||||
import { TemplateIntegration } from "../../integrations/templates/templateIntegration";
|
||||
import { PluginSettings } from "../../types/pluginSettings";
|
||||
|
||||
interface TemplateStatusSelectorProps {
|
||||
selectedStatuses: NoteStatus[];
|
||||
onStatusesChange: (statuses: NoteStatus[]) => void;
|
||||
templateId?: string;
|
||||
settings: PluginSettings;
|
||||
}
|
||||
|
||||
export const TemplateStatusSelector: React.FC<TemplateStatusSelectorProps> = ({
|
||||
selectedStatuses,
|
||||
onStatusesChange,
|
||||
templateId = "",
|
||||
settings,
|
||||
}) => {
|
||||
const [searchFilter, setSearchFilter] = useState("");
|
||||
const [isCreatingNew, setIsCreatingNew] = useState(false);
|
||||
const [newStatus, setNewStatus] = useState<NoteStatus>({
|
||||
name: "",
|
||||
icon: "",
|
||||
color: "#4CAF50",
|
||||
templateId: templateId,
|
||||
});
|
||||
|
||||
// Get all available statuses (custom + from other templates)
|
||||
const availableStatuses = useMemo(() => {
|
||||
const customStatuses = CustomStatusIntegration.getCustomStatuses();
|
||||
const allTemplates = TemplateIntegration.getTemplates();
|
||||
const templateStatuses = allTemplates
|
||||
.filter((t) => t.id !== templateId) // Exclude current template
|
||||
.flatMap((t) => t.statuses);
|
||||
|
||||
return [...customStatuses, ...templateStatuses];
|
||||
}, [templateId]);
|
||||
|
||||
// Filter statuses based on search
|
||||
const filteredStatuses = useMemo(() => {
|
||||
if (!searchFilter) return availableStatuses;
|
||||
const filter = searchFilter.toLowerCase();
|
||||
return availableStatuses.filter(
|
||||
(status) =>
|
||||
status.name.toLowerCase().includes(filter) ||
|
||||
status.description?.toLowerCase().includes(filter) ||
|
||||
status.templateId?.toLowerCase().includes(filter),
|
||||
);
|
||||
}, [availableStatuses, searchFilter]);
|
||||
|
||||
const handleToggleStatus = useCallback(
|
||||
(status: NoteStatus, selected: boolean) => {
|
||||
if (selected) {
|
||||
// Add status with current template ID
|
||||
const statusWithTemplateId = {
|
||||
...status,
|
||||
templateId: templateId,
|
||||
};
|
||||
onStatusesChange([...selectedStatuses, statusWithTemplateId]);
|
||||
} else {
|
||||
// Remove status
|
||||
const updatedStatuses = selectedStatuses.filter(
|
||||
(s) =>
|
||||
!(
|
||||
s.name === status.name &&
|
||||
s.templateId === status.templateId
|
||||
),
|
||||
);
|
||||
onStatusesChange(updatedStatuses);
|
||||
}
|
||||
},
|
||||
[selectedStatuses, onStatusesChange, templateId],
|
||||
);
|
||||
|
||||
const handleCreateNew = useCallback(() => {
|
||||
setIsCreatingNew(true);
|
||||
setNewStatus({
|
||||
name: "",
|
||||
icon: "",
|
||||
color: "#4CAF50",
|
||||
templateId: templateId,
|
||||
});
|
||||
}, [templateId]);
|
||||
|
||||
const handleSaveNewStatus = useCallback(() => {
|
||||
const errors = CustomStatusIntegration.validateStatus(newStatus);
|
||||
if (errors.length > 0) return;
|
||||
|
||||
// Check if name is unique in selected statuses
|
||||
const isUniqueInTemplate = !selectedStatuses.some(
|
||||
(s) => s.name.toLowerCase() === newStatus.name.toLowerCase(),
|
||||
);
|
||||
|
||||
if (!isUniqueInTemplate) {
|
||||
return; // Could show error message
|
||||
}
|
||||
|
||||
// Add to selected statuses
|
||||
const statusWithTemplateId = {
|
||||
...newStatus,
|
||||
templateId: templateId,
|
||||
};
|
||||
onStatusesChange([...selectedStatuses, statusWithTemplateId]);
|
||||
|
||||
setIsCreatingNew(false);
|
||||
setNewStatus({
|
||||
name: "",
|
||||
icon: "",
|
||||
color: "#4CAF50",
|
||||
templateId: templateId,
|
||||
});
|
||||
}, [newStatus, selectedStatuses, onStatusesChange, templateId]);
|
||||
|
||||
const handleCancelNewStatus = useCallback(() => {
|
||||
setIsCreatingNew(false);
|
||||
setNewStatus({
|
||||
name: "",
|
||||
icon: "",
|
||||
color: "#4CAF50",
|
||||
templateId: templateId,
|
||||
});
|
||||
}, [templateId]);
|
||||
|
||||
const handleNewStatusChange = useCallback(
|
||||
(column: "name" | "icon" | "color" | "description", value: string) => {
|
||||
setNewStatus((prev) => ({
|
||||
...prev,
|
||||
[column]: value,
|
||||
}));
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const handleRemoveSelectedStatus = useCallback(
|
||||
(index: number) => {
|
||||
const updatedStatuses = selectedStatuses.filter(
|
||||
(_, i) => i !== index,
|
||||
);
|
||||
onStatusesChange(updatedStatuses);
|
||||
},
|
||||
[selectedStatuses, onStatusesChange],
|
||||
);
|
||||
|
||||
const handleEditSelectedStatus = useCallback(
|
||||
(
|
||||
index: number,
|
||||
column: "name" | "icon" | "color" | "description",
|
||||
value: string,
|
||||
) => {
|
||||
const updatedStatuses = [...selectedStatuses];
|
||||
updatedStatuses[index] = {
|
||||
...updatedStatuses[index],
|
||||
[column]: value,
|
||||
};
|
||||
onStatusesChange(updatedStatuses);
|
||||
},
|
||||
[selectedStatuses, onStatusesChange],
|
||||
);
|
||||
|
||||
const handleMoveStatusUp = useCallback(
|
||||
(index: number) => {
|
||||
if (index <= 0) return;
|
||||
const updatedStatuses = [...selectedStatuses];
|
||||
[updatedStatuses[index - 1], updatedStatuses[index]] = [
|
||||
updatedStatuses[index],
|
||||
updatedStatuses[index - 1],
|
||||
];
|
||||
onStatusesChange(updatedStatuses);
|
||||
},
|
||||
[selectedStatuses, onStatusesChange],
|
||||
);
|
||||
|
||||
const handleMoveStatusDown = useCallback(
|
||||
(index: number) => {
|
||||
if (index >= selectedStatuses.length - 1) return;
|
||||
const updatedStatuses = [...selectedStatuses];
|
||||
[updatedStatuses[index], updatedStatuses[index + 1]] = [
|
||||
updatedStatuses[index + 1],
|
||||
updatedStatuses[index],
|
||||
];
|
||||
onStatusesChange(updatedStatuses);
|
||||
},
|
||||
[selectedStatuses, onStatusesChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="template-status-selector">
|
||||
<div className="template-status-selector__section">
|
||||
<h6 className="template-status-selector__title">
|
||||
Select from Existing Statuses
|
||||
</h6>
|
||||
<p className="template-status-selector__description">
|
||||
Choose from custom statuses or statuses from other templates
|
||||
</p>
|
||||
|
||||
<SearchFilter
|
||||
value={searchFilter}
|
||||
onFilterChange={setSearchFilter}
|
||||
/>
|
||||
|
||||
{filteredStatuses.length === 0 ? (
|
||||
<div className="template-status-selector__empty">
|
||||
{searchFilter
|
||||
? `No statuses match "${searchFilter}"`
|
||||
: "No existing statuses available"}
|
||||
</div>
|
||||
) : (
|
||||
<StatusSelector
|
||||
availableStatuses={filteredStatuses}
|
||||
currentStatuses={selectedStatuses}
|
||||
onToggleStatus={handleToggleStatus}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="template-status-selector__divider">
|
||||
<span>OR</span>
|
||||
</div>
|
||||
|
||||
<div className="template-status-selector__section">
|
||||
<div className="template-status-selector__new-header">
|
||||
<h6 className="template-status-selector__title">
|
||||
Create New Status
|
||||
</h6>
|
||||
{!isCreatingNew && (
|
||||
<button
|
||||
className="template-status-selector__create-btn"
|
||||
onClick={handleCreateNew}
|
||||
>
|
||||
+ Create New
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isCreatingNew && (
|
||||
<div className="template-status-selector__new-form">
|
||||
<CustomStatusItem
|
||||
status={newStatus}
|
||||
index={0}
|
||||
settings={settings}
|
||||
onCustomStatusChange={(_, column, value) =>
|
||||
handleNewStatusChange(column, value)
|
||||
}
|
||||
onCustomStatusRemove={() => {}} // Not used
|
||||
/>
|
||||
<div className="template-status-selector__new-actions">
|
||||
<button
|
||||
className="mod-cta"
|
||||
onClick={handleSaveNewStatus}
|
||||
disabled={
|
||||
!newStatus.name.trim() ||
|
||||
!newStatus.icon.trim()
|
||||
}
|
||||
>
|
||||
Add Status
|
||||
</button>
|
||||
<button onClick={handleCancelNewStatus}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{selectedStatuses.length > 0 && (
|
||||
<div className="template-status-selector__section">
|
||||
<h6 className="template-status-selector__title">
|
||||
Selected Statuses
|
||||
</h6>
|
||||
<div className="template-status-selector__selected">
|
||||
{selectedStatuses.map((status, index) => (
|
||||
<CustomStatusItem
|
||||
key={`${status.name}-${index}`}
|
||||
status={status}
|
||||
index={index}
|
||||
settings={settings}
|
||||
onCustomStatusChange={handleEditSelectedStatus}
|
||||
onCustomStatusRemove={
|
||||
handleRemoveSelectedStatus
|
||||
}
|
||||
onMoveUp={handleMoveStatusUp}
|
||||
onMoveDown={handleMoveStatusDown}
|
||||
canMoveUp={index > 0}
|
||||
canMoveDown={
|
||||
index < selectedStatuses.length - 1
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in a new issue