Splunk Dashboard Studio, Tokens behaviour with chained searches - splunk

Since the last Splunk update I've noticed some unexpected behavior when it comes to tokens with Splunk Dashboard Studio.
If you have an input (dropdown or multiselect) with a default value set to None.
After loading the dashboard page, then setting the input value,
The base searches in the dashboard that use the input token will update,
but any chain searches of that base search do not.
It does however update if you either refresh the page with the tokens set in the url, or a change to the input for a second time. (any other action which causes the page to refresh in some way eg: editing page will update the dashboard and the chain search will update)
is this behaviour a bug, and is there currently a way to fix this behaviour?
Thanks Daniel
Below is a self contained minimal example to demonstrate this.
Splunk Dashboard Studio: Absolute/Full control layout
{
"visualizations": {
"viz_cdPoxmBV": {
"type": "splunk.table",
"dataSources": {
"primary": "ds_CJTH14Fk"
},
"title": "Base"
},
"viz_t4aAHmKH": {
"type": "splunk.table",
"title": "Chain",
"dataSources": {
"primary": "ds_aqLh17e3"
}
}
},
"dataSources": {
"ds_CJTH14Fk": {
"type": "ds.search",
"options": {
"query": "| makeresults\n| eval a=\"$input$\"\n| table a ",
"queryParameters": {
"earliest": "0",
"latest": ""
}
},
"name": "Search_Base"
},
"ds_aqLh17e3": {
"type": "ds.chain",
"options": {
"extend": "ds_CJTH14Fk",
"query": "| eval a=a+\"_END\""
},
"name": "Search_1"
}
},
"defaults": {
"dataSources": {
"ds.search": {
"options": {
"queryParameters": {
"latest": "$global_time.latest$",
"earliest": "$global_time.earliest$"
}
}
}
}
},
"inputs": {
"input_aXQ6s8I2": {
"options": {
"items": [
{
"label": "All",
"value": "*"
},
{
"label": "Item 1",
"value": "item001"
},
{
"label": "Item 2",
"value": "item002"
}
],
"token": "input"
},
"title": "Dropdown Input Title",
"type": "input.dropdown"
}
},
"layout": {
"type": "absolute",
"options": {
"display": "auto-scale"
},
"structure": [
{
"item": "viz_cdPoxmBV",
"type": "block",
"position": {
"x": 10,
"y": 10,
"w": 410,
"h": 140
}
},
{
"item": "viz_t4aAHmKH",
"type": "block",
"position": {
"x": 430,
"y": 10,
"w": 400,
"h": 140
}
}
],
"globalInputs": [
"input_aXQ6s8I2"
]
},
"description": "",
"title": "Test_Token"
}
below is classic dashboard example where behaviour is not seen.
<form version="1.1">
<label>Test_Token</label>
<search id="baseSearch">
<query>| makeresults
| eval a="$input$"
| table a</query>
<earliest>-24h#h</earliest>
<latest>now</latest>
</search>
<fieldset submitButton="false">
<input type="dropdown" token="input">
<label>dropdown</label>
<choice value="*">All</choice>
<choice value="item001">Item 1</choice>
<choice value="item002">Item 2</choice>
</input>
</fieldset>
<row>
<panel>
<table>
<search>
<query>| makeresults
| eval a="$input$"
| table a</query>
<earliest>-24h#h</earliest>
<latest>now</latest>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<search base="baseSearch">
<query>| eval a=a+"_END"</query>
</search>
<option name="drilldown">none</option>
</table>
</panel>
</row>
</form>

Related

How render attributes in component Vue 3

I have products two types: simple and configurable:
"products" : [
{
"type": "simple",
"id": 1,
"sku": "s1",
"title": "Product 1",
"regular_price": {
"currency": "USD",
"value": 27.12
},
"image": "/images/1.png",
"brand": 9
},
{
"type": "configurable",
"id": 2,
"sku": "c1",
"title": "Product 2",
"regular_price": {
"currency": "USD",
"value": 54.21
},
"image": "/images/conf/default.png",
"configurable_options": [
{
"attribute_id": 93,
"attribute_code": "color",
"label": "Color",
"values": [
{
"label": "Red",
"value_index": 931,
"value": "#ff0000"
},
{
"label": "Blue",
"value_index": 932,
"value": "#0000ff"
},
{
"label": "Black",
"value_index": 933,
"value": "#000"
}
]
},
{
"attribute_code": "size",
"attribute_id": 144,
"position": 0,
"id": 2,
"label": "Size",
"values": [
{
"label": "M",
"value_index": 1441,
"value": 1
},
{
"label": "L",
"value_index": 1442,
"value": 2
}
]
}
],
"variants": [
{
"attributes": [
{
"code": "color",
"value_index": 931
},
{
"code": "size",
"value_index": 1441
}
],
"product": {
"id": 2001,
"sku": "c1-red-m",
"image": "/image/conf/red.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 931
},
{
"code": "size",
"value_index": 1442
}
],
"product": {
"id": 2002,
"sku": "c1-red-l",
"image": "/image/conf/red.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 932
},
{
"code": "size",
"value_index": 1441
}
],
"product": {
"id": 2003,
"sku": "c1-blue-m",
"image": "/image/conf/blue.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 933
},
{
"code": "size",
"value_index": 1442
}
],
"product": {
"id": 2004,
"sku": "c1-black-l",
"image": "/image/conf/black.png"
}
}
],
"brand": 1
}
]
The above data I get with actions (Vuex)
GET_PRODUCTS_FROM_API({ commit }) {
return axios('http://localhost:8080/products', {
method: 'GET',
})
.then((products) => {
commit('SET_PRODUCTS_TO_STATE', products.data);
return products;
})
.catch((e) => {
console.log(e);
return e;
});
}
then I mutate the data:
SET_PRODUCTS_TO_STATE: (state, products) => {
state.products = products
}
and get from in getters
PRODUCTS(state) {
return state.products = state.products.map((product) => {
const brand = state.brands.find((b) => b.id === product.brand)
return {...product, brandName: brand?.title || 'no brand'}
})
}
after which i get the data in the component
At the moment I'm stuck on how to render the color and size attributes of a configurable product. Tell me how to do it right? Do I need to write logic in vuex or parent component?
I tried to push data from parent component to child. But it stopped there again.
I also tried to separate the color and size attributes separately using getters.
For Vuex, the syntax is the following
<template>
<div>
<div v-for="product in products" :key="product.id">
<span>type: {{ product.type }}</span>
<span>type: {{ product.title }}</span>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['products']),
...mapGetters('fancyNamespace', ['products']), // if namespaced
},
}
</script>
As of where to call it, directly into the component I guess. Otherwise, as explained here it may not be relevant to use Vuex at all.
PS: you can even rename on the fly if you want.
Solved this issue by Computed Properties and transfer props to child components
computed: {
getAttributeColors() {
let attributes_colors = []
this.product_data.configurable_options.map((item) => {
if(item.label === 'Color') {
attributes_colors.push(item.values)
}
})
return attributes_colors
},
getAttributeSize() {
let attributes_size = []
this.product_data.configurable_options.map((item) => {
if(item.label === 'Size') {
attributes_size.push(item.values)
}
})
return attributes_size
}
}

Shopify. How to resuse a select setting across multiple schemas

I have a section sections/two-col-cta.liquid with a schema defined as per below:
{% schema %}
{
"name": "Two Column CTA",
"class": "section",
"settings": [
{
"type": "select",
"id": "color_select",
"options": [
{
"value": "option_1",
"label": "option_1"
},
{
"value": "option_2",
"label": "option_2"
},
{
"value": "option_3",
"label": "option_3"
},
{
"value": "option_4",
"label": "option_4"
},
{
"value": "option_5",
"label": "option_5"
}
],
"default": "image_first",
"label": "t:sections.two-col-content-img.settings.layout.label",
"info": "t:sections.two-col-content-img.settings.layout.info"
}
]
}
{% endschema %}
This same color_select setting is used/duplicated across multiple different sections (sections/.liquid files). Is there a way I can define this setting globally and just pull it into my sections instead of re defining it every time I want to a color select?

Needle in haystack: How to get value from array of objects via computed property?

I am trying to loop through the following JSON:
[ { "target": { "source": "https://firebasestorage.googleapis.com/v0/b/vue-photoapp-api.appspot.com/o/photos%2Fmountains-hero.jpg?alt=media&token=fbe93188-d13d-4a7f-a472-4a529aa565a0", "selector": { "conformsTo": "http://www.w3.org/TR/media-frags/", "value": "xywh=pixel:378.2608642578125,328.9855041503906,147.82611083984375,210.14492797851562", "type": "FragmentSelector" } }, "photoDocId": "92wNwz2aaqy7CWf3mGo1", "body": [ { "value": "new annotation", "purpose": "commenting", "type": "TextualBody" }, { "purpose": "tagging", "type": "TextualBody", "value": "error" } ], "id": "698RTBGMwWahQ15rXbe6", "type": "Annotation", "#context": "http://www.w3.org/ns/anno.jsonld" }, { "photoDocId": "92wNwz2aaqy7CWf3mGo1", "target": { "source": "https://firebasestorage.googleapis.com/v0/b/vue-photoapp-api.appspot.com/o/photos%2Fmountains-hero.jpg?alt=media&token=fbe93188-d13d-4a7f-a472-4a529aa565a0", "selector": { "conformsTo": "http://www.w3.org/TR/media-frags/", "value": "xywh=pixel:695.6521606445312,60.869564056396484,139.13043212890625,127.53622817993164", "type": "FragmentSelector" } }, "id": "AUMwWBjizjl8L8vU0XtA", "#context": "http://www.w3.org/ns/anno.jsonld", "type": "Annotation", "body": [ { "value": "clouds!", "type": "TextualBody", "purpose": "commenting" }, { "type": "TextualBody", "value": "clouds", "purpose": "tagging" } ] }, { "type": "Annotation", "body": [ { "type": "TextualBody", "value": "fourth anno", "purpose": "commenting" } ], "target": { "source": "https://firebasestorage.googleapis.com/v0/b/vue-photoapp-api.appspot.com/o/photos%2Fmountains-hero.jpg?alt=media&token=fbe93188-d13d-4a7f-a472-4a529aa565a0", "selector": { "type": "FragmentSelector", "conformsTo": "http://www.w3.org/TR/media-frags/", "value": "xywh=pixel:631.884033203125,389.8551025390625,172.4637451171875,128.9854736328125" } }, "#context": "http://www.w3.org/ns/anno.jsonld", "id": "CecyGAt47krNIOPgk8Su", "photoDocId": "92wNwz2aaqy7CWf3mGo1" }, { "photoDocId": "92wNwz2aaqy7CWf3mGo1", "body": [ { "type": "TextualBody", "purpose": "commenting", "value": "mountain top . Anyone ever climbed this?" }, { "value": "mountain", "type": "TextualBody", "purpose": "tagging" } ], "#context": "http://www.w3.org/ns/anno.jsonld", "id": "KxIMdih1fTSULjde3Ay4", "type": "Annotation", "target": { "selector": { "type": "FragmentSelector", "value": "xywh=pixel:272.4637756347656,60.869564056396484,252.17391967773438,185.50725173950195", "conformsTo": "http://www.w3.org/TR/media-frags/" }, "source": "https://firebasestorage.googleapis.com/v0/b/vue-photoapp-api.appspot.com/o/photos%2Fmountains-hero.jpg?alt=media&token=fbe93188-d13d-4a7f-a472-4a529aa565a0" } } ]
I want to return just the following values:
purpose, type, and value. They are located within the body array of clientAnnos
Will this need to be a v-for within a v-for loop?
Update: I tried:
<ul>
<li v-for="{ body, index } in clientAnnos" :key="index">
{{ body }}
</li>
</ul>
But I am wondering if there's possible update issues due to index variable not having a true id.
you can try by mapping through the data then looping through the body since its an array. You can use a method for this for example
methods: {
info() {
let required = this.data.map(d => d.body)
return required
}
}
Then use the blog as a data value in the v for. The method will return an array of the body array properties
<li v-for="{ body, index } in info" :key="index">
{{ body }}
</li>
I hope it helps...

Shopify Adding Image in Rich text box shows broken image after adding

I am attempting to add new block in Shopify using schema and Shopify liquid. I have added schema which is expected to add/import image one on left side and one for right side.I have created dynamic block just to show both images. When I added my schema , I am able to see the image rich text box to add images but when I add the images, I get them as broken images and when I inspect them in in browser i just get <img src=/>.I am quite close but something missing here.Is there something wrong with <img src={{settings.block.image}} /> ? Thanks.
Custom Block
{% elsif block.type == 'side_by_side' %}
<div class="homepage_content clearfix" >
<div class="container">
<div class="eight columns image_column">
<img src={{settings.block.image}} />
</div>
<div class="eight columns image_column">
<img src={{settings.block.image}} />
</div>
</div>
</div>
Schema
{
"type": "side_by_side",
"name": "side_by_side",
"settings": [
{
"type": "image_picker",
"id": "image-left",
"label": "Image-left"
},
{
"type": "image_picker",
"id": "image-right",
"label": "Image-right"
},
{
"type": "select",
"id": "layout",
"label": "Layout",
"default": "left",
"options": [
{
"value": "left",
"label": "Image on left"
},
{
"value": "right",
"label": "Image on right"
}
]
},
{
"type": "text",
"id": "title",
"label": "Heading",
"default": "Side by Side Engineering "
},
{
"type": "richtext",
"id": "text",
"label": "Text",
"default": "<p>Pair text with an image to give focus to your chosen product, collection, or blog post. Add details on availability, style, or even provide a review.</p>"
},
{
"type": "select",
"id": "text_alignment",
"label": "Text alignment",
"options": [
{
"value": "left",
"label": "Left"
},
{
"value": "center",
"label": "Center"
},
{
"value": "right",
"label": "Right"
}
],
"default": "left"
},
{
"type": "text",
"id": "button_label",
"label": "Button label"
},
{
"type": "url",
"id": "button_link",
"label": "Button link"
}
]
},
All images must include img_url in order for them to grab the CDN path to the image itself.
In addition you must target the block image this way block.settings.image not settings.block.image.
So your code should be {{ block.settings.image-left | img_url: '1024x' }} or the size you like it to be.

Vue js component with nested data

This is driving me crazy, I have nested data in an array and have not been successful in getting it to render using components, I am able to render it without a component though.
var data2 = {
"team": [{
"id":0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [
{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id":1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [
{
"id": "3",
"name": "name 3",
"text": "bio"
}
]
}
]}
What I am trying to do is loop through members, here is my current code
index.html
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id">
<detail v-for="mem in t.members" v-bind:ember="mem" v-bind:key="mem.id"></detail>
</entry>
</div>
and here is my js file
Vue.component('entry', {
props:['cat'],
template: '<div>{{cat.author}}</div>'
})
Vue.component('detail', {
props:['ember'],
template: '<div>{{ember.id}}</div>',
})
var vm2 = new Vue({
el: '#app2',
data: function() {
console.log(data2.team)
return data2;
}
});
The data in entry renders but nothing happens with detail, no warnings either, how do I proceed?
Note: When I approach it this way it DOES work, but this is not using a component:
var vm = new Vue({
el: '#app',
data: function() {
console.log(data2.team)
return data2;
}
});
and the html
<div id="app">
<div v-for="t in team" v-bind:key="t.id" v-bind:author="t.author">
{{t.author}}
<div v-for="m in t.members" v-bind:key="m.id">
{{m.name}}
</div>
</div>
</div>
You either need to add the detail component to the entry template, or you need to add a slot to the entry component.
Here is your code modified to use a slot.
console.clear()
var data2 = {
"team": [{
"id": 0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id": 1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [{
"id": "3",
"name": "name 3",
"text": "bio"
}]
}
]
}
Vue.component('entry', {
props: ['cat'],
template: '<div>{{cat.author}}<slot/></div>'
})
Vue.component('detail', {
props: ['ember'],
template: '<div>{{ember.id}}</div>',
})
var vm2 = new Vue({
el: '#app2',
data: function() {
console.log(data2.team)
return data2;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id">
<detail v-for="mem in t.members" v-bind:ember="mem" v-bind:key="mem.id">
</detail>
</entry>
</div>
And here it is modifying the entry component to include the detail.
console.clear()
var data2 = {
"team": [{
"id": 0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id": 1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [{
"id": "3",
"name": "name 3",
"text": "bio"
}]
}
]
}
Vue.component('detail', {
props: ['ember'],
template: '<div>{{ember.id}}</div>',
})
Vue.component('entry', {
props: ['cat'],
template: `<div>
{{cat.author}}
<detail v-for="mem in cat.members" v-bind:ember="mem" v-bind:key="mem.id">
</detail>
</div>`
})
var vm2 = new Vue({
el: '#app2',
data: function() {
return data2;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id"></entry>
</div>