diff --git a/app/reflexes/admin/products_v3_reflex.rb b/app/reflexes/admin/products_v3_reflex.rb new file mode 100644 index 0000000000..2b507593fb --- /dev/null +++ b/app/reflexes/admin/products_v3_reflex.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Admin + class ProductsV3Reflex < ApplicationReflex + + def fetch + cable_ready.replace( + selector: "#products-content", + html: render(partial: "admin/products_v3/content") + ).broadcast + + morph :nothing + end + end +end diff --git a/app/views/admin/products_v3/_content.html.haml b/app/views/admin/products_v3/_content.html.haml new file mode 100644 index 0000000000..8a572543b3 --- /dev/null +++ b/app/views/admin/products_v3/_content.html.haml @@ -0,0 +1,7 @@ +#no-products + = t('.no_products_found') + #no-products-actions + %a{ href: "/admin/products/new", class: "button icon-plus", icon: "icon-plus" } + = t(:new_product) + %a{ href: "/admin/products/import", class: "button icon-upload secondary", icon: "icon-upload" } + = t(".import_products") diff --git a/app/views/admin/products_v3/_table.html.haml b/app/views/admin/products_v3/_table.html.haml new file mode 100644 index 0000000000..15db8e632c --- /dev/null +++ b/app/views/admin/products_v3/_table.html.haml @@ -0,0 +1 @@ +%table.products diff --git a/app/views/admin/products_v3/index.html.haml b/app/views/admin/products_v3/index.html.haml index 00c53d0557..6304780b1f 100644 --- a/app/views/admin/products_v3/index.html.haml +++ b/app/views/admin/products_v3/index.html.haml @@ -7,3 +7,9 @@ = button_link_to t(:new_product), "/admin/products/new", { :icon => 'icon-plus', :id => 'admin_new_product' } = render partial: 'spree/admin/shared/product_sub_menu' + +#products_v3_page{"data-controller": "productsV3"} + #loading-spinner.spinner-container{"data-productsV3-target": "loading"} + .spinner + = t('.loading') + #products-content diff --git a/app/webpacker/controllers/productsV3_controller.js b/app/webpacker/controllers/productsV3_controller.js new file mode 100644 index 0000000000..9a034b69e0 --- /dev/null +++ b/app/webpacker/controllers/productsV3_controller.js @@ -0,0 +1,24 @@ +import ApplicationController from "./application_controller"; + +export default class extends ApplicationController { + static targets = ["loading"]; + + connect() { + super.connect(); + // Fetch the products on page load + this.load(); + } + + load = () => { + this.showLoading(); + this.stimulate("Admin::ProductsV3#fetch").then(() => this.hideLoading()); + }; + + hideLoading = () => { + this.loadingTarget.classList.add("hidden"); + }; + + showLoading = () => { + this.loadingTarget.classList.remove("hidden"); + }; +} diff --git a/app/webpacker/css/admin_v3/components/spinner.scss b/app/webpacker/css/admin_v3/components/spinner.scss new file mode 100644 index 0000000000..1a965e3c22 --- /dev/null +++ b/app/webpacker/css/admin_v3/components/spinner.scss @@ -0,0 +1,73 @@ +.spinner-container { + position: absolute; + width: 100%; + height: 100%; + min-height: 200px; + display: flex; + justify-content: flex-start; + align-items: center; + flex-direction: column; + gap: 40px; + font-size: 24px; + background: rgba(255, 255, 255, 0.8); + + &.hidden { + display: none; + } + + > .spinner { + width: 56px; + height: 56px; + border-radius: 50%; + border: 9px solid $teal; + animation: spinner-bulqg1 0.8s infinite linear alternate, spinner-oaa3wk 1.6s infinite linear; + } +} + +@keyframes spinner-bulqg1 { + 0% { + clip-path: polygon(50% 50%, 0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%); + } + + 12.5% { + clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%); + } + + 25% { + clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%); + } + + 50% { + clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%); + } + + 62.5% { + clip-path: polygon(50% 50%, 100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%); + } + + 75% { + clip-path: polygon(50% 50%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100%); + } + + 100% { + clip-path: polygon(50% 50%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100%); + } +} + +@keyframes spinner-oaa3wk { + 0% { + transform: scaleY(1) rotate(0deg); + } + + 49.99% { + transform: scaleY(1) rotate(135deg); + } + + 50% { + transform: scaleY(-1) rotate(0deg); + } + + 100% { + transform: scaleY(-1) rotate(-135deg); + } +} diff --git a/app/webpacker/packs/admin-style-v3.scss b/app/webpacker/packs/admin-style-v3.scss index f06ef083d5..4cbab328cd 100644 --- a/app/webpacker/packs/admin-style-v3.scss +++ b/app/webpacker/packs/admin-style-v3.scss @@ -1 +1,3 @@ @import "../css/admin_v3/all.scss"; + +@import "../css/admin_v3/components/spinner.scss"; diff --git a/config/locales/en.yml b/config/locales/en.yml index 66d2b07a14..422f199e1b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -768,6 +768,10 @@ en: index: header: title: Bulk Edit Products + loading: Loading your products + content: + no_products_found: No products found + import_products: Import multiple products product_import: title: Product Import file_not_found: File not found or could not be opened