@sprucelabs/spruce-calendar-components 38.1.9 → 38.1.11

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.
@@ -10,6 +10,7 @@ export default class VenueSelectionToolViewController extends AbstractViewContro
10
10
  private isLoaded;
11
11
  constructor(options: ViewControllerOptions & CalendarToolOptions);
12
12
  private VenueListVc;
13
+ private handleSelectVenueFromList;
13
14
  private get router();
14
15
  private CardVc;
15
16
  handleUpdateContext(context: CalendarToolBeltContext): Promise<void>;
@@ -21,11 +21,14 @@ class VenueSelectionToolViewController extends AbstractViewController {
21
21
  VenueListVc() {
22
22
  return this.Controller('calendar.venues-list', {
23
23
  router: this.router,
24
- onSelect: (venue) => __awaiter(this, void 0, void 0, function* () {
25
- yield this.updateContextHandler({
26
- 'event.venue': venue,
27
- });
28
- }),
24
+ onSelect: this.handleSelectVenueFromList.bind(this),
25
+ });
26
+ }
27
+ handleSelectVenueFromList(venue) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ yield this.updateContextHandler({
30
+ 'event.venue': venue,
31
+ });
29
32
  });
30
33
  }
31
34
  get router() {
@@ -33,6 +36,9 @@ class VenueSelectionToolViewController extends AbstractViewController {
33
36
  }
34
37
  CardVc() {
35
38
  return this.Controller('card', {
39
+ header: {
40
+ title: 'Venue',
41
+ },
36
42
  body: {
37
43
  sections: [
38
44
  {
@@ -44,10 +50,9 @@ class VenueSelectionToolViewController extends AbstractViewController {
44
50
  }
45
51
  handleUpdateContext(context) {
46
52
  return __awaiter(this, void 0, void 0, function* () {
47
- var _a;
48
- const provider = (_a = context.event.venue) === null || _a === void 0 ? void 0 : _a.provider;
49
- if (provider && this.isLoaded) {
50
- yield this.venueListVc.selectVenue(provider);
53
+ const venue = context.event.venue;
54
+ if (venue && this.isLoaded) {
55
+ yield this.venueListVc.selectVenue(venue);
51
56
  }
52
57
  });
53
58
  }
@@ -60,7 +65,7 @@ class VenueSelectionToolViewController extends AbstractViewController {
60
65
  organizationId: organization.id,
61
66
  });
62
67
  if ((_a = this.venue) === null || _a === void 0 ? void 0 : _a.provider) {
63
- yield this.venueListVc.selectVenue(this.venue.provider);
68
+ yield this.venueListVc.selectVenue(this.venue);
64
69
  }
65
70
  });
66
71
  }
@@ -6,15 +6,22 @@ export default class VenuesListViewController extends AbstractViewController<Lis
6
6
  private venues;
7
7
  protected onSelectHandler?: (venue: Venue) => void;
8
8
  private router;
9
+ private isLoaded;
10
+ private selectedVenue?;
9
11
  constructor(options: ViewControllerOptions & VenuesListConstructorOptions);
10
12
  private ListVc;
11
13
  load(options: VenuesListLoadOptions): Promise<void>;
12
14
  private populateList;
15
+ private renderDetailsRow;
13
16
  private renderVenueRow;
14
- selectVenue(provider: string): Promise<void>;
17
+ private renderVenueLabelCell;
18
+ selectVenue(venue: Venue): Promise<void>;
19
+ private optionallyRenderJoinUrlCell;
20
+ private isSelected;
21
+ private renderCheckboxCell;
15
22
  private handleOnClickJoinUrl;
16
- private handleChange;
17
- render(): import("@sprucelabs/heartwood-view-controllers").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.List;
23
+ private handleClickedCheckbox;
24
+ render(): List;
18
25
  }
19
26
  export interface VenuesListLoadOptions {
20
27
  organizationId: string;
@@ -12,6 +12,7 @@ class VenuesListViewController extends AbstractViewController {
12
12
  constructor(options) {
13
13
  super(options);
14
14
  this.venues = [];
15
+ this.isLoaded = false;
15
16
  const { router, onSelect } = options;
16
17
  this.onSelectHandler = onSelect;
17
18
  this.router = router;
@@ -20,98 +21,128 @@ class VenuesListViewController extends AbstractViewController {
20
21
  ListVc() {
21
22
  return this.Controller('list', {
22
23
  id: 'venues-list',
24
+ columnWidths: ['content', 'fill'],
23
25
  });
24
26
  }
25
27
  load(options) {
26
28
  return __awaiter(this, void 0, void 0, function* () {
27
29
  const { organizationId } = options;
28
30
  const client = yield this.connectToApi();
31
+ this.isLoaded = true;
29
32
  try {
30
- const [{ venues }] = yield client.emitAndFlattenResponses('calendar.register-venues::v2021_05_19', {
33
+ const results = yield client.emitAndFlattenResponses('calendar.register-venues::v2021_05_19', {
31
34
  target: {
32
35
  organizationId,
33
36
  },
34
37
  });
38
+ if (results.length === 0) {
39
+ return;
40
+ }
41
+ const venues = results[0].venues;
35
42
  this.venues.push(...venues);
36
43
  this.populateList();
37
44
  }
38
45
  catch (err) {
46
+ this.log.error(`Emitting register-venues failed`, err.stack);
39
47
  yield this.alert({
40
48
  message: `We had trouble loading your venues. Please try again later. Error: ${err.message}`,
41
49
  });
42
50
  }
51
+ this.triggerRender();
43
52
  });
44
53
  }
45
54
  populateList() {
46
- this.venues.forEach((venue) => this.listVc.addRow(this.renderVenueRow(venue)));
55
+ const rows = [];
56
+ this.venues.forEach((venue) => {
57
+ var _a;
58
+ rows.push(this.renderVenueRow(venue));
59
+ if (this.isSelected(venue) && ((_a = this.selectedVenue) === null || _a === void 0 ? void 0 : _a.details)) {
60
+ rows.push(this.renderDetailsRow());
61
+ }
62
+ });
63
+ this.listVc.setRows(rows);
47
64
  }
48
- renderVenueRow(venue) {
65
+ renderDetailsRow() {
66
+ var _a;
49
67
  return {
50
- id: venue.provider,
68
+ id: 'details',
51
69
  cells: [
52
70
  {
53
- checkboxInput: {
54
- name: 'isSelected',
55
- value: false,
56
- onChange: (value) => {
57
- if (value) {
58
- this.handleChange(venue);
59
- }
60
- },
71
+ text: {
72
+ markdown: (_a = this.selectedVenue) === null || _a === void 0 ? void 0 : _a.details,
61
73
  },
62
74
  },
63
- { text: { content: venue.label } },
64
- (venue.joinUrl
65
- ? {
66
- button: {
67
- id: `joinUrl`,
68
- label: venue.label,
69
- lineIcon: 'link-angle',
70
- onClick: this.handleOnClickJoinUrl.bind(this, venue.joinUrl),
71
- },
72
- }
73
- : {}),
74
75
  ],
75
76
  };
76
77
  }
77
- selectVenue(provider) {
78
+ renderVenueRow(venue) {
79
+ return {
80
+ id: venue.provider,
81
+ cells: [
82
+ this.renderCheckboxCell(venue),
83
+ this.renderVenueLabelCell(venue),
84
+ this.optionallyRenderJoinUrlCell(venue),
85
+ ].filter(Boolean),
86
+ };
87
+ }
88
+ renderVenueLabelCell(venue) {
89
+ return { text: { content: venue.label } };
90
+ }
91
+ selectVenue(venue) {
78
92
  return __awaiter(this, void 0, void 0, function* () {
79
- yield this.listVc.getRowVc(provider).setValue('isSelected', true);
93
+ this.selectedVenue = venue;
94
+ this.populateList();
80
95
  });
81
96
  }
97
+ optionallyRenderJoinUrlCell(venue) {
98
+ var _a;
99
+ const joinUrl = this.isSelected(venue) && ((_a = this.selectedVenue) === null || _a === void 0 ? void 0 : _a.joinUrl);
100
+ return (joinUrl
101
+ ? {
102
+ button: {
103
+ id: `joinUrl`,
104
+ lineIcon: 'link-angle',
105
+ onClick: this.handleOnClickJoinUrl.bind(this, joinUrl),
106
+ },
107
+ }
108
+ : null);
109
+ }
110
+ isSelected(venue) {
111
+ var _a;
112
+ return ((_a = this.selectedVenue) === null || _a === void 0 ? void 0 : _a.provider) === venue.provider;
113
+ }
114
+ renderCheckboxCell(venue) {
115
+ return {
116
+ checkboxInput: {
117
+ name: 'isSelected',
118
+ value: this.isSelected(venue),
119
+ onChange: (value) => {
120
+ if (value) {
121
+ this.handleClickedCheckbox(venue);
122
+ }
123
+ },
124
+ },
125
+ };
126
+ }
82
127
  handleOnClickJoinUrl(joinUrl) {
83
128
  return __awaiter(this, void 0, void 0, function* () {
84
129
  yield this.router.redirect(joinUrl);
85
130
  });
86
131
  }
87
- handleChange(venue) {
132
+ handleClickedCheckbox(venue) {
88
133
  var _a;
89
134
  this.venues.forEach((v) => __awaiter(this, void 0, void 0, function* () {
90
135
  if (v.provider === venue.provider) {
91
- if (venue.details) {
92
- const index = this.listVc
93
- .getRowVcs()
94
- .findIndex((r) => r.getId() === v.provider);
95
- this.listVc.addRow({
96
- id: 'details',
97
- atIndex: index + 1,
98
- cells: [
99
- {
100
- text: {
101
- markdown: venue.details,
102
- },
103
- },
104
- ],
105
- });
106
- }
107
136
  return;
108
137
  }
109
- yield this.listVc.getRowVc(v.provider).setValue('isSelected', false);
138
+ yield this.listVc.setValue(v.provider, 'isSelected', false);
110
139
  }));
111
140
  (_a = this.onSelectHandler) === null || _a === void 0 ? void 0 : _a.call(this, venue);
112
141
  }
113
142
  render() {
114
- return this.listVc.render();
143
+ return (this.venues.length === 0 && this.isLoaded
144
+ ? null
145
+ : this.listVc.render());
115
146
  }
116
147
  }
117
148
  VenuesListViewController.id = 'venues-list';
@@ -10,6 +10,7 @@ export default class VenueSelectionToolViewController extends AbstractViewContro
10
10
  private isLoaded;
11
11
  constructor(options: ViewControllerOptions & CalendarToolOptions);
12
12
  private VenueListVc;
13
+ private handleSelectVenueFromList;
13
14
  private get router();
14
15
  private CardVc;
15
16
  handleUpdateContext(context: CalendarToolBeltContext): Promise<void>;
@@ -14,11 +14,12 @@ class VenueSelectionToolViewController extends heartwood_view_controllers_1.Abst
14
14
  VenueListVc() {
15
15
  return this.Controller('calendar.venues-list', {
16
16
  router: this.router,
17
- onSelect: async (venue) => {
18
- await this.updateContextHandler({
19
- 'event.venue': venue,
20
- });
21
- },
17
+ onSelect: this.handleSelectVenueFromList.bind(this),
18
+ });
19
+ }
20
+ async handleSelectVenueFromList(venue) {
21
+ await this.updateContextHandler({
22
+ 'event.venue': venue,
22
23
  });
23
24
  }
24
25
  get router() {
@@ -26,6 +27,9 @@ class VenueSelectionToolViewController extends heartwood_view_controllers_1.Abst
26
27
  }
27
28
  CardVc() {
28
29
  return this.Controller('card', {
30
+ header: {
31
+ title: 'Venue',
32
+ },
29
33
  body: {
30
34
  sections: [
31
35
  {
@@ -36,9 +40,9 @@ class VenueSelectionToolViewController extends heartwood_view_controllers_1.Abst
36
40
  });
37
41
  }
38
42
  async handleUpdateContext(context) {
39
- const provider = context.event.venue?.provider;
40
- if (provider && this.isLoaded) {
41
- await this.venueListVc.selectVenue(provider);
43
+ const venue = context.event.venue;
44
+ if (venue && this.isLoaded) {
45
+ await this.venueListVc.selectVenue(venue);
42
46
  }
43
47
  }
44
48
  async load() {
@@ -48,7 +52,7 @@ class VenueSelectionToolViewController extends heartwood_view_controllers_1.Abst
48
52
  organizationId: organization.id,
49
53
  });
50
54
  if (this.venue?.provider) {
51
- await this.venueListVc.selectVenue(this.venue.provider);
55
+ await this.venueListVc.selectVenue(this.venue);
52
56
  }
53
57
  }
54
58
  get event() {
@@ -6,15 +6,22 @@ export default class VenuesListViewController extends AbstractViewController<Lis
6
6
  private venues;
7
7
  protected onSelectHandler?: (venue: Venue) => void;
8
8
  private router;
9
+ private isLoaded;
10
+ private selectedVenue?;
9
11
  constructor(options: ViewControllerOptions & VenuesListConstructorOptions);
10
12
  private ListVc;
11
13
  load(options: VenuesListLoadOptions): Promise<void>;
12
14
  private populateList;
15
+ private renderDetailsRow;
13
16
  private renderVenueRow;
14
- selectVenue(provider: string): Promise<void>;
17
+ private renderVenueLabelCell;
18
+ selectVenue(venue: Venue): Promise<void>;
19
+ private optionallyRenderJoinUrlCell;
20
+ private isSelected;
21
+ private renderCheckboxCell;
15
22
  private handleOnClickJoinUrl;
16
- private handleChange;
17
- render(): import("@sprucelabs/heartwood-view-controllers").SpruceSchemas.HeartwoodViewControllers.v2021_02_11.List;
23
+ private handleClickedCheckbox;
24
+ render(): List;
18
25
  }
19
26
  export interface VenuesListLoadOptions {
20
27
  organizationId: string;
@@ -5,6 +5,7 @@ class VenuesListViewController extends heartwood_view_controllers_1.AbstractView
5
5
  constructor(options) {
6
6
  super(options);
7
7
  this.venues = [];
8
+ this.isLoaded = false;
8
9
  const { router, onSelect } = options;
9
10
  this.onSelectHandler = onSelect;
10
11
  this.router = router;
@@ -13,91 +14,117 @@ class VenuesListViewController extends heartwood_view_controllers_1.AbstractView
13
14
  ListVc() {
14
15
  return this.Controller('list', {
15
16
  id: 'venues-list',
17
+ columnWidths: ['content', 'fill'],
16
18
  });
17
19
  }
18
20
  async load(options) {
19
21
  const { organizationId } = options;
20
22
  const client = await this.connectToApi();
23
+ this.isLoaded = true;
21
24
  try {
22
- const [{ venues }] = await client.emitAndFlattenResponses('calendar.register-venues::v2021_05_19', {
25
+ const results = await client.emitAndFlattenResponses('calendar.register-venues::v2021_05_19', {
23
26
  target: {
24
27
  organizationId,
25
28
  },
26
29
  });
30
+ if (results.length === 0) {
31
+ return;
32
+ }
33
+ const venues = results[0].venues;
27
34
  this.venues.push(...venues);
28
35
  this.populateList();
29
36
  }
30
37
  catch (err) {
38
+ this.log.error(`Emitting register-venues failed`, err.stack);
31
39
  await this.alert({
32
40
  message: `We had trouble loading your venues. Please try again later. Error: ${err.message}`,
33
41
  });
34
42
  }
43
+ this.triggerRender();
35
44
  }
36
45
  populateList() {
37
- this.venues.forEach((venue) => this.listVc.addRow(this.renderVenueRow(venue)));
46
+ const rows = [];
47
+ this.venues.forEach((venue) => {
48
+ rows.push(this.renderVenueRow(venue));
49
+ if (this.isSelected(venue) && this.selectedVenue?.details) {
50
+ rows.push(this.renderDetailsRow());
51
+ }
52
+ });
53
+ this.listVc.setRows(rows);
38
54
  }
39
- renderVenueRow(venue) {
55
+ renderDetailsRow() {
40
56
  return {
41
- id: venue.provider,
57
+ id: 'details',
42
58
  cells: [
43
59
  {
44
- checkboxInput: {
45
- name: 'isSelected',
46
- value: false,
47
- onChange: (value) => {
48
- if (value) {
49
- this.handleChange(venue);
50
- }
51
- },
60
+ text: {
61
+ markdown: this.selectedVenue?.details,
52
62
  },
53
63
  },
54
- { text: { content: venue.label } },
55
- (venue.joinUrl
56
- ? {
57
- button: {
58
- id: `joinUrl`,
59
- label: venue.label,
60
- lineIcon: 'link-angle',
61
- onClick: this.handleOnClickJoinUrl.bind(this, venue.joinUrl),
62
- },
63
- }
64
- : {}),
65
64
  ],
66
65
  };
67
66
  }
68
- async selectVenue(provider) {
69
- await this.listVc.getRowVc(provider).setValue('isSelected', true);
67
+ renderVenueRow(venue) {
68
+ return {
69
+ id: venue.provider,
70
+ cells: [
71
+ this.renderCheckboxCell(venue),
72
+ this.renderVenueLabelCell(venue),
73
+ this.optionallyRenderJoinUrlCell(venue),
74
+ ].filter(Boolean),
75
+ };
76
+ }
77
+ renderVenueLabelCell(venue) {
78
+ return { text: { content: venue.label } };
79
+ }
80
+ async selectVenue(venue) {
81
+ this.selectedVenue = venue;
82
+ this.populateList();
83
+ }
84
+ optionallyRenderJoinUrlCell(venue) {
85
+ const joinUrl = this.isSelected(venue) && this.selectedVenue?.joinUrl;
86
+ return (joinUrl
87
+ ? {
88
+ button: {
89
+ id: `joinUrl`,
90
+ lineIcon: 'link-angle',
91
+ onClick: this.handleOnClickJoinUrl.bind(this, joinUrl),
92
+ },
93
+ }
94
+ : null);
95
+ }
96
+ isSelected(venue) {
97
+ return this.selectedVenue?.provider === venue.provider;
98
+ }
99
+ renderCheckboxCell(venue) {
100
+ return {
101
+ checkboxInput: {
102
+ name: 'isSelected',
103
+ value: this.isSelected(venue),
104
+ onChange: (value) => {
105
+ if (value) {
106
+ this.handleClickedCheckbox(venue);
107
+ }
108
+ },
109
+ },
110
+ };
70
111
  }
71
112
  async handleOnClickJoinUrl(joinUrl) {
72
113
  await this.router.redirect(joinUrl);
73
114
  }
74
- handleChange(venue) {
115
+ handleClickedCheckbox(venue) {
75
116
  this.venues.forEach(async (v) => {
76
117
  if (v.provider === venue.provider) {
77
- if (venue.details) {
78
- const index = this.listVc
79
- .getRowVcs()
80
- .findIndex((r) => r.getId() === v.provider);
81
- this.listVc.addRow({
82
- id: 'details',
83
- atIndex: index + 1,
84
- cells: [
85
- {
86
- text: {
87
- markdown: venue.details,
88
- },
89
- },
90
- ],
91
- });
92
- }
93
118
  return;
94
119
  }
95
- await this.listVc.getRowVc(v.provider).setValue('isSelected', false);
120
+ await this.listVc.setValue(v.provider, 'isSelected', false);
96
121
  });
97
122
  this.onSelectHandler?.(venue);
98
123
  }
99
124
  render() {
100
- return this.listVc.render();
125
+ return (this.venues.length === 0 && this.isLoaded
126
+ ? null
127
+ : this.listVc.render());
101
128
  }
102
129
  }
103
130
  VenuesListViewController.id = 'venues-list';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sprucelabs/spruce-calendar-components",
3
3
  "description": "Calendar components for working with calendars and Sprucebot.",
4
- "version": "38.1.9",
4
+ "version": "38.1.11",
5
5
  "skill": {
6
6
  "namespace": "calendar"
7
7
  },