diff --git a/jest.config.js b/jest.config.js
index c33a3d6e..a0daf1b2 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,3 +1,24 @@
module.exports = {
- preset: '@vue/cli-plugin-unit-jest/presets/no-babel'
-}
+ verbose: true,
+ coverageReporters: ["html", "text", "jest-junit", "cobertura"],
+ testResultsProcessor: "jest-junit",
+ preset: "@vue/cli-plugin-unit-jest",
+ transform: { "^.+\\.vue$": "vue-jest" },
+ moduleFileExtensions: ["js", "vue"],
+ modulePathIgnorePatterns: ["vin-lookup"],
+ collectCoverageFrom: [
+ "src/**/*.{js,vue}",
+ "!src/main.js",
+ "!src/constants/*.js",
+ "!src/router/**/*.js",
+ "!src/helpers/unit-test-helper.js",
+ "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue"
+ // END
+ ], // ! means exclude from coverage.
+ testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
+ coverageThreshold: {
+ // global: {
+ // statements: 80,
+ // },
+ },
+};
diff --git a/package-lock.json b/package-lock.json
index 0cb1a890..659ddc3a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -990,6 +990,11 @@
"integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
"dev": true
},
+ "@popperjs/core": {
+ "version": "2.11.6",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
+ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
+ },
"@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
@@ -1532,29 +1537,6 @@
"webpack-merge": "^5.7.3",
"webpack-virtual-modules": "^0.4.2",
"whatwg-fetch": "^3.6.2"
- },
- "dependencies": {
- "@vue/vue-loader-v15": {
- "version": "npm:vue-loader@15.10.0",
- "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
- "integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
- "dev": true,
- "requires": {
- "@vue/component-compiler-utils": "^3.1.0",
- "hash-sum": "^1.0.2",
- "loader-utils": "^1.1.0",
- "vue-hot-reload-api": "^2.3.0",
- "vue-style-loader": "^4.1.0"
- },
- "dependencies": {
- "hash-sum": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
- "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
- "dev": true
- }
- }
- }
}
},
"@vue/cli-shared-utils": {
@@ -1804,6 +1786,27 @@
"integrity": "sha512-E2P4oXSaWDqTZNbmKZFVLrNN/siVN78YkEqs7pHryWerrlZR9bBFLWdJwRoguX45Ru6HxIflzKl4vQvwRMwm5g==",
"dev": true
},
+ "@vue/vue-loader-v15": {
+ "version": "npm:vue-loader@15.10.0",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
+ "integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
+ "dev": true,
+ "requires": {
+ "@vue/component-compiler-utils": "^3.1.0",
+ "hash-sum": "^1.0.2",
+ "loader-utils": "^1.1.0",
+ "vue-hot-reload-api": "^2.3.0",
+ "vue-style-loader": "^4.1.0"
+ },
+ "dependencies": {
+ "hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+ "dev": true
+ }
+ }
+ },
"@vue/vue3-jest": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@vue/vue3-jest/-/vue3-jest-27.0.0.tgz",
@@ -2499,6 +2502,11 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
+ "bootstrap": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.1.tgz",
+ "integrity": "sha512-UQi3v2NpVPEi1n35dmRRzBJFlgvWHYwyem6yHhuT6afYF+sziEt46McRbT//kVXZ7b1YUYEVGdXEH74Nx3xzGA=="
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -3310,7 +3318,8 @@
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
},
"default-gateway": {
"version": "6.0.3",
@@ -7702,6 +7711,20 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
+ "pinia": {
+ "version": "2.0.22",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.22.tgz",
+ "integrity": "sha512-u+b8/BC+tmvo3ACbYO2w5NfxHWFOjvvw9DQnyT0dW8aUMCPRQT5QnfZ5R5W2MzZBMTeZRMQI7V/QFbafmM9QHw==",
+ "requires": {
+ "@vue/devtools-api": "^6.2.1",
+ "vue-demi": "*"
+ }
+ },
+ "pinia-plugin-persistedstate": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-2.2.0.tgz",
+ "integrity": "sha512-j3CknBg4H17MXDwG+X6JT50wmGkxG5cWshVb5pdV8o/ivMxiVsML9ADwe7SEchas1myIWd6/sYeVv0/IGT5YrQ=="
+ },
"pirates": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@@ -8683,11 +8706,6 @@
"integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
"dev": true
},
- "shvl": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.3.tgz",
- "integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw=="
- },
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -9393,6 +9411,11 @@
"@vue/shared": "3.2.38"
}
},
+ "vue-demi": {
+ "version": "0.13.11",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
+ "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A=="
+ },
"vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
@@ -9504,23 +9527,6 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
- "vuex": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
- "integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
- "requires": {
- "@vue/devtools-api": "^6.0.0-beta.11"
- }
- },
- "vuex-persistedstate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-4.1.0.tgz",
- "integrity": "sha512-3SkEj4NqwM69ikJdFVw6gObeB0NHyspRYMYkR/EbhR0hbvAKyR5gksVhtAfY1UYuWUOCCA0QNGwv9pOwdj+XUQ==",
- "requires": {
- "deepmerge": "^4.2.2",
- "shvl": "^2.0.3"
- }
- },
"w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
diff --git a/package.json b/package.json
index f8c415c0..72c6e699 100644
--- a/package.json
+++ b/package.json
@@ -5,19 +5,21 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
- "test:unit": "vue-cli-service test:unit"
+ "test:unit": "vue-cli-service test:unit --coverage --ci",
+ "test:unit:lite": "vue-cli-service test:unit --ci"
},
"dependencies": {
+ "@popperjs/core": "^2.10.2",
"axios": "^0.27.2",
+ "bootstrap": "^5.1.1",
+ "pinia": "^2.0.22",
+ "pinia-plugin-persistedstate": "^2.2.0",
"vue": "^3.2.13",
- "vue-router": "^4.0.3",
- "vuex": "^4.0.0",
- "vuex-persistedstate": "^4.1.0"
+ "vue-router": "^4.0.3"
},
"devDependencies": {
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-unit-jest": "~5.0.0",
- "@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/test-utils": "^2.0.0-0",
"@vue/vue3-jest": "^27.0.0-alpha.1",
diff --git a/src/App.vue b/src/App.vue
index ec98c47b..d6c5927b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,30 +1,13 @@
-
-
+
+
+
+
+
+
+ @import "./node_modules/bootstrap/scss/bootstrap";
+ @import "@/styles/common-animations.scss";
+
\ No newline at end of file
diff --git a/src/constants/dynamic-strings.js b/src/constants/dynamic-strings.js
new file mode 100644
index 00000000..c526e45a
--- /dev/null
+++ b/src/constants/dynamic-strings.js
@@ -0,0 +1,7 @@
+const dynamicStrings = {
+ GLOBAL_STATE: "globalState",
+ CUSTOM: "custom",
+ ROUTER_LINK: "routerLink:"
+ };
+
+ export { dynamicStrings };
\ No newline at end of file
diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js
new file mode 100644
index 00000000..c1cfb957
--- /dev/null
+++ b/src/constants/query-strings.js
@@ -0,0 +1,5 @@
+const queryStrings = {
+ ISS_PAGE: 'issPage'
+ };
+
+ export { queryStrings };
\ No newline at end of file
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index d6ce74f3..5f310f43 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -25,9 +25,21 @@ const storeActions = {
GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer",
GET_MOLDING_QUESTIONS: "getMoldingQuestions",
VALIDATE_ZIP: "validateZip",
- GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser",
- RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger",
CLEAR_VIN: "clearVin",
+
+ // VEHICLE MUTATIONS
+ UPDATE_YEAR: "updateYear",
+ UPDATE_MAKE: "updateMake",
+ UPDATE_MODEL: "updateModel",
+ UPDATE_STYLE: "updateStyle",
+ UPDATE_CAR_ID: "updateCarId",
+ UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory",
+ UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl",
+ UPDATE_VEHICLE_IMAGE_VIF_NUMBER: "updateVehicleImageVifNumber",
+ UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
+ UPDATE_VEHICLE_VIN: "updateVehicleVin",
+ UPDATE_VEHICLE: "updateVehicle",
+
// DEPENDENCY MUTATIONS
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
deleted file mode 100644
index 059cf88d..00000000
--- a/src/constants/store-mutations.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const storeMutations = {
-
- // VEHICLE MUTATIONS
- UPDATE_YEAR: "updateYear",
- UPDATE_MAKE: "updateMake",
- UPDATE_MODEL: "updateModel",
- UPDATE_STYLE: "updateStyle",
- UPDATE_CAR_ID: "updateCarId",
- UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory",
- UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl",
- UPDATE_VEHICLE_IMAGE_VIF_NUMBER: "updateVehicleImageVifNumber",
- UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
- UPDATE_VEHICLE_VIN: "updateVehicleVin",
- UPDATE_VEHICLE: "updateVehicle",
-
-
- };
-
- export { storeMutations };
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index ae9d0aa3..49eb55a4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,12 +1,11 @@
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
-import store from './store';
+import "../node_modules/bootstrap/dist/js/bootstrap.js";
const vueApp = createApp(App);
vueApp.use(router);
-vueApp.use(store);
vueApp.mount("#app");
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
new file mode 100644
index 00000000..7e405d1b
--- /dev/null
+++ b/src/mixins/base-mixin.js
@@ -0,0 +1,50 @@
+import { storeActions } from "@/constants/store-actions.js";
+import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
+import { vehicleCategories } from "@/constants/vehicle-categories.js";
+import { queryStrings } from "@/constants/query-strings";
+import { dynamicStrings } from "@/constants/dynamic-strings";
+
+export default {
+ data() {
+ return {
+ cmsContentByWidget: {}
+ };
+ },
+ methods: {
+ setCmsContent(cmsContent) {
+ this.$root.cmsContentByWidget = cmsContent;
+ },
+ getCmsContent(widgetName, fieldName) {
+ return this.$root.cmsContentByWidget?.[widgetName]?.[fieldName] ? this.$root.cmsContentByWidget[widgetName][fieldName] : '';
+ },
+ },
+ computed: {
+ storeActions() {
+ return storeActions;
+ },
+ navigationScenarios() {
+ return navigationScenarios;
+ },
+ vehicleCategories() {
+ return vehicleCategories;
+ },
+ queryStrings(){
+ return queryStrings;
+ },
+ dynamicStrings(){
+ return dynamicStrings;
+ },
+ cssClassNameForCmsWidget(){
+ return "widget-name-" + this.cmsWidgetName;
+ },
+ },
+};
+
+function encodeUriData(payload) {
+ if (payload && Object.keys(payload).length > 0) {
+ // Loop through the payload and encode the values
+ Object.keys(payload).forEach((key) => {
+ payload[key] = encodeURIComponent(payload[key]);
+ });
+ }
+}
diff --git a/src/router/index.js b/src/router/index.js
index 0c4cf138..c76f41bf 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,5 +1,4 @@
import { storeActions } from "@/constants/store-actions";
-import { storeMutations } from "@/constants/store-mutations";
import { createWebHistory, createRouter } from "vue-router";
const routes = [
diff --git a/src/store/index.js b/src/store/index.js
deleted file mode 100644
index 6acc99d8..00000000
--- a/src/store/index.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import { createStore } from "vuex";
-import { endpoints } from "@/constants/endpoints.js";
-import createPersistedState from "vuex-persistedstate";
-import globalMethods from "@/global-methods";
-import { storeActions } from "@/constants/store-actions";
-import { applicationConfig } from "@/constants/application-config";
-import { issPageValues } from "@/router/router-constants/issPage-values";
-
-// Export State
-const getDefaultState = () => {
- return {
- // State ...
- };
-};
-
-export const state = getDefaultState();
-
-// Export Mutations
-export const mutations = {
- // Mutations...
-};
-
-// Export Getters
-export const getters = {
- // Getters...
-};
-
-function getAllValuesOfPropertyInArrayOfObjects(array, propertyName) {
- return (array ?? []).map(x => x[propertyName]).filter(x => x);
-}
-
-// Export Actions
-export const actions = {
- // Content API Actions
- getRouteInfo(context, { pageName }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetRouteInfo.method,
- endpoint: endpoints.GetRouteInfo.url,
- payload: {
- pageName: pageName,
- },
- });
- },
-
- getHomepageName(context) {
- return globalMethods.callHttpClient({
- method: endpoints.GetHomepageInfo.method,
- endpoint: endpoints.GetHomepageInfo.url,
- });
- },
-
- getPageData(context, { pageName }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetPageData.method,
- endpoint: `${endpoints.GetPageData.url}/${pageName}`,
- payload: {},
- });
- },
-};
-
-export default createStore({
- plugins: [createPersistedState()],
-
- // IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons:
- // * The CMS can reference the fields by name
- // * Return users may have a previous "version" of the model, and we don't want
- // them to have a breaking experience, because the model might have changed.
- state,
- mutations,
- getters,
- actions,
-});
\ No newline at end of file
diff --git a/src/styles/common-animations.scss b/src/styles/common-animations.scss
new file mode 100644
index 00000000..c03c267a
--- /dev/null
+++ b/src/styles/common-animations.scss
@@ -0,0 +1,30 @@
+.fade-enter-active {
+ transition: opacity 0.8s ease;
+}
+
+.fade-leave-active {
+ transition: opacity 0.3s ease;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+ opacity: 0;
+}
+
+.route-fade-enter-active .fade-on-route-transition {
+ transition: opacity 0.2s ease-out; //This duration should be kept in sync with the app.vue element attribute
+}
+
+.route-fade-leave-active .fade-on-route-transition {
+ transition: opacity 0.2s ease-in; //This duration should be kept in sync with the app.vue element attribute
+}
+
+.route-fade-enter-from .fade-on-route-transition,
+.route-fade-leave-to .fade-on-route-transition {
+ /*
+ Hack around a Chrome 96 bug in handling nested opacity transitions.
+ This is not needed in other browsers or Chrome 99+ where the bug
+ has been fixed.
+ */
+ opacity: 0.001;
+}
\ No newline at end of file
diff --git a/vue.config.js b/vue.config.js
index 2c0367e4..940b5656 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,5 +1,22 @@
+process.env.VUE_APP_CONSUMER_CF_DISTRO =
+ "https://consumerapidev.safelite.com";
+process.env.VUE_APP_CURRENT_ENVIRONMENT = "Localhost";
+
module.exports = {
publicPath: "/",
+ css: {
+ loaderOptions: {
+ sass: {
+ // Load Order Matters!!!
+ // Note: only include functions, variables and mixins here
+ additionalData: `
+ @import "./node_modules/bootstrap/scss/functions";
+ @import "./node_modules/bootstrap/scss/variables";
+ @import "./node_modules/bootstrap/scss/mixins";
+ `,
+ },
+ },
+ },
configureWebpack: {
devtool: 'source-map'
},
diff --git a/vue.release.config.js b/vue.release.config.js
index 2c0367e4..f6b57ccf 100644
--- a/vue.release.config.js
+++ b/vue.release.config.js
@@ -1,5 +1,21 @@
+process.env.VUE_APP_CONSUMER_CF_DISTRO = "__VUE_APP_CONSUMER_CF_DISTRO__";
+process.env.VUE_APP_CURRENT_ENVIRONMENT = "__VUE_APP_CURRENT_ENVIRONMENT__";
+
module.exports = {
publicPath: "/",
+ css: {
+ loaderOptions: {
+ sass: {
+ // Load Order Matters!!!
+ // Note: only include functions, variables and mixins here
+ additionalData: `
+ @import "./node_modules/bootstrap/scss/functions";
+ @import "./node_modules/bootstrap/scss/variables";
+ @import "./node_modules/bootstrap/scss/mixins";
+ `,
+ },
+ },
+ },
configureWebpack: {
devtool: 'source-map'
},