diff --git a/docs/docs/public/components/tags.png b/docs/docs/public/components/tags.png new file mode 100644 index 000000000..665796aac Binary files /dev/null and b/docs/docs/public/components/tags.png differ diff --git a/package-lock.json b/package-lock.json index bda8ff538..0a18bc848 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2439,6 +2439,11 @@ "node": ">= 6" } }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -7283,6 +7288,7 @@ "@monaco-editor/loader": "^1.3.3", "@tato30/vue-pdf": "1.9.4", "arquero": "^5.2.0", + "chroma-js": "^2.4.2", "mapbox-gl": "3.1.2", "marked": "^7.0.2", "monaco-editor": "^0.41.0", diff --git a/src/streamsync/core.py b/src/streamsync/core.py index 99adfc68f..5fcaa4e8b 100644 --- a/src/streamsync/core.py +++ b/src/streamsync/core.py @@ -511,6 +511,17 @@ def transform(self, ev: StreamsyncEvent) -> None: else: ev.payload = tf_payload + def _transform_tag_click(self, ev: StreamsyncEvent) -> Optional[str]: + payload = ev.payload + instance_path = ev.instancePath + options = self.evaluator.evaluate_field( + instance_path, "tags", True, "{ }") + if not isinstance(options, dict): + raise ValueError("Invalid value for tags") + if payload not in options.keys(): + raise ValueError("Unauthorised option") + return payload + def _transform_option_change(self, ev: StreamsyncEvent) -> Optional[str]: payload = ev.payload instance_path = ev.instancePath diff --git a/ui/package.json b/ui/package.json index eee4839df..98e07bbf4 100644 --- a/ui/package.json +++ b/ui/package.json @@ -17,6 +17,7 @@ "@monaco-editor/loader": "^1.3.3", "@tato30/vue-pdf": "1.9.4", "arquero": "^5.2.0", + "chroma-js": "^2.4.2", "mapbox-gl": "3.1.2", "marked": "^7.0.2", "monaco-editor": "^0.41.0", diff --git a/ui/src/core/templateMap.ts b/ui/src/core/templateMap.ts index 3cdf95845..d4e682d5d 100644 --- a/ui/src/core/templateMap.ts +++ b/ui/src/core/templateMap.ts @@ -12,6 +12,7 @@ import CoreVegaLiteChart from "../core_components/content/CoreVegaLiteChart.vue" import CoreVideoPlayer from "../core_components/content/CoreVideoPlayer.vue"; import CoreLink from "../core_components/content/CoreLink.vue"; import CoreChat from "../core_components/content/CoreChat.vue"; +import CoreTags from "../core_components/content/CoreTags.vue"; // input import CoreCheckboxInput from "../core_components/input/CoreCheckboxInput.vue"; import CoreDateInput from "../core_components/input/CoreDateInput.vue"; @@ -106,6 +107,7 @@ const templateMap = { step: CoreStep, steps: CoreSteps, ratinginput: CoreRating, + tags: CoreTags, switchinput: CoreSwitchInput, }; diff --git a/ui/src/core_components/content/CoreImage.vue b/ui/src/core_components/content/CoreImage.vue index 5da226cea..e95f59ac8 100644 --- a/ui/src/core_components/content/CoreImage.vue +++ b/ui/src/core_components/content/CoreImage.vue @@ -104,7 +104,8 @@ const componentId = inject(injectionKeys.componentId); const rootStyle = computed(() => { const component = ss.getComponentById(componentId); - const isClickHandled = typeof component.handlers?.["click"] !== "undefined"; + const isClickHandled = + typeof component.handlers?.["ss-click"] !== "undefined"; return { cursor: isClickHandled ? "pointer" : "unset", diff --git a/ui/src/core_components/content/CoreTags.vue b/ui/src/core_components/content/CoreTags.vue new file mode 100644 index 000000000..6301ee7a0 --- /dev/null +++ b/ui/src/core_components/content/CoreTags.vue @@ -0,0 +1,143 @@ + + + handleTagClick(tagId)" + > + {{ tagDesc }} + + + + + + + +