diff --git a/cypress/constants/machete-constants.ts b/cypress/constants/machete-constants.ts index af69d48a..a2ac7b29 100644 --- a/cypress/constants/machete-constants.ts +++ b/cypress/constants/machete-constants.ts @@ -27,6 +27,11 @@ export const onlineOrderRoutes: IOnlineOrderRoute = { orderConfirm: `${onlineOrdersBase}/order-confirm`, }; +const settingsBase: string = "/configuration/settings"; +export const macheteSettingsRoutes: { list: string } = { + list: `${settingsBase}` +} + export const initConfirmCheckedTerms = [ { name: "completion", diff --git a/cypress/fixtures/settings/DisableOnlineOrders.json b/cypress/fixtures/settings/DisableOnlineOrders.json new file mode 100644 index 00000000..3d7d7e14 --- /dev/null +++ b/cypress/fixtures/settings/DisableOnlineOrders.json @@ -0,0 +1,12 @@ +{ + "key": "DisableOnlineOrders", + "value": "FALSE", + "description": "Enter either TRUE or FALSE. Enter TRUE to turn off access to the online hiring portal", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.263", + "dateupdated": "2022-05-24T13:10:33.07", + "id": 28, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/DisableOnlineOrdersBanner.json b/cypress/fixtures/settings/DisableOnlineOrdersBanner.json new file mode 100644 index 00000000..c66f1a44 --- /dev/null +++ b/cypress/fixtures/settings/DisableOnlineOrdersBanner.json @@ -0,0 +1,12 @@ +{ + "key": "DisableOnlineOrdersBanner", + "value": "Online orders are currently disabled. Please call the center.anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "The message for employers when the online hring portal is turned off", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.277", + "dateupdated": "2022-05-29T00:52:38.217", + "id": 29, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/DisableOnlineOrdersBannerInfoUrl.json b/cypress/fixtures/settings/DisableOnlineOrdersBannerInfoUrl.json new file mode 100644 index 00000000..c26b1bed --- /dev/null +++ b/cypress/fixtures/settings/DisableOnlineOrdersBannerInfoUrl.json @@ -0,0 +1,12 @@ +{ + "key": "DisableOnlineOrdersBannerInfoUrl", + "value": "DisableOnlineOrdersBannerInfoUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "The URL to your center's website explaining why online hiring is turned off", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.29", + "dateupdated": "2022-05-29T00:52:39.46", + "id": 30, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/DisableWorkersVaccineRequirement.json b/cypress/fixtures/settings/DisableWorkersVaccineRequirement.json new file mode 100644 index 00000000..407a75f2 --- /dev/null +++ b/cypress/fixtures/settings/DisableWorkersVaccineRequirement.json @@ -0,0 +1,12 @@ +{ + "key": "DisableWorkersVaccineRequirement", + "value": "FALSE", + "description": null, + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T15:13:12.66", + "dateupdated": "2022-05-24T15:13:12.66", + "id": 32, + "updatedby": "Init T. Script" +} diff --git a/cypress/fixtures/settings/OnlineOrdersEnglishReqNote.json b/cypress/fixtures/settings/OnlineOrdersEnglishReqNote.json new file mode 100644 index 00000000..28f0c87a --- /dev/null +++ b/cypress/fixtures/settings/OnlineOrdersEnglishReqNote.json @@ -0,0 +1,12 @@ +{ + "key": "OnlineOrdersEnglishReqNote", + "value": "OnlineOrdersEnglishReqNoteanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the site details step. When employers requests an English-speaking worker, this note provides any center-specific details", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.137", + "dateupdated": "2022-05-29T00:53:29.85", + "id": 18, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OnlineOrdersIntroMessage.json b/cypress/fixtures/settings/OnlineOrdersIntroMessage.json new file mode 100644 index 00000000..0106a2f1 --- /dev/null +++ b/cypress/fixtures/settings/OnlineOrdersIntroMessage.json @@ -0,0 +1,12 @@ +{ + "key": "OnlineOrdersIntroMessage", + "value": "OnlineOrdersIntroMessageanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displays in the 1st step of the online hiring. Include your center's basic information and how you program works, contact number, etc. Links to your website will also work.", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.113", + "dateupdated": "2022-05-29T00:53:28.473", + "id": 16, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OnlineOrdersTerms.json b/cypress/fixtures/settings/OnlineOrdersTerms.json new file mode 100644 index 00000000..3fa499d4 --- /dev/null +++ b/cypress/fixtures/settings/OnlineOrdersTerms.json @@ -0,0 +1,12 @@ +{ + "key": "OnlineOrdersTerms", + "value": "[{\"name\":\"term1\",\"text\":\"This is the term one\"},{\"name\":\"term2\",\"text\":\"This is the term two\"}]", + "description": "The terms that an employer has to accept before proceding with creating a work order", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-06-21T15:29:44.333", + "dateupdated": "2022-06-21T15:29:44.333", + "id": 1002, + "updatedby": "Init T. Script" +} diff --git a/cypress/fixtures/settings/OnlineOrdersTransportDetailsLink.json b/cypress/fixtures/settings/OnlineOrdersTransportDetailsLink.json new file mode 100644 index 00000000..00392460 --- /dev/null +++ b/cypress/fixtures/settings/OnlineOrdersTransportDetailsLink.json @@ -0,0 +1,12 @@ +{ + "key": "OnlineOrdersTransportDetailsLink", + "value": "OnlineOrdersTransportDetailsLinkanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will display if your transport provider cost rules have any fees. Include the link to your website with transport cost info ", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.15", + "dateupdated": "2022-05-29T00:53:31.323", + "id": 19, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderConfirmTransportFeesNotice.json b/cypress/fixtures/settings/OrderConfirmTransportFeesNotice.json new file mode 100644 index 00000000..5678350e --- /dev/null +++ b/cypress/fixtures/settings/OrderConfirmTransportFeesNotice.json @@ -0,0 +1,12 @@ +{ + "key": "OrderConfirmTransportFeesNotice", + "value": "OrderConfirmTransportFeesNoticeanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will display in the last step if employer chooses a transport method with fees. Inlcude text on why the fee applies", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.16", + "dateupdated": "2022-05-29T00:53:32.737", + "id": 20, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewLaborCostMethodHelper.json b/cypress/fixtures/settings/OrderReviewLaborCostMethodHelper.json new file mode 100644 index 00000000..969937fe --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewLaborCostMethodHelper.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewLaborCostMethodHelper", + "value": "OrderReviewLaborCostMethodHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The helper text for labor cost explaining payment options", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.213", + "dateupdated": "2022-05-29T00:52:33.313", + "id": 24, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewLaborCostPayMethodHelper.json b/cypress/fixtures/settings/OrderReviewLaborCostPayMethodHelper.json new file mode 100644 index 00000000..9c01209e --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewLaborCostPayMethodHelper.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewLaborCostPayMethodHelper", + "value": "OrderReviewLaborCostAboutUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The url to your website explaining the labor cost", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.24", + "dateupdated": "2022-05-29T00:52:35.697", + "id": 26, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewNextStepsHelper.json b/cypress/fixtures/settings/OrderReviewNextStepsHelper.json new file mode 100644 index 00000000..a2fb16d8 --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewNextStepsHelper.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewNextStepsHelper", + "value": "OrderReviewNextStepsHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. Describe the next steps in the process, will employer need to wait for confirmation via a call, text or wait for email, etc.", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.25", + "dateupdated": "2022-05-29T00:52:36.943", + "id": 27, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewSkillsSummaryLabel.json b/cypress/fixtures/settings/OrderReviewSkillsSummaryLabel.json new file mode 100644 index 00000000..900203c4 --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewSkillsSummaryLabel.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewSkillsSummaryLabel", + "value": "OrderReviewSkillsSummaryLabelanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The label for the work assignments summary table", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.183", + "dateupdated": "2022-05-29T00:52:30.817", + "id": 22, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewTransportFeeEmplanationUrl.json b/cypress/fixtures/settings/OrderReviewTransportFeeEmplanationUrl.json new file mode 100644 index 00000000..b9d5c325 --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewTransportFeeEmplanationUrl.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewTransportFeeEmplanationUrl", + "value": "OrderReviewTransportFeeAboutUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The url to your website explaining the transport fees", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.227", + "dateupdated": "2022-05-29T00:52:34.5", + "id": 25, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewTransportFeeMethodHelper.json b/cypress/fixtures/settings/OrderReviewTransportFeeMethodHelper.json new file mode 100644 index 00000000..9082fc9f --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewTransportFeeMethodHelper.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewTransportFeeMethodHelper", + "value": "OrderReviewTransportFeeMethodHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The helper text for transport fees explaining payment options", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.2", + "dateupdated": "2022-05-29T00:52:32.02", + "id": 23, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrderReviewWorkerCountLabel.json b/cypress/fixtures/settings/OrderReviewWorkerCountLabel.json new file mode 100644 index 00000000..4e1ba671 --- /dev/null +++ b/cypress/fixtures/settings/OrderReviewWorkerCountLabel.json @@ -0,0 +1,12 @@ +{ + "key": "OrderReviewWorkerCountLabel", + "value": "OrderReviewWorkerCountLabelanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The label for the count of work assignments", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.173", + "dateupdated": "2022-05-29T00:52:29.627", + "id": 21, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrganizationAddress.json b/cypress/fixtures/settings/OrganizationAddress.json new file mode 100644 index 00000000..b944d3f5 --- /dev/null +++ b/cypress/fixtures/settings/OrganizationAddress.json @@ -0,0 +1,12 @@ +{ + "key": "OrganizationAddress", + "value": "123 main st, seattle, wa 98101anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will be displayed in work order summaries, etc", + "category": "General", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.047", + "dateupdated": "2022-05-29T00:53:25.613", + "id": 10, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/OrganizationName.json b/cypress/fixtures/settings/OrganizationName.json new file mode 100644 index 00000000..0df79fdd --- /dev/null +++ b/cypress/fixtures/settings/OrganizationName.json @@ -0,0 +1,14 @@ +[ + { + "key": "OrganizationName", + "value": "from stub", + "description": "Will be displayed in the employer's portal and throughout the app", + "category": "General", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:32.937", + "dateupdated": "2022-05-29T00:53:24.283", + "id": 1, + "updatedby": "jciispam@gmail.com" + } +] diff --git a/cypress/fixtures/settings/WorkCenterDescription_EN.json b/cypress/fixtures/settings/WorkCenterDescription_EN.json new file mode 100644 index 00000000..ff123775 --- /dev/null +++ b/cypress/fixtures/settings/WorkCenterDescription_EN.json @@ -0,0 +1,12 @@ +{ + "key": "WorkCenterDescription_EN", + "value": "

Casa Latina is nonprofit organization that empowers Latino immigrants through educational and economic opportunities. Our employment program connects immigrants with individuals and businesses looking for temporary labor. Our workers are skilled and dependable. From landscaping to dry walling to catering and housecleaning, if you can dream the project our workers can do it! Learn more about Casa Latina.

anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will be visible in the welcome page for all users", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.103", + "dateupdated": "2022-05-29T00:53:27.143", + "id": 15, + "updatedby": "jciispam@gmail.com" +} diff --git a/cypress/fixtures/settings/settings.json b/cypress/fixtures/settings/settings.json new file mode 100644 index 00000000..622fab8b --- /dev/null +++ b/cypress/fixtures/settings/settings.json @@ -0,0 +1,232 @@ +{ + "data": [ + { + "key": "OrganizationName", + "value": "from stub", + "description": "Will be displayed in the employer's portal and throughout the app", + "category": "General", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:32.937", + "dateupdated": "2022-05-29T00:53:24.283", + "id": 1, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrganizationAddress", + "value": "123 main st, seattle, wa 98101anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will be displayed in work order summaries, etc", + "category": "General", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.047", + "dateupdated": "2022-05-29T00:53:25.613", + "id": 10, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "WorkCenterDescription_EN", + "value": "

Casa Latina is nonprofit organization that empowers Latino immigrants through educational and economic opportunities. Our employment program connects immigrants with individuals and businesses looking for temporary labor. Our workers are skilled and dependable. From landscaping to dry walling to catering and housecleaning, if you can dream the project our workers can do it! Learn more about Casa Latina.

anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will be visible in the welcome page for all users", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.103", + "dateupdated": "2022-05-29T00:53:27.143", + "id": 15, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OnlineOrdersIntroMessage", + "value": "OnlineOrdersIntroMessageanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displays in the 1st step of the online hiring. Include your center's basic information and how you program works, contact number, etc. Links to your website will also work.", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.113", + "dateupdated": "2022-05-29T00:53:28.473", + "id": 16, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OnlineOrdersEnglishReqNote", + "value": "OnlineOrdersEnglishReqNoteanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the site details step. When employers requests an English-speaking worker, this note provides any center-specific details", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.137", + "dateupdated": "2022-05-29T00:53:29.85", + "id": 18, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OnlineOrdersTransportDetailsLink", + "value": "OnlineOrdersTransportDetailsLinkanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will display if your transport provider cost rules have any fees. Include the link to your website with transport cost info ", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.15", + "dateupdated": "2022-05-29T00:53:31.323", + "id": 19, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderConfirmTransportFeesNotice", + "value": "OrderConfirmTransportFeesNoticeanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Will display in the last step if employer chooses a transport method with fees. Inlcude text on why the fee applies", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.16", + "dateupdated": "2022-05-29T00:53:32.737", + "id": 20, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewWorkerCountLabel", + "value": "OrderReviewWorkerCountLabelanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The label for the count of work assignments", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.173", + "dateupdated": "2022-05-29T00:52:29.627", + "id": 21, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewSkillsSummaryLabel", + "value": "OrderReviewSkillsSummaryLabelanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The label for the work assignments summary table", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.183", + "dateupdated": "2022-05-29T00:52:30.817", + "id": 22, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewTransportFeeMethodHelper", + "value": "OrderReviewTransportFeeMethodHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The helper text for transport fees explaining payment options", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.2", + "dateupdated": "2022-05-29T00:52:32.02", + "id": 23, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewLaborCostMethodHelper", + "value": "OrderReviewLaborCostMethodHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The helper text for labor cost explaining payment options", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.213", + "dateupdated": "2022-05-29T00:52:33.313", + "id": 24, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewTransportFeeEmplanationUrl", + "value": "OrderReviewTransportFeeAboutUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The url to your website explaining the transport fees", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.227", + "dateupdated": "2022-05-29T00:52:34.5", + "id": 25, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewLaborCostPayMethodHelper", + "value": "OrderReviewLaborCostAboutUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. The url to your website explaining the labor cost", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.24", + "dateupdated": "2022-05-29T00:52:35.697", + "id": 26, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "OrderReviewNextStepsHelper", + "value": "OrderReviewNextStepsHelperanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "Displayed in the pre-sumbit review step. Describe the next steps in the process, will employer need to wait for confirmation via a call, text or wait for email, etc.", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.25", + "dateupdated": "2022-05-29T00:52:36.943", + "id": 27, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "DisableOnlineOrders", + "value": "FALSE", + "description": "Enter either TRUE or FALSE. Enter TRUE to turn off access to the online hiring portal", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.263", + "dateupdated": "2022-05-24T13:10:33.07", + "id": 28, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "DisableOnlineOrdersBanner", + "value": "Online orders are currently disabled. Please call the center.anythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "The message for employers when the online hring portal is turned off", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.277", + "dateupdated": "2022-05-29T00:52:38.217", + "id": 29, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "DisableOnlineOrdersBannerInfoUrl", + "value": "DisableOnlineOrdersBannerInfoUrlanythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganythinganything", + "description": "The URL to your center's website explaining why online hiring is turned off", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T13:08:33.29", + "dateupdated": "2022-05-29T00:52:39.46", + "id": 30, + "updatedby": "jciispam@gmail.com" + }, + { + "key": "DisableWorkersVaccineRequirement", + "value": "FALSE", + "description": null, + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-05-24T15:13:12.66", + "dateupdated": "2022-05-24T15:13:12.66", + "id": 32, + "updatedby": "Init T. Script" + }, + { + "key": "OnlineOrdersTerms", + "value": "[{\"name\":\"term1\",\"text\":\"This is the term one\"},{\"name\":\"term2\",\"text\":\"This is the term two\"}]", + "description": "The terms that an employer has to accept before proceding with creating a work order", + "category": "OnlineOrders", + "publicConfig": true, + "createdby": "Init T. Script", + "datecreated": "2022-06-21T15:29:44.333", + "dateupdated": "2022-06-21T15:29:44.333", + "id": 1002, + "updatedby": "Init T. Script" + } + ] +} diff --git a/cypress/integration/settings/edit-settings.spec.ts b/cypress/integration/settings/edit-settings.spec.ts new file mode 100644 index 00000000..20d93700 --- /dev/null +++ b/cypress/integration/settings/edit-settings.spec.ts @@ -0,0 +1,134 @@ +import { macheteSettingsRoutes, MACHETE_ADMIN } from "cypress/constants"; +import { MS_NON_EDITABLE_CONFIGS_LOWER_CASE } from "src/app/configs/machete-settings/shared/machete-settings-constants"; +import { Config } from "src/app/shared/models/config"; + +describe("machete settings edit", () => { + const STUBBED_CONFGIS_KEY = "stubbed.configs"; + let userEditableConfigs: Config[]; + + let privateConfigs: Config[]; + + beforeEach(() => { + cy.apiLogin(MACHETE_ADMIN.user, MACHETE_ADMIN.password); + + // Stubbing the response from server here + cy.fixture("settings/settings.json"); + cy.intercept( + { + method: "GET", + url: "/api/configs", + }, + { fixture: "settings/settings" } + ).as("configs"); + cy.visit(macheteSettingsRoutes.list); + + cy.wait("@configs").then((i) => { + Cypress.env(STUBBED_CONFGIS_KEY, i.response.body.data); + const configs = Cypress.env(STUBBED_CONFGIS_KEY) as Config[]; + + userEditableConfigs = configs.filter( + (c: Config) => + c.publicConfig && + !MS_NON_EDITABLE_CONFIGS_LOWER_CASE.includes(c.key.toLowerCase()) + ); + + privateConfigs = configs.filter( + (c: Config) => + !c.publicConfig && + MS_NON_EDITABLE_CONFIGS_LOWER_CASE.includes(c.key.toLowerCase()) + ); + }); + }); + + it("text field when valid saves", () => { + const nonTextFields = [ + "OnlineOrdersTerms", + "DisableOnlineOrders", + "DisableWorkersVaccineRequirement", + ]; + userEditableConfigs.forEach((c: Config) => { + if (!nonTextFields.includes(c.key)) { + // mock response + cy.intercept( + { + method: "PUT", + url: "/api/configs/*", + }, + (req) => { + req.body = {}; // don't acctually change anything + req.reply({ + statusCode: 200, + body: { fixture: `settings/${c.key}.json` }, + }); + } + ).as("edit"); + cy.visit(`${macheteSettingsRoutes.list}/${c.key}`); + cy.get("#value").type(" anything"); + cy.get(`button[label="Save"]`).click(); + cy.get(`.p-confirm-popup-accept`).click(); + cy.wait("@edit").then((i) => { + expect(i.request.body.value).to.contain("anything"); + }); + } + }); + }); + + it("text field when Invalid shows error", () => { + const nonTextFields = [ + "OnlineOrdersTerms", + "DisableOnlineOrders", + "DisableWorkersVaccineRequirement", + ]; + userEditableConfigs.forEach((c: Config) => { + if (!nonTextFields.includes(c.key)) { + cy.visit(`${macheteSettingsRoutes.list}/${c.key}`); + cy.get("#value").clear(); + cy.get(`button[label="Save"]`).should("have.attr", "disabled"); + cy.get("small").contains("Value is required"); + } + }); + }); + + it("TERMS field adds & removes children", () => { + const termField = ["OnlineOrdersTerms"]; + // Expect 3 divs. 2 divs for the stubbed 2 terms and one for the buttons + const elementPerChild = 3; + + cy.visit(`${macheteSettingsRoutes.list}/${termField}`); + cy.get("app-machete-settings-term-form") + .find("div") + .first() + .children() + .should("have.length", elementPerChild); + cy.get(".p-button-info > .p-button-icon").click(); + + cy.get("app-machete-settings-term-form") + .find("div") + .first() + .children() + .should("have.length", elementPerChild + 1); + + cy.get(".p-button-danger > .p-button-icon").click(); + cy.get("app-machete-settings-term-form") + .find("div") + .first() + .children() + .should("have.length", elementPerChild); + }); + + it("TERMS field when valid saves", () => { + const termField = ["OnlineOrdersTerms"]; + const elementPerChild = 3; + }); + + it("errors when saving", () => { + privateConfigs.forEach((c: Config) => { + cy.visit(`${macheteSettingsRoutes.list}/${c.key}`); + cy.get("#value").should("exist").type("test"); + cy.get(`button[label="Save"]`).click(); + cy.get("span.p-button-label"); + cy.get(`button[ng-reflect-label="Yes"]`).click(); + cy.contains("Action not allowed"); + }); + }); +}); diff --git a/cypress/integration/settings/list-settings.spec.ts b/cypress/integration/settings/list-settings.spec.ts new file mode 100644 index 00000000..06229b7d --- /dev/null +++ b/cypress/integration/settings/list-settings.spec.ts @@ -0,0 +1,76 @@ +import { + ENV_KEY_MACHETE_CONFIGS, + macheteSettingsRoutes, + MACHETE_ADMIN, +} from "cypress/constants"; +import { Config } from "src/app/shared/models/config"; +import { MS_NON_EDITABLE_CONFIGS_LOWER_CASE } from "src/app/configs/machete-settings/shared/machete-settings-constants"; + +describe("machete settings list", () => { + let userEditableConfigs: Config[]; + + let privateConfigs: Config[]; + + let configs: Config[]; + + beforeEach(() => { + cy.apiLogin(MACHETE_ADMIN.user, MACHETE_ADMIN.password); + + // wait for data to load + cy.intercept({ + method: "GET", + url: "/api/configs", + }).as("configs"); + + cy.getMacheteConfigs(); + cy.visit(macheteSettingsRoutes.list); + + cy.wait("@configs").then(() => { + configs = Cypress.env(ENV_KEY_MACHETE_CONFIGS) as Config[]; + userEditableConfigs = configs.filter( + (c: Config) => + c.publicConfig && + !MS_NON_EDITABLE_CONFIGS_LOWER_CASE.includes(c.key.toLowerCase()) + ); + + privateConfigs = configs.filter( + (c: Config) => + !c.publicConfig && + MS_NON_EDITABLE_CONFIGS_LOWER_CASE.includes(c.key.toLowerCase()) + ); + }); + + }); + + it("when list loads, should display table", () => { + cy.visit(macheteSettingsRoutes.list); + cy.get("table") + .should("be.visible") + .should("have.class", "p-datatable-table"); + }); + it("when list loads, results should contain user-editable configs", () => { + cy.visit(macheteSettingsRoutes.list); + + userEditableConfigs.forEach((c: Config) => { + cy.get("input").type(c.key); + cy.get("table").should("contain.text", c.key); + cy.get("input").clear(); + }); + + privateConfigs.forEach((c: Config) => { + cy.get("input").type(c.key); + cy.get("table").should("not.contain.text", c.key); + cy.get("input").clear(); + }); + }); +}); + +describe("when record selected", () => { + it("should navigate to detail page", () => { + cy.contains("OrganizationName").click(); + cy.url().should( + "include", + `${macheteSettingsRoutes.list}/OrganizationName` + ); + }); +}); diff --git a/package-lock.json b/package-lock.json index 6e100cd8..e6e6084b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,15 @@ "rxjs": "6.6.7", "source-map": "0.7.3" } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } } } }, @@ -199,6 +208,23 @@ "yocto-queue": "^0.1.0" } }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", @@ -350,6 +376,15 @@ "rxjs": "6.6.7", "source-map": "0.7.3" } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } } } }, @@ -365,6 +400,17 @@ "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@angular-devkit/schematics": { @@ -376,6 +422,17 @@ "@angular-devkit/core": "12.2.7", "ora": "5.4.1", "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@angular-eslint/builder": { @@ -511,6 +568,17 @@ "magic-string": "0.25.7", "rxjs": "6.6.7", "source-map": "0.7.3" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@angular-devkit/schematics": { @@ -522,6 +590,17 @@ "@angular-devkit/core": "12.2.16", "ora": "5.4.1", "rxjs": "6.6.7" + }, + "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + } } }, "@schematics/angular": { @@ -3681,6 +3760,15 @@ "requires": { "ajv": "^8.0.0" } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } } } }, @@ -3920,6 +4008,23 @@ "tslib": "^2.0.0" }, "dependencies": { + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -3995,6 +4100,23 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -5269,6 +5391,16 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -8292,6 +8424,13 @@ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz", "integrity": "sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg==" }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filelist": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", @@ -10828,6 +10967,13 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "dev": true, + "optional": true + }, "nanocolors": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.12.tgz", @@ -19388,7 +19534,11 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } }, "glob-parent": { "version": "3.1.0", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 221aa6f9..5b917328 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -10,7 +10,6 @@ import { OnDestroy, } from "@angular/core"; import { environment } from "../environments/environment"; -import { ConfigsService } from "./configs/configs.service"; import { LookupsService } from "./lookups/lookups.service"; import { Router, NavigationEnd } from "@angular/router"; import { MenuItem, Message, MessageService, PrimeNGConfig } from "primeng/api"; @@ -28,7 +27,7 @@ declare let jQuery: any; selector: "app-root", templateUrl: "./app.component.html", styleUrls: ["./app.component.scss"], - providers: [LookupsService, ConfigsService, MessageService], + providers: [LookupsService, MessageService], }) export class AppComponent implements AfterViewInit, OnInit, OnDestroy { @ViewChild("layoutContainer", { static: false }) diff --git a/src/app/configs/configs-routing.module.ts b/src/app/configs/configs-routing.module.ts index 2fcdf80e..7e59c4b3 100644 --- a/src/app/configs/configs-routing.module.ts +++ b/src/app/configs/configs-routing.module.ts @@ -19,6 +19,13 @@ const routes: Routes = [ }, ], }, + { + path: "settings", + loadChildren: () => + import("./machete-settings/machete-settings.module").then( + (m) => m.MacheteSettingsModule + ), + }, ]; @NgModule({ diff --git a/src/app/configs/configs.service.spec.ts b/src/app/configs/configs.service.spec.ts deleted file mode 100644 index fcef4cb5..00000000 --- a/src/app/configs/configs.service.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { TestBed, inject } from "@angular/core/testing"; - -import { ConfigsService } from "./configs.service"; -import { HttpClientTestingModule } from "@angular/common/http/testing"; - -describe("ConfigsService", () => { - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ConfigsService], - imports: [HttpClientTestingModule], - }); - }); - - it("should be created", inject( - [ConfigsService], - (service: ConfigsService) => { - expect(service).toBeTruthy(); - } - )); -}); diff --git a/src/app/configs/configs.service.ts b/src/app/configs/configs.service.ts deleted file mode 100644 index 57d490df..00000000 --- a/src/app/configs/configs.service.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Observable, of } from "rxjs"; - -import { first, mergeMap, map } from "rxjs/operators"; -import { Injectable } from "@angular/core"; -import { environment } from "../../environments/environment"; -import { HttpClient } from "@angular/common/http"; -import { Config, CCategory } from "../shared/models/config"; - -@Injectable() -export class ConfigsService { - uriBase = environment.dataUrl + "/api/configs"; - configs = new Array(); - configsAge = 0; - constructor(private http: HttpClient) {} - - // TODO simplify - isStale(): boolean { - if (this.configsAge > Date.now() - 36000) { - return false; - } - return true; - } - isNotStale(): boolean { - return !this.isStale(); - } - - getAllConfigs(): Observable { - if (this.isNotStale()) { - return of(this.configs); - } - - console.log("getAllConfigs: " + this.uriBase); - // withCredentials: true is normally necessary, but configs are enabled for anonymous - return this.http.get(this.uriBase).pipe( - map((res) => { - //console.log(res); // <~ outputs a configuration object - this.configs = res["data"] as Config[]; - this.configsAge = Date.now(); - return res["data"] as Config[]; - }) - ); - } - - getConfigs(category: CCategory): Observable { - return this.getAllConfigs().pipe( - map((res) => res.filter((l) => l.category === category)) - ); - } - - getConfig(key: string): Observable { - return this.getAllConfigs().pipe( - mergeMap((a) => a.filter((ll) => ll.key === key)), - first() - ); - } -} diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.css b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.css new file mode 100644 index 00000000..e69de29b diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.html b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.html new file mode 100644 index 00000000..43d85b35 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.html @@ -0,0 +1,119 @@ + + + + + {{ r.key }} + + + + {{ tpHelperText }} + +
+
+
+
+
+
+ Description +
+
+ {{ r.description }} +
+
+
+ +
+
+
+
+
+
+
+ + + + +
+
+ + + + + Value is required +
+
+ +
+
+
+
+ + +
+ + +
+ +
+ +
+
+
+
+ +
+
+
+ Updated By +
+ {{ r.updatedby }} +
+ + + +
+
+ Date Updated +
+ + {{ r.dateupdated | date: "short" }} + +
+
+
+
diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.spec.ts b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.spec.ts new file mode 100644 index 00000000..656897ca --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.spec.ts @@ -0,0 +1,57 @@ +import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { FormsModule } from "@angular/forms"; +import { ActivatedRoute } from "@angular/router"; +import { RouterTestingModule } from "@angular/router/testing"; +import { ConfirmationService } from "primeng/api"; +import { of } from "rxjs"; +import { AppSettingsStoreServiceSpy } from "src/app/shared/testing"; +import { AppSettingsStoreService } from "../../../shared/services/app-settings-store.service"; + +import { MacheteSettingsEditComponent } from "./machete-settings-edit.component"; + +describe("MacheteSettingsEditComponent", () => { + let component: MacheteSettingsEditComponent; + let fixture: ComponentFixture; + let confirmationSpy: jasmine.SpyObj; + + beforeEach(async () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + confirmationSpy = jasmine.createSpyObj("ConfirmationService", ["confirm"]); + + await TestBed.configureTestingModule({ + imports: [ + HttpClientTestingModule, + RouterTestingModule.withRoutes([]), + FormsModule, + ], + declarations: [MacheteSettingsEditComponent], + providers: [ + { + provide: AppSettingsStoreServiceSpy, + useClass: AppSettingsStoreService, + }, + { + provide: ConfirmationService, + useValue: confirmationSpy, + }, + { + provide: ActivatedRoute, + useValue: { + params: of("someRoute"), + }, + }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MacheteSettingsEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.ts b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.ts new file mode 100644 index 00000000..2029c785 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-edit.component.ts @@ -0,0 +1,88 @@ +/* eslint-disable @typescript-eslint/unbound-method */ +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { ConfirmationService } from "primeng/api"; +import { merge, Observable, Subject } from "rxjs"; +import { pluck, switchMap, takeWhile, tap } from "rxjs/operators"; +import { Config } from "src/app/shared/models/config"; +import { AppSettingsStoreService } from "../../../shared/services/app-settings-store.service"; + +@Component({ + selector: "app-machete-settings-edit", + templateUrl: "./machete-settings-edit.component.html", + styleUrls: ["./machete-settings-edit.component.css"], +}) +export class MacheteSettingsEditComponent implements OnInit, OnDestroy { + private routeRecordId: string; + private isAlive = true; + + public record$: Observable; + public activeTab = "register"; + public tpHelperText: string; + public readonly TERMS_KEY: string = "OnlineOrdersTerms"; + private updatedRecord$: Subject = new Subject(); + private initialData$ = this.activatedRoute.params.pipe( + pluck("id"), + switchMap((id: string) => { + this.routeRecordId = id; + return this.appSettingsStore.getConfig(this.routeRecordId); + }) + ); + + constructor( + private activatedRoute: ActivatedRoute, + private router: Router, + private appSettingsStore: AppSettingsStoreService, + private primeConfirmService: ConfirmationService + ) {} + + ngOnInit(): void { + this.tpHelperText = `Machete settings make system changes. Proceed with caution`; + + this.record$ = merge( + this.initialData$.pipe( + tap(() => console.log("on init: form set with initial")) + ), + this.updatedRecord$.pipe( + tap(() => + console.log("post update/create: form refresehed with API result") + ) + ) + ); + } + + public save(record: Config): void { + this.appSettingsStore + .update(record) + .pipe( + takeWhile(() => this.isAlive), + tap((config: Config) => this.updatedRecord$.next(config)) + ) + .subscribe(); + } + + public onConfirmSave(event: Event, record: Config): void { + this.primeConfirmService.confirm({ + target: event.target, + message: + "Are you sure that you want to save changes?. This cannot be undone", + icon: "pi pi-exclamation-triangle", + accept: () => { + this.save(record); + }, + reject: () => console.log("save canceled"), + }); + } + + public async onCancel(): Promise { + await this.router.navigate(["/configuration/settings"]); + } + + public onChildTermChange(data: string, r: Config): void { + this.updatedRecord$.next({ ...r, value: data }); + } + + ngOnDestroy(): void { + this.isAlive = false; + } +} diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.html b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.html new file mode 100644 index 00000000..00789e6e --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.html @@ -0,0 +1,67 @@ +
Terms
+
+ + +
+ + {{termForm.controls['name'].value}} + +
+ + + + + + Required + +
+
+ + + + + + Required + +
+
+
+ + +
+
+ + +
+
+
diff --git a/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.ts b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.ts new file mode 100644 index 00000000..522ec801 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/machete-settings-term-form.component.ts @@ -0,0 +1,95 @@ +/* eslint-disable @typescript-eslint/unbound-method */ +import { + Component, + EventEmitter, + Input, + OnDestroy, + OnInit, + Output, +} from "@angular/core"; +import { + FormArray, + FormBuilder, + FormControl, + FormGroup, + Validators, +} from "@angular/forms"; +import { debounceTime, takeWhile, tap } from "rxjs/operators"; +import { OnlineOrderTerm } from "./online-order-term"; + +@Component({ + selector: "app-machete-settings-term-form", + templateUrl: "./machete-settings-term-form.component.html", + styles: [], +}) +export class MacheteSettingsTermFormComponent implements OnInit, OnDestroy { + @Output() + public termChange = new EventEmitter(); + @Input() + public termsAsString = ""; + public termsFormArray: FormArray = new FormArray([]); + public records: OnlineOrderTerm[] = []; + private isAlive = true; + + constructor(private fb: FormBuilder) {} + + public onNewTerm(): void { + this.addBlankTerm(); + } + + public onPopTerm(): void { + this.popTerm(); + } + + private addBlankTerm(): void { + const termForm = new FormGroup({ + name: new FormControl("", Validators.required), + text: new FormControl("", Validators.required), + }); + this.termsFormArray.push(termForm); + } + + private addDefaultTerms(term: OnlineOrderTerm): void { + const termForm = new FormGroup({ + name: new FormControl(term.name, Validators.required), + text: new FormControl(term.text, Validators.required), + }); + this.termsFormArray.push(termForm); + } + + private popTerm(): void { + this.termsFormArray.removeAt(this.termsFormArray.length - 1); + } + + private parseTerms(termsString: string): OnlineOrderTerm[] { + return termsString === "" + ? [] + : (JSON.parse(termsString) as OnlineOrderTerm[]); + } + + private clearForm(): void { + this.termsFormArray.clear(); + } + + ngOnInit(): void { + this.records = this.parseTerms(this.termsAsString); + this.clearForm(); + this.records.forEach((term: OnlineOrderTerm) => { + this.addDefaultTerms(term); + }); + + this.termsFormArray.valueChanges + .pipe( + takeWhile(() => this.isAlive), + debounceTime(700), + tap((terms: OnlineOrderTerm[]) => { + this.termChange.emit(JSON.stringify(terms)); + }) + ) + .subscribe(); + } + + ngOnDestroy(): void { + this.isAlive = false; + } +} diff --git a/src/app/configs/machete-settings/machete-settings-edit/online-order-term.ts b/src/app/configs/machete-settings/machete-settings-edit/online-order-term.ts new file mode 100644 index 00000000..47a8296d --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-edit/online-order-term.ts @@ -0,0 +1,7 @@ +/** + * Model for Machete Setting Terms + */ +export class OnlineOrderTerm { + name: string; + text: string; +} diff --git a/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.css b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.css new file mode 100644 index 00000000..e69de29b diff --git a/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.html b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.html new file mode 100644 index 00000000..0af7889b --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.html @@ -0,0 +1,5 @@ + diff --git a/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.spec.ts b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.spec.ts new file mode 100644 index 00000000..d9872875 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.spec.ts @@ -0,0 +1,34 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { AppSettingsStoreServiceSpy, RouterSpy } from "src/app/shared/testing"; +import { AppSettingsStoreService } from "../../../shared/services/app-settings-store.service"; + +import { MacheteSettingsListComponent } from "./machete-settings-list.component"; + +describe("MacheteSettingsListComponent", () => { + let component: MacheteSettingsListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [MacheteSettingsListComponent], + providers: [ + { + provide: AppSettingsStoreService, + useClass: AppSettingsStoreServiceSpy, + }, + { provide: Router, useClass: RouterSpy }, + ], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MacheteSettingsListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.ts b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.ts new file mode 100644 index 00000000..82e7d340 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-list/machete-settings-list.component.ts @@ -0,0 +1,42 @@ +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { Config } from "src/app/shared/models/config"; +import { AppSettingsStoreService } from "../../../shared/services/app-settings-store.service"; +import { MS_NON_EDITABLE_CONFIGS } from "../shared/machete-settings-constants"; + +@Component({ + selector: "app-machete-settings-list", + templateUrl: "./machete-settings-list.component.html", + styleUrls: ["./machete-settings-list.component.css"], +}) +export class MacheteSettingsListComponent implements OnInit { + public configs$: Observable; + public excludeCols: string[] = [ + "publicConfig", + "datecreated", + "createdby", + "id", + ]; + + constructor( + private appSetttingsServ: AppSettingsStoreService, + private router: Router + ) {} + + async onRowSelect(selectedRecord: Config): Promise { + await this.router.navigate([ + `configuration/settings/${selectedRecord.key}`, + ]); + } + + ngOnInit(): void { + this.configs$ = this.appSetttingsServ.all$.pipe( + map((configs: Config[]) => configs.filter((c) => c.publicConfig)), + map((configs: Config[]) => + configs.filter((c) => !MS_NON_EDITABLE_CONFIGS.includes(c.key)) + ) + ); + } +} diff --git a/src/app/configs/machete-settings/machete-settings-routing.module.ts b/src/app/configs/machete-settings/machete-settings-routing.module.ts new file mode 100644 index 00000000..c08f235f --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings-routing.module.ts @@ -0,0 +1,30 @@ +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { AuthGuardService } from "src/app/shared/services/auth-guard.service"; +import { MacheteSettingsEditComponent } from "./machete-settings-edit/machete-settings-edit.component"; +import { MacheteSettingsListComponent } from "./machete-settings-list/machete-settings-list.component"; +import { MacheteSettingsComponent } from "./machete-settings.component"; + +const routes: Routes = [ + { + path: "", + component: MacheteSettingsComponent, + canActivate: [AuthGuardService], + children: [ + { + path: "", + component: MacheteSettingsListComponent, + }, + { + path: ":id", + component: MacheteSettingsEditComponent, + }, + ], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class MacheteSettingsRoutingModule {} diff --git a/src/app/configs/machete-settings/machete-settings.component.spec.ts b/src/app/configs/machete-settings/machete-settings.component.spec.ts new file mode 100644 index 00000000..22324490 --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from "@angular/core/testing"; + +import { MacheteSettingsComponent } from "./machete-settings.component"; + +describe("MacheteSettingsComponent", () => { + let component: MacheteSettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [MacheteSettingsComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MacheteSettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/configs/machete-settings/machete-settings.component.ts b/src/app/configs/machete-settings/machete-settings.component.ts new file mode 100644 index 00000000..3533f09b --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings.component.ts @@ -0,0 +1,9 @@ +import { Component } from "@angular/core"; + +@Component({ + selector: "app-machete-settings", + template: `

Machete Settings

+ `, + styles: [], +}) +export class MacheteSettingsComponent {} diff --git a/src/app/configs/machete-settings/machete-settings.module.ts b/src/app/configs/machete-settings/machete-settings.module.ts new file mode 100644 index 00000000..5dc7c3bf --- /dev/null +++ b/src/app/configs/machete-settings/machete-settings.module.ts @@ -0,0 +1,48 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; + +import { MacheteSettingsRoutingModule } from "./machete-settings-routing.module"; +import { MacheteSettingsComponent } from "./machete-settings.component"; +import { MacheteSettingsListComponent } from "./machete-settings-list/machete-settings-list.component"; +import { RecordsTableModule } from "src/app/shared/components/records-table/records-table.module"; +import { MacheteSettingsEditComponent } from "./machete-settings-edit/machete-settings-edit.component"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; +import { DividerModule } from "primeng/divider"; +import { InputTextModule } from "primeng/inputtext"; +import { FieldsetModule } from "primeng/fieldset"; +import { ChipModule } from "primeng/chip"; +import { CardModule } from "primeng/card"; +import { ButtonModule } from "primeng/button"; +import { ToolbarModule } from "primeng/toolbar"; +import { ConfirmPopupModule } from "primeng/confirmpopup"; +import { InputTextareaModule } from "primeng/inputtextarea"; + +import { ConfirmationService } from "primeng/api"; +import { MacheteSettingsTermFormComponent } from "./machete-settings-edit/machete-settings-term-form.component"; + +@NgModule({ + declarations: [ + MacheteSettingsComponent, + MacheteSettingsListComponent, + MacheteSettingsEditComponent, + MacheteSettingsTermFormComponent, + ], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + MacheteSettingsRoutingModule, + RecordsTableModule, + InputTextModule, + DividerModule, + FieldsetModule, + CardModule, + ChipModule, + ButtonModule, + ToolbarModule, + ConfirmPopupModule, + InputTextareaModule, + ], + providers: [ConfirmationService], +}) +export class MacheteSettingsModule {} diff --git a/src/app/configs/machete-settings/shared/machete-settings-constants.ts b/src/app/configs/machete-settings/shared/machete-settings-constants.ts new file mode 100644 index 00000000..1a4d8128 --- /dev/null +++ b/src/app/configs/machete-settings/shared/machete-settings-constants.ts @@ -0,0 +1,23 @@ +// Not configurable by users +export const MS_NON_EDITABLE_CONFIGS: string[] = [ + "EmailServerHostName", + "EmailServerPort", + "EmailEnableSSL", + "SmtpUser", + "SmtpPassword", + "EmailFromAddress", + "true", + "TimeZoneDifferenceFromPacific", + "PayPalClientID", + "PayPalUrl", + "PayPalClientSecret", + "PayPalEnvironment", + "MicrosoftTimeZoneIndex", + "FacebookAppId", + "GoogleClientId", + "OAuthStateParameter", +]; + +export const MS_NON_EDITABLE_CONFIGS_LOWER_CASE: string[] = [ + ...MS_NON_EDITABLE_CONFIGS, +].map((key) => key.toLowerCase()); diff --git a/src/app/menu/load-menu-rules.ts b/src/app/menu/load-menu-rules.ts index 6310ab42..a7ff5bf1 100644 --- a/src/app/menu/load-menu-rules.ts +++ b/src/app/menu/load-menu-rules.ts @@ -80,19 +80,17 @@ export function loadMenuRules(authList: string[]): Array { // }), new MenuRule({ id: 13, + label: "Machete Settings", + icon: "tune", + routerLink: ["configuration/settings"], + authorizedRoles: [LRole.ADMIN], + }), + new MenuRule({ + id: 14, label: "Transport Providers", icon: "airport_shuttle", routerLink: ["configuration/transport-providers"], authorizedRoles: [LRole.ADMIN], - items: [ - new MenuRule({ - id: 14, - label: "List", - icon: "list", - routerLink: ["configuration/transport-providers/list"], - authorizedRoles: [LRole.ADMIN], - }), - ], }), ], }), diff --git a/src/app/my-work-orders/order-complete/order-complete.component.spec.ts b/src/app/my-work-orders/order-complete/order-complete.component.spec.ts index 5ef65a59..57f510ff 100644 --- a/src/app/my-work-orders/order-complete/order-complete.component.spec.ts +++ b/src/app/my-work-orders/order-complete/order-complete.component.spec.ts @@ -8,7 +8,7 @@ import { TableModule } from "primeng/table"; import { MyWorkOrdersServiceSpy, RouterSpy, - ConfigsServiceSpy, + AppSettingsStoreServiceSpy, } from "../../shared/testing"; import { TransportProvidersServiceSpy, @@ -17,9 +17,9 @@ import { import * as paypal from "paypal-checkout"; import { MyWorkOrdersService } from "../my-work-orders.service"; import { ActivatedRoute, Router } from "@angular/router"; -import { ConfigsService } from "../../configs/configs.service"; import { MessageService } from "primeng/api"; import { TransportProvidersService } from "../../online-orders/transport-providers.service"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; describe("OrderCompleteComponent", () => { let component: OrderCompleteComponent; @@ -42,7 +42,10 @@ describe("OrderCompleteComponent", () => { provide: MyWorkOrdersService, useClass: MyWorkOrdersServiceSpy, }, - { provide: ConfigsService, useClass: ConfigsServiceSpy }, + { + provide: AppSettingsStoreService, + useClass: AppSettingsStoreServiceSpy, + }, { provide: MessageService, useClass: MessageServiceSpy }, { provide: ActivatedRoute, diff --git a/src/app/my-work-orders/order-complete/order-complete.component.ts b/src/app/my-work-orders/order-complete/order-complete.component.ts index 9276013a..05d6decf 100644 --- a/src/app/my-work-orders/order-complete/order-complete.component.ts +++ b/src/app/my-work-orders/order-complete/order-complete.component.ts @@ -8,8 +8,8 @@ import { WorkOrder } from "../../shared/models/work-order"; import * as paypal from "paypal-checkout"; import { ActivatedRoute, Router } from "@angular/router"; import { MyWorkOrdersService } from "../my-work-orders.service"; -import { ConfigsService } from "../../configs/configs.service"; import { TransportProvidersService } from "../../online-orders/transport-providers.service"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; @Component({ selector: "app-order-complete", @@ -80,7 +80,7 @@ export class OrderCompleteComponent implements OnInit, AfterViewChecked { private transportProviderService: TransportProvidersService, private route: ActivatedRoute, private router: Router, - private configsService: ConfigsService + private appSettingsStore: AppSettingsStoreService ) { console.log(".ctor"); } @@ -91,8 +91,8 @@ export class OrderCompleteComponent implements OnInit, AfterViewChecked { observableCombineLatest([ this.transportProviderService.getTransportProviders(), this.ordersService.getOrder(orderId), - this.configsService.getConfig("PayPalClientID"), - this.configsService.getConfig("PayPalEnvironment"), + this.appSettingsStore.getConfig("PayPalClientID"), + this.appSettingsStore.getConfig("PayPalEnvironment"), ]).subscribe( ([l, o, id, env]) => { console.log("ngOnInit:combineLatest received:", l, o, id, env); diff --git a/src/app/online-orders/guards/banner.guard.ts b/src/app/online-orders/guards/banner.guard.ts index 98c211c3..b93939ba 100644 --- a/src/app/online-orders/guards/banner.guard.ts +++ b/src/app/online-orders/guards/banner.guard.ts @@ -2,18 +2,21 @@ import { Injectable } from "@angular/core"; import { CanActivate, Router } from "@angular/router"; import { combineLatest, Observable } from "rxjs"; import { map } from "rxjs/operators"; -import { ConfigsService } from "../..//configs/configs.service"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; @Injectable() export class BannerGuard implements CanActivate { - constructor(private configsService: ConfigsService, private router: Router) { + constructor( + private appSettingsStore: AppSettingsStoreService, + private router: Router + ) { console.log(".ctor"); } canActivate(): Observable { return combineLatest([ - this.configsService.getConfig("DisableOnlineOrders"), - this.configsService.getConfig("DisableOnlineOrdersBanner"), + this.appSettingsStore.getConfig("DisableOnlineOrders"), + this.appSettingsStore.getConfig("DisableOnlineOrdersBanner"), ]).pipe( map( ([toggle, banner]) => { diff --git a/src/app/online-orders/intro-confirm/intro-confirm.component.ts b/src/app/online-orders/intro-confirm/intro-confirm.component.ts index c6f7f65c..f8d54da4 100644 --- a/src/app/online-orders/intro-confirm/intro-confirm.component.ts +++ b/src/app/online-orders/intro-confirm/intro-confirm.component.ts @@ -11,7 +11,6 @@ import { Confirm } from "../shared/models/confirm"; export class IntroConfirmComponent implements OnInit { confirmChoices = new Array(); confirmStatus = false; - // TODO: Refactor as a service that polls from API constructor( private onlineService: OnlineOrdersService, diff --git a/src/app/online-orders/introduction/introduction.component.html b/src/app/online-orders/introduction/introduction.component.html index 1bbce49f..17324e40 100644 --- a/src/app/online-orders/introduction/introduction.component.html +++ b/src/app/online-orders/introduction/introduction.component.html @@ -3,26 +3,9 @@ About Casa Latina -

- Casa Latina connects Latino immigrant workers with individuals and - businesses looking for temporary labor. Our workers are skilled and - dependable. -

-

- From landscaping to dry walling to catering and housecleaning, if you can - dream the project our workers can do it! For more information about our - program please read these Frequently Asked Questions If you are ready to - hire a worker, please fill out the following form. -

- -

- Casa Latina is taking all necessary precautions to keep employers and - workers safe, therefore some jobs might not be available at this time. -

-

- If you still have questions about hiring a worker, please call us at - 206.956.0779 x3. -

+ +

+
@@ -46,15 +29,15 @@
- Online Hiring Temporarily Unavailable diff --git a/src/app/online-orders/introduction/introduction.component.spec.ts b/src/app/online-orders/introduction/introduction.component.spec.ts index 0bc06688..b563d406 100644 --- a/src/app/online-orders/introduction/introduction.component.spec.ts +++ b/src/app/online-orders/introduction/introduction.component.spec.ts @@ -6,14 +6,14 @@ import { OnlineOrdersServiceSpy, WorkOrderServiceSpy, WorkAssignmentsServiceSpy, - ConfigsServiceSpy, + AppSettingsStoreServiceSpy, } from "../../shared/testing"; import { Router } from "@angular/router"; import { OnlineOrdersService } from "../online-orders.service"; import { WorkOrderService } from "../work-order/work-order.service"; import { WorkAssignmentsService } from "../work-assignments/work-assignments.service"; -import { ConfigsService } from "../../configs/configs.service"; import { CardModule } from "primeng/card"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; describe("IntroductionComponent", () => { let component: IntroductionComponent; @@ -38,7 +38,10 @@ describe("IntroductionComponent", () => { provide: WorkAssignmentsService, useClass: WorkAssignmentsServiceSpy, }, - { provide: ConfigsService, useClass: ConfigsServiceSpy }, + { + provide: AppSettingsStoreService, + useClass: AppSettingsStoreServiceSpy, + }, ], }, }) diff --git a/src/app/online-orders/introduction/introduction.component.ts b/src/app/online-orders/introduction/introduction.component.ts index a8bf7d90..747bfed6 100644 --- a/src/app/online-orders/introduction/introduction.component.ts +++ b/src/app/online-orders/introduction/introduction.component.ts @@ -3,7 +3,7 @@ import { Router } from "@angular/router"; import { OnlineOrdersService } from "../online-orders.service"; import { WorkOrderService } from "../work-order/work-order.service"; import { WorkAssignmentsService } from "../work-assignments/work-assignments.service"; -import { ConfigsService } from "../../configs/configs.service"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; @Component({ selector: "app-introduction", templateUrl: "./introduction.component.html", @@ -13,16 +13,17 @@ export class IntroductionComponent implements OnInit { macheteOutage = false; outageMessage: string; outageVisible = false; + stepOneIntro$ = this.appSettingsStore.getConfig("OnlineOrdersIntroMessage"); constructor( private router: Router, private onlineService: OnlineOrdersService, private orderService: WorkOrderService, private assignmentService: WorkAssignmentsService, - private cfgService: ConfigsService + private appSettingsStore: AppSettingsStoreService ) {} ngOnInit(): void { - this.cfgService.getAllConfigs().subscribe( + this.appSettingsStore.all$.subscribe( (data) => { this.macheteOutage = data.find((config) => config.key === "DisableOnlineOrders").value === diff --git a/src/app/online-orders/online-orders.module.ts b/src/app/online-orders/online-orders.module.ts index 78541012..21d38332 100644 --- a/src/app/online-orders/online-orders.module.ts +++ b/src/app/online-orders/online-orders.module.ts @@ -45,7 +45,6 @@ import { WorkOrdersModule } from "../shared/components/work-orders/work-orders.m import { ProfileGuard } from "./guards/profile.guard"; import { LayoutModule } from "@angular/cdk/layout"; import { SkillsComponent } from "./work-assignments/skills/skills.component"; -import { ConfigsService } from "../configs/configs.service"; import { BannerGuard } from "./guards/banner.guard"; @NgModule({ @@ -88,10 +87,8 @@ import { BannerGuard } from "./guards/banner.guard"; SkillsComponent, ], providers: [ - OnlineOrdersService, ScheduleRulesService, TransportRulesService, - ConfigsService, ProfileGuard, BannerGuard, MessageService, //PrimeNG Service diff --git a/src/app/online-orders/online-orders.service.spec.ts b/src/app/online-orders/online-orders.service.spec.ts index dbf94f00..4f57a62a 100644 --- a/src/app/online-orders/online-orders.service.spec.ts +++ b/src/app/online-orders/online-orders.service.spec.ts @@ -15,7 +15,9 @@ import { EmployersServiceSpy, AuthServiceSpy, WorkAssignmentsServiceSpy, + AppSettingsStoreServiceSpy, } from "../shared/testing"; +import { AppSettingsStoreService } from "../shared/services/app-settings-store.service"; describe("OnlineOrdersService", () => { beforeEach(() => { @@ -25,6 +27,10 @@ describe("OnlineOrdersService", () => { { provide: WorkOrderService, useClass: WorkOrderServiceSpy }, { provide: EmployersService, useClass: EmployersServiceSpy }, { provide: AuthService, useClass: AuthServiceSpy }, + { + provide: AppSettingsStoreService, + useClass: AppSettingsStoreServiceSpy, + }, { provide: WorkAssignmentsService, useClass: WorkAssignmentsServiceSpy, diff --git a/src/app/online-orders/online-orders.service.ts b/src/app/online-orders/online-orders.service.ts index 81340c41..0a3e0f71 100644 --- a/src/app/online-orders/online-orders.service.ts +++ b/src/app/online-orders/online-orders.service.ts @@ -1,15 +1,19 @@ -import { map } from "rxjs/operators"; -import { Injectable } from "@angular/core"; -import { Observable, BehaviorSubject } from "rxjs"; +import { map, tap } from "rxjs/operators"; +import { Injectable, OnDestroy } from "@angular/core"; +import { Observable, BehaviorSubject, Subscription } from "rxjs"; import { WorkOrder } from "../shared/models/work-order"; import { HttpClient, HttpHeaders } from "@angular/common/http"; import { environment } from "../../environments/environment"; import { Confirm } from "./shared/models/confirm"; -import { loadConfirms } from "./shared/rules/load-confirms"; - -@Injectable() -export class OnlineOrdersService { +import { AppSettingsStoreService } from "../shared/services/app-settings-store.service"; +import { Config } from "../shared/models/config"; +import { OnlineOrderTerm } from "../configs/machete-settings/machete-settings-edit/online-order-term"; + +@Injectable({ + providedIn: "root", +}) +export class OnlineOrdersService implements OnDestroy { storageKey = "machete.online-orders-service"; initialConfirmKey = this.storageKey + ".initialconfirm"; workOrderConfirmKey = this.storageKey + ".workorderconfirm"; @@ -18,12 +22,32 @@ export class OnlineOrdersService { private initialConfirmSource: BehaviorSubject; private workOrderConfirmSource = new BehaviorSubject(false); private workAssignmentsConfirmSource = new BehaviorSubject(false); + private confirmChoices = new Array(); + private termsSubscription: Subscription; + private terms$: Observable = this.appSettingsStore + .getConfig("OnlineOrdersTerms") + .pipe( + map((config: Config) => JSON.parse(config.value) as OnlineOrderTerm[]), + map((terms: OnlineOrderTerm[]) => + terms.map( + (x) => + new Confirm({ name: x.name, description: x.text, confirmed: false }) + ) + ), + tap((terms: Confirm[]) => (this.confirmChoices = terms)) + ); - constructor(private http: HttpClient) { + constructor( + private http: HttpClient, + private appSettingsStore: AppSettingsStoreService + ) { console.log(".ctor: OnlineOrdersService"); - // this loads static data from a file. will replace later. - - this.loadConfirmState(); + this.termsSubscription = this.terms$.subscribe(() => + this.loadConfirmState() + ); + } + ngOnDestroy(): void { + this.termsSubscription.unsubscribe(); } getInitialConfirmedStream(): Observable { @@ -50,7 +74,7 @@ export class OnlineOrdersService { ); } else { this.initialConfirmSource = new BehaviorSubject( - loadConfirms() + this.confirmChoices ); } @@ -65,7 +89,7 @@ export class OnlineOrdersService { clearState(): void { console.log("OnlineOrdersService.clearState-----"); - this.setInitialConfirm(loadConfirms()); + this.setInitialConfirm(this.confirmChoices); this.setWorkorderConfirm(false); this.setWorkAssignmentsConfirm(false); } diff --git a/src/app/online-orders/work-order/work-order.component.html b/src/app/online-orders/work-order/work-order.component.html index d9140aa6..4c03e138 100644 --- a/src/app/online-orders/work-order/work-order.component.html +++ b/src/app/online-orders/work-order/work-order.component.html @@ -146,18 +146,20 @@
- -
- - - - - - {{formErrors.requireVaccinatedWorkers}} - -
- + + +
+ + + + + + {{formErrors.requireVaccinatedWorkers}} + +
+
+
@@ -212,17 +214,18 @@
- - - - + + + + +
diff --git a/src/app/online-orders/work-order/work-order.component.spec.ts b/src/app/online-orders/work-order/work-order.component.spec.ts index 1dde9a3b..b625984f 100644 --- a/src/app/online-orders/work-order/work-order.component.spec.ts +++ b/src/app/online-orders/work-order/work-order.component.spec.ts @@ -11,7 +11,6 @@ import { ToggleButtonModule } from "primeng/togglebutton"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { OnlineOrdersService } from "../online-orders.service"; -import { ConfigsService } from "../../configs/configs.service"; import { TransportRulesServiceSpy, TransportProvidersServiceSpy, @@ -19,7 +18,6 @@ import { } from "../../shared/testing"; import { WorkOrderServiceSpy, - ConfigsServiceSpy, OnlineOrdersServiceSpy, RouterSpy, } from "../../shared/testing"; @@ -55,7 +53,6 @@ describe("WorkOrderComponent", () => { provide: OnlineOrdersService, useClass: OnlineOrdersServiceSpy, }, - { provide: ConfigsService, useClass: ConfigsServiceSpy }, { provide: Router, useClass: RouterSpy }, { provide: ScheduleRulesService, diff --git a/src/app/online-orders/work-order/work-order.component.ts b/src/app/online-orders/work-order/work-order.component.ts index 55e038b1..d1197e5b 100644 --- a/src/app/online-orders/work-order/work-order.component.ts +++ b/src/app/online-orders/work-order/work-order.component.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { combineLatest as observableCombineLatest } from "rxjs"; +import { combineLatest as observableCombineLatest, Observable } from "rxjs"; import { Component, OnInit } from "@angular/core"; import { FormGroup, FormBuilder } from "@angular/forms"; import { WorkOrder } from "../../shared/models/work-order"; @@ -31,6 +31,8 @@ import { transportAvailabilityValidator } from "../shared/validators/transport-a import { DateTime } from "luxon"; import { BreakpointObserver, Breakpoints } from "@angular/cdk/layout"; import { vaccineReqFlagResolver } from "../../shared/helpers"; +import { AppSettingsStoreService } from "../../shared/services/app-settings-store.service"; +import { map, pluck } from "rxjs/operators"; @Component({ selector: "app-work-order", @@ -80,11 +82,21 @@ export class WorkOrderComponent implements OnInit { new YesNoSelectItem("no", false), new YesNoSelectItem("yes", true), ]; + onlineOrdersTransportDetailsLink$: Observable = this.appSettingsStore + .getConfig("OnlineOrdersTransportDetailsLink") + .pipe(pluck("value")); + disableWorkersVaccineRequirement$: Observable = this.appSettingsStore + .getConfig("DisableWorkersVaccineRequirement") + .pipe( + pluck("value"), + map((flag: string) => flag === "TRUE") + ); constructor( private transportProviderService: TransportProvidersService, private orderService: WorkOrderService, private onlineService: OnlineOrdersService, + private appSettingsStore: AppSettingsStoreService, private schedulingRulesService: ScheduleRulesService, private transportRulesService: TransportRulesService, private router: Router, diff --git a/src/app/shared/services/app-settings-store.service.spec.ts b/src/app/shared/services/app-settings-store.service.spec.ts new file mode 100644 index 00000000..c903b173 --- /dev/null +++ b/src/app/shared/services/app-settings-store.service.spec.ts @@ -0,0 +1,49 @@ +import { + HttpClientTestingModule, + HttpTestingController, +} from "@angular/common/http/testing"; +import { TestBed } from "@angular/core/testing"; +import { environment } from "../../../environments/environment"; +import { MessagesService } from "../components/messages/messages.service"; +import { Config } from "../models/config"; +import { MessagesServiceSpy } from "../testing"; + +import { AppSettingsStoreService } from "./app-settings-store.service"; + +describe("AppSettingsService", () => { + let service: AppSettingsStoreService; + let controller: HttpTestingController; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + AppSettingsStoreService, + { provide: MessagesService, useClass: MessagesServiceSpy }, + ], + imports: [HttpClientTestingModule], + }); + service = TestBed.inject(AppSettingsStoreService); + controller = TestBed.inject(HttpTestingController); + }); + + it("should be created", () => { + expect(service).toBeTruthy(); + }); + + it("when STALE, SHOULD call Api", () => { + service.refreshCache(); + service.all$.subscribe((res) => { + expect(res.length).toEqual(1); + }); + const request = controller.expectOne(`${environment.dataUrl}/api/configs`); + request.flush({ data: [new Config()] }); + }); + + it("when NOT stale, should not callApi", () => { + controller.expectNone(`${environment.dataUrl}/api/configs`); + service.all$.subscribe(); //initial http request + service.setCacheTTL(5000); + service.all$.subscribe((res) => console.log("______RES_____", res)); // chache + controller.expectOne(`${environment.dataUrl}/api/configs`); + }); +}); diff --git a/src/app/shared/services/app-settings-store.service.ts b/src/app/shared/services/app-settings-store.service.ts new file mode 100644 index 00000000..b0b86898 --- /dev/null +++ b/src/app/shared/services/app-settings-store.service.ts @@ -0,0 +1,158 @@ +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable, Optional, SkipSelf } from "@angular/core"; +import { BehaviorSubject, iif, Observable, throwError } from "rxjs"; +import { catchError, map, pluck, share, tap } from "rxjs/operators"; +import { environment } from "../../../environments/environment"; +import { MS_NON_EDITABLE_CONFIGS_LOWER_CASE } from "../../configs/machete-settings/shared/machete-settings-constants"; +import { MessagesService } from "../components/messages/messages.service"; +import { CCategory, Config } from "../models/config"; + +/** + * Singleton store service. Caches data based on a TTL. + * Each config object represents an app setting + */ +@Injectable({ + providedIn: "root", +}) +export class AppSettingsStoreService { + private _configsAge = 0; + private _CACHE_TIME_TO_LIVE = 300000; // 5 minutes + private readonly _uriBase = environment.dataUrl + "/api/configs"; + private _appSettingsSubject = new BehaviorSubject([]); + + /** + * All Configs as Observable. Cached based on a TTL + */ + readonly all$ = iif( + () => this.isStale(), + this.getAllConfigs(), + this._appSettingsSubject.asObservable() + ); + + constructor( + private _http: HttpClient, + private _appMessages: MessagesService, + @Optional() @SkipSelf() parentModule?: AppSettingsStoreService + ) { + // enforce app singleton pattern + if (parentModule) { + throw new Error( + `Machete dev error: ${AppSettingsStoreService.name} is already loaded. Additional imports not needed` + ); + } + } + + private isStale = (): boolean => + this._configsAge < Date.now() - this._CACHE_TIME_TO_LIVE; + + private getAllConfigs(): Observable { + return this._http.get(this._uriBase).pipe( + pluck("data"), + map((data: Config[]) => data), + tap(() => (this._configsAge = Date.now())), + tap((configs: Config[]) => this._appSettingsSubject.next(configs)), + share() + ); + } + + private httpUpdate(config: Config): Observable { + return this._http + .put(`${this._uriBase}/${config.id}`, config, { + withCredentials: true, + }) + .pipe( + catchError((error: HttpErrorResponse) => { + const { statusText } = error; + this._appMessages.showErrors({ + Error: `${statusText}: Contact Machete support.`, + }); + console.log(error); + return throwError(error); + }), + pluck("data"), // if no error + map((data: Config) => data) + ); + } + + private validateUserEditable = (configKey: string): boolean => + !MS_NON_EDITABLE_CONFIGS_LOWER_CASE.includes(configKey.toLowerCase()); + + private getCacheWithNewVal(newConfig: Config, cache: Config[]) { + const configIndex = cache.findIndex((x) => x.id == newConfig.id); + cache.splice(configIndex, 1, newConfig); // side effect: changes the cache array + return cache; + } + + /** + * filters the cached values on `CCategory` + * @param category a `CCategory` type + * @returns the filtered values from cache as Observable, + * if the cache's TTL is reached, + * the new values + */ + getConfigsWith(category: CCategory): Observable { + return this.all$.pipe( + map((all) => all.filter((l) => l.category === category)) + ); + } + + /** + * @param key the config key property to filter + * @returns a single `Config` record from cache as Observable, + * if the cache's TTL is reached, sourced from new values + */ + getConfig(key: string): Observable { + return this.all$.pipe( + map((a) => a.filter((ll) => ll.key === key)), + map(([first]) => first), + map((a) => ({ ...a })) + ); + } + + /** + * makes an http PUT request and the cache is updated to reflect + * @param config the `Config` to update + * @returns the updated record returned from the http PUT request as Observable + */ + update(config: Config): Observable { + if (!this.validateUserEditable(config.key)) { + return this.getConfig(config.key).pipe( + tap(() => { + this._appMessages.showErrors({ + Error: "Action not allowed", + }); + }) + ); + } + + return this.httpUpdate(config).pipe( + tap(() => { + this._appMessages.showSuccess({ + label: "Success", + message: "Record Saved", + }); + }), + // replace cache with new val + tap((config) => + this._appSettingsSubject.next( + this.getCacheWithNewVal(config, this._appSettingsSubject.value) + ) + ) + ); + } + + /** + * Flags cache as stale and new data will be fetched from http when requested + */ + refreshCache(): void { + this._configsAge = 0; + } + + /** + * optionally override the cache TTL, only recommended for testing + * @param ttl ttl in milliseconds + */ + setCacheTTL(ttl: number): void { + this._CACHE_TIME_TO_LIVE = ttl; + } +} diff --git a/src/app/shared/testing/services.spy.ts b/src/app/shared/testing/services.spy.ts index ec02474b..0d030d71 100644 --- a/src/app/shared/testing/services.spy.ts +++ b/src/app/shared/testing/services.spy.ts @@ -23,7 +23,6 @@ import { ApiResponse } from "../../workers/models/api-response"; import { Worker } from "../models/worker"; import { Skill } from "../models/skill"; import { Report } from "src/app/reports/models/report"; -import { tick } from "@angular/core/testing"; export class EmployersServiceSpy { getEmployer = jasmine @@ -200,6 +199,12 @@ export class OnlineOrdersServiceSpy { export const getConfigsList = (): Config[] => { const configs: Config[] = new Array(); + configs.push( + new Config({ + key: "OnlineOrderTerms", + value: `[{"name":"term1","text":"This is the term one"},{"name":"term2","text":"This is the term two"}]`, + }) + ); configs.push(new Config({ key: "WorkCenterDescription_EN", value: "foo" })); configs.push(new Config({ key: "FacebookAppId", value: "foo" })); configs.push(new Config({ key: "GoogleClientId", value: "foo" })); @@ -220,6 +225,19 @@ export class ConfigsServiceSpy { .and.callFake(() => observableOf(getConfigsList())); } +export class AppSettingsStoreServiceSpy { + all$ = observableOf(getConfigsList()); + getConfigsWith = jasmine + .createSpy("getConfigsWith") + .and.callFake(() => observableOf(getConfigsList())); + getConfig = jasmine + .createSpy("getConfig") + .and.callFake(() => observableOf(getConfigsList()[0])); + update = jasmine + .createSpy("update") + .and.callFake(() => observableOf(getConfigsList[0])); +} + /** * the spy for PrimeNG message service */ diff --git a/src/app/welcome/welcome.component.spec.ts b/src/app/welcome/welcome.component.spec.ts index 9eda53c7..ca3e6fd2 100644 --- a/src/app/welcome/welcome.component.spec.ts +++ b/src/app/welcome/welcome.component.spec.ts @@ -3,17 +3,17 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { WelcomeComponent } from "./welcome.component"; -import { ConfigsService } from "../configs/configs.service"; import { AuthService } from "../shared/index"; import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRouteSpy, + AppSettingsStoreServiceSpy, AuthServiceSpy, - ConfigsServiceSpy, getConfigsList, RouterSpy, } from "../shared/testing"; import { MessageService } from "primeng/api"; +import { AppSettingsStoreService } from "../shared/services/app-settings-store.service"; describe("WelcomeComponent", () => { let component: WelcomeComponent; @@ -27,7 +27,10 @@ describe("WelcomeComponent", () => { .overrideComponent(WelcomeComponent, { set: { providers: [ - { provide: ConfigsService, useClass: ConfigsServiceSpy }, + { + provide: AppSettingsStoreService, + useClass: AppSettingsStoreServiceSpy, + }, { provide: AuthService, useClass: AuthServiceSpy }, { provide: Router, useClass: RouterSpy }, { provide: ActivatedRoute, useClass: ActivatedRouteSpy }, diff --git a/src/app/welcome/welcome.component.ts b/src/app/welcome/welcome.component.ts index 55748eb4..d56fb0ee 100644 --- a/src/app/welcome/welcome.component.ts +++ b/src/app/welcome/welcome.component.ts @@ -1,5 +1,4 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; -import { ConfigsService } from "../configs/configs.service"; import { AuthService } from "../shared/index"; import { ActivatedRoute, Router } from "@angular/router"; import { environment } from "../../environments/environment"; @@ -8,7 +7,7 @@ import { User } from "../shared/models/user"; import { map, pluck, takeWhile, tap } from "rxjs/operators"; import { Observable } from "rxjs"; import { MessageService } from "primeng/api"; - +import { AppSettingsStoreService } from "../shared/services/app-settings-store.service"; enum DashboardState { None = "None", @@ -78,7 +77,7 @@ export class WelcomeComponent implements OnInit, OnDestroy { ]; constructor( - private cfgService: ConfigsService, + private appSettingsStore: AppSettingsStoreService, private authService: AuthService, private router: Router, private activatedRoute: ActivatedRoute, @@ -117,7 +116,7 @@ export class WelcomeComponent implements OnInit, OnDestroy { ngOnInit(): void { // this.handleQueryParams(); - this.cfgService.getAllConfigs().subscribe( + this.appSettingsStore.all$.subscribe( (data) => { this.serverData = data; console.log("configs: ", data); // TODO this was 2am madness, this isn"t great JS