playbook_ui 11.12.1.pre.alpha.charts1 → 11.12.1.pre.alpha.passphrase1
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/index.js +1 -0
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.jsx +111 -0
- data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.jsx +151 -0
- data/app/pb_kits/playbook/pb_circle_chart/circle_chart.html.erb +21 -9
- data/app/pb_kits/playbook/pb_circle_chart/circle_chart.rb +47 -7
- data/app/pb_kits/playbook/pb_dashboard/{pbChartsDarkTheme.ts → pbChartsDarkTheme.js} +21 -6
- data/app/pb_kits/playbook/pb_dashboard/{pbChartsLightTheme.ts → pbChartsLightTheme.js} +21 -6
- data/app/pb_kits/playbook/pb_gauge/_gauge.jsx +112 -0
- data/app/pb_kits/playbook/pb_gauge/_gauge.scss +0 -4
- data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.html.erb +1 -1
- data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.jsx +8 -8
- data/app/pb_kits/playbook/pb_gauge/gauge.html.erb +11 -1
- data/app/pb_kits/playbook/pb_gauge/gauge.rb +8 -3
- data/app/pb_kits/playbook/pb_line_graph/_line_graph.jsx +113 -0
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +56 -97
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +145 -1
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.jsx +127 -3
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.md +11 -2
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +136 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx +90 -8
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.md +5 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.html.erb +51 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.jsx +39 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb +0 -2
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx +6 -20
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb +2 -2
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx +1 -1
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +318 -5
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +134 -48
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md +11 -5
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +123 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx +96 -20
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md +6 -2
- data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
- data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +5 -9
- data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +0 -47
- data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.jsx +79 -0
- data/app/pb_kits/playbook/pb_treemap_chart/docs/_treemap_chart_tooltip.jsx +1 -1
- data/app/pb_kits/playbook/playbook-rails-react-bindings.js +0 -4
- data/app/pb_kits/playbook/playbook-rails.js +4 -0
- data/app/pb_kits/playbook/plugins/pb_chart.js +322 -0
- data/lib/playbook/version.rb +1 -1
- metadata +15 -16
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +0 -145
- data/app/pb_kits/playbook/pb_circle_chart/ChartsTypes.ts +0 -2
- data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +0 -216
- data/app/pb_kits/playbook/pb_dashboard/pbChartsColorsHelper.ts +0 -16
- data/app/pb_kits/playbook/pb_dashboard/themeTypes.ts +0 -16
- data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +0 -213
- data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +0 -148
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md +0 -1
- data/app/pb_kits/playbook/pb_passphrase/passwordStrength.js +0 -55
- data/app/pb_kits/playbook/pb_passphrase/useHaveIBeenPwned.js +0 -52
- data/app/pb_kits/playbook/pb_passphrase/useZxcvbn.js +0 -58
- data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +0 -111
@@ -1,52 +0,0 @@
|
|
1
|
-
|
2
|
-
import { useEffect, useState } from 'react'
|
3
|
-
|
4
|
-
const checkHaveIBeenPwned = async function (passphrase) {
|
5
|
-
const buffer = new TextEncoder('utf-8').encode(passphrase)
|
6
|
-
const digest = await crypto.subtle.digest('SHA-1', buffer)
|
7
|
-
const hashArray = Array.from(new Uint8Array(digest))
|
8
|
-
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
|
9
|
-
|
10
|
-
const firstFive = hashHex.slice(0, 5)
|
11
|
-
const endOfHash = hashHex.slice(5)
|
12
|
-
|
13
|
-
const resp = await fetch(`https://api.pwnedpasswords.com/range/${firstFive}`)
|
14
|
-
const text = await resp.text()
|
15
|
-
|
16
|
-
const match = text.split('\n').some((line) => {
|
17
|
-
//Each line is <sha-1-hash-suffix>:<count of incidents>
|
18
|
-
return line.split(':')[0] === endOfHash.toUpperCase()
|
19
|
-
})
|
20
|
-
return match
|
21
|
-
}
|
22
|
-
|
23
|
-
/**
|
24
|
-
* If the input hasn't changed in <delay> ms,
|
25
|
-
* hit the haveibeenpwned api and check if the given passphrase is compromised
|
26
|
-
*/
|
27
|
-
export default function useHaveIBeenPwned(passphrase, minLength, delay = 400) {
|
28
|
-
const [isPwned, setIsPwned] = useState(false)
|
29
|
-
|
30
|
-
useEffect(
|
31
|
-
() => {
|
32
|
-
// only check the API for passphrases above the minimum size
|
33
|
-
if (passphrase.length < minLength) {
|
34
|
-
setIsPwned(false)
|
35
|
-
return
|
36
|
-
}
|
37
|
-
|
38
|
-
const handler = setTimeout(() => {
|
39
|
-
checkHaveIBeenPwned(passphrase)
|
40
|
-
.then((pwned) => setIsPwned(pwned))
|
41
|
-
.catch(() => setIsPwned(false))
|
42
|
-
}, delay)
|
43
|
-
|
44
|
-
return () => {
|
45
|
-
clearTimeout(handler)
|
46
|
-
}
|
47
|
-
},
|
48
|
-
[passphrase, minLength, delay]
|
49
|
-
)
|
50
|
-
|
51
|
-
return isPwned
|
52
|
-
}
|
@@ -1,58 +0,0 @@
|
|
1
|
-
import { useEffect, useMemo, useState } from 'react'
|
2
|
-
import zxcvbn from 'zxcvbn'
|
3
|
-
|
4
|
-
export default function useZxcvbn(options) {
|
5
|
-
const { passphrase = '', common, isPwned, confirmation, averageThreshold, minLength, strongThreshold } = options
|
6
|
-
const calculator = useMemo(
|
7
|
-
() => confirmation ? () => ({ score: 0 }) : zxcvbn,
|
8
|
-
[confirmation]
|
9
|
-
)
|
10
|
-
|
11
|
-
const [percent, setPercent] = useState('0')
|
12
|
-
const [variant, setVariant] = useState('negative')
|
13
|
-
const [text, setText] = useState('\u00A0') //nbsp to keep height constant
|
14
|
-
const [result, setResult] = useState({})
|
15
|
-
|
16
|
-
useEffect(() => {
|
17
|
-
if (confirmation) return
|
18
|
-
const newResult = calculator(passphrase)
|
19
|
-
setResult(newResult)
|
20
|
-
const str = newResult.score
|
21
|
-
|
22
|
-
const noPassphrase = passphrase.length <= 0
|
23
|
-
const commonPassphrase = common || isPwned
|
24
|
-
const weakPassphrase = passphrase.length < minLength || str < averageThreshold
|
25
|
-
const averagePassphrase = str < strongThreshold
|
26
|
-
const strongPassphrase = str >= strongThreshold
|
27
|
-
|
28
|
-
if (noPassphrase) {
|
29
|
-
setPercent('0')
|
30
|
-
setVariant('negative')
|
31
|
-
setText('\u00A0') //nbsp to keep height constant
|
32
|
-
} else if (commonPassphrase) {
|
33
|
-
setPercent('25')
|
34
|
-
setVariant('negative')
|
35
|
-
setText('This passphrase is too common')
|
36
|
-
} else if (weakPassphrase) {
|
37
|
-
setPercent('25')
|
38
|
-
setVariant('negative')
|
39
|
-
setText('Too weak')
|
40
|
-
} else if (averagePassphrase){
|
41
|
-
setPercent('50')
|
42
|
-
setVariant('warning')
|
43
|
-
setText('Almost there, keep going!')
|
44
|
-
} else if (strongPassphrase) {
|
45
|
-
setPercent('100')
|
46
|
-
setVariant('positive')
|
47
|
-
setText('Success! Strong passphrase')
|
48
|
-
}
|
49
|
-
}, [passphrase, common, isPwned, averageThreshold, minLength, strongThreshold]
|
50
|
-
)
|
51
|
-
|
52
|
-
return {
|
53
|
-
strength: common || isPwned ? 0 : result.score,
|
54
|
-
percent,
|
55
|
-
variant,
|
56
|
-
text,
|
57
|
-
}
|
58
|
-
}
|
@@ -1,111 +0,0 @@
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
2
|
-
import classnames from "classnames";
|
3
|
-
|
4
|
-
import { globalProps } from "../utilities/globalProps";
|
5
|
-
import { buildAriaProps, buildDataProps } from "../utilities/props";
|
6
|
-
|
7
|
-
import HighchartsReact from "highcharts-react-official";
|
8
|
-
import Highcharts from "highcharts";
|
9
|
-
import { highchartsTheme } from "../pb_dashboard/pbChartsLightTheme";
|
10
|
-
import { highchartsDarkTheme } from "../pb_dashboard/pbChartsDarkTheme";
|
11
|
-
import mapColors from "../pb_dashboard/pbChartsColorsHelper";
|
12
|
-
import treemap from 'highcharts/modules/treemap'
|
13
|
-
|
14
|
-
type TreemapChartProps = {
|
15
|
-
chartData: {
|
16
|
-
name: string;
|
17
|
-
parent?: string | number;
|
18
|
-
value: number;
|
19
|
-
color?: string;
|
20
|
-
id?: string | number;
|
21
|
-
}[];
|
22
|
-
className?: string;
|
23
|
-
colors: string[];
|
24
|
-
dark?: boolean;
|
25
|
-
drillable: boolean;
|
26
|
-
grouped: boolean;
|
27
|
-
height?: string;
|
28
|
-
id: number | string;
|
29
|
-
title?: string;
|
30
|
-
tooltipHtml: string;
|
31
|
-
type?: string;
|
32
|
-
aria?: { [key: string]: string };
|
33
|
-
data?: { [key: string]: string };
|
34
|
-
};
|
35
|
-
|
36
|
-
const TreemapChart = ({
|
37
|
-
aria = {},
|
38
|
-
data = {},
|
39
|
-
chartData,
|
40
|
-
colors,
|
41
|
-
dark = false,
|
42
|
-
drillable = false,
|
43
|
-
grouped = false,
|
44
|
-
height,
|
45
|
-
id,
|
46
|
-
title = "",
|
47
|
-
tooltipHtml = '<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.value}</b>',
|
48
|
-
type = "treemap",
|
49
|
-
...props
|
50
|
-
}: TreemapChartProps) => {
|
51
|
-
const ariaProps = buildAriaProps(aria);
|
52
|
-
const dataProps = buildDataProps(data);
|
53
|
-
const setupTheme = () => {
|
54
|
-
dark
|
55
|
-
? Highcharts.setOptions(highchartsDarkTheme)
|
56
|
-
: Highcharts.setOptions(highchartsTheme);
|
57
|
-
};
|
58
|
-
treemap(Highcharts)
|
59
|
-
setupTheme();
|
60
|
-
|
61
|
-
const staticOptions = {
|
62
|
-
title: {
|
63
|
-
text: title,
|
64
|
-
},
|
65
|
-
chart: {
|
66
|
-
height: height,
|
67
|
-
type: type,
|
68
|
-
},
|
69
|
-
credits: false,
|
70
|
-
series: [
|
71
|
-
{
|
72
|
-
data: chartData,
|
73
|
-
},
|
74
|
-
],
|
75
|
-
plotOptions: {
|
76
|
-
treemap: {
|
77
|
-
tooltip: {
|
78
|
-
pointFormat: tooltipHtml,
|
79
|
-
},
|
80
|
-
allowTraversingTree: drillable,
|
81
|
-
colorByPoint: !grouped,
|
82
|
-
colors:
|
83
|
-
colors !== undefined && colors.length > 0
|
84
|
-
? mapColors(colors)
|
85
|
-
: highchartsTheme.colors,
|
86
|
-
},
|
87
|
-
},
|
88
|
-
};
|
89
|
-
|
90
|
-
const [options, setOptions] = useState({});
|
91
|
-
|
92
|
-
useEffect(() => {
|
93
|
-
|
94
|
-
setOptions({ ...staticOptions });
|
95
|
-
}, [chartData]);
|
96
|
-
|
97
|
-
return (
|
98
|
-
<HighchartsReact
|
99
|
-
containerProps={{
|
100
|
-
className: classnames(globalProps(props), "pb_treemap_chart"),
|
101
|
-
id: id,
|
102
|
-
...ariaProps,
|
103
|
-
...dataProps,
|
104
|
-
}}
|
105
|
-
highcharts={Highcharts}
|
106
|
-
options={options}
|
107
|
-
/>
|
108
|
-
);
|
109
|
-
};
|
110
|
-
|
111
|
-
export default TreemapChart;
|