@@ -19,9 +19,7 @@ import '../cc-badge/cc-badge.js';
19
19
import { LostFocusController } from '../../controllers/lost-focus-controller.js' ;
20
20
import { ifDefined } from 'lit/directives/if-defined.js' ;
21
21
import { createRef , ref } from 'lit/directives/ref.js' ;
22
-
23
- /**
24
- */
22
+ import { isExpirationClose } from '../../lib/utils.js' ;
25
23
26
24
/**
27
25
* @typedef {import('./cc-session-tokens.types.js').SessionTokenState } SessionTokenState
@@ -64,7 +62,7 @@ export class CcSessionTokens extends LitElement {
64
62
this . _currentSessionCardRef = createRef ( ) ;
65
63
66
64
new ResizeController ( this , {
67
- widthBreakpoints : [ 900 , 730 ] ,
65
+ widthBreakpoints : [ 995 , 730 ] ,
68
66
} ) ;
69
67
70
68
new LostFocusController ( this , '.session-token-card__action-revoke' , ( { suggestedElement } ) => {
@@ -99,51 +97,28 @@ export class CcSessionTokens extends LitElement {
99
97
dispatchCustomEvent ( this , 'revoke-token' , tokenId ) ;
100
98
}
101
99
102
- /**
103
- * Adds expiration information to a token based on time remaining
104
- *
105
- * @param {SessionTokenState } token - The token to process
106
- * @returns {SessionTokenStateWithExpirationWarning } The token with added expiration information
107
- * @private
108
- */
109
- _addIsExpirationClose ( token ) {
110
- const expirationDate = new Date ( token . expirationDate ) ;
111
- const now = new Date ( ) ;
112
- const daysUntilExpiration = ( expirationDate . getTime ( ) - now . getTime ( ) ) / ( 1000 * 60 * 60 * 24 ) ;
113
-
114
- let thresholdDays ;
115
- if ( daysUntilExpiration <= 7 ) {
116
- thresholdDays = 2 ;
117
- } else if ( daysUntilExpiration <= 30 ) {
118
- thresholdDays = 7 ;
119
- } else if ( daysUntilExpiration <= 60 ) {
120
- thresholdDays = 10 ;
121
- } else if ( daysUntilExpiration <= 90 ) {
122
- thresholdDays = 20 ;
123
- } else {
124
- thresholdDays = 30 ;
125
- }
126
-
127
- const isExpirationClose = daysUntilExpiration <= thresholdDays ;
128
- return { ...token , isExpirationClose } ;
129
- }
130
-
131
100
/** @param {CcSessionTokensPropertyValues } changedProperties */
132
101
willUpdate ( changedProperties ) {
133
- if ( changedProperties . has ( 'state' ) && this . state . type === 'loaded' ) {
102
+ if ( changedProperties . has ( 'state' ) && ( this . state . type === 'loaded' || this . state . type === 'revoking-all' ) ) {
134
103
this . _sortedAndFormattedTokens = [ ...this . state . tokens ]
135
104
. sort ( ( tokenA , tokenB ) => {
136
105
// Current session always comes first
137
- if ( tokenA . isCurrentSession ) {
106
+ if ( tokenA . type === 'current' ) {
138
107
return - 1 ;
139
108
}
140
- if ( tokenB . isCurrentSession ) {
109
+ if ( tokenB . type === 'current' ) {
141
110
return 1 ;
142
111
}
143
112
// Then sort by creation date (newest first)
144
113
return new Date ( tokenB . creationDate ) . getTime ( ) - new Date ( tokenA . creationDate ) . getTime ( ) ;
145
114
} )
146
- . map ( this . _addIsExpirationClose ) ;
115
+ . map ( ( token ) => ( {
116
+ ...token ,
117
+ isExpirationClose : isExpirationClose ( {
118
+ creationDate : token . creationDate ,
119
+ expirationDate : token . expirationDate ,
120
+ } ) ,
121
+ } ) ) ;
147
122
}
148
123
}
149
124
@@ -165,7 +140,7 @@ export class CcSessionTokens extends LitElement {
165
140
class= "revoke-all-tokens-button"
166
141
danger
167
142
outlined
168
- . waiting = ${ this . state . type === 'revoking-all' }
143
+ ? waiting= ${ this . state . type === 'revoking-all' }
169
144
@cc-button : click= ${ this . _onRevokeAllTokens }
170
145
>
171
146
${ i18n ( 'cc-session-tokens.revoke-all-tokens' ) }
@@ -199,10 +174,8 @@ export class CcSessionTokens extends LitElement {
199
174
* @returns {TemplateResult } The rendered token card
200
175
* @private
201
176
*/
202
- _renderTokenCard (
203
- { type, id, creationDate, expirationDate, lastUsedDate, isCurrentSession, isExpirationClose, isCleverTeam } ,
204
- index ,
205
- ) {
177
+ _renderTokenCard ( { type, id, creationDate, expirationDate, lastUsedDate, isExpirationClose, isCleverTeam } , index ) {
178
+ const isCurrentSession = type === 'current' ;
206
179
const tabIndex = isCurrentSession ? - 1 : null ;
207
180
return html `
208
181
<li
@@ -211,7 +184,12 @@ export class CcSessionTokens extends LitElement {
211
184
${ isCurrentSession ? ref ( this . _currentSessionCardRef ) : '' }
212
185
>
213
186
${ isCurrentSession || isCleverTeam || isExpirationClose
214
- ? this . _renderCardHeader ( { isCurrentSession, isCleverTeam, isExpirationClose } )
187
+ ? this . _renderCardHeader ( {
188
+ isCurrentSession,
189
+ isCleverTeam,
190
+ isExpirationClose,
191
+ isRevoking : type === 'revoking' ,
192
+ } )
215
193
: '' }
216
194
<dl class= "session-token-card__info ${ classMap ( { 'is-revoking' : type === 'revoking' } ) } " >
217
195
<div class= "session-token-card__info__last-used" >
@@ -247,7 +225,7 @@ export class CcSessionTokens extends LitElement {
247
225
hide-text
248
226
.icon = ${ iconDelete }
249
227
circle
250
- . waiting = ${ type === 'revoking' }
228
+ ? waiting= ${ type === 'revoking' }
251
229
@cc-button : click= ${ ( ) => this . _onRevokeToken ( id ) }
252
230
>
253
231
${ i18n ( 'cc-session-tokens.revoke-token' , { tokenNumber : index + 1 } ) }
@@ -258,10 +236,10 @@ export class CcSessionTokens extends LitElement {
258
236
` ;
259
237
}
260
238
261
- /** @param {Pick<SessionTokenStateWithExpirationWarning, ' isCurrentSession' | 'isCleverTeam' | 'isExpirationClose'> } params */
262
- _renderCardHeader ( { isCurrentSession, isCleverTeam, isExpirationClose } ) {
239
+ /** @param {{ isCleverTeam: boolean, isExpirationClose: boolean, isCurrentSession: boolean, isRevoking: boolean } } params */
240
+ _renderCardHeader ( { isCurrentSession, isCleverTeam, isExpirationClose, isRevoking } ) {
263
241
return html `
264
- <div class= "session-token-card__header" >
242
+ <div class= "session-token-card__header ${ classMap ( { 'is-revoking' : isRevoking } ) } " >
265
243
${ isCurrentSession
266
244
? html `
267
245
<div class= "session-token-card__header__current-session" >
@@ -284,6 +262,7 @@ export class CcSessionTokens extends LitElement {
284
262
display : block;
285
263
}
286
264
265
+ /* Reset default margins and paddings */
287
266
ul ,
288
267
li ,
289
268
dl ,
@@ -297,12 +276,6 @@ export class CcSessionTokens extends LitElement {
297
276
list-style : none;
298
277
}
299
278
300
- /* the current session card may be focused after deleting the last session */
301
- .session-token-card : focus {
302
- outline : var (--cc-focus-outline );
303
- outline-offset : var (--cc-focus-outline-offset , 2px );
304
- }
305
-
306
279
p {
307
280
margin : 0 ;
308
281
}
@@ -311,13 +284,14 @@ export class CcSessionTokens extends LitElement {
311
284
opacity : var (--cc-opacity-when-disabled , 0.65 );
312
285
}
313
286
314
- .session-tokens-wrapper {
315
- margin-top : 2.5em ;
287
+ /* When all other sessions are revoked, focus may return to the current session card */
288
+ .session-token-card : focus-visible {
289
+ outline : var (--cc-focus-outline );
290
+ outline-offset : var (--cc-focus-outline-offset , 2px );
316
291
}
317
292
318
- .session-tokens-wrapper__list {
319
- display : grid;
320
- gap : 1.5em ;
293
+ .session-tokens-wrapper {
294
+ margin-top : 2.5em ;
321
295
}
322
296
323
297
.session-token-card {
@@ -333,13 +307,13 @@ export class CcSessionTokens extends LitElement {
333
307
--cc-icon-size : 1.2em ;
334
308
335
309
align-items : center;
310
+ column-gap : 1em ;
336
311
display : flex;
337
312
flex-wrap : wrap;
338
313
font-weight : bold;
339
- gap : 1em ;
340
314
grid-column : info-start / info-end;
341
315
margin-bottom : 1em ;
342
- width : 100 % ;
316
+ row-gap : 0.5 em ;
343
317
}
344
318
345
319
.session-token-card__header__current-session {
@@ -355,6 +329,12 @@ export class CcSessionTokens extends LitElement {
355
329
grid-column : info-start / info-end;
356
330
}
357
331
332
+ .session-token-card__info div {
333
+ display : flex;
334
+ flex-wrap : wrap;
335
+ gap : 0.5em ;
336
+ }
337
+
358
338
.session-token-card__info__last-used {
359
339
font-style : italic;
360
340
}
@@ -363,12 +343,6 @@ export class CcSessionTokens extends LitElement {
363
343
font-weight : bold;
364
344
}
365
345
366
- dl div {
367
- display : flex;
368
- flex-wrap : wrap;
369
- gap : 0.5em ;
370
- }
371
-
372
346
dt {
373
347
--line-height : 1.2em ;
374
348
--cc-icon-size : var (--line-height );
@@ -379,7 +353,6 @@ export class CcSessionTokens extends LitElement {
379
353
line-height : var (--line-height );
380
354
}
381
355
382
- /* Remove spacing below the font so that it matches dt spacing */
383
356
dd {
384
357
align-items : center;
385
358
display : flex;
@@ -391,6 +364,18 @@ export class CcSessionTokens extends LitElement {
391
364
font-weight : normal;
392
365
}
393
366
367
+ .session-token-card cc-button {
368
+ align-self : start;
369
+ grid-column : actions-start / actions-end;
370
+ grid-row : 1 / -1 ;
371
+ justify-self : end;
372
+ }
373
+
374
+ .session-tokens-wrapper__list {
375
+ display : grid;
376
+ gap : 1.5em ;
377
+ }
378
+
394
379
: host ([w-lt-730 ]) .session-token-card {
395
380
grid-template-columns : [card-start info- start] 1fr [info-end actions- start] max-content [actions-end card- end];
396
381
}
@@ -400,19 +385,9 @@ export class CcSessionTokens extends LitElement {
400
385
row-gap : 0.5em ;
401
386
}
402
387
403
- .session-token-card cc-button {
404
- align-self : start;
405
- grid-column : actions-start / actions-end;
406
- grid-row : 1 / -1 ;
407
- justify-self : end;
408
- }
409
-
410
388
@supports (grid-template-columns : subgrid) {
411
389
.session-tokens-wrapper__list {
412
- column-gap : 1.5em ;
413
- display : grid;
414
- grid-template-columns : [card-start info- start] max-content max-content max-content [info-end actions- start] 1fr [actions-end card- end];
415
- row-gap : 1.5em ;
390
+ grid-template-columns : [card-start info- start] max-content max-content max-content [info-end actions- start] auto [actions-end card- end];
416
391
}
417
392
418
393
.session-token-card {
@@ -421,27 +396,22 @@ export class CcSessionTokens extends LitElement {
421
396
grid-template-columns : subgrid;
422
397
}
423
398
424
- .session-token-card__header {
425
- grid-column : info-start / info-end;
426
- }
427
-
428
399
.session-token-card__info {
429
400
display : grid;
430
- gap : unset;
431
401
grid-column : info-start / info-end;
432
402
grid-template-columns : subgrid;
433
403
}
434
404
435
- : host ([w-lt-900 ]) .session-tokens-wrapper__list {
436
- grid-template-columns : [card-start info- start] 1fr 1fr 1fr [info-end actions- start] 1 fr [actions-end card- end];
405
+ : host ([w-lt-995 ]) .session-tokens-wrapper__list {
406
+ grid-template-columns : [card-start info- start] 1fr 1fr 1fr [info-end actions- start] auto [actions-end card- end];
437
407
}
438
408
439
- : host ([w-lt-900 ]) .session-token-card__info div {
409
+ : host ([w-lt-995 ]) .session-token-card__info div {
440
410
display : grid;
441
411
}
442
412
443
413
: host ([w-lt-730 ]) .session-tokens-wrapper__list {
444
- grid-template-columns : [card-start info- start] 1fr [info-end actions- start] max-content [actions-end card- end];
414
+ grid-template-columns : [card-start info- start] 1fr [info-end actions- start] auto [actions-end card- end];
445
415
}
446
416
447
417
: host ([w-lt-730 ]) .session-token-card__info {
0 commit comments