Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pin feature #200

Merged
merged 2 commits into from
Apr 27, 2024
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
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
}
})
Loading