Skip to content

Commit 5f3fba2

Browse files
committed
Fix sessions page after react upgrade
1 parent f89d289 commit 5f3fba2

6 files changed

Lines changed: 341 additions & 30 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* The contents of this file are subject to the terms of the Common Development and
3+
* Distribution License (the License). You may not use this file except in compliance with the
4+
* License.
5+
*
6+
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7+
* specific language governing permission and limitations under the License.
8+
*
9+
* When distributing Covered Software, include this CDDL Header Notice in each file and include
10+
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11+
* Header, with the fields enclosed by brackets [] replaced by your own identifying
12+
* information: "Portions copyright [year] [name of copyright owner]".
13+
*
14+
* Copyright 2017-2019 ForgeRock AS.
15+
*/
16+
17+
import { map, uniqueId } from "lodash";
18+
import PropTypes from "prop-types";
19+
import React from "react";
20+
21+
/**
22+
* This function creates an array of snippets, with the odd array snippets being the ones with matched characters,
23+
* and the even snippets being the characters inbetween. The matched snippets are then wrapped in the <strong> element.
24+
* @param {string} children The string to which the emphasized text will be applied.
25+
* @param {string} match The characters of the string to emphasize.
26+
* @returns {Array<string|ReactElement>} An array of alternating strings and react elements.
27+
* @example
28+
* Given the string "/applications",
29+
* a match of "a" will return the snippet array ["/", "a", "pplic", "a", "tions"]
30+
* a match of "/AP" will return the snippet array ["", "/ap", "plications"]
31+
*/
32+
function emphasizeMatchingText (children, match) {
33+
const isOdd = (number) => (number % 2) === 1;
34+
const snippets = children.split(new RegExp(`(${match})`, "gi"));
35+
return map(snippets, (snippet, index) => {
36+
const key = uniqueId(`emphasizedText${snippet}`);
37+
return isOdd(index) ? <strong key={ key }>{snippet}</strong> : snippet;
38+
});
39+
}
40+
41+
const EmphasizedText = ({ children, match }) => {
42+
if (!children) {
43+
return "";
44+
}
45+
if (match) {
46+
return <span>{ emphasizeMatchingText(children, match) }</span>;
47+
} else {
48+
return <span>{ children }</span>;
49+
}
50+
};
51+
52+
EmphasizedText.propTypes = {
53+
children: PropTypes.string,
54+
match: PropTypes.string
55+
};
56+
57+
export default EmphasizedText;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* The contents of this file are subject to the terms of the Common Development and
3+
* Distribution License (the License). You may not use this file except in compliance with the
4+
* License.
5+
*
6+
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7+
* specific language governing permission and limitations under the License.
8+
*
9+
* When distributing Covered Software, include this CDDL Header Notice in each file and include
10+
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11+
* Header, with the fields enclosed by brackets [] replaced by your own identifying
12+
* information: "Portions copyright [year] [name of copyright owner]".
13+
*
14+
* Copyright 2019 ForgeRock AS.
15+
* Portions copyright 2025 Wren Security.
16+
*/
17+
18+
import { isEmpty } from "lodash";
19+
import { t } from "i18next";
20+
import { Async } from "react-select";
21+
import PropTypes from "prop-types";
22+
import React from "react";
23+
24+
import DropdownIndicator from "./components/DropdownIndicator";
25+
import Option from "./components/options/DefaultOption";
26+
import styles from "./components/styles";
27+
28+
const noOptionsMessage = ({ inputValue }) => {
29+
if (isEmpty(inputValue)) {
30+
return t("common.form.searchPrompt");
31+
}
32+
};
33+
const hideLoadingMessage = () => null;
34+
35+
const AsyncSingleSelect = (props) => (
36+
<Async
37+
components={ { DropdownIndicator, Option } }
38+
isClearable
39+
isLoading
40+
loadingMessage={ hideLoadingMessage }
41+
noOptionsMessage={ noOptionsMessage }
42+
styles={ styles }
43+
{ ...props }
44+
/>
45+
);
46+
47+
AsyncSingleSelect.propTypes = {
48+
inputId: PropTypes.string.isRequired,
49+
onChange: PropTypes.func.isRequired
50+
};
51+
52+
export default AsyncSingleSelect;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* The contents of this file are subject to the terms of the Common Development and
3+
* Distribution License (the License). You may not use this file except in compliance with the
4+
* License.
5+
*
6+
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7+
* specific language governing permission and limitations under the License.
8+
*
9+
* When distributing Covered Software, include this CDDL Header Notice in each file and include
10+
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11+
* Header, with the fields enclosed by brackets [] replaced by your own identifying
12+
* information: "Portions copyright [year] [name of copyright owner]".
13+
*
14+
* Copyright 2019 ForgeRock AS.
15+
*/
16+
17+
import { components } from "react-select";
18+
import classnames from "classnames";
19+
import PropTypes from "prop-types";
20+
import React from "react";
21+
22+
/*
23+
* This custom DropdownIndicator component wraps the default react-select v2 componet with one that looks and behaves
24+
* in the same manner as our other selectors. The react-select v2 DropdownIndicator is styled to look like bootstrap 4,
25+
* and so looks out of place within our design. For more information @see https://react-select.com/components
26+
*/
27+
const DropdownIndicator = (props) => (
28+
<components.DropdownIndicator { ...props }>
29+
<i
30+
className={
31+
classnames({
32+
"fa": true,
33+
"fa-caret-down": !props.selectProps.menuIsOpen,
34+
"fa-caret-up": props.selectProps.menuIsOpen
35+
})
36+
}
37+
/>
38+
</components.DropdownIndicator>
39+
);
40+
41+
DropdownIndicator.propTypes = {
42+
selectProps: PropTypes.shape({
43+
menuIsOpen: PropTypes.bool.isRequired
44+
}).isRequired
45+
};
46+
47+
export default DropdownIndicator;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* The contents of this file are subject to the terms of the Common Development and
3+
* Distribution License (the License). You may not use this file except in compliance with the
4+
* License.
5+
*
6+
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7+
* specific language governing permission and limitations under the License.
8+
*
9+
* When distributing Covered Software, include this CDDL Header Notice in each file and include
10+
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11+
* Header, with the fields enclosed by brackets [] replaced by your own identifying
12+
* information: "Portions copyright [year] [name of copyright owner]".
13+
*
14+
* Copyright 2019 ForgeRock AS.
15+
* Portions copyright 2025 Wren Security.
16+
*/
17+
18+
import { components } from "react-select";
19+
import classnames from "classnames";
20+
import PropTypes from "prop-types";
21+
import React from "react";
22+
23+
import EmphasizedText from "components/EmphasizedText";
24+
25+
/*
26+
* This custom DefaultOption component wraps the default react-select v2 componet and adds classNames to the options
27+
* which are then targeted within our functional tests. For more information @see https://react-select.com/components
28+
*/
29+
30+
const DefaultOption = ({ children, ...props }) => {
31+
const isNewOption = props.data.__isNew__;
32+
33+
const optionText = isNewOption ? children : (
34+
<EmphasizedText match={ props.selectProps.inputValue }>
35+
{ children }
36+
</EmphasizedText>
37+
);
38+
39+
return (
40+
components.Option && (
41+
<components.Option
42+
className={
43+
classnames({
44+
"react-select-menu-option": !isNewOption,
45+
"react-select-menu-create": isNewOption
46+
})
47+
}
48+
{ ...props }
49+
>
50+
{ optionText }
51+
</components.Option>
52+
)
53+
);
54+
};
55+
56+
DefaultOption.propTypes = {
57+
children: PropTypes.node,
58+
data: PropTypes.shape({
59+
__isNew__: PropTypes.bool
60+
}).isRequired,
61+
selectProps: PropTypes.shape({
62+
inputValue: PropTypes.string
63+
})
64+
};
65+
66+
export default DefaultOption;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* The contents of this file are subject to the terms of the Common Development and
3+
* Distribution License (the License). You may not use this file except in compliance with the
4+
* License.
5+
*
6+
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7+
* specific language governing permission and limitations under the License.
8+
*
9+
* When distributing Covered Software, include this CDDL Header Notice in each file and include
10+
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11+
* Header, with the fields enclosed by brackets [] replaced by your own identifying
12+
* information: "Portions copyright [year] [name of copyright owner]".
13+
*
14+
* Copyright 2019-2021 ForgeRock AS.
15+
*/
16+
17+
/*
18+
* Styled to look like our other selectors which are a themed bootstrap 3 mixed with react-select v1.0 or the jquery
19+
* selectize plugin. For more information about stylying react-select v2 @see https://react-select.com/styles
20+
*/
21+
const styles = {
22+
option: (base, state) => ({
23+
...base,
24+
color: "#333",
25+
backgroundColor: state.isSelected ? "#b9d4cf" : state.isFocused ? "#f1f7f6" : "#fff"
26+
}),
27+
clearIndicator: (base) => ({
28+
...base,
29+
padding: 6
30+
}),
31+
control: (base, state) => ({
32+
...base,
33+
border: state.isFocused && !state.menuIsOpen ? "1px solid #66afe9" : "1px solid #ccc",
34+
":hover": {
35+
border: state.isFocused && !state.menuIsOpen ? "1px solid #66afe9" : "1px solid #ccc"
36+
},
37+
minHeight: 34,
38+
outline: state.isFocused && !state.menuIsOpen ? 0 : base.outline,
39+
boxShadow: state.isFocused && !state.menuIsOpen
40+
? "inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)"
41+
: 0
42+
}),
43+
groupHeading: (base) => ({
44+
...base,
45+
color: "#457d78",
46+
background: "#fff",
47+
textTransform: "none",
48+
fontSize: "1em"
49+
}),
50+
group: (base) => ({
51+
...base,
52+
borderBottom: "1px solid #ccc"
53+
}),
54+
indicatorSeparator: (base, state) => ({
55+
...base,
56+
visibility: state.hasValue && !state.selectProps.isClearable ? "hidden" : base.visibility
57+
}),
58+
valueContainer: (base, state) => ({
59+
...base,
60+
padding: state.isMulti && state.hasValue ? "2px" : base.padding
61+
}),
62+
menu: (base) => ({
63+
...base,
64+
zIndex: 3
65+
}),
66+
noOptionsMessage: (base) => ({
67+
...base,
68+
textAlign: "left"
69+
}),
70+
multiValue: (base) => ({
71+
...base,
72+
border: "1px solid rgba(81,147,135,.24)",
73+
color: "#457d78",
74+
background: "#f1f6f5"
75+
}),
76+
multiValueLabel: (base) => ({
77+
...base,
78+
color: "#457d78"
79+
}),
80+
multiValueRemove: (base) => ({
81+
...base,
82+
borderLeft: "1px solid #d5e5e2",
83+
":hover": {
84+
background: "#e4edeb",
85+
cursor: "pointer"
86+
}
87+
})
88+
};
89+
90+
export default styles;

0 commit comments

Comments
 (0)