Skip to content

Commit

Permalink
Merge pull request #200 from dejan/lockon
Browse files Browse the repository at this point in the history
Implement pin feature
  • Loading branch information
dejan authored Apr 27, 2024
2 parents 339db6e + 55dd9dd commit 076f173
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 15 deletions.
17 changes: 11 additions & 6 deletions extension/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
import Requests from './components/Requests.vue'
import { fakeEvents } from './fixtures/fakeEvents'
import { useEventsStore } from './stores/events';
import { useSettingsStore } from './stores/settings';
import { onMounted, onUnmounted, nextTick } from 'vue'
const store = useEventsStore()
const eventsStore = useEventsStore();
const settingsStore = useSettingsStore();
onUnmounted(() => store.clear())
onUnmounted(() => eventsStore.clear());
onMounted(() => {
if (typeof chrome.devtools == 'undefined') {
console.log("STANDALONE mode... mocking requests")
fakeEvents.forEach((data) => store.pushEvents(data.request_id, data.events));
console.log("STANDALONE mode... mocking requests");
fakeEvents.forEach((data) => eventsStore.pushEvents(data.request_id, data.events));
} else {
chrome.devtools.network.onRequestFinished.addListener(function(request) {
var headers = request.response.headers;
Expand All @@ -28,9 +30,12 @@ onMounted(() => {
url.search = "";
console.log(url)
chrome.runtime.sendMessage({action:'getJSON',url:url}, (data) => {
store.pushEvents(requestId, data);
const autoReselect = !settingsStore.lockOn;
eventsStore.pushEvents(requestId, data, autoReselect);
nextTick(() => {
document.querySelectorAll('[data-pc-section="wrapper"]')[0].scrollTop = 1000000
if (autoReselect) {
document.querySelectorAll('[data-pc-section="wrapper"]')[0].scrollTop = 1000000;
}
})
});
};
Expand Down
2 changes: 1 addition & 1 deletion extension/src/components/Requests.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function classForStatus(status) {
cls = "bg-red-700/80"
break;
default:
cls = "bg-purple-700/70"
cls = "bg-blue-700/80"
}
return cls + " text-white p-1 rounded text-xs"
}
Expand Down
12 changes: 8 additions & 4 deletions extension/src/components/Toolbar.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
<template>
<span class="fixed right-0 z-10 cursor-pointer space-x-2 text-base p-[6px]">
<Button size="small" severity="secondary" text outlined rounded class="text-xs" icon="pi pi-ban" label="Clear" @click="eventsStore.clear()"></Button>
<Button size="small" severity="secondary" text outlined rounded class="text-xs" icon="pi pi-sliders-h" label="Settings" @click="settingsVisible=true"></Button>
<span class="fixed right-0 z-10 cursor-pointer flex text-base pr-2 pt-[6px] space-x-1 bg-white">
<span class="flex center"><ToolbarToggle v-model="settingsStore.lockOn" off-icon="pi pi-thumbtack" off-label="Pin" on-icon="pi pi-thumbtack" on-label="Pin" /></span>
<span class="flex"><ToolbarButton icon="pi pi-ban" label="Clear" @click="eventsStore.clear()" /></span>
<span class="flex"><ToolbarButton icon="pi pi-sliders-h" label="Settings" @click="settingsVisible=true"/></span>
</span>
<SettingsDialog v-model:visible="settingsVisible" @save="settingsVisible=false"/>
</template>

<script setup>
import Button from 'primevue/button';
import ToolbarButton from './wrappers/ToolbarButton.vue';
import ToolbarToggle from './wrappers/ToolbarToggle.vue';
import SettingsDialog from './SettingsDialog.vue';
import { useEventsStore } from '../stores/events';
import { useSettingsStore } from '../stores/settings';
import { ref } from 'vue';
const settingsVisible = ref(false);
const eventsStore = useEventsStore();
const settingsStore = useSettingsStore();
</script>
2 changes: 1 addition & 1 deletion extension/src/components/wrappers/SelectionTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,7 @@ const preset = {
class: [
// Color
'dark:text-white/80',
{ 'bg-slate-800 text-white dark:bg-surface-500/30': context.selected && context.stripedRows },
{ 'bg-gray-700 text-white dark:bg-surface-500/30': context.selected && context.stripedRows },
// { 'bg-surface-0 text-surface-600 dark:bg-surface-800': !context.selected },
{ 'odd:bg-surface-0 odd:text-surface-600 dark:odd:bg-surface-800 even:bg-surface-100 even:text-surface-600 dark:even:bg-surface-900/60': context.stripedRows && !context.selected },
Expand Down
85 changes: 85 additions & 0 deletions extension/src/components/wrappers/ToolbarButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<Button size="small" rounded class="text-xs" :pt="preset" outline :ptOptions="{ mergeSections: false, mergeProps: false }" />
</template>

<script setup>
import Button from 'primevue/button';
const preset = {
root: ({ props, context, parent }) => ({
class: [
'relative',
// Alignments
'items-center justify-center inline-flex text-center align-bottom',
// Sizes & Spacing
'text-sm',
{
'px-2.5 py-1.5 min-w-[2rem]': props.size === null,
'px-2 py-1': props.size === 'small',
'px-3 py-2': props.size === 'large'
},
{
'h-8 w-8 p-0': props.label == null && props.icon !== null
},
// Shapes
{ 'rounded-md': !props.rounded, 'rounded-full': props.rounded },
{ 'rounded-none first:rounded-l-md last:rounded-r-md self-center': parent.instance.$name == 'InputGroup' },
// Colors
'text-surface-500 hover:bg-surface-200 dark:hover:bg-surface-300 hover:ring-surface-600 dark:hover:ring-surface-300',
'active:bg-surface-400',
// Disabled
{ 'opacity-60 pointer-events-none cursor-default': context.disabled },
// Transitions
'transition duration-200 ease-in-out',
// Misc
'cursor-pointer overflow-hidden select-none'
]
}),
label: ({ props }) => ({
class: [
'duration-200',
'font-semibold',
{
'hover:underline': props.link
},
{ 'flex-1': props.label !== null, 'invisible w-0': props.label == null }
]
}),
icon: ({ props }) => ({
class: [
'mx-0',
{
'mr-2': props.iconPos == 'left' && props.label != null,
'ml-2 order-1': props.iconPos == 'right' && props.label != null,
'mb-2': props.iconPos == 'top' && props.label != null,
'mt-2': props.iconPos == 'bottom' && props.label != null
}
]
}),
loadingicon: ({ props }) => ({
class: [
'h-3 w-3',
'mx-0',
{
'mr-2': props.iconPos == 'left' && props.label != null,
'ml-2 order-1': props.iconPos == 'right' && props.label != null,
'mb-2': props.iconPos == 'top' && props.label != null,
'mt-2': props.iconPos == 'bottom' && props.label != null
},
'animate-spin'
]
}),
badge: ({ props }) => ({
class: [{ 'ml-2 w-4 h-4 leading-none flex items-center justify-center': props.badge }]
})
};
</script>
113 changes: 113 additions & 0 deletions extension/src/components/wrappers/ToolbarToggle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<ToggleButton :pt="preset" outline :ptOptions="{ mergeSections: false, mergeProps: false }" />
</template>

<script setup>
import ToggleButton from 'primevue/togglebutton';
const preset = {
root: {
class: [
'border-none',
'relative',
// Alignment
'inline-flex',
// Misc
'cursor-pointer',
'select-none',
]
},
box: ({ props }) => ({
class: [
// Alignments
'items-center inline-flex flex-1 text-center align-bottom justify-center',
// Sizes & Spacing
'px-2 py-1',
'text-xs',
// Shapes
'rounded-xl',
{ 'ring-surface-200 dark:ring-surface-700': !props.invalid },
{
'bg-surface-0 dark:bg-surface-900 ': !props.modelValue,
'bg-surface-600 text-white dark:bg-surface-700': props.modelValue
},
// Invalid State
{ 'ring-red-500 dark:ring-red-400': props.invalid },
// States
{
'peer-hover:bg-surface-200': !props.modelValue,
'peer-hover:bg-surface-700': props.modelValue
},
,
{
'peer-focus-visible:ring-2 peer-focus-visible:ring-inset peer-focus-visible:ring-primary-500 dark:peer-focus-visible:ring-primary-400': !props.disabled
},
// Transitions
'transition-all duration-200',
// Misc
{ 'cursor-pointer': !props.disabled, 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }
]
}),
label: ({ props }) => ({
class: [
'font-semibold text-center w-full',
{
'text-surface-500': !props.modelValue,
'text-white': props.modelValue
},
]
}),
input: {
class: [
'peer',
// Size
'w-full ',
'h-full',
// Position
'absolute',
'top-0 left-0',
'z-10',
// Spacing
'p-0',
'm-0',
// Shape
'opacity-0',
// Misc
'appearance-none',
'cursor-pointer'
]
},
icon: ({ props }) => ({
class: [
'mr-2',
{
'text-surface-500': !props.modelValue,
'text-white': props.modelValue
},
'transition-transform duration-200',
{
'-rotate-45': !props.modelValue,
'-rotate-90': props.modelValue
},
]
})
};
</script>
7 changes: 5 additions & 2 deletions extension/src/stores/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const useEventsStore = defineStore('events', () => {
const selectedCacheCalls = computed(() => cacheCalls.value.get(selectedRequest.value.id));
const selectedParams = computed(() => selectedRequest.value.params);

function pushEvents(requestId, newEvents) {
function pushEvents(requestId, newEvents, autoReselect = true) {
const actionEvent = newEvents.find((event) => event.name == "process_action.action_controller")
const action = {
id: requestId,
Expand All @@ -44,7 +44,10 @@ export const useEventsStore = defineStore('events', () => {
params: Object.entries(actionEvent.payload.params).map(([name, value]) => ({ name, value }) )
}
actions.value.set(requestId, action);
selectedRequest.value = action;

if (actions.value.size == 1 || autoReselect) {
selectedRequest.value = action;
}

activeRecordQueries.value.set(requestId, newEvents.flatMap((event) => {
if (event.name == "sql.active_record" && event.payload.name != "SCHEMA" && event.payload.name != "EXPLAIN") {
Expand Down
8 changes: 7 additions & 1 deletion extension/src/stores/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const defaultEditor = editors[0].id;
export const useSettingsStore = defineStore('settings', () => {
const filepathLinkBehaviour = ref(localStorage.getItem('railspanel.filepathLinkBehaviour') || 'copy');
const editor = ref(editors.find((e) => e.id == (localStorage.getItem('railspanel.editor') || defaultEditor)) || defaultEditor);
const lockOn = ref(localStorage.getItem('railspanel.lockOn') === "true");

watch(editor, (newVal, oldVal) => {
localStorage.setItem('railspanel.editor', newVal.id);
Expand All @@ -16,9 +17,14 @@ export const useSettingsStore = defineStore('settings', () => {
localStorage.setItem('railspanel.filepathLinkBehaviour', newVal);
});

watch(lockOn, (newVal, oldVal) => {
localStorage.setItem('railspanel.lockOn', newVal);
});

return {
editors,
editor,
filepathLinkBehaviour
filepathLinkBehaviour,
lockOn
}
})

0 comments on commit 076f173

Please sign in to comment.