From c8d5e3a192af0219dd81bb00fbb044bc3f2c415b Mon Sep 17 00:00:00 2001 From: Cody Jackson Date: Tue, 11 Jan 2022 15:10:07 -0700 Subject: [PATCH 1/4] Fixing some issues that occur when empty results are received --- product/opni/components/Breakdown.vue | 8 ++++---- .../WorkloadBreakdownAggregation.ts | 14 +++++++------- product/opni/utils/munging.js | 5 +++++ product/opni/utils/requests.ts | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/product/opni/components/Breakdown.vue b/product/opni/components/Breakdown.vue index 4aac8a34c..7c25775b8 100644 --- a/product/opni/components/Breakdown.vue +++ b/product/opni/components/Breakdown.vue @@ -47,10 +47,10 @@ export default { const breakdowns = await getBreakdowns(from, to); - this.podBreakdown = breakdowns.pods; - this.namespaceBreakdown = breakdowns.namespaces; - this.workloadBreakdown = breakdowns.workloads; - this.controlPlaneBreakdown = breakdowns.controlPlanes; + this.podBreakdown = breakdowns?.pods || []; + this.namespaceBreakdown = breakdowns?.namespaces || []; + this.workloadBreakdown = breakdowns?.workloads || []; + this.controlPlaneBreakdown = breakdowns?.controlPlanes || []; this.loading = false; } diff --git a/product/opni/models/overallBreakdown/WorkloadBreakdownAggregation.ts b/product/opni/models/overallBreakdown/WorkloadBreakdownAggregation.ts index 17acf8cda..bd94026ec 100644 --- a/product/opni/models/overallBreakdown/WorkloadBreakdownAggregation.ts +++ b/product/opni/models/overallBreakdown/WorkloadBreakdownAggregation.ts @@ -20,12 +20,12 @@ export class WorkloadBreakdownAggregation { statefulSet: WorkloadBreakdown[]; constructor(response: WorkloadBreakdownAggregationResponse) { - this.customResource = response.CustomResource.map(b => new WorkloadBreakdown(b, 'CustomResource')); - this.daemonSet = response.DaemonSet.map(b => new WorkloadBreakdown(b, 'DaemonSet')); - this.deployment = response.Deployment.map(b => new WorkloadBreakdown(b, 'Deployment')); - this.independent = response.Independent.map(b => new WorkloadBreakdown(b, 'Independent')); - this.job = response.Job.map(b => new WorkloadBreakdown(b, 'Job')); - this.replicaSet = response.ReplicaSet.map(b => new WorkloadBreakdown(b, 'ReplicaSet')); - this.statefulSet = response.StatefulSet.map(b => new WorkloadBreakdown(b, 'StatefulSet')); + this.customResource = response?.CustomResource?.map(b => new WorkloadBreakdown(b, 'CustomResource')) || []; + this.daemonSet = response?.DaemonSet?.map(b => new WorkloadBreakdown(b, 'DaemonSet')) || []; + this.deployment = response?.Deployment?.map(b => new WorkloadBreakdown(b, 'Deployment')) || []; + this.independent = response?.Independent?.map(b => new WorkloadBreakdown(b, 'Independent')) || []; + this.job = response?.Job?.map(b => new WorkloadBreakdown(b, 'Job')) || []; + this.replicaSet = response?.ReplicaSet?.map(b => new WorkloadBreakdown(b, 'ReplicaSet')) || []; + this.statefulSet = response?.StatefulSet?.map(b => new WorkloadBreakdown(b, 'StatefulSet')) || []; } } diff --git a/product/opni/utils/munging.js b/product/opni/utils/munging.js index 16da7b7bb..fcb484d8c 100644 --- a/product/opni/utils/munging.js +++ b/product/opni/utils/munging.js @@ -1,6 +1,11 @@ export function formatForTimeseries(data) { + const keys = ['anomaly', 'normal', 'suspicious']; const out = {}; + keys.forEach((key) => { + out[[this.$store.getters['i18n/withFallback'](`opni.chart.labels.${ key }`, { count: 1 }, key)]] = { data: [] }; + }); + data.forEach((entry) => { Object.entries(entry).forEach(([key, value]) => { const label = this.$store.getters['i18n/withFallback'](`opni.chart.labels.${ key }`, { count: 1 }, key); diff --git a/product/opni/utils/requests.ts b/product/opni/utils/requests.ts index 1f0e477c6..912bc3e0f 100644 --- a/product/opni/utils/requests.ts +++ b/product/opni/utils/requests.ts @@ -17,7 +17,7 @@ type LogLevel = 'Normal' | 'Anomalous' | 'Suspicious'; export async function getAreasOfInterest(now: Dayjs, range: UnitCount, granularity: Granularity): Promise { const from = getStartTime(now, range, granularity); const to = now; - const response = (await axios.get(`opni-api/areas_of_interest?start_ts=${ from.valueOf() }&end_ts=${ to.valueOf() }`))?.data; + const response = (await axios.get(`opni-api/areas_of_interest?start_ts=${ from.valueOf() }&end_ts=${ to.valueOf() }`))?.data || []; return (response) .filter(r => r.start_ts > 0 && r.end_ts > 0) From c6cc994119843323345c139b74f1b188761445d6 Mon Sep 17 00:00:00 2001 From: Cody Jackson Date: Wed, 12 Jan 2022 23:45:39 -0700 Subject: [PATCH 2/4] Making log drawer resizable and log messages collapsable --- assets/translations/en-us.yaml | 1 + components/Drawer.vue | 113 ++++++++++++++++-- components/formatter/Collapse.vue | 41 +++++++ components/formatter/KibanaLink.vue | 38 ++++++ product/opni/components/Configurator.vue | 7 ++ product/opni/components/LogsDrawer.vue | 21 +++- .../opni/components/PodBreakdownDetail.vue | 11 +- product/opni/utils/munging.js | 4 +- 8 files changed, 217 insertions(+), 19 deletions(-) create mode 100644 components/formatter/Collapse.vue create mode 100644 components/formatter/KibanaLink.vue diff --git a/assets/translations/en-us.yaml b/assets/translations/en-us.yaml index 77b35290f..9b4128ca1 100644 --- a/assets/translations/en-us.yaml +++ b/assets/translations/en-us.yaml @@ -4094,6 +4094,7 @@ tableHeaders: customVerbs: Custom Verbs dateRange: Date Range description: Description + empty: "" expires: Expires feedback: Feedback providers: Providers diff --git a/components/Drawer.vue b/components/Drawer.vue index 5ae522f90..2fd06f681 100644 --- a/components/Drawer.vue +++ b/components/Drawer.vue @@ -11,22 +11,85 @@ export default { type: String, default: null } + }, + + data() { + return { + drawerHeight: null, + dragging: false, + maximized: false, + }; + }, + + methods: { + close() { + this.$emit('close'); + this.$set(this, 'maximized', false); + }, + + onMouseMove(ev) { + if (!this.dragging) { + return; + } + + const clientHeight = document.documentElement.clientHeight; + const mouseY = ev.clientY; + const drawerHeight = clientHeight - mouseY; + const value = this.maximized ? null : `${ drawerHeight }px`; + + this.$set(this, 'drawerHeight', value); + }, + + onDrag() { + this.$set(this, 'dragging', true); + }, + + onDragDone() { + this.$set(this, 'dragging', false); + }, + + toggle() { + console.log('toggle') + this.$set(this, 'maximized', !this.maximized); + } + }, + + computed: { + style() { + if (this.maximized) { + return {}; + } + + return { height: this.drawerHeight }; + }, + + toggleClass() { + return this.maximized ? 'icon-chevron-down' : 'icon-chevron-up'; + } } }; @@ -44,33 +107,65 @@ export default { transition: bottom 0.2s; &:not(.open) { - bottom: -450px; + bottom: -100%; pointer-events: none; } } .drawer { + display: flex; + flex-direction: column; + position: absolute; - left: 5px; - right: 5px; + left: 0; + right: 0; bottom: 0; - height: 450px; border-radius: var(--border-radius); box-shadow: 0 0 20px var(--shadow); background-color: #FFF; + transition: height 0.2s; + + &.maximized { + height: 100%; + } .title-bar { display: flex; flex-direction: row; justify-content: space-between; align-items: center; + + .actions { + display: flex; + flex-direction: row; + } } .closer { color: var(--link); cursor: pointer; } + + .handle { + position: absolute; + + top: -5px; + left: 0; + right: 0; + height:15px; + cursor: ns-resize; + } + + &.dragging { + user-select: none; + transition: none; + } + + .content { + position: relative; + height: 100%; + } } diff --git a/components/formatter/Collapse.vue b/components/formatter/Collapse.vue new file mode 100644 index 000000000..cf17c3c82 --- /dev/null +++ b/components/formatter/Collapse.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/components/formatter/KibanaLink.vue b/components/formatter/KibanaLink.vue new file mode 100644 index 000000000..3df85cad4 --- /dev/null +++ b/components/formatter/KibanaLink.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/product/opni/components/Configurator.vue b/product/opni/components/Configurator.vue index 9cca33f09..57e2df91e 100644 --- a/product/opni/components/Configurator.vue +++ b/product/opni/components/Configurator.vue @@ -73,6 +73,7 @@ export default {
+ + diff --git a/product/opni/components/LogsDrawer.vue b/product/opni/components/LogsDrawer.vue index f5f9004b8..67db033d5 100644 --- a/product/opni/components/LogsDrawer.vue +++ b/product/opni/components/LogsDrawer.vue @@ -5,6 +5,14 @@ import Banner from '@/components/Banner'; import Loading from '@/components/Loading'; export const LOG_HEADERS = [ + { + name: 'collapse', + labelKey: 'tableHeaders.empty', + formatter: 'Collapse', + value: 'timestamp', + sort: false, + width: '20px' + }, { name: 'date', labelKey: 'tableHeaders.date', @@ -100,7 +108,7 @@ export default {
-
+