Skip to content
This repository has been archived by the owner on Oct 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #110 from DivanteLtd/feature/107-rfc-for-page-cont…
Browse files Browse the repository at this point in the history
…ent-resolving-endpoint

feature/107-rfc-for-page-content-resolving-endpoint
  • Loading branch information
patzick authored Oct 29, 2019
2 parents 2d7d150 + 696a549 commit f15b6d7
Show file tree
Hide file tree
Showing 15 changed files with 519 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
CmsPageType,
CmsSlotType,
SectionType,
SizingMode,
MobileBehavior,
BackgroundMediaMode
} from "../../../../../src/interfaces/models/content/cms/CmsPage";

describe("Interfaces - CmsPage", () => {
it("should contain valid values for CmsPageType", async () => {
expect(CmsPageType.DEFAULT).toEqual("default");
expect(CmsPageType.LANDING_PAGE).toEqual("landingpage");
expect(CmsPageType.PRODUCT_LISTING).toEqual("product_list");
});

it("should contain valid values for CmsSlotType", async () => {
expect(CmsSlotType.IMAGE).toEqual("image");
expect(CmsSlotType.PRODUCT_BOX).toEqual("product-box");
expect(CmsSlotType.PRODUCT_LISTING).toEqual("product-listing");
expect(CmsSlotType.PRODUCT_SLIDER).toEqual("product-slider");
expect(CmsSlotType.SLOT).toEqual("slot");
expect(CmsSlotType.TEXT).toEqual("text");
});

it("should contain valid values for SectionType", async () => {
expect(SectionType.DEFAULT).toEqual("default");
});

it("should contain valid values for SizingMode", async () => {
expect(SizingMode.BOXED).toEqual("boxed");
});

it("should contain valid values for MobileBehavior", async () => {
expect(MobileBehavior.BOXED).toEqual("boxed");
expect(MobileBehavior.WRAP).toEqual("wrap");
});

it("should contain valid values for BackgroundMediaMode", async () => {
expect(BackgroundMediaMode.COVER).toEqual("cover");
});
});
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
export interface CustomFields {
[key: string]: boolean | string | number | Date;
}

export interface CustomField {}
Original file line number Diff line number Diff line change
@@ -1 +1,119 @@
export interface CmsPage {}
import { CustomField } from "../../common/CustomField";
import { Category } from "../category/Category";

export enum CmsPageType {
DEFAULT = "default",
PRODUCT_LISTING = "product_list",
LANDING_PAGE = "landingpage"
}
export interface CmsPage {
type: CmsPageType;
name: string;
customFields: CustomField[] | null;
locked: boolean;
_uniqueIdentifier: string;
versionId: string | null;
translated: any;
createdAt: Date;
updatedAt: Date;
extensions: [any];
id: string;
entity: any | null;
sections: CmsSection[];
translations: [any] | null;
categories: [Category] | null;
config: any | null;
previewMediaId: any | null;
previewMedia: any | null;
}

export enum CmsSlotType {
IMAGE = "image",
PRODUCT_SLIDER = "product-slider",
PRODUCT_LISTING = "product-listing",
PRODUCT_BOX = "product-box",
SLOT = "slot",
TEXT = "text"
}

export interface CmsFieldConfig {
name: string;
source: string;
value: string;
}

export interface CmsSlot {
type: CmsSlotType;
customFields: CustomField[] | null;
locked: boolean;
_uniqueIdentifier: string;
versionId: string;
translated: any;
createdAt: Date;
updatedAt: Date | null;
extensions: [any];
id: string;
translations: any | null;
config: any;
slot: string;
block: CmsBlock | null;
blockId: string;
fieldConfig: CmsFieldConfig[];
data?: any;
}

export interface CmsBlock {
name: string;
sectionPosition: string;
marginTop: string;
marginBottom: string;
marginLeft: string;
marginRight: string;
backgroundColor: string;
backgroundMediaId: string;
backgroundMediaMode: string;
cssClass: string;
slots: CmsSlot[];
}

export enum SectionType {
DEFAULT = "default"
}

export enum SizingMode {
BOXED = "boxed"
}

export enum MobileBehavior {
BOXED = "boxed",
WRAP = "wrap"
}

export enum BackgroundMediaMode {
COVER = "cover"
}

export interface CmsSection {
type: SectionType;
pageId: string;
page: null;
position: number;
name: string | null;
sizingMode: SizingMode;
mobileBehavior: MobileBehavior;
backgroundColor: string | null;
backgroundMediaId: string | null;
backgroundMedia: null;
backgroundMediaMode: BackgroundMediaMode;
cssClass: string | null;
customFields: CustomField[] | null;
locked: false;
_uniqueIdentifier: string;
versionId: string | null;
translated: [any];
createdAt: Date;
updatedAt: Date;
extensions: [any];
id: string;
blocks: CmsBlock[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import { CustomField } from "../../common/CustomField";
export interface Tax {
taxRate: number;
name: string;
products: Product[];
products: Product[] | null;
customFields: CustomField[];
}
1 change: 1 addition & 0 deletions packages/shopware-6-client/src/services/cmsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
interface cmsService {}
31 changes: 31 additions & 0 deletions rfc/Resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import axios from "axios";
import { PageCriteria } from "./ResolverInterface";

/**
* use case for specific category
*/
const getPageForHeadless = (params: PageCriteria) =>
axios.post("/resolver", params, {
headers: {
"sw-context-token": "JwQCccZtRmRtpoxORKSm6pFGGC18175P"
}
});

const searchCriteria: PageCriteria = {
path: "Kids-Toys/Health-Beauty"
};

!(async () => {
const { data } = await getPageForHeadless(searchCriteria);
})();

/**
* use case for specific product
*/
const resolveProductCriteria: PageCriteria = {
path: "Aerodynamic-Iron-Jetsilk/eea0f69ec02d44f7a4224272b3d99478"
};

!(async () => {
const { data } = await getPageForHeadless(resolveProductCriteria);
})();
4 changes: 4 additions & 0 deletions rfc/Resolver/Breadcrumb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Breadcrumb {
name: string;
path: string;
}
62 changes: 62 additions & 0 deletions rfc/Resolver/CategoryForHeadless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Breadcrumb } from "./Breadcrumb";
import { ProductForCategoryPageHeadless } from "./ProductForCategoryPageHeadless";
import { CmsPage } from "../../packages/shopware-6-client/src/interfaces/models/content/cms/CmsPage";
import { Media } from "../../packages/shopware-6-client/src/interfaces/models/content/media/Media";

// PLACEHOLDERS IN CMS PAGES OF SHOPWARE 6
//
// category.type
// category.name
// category.externalLink
// category.description
// category.media.alt
// category.media.title
// category.media.url
// category.media

export interface CategoryForHeadless {
availableSorting: [Sort];
availableFiltering: [Filter];

id: string;
name: string | null;
description: string;
childCount: number;

parentId: string | null;
breadcrumb: Breadcrumb[];
level: number;

children: CategoryForHeadless[] | null;
products: ProductForCategoryPageHeadless[] | null;

cmsPage: CmsPage | null;

// what is media here? some thumbnail of a category?
media: Media | null;
}

interface Sort {
field: string; // field name to sort by
label: string; // translated label
}

enum FilterType {
option = "option", // it's default and only one for properties - internally in SW
range = "range" // additional, does not exist in SW, but could be only marked as the range for price
// ...
}

interface FilterProperty {
id: string; // property id
label: string; // property label
}

interface Filter {
groupId: string; // id of the group the attribute belongs to
code: string; // literal code (user friendly insted of using groupId)
label: string; // translated label, the name of the Field name you can filter by
// translated : {} or just follow the SW translation standard and use to translated object inside the filter
type: FilterType;
properties?: [FilterProperty]; // optional, if type == 'option'
}
3 changes: 3 additions & 0 deletions rfc/Resolver/CmsPageForHeadless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { CmsPage } from "../../packages/shopware-6-client/src/interfaces/models/content/cms/CmsPage";

export interface CmsPageForHeadless extends CmsPage {}
6 changes: 6 additions & 0 deletions rfc/Resolver/ListingPriceForHeadless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { PriceNetGross } from "./PriceNetGross";

export interface ListingPriceForHeadless {
from: PriceNetGross;
to: PriceNetGross;
}
4 changes: 4 additions & 0 deletions rfc/Resolver/PriceNetGross.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PriceNetGross {
net: number;
gross: number;
}
41 changes: 41 additions & 0 deletions rfc/Resolver/ProductForCategoryPageHeadless.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ListingPriceForHeadless } from "./ListingPriceForHeadless";

export interface ProductForCategoryPageHeadless {
// basic product data for category page
id: string;
name: string | null;
description: string | null;

// labels to display in the frontend layer
available: boolean; // because of "Inform me about availability" or for making it possible to switch between variants
isNew: boolean;
isCloseout: boolean | null;
shippingFree: boolean | null;
markAsTopseller: boolean | null;

// it is a parent product of some variant
parentId: string | null;

// we would like to get price ranges or specific price, that we need to display in Category Page for given sw-context-token only
listingPrices: ListingPriceForHeadless;

// thumbnail
cover: {
media: {
title: string | null;
alt: string | null;
url: string;
thumbnails: [
// How do we choose the right thumbnail to display for specific view port?
{
width: number;
height: number;
url: string;
}
];
};
};

// star rating
ratingAverage: number | null;
}
Loading

0 comments on commit f15b6d7

Please sign in to comment.