Skip to content

Creating a New Homepage Module

Sam B edited this page May 27, 2020 · 7 revisions

What is a module?

The home page of MyMICDS is composed of different 'modules' (different from Angular Modules). These modules can be moved, resized, and configured to the user's liking. Within the MyMICDS Angular codebase, there's is an internal API to make it easy to create another module.

How to create a home page module

To create a new homepage module*, you first create a Angular component under /src/app/components/modules. Create a new folder following component/class naming conventions, and create the homepage module's styles, templates, and typescript there.

Example:

export class WeatherComponent implements OnInit, OnDestroy {
	// One instance variable required for every option!
	// Make sure to add `@Input()` and its default value specified in the decorator!
	@Input() location = 'MICDS';
	@Input() metric = false;
	@Input() decimalPrecision = 2;
	...
}

SDK

After Creating a new module, you'll need to register it in the MyMICDS-SDK repository. You can learn more about making changes to the SDK here. You'll add it to the MyMICDSModuleType enum in /src/libs/modules.ts

Backend

If your module takes input from the parent component and/or uses the @Input decorator, you'll have to register that in the MyMICDS-v2 Repository under /src/libs/modules.ts.

const modulesConfig: Partial<Record<MyMICDSModuleType, OptionsValues>> = {
	...
	// What order should it be in?
	// Trick question. Alphabetical.
	[MyMICDSModuleType.WEATHER]: {
		// Each option key should correspond with the option key in the front-end config
		metric: {
			// `Label` property is not needed unlike the front-end config
			type: 'boolean',
			default: false
		},
		location: {
			type: 'string',
			default: 'MICDS'
		},
		decimalPrecision: {
			type: 'number',
			default: 2
		}
	}
	...
};

Module Config Properties

Finally, add the module as an option on the home page by editing /src/app/components/modules/module-config.ts in the MyMICDS-v2-Angular repository.

export const moduleComponents: any[] = [
	...
	WeatherComponent // Put in alphabetical order!
	...
];

export const config: Config = {
	...
	// Again, put the modules in alphabetical order
	// (Same order as in the `moduleComponents` array)
	weather: {
		displayName: 'Weather',
		// Look at font-awesome icons for icon names.
		// If the icon does not come from the Solid-Icon pack,
		// you'll need to do some tinkering like we did with the twitter icon
		icon: 'cloud',
		component: WeatherComponent,
		defaultHeight: 2,
		defaultWidth: 2,
		options: {
			metric: {
				label: 'Metric Units',
				type: 'boolean',
				default: false
			},
			location: {
				label: 'Location',
				type: 'string',
				default: 'MICDS'
			},
			decimalPrecision: {
				label: 'Decimal Precision',
				type: 'number',
				default: 2
			}
		}
	}
	...
};

Key of Config

Id of the module. No spaces or dashes. Should be camel case.

displayName: string

Name of the module (use spaces, no dashes or camel case)

icon: string

Font Awesome icon name used to represent the module

defaultHeight: string

Initial grid height when module created in the drag-and-drop

defaultWidth: string

Initial grid width when module created in the drag-and-drop interface

options?: { [option: string]: { label: string, type: string, value: 'boolean' | 'number' | 'string' }}

Optional. This is where a module's options are declared. Each key must correlate to a component instance variable with the @Input decorator! Make sure the default value in the decorator matches the default instance variable value. These values are used to generate a form to configure the module's options. Make sure the option types are also documented in the back-end!

Design

Modules should be enforced with a consistent design spec for a uniform experience no matter what modules the user configured.

Responsiveness

Modules should be responsive on any dimensions as small as 250px wide and 250px high, and up to 1250px wide and 1250px height and every combination in between. Module content should not overflow these bounds.