{"id":3012,"date":"2021-04-12T10:00:00","date_gmt":"2021-04-12T14:00:00","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3012"},"modified":"2021-04-12T08:00:47","modified_gmt":"2021-04-12T12:00:47","slug":"angular-maintenance-alert-system","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-maintenance-alert-system\/","title":{"rendered":"Angular Maintenance Alert System"},"content":{"rendered":"\n<p>So often we need to schedule maintenance on a system, and we need to be able to stop users from doing things during this time. To that end, here is a system I created.  It uses a Spring backend, that is not presented here.<\/p>\n\n\n\n<p>Created a method that would contact a backend server and request the next scheduled maintenance.  However what if the server is down for some reason?  How do we handle that scenario?  <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private checkMaintenance() {\n        this.getNextScheduledMaintenance().subscribe(value => {\n            let maintenanceLock = false;\n            let notify = false;\n            if (this._maintenanceWindow == null &amp;&amp; value != null) {\n                notify = true;\n            }\n            this._maintenanceWindow = value;\n            if (this._maintenanceWindow != null) {\n                this._maintenanceWindow.start = new Date(this._maintenanceWindow.start);\n                this._maintenanceWindow.end = new Date(this._maintenanceWindow.end);\n                let current = new Date();\n\n                let diff = this._maintenanceWindow.start.getTime() - current.getTime();\n                if (diff &lt; this.fiveMinute) {\n                    maintenanceLock = true;\n                }\n\n                if (diff &lt; 0) {\n                    diff = this._maintenanceWindow.end.getTime() - current.getTime();\n                    if (diff > 0) {\n                        maintenanceLock = true;\n                    }\n                }\n            }\n            this.maintenanceLock.next(maintenanceLock);\n            if (notify) {\n                this.openSnackBar();\n            }\n        }, error => {\n            let current = new Date();\n            if (this._maintenanceWindow == null) {\n\n                this._maintenanceWindow = new ScheduledMaintenance();\n                this._maintenanceWindow.description = \"System undergoing Maintenance\";\n                this._maintenanceWindow.start = current;\n                this._maintenanceWindow.end = new Date(current.getTime() + this.fiveMinute);\n            } else if (this._maintenanceWindow.end.getTime() - current.getTime() &lt; 0) {\n                this._maintenanceWindow.end = new Date(current.getTime() + this.fiveMinute);\n            }\n            this.maintenanceLock.next(true);\n        });\n    }<\/code><\/pre>\n\n\n\n<p>Let&#8217;s break down this method. First we have our call to backend system to get the next scheduled maintenance. Then we check to see if we are aware of the scheduled maintenance, if we are not then we mark that we set the flag to notify.  <\/p>\n\n\n\n<p>Next we check if we are within 5 minutes of scheduled maintenance or in the time range, if we are then flag that we need to apply the maintenance lock.<\/p>\n\n\n\n<p>Now this   is important, we need to check to see if an error has occurred.  If it has then we flag to apply the maintenance lock.  Now how do we call this method?                                                                                                 <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private timer: Subscription;<\/code><\/pre>\n\n\n\n<p>We create a Subscription called timer, and then in the constructor we set it to run every 5 minutes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>this.timer = interval(this.fiveMinute).subscribe(() => {\n            this.checkMaintenance()\n        });<\/code><\/pre>\n\n\n\n<p>Now do not forget to call unsubscribe() on  ngOnDestroy()<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> ngOnDestroy(): void {\n        this.timer.unsubscribe();\n        this.maintenanceLock.complete();\n    }<\/code><\/pre>\n\n\n\n<p>Now I use a MatSnackBar to display when a schedule maintenance is occurring.  However I use the following component to display the application is in maintenance mode.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import {Component, Inject, OnInit} from '@angular\/core';\nimport {ScheduledMaintenance} from \"..\/..\/dto\/maintenance\/scheduled-maintenance\";\nimport {MAT_SNACK_BAR_DATA} from \"@angular\/material\/snack-bar\";\n\n@Component({\n    selector: 'app-maintenance-notification',\n    templateUrl: '.\/maintenance-notification.component.html',\n    styleUrls: &#91;'.\/maintenance-notification.component.scss']\n})\nexport class MaintenanceNotificationComponent {\n    maintenanceWindow: ScheduledMaintenance = null;\n\n    constructor(@Inject(MAT_SNACK_BAR_DATA) public data: any) {\n        this.maintenanceWindow = data;\n\n    }\n}<\/code><\/pre>\n\n\n\n<p>With the following HTML.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;span class=\"maintenance-notification\">\n    &lt;h2>Maintenance Schedule&lt;\/h2>\n    &lt;h4>{{maintenanceWindow.description}}&lt;\/h4>\n    {{this.maintenanceWindow.start | date: 'medium'}} - {{this.maintenanceWindow.end | date: 'medium'}}\n&lt;\/span><\/code><\/pre>\n\n\n\n<p>The following SCSS<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.maintenance-notification {\n  text-align: center;\n}\n<\/code><\/pre>\n\n\n\n<p>When maintenance mode kicks in we<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-bottom-wave\"><a href=\"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"293\" src=\"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?resize=640%2C293&#038;ssl=1\" alt=\"\" class=\"wp-image-3013\" srcset=\"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?resize=1024%2C468&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?resize=300%2C137&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?resize=768%2C351&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?resize=1536%2C701&amp;ssl=1 1536w, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?w=1890&amp;ssl=1 1890w, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/maintenance.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>So often we need to schedule maintenance on a system, and we need to be able to stop users from doing things during this time. To that end, here is a system I created. It uses a Spring backend, that is not presented here. Created a method that would contact a backend server and request [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3014,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[281],"tags":[269],"series":[],"class_list":["post-3012","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","tag-angular"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/wrench-717684_640.jpg?fit=640%2C426&ssl=1","jetpack-related-posts":[{"id":2943,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-string-component\/","url_meta":{"origin":3012,"position":0},"title":"Angular Material String Component","author":"Jeffery Miller","date":"January 4, 2021","format":false,"excerpt":"Create a compnent for Display\/Edit\/Delete of a string using Angular Material mat-form-field.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/application-1883453_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2946,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-checkbox\/","url_meta":{"origin":3012,"position":1},"title":"Angular Material Checkbox","author":"Jeffery Miller","date":"January 11, 2021","format":false,"excerpt":"Create a compnent for Display\/Edit of a checkbox using Angular Material mat-form-field.","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2020\/12\/checklist-2549229_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3811,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/streamline-your-workflow-generate-angular-services-from-spring-boot-rest-apis-with-gradle\/","url_meta":{"origin":3012,"position":2},"title":"Streamline Your Workflow: Generate Angular Services from Spring Boot REST APIs with Gradle","author":"Jeffery Miller","date":"February 24, 2025","format":false,"excerpt":"Integrating your Angular frontend with a Spring Boot backend can be a breeze if you automate the process of creating your Angular services. This post will show you how to leverage Gradle, OpenAPI (Swagger), and the OpenAPI Generator to generate type-safe Angular TypeScript services directly from your Spring Boot REST\u2026","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/immune-defense-1359197_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/immune-defense-1359197_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/immune-defense-1359197_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/immune-defense-1359197_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/immune-defense-1359197_1280-jpg.avif 3x"},"classes":[]},{"id":2657,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-grid-layout-responsive\/","url_meta":{"origin":3012,"position":3},"title":"Angular Material Grid Layout Responsive","author":"Jeffery Miller","date":"December 16, 2019","format":false,"excerpt":"Angular Material is a powerful extension onto Angular for UI design. I personally fell in love with it before I ever used it. When I started using it I knew I would find things I would want to improve. Material Grid List is so handy to use and makes layouts\u2026","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/12\/grid-684983_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/12\/grid-684983_640.jpg?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/12\/grid-684983_640.jpg?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":2967,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/translations-in-a-angular-library\/","url_meta":{"origin":3012,"position":4},"title":"Translations in a Angular Library","author":"Jeffery Miller","date":"January 1, 2021","format":false,"excerpt":"Developing a UI library for Angular, I had strings that needed be hardcoded. The question became how do I deal with them. I did not want to embed in ngx-translate into the library. I wanted the user to have the ability to modify the strings as well. So I created\u2026","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/globe-110775_640.jpg?fit=640%2C341&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/globe-110775_640.jpg?fit=640%2C341&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/01\/globe-110775_640.jpg?fit=640%2C341&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3004,"url":"https:\/\/www.mymiller.name\/wordpress\/angular\/angular-material-calendar\/","url_meta":{"origin":3012,"position":5},"title":"Angular Material Calendar","author":"Jeffery Miller","date":"March 29, 2021","format":false,"excerpt":"Sometimes you need to have a calendar for showing information in your web application. After looking around at different implementations and finding none that work. I decided to create my own. This Calendar is not mobile optimized, For that, I created an Agenda that shows a single day at a\u2026","rel":"","context":"In &quot;Angular&quot;","block_context":{"text":"Angular","link":"https:\/\/www.mymiller.name\/wordpress\/category\/angular\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/january-2290045_640.jpg?fit=640%2C396&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/january-2290045_640.jpg?fit=640%2C396&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/january-2290045_640.jpg?fit=640%2C396&ssl=1&resize=525%2C300 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3012","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3012"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3012\/revisions"}],"predecessor-version":[{"id":3015,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3012\/revisions\/3015"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3014"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3012"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3012"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3012"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3012"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}