@vendasta/meeting-scheduler

Confluence page: https://vendasta.jira.com/wiki/spaces/BOOKME/overview?homepageId=319915356

Usage no npm install needed!

<script type="module">
  import vendastaMeetingScheduler from 'https://cdn.skypack.dev/@vendasta/meeting-scheduler';
</script>

README

Meeting Scheduler

Confluence page: https://vendasta.jira.com/wiki/spaces/BOOKME/overview?homepageId=319915356

Owners: Booking Private Ryan

Meeting Scheduler is an application to facilitate scheduling and meetings between hosts and guests. The guest url can be visited at bookmenow.info.

Setup

Setting up the Meeting Scheduler to work in your application involves a few key steps:

If you are using meeting-scheduler from node_modules

You need to include the assets folder in your angular.json under build/assets

"build": {
          "builder": "...",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts",
            "assets": [
              "src/assets",
              "src/service-worker.js",
              {
                "glob": "**/*",
                "input": "node_modules/@vendasta/meeting-scheduler/src/assets",
                "output": "./assets/"
              }
            ],
    }
}

Also, you'll need to setup the icon registry:


/**
 * function registerIcon(iconName: string, url: string, registry: MatIconRegistry, sanitizer: DomSanitizer): void {
  registry.addSvgIcon(
    iconName,
    sanitizer.bypassSecurityTrustResourceUrl(url)
  );
}

 export function initializeIconRegistration(matIconRegistry: MatIconRegistry, sanitizer: DomSanitizer): void {
  registerIcon('meet-icon', '/assets/google-hangouts-meet.svg', matIconRegistry, sanitizer);
  registerIcon('zoom-icon', '/assets/zoom-icon.svg', matIconRegistry, sanitizer);
}

 export interface MatIconInitializer {
  initialize(): void;
}

 export const MatIconInitializerToken = new InjectionToken<MatIconInitializer>('[Meeting Scheduler]: Token for registering mat icons');

// In your module
{
  provide: MatIconInitializerToken,
    deps: [MatIconRegistry, DomSanitizer],
  useFactory: matIconRegistrationFactory
},

// factory
export function matIconRegistrationFactory(matIconRegistry: MatIconRegistry, sanitizer: DomSanitizer): MatIconInitializer {
  return {
    initialize: function(): void {
      initializeIconRegistration(matIconRegistry, sanitizer);
    },
  };
}

Setup I18N

Ensure you import

TranslateModule.forRoot()

at the root of your application. Meeting Scheduler depends on the TranslateModule to be i18n compatible. Do this before importing MeetingSchedulerDataModule.forRoot

Setup Integrations

Meeting Scheduler has a hard dependency on @vendasta/integrations See Here for instructions on how to set it up.

Know your hostId

Meeting Scheduler requires a hostId and that hostId can be unique between applications. For example:

  • S&SC: the hostId is the salespersonId.
  • Task Manager: the hostId is a specially formatted identifier (TM_PID_MKT_USERID)

Configure the MeetingSchedulerDataModule

The MeetingSchedulerDataModule is used to provide top-level dependencies into Meeting Scheduler. These dependencies are used by the services and components within this library.

The MeetingSchedulerDataModule should be imported at the highest point in your application's hierarchy where Meeting Scheduler will be used (usually, this can be the AppModule).

For example, if it was the AppModule you would import the MeetingSchedulerDataModule using the following syntax:

@NgModule({
  imports: [
    MeetingSchedulerDataModule.forRoot({config: MeetingSchedulerConfigToken})
  ],
  // additional app setup
})
export class AppModule{}

providing an appropriate configuration is very important and it takes the form of an InjectionToken.

The reason we accept an InjectionToken is so you have the ability to create the configuration based on non-statically analyzable elements. These elements can include results from an API, observables from your services, etc.

You can start creating the InjectionToken like so:

export const MEETING_SCHEDULER_CONFIG_TOKEN = new InjectionToken<MeetingSchedulerConfig>('[your app name]: token for MeetingScheduler config', {
  providedIn: 'root',
  factory: function (): MeetingSchedulerConfig {
    // ... implementation that returns the configuration
  }
})

Using functions like inject will allow you to obtain instances of your services to help you pass along the required configuration.

Note:: If you are using the default Meeting Scheduler experience, simply provide the routes in the configuration by using getDefaultMeetingSchedulerLinks() and passing along the absolute path from your application to the MeetingScheduler pages.

Decide whether you're using the default Meeting Scheduler setup or customizing your own

It is strongly recommended you use the default Meeting Scheduler setup. This setup has been tested in S&SC and the team is actively invested in making sure it works moving forward.

Option 1: The default experience

To use the default Meeting Scheduler experience simply import the MeetingSchedulerModule in the module where you'll use it. This allows you to lazy-load the Meeting Scheduler components.

const routes: Routes = [
  {
    path: 'meeting-scheduler',
    loadChildren: () => import('{{path to meeting scheduler module}}').then(m => m.MeetingSchedulerModule)
  }
]

Option 2: The custom experience

After importing the MeetingSchedulerDataModule you can import pieces of Meeting Scheduler as you see fit.

You can either import the MeetingSchedulerComponents module to easily use any of the components, or import specific modules to suite your needs.

Option 3: Only using the library for data / operations

If you only wish to use the Meeting Scheduler library for performing operations / state management you only need to import the MeetingSchedulerDataModule as shown above.

Then, you can use the MeetingSchedulerStoreService or the MeetingTypeService depending on your needs.

Meeting Scheduler uses these services internally for performing operations and managing its own state. So, any operations you call is guaranteed to be reflected in any UI components you use as well.