Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/frontend/src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ p {
color: #cecece !important;
}

.text-dark-gray {
color: #323232;
}

.body--dark .q-field__messages [role="alert"] {
color: #ff5353 !important;
font-weight: 500;
Expand Down
50 changes: 37 additions & 13 deletions src/frontend/src/components/TableComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
@keydown="keydown"
:rows-per-page-options="props.showAll ? [0] : [5,10,15,20,25,50,0]"
:hideBottom="props.hideBottom && rows.length > 0"
:loading="loading"
>
<template v-slot:header="props">
<q-tr :props="props">
Expand All @@ -45,10 +46,17 @@
<template v-slot:body="props">
<!-- props.row[field] - field needs to be unique ID, pass this in as a prop, or just use id -->
<q-tr
:class="`${getSelectedColor(props.selected)} cursor-pointer ${highlightRow(props)} ${disableRow(props)}` "
:class="`
cursor-pointer
${getSelectedColor(props.selected)}
${highlightRow(props)}
${disableRow(props)}
${props.expand ? 'row-top-border' : ''}
`"
:props="props"
@click="openResource(props, $event); selectResource(props)"
@auxclick="onAuxClick(props, $event)"
:no-hover="props.expand"
>
<q-td v-for="col in props.cols" :key="col.name" :props="props" :style="props.expand ? {'border-bottom': 'none'} : {}">
<q-menu
Expand Down Expand Up @@ -151,7 +159,7 @@
</slot>
</q-td>
</q-tr>
<q-tr v-show="props.expand" :props="props" :class="`${highlightRow(props)}`">
<q-tr v-show="props.expand" :props="props" :class="`${highlightRow(props)} ${disableRow(props)}`" no-hover>
<q-td colspan="100%">
<!-- <div class="text-left ">Additional info for {{ props.row.name }}.</div> -->
<slot name="expandedSlot" :row="props.row" :rowProps="props" />
Expand Down Expand Up @@ -516,17 +524,17 @@
}

function highlightRow(rowProps) {
if(rowProps.row.deleted === true) {
return darkMode.value ? 'bg-red-8' : 'bg-red-light'
}
if(props.disabledRowKeys.includes(rowProps.row[props.rowKey])) return
if(!props.highlightRow) return
if(!rowProps.expand) return
if(darkMode.value) {
return 'bg-yellow-8 text-black'
} else {
return 'bg-yellow-8'
}
if(rowProps.row.deleted === true) {
return darkMode.value ? 'bg-red-8' : 'bg-red-light'
}
if(props.disabledRowKeys.includes(rowProps.row[props.rowKey])) return
if(!props.highlightRow) return
if(!rowProps.expand) return
if(darkMode.value) {
return 'bg-yellow-8 text-dark-gray row-bottom-border'
} else {
return 'bg-yellow row-bottom-border'
}
}

function disableRow(rowProps) {
Expand Down Expand Up @@ -576,4 +584,20 @@ function truncateString(str, limit) {
.header-label--dark {
color: #cbe8f5;
}

:deep(tr.row-bottom-border .q-td) {
border-bottom: 1px solid #263238;
}

:deep(tr.row-top-border .q-td) {
/* Draw a top separator on the main row even with collapsed borders */
box-shadow: inset 0 1px 0 #263238;
}

:deep(.q-table__container table),
:deep(.q-table__middle table) {
border-collapse: collapse;
border-spacing: 0;
}

</style>
148 changes: 98 additions & 50 deletions src/frontend/src/dialogs/ImportPluginTasksDialog.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<q-dialog v-model="showDialog">
<q-dialog v-model="showDialog" @show="onDialogShow">
<q-card style="display: inline-block; width: auto; max-width: 800px;">
<q-card-section class="bg-primary text-white text-h6">
Import Plugin Tasks
Import Plugin Function Tasks
</q-card-section>

<q-card-section style="max-height: 75vh" class="scroll">
Expand All @@ -29,6 +29,7 @@
v-model:selected="selectedTasks"
selection="multiple"
row-key="name"
:loading="loading"
>
<template #body-cell-name="props">
<div style="font-size: 18px;">
Expand All @@ -42,7 +43,7 @@
</div>
</template>
<template #body-cell-inputParams="props">
<div class="column items-end fit q-mt-sm">
<div class="column items-end">
<q-chip
v-for="(param, i) in props.row.inputParams"
:key="i"
Expand All @@ -59,12 +60,13 @@
dense
color="orange"
text-color="white"
square
label="No params listed"
/>
</div>
</template>
<template #body-cell-outputParams="props">
<div class="column items-end fit q-mt-sm">
<div class="column items-end">
<q-chip
v-for="(param, i) in props.row.outputParams"
:key="i"
Expand All @@ -78,6 +80,7 @@
dense
color="orange"
text-color="white"
square
label="No params listed"
/>
</div>
Expand All @@ -89,50 +92,57 @@
/>
</template>
<template #expandedSlot="{ row, rowProps }">
<div class="row" v-if="Object.hasOwn(dupliateIdenticalTasks, row.name)" @vue:mounted="expandRow(row, rowProps)">
Duplicate task with identical params already exist in your plugin file.
</div>
<div v-if="Object.hasOwn(dupliateTasksWithDifferentParams, row.name)" @vue:mounted="expandRow(row, rowProps)">
<div class="row">
Duplicate task. Importing will overwrite the existing params below.
<div @click="rowProps.selected = !rowProps.selected" style="cursor: pointer;">
<div class="row" v-if="Object.hasOwn(dupliateIdenticalTasks, row.name)" @vue:mounted="expandRow(row, rowProps)">
Duplicate task with identical params already exist in your plugin file.
</div>
<div class="row justify-end">
<div class="column items-end">
<q-chip
v-for="(param, i) in dupliateTasksWithDifferentParams[row.name].inputParams"
:key="i"
color="indigo"
text-color="white"
dense
>
{{ `${param.name}` }}
<span v-if="param.required" class="text-red">*</span>
{{ `: ${param.type}` }}
</q-chip>
<q-chip
v-if="dupliateTasksWithDifferentParams[row.name].inputParams.length === 0"
dense
color="orange"
text-color="white"
label="No params listed"
/>
<div v-if="Object.hasOwn(dupliateTasksWithDifferentParams, row.name)" @vue:mounted="expandRow(row, rowProps)">
<div class="row">
Duplicate task. Importing will overwrite the existing params below.
</div>
<div class="column items-end" style="width: 142px; padding-left: 0; padding-right: 0;">
<q-chip
v-for="(param, i) in dupliateTasksWithDifferentParams[row.name].outputParams"
:key="i"
color="purple"
text-color="white"
dense
:label="`${param.name}: ${param.type}`"
/>
<q-chip
v-if="dupliateTasksWithDifferentParams[row.name].outputParams.length === 0"
dense
color="orange"
text-color="white"
label="No params listed"
/>
<div class="row justify-end">
<div class="column items-end">
<q-chip
v-for="(param, i) in dupliateTasksWithDifferentParams[row.name].inputParams"
:key="i"
color="indigo"
text-color="white"
dense
>
{{ `${param.name}` }}
<span v-if="param.required" class="text-red">*</span>
{{ `: ${param.type}` }}
</q-chip>
<q-chip
v-if="dupliateTasksWithDifferentParams[row.name].inputParams.length === 0"
dense
color="orange"
text-color="white"
square
label="No params listed"
/>
</div>
<div
class="column items-end"
:style="{width: outputParamsWidth ? outputParamsWidth + 'px' : '172px',}"
>
<q-chip
v-for="(param, i) in dupliateTasksWithDifferentParams[row.name].outputParams"
:key="i"
color="purple"
text-color="white"
dense
:label="`${param.name}: ${param.type}`"
/>
<q-chip
v-if="dupliateTasksWithDifferentParams[row.name].outputParams.length === 0"
dense
color="orange"
text-color="white"
square
label="No params listed"
/>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -164,7 +174,7 @@
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { ref, watch, computed, nextTick } from 'vue'
import * as api from '@/services/dataApi'
import TableComponent from '@/components/TableComponent.vue'
import * as notify from '../notify'
Expand All @@ -176,6 +186,10 @@ const showDialog = defineModel()

const existingTasksCopy = ref([])

const tableRef = ref()
const outputParamsWidth = ref(0)
const loading = ref(true)

watch(() => showDialog.value, (newVal) => {
if(newVal) {
tasks.value = []
Expand All @@ -186,6 +200,30 @@ watch(() => showDialog.value, (newVal) => {
}
})

function getColumnWidthPxByLabel(label) {
const tableEl = (tableRef.value && tableRef.value.$el) || null
if (!tableEl) return 0
const spans = tableEl.querySelectorAll('.header-label')
for (let i = 0; i < spans.length; i++) {
const s = spans[i]
if ((s.textContent || '').trim() === label) {
const th = s.closest('th')
if (th && th.getClientRects().length > 0 && th.offsetParent !== null) {
// minus 8 to account for the left padding in the table headers
return th.getBoundingClientRect().width - 8
}
}
}
return 0
}

function onDialogShow() {
// Let QDialog/QTable finish layout in the next frame
requestAnimationFrame(() => {
outputParamsWidth.value = getColumnWidthPxByLabel("Output Parameters")
})
}

const tasks = ref([])
const selectedTasks = ref([])
const errorMessage = ref('')
Expand Down Expand Up @@ -231,6 +269,7 @@ async function suggestPluginTasks() {
selectedTasks.value = tasks.value.filter(
task => !Object.keys(dupliateIdenticalTasks.value).includes(task.name)
)
loading.value = false
} catch(err) {
console.warn(err)
notify.error(err.response.data.message)
Expand All @@ -241,8 +280,8 @@ async function suggestPluginTasks() {
const taskColumns = [
{ name: 'select', label: 'Select', align: 'center', },
{ name: 'name', label: 'Name', align: 'left', field: 'name', sortable: false, },
{ name: 'inputParams', label: 'Input Parameters', field: 'inputParams', align: 'right', sortable: false, style: 'width: 150px', },
{ name: 'outputParams', label: 'Output Parameters', field: 'outputParams', align: 'right', sortable: false, style: 'width: 150px' },
{ name: 'inputParams', label: 'Input Parameters', field: 'inputParams', align: 'right', sortable: false, style: 'width: 175px', },
{ name: 'outputParams', label: 'Output Parameters', field: 'outputParams', align: 'right', sortable: false, style: 'width: 175px' },
]

async function submit() {
Expand Down Expand Up @@ -325,4 +364,13 @@ function deepEqual(obj1, obj2, ignoreKeys = []) {
}


</script>
</script>


<style scoped>
/* make inputParams and outputParams cells top-aligned */
:deep(.q-table tbody td:nth-child(3)),
:deep(.q-table tbody td:nth-child(4)) {
vertical-align: top;
}
</style>