fluency-v8-components 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { c as Da, _ as Va, g as il } from "./index-CS1vHSYo.mjs";
1
+ import { c as Da, _ as Va, g as il } from "./index-BAGLjhJi.mjs";
2
2
  var fn = {}, cn = {}, cr, vn;
3
3
  function Q() {
4
4
  if (vn) return cr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluency-v8-components",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "main": "dist/fluency-v8-components.umd.js",
5
5
  "module": "dist/fluency-v8-components.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -144,7 +144,7 @@
144
144
  }
145
145
 
146
146
  @utility std-light {
147
- @apply bg-blue-50;
147
+ @apply bg-blue-100;
148
148
  }
149
149
 
150
150
  @utility std-dark {
@@ -325,6 +325,10 @@
325
325
  @apply w-10 h-10;
326
326
  }
327
327
 
328
+ @utility link {
329
+ @apply text-blue-400 hover:underline;
330
+ }
331
+
328
332
  @font-face {
329
333
  font-family: "Open Sans";
330
334
  src: url("/OpenSans-VariableFont_wdth,wght.ttf");
@@ -510,22 +514,22 @@
510
514
  }
511
515
 
512
516
  .chip {
513
- @apply text-sm font-medium px-2 py-1 rounded-full flex flex-row;
517
+ @apply inline-flex items-center rounded-md px-2 py-1 font-medium ring-1 ring-inset;
514
518
  }
515
519
  .select-chip {
516
520
  @apply px-1 text-sm font-medium rounded-full bg-sky-200 dark:bg-sky-700;
517
521
  }
518
522
  .green-chip {
519
- @apply bg-green-200 text-green-700 dark:bg-green-800 dark:text-green-300;
523
+ @apply bg-green-400/10 ring-green-500/20 text-green-400;
520
524
  }
521
525
  .red-chip {
522
- @apply bg-red-200 text-red-600 dark:bg-red-800 dark:text-red-300;
526
+ @apply bg-red-400/10 ring-red-500/20 text-red-400;
523
527
  }
524
528
  .yellow-chip {
525
- @apply bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300;
529
+ @apply bg-yellow-400/10 ring-yellow-500/20 text-yellow-400;
526
530
  }
527
531
  .blue-chip {
528
- @apply bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300;
532
+ @apply bg-blue-400/10 ring-blue-500/20 text-blue-400;
529
533
  }
530
534
 
531
535
  .image-position-box {
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <div class="col items-center">
3
+ <div class="text-center">
4
+ <span>{{ title }} Timeline ({{ total }} Events)</span>
5
+ </div>
6
+ <div ref="myplot" :class="['px-4', { 'pb-4': !props.flow }]"></div>
7
+ <div class="flex justify-end w-full mr-2">
8
+ <div ref="myplotLegend"></div>
9
+ </div>
10
+ </div>
11
+ </template>
12
+
13
+ <script setup>
14
+ import { ref, watch } from "vue";
15
+ import * as d3 from "d3";
16
+ import * as Plot from "@observablehq/plot";
17
+ import { dateLocalTime } from "@/utils/timeUtils";
18
+
19
+ // props
20
+ const props = defineProps({
21
+ title: String,
22
+ buckets: Array,
23
+ total: Number,
24
+ from: Number,
25
+ to: Number,
26
+ flow: {
27
+ type: Boolean,
28
+ default: false,
29
+ },
30
+ width: {
31
+ type: Number,
32
+ default: 1200,
33
+ },
34
+ height: {
35
+ type: Number,
36
+ default: 300,
37
+ },
38
+ theme: {
39
+ type: String,
40
+ default: "light",
41
+ },
42
+ /** Key on each bucket for the risk score value (y-axis). Default "risk_score". */
43
+ valueKey: {
44
+ type: String,
45
+ default: "risk_score",
46
+ },
47
+ });
48
+ // states
49
+ const myplot = ref(null);
50
+ const myplotLegend = ref(null);
51
+ // watch for changes in data
52
+ watch([() => props.buckets], () => {
53
+ plotGraph();
54
+ });
55
+ watch([() => props.theme], () => {
56
+ plotGraph();
57
+ });
58
+
59
+ // function defs
60
+ function plotGraph() {
61
+ if (!props.buckets) return;
62
+ const valueKey = props.valueKey;
63
+ let options = {
64
+ marginTop: 30,
65
+ marks: [
66
+ Plot.frame(),
67
+ Plot.text(["No data available!"], { frameAnchor: "middle" }),
68
+ ],
69
+ };
70
+ let marginLeft = 80;
71
+ let marginRight = 80;
72
+
73
+ if (props.buckets.length > 0) {
74
+ if (props.flow) {
75
+ const b = props.buckets;
76
+
77
+ // Left axis (flow) domain = max of rx/tx
78
+ const leftMax = Math.max(
79
+ 1,
80
+ d3.max(b, (d) => Math.max(d?.rxHistogram?.value ?? 0, d?.txHistogram?.value ?? 0)) ?? 0
81
+ );
82
+
83
+ // Right axis (risk score) domain
84
+ const rightMax = Math.max(
85
+ 1,
86
+ d3.max(b, (d) => d?.[valueKey] ?? 0) ?? 0
87
+ );
88
+
89
+ const k = leftMax / rightMax;
90
+ const rightTicks = d3.ticks(0, rightMax, 5);
91
+ const leftTicks = d3.ticks(0, leftMax, 5);
92
+
93
+ options = {
94
+ x: { type: "time", label: "Time", tickSpacing: 100 },
95
+ y: {
96
+ label: "Flow",
97
+ domain: [0, leftMax],
98
+ },
99
+ grid: true,
100
+ marks: [
101
+ Plot.lineY(b, {
102
+ x: "key",
103
+ y: (d) => d?.rxHistogram?.value ?? 0,
104
+ strokeWidth: 2.5,
105
+ curve: "catmull-rom",
106
+ stroke: "#22c55e",
107
+ }),
108
+ Plot.lineY(b, {
109
+ x: "key",
110
+ y: (d) => d?.txHistogram?.value ?? 0,
111
+ strokeWidth: 2.5,
112
+ curve: "catmull-rom",
113
+ stroke: "#eab308",
114
+ }),
115
+ Plot.dotY(b, {
116
+ x: "key",
117
+ y: (d) => (d?.[valueKey] ?? 0) * k,
118
+ stroke: "#71b6e0",
119
+ strokeWidth: 3,
120
+ }),
121
+ Plot.axisY({
122
+ anchor: "left",
123
+ ticks: leftTicks.map((t) => t),
124
+ tickFormat: (_, i) => d3.format("~s")(leftTicks[i]) + "B",
125
+ label: "Bytes",
126
+ }),
127
+ Plot.axisY({
128
+ anchor: "right",
129
+ ticks: rightTicks.map((t) => t * k),
130
+ tickFormat: (_, i) => d3.format("~s")(rightTicks[i]),
131
+ label: "Risk Score",
132
+ }),
133
+ Plot.tip(
134
+ b,
135
+ Plot.pointerX({
136
+ x: "key",
137
+ y: (d) => (d?.[valueKey] ?? 0) * k,
138
+ fill: props.theme === "light" ? "white" : "black",
139
+ title: (d) =>
140
+ `Time: ${dateLocalTime(d.key)}\n` +
141
+ `rx: ${d?.rxHistogram?.value ?? 0}B (~${d3.format(".0s")(d?.rxHistogram?.value)}B)\n` +
142
+ `tx: ${d?.txHistogram?.value ?? 0}B (~${d3.format(".0s")(d?.txHistogram?.value)}B)\n` +
143
+ `Risk Score: ${Math.round(d?.[valueKey] ?? 0)}`,
144
+ })
145
+ ),
146
+ ],
147
+ };
148
+ } else {
149
+ const dataMax = d3.max(props.buckets, (d) => d?.[valueKey] ?? 0) ?? 0;
150
+ const maxRisk = dataMax > 0 ? Math.max(1, dataMax) : 500;
151
+ const allZeros = dataMax === 0;
152
+ const tickFormat = d3.format("d");
153
+ const widestTickLabel = tickFormat(maxRisk).toString();
154
+ marginLeft = Math.max(marginLeft, 24 + widestTickLabel.length * 8);
155
+
156
+ options = {
157
+ x: {
158
+ type: "time",
159
+ label: "Time",
160
+ tickSpacing: 100,
161
+ },
162
+ y: {
163
+ label: "Risk Score",
164
+ domain: [0, maxRisk],
165
+ tickFormat,
166
+ ...(allZeros && { ticks: [0, 100, 200, 300, 400, 500] }),
167
+ },
168
+ grid: true,
169
+ marks: [
170
+ Plot.dotY(props.buckets, {
171
+ x: "key",
172
+ y: (d) => d?.[valueKey] ?? 0,
173
+ stroke: "#71b6e0",
174
+ strokeWidth: 3,
175
+ }),
176
+ Plot.tip(
177
+ props.buckets,
178
+ Plot.pointerX({
179
+ x: "key",
180
+ y: (d) => d?.[valueKey] ?? 0,
181
+ fill: props.theme === "light" ? "white" : "black",
182
+ title: (d) =>
183
+ `Time: ${dateLocalTime(d.key)}\nRisk Score: ${Math.round(d?.[valueKey] ?? 0)}`,
184
+ })
185
+ ),
186
+ ],
187
+ };
188
+ }
189
+ }
190
+
191
+ const plot = Plot.plot({
192
+ marginLeft,
193
+ marginRight,
194
+ width: props.width,
195
+ height: props.height,
196
+ marginBottom: 50,
197
+ inset: 20,
198
+ style: {
199
+ fontSize: "16px",
200
+ backgroundColor: props.theme === "light" ? "white" : "#1a202c",
201
+ },
202
+ ...options,
203
+ });
204
+ myplot.value.innerHTML = "";
205
+ myplot.value.appendChild(plot);
206
+ if (props.flow) {
207
+ const legend = Plot.legend({
208
+ color: {
209
+ type: "categorical",
210
+ domain: ["Received", "Sent", "Risk Score"],
211
+ range: ["#22c55e", "#eab308", "#71b6e0"],
212
+ },
213
+ swatchSize: 8,
214
+ });
215
+ myplotLegend.value.innerHTML = "";
216
+ myplotLegend.value.appendChild(legend);
217
+ }
218
+ }
219
+ </script>
@@ -119,6 +119,7 @@ export { default as StackedChartClustered } from "./charts/StackedChartClustered
119
119
  export { default as PieChart } from "./charts/PieChart.vue";
120
120
  export { default as ProgressChart } from "./charts/ProgressChart.vue";
121
121
  export { default as TimelineChart } from "./charts/TimelineChart.vue";
122
+ export { default as TimelinePlot } from "./charts/TimelinePlot.vue";
122
123
  export { default as RangeSlider } from "./charts/RangeSlider.vue"
123
124
  export { default as EmptyChart } from "./charts/EmptyChart.vue";
124
125
  export { default as WorkflowChart } from "./charts/WorkflowChart.vue";
@@ -29,7 +29,7 @@
29
29
  </div>
30
30
  <div
31
31
  :class="[
32
- 'col-span-3 md:ml-5 md:overflow-auto',
32
+ 'col-span-3 md:ml-5 md:overflow-auto custom-scrollbar',
33
33
  { 'md:max-h-[calc(100vh-255px)]': searchBar },
34
34
  { 'md:max-h-[calc(100vh-200px)]': !searchBar },
35
35
  ]"
@@ -1,7 +1,7 @@
1
1
  import Prism from "prismjs";
2
2
 
3
3
  const builtinfunction =
4
- /#?(?!\s)\b(?:Add|After|Aggregate|alert|anomaly|append|Append|AWS_AccountRegionLambda|AWS_AccountLambda|AWS_GetCostUsage|AWS_GetMetric|AWS_GetPrice|AWS_LoadAsset|base64Encode|base64Decode|Before|Clone|coalesce|ColumnAggregate|concat|contains|content|Cylance_AddGlobalList|Cylance_GetDevice|Cylance_GetThreatDevices|Cylance_GetThreatDownload|Cylance_GetThreatInfo|Cylance_LoadDevice|Cylance_LoadThreat|decoder_CEF|decoder_CSV|decoder_MixedKeyValue|decoder_QuotedKeyValue|DimensionTable|Each|Emit|endsWith|Error|Find|Filter|Fluency_BehaviorSearch|Fluency_Device_Add|Fluency_Device_Delete|Fluency_DeviceSearch|Fluency_Device_Lookup|Fluency_Device_LookupName|Fluency_Device_Update|Fluency_EntityinfoLookup|Fluency_FusionEvent|fluencyLavadbFpl|Fluency_LavadbQuery|Fluency_LavaLakeFpl|Fluency_ResourceLoad|Fluency_SummarySearch|Fluency_Tenant_Device_Add|Fluency_Tenant_Device_Delete|Fluency_Tenant_Device_Lookup|Fluency_Tenant_Device_LookupName|Fluency_Tenant_Device_Update|Format|geoip|GetColumnValues|GetEnv|GetKeys|GetRow|gzipCompress|gzipDecompress|htmlTemplate|indexOf|isEmpty|IsEmpty|isIPv4|isIPv6|ipNormalize|isNull|isNumber|isString|isUndef|isValidIP|Join|JoinStream|jsonClone|jsonTable|len|Limit|main|Map|match|mergeTable|NewColumns|NewColumnLambda|parseBool|parseFloat|parseInt|parseJson|Platform_Action|Platform_Action_Endpoint|Platform_Asset_Lookup|Platform_Asset_Refresh|Platform_Asset_Register|Platform_Cache_Check|Platform_Cache_Delete|Platform_Cache_DeRegister|Platform_Cache_Get|Platform_Cache_Register|Platform_Cache_Replace|Platform_Cache_Set|Platform_Cache_SetMultiple|Platform_Channel|Platform_DataObject_Delete|Platform_DataObject_Get|Platform_DataObject_Save|Platform_DataObject_Search|Platform_EntityinfoCheck|Platform_EntityinfoLookup|Platform_EntityProvider_Lookup|Platform_EntityProvider_Refresh|Platform_Grok_Add_Pattern|Platform_Grok_Check|Platform_Grok_Parse|Platform_Grok_Register|Platform_LoadComponent|Platform_Metric_Alert_Counter_Stop|Platform_Metric_Counter|Platform_Metric_Query|Platform_Metric_QueryBuild|Platform_Metric_QueryRange|Platform_Metric_Sort|Platform_Metric_Sort_Histogram|Platform_Notification_Email|Platform_Notification_PagerDuty|Platform_Notification_Slack|Platform_Notification_ServiceNow|Platform_PluginLambda|Platform_REST_Call|Platform_Sink|Platform_Site_GetInfo|Platform_Site_GetTenants|Platform_Site_LoadTenantComponent|pluginLambda|Plugin_Bitdefender_LoadEndpoint|Plugin_Falcon_GetHost|Plugin_Falcon_GetIncident|Plugin_Falcon_LoadHost|Plugin_Falcon_LoadIncident|Plugin_InControl_LoadClient|Plugin_InControl_LoadDevice|printf|Prom_Push_Counter|Prom_Push_Gauge|regexp|replace|replaceAll|ReplaceKey|RenameColumn|RemoveColumn|Round|run|RxFPL_GetMetric|setEnv|split|Some|Sort|sprintf|startsWith|SetColumnUnit|SetDimensions|SetTags|SetUnit|sleep|SummaryTable|subString|template|TimeTable|toLower|timezoneOffset|toUpper|transform|trim|trimPrefix|trimSuffix|typeof|Unix|UnixMilli|window)\b(?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/g;
4
+ /#?(?!\s)\b(?:Add|After|Aggregate|alert|anomaly|append|Append|AWS_AccountRegionLambda|AWS_AccountLambda|AWS_GetCostUsage|AWS_GetMetric|AWS_GetPrice|AWS_LoadAsset|base64Encode|base64Decode|Before|Clone|coalesce|ColumnAggregate|concat|contains|content|Cylance_AddGlobalList|Cylance_GetDevice|Cylance_GetThreatDevices|Cylance_GetThreatDownload|Cylance_GetThreatInfo|Cylance_LoadDevice|Cylance_LoadThreat|decoder_CEF|decoder_CSV|decoder_MixedKeyValue|decoder_QuotedKeyValue|DimensionTable|Each|Emit|endsWith|Error|Find|Filter|Fluency_BehaviorSearch|Fluency_Device_Add|Fluency_Device_Delete|Fluency_DeviceSearch|Fluency_Device_Lookup|Fluency_Device_LookupName|Fluency_Device_Update|Fluency_EntityinfoLookup|Fluency_FusionEvent|fluencyLavadbFpl|Fluency_LavadbQuery|fluencyLavaLakeFpl|Fluency_LavaLakeFpl|Fluency_ResourceLoad|Fluency_SummarySearch|Fluency_Tenant_Device_Add|Fluency_Tenant_Device_Delete|Fluency_Tenant_Device_Lookup|Fluency_Tenant_Device_LookupName|Fluency_Tenant_Device_Update|Format|geoip|GetColumnValues|GetEnv|GetKeys|GetRow|gzipCompress|gzipDecompress|htmlTemplate|indexOf|isEmpty|IsEmpty|isIPv4|isIPv6|ipNormalize|isNull|isNumber|isString|isUndef|isValidIP|Join|JoinStream|jsonClone|jsonTable|len|Limit|main|Map|match|mergeTable|NewColumns|NewColumnLambda|parseBool|parseFloat|parseInt|parseJson|Platform_Action|Platform_Action_Endpoint|Platform_Asset_Lookup|Platform_Asset_Refresh|Platform_Asset_Register|Platform_Cache_Check|Platform_Cache_Delete|Platform_Cache_DeRegister|Platform_Cache_Get|Platform_Cache_Register|Platform_Cache_Replace|Platform_Cache_Set|Platform_Cache_SetMultiple|Platform_Channel|Platform_DataObject_Delete|Platform_DataObject_Get|Platform_DataObject_Save|Platform_DataObject_Search|Platform_EntityinfoCheck|Platform_EntityinfoLookup|Platform_EntityProvider_Lookup|Platform_EntityProvider_Refresh|Platform_Grok_Add_Pattern|Platform_Grok_Check|Platform_Grok_Parse|Platform_Grok_Register|Platform_LoadComponent|Platform_Metric_Alert_Counter_Stop|Platform_Metric_Counter|Platform_Metric_Query|Platform_Metric_QueryBuild|Platform_Metric_QueryRange|Platform_Metric_Sort|Platform_Metric_Sort_Histogram|Platform_Notification_Email|Platform_Notification_PagerDuty|Platform_Notification_Slack|Platform_Notification_ServiceNow|Platform_PluginLambda|Platform_REST_Call|Platform_Sink|Platform_Site_GetInfo|Platform_Site_GetTenants|Platform_Site_LoadTenantComponent|pluginLambda|Plugin_Bitdefender_LoadEndpoint|Plugin_Falcon_GetHost|Plugin_Falcon_GetIncident|Plugin_Falcon_LoadHost|Plugin_Falcon_LoadIncident|Plugin_InControl_LoadClient|Plugin_InControl_LoadDevice|printf|Prom_Push_Counter|Prom_Push_Gauge|regexp|replace|replaceAll|ReplaceKey|RenameColumn|RemoveColumn|Round|run|RxFPL_GetMetric|setEnv|split|Some|Sort|sprintf|startsWith|SetColumnUnit|SetDimensions|SetTags|SetUnit|sleep|SummaryTable|subString|template|TimeTable|toLower|timezoneOffset|toUpper|transform|trim|trimPrefix|trimSuffix|typeof|Unix|UnixMilli|window)\b(?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/g;
5
5
 
6
6
  const fpl2 = {
7
7
  regex: Prism.languages.javascript.regex,