@@ -2,20 +2,19 @@ import React from 'react';
22import { RouteComponentProps } from 'react-router' ;
33import styled from '@emotion/styled' ;
44
5- import Checkbox from 'app/components/checkbox ' ;
5+ import ExternalLink from 'app/components/links/externalLink ' ;
66import Pagination from 'app/components/pagination' ;
77import { PanelTable } from 'app/components/panels' ;
88import SearchBar from 'app/components/searchBar' ;
9- import { t } from 'app/locale' ;
10- import space from 'app/styles/space' ;
9+ import { t , tct } from 'app/locale' ;
1110import { Organization , Project } from 'app/types' ;
1211import { DebugFile } from 'app/types/debugFiles' ;
1312import routeTitleGen from 'app/utils/routeTitle' ;
1413import AsyncView from 'app/views/asyncView' ;
1514import SettingsPageHeader from 'app/views/settings/components/settingsPageHeader' ;
1615import TextBlock from 'app/views/settings/components/text/textBlock' ;
17- // TODO(android-mappings): use own components once we decide how this should look like
18- import DebugFileRow from 'app/views/settings/projectDebugFiles/debugFileRow ' ;
16+
17+ import ProjectProguardRow from './projectProguardRow ' ;
1918
2019type Props = RouteComponentProps < { orgId : string ; projectId : string } , { } > & {
2120 organization : Organization ;
@@ -24,7 +23,6 @@ type Props = RouteComponentProps<{orgId: string; projectId: string}, {}> & {
2423
2524type State = AsyncView [ 'state' ] & {
2625 mappings : DebugFile [ ] ;
27- showDetails : boolean ;
2826} ;
2927
3028class ProjectProguard extends AsyncView < Props , State > {
@@ -38,7 +36,6 @@ class ProjectProguard extends AsyncView<Props, State> {
3836 return {
3937 ...super . getDefaultState ( ) ,
4038 mappings : [ ] ,
41- showDetails : false ,
4239 } ;
4340 }
4441
@@ -101,7 +98,7 @@ class ProjectProguard extends AsyncView<Props, State> {
10198 }
10299
103100 renderMappings ( ) {
104- const { mappings, showDetails } = this . state ;
101+ const { mappings} = this . state ;
105102 const { organization, params} = this . props ;
106103 const { orgId, projectId} = params ;
107104
@@ -115,58 +112,50 @@ class ProjectProguard extends AsyncView<Props, State> {
115112 } /projects/${ orgId } /${ projectId } /files/dsyms/?id=${ encodeURIComponent ( mapping . id ) } `;
116113
117114 return (
118- < DebugFileRow
119- debugFile = { mapping }
120- showDetails = { showDetails }
115+ < ProjectProguardRow
116+ mapping = { mapping }
121117 downloadUrl = { downloadUrl }
122- downloadRole = { organization . debugFilesRole }
123118 onDelete = { this . handleDelete }
119+ downloadRole = { organization . debugFilesRole }
124120 key = { mapping . id }
125121 />
126122 ) ;
127123 } ) ;
128124 }
129125
130126 renderBody ( ) {
131- const { loading, showDetails , mappings, mappingsPageLinks} = this . state ;
127+ const { loading, mappings, mappingsPageLinks} = this . state ;
132128
133129 return (
134130 < React . Fragment >
135- < SettingsPageHeader title = { t ( 'ProGuard Mappings' ) } />
136-
137- < TextBlock >
138- { t (
139- `ProGuard mapping files are used to convert minified classes, methods and field names into a human readable format.`
140- ) }
141- </ TextBlock >
142-
143- < Wrapper >
144- < TextBlock noMargin > { t ( 'Uploaded mappings' ) } :</ TextBlock >
145-
146- < Filters >
147- < Label >
148- < Checkbox
149- checked = { showDetails }
150- onChange = { e => {
151- this . setState ( { showDetails : ( e . target as HTMLInputElement ) . checked } ) ;
152- } }
153- />
154- { t ( 'show details' ) }
155- </ Label >
156-
131+ < SettingsPageHeader
132+ title = { t ( 'ProGuard Mappings' ) }
133+ action = {
157134 < SearchBar
158- placeholder = { t ( 'Search mappings' ) }
135+ placeholder = { t ( 'Filter mappings' ) }
159136 onSearch = { this . handleSearch }
160137 query = { this . getQuery ( ) }
138+ width = "280px"
161139 />
162- </ Filters >
163- </ Wrapper >
140+ }
141+ />
142+
143+ < TextBlock >
144+ { tct (
145+ `ProGuard mapping files are used to convert minified classes, methods and field names into a human readable format. To learn more about proguard mapping files, [link: read the docs].` ,
146+ {
147+ link : (
148+ < ExternalLink href = "https://docs.sentry.io/platforms/android/proguard/" />
149+ ) ,
150+ }
151+ ) }
152+ </ TextBlock >
164153
165154 < StyledPanelTable
166155 headers = { [
167- t ( 'Debug ID ' ) ,
168- t ( 'Information' ) ,
169- < Actions key = "actions" > { t ( 'Actions' ) } </ Actions > ,
156+ t ( 'Mapping ' ) ,
157+ < SizeColumn key = "size" > { t ( 'File Size' ) } </ SizeColumn > ,
158+ '' ,
170159 ] }
171160 emptyMessage = { this . getEmptyMessage ( ) }
172161 isEmpty = { mappings ?. length === 0 }
@@ -181,45 +170,11 @@ class ProjectProguard extends AsyncView<Props, State> {
181170}
182171
183172const StyledPanelTable = styled ( PanelTable ) `
184- grid-template-columns: 37% 1fr auto ;
173+ grid-template-columns: minmax(220px, 1fr) max-content 120px ;
185174` ;
186175
187- const Actions = styled ( 'div' ) `
176+ const SizeColumn = styled ( 'div' ) `
188177 text-align: right;
189178` ;
190179
191- const Wrapper = styled ( 'div' ) `
192- display: grid;
193- grid-template-columns: auto 1fr;
194- grid-gap: ${ space ( 4 ) } ;
195- align-items: center;
196- margin-top: ${ space ( 4 ) } ;
197- margin-bottom: ${ space ( 1 ) } ;
198- @media (max-width: ${ p => p . theme . breakpoints [ 0 ] } ) {
199- display: block;
200- }
201- ` ;
202-
203- const Filters = styled ( 'div' ) `
204- display: grid;
205- grid-template-columns: min-content minmax(200px, 400px);
206- align-items: center;
207- justify-content: flex-end;
208- grid-gap: ${ space ( 2 ) } ;
209- @media (max-width: ${ p => p . theme . breakpoints [ 0 ] } ) {
210- grid-template-columns: min-content 1fr;
211- }
212- ` ;
213-
214- const Label = styled ( 'label' ) `
215- font-weight: normal;
216- display: flex;
217- margin-bottom: 0;
218- white-space: nowrap;
219- input {
220- margin-top: 0;
221- margin-right: ${ space ( 1 ) } ;
222- }
223- ` ;
224-
225180export default ProjectProguard ;
0 commit comments