optimize subscription model bug fixes
This commit is contained in:
@@ -16,101 +16,56 @@
|
||||
<template v-slot:[`default-header`]="props">
|
||||
<div
|
||||
class="row items-center text-blue"
|
||||
@contextmenu.prevent.stop="openContextMenu($event, props.node)"
|
||||
@contextmenu.prevent.stop="openSubMenu($event, props.node.key)"
|
||||
>
|
||||
<div class="row items-center text-blue"></div>
|
||||
<div>{{ props.node.path }}</div>
|
||||
</div>
|
||||
<q-popup-edit
|
||||
v-if="props.node.value !== undefined && props.node.value !== ''"
|
||||
v-model="props.node.value"
|
||||
class="q-ml-xl bg-grey text-white"
|
||||
@save="(val) => onValueEdit(val, props.node)"
|
||||
>
|
||||
<template v-slot="scope">
|
||||
<q-input
|
||||
dark
|
||||
color="white"
|
||||
v-model="scope.value"
|
||||
dense
|
||||
autofocus
|
||||
counter
|
||||
@keyup.enter="scope.set"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="edit" />
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</q-popup-edit>
|
||||
</template>
|
||||
</q-tree>
|
||||
<sub-menu :node="selectedNode"></sub-menu>
|
||||
<!-- not implemented yet <sub-menu ref="subMenuRef"></sub-menu> -->
|
||||
</q-card-section>
|
||||
<DataTable :rows="Subscriptions" class="col-8" />
|
||||
<dataTable class="col-8" :rows="getRows()" />
|
||||
</div>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import DataTable from './dataTable.vue';
|
||||
import type { TreeNode } from 'src/composables/dbm/dbmTree';
|
||||
import {
|
||||
dbmData,
|
||||
type TreeNode,
|
||||
buildTree,
|
||||
getSubscriptionsByUuid,
|
||||
addChildrentoTree,
|
||||
getAllSubscriptions,
|
||||
dbmData,
|
||||
removeSubtreeByParentKey,
|
||||
} from 'src/composables/dbm/dbmTree';
|
||||
import DataTable from './DataTable.vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { openContextMenu } from 'src/composables/dbm/useContextMenu';
|
||||
import { NotifyResponse } from 'src/composables/notify';
|
||||
import SubMenu from 'src/components/dbm/SubMenu.vue';
|
||||
import { QCard } from 'quasar';
|
||||
import { subscribe, unsubscribe, setValues } from 'src/services/websocket';
|
||||
import { subscribe, unsubscribe } from 'src/services/websocket';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { api } from 'boot/axios';
|
||||
import type { Subs } from 'src/models/Subscribe';
|
||||
import { reactive } from 'vue';
|
||||
// not implemented yet import SubMenu from './SubMenu.vue';
|
||||
import { type Subs, type RawSubs, convertToSubscribes } from 'src/models/Subscribe';
|
||||
import { addSubscriptions, getRows, removeAllSubscriptions } from 'src/models/Subscriptions';
|
||||
|
||||
const $q = useQuasar();
|
||||
const expanded = ref<string[]>([]);
|
||||
const selectedNode = ref<TreeNode | null>(null);
|
||||
const ZERO_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
const Subscriptions = reactive<Subs>([]);
|
||||
let lastExpanded: string[] = [];
|
||||
const postQuery = '/json_data';
|
||||
|
||||
onMounted(() => {
|
||||
const payload = {
|
||||
get: [
|
||||
{
|
||||
path: '.*',
|
||||
query: { depth: 1 },
|
||||
},
|
||||
],
|
||||
};
|
||||
api
|
||||
.post('/json_data', payload)
|
||||
.post(postQuery, { get: [{ path: '.*', query: { depth: 1 } }] })
|
||||
.then((res) => {
|
||||
if (res.data.get) {
|
||||
dbmData.splice(0, dbmData.length, ...buildTree(res.data.get));
|
||||
}
|
||||
if (res.data.get) buildTree(convertToSubscribes(res.data.get as RawSubs));
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
.catch((err) => NotifyResponse($q, err, 'error'));
|
||||
});
|
||||
|
||||
onBeforeRouteLeave(() => {
|
||||
unsubscribe([
|
||||
{
|
||||
path: '.*',
|
||||
depth: 0,
|
||||
},
|
||||
]).catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
unsubscribe([{ path: '.*', depth: 0 }]).catch((err) => NotifyResponse($q, err, 'error'));
|
||||
});
|
||||
|
||||
function onLazyLoad({
|
||||
@@ -122,47 +77,11 @@ function onLazyLoad({
|
||||
done: (children: TreeNode[]) => void;
|
||||
fail: () => void;
|
||||
}): void {
|
||||
//first unsubsrice nodes
|
||||
unsubscribe([
|
||||
{
|
||||
path: '.*',
|
||||
depth: 0,
|
||||
},
|
||||
])
|
||||
.then(() => {
|
||||
Subscriptions.length = 0;
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
|
||||
// now subscribe nodes
|
||||
subscribe([
|
||||
{
|
||||
uuid: node.key ?? ZERO_UUID,
|
||||
path: '',
|
||||
depth: 2,
|
||||
},
|
||||
])
|
||||
api
|
||||
.post(postQuery, { get: [{ uuid: node.key ?? ZERO_UUID, path: '', query: { depth: 2 } }] })
|
||||
.then((resp) => {
|
||||
if (resp?.subscribe) {
|
||||
// Optional: update your internal store too
|
||||
addChildrentoTree(resp?.subscribe);
|
||||
|
||||
const toRemove = new Set(
|
||||
resp.subscribe.filter((sub) => sub.uuid !== ZERO_UUID).map((sub) => sub.uuid),
|
||||
);
|
||||
|
||||
Subscriptions.splice(
|
||||
0,
|
||||
Subscriptions.length,
|
||||
...getAllSubscriptions().filter((sub) => toRemove.has(sub.uuid)),
|
||||
);
|
||||
|
||||
done(dbmData);
|
||||
} else {
|
||||
done([]); // no children returned
|
||||
}
|
||||
if (resp?.data.get) done(buildTree(convertToSubscribes(resp?.data.get as RawSubs)));
|
||||
else done([]); // no children returned
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
@@ -170,87 +89,61 @@ function onLazyLoad({
|
||||
});
|
||||
}
|
||||
|
||||
function onValueEdit(newValue: undefined, node: TreeNode) {
|
||||
console.log(node.value, node.value === undefined);
|
||||
if (!node.key) return;
|
||||
const sub = getSubscriptionsByUuid(node.key);
|
||||
if (sub) {
|
||||
setValues([
|
||||
{
|
||||
path: sub.value?.path ?? '',
|
||||
value: newValue,
|
||||
},
|
||||
]).catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onExpandedChange(newExpanded: readonly string[]) {
|
||||
async function onExpandedChange(newExpanded: readonly string[]) {
|
||||
const collapsed = lastExpanded.filter((k) => !newExpanded.includes(k));
|
||||
const newlyExpanded = newExpanded.filter((k) => !lastExpanded.includes(k));
|
||||
|
||||
if (collapsed.length) {
|
||||
collapsed.forEach((key: string) => {
|
||||
subscribe([
|
||||
{
|
||||
uuid: key,
|
||||
path: '',
|
||||
depth: 2,
|
||||
},
|
||||
])
|
||||
.then((resp) => {
|
||||
if (resp?.subscribe) {
|
||||
// Optional: update your internal store too
|
||||
addChildrentoTree(resp?.subscribe);
|
||||
try {
|
||||
await unsubscribe([{ path: '.*', depth: 0 }])
|
||||
.then(() => {
|
||||
removeAllSubscriptions();
|
||||
})
|
||||
.catch((err) => NotifyResponse($q, err, 'error'));
|
||||
|
||||
const toRemove = new Set(
|
||||
resp.subscribe.filter((sub) => sub.uuid !== ZERO_UUID).map((sub) => sub.uuid),
|
||||
);
|
||||
if (collapsed.length) {
|
||||
collapsed.forEach((key) => {
|
||||
removeSubtreeByParentKey(key);
|
||||
api
|
||||
.post(postQuery, { get: [{ uuid: key, path: '', query: { depth: 2 } }] })
|
||||
.then((resp) => {
|
||||
if (resp?.data.get) {
|
||||
buildTree(resp?.data.get as Subs);
|
||||
subscribe([{ uuid: key, path: '', depth: 2 }]).catch((err) =>
|
||||
NotifyResponse($q, err, 'error'),
|
||||
);
|
||||
addSubscriptions(resp?.data.get as RawSubs);
|
||||
}
|
||||
})
|
||||
.catch((err) => NotifyResponse($q, err, 'error'));
|
||||
});
|
||||
}
|
||||
if (newlyExpanded.length) {
|
||||
newlyExpanded.forEach((key) => {
|
||||
api
|
||||
.post(postQuery, { get: [{ uuid: key, path: '', query: { depth: 2 } }] })
|
||||
.then((resp) => {
|
||||
if (resp?.data.get) {
|
||||
buildTree(resp?.data.get as Subs);
|
||||
subscribe([{ uuid: key, path: '', depth: 2 }]).catch((err) =>
|
||||
NotifyResponse($q, err, 'error'),
|
||||
);
|
||||
addSubscriptions(resp?.data.get as RawSubs);
|
||||
}
|
||||
})
|
||||
.catch((err) => NotifyResponse($q, err, 'error'));
|
||||
});
|
||||
}
|
||||
|
||||
Subscriptions.splice(
|
||||
0,
|
||||
Subscriptions.length,
|
||||
...getAllSubscriptions().filter((sub) => toRemove.has(sub.uuid)),
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
});
|
||||
} else if (newlyExpanded.length) {
|
||||
newlyExpanded.forEach((key: string) => {
|
||||
subscribe([
|
||||
{
|
||||
uuid: key,
|
||||
path: '',
|
||||
depth: 2,
|
||||
},
|
||||
])
|
||||
.then((resp) => {
|
||||
if (resp?.subscribe) {
|
||||
// Optional: update your internal store too
|
||||
addChildrentoTree(resp?.subscribe);
|
||||
|
||||
const toRemove = new Set(
|
||||
resp.subscribe.filter((sub) => sub.uuid !== ZERO_UUID).map((sub) => sub.uuid),
|
||||
);
|
||||
|
||||
Subscriptions.splice(
|
||||
0,
|
||||
Subscriptions.length,
|
||||
...getAllSubscriptions().filter((sub) => toRemove.has(sub.uuid)),
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
});
|
||||
lastExpanded = [...newExpanded];
|
||||
} catch {
|
||||
console.error('error in expand function');
|
||||
}
|
||||
}
|
||||
|
||||
lastExpanded = [...newExpanded];
|
||||
const subMenuRef = ref();
|
||||
|
||||
function openSubMenu(event: MouseEvent, uuid: string) {
|
||||
subMenuRef.value?.open(event, uuid);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@@ -4,50 +4,49 @@
|
||||
<q-item clickable v-close-popup @click="handleAction('Add')">
|
||||
<q-item-section>Add Datapoint</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="handleAction('Delete')">
|
||||
<q-item
|
||||
:class="disable ? 'text-grey-5' : ''"
|
||||
:clickable="!disable"
|
||||
v-close-popup
|
||||
@click="handleAction('Delete')"
|
||||
>
|
||||
<q-item-section>Delete Datapoint</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
<AddDialog :dialogLabel="label" width="700px" button-ok-label="Add" ref="addDialog" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
//import { useQuasar } from 'quasar';
|
||||
//import { NotifyResponse, NotifyError } from 'src/composables/notify';
|
||||
import { contextMenuState, contextMenuRef } from 'src/composables/dbm/useContextMenu';
|
||||
//import AddDatapoint from 'src/components/dbm/AddDatapoint.vue';
|
||||
//import { send } from 'src/services/websocket';
|
||||
import AddDialog from 'src/components/dialog/AddDatapoint.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
//const $q = useQuasar();
|
||||
const ZERO_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
const addDialog = ref();
|
||||
const datapointUuid = ref('');
|
||||
const contextMenuRef = ref();
|
||||
const label = ref('');
|
||||
const disable = ref(false);
|
||||
|
||||
function handleAction(action: string) {
|
||||
console.log(`Action '${action}' on node:`, contextMenuState.value);
|
||||
|
||||
// Add your actual logic here
|
||||
switch (action) {
|
||||
case 'Add':
|
||||
// send({
|
||||
// set: [
|
||||
// {
|
||||
// uuid: contextMenuState.value?.key,
|
||||
// path: 'New',
|
||||
// type: 'BIT',
|
||||
// value: true,
|
||||
// create: true,
|
||||
// },
|
||||
// ],
|
||||
// })
|
||||
// .then((response) => {
|
||||
// if (response?.set) {
|
||||
// console.log(response);
|
||||
// } else {
|
||||
// NotifyResponse($q, response);
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// NotifyError($q, err);
|
||||
// });
|
||||
console.log(4);
|
||||
label.value = 'Add New Datapoint';
|
||||
addDialog.value?.open(datapointUuid.value);
|
||||
break;
|
||||
case 'Delete':
|
||||
label.value = 'Remove Datapoint';
|
||||
addDialog.value?.open(datapointUuid.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const open = (event: MouseEvent, uuid: string) => {
|
||||
if (uuid === ZERO_UUID) disable.value = true;
|
||||
event.preventDefault();
|
||||
datapointUuid.value = uuid;
|
||||
contextMenuRef.value?.show(event);
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
|
@@ -1,13 +0,0 @@
|
||||
<template>
|
||||
<QCard v-if="props.display"> Test </QCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
display: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
@@ -14,21 +14,42 @@
|
||||
>
|
||||
<template v-slot:body-cell-value="props">
|
||||
<q-td :props="props" @click="openDialog(props.row)">
|
||||
<span :class="['cursor-pointer', open ? 'text-green' : '']"> {{ props.row.value }}</span>
|
||||
<div :class="['cursor-pointer', 'q-mx-sm']">
|
||||
{{ props.row.value }}
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
<template v-slot:body-cell-drivers="props">
|
||||
<q-td :props="props" @click="openDialog(props.row, 'driver')">
|
||||
<div v-if="props.row.type !== 'none'" :class="['cursor-pointer']">
|
||||
<q-icon size="sm" name="cell_tower" :color="props.row.drivers ? 'blue-5' : 'grey-4'" />
|
||||
</div>
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
<Dialog dialogLabel="Update Value" :show-dialog="open" />
|
||||
<UpdateDialog
|
||||
dialogLabel="Update Value"
|
||||
width="400px"
|
||||
button-ok-label="Write"
|
||||
ref="updateDialog"
|
||||
v-model:datapoint="dialogValue"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Dialog from 'src/components/dialog/UpdateValueDialog.vue';
|
||||
import UpdateDialog from 'src/components/dialog/UpdateValueDialog.vue';
|
||||
import type { QTableProps } from 'quasar';
|
||||
import type { Subs, Subscribe } from 'src/models/Subscribe';
|
||||
import type { Subscribe } from 'src/models/Subscribe';
|
||||
import { computed, ref } from 'vue';
|
||||
import type { Subs } from 'src/models/Subscribe';
|
||||
|
||||
const open = ref(false);
|
||||
const updateDialog = ref();
|
||||
const dialogValue = ref();
|
||||
|
||||
const openDialog = (sub: Subscribe, type?: string) => {
|
||||
updateDialog.value?.open(sub, type);
|
||||
};
|
||||
|
||||
// we generate lots of rows here
|
||||
const props = defineProps<{
|
||||
@@ -39,22 +60,23 @@ const tableRows = computed(() => [...props.rows]);
|
||||
|
||||
const columns = [
|
||||
{ name: 'path', label: 'Path', field: 'path', align: 'left' },
|
||||
{
|
||||
name: 'type',
|
||||
label: 'Type',
|
||||
field: 'type',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
label: 'Value',
|
||||
field: 'value',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
name: 'test',
|
||||
label: '',
|
||||
field: 'test',
|
||||
align: 'left',
|
||||
},
|
||||
// {. not implemented yet
|
||||
// name: 'drivers',
|
||||
// label: 'Drivers',
|
||||
// field: 'drivers',
|
||||
// align: 'center',
|
||||
// },
|
||||
] as QTableProps['columns'];
|
||||
|
||||
function openDialog(item: Subscribe) {
|
||||
console.log(77, item);
|
||||
open.value = true;
|
||||
}
|
||||
</script>
|
||||
|
101
src/components/dialog/AddDatapoint.vue
Normal file
101
src/components/dialog/AddDatapoint.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<DialogFrame ref="Dialog" :width="props.width">
|
||||
<q-card-section
|
||||
v-if="props.dialogLabel"
|
||||
class="text-bold text-left q-mb-none q-pb-none"
|
||||
:class="'text-' + props.labelColor"
|
||||
>{{ props.dialogLabel }}
|
||||
</q-card-section>
|
||||
<q-form ref="addForm" @submit="onSubmit" class="q-gutter-md">
|
||||
<q-input
|
||||
class="q-pa-md"
|
||||
filled
|
||||
v-model="path"
|
||||
label=""
|
||||
:rules="[(val) => !!val || 'Path is required']"
|
||||
>
|
||||
<template #prepend>
|
||||
<div class="column">
|
||||
<span class="text-caption text-primary non-editable-prefix">Path *</span>
|
||||
<span class="text-body2 text-grey-6 non-editable-prefix">{{ staticPrefix }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</q-input>
|
||||
<DataTypes class="q-ma-md" flat></DataTypes>
|
||||
<q-btn no-caps class="q-ma-lg" type="submit" color="primary">{{ props.buttonOkLabel }}</q-btn>
|
||||
</q-form>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useQuasar } from 'quasar';
|
||||
import { ref } from 'vue';
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import { api } from 'boot/axios';
|
||||
import { NotifyResponse } from 'src/composables/notify';
|
||||
import DataTypes from 'src/vueLib/buttons/DataTypes.vue';
|
||||
//import datatype from 'src/vueLib/buttons/DataType.vue';
|
||||
|
||||
const $q = useQuasar();
|
||||
const Dialog = ref();
|
||||
const path = ref('');
|
||||
const staticPrefix = ref('');
|
||||
//const radio = ref('bool');
|
||||
const addForm = ref();
|
||||
|
||||
const open = (uuid: string) => {
|
||||
Dialog.value?.open();
|
||||
getDatapoint(uuid);
|
||||
};
|
||||
|
||||
function validate() {
|
||||
addForm.value.validate().then((success: undefined) => {
|
||||
if (success) {
|
||||
console.log(909);
|
||||
// yay, models are correct
|
||||
} else {
|
||||
console.log(910);
|
||||
// oh no, user has filled in
|
||||
// at least one invalid value
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
buttonOkLabel: {
|
||||
type: String,
|
||||
default: 'OK',
|
||||
},
|
||||
labelColor: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
},
|
||||
dialogLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '300px',
|
||||
},
|
||||
});
|
||||
|
||||
function onSubmit() {
|
||||
validate();
|
||||
console.log('submit', props);
|
||||
}
|
||||
|
||||
function getDatapoint(uuid: string) {
|
||||
api
|
||||
.post('/json_data', { get: [{ uuid: uuid, query: { depth: 1 } }] })
|
||||
.then((resp) => {
|
||||
if (resp.data.get) {
|
||||
staticPrefix.value = resp.data.get[0].path;
|
||||
if (staticPrefix.value !== '') staticPrefix.value += ':';
|
||||
}
|
||||
})
|
||||
.catch((err) => NotifyResponse($q, err, 'error'));
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
@@ -1,42 +1,61 @@
|
||||
<template>
|
||||
<q-dialog v-model="internalShowDialog">
|
||||
<q-card :style="'width:' + props.width">
|
||||
<q-card-section
|
||||
v-if="props.dialogLabel"
|
||||
class="text-h6 text-center"
|
||||
:class="'text-' + props.labelColor"
|
||||
>{{ props.dialogLabel }}</q-card-section
|
||||
<DialogFrame ref="Dialog" :width="props.width">
|
||||
<q-card-section
|
||||
v-if="props.dialogLabel"
|
||||
class="text-bold text-left q-mb-none q-pb-none"
|
||||
:class="'text-' + props.labelColor"
|
||||
>{{ props.dialogLabel + ': ' + props.datapoint?.path }}</q-card-section
|
||||
>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
class="q-px-md q-ma-sm"
|
||||
label="current value"
|
||||
dense
|
||||
filled
|
||||
readonly
|
||||
v-model="inputValue as string | number"
|
||||
></q-input>
|
||||
<q-input
|
||||
class="q-px-md q-mx-sm"
|
||||
label="new value"
|
||||
dense
|
||||
filled
|
||||
@keyup.enter="write"
|
||||
v-model="writeValue as string | number"
|
||||
></q-input>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="props.text" class="text-center" style="white-space: pre-line">{{
|
||||
props.text
|
||||
}}</q-card-section>
|
||||
<q-card-actions align="left" class="text-primary">
|
||||
<q-btn v-if="props.buttonCancelLabel" flat :label="props.buttonCancelLabel" v-close-popup>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
class="q-mb-xl q-ml-lg q-mt-none"
|
||||
v-if="props.buttonOkLabel"
|
||||
color="primary"
|
||||
:label="props.buttonOkLabel"
|
||||
@click="write"
|
||||
>
|
||||
<q-card-section>
|
||||
<q-input v-model="inputValue"></q-input>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="props.text" class="text-center" style="white-space: pre-line">{{
|
||||
props.text
|
||||
}}</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn v-if="props.buttonCancelLabel" flat :label="props.buttonCancelLabel" v-close-popup>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-if="props.buttonOkLabel"
|
||||
flat
|
||||
:label="props.buttonOkLabel"
|
||||
v-close-popup
|
||||
@click="closeDialog"
|
||||
>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import type { Subscribe } from 'src/models/Subscribe';
|
||||
import type { PropType } from 'vue';
|
||||
import { setValues } from 'src/services/websocket';
|
||||
import { NotifyResponse } from 'src/composables/notify';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
const $q = useQuasar();
|
||||
const Dialog = ref();
|
||||
const writeValue = ref();
|
||||
|
||||
const props = defineProps({
|
||||
showDialog: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
buttonOkLabel: {
|
||||
type: String,
|
||||
default: 'OK',
|
||||
@@ -61,41 +80,47 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: '300px',
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
},
|
||||
datapoint: Object as PropType<Subscribe>,
|
||||
});
|
||||
|
||||
const inputValue = ref(props.value);
|
||||
const inputValue = ref(props.datapoint?.value);
|
||||
|
||||
const emit = defineEmits(['update:showDialog', 'update:value', 'confirmed', 'cancel']);
|
||||
const internalShowDialog = ref(props.showDialog);
|
||||
|
||||
watch(inputValue, (val) => {
|
||||
emit('update:value', val);
|
||||
});
|
||||
const open = (sub: Subscribe, type?: string) => {
|
||||
Dialog.value?.open();
|
||||
switch (type) {
|
||||
case 'driver':
|
||||
console.log(9, sub.drivers);
|
||||
writeValue.value = sub.drivers;
|
||||
break;
|
||||
default:
|
||||
writeValue.value = sub.value;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.showDialog,
|
||||
(newValue) => {
|
||||
console.log('watch showDialog', newValue);
|
||||
internalShowDialog.value = newValue;
|
||||
() => props.datapoint?.value,
|
||||
(newVal) => {
|
||||
inputValue.value = newVal;
|
||||
},
|
||||
);
|
||||
watch(internalShowDialog, (newValue) => {
|
||||
console.log('watch internalShowDialog', newValue);
|
||||
emit('update:showDialog', newValue);
|
||||
if (!newValue) {
|
||||
console.log('emit cancel');
|
||||
emit('cancel');
|
||||
} else {
|
||||
console.log('emit confirmed');
|
||||
emit('confirmed');
|
||||
}
|
||||
});
|
||||
|
||||
function closeDialog() {
|
||||
internalShowDialog.value = false;
|
||||
emit('update:showDialog', false);
|
||||
function write() {
|
||||
setValues([{ uuid: props.datapoint?.uuid ?? '', value: writeValue.value ?? undefined }])
|
||||
.then((resp) => {
|
||||
if (resp?.set) {
|
||||
resp.set.forEach((set) => {
|
||||
inputValue.value = set.value;
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => NotifyResponse($q, err));
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.outercard {
|
||||
border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -69,43 +69,30 @@
|
||||
import { useQuasar } from 'quasar';
|
||||
import LightSlider from './LightSlider.vue';
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { subscribe, unsubscribe } from 'src/services/websocket';
|
||||
import { unsubscribe, subscribeToPath } from 'src/services/websocket';
|
||||
import SettingDialog from 'src/components/lights/SettingDomeLight.vue';
|
||||
import { NotifyResponse } from 'src/composables/notify';
|
||||
import { updateValue, buildTree, dbmData } from 'src/composables/dbm/dbmTree';
|
||||
import { updateValue } from 'src/composables/dbm/dbmTree';
|
||||
import { removeAllSubscriptions } from 'src/models/Subscriptions';
|
||||
|
||||
const $q = useQuasar();
|
||||
const settings = ref(false);
|
||||
const brightness = updateValue('LightBar:Brightness', $q);
|
||||
const state = updateValue('LightBar:State', $q);
|
||||
onMounted(() => {
|
||||
subscribe([
|
||||
{
|
||||
path: 'LightBar:.*',
|
||||
depth: 0,
|
||||
},
|
||||
])
|
||||
.then((response) => {
|
||||
if (response?.subscribe) {
|
||||
dbmData.splice(0, dbmData.length, ...buildTree(response.subscribe));
|
||||
} else {
|
||||
NotifyResponse($q, response);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
subscribeToPath($q, 'LightBar:.*');
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
unsubscribe([
|
||||
{
|
||||
path: '.*',
|
||||
path: 'LightBar',
|
||||
depth: 0,
|
||||
},
|
||||
]).catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
removeAllSubscriptions();
|
||||
});
|
||||
|
||||
function changeState() {
|
||||
|
@@ -107,10 +107,11 @@ import { NotifyResponse } from 'src/composables/notify';
|
||||
import { onBeforeUpdate, computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import { subscribeToPath, unsubscribe, setValues } from 'src/services/websocket';
|
||||
import { LocalStorage } from 'quasar';
|
||||
import { getSubscriptionsByPath, updateValue } from 'src/composables/dbm/dbmTree';
|
||||
import { updateValue } from 'src/composables/dbm/dbmTree';
|
||||
import DragPad from 'src/components/lights/DragPad.vue';
|
||||
import SettingDialog from './SettingMovingHead.vue';
|
||||
import type { Settings } from 'src/models/MovingHead';
|
||||
import { findSubscriptionByPath, removeAllSubscriptions } from 'src/models/Subscriptions';
|
||||
|
||||
const $q = useQuasar();
|
||||
const brightness = updateBrightnessValue('MovingHead:Brightness');
|
||||
@@ -141,31 +142,29 @@ onUnmounted(() => {
|
||||
]).catch((err) => {
|
||||
NotifyResponse($q, err, 'error');
|
||||
});
|
||||
removeAllSubscriptions();
|
||||
});
|
||||
|
||||
function changeState() {
|
||||
console.log(55, brightness.value);
|
||||
console.log(56, state.value);
|
||||
if (brightness.value === 0) {
|
||||
if (state.value === 0) {
|
||||
brightness.value = 255;
|
||||
return;
|
||||
}
|
||||
brightness.value = state.value;
|
||||
console.log(57, brightness.value);
|
||||
return;
|
||||
}
|
||||
state.value = brightness.value;
|
||||
console.log(58, state.value);
|
||||
brightness.value = 0;
|
||||
}
|
||||
|
||||
function updateBrightnessValue(path: string) {
|
||||
return computed({
|
||||
get() {
|
||||
const sub = getSubscriptionsByPath(path);
|
||||
const sub = findSubscriptionByPath(path);
|
||||
if (!sub) return 0;
|
||||
if (!sub.value) return 0;
|
||||
return Number(sub.value.value);
|
||||
return Number(sub.value);
|
||||
},
|
||||
set(val) {
|
||||
const setPaths = [{ path, value: val }];
|
||||
|
Reference in New Issue
Block a user