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 { try {
await this.$store.dispatch("wot/fetchThingDescriptions", `${baseUri}/thing_descriptions/`); await this.$store.dispatch("wot/fetchThingDescriptions", `${baseUri}/thing_descriptions/`);
for (let requiredThing of ["camera", "stage"]) { 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.`); 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); const calibrateableThings = Object.keys(this.availableCalibrationTasks);
for (const name of calibrateableThings) { for (const name of calibrateableThings) {
try { if (this.thingPropertyAvailable(name, "calibration_required")) {
const thingNeedsCal = await this.readThingProperty(name, "calibration_required"); const thingNeedsCal = await this.readThingProperty(name, "calibration_required");
if (thingNeedsCal) { if (thingNeedsCal) {
needsCalibration.push(name); 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"> <div class="uk-margin-small-bottom">
<b>Camera:</b> <b>Camera:</b>
<br /> <br />
<div v-if="'camera' in things"> <div>
{{ things.camera.title }} {{ cameraType }}
</div> </div>
<div v-else class="uk-text-danger"><b>No camera configured</b></div>
</div> </div>
<div> <div v-if="stageType">
<b>Stage:</b> <b>Stage:</b>
<br /> <br />
<div v-if="'stage' in things"> <div>
{{ things.stage.title }} {{ stageType }}
</div> </div>
<div v-else class="uk-text-danger"><b>No stage configured</b></div>
</div> </div>
<hr /> <hr />
@ -71,8 +69,12 @@ export default {
}, },
computed: { computed: {
things: function () { cameraType() {
return this.$store.getters["wot/thingDescriptions"]; // 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> </p>
<div class="buttons-container"> <div class="buttons-container">
<button <button
v-show="'shutdown' in things.system.actions" v-show="shutdownAvailable"
class="uk-button uk-button-primary uk-width-1-3 shutdown-button" class="uk-button uk-button-primary uk-width-1-3 shutdown-button"
@click="systemRequest('shutdown')" @click="systemRequest('shutdown')"
> >
@ -42,8 +42,8 @@ export default {
}, },
computed: { computed: {
things: function () { shutdownAvailable() {
return this.$store.getters["wot/thingDescriptions"]; return this.thingActionAvailable("system", "shutdown");
}, },
}, },

View file

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

View file

@ -69,10 +69,10 @@ export default {
computed: { computed: {
actions() { actions() {
return this.$store.getters["wot/thingDescription"]("camera_stage_mapping").actions; return this.thingDescription("camera_stage_mapping").actions;
}, },
properties() { 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: { computed: {
actions() { actions() {
return this.$store.getters["wot/thingDescription"]("camera").actions; return this.thingDescription("camera").actions;
}, },
}, },

View file

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

View file

@ -57,6 +57,13 @@ export const wotStoreModule = {
thingAvailable: (state) => (thingName) => { thingAvailable: (state) => (thingName) => {
return thingName in state.thingDescriptions; 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: thingFormUrl:
(state) => (state) =>
(thing, affordanceType, affordance, op, allowUndefined = true) => { (thing, affordanceType, affordance, op, allowUndefined = true) => {