@@ -3,6 +3,7 @@ import styled from 'styled-components';
33import { AssetContext } from '~/context/AssetContext' ;
44import { Icon } from '~/components' ;
55import { formatUuid , stringToColor } from '~/helpers/formatters' ;
6+ import { formatAssetDisplay } from '../../../utils' ;
67
78interface IAssetPermissionSelectorProps {
89 selectedAssets : string [ ] ;
@@ -192,6 +193,45 @@ const SelectedAssetsList = styled.div`
192193 margin-top: 12px;
193194` ;
194195
196+ const SelectedAssetsHeader = styled . div `
197+ display: flex;
198+ align-items: center;
199+ justify-content: space-between;
200+ margin-top: 12px;
201+ ` ;
202+
203+ const SelectedAssetsCount = styled . span `
204+ font-size: 14px;
205+ font-weight: 500;
206+ color: ${ ( { theme } ) => theme . colors . textPrimary } ;
207+ ` ;
208+
209+ const ClearAllButton = styled . button `
210+ display: flex;
211+ align-items: center;
212+ justify-content: center;
213+ gap: 4px;
214+ padding: 0 12px;
215+ background-color: transparent;
216+ font-weight: 500;
217+ font-size: 14px;
218+ color: ${ ( { theme } ) => theme . colors . textPink } ;
219+ border: none;
220+ cursor: pointer;
221+ transition: color 250ms ease-out;
222+
223+ &:hover:not(:disabled) {
224+ color: ${ ( { theme } ) => theme . colors . textBlue } ;
225+ }
226+
227+ &:disabled {
228+ color: ${ ( { theme } ) => theme . colors . textDisabled } ;
229+ cursor: not-allowed;
230+ }
231+ ` ;
232+
233+ const SelectedAssetsContainer = styled . div `` ;
234+
195235const SelectedAssetItem = styled . div `
196236 display: flex;
197237 align-items: center;
@@ -358,6 +398,10 @@ export const AssetPermissionSelector = ({
358398 }
359399 } ;
360400
401+ const handleClearAll = ( ) => {
402+ onChange ( [ ] ) ;
403+ } ;
404+
361405 return (
362406 < >
363407 < SelectWrapper ref = { ref } >
@@ -386,28 +430,32 @@ export const AssetPermissionSelector = ({
386430 onChange = { ( e ) => setSearchQuery ( e . target . value ) }
387431 onClick = { ( e ) => e . stopPropagation ( ) }
388432 />
389- { assetsLoading ? (
433+ { assetsLoading && (
390434 < StyledOption $selected = { false } > Loading assets...</ StyledOption >
391- ) : filteredAssets . length > 0 ? (
392- filteredAssets . map ( ( asset ) => (
393- < StyledOption
394- key = { asset . id }
395- $selected = { selectedAssets . includes ( asset . id ) }
396- onClick = { ( ) => handleToggle ( asset . id ) }
397- >
398- < IconWrapper $background = { stringToColor ( asset . id ) } >
399- < Icon name = "Coins" size = "16px" />
400- </ IconWrapper >
401- < div style = { { flex : 1 } } >
402- { formatUuid ( asset . id ) } - { asset . name }
403- { asset . ticker && ` (${ asset . ticker } )` }
404- </ div >
405- { selectedAssets . includes ( asset . id ) && (
406- < Icon name = "Check" size = "16px" />
407- ) }
408- </ StyledOption >
409- ) )
410- ) : (
435+ ) }
436+ { ! assetsLoading && filteredAssets . length > 0 && (
437+ < >
438+ { filteredAssets . map ( ( asset ) => (
439+ < StyledOption
440+ key = { asset . id }
441+ $selected = { selectedAssets . includes ( asset . id ) }
442+ onClick = { ( ) => handleToggle ( asset . id ) }
443+ >
444+ < IconWrapper $background = { stringToColor ( asset . id ) } >
445+ < Icon name = "Coins" size = "16px" />
446+ </ IconWrapper >
447+ < div style = { { flex : 1 } } >
448+ { formatUuid ( asset . id ) } - { asset . name }
449+ { asset . ticker && ` (${ asset . ticker } )` }
450+ </ div >
451+ { selectedAssets . includes ( asset . id ) && (
452+ < Icon name = "Check" size = "16px" />
453+ ) }
454+ </ StyledOption >
455+ ) ) }
456+ </ >
457+ ) }
458+ { ! assetsLoading && filteredAssets . length === 0 && (
411459 < StyledOption $selected = { false } >
412460 { searchQuery ? 'No assets found' : 'No assets available' }
413461 </ StyledOption >
@@ -440,27 +488,41 @@ export const AssetPermissionSelector = ({
440488 </ AssetIdSection >
441489
442490 { selectedAssets . length > 0 && (
443- < SelectedAssetsList >
444- { selectedAssets . map ( ( assetId ) => {
445- const asset = allAssets . find ( ( a ) => a . id === assetId ) ;
446- const displayText = asset
447- ? `${ formatUuid ( asset . id ) } ${ asset . ticker ? ` (${ asset . ticker } )` : '' } `
448- : formatUuid ( assetId ) ;
449-
450- return (
451- < SelectedAssetItem key = { assetId } >
452- { displayText }
453- < RemoveButton
454- type = "button"
455- onClick = { ( ) => handleToggle ( assetId ) }
456- aria-label = "Remove asset"
457- >
458- < Icon name = "CloseIcon" size = "12px" />
459- </ RemoveButton >
460- </ SelectedAssetItem >
461- ) ;
462- } ) }
463- </ SelectedAssetsList >
491+ < SelectedAssetsContainer >
492+ < SelectedAssetsHeader >
493+ < SelectedAssetsCount >
494+ { selectedAssets . length } asset
495+ { selectedAssets . length === 1 ? '' : 's' } selected
496+ </ SelectedAssetsCount >
497+ < ClearAllButton
498+ type = "button"
499+ onClick = { handleClearAll }
500+ disabled = { selectedAssets . length === 0 }
501+ aria-label = "Clear all selected assets"
502+ >
503+ Clear All
504+ < Icon name = "Delete" size = "14px" />
505+ </ ClearAllButton >
506+ </ SelectedAssetsHeader >
507+ < SelectedAssetsList >
508+ { selectedAssets . map ( ( assetId ) => {
509+ const displayText = formatAssetDisplay ( assetId , allAssets ) ;
510+
511+ return (
512+ < SelectedAssetItem key = { assetId } >
513+ { displayText }
514+ < RemoveButton
515+ type = "button"
516+ onClick = { ( ) => handleToggle ( assetId ) }
517+ aria-label = "Remove asset"
518+ >
519+ < Icon name = "CloseIcon" size = "12px" />
520+ </ RemoveButton >
521+ </ SelectedAssetItem >
522+ ) ;
523+ } ) }
524+ </ SelectedAssetsList >
525+ </ SelectedAssetsContainer >
464526 ) }
465527 </ >
466528 ) ;
0 commit comments