refactor: 💡 Refactor session-recordings routes (#222)

* refactor: 💡 Refactor session-recordings routes
This commit is contained in:
Carlos Alcaide Corvo authored and GitHub committed 2023-04-27 09:35:52 -07:00
1 parent 451fcdbfeb
commit 0d9602f4ba
11 files changed
+240 -191

No files matched your search

@@ -10,6 +10,6 @@ export default class ScopesScopeSessionRecordingsSessionRecordingController exte
* Session recording breadcrumb
*/
get breadCrumb() {
return this.model.sessionRecording.displayName;
return this.model.displayName;
}
}
@@ -55,6 +55,4 @@ export default class ScopesScopeSessionRecordingsRoute extends Route {
};
}
}
// =actions
}
@@ -17,32 +17,15 @@ export default class ScopesScopeSessionRecordingsSessionRecordingRoute extends R
}
/**
* Load session recording, sorted connections and channels,
* and related storage bucket if present
* @return {{sessionRecording: SessionRecordingModel, sortedConnections: [ConnectionRecordingModel], storageBucket: ?StorageBucketModel}}
* Load session recording.
* @return {sessionRecording: SessionRecordingModel}
*/
async model({ session_recording_id }) {
let storageBucket = null;
const sessionRecording = await this.store.findRecord(
'session-recording',
session_recording_id
);
try {
if (sessionRecording.target?.storage_bucket_id) {
const { storage_bucket_id } = sessionRecording.target;
storageBucket = await this.store.findRecord(
'storage-bucket',
storage_bucket_id
);
}
} catch (e) {
// no op
}
return {
sessionRecording,
storageBucket,
};
return sessionRecording;
}
}
@@ -1,3 +1,46 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionRoute extends Route {}
export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConnectionRoute extends Route {
// =services
@service store;
@service session;
// =methods
/**
* If arriving here unauthenticated, redirect to index for further processing.
*/
beforeModel() {
if (!this.session.isAuthenticated) this.router.transitionTo('index');
}
/**
* Load session recording (already in store) and related storage bucket if present
* @return {{sessionRecording: SessionRecordingModel, storageBucket: ?StorageBucketModel}}
*/
async model() {
let storageBucket = null;
const sessionRecording = this.modelFor(
'scopes.scope.session-recordings.session-recording'
);
try {
if (sessionRecording.target?.storage_bucket_id) {
const { storage_bucket_id } = sessionRecording.target;
storageBucket = await this.store.findRecord(
'storage-bucket',
storage_bucket_id
);
}
} catch (e) {
// no op
}
return {
sessionRecording,
storageBucket,
};
}
}
@@ -7,10 +7,15 @@ export default class ScopesScopeSessionRecordingsSessionRecordingChannelsByConne
@service can;
// =methods
/**
*
* @param {*} channel_id
* @returns {channelRecording: Object, sessionRecording: Object, storageBucket: Object, asciicast: Object}
*/
async model({ channel_id }) {
let asciicast;
const { sessionRecording, storageBucket } = await this.modelFor(
'scopes.scope.session-recordings.session-recording'
'scopes.scope.session-recordings.session-recording.channels-by-connection'
);
const channelRecording = await this.store.peekRecord(
'channel-recording',
@@ -1,3 +1,23 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ScopesScopeSessionRecordingsSessionRecordingIndexRoute extends Route {}
export default class ScopesScopeSessionRecordingsSessionRecordingIndexRoute extends Route {
// =services
@service router;
// =methods
/**
* Redirects to the sessionRecording type specific screen,
* for now just SSH types are supported.
* @param {SessionRecordingModel} sessionRecording
*/
async afterModel(sessionRecording) {
if (sessionRecording.isSSH) {
this.router.transitionTo(
'scopes.scope.session-recordings.session-recording.channels-by-connection',
sessionRecording.id
);
}
}
}
@@ -69,7 +69,7 @@
@iconPosition='trailing'
@color='secondary'
@text={{t 'actions.view'}}
@route='scopes.scope.session-recordings.session-recording'
@route='scopes.scope.session-recordings.session-recording.channels-by-connection'
@model={{B.data.id}}
/>
{{/if}}
@@ -0,0 +1,160 @@
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
<BreadCrumbs />
</page.breadcrumbs>
<page.header>
<h2>{{t 'resources.session-recording.session.title'}}</h2>
</page.header>
<page.body>
<div class='channels-by-connection'>
<Layout::Sidebar as |sb|>
<sb.Body>
{{#each
@model.sessionRecording.sortedConnectionsByStartTimeDesc
as |connection|
}}
<div class='channels-by-connection-connection-header'>
<p class='hds-typography-display-300 hds-font-weight-semibold'>
{{t 'resources.session-recording.connection.title'}}
{{connection.id}}
</p>
</div>
<Hds::Table
@model={{connection.sortedChannelsByStartTimeDesc}}
@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='' align='right')
}}
>
<:body as |B|>
<B.Tr>
<B.Td>
<span>{{B.data.id}}</span>
</B.Td>
<B.Td>
<MetadataList as |list|>
{{! Bytes up }}
<list.Item @icon='arrow-up' @color='success'>
{{format-bytes-size B.data.bytes_up}}
</list.Item>
{{! Bytes down }}
<list.Item @icon='arrow-down' @color='action'>
{{format-bytes-size B.data.bytes_down}}
</list.Item>
{{! Duration }}
<list.Item @icon='clock' @color='faint'>
{{format-time-duration B.data.duration}}
</list.Item>
</MetadataList>
</B.Td>
<B.Td align='right'>
<Hds::Button
@icon='play'
@color='secondary'
@text='Play'
@route='scopes.scope.session-recordings.session-recording.channels-by-connection.channel'
@model={{B.data.id}}
/>
</B.Td>
</B.Tr>
</:body>
</Hds::Table>
{{/each}}
</sb.Body>
<sb.Sidebar>
<div>
<h3>{{t 'resources.session-recording.details'}}</h3>
<MetadataList @orientation='vertical' as |list|>
{{! Start time }}
<list.Item @icon='calendar' @color='faint'>
{{t 'form.started.label'}}
<time
datetime={{format-date-iso
@model.sessionRecording.start_time
}}
>
{{format-date-iso-human @model.sessionRecording.start_time}}
</time>
</list.Item>
{{! Duration }}
<list.Item @icon='clock' @color='faint'>
{{format-time-duration @model.sessionRecording.duration}}
</list.Item>
{{! Bytes up }}
<list.Item @icon='arrow-up' @color='success'>
{{format-bytes-size @model.sessionRecording.bytes_up}}
</list.Item>
{{! Bytes down }}
<list.Item @icon='arrow-down' @color='action'>
{{format-bytes-size @model.sessionRecording.bytes_down}}
</list.Item>
</MetadataList>
</div>
{{! Related information }}
<div>
<h3>{{t 'resources.session-recording.related'}}</h3>
<LinkListPanel as |list|>
{{! User name }}
{{#if @model.sessionRecording.user}}
<list.Item
@icon='user'
@color='boundary'
@route='scopes.scope.users.user'
@model={{array
@model.sessionRecording.user.scopeId
@model.sessionRecording.user.id
}}
@text={{@model.sessionRecording.userDisplayName}}
/>
{{/if}}
{{! Target name }}
{{#if @model.sessionRecording.target}}
<list.Item
@icon='target'
@color='boundary'
@route='scopes.scope.targets.target'
@model={{array
@model.sessionRecording.target.scopeId
@model.sessionRecording.target.id
}}
@text={{@model.sessionRecording.target.name}}
>
{{#if @model.sessionRecording.target.type}}
<Hds::Badge @text={{@model.sessionRecording.target.type}} />
{{/if}}
</list.Item>
{{/if}}
{{! Bucket name }}
{{#if @model.storageBucket}}
<list.Item
@icon='cloud-check'
@color='boundary'
@route='scopes.scope.storage-buckets.storage-bucket'
@model={{array
@model.storageBucket.scope.id
@model.storageBucket.id
}}
@text={{@model.storageBucket.name}}
/>
{{/if}}
</LinkListPanel>
</div>
</sb.Sidebar>
</Layout::Sidebar>
</div>
</page.body>
</Rose::Layout::Page>
@@ -1,160 +0,0 @@
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
<BreadCrumbs />
</page.breadcrumbs>
<page.header>
<h2>{{t 'resources.session-recording.session.title'}}</h2>
</page.header>
<page.body>
<div class='channels-by-connection'>
<Layout::Sidebar as |sb|>
<sb.Body>
{{#each
@model.sessionRecording.sortedConnectionsByStartTimeDesc
as |connection|
}}
<div class='channels-by-connection-connection-header'>
<p class='hds-typography-display-300 hds-font-weight-semibold'>
{{t 'resources.session-recording.connection.title'}}
{{connection.id}}
</p>
</div>
<Hds::Table
@model={{connection.sortedChannelsByStartTimeDesc}}
@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='' align='right')
}}
>
<:body as |B|>
<B.Tr>
<B.Td>
<span>{{B.data.id}}</span>
</B.Td>
<B.Td>
<MetadataList as |list|>
{{! Bytes up }}
<list.Item @icon='arrow-up' @color='success'>
{{format-bytes-size B.data.bytes_up}}
</list.Item>
{{! Bytes down }}
<list.Item @icon='arrow-down' @color='action'>
{{format-bytes-size B.data.bytes_down}}
</list.Item>
{{! Duration }}
<list.Item @icon='clock' @color='faint'>
{{format-time-duration B.data.duration}}
</list.Item>
</MetadataList>
</B.Td>
<B.Td align='right'>
<Hds::Button
@icon='play'
@color='secondary'
@text='Play'
@route='scopes.scope.session-recordings.session-recording.channels-by-connection.channel'
@model={{B.data.id}}
/>
</B.Td>
</B.Tr>
</:body>
</Hds::Table>
{{/each}}
</sb.Body>
<sb.Sidebar>
<div>
<h3>{{t 'resources.session-recording.details'}}</h3>
<MetadataList @orientation='vertical' as |list|>
{{! Start time }}
<list.Item @icon='calendar' @color='faint'>
{{t 'form.started.label'}}
<time
datetime={{format-date-iso
@model.sessionRecording.start_time
}}
>
{{format-date-iso-human @model.sessionRecording.start_time}}
</time>
</list.Item>
{{! Duration }}
<list.Item @icon='clock' @color='faint'>
{{format-time-duration @model.sessionRecording.duration}}
</list.Item>
{{! Bytes up }}
<list.Item @icon='arrow-up' @color='success'>
{{format-bytes-size @model.sessionRecording.bytes_up}}
</list.Item>
{{! Bytes down }}
<list.Item @icon='arrow-down' @color='action'>
{{format-bytes-size @model.sessionRecording.bytes_down}}
</list.Item>
</MetadataList>
</div>
{{! Related information }}
<div>
<h3>{{t 'resources.session-recording.related'}}</h3>
<LinkListPanel as |list|>
{{! User name }}
{{#if @model.sessionRecording.user}}
<list.Item
@icon='user'
@color='boundary'
@route='scopes.scope.users.user'
@model={{array
@model.sessionRecording.user.scopeId
@model.sessionRecording.user.id
}}
@text={{@model.sessionRecording.userDisplayName}}
/>
{{/if}}
{{! Target name }}
{{#if @model.sessionRecording.target}}
<list.Item
@icon='target'
@color='boundary'
@route='scopes.scope.targets.target'
@model={{array
@model.sessionRecording.target.scopeId
@model.sessionRecording.target.id
}}
@text={{@model.sessionRecording.target.name}}
>
{{#if @model.sessionRecording.target.type}}
<Hds::Badge @text={{@model.sessionRecording.target.type}} />
{{/if}}
</list.Item>
{{/if}}
{{! Bucket name }}
{{#if @model.storageBucket}}
<list.Item
@icon='cloud-check'
@color='boundary'
@route='scopes.scope.storage-buckets.storage-bucket'
@model={{array
@model.storageBucket.scope.id
@model.storageBucket.id
}}
@text={{@model.storageBucket.name}}
/>
{{/if}}
</LinkListPanel>
</div>
</sb.Sidebar>
</Layout::Sidebar>
</div>
</page.body>
</Rose::Layout::Page>
@@ -50,8 +50,8 @@ module('Acceptance | session recordings | read', function (hooks) {
});
urls.globalScope = `/scopes/global`;
urls.sessionRecordings = `${urls.globalScope}/session-recordings`;
urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`;
urls.channelRecording = `${urls.sessionRecording}/channels-by-connection/${instances.channelRecording.id}`;
urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}/channels-by-connection`;
urls.channelRecording = `${urls.sessionRecording}/${instances.channelRecording.id}`;
authenticateSession({});
featuresService = this.owner.lookup('service:features');
});
@@ -48,8 +48,8 @@ module(
});
urls.globalScope = `/scopes/global`;
urls.sessionRecordings = `${urls.globalScope}/session-recordings`;
urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}`;
urls.connectionRecording = `${urls.sessionRecording}/channels-by-connection/${instances.channelRecording.id}`;
urls.sessionRecording = `${urls.sessionRecordings}/${instances.sessionRecording.id}/channels-by-connection`;
urls.connectionRecording = `${urls.sessionRecording}/${instances.channelRecording.id}`;
authenticateSession({});
});