From 204d2537d73f2d912b0702d9fa47974931dc482e Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Thu, 1 Jun 2023 10:15:38 -0400 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20Add=20loading=20subs?= =?UTF-8?q?tate=20for=20channels=20(#303)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 Add loading substate for channels * refactor: 💡 Use conditional block for session recording player * style: 💄 Use a unicode ellipsis instead of periods * refactor: 💡 rename asciiCast to asciicast (#307) --------- Co-authored-by: cameronperera --- addons/api/mirage/config.js | 4 +- addons/api/mirage/data/asciicasts.js | 6 +- addons/core/translations/resources/en-us.yaml | 1 + .../session-recording/player/index.hbs | 10 +++- ui/admin/app/routes/application.js | 12 ---- .../channels-by-connection/channel.js | 17 ++---- .../channels-by-connection/channel/index.js | 29 ++++++++++ ui/admin/app/styles/app.scss | 9 +++ .../channels-by-connection/channel.hbs | 55 +------------------ .../channels-by-connection/channel/index.hbs | 48 ++++++++++++++++ .../channel/loading.hbs | 9 +++ .../session-recording/player-test.js | 2 +- .../channel/index-test.js | 16 ++++++ 13 files changed, 131 insertions(+), 87 deletions(-) create mode 100644 ui/admin/app/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.js create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index.hbs create mode 100644 ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/loading.hbs create mode 100644 ui/admin/tests/unit/routes/scopes/scope/session-recordings/session-recording/channels-by-connection/channel/index-test.js 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); + }); + } +);