UNPKG

@shopware-ag/meteor-component-library

Version:

The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).

221 lines (183 loc) 8.34 kB
/** * Mock for the storybook story which mocks * the whole repository with a mock implementation. * This is necessary because the repository is not * available in the storybook story. * * See original implementation in: * meteor/packages/admin-sdk/src/data/repository.ts */ import Criteria from "@shopware-ag/meteor-admin-sdk/es/data/Criteria"; import type { Repository } from "@shopware-ag/meteor-admin-sdk/es/data/repository"; import type { Entity } from "@shopware-ag/meteor-admin-sdk/es/_internals/data/Entity"; import EntityCollection, { type ApiContext, } from "@shopware-ag/meteor-admin-sdk/es/_internals/data/EntityCollection"; import productFixtures from "../../../table-and-list/mt-data-table/mt-data-table.fixtures.json"; // Create the manufacturer fixtures from the product fixtures const manufacturerFixtures = productFixtures.map((product) => ({ id: product.manufacturer.id, name: product.manufacturer.name, translated: { name: product.manufacturer.name, }, })); export default <EntityName extends keyof EntitySchema.Entities>( entityName: EntityName, ): Repository<EntityName> => { // Simulate a database const entities: Entity<EntityName>[] = // @ts-expect-error - This is a mock entityName === "product" ? // @ts-expect-error - This is a mock (productFixtures as Entity<EntityName>[]) : // @ts-expect-error - This is a mock (manufacturerFixtures as Entity<EntityName>[]); const mockApiContext: ApiContext = { apiPath: null, apiResourcePath: null, assetsPath: null, authToken: null, basePath: null, pathInfo: null, inheritance: null, installationPath: null, languageId: "2fbb5fe2e29a4d70aa5854ce7ce3e20b", language: null, apiVersion: null, liveVersionId: null, systemLanguageId: null, }; return { search: async (criteria: Criteria): Promise<EntityCollection<EntityName> | null> => { let filteredEntities = [...entities]; // Handle term search (simple case-insensitive search in 'name' field) const term = criteria.term; if (term) { filteredEntities = filteredEntities.filter((entity) => { const name = (entity as any)?.name ?? (entity as any)?.translated?.name; return name?.toLowerCase().includes(term.toLowerCase()); }); } // Handle filters if (criteria.filters && criteria.filters.length > 0) { filteredEntities = filteredEntities.filter((entity) => { return (criteria.filters as any[]).every((filter) => { const { field, type, value } = filter as { field: string; type: string; value: any }; // Helper to get potentially nested entity values const entityValue = field.split(".").reduce((o, i) => o?.[i], entity as any); if (type === "equals") { // Handle boolean values that might come as strings 'true'/'false' from filter UI if (typeof entityValue === "boolean" && (value === "true" || value === "false")) { return entityValue === (value === "true"); } return entityValue === value; } if (type === "equalsAny") { if (Array.isArray(value) && value.length > 0) { return value.includes(entityValue); } // If value is not an array or is empty, and type is equalsAny, // it implies no restriction from this specific filter if it was meant to select from a list. // However, if the intention is "must be one of these (empty list)", it should filter out everything. // For simplicity, if value is not a non-empty array, we treat it as not matching. return false; } // Add more filter types like 'contains', 'greaterThan', etc. as needed // For unknown filter types, we'll assume the entity passes, or you could choose to make it fail. return true; }); }); } // Handle sorting const sortSettings = criteria.sortings[0]; if (sortSettings?.field) { const sortBy = sortSettings.field; const sortOrder = sortSettings.order || "ASC"; // Default to ASC filteredEntities = filteredEntities.sort((a, b) => { const valA = sortBy.split(".").reduce((o, i) => o?.[i], a as any); const valB = sortBy.split(".").reduce((o, i) => o?.[i], b as any); // Handle null or undefined values by pushing them to the end if (valA == null && valB == null) return 0; // If sortOrder is ASC, nulls go last. If DESC, nulls go first (after reversing). // So, if valA is null, it's "greater" for ASC, "lesser" for DESC (after reversal) if (valA == null) return 1; if (valB == null) return -1; let comparison = 0; if (typeof valA === "number" && typeof valB === "number") { comparison = valA - valB; } else if (typeof valA === "string" && typeof valB === "string") { comparison = valA.localeCompare(valB); } else { // Fallback for other types or mixed types: convert to string and compare comparison = String(valA).localeCompare(String(valB)); } return sortOrder === "DESC" ? comparison * -1 : comparison; }); } const page = criteria.getPage(); const limit = criteria.getLimit(); let paginatedEntities = filteredEntities; if (limit !== null && limit > 0 && page !== null && page > 0) { const startIndex = (page - 1) * limit; const endIndex = startIndex + limit; paginatedEntities = filteredEntities.slice(startIndex, endIndex); } else if (limit !== null && limit > 0) { paginatedEntities = filteredEntities.slice(0, limit); } // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); return new EntityCollection( `mock-${entityName}-source`, entityName, mockApiContext, // Use the mock ApiContext criteria, paginatedEntities, filteredEntities.length, // Total count of filtered (pre-pagination) entities {}, // Mock aggregations, can be expanded if needed ); }, get: async (id: string): Promise<Entity<EntityName> | null> => { const entity = entities.find((e: any) => e.id === id); // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); return entity || null; }, save: async (): Promise<void | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock save operation return Promise.resolve(); }, clone: async (): Promise<unknown | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock clone operation return Promise.resolve({}); }, hasChanges: async (): Promise<boolean | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock hasChanges operation return Promise.resolve(false); }, saveAll: async (): Promise<unknown | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock saveAll operation return Promise.resolve(); }, delete: async (): Promise<void | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock delete operation return Promise.resolve(); }, create: async (): Promise<Entity<EntityName> | null> => { // Wait for 200-500ms to simulate a real API call await new Promise((resolve) => setTimeout(resolve, Math.random() * 300 + 200)); // Mock create operation return Promise.resolve(null); }, } as Repository<EntityName>; };