@nyaruka/temba-components 0.26.11 → 0.27.0

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.
@@ -7,9 +7,15 @@ import {
7
7
  CompletionSchema,
8
8
  KeyedAssets,
9
9
  CustomEventType,
10
+ Workspace,
10
11
  } from '../interfaces';
11
12
  import { RapidElement } from '../RapidElement';
12
13
  import Lru from 'tiny-lru';
14
+ import {
15
+ HumanizeDurationLanguage,
16
+ HumanizeDuration,
17
+ } from 'humanize-duration-ts';
18
+ import { DateTime } from 'luxon';
13
19
 
14
20
  export class Store extends RapidElement {
15
21
  @property({ type: Number })
@@ -33,6 +39,9 @@ export class Store extends RapidElement {
33
39
  @property({ type: String, attribute: 'languages' })
34
40
  languagesEndpoint: string;
35
41
 
42
+ @property({ type: String, attribute: 'workspace' })
43
+ workspaceEndpoint: string;
44
+
36
45
  @property({ type: Object, attribute: false })
37
46
  private schema: CompletionSchema;
38
47
 
@@ -42,11 +51,17 @@ export class Store extends RapidElement {
42
51
  @property({ type: Object, attribute: false })
43
52
  private keyedAssets: KeyedAssets = {};
44
53
 
54
+ private locale = [...navigator.languages];
55
+
45
56
  private fields: { [key: string]: ContactField } = {};
46
57
  private groups: { [uuid: string]: ContactGroup } = {};
47
58
  private languages: any = {};
59
+ private workspace: Workspace;
48
60
  private pinnedFields: ContactField[] = [];
49
61
 
62
+ private langService = new HumanizeDurationLanguage();
63
+ private humanizer = new HumanizeDuration(this.langService);
64
+
50
65
  // http promise to monitor for completeness
51
66
  public httpComplete: Promise<void | WebResponse[]>;
52
67
 
@@ -55,6 +70,21 @@ export class Store extends RapidElement {
55
70
  public firstUpdated() {
56
71
  this.cache = Lru(this.max, this.ttl);
57
72
 
73
+ /*
74
+ // This will create a shorthand unit
75
+ this.humanizer.addLanguage("en", {
76
+ y: () => "y",
77
+ mo: () => "mo",
78
+ w: () => "w",
79
+ d: () => "d",
80
+ h: () => "h",
81
+ m: () => "m",
82
+ s: () => "s",
83
+ ms: () => "ms",
84
+ decimal: ".",
85
+ });
86
+ */
87
+
58
88
  const fetches = [];
59
89
  if (this.completionEndpoint) {
60
90
  fetches.push(
@@ -120,9 +150,40 @@ export class Store extends RapidElement {
120
150
  );
121
151
  }
122
152
 
153
+ if (this.workspaceEndpoint) {
154
+ fetches.push(
155
+ getUrl(this.workspaceEndpoint).then((response: WebResponse) => {
156
+ this.workspace = response.json;
157
+ const lang = response.headers.get('content-language');
158
+ if (lang) {
159
+ this.locale = [lang, ...this.locale];
160
+ }
161
+ })
162
+ );
163
+ }
164
+
123
165
  this.httpComplete = Promise.all(fetches);
124
166
  }
125
167
 
168
+ public getLanguageCode() {
169
+ if (this.locale.length > 0) {
170
+ return this.locale[0].split('-')[0];
171
+ }
172
+ return 'en';
173
+ }
174
+
175
+ public getShortDuration(isoDate: string) {
176
+ const scheduled = DateTime.fromISO(isoDate);
177
+ const now = DateTime.now();
178
+
179
+ const duration = scheduled.diff(now).valueOf();
180
+ return this.humanizer.humanize(duration, {
181
+ language: this.getLanguageCode(),
182
+ largest: 1,
183
+ round: false,
184
+ });
185
+ }
186
+
126
187
  public setKeyedAssets(name: string, values: string[]): void {
127
188
  this.keyedAssets[name] = values;
128
189
  }
@@ -163,6 +224,20 @@ export class Store extends RapidElement {
163
224
  return false;
164
225
  }
165
226
 
227
+ public getWorkspace(): Workspace {
228
+ return this.workspace;
229
+ }
230
+
231
+ public formatDate(dateString: string) {
232
+ return new Date(dateString).toLocaleString(this.locale, {
233
+ year: 'numeric',
234
+ month: 'long',
235
+ day: 'numeric',
236
+ hour: 'numeric',
237
+ minute: 'numeric',
238
+ });
239
+ }
240
+
166
241
  public getUrl(
167
242
  url: string,
168
243
  options?: {
@@ -231,6 +306,11 @@ export class Store extends RapidElement {
231
306
 
232
307
  public fetching: { [url: string]: number } = {};
233
308
 
309
+ public updateCache(url: string, data: any) {
310
+ this.cache.set(url, data);
311
+ this.fireCustomEvent(CustomEventType.StoreUpdated, { url, data });
312
+ }
313
+
234
314
  public makeRequest(
235
315
  url: string,
236
316
  options?: { force?: boolean; prepareData?: (data: any) => any }
@@ -6,7 +6,8 @@ import { ContactField, Ticket } from '../interfaces';
6
6
 
7
7
  export type Asset = KeyedAsset & Ticket & ContactField;
8
8
 
9
- export const DATE_FORMAT = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/;
9
+ export const DATE_FORMAT =
10
+ /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/;
10
11
 
11
12
  interface KeyedAsset {
12
13
  key?: string;
@@ -77,11 +78,11 @@ export const getUrl = (
77
78
  // eslint-disable-next-line no-empty
78
79
  } catch (err) {}
79
80
  resolve({
81
+ controller,
80
82
  body,
81
83
  json,
82
- status: response.status,
83
84
  headers: response.headers,
84
- controller,
85
+ status: response.status,
85
86
  });
86
87
  });
87
88
  })
@@ -210,8 +211,8 @@ export const postUrl = (
210
211
  resolve({
211
212
  body,
212
213
  json,
213
- status: response.status,
214
214
  headers: response.headers,
215
+ status: response.status,
215
216
  });
216
217
  });
217
218
  })
@@ -260,12 +261,11 @@ export const postForm = (
260
261
 
261
262
  /**
262
263
  */
263
- export const renderIf = (predicate: boolean | any) => (
264
- then: () => TemplateResult,
265
- otherwise?: () => TemplateResult
266
- ) => {
267
- return predicate ? then() : otherwise ? otherwise() : html``;
268
- };
264
+ export const renderIf =
265
+ (predicate: boolean | any) =>
266
+ (then: () => TemplateResult, otherwise?: () => TemplateResult) => {
267
+ return predicate ? then() : otherwise ? otherwise() : html``;
268
+ };
269
269
 
270
270
  export const hexToRgb = (hex: string): { r: number; g: number; b: number } => {
271
271
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
package/temba-modules.ts CHANGED
@@ -32,6 +32,7 @@ import { ContactFields } from './src/contacts/ContactFields';
32
32
  import { ContactFieldEditor } from './src/contacts/ContactFieldEditor';
33
33
 
34
34
  import { ContactBadges } from './src/contacts/ContactBadges';
35
+ import { ContactPending } from './src/contacts/ContactPending';
35
36
 
36
37
  export function addCustomElement(name: string, comp: any) {
37
38
  if (!window.customElements.get(name)) {
@@ -73,3 +74,4 @@ addCustomElement('temba-dropdown', Dropdown);
73
74
  addCustomElement('temba-tabs', TabPane);
74
75
  addCustomElement('temba-tab', Tab);
75
76
  addCustomElement('temba-contact-groups', ContactBadges);
77
+ addCustomElement('temba-contact-pending', ContactPending);