1+ import type { ACTOR_JOB_STATUSES } from '@apify/consts' ;
12import { Flags } from '@oclif/core' ;
3+ import { Time } from '@sapphire/duration' ;
24import type { Actor , ActorRunListItem , ActorTaggedBuild , PaginatedList } from 'apify-client' ;
35import chalk from 'chalk' ;
46
57import { ApifyCommand } from '../../lib/apify_command.js' ;
68import { prettyPrintStatus } from '../../lib/commands/pretty-print-status.js' ;
7- import { CompactMode , ResponsiveTable } from '../../lib/commands/responsive-table.js' ;
9+ import { CompactMode , kSkipColumn , ResponsiveTable } from '../../lib/commands/responsive-table.js' ;
810import { info , simpleLog } from '../../lib/outputs.js' ;
9- import { getLoggedClientOrThrow , ShortDurationFormatter , TimestampFormatter } from '../../lib/utils.js' ;
11+ import {
12+ DateOnlyTimestampFormatter ,
13+ getLoggedClientOrThrow ,
14+ MultilineTimestampFormatter ,
15+ ShortDurationFormatter ,
16+ } from '../../lib/utils.js' ;
17+
18+ const statusMap : Record < ( typeof ACTOR_JOB_STATUSES ) [ keyof typeof ACTOR_JOB_STATUSES ] , string > = {
19+ 'TIMED-OUT' : chalk . gray ( 'after' ) ,
20+ 'TIMING-OUT' : chalk . gray ( 'after' ) ,
21+ ABORTED : chalk . gray ( 'after' ) ,
22+ ABORTING : chalk . gray ( 'after' ) ,
23+ FAILED : chalk . gray ( 'after' ) ,
24+ READY : chalk . gray ( 'for' ) ,
25+ RUNNING : chalk . gray ( 'for' ) ,
26+ SUCCEEDED : chalk . gray ( 'after' ) ,
27+ } ;
1028
1129const recentlyUsedTable = new ResponsiveTable ( {
12- allColumns : [ 'Name' , 'Runs' , 'Last run started at' , 'Last run status' , 'Last run duration' ] ,
13- mandatoryColumns : [ 'Name' , 'Runs' , 'Last run started at' , 'Last run status', 'Last run duration' ] ,
30+ allColumns : [ 'Name' , 'Runs' , 'Last run started at' , 'Last run status' , 'Last run duration' , '_Small_LastRunText' ] ,
31+ mandatoryColumns : [ 'Name' , 'Runs' , 'Last run status' , 'Last run duration' ] ,
1432 columnAlignments : {
1533 'Runs' : 'right' ,
1634 'Last run duration' : 'right' ,
1735 Name : 'left' ,
1836 'Last run status' : 'center' ,
1937 } ,
38+ hiddenColumns : [ '_Small_LastRunText' ] ,
39+ breakpointOverrides : {
40+ small : {
41+ 'Last run status' : {
42+ label : 'Last run' ,
43+ valueFrom : '_Small_LastRunText' ,
44+ } ,
45+ } ,
46+ } ,
2047} ) ;
2148
2249const myRecentlyUsedTable = new ResponsiveTable ( {
@@ -29,24 +56,25 @@ const myRecentlyUsedTable = new ResponsiveTable({
2956 'Last run' ,
3057 'Last run status' ,
3158 'Last run duration' ,
59+ '_Small_LastRunText' ,
3260 ] ,
33- mandatoryColumns : [
34- 'Name' ,
35- 'Modified at' ,
36- 'Builds' ,
37- 'Default build' ,
38- 'Runs' ,
39- 'Last run' ,
40- 'Last run status' ,
41- 'Last run duration' ,
42- ] ,
61+ mandatoryColumns : [ 'Name' , 'Runs' , 'Last run' , 'Last run duration' ] ,
62+ hiddenColumns : [ '_Small_LastRunText' ] ,
4363 columnAlignments : {
4464 'Builds' : 'right' ,
4565 'Runs' : 'right' ,
4666 'Last run duration' : 'right' ,
4767 Name : 'left' ,
4868 'Last run status' : 'center' ,
4969 } ,
70+ breakpointOverrides : {
71+ small : {
72+ 'Last run' : {
73+ label : 'Last run' ,
74+ valueFrom : '_Small_LastRunText' ,
75+ } ,
76+ } ,
77+ } ,
5078} ) ;
5179
5280interface HydratedListData {
@@ -148,24 +176,37 @@ export class ActorsLsCommand extends ApifyCommand<typeof ActorsLsCommand> {
148176
149177 const table = my ? myRecentlyUsedTable : recentlyUsedTable ;
150178
179+ const longestActorTitleLength =
180+ actorList . items . reduce ( ( acc , curr ) => {
181+ const title = `${ curr . username } /${ curr . name } ` ;
182+
183+ if ( title . length > acc ) {
184+ return title . length ;
185+ }
186+
187+ return acc ;
188+ } , 0 ) +
189+ // Padding left right of the name column
190+ 2 +
191+ // Runs column minimum size with padding
192+ 6 ;
193+
151194 for ( const item of actorList . items ) {
152195 const lastRunDisplayedTimestamp = item . stats . lastRunStartedAt
153- ? TimestampFormatter . display ( item . stats . lastRunStartedAt )
196+ ? MultilineTimestampFormatter . display ( item . stats . lastRunStartedAt )
154197 : '' ;
155198
156199 const lastRunDuration = item . lastRun
157200 ? ( ( ) => {
158201 if ( item . lastRun . finishedAt ) {
159- return chalk . gray (
160- ShortDurationFormatter . format (
161- item . lastRun . finishedAt . getTime ( ) - item . lastRun . startedAt . getTime ( ) ,
162- ) ,
202+ return ShortDurationFormatter . format (
203+ item . lastRun . finishedAt . getTime ( ) - item . lastRun . startedAt . getTime ( ) ,
163204 ) ;
164205 }
165206
166207 const duration = Date . now ( ) - item . lastRun . startedAt . getTime ( ) ;
167208
168- return chalk . gray ( `${ ShortDurationFormatter . format ( duration ) } ...` ) ;
209+ return `${ ShortDurationFormatter . format ( duration ) } …` ;
169210 } ) ( )
170211 : '' ;
171212
@@ -187,16 +228,50 @@ export class ActorsLsCommand extends ApifyCommand<typeof ActorsLsCommand> {
187228 } ) ( )
188229 : chalk . gray ( 'Unknown' ) ;
189230
231+ const runStatus = ( ( ) => {
232+ if ( item . lastRun ) {
233+ const status = prettyPrintStatus ( item . lastRun . status ) ;
234+
235+ const stringParts = [ status ] ;
236+
237+ if ( lastRunDuration ) {
238+ stringParts . push ( statusMap [ item . lastRun . status ] , chalk . cyan ( lastRunDuration ) ) ;
239+ }
240+
241+ if ( item . lastRun . finishedAt ) {
242+ const diff = Date . now ( ) - item . lastRun . finishedAt . getTime ( ) ;
243+
244+ if ( diff < Time . Week ) {
245+ stringParts . push ( '\n' , chalk . gray ( `${ ShortDurationFormatter . format ( diff ) } ago` ) ) ;
246+ } else {
247+ stringParts . push (
248+ '\n' ,
249+ chalk . gray ( 'On' , DateOnlyTimestampFormatter . display ( item . lastRun . finishedAt ) ) ,
250+ ) ;
251+ }
252+ }
253+
254+ return stringParts . join ( ' ' ) ;
255+ }
256+
257+ return '' ;
258+ } ) ( ) ;
259+
190260 table . pushRow ( {
191261 Name : `${ item . title } \n${ chalk . gray ( `${ item . username } /${ item . name } ` ) } ` ,
192- Runs : chalk . cyan ( `${ item . stats ?. totalRuns ?? 0 } ` ) ,
262+ // Completely arbitrary number, but its enough for a very specific edge case where a full actor identifier could be very long, but only on small terminals
263+ Runs :
264+ ResponsiveTable . isSmallTerminal ( ) && longestActorTitleLength >= 56
265+ ? kSkipColumn
266+ : chalk . cyan ( `${ item . stats ?. totalRuns ?? 0 } ` ) ,
193267 'Last run started at' : lastRunDisplayedTimestamp ,
194268 'Last run' : lastRunDisplayedTimestamp ,
195269 'Last run status' : item . lastRun ? prettyPrintStatus ( item . lastRun . status ) : '' ,
196- 'Modified at' : TimestampFormatter . display ( item . modifiedAt ) ,
270+ 'Modified at' : MultilineTimestampFormatter . display ( item . modifiedAt ) ,
197271 Builds : item . actor ? chalk . cyan ( item . actor . stats . totalBuilds ) : chalk . gray ( 'Unknown' ) ,
198- 'Last run duration' : lastRunDuration ,
272+ 'Last run duration' : ResponsiveTable . isSmallTerminal ( ) ? kSkipColumn : chalk . cyan ( lastRunDuration ) ,
199273 'Default build' : defaultBuild ,
274+ _Small_LastRunText : runStatus ,
200275 } ) ;
201276 }
202277
0 commit comments