From 2e0e19572750d9a04928c359d97a980da0806b25 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Sun, 19 Jan 2025 18:36:01 -0500 Subject: [PATCH 1/7] WIP timeline updates --- .../src/app/api/event-horizon.models.ts | 15 +++++++- .../src/app/api/event-horizon.service.ts | 12 +++++- .../challenge-yaml-modal.component.html | 3 ++ .../challenge-yaml-modal.component.scss | 0 .../challenge-yaml-modal.component.ts | 20 ++++++++++ .../team-event-horizon.component.scss | 15 +++++--- .../team-event-horizon.component.ts | 15 +++----- .../event-horizon-rendering.service.ts | 37 +++++++++++++------ .../app/services/markdown-helpers.service.ts | 14 ++++--- 9 files changed, 94 insertions(+), 37 deletions(-) create mode 100644 projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.html create mode 100644 projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.scss create mode 100644 projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.ts diff --git a/projects/gameboard-ui/src/app/api/event-horizon.models.ts b/projects/gameboard-ui/src/app/api/event-horizon.models.ts index dd996aac..96633f3e 100644 --- a/projects/gameboard-ui/src/app/api/event-horizon.models.ts +++ b/projects/gameboard-ui/src/app/api/event-horizon.models.ts @@ -5,7 +5,8 @@ export type EventHorizonEventType = "challengeStarted" | "gamespaceOnOff" | "solveComplete" | "submissionRejected" | - "submissionScored" + "submissionScored" | + "ticketOpenClose" export interface EventHorizonGenericEvent { id: string; @@ -35,7 +36,17 @@ export interface EventHorizonSolveCompleteEvent extends EventHorizonGenericEvent }; } -export type EventHorizonEvent = EventHorizonGenericEvent | EventHorizonGamespaceOnOffEvent | EventHorizonSubmissionScoredEvent | EventHorizonSolveCompleteEvent; +export interface EventHorizonTicketOpenCloseEvent extends EventHorizonGenericEvent { + eventData: { + closedAt?: DateTime + } +} + +export type EventHorizonEvent = EventHorizonGenericEvent | + EventHorizonGamespaceOnOffEvent | + EventHorizonSubmissionScoredEvent | + EventHorizonSolveCompleteEvent | + EventHorizonTicketOpenCloseEvent; export interface EventHorizonChallenge { id: string; diff --git a/projects/gameboard-ui/src/app/api/event-horizon.service.ts b/projects/gameboard-ui/src/app/api/event-horizon.service.ts index 6c105938..9039b8a3 100644 --- a/projects/gameboard-ui/src/app/api/event-horizon.service.ts +++ b/projects/gameboard-ui/src/app/api/event-horizon.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { firstValueFrom, map, of } from 'rxjs'; -import { EventHorizonEventType, EventHorizonEvent, TeamEventHorizonViewModel, EventHorizonChallengeSpec, EventHorizonGamespaceOnOffEvent } from './event-horizon.models'; +import { EventHorizonEventType, EventHorizonEvent, TeamEventHorizonViewModel, EventHorizonChallengeSpec, EventHorizonGamespaceOnOffEvent, EventHorizonTicketOpenCloseEvent } from './event-horizon.models'; import { ApiUrlService } from '@/services/api-url.service'; import { ApiDateTimeService } from '@/services/api-date-time.service'; import { LogService } from '@/services/log.service'; @@ -44,6 +44,13 @@ export class EventHorizonService { const offAtStamp = this.apiDateTimeService.toDateTime(asGamespaceEvent.eventData?.offAt as any); asGamespaceEvent.eventData.offAt = offAtStamp || undefined; } + + // also true of tickety events + const asTicketEvent = event as EventHorizonTicketOpenCloseEvent; + if (asTicketEvent.eventData?.closedAt) { + const closedAtStamp = this.apiDateTimeService.toDateTime(asTicketEvent.eventData.closedAt as any); + asTicketEvent.eventData.closedAt = closedAtStamp || undefined; + } } return timeline; @@ -67,7 +74,8 @@ export class EventHorizonService { "gamespaceOnOff", "solveComplete", "submissionRejected", - "submissionScored" + "submissionScored", + "ticketOpenClose" ]; } diff --git a/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.html b/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.html new file mode 100644 index 00000000..6d695971 --- /dev/null +++ b/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.html @@ -0,0 +1,3 @@ + + + diff --git a/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.scss b/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.ts b/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.ts new file mode 100644 index 00000000..b5ca54c0 --- /dev/null +++ b/projects/gameboard-ui/src/app/core/components/challenge-yaml-modal/challenge-yaml-modal.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { CoreModule } from "../../core.module"; + +@Component({ + selector: 'app-challenge-yaml-modal', + standalone: true, + imports: [CommonModule, CoreModule], + templateUrl: './challenge-yaml-modal.component.html', + styleUrls: ['./challenge-yaml-modal.component.scss'] +}) +export class ChallengeYamlModalComponent implements OnInit { + challengeId?: string; + + ngOnInit(): void { + if (!this.challengeId) { + throw new Error("challengeId is required."); + } + } +} diff --git a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss index 6a764109..db5b1bc7 100644 --- a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss +++ b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss @@ -6,20 +6,22 @@ } .eh-event-type-challenge-started { - background-color: #e7eaf6; + background-color: #9cdaa9; } - .eh-event-type-gamespace { - background-color: #a2a8d3; + .eh-event-type-gamespace-on-off { + background-color: #ceecd4; + font-weight: bold; + color: #eee; } .eh-event-type-solve-complete { - background-color: #38598b; + background-color: #41ad57; } .eh-event-type-submission-scored { - background-color: #113f67; - color: #e7eaf6; + background-color: #318241; + color: #eee; } .vis-label { @@ -29,6 +31,7 @@ font-size: 1rem !important; font-weight: bold; margin: 0; + padding: 0 1rem; } h2 { diff --git a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts index d4d01f05..e85ab006 100644 --- a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts +++ b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts @@ -2,7 +2,6 @@ import { EventHorizonDataItem, EventHorizonEventType, TeamEventHorizonViewModel import { EventHorizonService } from '@/api/event-horizon.service'; import { EventHorizonRenderingService } from '@/services/event-horizon-rendering.service'; import { LogService } from '@/services/log.service'; -import { ModalConfirmService } from '@/services/modal-confirm.service'; import { ClipboardService } from '@/utility/services/clipboard.service'; import { ToastService } from '@/utility/services/toast.service'; import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; @@ -60,12 +59,9 @@ export class TeamEventHorizonComponent implements OnInit, AfterViewInit, OnDestr const teamChallengeInstance = this.timelineViewModel?.team.challenges.find(i => i.specId == c.id); return { id: c.id, - options: { - - }, title: c.name, content: ` -

${c.name}

+

${c.name}

${teamChallengeInstance ? `${teamChallengeInstance.id.substring(0, 6)} · ${teamChallengeInstance.score}/${c.maxPossibleScore} points` : "unlaunched"}

@@ -95,13 +91,14 @@ export class TeamEventHorizonComponent implements OnInit, AfterViewInit, OnDestr const timelineEvent = this.eventHorizonService.getEventId(eventId, this.timelineViewModel); const spec = this.eventHorizonService.getSpecForEventId(this.timelineViewModel, timelineEvent.id); - const bodyContent = this.eventHorizonRenderingService.toModalHtmlContent(timelineEvent, spec); + const bodyContent = this.eventHorizonRenderingService.toModalMarkdown(timelineEvent, spec); - if (!bodyContent) + if (!bodyContent) { return; + } await this.clipboardService.copy(bodyContent); - this.toastService.showMessage(`Copied this ** ${this.eventHorizonRenderingService.toFriendlyName(timelineEvent.type)}** event to your clipboard.`); + this.toastService.showMessage(`Copied this **${this.eventHorizonRenderingService.toFriendlyName(timelineEvent.type)}** event to your clipboard.`); } protected async handleEventTypeToggled(eventType: EventHorizonEventType) { @@ -133,7 +130,7 @@ export class TeamEventHorizonComponent implements OnInit, AfterViewInit, OnDestr visibleDataItems.push(this.eventHorizonRenderingService.toDataItem(event, spec)); } } - + console.log("visible adata items", visibleDataItems); this.timeline?.setItems(visibleDataItems); return visibleDataItems; } diff --git a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts index badf5497..80caa4bf 100644 --- a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts +++ b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts @@ -1,4 +1,4 @@ -import { EventHorizonDataItem, EventHorizonGenericEvent, EventHorizonEventType, EventHorizonSolveCompleteEvent, EventHorizonSubmissionScoredEvent, EventHorizonChallengeSpec, EventHorizonViewOptions, TeamEventHorizonViewModel, EventHorizonGamespaceOnOffEvent } from '@/api/event-horizon.models'; +import { EventHorizonDataItem, EventHorizonGenericEvent, EventHorizonEventType, EventHorizonSolveCompleteEvent, EventHorizonSubmissionScoredEvent, EventHorizonChallengeSpec, EventHorizonViewOptions, TeamEventHorizonViewModel, EventHorizonGamespaceOnOffEvent, EventHorizonTicketOpenCloseEvent } from '@/api/event-horizon.models'; import { Injectable } from '@angular/core'; import { DateTime } from 'luxon'; import { MarkdownHelpersService } from './markdown-helpers.service'; @@ -21,7 +21,7 @@ export class EventHorizonRenderingService { groupTemplate: (groupData: any, element: any) => this.toGroupTemplate(groupData), min: eventHorizonVm.team.session.start.toJSDate(), max: sessionEnd.toJSDate(), - selectable: true, + orientation: "top", stack: true, start: eventHorizonVm.team.session.start.toJSDate(), tooltip: { @@ -40,9 +40,10 @@ export class EventHorizonRenderingService { return this.toGamespaceOnOffDataItem(timelineEvent, challengeSpec); case "solveComplete": return this.toSolveCompleteDataItem(timelineEvent, challengeSpec); - case "submissionScored": { + case "submissionScored": return this.toSubmissionScoredDataItem(timelineEvent, challengeSpec); - } + case "ticketOpenClose": + return this.toTicketOpenCloseDataItem(timelineEvent, challengeSpec); } throw new Error("Timeline event type not templated."); } @@ -59,8 +60,10 @@ export class EventHorizonRenderingService { return "Submission Rejected (Session Expired)"; case "submissionScored": return "Submission"; + case "ticketOpenClose": + return "Active Ticket"; default: - throw new Error(`Couldn't find a friendly name for event type "${eventType}".`); + return eventType; } } @@ -71,7 +74,7 @@ export class EventHorizonRenderingService { return `
${groupData.content}
`; } - public toModalHtmlContent(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec, includeClipboardPrompt?: boolean): string { + public toModalMarkdown(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec, includeClipboardPrompt?: boolean): string { if (!timelineEvent) return ""; @@ -115,8 +118,7 @@ export class EventHorizonRenderingService { if (challengeSpec.maxAttempts) attemptSummary = `${attemptSummary}/${challengeSpec.maxAttempts}`; - return ` -**Attempt:** ${attemptSummary} + return `**Attempt:** ${attemptSummary} **Points after this attempt:** ${timelineEvent.eventData.score}/${challengeSpec.maxPossibleScore} @@ -143,13 +145,13 @@ export class EventHorizonRenderingService { content: eventName, className: `eh-event ${isClickable ? "eh-event-clickable" : ""} ${className}`, isClickable, - title: this.markdownHelpers.toHtml(this.toModalHtmlContent(timelineEvent, challengeSpec, true)), + title: this.markdownHelpers.toHtml(this.toModalMarkdown(timelineEvent, challengeSpec, true)), eventData: null }; } private toGamespaceOnOffDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { - const typedEvent = timelineEvent as unknown as EventHorizonGamespaceOnOffEvent; + const typedEvent = timelineEvent as EventHorizonGamespaceOnOffEvent; const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, "Gamespace On", "eh-event-type-gamespace-on-off", false); baseItem.end = typedEvent.eventData?.offAt ? typedEvent.eventData.offAt.toJSDate() : this.nowService.now(); @@ -160,7 +162,7 @@ export class EventHorizonRenderingService { } private toSolveCompleteDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { - const typedEvent = timelineEvent as unknown as EventHorizonSolveCompleteEvent; + const typedEvent = timelineEvent as EventHorizonSolveCompleteEvent; const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, "Completed", "eh-event-type-challenge-complete", true); baseItem.eventData = typedEvent; @@ -168,10 +170,21 @@ export class EventHorizonRenderingService { } private toSubmissionScoredDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { - const typedEvent = timelineEvent as unknown as EventHorizonSubmissionScoredEvent; + const typedEvent = timelineEvent as EventHorizonSubmissionScoredEvent; const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, "Submission", "eh-event-type-submission-scored", true); baseItem.eventData = typedEvent; return baseItem; } + + private toTicketOpenCloseDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { + const typedEvent = timelineEvent as EventHorizonTicketOpenCloseEvent; + const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, "Ticket Active", "eh-event-type-ticket-open-close", false); + + baseItem.end = typedEvent.eventData?.closedAt?.toJSDate() || this.nowService.now(); + baseItem.eventData = typedEvent; + baseItem.type = "background"; + + return baseItem; + } } diff --git a/projects/gameboard-ui/src/app/services/markdown-helpers.service.ts b/projects/gameboard-ui/src/app/services/markdown-helpers.service.ts index bc6ae548..2f32594d 100644 --- a/projects/gameboard-ui/src/app/services/markdown-helpers.service.ts +++ b/projects/gameboard-ui/src/app/services/markdown-helpers.service.ts @@ -1,9 +1,11 @@ -import { Injectable } from '@angular/core'; +import { inject, Injectable, SecurityContext } from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { MarkdownService } from 'ngx-markdown'; @Injectable({ providedIn: 'root' }) export class MarkdownHelpersService { - constructor(private markdownService: MarkdownService) { } + private domSanitizer = inject(DomSanitizer); + private mdService = inject(MarkdownService); arrayToBulletList(items: string[]): string { return items.map(i => `\n - ${i}`).join(''); @@ -19,15 +21,15 @@ export class MarkdownHelpersService { getMarkdownPlaceholderHelp(header?: string): string { const paragraphs: string[] = []; - if (header) + if (header) { paragraphs.push(header); - + } paragraphs.push("This is a markdown field. You can surround text with _underscores_ to make it italic or double **asterisks** to make it bold. You can also [link to content using this syntax](https://google.com)."); return paragraphs.join("\n\n").trim(); } - toHtml(markdownContent: string) { - return this.markdownService.parse(markdownContent); + toHtml(markdownContent: string): string { + return this.domSanitizer.sanitize(SecurityContext.HTML, this.domSanitizer.bypassSecurityTrustHtml(this.mdService.parse(markdownContent, { disableSanitizer: true }))) || ""; } } From 5da0b4d595b54675845a4af2e70148b0b92decf4 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 21 Jan 2025 13:18:03 -0500 Subject: [PATCH 2/7] Add ticket stuff to timeline --- .../src/app/api/event-horizon.models.ts | 3 ++- .../team-event-horizon.component.scss | 5 +++++ .../team-event-horizon.component.ts | 2 +- .../services/event-horizon-rendering.service.ts | 17 +++++++++++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/projects/gameboard-ui/src/app/api/event-horizon.models.ts b/projects/gameboard-ui/src/app/api/event-horizon.models.ts index 96633f3e..01beaa47 100644 --- a/projects/gameboard-ui/src/app/api/event-horizon.models.ts +++ b/projects/gameboard-ui/src/app/api/event-horizon.models.ts @@ -38,7 +38,8 @@ export interface EventHorizonSolveCompleteEvent extends EventHorizonGenericEvent export interface EventHorizonTicketOpenCloseEvent extends EventHorizonGenericEvent { eventData: { - closedAt?: DateTime + closedAt?: DateTime; + ticketKey: string; } } diff --git a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss index db5b1bc7..2a11a7de 100644 --- a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss +++ b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.scss @@ -24,6 +24,11 @@ color: #eee; } + .eh-event-type-ticket-open-close { + background-color: $warning; + color: #fff; + } + .vis-label { text-align: center !important; diff --git a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts index e85ab006..b1be7aba 100644 --- a/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts +++ b/projects/gameboard-ui/src/app/event-horizon/components/team-event-horizon/team-event-horizon.component.ts @@ -130,7 +130,7 @@ export class TeamEventHorizonComponent implements OnInit, AfterViewInit, OnDestr visibleDataItems.push(this.eventHorizonRenderingService.toDataItem(event, spec)); } } - console.log("visible adata items", visibleDataItems); + this.timeline?.setItems(visibleDataItems); return visibleDataItems; } diff --git a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts index 80caa4bf..de7cbf80 100644 --- a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts +++ b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts @@ -43,7 +43,7 @@ export class EventHorizonRenderingService { case "submissionScored": return this.toSubmissionScoredDataItem(timelineEvent, challengeSpec); case "ticketOpenClose": - return this.toTicketOpenCloseDataItem(timelineEvent, challengeSpec); + return this.toTicketOpenCloseDataItem(timelineEvent as EventHorizonTicketOpenCloseEvent, challengeSpec); } throw new Error("Timeline event type not templated."); } @@ -91,6 +91,8 @@ export class EventHorizonRenderingService { case "submissionScored": detail = this.toSubmissionScoredMarkdown(timelineEvent as EventHorizonSubmissionScoredEvent, challengeSpec); break; + case "ticketOpenClose": + detail = this.toTicketOpenCloseMarkdown(timelineEvent as EventHorizonTicketOpenCloseEvent, challengeSpec); } let retVal = header; @@ -137,6 +139,13 @@ export class EventHorizonRenderingService { `.trim(); } + private toTicketOpenCloseMarkdown(timelineEvent: EventHorizonTicketOpenCloseEvent, challengeSpec: EventHorizonChallengeSpec) { + let firstTicketText = `The team opened ticket **${timelineEvent.eventData.ticketKey}** here.`; + let closedInfo = timelineEvent.eventData.closedAt ? ` We fully closed it at ${timelineEvent.eventData.closedAt.toLocaleString(DateTime.DATETIME_MED)}.` : ""; + + return `${firstTicketText}${closedInfo}`; + } + private toGenericDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec, eventName: string, className: string, isClickable = false): EventHorizonDataItem { return { id: timelineEvent.id, @@ -177,13 +186,13 @@ export class EventHorizonRenderingService { return baseItem; } - private toTicketOpenCloseDataItem(timelineEvent: EventHorizonGenericEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { + private toTicketOpenCloseDataItem(timelineEvent: EventHorizonTicketOpenCloseEvent, challengeSpec: EventHorizonChallengeSpec): EventHorizonDataItem { const typedEvent = timelineEvent as EventHorizonTicketOpenCloseEvent; - const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, "Ticket Active", "eh-event-type-ticket-open-close", false); + const baseItem = this.toGenericDataItem(timelineEvent, challengeSpec, `Ticket ${timelineEvent.eventData.ticketKey}`, "eh-event-type-ticket-open-close", true); baseItem.end = typedEvent.eventData?.closedAt?.toJSDate() || this.nowService.now(); baseItem.eventData = typedEvent; - baseItem.type = "background"; + baseItem.type = "range"; return baseItem; } From 045d405bb7a28a11a3746427d5b62680e016ce87 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 21 Jan 2025 13:20:02 -0500 Subject: [PATCH 3/7] Update tooltip markdown for timestamp --- .../src/app/services/event-horizon-rendering.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts index de7cbf80..53569288 100644 --- a/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts +++ b/projects/gameboard-ui/src/app/services/event-horizon-rendering.service.ts @@ -92,7 +92,7 @@ export class EventHorizonRenderingService { detail = this.toSubmissionScoredMarkdown(timelineEvent as EventHorizonSubmissionScoredEvent, challengeSpec); break; case "ticketOpenClose": - detail = this.toTicketOpenCloseMarkdown(timelineEvent as EventHorizonTicketOpenCloseEvent, challengeSpec); + detail = this.toTicketOpenCloseMarkdown(timelineEvent as EventHorizonTicketOpenCloseEvent); } let retVal = header; @@ -139,7 +139,7 @@ export class EventHorizonRenderingService { `.trim(); } - private toTicketOpenCloseMarkdown(timelineEvent: EventHorizonTicketOpenCloseEvent, challengeSpec: EventHorizonChallengeSpec) { + private toTicketOpenCloseMarkdown(timelineEvent: EventHorizonTicketOpenCloseEvent) { let firstTicketText = `The team opened ticket **${timelineEvent.eventData.ticketKey}** here.`; let closedInfo = timelineEvent.eventData.closedAt ? ` We fully closed it at ${timelineEvent.eventData.closedAt.toLocaleString(DateTime.DATETIME_MED)}.` : ""; From 880ffeaf30befa736c2c0c0840ab132e9365176b Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 21 Jan 2025 13:37:56 -0500 Subject: [PATCH 4/7] Fix ticket label picker modal search --- .../ticket-label-picker-modal.component.html | 12 +++++++----- .../ticket-label-picker-modal.component.scss | 3 --- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.html b/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.html index 720d8cf5..d1e31649 100644 --- a/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.html +++ b/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.html @@ -1,14 +1,16 @@ -
    -
  • - -
  • + +
  • + +
  • +

diff --git a/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.scss b/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.scss index f859b357..e69de29b 100644 --- a/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.scss +++ b/projects/gameboard-ui/src/app/support/components/ticket-label-picker-modal/ticket-label-picker-modal.component.scss @@ -1,3 +0,0 @@ -li { - // flex-basis: 30%; -} From b3422a708260cb5eab79c78e26b363bc626487f3 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 21 Jan 2025 13:47:05 -0500 Subject: [PATCH 5/7] Ticket details styling --- .../app/support/ticket-details/ticket-details.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html index 0e39ce7e..0f20c4b5 100644 --- a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html +++ b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html @@ -206,7 +206,7 @@

- +
Status Changed to  Date: Tue, 21 Jan 2025 16:09:13 -0500 Subject: [PATCH 6/7] Minor styling to ticket details, fix certificate stuff --- .../src/app/api/certificates.service.ts | 1 + .../ticket-details.component.html | 34 ++++++++++-------- .../ticket-details.component.scss | 6 ++++ .../inplace-editor.component.html | 35 +++++++++++-------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/projects/gameboard-ui/src/app/api/certificates.service.ts b/projects/gameboard-ui/src/app/api/certificates.service.ts index e85ee642..07467e29 100644 --- a/projects/gameboard-ui/src/app/api/certificates.service.ts +++ b/projects/gameboard-ui/src/app/api/certificates.service.ts @@ -38,6 +38,7 @@ export class CertificatesService { } getCompetitiveCertificates(userId: string): Promise { + console.log("getting certs", userId); return firstValueFrom(this.http.get(this.apiUrl.build(`user/${userId}/certificates/competitive`))); } diff --git a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html index 0f20c4b5..851f14b8 100644 --- a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html +++ b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.html @@ -247,7 +247,7 @@

-
-
+
@@ -268,7 +268,7 @@

-
+
@@ -283,11 +283,11 @@

-
+
-

+

Support Code: @@ -296,21 +296,24 @@

-
-

Game Id: - {{changedTicket.player?.gameId | slice:0:16}}

+
+ {{ changedTicket.player?.gameId | slice:0:8 }} +
-
-
-

User Id: {{changedTicket.requesterId | - slice:0:16}}

+
+ {{changedTicket.requesterId | slice:0:8}}
-
-

+
+

{{ctx.ticket.creator?.name || 'None'}}

diff --git a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.scss b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.scss index bf3fe200..8ce60824 100644 --- a/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.scss +++ b/projects/gameboard-ui/src/app/support/ticket-details/ticket-details.component.scss @@ -132,3 +132,9 @@ textarea { .copy-id-button { color: $success; } + +.ticket-field-label { + font-size: 0.9rem; + font-weight: bold; + text-transform: uppercase; +} diff --git a/projects/gameboard-ui/src/app/utility/components/inplace-editor/inplace-editor.component.html b/projects/gameboard-ui/src/app/utility/components/inplace-editor/inplace-editor.component.html index ea74598f..ee29e28f 100644 --- a/projects/gameboard-ui/src/app/utility/components/inplace-editor/inplace-editor.component.html +++ b/projects/gameboard-ui/src/app/utility/components/inplace-editor/inplace-editor.component.html @@ -1,18 +1,25 @@ -
-
- -
- -
-
-
-
- {{option.name}} {{option.secondary}} - -
+
+
+ +
+
-
- {{currentText}}   +
+
+ {{option.name}} {{option.secondary}} + +
+
+
+ {{currentText}}   +
From 0a2be1da0ed2d6ffd04795b041491ad2e175e865 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 21 Jan 2025 16:18:19 -0500 Subject: [PATCH 7/7] Fix support pill --- .../src/app/components/nav/nav.component.html | 10 +++++++--- .../support/support-pill/support-pill.component.html | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/projects/gameboard-ui/src/app/components/nav/nav.component.html b/projects/gameboard-ui/src/app/components/nav/nav.component.html index fcd8ce12..a8135d98 100644 --- a/projects/gameboard-ui/src/app/components/nav/nav.component.html +++ b/projects/gameboard-ui/src/app/components/nav/nav.component.html @@ -6,13 +6,17 @@ {{t.display}} + Practice + - - Support + Profile diff --git a/projects/gameboard-ui/src/app/support/support-pill/support-pill.component.html b/projects/gameboard-ui/src/app/support/support-pill/support-pill.component.html index e3cafcbd..66c844a6 100644 --- a/projects/gameboard-ui/src/app/support/support-pill/support-pill.component.html +++ b/projects/gameboard-ui/src/app/support/support-pill/support-pill.component.html @@ -1 +1 @@ - +