@constructor-io/constructorio-ui-quizzes 1.4.0 → 1.4.2

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.
@@ -8,12 +8,12 @@ exports.initialState = {
8
8
  quizRequestState: constants_1.RequestStates.Stale,
9
9
  };
10
10
  function apiReducer(state, action) {
11
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
11
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
12
12
  switch (action.type) {
13
13
  case actions_1.QuizAPIActionTypes.SET_IS_LOADING:
14
14
  return Object.assign(Object.assign({}, state), { quizRequestState: constants_1.RequestStates.Loading, quizCurrentQuestion: undefined, quizResults: undefined });
15
15
  case actions_1.QuizAPIActionTypes.SET_IS_ERROR:
16
- return Object.assign(Object.assign({}, state), { quizRequestState: constants_1.RequestStates.Error, quizCurrentQuestion: undefined, quizResults: undefined });
16
+ return Object.assign(Object.assign({}, state), { quizRequestState: constants_1.RequestStates.Error, quizCurrentQuestion: undefined, quizResults: undefined, selectedOptionsWithAttributes: undefined });
17
17
  case actions_1.QuizAPIActionTypes.SET_CURRENT_QUESTION: {
18
18
  const { isOpenQuestion, isCoverQuestion, isSingleQuestion, isMultipleQuestion, isSelectQuestion, } = (0, utils_1.getQuestionTypes)((_c = (_b = (_a = action.payload) === null || _a === void 0 ? void 0 : _a.quizCurrentQuestion) === null || _b === void 0 ? void 0 : _b.next_question) === null || _c === void 0 ? void 0 : _c.type);
19
19
  const quizFirstQuestion = state.quizFirstQuestion || ((_d = action.payload) === null || _d === void 0 ? void 0 : _d.quizCurrentQuestion);
@@ -22,12 +22,11 @@ function apiReducer(state, action) {
22
22
  isCoverQuestion,
23
23
  isSingleQuestion,
24
24
  isMultipleQuestion,
25
- isSelectQuestion }), quizFirstQuestion, quizResults: undefined });
25
+ isSelectQuestion }), quizFirstQuestion, quizResults: undefined, selectedOptionsWithAttributes: undefined });
26
26
  }
27
27
  case actions_1.QuizAPIActionTypes.SET_QUIZ_RESULTS: {
28
- const filterExpression = ((_l = (_k = (_j = action.payload) === null || _j === void 0 ? void 0 : _j.quizResults) === null || _k === void 0 ? void 0 : _k.request) === null || _l === void 0 ? void 0 : _l.collection_filter_expression) || null;
29
- const quizResultsFilters = [...new Set((0, utils_1.getFilterValuesFromExpression)(filterExpression))];
30
- return Object.assign(Object.assign({}, state), { quizRequestState: constants_1.RequestStates.Success, quizResults: (_m = action.payload) === null || _m === void 0 ? void 0 : _m.quizResults, quizResultsFilters, quizCurrentQuestion: undefined });
28
+ const selectedOptionsWithAttributes = ((_j = action.payload) === null || _j === void 0 ? void 0 : _j.quizResults.quiz_selected_options.filter((option) => option.has_attribute).map((option) => option.value)) || [];
29
+ return Object.assign(Object.assign({}, state), { quizRequestState: constants_1.RequestStates.Success, quizResults: (_k = action.payload) === null || _k === void 0 ? void 0 : _k.quizResults, quizCurrentQuestion: undefined, selectedOptionsWithAttributes });
31
30
  }
32
31
  case actions_1.QuizAPIActionTypes.RESET_QUIZ:
33
32
  return exports.initialState;
@@ -10,7 +10,7 @@ function RedoButton(props) {
10
10
  if (getResetQuizButtonProps) {
11
11
  return (
12
12
  // eslint-disable-next-line react/button-has-type
13
- react_1.default.createElement("button", Object.assign({}, rest, getResetQuizButtonProps()),
13
+ react_1.default.createElement("button", Object.assign({}, rest, getResetQuizButtonProps('secondary')),
14
14
  react_1.default.createElement(RedoSVG_1.default, null),
15
15
  react_1.default.createElement("span", null, redoText)));
16
16
  }
@@ -8,6 +8,6 @@ function ResultFilters() {
8
8
  const { state } = (0, react_1.useContext)(context_1.default);
9
9
  return (react_1.default.createElement("div", { className: 'cio-results-filter-container' },
10
10
  react_1.default.createElement("p", null, "Because you answered"),
11
- react_1.default.createElement("div", { className: 'cio-results-filter-options' }, (_a = state === null || state === void 0 ? void 0 : state.quiz.resultsFilters) === null || _a === void 0 ? void 0 : _a.map((filter) => (react_1.default.createElement("div", { className: 'cio-results-filter-option', key: filter }, filter))))));
11
+ react_1.default.createElement("div", { className: 'cio-results-filter-options' }, (_a = state === null || state === void 0 ? void 0 : state.quiz.selectedOptionsWithAttributes) === null || _a === void 0 ? void 0 : _a.map((option) => (react_1.default.createElement("div", { className: 'cio-results-filter-option', key: option }, option))))));
12
12
  }
13
13
  exports.default = ResultFilters;
@@ -15,8 +15,8 @@ const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
15
15
  const getSelectInputProps = (0, useSelectInputProps_1.default)(quizAnswerChanged, nextQuestion, (_c = quizApiState.quizCurrentQuestion) === null || _c === void 0 ? void 0 : _c.next_question, quizLocalState.answerInputs);
16
16
  const getNextQuestionButtonProps = (0, useNextQuestionButtonProps_1.default)(nextQuestion, quizApiState, quizLocalState);
17
17
  const getPreviousQuestionButtonProps = (0, usePreviousQuestionButtonProps_1.default)(quizApiState, previousQuestion);
18
- const getResetQuizButtonProps = (0, react_1.useCallback)(() => ({
19
- className: 'cio-question-redo-button',
18
+ const getResetQuizButtonProps = (0, react_1.useCallback)((stylesType = 'primary') => ({
19
+ className: stylesType === 'primary' ? 'cio-question-cta-button' : 'cio-question-redo-button',
20
20
  type: 'button',
21
21
  onClick: () => resetQuiz(),
22
22
  }), [resetQuiz]);
@@ -33,7 +33,7 @@ const useQuiz = (quizOptions) => {
33
33
  sessionId: quizLocalState.quizSessionId,
34
34
  currentQuestion: quizApiState.quizCurrentQuestion,
35
35
  results: quizApiState.quizResults,
36
- resultsFilters: quizApiState.quizResultsFilters,
36
+ selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
37
37
  },
38
38
  }, events: Object.assign({}, quizEvents) }, propGetters), { primaryColorStyles });
39
39
  };
@@ -105,8 +105,12 @@ const getMockState = (question) => ({
105
105
  quiz_id: '',
106
106
  quiz_session_id: '',
107
107
  quiz_version_id: '',
108
+ quiz_selected_options: [
109
+ { value: 'Option 1', has_attribute: true },
110
+ { value: 'Option 2', has_attribute: true },
111
+ ],
108
112
  },
109
- resultsFilters: ['Chocolate', 'Medium'],
113
+ selectedOptionsWithAttributes: ['Option 1', 'Option 2'],
110
114
  },
111
115
  });
112
116
  exports.getMockState = getMockState;
package/lib/cjs/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertPrimaryColorsToString = exports.rgbToHsl = exports.sleep = exports.logger = exports.resetQuizSessionStorageState = exports.getStateFromSessionStorage = exports.getFilterValuesFromExpression = exports.isFunction = exports.getPreferredColorScheme = exports.getQuestionTypes = exports.stringify = exports.stringifyWithDefaults = exports.functionStrings = exports.getStoryParams = exports.renderImages = void 0;
3
+ exports.convertPrimaryColorsToString = exports.rgbToHsl = exports.sleep = exports.logger = exports.resetQuizSessionStorageState = exports.getStateFromSessionStorage = exports.isFunction = exports.getPreferredColorScheme = exports.getQuestionTypes = exports.stringify = exports.stringifyWithDefaults = exports.functionStrings = exports.getStoryParams = exports.renderImages = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  /* eslint-disable no-console */
6
6
  const react_1 = tslib_1.__importDefault(require("react"));
@@ -105,25 +105,6 @@ function isFunction(fn) {
105
105
  return fn && typeof fn === 'function';
106
106
  }
107
107
  exports.isFunction = isFunction;
108
- const isValueExpression = (exp) => 'name' in exp && 'value' in exp;
109
- const isAndFilter = (exp) => 'and' in exp;
110
- const isOrFilter = (exp) => 'or' in exp;
111
- const getFilterValuesFromExpression = (exp) => {
112
- if (!exp) {
113
- return [];
114
- }
115
- if (isAndFilter(exp)) {
116
- return exp.and.flatMap((innerExpression) => (0, exports.getFilterValuesFromExpression)(innerExpression));
117
- }
118
- if (isOrFilter(exp)) {
119
- return exp.or.flatMap((innerExpression) => (0, exports.getFilterValuesFromExpression)(innerExpression));
120
- }
121
- if (isValueExpression(exp)) {
122
- return [exp.value];
123
- }
124
- return [];
125
- };
126
- exports.getFilterValuesFromExpression = getFilterValuesFromExpression;
127
108
  const getStateFromSessionStorage = (quizStateKey) => {
128
109
  var _a;
129
110
  const state = (_a = window === null || window === void 0 ? void 0 : window.sessionStorage) === null || _a === void 0 ? void 0 : _a.getItem(quizStateKey);
@@ -1,5 +1,5 @@
1
1
  import { RequestStates } from '../../constants';
2
- import { getFilterValuesFromExpression, getQuestionTypes } from '../../utils';
2
+ import { getQuestionTypes } from '../../utils';
3
3
  import { QuizAPIActionTypes } from './actions';
4
4
  export const initialState = {
5
5
  quizRequestState: RequestStates.Stale,
@@ -19,6 +19,7 @@ export default function apiReducer(state, action) {
19
19
  quizRequestState: RequestStates.Error,
20
20
  quizCurrentQuestion: undefined,
21
21
  quizResults: undefined,
22
+ selectedOptionsWithAttributes: undefined,
22
23
  };
23
24
  case QuizAPIActionTypes.SET_CURRENT_QUESTION: {
24
25
  const { isOpenQuestion, isCoverQuestion, isSingleQuestion, isMultipleQuestion, isSelectQuestion, } = getQuestionTypes(action.payload?.quizCurrentQuestion?.next_question?.type);
@@ -38,17 +39,19 @@ export default function apiReducer(state, action) {
38
39
  },
39
40
  quizFirstQuestion,
40
41
  quizResults: undefined,
42
+ selectedOptionsWithAttributes: undefined,
41
43
  };
42
44
  }
43
45
  case QuizAPIActionTypes.SET_QUIZ_RESULTS: {
44
- const filterExpression = action.payload?.quizResults?.request?.collection_filter_expression || null;
45
- const quizResultsFilters = [...new Set(getFilterValuesFromExpression(filterExpression))];
46
+ const selectedOptionsWithAttributes = action.payload?.quizResults.quiz_selected_options
47
+ .filter((option) => option.has_attribute)
48
+ .map((option) => option.value) || [];
46
49
  return {
47
50
  ...state,
48
51
  quizRequestState: RequestStates.Success,
49
52
  quizResults: action.payload?.quizResults,
50
- quizResultsFilters,
51
53
  quizCurrentQuestion: undefined,
54
+ selectedOptionsWithAttributes,
52
55
  };
53
56
  }
54
57
  case QuizAPIActionTypes.RESET_QUIZ:
@@ -7,7 +7,7 @@ function RedoButton(props) {
7
7
  if (getResetQuizButtonProps) {
8
8
  return (
9
9
  // eslint-disable-next-line react/button-has-type
10
- React.createElement("button", { ...rest, ...getResetQuizButtonProps() },
10
+ React.createElement("button", { ...rest, ...getResetQuizButtonProps('secondary') },
11
11
  React.createElement(RedoSVG, null),
12
12
  React.createElement("span", null, redoText)));
13
13
  }
@@ -4,6 +4,6 @@ function ResultFilters() {
4
4
  const { state } = useContext(QuizContext);
5
5
  return (React.createElement("div", { className: 'cio-results-filter-container' },
6
6
  React.createElement("p", null, "Because you answered"),
7
- React.createElement("div", { className: 'cio-results-filter-options' }, state?.quiz.resultsFilters?.map((filter) => (React.createElement("div", { className: 'cio-results-filter-option', key: filter }, filter))))));
7
+ React.createElement("div", { className: 'cio-results-filter-options' }, state?.quiz.selectedOptionsWithAttributes?.map((option) => (React.createElement("div", { className: 'cio-results-filter-option', key: option }, option))))));
8
8
  }
9
9
  export default ResultFilters;
@@ -11,8 +11,8 @@ const usePropsGetters = (quizEvents, quizApiState, quizLocalState) => {
11
11
  const getSelectInputProps = useSelectInputProps(quizAnswerChanged, nextQuestion, quizApiState.quizCurrentQuestion?.next_question, quizLocalState.answerInputs);
12
12
  const getNextQuestionButtonProps = useNextQuestionButtonProps(nextQuestion, quizApiState, quizLocalState);
13
13
  const getPreviousQuestionButtonProps = usePreviousQuestionButtonProps(quizApiState, previousQuestion);
14
- const getResetQuizButtonProps = useCallback(() => ({
15
- className: 'cio-question-redo-button',
14
+ const getResetQuizButtonProps = useCallback((stylesType = 'primary') => ({
15
+ className: stylesType === 'primary' ? 'cio-question-cta-button' : 'cio-question-redo-button',
16
16
  type: 'button',
17
17
  onClick: () => resetQuiz(),
18
18
  }), [resetQuiz]);
@@ -32,7 +32,7 @@ const useQuiz = (quizOptions) => {
32
32
  sessionId: quizLocalState.quizSessionId,
33
33
  currentQuestion: quizApiState.quizCurrentQuestion,
34
34
  results: quizApiState.quizResults,
35
- resultsFilters: quizApiState.quizResultsFilters,
35
+ selectedOptionsWithAttributes: quizApiState.selectedOptionsWithAttributes,
36
36
  },
37
37
  },
38
38
  events: {
@@ -117,8 +117,12 @@ export const getMockState = (question) => ({
117
117
  quiz_id: '',
118
118
  quiz_session_id: '',
119
119
  quiz_version_id: '',
120
+ quiz_selected_options: [
121
+ { value: 'Option 1', has_attribute: true },
122
+ { value: 'Option 2', has_attribute: true },
123
+ ],
120
124
  },
121
- resultsFilters: ['Chocolate', 'Medium'],
125
+ selectedOptionsWithAttributes: ['Option 1', 'Option 2'],
122
126
  },
123
127
  });
124
128
  const mockElementProps = {
package/lib/mjs/utils.js CHANGED
@@ -93,24 +93,6 @@ export function getPreferredColorScheme() {
93
93
  export function isFunction(fn) {
94
94
  return fn && typeof fn === 'function';
95
95
  }
96
- const isValueExpression = (exp) => 'name' in exp && 'value' in exp;
97
- const isAndFilter = (exp) => 'and' in exp;
98
- const isOrFilter = (exp) => 'or' in exp;
99
- export const getFilterValuesFromExpression = (exp) => {
100
- if (!exp) {
101
- return [];
102
- }
103
- if (isAndFilter(exp)) {
104
- return exp.and.flatMap((innerExpression) => getFilterValuesFromExpression(innerExpression));
105
- }
106
- if (isOrFilter(exp)) {
107
- return exp.or.flatMap((innerExpression) => getFilterValuesFromExpression(innerExpression));
108
- }
109
- if (isValueExpression(exp)) {
110
- return [exp.value];
111
- }
112
- return [];
113
- };
114
96
  export const getStateFromSessionStorage = (quizStateKey) => {
115
97
  const state = window?.sessionStorage?.getItem(quizStateKey);
116
98
  if (state) {
package/lib/styles.css CHANGED
@@ -565,7 +565,6 @@
565
565
  /* Container */
566
566
  .cio-container--with-image {
567
567
  display: flex;
568
- justify-content: center;
569
568
  align-items: center;
570
569
  margin-bottom: 0;
571
570
  padding-bottom: 0;
@@ -582,7 +581,6 @@
582
581
 
583
582
  /* Cover Page Component */
584
583
  .cio-cover-question-container--with-image {
585
- justify-content: center;
586
584
  margin-bottom: 0;
587
585
  padding-bottom: 0;
588
586
  }
@@ -629,6 +627,7 @@
629
627
  padding: 6% 2%;
630
628
  align-items: center;
631
629
  flex-direction: row;
630
+ justify-content: center;
632
631
  }
633
632
  .cio-cover-question-container--with-image {
634
633
  flex-direction: row-reverse;
@@ -6,7 +6,7 @@ export type QuizAPIReducerState = {
6
6
  quizCurrentQuestion?: CurrentQuestion;
7
7
  quizFirstQuestion?: NextQuestionResponse;
8
8
  quizResults?: QuizResultsResponse;
9
- quizResultsFilters?: string[];
9
+ selectedOptionsWithAttributes?: string[];
10
10
  };
11
11
  export declare const initialState: QuizAPIReducerState;
12
12
  export default function apiReducer(state: QuizAPIReducerState, action: ActionQuizAPI): QuizAPIReducerState;
@@ -44,7 +44,7 @@ export interface QuizReturnState {
44
44
  sessionId?: string;
45
45
  currentQuestion?: CurrentQuestion | undefined;
46
46
  results?: QuizResultsResponse | undefined;
47
- resultsFilters?: string[];
47
+ selectedOptionsWithAttributes?: string[];
48
48
  };
49
49
  }
50
50
  export type AnswerInputState = {
@@ -154,7 +154,7 @@ export type GetCoverQuestionProps = () => CoverQuestionProps;
154
154
  export type GetSelectInputProps = (option: QuestionOption) => SelectInputProps;
155
155
  export type GetNextQuestionButtonProps = () => NextQuestionButtonProps;
156
156
  export type GetPreviousQuestionButtonProps = () => PreviousQuestionButtonProps;
157
- export type GetResetQuizButtonProps = () => ResetQuizButtonProps;
157
+ export type GetResetQuizButtonProps = (stylesType?: 'primary' | 'secondary') => ResetQuizButtonProps;
158
158
  export type GetHydrateQuizButtonProps = () => HydrateQuizButtonProps;
159
159
  export type GetAddToCartButtonProps = (result: QuizResultDataPartial, price?: number) => AddToCartButtonProps;
160
160
  export type GetQuizImageProps = () => QuizImageProps;
@@ -1,4 +1,3 @@
1
- import { FilterExpression } from '@constructor-io/constructorio-client-javascript/lib/types';
2
1
  import { QuestionTypes } from './components/CioQuiz/actions';
3
2
  import { QuizLocalReducerState } from './components/CioQuiz/quizLocalReducer';
4
3
  import { PrimaryColorStyles, QuestionImages } from './types';
@@ -37,7 +36,6 @@ export declare const getQuestionTypes: (questionType?: `${QuestionTypes}`) => {
37
36
  };
38
37
  export declare function getPreferredColorScheme(): string;
39
38
  export declare function isFunction(fn: any): boolean;
40
- export declare const getFilterValuesFromExpression: (exp: FilterExpression | null) => string[];
41
39
  export declare const getStateFromSessionStorage: (quizStateKey: string) => QuizLocalReducerState | null;
42
40
  export declare const resetQuizSessionStorageState: (quizStateKey: string) => () => void;
43
41
  export declare const logger: (action: any) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructor-io/constructorio-ui-quizzes",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Constructor.io Quizzes UI library for web applications",
5
5
  "author": "constructor.io",
6
6
  "license": "MIT",
@@ -54,7 +54,7 @@
54
54
  "check-license": "license-checker --production --onlyAllow 'Apache-2.0;BSD-3-Clause;MIT;0BSD;BSD-2-Clause' --excludePackages 'picocolors@1.0.0'"
55
55
  },
56
56
  "peerDependencies": {
57
- "@constructor-io/constructorio-client-javascript": "^2.35.12",
57
+ "@constructor-io/constructorio-client-javascript": "^2.35.14",
58
58
  "react": ">=16.12.0",
59
59
  "react-dom": ">=16.12.0",
60
60
  "tslib": "^2.4.0"