diff --git a/frontend/src/components/rules/ProjectRulesTab.vue b/frontend/src/components/rules/ProjectRulesTab.vue new file mode 100644 index 0000000..955b58c --- /dev/null +++ b/frontend/src/components/rules/ProjectRulesTab.vue @@ -0,0 +1,211 @@ + + + + + + Subscribed rulebooks + + + {{ rb.title }} + × + + + Subscribe + + Choose a rulebook… + + {{ rb.title }} + + + + + + + Applicable rules + + No rules yet — subscribe to a rulebook above, or create one at + Rulebooks. + + + {{ rbTitle }} + + {{ topicTitle }} + + + + {{ r.title }} + {{ r.statement }} + + + + Why: {{ ruleDetails[r.id].why }} + + + How to apply: {{ ruleDetails[r.id].how_to_apply }} + + + Edit in Rulebook → + + + + + + + + Truncated at 50 rules — there are more applicable rules. + + + + + + diff --git a/frontend/src/views/ProjectView.vue b/frontend/src/views/ProjectView.vue index 9b83782..f252429 100644 --- a/frontend/src/views/ProjectView.vue +++ b/frontend/src/views/ProjectView.vue @@ -5,6 +5,7 @@ import { apiGet, apiPatch, apiDelete, apiPost } from "@/api/client"; import { useToastStore } from "@/stores/toast"; import { relativeTime } from "@/composables/useRelativeTime"; import ShareDialog from "@/components/ShareDialog.vue"; +import ProjectRulesTab from "@/components/rules/ProjectRulesTab.vue"; import { LayoutGrid, Clock, @@ -67,7 +68,7 @@ const loading = ref(false); const saving = ref(false); const error = ref(null); -const activeTab = ref<"tasks" | "notes">("tasks"); +const activeTab = ref<"tasks" | "notes" | "rules">("tasks"); const tasks = ref([]); const notes = ref([]); @@ -436,6 +437,9 @@ async function confirmDelete() { Notes {{ project.summary.note_count }} + + Rules + @@ -616,6 +620,9 @@ async function confirmDelete() { No notes in this project. + + +
+ No rules yet — subscribe to a rulebook above, or create one at + Rulebooks. +
+ Truncated at 50 rules — there are more applicable rules. +
No notes in this project.