75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
/** 지표 추가 팝업 — 사용자 정의 탭 (localStorage) */
|
|
|
|
export interface IndicatorCustomTab {
|
|
id: string;
|
|
name: string;
|
|
/** INDICATOR_REGISTRY type 목록 (표시 순서) */
|
|
indicatorTypes: string[];
|
|
}
|
|
|
|
const STORAGE_KEY = 'gc-indicator-custom-tabs-v1';
|
|
|
|
function newId(): string {
|
|
return `tab-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`;
|
|
}
|
|
|
|
export function loadCustomTabs(): IndicatorCustomTab[] {
|
|
try {
|
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) return [];
|
|
const arr = JSON.parse(raw) as unknown;
|
|
if (!Array.isArray(arr)) return [];
|
|
return arr.filter(
|
|
(t): t is IndicatorCustomTab =>
|
|
t != null
|
|
&& typeof t === 'object'
|
|
&& typeof (t as IndicatorCustomTab).id === 'string'
|
|
&& typeof (t as IndicatorCustomTab).name === 'string'
|
|
&& Array.isArray((t as IndicatorCustomTab).indicatorTypes),
|
|
);
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export function saveCustomTabs(tabs: IndicatorCustomTab[]): void {
|
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(tabs));
|
|
window.dispatchEvent(new CustomEvent('gc-indicator-custom-tabs-changed'));
|
|
}
|
|
|
|
export function createCustomTab(name: string, indicatorTypes: string[]): IndicatorCustomTab {
|
|
const tab: IndicatorCustomTab = {
|
|
id: newId(),
|
|
name: name.trim(),
|
|
indicatorTypes: [...new Set(indicatorTypes)],
|
|
};
|
|
const tabs = loadCustomTabs();
|
|
tabs.push(tab);
|
|
saveCustomTabs(tabs);
|
|
return tab;
|
|
}
|
|
|
|
export function updateCustomTab(
|
|
id: string,
|
|
patch: Partial<Pick<IndicatorCustomTab, 'name' | 'indicatorTypes'>>,
|
|
): IndicatorCustomTab | null {
|
|
const tabs = loadCustomTabs();
|
|
const idx = tabs.findIndex(t => t.id === id);
|
|
if (idx < 0) return null;
|
|
const next: IndicatorCustomTab = {
|
|
...tabs[idx],
|
|
...patch,
|
|
name: patch.name != null ? patch.name.trim() : tabs[idx].name,
|
|
indicatorTypes: patch.indicatorTypes != null
|
|
? [...new Set(patch.indicatorTypes)]
|
|
: tabs[idx].indicatorTypes,
|
|
};
|
|
tabs[idx] = next;
|
|
saveCustomTabs(tabs);
|
|
return next;
|
|
}
|
|
|
|
export function deleteCustomTab(id: string): void {
|
|
saveCustomTabs(loadCustomTabs().filter(t => t.id !== id));
|
|
}
|