convertTemplateInsightsApps builds the list of builtin apps and template apps from the provided database rows, builtin apps are implicitly a part of all templates.
(usage database.GetTemplateInsightsRow, appUsage []database.GetTemplateAppInsightsRow)
| 568 | // from the provided database rows, builtin apps are implicitly a part of all |
| 569 | // templates. |
| 570 | func convertTemplateInsightsApps(usage database.GetTemplateInsightsRow, appUsage []database.GetTemplateAppInsightsRow) []codersdk.TemplateAppUsage { |
| 571 | // Builtin apps. |
| 572 | apps := []codersdk.TemplateAppUsage{ |
| 573 | { |
| 574 | TemplateIDs: usage.VscodeTemplateIds, |
| 575 | Type: codersdk.TemplateAppsTypeBuiltin, |
| 576 | DisplayName: codersdk.TemplateBuiltinAppDisplayNameVSCode, |
| 577 | Slug: "vscode", |
| 578 | Icon: "/icon/code.svg", |
| 579 | Seconds: usage.UsageVscodeSeconds, |
| 580 | }, |
| 581 | { |
| 582 | TemplateIDs: usage.JetbrainsTemplateIds, |
| 583 | Type: codersdk.TemplateAppsTypeBuiltin, |
| 584 | DisplayName: codersdk.TemplateBuiltinAppDisplayNameJetBrains, |
| 585 | Slug: "jetbrains", |
| 586 | Icon: "/icon/intellij.svg", |
| 587 | Seconds: usage.UsageJetbrainsSeconds, |
| 588 | }, |
| 589 | // TODO(mafredri): We could take Web Terminal usage from appUsage since |
| 590 | // that should be more accurate. The difference is that this reflects |
| 591 | // the rpty session as seen by the agent (can live past the connection), |
| 592 | // whereas appUsage reflects the lifetime of the client connection. The |
| 593 | // condition finding the corresponding app entry in appUsage is: |
| 594 | // !app.IsApp && app.AccessMethod == "terminal" && app.SlugOrPort == "" |
| 595 | { |
| 596 | TemplateIDs: usage.ReconnectingPtyTemplateIds, |
| 597 | Type: codersdk.TemplateAppsTypeBuiltin, |
| 598 | DisplayName: codersdk.TemplateBuiltinAppDisplayNameWebTerminal, |
| 599 | Slug: "reconnecting-pty", |
| 600 | Icon: "/icon/terminal.svg", |
| 601 | Seconds: usage.UsageReconnectingPtySeconds, |
| 602 | }, |
| 603 | { |
| 604 | TemplateIDs: usage.SshTemplateIds, |
| 605 | Type: codersdk.TemplateAppsTypeBuiltin, |
| 606 | DisplayName: codersdk.TemplateBuiltinAppDisplayNameSSH, |
| 607 | Slug: "ssh", |
| 608 | Icon: "/icon/terminal.svg", |
| 609 | Seconds: usage.UsageSshSeconds, |
| 610 | }, |
| 611 | { |
| 612 | TemplateIDs: usage.SftpTemplateIds, |
| 613 | Type: codersdk.TemplateAppsTypeBuiltin, |
| 614 | DisplayName: codersdk.TemplateBuiltinAppDisplayNameSFTP, |
| 615 | Slug: "sftp", |
| 616 | Icon: "/icon/terminal.svg", |
| 617 | Seconds: usage.UsageSftpSeconds, |
| 618 | }, |
| 619 | } |
| 620 | |
| 621 | // Use a stable sort, similarly to how we would sort in the query, note that |
| 622 | // we don't sort in the query because order varies depending on the table |
| 623 | // collation. |
| 624 | // |
| 625 | // ORDER BY slug, display_name, icon |
| 626 | slices.SortFunc(appUsage, func(a, b database.GetTemplateAppInsightsRow) int { |
| 627 | if a.Slug != b.Slug { |
no test coverage detected