Skip to content

Commit

Permalink
Merge pull request #735 from antares-sql/feat/new-scratchpad
Browse files Browse the repository at this point in the history
Feat/new scratchpad
  • Loading branch information
Fabio286 authored Dec 25, 2023
2 parents b734b24 + 532002c commit 88ec71c
Show file tree
Hide file tree
Showing 23 changed files with 1,178 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-e2e-win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Test end-to-end [WINDOWS]
on:
push:
branches:
- master
- develop

jobs:
release:
Expand Down
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
"source-map-support": "~0.5.20",
"spectre.css": "~0.5.9",
"sql-formatter": "~13.0.0",
"sql-highlight": "~4.4.0",
"v-mask": "~2.3.0",
"vue": "~3.3.4",
"vue-i18n": "~9.2.2",
Expand Down
1 change: 1 addition & 0 deletions scripts/devRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ function startRenderer (callback) {

const server = new WebpackDevServer(compiler, {
port: 9080,
hot: true,
client: {
overlay: true,
logging: 'warn'
Expand Down
1 change: 0 additions & 1 deletion src/renderer/components/BaseSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ export default defineComponent({
if (props.searchable)
searchInput.value.focus();
else
el.value.focus();
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/BaseVirtualScroll.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const updateWindow = () => {
const totalScrollHeight = props.items.length * props.itemHeight;
const offset = 50;
const scrollTop = localScrollElement.value.scrollTop;
const scrollTop = localScrollElement.value?.scrollTop;
const firstVisibleIndex = Math.floor(scrollTop / props.itemHeight);
const lastVisibleIndex = firstVisibleIndex + visibleItemsCount;
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/components/ModalAllConnections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,14 @@
/>
SSH
</div>
<div v-if="connection.readonly" class="chip bg-success mt-2">
<BaseIcon
icon-name="mdiLock"
class="mr-1"
:size="18"
/>
Read-only
</div>
</div>
</div>
</div>
Expand Down
18 changes: 15 additions & 3 deletions src/renderer/components/ModalHistory.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<code
class="cut-text"
:title="query.sql"
v-html="highlightWord(query.sql)"
v-html="highlight(highlightWord(query.sql), {html: true})"
/>
</div>
<div class="tile-bottom-content">
Expand Down Expand Up @@ -126,7 +126,19 @@

<script setup lang="ts">
import { ConnectionParams } from 'common/interfaces/antares';
import { Component, computed, ComputedRef, onBeforeUnmount, onMounted, onUpdated, Prop, Ref, ref, watch } from 'vue';
import { highlight } from 'sql-highlight';
import {
Component,
computed,
ComputedRef,
onBeforeUnmount,
onMounted,
onUpdated,
Prop,
Ref,
ref,
watch
} from 'vue';
import { useI18n } from 'vue-i18n';
import BaseIcon from '@/components/BaseIcon.vue';
Expand Down Expand Up @@ -163,7 +175,7 @@ const localSearchTerm = ref('');
const connectionName = computed(() => getConnectionName(props.connection.uid));
const history: ComputedRef<HistoryRecord[]> = computed(() => (getHistoryByWorkspace(props.connection.uid) || []));
const filteredHistory = computed(() => history.value.filter(q => q.sql.toLowerCase().search(searchTerm.value.toLowerCase()) >= 0));
const filteredHistory = computed(() => history.value.filter(q => q.sql.toLowerCase().search(localSearchTerm.value.toLowerCase()) >= 0));
watch(searchTerm, () => {
clearTimeout(searchTermInterval.value);
Expand Down
120 changes: 120 additions & 0 deletions src/renderer/components/ModalNoteEdit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<template>
<ConfirmModal
size="medium"
:disable-autofocus="true"
:close-on-confirm="!!localNote.note.length"
:confirm-text="t('general.save')"
@confirm="updateNote"
@hide="$emit('hide')"
>
<template #header>
<div class="d-flex">
<BaseIcon
icon-name="mdiNoteEditOutline"
class="mr-1"
:size="24"
/> {{ t('application.editNote') }}
</div>
</template>
<template #body>
<form class="form">
<div class="form-group columns">
<div class="column col-8">
<label class="form-label">{{ t('connection.connection') }}</label>
<BaseSelect
v-model="localNote.cUid"
class="form-select"
:options="connectionOptions"
option-track-by="code"
option-label="name"
@change="null"
/>
</div>
<div class="column col-4">
<label class="form-label">{{ t('application.tag') }}</label>
<BaseSelect
v-model="localNote.type"
class="form-select"
:options="noteTags"
option-track-by="code"
option-label="name"
@change="null"
/>
</div>
</div>
<div class="form-group">
<label class="form-label">{{ t('general.content') }} <small
v-if="localNote.type !== 'query'"
style="line-height: 1;"
class="text-gray"
>({{ t('application.markdownSupported') }})</small></label>
<BaseTextEditor
v-model="localNote.note"
:mode="editorMode"
:show-line-numbers="false"
/>
</div>
</form>
</template>
</ConfirmModal>
</template>

<script lang="ts" setup>
import { inject, onBeforeMount, PropType, Ref, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import ConfirmModal from '@/components/BaseConfirmModal.vue';
import BaseIcon from '@/components/BaseIcon.vue';
import BaseSelect from '@/components/BaseSelect.vue';
import BaseTextEditor from '@/components/BaseTextEditor.vue';
import { ConnectionNote, TagCode, useScratchpadStore } from '@/stores/scratchpad';
const { t } = useI18n();
const { editNote } = useScratchpadStore();
const emit = defineEmits(['hide']);
const props = defineProps({
note: {
type: Object as PropType<ConnectionNote>,
required: true
}
});
const noteTags = inject<{code: TagCode; name: string}[]>('noteTags');
const connectionOptions = inject<{code: string; name: string}[]>('connectionOptions');
const editorMode = ref('markdown');
const localNote: Ref<ConnectionNote> = ref({
uid: 'dummy',
cUid: null,
title: undefined,
note: '',
date: new Date(),
type: 'note',
isArchived: false
});
const updateNote = () => {
if (localNote.value.note) {
if (!localNote.value.title)// Set a default title
localNote.value.title = `${localNote.value.type.toLocaleUpperCase()}: ${localNote.value.uid}`;
localNote.value.date = new Date();
editNote(localNote.value);
emit('hide');
}
};
watch(() => localNote.value.type, () => {
if (localNote.value.type === 'query')
editorMode.value = 'sql';
else
editorMode.value = 'markdown';
});
onBeforeMount(() => {
localNote.value = JSON.parse(JSON.stringify(props.note));
});
</script>
118 changes: 118 additions & 0 deletions src/renderer/components/ModalNoteNew.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<template>
<ConfirmModal
size="medium"
:disable-autofocus="true"
:close-on-confirm="!!newNote.note.length"
:confirm-text="t('general.save')"
@confirm="createNote"
@hide="$emit('hide')"
>
<template #header>
<div class="d-flex">
<BaseIcon
icon-name="mdiNotePlusOutline"
class="mr-1"
:size="24"
/> {{ t('application.addNote') }}
</div>
</template>
<template #body>
<form class="form">
<div class="form-group columns">
<div class="column col-8">
<label class="form-label">{{ t('connection.connection') }}</label>
<BaseSelect
v-model="newNote.cUid"
class="form-select"
:options="connectionOptions"
option-track-by="code"
option-label="name"
@change="null"
/>
</div>
<div class="column col-4">
<label class="form-label">{{ t('application.tag') }}</label>
<BaseSelect
v-model="newNote.type"
class="form-select"
:options="noteTags"
option-track-by="code"
option-label="name"
@change="null"
/>
</div>
</div>
<div class="form-group">
<label class="form-label">{{ t('general.content') }} <small
v-if="newNote.type !== 'query'"
style="line-height: 1;"
class="text-gray"
>({{ t('application.markdownSupported') }})</small></label>
<BaseTextEditor
v-model="newNote.note"
:mode="editorMode"
:show-line-numbers="false"
/>
</div>
</form>
</template>
</ConfirmModal>
</template>

<script lang="ts" setup>
import { uidGen } from 'common/libs/uidGen';
import { inject, Ref, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import ConfirmModal from '@/components/BaseConfirmModal.vue';
import BaseIcon from '@/components/BaseIcon.vue';
import BaseSelect from '@/components/BaseSelect.vue';
import BaseTextEditor from '@/components/BaseTextEditor.vue';
import { ConnectionNote, TagCode, useScratchpadStore } from '@/stores/scratchpad';
const { t } = useI18n();
const { addNote } = useScratchpadStore();
const emit = defineEmits(['hide']);
const noteTags = inject<{code: TagCode; name: string}[]>('noteTags');
const selectedConnection = inject<Ref<null | string>>('selectedConnection');
const selectedTag = inject<Ref<TagCode>>('selectedTag');
const connectionOptions = inject<{code: string; name: string}[]>('connectionOptions');
const editorMode = ref('markdown');
const newNote: Ref<ConnectionNote> = ref({
uid: uidGen('N'),
cUid: null,
title: undefined,
note: '',
date: new Date(),
type: 'note',
isArchived: false
});
const createNote = () => {
if (newNote.value.note) {
if (!newNote.value.title)// Set a default title
newNote.value.title = `${newNote.value.type.toLocaleUpperCase()}: ${newNote.value.uid}`;
newNote.value.date = new Date();
addNote(newNote.value);
emit('hide');
}
};
watch(() => newNote.value.type, () => {
if (newNote.value.type === 'query')
editorMode.value = 'sql';
else
editorMode.value = 'markdown';
});
newNote.value.cUid = selectedConnection.value;
if (selectedTag.value !== 'all')
newNote.value.type = selectedTag.value;
</script>
Loading

0 comments on commit 88ec71c

Please sign in to comment.