feat(lessons): both records show the link in the web UI (milestone 440 step 7, #4635)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 57s
CI & Build / integration (push) Successful in 1m9s
CI & Build / Python tests (push) Successful in 1m53s
CI & Build / Build & push image (push) Successful in 41s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 57s
CI & Build / integration (push) Successful in 1m9s
CI & Build / Python tests (push) Successful in 1m53s
CI & Build / Build & push image (push) Successful in 41s
The lesson page gains an "Instance of" panel that holds one of three answers. Unjudged is the fall-through, so it is stated rather than left blank: - the rule(s) it was judged an instance of; - "No rule — <why>"; - "Not yet judged". Suggested links show what they rest on (distinct situations, and projects when more than one), with Confirm / Not an instance for a reader who can write. Rejected links stay listed with their reason. The rule slide-over lists the lessons that are instances of it, plus the suggestions waiting on a judgment. Each entry links through to the other record, and kind and state wear the existing .rule-chip. The write check moves to utils/permission.ts. The copy on the snippet page looked for "edit", which the server never sends, so shared editors saw a read-only page (#4640 "The snippet page hid its edit controls from shared editors"). Guards pin the client's unions and write levels to the service's, the model's and access.py's own values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,14 @@ const expiresWhen = ref("");
|
||||
|
||||
const relations = computed(() => store.currentRule?.relations ?? []);
|
||||
|
||||
// The lessons that point at this rule (milestone 440): confirmed instances
|
||||
// first, then suggestions waiting on a judgment. A rejected lesson does not
|
||||
// point at the rule, so it is not listed here — it stays readable on the
|
||||
// lesson, where the judgment was made.
|
||||
const lessons = computed(() =>
|
||||
(store.currentRule?.lessons ?? []).filter((l) => l.state !== "rejected"),
|
||||
);
|
||||
|
||||
// The label a reader needs to judge an edge, not the stored token.
|
||||
const RELATION_LABEL: Record<string, { outgoing: string; incoming: string }> = {
|
||||
co_surfaces: { outgoing: "arrives with", incoming: "arrives with" },
|
||||
@@ -279,6 +287,21 @@ watch(() => props.ruleId, load);
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section v-if="lessons.length" class="relations">
|
||||
<h3>Lessons that are instances of it</h3>
|
||||
<ul>
|
||||
<li v-for="l in lessons" :key="l.id" class="relation">
|
||||
<router-link :to="`/lessons/${l.id}`" class="relation-target">{{ l.title }}</router-link>
|
||||
<span v-if="l.state === 'suggested'" class="rule-chip">suggested</span>
|
||||
<span v-if="l.note" class="relation-note">{{ l.note }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="field-note">
|
||||
The situations that keep proving this rule. A confirmed lesson brings the rule along
|
||||
when it surfaces; a suggested one waits for a judgment on the lesson's page.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<label>
|
||||
Why
|
||||
<textarea v-model="why" rows="4" placeholder="Rationale — the reason this rule exists." />
|
||||
@@ -394,3 +417,8 @@ legend { padding: 0 0.35rem; font-size: 0.8rem; color: var(--fs-text-tertiary);
|
||||
.trash, .close { background: none; border: none; cursor: pointer; opacity: 0.6; font-size: 1.25em; }
|
||||
.trash:hover, .close:hover { opacity: 1; }
|
||||
</style>
|
||||
|
||||
<!-- `.rule-chip` for the "suggested" marker on a lesson — the chip the rule
|
||||
panes already use, loaded here because the slide-over can open with no
|
||||
pane that loads it (a link straight to ?rule=N). -->
|
||||
<style src="@/assets/rules-shared.css" />
|
||||
|
||||
Reference in New Issue
Block a user