Skip to content

Commit

Permalink
feat: add shelf page
Browse files Browse the repository at this point in the history
  • Loading branch information
srg-kostyrko committed Oct 19, 2024
1 parent 4c02940 commit c4d9ac9
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 33 deletions.
48 changes: 48 additions & 0 deletions src/components/modals/RenameShelf.modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import ObsidianSetting from "../obsidian/ObsidianSetting.vue";
import ObsidianTextInput from "../obsidian/ObsidianTextInput.vue";
import ObsidianButton from "../obsidian/ObsidianButton.vue";
import { pluginSettings$ } from "@/stores/settings.store";
const props = defineProps<{
name: string;
}>();
const emit = defineEmits<{
(event: "save", name: string): void;
(event: "close"): void;
}>();
const newName = ref(props.name);
const canSave = computed(() => {
return (
newName.value.length > 0 &&
newName.value !== props.name &&
pluginSettings$.value.shelves[newName.value] === undefined
);
});
const showUniqeWarning = computed(() => {
return newName.value && newName.value !== props.name && pluginSettings$.value.shelves[newName.value] !== undefined;
});
function save() {
emit("save", newName.value);
emit("close");
}
</script>

<template>
<ObsidianSetting name="New name">
<template #description>
<span v-if="showUniqeWarning" class="journal-important">This name is already used.</span>
</template>
<ObsidianTextInput v-model="newName" />
</ObsidianSetting>
<ObsidianSetting>
<ObsidianButton @click="$emit('close')">Cancel</ObsidianButton>
<ObsidianButton cta :disabled="!canSave" @click="save">Save</ObsidianButton>
</ObsidianSetting>
</template>

<style scoped></style>
3 changes: 2 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class JournalPlugin extends Plugin {
return this.#journals.get(name);
}

createJournal(name: string, write: JournalSettings["write"]): void {
createJournal(name: string, write: JournalSettings["write"]): JournalSettings {
const settings: JournalSettings = deepCopy({
...deepCopy(defaultJournalSettings),
...prepareJournalDefaultsBasedOnType(write),
Expand All @@ -40,6 +40,7 @@ export default class JournalPlugin extends Plugin {
});
pluginSettings$.value.journals[name] = settings;
this.#journals.set(name, new Journal(name));
return pluginSettings$.value.journals[name];
}

async renameJournal(name: string, newName: string): Promise<void> {
Expand Down
4 changes: 2 additions & 2 deletions src/settings/JournalSettingsDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { updateLocale } from "../calendar";
import JournalSettingsWithoutShelves from "./JournalSettingsWithoutShelves.vue";
import JournalSettingsWithShelves from "./JournalSettingsWithShelves.vue";
const emit = defineEmits<(event: "edit" | "orgamize", name: string) => void>();
const emit = defineEmits<(event: "edit" | "organize", name: string) => void>();
const fow = moment().localeData().firstDayOfWeek();
const fowText = moment().localeData().weekdays()[fow];
Expand Down Expand Up @@ -58,7 +58,7 @@ function changeFirstWeekOfYear(value: number): void {
<ObsidianToggle v-model="pluginSettings$.useShelves" />
</ObsidianSetting>

<JournalSettingsWithShelves v-if="pluginSettings$.useShelves" @organize="emit('orgamize', $event)" />
<JournalSettingsWithShelves v-if="pluginSettings$.useShelves" @organize="emit('organize', $event)" />
<JournalSettingsWithoutShelves v-else @edit="emit('edit', $event)" />

<ObsidianSetting name="Calendar view" heading />
Expand Down
29 changes: 22 additions & 7 deletions src/settings/JournalSettingsList.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
<script setup lang="ts">
import { computed } from "vue";
import { journals$ } from "../stores/settings.store";
import ObsidianSetting from "../components/obsidian/ObsidianSetting.vue";
import ObsidianIconButton from "../components/obsidian/ObsidianIconButton.vue";
import type { JournalSettings, NotesProcessing } from "@/types/settings.types";
import { VueModal } from "@/components/modals/vue-modal";
import RemoveJournal from "@/components/modals/RemoveJournal.modal.vue";
import { plugin$ } from "@/stores/obsidian.store";
import { journals$ } from "@/stores/settings.store";
defineEmits<{
(event: "edit", name: string): void;
// eslint-disable-next-line @typescript-eslint/unified-signatures
(event: "remove", name: string): void;
const { journals } = defineProps<{
journals: JournalSettings[];
}>();
const journalsList = computed(() => Object.values(journals$.value).toSorted((a, b) => a.name.localeCompare(b.name)));
defineEmits<(event: "edit", name: string) => void>();
const journalsList = computed(() => Object.values(journals).toSorted((a, b) => a.name.localeCompare(b.name)));
function remove(name: string): void {
const journal = journals$.value[name];
if (!journal) return;
new VueModal(`Remove ${journal.name} journal`, RemoveJournal, {
onRemove(_noteProcessing: NotesProcessing) {
// TODO Process notes on remove
plugin$.value.removeJournal(name);
},
}).open();
}
</script>

<template>
Expand All @@ -22,7 +37,7 @@ const journalsList = computed(() => Object.values(journals$.value).toSorted((a,
<span class="flair">{{ journal.write.type }}</span>
</template>
<ObsidianIconButton icon="pencil" :tooltip="'Edit ' + journal.name" @click="$emit('edit', journal.name)" />
<ObsidianIconButton icon="trash-2" :tooltip="'Delete ' + journal.name" @click="$emit('remove', journal.name)" />
<ObsidianIconButton icon="trash-2" :tooltip="'Delete ' + journal.name" @click="remove(journal.name)" />
</ObsidianSetting>
</template>
</template>
11 changes: 10 additions & 1 deletion src/settings/JournalSettingsRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import { ref } from "vue";
import JournalSettingsDashboard from "./JournalSettingsDashboard.vue";
import JournalSettingsEdit from "./JournalSettingsEdit.vue";
import JournalSettingsShelfDetails from "./JournalSettingsShelfDetails.vue";
const selectedJournalName = ref<string | null>(null);
const selectedShelfName = ref<string | null>(null);
</script>

<template>
Expand All @@ -13,5 +15,12 @@ const selectedJournalName = ref<string | null>(null);
@back="selectedJournalName = null"
@edit="selectedJournalName = $event"
/>
<JournalSettingsDashboard v-else @edit="selectedJournalName = $event" />
<JournalSettingsShelfDetails
v-else-if="selectedShelfName"
:shelf-name="selectedShelfName"
@back="selectedShelfName = null"
@organize="selectedShelfName = $event"
@edit="selectedJournalName = $event"
/>
<JournalSettingsDashboard v-else @edit="selectedJournalName = $event" @organize="selectedShelfName = $event" />
</template>
66 changes: 66 additions & 0 deletions src/settings/JournalSettingsShelfDetails.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup lang="ts">
import { pluginSettings$ } from "@/stores/settings.store";
import { computed } from "vue";
import ObsidianSetting from "@/components/obsidian/ObsidianSetting.vue";
import ObsidianIconButton from "@/components/obsidian/ObsidianIconButton.vue";
import { VueModal } from "@/components/modals/vue-modal";
import { plugin$ } from "@/stores/obsidian.store";
import RenameShelfModal from "@/components/modals/RenameShelf.modal.vue";
import CreateJournal from "@/components/modals/CreateJournal.modal.vue";
import type { JournalSettings } from "@/types/settings.types";
import JournalSettingsList from "./JournalSettingsList.vue";
const { shelfName } = defineProps<{
shelfName: string;
}>();
const emit = defineEmits<{
(event: "back"): void;
(event: "edit" | "organize", name: string): void;
}>();
const shelf = computed(() => pluginSettings$.value.shelves[shelfName]);
const shelfJournals = computed(() => {
if (!shelf.value) return [];
return shelf.value.journals.map((journalName) => pluginSettings$.value.journals[journalName]);
});
function showRenameModal(): void {
new VueModal("Rename shelf", RenameShelfModal, {
name: shelf.value.name,
onSave(name: string) {
plugin$.value.renameShelf(shelfName, name);
emit("organize", name);
},
}).open();
}
function create(): void {
new VueModal("Add Journal", CreateJournal, {
onCreate(name: string, writing: JournalSettings["write"]) {
const journal = plugin$.value.createJournal(name, writing);
shelf.value.journals.push(name);
journal.shelves.push(shelfName);
emit("edit", name);
},
}).open();
}
</script>

<template>
<div v-if="shelf">
<ObsidianSetting heading>
<template #name> Configuring {{ shelf.name }} </template>
<ObsidianIconButton icon="pencil" tooltip="Rename shelf" @click="showRenameModal" />
<ObsidianIconButton icon="chevron-left" tooltip="Back to list" @click="$emit('back')" />
</ObsidianSetting>

<ObsidianSetting name="Journals" heading>
<ObsidianIconButton icon="plus" cta tooltip="Create new journal" @click="create" />
</ObsidianSetting>

<JournalSettingsList :journals="shelfJournals" @edit="$emit('edit', $event)" />
</div>
</template>

<style scoped></style>
5 changes: 3 additions & 2 deletions src/settings/JournalSettingsWithShelves.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ function removeShelf(shelfName: string): void {
<ObsidianSetting v-for="shelf of shelvesList" :key="shelf.name">
<template #name>
<b>
{{ shelf.name }} </b
><br />
{{ shelf.name }}
</b>
<br />
{{ shelf.journals.length }} journals
</template>
<ObsidianIconButton icon="library" :tooltip="'Organize ' + shelf.name" @click="$emit('organize', shelf.name)" />
Expand Down
24 changes: 5 additions & 19 deletions src/settings/JournalSettingsWithoutShelves.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import JournalSettingsList from "./JournalSettingsList.vue";
import ObsidianIconButton from "@/components/obsidian/ObsidianIconButton.vue";
import { VueModal } from "@/components/modals/vue-modal";
import CreateJournal from "@/components/modals/CreateJournal.modal.vue";
import RemoveJournal from "@/components/modals/RemoveJournal.modal.vue";
import { plugin$ } from "@/stores/obsidian.store";
import type { JournalSettings, NotesProcessing } from "@/types/settings.types";
import { journals$ } from "@/stores/settings.store";
import type { JournalSettings } from "@/types/settings.types";
import { journalsList$ } from "@/stores/settings.store";
const emit = defineEmits<(event: "edit", name: string) => void>();
defineEmits<(event: "edit", name: string) => void>();
function create(): void {
new VueModal("Add Journal", CreateJournal, {
Expand All @@ -18,27 +17,14 @@ function create(): void {
},
}).open();
}
function edit(name: string): void {
emit("edit", name);
}
function remove(name: string): void {
const journal = journals$.value[name];
if (!journal) return;
new VueModal(`Remove ${journal.name} journal`, RemoveJournal, {
onRemove(_noteProcessing: NotesProcessing) {
// TODO Process notes on remove
plugin$.value.removeJournal(name);
},
}).open();
}
</script>

<template>
<ObsidianSetting name="Journals" heading>
<ObsidianIconButton :icon="'plus'" cta tooltip="Create new journal" @click="create" />
<ObsidianIconButton icon="plus" cta tooltip="Create new journal" @click="create" />
</ObsidianSetting>

<JournalSettingsList @edit="edit" @remove="remove" />
<JournalSettingsList :journals="journalsList$" @edit="$emit('edit', $event)" />
</template>

<style scoped></style>
2 changes: 1 addition & 1 deletion src/types/plugin.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Journal } from "../journals/journal";
export interface JournalPlugin extends Plugin {
readonly index: JournalsIndex;
getJournal(name: string): Journal | undefined;
createJournal(name: string, write: JournalSettings["write"]): void;
createJournal(name: string, write: JournalSettings["write"]): JournalSettings;
renameJournal(name: string, newName: string): void;
removeJournal(name: string): void;

Expand Down

0 comments on commit c4d9ac9

Please sign in to comment.