Implement addItem cohort creation flow in settings

This commit is contained in:
Jack Williams 2026-05-30 22:27:16 +10:00
parent 9b600cf7e1
commit 2ec43d9f85
2 changed files with 58 additions and 28 deletions

View file

@ -5,6 +5,7 @@ import { prettyCohortDefinition, resolveFilesForCohort } from '../domain/cohort/
import type GlickoPlugin from '../main';
import type { CohortData, CohortDefinition } from '../types';
import { CohortOptionsModal } from '../ui/CohortOptionsModal';
import { CohortPicker } from '../ui/CohortPicker';
import { ConfirmModal } from '../ui/ConfirmModal';
import {
computeRanksForAll,
@ -304,8 +305,13 @@ export default class GlickoSettingsTab extends PluginSettingTab {
return {
type: 'list',
heading: 'Cohorts',
emptyState:
'No cohorts saved yet. Start a session to create one, or use the command palette.',
emptyState: 'No cohorts saved yet. Add one to get started, or use the command palette.',
addItem: {
name: 'Add cohort',
action: () => {
void this.addNewCohort();
},
},
onDelete: (idx) => {
const def = this.sortedCohortDefs()[idx];
if (!def) return;
@ -321,6 +327,21 @@ export default class GlickoSettingsTab extends PluginSettingTab {
};
}
private async addNewCohort(): Promise<void> {
const def = await new CohortPicker(this.app, this.plugin, {
createOnly: true,
}).openAndGetSelection();
if (!def) return;
// upsert only when this is genuinely a new entry.
if (!this.plugin.dataStore.getCohortDef(def.key)) {
this.plugin.dataStore.upsertCohortDef(def);
await this.plugin.dataStore.saveStore();
}
this.update();
}
private sortedCohortDefs(): CohortDefinition[] {
return this.plugin.dataStore
.listCohortDefs()

View file

@ -26,11 +26,15 @@ export class CohortPicker extends FuzzySuggestModal<Choice> {
private resolver?: (def?: CohortDefinition) => void;
private resolved = false;
private awaitingChild = false;
private createOnly: boolean;
constructor(app: App, plugin: GlickoPlugin) {
constructor(app: App, plugin: GlickoPlugin, opts?: { createOnly?: boolean }) {
super(app);
this.plugin = plugin;
this.setPlaceholder('Choose a cohort or create a new one...');
this.createOnly = opts?.createOnly ?? false;
this.setPlaceholder(
this.createOnly ? 'Choose a new cohort type...' : 'Choose a cohort or create a new one...',
);
}
async openAndGetSelection(): Promise<CohortDefinition | undefined> {
@ -43,34 +47,39 @@ export class CohortPicker extends FuzzySuggestModal<Choice> {
getItems(): Choice[] {
const items: Choice[] = [];
// Last used
const lastKey = this.plugin.dataStore.store.lastUsedCohortKey;
if (lastKey) {
const lastDef = this.plugin.dataStore.getCohortDef(lastKey) ?? parseCohortKey(lastKey);
if (lastDef)
if (!this.createOnly) {
// Last used
const lastKey = this.plugin.dataStore.store.lastUsedCohortKey;
if (lastKey) {
const lastDef = this.plugin.dataStore.getCohortDef(lastKey) ?? parseCohortKey(lastKey);
if (lastDef)
items.push({
kind: 'saved',
key: lastDef.key,
label: `Last used: ${lastDef.label ?? prettyCohortDefinition(lastDef)}`,
def: lastDef,
});
}
// Saved definitions
const defs = this.plugin.dataStore.listCohortDefs();
for (const def of defs) {
if (def.key === 'vault:all') continue;
if (def.key === lastKey) continue;
items.push({
kind: 'saved',
key: lastDef.key,
label: `Last used: ${lastDef.label ?? prettyCohortDefinition(lastDef)}`,
def: lastDef,
key: def.key,
label: def.label ?? prettyCohortDefinition(def),
def,
});
}
}
// Saved definitions
const defs = this.plugin.dataStore.listCohortDefs();
for (const def of defs) {
if (def.key === 'vault:all') continue;
if (def.key === lastKey) continue;
items.push({
kind: 'saved',
key: def.key,
label: def.label ?? prettyCohortDefinition(def),
def,
});
}
// Add "Vault: all notes" only if not already present
if (!items.some((item) => item.kind === 'saved' && item.def.key === 'vault:all')) {
// Add "Vault: all notes" only if not already present
if (!items.some((item) => item.kind === 'saved' && item.def.key === 'vault:all')) {
items.push({ kind: 'action', action: 'vault-all', label: 'Vault: all notes' });
}
} else if (!this.plugin.dataStore.getCohortDef('vault:all')) {
// Create-only: offer vault-all only if the user doesn't already have one.
items.push({ kind: 'action', action: 'vault-all', label: 'Vault: all notes' });
}