diff --git a/addons/api/mirage/config.js b/addons/api/mirage/config.js
index 25be61159..c3bdda3f7 100644
--- a/addons/api/mirage/config.js
+++ b/addons/api/mirage/config.js
@@ -15,7 +15,7 @@ import { pickRandomStatusString } from './factories/session';
import initializeMockIPC from './scenarios/ipc';
import makeBooleanFilter from './helpers/bexpr-filter';
import { faker } from '@faker-js/faker';
-import { asciiCasts } from './data/asciicasts';
+import { asciicasts } from './data/asciicasts';
const isTesting = environmentConfig.environment === 'test';
@@ -725,7 +725,7 @@ function routes() {
const method = idMethod.split(':')[1];
if (method === 'download') {
- return faker.helpers.arrayElement(asciiCasts);
+ return faker.helpers.arrayElement(asciicasts);
} else {
return sessionRecordings.find(id);
}
diff --git a/addons/api/mirage/data/asciicasts.js b/addons/api/mirage/data/asciicasts.js
index 99ce39286..478913dc7 100644
--- a/addons/api/mirage/data/asciicasts.js
+++ b/addons/api/mirage/data/asciicasts.js
@@ -1,4 +1,4 @@
-export const asciiCast1 = `{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
+export const asciicast1 = `{"version": 2, "width": 124, "height": 36, "timestamp": 1670352594, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
[2.138652, "o", "\\u001b[1m\\u001b[7m%\\u001b[27m\\u001b[1m\\u001b[0m \\r \\r\\u001b]2;ember-asciinema-player\\u0007\\u001b]1;..iinema-player\\u0007"]
[2.220877, "o", "\\r\\u001b[0m\\u001b[27m\\u001b[24m\\u001b[J\\u001b[33member-asciinema-player\\u001b[00m \\u001b[32mgit\\u001b[00m:\\u001b[36m(main*)\\u001b[00m $ \\u001b[K"]
[2.221019, "o", "\\u001b[?1h\\u001b="]
@@ -68,7 +68,7 @@ export const asciiCast1 = `{"version": 2, "width": 124, "height": 36, "timestamp
[16.52863, "o", "\\u001b[?2004h"]
[19.078794, "o", "\\u001b[?2004l\\r\\r\\n"]`;
-export const asciiCast2 = `{"version": 2, "width": 112, "height": 30, "timestamp": 1672793720, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
+export const asciicast2 = `{"version": 2, "width": 112, "height": 30, "timestamp": 1672793720, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[0.036928, "o", "\\u001b[?2004h\\u001b[1;32m[\\u001b]0;johan@nixos: ~/src/hashicorp/boundary-enterprise\\u0007johan@nixos:~/src/hashicorp/boundary-enterprise]$\\u001b[0m "]
[2.827983, "o", "b"]
[2.9386, "o", "o"]
@@ -148,4 +148,4 @@ export const asciiCast2 = `{"version": 2, "width": 112, "height": 30, "timestamp
[21.303896, "o", "\\r\\n"]
[21.307902, "o", "\\u001b[?2004l\\rexit\\r\\n"]`;
-export const asciiCasts = [asciiCast1, asciiCast2];
+export const asciicasts = [asciicast1, asciicast2];
diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index 4ada52c62..6065a103e 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -257,6 +257,7 @@ session-recording:
description: The contents of this channel cannot be replayed.
player:
back-navigation: Back to channels
+ loading: Loading recording…
session:
title: Session Playback
form:
diff --git a/ui/admin/app/components/session-recording/player/index.hbs b/ui/admin/app/components/session-recording/player/index.hbs
index d8850e80f..80a9f85f8 100644
--- a/ui/admin/app/components/session-recording/player/index.hbs
+++ b/ui/admin/app/components/session-recording/player/index.hbs
@@ -8,7 +8,11 @@
@model={{@model}}
/>
-
-
-
+ {{#if (has-block)}}
+ {{yield}}
+ {{else}}
+
+
+
+ {{/if}}
\ No newline at end of file
diff --git a/ui/admin/app/routes/application.js b/ui/admin/app/routes/application.js
index cbdbc109e..137527b1a 100644
--- a/ui/admin/app/routes/application.js
+++ b/ui/admin/app/routes/application.js
@@ -7,7 +7,6 @@ import Route from '@ember/routing/route';
import { getOwner } from '@ember/application';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
-import { loading } from 'ember-loading';
import { A } from '@ember/array';
/**
@@ -75,17 +74,6 @@ export default class ApplicationRoute extends Route {
this.session.invalidate();
}
- /**
- * Hooks into ember-loading to kick off loading indicator in the
- * application template.
- * @return {boolean} always returns true
- */
- @action
- @loading
- loading() {
- return true;
- }
-
/**
* Invalidates the session if a 401 error occurs and returns false to
* prevent further error handling.
diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js
index 5736d68c1..60dd486cb 100644
--- a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js
+++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.js
@@ -4,33 +4,26 @@ import { inject as service } from '@ember/service';
export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelRoute extends Route {
// =services
@service store;
- @service can;
// =methods
/**
*
- * @param {*} channel_id
- * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object, asciicast: Object}
+ * @param {string} channel_id
+ * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object}
*/
- async model({ channel_id }) {
- let asciicast;
- const { sessionRecording, storageBucket } = await this.modelFor(
+ model({ channel_id }) {
+ const { sessionRecording, storageBucket } = this.modelFor(
'scopes.scope.session-recordings.session-recording.channels-by-connection'
);
- const channelRecording = await this.store.peekRecord(
+ const channelRecording = this.store.peekRecord(
'channel-recording',
channel_id
);
- if (this.can.can('getAsciicast channel-recording', channelRecording)) {
- asciicast = await channelRecording.getAsciicast();
- }
-
return {
channelRecording,
sessionRecording,
storageBucket,
- asciicast,
};
}
}
diff --git a/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js
new file mode 100644
index 000000000..18d552c72
--- /dev/null
+++ b/ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js
@@ -0,0 +1,29 @@
+import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
+
+export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionChannelIndexRoute extends Route {
+ // =services
+ @service can;
+
+ // =methods
+ /**
+ * @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object, asciicast: Object}
+ */
+ async model() {
+ let asciicast;
+ const { sessionRecording, storageBucket, channelRecording } = this.modelFor(
+ 'scopes.scope.session-recordings.session-recording.channels-by-connection.channel'
+ );
+
+ if (this.can.can('getAsciicast channel-recording', channelRecording)) {
+ asciicast = await channelRecording.getAsciicast();
+ }
+
+ return {
+ channelRecording,
+ sessionRecording,
+ storageBucket,
+ asciicast,
+ };
+ }
+}
diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss
index 63db717cf..24162d53c 100644
--- a/ui/admin/app/styles/app.scss
+++ b/ui/admin/app/styles/app.scss
@@ -800,6 +800,15 @@
}
}
+ &-loading {
+ color: var(--token-color-palette-neutral-400);
+ display: flex;
+ gap: 1rem;
+ justify-content: center;
+ align-items: center;
+ height: 75vh;
+ }
+
&-theme {
.asciinema-theme-asciinema {
background-color: var(--player-background-color);
diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs
index 4c014e10e..f6b5ce31f 100644
--- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs
+++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel.hbs
@@ -25,60 +25,7 @@
- {{#if @model.asciicast}}
-
- {{else}}
-
- {{#if
- (can 'getAsciicast channel-recording' @model.channelRecording)
- }}
- {{! Was not able to download asciicast }}
-
-
- {{else}}
- {{#if @model.channelRecording.isAsciicast}}
- {{! Not authorized to download asciicast }}
-
-
- {{else}}
- {{! Playback not supported }}
-
-
- {{/if}}
- {{/if}}
-
- {{/if}}
+ {{outlet}}
diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs
new file mode 100644
index 000000000..3ac73d930
--- /dev/null
+++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs
@@ -0,0 +1,48 @@
+{{#if @model.asciicast}}
+
+{{else}}
+
+ {{#if (can 'getAsciicast channel-recording' @model.channelRecording)}}
+ {{! Was not able to download asciicast }}
+
+
+ {{else}}
+ {{#if @model.channelRecording.isAsciicast}}
+ {{! Not authorized to download asciicast }}
+
+
+ {{else}}
+ {{! Playback not supported }}
+
+
+ {{/if}}
+ {{/if}}
+
+{{/if}}
\ No newline at end of file
diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs
new file mode 100644
index 000000000..2918ed16a
--- /dev/null
+++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs
@@ -0,0 +1,9 @@
+
+
+
+ {{t 'resources.session-recording.channel.player.loading'}}
+
+
\ No newline at end of file
diff --git a/ui/admin/tests/integration/components/session-recording/player-test.js b/ui/admin/tests/integration/components/session-recording/player-test.js
index d299706a7..0a8415298 100644
--- a/ui/admin/tests/integration/components/session-recording/player-test.js
+++ b/ui/admin/tests/integration/components/session-recording/player-test.js
@@ -28,7 +28,7 @@ module('Integration | Component | session-recording/player', function (hooks) {
[3.63678, "o", "t"]`;
await render(hbs`
-
+
`);
assert.dom('.session-recording-player-header').hasText('Back to channels');
diff --git a/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js
new file mode 100644
index 000000000..432ccb9e2
--- /dev/null
+++ b/ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js
@@ -0,0 +1,16 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'admin/tests/helpers';
+
+module(
+ 'Unit | Route | scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index',
+ function (hooks) {
+ setupTest(hooks);
+
+ test('it exists', function (assert) {
+ let route = this.owner.lookup(
+ 'route:scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index'
+ );
+ assert.ok(route);
+ });
+ }
+);