@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 +53 -57
- package/dist/01b11c560bc52c756c239af9d0bf60f1.woff2 +0 -0
- package/dist/1ed998a42083750e175e667c41c34be3.woff2 +0 -0
- package/dist/3064bf7e87155fcb14a1470cbb2aee64.woff2 +0 -0
- package/dist/473f6b09ca8f5658857e91a7549d7204.woff2 +0 -0
- package/dist/5a546777799f438b6bb4ef70bd2f8725.woff2 +0 -0
- package/dist/a1535f451fb7bb98f526f30e1050f487.woff2 +0 -0
- package/dist/cb2542fccedadc68d737ea53c1b559e2.woff +0 -0
- package/dist/ccfa20f8de7f73249c39bd9b206e0b3b.woff2 +0 -0
- package/dist/daafcec89c2332b84c255898b152ee43.woff2 +0 -0
- package/dist/timekit_project_selector.js +3039 -3317
- package/dist/timekit_project_selector.min.js +2 -2
- package/jest.config.js +5 -0
- package/junit.xml +116 -0
- package/package-lock.json +25103 -0
- package/package.json +3 -1
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
|
-
|
|
56
|
+
service_project: true,
|
|
55
57
|
}
|
|
56
58
|
});
|
|
57
59
|
```
|
|
58
|
-
> You must use project type as key in the selectorOptions. Ex.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
422
|
-
|
|
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
|
|
438
|
-
let globalProjects = tps.getStrategy().getProjects(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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(
|
|
475
|
+
tps.selectProject(project);
|
|
480
476
|
});
|
|
481
477
|
});
|
|
482
478
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|