Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions custom_modules/main/pty.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,22 @@ class Pty {
throw 0

// Add the received data to the variable
instance.allOutput += minifyText(data)
instance.allOutput += minifyText(data, false)

// If any of the keywords have been found
if ((['KEYWORD:OUTPUT:COMPLETED:ALL', 'KEYWORD:CQLSH:STARTED', 'cqlsh>']).some((keyword) => instance.allOutput.indexOf(minifyText(keyword)) != -1)) {
if ((['KEYWORD:OUTPUT:COMPLETED:ALL', 'KEYWORD:CQLSH:STARTED', 'cqlsh>']).some((keyword) => instance.allOutput.indexOf(minifyText(keyword, false)) != -1)) {
let loggedInUsername = ''

try {
loggedInUsername = instance.allOutput.match(/KEYWORD\:USERNAME\:\[(.*?)\]/i)[1]
} catch (e) {}

// Add the ignore keyword
instance.allOutput = 'ignore-text'

// Send the `started` keyword to the renderer thread
return instance[instance.windowBackground != null ? 'windowBackground' : 'window'].webContents.send(`pty:data:${instance.id}`, {
output: 'KEYWORD:CQLSH:STARTED'
output: (`${loggedInUsername}`.length != 0 ? (OS.EOL + `KEYWORD:USERNAME:[${loggedInUsername}] `) : '') + 'KEYWORD:CQLSH:STARTED'
})
}
} catch (e) {
Expand Down Expand Up @@ -1282,7 +1288,7 @@ let cleanCommand = (command) => {
*
* @Return: {string} the manipulated text
*/
let minifyText = (text) => {
let minifyText = (text, toLowerCase = true) => {
// Define the regex expression to be created
let regexs = ['\\n', '\\r']

Expand All @@ -1296,7 +1302,10 @@ let minifyText = (text) => {
})

// Call the text manipulation function
text = `${text}`.replace(/\s+/gm, '').toLowerCase()
text = `${text}`.replace(/\s+/gm, '')

if (toLowerCase)
text = `${text}`.toLowerCase()

// Return final result
return text
Expand Down
19 changes: 18 additions & 1 deletion custom_modules/renderer/connections.js
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,21 @@ let getPrePostScripts = async (workspaceID, connectionID = null) => {
}
}

let ignoredConnections = [],
watchConnectionPath = (connectionID, connectionPath, callback) => {
if (Modules.Connections.ignoredConnections.includes(connectionID)) {
Modules.Connections.ignoredConnections = Modules.Connections.ignoredConnections.filter((id) => id != connectionID)
return
}

setTimeout(() => {
if (!pathIsAccessible(connectionPath, false))
return callback()

watchConnectionPath(connectionID, connectionPath, callback)
}, getRandom.numberInterval(1000, 10000))
}

module.exports = {
// Main connection's operations
getConnections,
Expand All @@ -1859,5 +1874,7 @@ module.exports = {
getSnapshots,
getNewestSnapshot,
executeScript,
getPrePostScripts
getPrePostScripts,
ignoredConnections,
watchConnectionPath
}
19 changes: 18 additions & 1 deletion custom_modules/renderer/workspaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,27 @@ let deleteWorkspace = async (workspace, workspaces, keepFiles = false) => {
}
}

let ignoredWorkspaces = [],
watchWorkspacePath = (workspaceID, workspacePath, callback) => {
if (Modules.Workspaces.ignoredWorkspaces.includes(workspaceID)) {
Modules.Workspaces.ignoredWorkspaces = Modules.Workspaces.ignoredWorkspaces.filter((id) => id != workspaceID)
return
}

setTimeout(() => {
if (!pathIsAccessible(workspacePath, false))
return callback()

watchWorkspacePath(workspaceID, workspacePath, callback)
}, getRandom.numberInterval(1000, 10000))
}

module.exports = {
getWorkspaces,
getWorkspacesNoAsync,
saveWorkspace,
updateWorkspace,
deleteWorkspace
deleteWorkspace,
ignoredWorkspaces,
watchWorkspacePath
}
Binary file modified data/credits.db
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/black.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/bold.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/extrabold.ttf
Binary file not shown.
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/light.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/medium.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/regular.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/semibold.ttf
Binary file not shown.
Binary file added renderer/assets/fonts/vazirmatn/thin.ttf
Binary file not shown.
6 changes: 6 additions & 0 deletions renderer/js/background_processes.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ $(document).ready(() => IPCRenderer.on('extra-resources-path', (_, path) => {
// Catch any occurred error
result.error = e.toString()

if (minifyText(result.error).includes('connectionrefused'))
result.error = `${result.error}. Ensure that Cassandra is up and running, then start taking additional steps if the error persists`

// Send the creation result to the main thread
IPCRenderer.send(`ssh-tunnel:create:result:${data.requestID}`, {
...result,
Expand All @@ -339,6 +342,9 @@ $(document).ready(() => IPCRenderer.on('extra-resources-path', (_, path) => {
// Catch any occurred error
result.error = e.toString()

if (minifyText(result.error).includes('connectionrefused'))
result.error = `${result.error}. Ensure that Cassandra is up and running, then start taking additional steps if the error persists`

// Send the creation result to the main thread
IPCRenderer.send(`ssh-tunnel:create:result:${data.requestID}`, {
...result,
Expand Down
82 changes: 78 additions & 4 deletions renderer/js/events/connections/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,15 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
scbFilePath = `data-scb-path="${connection.info.secureConnectionBundlePath}"`
} catch (e) {}

let inAccessible = false

try {
inAccessible = !pathIsAccessible(Path.join(getWorkspaceFolderPath(workspaceID), getAttributes($(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`), 'data-folder')))
} catch (e) {}

// Connection UI element structure
let element = `
<div class="connection" data-name="${connection.name}" data-folder="${connection.folder}" data-id="${connectionID}" data-workspace-id="${workspaceID}" data-host="${connection.host}" data-datacenter="${connection.info.datacenter}" data-connected="false" data-is-sandbox="${isSandbox}" data-axonops-installed="${connection.axonops || 'unknown'}" data-workarea="false" ${secrets} ${credentials} ${scbFilePath} ${axonOpsIntegration} ${axonOpsIntegration.length != 0 ? 'axonops-integration="true"' : ''}>
<div class="connection ${inAccessible ? 'inaccessible' : ''}" data-name="${connection.name}" data-folder="${connection.folder}" data-id="${connectionID}" data-workspace-id="${workspaceID}" data-host="${connection.host}" data-datacenter="${connection.info.datacenter}" data-connected="false" data-is-sandbox="${isSandbox}" data-axonops-installed="${connection.axonops || 'unknown'}" data-workarea="false" ${secrets} ${credentials} ${scbFilePath} ${axonOpsIntegration} ${axonOpsIntegration.length != 0 ? 'axonops-integration="true"' : ''}>
<div class="header">
<div class="title connection-name">${connection.name}</div>
<div class="connection-info" ${isSCBConnection ? 'style="flex-direction: column; flex-wrap: nowrap; justify-content: flex-start; align-items: flex-start;"' : ''}>
Expand All @@ -306,7 +312,7 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
<div class="text">${connection.host}</div>
<div class="_placeholder" hidden></div>
</div>
<div class="info" info="cassandra">
<div class="info" info="cassandra" ${isSandbox ? 'style="min-width: fit-content;"' : ''}>
<div class="title">cassandra
<ion-icon name="right-arrow-filled"></ion-icon>
</div>
Expand All @@ -325,6 +331,9 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
${managementTool}
</div>
</div>
<div class="path-inaccessible" data-tippy="tooltip" data-mdb-placement="bottom" data-title data-mulang="the main folder for this connection has become inaccessible. Click the icon to copy its path" capitalize-first>
<ion-icon name="danger"></ion-icon>
</div>
${!isSandbox ? footerStructure.nonSandbox : footerStructure.sandbox}
<div class="status">
<l-ripples size="20" speed="7" color="#ff8000"></l-ripples>
Expand All @@ -342,7 +351,25 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
</div>
</div>`


try {
setTimeout(() => {
$(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`).toggleClass('inaccessible', inAccessible)

try {
if ($(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`).hasClass('is-being-watched'))
throw 0

$(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`).addClass('is-being-watched')

Modules.Connections.watchConnectionPath(connectionID, Path.join(getWorkspaceFolderPath(workspaceID), getAttributes($(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`), 'data-folder')), () => {
$(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`).removeClass('is-being-watched')

$(`div.connection[data-id="${connectionID}"][data-workspace-id="${workspaceID}"]`).addClass('inaccessible')
})
} catch (e) {}
})

// If the current connection won't be appended then skip this try-catch block
if (!isAppendAllowed)
throw 0
Expand Down Expand Up @@ -767,9 +794,16 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
<div class="text no-select-reverse"></div>
<div class="_placeholder" style="width: 50px;"></div>
</div>
<div class="info" info="cassandra-username">
<div class="title">username
<ion-icon name="right-arrow-filled"></ion-icon>
</div>
<div class="text no-select-reverse"></div>
<div class="_placeholder" style="width: 50px;"></div>
</div>
</div>
</div>
<div class="connection-metadata loading" ${isSCBConnection ? 'style="height: calc(100% - 196px);"' : ''}>
<div class="connection-metadata loading" ${isSCBConnection ? 'style="height: calc(100% - 217px);"' : ''}>
<div class="search-in-metadata">
<div class="form-outline form-white margin-bottom">
<input type="text" class="form-control form-icon-trailing form-control-sm">
Expand Down Expand Up @@ -2069,7 +2103,8 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
detectedSessionsID = [],
// Flag to tell if an empty line has been found or not
isEmptyLineFound = false,
isConnectionLost = false
isConnectionLost = false,
loggedInUsername = ''

try {
IPCRenderer.removeAllListeners(`pty:data:${connectionID}`)
Expand Down Expand Up @@ -2178,6 +2213,23 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
}, 1000)
}, 1000)

try {
loggedInUsername = allOutput.match(/KEYWORD\:USERNAME\:\[(.*?)\]/i)[1]
} catch (e) {}

{
let cassandraUsernameInfoElement = workareaElement.find('div.connection-info').find('div.info[info="cassandra-username"]')

try {
if (loggedInUsername == undefined || `${loggedInUsername}`.length <= 0)
throw 0

cassandraUsernameInfoElement.children('div._placeholder').hide()

cassandraUsernameInfoElement.children('div.text').text(`${loggedInUsername}`)
} catch (e) {}
}

// Remove the loading class
workareaElement.find(`div.tab-pane[tab="cqlsh-session"]#_${cqlshSessionContentID}`).removeClass('loading')

Expand Down Expand Up @@ -8742,6 +8794,28 @@ $(document).on('getConnections refreshConnections', function(e, passedData) {
$(this).find('ion-icon.status').attr('name', !isAxonOpsIntegrationEnabled ? 'check' : 'close')
})

$(this).find('div.path-inaccessible').click(function() {
try {
let inaccessibleConnectionPath = Path.join(getWorkspaceFolderPath(workspaceID), getAttributes(connectionElement, 'data-folder'))

if (inaccessibleConnectionPath.length <= 0)
throw 0

// Copy the path to the clipboard
try {
Clipboard.writeText(inaccessibleConnectionPath)
} catch (e) {
try {
errorLog(e, 'connections')
} catch (e) {}
}

showToast(I18next.capitalize(I18next.t('inaccessible path')), I18next.capitalizeFirstLetter(I18next.t('the path has been copied to the clipboard. Once it becomes accessible again, click the refresh button to update the connection status')) + '.', 'success')
} catch (e) {
showToast(I18next.capitalize(I18next.t('inaccessible path')), I18next.capitalizeFirstLetter(I18next.t('something went wrong, failed to get the inaccessible path')) + '.', 'failure')
}
})

// Clicks the process termination button
$(`div.btn[button-id="${terminateProcessBtnID}"]`).click(() => {
// Disable this button while processing
Expand Down
Loading