Skip to content

Commit

Permalink
Add support for proxy lists
Browse files Browse the repository at this point in the history
Support proxy lists in the same way as string/number lists
  • Loading branch information
Jo-Byr committed Dec 17, 2024
1 parent f8f3e54 commit 6d4ebdb
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 42 deletions.
15 changes: 9 additions & 6 deletions trame_simput/core/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,12 @@ def set_property(self, name, value):
prop_type = definition.get("type", "string")
safe_value = value
if value is not None:
if prop_type == "proxy" and not isinstance(value, str):
safe_value = value.id
if prop_type == "proxy":
if isinstance(value, list):
if len(value) > 0 and not isinstance(value[0], str):
safe_value = [val.id for val in value]
elif not isinstance(value, str):
safe_value = value.id

# check if change
change_detected = False
Expand Down Expand Up @@ -253,6 +257,8 @@ def get_property(self, name, default=None):
"""Return a property value"""
value = self._properties.get(name, default)
if "proxy" == self.definition.get(name).get("type"):
if isinstance(value, list):
return [self._proxy_manager.get(proxy_id) for proxy_id in value]
return self._proxy_manager.get(self._properties.get(name))

return value
Expand Down Expand Up @@ -321,10 +327,7 @@ def __getitem__(self, name):
"""value = proxy[prop_name]"""

if self._properties and name in self._properties:
if "proxy" == self.definition.get(name).get("type"):
return self._proxy_manager.get(self._properties.get(name))

return self._properties[name]
return self.get_property(name)

logger.error("Proxy[%s] not found", name)

Expand Down
5 changes: 3 additions & 2 deletions trame_simput/core/ui/resolvers/vuetify.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ def __init__(self):
self._labels = None

def get_widget(self, elem):
attributes = {}
model = self._model.get(elem.get("name"), {})
attributes = {key: model[key] for key in model if not key.startswith('_')}
if elem.tag in VUETIFY_MAP:
return VUETIFY_MAP[elem.tag], attributes
elif elem.tag == "input":
domains = self._model.get(elem.get("name"), {}).get("domains", [])
domains = model.get("domains", [])
widget = "sw-text-field"
for domain in domains:
ctype = domain.get("type")
Expand Down
6 changes: 6 additions & 0 deletions trame_simput/module/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ def reset_cache(self):
logger.info("reset_cache")
self.net_cache_domains = {}

@exportRpc("simput.create_proxy")
def test(self, manager_id, proxy_type):
pxm = get_simput_manager(manager_id).proxymanager
proxy = pxm.create(proxy_type)
return proxy.id

@exportRpc("simput.push")
def push(self, manager_id, id=None, type=None):
logger.info("push")
Expand Down
26 changes: 26 additions & 0 deletions vue2-components/src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,29 @@ export function getSimputManager(id, namespace, client) {
MANAGERS[id] = manager;
return manager;
}

export function getComponentProps(layout, index) {
if (layout === 'vertical') {
return { cols: 12 };
}
if (layout === 'l2') {
return { cols: 6 };
}
if (layout === 'l3') {
return { cols: 4 };
}
if (layout === 'l4') {
return { cols: 3 };
}
if (layout === 'm3-half') {
const props = { cols: 4 };
if (index === 3) {
props.offset = 4;
}
if (index === 5) {
props.offset = 8;
}
return props;
}
return {};
}
60 changes: 59 additions & 1 deletion vue2-components/src/widgets/Proxy/script.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,84 @@
import SimputInput from '../../components/SimputItem';
import { COMPUTED } from '../../core/utils';
import { COMPUTED, getComponentProps } from '../../core/utils';

export default {
name: 'swProxy',
props: {
name: {
type: String,
},
size: {
type: Number,
default: 1,
},
sizeControl: {
type: Boolean,
default: false,
},
proxyType: {
type: String,
},
mtime: {
type: Number,
},
},
components: {
SimputInput,
},
data() {
return {
dynamicSize: this.size,
};
},
computed: {
...COMPUTED.decorator,
model: {
get() {
/* eslint-disable no-unused-expressions */
this.mtime; // force refresh
this.dynamicSize;
const value = this.properties() && this.properties()[this.name];
if (!value && this.size > 1) {
const emptyArray = [];
emptyArray.length = this.size;
return emptyArray;
}
return value;
},
set(v) {
this.properties()[this.name] = v;
},
},
itemId() {
/* eslint-disable no-unused-expressions */
this.mtime; // force refresh
return this.properties()[this.name];
},
computedLayout() {
/* eslint-disable no-unused-expressions */
this.mtime; // force refresh
return this.layout || this.domains()[this.name]?.UI?.layout || 'vertical';
},
computedSize() {
if (Number(this.size) !== 1) {
return Math.max(this.size || 1, this.model?.length || 0);
}
return Number(this.size);
},
computedSizeControl() {
/* eslint-disable no-unused-expressions */
this.mtime; // force refresh
return this.sizeControl || this.domains()[this.name]?.UI?.sizeControl;
},
},
methods: {
getComponentProps(index) {
return getComponentProps(this.computedLayout, index);
},
deleteEntry(index) {
this.model.splice(index, 1);
this.dirty(this.name);
},
},
inject: ['data', 'properties', 'domains', 'dirty'],
};
25 changes: 24 additions & 1 deletion vue2-components/src/widgets/Proxy/template.html
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
<SimputInput :itemId="itemId" v-show="decorator.show" />
<template v-if="size==1">
<SimputInput :itemId="itemId" v-show="decorator.show" />
</template>
<template v-else>
<v-col>
<v-row
class="py-1"
v-for="i in computedSize"
:key="i"
v-bind="getComponentProps(i-1)"
>
<SimputInput :itemId="itemId[i-1]" v-show="decorator.show" />
<v-btn
v-if="computedSizeControl"
class="ml-2"
icon
x-small
@click="deleteEntry(i - 1)"
>
<v-icon>mdi-minus-circle-outline</v-icon>
</v-btn>
</v-row>
</v-col>
</template>
57 changes: 26 additions & 31 deletions vue2-components/src/widgets/TextField/script.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { COMPUTED } from '../../core/utils';
import { COMPUTED, getComponentProps } from '../../core/utils';

// Layouts: horizontal, vertical, l2, l3, l4
export default {
Expand Down Expand Up @@ -52,6 +52,9 @@ export default {
type: Boolean,
default: false,
},
proxyType: {
type: String,
},
},
data() {
return {
Expand Down Expand Up @@ -143,14 +146,28 @@ export default {
if (!this.model) {
this.model = [];
}
this.dynamicSize = this.model.length + 1;
this.model.length = this.dynamicSize;

if (this.newValue === 'null') {
this.model[this.model.length - 1] = null;
} else if (this.newValue === 'same') {
this.model[this.model.length - 1] = this.model[this.model.length - 2];
if (this.type == 'proxy') {
this.getSimput()
.wsClient.getConnection()
.getSession()
.call('simput.create_proxy', [
this.simputChannel.managerId,
this.proxyType,
])
.then((proxy_id) => {
if (proxy_id != undefined) {
this.model.push(proxy_id);
this.dirty(this.name);
}
});
} else {
if (this.newValue === 'null') {
this.model.push(null);
} else if (this.newValue === 'same') {
this.model.push(this.model[this.model.length - 2]);
}
}
this.dynamicSize = this.model.length;

this.validate(this.dynamicSize);
},
Expand All @@ -159,29 +176,7 @@ export default {
this.dirty(this.name);
},
getComponentProps(index) {
if (this.computedLayout === 'vertical') {
return { cols: 12 };
}
if (this.computedLayout === 'l2') {
return { cols: 6 };
}
if (this.computedLayout === 'l3') {
return { cols: 4 };
}
if (this.computedLayout === 'l4') {
return { cols: 3 };
}
if (this.computedLayout === 'm3-half') {
const props = { cols: 4 };
if (index === 3) {
props.offset = 4;
}
if (index === 5) {
props.offset = 8;
}
return props;
}
return {};
return getComponentProps(this.computedLayout, index);
},
color(component = 0) {
if (
Expand Down
2 changes: 1 addition & 1 deletion vue2-components/src/widgets/TextField/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</div>
</v-col>
</v-row>
<v-row>
<v-row v-if="type != 'proxy'">
<v-col v-if="size == 1" class="pt-0 pb-1">
<v-text-field
:name="`${data().type}:${name}:${i}`"
Expand Down

0 comments on commit 6d4ebdb

Please sign in to comment.