Procházet zdrojové kódy

feat(dashboard): Add rebuild search index button

David Höck před 3 měsíci
rodič
revize
c162135986

+ 8 - 0
packages/dashboard/src/app/routes/_authenticated/_products/products.graphql.ts

@@ -332,3 +332,11 @@ export const createProductVariantsDocument = graphql(`
         }
     }
 `);
+
+export const reindexDocument = graphql(`
+    mutation Reindex {
+        reindex {
+            id
+        }
+    }
+`);

+ 27 - 3
packages/dashboard/src/app/routes/_authenticated/_products/products.tsx

@@ -3,9 +3,12 @@ import { PermissionGuard } from '@/vdb/components/shared/permission-guard.js';
 import { Button } from '@/vdb/components/ui/button.js';
 import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/vdb/framework/page/list-page.js';
-import { Trans } from '@/vdb/lib/trans.js';
+import { api } from '@/vdb/graphql/api.js';
+import { Trans, useLingui } from '@/vdb/lib/trans.js';
+import { useMutation } from '@tanstack/react-query';
 import { createFileRoute, Link } from '@tanstack/react-router';
-import { PlusIcon } from 'lucide-react';
+import { PlusIcon, RefreshCwIcon } from 'lucide-react';
+import { toast } from 'sonner';
 import {
     AssignFacetValuesToProductsBulkAction,
     AssignProductsToChannelBulkAction,
@@ -13,7 +16,7 @@ import {
     DuplicateProductsBulkAction,
     RemoveProductsFromChannelBulkAction,
 } from './components/product-bulk-actions.js';
-import { productListDocument } from './products.graphql.js';
+import { productListDocument, reindexDocument } from './products.graphql.js';
 
 export const Route = createFileRoute('/_authenticated/_products/products')({
     component: ProductListPage,
@@ -21,6 +24,21 @@ export const Route = createFileRoute('/_authenticated/_products/products')({
 });
 
 function ProductListPage() {
+    const { i18n } = useLingui();
+    const reindexMutation = useMutation({
+        mutationFn: () => api.mutate(reindexDocument, {}),
+        onSuccess: () => {
+            toast.success(i18n.t('Search index rebuild started'));
+        },
+        onError: () => {
+            toast.error(i18n.t('Search index rebuild could not be started'));
+        },
+    });
+
+    const handleRebuildSearchIndex = () => {
+        reindexMutation.mutate();
+    };
+
     return (
         <ListPage
             pageId="product-list"
@@ -62,6 +80,12 @@ function ProductListPage() {
             ]}
         >
             <PageActionBarRight>
+                <PermissionGuard requires={['UpdateCatalog']}>
+                    <Button variant="outline" onClick={handleRebuildSearchIndex}>
+                        <RefreshCwIcon />
+                        <Trans>Rebuild search index</Trans>
+                    </Button>
+                </PermissionGuard>
                 <PermissionGuard requires={['CreateProduct', 'CreateCatalog']}>
                     <Button asChild>
                         <Link to="./new">

+ 1 - 1
packages/dashboard/src/lib/graphql/graphql-env.d.ts

@@ -273,7 +273,7 @@ export type introspection_types = {
     'PaymentMethodTranslationInput': { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'languageCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'LanguageCode'; ofType: null; }; }; defaultValue: null }, { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
     'PaymentOrderMismatchError': { kind: 'OBJECT'; name: 'PaymentOrderMismatchError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
     'PaymentStateTransitionError': { kind: 'OBJECT'; name: 'PaymentStateTransitionError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'fromState': { name: 'fromState'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'toState': { name: 'toState'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'transitionError': { name: 'transitionError'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
-    'Permission': { name: 'Permission'; enumValues: 'Authenticated' | 'SuperAdmin' | 'Owner' | 'Public' | 'UpdateGlobalSettings' | 'CreateCatalog' | 'ReadCatalog' | 'UpdateCatalog' | 'DeleteCatalog' | 'CreateSettings' | 'ReadSettings' | 'UpdateSettings' | 'DeleteSettings' | 'CreateAdministrator' | 'ReadAdministrator' | 'UpdateAdministrator' | 'DeleteAdministrator' | 'CreateAsset' | 'ReadAsset' | 'UpdateAsset' | 'DeleteAsset' | 'CreateChannel' | 'ReadChannel' | 'UpdateChannel' | 'DeleteChannel' | 'CreateCollection' | 'ReadCollection' | 'UpdateCollection' | 'DeleteCollection' | 'CreateCountry' | 'ReadCountry' | 'UpdateCountry' | 'DeleteCountry' | 'CreateCustomer' | 'ReadCustomer' | 'UpdateCustomer' | 'DeleteCustomer' | 'CreateCustomerGroup' | 'ReadCustomerGroup' | 'UpdateCustomerGroup' | 'DeleteCustomerGroup' | 'CreateFacet' | 'ReadFacet' | 'UpdateFacet' | 'DeleteFacet' | 'CreateOrder' | 'ReadOrder' | 'UpdateOrder' | 'DeleteOrder' | 'CreatePaymentMethod' | 'ReadPaymentMethod' | 'UpdatePaymentMethod' | 'DeletePaymentMethod' | 'CreateProduct' | 'ReadProduct' | 'UpdateProduct' | 'DeleteProduct' | 'CreatePromotion' | 'ReadPromotion' | 'UpdatePromotion' | 'DeletePromotion' | 'CreateShippingMethod' | 'ReadShippingMethod' | 'UpdateShippingMethod' | 'DeleteShippingMethod' | 'CreateTag' | 'ReadTag' | 'UpdateTag' | 'DeleteTag' | 'CreateTaxCategory' | 'ReadTaxCategory' | 'UpdateTaxCategory' | 'DeleteTaxCategory' | 'CreateTaxRate' | 'ReadTaxRate' | 'UpdateTaxRate' | 'DeleteTaxRate' | 'CreateSeller' | 'ReadSeller' | 'UpdateSeller' | 'DeleteSeller' | 'CreateStockLocation' | 'ReadStockLocation' | 'UpdateStockLocation' | 'DeleteStockLocation' | 'CreateSystem' | 'ReadSystem' | 'UpdateSystem' | 'DeleteSystem' | 'CreateZone' | 'ReadZone' | 'UpdateZone' | 'DeleteZone'; };
+    'Permission': { name: 'Permission'; enumValues: 'Authenticated' | 'SuperAdmin' | 'Owner' | 'Public' | 'UpdateGlobalSettings' | 'CreateCatalog' | 'ReadCatalog' | 'UpdateCatalog' | 'DeleteCatalog' | 'CreateSettings' | 'ReadSettings' | 'UpdateSettings' | 'DeleteSettings' | 'CreateAdministrator' | 'ReadAdministrator' | 'UpdateAdministrator' | 'DeleteAdministrator' | 'CreateAsset' | 'ReadAsset' | 'UpdateAsset' | 'DeleteAsset' | 'CreateChannel' | 'ReadChannel' | 'UpdateChannel' | 'DeleteChannel' | 'CreateCollection' | 'ReadCollection' | 'UpdateCollection' | 'DeleteCollection' | 'CreateCountry' | 'ReadCountry' | 'UpdateCountry' | 'DeleteCountry' | 'CreateCustomer' | 'ReadCustomer' | 'UpdateCustomer' | 'DeleteCustomer' | 'CreateCustomerGroup' | 'ReadCustomerGroup' | 'UpdateCustomerGroup' | 'DeleteCustomerGroup' | 'CreateFacet' | 'ReadFacet' | 'UpdateFacet' | 'DeleteFacet' | 'CreateOrder' | 'ReadOrder' | 'UpdateOrder' | 'DeleteOrder' | 'CreatePaymentMethod' | 'ReadPaymentMethod' | 'UpdatePaymentMethod' | 'DeletePaymentMethod' | 'CreateProduct' | 'ReadProduct' | 'UpdateProduct' | 'DeleteProduct' | 'CreatePromotion' | 'ReadPromotion' | 'UpdatePromotion' | 'DeletePromotion' | 'CreateShippingMethod' | 'ReadShippingMethod' | 'UpdateShippingMethod' | 'DeleteShippingMethod' | 'CreateTag' | 'ReadTag' | 'UpdateTag' | 'DeleteTag' | 'CreateTaxCategory' | 'ReadTaxCategory' | 'UpdateTaxCategory' | 'DeleteTaxCategory' | 'CreateTaxRate' | 'ReadTaxRate' | 'UpdateTaxRate' | 'DeleteTaxRate' | 'CreateSeller' | 'ReadSeller' | 'UpdateSeller' | 'DeleteSeller' | 'CreateStockLocation' | 'ReadStockLocation' | 'UpdateStockLocation' | 'DeleteStockLocation' | 'CreateSystem' | 'ReadSystem' | 'UpdateSystem' | 'DeleteSystem' | 'CreateZone' | 'ReadZone' | 'UpdateZone' | 'DeleteZone' | 'ReadDashboardGlobalViews' | 'WriteDashboardGlobalViews'; };
     'PermissionDefinition': { kind: 'OBJECT'; name: 'PermissionDefinition'; fields: { 'assignable': { name: 'assignable'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
     'PreviewCollectionVariantsInput': { kind: 'INPUT_OBJECT'; name: 'PreviewCollectionVariantsInput'; isOneOf: false; inputFields: [{ name: 'parentId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'inheritFilters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'filters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
     'PriceRange': { kind: 'OBJECT'; name: 'PriceRange'; fields: { 'max': { name: 'max'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; 'min': { name: 'min'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; }; };

+ 1 - 1
packages/dev-server/graphql/graphql-env.d.ts

@@ -273,7 +273,7 @@ export type introspection_types = {
     'PaymentMethodTranslationInput': { kind: 'INPUT_OBJECT'; name: 'PaymentMethodTranslationInput'; isOneOf: false; inputFields: [{ name: 'id'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'languageCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'LanguageCode'; ofType: null; }; }; defaultValue: null }, { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'customFields'; type: { kind: 'SCALAR'; name: 'JSON'; ofType: null; }; defaultValue: null }]; };
     'PaymentOrderMismatchError': { kind: 'OBJECT'; name: 'PaymentOrderMismatchError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
     'PaymentStateTransitionError': { kind: 'OBJECT'; name: 'PaymentStateTransitionError'; fields: { 'errorCode': { name: 'errorCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'ErrorCode'; ofType: null; }; } }; 'fromState': { name: 'fromState'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'message': { name: 'message'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'toState': { name: 'toState'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'transitionError': { name: 'transitionError'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
-    'Permission': { name: 'Permission'; enumValues: 'Authenticated' | 'SuperAdmin' | 'Owner' | 'Public' | 'UpdateGlobalSettings' | 'CreateCatalog' | 'ReadCatalog' | 'UpdateCatalog' | 'DeleteCatalog' | 'CreateSettings' | 'ReadSettings' | 'UpdateSettings' | 'DeleteSettings' | 'CreateAdministrator' | 'ReadAdministrator' | 'UpdateAdministrator' | 'DeleteAdministrator' | 'CreateAsset' | 'ReadAsset' | 'UpdateAsset' | 'DeleteAsset' | 'CreateChannel' | 'ReadChannel' | 'UpdateChannel' | 'DeleteChannel' | 'CreateCollection' | 'ReadCollection' | 'UpdateCollection' | 'DeleteCollection' | 'CreateCountry' | 'ReadCountry' | 'UpdateCountry' | 'DeleteCountry' | 'CreateCustomer' | 'ReadCustomer' | 'UpdateCustomer' | 'DeleteCustomer' | 'CreateCustomerGroup' | 'ReadCustomerGroup' | 'UpdateCustomerGroup' | 'DeleteCustomerGroup' | 'CreateFacet' | 'ReadFacet' | 'UpdateFacet' | 'DeleteFacet' | 'CreateOrder' | 'ReadOrder' | 'UpdateOrder' | 'DeleteOrder' | 'CreatePaymentMethod' | 'ReadPaymentMethod' | 'UpdatePaymentMethod' | 'DeletePaymentMethod' | 'CreateProduct' | 'ReadProduct' | 'UpdateProduct' | 'DeleteProduct' | 'CreatePromotion' | 'ReadPromotion' | 'UpdatePromotion' | 'DeletePromotion' | 'CreateShippingMethod' | 'ReadShippingMethod' | 'UpdateShippingMethod' | 'DeleteShippingMethod' | 'CreateTag' | 'ReadTag' | 'UpdateTag' | 'DeleteTag' | 'CreateTaxCategory' | 'ReadTaxCategory' | 'UpdateTaxCategory' | 'DeleteTaxCategory' | 'CreateTaxRate' | 'ReadTaxRate' | 'UpdateTaxRate' | 'DeleteTaxRate' | 'CreateSeller' | 'ReadSeller' | 'UpdateSeller' | 'DeleteSeller' | 'CreateStockLocation' | 'ReadStockLocation' | 'UpdateStockLocation' | 'DeleteStockLocation' | 'CreateSystem' | 'ReadSystem' | 'UpdateSystem' | 'DeleteSystem' | 'CreateZone' | 'ReadZone' | 'UpdateZone' | 'DeleteZone'; };
+    'Permission': { name: 'Permission'; enumValues: 'Authenticated' | 'SuperAdmin' | 'Owner' | 'Public' | 'UpdateGlobalSettings' | 'CreateCatalog' | 'ReadCatalog' | 'UpdateCatalog' | 'DeleteCatalog' | 'CreateSettings' | 'ReadSettings' | 'UpdateSettings' | 'DeleteSettings' | 'CreateAdministrator' | 'ReadAdministrator' | 'UpdateAdministrator' | 'DeleteAdministrator' | 'CreateAsset' | 'ReadAsset' | 'UpdateAsset' | 'DeleteAsset' | 'CreateChannel' | 'ReadChannel' | 'UpdateChannel' | 'DeleteChannel' | 'CreateCollection' | 'ReadCollection' | 'UpdateCollection' | 'DeleteCollection' | 'CreateCountry' | 'ReadCountry' | 'UpdateCountry' | 'DeleteCountry' | 'CreateCustomer' | 'ReadCustomer' | 'UpdateCustomer' | 'DeleteCustomer' | 'CreateCustomerGroup' | 'ReadCustomerGroup' | 'UpdateCustomerGroup' | 'DeleteCustomerGroup' | 'CreateFacet' | 'ReadFacet' | 'UpdateFacet' | 'DeleteFacet' | 'CreateOrder' | 'ReadOrder' | 'UpdateOrder' | 'DeleteOrder' | 'CreatePaymentMethod' | 'ReadPaymentMethod' | 'UpdatePaymentMethod' | 'DeletePaymentMethod' | 'CreateProduct' | 'ReadProduct' | 'UpdateProduct' | 'DeleteProduct' | 'CreatePromotion' | 'ReadPromotion' | 'UpdatePromotion' | 'DeletePromotion' | 'CreateShippingMethod' | 'ReadShippingMethod' | 'UpdateShippingMethod' | 'DeleteShippingMethod' | 'CreateTag' | 'ReadTag' | 'UpdateTag' | 'DeleteTag' | 'CreateTaxCategory' | 'ReadTaxCategory' | 'UpdateTaxCategory' | 'DeleteTaxCategory' | 'CreateTaxRate' | 'ReadTaxRate' | 'UpdateTaxRate' | 'DeleteTaxRate' | 'CreateSeller' | 'ReadSeller' | 'UpdateSeller' | 'DeleteSeller' | 'CreateStockLocation' | 'ReadStockLocation' | 'UpdateStockLocation' | 'DeleteStockLocation' | 'CreateSystem' | 'ReadSystem' | 'UpdateSystem' | 'DeleteSystem' | 'CreateZone' | 'ReadZone' | 'UpdateZone' | 'DeleteZone' | 'ReadDashboardGlobalViews' | 'WriteDashboardGlobalViews'; };
     'PermissionDefinition': { kind: 'OBJECT'; name: 'PermissionDefinition'; fields: { 'assignable': { name: 'assignable'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
     'PreviewCollectionVariantsInput': { kind: 'INPUT_OBJECT'; name: 'PreviewCollectionVariantsInput'; isOneOf: false; inputFields: [{ name: 'parentId'; type: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; defaultValue: null }, { name: 'inheritFilters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; }; defaultValue: null }, { name: 'filters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'ConfigurableOperationInput'; ofType: null; }; }; }; }; defaultValue: null }]; };
     'PriceRange': { kind: 'OBJECT'; name: 'PriceRange'; fields: { 'max': { name: 'max'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; 'min': { name: 'min'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Money'; ofType: null; }; } }; }; };