Icu 9482 add no connection message for session recording with no connections (#294)
* 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
This commit is contained in:
1 parent
0aef13446b
commit
3d9836a55b
5 files changed
+282
-111
No files matched your search
@@ -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}
|
||||
|
||||
+31
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
+140
-110
@@ -11,119 +11,149 @@
|
||||
<div class='channels-by-connection'>
|
||||
<Layout::Sidebar as |sb|>
|
||||
<sb.Body>
|
||||
{{#each
|
||||
@model.sessionRecording.connection_recordings
|
||||
as |connection|
|
||||
}}
|
||||
<div class='channels-by-connection-connection-header'>
|
||||
<p class='hds-typography-display-300 hds-font-weight-semibold'>
|
||||
{{indexed-display-name
|
||||
'resources.session-recording.connection.title_index'
|
||||
@model.sessionRecording.connection_recordings
|
||||
connection
|
||||
{{#if this.isSessionInprogressWithNoConnections}}
|
||||
<Hds::ApplicationState as |A|>
|
||||
{{! Session recording in progress with no connections }}
|
||||
<A.Header
|
||||
@title={{t
|
||||
'resources.session-recording.channels-by-connection.messages.started-no-connections.title'
|
||||
}}
|
||||
</p>
|
||||
<Copyable
|
||||
@text={{connection.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{connection.id}}</code>
|
||||
</Copyable>
|
||||
</div>
|
||||
{{#if connection.channel_recordings}}
|
||||
<Hds::Table
|
||||
@model={{connection.channel_recordings}}
|
||||
@density='tall'
|
||||
@columns={{array
|
||||
(hash
|
||||
label=(t
|
||||
'resources.session-recording.connection.form.channel.label'
|
||||
)
|
||||
)
|
||||
(hash
|
||||
label=(t
|
||||
'resources.session-recording.connection.form.summary.label'
|
||||
)
|
||||
)
|
||||
(hash label=(t 'form.id.label'))
|
||||
(hash label='' align='right')
|
||||
/>
|
||||
<A.Body
|
||||
@text={{t
|
||||
'resources.session-recording.channels-by-connection.messages.started-no-connections.description'
|
||||
}}
|
||||
>
|
||||
<:body as |B|>
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<span>
|
||||
{{indexed-display-name
|
||||
'resources.session-recording.channel.title_index'
|
||||
connection.channel_recordings
|
||||
B.data
|
||||
}}
|
||||
</span>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<MetadataList as |list|>
|
||||
{{! Bytes up }}
|
||||
{{#if B.data.bytes_up}}
|
||||
<list.Item @icon='arrow-up' @color='success'>
|
||||
{{t
|
||||
'resources.session-recording.up'
|
||||
bytes=(format-bytes-size B.data.bytes_up)
|
||||
}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Bytes down }}
|
||||
{{#if B.data.bytes_down}}
|
||||
<list.Item @icon='arrow-down' @color='action'>
|
||||
{{t
|
||||
'resources.session-recording.down'
|
||||
bytes=(format-bytes-size B.data.bytes_down)
|
||||
}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Duration }}
|
||||
{{#if B.data.duration}}
|
||||
<list.Item @icon='clock' @color='faint'>
|
||||
{{format-time-duration B.data.duration}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
</MetadataList>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
</B.Td>
|
||||
<B.Td align='right'>
|
||||
{{#if @model.sessionRecording.isAvailable}}
|
||||
<Hds::Button
|
||||
@icon='play'
|
||||
@color='secondary'
|
||||
@text={{t 'actions.play'}}
|
||||
@route='scopes.scope.session-recordings.session-recording.channels-by-connection.channel'
|
||||
@model={{B.data.id}}
|
||||
/>
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
</Hds::Table>
|
||||
{{else}}
|
||||
<div class='no-channels-message'>
|
||||
<Hds::Alert @type='compact' as |A|>
|
||||
<A.Description>
|
||||
{{t
|
||||
'resources.session-recording.channels-by-connection.messages.no-channels'
|
||||
}}
|
||||
</A.Description>
|
||||
</Hds::Alert>
|
||||
/>
|
||||
</Hds::ApplicationState>
|
||||
{{else if this.isSessionUnknownWithNoConnections}}
|
||||
<Hds::ApplicationState as |A|>
|
||||
{{! Session recording unknown with no connections }}
|
||||
<A.Header
|
||||
@title={{t
|
||||
'resources.session-recording.channels-by-connection.messages.unknown-no-connections.title'
|
||||
}}
|
||||
/>
|
||||
<A.Body
|
||||
@text={{t
|
||||
'resources.session-recording.channels-by-connection.messages.unknown-no-connections.description'
|
||||
}}
|
||||
/>
|
||||
</Hds::ApplicationState>
|
||||
{{else}}
|
||||
{{#each
|
||||
@model.sessionRecording.connection_recordings
|
||||
as |connection|
|
||||
}}
|
||||
<div class='channels-by-connection-connection-header'>
|
||||
<p class='hds-typography-display-300 hds-font-weight-semibold'>
|
||||
{{indexed-display-name
|
||||
'resources.session-recording.connection.title_index'
|
||||
@model.sessionRecording.connection_recordings
|
||||
connection
|
||||
}}
|
||||
</p>
|
||||
<Copyable
|
||||
@text={{connection.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{connection.id}}</code>
|
||||
</Copyable>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{#if connection.channel_recordings}}
|
||||
<Hds::Table
|
||||
@model={{connection.channel_recordings}}
|
||||
@density='tall'
|
||||
@columns={{array
|
||||
(hash
|
||||
label=(t
|
||||
'resources.session-recording.connection.form.channel.label'
|
||||
)
|
||||
)
|
||||
(hash
|
||||
label=(t
|
||||
'resources.session-recording.connection.form.summary.label'
|
||||
)
|
||||
)
|
||||
(hash label=(t 'form.id.label'))
|
||||
(hash label='' align='right')
|
||||
}}
|
||||
>
|
||||
<:body as |B|>
|
||||
<B.Tr>
|
||||
<B.Td>
|
||||
<span>
|
||||
{{indexed-display-name
|
||||
'resources.session-recording.channel.title_index'
|
||||
connection.channel_recordings
|
||||
B.data
|
||||
}}
|
||||
</span>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<MetadataList as |list|>
|
||||
{{! Bytes up }}
|
||||
{{#if B.data.bytes_up}}
|
||||
<list.Item @icon='arrow-up' @color='success'>
|
||||
{{t
|
||||
'resources.session-recording.up'
|
||||
bytes=(format-bytes-size B.data.bytes_up)
|
||||
}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Bytes down }}
|
||||
{{#if B.data.bytes_down}}
|
||||
<list.Item @icon='arrow-down' @color='action'>
|
||||
{{t
|
||||
'resources.session-recording.down'
|
||||
bytes=(format-bytes-size B.data.bytes_down)
|
||||
}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Duration }}
|
||||
{{#if B.data.duration}}
|
||||
<list.Item @icon='clock' @color='faint'>
|
||||
{{format-time-duration B.data.duration}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
</MetadataList>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Copyable
|
||||
@text={{B.data.id}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{B.data.id}}</code>
|
||||
</Copyable>
|
||||
</B.Td>
|
||||
<B.Td align='right'>
|
||||
{{#if @model.sessionRecording.isAvailable}}
|
||||
<Hds::Button
|
||||
@icon='play'
|
||||
@color='secondary'
|
||||
@text={{t 'actions.play'}}
|
||||
@route='scopes.scope.session-recordings.session-recording.channels-by-connection.channel'
|
||||
@model={{B.data.id}}
|
||||
/>
|
||||
{{/if}}
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
</Hds::Table>
|
||||
{{else}}
|
||||
<div class='no-channels-message'>
|
||||
<Hds::Alert @type='compact' as |A|>
|
||||
<A.Description>
|
||||
{{t
|
||||
'resources.session-recording.channels-by-connection.messages.no-channels'
|
||||
}}
|
||||
</A.Description>
|
||||
</Hds::Alert>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</sb.Body>
|
||||
<sb.Sidebar>
|
||||
<div class='layout-sidebar-sidebar-details'>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+104
@@ -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);
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in new issue
Block a user