From 3d9836a55b0b8d3219ef710742737a49f8566ab4 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Tue, 30 May 2023 11:34:07 -0500 Subject: [PATCH] Icu 9482 add no connection message for session recording with no connections (#294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 add controller for channels-by-connection/index * feat: 🎸 show message for new session that have no connections ✅ Closes: ICU-9482 * feat: 🎸 add message for failed session with no connections (#296) ✅ Closes: ICU-9489 * refactor: 💡 remove '-' from 'in progress' usage --- addons/core/translations/resources/en-us.yaml | 6 + .../channels-by-connection/index.js | 31 +++ .../channels-by-connection/index.hbs | 250 ++++++++++-------- .../session-recording/status-test.js | 2 +- .../channels-by-connection/index-test.js | 104 ++++++++ 5 files changed, 282 insertions(+), 111 deletions(-) create mode 100644 ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js create mode 100644 ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index d843a0f32..3833ad15a 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -234,6 +234,12 @@ session-recording: title: Channels by connection messages: no-channels: There are no channels for this connection + started-no-connections: + title: Session Recording In Progress + description: The Session has started but no connections have been made. + unknown-no-connections: + title: Session Recording Failure + description: This Session cannot be played back because no connections were established, and the Session has failed. channel: title: Channel title_index: Channel {index} diff --git a/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js new file mode 100644 index 000000000..8a779769b --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index.js @@ -0,0 +1,31 @@ +import Controller from '@ember/controller'; +import { + STATE_SESSION_RECORDING_STARTED, + STATE_SESSION_RECORDING_UNKNOWN, +} from 'api/models/session-recording'; + +export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionIndexController extends Controller { + /** + * Returns true if the session recording has started + * but has not started any connections + * @type {boolean} + */ + get isSessionInprogressWithNoConnections() { + return ( + this.model?.sessionRecording?.connection_recordings?.length === 0 && + this.model?.sessionRecording?.state === STATE_SESSION_RECORDING_STARTED + ); + } + + /** + * Returns true if the session recording state is unknown + * and has no connections + * @type {boolean} + */ + get isSessionUnknownWithNoConnections() { + return ( + this.model?.sessionRecording?.connection_recordings?.length === 0 && + this.model?.sessionRecording?.state === STATE_SESSION_RECORDING_UNKNOWN + ); + } +} diff --git a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs index f71adf356..6ec4cfc0d 100644 --- a/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs +++ b/ui/admin/app/templates/scopes/scope/session-recordings/session-recording/channels-by-connection/index.hbs @@ -11,119 +11,149 @@
- {{#each - @model.sessionRecording.connection_recordings - as |connection| - }} -
-

- {{indexed-display-name - 'resources.session-recording.connection.title_index' - @model.sessionRecording.connection_recordings - connection + {{#if this.isSessionInprogressWithNoConnections}} + + {{! Session recording in progress with no connections }} + - - {{connection.id}} - -

- {{#if connection.channel_recordings}} - + - <:body as |B|> - - - - {{indexed-display-name - 'resources.session-recording.channel.title_index' - connection.channel_recordings - B.data - }} - - - - - {{! Bytes up }} - {{#if B.data.bytes_up}} - - {{t - 'resources.session-recording.up' - bytes=(format-bytes-size B.data.bytes_up) - }} - - {{/if}} - {{! Bytes down }} - {{#if B.data.bytes_down}} - - {{t - 'resources.session-recording.down' - bytes=(format-bytes-size B.data.bytes_down) - }} - - {{/if}} - {{! Duration }} - {{#if B.data.duration}} - - {{format-time-duration B.data.duration}} - - {{/if}} - - - - - {{B.data.id}} - - - - {{#if @model.sessionRecording.isAvailable}} - - {{/if}} - - - - - {{else}} -
- - - {{t - 'resources.session-recording.channels-by-connection.messages.no-channels' - }} - - + /> + + {{else if this.isSessionUnknownWithNoConnections}} + + {{! Session recording unknown with no connections }} + + + + {{else}} + {{#each + @model.sessionRecording.connection_recordings + as |connection| + }} +
+

+ {{indexed-display-name + 'resources.session-recording.connection.title_index' + @model.sessionRecording.connection_recordings + connection + }} +

+ + {{connection.id}} +
- {{/if}} - {{/each}} + {{#if connection.channel_recordings}} + + <:body as |B|> + + + + {{indexed-display-name + 'resources.session-recording.channel.title_index' + connection.channel_recordings + B.data + }} + + + + + {{! Bytes up }} + {{#if B.data.bytes_up}} + + {{t + 'resources.session-recording.up' + bytes=(format-bytes-size B.data.bytes_up) + }} + + {{/if}} + {{! Bytes down }} + {{#if B.data.bytes_down}} + + {{t + 'resources.session-recording.down' + bytes=(format-bytes-size B.data.bytes_down) + }} + + {{/if}} + {{! Duration }} + {{#if B.data.duration}} + + {{format-time-duration B.data.duration}} + + {{/if}} + + + + + {{B.data.id}} + + + + {{#if @model.sessionRecording.isAvailable}} + + {{/if}} + + + + + {{else}} +
+ + + {{t + 'resources.session-recording.channels-by-connection.messages.no-channels' + }} + + +
+ {{/if}} + {{/each}} + {{/if}}
diff --git a/ui/admin/tests/integration/components/session-recording/status-test.js b/ui/admin/tests/integration/components/session-recording/status-test.js index 234e816c9..01c77093a 100644 --- a/ui/admin/tests/integration/components/session-recording/status-test.js +++ b/ui/admin/tests/integration/components/session-recording/status-test.js @@ -30,7 +30,7 @@ module('Integration | Component | session-recording/status', function (hooks) { assert.dom(BADGE_TEXT_SELECTOR).hasText('Completed'); }); - test('it renders an in-progress status badge', async function (assert) { + test('it renders an in progress status badge', async function (assert) { assert.expect(2); this.status = STATE_SESSION_RECORDING_STARTED; diff --git a/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js new file mode 100644 index 000000000..b28e1e4e7 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/session-recordings/session-recording/channels-by-connection/index-test.js @@ -0,0 +1,104 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; +import { + STATE_SESSION_RECORDING_AVAILABLE, + STATE_SESSION_RECORDING_STARTED, + STATE_SESSION_RECORDING_UNKNOWN, +} from 'api/models/session-recording'; + +module( + 'Unit | Controller | scopes/scope/session-recordings/session-recording/channels-by-connection/index', + function (hooks) { + setupTest(hooks); + + test('isSessionInprogressWithNoConnections returns true if session has started with no connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_STARTED, + connection_recordings: [], + }); + controller.set('model', { sessionRecording }); + + assert.true(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionInprogressWithNoConnections returns false if session has started and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_STARTED, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionInprogressWithNoConnections returns false if session is complete and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_AVAILABLE, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionInprogressWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns true if session is unknown with no connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_UNKNOWN, + connection_recordings: [], + }); + controller.set('model', { sessionRecording }); + + assert.true(controller.isSessionUnknownWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns false if session is unknown and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_UNKNOWN, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionUnknownWithNoConnections); + }); + + test('isSessionUnknownWithNoConnections returns false if session is complete and has connections', function (assert) { + const store = this.owner.lookup('service:store'); + const controller = this.owner.lookup( + 'controller:scopes/scope/session-recordings/session-recording/channels-by-connection/index' + ); + + const sessionRecording = store.createRecord('session-recording', { + state: STATE_SESSION_RECORDING_AVAILABLE, + connection_recordings: [store.createRecord('connection-recording')], + }); + controller.set('model', { sessionRecording }); + + assert.false(controller.isSessionUnknownWithNoConnections); + }); + } +);