Skip to content
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #134 from slashbaseide/develop
Browse files Browse the repository at this point in the history
Release v0.10.1
  • Loading branch information
paraswaykole committed Aug 5, 2023
2 parents 94b9820 + de76a11 commit 3bba097
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 36 deletions.
2 changes: 1 addition & 1 deletion frontend/desktop/package.json.md5
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a24ece3a3d86e13594977247e3352385
371e648509f99cc686955a6284995fb5
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
left: 0;
}

.consoleend {
height: 100px;
}

}
56 changes: 40 additions & 16 deletions frontend/desktop/src/components/dbfragments/console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ const DBConsoleFragment = ({ }: DBConsolePropType) => {

const currentTab: Tab = useContext(TabContext)!

const consoleEndRef = useRef<HTMLSpanElement>(null)
const consoleRef = useRef<HTMLDivElement>(null)
const consoleEndRef = useRef<HTMLDivElement>(null)

const dbConnection = useAppSelector(selectDBConnection)
const output = useAppSelector(selectBlocks)
const [input, setInput] = useState("")
const [nfocus, setFocus] = useState<number>(0)
const commands = output.filter( e => e.cmd === true)
const [pointer, setPointer] = useState<number>(commands.length-1)
const history = output.filter(e => e.cmd).filter(e => e.text !== "").map(e => e.text)
useEffect(() => {
dispatch(initConsole(dbConnection!.id))
}, [dbConnection])

useEffect(() => {
consoleEndRef.current?.scrollIntoView({ behavior: 'smooth' })
scrollToBottom("smooth")
}, [output])

const confirmInput = () => {
Expand All @@ -37,21 +37,27 @@ const DBConsoleFragment = ({ }: DBConsolePropType) => {
}

const focus = (e: any) => {
if (e.target.id === "console") {
if (consoleRef.current?.contains(e.target)) {
setFocus(Math.random())
}
}

return <div className={styles.console + " " + (currentTab.isActive ? "db-tab-active" : "db-tab")} id="console" onClick={focus}>
const scrollToBottom = (behavior: ScrollBehavior) => {
const mainContentDiv = consoleRef.current?.parentNode as HTMLDivElement
if (mainContentDiv.scrollTop !== consoleEndRef.current?.offsetTop)
mainContentDiv.scrollTo({ top: consoleEndRef.current?.offsetTop, behavior })
}

return <div className={styles.console + " " + (currentTab.isActive ? "db-tab-active" : "db-tab")} id="console" ref={consoleRef} onClick={focus}>
<OutputBlock block={{
text: "Start typing command and press enter to run it.\nType 'help' for more info on console.",
cmd: false
}} />
{output.map((block, idx) => {
return <OutputBlock block={block} key={idx} />
})}
<PromptInputWithRef onChange={setInput} isActive={currentTab.isActive} nfocus={nfocus} confirmInput={confirmInput} commands={commands} pointer={pointer} setPointer={setPointer} />
<span ref={consoleEndRef}></span>
<PromptInputWithRef onChange={setInput} isActive={currentTab.isActive} nfocus={nfocus} scrollToBottom={scrollToBottom} confirmInput={confirmInput} history={history} />
<div id="consoleend" className={styles.consoleend} ref={consoleEndRef}></div>
</div>
}

Expand All @@ -66,8 +72,10 @@ const OutputBlock = ({ block }: any) => {
const PromptInputWithRef = (props: any) => {
const defaultValue = useRef("")
const inputRef = useRef<HTMLParagraphElement>(null)
const [pointer, setPointer] = useState<number>(-1)
useEffect(() => {
if (props.isActive) {
props.scrollToBottom("instant")
inputRef.current?.focus()
}
}, [props.isActive, props.nfocus])
Expand All @@ -78,8 +86,8 @@ const PromptInputWithRef = (props: any) => {
}
}

const setInputRef = ( cmd : string) => {
if(inputRef.current !== null){
const setInputRef = (cmd: string) => {
if (inputRef.current !== null) {
inputRef.current.textContent = cmd;
}
}
Expand All @@ -89,14 +97,30 @@ const PromptInputWithRef = (props: any) => {
if (inputRef.current) {
inputRef.current.innerText = ""
}
setPointer(-1)
}
const updateInputFromPointer = (newPointer: number) => {
let text = props.history.at(props.history.length - 1 - newPointer)
if (!text) {
text = ""
}
setInputRef(text)
}
if ( event.key.toLocaleLowerCase() === 'arrowup') {
props.setPointer( () => ((props.pointer + props.commands.length -1 ) % props.commands.length))
setInputRef(props.commands.at(props.pointer)?.text)
if (event.key.toLocaleLowerCase() === 'arrowup') {
if (pointer !== props.history.length - 1) {
setPointer(() => (pointer + 1))
updateInputFromPointer(pointer + 1)
}
}
if ( event.key.toLocaleLowerCase() === 'arrowdown'){
props.setPointer( () => ((props.pointer + 1 ) % props.commands.length))
setInputRef(props.commands.at(props.pointer)?.text)
if (event.key.toLocaleLowerCase() === 'arrowdown') {
let newPointer
if (pointer < 0) {
newPointer = -1
} else {
newPointer = pointer - 1
}
setPointer(newPointer)
updateInputFromPointer(newPointer)
}
}

Expand Down
3 changes: 3 additions & 0 deletions frontend/desktop/src/redux/consoleSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export const runConsoleCmd = createAsyncThunk(
async (payload: { dbConnId: string, cmdString: string }, { rejectWithValue, getState }: any) => {
const dbConnectionId = payload.dbConnId
const cmdString = payload.cmdString
if (cmdString === "") {
return rejectWithValue("empty command")
}
const result = await eventService.runConsoleCommand(dbConnectionId, cmdString)
if (result.success) {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
left: 0;
}

.consoleend {
height: 100px;
}

}
58 changes: 40 additions & 18 deletions frontend/server/src/components/dbfragments/console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,20 @@ const DBConsoleFragment = ({ }: DBConsolePropType) => {

const currentTab: Tab = useContext(TabContext)!

const consoleEndRef = useRef<HTMLSpanElement>(null)
const consoleRef = useRef<HTMLDivElement>(null)
const consoleEndRef = useRef<HTMLDivElement>(null)

const dbConnection = useAppSelector(selectDBConnection)
const output = useAppSelector(selectBlocks)
const [input, setInput] = useState("")
const [nfocus, setFocus] = useState<number>(0)
const commands = output.filter( e => e.cmd === true)
const [pointer, setPointer] = useState<number>(commands.length-1)

const history = output.filter(e => e.cmd).filter(e => e.text !== "").map(e => e.text)
useEffect(() => {
dispatch(initConsole(dbConnection!.id))
}, [dbConnection])

useEffect(() => {
consoleEndRef.current?.scrollIntoView({ behavior: 'smooth' })
scrollToBottom("smooth")
}, [output])

const confirmInput = () => {
Expand All @@ -38,21 +37,27 @@ const DBConsoleFragment = ({ }: DBConsolePropType) => {
}

const focus = (e: any) => {
if (e.target.id === "console") {
if (consoleRef.current?.contains(e.target)) {
setFocus(Math.random())
}
}

return <div className={styles.console + " " + (currentTab.isActive ? "db-tab-active" : "db-tab")} id="console" onClick={focus}>
const scrollToBottom = (behavior: ScrollBehavior) => {
const mainContentDiv = consoleRef.current?.parentNode as HTMLDivElement
if (mainContentDiv.scrollTop !== consoleEndRef.current?.offsetTop)
mainContentDiv.scrollTo({ top: consoleEndRef.current?.offsetTop, behavior })
}

return <div className={styles.console + " " + (currentTab.isActive ? "db-tab-active" : "db-tab")} id="console" ref={consoleRef} onClick={focus}>
<OutputBlock block={{
text: "Start typing command and press enter to run it.\nType 'help' for more info on console.",
cmd: false
}} />
{output.map((block, idx) => {
return <OutputBlock block={block} key={idx} />
})}
<PromptInputWithRef onChange={setInput} isActive={currentTab.isActive} nfocus={nfocus} confirmInput={confirmInput} commands={commands} pointer={pointer} setPointer={setPointer} />
<span ref={consoleEndRef}></span>
<PromptInputWithRef onChange={setInput} isActive={currentTab.isActive} nfocus={nfocus} scrollToBottom={scrollToBottom} confirmInput={confirmInput} history={history} />
<div id="consoleend" className={styles.consoleend} ref={consoleEndRef}></div>
</div>
}

Expand All @@ -68,9 +73,10 @@ const PromptInputWithRef = (props: any) => {

const defaultValue = useRef("")
const inputRef = useRef<HTMLParagraphElement>(null)

const [pointer, setPointer] = useState<number>(-1)
useEffect(() => {
if (props.isActive) {
props.scrollToBottom("instant")
inputRef.current?.focus()
}
}, [props.isActive, props.nfocus])
Expand All @@ -81,8 +87,8 @@ const PromptInputWithRef = (props: any) => {
}
}

const setInputRef = ( cmd : string) => {
if(inputRef.current !== null){
const setInputRef = (cmd: string) => {
if (inputRef.current !== null) {
inputRef.current.textContent = cmd;
}
}
Expand All @@ -92,14 +98,30 @@ const PromptInputWithRef = (props: any) => {
if (inputRef.current) {
inputRef.current.innerText = ""
}
setPointer(-1)
}
if ( event.key.toLocaleLowerCase() === 'arrowup') {
props.setPointer( () => ((props.pointer + props.commands.length -1 ) % props.commands.length))
setInputRef(props.commands.at(props.pointer)?.text)
const updateInputFromPointer = (newPointer: number) => {
let text = props.history.at(props.history.length - 1 - newPointer)
if (!text) {
text = ""
}
setInputRef(text)
}
if (event.key.toLocaleLowerCase() === 'arrowup') {
if (pointer !== props.history.length - 1) {
setPointer(() => (pointer + 1))
updateInputFromPointer(pointer + 1)
}
}
if ( event.key.toLocaleLowerCase() === 'arrowdown'){
props.setPointer( () => ((props.pointer + 1 ) % props.commands.length))
setInputRef(props.commands.at(props.pointer)?.text)
if (event.key.toLocaleLowerCase() === 'arrowdown') {
let newPointer
if (pointer < 0) {
newPointer = -1
} else {
newPointer = pointer - 1
}
setPointer(newPointer)
updateInputFromPointer(newPointer)
}
}

Expand Down
4 changes: 4 additions & 0 deletions internal/common/analytics/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ func SendLowCodeModelViewEvent() {
func SendUpdatedTelemetryEvent(value bool) {
sendEvent("Updated Telemetry Settings", map[string]interface{}{"value": value})
}

func SendAISQLGeneratedEvent() {
sendEvent("AI SQL Generated", map[string]interface{}{})
}
2 changes: 2 additions & 0 deletions internal/desktop/events/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package events
import (
"context"

"github.com/slashbaseide/slashbase/internal/common/analytics"
"github.com/slashbaseide/slashbase/internal/common/controllers"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
Expand All @@ -21,6 +22,7 @@ func (AIEventListeners) GenSQLEvent(ctx context.Context) {
defer recovery(ctx, responseEventName)
dbConnectionId := args[1].(string)
text := args[2].(string)
analytics.SendAISQLGeneratedEvent()
output, err := aiController.GenerateSQL(dbConnectionId, text)
if err != nil {
runtime.EventsEmit(ctx, responseEventName, map[string]interface{}{
Expand Down
2 changes: 2 additions & 0 deletions internal/server/handlers/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package handlers

import (
"github.com/gofiber/fiber/v2"
"github.com/slashbaseide/slashbase/internal/common/analytics"
"github.com/slashbaseide/slashbase/internal/common/controllers"
)

Expand All @@ -20,6 +21,7 @@ func (AIHandlers) GenerateSQL(c *fiber.Ctx) error {
"error": err.Error(),
})
}
analytics.SendAISQLGeneratedEvent()
output, err := aiController.GenerateSQL(body.DBConnectionID, body.Text)
if err != nil {
return c.JSON(map[string]interface{}{
Expand Down
2 changes: 1 addition & 1 deletion wails.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"info": {
"productName": "Slashbase",
"productVersion": "v0.10.0",
"productVersion": "v0.10.1",
"copyright": "Copyright © Slashbase.com",
"comments": "Open-source Modern database IDE"
}
Expand Down

0 comments on commit 3bba097

Please sign in to comment.