Skip to content

Commit

Permalink
Generate types from Swagger spec (#40)
Browse files Browse the repository at this point in the history
* Generate types from Swagger spec

* Remove accidental files (oops!)

* Add note to README
  • Loading branch information
DangoDev authored Mar 19, 2019
1 parent 600524c commit 500e8d4
Show file tree
Hide file tree
Showing 18 changed files with 2,398 additions and 207 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"format:ts": "prettier --write 'src/**/*.{ts,tsx}'",
"format:watch": "npx onchange 'src/**/*.{css,ts,tsx}' -- npm run format",
"generate:docs": "node scripts/docs",
"generate:specs": "npm run generate:specs:catalog",
"generate:specs:catalog": "npx @manifoldco/swagger-to-ts src/spec/catalog/v1.yaml -o src/types/catalog.ts -n Catalog",
"postgenerate:docs": "npm run format:html",
"generate:docs:watch": "npx onchange 'src/**/readme.md' -- npm run generate:docs",
"lint": "npm run lint:js && npm run lint:css",
Expand Down
41 changes: 16 additions & 25 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
import '@stencil/core';

import '@stencil/state-tunnel';
import {
ExpandedFeature,
Plan,
} from 'types/Plan';
import {
Collection,
} from 'types/Collection';
Expand All @@ -22,24 +18,19 @@ import {
Option,
Value,
} from 'types/Select';
import {
Product,
} from 'types/Product';


export namespace Components {

interface CustomPlanFeature {
'feature': ExpandedFeature;
'feature': Catalog.ExpandedFeature;
'planLabel': string;
'selectedValue': string;
'setFeature': (label: string, value: string) => void;
}
interface CustomPlanFeatureAttributes extends StencilHTMLAttributes {
'feature'?: ExpandedFeature;
'feature'?: Catalog.ExpandedFeature;
'planLabel'?: string;
'selectedValue'?: string;
'setFeature'?: (label: string, value: string) => void;
}

interface FeaturedService {
Expand Down Expand Up @@ -225,46 +216,46 @@ export namespace Components {
}

interface PlanDetails {
'plan': Plan;
'product': Product;
'plan': Catalog.ExpandedPlan;
'product': Catalog.ExpandedProduct;
}
interface PlanDetailsAttributes extends StencilHTMLAttributes {
'plan'?: Plan;
'product'?: Product;
'plan'?: Catalog.ExpandedPlan;
'product'?: Catalog.ExpandedProduct;
}

interface PlanMenu {
'plans': Plan[];
'plans': Catalog.ExpandedPlan[];
'selectPlan': Function;
'selectedPlanId': string;
}
interface PlanMenuAttributes extends StencilHTMLAttributes {
'plans'?: Plan[];
'plans'?: Catalog.ExpandedPlan[];
'selectPlan'?: Function;
'selectedPlanId'?: string;
}

interface PlanSelector {
'plans': Plan[];
'product': Product;
'plans': Catalog.ExpandedPlan[];
'product': Catalog.ExpandedProduct;
}
interface PlanSelectorAttributes extends StencilHTMLAttributes {
'plans'?: Plan[];
'product'?: Product;
'plans'?: Catalog.ExpandedPlan[];
'product'?: Catalog.ExpandedProduct;
}

interface ProductDetails {
'product': Product;
'product': Catalog.ExpandedProduct;
}
interface ProductDetailsAttributes extends StencilHTMLAttributes {
'product'?: Product;
'product'?: Catalog.ExpandedProduct;
}

interface ProductPage {
'product': Product;
'product': Catalog.ExpandedProduct;
}
interface ProductPageAttributes extends StencilHTMLAttributes {
'product'?: Product;
'product'?: Catalog.ExpandedProduct;
}

interface ServiceCard {
Expand Down
72 changes: 18 additions & 54 deletions src/components/custom-plan-feature/custom-plan-feature.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, Prop, FunctionalComponent } from '@stencil/core';
import { ExpandedFeature } from 'types/Plan';
import { $ } from '../../utils/currency';

const STRING = 'string';
Expand All @@ -8,49 +7,34 @@ const BOOLEAN = 'boolean';

interface DropdownProps {
name: string;
onChange: (e: UIEvent) => void;
values: {
cost: number;
label: string;
name: string;
}[];
values?: Catalog.FeatureValueDetails[];
}

interface ToggleProps {
name: string;
onChange: (e: UIEvent) => void;
values: {
cost?: number;
label: string;
name: string;
price?: {};
}[];
values: Catalog.FeatureValueDetails[];
}

interface SliderProps {
name: string;
onChange: (e: UIEvent) => void;
value: {
numeric_details: {
min: number;
max: number;
increment: number;
suffix: string;
};
};
value?: Catalog.FeatureValueDetails;
}

const Dropdown: FunctionalComponent<DropdownProps> = ({ name, values }) => {
const options = values.map(({ cost, label, name: optionName }) => ({
label: `${optionName} (${cost ? $(cost) : 'Included'})`,
value: label,
}));
const options = Array.isArray(values)
? values.map(({ cost, label, name: optionName }) => ({
label: `${optionName} (${cost ? $(cost) : 'Included'})`,
value: label,
}))
: [];

return <mf-select name={name} options={options} />;
};

const Slider: FunctionalComponent<SliderProps> = ({ value, name }) => {
const { min, max, increment, suffix } = value.numeric_details;
let details: Catalog.FeatureNumericDetails = {};
if (value && value.numeric_details) details = value.numeric_details;
const { min, max, increment, suffix } = details;
return <mf-slider name={name} min={min} max={max} suffix={suffix} increment={increment} />;
};

Expand All @@ -64,44 +48,24 @@ const Toggle: FunctionalComponent<ToggleProps> = () => {
scoped: true,
})
export class CustomPlanFeature {
@Prop() feature: ExpandedFeature;
@Prop() feature: Catalog.ExpandedFeature;
@Prop() selectedValue: string;
@Prop() setFeature: (label: string, value: string) => void;
@Prop() planLabel: string = '';

handleChange = (value: string) => this.setFeature(this.feature.label, value);

get featureID() {
return `plan-${this.planLabel}-feature-${this.feature.label}`;
}

render() {
console.log(this.feature);
const { values = [], value } = this.feature;

switch (this.feature.type) {
case STRING:
return (
<Dropdown
name={this.featureID}
values={this.feature.values}
onChange={(e: any) => this.handleChange(e.target && e.target.value)}
/>
);
return <Dropdown name={this.featureID} values={values} />;
case NUMBER:
return (
<Slider
name={this.featureID}
value={this.feature.value}
onChange={(e: any) => this.handleChange(e.target && e.target.checked)}
/>
);
return <Slider name={this.featureID} value={value} />;
case BOOLEAN:
return (
<Toggle
name={this.featureID}
values={this.feature.values}
onChange={(e: any) => this.handleChange(e.target && e.target.value)}
/>
);
return <Toggle name={this.featureID} values={values} />;
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Component, State, Prop } from '@stencil/core';
import { Plan } from 'types/Plan';
import { Product } from 'types/Product';

const byCost = (a: Plan, b: Plan) => (a.body.cost < b.body.cost ? -1 : 1);
const byCost = (a: Catalog.ExpandedPlan, b: Catalog.ExpandedPlan) =>
a.body.cost < b.body.cost ? -1 : 1;

@Component({
tag: 'manifold-plan-selector',
shadow: true,
})
export class ManifoldPlanSelector {
@Prop() productId: string;
@State() product: Product;
@State() plans: Plan[];
@State() product: Catalog.ExpandedProduct;
@State() plans: Catalog.Plan[];

async componentWillLoad() {
await fetch(`https://api.catalog.stage.manifold.co/v1/products/${this.productId}`)
Expand Down
3 changes: 1 addition & 2 deletions src/components/manifold-product/manifold-product.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Component, Prop, State } from '@stencil/core';
import { Product } from 'types/Product';

@Component({ tag: 'manifold-product' })
export class ManifoldProduct {
@Prop() productLabel: string;
@State() product?: Product;
@State() product?: Catalog.ExpandedProduct;

componentWillLoad() {
return fetch(`https://api.catalog.manifold.co/v1/products?label=${this.productLabel}`)
Expand Down
Loading

0 comments on commit 500e8d4

Please sign in to comment.