@@ -11,6 +11,9 @@ class CSWApp extends LitElement {
11
11
startRecord : { type : Number } ,
12
12
endRecord : { type : Number } ,
13
13
fullRecord : { type : Object } ,
14
+ translatedAbstract : { type : String } ,
15
+ translatedDescription : { type : String } ,
16
+ translatedSubject : { type : String }
14
17
} ;
15
18
}
16
19
static get styles ( ) {
@@ -39,6 +42,9 @@ class CSWApp extends LitElement {
39
42
this . searchType = '' ;
40
43
this . searchString = '' ;
41
44
this . fullRecord = null ;
45
+ this . translatedAbstract = '' ;
46
+ this . translatedDescription = '' ;
47
+ this . translatedSubject = '' ;
42
48
}
43
49
render ( ) {
44
50
return html `
@@ -53,30 +59,69 @@ class CSWApp extends LitElement {
53
59
< hr >
54
60
< h2 > Search</ h2 >
55
61
< label for ="type "> Type: </ label > < input @keyup ="${ ( event ) => this . updateType ( event ) } " type ="text " id ="type " placeholder ="Type... "> < br >
56
- < label for ="search "> Search: < label > < input @keyup ="${ ( event ) => this . updateSearch ( event ) } " type ="text " id ="search " placeholder ="Search... "> < br >
62
+ < label for ="search "> Search: </ label > < input @keyup ="${ ( event ) => this . updateSearch ( event ) } " type ="text " id ="search " placeholder ="Search... "> < br >
57
63
< label for ="bbox "> Bounding box: </ label > < input type ="text " id ="bbox " placeholder ="Bounding box... "> < br >
58
- < button @click ="${ ( ) => this . getRecordsHandler ( 1 ) } " id ="get-records-button "> Get Records </ button >
64
+ < button @click ="${ ( ) => this . getRecordsHandler ( 1 ) } " id ="get-records-button "> Search </ button >
59
65
< div id ="records ">
60
66
< h2 > Records</ h2 >
67
+ Search string: ${ this . translatedSearch } < br >
68
+ Type: ${ this . searchType } < br >
61
69
Total records: ${ this . totalRecords } < br >
70
+ ${ this . message !== '' ? html `< p > ${ this . message } </ p > ` : '' }
62
71
${ this . totalRecords > 0 && this . briefRecords . length > 0 ? html `
63
72
Showing records ${ this . startRecord } to ${ this . endRecord }
64
73
< table >
65
74
< thead > < tr > < th > Type</ th > < th > title</ th > < th > title (AI-translated)</ th > </ tr > </ thead >
66
75
< tbody >
67
- ${ this . briefRecords . map ( record => html `< tr > < td > ${ record . type } </ td > < td @click ="${ ( _e ) => this . getRecordById ( record . identifier ) } " class ="recordtitle "> ${ record . title } </ td > < td > ${ record . englishTitle } </ td > </ tr > ` ) }
76
+ ${ this . briefRecords . map ( record => html `< tr > < td > ${ record . type } </ td > < td @click ="${ ( event ) => this . briefRecordTitleClicked ( event , record . identifier ) } " class ="recordtitle "> ${ record . title } </ td > < td > ${ record . englishTitle } </ td > </ tr > ` ) }
68
77
</ tbody >
69
78
</ table >
70
- ${ this . startRecord > 1 ? html `< button @click ="${ ( ) => this . getRecordsHandler ( this . startRecord - 10 ) } "> Previous</ button > ` : '' }
71
- ${ this . totalRecords > this . endRecord ? html `< button @click ="${ ( ) => this . getRecordsHandler ( this . startRecord + 10 ) } "> Next</ button > ` : '' }
72
- ` : '' }
73
- ${ this . fullRecord ? html `
74
- < h2 > Full Record</ h2 >
75
- < pre > ${ JSON . stringify ( this . fullRecord , null , 2 ) } </ pre >
79
+ < button ?disabled =${ this . startRecord <= 1 } @click ="${ ( ) => this . getRecordsHandler ( this . startRecord - 10 ) } "> Previous</ button >
80
+ < button ?disabled =${ this . nextRecord === 0 } @click ="${ ( ) => this . getRecordsHandler ( this . startRecord + 10 ) } "> Next</ button >
76
81
` : '' }
82
+ ${ this . fullRecord ? this . renderFullRecord ( this . fullRecord ) : '' }
77
83
</ div >
78
84
` ;
79
85
}
86
+ renderOtherKeys ( record ) {
87
+ for ( const key in record ) {
88
+ if ( ! [ 'identifier' , 'title' , 'type' , 'subject' , 'format' , 'date' , 'abstract' , 'description' , 'rights' , 'source' , 'relation' , 'URI' ] . includes ( key ) ) {
89
+ return html `< tr > < td > ${ key } :</ td > < td > ${ record [ key ] } </ td > </ tr > ` ;
90
+ }
91
+ }
92
+ }
93
+ renderFullRecord ( record ) {
94
+ if ( ! record ) return html `< p > No record selected</ p > ` ;
95
+ const subject = record . subject ? Array . isArray ( record . subject ) ? record . subject . join ( ', ' ) : record . subject : '' ;
96
+ let abstractLabel = record . abstract === record . description ? 'Abstract / description' : 'Abstract' ;
97
+
98
+ return html `
99
+ < h2 > Full Record</ h2 >
100
+ < table >
101
+ < tr > < td class ="label "> Identifier:</ td > < td > ${ record . identifier } </ td > </ tr >
102
+ < tr > < td class ="label "> Title:</ td > < td > ${ record . title } </ td > </ tr >
103
+ < tr > < td class ="label "> Type:</ td > < td > ${ record . type } </ td > </ tr >
104
+ < tr > < td class ="label "> Subject:</ td > < td > ${ subject } </ td > </ tr >
105
+ < tr > < td class ="label "> Subject (english):</ td > < td > ${ this . translatedSubject } </ td > </ tr >
106
+ < tr > < td class ="label "> Format:</ td > < td > ${ record . format } </ td > </ tr >
107
+ < tr > < td class ="label "> Date:</ td > < td > ${ record . date } </ td > </ tr >
108
+ < tr > < td class ="label "> ${ abstractLabel } :</ td > < td > ${ record . abstract } </ td > </ tr >
109
+ < tr > < td class ="label "> ${ abstractLabel } (english)</ td > < td > ${ this . translatedAbstract } </ td > </ tr >
110
+ ${ record . abstract !== record . description ? html `< tr > < td class ="label "> Description:</ td > < td > ${ record . description } </ td > </ tr > ` : '' }
111
+ ${ record . abstract !== record . description ? html `< tr > < td class ="label "> Description (english):</ td > < td > ${ this . translatedDescription } </ td > </ tr > ` : '' }
112
+ < tr > < td > Rights:</ td > < td > ${ record . rights ?record . rights :'none' } </ td > </ tr >
113
+ < tr > < td > Source:</ td > < td > ${ record . source ?record . source :'none' } </ td > </ tr >
114
+ < tr > < td > Relation:</ td > < td > ${ record . relation ? html `< span @click ="${ ( _e ) => this . updateFullRecord ( record . relation ) } "> Link</ span > ` :'none' } </ td > </ tr >
115
+ < tr > < td > Links: </ td > < td > </ td > </ tr >
116
+ ${ record . URI ?
117
+ record . URI . map ( uri => html `< tr > < td > </ td > < td > ${ uri . protocol } < a href ="${ uri . url } " target ="cswlink "> ${ uri . name ?uri . name :'No name' } ${ uri . description } </ a > </ td > </ tr > ` )
118
+ :
119
+ html `< tr > < td > </ td > < td > no URI/URLs defined</ td > </ tr > `
120
+ }
121
+ ${ this . renderOtherKeys ( record ) }
122
+ </ table >
123
+ ` ;
124
+ }
80
125
connectedCallback ( ) {
81
126
super . connectedCallback ( ) ;
82
127
this . init ( ) ;
@@ -113,40 +158,85 @@ class CSWApp extends LitElement {
113
158
return null ;
114
159
}
115
160
}
116
- async getRecordById ( identifier ) {
161
+ async getTranslatedStrings ( strings , language ) {
162
+ return await this . fetchJson ( './translate' , {
163
+ method : 'POST' ,
164
+ headers : {
165
+ 'Content-Type' : 'application/json'
166
+ } ,
167
+ body : JSON . stringify ( {
168
+ strings : strings ,
169
+ language : language
170
+ } )
171
+ } )
172
+ }
173
+ briefRecordTitleClicked ( event , identifier ) {
174
+ const rows = event . target . parentElement . parentElement . querySelectorAll ( 'tr' ) ;
175
+ rows . forEach ( row => row . style . backgroundColor = 'white' ) ;
176
+ event . target . parentElement . style . backgroundColor = 'whitesmoke' ;
177
+ // remove focus of all previously selected input fields
178
+ const inputs = this . shadowRoot . querySelectorAll ( 'input' ) ;
179
+ inputs . forEach ( input => input . blur ( ) ) ;
180
+ this . updateFullRecord ( identifier ) ;
181
+ }
182
+ async updateFullRecord ( identifier ) {
117
183
this . fullRecord = null ;
184
+ this . translatedAbstract = this . translatedDescription = this . translatedSubject = 'Translating...'
118
185
const fullRecord = await this . fetchJson ( `./csw_record_by_id?url=${ encodeURIComponent ( this . catalogList [ this . catalogSelect . value ] . url ) } &id=${ encodeURIComponent ( identifier ) } ` ) ;
119
186
if ( fullRecord && ! fullRecord . error ) {
120
- this . fullRecord = fullRecord ;
187
+ this . fullRecord = fullRecord ?. records ?. [ 0 ] ;
188
+ const subject = this . fullRecord . subject ? Array . isArray ( this . fullRecord . subject ) ? this . fullRecord . subject . join ( ', ' ) : this . fullRecord . subject : '' ;
189
+ [ this . translatedAbstract , this . translatedDescription , this . translatedSubject ] = await this . getTranslatedStrings (
190
+ [ this . fullRecord . abstract ,
191
+ this . fullRecord . description ,
192
+ subject ] , this . catalogList [ this . catalogSelect . value ] . language )
121
193
}
122
194
}
123
195
async getRecordsHandler ( startRecord ) {
124
196
const catalogUrl = this . catalogList [ this . catalogSelect . value ] . url ;
125
- const records = await this . fetchJson ( `./csw_records?url=${ encodeURIComponent ( catalogUrl ) } &startRecord=${ startRecord } &type=${ this . searchType } &search=${ this . searchString } ` ) ;
126
- this . totalRecords = 0 ;
127
197
this . briefRecords = [ ] ;
128
198
this . fullRecord = null ;
129
- this . requestUpdate ( ) ;
199
+ this . startRecord = startRecord ;
200
+ if ( startRecord == 1 ) {
201
+ this . translatedSearch = this . searchString ;
202
+ this . totalRecords = 0 ;
203
+ }
204
+ this . requestUpdate ( ) ;
205
+ let search = this . searchString ;
206
+ if ( this . searchString . trim ( ) !== '' ) {
207
+ if ( this . startRecord === 1 ) {
208
+ const targetLanguage = this . catalogList [ this . catalogSelect . value ] . language ;
209
+ const userLanguage = navigator . language ;
210
+ this . message = `Translating ${ this . searchString } to ${ targetLanguage } ` ;
211
+ search = await this . fetchJson ( `./translateSearch?searchString=${ encodeURIComponent ( this . searchString ) } &userLanguage=${ userLanguage } &targetLanguage=${ targetLanguage } ` ) ;
212
+ this . message = '' ;
213
+ this . translatedSearch = search ;
214
+ } else {
215
+ search = this . translatedSearch ; // keep the translated search string for search pages > 1
216
+ }
217
+ } else {
218
+ this . translatedSearch = '' ;
219
+ }
220
+ this . message = 'Searching Catalogue...'
221
+ const records = await this . fetchJson ( `./csw_records?url=${ encodeURIComponent ( catalogUrl ) } &startRecord=${ startRecord } &type=${ this . searchType } &search=${ search } ` ) ;
222
+ this . message = '' ;
130
223
if ( records && ! records . error ) {
131
224
const searchResults = records . searchResults ;
132
- this . totalRecords = searchResults . numberOfRecordsMatched ;
133
- this . startRecord = searchResults . nextRecord - searchResults . numberOfRecordsReturned ;
134
- this . endRecord = searchResults . nextRecord - 1 ;
225
+ if ( searchResults ) {
226
+ this . totalRecords = parseInt ( searchResults . numberOfRecordsMatched ) ;
227
+ this . endRecord = this . startRecord + parseInt ( searchResults . numberOfRecordsReturned ) - 1 ;
228
+ this . nextRecord = parseInt ( searchResults . nextRecord ) ;
229
+ } else {
230
+ this . totalRecords = 0 ;
231
+ this . startRecord = 1 ;
232
+ this . endRecord = 0 ;
233
+ }
135
234
const briefRecords = records . records ;
136
235
briefRecords . forEach ( record => record . englishTitle = 'Translating...' ) ;
137
236
this . briefRecords = briefRecords ;
138
237
let translatedStrings = null ;
139
238
if ( briefRecords . length > 0 ) {
140
- translatedStrings = await this . fetchJson ( './translate' , {
141
- method : 'POST' ,
142
- headers : {
143
- 'Content-Type' : 'application/json'
144
- } ,
145
- body : JSON . stringify ( {
146
- strings : briefRecords . map ( record => record . title ) ,
147
- language : this . catalogList [ this . catalogSelect . value ] . language
148
- } )
149
- } )
239
+ translatedStrings = await this . getTranslatedStrings ( briefRecords . map ( record => record . title ) , this . catalogList [ this . catalogSelect . value ] . language ) ;
150
240
}
151
241
if ( translatedStrings ) {
152
242
briefRecords . forEach ( ( record , index ) => record . englishTitle = translatedStrings [ index ] ) ;
0 commit comments