mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	Improvements to query table
This commit is contained in:
		
							
								
								
									
										7
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | # Changelog | ||||||
|  |  | ||||||
|  | ## [0.0.1-alpha]() - Coming Soon | ||||||
|  |  | ||||||
|  | ### Features | ||||||
|  |  | ||||||
|  | - **Initial release:** | ||||||
							
								
								
									
										
											BIN
										
									
								
								build/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								build/icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -8475,6 +8475,11 @@ | |||||||
|         "minimist": "^1.2.5" |         "minimist": "^1.2.5" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "moment": { | ||||||
|  |       "version": "2.26.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", | ||||||
|  |       "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" | ||||||
|  |     }, | ||||||
|     "move-concurrently": { |     "move-concurrently": { | ||||||
|       "version": "1.0.1", |       "version": "1.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", |       "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", | ||||||
|   | |||||||
| @@ -9,7 +9,8 @@ | |||||||
|     "dev": "cross-env NODE_ENV=development electron-webpack dev", |     "dev": "cross-env NODE_ENV=development electron-webpack dev", | ||||||
|     "compile": "electron-webpack", |     "compile": "electron-webpack", | ||||||
|     "dist": "cross-env NODE_ENV=production npm run compile && electron-builder", |     "dist": "cross-env NODE_ENV=production npm run compile && electron-builder", | ||||||
|     "dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null" |     "dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null", | ||||||
|  |     "publish": "build -p always" | ||||||
|   }, |   }, | ||||||
|   "author": "Fabio Di Stasio <fabio286@gmail.com>", |   "author": "Fabio Di Stasio <fabio286@gmail.com>", | ||||||
|   "build": { |   "build": { | ||||||
| @@ -33,6 +34,7 @@ | |||||||
|     "electron-updater": "^4.3.1", |     "electron-updater": "^4.3.1", | ||||||
|     "lodash": "^4.17.15", |     "lodash": "^4.17.15", | ||||||
|     "material-design-icons": "^3.0.1", |     "material-design-icons": "^3.0.1", | ||||||
|  |     "moment": "^2.26.0", | ||||||
|     "mssql": "^6.2.0", |     "mssql": "^6.2.0", | ||||||
|     "mysql": "^2.18.1", |     "mysql": "^2.18.1", | ||||||
|     "pg": "^8.2.1", |     "pg": "^8.2.1", | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								src/common/libs/hexToBinary.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/common/libs/hexToBinary.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | const lookup = { | ||||||
|  |    0: '0000', | ||||||
|  |    1: '0001', | ||||||
|  |    2: '0010', | ||||||
|  |    3: '0011', | ||||||
|  |    4: '0100', | ||||||
|  |    5: '0101', | ||||||
|  |    6: '0110', | ||||||
|  |    7: '0111', | ||||||
|  |    8: '1000', | ||||||
|  |    9: '1001', | ||||||
|  |    a: '1010', | ||||||
|  |    b: '1011', | ||||||
|  |    c: '1100', | ||||||
|  |    d: '1101', | ||||||
|  |    e: '1110', | ||||||
|  |    f: '1111', | ||||||
|  |    A: '1010', | ||||||
|  |    B: '1011', | ||||||
|  |    C: '1100', | ||||||
|  |    D: '1101', | ||||||
|  |    E: '1110', | ||||||
|  |    F: '1111' | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Converts hexadecimal string to binary string | ||||||
|  |  * | ||||||
|  |  * @param {string} hex Hexadecimal string | ||||||
|  |  * @returns {string} Binary string | ||||||
|  |  */ | ||||||
|  | export default function hexToBinary (hex) { | ||||||
|  |    let binary = ''; | ||||||
|  |    for (let i = 0, len = hex.length; i < len; i++) | ||||||
|  |       binary += lookup[hex[i]]; | ||||||
|  |  | ||||||
|  |    return binary; | ||||||
|  | } | ||||||
| @@ -1,3 +1,59 @@ | |||||||
| export function uidGen () { | export function uidGen () { | ||||||
|    return Math.random().toString(36).substr(2, 9).toUpperCase(); |    return Math.random().toString(36).substr(2, 9).toUpperCase(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | export function mimeFromHex (hex) { | ||||||
|  |    switch (hex.substring(0, 4)) { // 2 bytes | ||||||
|  |       case '424D': | ||||||
|  |          return { ext: 'bmp', mime: 'image/bmp' }; | ||||||
|  |       case '1F8B': | ||||||
|  |          return { ext: 'gz', mime: 'application/gzip' }; | ||||||
|  |       case '0B77': | ||||||
|  |          return { ext: 'ac3', mime: 'audio/vnd.dolby.dd-raw' }; | ||||||
|  |       case '7801': | ||||||
|  |          return { ext: 'dmg', mime: 'application/x-apple-diskimage' }; | ||||||
|  |       case '4D5A': | ||||||
|  |          return { ext: 'exe', mime: 'application/x-msdownload' }; | ||||||
|  |       case '1FA0': | ||||||
|  |       case '1F9D': | ||||||
|  |          return { ext: 'Z', mime: 'application/x-compress' }; | ||||||
|  |       default: | ||||||
|  |          switch (hex.substring(0, 6)) { // 3 bytes | ||||||
|  |             case 'FFD8FF': | ||||||
|  |                return { ext: 'jpj', mime: 'image/jpeg' }; | ||||||
|  |             case '4949BC': | ||||||
|  |                return { ext: 'jxr', mime: 'image/vnd.ms-photo' }; | ||||||
|  |             case '425A68': | ||||||
|  |                return { ext: 'bz2', mime: 'application/x-bzip2' }; | ||||||
|  |             default: | ||||||
|  |                switch (hex) { // 4 bites | ||||||
|  |                   case '89504E47': | ||||||
|  |                      return { ext: 'png', mime: 'image/png' }; | ||||||
|  |                   case '47494638': | ||||||
|  |                      return { ext: 'gif', mime: 'image/gif' }; | ||||||
|  |                   case '25504446': | ||||||
|  |                      return { ext: 'pdf', mime: 'application/pdf' }; | ||||||
|  |                   case '504B0304': | ||||||
|  |                      return { ext: 'zip', mime: 'application/zip' }; | ||||||
|  |                   case '425047FB': | ||||||
|  |                      return { ext: 'bpg', mime: 'image/bpg' }; | ||||||
|  |                   case '4D4D002A': | ||||||
|  |                      return { ext: 'tif', mime: 'image/tiff' }; | ||||||
|  |                   default: | ||||||
|  |                      return { ext: '???', mime: 'unknown ' + hex }; | ||||||
|  |                } | ||||||
|  |          } | ||||||
|  |    } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export function formatBytes (bytes, decimals = 2) { | ||||||
|  |    if (bytes === 0) return '0 Bytes'; | ||||||
|  |  | ||||||
|  |    const k = 1024; | ||||||
|  |    const dm = decimals < 0 ? 0 : decimals; | ||||||
|  |    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; | ||||||
|  |  | ||||||
|  |    const i = Math.floor(Math.log(bytes) / Math.log(k)); | ||||||
|  |  | ||||||
|  |    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -94,10 +94,19 @@ app.on('ready', () => { | |||||||
| }); | }); | ||||||
|  |  | ||||||
| // auto-updater events | // auto-updater events | ||||||
|  | autoUpdater.on('checking-for-update', () => { | ||||||
|  | }); | ||||||
|  |  | ||||||
| autoUpdater.on('update-available', () => { | autoUpdater.on('update-available', () => { | ||||||
|    mainWindow.webContents.send('update_available'); |    mainWindow.webContents.send('update_available'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | autoUpdater.on('update-not-available', () => { | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | autoUpdater.on('download-progress', (progressObj) => { | ||||||
|  | }); | ||||||
|  |  | ||||||
| autoUpdater.on('update-downloaded', () => { | autoUpdater.on('update-downloaded', () => { | ||||||
|    mainWindow.webContents.send('update_downloaded'); |    mainWindow.webContents.send('update_downloaded'); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -151,6 +151,7 @@ export default { | |||||||
|             background: $bg-color; |             background: $bg-color; | ||||||
|             border: 1px solid; |             border: 1px solid; | ||||||
|             border-left: none; |             border-left: none; | ||||||
|  |             border-bottom-width: 2px; | ||||||
|             border-color: $bg-color-light; |             border-color: $bg-color-light; | ||||||
|             padding: .1rem .4rem; |             padding: .1rem .4rem; | ||||||
|             font-weight: 700; |             font-weight: 700; | ||||||
|   | |||||||
| @@ -38,11 +38,11 @@ | |||||||
|                      v-for="(col, cKey) in row" |                      v-for="(col, cKey) in row" | ||||||
|                      :key="cKey" |                      :key="cKey" | ||||||
|                      class="td" |                      class="td" | ||||||
|                      :class="fieldType(col)" |                      :class="`type-${fieldType(cKey)}${isNull(col)}`" | ||||||
|                      :style="{'display': cKey === '_id'? 'none' : ''}" |                      :style="{'display': cKey === '_id' ? 'none' : ''}" | ||||||
|                      tabindex="0" |                      tabindex="0" | ||||||
|                   > |                   > | ||||||
|                      {{ col }} |                      {{ col | typeFormat(fieldType(cKey)) }} | ||||||
|                   </div> |                   </div> | ||||||
|                </div> |                </div> | ||||||
|             </div> |             </div> | ||||||
| @@ -52,7 +52,9 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
| import { uidGen } from 'common/libs/utilities'; | import { uidGen, mimeFromHex, formatBytes } from 'common/libs/utilities'; | ||||||
|  | import hexToBinary from 'common/libs/hexToBinary'; | ||||||
|  | import moment from 'moment'; | ||||||
| import BaseVirtualScroll from '@/components/BaseVirtualScroll'; | import BaseVirtualScroll from '@/components/BaseVirtualScroll'; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
| @@ -60,6 +62,37 @@ export default { | |||||||
|    components: { |    components: { | ||||||
|       BaseVirtualScroll |       BaseVirtualScroll | ||||||
|    }, |    }, | ||||||
|  |    filters: { | ||||||
|  |       typeFormat (val, type) { | ||||||
|  |          if (!val) return val; | ||||||
|  |  | ||||||
|  |          switch (type) { | ||||||
|  |             case 'char': | ||||||
|  |             case 'varchar': | ||||||
|  |             case 'text': | ||||||
|  |                return val.substring(0, 128); | ||||||
|  |             case 'date': | ||||||
|  |                return moment(val).format('YYYY-MM-DD'); | ||||||
|  |             case 'datetime': | ||||||
|  |                return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS'); | ||||||
|  |             case 'blob': | ||||||
|  |             case 'mediumblob': | ||||||
|  |             case 'longblob': { | ||||||
|  |                const buff = Buffer.from(val); | ||||||
|  |                if (!buff.length) return ''; | ||||||
|  |  | ||||||
|  |                const hex = buff.toString('hex').substring(0, 8).toUpperCase(); | ||||||
|  |                return `${mimeFromHex(hex).mime} (${formatBytes(buff.length)})`; | ||||||
|  |             } | ||||||
|  |             case 'bit': { | ||||||
|  |                const hex = Buffer.from(val).toString('hex'); | ||||||
|  |                return hexToBinary(hex); | ||||||
|  |             } | ||||||
|  |             default: | ||||||
|  |                return val; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    }, | ||||||
|    props: { |    props: { | ||||||
|       results: Object, |       results: Object, | ||||||
|       fields: Array |       fields: Array | ||||||
| @@ -88,14 +121,16 @@ export default { | |||||||
|       window.removeEventListener('resize', this.resizeResults); |       window.removeEventListener('resize', this.resizeResults); | ||||||
|    }, |    }, | ||||||
|    methods: { |    methods: { | ||||||
|       fieldType (col) { // TODO: get from fields |       fieldType (cKey) { | ||||||
|          let type = typeof col; |          let type = 'unknown'; | ||||||
|          if (type === 'object') |          const field = this.fields.filter(field => field.name === cKey)[0]; | ||||||
|             if (col instanceof Date) type = 'date'; |          if (field) | ||||||
|          if (col instanceof Uint8Array) type = 'blob'; |             type = field.type; | ||||||
|          if (col === null) type = 'null'; |  | ||||||
|  |  | ||||||
|          return `type-${type}`; |          return type; | ||||||
|  |       }, | ||||||
|  |       isNull (col) { | ||||||
|  |          return col === null ? ' is-null' : ''; | ||||||
|       }, |       }, | ||||||
|       keyName (key) { |       keyName (key) { | ||||||
|          switch (key) { |          switch (key) { | ||||||
|   | |||||||
| @@ -3,12 +3,6 @@ | |||||||
|       .type-#{$type} { |       .type-#{$type} { | ||||||
|          color: $color; |          color: $color; | ||||||
|  |  | ||||||
|          @if $type == 'null'{ |  | ||||||
|             &::after{ |  | ||||||
|                content: 'NULL'; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          @if $type == 'number'{ |          @if $type == 'number'{ | ||||||
|             text-align: right; |             text-align: right; | ||||||
|          } |          } | ||||||
| @@ -17,9 +11,32 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| @include type-colors(( | @include type-colors(( | ||||||
|    "string": seagreen, |    "char": seagreen, | ||||||
|    "number": cornflowerblue, |    "varchar": seagreen, | ||||||
|  |    "text": seagreen, | ||||||
|  |  | ||||||
|  |    "int": cornflowerblue, | ||||||
|  |    "tinyint": cornflowerblue, | ||||||
|  |    "smallint": cornflowerblue, | ||||||
|  |    "mediumint": cornflowerblue, | ||||||
|  |     | ||||||
|  |    "datetime": coral, | ||||||
|    "date": coral, |    "date": coral, | ||||||
|  |    "time": coral, | ||||||
|  |  | ||||||
|  |    "bit": lightskyblue, | ||||||
|  |     | ||||||
|    "blob": darkorchid, |    "blob": darkorchid, | ||||||
|    "null": gray, |    "mediumblob": darkorchid, | ||||||
| )) |    "longblob": darkorchid, | ||||||
|  |     | ||||||
|  |    "unknown": gray, | ||||||
|  | )); | ||||||
|  |  | ||||||
|  | .is-null{ | ||||||
|  |    color: gray; | ||||||
|  |  | ||||||
|  |    &::after{ | ||||||
|  |       content: 'NULL'; | ||||||
|  |    } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user