@tulipnpm/timekit_project_selector 2.0.1-rc.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,9 +5,9 @@ The TimeKit Project Selector is a library that extends the functionality of [Tim
5
5
  ## Installation
6
6
 
7
7
  ```html
8
- <script src="https://cdn.jsdelivr.net/npm/@tulipnpm/timekit_project_selector@latest/dist/timekit_project_selector.min.js"></script>
9
8
  <link rel="stylesheet" href="https://cdn.timekit.io/booking-js/v3/booking.min.css" />
10
9
  <script type="text/javascript" src="//cdn.timekit.io/booking-js/v3/booking.min.js" defer></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/@tulipnpm/timekit_project_selector@latest/dist/timekit_project_selector.min.js"></script>
11
11
  ```
12
12
 
13
13
  ## Initialization
@@ -17,6 +17,7 @@ To initialize the TimeKit Project Selector on your site, you first need to impor
17
17
  ```js
18
18
  timekit_project_selector.init({
19
19
  app_key: <timekit_app_key>,
20
+ api_base_url: <timekit_api_url>
20
21
  }).then(() => {
21
22
  // Your code here...
22
23
  });
@@ -33,6 +34,7 @@ TimeKit Project Selector has many configuration options:
33
34
  | Option | Optional? | Default value | Description |
34
35
  |--------|-----------|---------------|-------------|
35
36
  | app_key | No | | Token required to connect to TimeKit API. Can be found at **https://admin.timekit.io/a/apps/<app_slug>/apisettings/keys** |
37
+ | api_base_url | Yes | https://api.timekit.io | Timekit API url pointing to production environment. For staging env change it to staging url.
36
38
  | defaultUI | Yes | true | When true, will create the default user interface for the project selector. More details below |
37
39
  | embed | Yes | false | When true, the user interface will not be shown in the widget, it will be placed inside of a specified div. More details below |
38
40
  | includePrivateAppointments | Yes | false | When true, private appointment types will be fetched from the TimeKit API |
@@ -51,11 +53,11 @@ timekit_project_selector.init({
51
53
  ...,
52
54
  selectorOptions: {
53
55
  store_project: true,
54
- store_appointment_type_project: true,
56
+ service_project: true,
55
57
  }
56
58
  });
57
59
  ```
58
- > You must use project type as key in the selectorOptions. Ex. global_appointment_type_project for render Global Appointment Type in step, store_appointment_type_project for render Store Appointment Type in step, store_project for render Stores in step
60
+ > You must use project type as key in the selectorOptions. Ex. service_project for render Global Appointment Type in step, store_appointment_type_project for render Store Appointment Type in step, store_project for render Stores in step
59
61
 
60
62
  ### Selector Option Copyright
61
63
 
@@ -133,12 +135,13 @@ Here is a sample of combined selectorOptions.
133
135
  timekit_project_selector.init({
134
136
  ...,
135
137
  selectorOptions: {
136
- global_appointment_type_project: {
138
+ service_project: {
139
+ strategy: 'service_project',
140
+ card_title: `{{[project]name}}`,
137
141
  title: 'Select an Appointment Type',
142
+ card_image: `{{[project]image_url}}`,
143
+ card_body: `{{[project]description}}`,
138
144
  description: 'Which appointment type would you like?',
139
- card_image: '[meta]t_appointment_type_image',
140
- card_title: '[meta]t_appointment_type_name',
141
- card_body: '[meta]t_appointment_type_description',
142
145
  card_footer: '<i class="far fa-clock"></i> {{[project]availability.length}}',
143
146
  filters: {
144
147
  't_disabled': 0,
@@ -147,15 +150,15 @@ timekit_project_selector.init({
147
150
  },
148
151
  store_project: {
149
152
  title: 'Select a Store',
150
- description: 'Choose a store from the following that you will be visiting for your appointment.',
153
+ strategy: 'store_project',
151
154
  card_title: '[meta]t_store_name',
152
- card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
153
155
  card_footer: '[meta]t_store_phone',
156
+ card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
157
+ description: 'Choose a store from the following that you will be visiting for your appointment.',
154
158
  search_bar: {
155
159
  enabled: true,
156
160
  placeholder: 'Search for a city or postal code'
157
161
  },
158
- strategy: 'store_project',
159
162
  },
160
163
  }
161
164
  });
@@ -218,7 +221,7 @@ timekit_project_selector.init({
218
221
  defaultUI: false,
219
222
  includePrivateAppointments: true,
220
223
  selectorOptions: {
221
- global_appointment_type_project: true,
224
+ service_project: true,
222
225
  store_project: true,
223
226
  }
224
227
  }).then(() => {
@@ -277,10 +280,7 @@ Optionally takes project type for return projects by project type only.(Filters
277
280
  Optionally takes filters for return filtered projects
278
281
 
279
282
  ```js
280
- let filters = [];
281
- filters['key'] = 'value';
282
-
283
- timekit_project_selector.getStrategy().getProjects('global_appointment_type', filters);
283
+ await timekit_project_selector.getStrategy('store_project').getProjects({ id: 'ef0cee8a-6096-453f-a634-1597b359cdfa'});
284
284
  ```
285
285
 
286
286
  ### getFilters
@@ -320,12 +320,13 @@ timekit_project_selector.selectProject(timekitProject);
320
320
  ### Global Appointment Type -> Store -> Booking.js
321
321
  ```js
322
322
  selectorOptions: {
323
- global_appointment_type_project: {
323
+ service_project: {
324
+ strategy: 'service_project',
325
+ card_title: `{{[project]name}}`,
324
326
  title: 'Select an Appointment Type',
327
+ card_image: `{{[project]image_url}}`,
328
+ card_body: `{{[project]description}}`,
325
329
  description: 'Which appointment type would you like?',
326
- card_image: '[meta]t_appointment_type_image',
327
- card_title: '[meta]t_appointment_type_name',
328
- card_body: '[meta]t_appointment_type_description',
329
330
  card_footer: '<i class="far fa-clock"></i> {{[project]availability.length}}',
330
331
  filters: {
331
332
  't_disabled': 0,
@@ -334,15 +335,15 @@ timekit_project_selector.selectProject(timekitProject);
334
335
  },
335
336
  store_project: {
336
337
  title: 'Select a Store',
337
- description: 'Choose a store from the following that you will be visiting for your appointment.',
338
+ strategy: 'store_project',
338
339
  card_title: '[meta]t_store_name',
339
- card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
340
340
  card_footer: '[meta]t_store_phone',
341
+ card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
342
+ description: 'Choose a store from the following that you will be visiting for your appointment.',
341
343
  search_bar: {
342
344
  enabled: true,
343
345
  placeholder: 'Search for a city or postal code'
344
346
  },
345
- strategy: 'store_project'
346
347
  }
347
348
  }
348
349
  ```
@@ -352,10 +353,11 @@ timekit_project_selector.selectProject(timekitProject);
352
353
  selectorOptions: {
353
354
  store_project: {
354
355
  title: 'Select a Store',
355
- description: 'Choose a store from the following that you will be visiting for your appointment.',
356
+ strategy: 'store_project',
356
357
  card_title: '[meta]t_store_name',
357
- card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
358
358
  card_footer: '[meta]t_store_phone',
359
+ card_body: `{{[meta]t_store_address}}, {{[meta]t_store_city}}`,
360
+ description: 'Choose a store from the following that you will be visiting for your appointment.',
359
361
  search_bar: {
360
362
  enabled: true,
361
363
  placeholder: 'Search for a city or postal code'
@@ -363,11 +365,12 @@ timekit_project_selector.selectProject(timekitProject);
363
365
  //strategy: 'store_project'
364
366
  },
365
367
  store_appointment_type_project: {
368
+ strategy: 'service_project',
369
+ card_title: `{{[project]name}}`,
366
370
  title: 'Select an Appointment Type',
371
+ card_image: `{{[project]image_url}}`,
372
+ card_body: `{{[project]description}}`,
367
373
  description: 'Which appointment type would you like?',
368
- card_image: '[meta]t_appointment_type_image',
369
- card_title: '[meta]t_appointment_type_name',
370
- card_body: '[meta]t_appointment_type_description',
371
374
  card_footer: '<i class="far fa-clock"></i> {{[project]availability.length}}',
372
375
  filters: {
373
376
  't_disabled': 0,
@@ -397,7 +400,7 @@ timekit_project_selector.selectProject(timekitProject);
397
400
  <body>
398
401
  <h1>Custom UI - TimeKit Project Selector Example</h1>
399
402
 
400
- <!-- Placeholder div for TK Projects of t_project_type = global_appointment_type_project -->
403
+ <!-- Placeholder div for TK Projects of t_project_type = service_project -->
401
404
  <ul class="global_projects"></ul>
402
405
 
403
406
  <!-- Placeholder div for TK Projects of t_project_type = store_project -->
@@ -418,26 +421,23 @@ timekit_project_selector.selectProject(timekitProject);
418
421
  defaultUI: false,
419
422
  // Selector options still prvided but values are set to true
420
423
  selectorOptions: {
421
- // Step 1: Is to select the global_appointment_type_project
422
- global_appointment_type_project: true,
424
+ // Step 1: Is to select the service_project
425
+ service_project: true,
423
426
  // Step 2: Is to select the store project
424
427
  store_project: true,
425
428
  }
426
- }).then(() => {
429
+ }).then(async () => {
427
430
  // You could use simple array instead of using the steps factor.
428
431
  // This factory makes it simple to track which TK project uuids were selected
429
432
  let stepsFactory = tps.getStepsFactory();
430
-
431
- let globalProjectFilters = [];
432
- // We only want to surface active global appointment types
433
- globalProjectFilters['t_disabled'] = 0;
434
- // We only want to surface public global appointment types
435
- globalProjectFilters['t_private'] = 0;
436
433
 
437
- // Fetch the global_appointment_type_project
438
- let globalProjects = tps.getStrategy().getProjects('global_appointment_type_project', globalProjectFilters);
434
+ // Fetch the service_project
435
+ let globalProjects = await tps.getStrategy('service_project').getProjects({
436
+ t_private: 0,
437
+ t_disabled: 0
438
+ });
439
439
 
440
- // Render out links for each global_appointment_type_project
440
+ // Render out links for each service_project
441
441
  globalProjects.forEach((globalProject) => {
442
442
  let link = "<a href=\"#\" class=\"global_appointment\" id=\"" + globalProject.id + "\"> <li>'" + globalProject.name + "'</li></a>";
443
443
  $('.global_projects').append(link);
@@ -445,18 +445,15 @@ timekit_project_selector.selectProject(timekitProject);
445
445
 
446
446
  // Register an event listener on the newly generated link
447
447
  $("a.global_appointment").click(function (event) {
448
- let storeProjectFilters = [];
449
- storeProjectFilters['t_global_appointment_type_project_uuid'] = $(this).attr('id');
450
- storeProjectFilters['t_disabled'] = 0;
451
- storeProjectFilters['t_private'] = 0;
452
-
453
- // We add the UUID of the selected global_appointment_type_project. This will be used at the end
454
- // when we are selecting the store_appointment_type_project
455
- stepsFactory.addFilterForLastStep('t_global_appointment_type_project_uuid', $(this).attr('id'));
456
448
  stepsFactory.nextStep();
457
449
 
458
- let storeProjects = tps.getStrategy('store_project').getProjects('store_project', storeProjectFilters);
459
-
450
+ const service_project_id = $(this).attr('id');
451
+ let storeProjects = await tps.getStrategy('store_project').getProjects({
452
+ service_project_id,
453
+ t_disabled: 0,
454
+ t_private: 0
455
+ });
456
+
460
457
  // Render out links for each store_project
461
458
  storeProjects.forEach((project) => {
462
459
  let link = "<a href=\"#\" class=\"store_project\" id=\"" + project.id + "\"> <li>'" + project.name + "'</li></a>";
@@ -466,17 +463,16 @@ timekit_project_selector.selectProject(timekitProject);
466
463
  // Register an event listener on the newly generated store link
467
464
  $("a.store_project").click(function (event) {
468
465
 
469
- // We add the UUID of the selected store_project. This will be used at the end
470
- // when we are selecting the store_appointment_type_project
471
- stepsFactory.addFilterForLastStep('t_store_project_uuid', $(this).attr('id'));
472
466
  stepsFactory.nextStep();
473
467
 
474
- // From the step factory get the filters we had applied throughout the process
475
- let filters = stepsFactory.currentStep().getFilters();
476
- let store_appointments = tps.getStrategy().getProjects('store_appointment_type_project', filters);
468
+ const store_project_id = $(this).attr('id');
469
+ const project = await tps.getStrategy().getProjects({
470
+ store_project_id,
471
+ service_project_id
472
+ });
477
473
 
478
474
  // Render Booking.js
479
- tps.selectProject(store_appointments[0]);
475
+ tps.selectProject(project);
480
476
  });
481
477
  });
482
478