mirror of
https://github.com/ttusk/leif.git
synced 2026-07-22 08:32:51 +00:00
refactor(ui): share scannable metric layout
This commit is contained in:
parent
8b381c463c
commit
c3ff030c7d
9 changed files with 278 additions and 141 deletions
86
sample-vault/.obsidian/plugins/leif/main.js
vendored
86
sample-vault/.obsidian/plugins/leif/main.js
vendored
|
|
@ -445,6 +445,18 @@ var DomHelpers = class {
|
|||
row.append(labelEl, valueEl);
|
||||
return row;
|
||||
}
|
||||
/**
|
||||
* Creates a compact label/value metric for scannable list rows.
|
||||
*/
|
||||
static createMetric(label, value) {
|
||||
const metric = this.createElement("div", "leif-metric");
|
||||
const labelEl = this.createElement("span", "leif-metric-label");
|
||||
labelEl.textContent = label;
|
||||
const valueEl = this.createElement("span", "leif-metric-value");
|
||||
valueEl.textContent = value;
|
||||
metric.append(labelEl, valueEl);
|
||||
return metric;
|
||||
}
|
||||
/**
|
||||
* Creates a table with headers and rows.
|
||||
* @param headers - Column headers
|
||||
|
|
@ -2702,30 +2714,29 @@ var ContestsTab = class {
|
|||
})
|
||||
);
|
||||
}
|
||||
const header = DomHelpers.createElement("div", "leif-contest-card-header");
|
||||
const titleGroup = DomHelpers.createElement("div", "leif-contest-card-title-group");
|
||||
const title = DomHelpers.createElement("strong", "leif-contest-card-title");
|
||||
title.textContent = contest.name;
|
||||
const status = DomHelpers.createElement("span", isActive ? "leif-status-active" : "leif-status-inactive");
|
||||
status.textContent = isActive ? "Estudando agora" : "Guardado";
|
||||
titleGroup.append(title, status);
|
||||
header.append(titleGroup, actions);
|
||||
const notes = DomHelpers.createParagraph(contest.wall.notes?.trim() || "Sem notas ainda.");
|
||||
notes.classList.add("leif-contest-notes");
|
||||
const meta = DomHelpers.createElement("div", "leif-contest-meta");
|
||||
meta.append(this.renderMetaChip("ID", contest.id));
|
||||
meta.append(DomHelpers.createMetric("ID", contest.id));
|
||||
if (contest.examPlan?.examDate) {
|
||||
meta.append(this.renderMetaChip("Prova", contest.examPlan.examDate));
|
||||
meta.append(DomHelpers.createMetric("Prova", contest.examPlan.examDate));
|
||||
}
|
||||
if (contest.examPlan?.board) {
|
||||
meta.append(this.renderMetaChip("Banca", contest.examPlan.board));
|
||||
meta.append(DomHelpers.createMetric("Banca", contest.examPlan.board));
|
||||
}
|
||||
if (contest.examPlan?.weeklyStudyHours !== void 0) {
|
||||
meta.append(this.renderMetaChip("Carga", `${contest.examPlan.weeklyStudyHours} h/semana`));
|
||||
meta.append(DomHelpers.createMetric("Carga", `${contest.examPlan.weeklyStudyHours} h/semana`));
|
||||
}
|
||||
if (contest.examPlan?.weeklyQuestionGoal !== void 0) {
|
||||
meta.append(this.renderMetaChip("Meta", `${contest.examPlan.weeklyQuestionGoal} quest\xF5es/semana`));
|
||||
meta.append(DomHelpers.createMetric("Meta", `${contest.examPlan.weeklyQuestionGoal} quest\xF5es/semana`));
|
||||
}
|
||||
card.append(header, notes, meta);
|
||||
card.append(titleGroup, meta, actions, notes);
|
||||
return card;
|
||||
}
|
||||
renderEditableCard(contest, data) {
|
||||
|
|
@ -2832,15 +2843,6 @@ var ContestsTab = class {
|
|||
);
|
||||
return form;
|
||||
}
|
||||
renderMetaChip(label, value) {
|
||||
const chip = DomHelpers.createElement("span", "leif-next-activity-chip");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-next-activity-chip-label");
|
||||
labelEl.textContent = `${label}:`;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-next-activity-chip-value");
|
||||
valueEl.textContent = value;
|
||||
chip.append(labelEl, valueEl);
|
||||
return chip;
|
||||
}
|
||||
readOptionalNumber(value) {
|
||||
if (!value.trim()) {
|
||||
return void 0;
|
||||
|
|
@ -2946,8 +2948,8 @@ var CycleTab = class {
|
|||
);
|
||||
const meta = DomHelpers.createElement("div", "leif-cycle-card-meta");
|
||||
meta.append(
|
||||
this.renderCycleMetric("Tempo", `${subject.plannedStudyMinutes} min`),
|
||||
this.renderCycleMetric("Etapa", subject.currentStage ?? "\u2014")
|
||||
DomHelpers.createMetric("Tempo", `${subject.plannedStudyMinutes} min`),
|
||||
DomHelpers.createMetric("Etapa", subject.currentStage ?? "\u2014")
|
||||
);
|
||||
card.append(titleGroup, meta, actions);
|
||||
return card;
|
||||
|
|
@ -3083,15 +3085,6 @@ var CycleTab = class {
|
|||
chip.append(labelEl, valueEl);
|
||||
return chip;
|
||||
}
|
||||
renderCycleMetric(label, value) {
|
||||
const metric = DomHelpers.createElement("div", "leif-cycle-metric");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-cycle-metric-label");
|
||||
labelEl.textContent = label;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-cycle-metric-value");
|
||||
valueEl.textContent = value;
|
||||
metric.append(labelEl, valueEl);
|
||||
return metric;
|
||||
}
|
||||
async moveSubject(subjects, sourceIndex, targetIndex, activeContestId) {
|
||||
try {
|
||||
if (!activeContestId) {
|
||||
|
|
@ -3341,13 +3334,7 @@ var DashboardTab = class {
|
|||
return panel;
|
||||
}
|
||||
renderActivityMeta(label, value) {
|
||||
const item = DomHelpers.createElement("span", "leif-next-activity-chip");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-next-activity-chip-label");
|
||||
labelEl.textContent = `${label}:`;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-next-activity-chip-value");
|
||||
valueEl.textContent = value;
|
||||
item.append(labelEl, valueEl);
|
||||
return item;
|
||||
return DomHelpers.createMetric(label, value);
|
||||
}
|
||||
formatDaysUntilExam(examDate) {
|
||||
const now = /* @__PURE__ */ new Date();
|
||||
|
|
@ -5057,17 +5044,26 @@ var WallTab = class {
|
|||
} else {
|
||||
const subjectMap = new Map(data.subjects.map((s) => [s.id, s.name]));
|
||||
const itemMap = new Map(data.studyItems.map((item) => [item.id, item.title]));
|
||||
card.appendChild(
|
||||
DomHelpers.createTable(
|
||||
["Mat\xE9ria", "Peso", "Pontua\xE7\xE3o", "Itens alvo"],
|
||||
activeContest.wall.subjectSnapshots.map((snapshot) => [
|
||||
subjectMap.get(snapshot.subjectId) ?? snapshot.subjectId,
|
||||
snapshot.weight !== void 0 ? String(snapshot.weight) : "\u2014",
|
||||
snapshot.score !== void 0 ? String(snapshot.score) : "\u2014",
|
||||
const list = DomHelpers.createElement("div", "leif-wall-snapshot-list");
|
||||
activeContest.wall.subjectSnapshots.forEach((snapshot) => {
|
||||
const row = DomHelpers.createElement("section", "leif-wall-snapshot-card");
|
||||
const titleGroup = DomHelpers.createElement("div", "leif-wall-snapshot-title-group");
|
||||
const title = DomHelpers.createElement("strong", "leif-wall-snapshot-title");
|
||||
title.textContent = subjectMap.get(snapshot.subjectId) ?? snapshot.subjectId;
|
||||
titleGroup.appendChild(title);
|
||||
const metrics = DomHelpers.createElement("div", "leif-wall-snapshot-meta");
|
||||
metrics.append(
|
||||
DomHelpers.createMetric("Peso", snapshot.weight !== void 0 ? String(snapshot.weight) : "\u2014"),
|
||||
DomHelpers.createMetric("Pontua\xE7\xE3o", snapshot.score !== void 0 ? String(snapshot.score) : "\u2014"),
|
||||
DomHelpers.createMetric(
|
||||
"Itens alvo",
|
||||
snapshot.targetItems?.map((itemId) => itemMap.get(itemId) ?? itemId).join(", ") ?? "\u2014"
|
||||
])
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
row.append(titleGroup, metrics);
|
||||
list.appendChild(row);
|
||||
});
|
||||
card.appendChild(list);
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
|
|
|||
104
sample-vault/.obsidian/plugins/leif/styles.css
vendored
104
sample-vault/.obsidian/plugins/leif/styles.css
vendored
|
|
@ -268,6 +268,25 @@
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
.leif-metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2-1);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-metric-label {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.leif-metric-value {
|
||||
color: var(--text-normal);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.leif-toolbar {
|
||||
display: flex;
|
||||
gap: var(--size-4-3);
|
||||
|
|
@ -567,23 +586,10 @@
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-cycle-metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2-1);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-cycle-metric-label {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.leif-cycle-metric-value {
|
||||
color: var(--text-normal);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
.leif-cycle-card > .leif-inline-actions,
|
||||
.leif-contest-card > .leif-inline-actions {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.leif-cycle-edit-form {
|
||||
|
|
@ -599,9 +605,10 @@
|
|||
}
|
||||
|
||||
.leif-contest-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-4-3);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(240px, 1.2fr) minmax(260px, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: var(--size-4-4);
|
||||
padding: var(--size-4-3) 0;
|
||||
border-top: 1px solid var(--leif-border);
|
||||
}
|
||||
|
|
@ -632,10 +639,14 @@
|
|||
}
|
||||
|
||||
.leif-contest-meta {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
|
||||
gap: var(--size-4-3);
|
||||
flex-wrap: wrap;
|
||||
color: var(--text-muted);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-contest-notes {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.leif-contest-edit-form {
|
||||
|
|
@ -801,6 +812,37 @@
|
|||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-card {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(220px, 0.9fr) minmax(300px, 1.4fr);
|
||||
align-items: start;
|
||||
gap: var(--size-4-4);
|
||||
padding: var(--size-4-3) 0;
|
||||
border-top: 1px solid var(--leif-border);
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-card:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-title {
|
||||
font-size: var(--font-ui-medium);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: var(--size-4-3);
|
||||
}
|
||||
|
||||
/* Dashboard next activity */
|
||||
.leif-next-activity {
|
||||
display: flex;
|
||||
|
|
@ -827,6 +869,11 @@
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.leif-next-activity-meta .leif-metric {
|
||||
align-items: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.leif-next-activity-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
|
|
@ -1067,6 +1114,11 @@
|
|||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.leif-next-activity-meta .leif-metric {
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leif-next-activity-chip {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
|
@ -1079,13 +1131,17 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.leif-contest-card,
|
||||
.leif-cycle-card {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--size-4-3);
|
||||
}
|
||||
|
||||
.leif-contest-meta,
|
||||
.leif-cycle-card-meta,
|
||||
.leif-cycle-edit-form {
|
||||
.leif-cycle-edit-form,
|
||||
.leif-wall-snapshot-card,
|
||||
.leif-wall-snapshot-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -138,32 +138,31 @@ export class ContestsTab {
|
|||
);
|
||||
}
|
||||
|
||||
const header = DomHelpers.createElement("div", "leif-contest-card-header");
|
||||
const titleGroup = DomHelpers.createElement("div", "leif-contest-card-title-group");
|
||||
const title = DomHelpers.createElement("strong", "leif-contest-card-title");
|
||||
title.textContent = contest.name;
|
||||
const status = DomHelpers.createElement("span", isActive ? "leif-status-active" : "leif-status-inactive");
|
||||
status.textContent = isActive ? "Estudando agora" : "Guardado";
|
||||
titleGroup.append(title, status);
|
||||
header.append(titleGroup, actions);
|
||||
|
||||
const notes = DomHelpers.createParagraph(contest.wall.notes?.trim() || "Sem notas ainda.");
|
||||
notes.classList.add("leif-contest-notes");
|
||||
const meta = DomHelpers.createElement("div", "leif-contest-meta");
|
||||
meta.append(this.renderMetaChip("ID", contest.id));
|
||||
meta.append(DomHelpers.createMetric("ID", contest.id));
|
||||
if (contest.examPlan?.examDate) {
|
||||
meta.append(this.renderMetaChip("Prova", contest.examPlan.examDate));
|
||||
meta.append(DomHelpers.createMetric("Prova", contest.examPlan.examDate));
|
||||
}
|
||||
if (contest.examPlan?.board) {
|
||||
meta.append(this.renderMetaChip("Banca", contest.examPlan.board));
|
||||
meta.append(DomHelpers.createMetric("Banca", contest.examPlan.board));
|
||||
}
|
||||
if (contest.examPlan?.weeklyStudyHours !== undefined) {
|
||||
meta.append(this.renderMetaChip("Carga", `${contest.examPlan.weeklyStudyHours} h/semana`));
|
||||
meta.append(DomHelpers.createMetric("Carga", `${contest.examPlan.weeklyStudyHours} h/semana`));
|
||||
}
|
||||
if (contest.examPlan?.weeklyQuestionGoal !== undefined) {
|
||||
meta.append(this.renderMetaChip("Meta", `${contest.examPlan.weeklyQuestionGoal} questões/semana`));
|
||||
meta.append(DomHelpers.createMetric("Meta", `${contest.examPlan.weeklyQuestionGoal} questões/semana`));
|
||||
}
|
||||
|
||||
card.append(header, notes, meta);
|
||||
card.append(titleGroup, meta, actions, notes);
|
||||
return card;
|
||||
}
|
||||
|
||||
|
|
@ -285,16 +284,6 @@ export class ContestsTab {
|
|||
return form;
|
||||
}
|
||||
|
||||
private renderMetaChip(label: string, value: string): HTMLElement {
|
||||
const chip = DomHelpers.createElement("span", "leif-next-activity-chip");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-next-activity-chip-label");
|
||||
labelEl.textContent = `${label}:`;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-next-activity-chip-value");
|
||||
valueEl.textContent = value;
|
||||
chip.append(labelEl, valueEl);
|
||||
return chip;
|
||||
}
|
||||
|
||||
private readOptionalNumber(value: string): number | undefined {
|
||||
if (!value.trim()) {
|
||||
return undefined;
|
||||
|
|
|
|||
|
|
@ -139,8 +139,8 @@ export class CycleTab {
|
|||
|
||||
const meta = DomHelpers.createElement("div", "leif-cycle-card-meta");
|
||||
meta.append(
|
||||
this.renderCycleMetric("Tempo", `${subject.plannedStudyMinutes} min`),
|
||||
this.renderCycleMetric("Etapa", subject.currentStage ?? "—")
|
||||
DomHelpers.createMetric("Tempo", `${subject.plannedStudyMinutes} min`),
|
||||
DomHelpers.createMetric("Etapa", subject.currentStage ?? "—")
|
||||
);
|
||||
|
||||
card.append(titleGroup, meta, actions);
|
||||
|
|
@ -302,16 +302,6 @@ export class CycleTab {
|
|||
return chip;
|
||||
}
|
||||
|
||||
private renderCycleMetric(label: string, value: string): HTMLElement {
|
||||
const metric = DomHelpers.createElement("div", "leif-cycle-metric");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-cycle-metric-label");
|
||||
labelEl.textContent = label;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-cycle-metric-value");
|
||||
valueEl.textContent = value;
|
||||
metric.append(labelEl, valueEl);
|
||||
return metric;
|
||||
}
|
||||
|
||||
private async moveSubject(
|
||||
subjects: Subject[],
|
||||
sourceIndex: number,
|
||||
|
|
|
|||
|
|
@ -216,13 +216,7 @@ export class DashboardTab {
|
|||
}
|
||||
|
||||
private renderActivityMeta(label: string, value: string): HTMLElement {
|
||||
const item = DomHelpers.createElement("span", "leif-next-activity-chip");
|
||||
const labelEl = DomHelpers.createElement("span", "leif-next-activity-chip-label");
|
||||
labelEl.textContent = `${label}:`;
|
||||
const valueEl = DomHelpers.createElement("span", "leif-next-activity-chip-value");
|
||||
valueEl.textContent = value;
|
||||
item.append(labelEl, valueEl);
|
||||
return item;
|
||||
return DomHelpers.createMetric(label, value);
|
||||
}
|
||||
|
||||
private formatDaysUntilExam(examDate: string): string {
|
||||
|
|
|
|||
|
|
@ -159,17 +159,28 @@ export class WallTab {
|
|||
} else {
|
||||
const subjectMap = new Map(data.subjects.map((s) => [s.id, s.name]));
|
||||
const itemMap = new Map(data.studyItems.map((item) => [item.id, item.title]));
|
||||
card.appendChild(
|
||||
DomHelpers.createTable(
|
||||
["Matéria", "Peso", "Pontuação", "Itens alvo"],
|
||||
activeContest.wall.subjectSnapshots.map((snapshot) => [
|
||||
subjectMap.get(snapshot.subjectId) ?? snapshot.subjectId,
|
||||
snapshot.weight !== undefined ? String(snapshot.weight) : "—",
|
||||
snapshot.score !== undefined ? String(snapshot.score) : "—",
|
||||
const list = DomHelpers.createElement("div", "leif-wall-snapshot-list");
|
||||
activeContest.wall.subjectSnapshots.forEach((snapshot) => {
|
||||
const row = DomHelpers.createElement("section", "leif-wall-snapshot-card");
|
||||
const titleGroup = DomHelpers.createElement("div", "leif-wall-snapshot-title-group");
|
||||
const title = DomHelpers.createElement("strong", "leif-wall-snapshot-title");
|
||||
title.textContent = subjectMap.get(snapshot.subjectId) ?? snapshot.subjectId;
|
||||
titleGroup.appendChild(title);
|
||||
|
||||
const metrics = DomHelpers.createElement("div", "leif-wall-snapshot-meta");
|
||||
metrics.append(
|
||||
DomHelpers.createMetric("Peso", snapshot.weight !== undefined ? String(snapshot.weight) : "—"),
|
||||
DomHelpers.createMetric("Pontuação", snapshot.score !== undefined ? String(snapshot.score) : "—"),
|
||||
DomHelpers.createMetric(
|
||||
"Itens alvo",
|
||||
snapshot.targetItems?.map((itemId) => itemMap.get(itemId) ?? itemId).join(", ") ?? "—"
|
||||
])
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
|
||||
row.append(titleGroup, metrics);
|
||||
list.appendChild(row);
|
||||
});
|
||||
card.appendChild(list);
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,6 +223,19 @@ export class DomHelpers {
|
|||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a compact label/value metric for scannable list rows.
|
||||
*/
|
||||
static createMetric(label: string, value: string): HTMLElement {
|
||||
const metric = this.createElement("div", "leif-metric");
|
||||
const labelEl = this.createElement("span", "leif-metric-label");
|
||||
labelEl.textContent = label;
|
||||
const valueEl = this.createElement("span", "leif-metric-value");
|
||||
valueEl.textContent = value;
|
||||
metric.append(labelEl, valueEl);
|
||||
return metric;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table with headers and rows.
|
||||
* @param headers - Column headers
|
||||
|
|
|
|||
104
styles.css
104
styles.css
|
|
@ -268,6 +268,25 @@
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
.leif-metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2-1);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-metric-label {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.leif-metric-value {
|
||||
color: var(--text-normal);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.leif-toolbar {
|
||||
display: flex;
|
||||
gap: var(--size-4-3);
|
||||
|
|
@ -567,23 +586,10 @@
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-cycle-metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-2-1);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-cycle-metric-label {
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.leif-cycle-metric-value {
|
||||
color: var(--text-normal);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
.leif-cycle-card > .leif-inline-actions,
|
||||
.leif-contest-card > .leif-inline-actions {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.leif-cycle-edit-form {
|
||||
|
|
@ -599,9 +605,10 @@
|
|||
}
|
||||
|
||||
.leif-contest-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--size-4-3);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(240px, 1.2fr) minmax(260px, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: var(--size-4-4);
|
||||
padding: var(--size-4-3) 0;
|
||||
border-top: 1px solid var(--leif-border);
|
||||
}
|
||||
|
|
@ -632,10 +639,14 @@
|
|||
}
|
||||
|
||||
.leif-contest-meta {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
|
||||
gap: var(--size-4-3);
|
||||
flex-wrap: wrap;
|
||||
color: var(--text-muted);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.leif-contest-notes {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.leif-contest-edit-form {
|
||||
|
|
@ -801,6 +812,37 @@
|
|||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-card {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(220px, 0.9fr) minmax(300px, 1.4fr);
|
||||
align-items: start;
|
||||
gap: var(--size-4-4);
|
||||
padding: var(--size-4-3) 0;
|
||||
border-top: 1px solid var(--leif-border);
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-card:first-child {
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-title {
|
||||
font-size: var(--font-ui-medium);
|
||||
line-height: 1.3;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.leif-wall-snapshot-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: var(--size-4-3);
|
||||
}
|
||||
|
||||
/* Dashboard next activity */
|
||||
.leif-next-activity {
|
||||
display: flex;
|
||||
|
|
@ -827,6 +869,11 @@
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
.leif-next-activity-meta .leif-metric {
|
||||
align-items: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.leif-next-activity-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
|
|
@ -1067,6 +1114,11 @@
|
|||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.leif-next-activity-meta .leif-metric {
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.leif-next-activity-chip {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
|
@ -1079,13 +1131,17 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.leif-contest-card,
|
||||
.leif-cycle-card {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--size-4-3);
|
||||
}
|
||||
|
||||
.leif-contest-meta,
|
||||
.leif-cycle-card-meta,
|
||||
.leif-cycle-edit-form {
|
||||
.leif-cycle-edit-form,
|
||||
.leif-wall-snapshot-card,
|
||||
.leif-wall-snapshot-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ describe("LeifView", () => {
|
|||
expect(cycleCards.length).toBeGreaterThanOrEqual(2);
|
||||
expect(cycleCards[0]?.querySelector(".leif-cycle-card-order")?.textContent).toContain("1");
|
||||
expect(cycleCards[0]?.querySelector(".leif-cycle-card-title")?.textContent).toBeTruthy();
|
||||
expect(cycleCards[0]?.querySelectorAll(".leif-cycle-metric").length).toBe(2);
|
||||
expect(cycleCards[0]?.querySelectorAll(".leif-metric").length).toBe(2);
|
||||
expect(cycleCards[0]?.querySelector(".leif-key-value")).toBeNull();
|
||||
expect(cycleCards[0]?.textContent).toContain("No ciclo");
|
||||
expect(cycleCards[0]?.textContent).toContain("Tempo");
|
||||
|
|
@ -510,6 +510,35 @@ describe("LeifView", () => {
|
|||
it("organizes the wall into clear edital, prova and notes sections", async () => {
|
||||
const dataStore = new InMemoryPluginDataStore();
|
||||
await seedUiData(dataStore);
|
||||
const data = await dataStore.load();
|
||||
const activeContest = data.contests.find((contest) => contest.id === data.activeContestId);
|
||||
const subject = data.subjects[0];
|
||||
const item = data.studyItems[0];
|
||||
|
||||
if (!activeContest || !subject || !item) {
|
||||
throw new Error("Seed data was not created.");
|
||||
}
|
||||
|
||||
const updateContestWall = new UpdateContestWallUseCase(
|
||||
dataStore,
|
||||
new EntityRepositoryFactory(dataStore)
|
||||
);
|
||||
await updateContestWall.execute({
|
||||
contestId: activeContest.id,
|
||||
wall: {
|
||||
noticeLinks: activeContest.wall.noticeLinks,
|
||||
examLinks: activeContest.wall.examLinks,
|
||||
notes: activeContest.wall.notes,
|
||||
subjectSnapshots: [
|
||||
{
|
||||
subjectId: subject.id,
|
||||
weight: 2,
|
||||
score: 8,
|
||||
targetItems: [item.id]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
const { leaf } = await openLeifView(dataStore);
|
||||
const wallTabButton = leaf.containerEl.querySelector<HTMLButtonElement>("[data-tab='wall']");
|
||||
|
|
@ -531,6 +560,9 @@ describe("LeifView", () => {
|
|||
expect(leaf.containerEl.querySelector(".leif-wall-links")).toBeNull();
|
||||
expect(leaf.containerEl.querySelector(".leif-wall-card-wide")).toBeNull();
|
||||
expect(leaf.containerEl.querySelector("button.leif-wall-save")).not.toBeNull();
|
||||
expect(leaf.containerEl.querySelector(".leif-wall-snapshot-card")).not.toBeNull();
|
||||
expect(leaf.containerEl.querySelector(".leif-wall-snapshot-card .leif-metric")).not.toBeNull();
|
||||
expect(leaf.containerEl.querySelector(".leif-wall-snapshot-list table.leif-table")).toBeNull();
|
||||
expect(leaf.containerEl.textContent).toContain("Salvar mural");
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue