11// Copyright © 2024, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
3- import { Uri } from "vscode" ;
3+ import { Uri , l10n } from "vscode" ;
44
55import { Column } from "../connection/rest/api/compute" ;
66import { TableInfo } from "../connection/rest/api/compute" ;
@@ -18,115 +18,44 @@ class TablePropertiesViewer extends WebView {
1818 }
1919
2020 public render ( ) : WebView {
21- this . panel . webview . html = this . getContent ( ) ;
21+ const policies = [
22+ `default-src 'none';` ,
23+ `font-src ${ this . panel . webview . cspSource } data:;` ,
24+ `img-src ${ this . panel . webview . cspSource } data:;` ,
25+ `script-src ${ this . panel . webview . cspSource } ;` ,
26+ `style-src ${ this . panel . webview . cspSource } ;` ,
27+ ] ;
28+ this . panel . webview . html = this . getContent ( policies ) ;
2229 return this ;
2330 }
2431
2532 public processMessage ( ) : void {
2633 // No messages to process for this static viewer
2734 }
2835
29- public getContent ( ) : string {
36+ public getContent ( policies : string [ ] ) : string {
3037 return `
3138 <!DOCTYPE html>
3239 <html lang="en">
3340 <head>
3441 <meta charset="UTF-8">
3542 <meta name="viewport" content="width=device-width, initial-scale=1.0">
36- <title>Table Properties</title>
37- <style>
38- body {
39- font-family: var(--vscode-font-family);
40- font-size: var(--vscode-font-size);
41- font-weight: var(--vscode-font-weight);
42- color: var(--vscode-foreground);
43- background-color: var(--vscode-editor-background);
44- margin: 0;
45- padding: 16px;
46- }
47-
48- .container {
49- max-width: 1200px;
50- margin: 0 auto;
51- }
52-
53- .tabs {
54- display: flex;
55- border-bottom: 1px solid var(--vscode-panel-border);
56- margin-bottom: 16px;
57- }
58-
59- .tab {
60- padding: 10px 20px;
61- cursor: pointer;
62- border: none;
63- background: none;
64- color: var(--vscode-foreground);
65- border-bottom: 2px solid transparent;
66- font-family: inherit;
67- font-size: inherit;
68- }
69-
70- .tab:hover {
71- background-color: var(--vscode-list-hoverBackground);
72- }
73-
74- .tab.active {
75- border-bottom-color: var(--vscode-focusBorder);
76- color: var(--vscode-tab-activeForeground);
77- }
78-
79- .tab-content {
80- display: none;
81- padding: 20px 0;
82- }
83-
84- .tab-content.active {
85- display: block;
86- }
87-
88- .properties-table {
89- width: 100%;
90- border-collapse: collapse;
91- margin-bottom: 16px;
92- }
93-
94- .properties-table th,
95- .properties-table td {
96- border: 1px solid var(--vscode-panel-border);
97- padding: 8px 12px;
98- text-align: left;
99- }
100-
101- .properties-table th {
102- background-color: var(--vscode-list-hoverBackground);
103- font-weight: bold;
104- }
105-
106- .properties-table tr:nth-child(even) {
107- background-color: var(--vscode-list-hoverBackground);
108- }
109-
110- .property-label {
111- font-weight: bold;
112- min-width: 200px;
113- }
114-
115- .section-title {
116- font-size: 1.2em;
117- font-weight: bold;
118- margin: 20px 0 10px 0;
119- color: var(--vscode-foreground);
120- }
121- </style>
43+ <meta http-equiv="Content-Security-Policy" content="${ policies . join (
44+ " " ,
45+ ) } " />
46+ <link rel="stylesheet" href="${ this . webviewUri (
47+ this . extensionUri ,
48+ "TablePropertiesViewer.css" ,
49+ ) } ">
50+ <title>${ l10n . t ( "Table Properties" ) } </title>
12251 </head>
12352 <body>
12453 <div class="container">
125- <h1>Table: ${ this . tableName } </h1>
54+ <h1>${ l10n . t ( " Table: {tableName}" , { tableName : this . tableName } ) } </h1>
12655
12756 <div class="tabs">
128- <button class="tab active" onclick="showTab(' properties')"> General</button>
129- <button class="tab" onclick="showTab(' columns')"> Columns</button>
57+ <button class="tab active" data-tab=" properties"> ${ l10n . t ( " General" ) } </button>
58+ <button class="tab" data-tab=" columns"> ${ l10n . t ( " Columns" ) } </button>
13059 </div>
13160
13261 <div id="properties" class="tab-content active">
@@ -138,23 +67,10 @@ class TablePropertiesViewer extends WebView {
13867 </div>
13968 </div>
14069
141- <script>
142- function showTab(tabName) {
143- // Hide all tab contents
144- const contents = document.querySelectorAll('.tab-content');
145- contents.forEach(content => content.classList.remove('active'));
146-
147- // Remove active class from all tabs
148- const tabs = document.querySelectorAll('.tab');
149- tabs.forEach(tab => tab.classList.remove('active'));
150-
151- // Show selected tab content
152- document.getElementById(tabName).classList.add('active');
153-
154- // Add active class to clicked tab
155- event.target.classList.add('active');
156- }
157- </script>
70+ <script type="module" src="${ this . webviewUri (
71+ this . extensionUri ,
72+ "TablePropertiesViewer.js" ,
73+ ) } "></script>
15874 </body>
15975 </html>
16076 ` ;
@@ -183,78 +99,78 @@ class TablePropertiesViewer extends WebView {
18399 } ;
184100
185101 return `
186- <div class="section-title">General Information</div>
102+ <div class="section-title">${ l10n . t ( " General Information" ) } </div>
187103 <table class="properties-table">
188104 <tr>
189- <td class="property-label">Name</td>
105+ <td class="property-label">${ l10n . t ( " Name" ) } </td>
190106 <td>${ formatValue ( this . tableInfo . name ) } </td>
191107 </tr>
192108 <tr>
193- <td class="property-label">Library</td>
109+ <td class="property-label">${ l10n . t ( " Library" ) } </td>
194110 <td>${ formatValue ( this . tableInfo . libref ) } </td>
195111 </tr>
196112 <tr>
197- <td class="property-label">Type</td>
113+ <td class="property-label">${ l10n . t ( " Type" ) } </td>
198114 <td>${ formatValue ( this . tableInfo . type ) } </td>
199115 </tr>
200116 <tr>
201- <td class="property-label">Label</td>
117+ <td class="property-label">${ l10n . t ( " Label" ) } </td>
202118 <td>${ formatValue ( this . tableInfo . label ) } </td>
203119 </tr>
204120 <tr>
205- <td class="property-label">Engine</td>
121+ <td class="property-label">${ l10n . t ( " Engine" ) } </td>
206122 <td>${ formatValue ( this . tableInfo . engine ) } </td>
207123 </tr>
208124 <tr>
209- <td class="property-label">Extended Type</td>
125+ <td class="property-label">${ l10n . t ( " Extended Type" ) } </td>
210126 <td>${ formatValue ( this . tableInfo . extendedType ) } </td>
211127 </tr>
212128 </table>
213129
214- <div class="section-title">Size Information</div>
130+ <div class="section-title">${ l10n . t ( " Size Information" ) } </div>
215131 <table class="properties-table">
216132 <tr>
217- <td class="property-label">Number of Rows</td>
133+ <td class="property-label">${ l10n . t ( " Number of Rows" ) } </td>
218134 <td>${ formatValue ( this . tableInfo . rowCount ) } </td>
219135 </tr>
220136 <tr>
221- <td class="property-label">Number of Columns</td>
137+ <td class="property-label">${ l10n . t ( " Number of Columns" ) } </td>
222138 <td>${ formatValue ( this . tableInfo . columnCount ) } </td>
223139 </tr>
224140 <tr>
225- <td class="property-label">Logical Record Count</td>
141+ <td class="property-label">${ l10n . t ( " Logical Record Count" ) } </td>
226142 <td>${ formatValue ( this . tableInfo . logicalRecordCount ) } </td>
227143 </tr>
228144 <tr>
229- <td class="property-label">Physical Record Count</td>
145+ <td class="property-label">${ l10n . t ( " Physical Record Count" ) } </td>
230146 <td>${ formatValue ( this . tableInfo . physicalRecordCount ) } </td>
231147 </tr>
232148 <tr>
233- <td class="property-label">Record Length</td>
149+ <td class="property-label">${ l10n . t ( " Record Length" ) } </td>
234150 <td>${ formatValue ( this . tableInfo . recordLength ) } </td>
235151 </tr>
236152 </table>
237153
238- <div class="section-title">Technical Information</div>
154+ <div class="section-title">${ l10n . t ( " Technical Information" ) } </div>
239155 <table class="properties-table">
240156 <tr>
241- <td class="property-label">Created</td>
157+ <td class="property-label">${ l10n . t ( " Created" ) } </td>
242158 <td>${ formatDate ( this . tableInfo . creationTimeStamp ) } </td>
243159 </tr>
244160 <tr>
245- <td class="property-label">Modified</td>
161+ <td class="property-label">${ l10n . t ( " Modified" ) } </td>
246162 <td>${ formatDate ( this . tableInfo . modifiedTimeStamp ) } </td>
247163 </tr>
248164 <tr>
249- <td class="property-label">Compression</td>
165+ <td class="property-label">${ l10n . t ( " Compression" ) } </td>
250166 <td>${ formatValue ( this . tableInfo . compressionRoutine ) } </td>
251167 </tr>
252168 <tr>
253- <td class="property-label">Character Encoding</td>
169+ <td class="property-label">${ l10n . t ( " Character Encoding" ) } </td>
254170 <td>${ formatValue ( this . tableInfo . encoding ) } </td>
255171 </tr>
256172 <tr>
257- <td class="property-label">Bookmark Length</td>
173+ <td class="property-label">${ l10n . t ( " Bookmark Length" ) } </td>
258174 <td>${ formatValue ( this . tableInfo . bookmarkLength ) } </td>
259175 </tr>
260176 </table>
@@ -286,17 +202,17 @@ class TablePropertiesViewer extends WebView {
286202 . join ( "" ) ;
287203
288204 return `
289- <div class="section-title">Columns (${ this . columns . length } ) </div>
205+ <div class="section-title">${ l10n . t ( " Columns ({count})" , { count : this . columns . length } ) } </div>
290206 <table class="properties-table">
291207 <thead>
292208 <tr>
293- <th># </th>
294- <th>Name</th>
295- <th>Type</th>
296- <th>Length</th>
297- <th>Format</th>
298- <th>Informat</th>
299- <th>Label</th>
209+ <th>${ l10n . t ( "#" ) } </th>
210+ <th>${ l10n . t ( " Name" ) } </th>
211+ <th>${ l10n . t ( " Type" ) } </th>
212+ <th>${ l10n . t ( " Length" ) } </th>
213+ <th>${ l10n . t ( " Format" ) } </th>
214+ <th>${ l10n . t ( " Informat" ) } </th>
215+ <th>${ l10n . t ( " Label" ) } </th>
300216 </tr>
301217 </thead>
302218 <tbody>
0 commit comments