feat: Entity directories, inline actions, and all entity fields are now available in the entity details view
This commit is contained in:
parent
32fea4ec30
commit
a2410fc9d6
|
|
@ -151,6 +151,11 @@ export declare type Entity = Message<"olivetin.api.v1.Entity"> & {
|
||||||
* @generated from field: repeated string directories = 4;
|
* @generated from field: repeated string directories = 4;
|
||||||
*/
|
*/
|
||||||
directories: string[];
|
directories: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generated from field: map<string, string> fields = 5;
|
||||||
|
*/
|
||||||
|
fields: { [key: string]: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -21,10 +21,14 @@
|
||||||
|
|
||||||
<h3>Used on Dashboards:</h3>
|
<h3>Used on Dashboards:</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="dash in def.usedOnDashboards">
|
<li v-for="dash in filteredDashboards(def.usedOnDashboards)" :key="dash">
|
||||||
<router-link :to="{ name: 'Dashboard', params: { title: dash } }">
|
<template v-if="isEntityDirectory(dash)">
|
||||||
{{ dash }}
|
{{ getDashboardTitle(dash) }} <span class="entity-directory-label">[Entity Directory]</span>
|
||||||
|
</template>
|
||||||
|
<router-link v-else-if="!dash.includes('entity:')" :to="{ name: 'Dashboard', params: { title: getDashboardTitle(dash) } }">
|
||||||
|
{{ getDashboardTitle(dash) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<span v-else>{{ dash }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,6 +48,21 @@
|
||||||
entityDefinitions.value = ret.entityDefinitions
|
entityDefinitions.value = ret.entityDefinitions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filteredDashboards(dashboards) {
|
||||||
|
return dashboards.filter(d => d && !d.includes('{{'))
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEntityDirectory(dashboardTitle) {
|
||||||
|
return dashboardTitle.endsWith(' [Entity Directory]')
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDashboardTitle(dashboardTitle) {
|
||||||
|
if (isEntityDirectory(dashboardTitle)) {
|
||||||
|
return dashboardTitle.slice(0, -' [Entity Directory]'.length)
|
||||||
|
}
|
||||||
|
return dashboardTitle
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchEntities()
|
fetchEntities()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,21 @@
|
||||||
</dd>
|
</dd>
|
||||||
<dt v-if="entityDetails.title">Title</dt>
|
<dt v-if="entityDetails.title">Title</dt>
|
||||||
<dd v-if="entityDetails.title">{{ entityDetails.title }}</dd>
|
<dd v-if="entityDetails.title">{{ entityDetails.title }}</dd>
|
||||||
|
<template v-if="entityDetails.fields">
|
||||||
|
<template v-for="(value, key) in entityDetails.fields" :key="key">
|
||||||
|
<dt>{{ key }}</dt>
|
||||||
|
<dd>{{ value }}</dd>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
</dl>
|
</dl>
|
||||||
<p v-if="!entityDetails.title">No details available for this entity.</p>
|
<p v-if="!entityDetails.title && (!entityDetails.fields || Object.keys(entityDetails.fields).length === 0)">No details available for this entity.</p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h3>Dashboard Entity Directories</h3>
|
<h3>Dashboard Entity Directories</h3>
|
||||||
<div v-if="entityDetails.directories && entityDetails.directories.length > 0" class="directories-section">
|
<div v-if="filteredDirectories.length > 0" class="directories-section">
|
||||||
<ul class="directory-list">
|
<ul class="directory-list">
|
||||||
<li v-for="directory in entityDetails.directories" :key="directory">
|
<li v-for="(directory, idx) in filteredDirectories" :key="idx">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{
|
:to="{
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
|
|
@ -50,7 +56,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { HugeiconsIcon } from '@hugeicons/vue'
|
import { HugeiconsIcon } from '@hugeicons/vue'
|
||||||
import { ArrowLeftIcon } from '@hugeicons/core-free-icons'
|
import { ArrowLeftIcon } from '@hugeicons/core-free-icons'
|
||||||
|
|
@ -64,6 +70,13 @@
|
||||||
entityKey: String
|
entityKey: String
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const filteredDirectories = computed(() => {
|
||||||
|
if (!entityDetails.value?.directories) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return entityDetails.value.directories.filter(d => d)
|
||||||
|
})
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
router.push({ name: 'Entities' })
|
router.push({ name: 'Entities' })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,17 @@ entities:
|
||||||
name: person
|
name: person
|
||||||
|
|
||||||
dashboards:
|
dashboards:
|
||||||
- title: People
|
- title: Second Dashboard
|
||||||
contents:
|
contents:
|
||||||
- type: action
|
- type: action
|
||||||
inlineAction:
|
inlineAction:
|
||||||
title: Third Action
|
title: Third Action
|
||||||
shell: echo "First Dashboard, Third Action!"
|
shell: echo "Second Dashboard, Third Action!"
|
||||||
|
|
||||||
- type: action
|
- type: action
|
||||||
inlineAction:
|
inlineAction:
|
||||||
title: Forth Action
|
title: Forth Action
|
||||||
shell: echo "First Dashboard, Forth Action!"
|
shell: echo "Second Dashboard, Fourth Action!"
|
||||||
|
|
||||||
- title: "Person: {{ person.name }}"
|
- title: "Person: {{ person.name }}"
|
||||||
type: fieldset
|
type: fieldset
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,10 @@ describe('config: multi-dashboard-includes', function () {
|
||||||
|
|
||||||
// Ensure actions from the second dashboard are not rendered here
|
// Ensure actions from the second dashboard are not rendered here
|
||||||
expect(titles).to.not.include('Third Action')
|
expect(titles).to.not.include('Third Action')
|
||||||
expect(titles).to.not.include('Forth Action')
|
expect(titles).to.not.include('Fourth Action')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Second Dashboard shows Third and Forth inline actions from include', async function () {
|
it('Second Dashboard shows Third and Fourth inline actions from include', async function () {
|
||||||
await getRootAndWait()
|
await getRootAndWait()
|
||||||
|
|
||||||
// Navigate to "Second Dashboard"
|
// Navigate to "Second Dashboard"
|
||||||
|
|
@ -96,7 +96,7 @@ describe('config: multi-dashboard-includes', function () {
|
||||||
const titles = await getActionTitlesOnDashboard('Second Dashboard')
|
const titles = await getActionTitlesOnDashboard('Second Dashboard')
|
||||||
|
|
||||||
expect(titles).to.include('Third Action')
|
expect(titles).to.include('Third Action')
|
||||||
expect(titles).to.include('Forth Action')
|
expect(titles).to.include('Fourth Action')
|
||||||
|
|
||||||
// Ensure actions from the first dashboard are not rendered here
|
// Ensure actions from the first dashboard are not rendered here
|
||||||
expect(titles).to.not.include('First Action')
|
expect(titles).to.not.include('First Action')
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ message Entity {
|
||||||
string unique_key = 2;
|
string unique_key = 2;
|
||||||
string type = 3;
|
string type = 3;
|
||||||
repeated string directories = 4;
|
repeated string directories = 4;
|
||||||
|
map<string, string> fields = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetDashboardResponse {
|
message GetDashboardResponse {
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ type Entity struct {
|
||||||
UniqueKey string `protobuf:"bytes,2,opt,name=unique_key,json=uniqueKey,proto3" json:"unique_key,omitempty"`
|
UniqueKey string `protobuf:"bytes,2,opt,name=unique_key,json=uniqueKey,proto3" json:"unique_key,omitempty"`
|
||||||
Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
|
Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
|
||||||
Directories []string `protobuf:"bytes,4,rep,name=directories,proto3" json:"directories,omitempty"`
|
Directories []string `protobuf:"bytes,4,rep,name=directories,proto3" json:"directories,omitempty"`
|
||||||
|
Fields map[string]string `protobuf:"bytes,5,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
@ -333,6 +334,13 @@ func (x *Entity) GetDirectories() []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Entity) GetFields() map[string]string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Fields
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type GetDashboardResponse struct {
|
type GetDashboardResponse struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
||||||
|
|
@ -3839,13 +3847,17 @@ const file_olivetin_api_v1_olivetin_proto_rawDesc = "" +
|
||||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"B\n" +
|
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"B\n" +
|
||||||
"\x14ActionArgumentChoice\x12\x14\n" +
|
"\x14ActionArgumentChoice\x12\x14\n" +
|
||||||
"\x05value\x18\x01 \x01(\tR\x05value\x12\x14\n" +
|
"\x05value\x18\x01 \x01(\tR\x05value\x12\x14\n" +
|
||||||
"\x05title\x18\x02 \x01(\tR\x05title\"s\n" +
|
"\x05title\x18\x02 \x01(\tR\x05title\"\xeb\x01\n" +
|
||||||
"\x06Entity\x12\x14\n" +
|
"\x06Entity\x12\x14\n" +
|
||||||
"\x05title\x18\x01 \x01(\tR\x05title\x12\x1d\n" +
|
"\x05title\x18\x01 \x01(\tR\x05title\x12\x1d\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"unique_key\x18\x02 \x01(\tR\tuniqueKey\x12\x12\n" +
|
"unique_key\x18\x02 \x01(\tR\tuniqueKey\x12\x12\n" +
|
||||||
"\x04type\x18\x03 \x01(\tR\x04type\x12 \n" +
|
"\x04type\x18\x03 \x01(\tR\x04type\x12 \n" +
|
||||||
"\vdirectories\x18\x04 \x03(\tR\vdirectories\"f\n" +
|
"\vdirectories\x18\x04 \x03(\tR\vdirectories\x12;\n" +
|
||||||
|
"\x06fields\x18\x05 \x03(\v2#.olivetin.api.v1.Entity.FieldsEntryR\x06fields\x1a9\n" +
|
||||||
|
"\vFieldsEntry\x12\x10\n" +
|
||||||
|
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||||
|
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"f\n" +
|
||||||
"\x14GetDashboardResponse\x12\x14\n" +
|
"\x14GetDashboardResponse\x12\x14\n" +
|
||||||
"\x05title\x18\x01 \x01(\tR\x05title\x128\n" +
|
"\x05title\x18\x01 \x01(\tR\x05title\x128\n" +
|
||||||
"\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"`\n" +
|
"\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"`\n" +
|
||||||
|
|
@ -4113,7 +4125,7 @@ func file_olivetin_api_v1_olivetin_proto_rawDescGZIP() []byte {
|
||||||
return file_olivetin_api_v1_olivetin_proto_rawDescData
|
return file_olivetin_api_v1_olivetin_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_olivetin_api_v1_olivetin_proto_msgTypes = make([]protoimpl.MessageInfo, 71)
|
var file_olivetin_api_v1_olivetin_proto_msgTypes = make([]protoimpl.MessageInfo, 72)
|
||||||
var file_olivetin_api_v1_olivetin_proto_goTypes = []any{
|
var file_olivetin_api_v1_olivetin_proto_goTypes = []any{
|
||||||
(*Action)(nil), // 0: olivetin.api.v1.Action
|
(*Action)(nil), // 0: olivetin.api.v1.Action
|
||||||
(*ActionArgument)(nil), // 1: olivetin.api.v1.ActionArgument
|
(*ActionArgument)(nil), // 1: olivetin.api.v1.ActionArgument
|
||||||
|
|
@ -4184,95 +4196,97 @@ var file_olivetin_api_v1_olivetin_proto_goTypes = []any{
|
||||||
(*GetEntityRequest)(nil), // 66: olivetin.api.v1.GetEntityRequest
|
(*GetEntityRequest)(nil), // 66: olivetin.api.v1.GetEntityRequest
|
||||||
(*RestartActionRequest)(nil), // 67: olivetin.api.v1.RestartActionRequest
|
(*RestartActionRequest)(nil), // 67: olivetin.api.v1.RestartActionRequest
|
||||||
nil, // 68: olivetin.api.v1.ActionArgument.SuggestionsEntry
|
nil, // 68: olivetin.api.v1.ActionArgument.SuggestionsEntry
|
||||||
nil, // 69: olivetin.api.v1.DumpVarsResponse.ContentsEntry
|
nil, // 69: olivetin.api.v1.Entity.FieldsEntry
|
||||||
nil, // 70: olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry
|
nil, // 70: olivetin.api.v1.DumpVarsResponse.ContentsEntry
|
||||||
|
nil, // 71: olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry
|
||||||
}
|
}
|
||||||
var file_olivetin_api_v1_olivetin_proto_depIdxs = []int32{
|
var file_olivetin_api_v1_olivetin_proto_depIdxs = []int32{
|
||||||
1, // 0: olivetin.api.v1.Action.arguments:type_name -> olivetin.api.v1.ActionArgument
|
1, // 0: olivetin.api.v1.Action.arguments:type_name -> olivetin.api.v1.ActionArgument
|
||||||
2, // 1: olivetin.api.v1.ActionArgument.choices:type_name -> olivetin.api.v1.ActionArgumentChoice
|
2, // 1: olivetin.api.v1.ActionArgument.choices:type_name -> olivetin.api.v1.ActionArgumentChoice
|
||||||
68, // 2: olivetin.api.v1.ActionArgument.suggestions:type_name -> olivetin.api.v1.ActionArgument.SuggestionsEntry
|
68, // 2: olivetin.api.v1.ActionArgument.suggestions:type_name -> olivetin.api.v1.ActionArgument.SuggestionsEntry
|
||||||
7, // 3: olivetin.api.v1.GetDashboardResponse.dashboard:type_name -> olivetin.api.v1.Dashboard
|
69, // 3: olivetin.api.v1.Entity.fields:type_name -> olivetin.api.v1.Entity.FieldsEntry
|
||||||
8, // 4: olivetin.api.v1.Dashboard.contents:type_name -> olivetin.api.v1.DashboardComponent
|
7, // 4: olivetin.api.v1.GetDashboardResponse.dashboard:type_name -> olivetin.api.v1.Dashboard
|
||||||
8, // 5: olivetin.api.v1.DashboardComponent.contents:type_name -> olivetin.api.v1.DashboardComponent
|
8, // 5: olivetin.api.v1.Dashboard.contents:type_name -> olivetin.api.v1.DashboardComponent
|
||||||
0, // 6: olivetin.api.v1.DashboardComponent.action:type_name -> olivetin.api.v1.Action
|
8, // 6: olivetin.api.v1.DashboardComponent.contents:type_name -> olivetin.api.v1.DashboardComponent
|
||||||
10, // 7: olivetin.api.v1.StartActionRequest.arguments:type_name -> olivetin.api.v1.StartActionArgument
|
0, // 7: olivetin.api.v1.DashboardComponent.action:type_name -> olivetin.api.v1.Action
|
||||||
10, // 8: olivetin.api.v1.StartActionAndWaitRequest.arguments:type_name -> olivetin.api.v1.StartActionArgument
|
10, // 8: olivetin.api.v1.StartActionRequest.arguments:type_name -> olivetin.api.v1.StartActionArgument
|
||||||
19, // 9: olivetin.api.v1.StartActionAndWaitResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
10, // 9: olivetin.api.v1.StartActionAndWaitRequest.arguments:type_name -> olivetin.api.v1.StartActionArgument
|
||||||
19, // 10: olivetin.api.v1.StartActionByGetAndWaitResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
19, // 10: olivetin.api.v1.StartActionAndWaitResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
||||||
19, // 11: olivetin.api.v1.GetLogsResponse.logs:type_name -> olivetin.api.v1.LogEntry
|
19, // 11: olivetin.api.v1.StartActionByGetAndWaitResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
||||||
19, // 12: olivetin.api.v1.GetActionLogsResponse.logs:type_name -> olivetin.api.v1.LogEntry
|
19, // 12: olivetin.api.v1.GetLogsResponse.logs:type_name -> olivetin.api.v1.LogEntry
|
||||||
19, // 13: olivetin.api.v1.ExecutionStatusResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
19, // 13: olivetin.api.v1.GetActionLogsResponse.logs:type_name -> olivetin.api.v1.LogEntry
|
||||||
69, // 14: olivetin.api.v1.DumpVarsResponse.contents:type_name -> olivetin.api.v1.DumpVarsResponse.ContentsEntry
|
19, // 14: olivetin.api.v1.ExecutionStatusResponse.log_entry:type_name -> olivetin.api.v1.LogEntry
|
||||||
70, // 15: olivetin.api.v1.DumpPublicIdActionMapResponse.contents:type_name -> olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry
|
70, // 15: olivetin.api.v1.DumpVarsResponse.contents:type_name -> olivetin.api.v1.DumpVarsResponse.ContentsEntry
|
||||||
43, // 16: olivetin.api.v1.EventStreamResponse.entity_changed:type_name -> olivetin.api.v1.EventEntityChanged
|
71, // 16: olivetin.api.v1.DumpPublicIdActionMapResponse.contents:type_name -> olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry
|
||||||
44, // 17: olivetin.api.v1.EventStreamResponse.config_changed:type_name -> olivetin.api.v1.EventConfigChanged
|
43, // 17: olivetin.api.v1.EventStreamResponse.entity_changed:type_name -> olivetin.api.v1.EventEntityChanged
|
||||||
45, // 18: olivetin.api.v1.EventStreamResponse.execution_finished:type_name -> olivetin.api.v1.EventExecutionFinished
|
44, // 18: olivetin.api.v1.EventStreamResponse.config_changed:type_name -> olivetin.api.v1.EventConfigChanged
|
||||||
46, // 19: olivetin.api.v1.EventStreamResponse.execution_started:type_name -> olivetin.api.v1.EventExecutionStarted
|
45, // 19: olivetin.api.v1.EventStreamResponse.execution_finished:type_name -> olivetin.api.v1.EventExecutionFinished
|
||||||
42, // 20: olivetin.api.v1.EventStreamResponse.output_chunk:type_name -> olivetin.api.v1.EventOutputChunk
|
46, // 20: olivetin.api.v1.EventStreamResponse.execution_started:type_name -> olivetin.api.v1.EventExecutionStarted
|
||||||
19, // 21: olivetin.api.v1.EventExecutionFinished.log_entry:type_name -> olivetin.api.v1.LogEntry
|
42, // 21: olivetin.api.v1.EventStreamResponse.output_chunk:type_name -> olivetin.api.v1.EventOutputChunk
|
||||||
19, // 22: olivetin.api.v1.EventExecutionStarted.log_entry:type_name -> olivetin.api.v1.LogEntry
|
19, // 22: olivetin.api.v1.EventExecutionFinished.log_entry:type_name -> olivetin.api.v1.LogEntry
|
||||||
60, // 23: olivetin.api.v1.InitResponse.oAuth2Providers:type_name -> olivetin.api.v1.OAuth2Provider
|
19, // 23: olivetin.api.v1.EventExecutionStarted.log_entry:type_name -> olivetin.api.v1.LogEntry
|
||||||
59, // 24: olivetin.api.v1.InitResponse.additionalLinks:type_name -> olivetin.api.v1.AdditionalLink
|
60, // 24: olivetin.api.v1.InitResponse.oAuth2Providers:type_name -> olivetin.api.v1.OAuth2Provider
|
||||||
5, // 25: olivetin.api.v1.InitResponse.effective_policy:type_name -> olivetin.api.v1.EffectivePolicy
|
59, // 25: olivetin.api.v1.InitResponse.additionalLinks:type_name -> olivetin.api.v1.AdditionalLink
|
||||||
0, // 26: olivetin.api.v1.GetActionBindingResponse.action:type_name -> olivetin.api.v1.Action
|
5, // 26: olivetin.api.v1.InitResponse.effective_policy:type_name -> olivetin.api.v1.EffectivePolicy
|
||||||
65, // 27: olivetin.api.v1.GetEntitiesResponse.entity_definitions:type_name -> olivetin.api.v1.EntityDefinition
|
0, // 27: olivetin.api.v1.GetActionBindingResponse.action:type_name -> olivetin.api.v1.Action
|
||||||
3, // 28: olivetin.api.v1.EntityDefinition.instances:type_name -> olivetin.api.v1.Entity
|
65, // 28: olivetin.api.v1.GetEntitiesResponse.entity_definitions:type_name -> olivetin.api.v1.EntityDefinition
|
||||||
35, // 29: olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry.value:type_name -> olivetin.api.v1.ActionEntityPair
|
3, // 29: olivetin.api.v1.EntityDefinition.instances:type_name -> olivetin.api.v1.Entity
|
||||||
6, // 30: olivetin.api.v1.OliveTinApiService.GetDashboard:input_type -> olivetin.api.v1.GetDashboardRequest
|
35, // 30: olivetin.api.v1.DumpPublicIdActionMapResponse.ContentsEntry.value:type_name -> olivetin.api.v1.ActionEntityPair
|
||||||
9, // 31: olivetin.api.v1.OliveTinApiService.StartAction:input_type -> olivetin.api.v1.StartActionRequest
|
6, // 31: olivetin.api.v1.OliveTinApiService.GetDashboard:input_type -> olivetin.api.v1.GetDashboardRequest
|
||||||
12, // 32: olivetin.api.v1.OliveTinApiService.StartActionAndWait:input_type -> olivetin.api.v1.StartActionAndWaitRequest
|
9, // 32: olivetin.api.v1.OliveTinApiService.StartAction:input_type -> olivetin.api.v1.StartActionRequest
|
||||||
14, // 33: olivetin.api.v1.OliveTinApiService.StartActionByGet:input_type -> olivetin.api.v1.StartActionByGetRequest
|
12, // 33: olivetin.api.v1.OliveTinApiService.StartActionAndWait:input_type -> olivetin.api.v1.StartActionAndWaitRequest
|
||||||
16, // 34: olivetin.api.v1.OliveTinApiService.StartActionByGetAndWait:input_type -> olivetin.api.v1.StartActionByGetAndWaitRequest
|
14, // 34: olivetin.api.v1.OliveTinApiService.StartActionByGet:input_type -> olivetin.api.v1.StartActionByGetRequest
|
||||||
67, // 35: olivetin.api.v1.OliveTinApiService.RestartAction:input_type -> olivetin.api.v1.RestartActionRequest
|
16, // 35: olivetin.api.v1.OliveTinApiService.StartActionByGetAndWait:input_type -> olivetin.api.v1.StartActionByGetAndWaitRequest
|
||||||
47, // 36: olivetin.api.v1.OliveTinApiService.KillAction:input_type -> olivetin.api.v1.KillActionRequest
|
67, // 36: olivetin.api.v1.OliveTinApiService.RestartAction:input_type -> olivetin.api.v1.RestartActionRequest
|
||||||
27, // 37: olivetin.api.v1.OliveTinApiService.ExecutionStatus:input_type -> olivetin.api.v1.ExecutionStatusRequest
|
47, // 37: olivetin.api.v1.OliveTinApiService.KillAction:input_type -> olivetin.api.v1.KillActionRequest
|
||||||
18, // 38: olivetin.api.v1.OliveTinApiService.GetLogs:input_type -> olivetin.api.v1.GetLogsRequest
|
27, // 38: olivetin.api.v1.OliveTinApiService.ExecutionStatus:input_type -> olivetin.api.v1.ExecutionStatusRequest
|
||||||
21, // 39: olivetin.api.v1.OliveTinApiService.GetActionLogs:input_type -> olivetin.api.v1.GetActionLogsRequest
|
18, // 39: olivetin.api.v1.OliveTinApiService.GetLogs:input_type -> olivetin.api.v1.GetLogsRequest
|
||||||
23, // 40: olivetin.api.v1.OliveTinApiService.ValidateArgumentType:input_type -> olivetin.api.v1.ValidateArgumentTypeRequest
|
21, // 40: olivetin.api.v1.OliveTinApiService.GetActionLogs:input_type -> olivetin.api.v1.GetActionLogsRequest
|
||||||
29, // 41: olivetin.api.v1.OliveTinApiService.WhoAmI:input_type -> olivetin.api.v1.WhoAmIRequest
|
23, // 41: olivetin.api.v1.OliveTinApiService.ValidateArgumentType:input_type -> olivetin.api.v1.ValidateArgumentTypeRequest
|
||||||
31, // 42: olivetin.api.v1.OliveTinApiService.SosReport:input_type -> olivetin.api.v1.SosReportRequest
|
29, // 42: olivetin.api.v1.OliveTinApiService.WhoAmI:input_type -> olivetin.api.v1.WhoAmIRequest
|
||||||
33, // 43: olivetin.api.v1.OliveTinApiService.DumpVars:input_type -> olivetin.api.v1.DumpVarsRequest
|
31, // 43: olivetin.api.v1.OliveTinApiService.SosReport:input_type -> olivetin.api.v1.SosReportRequest
|
||||||
36, // 44: olivetin.api.v1.OliveTinApiService.DumpPublicIdActionMap:input_type -> olivetin.api.v1.DumpPublicIdActionMapRequest
|
33, // 44: olivetin.api.v1.OliveTinApiService.DumpVars:input_type -> olivetin.api.v1.DumpVarsRequest
|
||||||
38, // 45: olivetin.api.v1.OliveTinApiService.GetReadyz:input_type -> olivetin.api.v1.GetReadyzRequest
|
36, // 45: olivetin.api.v1.OliveTinApiService.DumpPublicIdActionMap:input_type -> olivetin.api.v1.DumpPublicIdActionMapRequest
|
||||||
49, // 46: olivetin.api.v1.OliveTinApiService.LocalUserLogin:input_type -> olivetin.api.v1.LocalUserLoginRequest
|
38, // 46: olivetin.api.v1.OliveTinApiService.GetReadyz:input_type -> olivetin.api.v1.GetReadyzRequest
|
||||||
51, // 47: olivetin.api.v1.OliveTinApiService.PasswordHash:input_type -> olivetin.api.v1.PasswordHashRequest
|
49, // 47: olivetin.api.v1.OliveTinApiService.LocalUserLogin:input_type -> olivetin.api.v1.LocalUserLoginRequest
|
||||||
53, // 48: olivetin.api.v1.OliveTinApiService.Logout:input_type -> olivetin.api.v1.LogoutRequest
|
51, // 48: olivetin.api.v1.OliveTinApiService.PasswordHash:input_type -> olivetin.api.v1.PasswordHashRequest
|
||||||
40, // 49: olivetin.api.v1.OliveTinApiService.EventStream:input_type -> olivetin.api.v1.EventStreamRequest
|
53, // 49: olivetin.api.v1.OliveTinApiService.Logout:input_type -> olivetin.api.v1.LogoutRequest
|
||||||
55, // 50: olivetin.api.v1.OliveTinApiService.GetDiagnostics:input_type -> olivetin.api.v1.GetDiagnosticsRequest
|
40, // 50: olivetin.api.v1.OliveTinApiService.EventStream:input_type -> olivetin.api.v1.EventStreamRequest
|
||||||
57, // 51: olivetin.api.v1.OliveTinApiService.Init:input_type -> olivetin.api.v1.InitRequest
|
55, // 51: olivetin.api.v1.OliveTinApiService.GetDiagnostics:input_type -> olivetin.api.v1.GetDiagnosticsRequest
|
||||||
61, // 52: olivetin.api.v1.OliveTinApiService.GetActionBinding:input_type -> olivetin.api.v1.GetActionBindingRequest
|
57, // 52: olivetin.api.v1.OliveTinApiService.Init:input_type -> olivetin.api.v1.InitRequest
|
||||||
63, // 53: olivetin.api.v1.OliveTinApiService.GetEntities:input_type -> olivetin.api.v1.GetEntitiesRequest
|
61, // 53: olivetin.api.v1.OliveTinApiService.GetActionBinding:input_type -> olivetin.api.v1.GetActionBindingRequest
|
||||||
66, // 54: olivetin.api.v1.OliveTinApiService.GetEntity:input_type -> olivetin.api.v1.GetEntityRequest
|
63, // 54: olivetin.api.v1.OliveTinApiService.GetEntities:input_type -> olivetin.api.v1.GetEntitiesRequest
|
||||||
4, // 55: olivetin.api.v1.OliveTinApiService.GetDashboard:output_type -> olivetin.api.v1.GetDashboardResponse
|
66, // 55: olivetin.api.v1.OliveTinApiService.GetEntity:input_type -> olivetin.api.v1.GetEntityRequest
|
||||||
11, // 56: olivetin.api.v1.OliveTinApiService.StartAction:output_type -> olivetin.api.v1.StartActionResponse
|
4, // 56: olivetin.api.v1.OliveTinApiService.GetDashboard:output_type -> olivetin.api.v1.GetDashboardResponse
|
||||||
13, // 57: olivetin.api.v1.OliveTinApiService.StartActionAndWait:output_type -> olivetin.api.v1.StartActionAndWaitResponse
|
11, // 57: olivetin.api.v1.OliveTinApiService.StartAction:output_type -> olivetin.api.v1.StartActionResponse
|
||||||
15, // 58: olivetin.api.v1.OliveTinApiService.StartActionByGet:output_type -> olivetin.api.v1.StartActionByGetResponse
|
13, // 58: olivetin.api.v1.OliveTinApiService.StartActionAndWait:output_type -> olivetin.api.v1.StartActionAndWaitResponse
|
||||||
17, // 59: olivetin.api.v1.OliveTinApiService.StartActionByGetAndWait:output_type -> olivetin.api.v1.StartActionByGetAndWaitResponse
|
15, // 59: olivetin.api.v1.OliveTinApiService.StartActionByGet:output_type -> olivetin.api.v1.StartActionByGetResponse
|
||||||
11, // 60: olivetin.api.v1.OliveTinApiService.RestartAction:output_type -> olivetin.api.v1.StartActionResponse
|
17, // 60: olivetin.api.v1.OliveTinApiService.StartActionByGetAndWait:output_type -> olivetin.api.v1.StartActionByGetAndWaitResponse
|
||||||
48, // 61: olivetin.api.v1.OliveTinApiService.KillAction:output_type -> olivetin.api.v1.KillActionResponse
|
11, // 61: olivetin.api.v1.OliveTinApiService.RestartAction:output_type -> olivetin.api.v1.StartActionResponse
|
||||||
28, // 62: olivetin.api.v1.OliveTinApiService.ExecutionStatus:output_type -> olivetin.api.v1.ExecutionStatusResponse
|
48, // 62: olivetin.api.v1.OliveTinApiService.KillAction:output_type -> olivetin.api.v1.KillActionResponse
|
||||||
20, // 63: olivetin.api.v1.OliveTinApiService.GetLogs:output_type -> olivetin.api.v1.GetLogsResponse
|
28, // 63: olivetin.api.v1.OliveTinApiService.ExecutionStatus:output_type -> olivetin.api.v1.ExecutionStatusResponse
|
||||||
22, // 64: olivetin.api.v1.OliveTinApiService.GetActionLogs:output_type -> olivetin.api.v1.GetActionLogsResponse
|
20, // 64: olivetin.api.v1.OliveTinApiService.GetLogs:output_type -> olivetin.api.v1.GetLogsResponse
|
||||||
24, // 65: olivetin.api.v1.OliveTinApiService.ValidateArgumentType:output_type -> olivetin.api.v1.ValidateArgumentTypeResponse
|
22, // 65: olivetin.api.v1.OliveTinApiService.GetActionLogs:output_type -> olivetin.api.v1.GetActionLogsResponse
|
||||||
30, // 66: olivetin.api.v1.OliveTinApiService.WhoAmI:output_type -> olivetin.api.v1.WhoAmIResponse
|
24, // 66: olivetin.api.v1.OliveTinApiService.ValidateArgumentType:output_type -> olivetin.api.v1.ValidateArgumentTypeResponse
|
||||||
32, // 67: olivetin.api.v1.OliveTinApiService.SosReport:output_type -> olivetin.api.v1.SosReportResponse
|
30, // 67: olivetin.api.v1.OliveTinApiService.WhoAmI:output_type -> olivetin.api.v1.WhoAmIResponse
|
||||||
34, // 68: olivetin.api.v1.OliveTinApiService.DumpVars:output_type -> olivetin.api.v1.DumpVarsResponse
|
32, // 68: olivetin.api.v1.OliveTinApiService.SosReport:output_type -> olivetin.api.v1.SosReportResponse
|
||||||
37, // 69: olivetin.api.v1.OliveTinApiService.DumpPublicIdActionMap:output_type -> olivetin.api.v1.DumpPublicIdActionMapResponse
|
34, // 69: olivetin.api.v1.OliveTinApiService.DumpVars:output_type -> olivetin.api.v1.DumpVarsResponse
|
||||||
39, // 70: olivetin.api.v1.OliveTinApiService.GetReadyz:output_type -> olivetin.api.v1.GetReadyzResponse
|
37, // 70: olivetin.api.v1.OliveTinApiService.DumpPublicIdActionMap:output_type -> olivetin.api.v1.DumpPublicIdActionMapResponse
|
||||||
50, // 71: olivetin.api.v1.OliveTinApiService.LocalUserLogin:output_type -> olivetin.api.v1.LocalUserLoginResponse
|
39, // 71: olivetin.api.v1.OliveTinApiService.GetReadyz:output_type -> olivetin.api.v1.GetReadyzResponse
|
||||||
52, // 72: olivetin.api.v1.OliveTinApiService.PasswordHash:output_type -> olivetin.api.v1.PasswordHashResponse
|
50, // 72: olivetin.api.v1.OliveTinApiService.LocalUserLogin:output_type -> olivetin.api.v1.LocalUserLoginResponse
|
||||||
54, // 73: olivetin.api.v1.OliveTinApiService.Logout:output_type -> olivetin.api.v1.LogoutResponse
|
52, // 73: olivetin.api.v1.OliveTinApiService.PasswordHash:output_type -> olivetin.api.v1.PasswordHashResponse
|
||||||
41, // 74: olivetin.api.v1.OliveTinApiService.EventStream:output_type -> olivetin.api.v1.EventStreamResponse
|
54, // 74: olivetin.api.v1.OliveTinApiService.Logout:output_type -> olivetin.api.v1.LogoutResponse
|
||||||
56, // 75: olivetin.api.v1.OliveTinApiService.GetDiagnostics:output_type -> olivetin.api.v1.GetDiagnosticsResponse
|
41, // 75: olivetin.api.v1.OliveTinApiService.EventStream:output_type -> olivetin.api.v1.EventStreamResponse
|
||||||
58, // 76: olivetin.api.v1.OliveTinApiService.Init:output_type -> olivetin.api.v1.InitResponse
|
56, // 76: olivetin.api.v1.OliveTinApiService.GetDiagnostics:output_type -> olivetin.api.v1.GetDiagnosticsResponse
|
||||||
62, // 77: olivetin.api.v1.OliveTinApiService.GetActionBinding:output_type -> olivetin.api.v1.GetActionBindingResponse
|
58, // 77: olivetin.api.v1.OliveTinApiService.Init:output_type -> olivetin.api.v1.InitResponse
|
||||||
64, // 78: olivetin.api.v1.OliveTinApiService.GetEntities:output_type -> olivetin.api.v1.GetEntitiesResponse
|
62, // 78: olivetin.api.v1.OliveTinApiService.GetActionBinding:output_type -> olivetin.api.v1.GetActionBindingResponse
|
||||||
3, // 79: olivetin.api.v1.OliveTinApiService.GetEntity:output_type -> olivetin.api.v1.Entity
|
64, // 79: olivetin.api.v1.OliveTinApiService.GetEntities:output_type -> olivetin.api.v1.GetEntitiesResponse
|
||||||
55, // [55:80] is the sub-list for method output_type
|
3, // 80: olivetin.api.v1.OliveTinApiService.GetEntity:output_type -> olivetin.api.v1.Entity
|
||||||
30, // [30:55] is the sub-list for method input_type
|
56, // [56:81] is the sub-list for method output_type
|
||||||
30, // [30:30] is the sub-list for extension type_name
|
31, // [31:56] is the sub-list for method input_type
|
||||||
30, // [30:30] is the sub-list for extension extendee
|
31, // [31:31] is the sub-list for extension type_name
|
||||||
0, // [0:30] is the sub-list for field type_name
|
31, // [31:31] is the sub-list for extension extendee
|
||||||
|
0, // [0:31] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_olivetin_api_v1_olivetin_proto_init() }
|
func init() { file_olivetin_api_v1_olivetin_proto_init() }
|
||||||
|
|
@ -4293,7 +4307,7 @@ func file_olivetin_api_v1_olivetin_proto_init() {
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_olivetin_api_v1_olivetin_proto_rawDesc), len(file_olivetin_api_v1_olivetin_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_olivetin_api_v1_olivetin_proto_rawDesc), len(file_olivetin_api_v1_olivetin_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 71,
|
NumMessages: 72,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -977,24 +977,49 @@ func buildSortedEntityInstances(entityType string, entityInstances map[string]*e
|
||||||
|
|
||||||
func findDashboardsForEntity(entityTitle string, dashboards []*config.DashboardComponent) []string {
|
func findDashboardsForEntity(entityTitle string, dashboards []*config.DashboardComponent) []string {
|
||||||
var foundDashboards []string
|
var foundDashboards []string
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
|
||||||
findEntityInComponents(entityTitle, "", dashboards, &foundDashboards)
|
findEntityInComponents(entityTitle, "", dashboards, &foundDashboards, seen)
|
||||||
|
|
||||||
return foundDashboards
|
return foundDashboards
|
||||||
}
|
}
|
||||||
|
|
||||||
func findEntityInComponents(entityTitle string, parentTitle string, components []*config.DashboardComponent, foundDashboards *[]string) {
|
func findEntityInComponents(entityTitle string, parentTitle string, components []*config.DashboardComponent, foundDashboards *[]string, seen map[string]bool) {
|
||||||
for _, component := range components {
|
for _, component := range components {
|
||||||
if component.Entity == entityTitle {
|
if component.Entity == entityTitle {
|
||||||
*foundDashboards = append(*foundDashboards, parentTitle)
|
addEntityDashboard(component, parentTitle, foundDashboards, seen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(component.Contents) > 0 {
|
if len(component.Contents) > 0 {
|
||||||
findEntityInComponents(entityTitle, component.Title, component.Contents, foundDashboards)
|
findEntityInComponents(entityTitle, component.Title, component.Contents, foundDashboards, seen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addEntityDashboard(component *config.DashboardComponent, parentTitle string, foundDashboards *[]string, seen map[string]bool) {
|
||||||
|
if component.Type == "directory" {
|
||||||
|
addEntityDirectory(component, foundDashboards, seen)
|
||||||
|
} else {
|
||||||
|
addParentDashboard(parentTitle, foundDashboards, seen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addEntityDirectory(component *config.DashboardComponent, foundDashboards *[]string, seen map[string]bool) {
|
||||||
|
dashboardTitle := component.Title + " [Entity Directory]"
|
||||||
|
if !seen[dashboardTitle] {
|
||||||
|
*foundDashboards = append(*foundDashboards, dashboardTitle)
|
||||||
|
seen[dashboardTitle] = true
|
||||||
|
seen[component.Title] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addParentDashboard(parentTitle string, foundDashboards *[]string, seen map[string]bool) {
|
||||||
|
if parentTitle != "" && !seen[parentTitle] {
|
||||||
|
*foundDashboards = append(*foundDashboards, parentTitle)
|
||||||
|
seen[parentTitle] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func findDirectoriesInEntityFieldsets(entityType string, dashboards []*config.DashboardComponent) []string {
|
func findDirectoriesInEntityFieldsets(entityType string, dashboards []*config.DashboardComponent) []string {
|
||||||
var directories []string
|
var directories []string
|
||||||
|
|
||||||
|
|
@ -1036,26 +1061,46 @@ func (api *oliveTinAPI) GetEntity(ctx ctx.Context, req *connect.Request[apiv1.Ge
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := &apiv1.Entity{}
|
|
||||||
|
|
||||||
instances := entities.GetEntityInstances(req.Msg.Type)
|
instances := entities.GetEntityInstances(req.Msg.Type)
|
||||||
|
|
||||||
log.Infof("msg: %+v", req.Msg)
|
|
||||||
|
|
||||||
if len(instances) == 0 {
|
if len(instances) == 0 {
|
||||||
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("entity type %s not found", req.Msg.Type))
|
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("entity type %s not found", req.Msg.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
if entity, ok := instances[req.Msg.UniqueKey]; !ok {
|
entity, ok := instances[req.Msg.UniqueKey]
|
||||||
|
if !ok {
|
||||||
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("entity with unique key %s not found in type %s", req.Msg.UniqueKey, req.Msg.Type))
|
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("entity with unique key %s not found in type %s", req.Msg.UniqueKey, req.Msg.Type))
|
||||||
} else {
|
|
||||||
res.Title = entity.Title
|
|
||||||
res.UniqueKey = entity.UniqueKey
|
|
||||||
res.Type = req.Msg.Type
|
|
||||||
res.Directories = findDirectoriesInEntityFieldsets(req.Msg.Type, api.cfg.Dashboards)
|
|
||||||
|
|
||||||
return connect.NewResponse(res), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res := buildEntityResponse(entity, req.Msg.Type, api.cfg.Dashboards)
|
||||||
|
return connect.NewResponse(res), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildEntityResponse(entity *entities.Entity, entityType string, dashboards []*config.DashboardComponent) *apiv1.Entity {
|
||||||
|
res := &apiv1.Entity{
|
||||||
|
Title: entity.Title,
|
||||||
|
UniqueKey: entity.UniqueKey,
|
||||||
|
Type: entityType,
|
||||||
|
Directories: findDirectoriesInEntityFieldsets(entityType, dashboards),
|
||||||
|
Fields: serializeEntityFields(entity.Data),
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeEntityFields(data any) map[string]string {
|
||||||
|
if data == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dataMap, ok := data.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := make(map[string]string)
|
||||||
|
for k, v := range dataMap {
|
||||||
|
fields[k] = fmt.Sprintf("%v", v)
|
||||||
|
}
|
||||||
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *oliveTinAPI) RestartAction(ctx ctx.Context, req *connect.Request[apiv1.RestartActionRequest]) (*connect.Response[apiv1.StartActionResponse], error) {
|
func (api *oliveTinAPI) RestartAction(ctx ctx.Context, req *connect.Request[apiv1.RestartActionRequest]) (*connect.Response[apiv1.StartActionResponse], error) {
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,23 @@ func (cfg *Config) sanitizeDashboardsForInlineActions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (cfg *Config) sanitizeDashboardComponentForInlineActions(component *DashboardComponent) {
|
func (cfg *Config) sanitizeDashboardComponentForInlineActions(component *DashboardComponent) {
|
||||||
|
visited := make(map[*DashboardComponent]bool)
|
||||||
|
cfg.sanitizeDashboardComponentForInlineActionsHelper(component, visited)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) sanitizeDashboardComponentForInlineActionsHelper(component *DashboardComponent, visited map[*DashboardComponent]bool) {
|
||||||
if component == nil {
|
if component == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if visited[component] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
visited[component] = true
|
||||||
|
|
||||||
cfg.sanitizeInlineAction(component)
|
cfg.sanitizeInlineAction(component)
|
||||||
cfg.sanitizeChildDashboardComponents(component)
|
cfg.sanitizeChildDashboardComponents(component, visited)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) sanitizeInlineAction(component *DashboardComponent) {
|
func (cfg *Config) sanitizeInlineAction(component *DashboardComponent) {
|
||||||
|
|
@ -107,13 +118,13 @@ func (cfg *Config) inlineActionIDExists(action *Action) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) sanitizeChildDashboardComponents(component *DashboardComponent) {
|
func (cfg *Config) sanitizeChildDashboardComponents(component *DashboardComponent, visited map[*DashboardComponent]bool) {
|
||||||
for _, child := range component.Contents {
|
for _, child := range component.Contents {
|
||||||
if child.Entity == "" {
|
if child.Entity == "" {
|
||||||
child.Entity = component.Entity
|
child.Entity = component.Entity
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.sanitizeDashboardComponentForInlineActions(child)
|
cfg.sanitizeDashboardComponentForInlineActionsHelper(child, visited)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ func findEntityTitle(data any) string {
|
||||||
keys[lookupKey] = k
|
keys[lookupKey] = k
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, key := range []string{"title", "name", "id"} {
|
for _, key := range []string{"title", "name", "id", "hostname", "host", "label"} {
|
||||||
if lookupKey, exists := keys[strings.ToLower(key)]; exists {
|
if lookupKey, exists := keys[strings.ToLower(key)]; exists {
|
||||||
if value, ok := mapData[lookupKey]; ok {
|
if value, ok := mapData[lookupKey]; ok {
|
||||||
if valueStr, ok := value.(string); ok {
|
if valueStr, ok := value.(string); ok {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,9 @@ func recurseDashboardForActionTitles(component *config.DashboardComponent, req *
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = sub.InlineAction.Title
|
title = sub.InlineAction.Title
|
||||||
}
|
}
|
||||||
req.DashboardActionTitles = append(req.DashboardActionTitles, title)
|
if title != "" {
|
||||||
|
req.DashboardActionTitles = append(req.DashboardActionTitles, title)
|
||||||
|
}
|
||||||
} else if sub.Type == "link" || sub.Type == "" {
|
} else if sub.Type == "link" || sub.Type == "" {
|
||||||
req.DashboardActionTitles = append(req.DashboardActionTitles, sub.Title)
|
req.DashboardActionTitles = append(req.DashboardActionTitles, sub.Title)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue