From f2330d58b81d48cb131f193133399aa4ebca2171 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Thu, 1 Feb 2024 19:38:40 +1100 Subject: [PATCH 01/79] add basic sorting with pagination --- Gemfile | 6 + Gemfile.lock | 62 + web/app.rb | 33 + web/index.html | 71 + web/node_modules/.package-lock.json | 35 + web/node_modules/@popperjs/core/LICENSE.md | 20 + web/node_modules/@popperjs/core/README.md | 376 + .../@popperjs/core/dist/cjs/enums.js | 65 + .../@popperjs/core/dist/cjs/enums.js.flow | 3 + .../@popperjs/core/dist/cjs/enums.js.map | 1 + .../@popperjs/core/dist/cjs/popper-base.js | 939 ++ .../core/dist/cjs/popper-base.js.flow | 3 + .../core/dist/cjs/popper-base.js.map | 1 + .../@popperjs/core/dist/cjs/popper-lite.js | 1260 ++ .../core/dist/cjs/popper-lite.js.flow | 3 + .../core/dist/cjs/popper-lite.js.map | 1 + .../@popperjs/core/dist/cjs/popper.js | 1819 +++ .../@popperjs/core/dist/cjs/popper.js.flow | 3 + .../@popperjs/core/dist/cjs/popper.js.map | 1 + .../@popperjs/core/dist/esm/createPopper.js | 199 + .../core/dist/esm/dom-utils/contains.js | 23 + .../esm/dom-utils/getBoundingClientRect.js | 41 + .../dist/esm/dom-utils/getClippingRect.js | 70 + .../dist/esm/dom-utils/getCompositeRect.js | 58 + .../dist/esm/dom-utils/getComputedStyle.js | 4 + .../dist/esm/dom-utils/getDocumentElement.js | 6 + .../dist/esm/dom-utils/getDocumentRect.js | 29 + .../esm/dom-utils/getHTMLElementScroll.js | 6 + .../core/dist/esm/dom-utils/getLayoutRect.js | 25 + .../core/dist/esm/dom-utils/getNodeName.js | 3 + .../core/dist/esm/dom-utils/getNodeScroll.js | 11 + .../dist/esm/dom-utils/getOffsetParent.js | 69 + .../core/dist/esm/dom-utils/getParentNode.js | 19 + .../dist/esm/dom-utils/getScrollParent.js | 16 + .../dist/esm/dom-utils/getViewportRect.js | 31 + .../core/dist/esm/dom-utils/getWindow.js | 12 + .../dist/esm/dom-utils/getWindowScroll.js | 10 + .../dist/esm/dom-utils/getWindowScrollBarX.js | 13 + .../core/dist/esm/dom-utils/instanceOf.js | 23 + .../dist/esm/dom-utils/isLayoutViewport.js | 4 + .../core/dist/esm/dom-utils/isScrollParent.js | 10 + .../core/dist/esm/dom-utils/isTableElement.js | 4 + .../dist/esm/dom-utils/listScrollParents.js | 26 + .../@popperjs/core/dist/esm/enums.js | 31 + .../@popperjs/core/dist/esm/index.js | 8 + .../core/dist/esm/modifiers/applyStyles.js | 84 + .../core/dist/esm/modifiers/arrow.js | 90 + .../core/dist/esm/modifiers/computeStyles.js | 169 + .../core/dist/esm/modifiers/eventListeners.js | 49 + .../@popperjs/core/dist/esm/modifiers/flip.js | 147 + .../@popperjs/core/dist/esm/modifiers/hide.js | 61 + .../core/dist/esm/modifiers/index.js | 9 + .../core/dist/esm/modifiers/offset.js | 54 + .../core/dist/esm/modifiers/popperOffsets.js | 25 + .../dist/esm/modifiers/preventOverflow.js | 142 + .../@popperjs/core/dist/esm/popper-base.js | 3 + .../@popperjs/core/dist/esm/popper-lite.js | 11 + .../@popperjs/core/dist/esm/popper.js | 20 + .../@popperjs/core/dist/esm/types.js | 0 .../dist/esm/utils/computeAutoPlacement.js | 43 + .../core/dist/esm/utils/computeOffsets.js | 70 + .../@popperjs/core/dist/esm/utils/debounce.js | 15 + .../core/dist/esm/utils/detectOverflow.js | 65 + .../core/dist/esm/utils/expandToHashMap.js | 6 + .../core/dist/esm/utils/getAltAxis.js | 3 + .../core/dist/esm/utils/getAltLen.js | 3 + .../core/dist/esm/utils/getBasePlacement.js | 4 + .../core/dist/esm/utils/getFreshSideObject.js | 8 + .../esm/utils/getMainAxisFromPlacement.js | 3 + .../dist/esm/utils/getOppositePlacement.js | 11 + .../utils/getOppositeVariationPlacement.js | 9 + .../core/dist/esm/utils/getVariation.js | 3 + .../@popperjs/core/dist/esm/utils/math.js | 3 + .../core/dist/esm/utils/mergeByName.js | 14 + .../core/dist/esm/utils/mergePaddingObject.js | 4 + .../core/dist/esm/utils/orderModifiers.js | 44 + .../core/dist/esm/utils/rectToClientRect.js | 8 + .../@popperjs/core/dist/esm/utils/uniqueBy.js | 11 + .../core/dist/esm/utils/userAgent.js | 11 + .../@popperjs/core/dist/esm/utils/within.js | 8 + .../@popperjs/core/dist/umd/enums.js | 71 + .../@popperjs/core/dist/umd/enums.js.map | 1 + .../@popperjs/core/dist/umd/enums.min.js | 6 + .../@popperjs/core/dist/umd/enums.min.js.flow | 3 + .../@popperjs/core/dist/umd/enums.min.js.map | 1 + .../@popperjs/core/dist/umd/popper-base.js | 945 ++ .../core/dist/umd/popper-base.js.map | 1 + .../core/dist/umd/popper-base.min.js | 6 + .../core/dist/umd/popper-base.min.js.flow | 3 + .../core/dist/umd/popper-base.min.js.map | 1 + .../@popperjs/core/dist/umd/popper-lite.js | 1266 ++ .../core/dist/umd/popper-lite.js.map | 1 + .../core/dist/umd/popper-lite.min.js | 6 + .../core/dist/umd/popper-lite.min.js.flow | 3 + .../core/dist/umd/popper-lite.min.js.map | 1 + .../@popperjs/core/dist/umd/popper.js | 1825 +++ .../@popperjs/core/dist/umd/popper.js.map | 1 + .../@popperjs/core/dist/umd/popper.min.js | 6 + .../core/dist/umd/popper.min.js.flow | 3 + .../@popperjs/core/dist/umd/popper.min.js.map | 1 + web/node_modules/@popperjs/core/index.d.ts | 1 + .../@popperjs/core/lib/createPopper.d.ts | 9 + .../@popperjs/core/lib/createPopper.js | 199 + .../@popperjs/core/lib/createPopper.js.flow | 218 + .../core/lib/dom-utils/contains.d.ts | 1 + .../@popperjs/core/lib/dom-utils/contains.js | 23 + .../core/lib/dom-utils/contains.js.flow | 25 + .../lib/dom-utils/getBoundingClientRect.d.ts | 2 + .../lib/dom-utils/getBoundingClientRect.js | 41 + .../dom-utils/getBoundingClientRect.js.flow | 52 + .../core/lib/dom-utils/getClippingRect.d.ts | 3 + .../core/lib/dom-utils/getClippingRect.js | 70 + .../lib/dom-utils/getClippingRect.js.flow | 106 + .../core/lib/dom-utils/getCompositeRect.d.ts | 2 + .../core/lib/dom-utils/getCompositeRect.js | 58 + .../lib/dom-utils/getCompositeRect.js.flow | 64 + .../core/lib/dom-utils/getComputedStyle.d.ts | 1 + .../core/lib/dom-utils/getComputedStyle.js | 4 + .../lib/dom-utils/getComputedStyle.js.flow | 8 + .../lib/dom-utils/getDocumentElement.d.ts | 2 + .../core/lib/dom-utils/getDocumentElement.js | 6 + .../lib/dom-utils/getDocumentElement.js.flow | 15 + .../core/lib/dom-utils/getDocumentRect.d.ts | 2 + .../core/lib/dom-utils/getDocumentRect.js | 29 + .../lib/dom-utils/getDocumentRect.js.flow | 37 + .../lib/dom-utils/getHTMLElementScroll.d.ts | 4 + .../lib/dom-utils/getHTMLElementScroll.js | 6 + .../dom-utils/getHTMLElementScroll.js.flow | 8 + .../core/lib/dom-utils/getLayoutRect.d.ts | 2 + .../core/lib/dom-utils/getLayoutRect.js | 25 + .../core/lib/dom-utils/getLayoutRect.js.flow | 29 + .../core/lib/dom-utils/getNodeName.d.ts | 2 + .../core/lib/dom-utils/getNodeName.js | 3 + .../core/lib/dom-utils/getNodeName.js.flow | 6 + .../core/lib/dom-utils/getNodeScroll.d.ts | 5 + .../core/lib/dom-utils/getNodeScroll.js | 11 + .../core/lib/dom-utils/getNodeScroll.js.flow | 14 + .../core/lib/dom-utils/getOffsetParent.d.ts | 1 + .../core/lib/dom-utils/getOffsetParent.js | 69 + .../lib/dom-utils/getOffsetParent.js.flow | 93 + .../core/lib/dom-utils/getParentNode.d.ts | 1 + .../core/lib/dom-utils/getParentNode.js | 19 + .../core/lib/dom-utils/getParentNode.js.flow | 21 + .../core/lib/dom-utils/getScrollParent.d.ts | 1 + .../core/lib/dom-utils/getScrollParent.js | 16 + .../lib/dom-utils/getScrollParent.js.flow | 18 + .../core/lib/dom-utils/getViewportRect.d.ts | 7 + .../core/lib/dom-utils/getViewportRect.js | 31 + .../lib/dom-utils/getViewportRect.js.flow | 39 + .../core/lib/dom-utils/getWindow.d.ts | 1 + .../@popperjs/core/lib/dom-utils/getWindow.js | 12 + .../core/lib/dom-utils/getWindow.js.flow | 16 + .../core/lib/dom-utils/getWindowScroll.d.ts | 5 + .../core/lib/dom-utils/getWindowScroll.js | 10 + .../lib/dom-utils/getWindowScroll.js.flow | 14 + .../lib/dom-utils/getWindowScrollBarX.d.ts | 1 + .../core/lib/dom-utils/getWindowScrollBarX.js | 13 + .../lib/dom-utils/getWindowScrollBarX.js.flow | 18 + .../core/lib/dom-utils/instanceOf.d.ts | 4 + .../core/lib/dom-utils/instanceOf.js | 23 + .../core/lib/dom-utils/instanceOf.js.flow | 29 + .../core/lib/dom-utils/isLayoutViewport.d.ts | 1 + .../core/lib/dom-utils/isLayoutViewport.js | 4 + .../lib/dom-utils/isLayoutViewport.js.flow | 6 + .../core/lib/dom-utils/isScrollParent.d.ts | 1 + .../core/lib/dom-utils/isScrollParent.js | 10 + .../core/lib/dom-utils/isScrollParent.js.flow | 8 + .../core/lib/dom-utils/isTableElement.d.ts | 1 + .../core/lib/dom-utils/isTableElement.js | 4 + .../core/lib/dom-utils/isTableElement.js.flow | 6 + .../core/lib/dom-utils/listScrollParents.d.ts | 2 + .../core/lib/dom-utils/listScrollParents.js | 26 + .../lib/dom-utils/listScrollParents.js.flow | 33 + .../@popperjs/core/lib/enums.d.ts | 34 + web/node_modules/@popperjs/core/lib/enums.js | 31 + .../@popperjs/core/lib/enums.js.flow | 91 + .../@popperjs/core/lib/index.d.ts | 6 + web/node_modules/@popperjs/core/lib/index.js | 8 + .../@popperjs/core/lib/index.js.flow | 13 + .../core/lib/modifiers/applyStyles.d.ts | 4 + .../core/lib/modifiers/applyStyles.js | 84 + .../core/lib/modifiers/applyStyles.js.flow | 98 + .../@popperjs/core/lib/modifiers/arrow.d.ts | 13 + .../@popperjs/core/lib/modifiers/arrow.js | 90 + .../core/lib/modifiers/arrow.js.flow | 120 + .../core/lib/modifiers/computeStyles.d.ts | 38 + .../core/lib/modifiers/computeStyles.js | 169 + .../core/lib/modifiers/computeStyles.js.flow | 233 + .../core/lib/modifiers/eventListeners.d.ts | 8 + .../core/lib/modifiers/eventListeners.js | 49 + .../core/lib/modifiers/eventListeners.js.flow | 54 + .../@popperjs/core/lib/modifiers/flip.d.ts | 16 + .../@popperjs/core/lib/modifiers/flip.js | 147 + .../@popperjs/core/lib/modifiers/flip.js.flow | 177 + .../@popperjs/core/lib/modifiers/hide.d.ts | 4 + .../@popperjs/core/lib/modifiers/hide.js | 61 + .../@popperjs/core/lib/modifiers/hide.js.flow | 76 + .../@popperjs/core/lib/modifiers/index.d.ts | 9 + .../@popperjs/core/lib/modifiers/index.js | 9 + .../core/lib/modifiers/index.js.flow | 10 + .../@popperjs/core/lib/modifiers/offset.d.ts | 18 + .../@popperjs/core/lib/modifiers/offset.js | 54 + .../core/lib/modifiers/offset.js.flow | 71 + .../core/lib/modifiers/popperOffsets.d.ts | 4 + .../core/lib/modifiers/popperOffsets.js | 25 + .../core/lib/modifiers/popperOffsets.js.flow | 26 + .../core/lib/modifiers/preventOverflow.d.ts | 30 + .../core/lib/modifiers/preventOverflow.js | 142 + .../lib/modifiers/preventOverflow.js.flow | 220 + .../@popperjs/core/lib/popper-base.d.ts | 3 + .../@popperjs/core/lib/popper-base.js | 3 + .../@popperjs/core/lib/popper-base.js.flow | 7 + .../@popperjs/core/lib/popper-lite.d.ts | 5 + .../@popperjs/core/lib/popper-lite.js | 11 + .../@popperjs/core/lib/popper-lite.js.flow | 21 + .../@popperjs/core/lib/popper.d.ts | 7 + web/node_modules/@popperjs/core/lib/popper.js | 20 + .../@popperjs/core/lib/popper.js.flow | 35 + .../@popperjs/core/lib/types.d.ts | 167 + web/node_modules/@popperjs/core/lib/types.js | 0 .../@popperjs/core/lib/types.js.flow | 199 + .../core/lib/utils/computeAutoPlacement.d.ts | 12 + .../core/lib/utils/computeAutoPlacement.js | 43 + .../lib/utils/computeAutoPlacement.js.flow | 73 + .../core/lib/utils/computeOffsets.d.ts | 8 + .../core/lib/utils/computeOffsets.js | 70 + .../core/lib/utils/computeOffsets.js.flow | 82 + .../@popperjs/core/lib/utils/debounce.d.ts | 1 + .../@popperjs/core/lib/utils/debounce.js | 15 + .../@popperjs/core/lib/utils/debounce.js.flow | 17 + .../core/lib/utils/detectOverflow.d.ts | 12 + .../core/lib/utils/detectOverflow.js | 65 + .../core/lib/utils/detectOverflow.js.flow | 112 + .../core/lib/utils/expandToHashMap.d.ts | 3 + .../core/lib/utils/expandToHashMap.js | 6 + .../core/lib/utils/expandToHashMap.js.flow | 11 + .../@popperjs/core/lib/utils/getAltAxis.d.ts | 1 + .../@popperjs/core/lib/utils/getAltAxis.js | 3 + .../core/lib/utils/getAltAxis.js.flow | 5 + .../@popperjs/core/lib/utils/getAltLen.d.ts | 1 + .../@popperjs/core/lib/utils/getAltLen.js | 3 + .../core/lib/utils/getAltLen.js.flow | 5 + .../core/lib/utils/getBasePlacement.d.ts | 2 + .../core/lib/utils/getBasePlacement.js | 4 + .../core/lib/utils/getBasePlacement.js.flow | 8 + .../core/lib/utils/getFreshSideObject.d.ts | 2 + .../core/lib/utils/getFreshSideObject.js | 8 + .../core/lib/utils/getFreshSideObject.js.flow | 11 + .../lib/utils/getMainAxisFromPlacement.d.ts | 2 + .../lib/utils/getMainAxisFromPlacement.js | 3 + .../utils/getMainAxisFromPlacement.js.flow | 8 + .../core/lib/utils/getOppositePlacement.d.ts | 2 + .../core/lib/utils/getOppositePlacement.js | 11 + .../lib/utils/getOppositePlacement.js.flow | 11 + .../utils/getOppositeVariationPlacement.d.ts | 2 + .../utils/getOppositeVariationPlacement.js | 9 + .../getOppositeVariationPlacement.js.flow | 10 + .../core/lib/utils/getVariation.d.ts | 2 + .../@popperjs/core/lib/utils/getVariation.js | 3 + .../core/lib/utils/getVariation.js.flow | 6 + .../@popperjs/core/lib/utils/math.d.ts | 3 + .../@popperjs/core/lib/utils/math.js | 3 + .../@popperjs/core/lib/utils/math.js.flow | 4 + .../@popperjs/core/lib/utils/mergeByName.d.ts | 2 + .../@popperjs/core/lib/utils/mergeByName.js | 14 + .../core/lib/utils/mergeByName.js.flow | 22 + .../core/lib/utils/mergePaddingObject.d.ts | 2 + .../core/lib/utils/mergePaddingObject.js | 4 + .../core/lib/utils/mergePaddingObject.js.flow | 12 + .../core/lib/utils/orderModifiers.d.ts | 2 + .../core/lib/utils/orderModifiers.js | 44 + .../core/lib/utils/orderModifiers.js.flow | 59 + .../core/lib/utils/rectToClientRect.d.ts | 2 + .../core/lib/utils/rectToClientRect.js | 8 + .../core/lib/utils/rectToClientRect.js.flow | 12 + .../@popperjs/core/lib/utils/uniqueBy.d.ts | 1 + .../@popperjs/core/lib/utils/uniqueBy.js | 11 + .../@popperjs/core/lib/utils/uniqueBy.js.flow | 14 + .../@popperjs/core/lib/utils/userAgent.d.ts | 1 + .../@popperjs/core/lib/utils/userAgent.js | 11 + .../core/lib/utils/userAgent.js.flow | 20 + .../@popperjs/core/lib/utils/within.d.ts | 2 + .../@popperjs/core/lib/utils/within.js | 8 + .../@popperjs/core/lib/utils/within.js.flow | 11 + web/node_modules/@popperjs/core/package.json | 119 + web/node_modules/bootstrap/LICENSE | 21 + web/node_modules/bootstrap/README.md | 246 + .../bootstrap/dist/css/bootstrap-grid.css | 4085 ++++++ .../bootstrap/dist/css/bootstrap-grid.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.min.css | 6 + .../dist/css/bootstrap-grid.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.rtl.css | 4084 ++++++ .../dist/css/bootstrap-grid.rtl.css.map | 1 + .../dist/css/bootstrap-grid.rtl.min.css | 6 + .../dist/css/bootstrap-grid.rtl.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-reboot.css | 597 + .../dist/css/bootstrap-reboot.css.map | 1 + .../dist/css/bootstrap-reboot.min.css | 6 + .../dist/css/bootstrap-reboot.min.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.css | 594 + .../dist/css/bootstrap-reboot.rtl.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.min.css | 6 + .../dist/css/bootstrap-reboot.rtl.min.css.map | 1 + .../dist/css/bootstrap-utilities.css | 5402 +++++++ .../dist/css/bootstrap-utilities.css.map | 1 + .../dist/css/bootstrap-utilities.min.css | 6 + .../dist/css/bootstrap-utilities.min.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.css | 5393 +++++++ .../dist/css/bootstrap-utilities.rtl.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.min.css | 6 + .../css/bootstrap-utilities.rtl.min.css.map | 1 + .../bootstrap/dist/css/bootstrap.css | 12068 ++++++++++++++++ .../bootstrap/dist/css/bootstrap.css.map | 1 + .../bootstrap/dist/css/bootstrap.min.css | 6 + .../bootstrap/dist/css/bootstrap.min.css.map | 1 + .../bootstrap/dist/css/bootstrap.rtl.css | 12032 +++++++++++++++ .../bootstrap/dist/css/bootstrap.rtl.css.map | 1 + .../bootstrap/dist/css/bootstrap.rtl.min.css | 6 + .../dist/css/bootstrap.rtl.min.css.map | 1 + .../bootstrap/dist/js/bootstrap.bundle.js | 6314 ++++++++ .../bootstrap/dist/js/bootstrap.bundle.js.map | 1 + .../bootstrap/dist/js/bootstrap.bundle.min.js | 7 + .../dist/js/bootstrap.bundle.min.js.map | 1 + .../bootstrap/dist/js/bootstrap.esm.js | 4447 ++++++ .../bootstrap/dist/js/bootstrap.esm.js.map | 1 + .../bootstrap/dist/js/bootstrap.esm.min.js | 7 + .../dist/js/bootstrap.esm.min.js.map | 1 + .../bootstrap/dist/js/bootstrap.js | 4494 ++++++ .../bootstrap/dist/js/bootstrap.js.map | 1 + .../bootstrap/dist/js/bootstrap.min.js | 7 + .../bootstrap/dist/js/bootstrap.min.js.map | 1 + web/node_modules/bootstrap/js/dist/alert.js | 90 + .../bootstrap/js/dist/alert.js.map | 1 + .../bootstrap/js/dist/base-component.js | 84 + .../bootstrap/js/dist/base-component.js.map | 1 + web/node_modules/bootstrap/js/dist/button.js | 79 + .../bootstrap/js/dist/button.js.map | 1 + .../bootstrap/js/dist/carousel.js | 388 + .../bootstrap/js/dist/carousel.js.map | 1 + .../bootstrap/js/dist/collapse.js | 249 + .../bootstrap/js/dist/collapse.js.map | 1 + .../bootstrap/js/dist/dom/data.js | 63 + .../bootstrap/js/dist/dom/data.js.map | 1 + .../bootstrap/js/dist/dom/event-handler.js | 237 + .../js/dist/dom/event-handler.js.map | 1 + .../bootstrap/js/dist/dom/manipulator.js | 72 + .../bootstrap/js/dist/dom/manipulator.js.map | 1 + .../bootstrap/js/dist/dom/selector-engine.js | 104 + .../js/dist/dom/selector-engine.js.map | 1 + .../bootstrap/js/dist/dropdown.js | 402 + .../bootstrap/js/dist/dropdown.js.map | 1 + web/node_modules/bootstrap/js/dist/modal.js | 320 + .../bootstrap/js/dist/modal.js.map | 1 + .../bootstrap/js/dist/offcanvas.js | 246 + .../bootstrap/js/dist/offcanvas.js.map | 1 + web/node_modules/bootstrap/js/dist/popover.js | 96 + .../bootstrap/js/dist/popover.js.map | 1 + .../bootstrap/js/dist/scrollspy.js | 275 + .../bootstrap/js/dist/scrollspy.js.map | 1 + web/node_modules/bootstrap/js/dist/tab.js | 285 + web/node_modules/bootstrap/js/dist/tab.js.map | 1 + web/node_modules/bootstrap/js/dist/toast.js | 199 + .../bootstrap/js/dist/toast.js.map | 1 + web/node_modules/bootstrap/js/dist/tooltip.js | 546 + .../bootstrap/js/dist/tooltip.js.map | 1 + .../bootstrap/js/dist/util/backdrop.js | 140 + .../bootstrap/js/dist/util/backdrop.js.map | 1 + .../js/dist/util/component-functions.js | 42 + .../js/dist/util/component-functions.js.map | 1 + .../bootstrap/js/dist/util/config.js | 68 + .../bootstrap/js/dist/util/config.js.map | 1 + .../bootstrap/js/dist/util/focustrap.js | 114 + .../bootstrap/js/dist/util/focustrap.js.map | 1 + .../bootstrap/js/dist/util/index.js | 282 + .../bootstrap/js/dist/util/index.js.map | 1 + .../bootstrap/js/dist/util/sanitizer.js | 111 + .../bootstrap/js/dist/util/sanitizer.js.map | 1 + .../bootstrap/js/dist/util/scrollbar.js | 113 + .../bootstrap/js/dist/util/scrollbar.js.map | 1 + .../bootstrap/js/dist/util/swipe.js | 135 + .../bootstrap/js/dist/util/swipe.js.map | 1 + .../js/dist/util/template-factory.js | 151 + .../js/dist/util/template-factory.js.map | 1 + web/node_modules/bootstrap/js/index.esm.js | 19 + web/node_modules/bootstrap/js/index.umd.js | 34 + web/node_modules/bootstrap/js/src/alert.js | 87 + .../bootstrap/js/src/base-component.js | 85 + web/node_modules/bootstrap/js/src/button.js | 72 + web/node_modules/bootstrap/js/src/carousel.js | 474 + web/node_modules/bootstrap/js/src/collapse.js | 297 + web/node_modules/bootstrap/js/src/dom/data.js | 55 + .../bootstrap/js/src/dom/event-handler.js | 317 + .../bootstrap/js/src/dom/manipulator.js | 71 + .../bootstrap/js/src/dom/selector-engine.js | 126 + web/node_modules/bootstrap/js/src/dropdown.js | 455 + web/node_modules/bootstrap/js/src/modal.js | 376 + .../bootstrap/js/src/offcanvas.js | 282 + web/node_modules/bootstrap/js/src/popover.js | 97 + .../bootstrap/js/src/scrollspy.js | 294 + web/node_modules/bootstrap/js/src/tab.js | 315 + web/node_modules/bootstrap/js/src/toast.js | 225 + web/node_modules/bootstrap/js/src/tooltip.js | 631 + .../bootstrap/js/src/util/backdrop.js | 149 + .../js/src/util/component-functions.js | 35 + .../bootstrap/js/src/util/config.js | 65 + .../bootstrap/js/src/util/focustrap.js | 115 + .../bootstrap/js/src/util/index.js | 306 + .../bootstrap/js/src/util/sanitizer.js | 114 + .../bootstrap/js/src/util/scrollbar.js | 114 + .../bootstrap/js/src/util/swipe.js | 146 + .../bootstrap/js/src/util/template-factory.js | 160 + web/node_modules/bootstrap/package.json | 184 + .../bootstrap/scss/_accordion.scss | 158 + web/node_modules/bootstrap/scss/_alert.scss | 68 + web/node_modules/bootstrap/scss/_badge.scss | 38 + .../bootstrap/scss/_breadcrumb.scss | 40 + .../bootstrap/scss/_button-group.scss | 142 + web/node_modules/bootstrap/scss/_buttons.scss | 207 + web/node_modules/bootstrap/scss/_card.scss | 239 + .../bootstrap/scss/_carousel.scss | 244 + web/node_modules/bootstrap/scss/_close.scss | 63 + .../bootstrap/scss/_containers.scss | 41 + .../bootstrap/scss/_dropdown.scss | 250 + web/node_modules/bootstrap/scss/_forms.scss | 9 + .../bootstrap/scss/_functions.scss | 302 + web/node_modules/bootstrap/scss/_grid.scss | 39 + web/node_modules/bootstrap/scss/_helpers.scss | 12 + web/node_modules/bootstrap/scss/_images.scss | 42 + .../bootstrap/scss/_list-group.scss | 197 + web/node_modules/bootstrap/scss/_maps.scss | 174 + web/node_modules/bootstrap/scss/_mixins.scss | 42 + web/node_modules/bootstrap/scss/_modal.scss | 237 + web/node_modules/bootstrap/scss/_nav.scss | 197 + web/node_modules/bootstrap/scss/_navbar.scss | 289 + .../bootstrap/scss/_offcanvas.scss | 146 + .../bootstrap/scss/_pagination.scss | 109 + .../bootstrap/scss/_placeholders.scss | 51 + web/node_modules/bootstrap/scss/_popover.scss | 196 + .../bootstrap/scss/_progress.scss | 68 + web/node_modules/bootstrap/scss/_reboot.scss | 611 + web/node_modules/bootstrap/scss/_root.scss | 187 + .../bootstrap/scss/_spinners.scss | 85 + web/node_modules/bootstrap/scss/_tables.scss | 171 + web/node_modules/bootstrap/scss/_toasts.scss | 73 + web/node_modules/bootstrap/scss/_tooltip.scss | 119 + .../bootstrap/scss/_transitions.scss | 27 + web/node_modules/bootstrap/scss/_type.scss | 106 + .../bootstrap/scss/_utilities.scss | 806 ++ .../bootstrap/scss/_variables-dark.scss | 87 + .../bootstrap/scss/_variables.scss | 1747 +++ .../bootstrap/scss/bootstrap-grid.scss | 62 + .../bootstrap/scss/bootstrap-reboot.scss | 10 + .../bootstrap/scss/bootstrap-utilities.scss | 19 + .../bootstrap/scss/bootstrap.scss | 52 + .../scss/forms/_floating-labels.scss | 95 + .../bootstrap/scss/forms/_form-check.scss | 189 + .../bootstrap/scss/forms/_form-control.scss | 214 + .../bootstrap/scss/forms/_form-range.scss | 91 + .../bootstrap/scss/forms/_form-select.scss | 80 + .../bootstrap/scss/forms/_form-text.scss | 11 + .../bootstrap/scss/forms/_input-group.scss | 132 + .../bootstrap/scss/forms/_labels.scss | 36 + .../bootstrap/scss/forms/_validation.scss | 12 + .../bootstrap/scss/helpers/_clearfix.scss | 3 + .../bootstrap/scss/helpers/_color-bg.scss | 7 + .../scss/helpers/_colored-links.scss | 30 + .../bootstrap/scss/helpers/_focus-ring.scss | 5 + .../bootstrap/scss/helpers/_icon-link.scss | 25 + .../bootstrap/scss/helpers/_position.scss | 36 + .../bootstrap/scss/helpers/_ratio.scss | 26 + .../bootstrap/scss/helpers/_stacks.scss | 15 + .../scss/helpers/_stretched-link.scss | 15 + .../scss/helpers/_text-truncation.scss | 7 + .../scss/helpers/_visually-hidden.scss | 8 + .../bootstrap/scss/helpers/_vr.scss | 8 + .../bootstrap/scss/mixins/_alert.scss | 18 + .../bootstrap/scss/mixins/_backdrop.scss | 14 + .../bootstrap/scss/mixins/_banner.scss | 7 + .../bootstrap/scss/mixins/_border-radius.scss | 78 + .../bootstrap/scss/mixins/_box-shadow.scss | 18 + .../bootstrap/scss/mixins/_breakpoints.scss | 127 + .../bootstrap/scss/mixins/_buttons.scss | 70 + .../bootstrap/scss/mixins/_caret.scss | 69 + .../bootstrap/scss/mixins/_clearfix.scss | 9 + .../bootstrap/scss/mixins/_color-mode.scss | 21 + .../bootstrap/scss/mixins/_color-scheme.scss | 7 + .../bootstrap/scss/mixins/_container.scss | 11 + .../bootstrap/scss/mixins/_deprecate.scss | 10 + .../bootstrap/scss/mixins/_forms.scss | 153 + .../bootstrap/scss/mixins/_gradients.scss | 47 + .../bootstrap/scss/mixins/_grid.scss | 151 + .../bootstrap/scss/mixins/_image.scss | 16 + .../bootstrap/scss/mixins/_list-group.scss | 26 + .../bootstrap/scss/mixins/_lists.scss | 7 + .../bootstrap/scss/mixins/_pagination.scss | 10 + .../bootstrap/scss/mixins/_reset-text.scss | 17 + .../bootstrap/scss/mixins/_resize.scss | 6 + .../scss/mixins/_table-variants.scss | 24 + .../bootstrap/scss/mixins/_text-truncate.scss | 8 + .../bootstrap/scss/mixins/_transition.scss | 26 + .../bootstrap/scss/mixins/_utilities.scss | 97 + .../scss/mixins/_visually-hidden.scss | 33 + .../bootstrap/scss/utilities/_api.scss | 47 + .../bootstrap/scss/vendor/_rfs.scss | 348 + web/package-lock.json | 40 + web/package.json | 5 + web/public/css/bootstrap.min.css | 6 + web/public/js/bootstrap.bundle.min.js | 7 + web/views/layout.erb | 103 + 509 files changed, 97162 insertions(+) create mode 100644 web/app.rb create mode 100644 web/index.html create mode 100644 web/node_modules/.package-lock.json create mode 100644 web/node_modules/@popperjs/core/LICENSE.md create mode 100644 web/node_modules/@popperjs/core/README.md create mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js create mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js.map create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js.map create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js.map create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js.map create mode 100644 web/node_modules/@popperjs/core/dist/esm/createPopper.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/contains.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getBoundingClientRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getClippingRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getCompositeRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getComputedStyle.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getDocumentElement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getDocumentRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getHTMLElementScroll.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getLayoutRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getNodeName.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getNodeScroll.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getOffsetParent.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getParentNode.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getScrollParent.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getViewportRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindow.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindowScroll.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindowScrollBarX.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/instanceOf.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isLayoutViewport.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isScrollParent.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isTableElement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/listScrollParents.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/enums.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/index.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/applyStyles.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/arrow.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/computeStyles.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/eventListeners.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/flip.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/hide.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/index.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/offset.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/popperOffsets.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/preventOverflow.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/popper-base.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/popper-lite.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/popper.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/types.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/computeAutoPlacement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/computeOffsets.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/debounce.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/detectOverflow.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/expandToHashMap.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getAltAxis.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getAltLen.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getBasePlacement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getFreshSideObject.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getMainAxisFromPlacement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getOppositePlacement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getOppositeVariationPlacement.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getVariation.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/math.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/mergeByName.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/mergePaddingObject.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/orderModifiers.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/rectToClientRect.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/uniqueBy.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/userAgent.js create mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/within.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.js.map create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js.flow create mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js.map create mode 100644 web/node_modules/@popperjs/core/index.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/createPopper.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/createPopper.js create mode 100644 web/node_modules/@popperjs/core/lib/createPopper.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js create mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/enums.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/enums.js create mode 100644 web/node_modules/@popperjs/core/lib/enums.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/index.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/index.js create mode 100644 web/node_modules/@popperjs/core/lib/index.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js create mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/popper-base.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/popper-base.js create mode 100644 web/node_modules/@popperjs/core/lib/popper-base.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.js create mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/popper.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/popper.js create mode 100644 web/node_modules/@popperjs/core/lib/popper.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/types.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/types.js create mode 100644 web/node_modules/@popperjs/core/lib/types.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/math.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/math.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/math.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.js.flow create mode 100644 web/node_modules/@popperjs/core/lib/utils/within.d.ts create mode 100644 web/node_modules/@popperjs/core/lib/utils/within.js create mode 100644 web/node_modules/@popperjs/core/lib/utils/within.js.flow create mode 100644 web/node_modules/@popperjs/core/package.json create mode 100644 web/node_modules/bootstrap/LICENSE create mode 100644 web/node_modules/bootstrap/README.md create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.min.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.css.map create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css create mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.js.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.js.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.min.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.min.js.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.js.map create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.min.js create mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.min.js.map create mode 100644 web/node_modules/bootstrap/js/dist/alert.js create mode 100644 web/node_modules/bootstrap/js/dist/alert.js.map create mode 100644 web/node_modules/bootstrap/js/dist/base-component.js create mode 100644 web/node_modules/bootstrap/js/dist/base-component.js.map create mode 100644 web/node_modules/bootstrap/js/dist/button.js create mode 100644 web/node_modules/bootstrap/js/dist/button.js.map create mode 100644 web/node_modules/bootstrap/js/dist/carousel.js create mode 100644 web/node_modules/bootstrap/js/dist/carousel.js.map create mode 100644 web/node_modules/bootstrap/js/dist/collapse.js create mode 100644 web/node_modules/bootstrap/js/dist/collapse.js.map create mode 100644 web/node_modules/bootstrap/js/dist/dom/data.js create mode 100644 web/node_modules/bootstrap/js/dist/dom/data.js.map create mode 100644 web/node_modules/bootstrap/js/dist/dom/event-handler.js create mode 100644 web/node_modules/bootstrap/js/dist/dom/event-handler.js.map create mode 100644 web/node_modules/bootstrap/js/dist/dom/manipulator.js create mode 100644 web/node_modules/bootstrap/js/dist/dom/manipulator.js.map create mode 100644 web/node_modules/bootstrap/js/dist/dom/selector-engine.js create mode 100644 web/node_modules/bootstrap/js/dist/dom/selector-engine.js.map create mode 100644 web/node_modules/bootstrap/js/dist/dropdown.js create mode 100644 web/node_modules/bootstrap/js/dist/dropdown.js.map create mode 100644 web/node_modules/bootstrap/js/dist/modal.js create mode 100644 web/node_modules/bootstrap/js/dist/modal.js.map create mode 100644 web/node_modules/bootstrap/js/dist/offcanvas.js create mode 100644 web/node_modules/bootstrap/js/dist/offcanvas.js.map create mode 100644 web/node_modules/bootstrap/js/dist/popover.js create mode 100644 web/node_modules/bootstrap/js/dist/popover.js.map create mode 100644 web/node_modules/bootstrap/js/dist/scrollspy.js create mode 100644 web/node_modules/bootstrap/js/dist/scrollspy.js.map create mode 100644 web/node_modules/bootstrap/js/dist/tab.js create mode 100644 web/node_modules/bootstrap/js/dist/tab.js.map create mode 100644 web/node_modules/bootstrap/js/dist/toast.js create mode 100644 web/node_modules/bootstrap/js/dist/toast.js.map create mode 100644 web/node_modules/bootstrap/js/dist/tooltip.js create mode 100644 web/node_modules/bootstrap/js/dist/tooltip.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/backdrop.js create mode 100644 web/node_modules/bootstrap/js/dist/util/backdrop.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/component-functions.js create mode 100644 web/node_modules/bootstrap/js/dist/util/component-functions.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/config.js create mode 100644 web/node_modules/bootstrap/js/dist/util/config.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/focustrap.js create mode 100644 web/node_modules/bootstrap/js/dist/util/focustrap.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/index.js create mode 100644 web/node_modules/bootstrap/js/dist/util/index.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/sanitizer.js create mode 100644 web/node_modules/bootstrap/js/dist/util/sanitizer.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/scrollbar.js create mode 100644 web/node_modules/bootstrap/js/dist/util/scrollbar.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/swipe.js create mode 100644 web/node_modules/bootstrap/js/dist/util/swipe.js.map create mode 100644 web/node_modules/bootstrap/js/dist/util/template-factory.js create mode 100644 web/node_modules/bootstrap/js/dist/util/template-factory.js.map create mode 100644 web/node_modules/bootstrap/js/index.esm.js create mode 100644 web/node_modules/bootstrap/js/index.umd.js create mode 100644 web/node_modules/bootstrap/js/src/alert.js create mode 100644 web/node_modules/bootstrap/js/src/base-component.js create mode 100644 web/node_modules/bootstrap/js/src/button.js create mode 100644 web/node_modules/bootstrap/js/src/carousel.js create mode 100644 web/node_modules/bootstrap/js/src/collapse.js create mode 100644 web/node_modules/bootstrap/js/src/dom/data.js create mode 100644 web/node_modules/bootstrap/js/src/dom/event-handler.js create mode 100644 web/node_modules/bootstrap/js/src/dom/manipulator.js create mode 100644 web/node_modules/bootstrap/js/src/dom/selector-engine.js create mode 100644 web/node_modules/bootstrap/js/src/dropdown.js create mode 100644 web/node_modules/bootstrap/js/src/modal.js create mode 100644 web/node_modules/bootstrap/js/src/offcanvas.js create mode 100644 web/node_modules/bootstrap/js/src/popover.js create mode 100644 web/node_modules/bootstrap/js/src/scrollspy.js create mode 100644 web/node_modules/bootstrap/js/src/tab.js create mode 100644 web/node_modules/bootstrap/js/src/toast.js create mode 100644 web/node_modules/bootstrap/js/src/tooltip.js create mode 100644 web/node_modules/bootstrap/js/src/util/backdrop.js create mode 100644 web/node_modules/bootstrap/js/src/util/component-functions.js create mode 100644 web/node_modules/bootstrap/js/src/util/config.js create mode 100644 web/node_modules/bootstrap/js/src/util/focustrap.js create mode 100644 web/node_modules/bootstrap/js/src/util/index.js create mode 100644 web/node_modules/bootstrap/js/src/util/sanitizer.js create mode 100644 web/node_modules/bootstrap/js/src/util/scrollbar.js create mode 100644 web/node_modules/bootstrap/js/src/util/swipe.js create mode 100644 web/node_modules/bootstrap/js/src/util/template-factory.js create mode 100644 web/node_modules/bootstrap/package.json create mode 100644 web/node_modules/bootstrap/scss/_accordion.scss create mode 100644 web/node_modules/bootstrap/scss/_alert.scss create mode 100644 web/node_modules/bootstrap/scss/_badge.scss create mode 100644 web/node_modules/bootstrap/scss/_breadcrumb.scss create mode 100644 web/node_modules/bootstrap/scss/_button-group.scss create mode 100644 web/node_modules/bootstrap/scss/_buttons.scss create mode 100644 web/node_modules/bootstrap/scss/_card.scss create mode 100644 web/node_modules/bootstrap/scss/_carousel.scss create mode 100644 web/node_modules/bootstrap/scss/_close.scss create mode 100644 web/node_modules/bootstrap/scss/_containers.scss create mode 100644 web/node_modules/bootstrap/scss/_dropdown.scss create mode 100644 web/node_modules/bootstrap/scss/_forms.scss create mode 100644 web/node_modules/bootstrap/scss/_functions.scss create mode 100644 web/node_modules/bootstrap/scss/_grid.scss create mode 100644 web/node_modules/bootstrap/scss/_helpers.scss create mode 100644 web/node_modules/bootstrap/scss/_images.scss create mode 100644 web/node_modules/bootstrap/scss/_list-group.scss create mode 100644 web/node_modules/bootstrap/scss/_maps.scss create mode 100644 web/node_modules/bootstrap/scss/_mixins.scss create mode 100644 web/node_modules/bootstrap/scss/_modal.scss create mode 100644 web/node_modules/bootstrap/scss/_nav.scss create mode 100644 web/node_modules/bootstrap/scss/_navbar.scss create mode 100644 web/node_modules/bootstrap/scss/_offcanvas.scss create mode 100644 web/node_modules/bootstrap/scss/_pagination.scss create mode 100644 web/node_modules/bootstrap/scss/_placeholders.scss create mode 100644 web/node_modules/bootstrap/scss/_popover.scss create mode 100644 web/node_modules/bootstrap/scss/_progress.scss create mode 100644 web/node_modules/bootstrap/scss/_reboot.scss create mode 100644 web/node_modules/bootstrap/scss/_root.scss create mode 100644 web/node_modules/bootstrap/scss/_spinners.scss create mode 100644 web/node_modules/bootstrap/scss/_tables.scss create mode 100644 web/node_modules/bootstrap/scss/_toasts.scss create mode 100644 web/node_modules/bootstrap/scss/_tooltip.scss create mode 100644 web/node_modules/bootstrap/scss/_transitions.scss create mode 100644 web/node_modules/bootstrap/scss/_type.scss create mode 100644 web/node_modules/bootstrap/scss/_utilities.scss create mode 100644 web/node_modules/bootstrap/scss/_variables-dark.scss create mode 100644 web/node_modules/bootstrap/scss/_variables.scss create mode 100644 web/node_modules/bootstrap/scss/bootstrap-grid.scss create mode 100644 web/node_modules/bootstrap/scss/bootstrap-reboot.scss create mode 100644 web/node_modules/bootstrap/scss/bootstrap-utilities.scss create mode 100644 web/node_modules/bootstrap/scss/bootstrap.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_floating-labels.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_form-check.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_form-control.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_form-range.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_form-select.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_form-text.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_input-group.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_labels.scss create mode 100644 web/node_modules/bootstrap/scss/forms/_validation.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_clearfix.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_color-bg.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_colored-links.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_focus-ring.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_icon-link.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_position.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_ratio.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_stacks.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_stretched-link.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_text-truncation.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_visually-hidden.scss create mode 100644 web/node_modules/bootstrap/scss/helpers/_vr.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_alert.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_backdrop.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_banner.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_border-radius.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_box-shadow.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_breakpoints.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_buttons.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_caret.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_clearfix.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_color-mode.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_color-scheme.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_container.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_deprecate.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_forms.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_gradients.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_grid.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_image.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_list-group.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_lists.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_pagination.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_reset-text.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_resize.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_table-variants.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_text-truncate.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_transition.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_utilities.scss create mode 100644 web/node_modules/bootstrap/scss/mixins/_visually-hidden.scss create mode 100644 web/node_modules/bootstrap/scss/utilities/_api.scss create mode 100644 web/node_modules/bootstrap/scss/vendor/_rfs.scss create mode 100644 web/package-lock.json create mode 100644 web/package.json create mode 100644 web/public/css/bootstrap.min.css create mode 100644 web/public/js/bootstrap.bundle.min.js create mode 100644 web/views/layout.erb diff --git a/Gemfile b/Gemfile index 052f995c..665d95cd 100644 --- a/Gemfile +++ b/Gemfile @@ -19,3 +19,9 @@ gem 'foreman', '~> 0.87.2' # group :test do # gem 'database_cleaner', '~> 2.0', '>= 2.0.2' # end + +# web +gem 'rackup', '~> 2.1' +gem 'sinatra', '~> 4.0' +gem 'puma', '~> 6.4', '>= 6.4.2' +gem 'kaminari', '~> 1.2', '>= 1.2.2' diff --git a/Gemfile.lock b/Gemfile.lock index 4b7a6da8..5828631c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,12 @@ PATH GEM remote: https://rubygems.org/ specs: + actionview (7.1.2) + activesupport (= 7.1.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) activemodel (7.1.2) activesupport (= 7.1.2) activerecord (7.1.2) @@ -26,10 +32,12 @@ GEM ast (2.4.2) base64 (0.2.0) bigdecimal (3.1.5) + builder (3.2.4) byebug (11.1.3) coderay (1.1.3) concurrent-ruby (1.2.2) connection_pool (2.4.1) + crass (1.0.6) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.1.0) @@ -40,14 +48,39 @@ GEM docile (1.4.0) drb (2.2.0) ruby2_keywords + erubi (1.12.0) foreman (0.87.2) i18n (1.14.1) concurrent-ruby (~> 1.0) json (2.6.3) + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) language_server-protocol (3.17.0.3) + loofah (2.22.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) method_source (1.0.0) minitest (5.20.0) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) mutex_m (0.2.0) + nio4r (2.7.0) + nokogiri (1.16.0-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.0-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.16.0-x86_64-linux) + racc (~> 1.4) parallel (1.23.0) parser (3.2.2.3) ast (~> 2.4.1) @@ -59,8 +92,25 @@ GEM pry-byebug (3.10.1) byebug (~> 11.0) pry (>= 0.13, < 0.15) + puma (6.4.2) + nio4r (~> 2.0) racc (1.7.1) rack (3.0.8) + rack-protection (4.0.0) + base64 (>= 0.1.0) + rack (>= 3.0.0, < 4) + rack-session (2.0.0) + rack (>= 3.0.0) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) rainbow (3.1.1) rake (13.0.6) redis-client (0.19.1) @@ -106,10 +156,18 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) + sinatra (4.0.0) + mustermann (~> 3.0) + rack (>= 3.0.0, < 4) + rack-protection (= 4.0.0) + rack-session (>= 2.0.0, < 3) + tilt (~> 2.0) + tilt (2.3.0) timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unicode-display_width (2.4.2) + webrick (1.8.1) yard (0.9.34) PLATFORMS @@ -121,14 +179,18 @@ DEPENDENCIES activerecord (~> 7.1, >= 7.1.2) database_cleaner (~> 2.0, >= 2.0.2) foreman (~> 0.87.2) + kaminari (~> 1.2, >= 1.2.2) outboxer! pg (~> 1.5) pry-byebug (~> 3.10) + puma (~> 6.4, >= 6.4.2) + rackup (~> 2.1) rake (~> 13.0) rspec rubocop (~> 1.55) sidekiq (~> 7.2) simplecov (~> 0.22.0) + sinatra (~> 4.0) yard (~> 0.9.34) BUNDLED WITH diff --git a/web/app.rb b/web/app.rb new file mode 100644 index 00000000..5c42a456 --- /dev/null +++ b/web/app.rb @@ -0,0 +1,33 @@ +require 'bundler/setup' +require 'outboxer' +require 'sinatra/base' +require 'kaminari' +require 'pry-byebug' + +environment = ENV['RAILS_ENV'] || 'development' +config = Outboxer::Database.config(environment: environment) +Outboxer::Database.connect!(config: config.merge('pool' => 5)) + +module Outboxer + class App < Sinatra::Base + get '/' do + page = params[:page] || 1 + limit = params[:limit] || 10 + sort = %w[id status outboxer_messageable_type outboxer_messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + messages = Models::Message.order(sort => order).page(page).per(limit) + + erb :layout, locals: { + messages: messages, + page: page, + limit: limit, + sort: sort, + order: order + } + end + end +end + +Outboxer::App.run! diff --git a/web/index.html b/web/index.html new file mode 100644 index 00000000..6eb4f8af --- /dev/null +++ b/web/index.html @@ -0,0 +1,71 @@ + + + + + + Web App + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IDStatusMessageable IDMessageable TypeCreated AtUpdated At
1unpublishedEvent12024-01-31 12:53:192024-01-31 12:53:19
+
+ + + + + diff --git a/web/node_modules/.package-lock.json b/web/node_modules/.package-lock.json new file mode 100644 index 00000000..62656757 --- /dev/null +++ b/web/node_modules/.package-lock.json @@ -0,0 +1,35 @@ +{ + "name": "outboxer", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + } + } +} diff --git a/web/node_modules/@popperjs/core/LICENSE.md b/web/node_modules/@popperjs/core/LICENSE.md new file mode 100644 index 00000000..0370c458 --- /dev/null +++ b/web/node_modules/@popperjs/core/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2019 Federico Zivolo + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/web/node_modules/@popperjs/core/README.md b/web/node_modules/@popperjs/core/README.md new file mode 100644 index 00000000..53be7b9d --- /dev/null +++ b/web/node_modules/@popperjs/core/README.md @@ -0,0 +1,376 @@ + +

+ Popper +

+ +
+

Tooltip & Popover Positioning Engine

+
+ +

+ + npm version + + + npm downloads per month (popper.js + @popperjs/core) + + + Rolling Versions + +

+ +
+ + +**Positioning tooltips and popovers is difficult. Popper is here to help!** + +Given an element, such as a button, and a tooltip element describing it, Popper +will automatically put the tooltip in the right place near the button. + +It will position _any_ UI element that "pops out" from the flow of your document +and floats near a target element. The most common example is a tooltip, but it +also includes popovers, drop-downs, and more. All of these can be generically +described as a "popper" element. + +## Demo + +[![Popper visualized](https://i.imgur.com/F7qWsmV.jpg)](https://popper.js.org) + +## Docs + +- [v2.x (latest)](https://popper.js.org/docs/v2/) +- [v1.x](https://popper.js.org/docs/v1/) + +We've created a +[Migration Guide](https://popper.js.org/docs/v2/migration-guide/) to help you +migrate from Popper 1 to Popper 2. + +To contribute to the Popper website and documentation, please visit the +[dedicated repository](https://github.com/popperjs/website). + +## Why not use pure CSS? + +- **Clipping and overflow issues**: Pure CSS poppers will not be prevented from + overflowing clipping boundaries, such as the viewport. It will get partially + cut off or overflows if it's near the edge since there is no dynamic + positioning logic. When using Popper, your popper will always be positioned in + the right place without needing manual adjustments. +- **No flipping**: CSS poppers will not flip to a different placement to fit + better in view if necessary. While you can manually adjust for the main axis + overflow, this feature cannot be achieved via CSS alone. Popper automatically + flips the tooltip to make it fit in view as best as possible for the user. +- **No virtual positioning**: CSS poppers cannot follow the mouse cursor or be + used as a context menu. Popper allows you to position your tooltip relative to + any coordinates you desire. +- **Slower development cycle**: When pure CSS is used to position popper + elements, the lack of dynamic positioning means they must be carefully placed + to consider overflow on all screen sizes. In reusable component libraries, + this means a developer can't just add the component anywhere on the page, + because these issues need to be considered and adjusted for every time. With + Popper, you can place your elements anywhere and they will be positioned + correctly, without needing to consider different screen sizes, layouts, etc. + This massively speeds up development time because this work is automatically + offloaded to Popper. +- **Lack of extensibility**: CSS poppers cannot be easily extended to fit any + arbitrary use case you may need to adjust for. Popper is built with + extensibility in mind. + +## Why Popper? + +With the CSS drawbacks out of the way, we now move on to Popper in the +JavaScript space itself. + +Naive JavaScript tooltip implementations usually have the following problems: + +- **Scrolling containers**: They don't ensure the tooltip stays with the + reference element while scrolling when inside any number of scrolling + containers. +- **DOM context**: They often require the tooltip move outside of its original + DOM context because they don't handle `offsetParent` contexts. +- **Compatibility**: Popper handles an incredible number of edge cases regarding + different browsers and environments (mobile viewports, RTL, scrollbars enabled + or disabled, etc.). Popper is a popular and well-maintained library, so you + can be confident positioning will work for your users on any device. +- **Configurability**: They often lack advanced configurability to suit any + possible use case. +- **Size**: They are usually relatively large in size, or require an ancient + jQuery dependency. +- **Performance**: They often have runtime performance issues and update the + tooltip position too slowly. + +**Popper solves all of these key problems in an elegant, performant manner.** It +is a lightweight ~3 kB library that aims to provide a reliable and extensible +positioning engine you can use to ensure all your popper elements are positioned +in the right place. + +When you start writing your own popper implementation, you'll quickly run into +all of the problems mentioned above. These widgets are incredibly common in our +UIs; we've done the hard work figuring this out so you don't need to spend hours +fixing and handling numerous edge cases that we already ran into while building +the library! + +Popper is used in popular libraries like Bootstrap, Foundation, Material UI, and +more. It's likely you've already used popper elements on the web positioned by +Popper at some point in the past few years. + +Since we write UIs using powerful abstraction libraries such as React or Angular +nowadays, you'll also be glad to know Popper can fully integrate with them and +be a good citizen together with your other components. Check out `react-popper` +for the official Popper wrapper for React. + +## Installation + +### 1. Package Manager + +```bash +# With npm +npm i @popperjs/core + +# With Yarn +yarn add @popperjs/core +``` + +### 2. CDN + +```html + + + + + +``` + +### 3. Direct Download? + +Managing dependencies by "directly downloading" them and placing them into your +source code is not recommended for a variety of reasons, including missing out +on feat/fix updates easily. Please use a versioning management system like a CDN +or npm/Yarn. + +## Usage + +The most straightforward way to get started is to import Popper from the `unpkg` +CDN, which includes all of its features. You can call the `Popper.createPopper` +constructor to create new popper instances. + +Here is a complete example: + +```html + +Popper example + + + + + + + + +``` + +Visit the [tutorial](https://popper.js.org/docs/v2/tutorial/) for an example of +how to build your own tooltip from scratch using Popper. + +### Module bundlers + +You can import the `createPopper` constructor from the fully-featured file: + +```js +import { createPopper } from '@popperjs/core'; + +const button = document.querySelector('#button'); +const tooltip = document.querySelector('#tooltip'); + +// Pass the button, the tooltip, and some options, and Popper will do the +// magic positioning for you: +createPopper(button, tooltip, { + placement: 'right', +}); +``` + +All the modifiers listed in the docs menu will be enabled and "just work", so +you don't need to think about setting Popper up. The size of Popper including +all of its features is about 5 kB minzipped, but it may grow a bit in the +future. + +#### Popper Lite (tree-shaking) + +If bundle size is important, you'll want to take advantage of tree-shaking. The +library is built in a modular way to allow to import only the parts you really +need. + +```js +import { createPopperLite as createPopper } from '@popperjs/core'; +``` + +The Lite version includes the most necessary modifiers that will compute the +offsets of the popper, compute and add the positioning styles, and add event +listeners. This is close in bundle size to pure CSS tooltip libraries, and +behaves somewhat similarly. + +However, this does not include the features that makes Popper truly useful. + +The two most useful modifiers not included in Lite are `preventOverflow` and +`flip`: + +```js +import { + createPopperLite as createPopper, + preventOverflow, + flip, +} from '@popperjs/core'; + +const button = document.querySelector('#button'); +const tooltip = document.querySelector('#tooltip'); + +createPopper(button, tooltip, { + modifiers: [preventOverflow, flip], +}); +``` + +As you make more poppers, you may be finding yourself needing other modifiers +provided by the library. + +See [tree-shaking](https://popper.js.org/docs/v2/performance/#tree-shaking) for more +information. + +## Distribution targets + +Popper is distributed in 3 different versions, in 3 different file formats. + +The 3 file formats are: + +- `esm` (works with `import` syntax — **recommended**) +- `umd` (works with ` + + From f75bbd62ffc6e0279f95e6597ae21a530e553123 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Wed, 7 Feb 2024 13:17:15 +0700 Subject: [PATCH 02/79] update ui --- bin/sidekiq_publisher | 3 +- db/seeds.rb | 44 ++++++++++++---- web/app.rb | 31 +++++++++-- web/views/layout.erb | 99 ++++++++++++------------------------ web/views/messages/index.erb | 60 ++++++++++++++++++++++ web/views/messages/show.erb | 32 ++++++++++++ 6 files changed, 188 insertions(+), 81 deletions(-) create mode 100644 web/views/messages/index.erb create mode 100644 web/views/messages/show.erb diff --git a/bin/sidekiq_publisher b/bin/sidekiq_publisher index f481cc23..a5b32110 100755 --- a/bin/sidekiq_publisher +++ b/bin/sidekiq_publisher @@ -21,8 +21,7 @@ config = Outboxer::Database.config(environment: environment) Outboxer::Database.connect!(config: config.merge('pool' => concurrency + 1)) Outboxer::Publisher.publish!( - thread_count: concurrency, queue_size: concurrency * 2, poll_interval: 1, - logger: logger + thread_count: concurrency, queue_size: concurrency * 2, poll_interval: 1, logger: logger ) do |outboxer_message| case outboxer_message.outboxer_messageable_type when 'Event' diff --git a/db/seeds.rb b/db/seeds.rb index 1d1f050a..389463a7 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,13 +1,39 @@ -require_relative '../app/models/invoice' -require_relative '../app/models/event' +# require_relative '../app/models/message' +# require_relative '../app/models/outboxer_exception' -loop do - 100.times do |_i| - invoice = Invoice.create! - event = invoice.events.create!(type: 'Invoice.created') +100.times do |i| + messageable_type = 'Event' + messageable_id = 1 - puts "Invoice##{invoice.id} - #{event.type} event #{event.id}" - end + Outboxer::Models::Message + .create!( + outboxer_messageable_type: messageable_type, + outboxer_messageable_id: messageable_id, + status: Outboxer::Models::Message::STATUS[:unpublished]) - sleep 5 + Outboxer::Models::Message + .create!( + outboxer_messageable_type: messageable_type, + outboxer_messageable_id: messageable_id, + status: Outboxer::Models::Message::STATUS[:publishing]) + + failed_message = Outboxer::Models::Message + .create!( + outboxer_messageable_type: messageable_type, + outboxer_messageable_id: messageable_id, + status: Outboxer::Models::Message::STATUS[:failed]) + + failed_message + .outboxer_exceptions + .create!( + class_name: 'StandardError', + message_text: 'Sample error message', + backtrace: ['Sample backtrace line 1', 'Sample backtrace line 2']) + + failed_message + .outboxer_exceptions + .create!( + class_name: 'StandardError', + message_text: 'Sample error message', + backtrace: ['Sample backtrace line 1', 'Sample backtrace line 2']) end diff --git a/web/app.rb b/web/app.rb index 5c42a456..5f3418ce 100644 --- a/web/app.rb +++ b/web/app.rb @@ -11,15 +11,40 @@ module Outboxer class App < Sinatra::Base get '/' do + redirect to('/all') + end + + get '/messages/:id' do |id| + messages_count = Models::Message.count + + message = Models::Message.includes(:outboxer_exceptions).find(id) + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) + + erb :'messages/show', locals: { + status_counts: status_counts, + messages_count: messages_count, + message: message + } + end + + get '/:status' do |status| page = params[:page] || 1 - limit = params[:limit] || 10 + limit = params[:limit] || 100 sort = %w[id status outboxer_messageable_type outboxer_messageable_id created_at updated_at] .include?(params[:sort]) ? params[:sort].to_sym : :created_at order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc - messages = Models::Message.order(sort => order).page(page).per(limit) + messages_scope = status == 'all' ? Models::Message : Models::Message.where(status: status) + messages = messages_scope.order(sort => order).page(page).per(limit) + messages_count = Models::Message.count + + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) - erb :layout, locals: { + erb :'messages/index', locals: { + status_counts: status_counts, + messages_count: messages_count, messages: messages, page: page, limit: limit, diff --git a/web/views/layout.erb b/web/views/layout.erb index 8371eeb6..88dd0e77 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -16,6 +16,20 @@ .table-container { margin-top: 30px; } + /* Style for pagination controls */ + .pagination { + flex-wrap: wrap; /* Allows pagination items to wrap */ + } + .pagination .page-item { + margin-bottom: 5px; /* Adds spacing between wrapped lines */ + } + .clickable-row { + cursor: pointer; + } + + .clickable-row:hover { + background-color: #f5f5f5; /* Light gray background on hover */ + } @@ -24,80 +38,31 @@
- -
- - - - <% - headers = { - 'Id' => 'id', - 'Status' => 'status', - 'Messageable Type' => 'outboxer_messageable_type', - 'Messageable Id' => 'outboxer_messageable_id', - 'Created At' => 'created_at', - 'Updated At' => 'updated_at' - } - headers.each do |display, col| - %> - - <% end %> - - - - <% messages.each do |message| %> - - - - - - - - - <% end %> - -
- - <%= display %> - <% if sort.to_s == col %> - <%= order == :asc ? '▲' : '▼' %> - <% end %> - -
<%= message.id %><%= message.status %><%= message.outboxer_messageable_id %><%= message.outboxer_messageable_type %><%= message.created_at %><%= message.updated_at %>
-
- - -
- -
+ <%= yield %>> + diff --git a/web/views/messages/index.erb b/web/views/messages/index.erb new file mode 100644 index 00000000..980199d9 --- /dev/null +++ b/web/views/messages/index.erb @@ -0,0 +1,60 @@ + +
+ + + + <% + headers = { + 'Id' => 'id', + 'Messageable Type' => 'outboxer_messageable_type', + 'Messageable Id' => 'outboxer_messageable_id', + 'Status' => 'status', + 'Created At' => 'created_at', + 'Updated At' => 'updated_at' + } + headers.each do |display, col| + %> + + <% end %> + + + + <% messages.each do |message| %> + + + + + + + + + <% end %> + +
+ + <%= display %> + <% if sort.to_s == col %> + <%= order == :asc ? '▲' : '▼' %> + <% end %> + +
<%= message.id %><%= message.outboxer_messageable_type %><%= message.outboxer_messageable_id %><%= message.status %><%= message.created_at %><%= message.updated_at %>
+
+ + +
+ +
diff --git a/web/views/messages/show.erb b/web/views/messages/show.erb new file mode 100644 index 00000000..0fcb11b7 --- /dev/null +++ b/web/views/messages/show.erb @@ -0,0 +1,32 @@ +
+

Message Details

+ +
+
+
Message Info
+

ID: <%= message.id %>

+

Status: <%= message.status %>

+

Messageable Type: <%= message.outboxer_messageable_type %>

+

Messageable ID: <%= message.outboxer_messageable_id %>

+

Created At: <%= message.created_at %>

+

Updated At: <%= message.updated_at %>

+
+
+ + <% if message.outboxer_exceptions.any? %> +
+
+
Exceptions
+
    + <% message.outboxer_exceptions.each do |exception| %> +
  • +

    Class Name: <%= exception.class_name %>

    +

    Message: <%= exception.message_text %>

    +

    Backtrace:

    <%= exception.backtrace.join("\n") %>

    +
  • + <% end %> +
+
+
+ <% end %> +
From 7d5f74cf4ea04282c5d82f8a1976d70b9bce8806 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Wed, 7 Feb 2024 13:20:30 +0700 Subject: [PATCH 03/79] don't track web/node_modules --- .gitignore | 2 + web/node_modules/.package-lock.json | 35 - web/node_modules/@popperjs/core/LICENSE.md | 20 - web/node_modules/@popperjs/core/README.md | 376 - .../@popperjs/core/dist/cjs/enums.js | 65 - .../@popperjs/core/dist/cjs/enums.js.flow | 3 - .../@popperjs/core/dist/cjs/enums.js.map | 1 - .../@popperjs/core/dist/cjs/popper-base.js | 939 -- .../core/dist/cjs/popper-base.js.flow | 3 - .../core/dist/cjs/popper-base.js.map | 1 - .../@popperjs/core/dist/cjs/popper-lite.js | 1260 -- .../core/dist/cjs/popper-lite.js.flow | 3 - .../core/dist/cjs/popper-lite.js.map | 1 - .../@popperjs/core/dist/cjs/popper.js | 1819 --- .../@popperjs/core/dist/cjs/popper.js.flow | 3 - .../@popperjs/core/dist/cjs/popper.js.map | 1 - .../@popperjs/core/dist/esm/createPopper.js | 199 - .../core/dist/esm/dom-utils/contains.js | 23 - .../esm/dom-utils/getBoundingClientRect.js | 41 - .../dist/esm/dom-utils/getClippingRect.js | 70 - .../dist/esm/dom-utils/getCompositeRect.js | 58 - .../dist/esm/dom-utils/getComputedStyle.js | 4 - .../dist/esm/dom-utils/getDocumentElement.js | 6 - .../dist/esm/dom-utils/getDocumentRect.js | 29 - .../esm/dom-utils/getHTMLElementScroll.js | 6 - .../core/dist/esm/dom-utils/getLayoutRect.js | 25 - .../core/dist/esm/dom-utils/getNodeName.js | 3 - .../core/dist/esm/dom-utils/getNodeScroll.js | 11 - .../dist/esm/dom-utils/getOffsetParent.js | 69 - .../core/dist/esm/dom-utils/getParentNode.js | 19 - .../dist/esm/dom-utils/getScrollParent.js | 16 - .../dist/esm/dom-utils/getViewportRect.js | 31 - .../core/dist/esm/dom-utils/getWindow.js | 12 - .../dist/esm/dom-utils/getWindowScroll.js | 10 - .../dist/esm/dom-utils/getWindowScrollBarX.js | 13 - .../core/dist/esm/dom-utils/instanceOf.js | 23 - .../dist/esm/dom-utils/isLayoutViewport.js | 4 - .../core/dist/esm/dom-utils/isScrollParent.js | 10 - .../core/dist/esm/dom-utils/isTableElement.js | 4 - .../dist/esm/dom-utils/listScrollParents.js | 26 - .../@popperjs/core/dist/esm/enums.js | 31 - .../@popperjs/core/dist/esm/index.js | 8 - .../core/dist/esm/modifiers/applyStyles.js | 84 - .../core/dist/esm/modifiers/arrow.js | 90 - .../core/dist/esm/modifiers/computeStyles.js | 169 - .../core/dist/esm/modifiers/eventListeners.js | 49 - .../@popperjs/core/dist/esm/modifiers/flip.js | 147 - .../@popperjs/core/dist/esm/modifiers/hide.js | 61 - .../core/dist/esm/modifiers/index.js | 9 - .../core/dist/esm/modifiers/offset.js | 54 - .../core/dist/esm/modifiers/popperOffsets.js | 25 - .../dist/esm/modifiers/preventOverflow.js | 142 - .../@popperjs/core/dist/esm/popper-base.js | 3 - .../@popperjs/core/dist/esm/popper-lite.js | 11 - .../@popperjs/core/dist/esm/popper.js | 20 - .../@popperjs/core/dist/esm/types.js | 0 .../dist/esm/utils/computeAutoPlacement.js | 43 - .../core/dist/esm/utils/computeOffsets.js | 70 - .../@popperjs/core/dist/esm/utils/debounce.js | 15 - .../core/dist/esm/utils/detectOverflow.js | 65 - .../core/dist/esm/utils/expandToHashMap.js | 6 - .../core/dist/esm/utils/getAltAxis.js | 3 - .../core/dist/esm/utils/getAltLen.js | 3 - .../core/dist/esm/utils/getBasePlacement.js | 4 - .../core/dist/esm/utils/getFreshSideObject.js | 8 - .../esm/utils/getMainAxisFromPlacement.js | 3 - .../dist/esm/utils/getOppositePlacement.js | 11 - .../utils/getOppositeVariationPlacement.js | 9 - .../core/dist/esm/utils/getVariation.js | 3 - .../@popperjs/core/dist/esm/utils/math.js | 3 - .../core/dist/esm/utils/mergeByName.js | 14 - .../core/dist/esm/utils/mergePaddingObject.js | 4 - .../core/dist/esm/utils/orderModifiers.js | 44 - .../core/dist/esm/utils/rectToClientRect.js | 8 - .../@popperjs/core/dist/esm/utils/uniqueBy.js | 11 - .../core/dist/esm/utils/userAgent.js | 11 - .../@popperjs/core/dist/esm/utils/within.js | 8 - .../@popperjs/core/dist/umd/enums.js | 71 - .../@popperjs/core/dist/umd/enums.js.map | 1 - .../@popperjs/core/dist/umd/enums.min.js | 6 - .../@popperjs/core/dist/umd/enums.min.js.flow | 3 - .../@popperjs/core/dist/umd/enums.min.js.map | 1 - .../@popperjs/core/dist/umd/popper-base.js | 945 -- .../core/dist/umd/popper-base.js.map | 1 - .../core/dist/umd/popper-base.min.js | 6 - .../core/dist/umd/popper-base.min.js.flow | 3 - .../core/dist/umd/popper-base.min.js.map | 1 - .../@popperjs/core/dist/umd/popper-lite.js | 1266 -- .../core/dist/umd/popper-lite.js.map | 1 - .../core/dist/umd/popper-lite.min.js | 6 - .../core/dist/umd/popper-lite.min.js.flow | 3 - .../core/dist/umd/popper-lite.min.js.map | 1 - .../@popperjs/core/dist/umd/popper.js | 1825 --- .../@popperjs/core/dist/umd/popper.js.map | 1 - .../@popperjs/core/dist/umd/popper.min.js | 6 - .../core/dist/umd/popper.min.js.flow | 3 - .../@popperjs/core/dist/umd/popper.min.js.map | 1 - web/node_modules/@popperjs/core/index.d.ts | 1 - .../@popperjs/core/lib/createPopper.d.ts | 9 - .../@popperjs/core/lib/createPopper.js | 199 - .../@popperjs/core/lib/createPopper.js.flow | 218 - .../core/lib/dom-utils/contains.d.ts | 1 - .../@popperjs/core/lib/dom-utils/contains.js | 23 - .../core/lib/dom-utils/contains.js.flow | 25 - .../lib/dom-utils/getBoundingClientRect.d.ts | 2 - .../lib/dom-utils/getBoundingClientRect.js | 41 - .../dom-utils/getBoundingClientRect.js.flow | 52 - .../core/lib/dom-utils/getClippingRect.d.ts | 3 - .../core/lib/dom-utils/getClippingRect.js | 70 - .../lib/dom-utils/getClippingRect.js.flow | 106 - .../core/lib/dom-utils/getCompositeRect.d.ts | 2 - .../core/lib/dom-utils/getCompositeRect.js | 58 - .../lib/dom-utils/getCompositeRect.js.flow | 64 - .../core/lib/dom-utils/getComputedStyle.d.ts | 1 - .../core/lib/dom-utils/getComputedStyle.js | 4 - .../lib/dom-utils/getComputedStyle.js.flow | 8 - .../lib/dom-utils/getDocumentElement.d.ts | 2 - .../core/lib/dom-utils/getDocumentElement.js | 6 - .../lib/dom-utils/getDocumentElement.js.flow | 15 - .../core/lib/dom-utils/getDocumentRect.d.ts | 2 - .../core/lib/dom-utils/getDocumentRect.js | 29 - .../lib/dom-utils/getDocumentRect.js.flow | 37 - .../lib/dom-utils/getHTMLElementScroll.d.ts | 4 - .../lib/dom-utils/getHTMLElementScroll.js | 6 - .../dom-utils/getHTMLElementScroll.js.flow | 8 - .../core/lib/dom-utils/getLayoutRect.d.ts | 2 - .../core/lib/dom-utils/getLayoutRect.js | 25 - .../core/lib/dom-utils/getLayoutRect.js.flow | 29 - .../core/lib/dom-utils/getNodeName.d.ts | 2 - .../core/lib/dom-utils/getNodeName.js | 3 - .../core/lib/dom-utils/getNodeName.js.flow | 6 - .../core/lib/dom-utils/getNodeScroll.d.ts | 5 - .../core/lib/dom-utils/getNodeScroll.js | 11 - .../core/lib/dom-utils/getNodeScroll.js.flow | 14 - .../core/lib/dom-utils/getOffsetParent.d.ts | 1 - .../core/lib/dom-utils/getOffsetParent.js | 69 - .../lib/dom-utils/getOffsetParent.js.flow | 93 - .../core/lib/dom-utils/getParentNode.d.ts | 1 - .../core/lib/dom-utils/getParentNode.js | 19 - .../core/lib/dom-utils/getParentNode.js.flow | 21 - .../core/lib/dom-utils/getScrollParent.d.ts | 1 - .../core/lib/dom-utils/getScrollParent.js | 16 - .../lib/dom-utils/getScrollParent.js.flow | 18 - .../core/lib/dom-utils/getViewportRect.d.ts | 7 - .../core/lib/dom-utils/getViewportRect.js | 31 - .../lib/dom-utils/getViewportRect.js.flow | 39 - .../core/lib/dom-utils/getWindow.d.ts | 1 - .../@popperjs/core/lib/dom-utils/getWindow.js | 12 - .../core/lib/dom-utils/getWindow.js.flow | 16 - .../core/lib/dom-utils/getWindowScroll.d.ts | 5 - .../core/lib/dom-utils/getWindowScroll.js | 10 - .../lib/dom-utils/getWindowScroll.js.flow | 14 - .../lib/dom-utils/getWindowScrollBarX.d.ts | 1 - .../core/lib/dom-utils/getWindowScrollBarX.js | 13 - .../lib/dom-utils/getWindowScrollBarX.js.flow | 18 - .../core/lib/dom-utils/instanceOf.d.ts | 4 - .../core/lib/dom-utils/instanceOf.js | 23 - .../core/lib/dom-utils/instanceOf.js.flow | 29 - .../core/lib/dom-utils/isLayoutViewport.d.ts | 1 - .../core/lib/dom-utils/isLayoutViewport.js | 4 - .../lib/dom-utils/isLayoutViewport.js.flow | 6 - .../core/lib/dom-utils/isScrollParent.d.ts | 1 - .../core/lib/dom-utils/isScrollParent.js | 10 - .../core/lib/dom-utils/isScrollParent.js.flow | 8 - .../core/lib/dom-utils/isTableElement.d.ts | 1 - .../core/lib/dom-utils/isTableElement.js | 4 - .../core/lib/dom-utils/isTableElement.js.flow | 6 - .../core/lib/dom-utils/listScrollParents.d.ts | 2 - .../core/lib/dom-utils/listScrollParents.js | 26 - .../lib/dom-utils/listScrollParents.js.flow | 33 - .../@popperjs/core/lib/enums.d.ts | 34 - web/node_modules/@popperjs/core/lib/enums.js | 31 - .../@popperjs/core/lib/enums.js.flow | 91 - .../@popperjs/core/lib/index.d.ts | 6 - web/node_modules/@popperjs/core/lib/index.js | 8 - .../@popperjs/core/lib/index.js.flow | 13 - .../core/lib/modifiers/applyStyles.d.ts | 4 - .../core/lib/modifiers/applyStyles.js | 84 - .../core/lib/modifiers/applyStyles.js.flow | 98 - .../@popperjs/core/lib/modifiers/arrow.d.ts | 13 - .../@popperjs/core/lib/modifiers/arrow.js | 90 - .../core/lib/modifiers/arrow.js.flow | 120 - .../core/lib/modifiers/computeStyles.d.ts | 38 - .../core/lib/modifiers/computeStyles.js | 169 - .../core/lib/modifiers/computeStyles.js.flow | 233 - .../core/lib/modifiers/eventListeners.d.ts | 8 - .../core/lib/modifiers/eventListeners.js | 49 - .../core/lib/modifiers/eventListeners.js.flow | 54 - .../@popperjs/core/lib/modifiers/flip.d.ts | 16 - .../@popperjs/core/lib/modifiers/flip.js | 147 - .../@popperjs/core/lib/modifiers/flip.js.flow | 177 - .../@popperjs/core/lib/modifiers/hide.d.ts | 4 - .../@popperjs/core/lib/modifiers/hide.js | 61 - .../@popperjs/core/lib/modifiers/hide.js.flow | 76 - .../@popperjs/core/lib/modifiers/index.d.ts | 9 - .../@popperjs/core/lib/modifiers/index.js | 9 - .../core/lib/modifiers/index.js.flow | 10 - .../@popperjs/core/lib/modifiers/offset.d.ts | 18 - .../@popperjs/core/lib/modifiers/offset.js | 54 - .../core/lib/modifiers/offset.js.flow | 71 - .../core/lib/modifiers/popperOffsets.d.ts | 4 - .../core/lib/modifiers/popperOffsets.js | 25 - .../core/lib/modifiers/popperOffsets.js.flow | 26 - .../core/lib/modifiers/preventOverflow.d.ts | 30 - .../core/lib/modifiers/preventOverflow.js | 142 - .../lib/modifiers/preventOverflow.js.flow | 220 - .../@popperjs/core/lib/popper-base.d.ts | 3 - .../@popperjs/core/lib/popper-base.js | 3 - .../@popperjs/core/lib/popper-base.js.flow | 7 - .../@popperjs/core/lib/popper-lite.d.ts | 5 - .../@popperjs/core/lib/popper-lite.js | 11 - .../@popperjs/core/lib/popper-lite.js.flow | 21 - .../@popperjs/core/lib/popper.d.ts | 7 - web/node_modules/@popperjs/core/lib/popper.js | 20 - .../@popperjs/core/lib/popper.js.flow | 35 - .../@popperjs/core/lib/types.d.ts | 167 - web/node_modules/@popperjs/core/lib/types.js | 0 .../@popperjs/core/lib/types.js.flow | 199 - .../core/lib/utils/computeAutoPlacement.d.ts | 12 - .../core/lib/utils/computeAutoPlacement.js | 43 - .../lib/utils/computeAutoPlacement.js.flow | 73 - .../core/lib/utils/computeOffsets.d.ts | 8 - .../core/lib/utils/computeOffsets.js | 70 - .../core/lib/utils/computeOffsets.js.flow | 82 - .../@popperjs/core/lib/utils/debounce.d.ts | 1 - .../@popperjs/core/lib/utils/debounce.js | 15 - .../@popperjs/core/lib/utils/debounce.js.flow | 17 - .../core/lib/utils/detectOverflow.d.ts | 12 - .../core/lib/utils/detectOverflow.js | 65 - .../core/lib/utils/detectOverflow.js.flow | 112 - .../core/lib/utils/expandToHashMap.d.ts | 3 - .../core/lib/utils/expandToHashMap.js | 6 - .../core/lib/utils/expandToHashMap.js.flow | 11 - .../@popperjs/core/lib/utils/getAltAxis.d.ts | 1 - .../@popperjs/core/lib/utils/getAltAxis.js | 3 - .../core/lib/utils/getAltAxis.js.flow | 5 - .../@popperjs/core/lib/utils/getAltLen.d.ts | 1 - .../@popperjs/core/lib/utils/getAltLen.js | 3 - .../core/lib/utils/getAltLen.js.flow | 5 - .../core/lib/utils/getBasePlacement.d.ts | 2 - .../core/lib/utils/getBasePlacement.js | 4 - .../core/lib/utils/getBasePlacement.js.flow | 8 - .../core/lib/utils/getFreshSideObject.d.ts | 2 - .../core/lib/utils/getFreshSideObject.js | 8 - .../core/lib/utils/getFreshSideObject.js.flow | 11 - .../lib/utils/getMainAxisFromPlacement.d.ts | 2 - .../lib/utils/getMainAxisFromPlacement.js | 3 - .../utils/getMainAxisFromPlacement.js.flow | 8 - .../core/lib/utils/getOppositePlacement.d.ts | 2 - .../core/lib/utils/getOppositePlacement.js | 11 - .../lib/utils/getOppositePlacement.js.flow | 11 - .../utils/getOppositeVariationPlacement.d.ts | 2 - .../utils/getOppositeVariationPlacement.js | 9 - .../getOppositeVariationPlacement.js.flow | 10 - .../core/lib/utils/getVariation.d.ts | 2 - .../@popperjs/core/lib/utils/getVariation.js | 3 - .../core/lib/utils/getVariation.js.flow | 6 - .../@popperjs/core/lib/utils/math.d.ts | 3 - .../@popperjs/core/lib/utils/math.js | 3 - .../@popperjs/core/lib/utils/math.js.flow | 4 - .../@popperjs/core/lib/utils/mergeByName.d.ts | 2 - .../@popperjs/core/lib/utils/mergeByName.js | 14 - .../core/lib/utils/mergeByName.js.flow | 22 - .../core/lib/utils/mergePaddingObject.d.ts | 2 - .../core/lib/utils/mergePaddingObject.js | 4 - .../core/lib/utils/mergePaddingObject.js.flow | 12 - .../core/lib/utils/orderModifiers.d.ts | 2 - .../core/lib/utils/orderModifiers.js | 44 - .../core/lib/utils/orderModifiers.js.flow | 59 - .../core/lib/utils/rectToClientRect.d.ts | 2 - .../core/lib/utils/rectToClientRect.js | 8 - .../core/lib/utils/rectToClientRect.js.flow | 12 - .../@popperjs/core/lib/utils/uniqueBy.d.ts | 1 - .../@popperjs/core/lib/utils/uniqueBy.js | 11 - .../@popperjs/core/lib/utils/uniqueBy.js.flow | 14 - .../@popperjs/core/lib/utils/userAgent.d.ts | 1 - .../@popperjs/core/lib/utils/userAgent.js | 11 - .../core/lib/utils/userAgent.js.flow | 20 - .../@popperjs/core/lib/utils/within.d.ts | 2 - .../@popperjs/core/lib/utils/within.js | 8 - .../@popperjs/core/lib/utils/within.js.flow | 11 - web/node_modules/@popperjs/core/package.json | 119 - web/node_modules/bootstrap/LICENSE | 21 - web/node_modules/bootstrap/README.md | 246 - .../bootstrap/dist/css/bootstrap-grid.css | 4085 ------ .../bootstrap/dist/css/bootstrap-grid.css.map | 1 - .../bootstrap/dist/css/bootstrap-grid.min.css | 6 - .../dist/css/bootstrap-grid.min.css.map | 1 - .../bootstrap/dist/css/bootstrap-grid.rtl.css | 4084 ------ .../dist/css/bootstrap-grid.rtl.css.map | 1 - .../dist/css/bootstrap-grid.rtl.min.css | 6 - .../dist/css/bootstrap-grid.rtl.min.css.map | 1 - .../bootstrap/dist/css/bootstrap-reboot.css | 597 - .../dist/css/bootstrap-reboot.css.map | 1 - .../dist/css/bootstrap-reboot.min.css | 6 - .../dist/css/bootstrap-reboot.min.css.map | 1 - .../dist/css/bootstrap-reboot.rtl.css | 594 - .../dist/css/bootstrap-reboot.rtl.css.map | 1 - .../dist/css/bootstrap-reboot.rtl.min.css | 6 - .../dist/css/bootstrap-reboot.rtl.min.css.map | 1 - .../dist/css/bootstrap-utilities.css | 5402 ------- .../dist/css/bootstrap-utilities.css.map | 1 - .../dist/css/bootstrap-utilities.min.css | 6 - .../dist/css/bootstrap-utilities.min.css.map | 1 - .../dist/css/bootstrap-utilities.rtl.css | 5393 ------- .../dist/css/bootstrap-utilities.rtl.css.map | 1 - .../dist/css/bootstrap-utilities.rtl.min.css | 6 - .../css/bootstrap-utilities.rtl.min.css.map | 1 - .../bootstrap/dist/css/bootstrap.css | 12068 ---------------- .../bootstrap/dist/css/bootstrap.css.map | 1 - .../bootstrap/dist/css/bootstrap.min.css | 6 - .../bootstrap/dist/css/bootstrap.min.css.map | 1 - .../bootstrap/dist/css/bootstrap.rtl.css | 12032 --------------- .../bootstrap/dist/css/bootstrap.rtl.css.map | 1 - .../bootstrap/dist/css/bootstrap.rtl.min.css | 6 - .../dist/css/bootstrap.rtl.min.css.map | 1 - .../bootstrap/dist/js/bootstrap.bundle.js | 6314 -------- .../bootstrap/dist/js/bootstrap.bundle.js.map | 1 - .../bootstrap/dist/js/bootstrap.bundle.min.js | 7 - .../dist/js/bootstrap.bundle.min.js.map | 1 - .../bootstrap/dist/js/bootstrap.esm.js | 4447 ------ .../bootstrap/dist/js/bootstrap.esm.js.map | 1 - .../bootstrap/dist/js/bootstrap.esm.min.js | 7 - .../dist/js/bootstrap.esm.min.js.map | 1 - .../bootstrap/dist/js/bootstrap.js | 4494 ------ .../bootstrap/dist/js/bootstrap.js.map | 1 - .../bootstrap/dist/js/bootstrap.min.js | 7 - .../bootstrap/dist/js/bootstrap.min.js.map | 1 - web/node_modules/bootstrap/js/dist/alert.js | 90 - .../bootstrap/js/dist/alert.js.map | 1 - .../bootstrap/js/dist/base-component.js | 84 - .../bootstrap/js/dist/base-component.js.map | 1 - web/node_modules/bootstrap/js/dist/button.js | 79 - .../bootstrap/js/dist/button.js.map | 1 - .../bootstrap/js/dist/carousel.js | 388 - .../bootstrap/js/dist/carousel.js.map | 1 - .../bootstrap/js/dist/collapse.js | 249 - .../bootstrap/js/dist/collapse.js.map | 1 - .../bootstrap/js/dist/dom/data.js | 63 - .../bootstrap/js/dist/dom/data.js.map | 1 - .../bootstrap/js/dist/dom/event-handler.js | 237 - .../js/dist/dom/event-handler.js.map | 1 - .../bootstrap/js/dist/dom/manipulator.js | 72 - .../bootstrap/js/dist/dom/manipulator.js.map | 1 - .../bootstrap/js/dist/dom/selector-engine.js | 104 - .../js/dist/dom/selector-engine.js.map | 1 - .../bootstrap/js/dist/dropdown.js | 402 - .../bootstrap/js/dist/dropdown.js.map | 1 - web/node_modules/bootstrap/js/dist/modal.js | 320 - .../bootstrap/js/dist/modal.js.map | 1 - .../bootstrap/js/dist/offcanvas.js | 246 - .../bootstrap/js/dist/offcanvas.js.map | 1 - web/node_modules/bootstrap/js/dist/popover.js | 96 - .../bootstrap/js/dist/popover.js.map | 1 - .../bootstrap/js/dist/scrollspy.js | 275 - .../bootstrap/js/dist/scrollspy.js.map | 1 - web/node_modules/bootstrap/js/dist/tab.js | 285 - web/node_modules/bootstrap/js/dist/tab.js.map | 1 - web/node_modules/bootstrap/js/dist/toast.js | 199 - .../bootstrap/js/dist/toast.js.map | 1 - web/node_modules/bootstrap/js/dist/tooltip.js | 546 - .../bootstrap/js/dist/tooltip.js.map | 1 - .../bootstrap/js/dist/util/backdrop.js | 140 - .../bootstrap/js/dist/util/backdrop.js.map | 1 - .../js/dist/util/component-functions.js | 42 - .../js/dist/util/component-functions.js.map | 1 - .../bootstrap/js/dist/util/config.js | 68 - .../bootstrap/js/dist/util/config.js.map | 1 - .../bootstrap/js/dist/util/focustrap.js | 114 - .../bootstrap/js/dist/util/focustrap.js.map | 1 - .../bootstrap/js/dist/util/index.js | 282 - .../bootstrap/js/dist/util/index.js.map | 1 - .../bootstrap/js/dist/util/sanitizer.js | 111 - .../bootstrap/js/dist/util/sanitizer.js.map | 1 - .../bootstrap/js/dist/util/scrollbar.js | 113 - .../bootstrap/js/dist/util/scrollbar.js.map | 1 - .../bootstrap/js/dist/util/swipe.js | 135 - .../bootstrap/js/dist/util/swipe.js.map | 1 - .../js/dist/util/template-factory.js | 151 - .../js/dist/util/template-factory.js.map | 1 - web/node_modules/bootstrap/js/index.esm.js | 19 - web/node_modules/bootstrap/js/index.umd.js | 34 - web/node_modules/bootstrap/js/src/alert.js | 87 - .../bootstrap/js/src/base-component.js | 85 - web/node_modules/bootstrap/js/src/button.js | 72 - web/node_modules/bootstrap/js/src/carousel.js | 474 - web/node_modules/bootstrap/js/src/collapse.js | 297 - web/node_modules/bootstrap/js/src/dom/data.js | 55 - .../bootstrap/js/src/dom/event-handler.js | 317 - .../bootstrap/js/src/dom/manipulator.js | 71 - .../bootstrap/js/src/dom/selector-engine.js | 126 - web/node_modules/bootstrap/js/src/dropdown.js | 455 - web/node_modules/bootstrap/js/src/modal.js | 376 - .../bootstrap/js/src/offcanvas.js | 282 - web/node_modules/bootstrap/js/src/popover.js | 97 - .../bootstrap/js/src/scrollspy.js | 294 - web/node_modules/bootstrap/js/src/tab.js | 315 - web/node_modules/bootstrap/js/src/toast.js | 225 - web/node_modules/bootstrap/js/src/tooltip.js | 631 - .../bootstrap/js/src/util/backdrop.js | 149 - .../js/src/util/component-functions.js | 35 - .../bootstrap/js/src/util/config.js | 65 - .../bootstrap/js/src/util/focustrap.js | 115 - .../bootstrap/js/src/util/index.js | 306 - .../bootstrap/js/src/util/sanitizer.js | 114 - .../bootstrap/js/src/util/scrollbar.js | 114 - .../bootstrap/js/src/util/swipe.js | 146 - .../bootstrap/js/src/util/template-factory.js | 160 - web/node_modules/bootstrap/package.json | 184 - .../bootstrap/scss/_accordion.scss | 158 - web/node_modules/bootstrap/scss/_alert.scss | 68 - web/node_modules/bootstrap/scss/_badge.scss | 38 - .../bootstrap/scss/_breadcrumb.scss | 40 - .../bootstrap/scss/_button-group.scss | 142 - web/node_modules/bootstrap/scss/_buttons.scss | 207 - web/node_modules/bootstrap/scss/_card.scss | 239 - .../bootstrap/scss/_carousel.scss | 244 - web/node_modules/bootstrap/scss/_close.scss | 63 - .../bootstrap/scss/_containers.scss | 41 - .../bootstrap/scss/_dropdown.scss | 250 - web/node_modules/bootstrap/scss/_forms.scss | 9 - .../bootstrap/scss/_functions.scss | 302 - web/node_modules/bootstrap/scss/_grid.scss | 39 - web/node_modules/bootstrap/scss/_helpers.scss | 12 - web/node_modules/bootstrap/scss/_images.scss | 42 - .../bootstrap/scss/_list-group.scss | 197 - web/node_modules/bootstrap/scss/_maps.scss | 174 - web/node_modules/bootstrap/scss/_mixins.scss | 42 - web/node_modules/bootstrap/scss/_modal.scss | 237 - web/node_modules/bootstrap/scss/_nav.scss | 197 - web/node_modules/bootstrap/scss/_navbar.scss | 289 - .../bootstrap/scss/_offcanvas.scss | 146 - .../bootstrap/scss/_pagination.scss | 109 - .../bootstrap/scss/_placeholders.scss | 51 - web/node_modules/bootstrap/scss/_popover.scss | 196 - .../bootstrap/scss/_progress.scss | 68 - web/node_modules/bootstrap/scss/_reboot.scss | 611 - web/node_modules/bootstrap/scss/_root.scss | 187 - .../bootstrap/scss/_spinners.scss | 85 - web/node_modules/bootstrap/scss/_tables.scss | 171 - web/node_modules/bootstrap/scss/_toasts.scss | 73 - web/node_modules/bootstrap/scss/_tooltip.scss | 119 - .../bootstrap/scss/_transitions.scss | 27 - web/node_modules/bootstrap/scss/_type.scss | 106 - .../bootstrap/scss/_utilities.scss | 806 -- .../bootstrap/scss/_variables-dark.scss | 87 - .../bootstrap/scss/_variables.scss | 1747 --- .../bootstrap/scss/bootstrap-grid.scss | 62 - .../bootstrap/scss/bootstrap-reboot.scss | 10 - .../bootstrap/scss/bootstrap-utilities.scss | 19 - .../bootstrap/scss/bootstrap.scss | 52 - .../scss/forms/_floating-labels.scss | 95 - .../bootstrap/scss/forms/_form-check.scss | 189 - .../bootstrap/scss/forms/_form-control.scss | 214 - .../bootstrap/scss/forms/_form-range.scss | 91 - .../bootstrap/scss/forms/_form-select.scss | 80 - .../bootstrap/scss/forms/_form-text.scss | 11 - .../bootstrap/scss/forms/_input-group.scss | 132 - .../bootstrap/scss/forms/_labels.scss | 36 - .../bootstrap/scss/forms/_validation.scss | 12 - .../bootstrap/scss/helpers/_clearfix.scss | 3 - .../bootstrap/scss/helpers/_color-bg.scss | 7 - .../scss/helpers/_colored-links.scss | 30 - .../bootstrap/scss/helpers/_focus-ring.scss | 5 - .../bootstrap/scss/helpers/_icon-link.scss | 25 - .../bootstrap/scss/helpers/_position.scss | 36 - .../bootstrap/scss/helpers/_ratio.scss | 26 - .../bootstrap/scss/helpers/_stacks.scss | 15 - .../scss/helpers/_stretched-link.scss | 15 - .../scss/helpers/_text-truncation.scss | 7 - .../scss/helpers/_visually-hidden.scss | 8 - .../bootstrap/scss/helpers/_vr.scss | 8 - .../bootstrap/scss/mixins/_alert.scss | 18 - .../bootstrap/scss/mixins/_backdrop.scss | 14 - .../bootstrap/scss/mixins/_banner.scss | 7 - .../bootstrap/scss/mixins/_border-radius.scss | 78 - .../bootstrap/scss/mixins/_box-shadow.scss | 18 - .../bootstrap/scss/mixins/_breakpoints.scss | 127 - .../bootstrap/scss/mixins/_buttons.scss | 70 - .../bootstrap/scss/mixins/_caret.scss | 69 - .../bootstrap/scss/mixins/_clearfix.scss | 9 - .../bootstrap/scss/mixins/_color-mode.scss | 21 - .../bootstrap/scss/mixins/_color-scheme.scss | 7 - .../bootstrap/scss/mixins/_container.scss | 11 - .../bootstrap/scss/mixins/_deprecate.scss | 10 - .../bootstrap/scss/mixins/_forms.scss | 153 - .../bootstrap/scss/mixins/_gradients.scss | 47 - .../bootstrap/scss/mixins/_grid.scss | 151 - .../bootstrap/scss/mixins/_image.scss | 16 - .../bootstrap/scss/mixins/_list-group.scss | 26 - .../bootstrap/scss/mixins/_lists.scss | 7 - .../bootstrap/scss/mixins/_pagination.scss | 10 - .../bootstrap/scss/mixins/_reset-text.scss | 17 - .../bootstrap/scss/mixins/_resize.scss | 6 - .../scss/mixins/_table-variants.scss | 24 - .../bootstrap/scss/mixins/_text-truncate.scss | 8 - .../bootstrap/scss/mixins/_transition.scss | 26 - .../bootstrap/scss/mixins/_utilities.scss | 97 - .../scss/mixins/_visually-hidden.scss | 33 - .../bootstrap/scss/utilities/_api.scss | 47 - .../bootstrap/scss/vendor/_rfs.scss | 348 - 501 files changed, 2 insertions(+), 96829 deletions(-) delete mode 100644 web/node_modules/.package-lock.json delete mode 100644 web/node_modules/@popperjs/core/LICENSE.md delete mode 100644 web/node_modules/@popperjs/core/README.md delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/enums.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-base.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper-lite.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/cjs/popper.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/esm/createPopper.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/contains.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getBoundingClientRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getClippingRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getCompositeRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getComputedStyle.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getDocumentElement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getDocumentRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getHTMLElementScroll.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getLayoutRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getNodeName.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getNodeScroll.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getOffsetParent.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getParentNode.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getScrollParent.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getViewportRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindow.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindowScroll.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/getWindowScrollBarX.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/instanceOf.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isLayoutViewport.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isScrollParent.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/isTableElement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/dom-utils/listScrollParents.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/enums.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/index.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/applyStyles.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/arrow.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/computeStyles.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/eventListeners.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/flip.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/hide.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/index.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/offset.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/popperOffsets.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/modifiers/preventOverflow.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/popper-base.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/popper-lite.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/popper.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/types.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/computeAutoPlacement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/computeOffsets.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/debounce.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/detectOverflow.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/expandToHashMap.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getAltAxis.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getAltLen.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getBasePlacement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getFreshSideObject.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getMainAxisFromPlacement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getOppositePlacement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getOppositeVariationPlacement.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/getVariation.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/math.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/mergeByName.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/mergePaddingObject.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/orderModifiers.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/rectToClientRect.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/uniqueBy.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/userAgent.js delete mode 100644 web/node_modules/@popperjs/core/dist/esm/utils/within.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/umd/enums.min.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-base.min.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper-lite.min.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.js.map delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js.flow delete mode 100644 web/node_modules/@popperjs/core/dist/umd/popper.min.js.map delete mode 100644 web/node_modules/@popperjs/core/index.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/createPopper.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/createPopper.js delete mode 100644 web/node_modules/@popperjs/core/lib/createPopper.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/contains.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindow.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js delete mode 100644 web/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/enums.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/enums.js delete mode 100644 web/node_modules/@popperjs/core/lib/enums.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/index.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/index.js delete mode 100644 web/node_modules/@popperjs/core/lib/index.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/applyStyles.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/arrow.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/computeStyles.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/eventListeners.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/flip.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/hide.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/index.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/offset.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js delete mode 100644 web/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/popper-base.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/popper-base.js delete mode 100644 web/node_modules/@popperjs/core/lib/popper-base.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.js delete mode 100644 web/node_modules/@popperjs/core/lib/popper-lite.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/popper.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/popper.js delete mode 100644 web/node_modules/@popperjs/core/lib/popper.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/types.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/types.js delete mode 100644 web/node_modules/@popperjs/core/lib/types.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/computeOffsets.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/debounce.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/detectOverflow.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/expandToHashMap.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltAxis.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getAltLen.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getBasePlacement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/getVariation.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/math.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/math.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/math.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergeByName.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/orderModifiers.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/rectToClientRect.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/uniqueBy.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/userAgent.js.flow delete mode 100644 web/node_modules/@popperjs/core/lib/utils/within.d.ts delete mode 100644 web/node_modules/@popperjs/core/lib/utils/within.js delete mode 100644 web/node_modules/@popperjs/core/lib/utils/within.js.flow delete mode 100644 web/node_modules/@popperjs/core/package.json delete mode 100644 web/node_modules/bootstrap/LICENSE delete mode 100644 web/node_modules/bootstrap/README.md delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.css.map delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css delete mode 100644 web/node_modules/bootstrap/dist/css/bootstrap.rtl.min.css.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.js.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.js.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.min.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.esm.min.js.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.js.map delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.min.js delete mode 100644 web/node_modules/bootstrap/dist/js/bootstrap.min.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/alert.js delete mode 100644 web/node_modules/bootstrap/js/dist/alert.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/base-component.js delete mode 100644 web/node_modules/bootstrap/js/dist/base-component.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/button.js delete mode 100644 web/node_modules/bootstrap/js/dist/button.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/carousel.js delete mode 100644 web/node_modules/bootstrap/js/dist/carousel.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/collapse.js delete mode 100644 web/node_modules/bootstrap/js/dist/collapse.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/dom/data.js delete mode 100644 web/node_modules/bootstrap/js/dist/dom/data.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/dom/event-handler.js delete mode 100644 web/node_modules/bootstrap/js/dist/dom/event-handler.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/dom/manipulator.js delete mode 100644 web/node_modules/bootstrap/js/dist/dom/manipulator.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/dom/selector-engine.js delete mode 100644 web/node_modules/bootstrap/js/dist/dom/selector-engine.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/dropdown.js delete mode 100644 web/node_modules/bootstrap/js/dist/dropdown.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/modal.js delete mode 100644 web/node_modules/bootstrap/js/dist/modal.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/offcanvas.js delete mode 100644 web/node_modules/bootstrap/js/dist/offcanvas.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/popover.js delete mode 100644 web/node_modules/bootstrap/js/dist/popover.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/scrollspy.js delete mode 100644 web/node_modules/bootstrap/js/dist/scrollspy.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/tab.js delete mode 100644 web/node_modules/bootstrap/js/dist/tab.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/toast.js delete mode 100644 web/node_modules/bootstrap/js/dist/toast.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/tooltip.js delete mode 100644 web/node_modules/bootstrap/js/dist/tooltip.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/backdrop.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/backdrop.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/component-functions.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/component-functions.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/config.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/config.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/focustrap.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/focustrap.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/index.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/index.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/sanitizer.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/sanitizer.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/scrollbar.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/scrollbar.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/swipe.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/swipe.js.map delete mode 100644 web/node_modules/bootstrap/js/dist/util/template-factory.js delete mode 100644 web/node_modules/bootstrap/js/dist/util/template-factory.js.map delete mode 100644 web/node_modules/bootstrap/js/index.esm.js delete mode 100644 web/node_modules/bootstrap/js/index.umd.js delete mode 100644 web/node_modules/bootstrap/js/src/alert.js delete mode 100644 web/node_modules/bootstrap/js/src/base-component.js delete mode 100644 web/node_modules/bootstrap/js/src/button.js delete mode 100644 web/node_modules/bootstrap/js/src/carousel.js delete mode 100644 web/node_modules/bootstrap/js/src/collapse.js delete mode 100644 web/node_modules/bootstrap/js/src/dom/data.js delete mode 100644 web/node_modules/bootstrap/js/src/dom/event-handler.js delete mode 100644 web/node_modules/bootstrap/js/src/dom/manipulator.js delete mode 100644 web/node_modules/bootstrap/js/src/dom/selector-engine.js delete mode 100644 web/node_modules/bootstrap/js/src/dropdown.js delete mode 100644 web/node_modules/bootstrap/js/src/modal.js delete mode 100644 web/node_modules/bootstrap/js/src/offcanvas.js delete mode 100644 web/node_modules/bootstrap/js/src/popover.js delete mode 100644 web/node_modules/bootstrap/js/src/scrollspy.js delete mode 100644 web/node_modules/bootstrap/js/src/tab.js delete mode 100644 web/node_modules/bootstrap/js/src/toast.js delete mode 100644 web/node_modules/bootstrap/js/src/tooltip.js delete mode 100644 web/node_modules/bootstrap/js/src/util/backdrop.js delete mode 100644 web/node_modules/bootstrap/js/src/util/component-functions.js delete mode 100644 web/node_modules/bootstrap/js/src/util/config.js delete mode 100644 web/node_modules/bootstrap/js/src/util/focustrap.js delete mode 100644 web/node_modules/bootstrap/js/src/util/index.js delete mode 100644 web/node_modules/bootstrap/js/src/util/sanitizer.js delete mode 100644 web/node_modules/bootstrap/js/src/util/scrollbar.js delete mode 100644 web/node_modules/bootstrap/js/src/util/swipe.js delete mode 100644 web/node_modules/bootstrap/js/src/util/template-factory.js delete mode 100644 web/node_modules/bootstrap/package.json delete mode 100644 web/node_modules/bootstrap/scss/_accordion.scss delete mode 100644 web/node_modules/bootstrap/scss/_alert.scss delete mode 100644 web/node_modules/bootstrap/scss/_badge.scss delete mode 100644 web/node_modules/bootstrap/scss/_breadcrumb.scss delete mode 100644 web/node_modules/bootstrap/scss/_button-group.scss delete mode 100644 web/node_modules/bootstrap/scss/_buttons.scss delete mode 100644 web/node_modules/bootstrap/scss/_card.scss delete mode 100644 web/node_modules/bootstrap/scss/_carousel.scss delete mode 100644 web/node_modules/bootstrap/scss/_close.scss delete mode 100644 web/node_modules/bootstrap/scss/_containers.scss delete mode 100644 web/node_modules/bootstrap/scss/_dropdown.scss delete mode 100644 web/node_modules/bootstrap/scss/_forms.scss delete mode 100644 web/node_modules/bootstrap/scss/_functions.scss delete mode 100644 web/node_modules/bootstrap/scss/_grid.scss delete mode 100644 web/node_modules/bootstrap/scss/_helpers.scss delete mode 100644 web/node_modules/bootstrap/scss/_images.scss delete mode 100644 web/node_modules/bootstrap/scss/_list-group.scss delete mode 100644 web/node_modules/bootstrap/scss/_maps.scss delete mode 100644 web/node_modules/bootstrap/scss/_mixins.scss delete mode 100644 web/node_modules/bootstrap/scss/_modal.scss delete mode 100644 web/node_modules/bootstrap/scss/_nav.scss delete mode 100644 web/node_modules/bootstrap/scss/_navbar.scss delete mode 100644 web/node_modules/bootstrap/scss/_offcanvas.scss delete mode 100644 web/node_modules/bootstrap/scss/_pagination.scss delete mode 100644 web/node_modules/bootstrap/scss/_placeholders.scss delete mode 100644 web/node_modules/bootstrap/scss/_popover.scss delete mode 100644 web/node_modules/bootstrap/scss/_progress.scss delete mode 100644 web/node_modules/bootstrap/scss/_reboot.scss delete mode 100644 web/node_modules/bootstrap/scss/_root.scss delete mode 100644 web/node_modules/bootstrap/scss/_spinners.scss delete mode 100644 web/node_modules/bootstrap/scss/_tables.scss delete mode 100644 web/node_modules/bootstrap/scss/_toasts.scss delete mode 100644 web/node_modules/bootstrap/scss/_tooltip.scss delete mode 100644 web/node_modules/bootstrap/scss/_transitions.scss delete mode 100644 web/node_modules/bootstrap/scss/_type.scss delete mode 100644 web/node_modules/bootstrap/scss/_utilities.scss delete mode 100644 web/node_modules/bootstrap/scss/_variables-dark.scss delete mode 100644 web/node_modules/bootstrap/scss/_variables.scss delete mode 100644 web/node_modules/bootstrap/scss/bootstrap-grid.scss delete mode 100644 web/node_modules/bootstrap/scss/bootstrap-reboot.scss delete mode 100644 web/node_modules/bootstrap/scss/bootstrap-utilities.scss delete mode 100644 web/node_modules/bootstrap/scss/bootstrap.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_floating-labels.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_form-check.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_form-control.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_form-range.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_form-select.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_form-text.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_input-group.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_labels.scss delete mode 100644 web/node_modules/bootstrap/scss/forms/_validation.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_clearfix.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_color-bg.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_colored-links.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_focus-ring.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_icon-link.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_position.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_ratio.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_stacks.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_stretched-link.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_text-truncation.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_visually-hidden.scss delete mode 100644 web/node_modules/bootstrap/scss/helpers/_vr.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_alert.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_backdrop.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_banner.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_border-radius.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_box-shadow.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_breakpoints.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_buttons.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_caret.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_clearfix.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_color-mode.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_color-scheme.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_container.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_deprecate.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_forms.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_gradients.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_grid.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_image.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_list-group.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_lists.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_pagination.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_reset-text.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_resize.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_table-variants.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_text-truncate.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_transition.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_utilities.scss delete mode 100644 web/node_modules/bootstrap/scss/mixins/_visually-hidden.scss delete mode 100644 web/node_modules/bootstrap/scss/utilities/_api.scss delete mode 100644 web/node_modules/bootstrap/scss/vendor/_rfs.scss diff --git a/.gitignore b/.gitignore index aa6a8513..375584d6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ /pkg/ /spec/reports/ /tmp/ +/tmp/ +web/node_modules *.gem diff --git a/web/node_modules/.package-lock.json b/web/node_modules/.package-lock.json deleted file mode 100644 index 62656757..00000000 --- a/web/node_modules/.package-lock.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "outboxer", - "lockfileVersion": 3, - "requires": true, - "packages": { - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/bootstrap": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", - "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/twbs" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/bootstrap" - } - ], - "peerDependencies": { - "@popperjs/core": "^2.11.8" - } - } - } -} diff --git a/web/node_modules/@popperjs/core/LICENSE.md b/web/node_modules/@popperjs/core/LICENSE.md deleted file mode 100644 index 0370c458..00000000 --- a/web/node_modules/@popperjs/core/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019 Federico Zivolo - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/web/node_modules/@popperjs/core/README.md b/web/node_modules/@popperjs/core/README.md deleted file mode 100644 index 53be7b9d..00000000 --- a/web/node_modules/@popperjs/core/README.md +++ /dev/null @@ -1,376 +0,0 @@ - -

- Popper -

- -
-

Tooltip & Popover Positioning Engine

-
- -

- - npm version - - - npm downloads per month (popper.js + @popperjs/core) - - - Rolling Versions - -

- -
- - -**Positioning tooltips and popovers is difficult. Popper is here to help!** - -Given an element, such as a button, and a tooltip element describing it, Popper -will automatically put the tooltip in the right place near the button. - -It will position _any_ UI element that "pops out" from the flow of your document -and floats near a target element. The most common example is a tooltip, but it -also includes popovers, drop-downs, and more. All of these can be generically -described as a "popper" element. - -## Demo - -[![Popper visualized](https://i.imgur.com/F7qWsmV.jpg)](https://popper.js.org) - -## Docs - -- [v2.x (latest)](https://popper.js.org/docs/v2/) -- [v1.x](https://popper.js.org/docs/v1/) - -We've created a -[Migration Guide](https://popper.js.org/docs/v2/migration-guide/) to help you -migrate from Popper 1 to Popper 2. - -To contribute to the Popper website and documentation, please visit the -[dedicated repository](https://github.com/popperjs/website). - -## Why not use pure CSS? - -- **Clipping and overflow issues**: Pure CSS poppers will not be prevented from - overflowing clipping boundaries, such as the viewport. It will get partially - cut off or overflows if it's near the edge since there is no dynamic - positioning logic. When using Popper, your popper will always be positioned in - the right place without needing manual adjustments. -- **No flipping**: CSS poppers will not flip to a different placement to fit - better in view if necessary. While you can manually adjust for the main axis - overflow, this feature cannot be achieved via CSS alone. Popper automatically - flips the tooltip to make it fit in view as best as possible for the user. -- **No virtual positioning**: CSS poppers cannot follow the mouse cursor or be - used as a context menu. Popper allows you to position your tooltip relative to - any coordinates you desire. -- **Slower development cycle**: When pure CSS is used to position popper - elements, the lack of dynamic positioning means they must be carefully placed - to consider overflow on all screen sizes. In reusable component libraries, - this means a developer can't just add the component anywhere on the page, - because these issues need to be considered and adjusted for every time. With - Popper, you can place your elements anywhere and they will be positioned - correctly, without needing to consider different screen sizes, layouts, etc. - This massively speeds up development time because this work is automatically - offloaded to Popper. -- **Lack of extensibility**: CSS poppers cannot be easily extended to fit any - arbitrary use case you may need to adjust for. Popper is built with - extensibility in mind. - -## Why Popper? - -With the CSS drawbacks out of the way, we now move on to Popper in the -JavaScript space itself. - -Naive JavaScript tooltip implementations usually have the following problems: - -- **Scrolling containers**: They don't ensure the tooltip stays with the - reference element while scrolling when inside any number of scrolling - containers. -- **DOM context**: They often require the tooltip move outside of its original - DOM context because they don't handle `offsetParent` contexts. -- **Compatibility**: Popper handles an incredible number of edge cases regarding - different browsers and environments (mobile viewports, RTL, scrollbars enabled - or disabled, etc.). Popper is a popular and well-maintained library, so you - can be confident positioning will work for your users on any device. -- **Configurability**: They often lack advanced configurability to suit any - possible use case. -- **Size**: They are usually relatively large in size, or require an ancient - jQuery dependency. -- **Performance**: They often have runtime performance issues and update the - tooltip position too slowly. - -**Popper solves all of these key problems in an elegant, performant manner.** It -is a lightweight ~3 kB library that aims to provide a reliable and extensible -positioning engine you can use to ensure all your popper elements are positioned -in the right place. - -When you start writing your own popper implementation, you'll quickly run into -all of the problems mentioned above. These widgets are incredibly common in our -UIs; we've done the hard work figuring this out so you don't need to spend hours -fixing and handling numerous edge cases that we already ran into while building -the library! - -Popper is used in popular libraries like Bootstrap, Foundation, Material UI, and -more. It's likely you've already used popper elements on the web positioned by -Popper at some point in the past few years. - -Since we write UIs using powerful abstraction libraries such as React or Angular -nowadays, you'll also be glad to know Popper can fully integrate with them and -be a good citizen together with your other components. Check out `react-popper` -for the official Popper wrapper for React. - -## Installation - -### 1. Package Manager - -```bash -# With npm -npm i @popperjs/core - -# With Yarn -yarn add @popperjs/core -``` - -### 2. CDN - -```html - - - - - -``` - -### 3. Direct Download? - -Managing dependencies by "directly downloading" them and placing them into your -source code is not recommended for a variety of reasons, including missing out -on feat/fix updates easily. Please use a versioning management system like a CDN -or npm/Yarn. - -## Usage - -The most straightforward way to get started is to import Popper from the `unpkg` -CDN, which includes all of its features. You can call the `Popper.createPopper` -constructor to create new popper instances. - -Here is a complete example: - -```html - -Popper example - - - - - - - - -``` - -Visit the [tutorial](https://popper.js.org/docs/v2/tutorial/) for an example of -how to build your own tooltip from scratch using Popper. - -### Module bundlers - -You can import the `createPopper` constructor from the fully-featured file: - -```js -import { createPopper } from '@popperjs/core'; - -const button = document.querySelector('#button'); -const tooltip = document.querySelector('#tooltip'); - -// Pass the button, the tooltip, and some options, and Popper will do the -// magic positioning for you: -createPopper(button, tooltip, { - placement: 'right', -}); -``` - -All the modifiers listed in the docs menu will be enabled and "just work", so -you don't need to think about setting Popper up. The size of Popper including -all of its features is about 5 kB minzipped, but it may grow a bit in the -future. - -#### Popper Lite (tree-shaking) - -If bundle size is important, you'll want to take advantage of tree-shaking. The -library is built in a modular way to allow to import only the parts you really -need. - -```js -import { createPopperLite as createPopper } from '@popperjs/core'; -``` - -The Lite version includes the most necessary modifiers that will compute the -offsets of the popper, compute and add the positioning styles, and add event -listeners. This is close in bundle size to pure CSS tooltip libraries, and -behaves somewhat similarly. - -However, this does not include the features that makes Popper truly useful. - -The two most useful modifiers not included in Lite are `preventOverflow` and -`flip`: - -```js -import { - createPopperLite as createPopper, - preventOverflow, - flip, -} from '@popperjs/core'; - -const button = document.querySelector('#button'); -const tooltip = document.querySelector('#tooltip'); - -createPopper(button, tooltip, { - modifiers: [preventOverflow, flip], -}); -``` - -As you make more poppers, you may be finding yourself needing other modifiers -provided by the library. - -See [tree-shaking](https://popper.js.org/docs/v2/performance/#tree-shaking) for more -information. - -## Distribution targets - -Popper is distributed in 3 different versions, in 3 different file formats. - -The 3 file formats are: - -- `esm` (works with `import` syntax — **recommended**) -- `umd` (works with ` + + From c70e31a07a47ef8b91bb9681c197885b9f4c262b Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 24 Feb 2024 22:09:13 +1100 Subject: [PATCH 05/79] support bulk actions (WIP) --- Gemfile | 1 + Gemfile.lock | 8 +++ web/app.rb | 47 ++++++++++++++++++ web/views/table.erb | 118 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+) mode change 100644 => 100755 web/app.rb create mode 100644 web/views/table.erb diff --git a/Gemfile b/Gemfile index 49c2d84d..c2f8db49 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ gem 'foreman', '~> 0.87.2' # web gem 'rackup', '~> 2.1' gem 'sinatra', '~> 4.0' +gem 'sinatra-contrib' gem 'puma', '~> 6.4', '>= 6.4.2' gem 'kaminari', '~> 1.2', '>= 1.2.2' gem 'ransack', '~> 4.1', '>= 4.1.1' diff --git a/Gemfile.lock b/Gemfile.lock index 58f61689..ffccc635 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,6 +71,7 @@ GEM nokogiri (>= 1.12.0) method_source (1.0.0) minitest (5.20.0) + multi_json (1.15.0) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) mutex_m (0.2.0) @@ -166,6 +167,12 @@ GEM rack-protection (= 4.0.0) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) + sinatra-contrib (4.0.0) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.0.0) + sinatra (= 4.0.0) + tilt (~> 2.0) tilt (2.3.0) timeout (0.4.1) tzinfo (2.0.6) @@ -196,6 +203,7 @@ DEPENDENCIES sidekiq (~> 7.2) simplecov (~> 0.22.0) sinatra (~> 4.0) + sinatra-contrib yard (~> 0.9.34) BUNDLED WITH diff --git a/web/app.rb b/web/app.rb old mode 100644 new mode 100755 index e1a11f64..62eefb95 --- a/web/app.rb +++ b/web/app.rb @@ -5,6 +5,7 @@ require 'kaminari' require 'ransack' +require 'sinatra/reloader' require 'pry-byebug' environment = ENV['RAILS_ENV'] || 'development' @@ -13,6 +14,52 @@ module Outboxer class App < Sinatra::Base + set :method_override, true + + get '/table' do + fruits = 10.times.map do |i| + { id: i + 1, name: "Fruit #{i + 1}", health_rating: rand(1..10) } + end + + erb :table, locals: { fruits: fruits }, layout: nil + end + + post '/bulk_action' do + bulk_action = params['bulk_action'] + fruit_ids = params['fruit_ids'] + + binding.pry + + case bulk_action + when 'retry_selected' + # TODO + when 'delete_selected' + # TODO + else + raise "#{params['bulk_action']} not supported" + end + + if params['retry_selected'] + # TODO + elsif params['delete'] + # TODO + end + + redirect to('/table') + end + + delete '/fruits/:id' do + binding.pry + + redirect to('/table') + end + + patch '/fruits/:id/retry' do + binding.pry + + redirect to('/table') + end + get '/searches' do q = Outboxer::Models::Message.ransack(params[:q]) messages = q.result.includes(:outboxer_exceptions) diff --git a/web/views/table.erb b/web/views/table.erb new file mode 100644 index 00000000..a42fc38a --- /dev/null +++ b/web/views/table.erb @@ -0,0 +1,118 @@ + + + + + + Outboxer + + + +
+ + +
+ + + +
+ <% if @message %> +
+ <%= @message %> +
+ <% end %> + +
+ +
+
+ + + + + + + + + + + + <% fruits.each do |fruit| %> + + + + + + + + <% end %> + +
IDNameHealth RatingActions
<%= fruit[:id] %><%= fruit[:name] %><%= fruit[:health_rating] %> + + + + + +
+ + + + +
+
+ + <% fruits.each do |fruit| %> +
+ +
+
+ +
+ <% end %> + + + + + + From 0a2947d869b1e750be41131d99505beaf6962443 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 24 Feb 2024 22:37:18 +1100 Subject: [PATCH 06/79] update to work with messages --- web/app.rb | 40 ++++++++++++--------------- web/views/{table.erb => messages.erb} | 38 +++++++++++++------------ 2 files changed, 39 insertions(+), 39 deletions(-) rename web/views/{table.erb => messages.erb} (75%) diff --git a/web/app.rb b/web/app.rb index 62eefb95..be613964 100755 --- a/web/app.rb +++ b/web/app.rb @@ -16,17 +16,23 @@ module Outboxer class App < Sinatra::Base set :method_override, true - get '/table' do - fruits = 10.times.map do |i| - { id: i + 1, name: "Fruit #{i + 1}", health_rating: rand(1..10) } - end + post '/messages/search' do + text = params['text'] + + binding.pry + + redirect to('/messages') + end + + get '/messages' do + messages = Models::Message.all - erb :table, locals: { fruits: fruits }, layout: nil + erb :messages, locals: { messages: messages }, layout: nil end - post '/bulk_action' do + post '/messages/bulk_action' do bulk_action = params['bulk_action'] - fruit_ids = params['fruit_ids'] + message_ids = params['message_ids'] binding.pry @@ -36,28 +42,18 @@ class App < Sinatra::Base when 'delete_selected' # TODO else - raise "#{params['bulk_action']} not supported" - end - - if params['retry_selected'] - # TODO - elsif params['delete'] - # TODO + raise "#{bulk_action} not supported" end - redirect to('/table') + redirect to('/messages') end - delete '/fruits/:id' do - binding.pry - + delete '/messages/:id' do redirect to('/table') end - patch '/fruits/:id/retry' do - binding.pry - - redirect to('/table') + patch '/messages/:id/retry' do + redirect to('/messages') end get '/searches' do diff --git a/web/views/table.erb b/web/views/messages.erb similarity index 75% rename from web/views/table.erb rename to web/views/messages.erb index a42fc38a..2e37298b 100644 --- a/web/views/table.erb +++ b/web/views/messages.erb @@ -30,8 +30,8 @@ Failed - @@ -44,39 +44,43 @@
<% if @message %>
- <%= @message %> + <%= @flash %>
<% end %>
-
+

Messages

+ + - - - + + + + - <% fruits.each do |fruit| %> + <% messages.each do |message| %> - - - - + + + + + @@ -95,11 +99,11 @@ - <% fruits.each do |fruit| %> - + <% messages.each do |message| %> + - + <% end %> From 8ce243d67217094773f5a2fce2cc5ce1650f8d29 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 00:22:52 +1100 Subject: [PATCH 07/79] support pagination --- web/app.rb | 192 ++++++++++++++++++++++++++++++++--------- web/views/messages.erb | 47 +++++++--- 2 files changed, 188 insertions(+), 51 deletions(-) diff --git a/web/app.rb b/web/app.rb index be613964..3caa17f8 100755 --- a/web/app.rb +++ b/web/app.rb @@ -4,6 +4,7 @@ require 'sinatra/base' require 'kaminari' require 'ransack' +require 'uri' require 'sinatra/reloader' require 'pry-byebug' @@ -24,12 +25,121 @@ class App < Sinatra::Base redirect to('/messages') end + post '/messages/per_page' do + page_number = params[:page_number] || 1 + per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 + sort = %w[id status messageable_type messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + redirect "/messages?" \ + "#{URI.encode_www_form_component('page_number')}=#{URI.encode_www_form_component(page_number)}&" \ + "#{URI.encode_www_form_component('per_page')}=#{URI.encode_www_form_component(per_page)}&" \ + "#{URI.encode_www_form_component('sort')}=#{URI.encode_www_form_component(sort)}&" \ + "#{URI.encode_www_form_component('order')}=#{URI.encode_www_form_component(order)}" + end + get '/messages' do - messages = Models::Message.all + page_number = params[:page_number] || 1 + per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 + sort = %w[id status messageable_type messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + messages_scope = Models::Message + messages = messages_scope.order(sort => order).page(page_number).per(per_page) + messages_count = Models::Message.count + + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) + + erb :messages, layout: nil, locals: { + status_counts: status_counts, + messages_count: messages_count, + messages: messages, + page_number: page_number, + per_page: per_page, + sort: sort, + order: order + } + end + + get '/messages/unpublished' do + page_number = params[:page_number] || 1 + per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 + sort = %w[id status messageable_type messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + messages_scope = Models::Message.where(status: 'unpublished') + messages = messages_scope.order(sort => order).page(page_number).per(per_page) + messages_count = Models::Message.count + + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) + + erb :messages, layout: nil, locals: { + status_counts: status_counts, + messages_count: messages_count, + messages: messages, + page_number: page_number, + per_page: per_page, + sort: sort, + order: order + } + end + + get '/messages/publishing' do + page_number = params[:page_number] || 1 + per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 + sort = %w[id status messageable_type messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + messages_scope = Models::Message.where(status: 'publishing') + messages = messages_scope.order(sort => order).page(page_number).per(per_page) + messages_count = Models::Message.count + + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) + + erb :messages, layout: nil, locals: { + status_counts: status_counts, + messages_count: messages_count, + messages: messages, + page_number: page_number, + per_page: per_page, + sort: sort, + order: order + } + end + + get '/messages/failed' do + page_number = params[:page_number] || 1 + per_page = [100, 200, 500, 1000].include?(params[:per_page]) ? params[:per_page].to_i : 100 + sort = %w[id status messageable_type messageable_id created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + messages_scope = Models::Message.where(status: 'failed') + messages = messages_scope.order(sort => order).page(page_number).per(per_page) + messages_count = Models::Message.count - erb :messages, locals: { messages: messages }, layout: nil + status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + Models::Message.group(:status).count) + + erb :messages, layout: nil, locals: { + status_counts: status_counts, + messages_count: messages_count, + messages: messages, + page_number: page_number, + per_page: per_page, + sort: sort, + order: order + } end + post '/messages/bulk_action' do bulk_action = params['bulk_action'] message_ids = params['message_ids'] @@ -79,47 +189,47 @@ class App < Sinatra::Base end get '/' do - redirect to('/all') + redirect to('/messages/all') end - get '/messages/:id' do |id| - messages_count = Models::Message.count - - message = Models::Message.includes(:outboxer_exceptions).find(id) - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :'messages/show', locals: { - status_counts: status_counts, - messages_count: messages_count, - message: message - } - end - - get '/:status' do |status| - page = params[:page] || 1 - limit = params[:limit] || 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at - order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc - - messages_scope = status == 'all' ? Models::Message : Models::Message.where(status: status) - messages = messages_scope.order(sort => order).page(page).per(limit) - messages_count = Models::Message.count - - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :'messages/index', locals: { - status_counts: status_counts, - messages_count: messages_count, - messages: messages, - page: page, - limit: limit, - sort: sort, - order: order - } - end + # get '/messages/:id' do |id| + # messages_count = Models::Message.count + + # message = Models::Message.includes(:outboxer_exceptions).find(id) + # status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + # Models::Message.group(:status).count) + + # erb :'messages/show', locals: { + # status_counts: status_counts, + # messages_count: messages_count, + # message: message + # } + # end + + # get '/:status' do |status| + # page = params[:page] || 1 + # limit = params[:limit] || 100 + # sort = %w[id status messageable_type messageable_id created_at updated_at] + # .include?(params[:sort]) ? params[:sort].to_sym : :created_at + # order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + + # messages_scope = status == 'all' ? Models::Message : Models::Message.where(status: status) + # messages = messages_scope.order(sort => order).page(page).per(limit) + # messages_count = Models::Message.count + + # status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( + # Models::Message.group(:status).count) + + # erb :'messages/index', locals: { + # status_counts: status_counts, + # messages_count: messages_count, + # messages: messages, + # page: page, + # limit: limit, + # sort: sort, + # order: order + # } + # end end end diff --git a/web/views/messages.erb b/web/views/messages.erb index 2e37298b..c75ee0a6 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -18,17 +18,14 @@ + +
+ + + + + + +
+ +
<% messages.each do |message| %>
From d454a7eb874db6574627173c807e4074060f0a8f Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 00:48:27 +1100 Subject: [PATCH 08/79] add sorting (without messageable) --- web/app.rb | 27 +++++++++++++++++++-------- web/views/messages.erb | 25 +++++++++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/web/app.rb b/web/app.rb index 3caa17f8..5d6e7f69 100755 --- a/web/app.rb +++ b/web/app.rb @@ -28,7 +28,7 @@ class App < Sinatra::Base post '/messages/per_page' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] + sort = %w[id status messageable created_at updated_at] .include?(params[:sort]) ? params[:sort].to_sym : :created_at order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc @@ -40,14 +40,25 @@ class App < Sinatra::Base end get '/messages' do + messages = Models::Message + page_number = params[:page_number] || 1 + messages = messages.page(page_number) + per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at + messages = messages.per(per_page) + order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc - messages_scope = Models::Message - messages = messages_scope.order(sort => order).page(page_number).per(per_page) + sort = %w[id status messageable created_at updated_at] + .include?(params[:sort]) ? params[:sort].to_sym : :created_at + + if params[:sort] == :messageable + messages = messages.order(:messageable_type, :messageable_id) + else + messages = messages.order(sort => order) + end + messages_count = Models::Message.count status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( @@ -67,7 +78,7 @@ class App < Sinatra::Base get '/messages/unpublished' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] + sort = %w[id status messageable created_at updated_at] .include?(params[:sort]) ? params[:sort].to_sym : :created_at order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc @@ -92,7 +103,7 @@ class App < Sinatra::Base get '/messages/publishing' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] + sort = %w[id status messageable created_at updated_at] .include?(params[:sort]) ? params[:sort].to_sym : :created_at order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc @@ -117,7 +128,7 @@ class App < Sinatra::Base get '/messages/failed' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page]) ? params[:per_page].to_i : 100 - sort = %w[id status messageable_type messageable_id created_at updated_at] + sort = %w[id status messageable created_at updated_at] .include?(params[:sort]) ? params[:sort].to_sym : :created_at order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc diff --git a/web/views/messages.erb b/web/views/messages.erb index c75ee0a6..6bebdce7 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -55,10 +55,26 @@
- - - - + + <% + headers = { + 'Id' => 'id', + 'Messageable' => 'messageable', + 'Status' => 'status', + 'Created At' => 'created_at', + 'Updated At' => 'updated_at' + } + headers.each do |display, col| + %> + + <% end %> @@ -70,6 +86,7 @@ + - <% messages.each do |message| %> - + @@ -161,6 +168,13 @@ checkbox.checked = this.checked; } }); + + var rows = document.querySelectorAll('.clickable-row'); + rows.forEach(function(row) { + row.addEventListener('click', function() { + window.location.href = this.dataset.href; + }); + }); diff --git a/web/views/messages/show.erb b/web/views/messages/show.erb index 2a149682..5c3f90a8 100644 --- a/web/views/messages/show.erb +++ b/web/views/messages/show.erb @@ -13,16 +13,15 @@ - <% if message.outboxer_exceptions.any? %> + <% if message.exceptions.any? %>
Exceptions
    - <% message.outboxer_exceptions.each do |exception| %> + <% message.exceptions.each do |exception| %>
  • Class Name: <%= exception.class_name %>

    Message: <%= exception.message_text %>

    -

    Backtrace:

    <%= exception.backtrace.join("\n") %>

  • <% end %>
From 49e4213109abb6f2db08dc4fe9b9db45a96f3104 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 20:30:15 +1100 Subject: [PATCH 11/79] add mockups (missing buttons) --- web/mockup.html | 169 ++++++++++++++++++++++++++++ web/mockup_show.html | 218 ++++++++++++++++++++++++++++++++++++ web/views/messages.erb | 248 ++++++++++++++--------------------------- 3 files changed, 469 insertions(+), 166 deletions(-) create mode 100644 web/mockup.html create mode 100644 web/mockup_show.html diff --git a/web/mockup.html b/web/mockup.html new file mode 100644 index 00000000..09213ced --- /dev/null +++ b/web/mockup.html @@ -0,0 +1,169 @@ + + + + + + Responsive Bootstrap 5.3 Table with Navigation + + + + + + + + + + +
+ +
+
+ +
+ +
+

Messages

+
+ + +
+ +
+ + +
+
+ + +
+
+
+
+
+ +
IDNameHealth RatingIdMessageableStatusCreated At Actions
<%= fruit[:id] %><%= fruit[:name] %><%= fruit[:health_rating] %><%= message.id %><%= message.messageable_type %>::<%= message.messageable_id %><%= message.status %><%= message.created_at %> - -
IdMessageableStatusCreated At + + <%= display %> + <% if sort.to_s == col %> + <%= order == :asc ? '▲' : '▼' %> + <% end %> + + Actions
<%= message.messageable_type %>::<%= message.messageable_id %> <%= message.status %> <%= message.created_at %><%= message.updated_at %> <%= message.messageable_type %>::<%= message.messageable_id %> <%= message.status %> <%= message.created_at %><%= message.updated_at %>
<%= message.id %> <%= message.messageable_type %>::<%= message.messageable_id %>
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + IdStatusMessageable + Created At + + Updated AtActions
+ + 79b5c0a8-0954-41f4-b4b1-86e9e4af1963 + + unpublishedUser::12024-02-24 14:59:06 UTC2024-02-24 14:59:06 UTC + +
+ + +
+
+
+ + + + + + + + + + + diff --git a/web/mockup_show.html b/web/mockup_show.html new file mode 100644 index 00000000..0ed02019 --- /dev/null +++ b/web/mockup_show.html @@ -0,0 +1,218 @@ + + + + + + Responsive Bootstrap 5.3 Table with Navigation + + + + + + + + + +
+
+
+

Message

+
+
+ + + + + + + + + + + + + + + + + + + +
IdMessage ID Here
StatusMessage Status Here
+
Exceptions
+ + + + + + + + + + + + + + + + + + + + + + +
Id949337b6-9440-47c6-96cb-ee39146e13f0
Message TextException Message 1
Class NameStandardError
+
Frames
+ + + + + + + + + + + + + + + +
IndexText
1Error occurred in method 'send_email'
+
+
+
+
+
+ + +
+
+
+

Message

+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
Id79b5c0a8-0954-41f4-b4b1-86e9e4af1963
Statusunpublished
MessageableUser::1
Created At2024-02-24 14:59:06 UTC
Updated At2024-02-24 14:59:06 UTC
+ + +
+
Exceptions
+
+ +
+

+ +

+
+
+ + + + + + + + + + + + + + + + +
Id949337b6-9440-47c6-96cb-ee39146e13f0
Message TextException Message 1
Class NameStandardError
+ + + + + + + + + + + + + + + + + +
IndexText
1Error occurred in method 'send_email'
+
+
+
+ +
+
+
+
+ + Back + +
+ + + + + diff --git a/web/views/messages.erb b/web/views/messages.erb index 51336713..ade679a3 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -3,178 +3,94 @@ - Outboxer + Responsive Bootstrap 5.3 Table with Pagination and Filters + + + - - -
- - -
- - -
- <% if @message %> -
- <%= @flash %> +
Messages
+ +
+
+ +
+
+ +
+
+ +
+ + +
+
+
- <% end %> - -
- -
-

Messages

- -
- - - - - - <% - headers = { - 'Id' => 'id', - 'Messageable' => 'messageable', - 'Status' => 'status', - 'Created At' => 'created_at', - 'Updated At' => 'updated_at' - } - headers.each do |display, col| - %> - - <% end %> - - - - - <% messages.each do |message| %> - - - - - - - - +
+ +
- - <%= display %> - <% if sort.to_s == col %> - <%= order == :asc ? '▲' : '▼' %> - <% end %> - - Actions
<%= message.id %><%= message.messageable_type %>::<%= message.messageable_id %><%= message.status %><%= message.created_at %><%= message.updated_at %> - - - - - -
+ + + + + + + - <% end %> - -
#First ColumnSecond ColumnThird Column
- - - - -
+ + + + + 1 + Data 1 + Data 2 + Data 3 + + + + + + +
+ +
+ + +
+
+
+
- -
- - -
- - -
- -
- - <% messages.each do |message| %> -
- -
-
- -
- <% end %> - - - - + + + - From 1ae47e7b13e8a8c320b8d13f04f43816b8fe5570 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 20:32:33 +1100 Subject: [PATCH 12/79] readd buttons --- web/mockup_show.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/web/mockup_show.html b/web/mockup_show.html index 0ed02019..ebf6993d 100644 --- a/web/mockup_show.html +++ b/web/mockup_show.html @@ -53,6 +53,17 @@

Message

+ +
+
+ + +
+
@@ -70,6 +81,7 @@

Message

Exceptions
+ From 9ada86209dc41f6d9f6690c855b97eb7eba976ac Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 23:44:04 +1100 Subject: [PATCH 13/79] spike options --- web/mockup_show_accordian.html | 138 ++++++++++++++++++++++++++++++++ web/mockup_show_list_group.html | 93 +++++++++++++++++++++ web/mockup_show_nested.html | 62 ++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 web/mockup_show_accordian.html create mode 100644 web/mockup_show_list_group.html create mode 100644 web/mockup_show_nested.html diff --git a/web/mockup_show_accordian.html b/web/mockup_show_accordian.html new file mode 100644 index 00000000..57c2dc7e --- /dev/null +++ b/web/mockup_show_accordian.html @@ -0,0 +1,138 @@ + + + + + + Message Details + + + + + + + +
+
+
+ Message +
+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
Id123e4567-e89b-12d3-a456-426614174000
MessageableEvent::1
Statusfailed
Created at2024-02-25 10:00:00
Updated at2024-02-25 10:00:00
+ +
+ +
+

+ +

+
+
+ + + + + + + + + + + +
Id456f4567-g89h-12d3-a456-426614174abc
Created at2024-02-25 11:00:00
+
    +
  • app/controllers/my_controller.rb:23:in `index`
  • +
  • app/models/my_model.rb:45:in `calculate`
  • +
  • app/helpers/my_helper.rb:10:in `format`
  • +
+
+
+
+ + +
+

+ +

+
+
+ + + + + + + + + + + +
Id789g4567-h89j-12d3-a456-426614174xyz
Created at2024-02-25 11:30:00
+
    +
  • app/services/my_service.rb:30:in `execute`
  • +
  • app/controllers/another_controller.rb:52:in `show`
  • +
  • app/jobs/my_job.rb:15:in `perform`
  • +
+
+
+
+ +
+ + + + + + + + diff --git a/web/mockup_show_list_group.html b/web/mockup_show_list_group.html new file mode 100644 index 00000000..6aea0eef --- /dev/null +++ b/web/mockup_show_list_group.html @@ -0,0 +1,93 @@ + + + + + + Message Details + + + + + + + +
+
+
+ Message +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
ID123e4567-e89b-12d3-a456-426614174000
MessageableEvent::1
Statusunpublished
Created at2024-02-25 10:00:00
Updated at2024-02-25 10:00:00
+ +
    + +
  • + StandardError - undefined method 'blah' +
      +
    • app/controllers/my_controller.rb:23:in `index`
    • +
    • app/models/my_model.rb:45:in `calculate`
    • +
    • app/helpers/my_helper.rb:10:in `format`
    • +
    +
  • + + +
  • + ArgumentError - wrong number of arguments +
      +
    • app/services/my_service.rb:30:in `execute`
    • +
    • app/controllers/another_controller.rb:52:in `show`
    • +
    • app/jobs/my_job.rb:15:in `perform`
    • +
    +
  • + +
+
+
+
+ + + + + diff --git a/web/mockup_show_nested.html b/web/mockup_show_nested.html new file mode 100644 index 00000000..82974aa0 --- /dev/null +++ b/web/mockup_show_nested.html @@ -0,0 +1,62 @@ + + + + + + Message Details + + + +
+
+
Message
+
+

ID: 123e4567-e89b-12d3-a456-426614174000

+

Status: Success

+

Created at: 2024-02-25 10:00:00

+ + +
+
Exception
+
+

Class Name: StandardError

+

Message: undefined method 'blah'

+ + +
+
Frames
+
    +
  • app/controllers/my_controller.rb:23:in `index`
  • +
  • app/models/my_model.rb:45:in `calculate`
  • +
  • app/helpers/my_helper.rb:10:in `format`
  • +
+
+
+
+ + +
+
Exception
+
+

Class Name: ArgumentError

+

Message: wrong number of arguments

+ + +
+
Frames
+
    +
  • app/services/my_service.rb:30:in `execute`
  • +
  • app/controllers/another_controller.rb:52:in `show`
  • +
  • app/jobs/my_job.rb:15:in `perform`
  • +
+
+
+
+ +
+
+
+ + + + From 4ac98456ec9db77494b5cc18a82a208160d2ffeb Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 25 Feb 2024 23:50:06 +1100 Subject: [PATCH 14/79] commit show mockups --- web/mockup_show_accordian.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/mockup_show_accordian.html b/web/mockup_show_accordian.html index 57c2dc7e..5f9db52b 100644 --- a/web/mockup_show_accordian.html +++ b/web/mockup_show_accordian.html @@ -24,6 +24,9 @@ width: 100%; text-align: left; } + .back-button { + margin-top: 20px; + } @@ -130,6 +133,10 @@

+ + From b995b35bd0a146ad4084397bee3e7771b6575c22 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Mon, 26 Feb 2024 18:44:37 +1100 Subject: [PATCH 15/79] add mockup --- web/mockup.html | 300 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 261 insertions(+), 39 deletions(-) diff --git a/web/mockup.html b/web/mockup.html index 09213ced..d90a216b 100644 --- a/web/mockup.html +++ b/web/mockup.html @@ -52,17 +52,29 @@
-
+

Messages

- -
+ +
+ +
+ + +
+ + -
-
+
+
-
+
+
@@ -100,6 +113,7 @@

Messages

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -
@@ -113,44 +127,252 @@

Messages

2024-02-24 14:59:06 UTC -
- - -
+
+ + +
+
+ + 8f5b2c0d-0632-48f5-a2c7-34e9e8af1974 + + publishingUser::22024-02-24 15:10:07 UTC2024-02-24 15:10:07 UTC + +
+ + +
+
+ + a2c3d405-0968-4f6b-8b34-56f1e9af1985 + + failedUser::32024-02-24 15:20:08 UTC2024-02-24 15:20:08 UTC + +
+ + +
+
+ + b4d5e607-0a29-45f6-9b3a-67f2eaaf1996 + + publishedUser::42024-02-24 15:30:09 UTC2024-02-24 15:30:09 UTC + +
+ + +
+
+ + c6e7f809-0b4a-46f7-abc4-78f3ebaf1a07 + + unpublishedUser::52024-02-24 15:40:10 UTC2024-02-24 15:40:10 UTC + +
+ + +
+
+ + d8f9g0ab-1c5b-48f8-bd2d-89f4fcac1b18 + + failedUser::62024-02-24 15:50:11 UTC2024-02-24 15:50:11 UTC + +
+ + +
+
+ + ea1fb2cd-2e6c-49f9-ce3e-9a5bfdad2c19 + + publishingUser::72024-02-24 16:00:12 UTC2024-02-24 16:00:12 UTC + +
+ + +
+
+ + fc1d2e3f-3f7d-50a0-de4f-ab6cdeaf3d20 + + publishedUser::82024-02-24 16:10:13 UTC2024-02-24 16:10:13 UTC + +
+ + +
+
+ + ge2f3g4h-4g8h-51b1-ef5g-cb7dfebg4e21 + + unpublishedUser::92024-02-24 16:20:14 UTC2024-02-24 16:20:14 UTC + +
+ + +
+
+ + hf3g4h5i-5i9j-62c2-fg6h-dc8efgci5f22 + + failedUser::102024-02-24 16:30:15 UTC2024-02-24 16:30:15 UTC + +
+ + +
- +
From be73735988e74086bac04c8a23f966bbd3e2a042 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 2 Mar 2024 15:59:01 +1100 Subject: [PATCH 16/79] commit messages table markup --- web/card_test.html | 111 ++++++++++++++ web/mockup.html | 354 +++++++++++++-------------------------------- 2 files changed, 213 insertions(+), 252 deletions(-) create mode 100644 web/card_test.html diff --git a/web/card_test.html b/web/card_test.html new file mode 100644 index 00000000..b9bbc043 --- /dev/null +++ b/web/card_test.html @@ -0,0 +1,111 @@ + + + + + + Bootstrap Card with Enhanced Header + + + + +
+
+
+
+ Messages +
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + IdStatusMessageable + Created At + + Updated AtActions
+ + 79b5c0a8-0954-41f4-b4b1-86e9e4af1963 + + unpublishedUser::12024-02-24 14:59:06 UTC2024-02-24 14:59:06 UTC + +
+ + +
+
+
+
+ +
+
+ + + diff --git a/web/mockup.html b/web/mockup.html index d90a216b..5a7d6315 100644 --- a/web/mockup.html +++ b/web/mockup.html @@ -48,51 +48,41 @@
-
- -
- -
-

Messages

-
- - -
- -
- - -
+
+ +
+ +
+

Messages

+
- -
-
- - -
-
- - + +
+
+
+
+ + +
+
+
-
-
-
-
+
@@ -113,11 +103,11 @@

Messages

- + @@ -127,14 +117,14 @@

Messages

@@ -151,14 +141,14 @@

Messages

@@ -175,204 +165,42 @@

Messages

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- + 79b5c0a8-0954-41f4-b4b1-86e9e4af1963 2024-02-24 14:59:06 UTC -
- - -
+
+ + +
2024-02-24 15:10:07 UTC -
- - -
+
+ + +
2024-02-24 15:20:08 UTC -
- - -
-
- - b4d5e607-0a29-45f6-9b3a-67f2eaaf1996 - - publishedUser::42024-02-24 15:30:09 UTC2024-02-24 15:30:09 UTC - -
- - -
-
- - c6e7f809-0b4a-46f7-abc4-78f3ebaf1a07 - - unpublishedUser::52024-02-24 15:40:10 UTC2024-02-24 15:40:10 UTC - -
- - -
-
- - d8f9g0ab-1c5b-48f8-bd2d-89f4fcac1b18 - - failedUser::62024-02-24 15:50:11 UTC2024-02-24 15:50:11 UTC - -
- - -
-
- - ea1fb2cd-2e6c-49f9-ce3e-9a5bfdad2c19 - - publishingUser::72024-02-24 16:00:12 UTC2024-02-24 16:00:12 UTC - -
- - -
-
- - fc1d2e3f-3f7d-50a0-de4f-ab6cdeaf3d20 - - publishedUser::82024-02-24 16:10:13 UTC2024-02-24 16:10:13 UTC - -
- - -
-
- - ge2f3g4h-4g8h-51b1-ef5g-cb7dfebg4e21 - - unpublishedUser::92024-02-24 16:20:14 UTC2024-02-24 16:20:14 UTC - -
- - -
-
- - hf3g4h5i-5i9j-62c2-fg6h-dc8efgci5f22 - - failedUser::102024-02-24 16:30:15 UTC2024-02-24 16:30:15 UTC - -
- - -
+
+ + +
- +
@@ -380,6 +208,28 @@

Messages

diff --git a/web/mockup_show.html b/web/mockup_show.html deleted file mode 100644 index 2992330d..00000000 --- a/web/mockup_show.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - Responsive Bootstrap 5.3 Table with Navigation - - - - - - - - - -
-
-
-

Message

-
-
- - -
-
- - -
-
- - - - - - - - - - - - - - - - - - -
IdMessage ID Here
StatusMessage Status Here
-
Exceptions
- - - - - - - - - - - - - - - - - - - - - - - -
Id949337b6-9440-47c6-96cb-ee39146e13f0
Message TextException Message 1
Class NameStandardError
-
Frames
- - - - - - - - - - - - - - - -
IndexText
1Error occurred in method 'send_email'
-
-
-
-
-
- - -
-
-
-

Message

-
-
- - - - - - - - - - - - - - - - - - - - - - - -
Id79b5c0a8-0954-41f4-b4b1-86e9e4af1963
Statusunpublished
MessageableUser::1
Created At2024-02-24 14:59:06 UTC
Updated At2024-02-24 14:59:06 UTC
- - -
-
Exceptions
-
- -
-

- -

-

- -

-
-
- - - - - - - - - - - - - - - - -
Id949337b6-9440-47c6-96cb-ee39146e13f0
Message TextException Message 1
Class NameStandardError
- - - - - - - - - - - - - - - - - -
IndexText
1Error occurred in method 'send_email'
-
-
-
- -
-
-
-
- - Back - -
- - - - - diff --git a/web/mockup_show_list_group.html b/web/mockup_show_list_group.html deleted file mode 100644 index 6aea0eef..00000000 --- a/web/mockup_show_list_group.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - Message Details - - - - - - - -
-
-
- Message -
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - -
ID123e4567-e89b-12d3-a456-426614174000
MessageableEvent::1
Statusunpublished
Created at2024-02-25 10:00:00
Updated at2024-02-25 10:00:00
- -
    - -
  • - StandardError - undefined method 'blah' -
      -
    • app/controllers/my_controller.rb:23:in `index`
    • -
    • app/models/my_model.rb:45:in `calculate`
    • -
    • app/helpers/my_helper.rb:10:in `format`
    • -
    -
  • - - -
  • - ArgumentError - wrong number of arguments -
      -
    • app/services/my_service.rb:30:in `execute`
    • -
    • app/controllers/another_controller.rb:52:in `show`
    • -
    • app/jobs/my_job.rb:15:in `perform`
    • -
    -
  • - -
-
-
-
- - - - - diff --git a/web/mockup_show_nested.html b/web/mockup_show_nested.html deleted file mode 100644 index 82974aa0..00000000 --- a/web/mockup_show_nested.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - Message Details - - - -
-
-
Message
-
-

ID: 123e4567-e89b-12d3-a456-426614174000

-

Status: Success

-

Created at: 2024-02-25 10:00:00

- - -
-
Exception
-
-

Class Name: StandardError

-

Message: undefined method 'blah'

- - -
-
Frames
-
    -
  • app/controllers/my_controller.rb:23:in `index`
  • -
  • app/models/my_model.rb:45:in `calculate`
  • -
  • app/helpers/my_helper.rb:10:in `format`
  • -
-
-
-
- - -
-
Exception
-
-

Class Name: ArgumentError

-

Message: wrong number of arguments

- - -
-
Frames
-
    -
  • app/services/my_service.rb:30:in `execute`
  • -
  • app/controllers/another_controller.rb:52:in `show`
  • -
  • app/jobs/my_job.rb:15:in `perform`
  • -
-
-
-
- -
-
-
- - - - From d8eb7fb8bda6d786569964e007a17c9b339567cb Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Wed, 6 Mar 2024 18:46:43 +1100 Subject: [PATCH 19/79] add working form --- web/messages.html | 78 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/web/messages.html b/web/messages.html index e7d12cba..f4d1cd4c 100644 --- a/web/messages.html +++ b/web/messages.html @@ -62,7 +62,6 @@ 10 messages have been deleted
-
@@ -76,22 +75,18 @@

Messages

-
-
+
+ - - +
-
@@ -109,10 +104,10 @@

Messages

- -
@@ -155,10 +150,13 @@

Messages

- -
@@ -179,10 +177,13 @@

Messages

- -
@@ -203,10 +204,13 @@

Messages

- -
@@ -268,6 +272,34 @@

Messages

checkAll.addEventListener('change', function () { toggleBulkActionsToolbar(); }); + + // Confirm before delete all + deleteAllBtn.addEventListener('click', function(e) { + e.preventDefault(); // Prevent the form from submitting if necessary + const confirmation = confirm('Are you sure you want to delete all?'); + if (!confirmation) { + return false; // Stop the function if the user clicks "Cancel" + } + // Place the code to delete all here if they click "OK" + }); + + // Confirm before retry all + retryAllBtn.addEventListener('click', function(e) { + e.preventDefault(); // Prevent the form from submitting if necessary + const confirmation = confirm('Are you sure you want to retry all?'); + if (!confirmation) { + return false; // Stop the function if the user clicks "Cancel" + } + // Place the code to retry all here if they click "OK" + }); + }); + + document.getElementById('checkAll').addEventListener('change', function (e) { + var checkboxes = document.querySelectorAll('.individual-check'); + for (var i = 0; i < checkboxes.length; i++) { + checkboxes[i].checked = e.target.checked; + } + }); From 739b6cd80212c42049d5793ff3b43abb531fbbaf Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Wed, 6 Mar 2024 20:08:07 +1100 Subject: [PATCH 20/79] make card-header responsive --- web/messages.html | 92 +++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/web/messages.html b/web/messages.html index f4d1cd4c..80472641 100644 --- a/web/messages.html +++ b/web/messages.html @@ -16,19 +16,6 @@ .custom-link:hover { text-decoration: underline; /* Adds underline on hover for better UX */ } - .btn-sm, .btn-label { - padding: 0.25rem 0.4rem; /* Slightly reduce padding */ - font-size: 0.8rem; /* Slightly reduce font size */ - } - .btn-label { - white-space: nowrap; - } - @media (max-width: 768px) { - /* Add margin to the bottom of the Messages header for small screens */ - .card-header .row > div:first-child { - margin-bottom: 0.5rem; - } - } @@ -67,47 +54,56 @@
-
- -
-

Messages

-
- -
-
-
- - -
-
- - -
-
- - -
+ +
+
+ +
+

Messages

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
-
+
+
+
+
- -
@@ -150,13 +146,13 @@

Messages

- -
@@ -177,13 +173,13 @@

Messages

- -
@@ -204,13 +200,13 @@

Messages

- -
From 22fab447dd0083b8c652086a52d0a5111898297f Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Thu, 7 Mar 2024 08:31:15 +1100 Subject: [PATCH 21/79] add changes --- web/messages.html | 53 +++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/web/messages.html b/web/messages.html index 80472641..f5837722 100644 --- a/web/messages.html +++ b/web/messages.html @@ -216,31 +216,38 @@

Messages

- From 26ce7488132bff91f237fe3f6c8a3d26b38ec2ee Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 10 Mar 2024 15:12:20 +1100 Subject: [PATCH 22/79] commit html --- web/app.rb | 127 +++++++++++++------------- web/messages.html | 226 ++++++++++++++++++++++++---------------------- 2 files changed, 181 insertions(+), 172 deletions(-) diff --git a/web/app.rb b/web/app.rb index a27e262e..8df42db6 100755 --- a/web/app.rb +++ b/web/app.rb @@ -15,8 +15,6 @@ module Outboxer class App < Sinatra::Base - set :method_override, true - get '/messages/unpublished' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 @@ -92,8 +90,32 @@ class App < Sinatra::Base } end + post '/messages/update' do + message_ids = params[:message_ids].map(&:to_i) + + case params[:submit] + when 'Retry Selected' + Messages.retry_selected(message_ids: message_ids) + when 'Delete Selected' + Messages.delete_selected(message_ids: message_ids) + else + raise "Unknown value: #{params[:submit]}" + end + + redirect to('/messages') + end + + post '/messages/retry_all' do + Messages.retry_all(message_ids: message_ids) - get '/messages/:id' do |id| + redirect to('/messages') + end + + post '/messages/delete_all' do + Messages.delete_all(message_ids: message_ids) + end + + get '/message/:id' do |id| messages_count = Models::Message.count message = Models::Message.includes(:exceptions).find(id) @@ -108,15 +130,7 @@ class App < Sinatra::Base end - post '/messages/search' do - text = params['text'] - - binding.pry - - redirect to('/messages') - end - - post '/messages/per_page' do + post '/messages/update_per_page' do page_number = params[:page_number] || 1 per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 order = %w[id status messageable created_at updated_at] @@ -126,10 +140,44 @@ class App < Sinatra::Base redirect "/messages?" \ "#{URI.encode_www_form_component('order')}=#{URI.encode_www_form_component(order)}&" \ "#{URI.encode_www_form_component('sort')}=#{URI.encode_www_form_component(sort)}&" \ - "#{URI.encode_www_form_component('page_number')}=#{URI.encode_www_form_component(page_number)}&" \ + "#{URI.encode_www_form_component('page')}=#{URI.encode_www_form_component(page)}&" \ "#{URI.encode_www_form_component('per_page')}=#{URI.encode_www_form_component(per_page)}" end + get '/messages' do + Messages.list( + status: params['status'], + sort: params['sort'], + order: params['order'], + page: params['page'].nil? , + per_page: params['per_page']) + + status = params['status'] || nil + sort = params['sort'] || 'created_at' + order = params['order'] || 'asc' + page = params['page'] || 1 + per_page = params['per_page'] || 100 + + status = params['status'] && params['status'].include?(['']) + per_page = [100, 200, 500, 1000].include?(params[:per_page]) ? params[:per_page] : 100 + + sort = ['id', 'status', 'messageable', 'created_at', 'updated_at'] + .include?(sort) ? params['sort'] : 'created_at' + + messages = status.nil? ? User.all : User.where(status: status) + + messages = + if sort == :messageable + messages.order(messageable_type: order, messageable_id: order) + else + messages.order(sort => order) + end + + messages = messages.paginate(page: page, per_page: per_page) + + messages + end + get '/messages' do messages = Models::Message @@ -167,7 +215,7 @@ class App < Sinatra::Base end - post '/messages/bulk_action' do + post '/messages/update' do bulk_action = params['bulk_action'] message_ids = params['message_ids'] @@ -185,64 +233,19 @@ class App < Sinatra::Base redirect to('/messages') end - delete '/messages/:id' do - redirect to('/table') - end - - patch '/messages/:id/retry' do + post '/message/:id/retry' do redirect to('/messages') end - get '/searches' do - q = Outboxer::Models::Message.ransack(params[:q]) - messages = q.result.includes(:outboxer_exceptions) - - erb :'searches/new', - locals: { q: q, messages: messages }, - layout: nil + post '/message/:id/delete' do + redirect to('/messages') end - post '/searches' do - q = Outboxer::Models::Message.ransack(params[:q]) - # messages = q.result.includes(:outboxer_exceptions) - - query_string = URI.encode_www_form(params[:q].to_h) - - redirect to("/searches?q=#{query_string}") - - # erb :'searches/new', - # locals: { q: q, messages: messages }, - # layout: nil - end get '/' do redirect to('/messages/all') end - # get '/:status' do |status| - # page = params[:page] || 1 - # limit = params[:limit] || 100 - # sort = %w[id status messageable_type messageable_id created_at updated_at] - # .include?(params[:sort]) ? params[:sort].to_sym : :created_at - # order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc - - # messages_scope = status == 'all' ? Models::Message : Models::Message.where(status: status) - # messages = messages_scope.order(sort => order).page(page).per(limit) - # messages_count = Models::Message.count - - # status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - # Models::Message.group(:status).count) - - # erb :'messages/index', locals: { - # status_counts: status_counts, - # messages_count: messages_count, - # messages: messages, - # page: page, - # limit: limit, - # sort: sort, - # order: order - # } - # end end end diff --git a/web/messages.html b/web/messages.html index f5837722..5fc390e5 100644 --- a/web/messages.html +++ b/web/messages.html @@ -52,64 +52,52 @@
-
- - - - -
-
- -
-

Messages

-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
-
-
-
-
+ - From d15d53d8ee29da661630a5feb6b5e9cc315bb112 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 23 Mar 2024 04:01:04 +1100 Subject: [PATCH 23/79] add messages/unpublished (wip) --- lib/outboxer/messages.rb | 23 +- .../messages/counts_by_status_spec.rb | 4 +- web/app.rb | 87 ++---- web/views/layout.erb | 132 ++++++--- web/views/messages.erb | 257 +++++++++++++----- 5 files changed, 314 insertions(+), 189 deletions(-) diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index d899755e..9a5efb36 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -10,12 +10,13 @@ class InvalidTransition < Error; end def counts_by_status ActiveRecord::Base.connection_pool.with_connection do - status_counts = Models::Message::STATUSES.each_with_object({}) do |status, hash| + status_counts = Models::Message::STATUSES.each_with_object({ 'all' => 0 }) do |status, hash| hash[status.to_s] = 0 end Models::Message.group(:status).count.each do |status, count| status_counts[status.to_s] = count + status_counts['all'] += count end status_counts @@ -44,7 +45,25 @@ def unpublished!(limit: 1, order: :asc) end end - def list(status: nil, sort: :updated_at, order: :asc, page: 1, per_page: 100) + STATUS = nil + SORT = :updated_at + ORDER = :asc + PAGE = 1 + PER_PAGE = 100 + + def unpublished(sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAGE) + list(status: Models::Message::Status::UNPUBLISHED) + end + + def publishing(sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAGE) + list(status: Models::Message::Status::PUBLISHING) + end + + def failed(sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAGE) + list(status: Models::Message::Status::FAILED) + end + + def list(status: STATUS, sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAGE) if !status.nil? && !Models::Message::STATUSES.include?(status.to_s) raise ArgumentError, "status must be #{Models::Message::STATUSES.join(' ')}" end diff --git a/spec/lib/outboxer/messages/counts_by_status_spec.rb b/spec/lib/outboxer/messages/counts_by_status_spec.rb index 42a11c46..fea0d79c 100644 --- a/spec/lib/outboxer/messages/counts_by_status_spec.rb +++ b/spec/lib/outboxer/messages/counts_by_status_spec.rb @@ -5,7 +5,7 @@ module Outboxer describe '.counts_by_status' do context 'when no messages exist' do it 'returns 0 for all statuses' do - expected_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 } + expected_counts = { 'all' => 0, 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 } expect(Outboxer::Messages.counts_by_status).to eq(expected_counts) end @@ -19,7 +19,7 @@ module Outboxer end it 'returns correct counts for each status' do - expected_counts = { 'unpublished' => 2, 'publishing' => 3, 'failed' => 4 } + expected_counts = { 'all' => 9, 'unpublished' => 2, 'publishing' => 3, 'failed' => 4 } expect(Messages.counts_by_status).to eq(expected_counts) end diff --git a/web/app.rb b/web/app.rb index 8df42db6..b635f8cc 100755 --- a/web/app.rb +++ b/web/app.rb @@ -16,88 +16,39 @@ module Outboxer class App < Sinatra::Base get '/messages/unpublished' do - page_number = params[:page_number] || 1 - per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at - order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + status_counts = Messages.counts_by_status - messages_scope = Models::Message.where(status: 'unpublished') - messages = messages_scope.order(sort => order).page(page_number).per(per_page) - messages_count = Models::Message.count + sort = params[:sort]|| Messages::SORT + order = params[:order] || Messages::ORDER + page = params[:page] || Messages::PAGE + per_page = params[:per_page] || Messages::PER_PAGE - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) + messages = Messages.unpublished(sort: sort, order: order, page: page, per_page: per_page) - erb :messages, layout: nil, locals: { + erb :messages, locals: { status_counts: status_counts, - messages_count: messages_count, messages: messages, - page_number: page_number, + page: page, per_page: per_page, sort: sort, order: order } end - get '/messages/publishing' do - page_number = params[:page_number] || 1 - per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - sort = %w[id status messageable created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at - order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + # get '/messages/publishing' do + # end - messages_scope = Models::Message.where(status: 'publishing') - messages = messages_scope.order(sort => order).page(page_number).per(per_page) - messages_count = Models::Message.count - - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :messages, layout: nil, locals: { - status_counts: status_counts, - messages_count: messages_count, - messages: messages, - page_number: page_number, - per_page: per_page, - sort: sort, - order: order - } - end - - get '/messages/failed' do - page_number = params[:page_number] || 1 - per_page = [100, 200, 500, 1000].include?(params[:per_page]) ? params[:per_page].to_i : 100 - sort = %w[id status messageable created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at - order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc - - messages_scope = Models::Message.where(status: 'failed') - messages = messages_scope.order(sort => order).page(page_number).per(per_page) - messages_count = Models::Message.count - - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :messages, layout: nil, locals: { - status_counts: status_counts, - messages_count: messages_count, - messages: messages, - page_number: page_number, - per_page: per_page, - sort: sort, - order: order - } - end + # get '/messages/failed' do + # end post '/messages/update' do - message_ids = params[:message_ids].map(&:to_i) + ids = params[:ids].map(&:to_i) case params[:submit] when 'Retry Selected' - Messages.retry_selected(message_ids: message_ids) + Messages.republish_selected!(ids: ids) when 'Delete Selected' - Messages.delete_selected(message_ids: message_ids) + Messages.delete_selected!(ids: ids) else raise "Unknown value: #{params[:submit]}" end @@ -105,14 +56,16 @@ class App < Sinatra::Base redirect to('/messages') end - post '/messages/retry_all' do - Messages.retry_all(message_ids: message_ids) + post '/messages/republish_all' do + ids = params[:ids].map(&:to_i) + + Messages.republish_all!(ids: ids) redirect to('/messages') end post '/messages/delete_all' do - Messages.delete_all(message_ids: message_ids) + Messages.delete_all!(batch_size: 100) end get '/message/:id' do |id| diff --git a/web/views/layout.erb b/web/views/layout.erb index 88dd0e77..b7b64244 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -1,67 +1,109 @@ + - Web App + Responsive Bootstrap 5.3 Table with Navigation - + + + -
+ + - <%= yield %>> + <%= yield %> - - + + + diff --git a/web/views/messages.erb b/web/views/messages.erb index ade679a3..17c0a0e5 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -1,96 +1,207 @@ - - - - - - Responsive Bootstrap 5.3 Table with Pagination and Filters - - - - - - -
-
Messages
- -
-
- -
-
- + +
+ + +
-
- -
- -
+
+
+ +
+
+
+
+
+ + + +
-
+ +
+
- - - - - + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + -
#First ColumnSecond ColumnThird Column + + IdStatusMessageable + Created At + + Updated AtActions
+ + 1 + + unpublishedEvent::12024-02-24 14:59:06 UTC2024-02-24 14:59:06 UTC + +
+ +
+ +
+ + +
+ +
+
+
1Data 1Data 2Data 3 + + 2 + + publishingEvent::22024-02-24 15:10:07 UTC2024-02-24 15:10:07 UTC + +
+ +
+ +
+ + +
+ +
+
+
+ + 3 + + failedEvent::32024-02-24 15:20:08 UTC2024-02-24 15:20:08 UTC + +
+ +
+ +
+ + +
+ +
+
+
- - -
- -
- - +
+
+
- - - - - +
From c09443b4cde1a9addee4b21b4de96e2dee520fa8 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 23 Mar 2024 05:02:51 +1100 Subject: [PATCH 24/79] commit changes (wip) --- Gemfile.lock | 10 ++ lib/outboxer/messages.rb | 4 +- outboxer.gemspec | 1 + web/app.rb | 216 +++++++++++++++++---------------------- web/views/layout.erb | 10 +- web/views/message.erb | 75 ++++++++++++++ web/views/messages.erb | 127 ++++++----------------- 7 files changed, 217 insertions(+), 226 deletions(-) create mode 100644 web/views/message.erb diff --git a/Gemfile.lock b/Gemfile.lock index 16cad296..1972aef5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,6 +52,7 @@ GEM erubi (1.12.0) factory_bot (6.4.6) activesupport (>= 5.0.0) + ffi (1.16.3) foreman (0.87.2) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -69,6 +70,9 @@ GEM kaminari-core (= 1.2.2) kaminari-core (1.2.2) language_server-protocol (3.17.0.3) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -121,9 +125,14 @@ GEM activerecord (>= 6.1.5) activesupport (>= 6.1.5) i18n + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) redis-client (0.19.1) connection_pool regexp_parser (2.8.1) + rerun (0.14.0) + listen (~> 3.0) rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) @@ -202,6 +211,7 @@ DEPENDENCIES rackup (~> 2.1) rake (~> 13.0) ransack (~> 4.1, >= 4.1.1) + rerun (~> 0.14.0) rspec rubocop (~> 1.55) sidekiq (~> 7.2) diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index 9a5efb36..e42dae8b 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -82,8 +82,8 @@ def list(status: STATUS, sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAG raise ArgumentError, "page must be >= 1" end - per_page_options = [100, 200, 500, 1000] - if !per_page_options.include?(per_page) + per_page_options = [10, 100, 200, 500, 1000] + if !per_page_options.include?(per_page.to_i) raise ArgumentError, "per_page must be #{per_page_options.join(' ')}" end diff --git a/outboxer.gemspec b/outboxer.gemspec index b09208f0..9bb59e88 100644 --- a/outboxer.gemspec +++ b/outboxer.gemspec @@ -38,5 +38,6 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'sidekiq', '~> 7.2', '>= 7.2.1' spec.add_development_dependency 'simplecov', '~> 0.22.0' spec.add_development_dependency 'factory_bot', '~> 6.4', '>= 6.4.6' + spec.add_development_dependency 'rerun', '~> 0.14.0' end # rubocop:enable Layout/LineLength diff --git a/web/app.rb b/web/app.rb index b635f8cc..eb9c4e76 100755 --- a/web/app.rb +++ b/web/app.rb @@ -15,8 +15,32 @@ module Outboxer class App < Sinatra::Base + get '/' do + redirect to('/messages/all') + end + + get '/messages/all' do + message_status_counts = Messages.counts_by_status + + sort = params[:sort] || Messages::SORT + order = params[:order] || Messages::ORDER + page = params[:page] || Messages::PAGE + per_page = params[:per_page] || Messages::PER_PAGE + + messages = Messages.list(sort: sort, order: order, page: page, per_page: per_page) + + erb :messages, locals: { + message_status_counts: message_status_counts, + messages: messages, + page: page, + per_page: per_page, + sort: sort, + order: order + } + end + get '/messages/unpublished' do - status_counts = Messages.counts_by_status + message_status_counts = Messages.counts_by_status sort = params[:sort]|| Messages::SORT order = params[:order] || Messages::ORDER @@ -26,7 +50,27 @@ class App < Sinatra::Base messages = Messages.unpublished(sort: sort, order: order, page: page, per_page: per_page) erb :messages, locals: { - status_counts: status_counts, + message_status_counts: message_status_counts, + messages: messages, + page: page, + per_page: per_page, + sort: sort, + order: order + } + end + + get '/messages/publishing' do + message_status_counts = Messages.counts_by_status + + sort = params[:sort]|| Messages::SORT + order = params[:order] || Messages::ORDER + page = params[:page] || Messages::PAGE + per_page = params[:per_page] || Messages::PER_PAGE + + messages = Messages.publishing(sort: sort, order: order, page: page, per_page: per_page) + + erb :messages, locals: { + message_status_counts: message_status_counts, messages: messages, page: page, per_page: per_page, @@ -35,17 +79,31 @@ class App < Sinatra::Base } end - # get '/messages/publishing' do - # end + get '/messages/failed' do + message_status_counts = Messages.counts_by_status - # get '/messages/failed' do - # end + sort = params[:sort]|| Messages::SORT + order = params[:order] || Messages::ORDER + page = params[:page] || Messages::PAGE + per_page = params[:per_page] || Messages::PER_PAGE + + messages = Messages.failed(sort: sort, order: order, page: page, per_page: per_page) + + erb :messages, locals: { + message_status_counts: message_status_counts, + messages: messages, + page: page, + per_page: per_page, + sort: sort, + order: order + } + end post '/messages/update' do ids = params[:ids].map(&:to_i) case params[:submit] - when 'Retry Selected' + when 'Republish Selected' Messages.republish_selected!(ids: ids) when 'Delete Selected' Messages.delete_selected!(ids: ids) @@ -53,153 +111,63 @@ class App < Sinatra::Base raise "Unknown value: #{params[:submit]}" end - redirect to('/messages') + redirect to('/messages/all') end post '/messages/republish_all' do - ids = params[:ids].map(&:to_i) - - Messages.republish_all!(ids: ids) + Messages.republish_all! - redirect to('/messages') + redirect to('/messages/all') end post '/messages/delete_all' do Messages.delete_all!(batch_size: 100) - end - - get '/message/:id' do |id| - messages_count = Models::Message.count - message = Models::Message.includes(:exceptions).find(id) - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :'messages/show', locals: { - status_counts: status_counts, - messages_count: messages_count, - message: message - } - end - - - post '/messages/update_per_page' do - page_number = params[:page_number] || 1 - per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - order = %w[id status messageable created_at updated_at] - .include?(params[:order]) ? params[:order].to_sym : :created_at - sort = %w[asc desc].include?(params[:sort]) ? params[:sort].to_sym : :asc - - redirect "/messages?" \ - "#{URI.encode_www_form_component('order')}=#{URI.encode_www_form_component(order)}&" \ - "#{URI.encode_www_form_component('sort')}=#{URI.encode_www_form_component(sort)}&" \ - "#{URI.encode_www_form_component('page')}=#{URI.encode_www_form_component(page)}&" \ - "#{URI.encode_www_form_component('per_page')}=#{URI.encode_www_form_component(per_page)}" + redirect to('/messages/all') end - get '/messages' do - Messages.list( - status: params['status'], - sort: params['sort'], - order: params['order'], - page: params['page'].nil? , - per_page: params['per_page']) - - status = params['status'] || nil - sort = params['sort'] || 'created_at' - order = params['order'] || 'asc' - page = params['page'] || 1 - per_page = params['per_page'] || 100 - - status = params['status'] && params['status'].include?(['']) - per_page = [100, 200, 500, 1000].include?(params[:per_page]) ? params[:per_page] : 100 - - sort = ['id', 'status', 'messageable', 'created_at', 'updated_at'] - .include?(sort) ? params['sort'] : 'created_at' - - messages = status.nil? ? User.all : User.where(status: status) + post '/messages/per_page' do + params_hash = { + 'order' => params[:order], + 'sort' => params[:sort], + 'page' => params[:page], + 'per_page' => params[:per_page] + } - messages = - if sort == :messageable - messages.order(messageable_type: order, messageable_id: order) - else - messages.order(sort => order) - end + filtered_params = params_hash.reject { |_, value| value.nil? || value.strip.empty? } - messages = messages.paginate(page: page, per_page: per_page) + query_string = URI.encode_www_form(filtered_params) - messages + redirect "/messages/all?#{query_string}" end - get '/messages' do - messages = Models::Message - - page_number = params[:page_number] || 1 - messages = messages.page(page_number) + get '/message/:id' do + message_status_counts = Messages.counts_by_status - per_page = [100, 200, 500, 1000].include?(params[:per_page].to_i) ? params[:per_page].to_i : 100 - messages = messages.per(per_page) + message = Message.find_by_id!(id: params[:id].to_i) - order = %w[asc desc].include?(params[:order]) ? params[:order].to_sym : :asc + halt 404, "Message not found" unless message - sort = %w[id status messageable created_at updated_at] - .include?(params[:sort]) ? params[:sort].to_sym : :created_at - - if sort == :messageable - messages.order(messageable_type: order, messageable_id: order).to_sql - else - messages = messages.order(sort => order) - end - - messages_count = Models::Message.count - - status_counts = { 'unpublished' => 0, 'publishing' => 0, 'failed' => 0 }.merge( - Models::Message.group(:status).count) - - erb :messages, layout: nil, locals: { - status_counts: status_counts, - messages_count: messages_count, - messages: messages, - order: order, - sort: sort, - page_number: page_number, - per_page: per_page + erb :message, locals: { + message_status_counts: message_status_counts, + message: message } end + post '/message/:id/republish' do + Message.republish!(id: params[:id]) - post '/messages/update' do - bulk_action = params['bulk_action'] - message_ids = params['message_ids'] - - binding.pry - - case bulk_action - when 'retry_selected' - # TODO - when 'delete_selected' - # TODO - else - raise "#{bulk_action} not supported" - end - - redirect to('/messages') - end - - post '/message/:id/retry' do - redirect to('/messages') + redirect to('/messages/all') end post '/message/:id/delete' do - redirect to('/messages') - end - + Message.delete!(id: params[:id]) - get '/' do redirect to('/messages/all') end - end end Outboxer::App.run! + +# bundle exec rerun 'ruby web/app.rb' diff --git a/web/views/layout.erb b/web/views/layout.erb index b7b64244..94e83ebe 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -23,23 +23,23 @@
+
- + + + +
+
From b2612b1ad47cdd2e8739f55c42a7e677e9a11d99 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 23 Mar 2024 05:14:59 +1100 Subject: [PATCH 25/79] fix nav links --- web/views/layout.erb | 8 ++++---- web/views/messages.erb | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/views/layout.erb b/web/views/layout.erb index 94e83ebe..6ee49537 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -30,16 +30,16 @@ diff --git a/web/views/messages.erb b/web/views/messages.erb index 13abb2fc..0fc3a5ba 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -61,9 +61,10 @@ Messageable Created At + + Updated At - Updated At Actions From 60e02754d089e76ce44ac223dfd065f972c850b0 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 23 Mar 2024 05:19:59 +1100 Subject: [PATCH 26/79] add flash --- Gemfile.lock | 3 +++ outboxer.gemspec | 1 + web/app.rb | 10 +++++++++- web/views/layout.erb | 4 +++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1972aef5..ecc0b9ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,6 +4,7 @@ PATH outboxer (0.1.11) activerecord (~> 7.0) kaminari (~> 1.2) + rack-flash3 (~> 1.0, >= 1.0.5) GEM remote: https://rubygems.org/ @@ -104,6 +105,8 @@ GEM nio4r (~> 2.0) racc (1.7.1) rack (3.0.8) + rack-flash3 (1.0.5) + rack rack-protection (4.0.0) base64 (>= 0.1.0) rack (>= 3.0.0, < 4) diff --git a/outboxer.gemspec b/outboxer.gemspec index 9bb59e88..a519fea7 100644 --- a/outboxer.gemspec +++ b/outboxer.gemspec @@ -30,6 +30,7 @@ Gem::Specification.new do |spec| spec.add_dependency "activerecord", "~> 7.0" spec.add_dependency 'kaminari', '~> 1.2' + spec.add_dependency 'rack-flash3', '~> 1.0', '>= 1.0.5' spec.add_development_dependency 'foreman', '~> 0.87.2' spec.add_development_dependency 'pry-byebug', '3.10' diff --git a/web/app.rb b/web/app.rb index eb9c4e76..7dc984e4 100755 --- a/web/app.rb +++ b/web/app.rb @@ -5,6 +5,7 @@ require 'kaminari' require 'ransack' require 'uri' +require 'rack/flash' require 'sinatra/reloader' require 'pry-byebug' @@ -15,6 +16,9 @@ module Outboxer class App < Sinatra::Base + enable :sessions + use Rack::Flash + get '/' do redirect to('/messages/all') end @@ -115,7 +119,11 @@ class App < Sinatra::Base end post '/messages/republish_all' do - Messages.republish_all! + # Messages.republish_all! + + republished_count = 0 + + flash[:notice] = "#{republished_count} messages have been republished." redirect to('/messages/all') end diff --git a/web/views/layout.erb b/web/views/layout.erb index 6ee49537..451d45e0 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -46,10 +46,12 @@
+ <% if flash[:notice] %> + <% end %> <%= yield %> From 86566d425a8b82513a336423e4cf079a6fc4a35e Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 31 Mar 2024 12:35:21 +1100 Subject: [PATCH 27/79] somewhat functioning ui --- db/seeds.rb | 36 -------------- lib/outboxer/messages.rb | 33 ++++++++----- web/app.rb | 22 ++++++--- web/sortable.html | 59 ++++++++++++++++++++++ web/tabs.html | 102 +++++++++++++++++++++++++++++++++++++++ web/views/message.erb | 9 ++-- web/views/messages.erb | 75 ++++++++++++++++++++-------- 7 files changed, 254 insertions(+), 82 deletions(-) create mode 100644 web/sortable.html create mode 100644 web/tabs.html diff --git a/db/seeds.rb b/db/seeds.rb index 2c6f2591..8ad83946 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,7 +1,6 @@ # require_relative '../app/models/message' # require_relative '../app/models/outboxer_exception' -<<<<<<< HEAD 600.times do |i| case i % 3 when 0 @@ -39,40 +38,5 @@ failed_message_exception.frames.create!( index: 2, text: "lib/active_record/transactions.rb:313:in `block in save!'" ) -======= -100.times do |i| - case i % 3 - when 0 - Outboxer::Models::Message.create!( - messageable_type: 'Event', - messageable_id: i, - status: Outboxer::Models::Message::Status::UNPUBLISHED) - when 1 - Outboxer::Models::Message.create!( - messageable_type: 'Event', - messageable_id: i, - status: Outboxer::Models::Message::Status::PUBLISHING) - else - failed_message = Outboxer::Models::Message.create!( - messageable_type: 'Event', - messageable_id: i, - status: Outboxer::Models::Message::Status::FAILED) - - failed_message_exception = failed_message.exceptions.create!( - class_name: 'ActiveRecord::RecordInvalid', - message_text: 'Validation failed: Exceptions is invalid') - - failed_message_exception.frames.create!( - index: 1, - text: "/lib/active_record/validations.rb:84:in `raise_validation_error'") - - failed_message_exception.frames.create!( - index: 2, - text: "/lib/active_record/validations.rb:55:in `save!'") - - failed_message_exception.frames.create!( - index: 3, - text: "lib/active_record/transactions.rb:313:in `block in save!'") ->>>>>>> master end end diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index e42dae8b..0b563aea 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -49,7 +49,7 @@ def unpublished!(limit: 1, order: :asc) SORT = :updated_at ORDER = :asc PAGE = 1 - PER_PAGE = 100 + PER_PAGE = 10 def unpublished(sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAGE) list(status: Models::Message::Status::UNPUBLISHED) @@ -97,19 +97,28 @@ def list(status: STATUS, sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAG message_scope.order(sort.to_sym => order.to_sym) end - messages = ActiveRecord::Base.connection_pool.with_connection do - message_scope.page(page).per(per_page) - end + result = {} - messages.map do |message| - { - 'id' => message.id, - 'status' => message.status, - 'messageable' => "#{message.messageable_type}::#{message.messageable_id}", - 'created_at' => message.created_at.utc.to_s, - 'updated_at' => message.updated_at.utc.to_s - } + ActiveRecord::Base.connection_pool.with_connection do + messages = message_scope.page(page).per(per_page) + + result['data'] = messages.map do |message| + { + 'id' => message.id, + 'status' => message.status, + 'messageable' => "#{message.messageable_type}::#{message.messageable_id}", + 'created_at' => message.created_at.utc.to_s, + 'updated_at' => message.updated_at.utc.to_s + } + end + + result['total_pages'] = messages.total_pages + result['current_page'] = messages.current_page + result['limit_value'] = messages.limit_value + result['total_count'] = messages.total_count end + + result end def republish_all!(batch_size: 100) diff --git a/web/app.rb b/web/app.rb index 7dc984e4..d6543f3b 100755 --- a/web/app.rb +++ b/web/app.rb @@ -28,8 +28,8 @@ class App < Sinatra::Base sort = params[:sort] || Messages::SORT order = params[:order] || Messages::ORDER - page = params[:page] || Messages::PAGE - per_page = params[:per_page] || Messages::PER_PAGE + page = params[:page]&.to_i || Messages::PAGE + per_page = params[:per_page]&.to_i || Messages::PER_PAGE messages = Messages.list(sort: sort, order: order, page: page, per_page: per_page) @@ -106,7 +106,7 @@ class App < Sinatra::Base post '/messages/update' do ids = params[:ids].map(&:to_i) - case params[:submit] + result = case params[:submit] when 'Republish Selected' Messages.republish_selected!(ids: ids) when 'Delete Selected' @@ -115,21 +115,23 @@ class App < Sinatra::Base raise "Unknown value: #{params[:submit]}" end + flash[:notice] = "#{result['count']} messages have been updated." + redirect to('/messages/all') end post '/messages/republish_all' do - # Messages.republish_all! - - republished_count = 0 + result = Messages.republish_all! - flash[:notice] = "#{republished_count} messages have been republished." + flash[:notice] = "#{result['count']} messages have been republished." redirect to('/messages/all') end post '/messages/delete_all' do - Messages.delete_all!(batch_size: 100) + result = Messages.delete_all!(batch_size: 100) + + flash[:notice] = "#{result['count']} messages have been deleted." redirect to('/messages/all') end @@ -165,12 +167,16 @@ class App < Sinatra::Base post '/message/:id/republish' do Message.republish!(id: params[:id]) + flash[:notice] = "message #{params[:id]} was republished." + redirect to('/messages/all') end post '/message/:id/delete' do Message.delete!(id: params[:id]) + flash[:notice] = "message #{params[:id]} was deleted." + redirect to('/messages/all') end end diff --git a/web/sortable.html b/web/sortable.html new file mode 100644 index 00000000..a15e504c --- /dev/null +++ b/web/sortable.html @@ -0,0 +1,59 @@ + + + + + + Sortable Table + + + + + + +
+ + + + + + + + + + + + +
+ + + + Id + + + + Status + + + + Messageable + + + + Created At + + + + Updated At + +
+
+ + + + + diff --git a/web/tabs.html b/web/tabs.html new file mode 100644 index 00000000..4add23c8 --- /dev/null +++ b/web/tabs.html @@ -0,0 +1,102 @@ + + + + + + + Responsive Bootstrap 5.3 Table with Navigation + + + + + + + + + +
+
+
+

Messages

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#MessageableUpdated AtCreated At
+ Publishing (5) +
1User2024-03-302024-03-29
2Admin2024-03-292024-03-28
3Support2024-03-282024-03-27
4Developer2024-03-272024-03-26
5Manager2024-03-262024-03-25
Queued (10)
6User A2024-03-242024-03-23
7User B2024-03-232024-03-22
8User C2024-03-222024-03-21
9User D2024-03-212024-03-20
10User E2024-03-202024-03-19
11User F2024-03-192024-03-18
12User G2024-03-182024-03-17
13User H2024-03-172024-03-16
14User I2024-03-162024-03-15
15User J2024-03-152024-03-14
Backlogged (105)
16User K2024-03-132024-03-12
17User L2024-03-122024-03-11
18User M2024-03-112024-03-10
19User N2024-03-102024-03-09
20User O2024-03-092024-03-08
21User P2024-03-082024-03-07
22User Q2024-03-072024-03-06
23User R2024-03-062024-03-05
24User S2024-03-052024-03-04
25User T2024-03-042024-03-03
Plus 95 more...
+
+
+
+
+ + diff --git a/web/views/message.erb b/web/views/message.erb index c1799cc3..7f67e929 100644 --- a/web/views/message.erb +++ b/web/views/message.erb @@ -1,20 +1,19 @@
-
+

Message <%= message['id'] %>

-
-
+
diff --git a/web/views/messages.erb b/web/views/messages.erb index 0fc3a5ba..f4dbfc35 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -48,28 +48,48 @@
+
- - - - - - - - - + + + + + + + - <% messages.each do |message| %> + <% messages['data'].each do |message| %> - - - - - - - - - - - - - - - - + diff --git a/web/views/home.erb b/web/views/home.erb new file mode 100644 index 00000000..539927c5 --- /dev/null +++ b/web/views/home.erb @@ -0,0 +1,59 @@ +
+
+
+

Messages

+
+
+
+
- - IdStatusMessageable - Created At - Updated At - - Actions
+ + + + Id + + + + Status + + + + Messageable + + + + Created At + + + + Updated At + +
@@ -115,11 +135,23 @@
@@ -130,6 +162,7 @@
Queued (10)
6User A2024-03-242024-03-23
7User B2024-03-232024-03-22
8User C2024-03-222024-03-21
9User D2024-03-212024-03-20
10User E2024-03-202024-03-19
11User F2024-03-192024-03-18
12User G2024-03-182024-03-17
13User H2024-03-172024-03-16
14User I2024-03-162024-03-15
15User J2024-03-152024-03-14
+ + + + + + + + + + + + + + + + + <% messages_publishing['data'].each do |message| %> + + + + + + + <% end %> + + + + + + + + + + <% messages_unpublished['data'].each do |message| %> + + + + + + + <% end %> + +
#MessageableUpdated AtCreated At
+ Publishing (<%= message_status_counts['publishing'] %>) +
<%= message['id'] %><%= message['messageable'] %><%= message['updated_at'] %><%= message['created_at'] %>
+ Unpublished (<%= message_status_counts['unpublished'] %>) +
<%= message['id'] %><%= message['messageable'] %><%= message['updated_at'] %><%= message['created_at'] %>
+
+
+
+
From 2dcbc3ee6fa0acd4c86807e1b6d98f0b6a625585 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 31 Mar 2024 16:07:19 +1100 Subject: [PATCH 29/79] add homepage --- db/seeds.rb | 27 +++++++++++++++++++++------ web/views/home.erb | 29 +++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index 520d73c8..59fb807d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,25 +1,40 @@ # require_relative '../app/models/message' # require_relative '../app/models/outboxer_exception' +now = Time.now +today = Time.new(now.year, now.month, now.day, 0, 0, 0, now.utc_offset) + 5.times do |i| + created_at = today - (i + 1).days + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds + Outboxer::Models::Message.create!( messageable_type: 'Event', - messageable_id: i, - status: Outboxer::Models::Message::Status::PUBLISHING) + messageable_id: i + 1, + status: Outboxer::Models::Message::Status::PUBLISHING, + created_at: created_at, + updated_at: created_at + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds) end 15.times do |i| + created_at = today - (i + 21).days + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds + Outboxer::Models::Message.create!( messageable_type: 'Event', - messageable_id: i + 5, - status: Outboxer::Models::Message::Status::UNPUBLISHED) + messageable_id: i + 6, + status: Outboxer::Models::Message::Status::UNPUBLISHED, + created_at: created_at, + updated_at: created_at + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds) end 5.times do |i| + created_at = today - (i + 30).days + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds + failed_message = Outboxer::Models::Message.create!( messageable_type: 'Event', - messageable_id: i + 20, - status: Outboxer::Models::Message::Status::FAILED) + messageable_id: i + 21, + status: Outboxer::Models::Message::Status::FAILED, + created_at: created_at, + updated_at: created_at + rand(0..23).hours + rand(0..59).minutes + rand(0..59).seconds) failed_message_exception = failed_message.exceptions.create!( class_name: 'ActiveRecord::RecordInvalid', diff --git a/web/views/home.erb b/web/views/home.erb index 539927c5..8e1209ac 100644 --- a/web/views/home.erb +++ b/web/views/home.erb @@ -8,10 +8,13 @@ - + + - + @@ -24,12 +27,17 @@ - <% messages_publishing['data'].each do |message| %> + <% messages_publishing['data'].each_with_index do |message, index| %> - + + - + <% end %> @@ -43,12 +51,17 @@ - <% messages_unpublished['data'].each do |message| %> + <% messages_unpublished['data'].each_with_index do |message, index| %> - + + - + <% end %> From bf218280db2ae55082f7f11c18060d0e76cb2d4d Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 6 Apr 2024 22:00:42 +1100 Subject: [PATCH 30/79] remove unused files --- web/card_test.html | 111 ------------- web/index.html | 71 --------- web/message.html | 186 ---------------------- web/messages.html | 314 ------------------------------------- web/sortable.html | 59 ------- web/tabs.html | 102 ------------ web/views/searches/new.erb | 114 -------------- 7 files changed, 957 deletions(-) delete mode 100644 web/card_test.html delete mode 100644 web/index.html delete mode 100644 web/message.html delete mode 100644 web/messages.html delete mode 100644 web/sortable.html delete mode 100644 web/tabs.html delete mode 100644 web/views/searches/new.erb diff --git a/web/card_test.html b/web/card_test.html deleted file mode 100644 index 320bdc4a..00000000 --- a/web/card_test.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - Bootstrap Card with Enhanced Header - - - - -
-
-
-
- Messages -
-
- -
- - -
-
-
-
-
- -
#OrderId MessageableUpdated At Created At + Updated At +
<%= message['id'] %><%= index + 1 %> + + <%= message['id'] %> + + <%= message['messageable'] %><%= message['updated_at'] %> <%= message['created_at'] %><%= message['updated_at'] %>
<%= message['id'] %><%= messages_publishing['data'].count + index + 1 %> + + <%= message['id'] %> + + <%= message['messageable'] %><%= message['updated_at'] %> <%= message['created_at'] %><%= message['updated_at'] %>
- - - - - - - - - - - - - - - - - - - - - - - - -
- - IdStatusMessageable - Created At - - Updated AtActions
- - 79b5c0a8-0954-41f4-b4b1-86e9e4af1963 - - unpublishedUser::12024-02-24 14:59:06 UTC2024-02-24 14:59:06 UTC - -
- - -
-
- - - - - - - - diff --git a/web/index.html b/web/index.html deleted file mode 100644 index 6eb4f8af..00000000 --- a/web/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - Web App - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
IDStatusMessageable IDMessageable TypeCreated AtUpdated At
1unpublishedEvent12024-01-31 12:53:192024-01-31 12:53:19
-
- - - - - diff --git a/web/message.html b/web/message.html deleted file mode 100644 index 5678e0f0..00000000 --- a/web/message.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - Message Details - - - - - - - - - - -
-
-
-

Message 1

-
- - -
-
-
- - - - - - - - - - - - - - - - - - - -
MessageableEvent::1
Statusfailed
Created at2024-02-25 10:00:00
Updated at2024-02-25 11:30:00
- -
- -
-

- -

-
-
-
    -
  • 1: app/controllers/my_controller.rb:23:in `index`
  • -
  • 2: app/models/my_model.rb:45:in `calculate`
  • -
  • 3: app/helpers/my_helper.rb:10:in `format`
  • -
-
-
-
- -
-

- -

-
-
-
    -
  • 4: app/services/my_service.rb:30:in `execute`
  • -
  • 5: app/controllers/another_controller.rb:52:in `show`
  • -
  • 6: app/jobs/my_job.rb:15:in `perform`
  • -
-
-
-
-
-
-
-
- - - - - diff --git a/web/messages.html b/web/messages.html deleted file mode 100644 index 5fc390e5..00000000 --- a/web/messages.html +++ /dev/null @@ -1,314 +0,0 @@ - - - - - - Responsive Bootstrap 5.3 Table with Navigation - - - - - - - - - - - -
- -
-
- -
-
- -
-

Messages

-
- - -
-
- - -
-
- - -
-
-
-
-
- -
-
-
-
-
- - - - -
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - IdStatusMessageable - Created At - - Updated AtActions
- - 1 - - unpublishedEvent::12024-02-24 14:59:06 UTC2024-02-24 14:59:06 UTC - -
- -
- -
- - -
- -
-
-
- - 2 - - publishingEvent::22024-02-24 15:10:07 UTC2024-02-24 15:10:07 UTC - -
- -
- -
- - -
- -
-
-
- - 3 - - failedEvent::32024-02-24 15:20:08 UTC2024-02-24 15:20:08 UTC - -
- -
- -
- - -
- -
-
-
-
-
- -
-
- - - - - - - diff --git a/web/sortable.html b/web/sortable.html deleted file mode 100644 index a15e504c..00000000 --- a/web/sortable.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - Sortable Table - - - - - - -
- - - - - - - - - - - - -
- - - - Id - - - - Status - - - - Messageable - - - - Created At - - - - Updated At - -
-
- - - - - diff --git a/web/tabs.html b/web/tabs.html deleted file mode 100644 index 03fef3ff..00000000 --- a/web/tabs.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - Responsive Bootstrap 5.3 Table with Navigation - - - - - - - - - -
-
-
-

Messages

-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#MessageableUpdated AtCreated At
- Publishing (5) -
1User2024-03-302024-03-29
2Admin2024-03-292024-03-28
3Support2024-03-282024-03-27
4Developer2024-03-272024-03-26
5Manager2024-03-262024-03-25
Backlogged (105)
16User K2024-03-132024-03-12
17User L2024-03-122024-03-11
18User M2024-03-112024-03-10
19User N2024-03-102024-03-09
20User O2024-03-092024-03-08
21User P2024-03-082024-03-07
22User Q2024-03-072024-03-06
23User R2024-03-062024-03-05
24User S2024-03-052024-03-04
25User T2024-03-042024-03-03
Plus 95 more...
-
-
-
-
- - diff --git a/web/views/searches/new.erb b/web/views/searches/new.erb deleted file mode 100644 index ea84e61f..00000000 --- a/web/views/searches/new.erb +++ /dev/null @@ -1,114 +0,0 @@ - - - - Search Messages - - - -
-

Search Messages

- -
- -
-

Message Search

-
-
- - <% Outboxer::Models::Message::STATUSES.each do |status| %> -
- - -
- <% end %> -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
- - -
-
- - -
-
- - -
-
- - -
- - -
-

Exception Search

-
-
- -
-
- -
-
- -
-
-
- - -
- -
- - - - <% if messages.any? %> - <% messages.each do |message| %> -
-
-
Message ID: <%= message.id %>
-

Status: <%= message.status %>

-

Messageable Type: <%= message.messageable_type %>

-

Messageable ID: <%= message.messageable_id %>

-

Created At: <%= message.created_at %>

- - <% if message.outboxer_exceptions.any? %> -
Exceptions:
- <% message.outboxer_exceptions.each do |exception| %> -

Exception Class: <%= exception.class_name %>

-

Exception Message: <%= exception.message_text %>

- <% end %> - <% end %> -
-
- <% end %> - <% else %> -

No results found

- <% end %> -
- - - - From 396758cb7bb95133385c16a30d5a3272dc859ed2 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 6 Apr 2024 22:02:38 +1100 Subject: [PATCH 31/79] remove ransack --- Gemfile | 1 - Gemfile.lock | 5 ----- lib/outboxer/models/message.rb | 8 -------- web/app.rb | 1 - 4 files changed, 15 deletions(-) diff --git a/Gemfile b/Gemfile index c2f8db49..4c15ad1d 100644 --- a/Gemfile +++ b/Gemfile @@ -26,4 +26,3 @@ gem 'sinatra', '~> 4.0' gem 'sinatra-contrib' gem 'puma', '~> 6.4', '>= 6.4.2' gem 'kaminari', '~> 1.2', '>= 1.2.2' -gem 'ransack', '~> 4.1', '>= 4.1.1' diff --git a/Gemfile.lock b/Gemfile.lock index ecc0b9ed..023bbf40 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,10 +124,6 @@ GEM nokogiri (~> 1.14) rainbow (3.1.1) rake (13.0.6) - ransack (4.1.1) - activerecord (>= 6.1.5) - activesupport (>= 6.1.5) - i18n rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) @@ -213,7 +209,6 @@ DEPENDENCIES puma (~> 6.4, >= 6.4.2) rackup (~> 2.1) rake (~> 13.0) - ransack (~> 4.1, >= 4.1.1) rerun (~> 0.14.0) rspec rubocop (~> 1.55) diff --git a/lib/outboxer/models/message.rb b/lib/outboxer/models/message.rb index 97369650..371cc602 100644 --- a/lib/outboxer/models/message.rb +++ b/lib/outboxer/models/message.rb @@ -41,14 +41,6 @@ module Status foreign_key: 'message_id', class_name: "Outboxer::Models::Exception", dependent: :destroy - - def self.ransackable_attributes(auth_object = nil) - ["created_at", "id", "id_value", "messageable_id", "messageable_type", "status", "updated_at"] - end - - def self.ransackable_associations(auth_object = nil) - ["messageable", "outboxer_exceptions"] - end end end end diff --git a/web/app.rb b/web/app.rb index bf3bb133..818743f9 100755 --- a/web/app.rb +++ b/web/app.rb @@ -3,7 +3,6 @@ require 'outboxer' require 'sinatra/base' require 'kaminari' -require 'ransack' require 'uri' require 'rack/flash' From 5fbaa41d77034358fcb93402bed3585e068f527b Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 6 Apr 2024 22:06:52 +1100 Subject: [PATCH 32/79] minimise changes --- lib/outboxer/messages.rb | 25 +++++++++++-------------- lib/outboxer/models/message.rb | 8 ++++---- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index 95f5359e..5a340cab 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -101,12 +101,12 @@ def list(status: STATUS, sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAG message_scope.order(sort.to_sym => order.to_sym) end - result = {} - - ActiveRecord::Base.connection_pool.with_connection do - messages = message_scope.page(page).per(per_page) + messages = ActiveRecord::Base.connection_pool.with_connection do + message_scope.page(page).per(per_page) + end - result[:data] = messages.map do |message| + { + data: messages.map do |message| { id: message.id, status: message.status, @@ -115,15 +115,12 @@ def list(status: STATUS, sort: SORT, order: ORDER, page: PAGE, per_page: PER_PAG created_at: message.created_at.utc.to_s, updated_at: message.updated_at.utc.to_s } - end - - result[:total_pages] = messages.total_pages - result[:current_page] = messages.current_page - result[:limit_value] = messages.limit_value - result[:total_count] = messages.total_count - end - - result + end, + total_pages: messages.total_pages, + current_page: messages.current_page, + limit_value: messages.limit_value, + total_count: messages.total_count + } end def republish_all(batch_size: 100) diff --git a/lib/outboxer/models/message.rb b/lib/outboxer/models/message.rb index 371cc602..e272486a 100644 --- a/lib/outboxer/models/message.rb +++ b/lib/outboxer/models/message.rb @@ -37,10 +37,10 @@ module Status belongs_to :messageable, polymorphic: true has_many :exceptions, - -> { order(created_at: :asc) }, - foreign_key: 'message_id', - class_name: "Outboxer::Models::Exception", - dependent: :destroy + -> { order(created_at: :asc) }, + foreign_key: 'message_id', + class_name: "Outboxer::Models::Exception", + dependent: :destroy end end end From a81d5a2cbf97c8257baee93db14df085ab79c38c Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 6 Apr 2024 22:07:58 +1100 Subject: [PATCH 33/79] update rack --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 023bbf40..718030c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -104,7 +104,7 @@ GEM puma (6.4.2) nio4r (~> 2.0) racc (1.7.1) - rack (3.0.8) + rack (3.0.10) rack-flash3 (1.0.5) rack rack-protection (4.0.0) From 7e0f02df2fec75cfa02e0173fa586fb5b47c3aeb Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sun, 7 Apr 2024 16:57:17 +1000 Subject: [PATCH 34/79] fix broken UI --- bin/outboxer_message_publisher | 10 ++++++++-- web/app.rb | 20 ++++++++++---------- web/views/messages.erb | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/bin/outboxer_message_publisher b/bin/outboxer_message_publisher index b1f8e882..b1d27f09 100755 --- a/bin/outboxer_message_publisher +++ b/bin/outboxer_message_publisher @@ -13,10 +13,16 @@ end Signal.trap('INT') { Outboxer::Message.stop_publishing } -Outboxer::Message.publish(threads: 25, queue: 100, poll: 0.1) do |message| +Outboxer::Message.publish( + threads: 25, + queue: 100, + poll: 0.1, + logger: Logger.new($stdout, level: Logger::WARN) +) do |message| case message[:messageable_type] when 'Event' - EventCreatedJob.perform_async({ 'id' => message[:messageable_id] }) + sleep rand + # EventCreatedJob.perform_async({ 'id' => message[:messageable_id] }) end end diff --git a/web/app.rb b/web/app.rb index 818743f9..7483908e 100755 --- a/web/app.rb +++ b/web/app.rb @@ -147,30 +147,30 @@ class App < Sinatra::Base result = case params[:submit] when 'Republish Selected' - Messages.republish_selected!(ids: ids) + Messages.republish_selected(ids: ids) when 'Delete Selected' - Messages.delete_selected!(ids: ids) + Messages.delete_selected(ids: ids) else raise "Unknown value: #{params[:submit]}" end - flash[:notice] = "#{result['count']} messages have been updated." + flash[:notice] = "#{result[:count]} messages have been updated." redirect to('/messages/all') end post '/messages/republish_all' do - result = Messages.republish_all! + result = Messages.republish_all - flash[:notice] = "#{result['count']} messages have been republished." + flash[:notice] = "#{result[:count]} messages have been republished." redirect to('/messages/all') end post '/messages/delete_all' do - result = Messages.delete_all!(batch_size: 100) + result = Messages.delete_all(batch_size: 100) - flash[:notice] = "#{result['count']} messages have been deleted." + flash[:notice] = "#{result[:count]} messages have been deleted." redirect to('/messages/all') end @@ -193,7 +193,7 @@ class App < Sinatra::Base get '/message/:id' do message_status_counts = Messages.counts_by_status - message = Message.find_by_id!(id: params[:id].to_i) + message = Message.find_by_id(id: params[:id].to_i) halt 404, "Message not found" unless message @@ -204,7 +204,7 @@ class App < Sinatra::Base end post '/message/:id/republish' do - Message.republish!(id: params[:id]) + Message.republish(id: params[:id]) flash[:notice] = "message #{params[:id]} was republished." @@ -212,7 +212,7 @@ class App < Sinatra::Base end post '/message/:id/delete' do - Message.delete!(id: params[:id]) + Message.delete(id: params[:id]) flash[:notice] = "message #{params[:id]} was deleted." diff --git a/web/views/messages.erb b/web/views/messages.erb index cb91c276..0c18f7de 100644 --- a/web/views/messages.erb +++ b/web/views/messages.erb @@ -18,7 +18,7 @@ Republish All -
+
- From c07301721c421719d988e8bff73e57297ff48ae9 Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Thu, 25 Apr 2024 21:31:53 +1000 Subject: [PATCH 36/79] fix filtering --- lib/outboxer/messages.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index bf8b8a53..e60fec13 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -45,8 +45,8 @@ def queue(limit: 1) end DEFAULT_STATUS = nil - DEFAULT_SORT = :updated_at - DEFAULT_ORDER = :asc + DEFAULT_SORT = 'updated_at' + DEFAULT_ORDER = 'asc' DEFAULT_PAGE = 1 DEFAULT_PER_PAGE = 100 @@ -57,13 +57,13 @@ def paginate(status: DEFAULT_STATUS, raise ArgumentError, "status must be #{Models::Message::STATUSES.join(' ')}" end - sort_options = [:id, :status, :messageable, :created_at, :updated_at] - if !sort_options.include?(sort.to_sym) + sort_options = ['id', 'status', 'messageable', 'created_at', 'updated_at'] + if !sort_options.include?(sort) raise ArgumentError, "sort must be #{sort_options.join(' ')}" end - order_options = [:asc, :desc] - if !order_options.include?(order.to_sym) + order_options = ['asc', 'desc'] + if !order_options.include?(order) raise ArgumentError, "order must be #{order_options.join(' ')}" end @@ -80,10 +80,10 @@ def paginate(status: DEFAULT_STATUS, message_scope = status.nil? ? message_scope.all : message_scope.where(status: status) message_scope = - if sort.to_sym == :messageable - message_scope.order(messageable_type: order.to_sym, messageable_id: order.to_sym) + if sort == 'messageable' + message_scope.order(messageable_type: order, messageable_id: order) else - message_scope.order(sort.to_sym => order.to_sym) + message_scope.order(sort => order) end messages = ActiveRecord::Base.connection_pool.with_connection do From cf1130a2f6c4568751b9ecaf4d52b25610d5f9bf Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Thu, 25 Apr 2024 21:38:06 +1000 Subject: [PATCH 37/79] fix per page bug --- web/app.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/web/app.rb b/web/app.rb index 3a77e46c..39c0e4d4 100755 --- a/web/app.rb +++ b/web/app.rb @@ -221,21 +221,21 @@ def normalise_params(status: Messages::DEFAULT_STATUS, end post '/messages/update_per_page' do - status = params[:status] || Messages::DEFAULT_STATUS - sort = params[:sort] || Messages::DEFAULT_SORT - order = params[:order] || Messages::DEFAULT_ORDER - page = params[:page]&.to_i || Messages::DEFAULT_PAGE - per_page = params[:per_page]&.to_i || Messages::DEFAULT_PER_PAGE + denormalised_params = denormalise_params( + status: params[:status], + sort: params[:sort], + order: params[:order], + page: params[:page]&.to_i, + per_page: params[:per_page]&.to_i) - query_params = URI.encode_www_form({ - status: status == Messages::DEFAULT_STATUS ? nil : status, - sort: sort == Messages::DEFAULT_SORT ? nil : sort, - order: order == Messages::DEFAULT_ORDER ? nil : order, - page: page == Messages::DEFAULT_PAGE ? nil : order, - per_page: per_page == Messages::DEFAULT_PER_PAGE ? nil : per_page - }.compact) + normalised_params = normalise_params( + status: denormalised_params[:status], + sort: denormalised_params[:sort], + order: denormalised_params[:order], + page: denormalised_params[:page], + per_page: denormalised_params[:per_page]) - redirect "/messages?#{query_params}" + redirect "/messages#{normalised_params}" end get '/message/:id' do From a8b6afc5d9ade46ed07fc5dc92612b96eaab445a Mon Sep 17 00:00:00 2001 From: bedrock-adam Date: Sat, 27 Apr 2024 13:25:57 +1000 Subject: [PATCH 38/79] fix bugs --- lib/outboxer/message.rb | 24 +++++++++++++---------- lib/outboxer/messages.rb | 4 ++-- web/app.rb | 33 ++++++++++++++++--------------- web/views/home.erb | 8 ++++---- web/views/layout.erb | 4 ++-- web/views/message.erb | 24 ++++++++++++++--------- web/views/messages.erb | 42 ++++++++++++++++++++++++++-------------- 7 files changed, 82 insertions(+), 57 deletions(-) diff --git a/lib/outboxer/message.rb b/lib/outboxer/message.rb index 0d4500db..255c06f2 100644 --- a/lib/outboxer/message.rb +++ b/lib/outboxer/message.rb @@ -5,10 +5,14 @@ module Message def backlog(messageable_type:, messageable_id:) ActiveRecord::Base.connection_pool.with_connection do ActiveRecord::Base.transaction do + current_time = Time.now.utc + message = Models::Message.create!( messageable_id: messageable_id, messageable_type: messageable_type, - status: Models::Message::Status::BACKLOGGED) + status: Models::Message::Status::BACKLOGGED, + created_at: current_time, + updated_at: current_time) { id: message.id } end @@ -60,7 +64,9 @@ def publishing(id:) "from #{message.status} to #{Models::Message::Status::PUBLISHING}" end - message.update!(status: Models::Message::Status::PUBLISHING) + message.update!( + status: Models::Message::Status::PUBLISHING, + updated_at: Time.now.utc) { id: id, @@ -104,7 +110,9 @@ def failed(id:, exception:) "from #{message.status} to #{Models::Message::Status::FAILED}" end - message.update!(status: Models::Message::Status::FAILED) + message.update!( + status: Models::Message::Status::FAILED, + updated_at: Time.now.utc) outboxer_exception = message.exceptions.create!( class_name: exception.class.name, message_text: exception.message) @@ -137,13 +145,9 @@ def republish(id:) ActiveRecord::Base.transaction do message = Models::Message.lock.find_by!(id: id) - if message.status != Models::Message::Status::FAILED - raise InvalidTransition, - "cannot transition outboxer message #{id} " \ - "from #{message.status} to #{Models::Message::Status::BACKLOGGED}" - end - - message.update!(status: Models::Message::Status::BACKLOGGED) + message.update!( + status: Models::Message::Status::BACKLOGGED, + updated_at: Time.now.utc) { id: id } end diff --git a/lib/outboxer/messages.rb b/lib/outboxer/messages.rb index e60fec13..d87a1341 100644 --- a/lib/outboxer/messages.rb +++ b/lib/outboxer/messages.rb @@ -125,7 +125,7 @@ def republish_all_failed(batch_size: 100) republished_count_batch = Models::Message .where(id: locked_ids) - .update_all(status: Models::Message::Status::BACKLOGGED, updated_at: DateTime.now.utc) + .update_all(status: Models::Message::Status::BACKLOGGED, updated_at: Time.now.utc) republished_count += republished_count_batch end @@ -148,7 +148,7 @@ def republish_selected(ids:) republished_count = Models::Message .where(id: locked_ids) - .update_all(status: Models::Message::Status::BACKLOGGED, updated_at: DateTime.now.utc) + .update_all(status: Models::Message::Status::BACKLOGGED, updated_at: Time.now.utc) { republished_count: republished_count, not_republished_ids: ids - locked_ids } end diff --git a/web/app.rb b/web/app.rb index 39c0e4d4..62c49e17 100755 --- a/web/app.rb +++ b/web/app.rb @@ -21,14 +21,14 @@ class App < Sinatra::Base get '/' do message_status_counts = Messages.counts_by_status - messages_publishing = Messages.publishing( - sort: :updated_at, order: :asc, page: 1, per_page: 100) + messages_publishing = Messages.paginate( + status: 'publishing', sort: 'updated_at', order: 'asc', page: 1, per_page: 100) - messages_queued = Messages.queued( - sort: :updated_at, order: :asc, page: 1, per_page: 100) + messages_queued = Messages.paginate( + status: 'queued', sort: 'updated_at', order: 'asc', page: 1, per_page: 100) - messages_backlogged = Messages.backlogged( - sort: :updated_at, order: :asc, page: 1, per_page: 100) + messages_backlogged = Messages.paginate( + status: 'backlogged', sort: 'updated_at', order: 'asc', page: 1, per_page: 100) erb :home, locals: { message_status_counts: message_status_counts, @@ -65,6 +65,7 @@ class App < Sinatra::Base messages: paginated_messages[:messages], headers: generate_headers(params: denormalised_params), pagination: pagination, + normalised_params: denormalised_params, per_page: params[:per_page]&.to_i || Messages::DEFAULT_PER_PAGE } end @@ -144,7 +145,7 @@ def generate_headers(params:) else { text: header_text, - icon_class: 'bi bi-arrow-down-up', + icon_class: '', href: 'messages' + normalise_params( status: params[:status], order: 'asc', @@ -188,12 +189,12 @@ def normalise_params(status: Messages::DEFAULT_STATUS, end post '/messages/update' do - ids = params[:ids].map(&:to_i) + ids = params[:selected_ids].map(&:to_i) - result = case params[:submit] - when 'Republish Selected' + result = case params[:action] + when 'republish_selected' Messages.republish_selected(ids: ids) - when 'Delete Selected' + when 'delete_selected' Messages.delete_selected(ids: ids) else raise "Unknown value: #{params[:submit]}" @@ -201,7 +202,7 @@ def normalise_params(status: Messages::DEFAULT_STATUS, flash[:notice] = "#{result[:count]} messages have been updated." - redirect to('/messages/all') + redirect to('/messages') end post '/messages/republish_all' do @@ -209,7 +210,7 @@ def normalise_params(status: Messages::DEFAULT_STATUS, flash[:notice] = "#{result[:count]} messages have been republished." - redirect to('/messages/all') + redirect to('/messages') end post '/messages/delete_all' do @@ -217,7 +218,7 @@ def normalise_params(status: Messages::DEFAULT_STATUS, flash[:notice] = "#{result[:count]} messages have been deleted." - redirect to('/messages/all') + redirect to('/messages') end post '/messages/update_per_page' do @@ -256,7 +257,7 @@ def normalise_params(status: Messages::DEFAULT_STATUS, flash[:notice] = "message #{params[:id]} was republished." - redirect to('/messages/all') + redirect to('/messages') end post '/message/:id/delete' do @@ -264,7 +265,7 @@ def normalise_params(status: Messages::DEFAULT_STATUS, flash[:notice] = "message #{params[:id]} was deleted." - redirect to('/messages/all') + redirect to('/messages') end end end diff --git a/web/views/home.erb b/web/views/home.erb index 3fe74fe5..b976ac63 100644 --- a/web/views/home.erb +++ b/web/views/home.erb @@ -27,7 +27,7 @@ - <% messages_publishing[:data].each_with_index do |message, index| %> + <% messages_publishing[:messages].each_with_index do |message, index| %> <%= index + 1 %> @@ -51,7 +51,7 @@ - <% messages_queued[:data].each_with_index do |message, index| %> + <% messages_queued[:messages].each_with_index do |message, index| %> <%= messages_publishing[:data].count + index + 1 %> @@ -75,9 +75,9 @@ - <% messages_backlogged[:data].each_with_index do |message, index| %> + <% messages_backlogged[:messages].each_with_index do |message, index| %> - <%= messages_publishing[:data].count + messages_queued[:data].count + index + 1 %> + <%= messages_publishing[:messages].count + messages_queued[:messages].count + index + 1 %> <%= message[:id] %> diff --git a/web/views/layout.erb b/web/views/layout.erb index b8d5f406..a6e2f265 100644 --- a/web/views/layout.erb +++ b/web/views/layout.erb @@ -33,13 +33,13 @@ All (<%= message_status_counts[:all] %>)