More consitent use of mixins for interaactiong with thing descriptions

This commit is contained in:
Julian Stirling 2025-11-05 17:05:34 +00:00
parent 40b3d993ee
commit 1ba1a3082b
9 changed files with 45 additions and 29 deletions

View file

@ -214,7 +214,7 @@ export default {
try {
await this.$store.dispatch("wot/fetchThingDescriptions", `${baseUri}/thing_descriptions/`);
for (let requiredThing of ["camera", "stage"]) {
if (!this.$store.getters["wot/thingAvailable"](requiredThing)) {
if (!this.thingAvailable(requiredThing)) {
throw new Error(`No ${requiredThing} found, the GUI won't work without one.`);
}
}

View file

@ -78,13 +78,11 @@ export default {
const calibrateableThings = Object.keys(this.availableCalibrationTasks);
for (const name of calibrateableThings) {
try {
if (this.thingPropertyAvailable(name, "calibration_required")) {
const thingNeedsCal = await this.readThingProperty(name, "calibration_required");
if (thingNeedsCal) {
needsCalibration.push(name);
}
} catch (e) {
console.error(`${name}: missing calibration_required property`, e);
}
}

View file

@ -34,18 +34,16 @@
<div class="uk-margin-small-bottom">
<b>Camera:</b>
<br />
<div v-if="'camera' in things">
{{ things.camera.title }}
<div>
{{ cameraType }}
</div>
<div v-else class="uk-text-danger"><b>No camera configured</b></div>
</div>
<div>
<div v-if="stageType">
<b>Stage:</b>
<br />
<div v-if="'stage' in things">
{{ things.stage.title }}
<div>
{{ stageType }}
</div>
<div v-else class="uk-text-danger"><b>No stage configured</b></div>
</div>
<hr />
@ -71,8 +69,12 @@ export default {
},
computed: {
things: function () {
return this.$store.getters["wot/thingDescriptions"];
cameraType() {
// No need to check as the microscope won't start up without a camera defined
return this.thingDescription("camera").title;
},
stageType() {
return this.thingAvailable("stage") ? this.thingDescription("stage").title : undefined;
},
},

View file

@ -10,7 +10,7 @@
</p>
<div class="buttons-container">
<button
v-show="'shutdown' in things.system.actions"
v-show="shutdownAvailable"
class="uk-button uk-button-primary uk-width-1-3 shutdown-button"
@click="systemRequest('shutdown')"
>
@ -42,8 +42,8 @@ export default {
},
computed: {
things: function () {
return this.$store.getters["wot/thingDescriptions"];
shutdownAvailable() {
return this.thingActionAvailable("system", "shutdown");
},
},

View file

@ -119,12 +119,7 @@ export default {
computed: {
scansUri() {
return this.$store.getters["wot/thingPropertyUrl"](
"smart_scan",
"scans",
"readproperty",
true,
);
return this.thingPropertyUrl("smart_scan", "scans");
},
scansEmpty() {
return this.scans.length == 0;

View file

@ -69,10 +69,10 @@ export default {
computed: {
actions() {
return this.$store.getters["wot/thingDescription"]("camera_stage_mapping").actions;
return this.thingDescription("camera_stage_mapping").actions;
},
properties() {
return this.$store.getters["wot/thingDescription"]("camera_stage_mapping").properties;
return this.thingDescription("camera_stage_mapping").properties;
},
},

View file

@ -52,7 +52,7 @@ export default {
computed: {
actions() {
return this.$store.getters["wot/thingDescription"]("camera").actions;
return this.thingDescription("camera").actions;
},
},

View file

@ -36,13 +36,27 @@ Vue.mixin({
thingAvailable(thing) {
return this.$store.getters["wot/thingAvailable"](thing);
},
async readThingProperty(thing, property, silence_errors = false) {
thingPropertyUrl(thing, property, allowUndefined = false) {
return this.$store.getters["wot/thingPropertyUrl"](
thing,
property,
"readproperty",
allowUndefined,
);
},
thingActionAvailable(thing, action) {
return this.$store.getters["wot/thingAffordanceAvailable"](thing, "actions", action);
},
thingPropertyAvailable(thing, property) {
return this.$store.getters["wot/thingAffordanceAvailable"](thing, "properties", property);
},
async readThingProperty(thing, property, silenceErrors = false) {
let url = this.$store.getters["wot/thingPropertyUrl"](thing, property, "readproperty", false);
try {
let response = await axios.get(url);
return response.data;
} catch (error) {
if (!silence_errors) this.modalError(error);
if (!silenceErrors) this.modalError(error);
return undefined;
}
},
@ -71,12 +85,12 @@ Vue.mixin({
return undefined;
}
},
thingActionUrl(thing, action, allow_missing = false) {
thingActionUrl(thing, action, allowUndefined = false) {
let url = this.$store.getters["wot/thingActionUrl"](
thing,
action,
"invokeaction",
allow_missing,
allowUndefined,
);
return url;
},

View file

@ -57,6 +57,13 @@ export const wotStoreModule = {
thingAvailable: (state) => (thingName) => {
return thingName in state.thingDescriptions;
},
thingAffordanceAvailable: (state) => (thing, affordanceType, affordance) => {
let td = state.thingDescriptions[thing];
if (!td) {
return false;
}
return affordance in td[affordanceType];
},
thingFormUrl:
(state) =>
(thing, affordanceType, affordance, op, allowUndefined = true) => {