workarea 3.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (571) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +326 -0
  3. data/CHANGELOG.md +20501 -0
  4. data/README.md +163 -0
  5. data/docker-compose.yml +27 -0
  6. data/docs/Gemfile +8 -0
  7. data/docs/bin/middleman +29 -0
  8. data/docs/config.rb +87 -0
  9. data/docs/config.ru +7 -0
  10. data/docs/data/articles.yml +157 -0
  11. data/docs/package.json +15 -0
  12. data/docs/source/404.html.erb +13 -0
  13. data/docs/source/articles/access-routes-in-javascript.html.md +33 -0
  14. data/docs/source/articles/add-a-content-area.html.md +169 -0
  15. data/docs/source/articles/add-a-content-block-type.html.md +334 -0
  16. data/docs/source/articles/add-a-report.html.md +202 -0
  17. data/docs/source/articles/add-css-through-the-admin-ui.html.md +30 -0
  18. data/docs/source/articles/add-javascript-through-a-manifest.html.md +367 -0
  19. data/docs/source/articles/add-javascript-through-a-view.html.md +80 -0
  20. data/docs/source/articles/add-javascript-through-the-admin-ui.html.md +30 -0
  21. data/docs/source/articles/add-metrics.html.md +58 -0
  22. data/docs/source/articles/add-or-replace-a-pricing-calculator.html.md +150 -0
  23. data/docs/source/articles/add-remove-or-change-a-mongoid-validation.html.md +147 -0
  24. data/docs/source/articles/add-remove-or-change-a-product-template.html.md +142 -0
  25. data/docs/source/articles/add-remove-sort-and-group-storefront-search-filters.html.md +483 -0
  26. data/docs/source/articles/add-stylesheets-through-a-manifest.html.md +276 -0
  27. data/docs/source/articles/add-system-content.html.md +138 -0
  28. data/docs/source/articles/analytics-overview.html.md +51 -0
  29. data/docs/source/articles/analyze-storefront-search-results.html.md +261 -0
  30. data/docs/source/articles/api-overview.html.md +35 -0
  31. data/docs/source/articles/appending.html.md +506 -0
  32. data/docs/source/articles/application-document.html.md +88 -0
  33. data/docs/source/articles/automated-javascript-testing.html.md +162 -0
  34. data/docs/source/articles/b2b-overview.html.md +64 -0
  35. data/docs/source/articles/browser-and-device-support.html.md +47 -0
  36. data/docs/source/articles/change-product-placeholder-image.html.md +39 -0
  37. data/docs/source/articles/change-storefront-search-results.html.md +283 -0
  38. data/docs/source/articles/change-the-storefront-product-pricing-ui.html.md +348 -0
  39. data/docs/source/articles/change-the-storefront-search-filters-ui.html.md +103 -0
  40. data/docs/source/articles/checkout.html.md +479 -0
  41. data/docs/source/articles/commerce-model.html.md +164 -0
  42. data/docs/source/articles/configuration-for-hosting.html.md +106 -0
  43. data/docs/source/articles/configuration.html.md +406 -0
  44. data/docs/source/articles/configure-a-payment-gateway.html.md +58 -0
  45. data/docs/source/articles/configure-asset-storage.html.md +29 -0
  46. data/docs/source/articles/configure-asset-types.html.md +18 -0
  47. data/docs/source/articles/configure-contact-form-subjects-list.html.md +24 -0
  48. data/docs/source/articles/configure-imageoptim.html.md +23 -0
  49. data/docs/source/articles/configure-locales.html.md +45 -0
  50. data/docs/source/articles/configure-logins-and-authentication.html.md +42 -0
  51. data/docs/source/articles/configure-low-inventory-threshold.html.md +26 -0
  52. data/docs/source/articles/configure-product-image-sizes-and-processing.html.md +28 -0
  53. data/docs/source/articles/content.html.md +554 -0
  54. data/docs/source/articles/contentable.html.md +41 -0
  55. data/docs/source/articles/contribute-code.html.md +69 -0
  56. data/docs/source/articles/contribute-documentation.html.md +60 -0
  57. data/docs/source/articles/create-a-custom-discount.html.md +234 -0
  58. data/docs/source/articles/create-a-new-app.html.md +131 -0
  59. data/docs/source/articles/create-a-plugin.html.md +19 -0
  60. data/docs/source/articles/create-a-style-guide.html.md +71 -0
  61. data/docs/source/articles/create-a-theme.html.md +134 -0
  62. data/docs/source/articles/css-architectural-overview.html.md +89 -0
  63. data/docs/source/articles/customize-a-helper.html.md +91 -0
  64. data/docs/source/articles/decoration.html.md +415 -0
  65. data/docs/source/articles/define-and-configure-inventory-policies.html.md +107 -0
  66. data/docs/source/articles/documentation-style-guide.html.md +48 -0
  67. data/docs/source/articles/documentation.html.md +54 -0
  68. data/docs/source/articles/domain-modeling.html.md +82 -0
  69. data/docs/source/articles/error-pages.html.md.erb +95 -0
  70. data/docs/source/articles/extension-overview.html.md +152 -0
  71. data/docs/source/articles/favicon-support.html.md +112 -0
  72. data/docs/source/articles/feature-spec-helper-stylesheet.html.md +25 -0
  73. data/docs/source/articles/featurejs-and-feature-spec-helper.html.md +20 -0
  74. data/docs/source/articles/help-and-support.html.md +34 -0
  75. data/docs/source/articles/html-fragment-caching.html.md +46 -0
  76. data/docs/source/articles/http-caching.html.md +43 -0
  77. data/docs/source/articles/i18n.html.md +35 -0
  78. data/docs/source/articles/images-flow.html.md +10 -0
  79. data/docs/source/articles/index-storefront-search-documents.html.md +104 -0
  80. data/docs/source/articles/infrastructure.html.md +46 -0
  81. data/docs/source/articles/installing.html.md +61 -0
  82. data/docs/source/articles/integrate-a-payment-gateway.html.md +124 -0
  83. data/docs/source/articles/integrate-a-web-analytics-provider.html.md +35 -0
  84. data/docs/source/articles/integrate-an-inventory-management-system.html.md +88 -0
  85. data/docs/source/articles/integrating-with-other-software.html.md +59 -0
  86. data/docs/source/articles/inventory.html.md +352 -0
  87. data/docs/source/articles/javascript-coding-standards.html.md +30 -0
  88. data/docs/source/articles/javascript-modules.html.md +174 -0
  89. data/docs/source/articles/javascript-overview.html.md +62 -0
  90. data/docs/source/articles/javascript-reference-documentation.html.md +51 -0
  91. data/docs/source/articles/javascript-templates.html.md +52 -0
  92. data/docs/source/articles/low-level-caching.html.md +25 -0
  93. data/docs/source/articles/maintain-a-plugin.html.md +12 -0
  94. data/docs/source/articles/maintenance-policy.html.md +79 -0
  95. data/docs/source/articles/navigable.html.md +51 -0
  96. data/docs/source/articles/navigating-the-code.html.md +149 -0
  97. data/docs/source/articles/navigation.html.md +386 -0
  98. data/docs/source/articles/order-life-cycle.html.md +546 -0
  99. data/docs/source/articles/order-pricing.html.md +389 -0
  100. data/docs/source/articles/orders-and-items.html.md +210 -0
  101. data/docs/source/articles/orders.html.md +66 -0
  102. data/docs/source/articles/overriding.html.md +155 -0
  103. data/docs/source/articles/overview.html.md +43 -0
  104. data/docs/source/articles/plugins-overview.html.md +12 -0
  105. data/docs/source/articles/prerequisites-and-dependencies.html.md +202 -0
  106. data/docs/source/articles/products.html.md.erb +1270 -0
  107. data/docs/source/articles/progressive-web-application-support.html.md +148 -0
  108. data/docs/source/articles/rails-asset-manifests.html.md +33 -0
  109. data/docs/source/articles/rails-asset-view-helpers.html.md +25 -0
  110. data/docs/source/articles/reading-data.html.md +10 -0
  111. data/docs/source/articles/releasable.html.md +37 -0
  112. data/docs/source/articles/report-a-bug.html.md +75 -0
  113. data/docs/source/articles/ruby-coding-standards.html.md +10 -0
  114. data/docs/source/articles/run-sidekiq-in-a-local-environment.html.md +40 -0
  115. data/docs/source/articles/searching.html.md +1005 -0
  116. data/docs/source/articles/security-policy.html.md +42 -0
  117. data/docs/source/articles/seeds.html.md +345 -0
  118. data/docs/source/articles/shipping.html.md +756 -0
  119. data/docs/source/articles/sort-and-exclude-product-options.html.md +47 -0
  120. data/docs/source/articles/storefront-search-features.html.md +568 -0
  121. data/docs/source/articles/storefront-searches.html.md +126 -0
  122. data/docs/source/articles/style-guides.html.md +21 -0
  123. data/docs/source/articles/stylesheet-coding-standards.html.md +24 -0
  124. data/docs/source/articles/stylesheets-overview.html.md +67 -0
  125. data/docs/source/articles/swappable-list-data-structure.html.md +81 -0
  126. data/docs/source/articles/system-emails.html.md +102 -0
  127. data/docs/source/articles/taggable.html.md +8 -0
  128. data/docs/source/articles/test-a-credit-card-transaction.html.md +16 -0
  129. data/docs/source/articles/test-if-a-plugin-is-installed.html.md +34 -0
  130. data/docs/source/articles/testing.html.md +914 -0
  131. data/docs/source/articles/themes-overview.html.md +155 -0
  132. data/docs/source/articles/translate-administrable-content.html.md +14 -0
  133. data/docs/source/articles/translate-javascript-content.html.md +16 -0
  134. data/docs/source/articles/translate-or-customize-message-content.html.md +29 -0
  135. data/docs/source/articles/translate-or-customize-static-content.html.md +30 -0
  136. data/docs/source/articles/use-an-existing-workarea-app.html.md +108 -0
  137. data/docs/source/articles/view-models.html.md +509 -0
  138. data/docs/source/articles/views.html.md +14 -0
  139. data/docs/source/articles/workers.html.md +613 -0
  140. data/docs/source/articles/writing-data.html.md +10 -0
  141. data/docs/source/cli.html.md +163 -0
  142. data/docs/source/favicon.ico +0 -0
  143. data/docs/source/images/3-variants-1-option.png +0 -0
  144. data/docs/source/images/3-variants-3-options.png +0 -0
  145. data/docs/source/images/3-years-primary-image.png +0 -0
  146. data/docs/source/images/404-storefront-error-page.png +0 -0
  147. data/docs/source/images/404-system-content-admin.png +0 -0
  148. data/docs/source/images/404.jpg +0 -0
  149. data/docs/source/images/5-years-primary-image.png +0 -0
  150. data/docs/source/images/activity-dashboard.png +0 -0
  151. data/docs/source/images/activity-for-object.png +0 -0
  152. data/docs/source/images/activity-ui.png +0 -0
  153. data/docs/source/images/adding-captioned-image-block-custom-icon.png +0 -0
  154. data/docs/source/images/adding-captioned-image-block-default-icon.png +0 -0
  155. data/docs/source/images/admin-alerts-ui.png +0 -0
  156. data/docs/source/images/admin-category-range-filters.png +0 -0
  157. data/docs/source/images/admin-for-3-column-hero.png +0 -0
  158. data/docs/source/images/admin-help-index.png +0 -0
  159. data/docs/source/images/admin-help-ui.png +0 -0
  160. data/docs/source/images/admin-javascript.png +0 -0
  161. data/docs/source/images/admin-notification-for-deactivated-discount.png +0 -0
  162. data/docs/source/images/admin-notifications-ui.png +0 -0
  163. data/docs/source/images/admin-product-show-page.png +0 -0
  164. data/docs/source/images/admin-products-index-page.png +0 -0
  165. data/docs/source/images/admin-range-filters.png +0 -0
  166. data/docs/source/images/admin-style-guides-navigation.png +0 -0
  167. data/docs/source/images/after-re-seeding.png +0 -0
  168. data/docs/source/images/after-seeding-localhost-3000.png +0 -0
  169. data/docs/source/images/after-seeding.png +0 -0
  170. data/docs/source/images/arrow.svg +1 -0
  171. data/docs/source/images/arrow_white.svg +1 -0
  172. data/docs/source/images/aws-resource-map.png +0 -0
  173. data/docs/source/images/backordered-until-output-on-inventory-sku-card.png +0 -0
  174. data/docs/source/images/before-seeding-localhost-3000.png +0 -0
  175. data/docs/source/images/before-seeding.png +0 -0
  176. data/docs/source/images/browsing-workarea-versions-on-the-web.png +0 -0
  177. data/docs/source/images/bulk-asset-upload-on-assets-index-page.png +0 -0
  178. data/docs/source/images/bulk-asset-upload-while-editing-content.png +0 -0
  179. data/docs/source/images/bundle-show-workarea-core.png +0 -0
  180. data/docs/source/images/bundle-show-workarea.png +0 -0
  181. data/docs/source/images/calendar-for-backordered-until-field.png +0 -0
  182. data/docs/source/images/captioned-image-block-in-storefront.png +0 -0
  183. data/docs/source/images/captioned-image-content-block-storefront-component-style-guide.png +0 -0
  184. data/docs/source/images/cart-system-content-in-admin.png +0 -0
  185. data/docs/source/images/cart-system-content-in-storefront.png +0 -0
  186. data/docs/source/images/checkout-addresses-guest.png +0 -0
  187. data/docs/source/images/checkout-addresses-user.png +0 -0
  188. data/docs/source/images/checkout-confirmation.png +0 -0
  189. data/docs/source/images/checkout-flow-0.png +0 -0
  190. data/docs/source/images/checkout-flow-1.png +0 -0
  191. data/docs/source/images/checkout-flow-2.png +0 -0
  192. data/docs/source/images/checkout-flow-3.png +0 -0
  193. data/docs/source/images/checkout-flow-4.png +0 -0
  194. data/docs/source/images/checkout-payment-guest.png +0 -0
  195. data/docs/source/images/checkout-payment-user.png +0 -0
  196. data/docs/source/images/checkout-shipping.png +0 -0
  197. data/docs/source/images/color-picker-component-admin-style-guide.png +0 -0
  198. data/docs/source/images/color-picker-component-on-content-editing-screen.png +0 -0
  199. data/docs/source/images/commerce-model-carts-orders.png +0 -0
  200. data/docs/source/images/commerce-model-order-pricing.png +0 -0
  201. data/docs/source/images/commerce-model.png +0 -0
  202. data/docs/source/images/configuring-an-index-pattern-in-kibana.png +0 -0
  203. data/docs/source/images/content-block-presets.png +0 -0
  204. data/docs/source/images/content-search-customization.png +0 -0
  205. data/docs/source/images/country-with-region-data-in-address-form.png +0 -0
  206. data/docs/source/images/country-without-region-data-in-address-form.png +0 -0
  207. data/docs/source/images/create-content-block-preset-ui.png +0 -0
  208. data/docs/source/images/credit-card-icons.png +0 -0
  209. data/docs/source/images/css-added-through-admin.png +0 -0
  210. data/docs/source/images/css-admin-ui.png +0 -0
  211. data/docs/source/images/current-configuration-shown-in-admin-settings.png +0 -0
  212. data/docs/source/images/customer-impersonation-in-admin.png +0 -0
  213. data/docs/source/images/customer-impersonation-in-store-front.png +0 -0
  214. data/docs/source/images/date-filter-same-day.png +0 -0
  215. data/docs/source/images/developer-toolbar-in-store-front.png +0 -0
  216. data/docs/source/images/discounts-sorted-by-most-redeemed.png +0 -0
  217. data/docs/source/images/edit-help-article.png +0 -0
  218. data/docs/source/images/editing-content-for-search-customization.png +0 -0
  219. data/docs/source/images/editing-dynamic-captioned-image-block.png +0 -0
  220. data/docs/source/images/editing-product-fields-in-the-admin.png +0 -0
  221. data/docs/source/images/editing-search-system-content.png +0 -0
  222. data/docs/source/images/editing-static-captioned-image-block-custom-icon.png +0 -0
  223. data/docs/source/images/editing-static-captioned-image-block-default-icon.png +0 -0
  224. data/docs/source/images/external.svg +1 -0
  225. data/docs/source/images/favicon_16.png +0 -0
  226. data/docs/source/images/favicon_180.png +0 -0
  227. data/docs/source/images/favicon_32.png +0 -0
  228. data/docs/source/images/filters-all.png +0 -0
  229. data/docs/source/images/filters-control.png +0 -0
  230. data/docs/source/images/filters-custom.png +0 -0
  231. data/docs/source/images/filters-groups.png +0 -0
  232. data/docs/source/images/filters-material.png +0 -0
  233. data/docs/source/images/filters-omitted.png +0 -0
  234. data/docs/source/images/filters-pinned.png +0 -0
  235. data/docs/source/images/filters-range.png +0 -0
  236. data/docs/source/images/filters-sorted.png +0 -0
  237. data/docs/source/images/filters-wrapping-to-second-line-in-admin.png +0 -0
  238. data/docs/source/images/generic-product-template-images-no-options-selected.png +0 -0
  239. data/docs/source/images/generic-product-template-images-options-selected.png +0 -0
  240. data/docs/source/images/generic-template.png +0 -0
  241. data/docs/source/images/hosting.svg +1 -0
  242. data/docs/source/images/image-group-content-block-in-storefront.png +0 -0
  243. data/docs/source/images/images.svg +1 -0
  244. data/docs/source/images/import-export-screenshot.png +0 -0
  245. data/docs/source/images/invalid-display.png +0 -0
  246. data/docs/source/images/itcss.png +0 -0
  247. data/docs/source/images/kibana-dev-tools-console.png +0 -0
  248. data/docs/source/images/layout-content-admin-with-2-areas.png +0 -0
  249. data/docs/source/images/layout-content-admin-with-3-areas.png +0 -0
  250. data/docs/source/images/link-to-search-system-content.png +0 -0
  251. data/docs/source/images/logo.svg +1 -0
  252. data/docs/source/images/menu.svg +2 -0
  253. data/docs/source/images/mongo-replica-set.svg +1 -0
  254. data/docs/source/images/multi-column-hero-blocks.png +0 -0
  255. data/docs/source/images/option-selects-product-template-images-options-selected.png +0 -0
  256. data/docs/source/images/option-selects-template.png +0 -0
  257. data/docs/source/images/option-thumbnails-template.png +0 -0
  258. data/docs/source/images/order-item-total-price-diagram.png +0 -0
  259. data/docs/source/images/order-pricing-cart-example.png +0 -0
  260. data/docs/source/images/order-pricing-example-adjustments.png +0 -0
  261. data/docs/source/images/order-pricing-example-totals.png +0 -0
  262. data/docs/source/images/order-pricing-placed-order-example.png +0 -0
  263. data/docs/source/images/order-shipping-total-diagram.png +0 -0
  264. data/docs/source/images/order-show-with-multiple-tenders.png +0 -0
  265. data/docs/source/images/order-subtotal-price-diagram.png +0 -0
  266. data/docs/source/images/order-tax-total-diagram.png +0 -0
  267. data/docs/source/images/order-total-price-diagram.png +0 -0
  268. data/docs/source/images/order-total-value-diagram.png +0 -0
  269. data/docs/source/images/orders-dashboard-links.png +0 -0
  270. data/docs/source/images/oval.svg +1 -0
  271. data/docs/source/images/payment-icon-storefront-style-guide.png +0 -0
  272. data/docs/source/images/people-dashboard-links.png +0 -0
  273. data/docs/source/images/price-adjustments-diagram.png +0 -0
  274. data/docs/source/images/price-display-no-options.png +0 -0
  275. data/docs/source/images/price-display-options-selected.png +0 -0
  276. data/docs/source/images/pricing-calculators-diagram.png +0 -0
  277. data/docs/source/images/product-list-content-block-admin.png +0 -0
  278. data/docs/source/images/product-list-content-block-in-store-front.png +0 -0
  279. data/docs/source/images/promo-products-excluded-autocomplete-results-after.png +0 -0
  280. data/docs/source/images/promo-products-excluded-featured-category-results-after.png +0 -0
  281. data/docs/source/images/promo-products-excluded-recommendations-results-after.png +0 -0
  282. data/docs/source/images/promo-products-excluded-search-category-results-after.png +0 -0
  283. data/docs/source/images/promo-products-excluded-search-results-after.png +0 -0
  284. data/docs/source/images/promo-products-included-autocomplete-results-before.png +0 -0
  285. data/docs/source/images/promo-products-included-featured-category-results-before.png +0 -0
  286. data/docs/source/images/promo-products-included-recommendations-results-before.png +0 -0
  287. data/docs/source/images/promo-products-included-search-category-results-before.png +0 -0
  288. data/docs/source/images/promo-products-included-search-results-before.png +0 -0
  289. data/docs/source/images/rails-version-constraint.png +0 -0
  290. data/docs/source/images/re-enable-discount.png +0 -0
  291. data/docs/source/images/reading-data.svg +1 -0
  292. data/docs/source/images/readme-hero.png +0 -0
  293. data/docs/source/images/redesigned-customized-sort-for-search-results.png +0 -0
  294. data/docs/source/images/reviews-summary-above-share-buttons.png +0 -0
  295. data/docs/source/images/reviews-summary-below-product-name.png +0 -0
  296. data/docs/source/images/reviews-summary-below-share-buttons.png +0 -0
  297. data/docs/source/images/reviews-summary-removed.png +0 -0
  298. data/docs/source/images/rsa-fingerprint-for-stash.png +0 -0
  299. data/docs/source/images/ruby-version-constraint.png +0 -0
  300. data/docs/source/images/script-tag-added-through-admin.png +0 -0
  301. data/docs/source/images/search-analysis-admin-alternate-rendering.png +0 -0
  302. data/docs/source/images/search-analysis-admin.png +0 -0
  303. data/docs/source/images/search-quality-report.png +0 -0
  304. data/docs/source/images/search.svg +1 -0
  305. data/docs/source/images/searching-for-cart-system-content-in-admin.png +0 -0
  306. data/docs/source/images/searching-for-layout-system-content-in-admin.png +0 -0
  307. data/docs/source/images/seeded-admin.png +0 -0
  308. data/docs/source/images/seeds-from-plugins.png +0 -0
  309. data/docs/source/images/seo-metadata-automation-ui.png +0 -0
  310. data/docs/source/images/show-password-button.png +0 -0
  311. data/docs/source/images/storefront-autocomplete.png +0 -0
  312. data/docs/source/images/storefront-category-summary-content-block.png +0 -0
  313. data/docs/source/images/storefront-category.png +0 -0
  314. data/docs/source/images/storefront-product-after-overriding.png +0 -0
  315. data/docs/source/images/storefront-product-before-overriding.png +0 -0
  316. data/docs/source/images/storefront-product-browse-page.png +0 -0
  317. data/docs/source/images/storefront-product-recommendations.png +0 -0
  318. data/docs/source/images/storefront-product-show-page.png +0 -0
  319. data/docs/source/images/storefront-requests-and-search-requests.png +0 -0
  320. data/docs/source/images/storefront-search-request-handling.png +0 -0
  321. data/docs/source/images/storefront-search-response-creation.png +0 -0
  322. data/docs/source/images/storefront-search.png +0 -0
  323. data/docs/source/images/storefront-style-guides-navigation.png +0 -0
  324. data/docs/source/images/styles.css +3 -0
  325. data/docs/source/images/tax-categories-ui.png +0 -0
  326. data/docs/source/images/tax-rates-ui.png +0 -0
  327. data/docs/source/images/unpurchasable-product.png +0 -0
  328. data/docs/source/images/url-redirects-filtering.png +0 -0
  329. data/docs/source/images/utility-nav-area-in-admin.png +0 -0
  330. data/docs/source/images/utility-nav-area-in-storefront.png +0 -0
  331. data/docs/source/images/validation-message-in-storefront.png +0 -0
  332. data/docs/source/images/view-model-interface.png +0 -0
  333. data/docs/source/images/viewing-workarea-version-in-source.png +0 -0
  334. data/docs/source/images/workarea.svg +1 -0
  335. data/docs/source/images/worst-performing-searches-on-results-customization-page.png +0 -0
  336. data/docs/source/images/writing-data.svg +1 -0
  337. data/docs/source/index.html.erb +167 -0
  338. data/docs/source/javascripts/jquery.js +2 -0
  339. data/docs/source/javascripts/lunr.js +7 -0
  340. data/docs/source/javascripts/site.js +299 -0
  341. data/docs/source/javascripts/vendor/highlight.pack.js +2 -0
  342. data/docs/source/layouts/article.erb +106 -0
  343. data/docs/source/layouts/bare.erb +46 -0
  344. data/docs/source/layouts/layout.erb +43 -0
  345. data/docs/source/release-notes.html.md +258 -0
  346. data/docs/source/release-notes/workarea-3-0-0.html.md +146 -0
  347. data/docs/source/release-notes/workarea-3-0-1.html.md +161 -0
  348. data/docs/source/release-notes/workarea-3-0-10.html.md +39 -0
  349. data/docs/source/release-notes/workarea-3-0-11.html.md +277 -0
  350. data/docs/source/release-notes/workarea-3-0-12.html.md +14 -0
  351. data/docs/source/release-notes/workarea-3-0-13.html.md +153 -0
  352. data/docs/source/release-notes/workarea-3-0-14.html.md +93 -0
  353. data/docs/source/release-notes/workarea-3-0-15.html.md +107 -0
  354. data/docs/source/release-notes/workarea-3-0-16.html.md +36 -0
  355. data/docs/source/release-notes/workarea-3-0-17.html.md +141 -0
  356. data/docs/source/release-notes/workarea-3-0-18.html.md +123 -0
  357. data/docs/source/release-notes/workarea-3-0-19.html.md +160 -0
  358. data/docs/source/release-notes/workarea-3-0-2.html.md +222 -0
  359. data/docs/source/release-notes/workarea-3-0-20.html.md +95 -0
  360. data/docs/source/release-notes/workarea-3-0-21.html.md +168 -0
  361. data/docs/source/release-notes/workarea-3-0-22.html.md +268 -0
  362. data/docs/source/release-notes/workarea-3-0-23.html.md +173 -0
  363. data/docs/source/release-notes/workarea-3-0-24.html.md +19 -0
  364. data/docs/source/release-notes/workarea-3-0-25.html.md +26 -0
  365. data/docs/source/release-notes/workarea-3-0-26.html.md +199 -0
  366. data/docs/source/release-notes/workarea-3-0-27.html.md +113 -0
  367. data/docs/source/release-notes/workarea-3-0-28.html.md +39 -0
  368. data/docs/source/release-notes/workarea-3-0-29.html.md +73 -0
  369. data/docs/source/release-notes/workarea-3-0-3.html.md +35 -0
  370. data/docs/source/release-notes/workarea-3-0-30.html.md +186 -0
  371. data/docs/source/release-notes/workarea-3-0-31.html.md +125 -0
  372. data/docs/source/release-notes/workarea-3-0-32.html.md +73 -0
  373. data/docs/source/release-notes/workarea-3-0-33.html.md +137 -0
  374. data/docs/source/release-notes/workarea-3-0-34.html.md +203 -0
  375. data/docs/source/release-notes/workarea-3-0-35.html.md +205 -0
  376. data/docs/source/release-notes/workarea-3-0-36.html.md +105 -0
  377. data/docs/source/release-notes/workarea-3-0-37.html.md +144 -0
  378. data/docs/source/release-notes/workarea-3-0-38.html.md +73 -0
  379. data/docs/source/release-notes/workarea-3-0-39.html.md +77 -0
  380. data/docs/source/release-notes/workarea-3-0-4.html.md +14 -0
  381. data/docs/source/release-notes/workarea-3-0-40.html.md +130 -0
  382. data/docs/source/release-notes/workarea-3-0-41.html.md +70 -0
  383. data/docs/source/release-notes/workarea-3-0-42.html.md +52 -0
  384. data/docs/source/release-notes/workarea-3-0-43.html.md +72 -0
  385. data/docs/source/release-notes/workarea-3-0-44.html.md +93 -0
  386. data/docs/source/release-notes/workarea-3-0-45.html.md +61 -0
  387. data/docs/source/release-notes/workarea-3-0-46.html.md +171 -0
  388. data/docs/source/release-notes/workarea-3-0-47.html.md +130 -0
  389. data/docs/source/release-notes/workarea-3-0-48.html.md +160 -0
  390. data/docs/source/release-notes/workarea-3-0-49.html.md +28 -0
  391. data/docs/source/release-notes/workarea-3-0-5.html.md +225 -0
  392. data/docs/source/release-notes/workarea-3-0-50.html.md +74 -0
  393. data/docs/source/release-notes/workarea-3-0-51.html.md +61 -0
  394. data/docs/source/release-notes/workarea-3-0-52.html.md +76 -0
  395. data/docs/source/release-notes/workarea-3-0-53.html.md +126 -0
  396. data/docs/source/release-notes/workarea-3-0-54.html.md +112 -0
  397. data/docs/source/release-notes/workarea-3-0-55.html.md +105 -0
  398. data/docs/source/release-notes/workarea-3-0-56.html.md +56 -0
  399. data/docs/source/release-notes/workarea-3-0-57.html.md +82 -0
  400. data/docs/source/release-notes/workarea-3-0-58.html.md +153 -0
  401. data/docs/source/release-notes/workarea-3-0-59.html.md +78 -0
  402. data/docs/source/release-notes/workarea-3-0-6.html.md +165 -0
  403. data/docs/source/release-notes/workarea-3-0-60.html.md +43 -0
  404. data/docs/source/release-notes/workarea-3-0-61.html.md +46 -0
  405. data/docs/source/release-notes/workarea-3-0-62.html.md +23 -0
  406. data/docs/source/release-notes/workarea-3-0-63.html.md +25 -0
  407. data/docs/source/release-notes/workarea-3-0-64.html.md +25 -0
  408. data/docs/source/release-notes/workarea-3-0-65.html.md +37 -0
  409. data/docs/source/release-notes/workarea-3-0-7.html.md +207 -0
  410. data/docs/source/release-notes/workarea-3-0-8.html.md +337 -0
  411. data/docs/source/release-notes/workarea-3-0-9.html.md +196 -0
  412. data/docs/source/release-notes/workarea-3-1-0.html.md +414 -0
  413. data/docs/source/release-notes/workarea-3-1-1.html.md +139 -0
  414. data/docs/source/release-notes/workarea-3-1-10.html.md +19 -0
  415. data/docs/source/release-notes/workarea-3-1-11.html.md +27 -0
  416. data/docs/source/release-notes/workarea-3-1-12.html.md +216 -0
  417. data/docs/source/release-notes/workarea-3-1-13.html.md +113 -0
  418. data/docs/source/release-notes/workarea-3-1-14.html.md +39 -0
  419. data/docs/source/release-notes/workarea-3-1-15.html.md +107 -0
  420. data/docs/source/release-notes/workarea-3-1-16.html.md +188 -0
  421. data/docs/source/release-notes/workarea-3-1-17.html.md +141 -0
  422. data/docs/source/release-notes/workarea-3-1-18.html.md +73 -0
  423. data/docs/source/release-notes/workarea-3-1-19.html.md +137 -0
  424. data/docs/source/release-notes/workarea-3-1-2.html.md +55 -0
  425. data/docs/source/release-notes/workarea-3-1-20.html.md +203 -0
  426. data/docs/source/release-notes/workarea-3-1-21.html.md +205 -0
  427. data/docs/source/release-notes/workarea-3-1-22.html.md +121 -0
  428. data/docs/source/release-notes/workarea-3-1-23.html.md +144 -0
  429. data/docs/source/release-notes/workarea-3-1-24.html.md +94 -0
  430. data/docs/source/release-notes/workarea-3-1-25.html.md +77 -0
  431. data/docs/source/release-notes/workarea-3-1-26.html.md +130 -0
  432. data/docs/source/release-notes/workarea-3-1-27.html.md +70 -0
  433. data/docs/source/release-notes/workarea-3-1-28.html.md +52 -0
  434. data/docs/source/release-notes/workarea-3-1-29.html.md +44 -0
  435. data/docs/source/release-notes/workarea-3-1-3.html.md +185 -0
  436. data/docs/source/release-notes/workarea-3-1-30.html.md +72 -0
  437. data/docs/source/release-notes/workarea-3-1-31.html.md +93 -0
  438. data/docs/source/release-notes/workarea-3-1-32.html.md +61 -0
  439. data/docs/source/release-notes/workarea-3-1-33.html.md +171 -0
  440. data/docs/source/release-notes/workarea-3-1-34.html.md +130 -0
  441. data/docs/source/release-notes/workarea-3-1-35.html.md +179 -0
  442. data/docs/source/release-notes/workarea-3-1-36.html.md +28 -0
  443. data/docs/source/release-notes/workarea-3-1-37.html.md +74 -0
  444. data/docs/source/release-notes/workarea-3-1-38.html.md +61 -0
  445. data/docs/source/release-notes/workarea-3-1-39.html.md +96 -0
  446. data/docs/source/release-notes/workarea-3-1-4.html.md +148 -0
  447. data/docs/source/release-notes/workarea-3-1-40.html.md +126 -0
  448. data/docs/source/release-notes/workarea-3-1-41.html.md +128 -0
  449. data/docs/source/release-notes/workarea-3-1-42.html.md +105 -0
  450. data/docs/source/release-notes/workarea-3-1-43.html.md +37 -0
  451. data/docs/source/release-notes/workarea-3-1-44.html.md +82 -0
  452. data/docs/source/release-notes/workarea-3-1-45.html.md +153 -0
  453. data/docs/source/release-notes/workarea-3-1-46.html.md +91 -0
  454. data/docs/source/release-notes/workarea-3-1-47.html.md +65 -0
  455. data/docs/source/release-notes/workarea-3-1-48.html.md +46 -0
  456. data/docs/source/release-notes/workarea-3-1-49.html.md +23 -0
  457. data/docs/source/release-notes/workarea-3-1-5.html.md +169 -0
  458. data/docs/source/release-notes/workarea-3-1-50.html.md +42 -0
  459. data/docs/source/release-notes/workarea-3-1-51.html.md +25 -0
  460. data/docs/source/release-notes/workarea-3-1-52.html.md +57 -0
  461. data/docs/source/release-notes/workarea-3-1-6.html.md +117 -0
  462. data/docs/source/release-notes/workarea-3-1-7.html.md +176 -0
  463. data/docs/source/release-notes/workarea-3-1-8.html.md +283 -0
  464. data/docs/source/release-notes/workarea-3-1-9.html.md +212 -0
  465. data/docs/source/release-notes/workarea-3-2-0.html.md +1705 -0
  466. data/docs/source/release-notes/workarea-3-2-1.html.md +216 -0
  467. data/docs/source/release-notes/workarea-3-2-10.html.md +237 -0
  468. data/docs/source/release-notes/workarea-3-2-11.html.md +121 -0
  469. data/docs/source/release-notes/workarea-3-2-12.html.md +145 -0
  470. data/docs/source/release-notes/workarea-3-2-13.html.md +138 -0
  471. data/docs/source/release-notes/workarea-3-2-14.html.md +77 -0
  472. data/docs/source/release-notes/workarea-3-2-15.html.md +130 -0
  473. data/docs/source/release-notes/workarea-3-2-16.html.md +111 -0
  474. data/docs/source/release-notes/workarea-3-2-17.html.md +52 -0
  475. data/docs/source/release-notes/workarea-3-2-18.html.md +44 -0
  476. data/docs/source/release-notes/workarea-3-2-19.html.md +72 -0
  477. data/docs/source/release-notes/workarea-3-2-2.html.md +145 -0
  478. data/docs/source/release-notes/workarea-3-2-20.html.md +93 -0
  479. data/docs/source/release-notes/workarea-3-2-21.html.md +61 -0
  480. data/docs/source/release-notes/workarea-3-2-22.html.md +154 -0
  481. data/docs/source/release-notes/workarea-3-2-23.html.md +130 -0
  482. data/docs/source/release-notes/workarea-3-2-24.html.md +200 -0
  483. data/docs/source/release-notes/workarea-3-2-25.html.md +28 -0
  484. data/docs/source/release-notes/workarea-3-2-26.html.md +94 -0
  485. data/docs/source/release-notes/workarea-3-2-27.html.md +61 -0
  486. data/docs/source/release-notes/workarea-3-2-28.html.md +96 -0
  487. data/docs/source/release-notes/workarea-3-2-29.html.md +126 -0
  488. data/docs/source/release-notes/workarea-3-2-30.html.md +112 -0
  489. data/docs/source/release-notes/workarea-3-2-31.html.md +105 -0
  490. data/docs/source/release-notes/workarea-3-2-32.html.md +56 -0
  491. data/docs/source/release-notes/workarea-3-2-33.html.md +82 -0
  492. data/docs/source/release-notes/workarea-3-2-34.html.md +153 -0
  493. data/docs/source/release-notes/workarea-3-2-35.html.md +91 -0
  494. data/docs/source/release-notes/workarea-3-2-36.html.md +118 -0
  495. data/docs/source/release-notes/workarea-3-2-37.html.md +46 -0
  496. data/docs/source/release-notes/workarea-3-2-38.html.md +23 -0
  497. data/docs/source/release-notes/workarea-3-2-39.html.md +42 -0
  498. data/docs/source/release-notes/workarea-3-2-4.html.md +109 -0
  499. data/docs/source/release-notes/workarea-3-2-40.html.md +25 -0
  500. data/docs/source/release-notes/workarea-3-2-41.html.md +90 -0
  501. data/docs/source/release-notes/workarea-3-2-5.html.md +186 -0
  502. data/docs/source/release-notes/workarea-3-2-6.html.md +173 -0
  503. data/docs/source/release-notes/workarea-3-2-7.html.md +89 -0
  504. data/docs/source/release-notes/workarea-3-2-8.html.md +137 -0
  505. data/docs/source/release-notes/workarea-3-2-9.html.md +219 -0
  506. data/docs/source/release-notes/workarea-3-3-0.html.md +1272 -0
  507. data/docs/source/release-notes/workarea-3-3-1.html.md +324 -0
  508. data/docs/source/release-notes/workarea-3-3-10.html.md +69 -0
  509. data/docs/source/release-notes/workarea-3-3-11.html.md +72 -0
  510. data/docs/source/release-notes/workarea-3-3-12.html.md +136 -0
  511. data/docs/source/release-notes/workarea-3-3-13.html.md +61 -0
  512. data/docs/source/release-notes/workarea-3-3-14.html.md +196 -0
  513. data/docs/source/release-notes/workarea-3-3-15.html.md +167 -0
  514. data/docs/source/release-notes/workarea-3-3-16.html.md +234 -0
  515. data/docs/source/release-notes/workarea-3-3-17.html.md +82 -0
  516. data/docs/source/release-notes/workarea-3-3-18.html.md +165 -0
  517. data/docs/source/release-notes/workarea-3-3-19.html.md +106 -0
  518. data/docs/source/release-notes/workarea-3-3-2.html.md +72 -0
  519. data/docs/source/release-notes/workarea-3-3-20.html.md +116 -0
  520. data/docs/source/release-notes/workarea-3-3-21.html.md +228 -0
  521. data/docs/source/release-notes/workarea-3-3-22.html.md +125 -0
  522. data/docs/source/release-notes/workarea-3-3-23.html.md +154 -0
  523. data/docs/source/release-notes/workarea-3-3-24.html.md +70 -0
  524. data/docs/source/release-notes/workarea-3-3-25.html.md +114 -0
  525. data/docs/source/release-notes/workarea-3-3-26.html.md +260 -0
  526. data/docs/source/release-notes/workarea-3-3-27.html.md +138 -0
  527. data/docs/source/release-notes/workarea-3-3-28.html.md +147 -0
  528. data/docs/source/release-notes/workarea-3-3-29.html.md +63 -0
  529. data/docs/source/release-notes/workarea-3-3-3.html.md +153 -0
  530. data/docs/source/release-notes/workarea-3-3-30.html.md +102 -0
  531. data/docs/source/release-notes/workarea-3-3-31.html.md +57 -0
  532. data/docs/source/release-notes/workarea-3-3-32.html.md +44 -0
  533. data/docs/source/release-notes/workarea-3-3-33.html.md +114 -0
  534. data/docs/source/release-notes/workarea-3-3-4.html.md +332 -0
  535. data/docs/source/release-notes/workarea-3-3-5.html.md +242 -0
  536. data/docs/source/release-notes/workarea-3-3-6.html.md +100 -0
  537. data/docs/source/release-notes/workarea-3-3-7.html.md +148 -0
  538. data/docs/source/release-notes/workarea-3-3-8.html.md +163 -0
  539. data/docs/source/release-notes/workarea-3-3-9.html.md +93 -0
  540. data/docs/source/release-notes/workarea-3-4-0.html.md +580 -0
  541. data/docs/source/release-notes/workarea-3-4-1.html.md +150 -0
  542. data/docs/source/release-notes/workarea-3-4-10.html.md +72 -0
  543. data/docs/source/release-notes/workarea-3-4-11.html.md +60 -0
  544. data/docs/source/release-notes/workarea-3-4-12.html.md +155 -0
  545. data/docs/source/release-notes/workarea-3-4-2.html.md +188 -0
  546. data/docs/source/release-notes/workarea-3-4-3.html.md +136 -0
  547. data/docs/source/release-notes/workarea-3-4-4.html.md +114 -0
  548. data/docs/source/release-notes/workarea-3-4-5.html.md +275 -0
  549. data/docs/source/release-notes/workarea-3-4-6.html.md +169 -0
  550. data/docs/source/release-notes/workarea-3-4-7.html.md +162 -0
  551. data/docs/source/release-notes/workarea-3-4-8.html.md +95 -0
  552. data/docs/source/release-notes/workarea-3-4-9.html.md +135 -0
  553. data/docs/source/search.html.erb +34 -0
  554. data/docs/source/shared/_header.erb +61 -0
  555. data/docs/source/shared/_svgs.erb +17 -0
  556. data/docs/source/style_guide/index.html.erb +382 -0
  557. data/docs/source/stylesheets/_base.scss +125 -0
  558. data/docs/source/stylesheets/_components.scss +669 -0
  559. data/docs/source/stylesheets/_helpers.scss +10 -0
  560. data/docs/source/stylesheets/_opinions.scss +42 -0
  561. data/docs/source/stylesheets/_settings.scss +56 -0
  562. data/docs/source/stylesheets/_typography.scss +119 -0
  563. data/docs/source/stylesheets/site.css.scss +14 -0
  564. data/docs/source/stylesheets/vendor/_avalanche.scss +328 -0
  565. data/docs/source/stylesheets/vendor/_normalize.scss +341 -0
  566. data/docs/source/stylesheets/vendor/highlight/_tomorrow_night_blue.scss +75 -0
  567. data/docs/source/upgrade-guides.html.md +18 -0
  568. data/docs/source/upgrade-guides/workarea-3-4-0.html.md +152 -0
  569. data/docs/workarea_renderer.rb +8 -0
  570. data/docs/yarn.lock +2522 -0
  571. metadata +669 -0
@@ -0,0 +1,202 @@
1
+ ---
2
+ title: Add a Report
3
+ excerpt: This page will guide you through a step-by-step process of creating a new report within the Workarea admin.
4
+ ---
5
+
6
+ # Add a Report
7
+
8
+ Workarea provides a number of useful reports that can be used to analyze the data collected via [metrics](add-metrics.html) or any other collection in the database. Though extensive, it is possible a retailer may have the need for a report not provided out of the box. Adding a new report includes:
9
+
10
+ * A class to generate the report results
11
+ * A view model to help format the results
12
+ * A route/controller action
13
+ * Views to display the results on both the reports dashboard and the full reports page.
14
+
15
+ ## Create a report class
16
+
17
+ Reports are typically not much more than a class the performs a [MongoDB aggregation](https://docs.mongodb.com/manual/aggregation/) on an existing collection. A report is represented by a class in `app/queries` that follows a structure like this:
18
+
19
+ ```ruby
20
+ # app/queries/workarea/reports/custom.rb
21
+ module Workarea
22
+ module Reports
23
+ class Custom
24
+ include Report
25
+
26
+ self.reporting_class = Metrics::ProductByDay
27
+ self.sort_fields = %w(revenue units_sold)
28
+
29
+ def aggregation
30
+ [
31
+ # aggregation stages
32
+ ]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ ```
38
+
39
+ Each report will `include Report`, which is a module that provides shared behavior of reporting date filtering helpers, sorting, result limits, and the logic for generating the results from the aggregation. `reporting_class` tells the `Report` module which collection to aggregate on, and `sort_fields` defines which fields from the resulting documents can be used to sort the documents. The `#aggregation` method defines the aggregation to run, and must return an array of the mongo aggregation stages.
40
+
41
+ The `reporting_class` can be any model representing a Mongo collection, but typically will be a `Metrics` collection. If a new report requires data that does not exist, you can [add new metrics](add-metrics.html) along with the new report.
42
+
43
+ It is encouraged that you write a unit test for your report to ensure it is generating results as expected.
44
+
45
+ ## Create a view model
46
+
47
+ Each report is expected to have corresponding view model in the admin. These view models serve to enrich the result set with more user-friendly information like adding the product model to each document instead of just displaying a product id.
48
+
49
+ ```ruby
50
+ # app/view_models/workarea/admin/reports/custom_view_model.rb
51
+ module Workarea
52
+ module Admin
53
+ module Reports
54
+ class CustomViewModel < ApplicationViewModel
55
+ def results
56
+ @results ||= model.results.map do |result|
57
+ product = products.detect { |p| p.id == result['_id'] }
58
+ OpenStruct.new({ product: product }.merge(result))
59
+ end
60
+ end
61
+
62
+ def products
63
+ @products ||= Catalog::Product.any_in(
64
+ id: model.results.map { |r| r['_id'] }
65
+ ).to_a
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ `OpenStruct` is used to provide a more developer-friendly API to the result sets from reports.
74
+
75
+ ## Decorate `Dashboards::ReportsViewModel`
76
+
77
+ To begin making this report visible to an admin user, a method on the `Admin::Dashboards::ReportsViewModel` is required so that the new report's results are available to display on the reports dashboard.
78
+
79
+ ```ruby
80
+ # app/view_models/workarea/admin/dashboards/reports_view_model.decorator
81
+ module Workarea
82
+ decorate Admin::Dashboards::ReportsViewModel, with: :project_name do
83
+ def custom
84
+ @custom ||= Admin::Reports::CustomViewModel.wrap(
85
+ Workarea::Reports::Custom.new(options),
86
+ options
87
+ )
88
+ end
89
+ end
90
+ end
91
+
92
+ ```
93
+
94
+ ## Add route and controller action
95
+
96
+ Each report requires its own route and controller action to be defined.
97
+
98
+ ```ruby
99
+ # config/routes.rb
100
+ Workarea::Admin::Engine.routes.draw do
101
+ scope '(:locale)', constraints: Workarea::I18n.routes_constraint do
102
+ resource :report, only: [] do
103
+ get :custom
104
+ end
105
+ end
106
+ end
107
+ ```
108
+
109
+ Decorate `Admin::ReportsController` to add the new report's action:
110
+
111
+ ```ruby
112
+ # app/controllers/workarea/admin/reports_controller.decorator
113
+ module Workarea
114
+ decorate Admin::ReportsController, with: :project_name do
115
+ def custom
116
+ @report = Admin::Reports::CustomViewModel.wrap(
117
+ Workarea::Reports::Custom.new(params),
118
+ view_model_options
119
+ )
120
+ end
121
+ end
122
+ end
123
+ ```
124
+
125
+ ## Add view partials for reports dashboard
126
+
127
+ To display the new report on the report's dashboard, a partial view needs to be created and appended to the dashboard view.
128
+
129
+ ```ruby
130
+ # app/views/workarea/admin/dashboards/_custom_report.html.haml
131
+ .grid__cell
132
+ .card{ class: card_classes(:custom_report, local_assigns[:active]) }
133
+ = link_to custom_report_path, class: 'card__header' do
134
+ %span.card__header-text= t('workarea.admin.reports.custom.title')
135
+ = inline_svg 'workarea/admin/icons/insights.svg', class: 'card__icon'
136
+
137
+ .card__body
138
+ .card__centered-content
139
+ %table
140
+ %tbody
141
+ - dashboard.custom.results.take(4).each do |result|
142
+ %tr
143
+ %td= result.product.present? ? result.product.name : result._id
144
+ %td.align-right= number_to_currency(result.revenue)
145
+
146
+ = link_to custom_report_path, class: 'card__button' do
147
+ %span.button.button--small= t('workarea.admin.dashboards.reports.view_full_report')
148
+
149
+ ```
150
+
151
+ ```ruby
152
+ # config/initializers/appends.rb
153
+ Workarea.append_partials(
154
+ 'admin.reports_dashboard',
155
+ 'workarea/admin/dashboards/custom_card'
156
+ )
157
+ ```
158
+
159
+ ## Add view for report
160
+
161
+ The last thing that needs to be added is the view for the report itself, which contains some amount of boilerplate to offer the user exporting of the data and provide helpful information and date filtering. Most reports are a table of the results that offers sorting by clicking on column headers. The logic for all common behavior is extracted and available to use in your report views.
162
+
163
+ ```ruby
164
+ # app/views/workarea/admin/reports/custom.html.haml
165
+ - @page_title = t('workarea.admin.reports.custom.title')
166
+
167
+ .view
168
+ .view__header
169
+ .view__heading
170
+ = link_to "↑ #{t('workarea.admin.reports.all_reports')}", reports_dashboards_path
171
+ %h1.heading.heading--no-margin= t('workarea.admin.reports.custom.title')
172
+ %p= t('workarea.admin.reports.reference_link_html', path: reference_report_path)
173
+
174
+ .view__container
175
+ .browsing-controls.browsing-controls--with-divider.browsing-controls--center.browsing-controls--filters-displayed
176
+ = form_tag custom_report_path, method: 'get', class: 'browsing-controls__form' do
177
+ = render 'workarea/admin/shared/date_selector', starts_at: @report.starts_at, ends_at: @report.ends_at
178
+
179
+ .browsing-controls__count
180
+ = render_reports_results_message(@report)
181
+ = render 'workarea/admin/reports/export', report: @report
182
+
183
+ %table
184
+ %thead
185
+ %tr
186
+ %th= t('workarea.admin.fields.product')
187
+ %th.align-center= link_to_reports_sorting t('workarea.admin.fields.units_sold'), report: @report, sort_by: 'units_sold'
188
+ %th.align-right= link_to_reports_sorting t('workarea.admin.fields.revenue'), report: @report, sort_by: 'revenue'
189
+ %tbody
190
+ - @report.results.each do |result|
191
+ %tr
192
+ %td
193
+ - if result.product.present?
194
+ = link_to result.product.name, catalog_product_path(result.product)
195
+ - else
196
+ = result._id
197
+ %td.align-center= number_with_delimiter(result.units_sold)
198
+ %td.align-right= number_to_currency(result.revenue)
199
+
200
+ ```
201
+
202
+ It is encouraged that you write a system test to ensure that your report renders as expected and without errors.
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: Add CSS through the Admin UI
3
+ excerpt: CSS can be added on a page by page basis through the Admin UI. To do so, visit a content edit page in the Admin, such as the home page edit screen.
4
+ ---
5
+
6
+ # Add CSS through the Admin UI
7
+
8
+ CSS can be added on a page by page basis through the Admin UI. To do so, visit a content edit page in the Admin, such as the home page edit screen.
9
+
10
+ <!-- TODO: add image of home page edit screen -->
11
+
12
+ Hover over the Content card and click the "Manage Content" button.
13
+
14
+ <!-- TODO: add image of hover interaction -->
15
+
16
+ Click the "Advanced" link at the top of the Content Editor UI.
17
+
18
+ <!-- TODO: add image of Content Editing UI, "Advanced" link highlighted -->
19
+
20
+ Type CSS into the "CSS" field and save.
21
+
22
+ <!-- TODO: update image
23
+ <p><%= image_tag "images/css-admin-ui.png", alt: "CSS field in Admin" %></p>
24
+ -->
25
+
26
+ Visit the home page in the Storefront and behold! CSS!
27
+
28
+ <!-- TODO: update image
29
+ <p><%= image_tag "images/css-added-through-admin.png", alt: "CSS added through Admin" %></p>
30
+ -->
@@ -0,0 +1,367 @@
1
+ ---
2
+ title: Add JavaScript through a Manifest
3
+ excerpt: JavaScript manifests are the preferred solution for adding JavaScripts to and removing JavaScripts from a Workarea application. The Workarea Storefront includes 2 manifests, head and application, which are introduced in the JavaScript overview, wherea
4
+ ---
5
+
6
+ # Add JavaScript through a Manifest
7
+
8
+ JavaScript manifests are the preferred solution for adding JavaScripts to and removing JavaScripts from a Workarea application. The Workarea Storefront includes 2 manifests, **head** and **application** , which are introduced in the [JavaScript overview](javascript-overview.html), whereas the Admin includes only an **application** manifest. This guides covers them in detail.
9
+
10
+ If you're new to Ruby on Rails and the concept of asset manifests, check out the following guides to get you started.
11
+
12
+ - [Rails Asset Manifests](rails-asset-manifests.html)
13
+ - [Rails Asset View Helpers](rails-asset-view-helpers.html)
14
+
15
+ ## Customizing a Manifest
16
+
17
+ To add and remove JavaScript through a manifest, you need to have a copy of the manifest in your app. If you're working in a new application, start by [overriding](overriding.html) the manifest file you want to customize. You can override a manifest in the same way as any other JavaScript file. When overriding, note that the manifest files end with the extensions `.js.erb`. I'll explain the reason for that in the following sections which look at the head and application manifests in detail.
18
+
19
+ Now that you have a copy of the manifest in your app, edit it to taste. The follow sections explain how Workarea manifests differ from default Rails manifests and what is included out of the box.
20
+
21
+ ## Storefront's Head Manifest
22
+
23
+ In the Storefront, the head manifest is loaded in the document `head` and generally blocks the rest of the page from loading. It should therefore be kept as light as possible. Include only those scripts that must execute before the DOM is ready (like Feature.js) or those that must execute as soon as possible (like analytics).
24
+
25
+ The Storefront's head manifest looks something like this:
26
+
27
+ workarea-storefront/app/assets/javascripts/workarea/storefront/head.js.erb:
28
+
29
+ ```ruby
30
+ <%
31
+ # Feature.js
32
+ require_asset 'featurejs_rails/feature'
33
+ # Test Helper
34
+ require_asset 'workarea/core/feature_test_helper' if Rails.env.test?
35
+ %>
36
+
37
+ // apply Feature.js classes to the root HTML element
38
+ window.feature.testAll();
39
+
40
+ <%
41
+ # Plugin Head Append Point
42
+ append_javascripts('storefront.head')
43
+ %>
44
+ ```
45
+
46
+ Unlike a [standard Rails manifest](rails-asset-manifests.html) there are no directives. Instead, the is a mix of method calls and ERB blocks, hence the need for the `.erb` file extension mentioned above. The manifest is designed as such to support the Workarea plugin system and to load some assets conditionally, as you'll see shortly.
47
+
48
+ Let's work down the manifest, line by line.
49
+
50
+ ### Feature.js
51
+
52
+ The first called method, `require_asset`, is provided by the Rails asset pipeline and is equivalent to the directive `//= require` seen in a [standard Rails manifest](rails-asset-manifests.html). In this case, it is including the Feature.js library, whose path is determined by the featurejs\_rails gem. In some ways, Feature.js is different from the other dependencies bundled with Workarea, which is explained in the [Feature.js and Feature Test Helper](featurejs-and-feature-spec-helper.html) guide.
53
+
54
+ ### Feature Test Helper
55
+
56
+ Next up is feature\_test\_helper, which is—you guessed it—also explained in the [Feature.js and Feature Test Helper](featurejs-and-feature-spec-helper.html) guide. The path to feature\_test\_helper indicates it lives in the workarea-core gem. Workarea assets shared between workarea-admin and workarea-storefront are kept in workarea-core.
57
+
58
+ ### Running Feature.js Tests
59
+
60
+ The purpose of Feature.js is to detect which newer browser APIs are at the developer's disposal. It provides its own API that allows a developer to "test" if a feature is available or not in their JavaScript code, but that all happens when Feature.js is included on the first line. This line runs all of the tests and adds classes to the root HTML element of the document, allowing a developer to progressively enhance their application at the CSS level. It is loaded in this order because the Feature Test Helper disables some features, like CSS animations and transformations, which make an application more difficult to write system tests against.
61
+
62
+ ### Plugin JavaScripts
63
+
64
+ Next is a call to `append_javascripts`. This method is defined by Workarea and is used to load JavaScripts from Workarea plugins. See [Appending](appending.html) for a full explanation, but in short, plugins may be configured to insert their JavaScript files here.
65
+
66
+ ## Storefront's Application Manifest
67
+
68
+ Moving on to the application manifest, in contrast to the head manifest, it is loaded at the end of the document `body`, it does not block the page from rendering, and is used for scripts that can or should be deferred until the DOM is ready. Because the DOM is ready when the application manifest is executed, scripts included in this manifest are not wrapped in a "on ready" handler.
69
+
70
+ Like the head manifest, the application manifest is essentially one big ERB block, with the exception of a single line of executable JavaScript code at the end. The application manifest is composed of multiple thematic sections. "Zoomed out", it looks something like this:
71
+
72
+ workarea-storefront/app/assets/javascripts/workarea/storefront/application.js.erb:
73
+
74
+ ```
75
+ <%
76
+
77
+ # require dependencies
78
+ # append plugin dependencies
79
+
80
+ # require templates
81
+ # append plugin templates
82
+
83
+ # require custom jquery ui widgets
84
+
85
+ # require workarea's module controller
86
+
87
+ # require configuration
88
+ # append plugin configuration
89
+
90
+ # require routes
91
+
92
+ # require modules
93
+ # append plugin modules
94
+
95
+ %>
96
+
97
+ WORKAREA.initModules($(document));
98
+ ```
99
+
100
+ Now let's zoom in on each of the manifest sections.
101
+
102
+ ### Dependencies
103
+
104
+ ```ruby
105
+ # Library Dependencies
106
+ %w(
107
+ webcomponentsjs-rails/MutationObserver
108
+ i18n
109
+ i18n/translations
110
+ local_time
111
+ lodash
112
+ jquery3
113
+ jquery-ui/core
114
+ jquery-ui/widget
115
+ jquery-ui/position
116
+ jquery-ui/widgets/mouse
117
+ jquery-ui/widgets/draggable
118
+ jquery-ui/widgets/resizable
119
+ jquery-ui/widgets/autocomplete
120
+ jquery-ui/widgets/button
121
+ jquery-ui/widgets/dialog
122
+ jquery-ui/widgets/menu
123
+ jquery.validate
124
+ waypoints/noframework.waypoints
125
+ jquery-unique-clone
126
+ ).each do |asset|
127
+ require_asset asset
128
+ end
129
+
130
+ # Plugin Library Dependencies
131
+ append_javascripts('storefront.dependencies')
132
+ ```
133
+
134
+ This code creates an array of asset paths and then loops over the array, passing each path to `require_asset`, which is explained above.
135
+
136
+ Each asset in the array is a 3rd party library or framework on which Workarea JavaScripts depend. None of these files are bundled with Workarea. Instead, each file is included through a Ruby gem. Those gems are `require`d by workarea-core, which makes the assets available to the asset pipeline.
137
+
138
+ Following the `require_asset` loop is call `append_javascripts`. This is the same method covered in the head manifest section above, but the name of this append point is 'storefront.dependencies'. As the name of the method suggests, append points allow [plugins to append their JavaScripts to a manifest](appending.html).
139
+
140
+ ### JavaScript Templates
141
+
142
+ The next section is structured like the section above it, but the referenced assets are [JavaScript templates](javascript-templates.html). In the Storefront example below, some of the assets are from workarea-core, while the others are from workarea-storefront. The Admin application manifest similarly contains a mixture or Core and Admin templates. Templates in workarea-core are shared between the Admin and Storefront.
143
+
144
+ ```ruby
145
+ # JST Templates
146
+ %w(
147
+ workarea/core/templates/ui_menu_heading
148
+ workarea/core/templates/ui_menu_item
149
+ workarea/core/templates/lorem_ipsum_view
150
+ workarea/core/templates/reveal_password_button
151
+ workarea/storefront/templates/loading
152
+ workarea/storefront/templates/message
153
+ workarea/storefront/templates/message_dismiss_action
154
+ workarea/storefront/templates/button
155
+ workarea/storefront/templates/same_as_shipping_button_property
156
+ workarea/storefront/templates/saved_addresses_property
157
+ workarea/storefront/templates/log_out_link
158
+ workarea/storefront/templates/page_header_cart_count
159
+ workarea/storefront/templates/pagination_button
160
+ ).each do |asset|
161
+ require_asset asset
162
+ end
163
+
164
+ # Plugin JST Templates
165
+ append_javascripts('storefront.templates')
166
+ ```
167
+
168
+ Following the `require_asset` loop is another call to `append_javascripts`, this time allowing Plugins to append their templates to the manifest.
169
+
170
+ ### jQuery UI Widgets
171
+
172
+ Workarea uses a variety of [jQuery UI](https://jqueryui.com/) widgets, such as dialog and autocomplete, to build out the Storefront and Admin user interfaces. Workarea also extends jQuery UI, using the provided [widget factory](https://jqueryui.com/widget/), to create custom widgets.
173
+
174
+ Those widgets are included in the manifest next. Although previous versions of Workarea had more, there is now only one. Poor little fella.
175
+
176
+ ```ruby
177
+ # Library Extensions
178
+ %w(
179
+ jquery_ui/core/categorized_autocomplete
180
+ ).each do |asset|
181
+ require_asset asset
182
+ end
183
+ ```
184
+
185
+ Note that these files (ok, file) are in a subdirectory of `jquery_ui` rather than `workarea` since they follow the rules established by the jQuery framework, not Workarea.
186
+
187
+ ### workarea.js
188
+
189
+ Next up is the workarea.js file.
190
+
191
+ ```ruby
192
+ # Workarea Module Controller
193
+ require_asset 'workarea/core/workarea'
194
+ ```
195
+
196
+ This file establishes the `WORKAREA` namespace, the global variable on which the Workarea JavaScript API is built. Everythig before this point in the manifest hangs off other globals, like `$`, `_`, and `JST`, for example. workarea.js will not overwrite an existing `WORKAREA` global if for some reason you need to define it earlier in your app.
197
+
198
+ After establishing the top level namespace, the methods `registerModule` and `initModules` are added to it. If you didn't already guess, these are used to register and init [Workarea JavaScript modules](javascript-modules.html).
199
+
200
+ ### Configuration Files
201
+
202
+ [Configuration files](configuration.html) are included next in the application manifest, including an append point for plugins. This is where the global `WORKAREA.config` object is defined and subsequently added to.
203
+
204
+ ```ruby
205
+ # Configuration
206
+ %w(
207
+ workarea/core/config
208
+ workarea/storefront/config
209
+ ).each do |asset|
210
+ require_asset asset
211
+ end
212
+
213
+ # Plugin Configuration
214
+ append_javascripts('storefront.config')
215
+ ```
216
+
217
+ ### Routes
218
+
219
+ Included next are files that allow [accessing routes in javascript](access-routes-in-javascript.html).
220
+
221
+ ```ruby
222
+ # Routing
223
+ %w(
224
+ workarea/core/routes
225
+ workarea/storefront/routes
226
+ ).each do |asset|
227
+ require_asset asset
228
+ end
229
+ ```
230
+
231
+ ### Modules
232
+
233
+ Everything up until this point has been an opening act—fun, but not what you came out for. **[Modules](javascript-modules.html) are the band you came to see**, and they get added to the manifest next. Modules make use of the dependencies, templates, jQuery UI widgets, namespaces, configs, and routes above to do the actual client-side work.
234
+
235
+ ```ruby
236
+ # Modules
237
+ %w(
238
+ workarea/core/modules/transition_events
239
+ workarea/core/modules/environment
240
+ workarea/core/modules/cookie
241
+ workarea/core/modules/string
242
+ workarea/core/modules/url
243
+ workarea/core/modules/image
244
+ workarea/core/modules/deletion_forms
245
+ workarea/core/modules/form_submitting_controls
246
+ workarea/core/modules/jquery
247
+ workarea/core/modules/style_guide_empty_links
248
+ workarea/core/modules/style_guide_autocomplete_fields
249
+ workarea/core/modules/reveal_password
250
+ workarea/core/modules/local_time
251
+ workarea/storefront/modules/forms
252
+ workarea/storefront/modules/dialog
253
+ workarea/storefront/modules/dialog_buttons
254
+ workarea/storefront/modules/dialog_forms
255
+ workarea/storefront/modules/dialog_close_buttons
256
+ workarea/storefront/modules/loading
257
+ workarea/storefront/modules/messages
258
+ workarea/storefront/modules/pagination
259
+ workarea/storefront/modules/current_user
260
+ workarea/storefront/modules/break_points
261
+ workarea/storefront/modules/primary_nav_content
262
+ workarea/storefront/modules/product_details_sku_selects
263
+ workarea/storefront/modules/popup_buttons
264
+ workarea/storefront/modules/search_fields
265
+ workarea/storefront/modules/alternate_image_buttons
266
+ workarea/storefront/modules/scroll_to_buttons
267
+ workarea/storefront/modules/address_region_fields
268
+ workarea/storefront/modules/checkout_addresses_forms
269
+ workarea/storefront/modules/checkout_shipping_services
270
+ workarea/storefront/modules/checkout_primary_payments
271
+ workarea/storefront/modules/single_submit_forms
272
+ workarea/storefront/modules/log_out_link_placeholders
273
+ workarea/storefront/modules/admin_toolbar
274
+ workarea/storefront/modules/analytics
275
+ workarea/storefront/modules/cart_count
276
+ workarea/storefront/modules/recommendations_placeholders
277
+ workarea/storefront/modules/recent_views
278
+ workarea/storefront/modules/workarea_analytics
279
+ workarea/storefront/modules/mobile_nav_button
280
+ ).each do |asset|
281
+ require_asset asset
282
+ end
283
+
284
+ # Plugin Modules
285
+ append_javascripts('storefront.modules')
286
+ ```
287
+
288
+ Similarly to the other manifest sections, modules are loaded from both Core and Storefront (or Admin if looking at the Admin application manifest), and plugins can append their modules after the Core and Storefront modules.
289
+
290
+ ### Module Initialization
291
+
292
+ The last line of the manifest is executable JavaScript code used to initialize modules. This process is covered in detail in the [JavaScript Modules](javascript-modules.html) guide.
293
+
294
+ ```js
295
+ WORKAREA.initModules($(document));
296
+ ```
297
+
298
+ ## Admin's Application Manifest
299
+
300
+ The Admin has one single application manifest, but it is loaded at the end of the `head` element rather than the `body`. This is because the Admin uses a library called [Turbolinks](https://github.com/turbolinks/turbolinks) which aims to make navigating the Admin faster. This is achieved by loading the entire `document` once and relying on AJAX-enabled links to replace the `body` tag with that of the next page each time a request is made.
301
+
302
+ Since there is only one manifest, and since it is appended to the `head`, it is naturally an amalgam of both a head and application manifest, as outlined int he previous sections.
303
+
304
+ Because the Admin uses Turbolinks, we handle the last part of the Admin's application manifest a little differently:
305
+
306
+ ### Module Initialization
307
+
308
+ ```js
309
+ $(document).on('turbolinks:load', function () {
310
+ WORKAREA.initModules($(body)); // Initialize all modules
311
+ });
312
+ ```
313
+
314
+ Turbolinks provides [event hooks](https://github.com/turbolinks/turbolinks#full-list-of-events) for each stage of the request and response functionality it handles. When a page is requested and its `body` tag replaces the current `body` tag, it fires a `turbolinks:load` event. This is the hook we use to initialize our modules.
315
+
316
+ ### Handling Outbound Linking
317
+
318
+ ```js
319
+ $(document).on('turbolinks:click', function (event) {
320
+ var goingElsewhere = !_.includes(
321
+ event.originalEvent.data.url,
322
+ WORKAREA.routes.admin.rootPath()
323
+ );
324
+
325
+ if (goingElsewhere) {
326
+ event.preventDefault();
327
+ }
328
+ });
329
+ ```
330
+
331
+ Since Turbolinks has controls clicks on all links in its domain, we listen for and stop this behavior for links that do not begin with `http://domain.com/admin`.
332
+
333
+ ### Handling Outbound Redirects
334
+
335
+ ```js
336
+ $(document).on('turbolinks:request-end', function(event) {
337
+ var redirectElsewhere = !_.includes(
338
+ event.originalEvent.data.xhr.responseURL,
339
+ WORKAREA.routes.admin.rootPath()
340
+ );
341
+
342
+ if (redirectElsewhere) {
343
+ event.preventDefault();
344
+ window.location = event.originalEvent.data.url;
345
+ }
346
+ });
347
+ ```
348
+
349
+ Similarly, when we detect that an asynchronous request should redirect to an outbound URL, we hijack that interaction as well.
350
+
351
+ ## Adding and Removing JavaScripts
352
+
353
+ Oh yeah, I guess this guide was supposed to be about adding and removing JavaScripts through a manifest. Well, now that you know how the manifests are structured, adding and removing files is as easy as adding and removing paths within the various arrays.
354
+
355
+ If the asset you want to include has been packaged as a gem, first add the gem to your Gemfile and then require the asset in your manifest using the path to the asset within the gem. If the asset is not available as a gem, simply download the asset and copy it to your application's `vendor/assets/javascripts` directory and reference it from there.
356
+
357
+ ```ruby
358
+ %w(
359
+ # ...
360
+ your_additional_asset # from some_gem/app/assets/javascripts
361
+ your_additional_additional_asset # from your_app/vendor/assets/javascripts
362
+ ).each do |asset|
363
+ require_asset asset
364
+ end
365
+ ```
366
+
367
+ Refer to [Appending](appending.html) for advice on managing plugin JavaScripts in your manifests.