Skip to content

Commit 94b3df7

Browse files
committed
Merge remote-tracking branch 'origin/dev' into TCA-455_npm-modules-update
2 parents 6dc5077 + c7ba856 commit 94b3df7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1265
-39
lines changed

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"start": "sh start-ssl.sh",
88
"start:brooke": "sudo sh start-ssl-brooke.sh",
99
"build": "yarn react-app-rewired build",
10+
"postbuild": "gzip build/static/js/*.js && gzip build/static/css/*.css",
1011
"lint": "tslint 'src-ts/**/*.{ts,tsx}' && eslint 'src*/**/*.{js,jsx,ts,tsx}'",
1112
"lint:fix": "tslint 'src-ts/**/*.{ts,tsx}' --fix && eslint 'src*/**/*.{js,jsx,ts,tsx}' --fix",
1213
"tslint": "tslint 'src-ts/**/*.{ts,tsx}'",
@@ -34,14 +35,17 @@
3435
"highlight.js": "^11.6.0",
3536
"html2canvas": "^1.4.1",
3637
"lodash": "^4.17.21",
38+
"markdown-it": "^13.0.1",
3739
"marked": "4.1.1",
3840
"moment": "^2.29.4",
3941
"moment-timezone": "^0.5.37",
4042
"prop-types": "^15.8.1",
43+
"qs": "^6.11.0",
4144
"rc-checkbox": "^2.3.2",
4245
"react": "^18.2.0",
4346
"react-apexcharts": "^1.4.0",
4447
"react-app-rewired": "^2.2.1",
48+
"react-contenteditable": "^3.3.6",
4549
"react-dom": "^18.2.0",
4650
"react-elastic-carousel": "^0.11.5",
4751
"react-gtm-module": "^2.0.11",
@@ -58,6 +62,7 @@
5862
"redux-logger": "^3.0.6",
5963
"redux-promise-middleware": "^6.1.3",
6064
"redux-thunk": "^2.4.1",
65+
"sanitize-html": "^2.7.2",
6166
"sass": "^1.55.0",
6267
"styled-components": "^5.3.6",
6368
"swr": "^1.3.0",
@@ -85,6 +90,7 @@
8590
"@types/highlightjs": "^9.12.2",
8691
"@types/jest": "^29.1.2",
8792
"@types/lodash": "^4.14.186",
93+
"@types/markdown-it": "^12.2.3",
8894
"@types/marked": "4.0.7",
8995
"@types/node": "^18.8.5",
9096
"@types/reach__router": "^1.3.11",
@@ -93,6 +99,7 @@
9399
"@types/react-gtm-module": "^2.0.1",
94100
"@types/react-redux-toastr": "^7.6.2",
95101
"@types/react-router-dom": "^5.3.3",
102+
"@types/sanitize-html": "^2.6.2",
96103
"@types/segment-analytics": "^0.0.34",
97104
"@types/systemjs": "^6.1.1",
98105
"@types/uuid": "^8.3.4",

src-ts/lib/functions/xhr-functions/xhr.functions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ function interceptError(instance: AxiosInstance): void {
7474

7575
// if there is server error message, then return it inside `message` property of error
7676
error.message = error?.response?.data?.message || error.message
77+
// if there is server errors data, then return it inside `errors` property of error
78+
error.errors = error?.response?.data?.errors
7779

7880
return Promise.reject(error)
7981
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import "../styles/variables/palette";
2+
3+
.memberSelect {
4+
color: $black-60;
5+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { FC, FocusEvent } from 'react'
2+
import { MultiValue, StylesConfig } from 'react-select'
3+
// tslint:disable-next-line: no-submodule-imports
4+
import AsyncSelect from 'react-select/async'
5+
6+
import { InputWrapper } from '../form/form-groups/form-input/input-wrapper'
7+
8+
import { membersAutocompete, MembersAutocompeteResult } from './input-handle-functions'
9+
import styles from './InputHandleAutocomplete.module.scss'
10+
11+
export interface InputHandleAutocompleteProps {
12+
readonly className?: string
13+
readonly dirty?: boolean
14+
readonly disabled?: boolean
15+
readonly error?: string
16+
readonly hideInlineErrors?: boolean
17+
readonly hint?: string
18+
readonly label?: string | JSX.Element
19+
readonly name: string
20+
readonly onBlur?: (event: FocusEvent<HTMLInputElement>) => void
21+
readonly onChange: (newValue: Array<MembersAutocompeteResult>) => void
22+
readonly placeholder?: string
23+
readonly tabIndex: number
24+
readonly value?: Array<MembersAutocompeteResult>
25+
}
26+
27+
const InputHandleAutocomplete: FC<InputHandleAutocompleteProps> = (props: InputHandleAutocompleteProps) => {
28+
const customStyles: StylesConfig<any> = {
29+
control: (provided) => ({
30+
...provided,
31+
border: 'none',
32+
}),
33+
input: (provided) => ({
34+
...provided,
35+
color: 'inherit',
36+
fontSize: 16,
37+
}),
38+
multiValue: (provided) => ({
39+
...provided,
40+
borderRadius: 50,
41+
}),
42+
multiValueLabel: (provided) => ({
43+
...provided,
44+
fontSize: 12,
45+
}),
46+
option: (provided) => ({
47+
...provided,
48+
borderBottom: '1px solid #E9E9E9',
49+
color: 'inherit',
50+
fontSize: 16,
51+
fontWeight: 400,
52+
padding: 16,
53+
}),
54+
placeholder: (provided) => ({
55+
...provided,
56+
color: 'inherit',
57+
fontSize: 16,
58+
fontWeight: 400,
59+
}),
60+
valueContainer: (provided) => ({
61+
...provided,
62+
padding: 0,
63+
}),
64+
}
65+
66+
return (
67+
<InputWrapper
68+
{...props}
69+
dirty={!!props.dirty}
70+
disabled={!!props.disabled}
71+
label={props.label || props.name}
72+
hideInlineErrors={props.hideInlineErrors}
73+
type='text'
74+
>
75+
<AsyncSelect
76+
className={styles.memberSelect}
77+
cacheOptions
78+
getOptionLabel={({ handle }) => handle}
79+
getOptionValue={({ userId }) => userId}
80+
isMulti
81+
key={props.value?.length}
82+
loadOptions={membersAutocompete}
83+
styles={customStyles}
84+
placeholder={props.placeholder}
85+
onBlur={props.onBlur}
86+
onChange={(newValue: MultiValue<MembersAutocompeteResult>) => props.onChange(newValue as Array<MembersAutocompeteResult>)}
87+
value={props.value}
88+
isDisabled={props.disabled}
89+
/>
90+
</InputWrapper>
91+
)
92+
}
93+
94+
export default InputHandleAutocomplete
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as InputHandleAutocomplete } from './InputHandleAutocomplete'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import qs from 'qs'
2+
3+
import { xhrGetAsync } from '..'
4+
import { EnvironmentConfig } from '../../config'
5+
6+
export interface MembersAutocompeteQuery {
7+
term: string
8+
}
9+
10+
export interface MembersAutocompeteResult {
11+
firstName: string
12+
handle: string
13+
lastName: string
14+
userId: string
15+
}
16+
17+
export async function membersAutocompete(term: string): Promise<Array<MembersAutocompeteResult>> {
18+
const query: MembersAutocompeteQuery = {
19+
term,
20+
}
21+
22+
return xhrGetAsync(`${EnvironmentConfig.API.V5}/members/autocomplete?${qs.stringify(query)}`)
23+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
import { KeyedMutator } from 'swr'
2+
3+
import { InfinitePageDao } from './infinite-page-dao.model'
4+
15
export interface InfinitePageHandler<T> {
26
data?: ReadonlyArray<T>
37
getAndSetNext: () => void
48
hasMore: boolean
9+
mutate: KeyedMutator<Array<InfinitePageDao<T>>>
510
}

src-ts/lib/pagination/use-infinite-page.hook.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { InfinitePageHandler } from './infinite-page-handler.model'
88
export function useGetInfinitePage<T>(getKey: (index: number, previousPageData: InfinitePageDao<T>) => string | undefined):
99
InfinitePageHandler<T> {
1010

11-
const { data, setSize, size }: SWRInfiniteResponse<InfinitePageDao<T>> = useSWRInfinite(getKey, { revalidateFirstPage: false })
11+
const { data, mutate, setSize, size }: SWRInfiniteResponse<InfinitePageDao<T>> = useSWRInfinite(getKey, { revalidateFirstPage: false })
1212

1313
// flatten version of badges paginated data
1414
const outputData: ReadonlyArray<T> = flatten(map(data, dao => dao.rows))
@@ -21,5 +21,6 @@ export function useGetInfinitePage<T>(getKey: (index: number, previousPageData:
2121
data: outputData,
2222
getAndSetNext,
2323
hasMore: outputData.length < (data?.[0]?.count || 0),
24+
mutate,
2425
}
2526
}

src-ts/lib/styles/mixins/_layout.mixins.scss

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
padding-left: $space-xxl;
99
padding-right: $space-xxl;
1010
}
11-
11+
1212
@include xxs {
1313
padding-left: $space-lg;
1414
padding-right: $space-lg;
@@ -23,20 +23,27 @@
2323
}
2424

2525
@mixin scrollbar {
26+
// firefox's solution for "customizing" scrollbars
27+
& {
28+
scrollbar-width: thin;
29+
scrollbar-color: rgba($tc-black, 0.4) transparent;
30+
}
31+
2632
&::-webkit-scrollbar-track {
2733
background: transparent;
2834
}
35+
2936
&::-webkit-scrollbar {
3037
width: 5px;
3138
height: 5px;
3239
}
33-
40+
3441
&::-webkit-scrollbar-thumb {
3542
background-color: rgba($tc-black, 0.4);
3643
border-radius: 4px;
37-
44+
3845
&:hover {
3946
background-color: rgba($tc-black, 0.6);
4047
}
4148
}
42-
}
49+
}

src-ts/tools/gamification-admin/game-config/gamification-config.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export interface GamificationConfigModel {
22
ACCEPTED_BADGE_MIME_TYPES: string
3+
CSV_HEADER: Array<string>,
34
MAX_BADGE_IMAGE_FILE_SIZE: number
45
ORG_ID: string
56
PAGE_SIZE: number

0 commit comments

Comments
 (0)