@things-factory/auth-ui 6.2.6 → 6.2.9

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.
Files changed (50) hide show
  1. package/client/components/abstract-auth-page.ts +16 -13
  2. package/client/components/create-domain-popup.ts +2 -2
  3. package/client/components/create-role.ts +38 -34
  4. package/client/components/create-user.ts +27 -52
  5. package/client/components/invite-customer.ts +29 -29
  6. package/client/components/invite-user.ts +15 -14
  7. package/client/components/ownership-transfer-popup.ts +29 -30
  8. package/client/components/partner-role-editor.ts +28 -28
  9. package/client/components/role-privilege-editor.ts +32 -31
  10. package/client/components/role-selector.ts +2 -2
  11. package/client/components/user-role-editor.ts +64 -66
  12. package/client/entries/auth/forgot-password.ts +1 -1
  13. package/client/entries/auth/signup.ts +15 -9
  14. package/client/entries/oauth2/oauth2-decision-page.ts +2 -2
  15. package/client/pages/role/role-management.ts +0 -1
  16. package/client/pages/user/user-management.ts +26 -26
  17. package/dist-client/components/abstract-auth-page.js +16 -14
  18. package/dist-client/components/abstract-auth-page.js.map +1 -1
  19. package/dist-client/components/create-domain-popup.js +2 -2
  20. package/dist-client/components/create-domain-popup.js.map +1 -1
  21. package/dist-client/components/create-role.js +30 -27
  22. package/dist-client/components/create-role.js.map +1 -1
  23. package/dist-client/components/create-user.js +26 -51
  24. package/dist-client/components/create-user.js.map +1 -1
  25. package/dist-client/components/invite-customer.js +24 -25
  26. package/dist-client/components/invite-customer.js.map +1 -1
  27. package/dist-client/components/invite-user.js +8 -9
  28. package/dist-client/components/invite-user.js.map +1 -1
  29. package/dist-client/components/ownership-transfer-popup.js +23 -23
  30. package/dist-client/components/ownership-transfer-popup.js.map +1 -1
  31. package/dist-client/components/partner-role-editor.js +21 -22
  32. package/dist-client/components/partner-role-editor.js.map +1 -1
  33. package/dist-client/components/role-privilege-editor.js +25 -25
  34. package/dist-client/components/role-privilege-editor.js.map +1 -1
  35. package/dist-client/components/role-selector.js +2 -2
  36. package/dist-client/components/role-selector.js.map +1 -1
  37. package/dist-client/components/user-role-editor.js +54 -58
  38. package/dist-client/components/user-role-editor.js.map +1 -1
  39. package/dist-client/entries/auth/forgot-password.js +1 -1
  40. package/dist-client/entries/auth/forgot-password.js.map +1 -1
  41. package/dist-client/entries/auth/signup.js +15 -9
  42. package/dist-client/entries/auth/signup.js.map +1 -1
  43. package/dist-client/entries/oauth2/oauth2-decision-page.js +2 -2
  44. package/dist-client/entries/oauth2/oauth2-decision-page.js.map +1 -1
  45. package/dist-client/pages/role/role-management.js +0 -1
  46. package/dist-client/pages/role/role-management.js.map +1 -1
  47. package/dist-client/pages/user/user-management.js +19 -20
  48. package/dist-client/pages/user/user-management.js.map +1 -1
  49. package/dist-client/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +4 -5
@@ -4,7 +4,7 @@ import { customElement, property } from 'lit/decorators.js'
4
4
 
5
5
  import { client, gqlContext } from '@operato/graphql'
6
6
  import { i18next, localize } from '@operato/i18n'
7
- import { CustomAlert } from '@things-factory/shell/client'
7
+ import { OxPrompt } from '@operato/popup/ox-prompt.js'
8
8
 
9
9
  @customElement('role-privilege-editor')
10
10
  class RolePrivilegeEditor extends localize(i18next)(LitElement) {
@@ -51,14 +51,15 @@ class RolePrivilegeEditor extends localize(i18next)(LitElement) {
51
51
 
52
52
  [buttons] {
53
53
  margin: 0;
54
- padding: var(--padding-default);
54
+ padding: 5px;
55
55
  background-color: rgba(var(--primary-color-rgb), 0.2);
56
56
  }
57
57
 
58
58
  mwc-button {
59
+ margin: 5px;
59
60
  background-color: var(--theme-white-color);
60
- overflow: hidden;
61
61
  }
62
+
62
63
  [danger] {
63
64
  --mdc-theme-primary: var(--mdc-danger-button-primary-color);
64
65
  }
@@ -106,12 +107,12 @@ class RolePrivilegeEditor extends localize(i18next)(LitElement) {
106
107
  </ul>
107
108
 
108
109
  <div buttons>
109
- <mwc-button @click=${e => this.onSave()} outlined label="${i18next.t('button.save')}"></mwc-button>
110
+ <mwc-button @click=${e => this.onSave()} outlined label=${String(i18next.t('button.save'))}></mwc-button>
110
111
  <mwc-button
111
112
  @click=${e => this.onDeleteRole()}
112
113
  raised
113
114
  danger
114
- label="${i18next.t('button.delete role')}"
115
+ label=${String(i18next.t('button.delete role'))}
115
116
  ></mwc-button>
116
117
  </div>
117
118
  `
@@ -172,34 +173,34 @@ class RolePrivilegeEditor extends localize(i18next)(LitElement) {
172
173
  }
173
174
 
174
175
  async onDeleteRole() {
175
- const answer = await CustomAlert({
176
- title: i18next.t('text.are_you_sure'),
177
- text: i18next.t('text.are_you_sure_to_delete_x', { x: i18next.t('label.role') }),
178
- confirmButton: { text: i18next.t('button.delete') },
179
- cancelButton: { text: i18next.t('button.cancel') }
180
- })
181
-
182
- if (!answer.value) return
183
-
184
- const response = await client.mutate({
185
- mutation: gql`
186
- mutation ($id: String!) {
187
- deleteRole(id: $id)
188
- }
189
- `,
190
- variables: { id: this.role.id },
191
- context: gqlContext()
192
- })
176
+ if (
177
+ await OxPrompt.open({
178
+ title: i18next.t('text.are_you_sure'),
179
+ text: i18next.t('text.are_you_sure_to_delete_x', { x: i18next.t('label.role') }),
180
+ confirmButton: { text: i18next.t('button.delete') },
181
+ cancelButton: { text: i18next.t('button.cancel') }
182
+ })
183
+ ) {
184
+ const response = await client.mutate({
185
+ mutation: gql`
186
+ mutation ($id: String!) {
187
+ deleteRole(id: $id)
188
+ }
189
+ `,
190
+ variables: { id: this.role.id },
191
+ context: gqlContext()
192
+ })
193
193
 
194
- if (!response.errors) {
195
- await this.dispatchEvent(new CustomEvent('fetch-roles'))
194
+ if (!response.errors) {
195
+ await this.dispatchEvent(new CustomEvent('fetch-roles'))
196
196
 
197
- await CustomAlert({
198
- type: 'success',
199
- title: i18next.t('text.completed'),
200
- text: i18next.t('text.x_deleted_successfully', { x: i18next.t('label.role') }),
201
- confirmButton: { text: i18next.t('button.confirm') }
202
- })
197
+ await OxPrompt.open({
198
+ type: 'success',
199
+ title: i18next.t('text.completed'),
200
+ text: i18next.t('text.x_deleted_successfully', { x: i18next.t('label.role') }),
201
+ confirmButton: { text: i18next.t('button.confirm') }
202
+ })
203
+ }
203
204
  }
204
205
  }
205
206
 
@@ -1,4 +1,4 @@
1
- import { css, html, LitElement } from 'lit'
1
+ import { css, html, LitElement, nothing } from 'lit'
2
2
  import { customElement, property } from 'lit/decorators.js'
3
3
 
4
4
  @customElement('role-selector')
@@ -59,7 +59,7 @@ export class RoleSelector extends LitElement {
59
59
  ${this.roles.length
60
60
  ? html`
61
61
  <div>
62
- <h3 subtitle>${this.roleCategory}</h3>
62
+ ${this.roleCategory ? html`<h3 subtitle>${this.roleCategory}</h3>` : nothing}
63
63
  <input id="checkAll" type="checkbox" @change=${this.checkAll.bind(this)} />
64
64
  <label for="checkAll">Check all</label>
65
65
  </div>
@@ -10,7 +10,7 @@ import { client, gqlContext } from '@operato/graphql'
10
10
  import { i18next } from '@operato/i18n'
11
11
  import { openPopup } from '@operato/layout'
12
12
  import { store } from '@operato/shell'
13
- import { CustomAlert } from '@things-factory/shell/client'
13
+ import { OxPrompt } from '@operato/popup/ox-prompt.js'
14
14
 
15
15
  import { RoleSelector } from './role-selector'
16
16
 
@@ -62,14 +62,17 @@ class UserRoleEditor extends connect(store)(LitElement) {
62
62
  [detail] li input {
63
63
  flex: 1;
64
64
  }
65
+
65
66
  [buttons] {
66
67
  margin: 0;
67
- padding: var(--padding-default);
68
+ padding: 5px;
68
69
  background-color: rgba(var(--primary-color-rgb), 0.2);
69
70
  }
71
+
70
72
  mwc-button {
71
- margin-right: var(--padding-narrow);
73
+ margin: 5px;
72
74
  }
75
+
73
76
  [danger] {
74
77
  --mdc-theme-primary: var(--mdc-danger-button-primary-color);
75
78
  }
@@ -122,20 +125,15 @@ class UserRoleEditor extends connect(store)(LitElement) {
122
125
  : ''}
123
126
  </ul>
124
127
 
125
- <role-selector
126
- .roleCategory="${currentDomainName}"
127
- .user="${this.user}"
128
- .roles="${domainRoles}"
129
- .userRoles="${this.userRoles}"
130
- ></role-selector>
128
+ <role-selector .user=${this.user} .roles=${domainRoles} .userRoles=${this.userRoles}></role-selector>
131
129
 
132
130
  ${Object.keys(grantedRoles).map(
133
131
  partnerName => html`
134
132
  <role-selector
135
- .roleCategory="${partnerName}"
136
- .user="${this.user}"
137
- .roles="${this.grantedRoles[partnerName]}"
138
- .userRoles="${this.userRoles}"
133
+ .roleCategory=${partnerName}
134
+ .user=${this.user}
135
+ .roles=${this.grantedRoles[partnerName]}
136
+ .userRoles=${this.userRoles}
139
137
  >
140
138
  </role-selector>
141
139
  `
@@ -398,19 +396,8 @@ class UserRoleEditor extends connect(store)(LitElement) {
398
396
  }
399
397
 
400
398
  async onDelete(user) {
401
- const answer = await CustomAlert({
402
- title: i18next.t('text.are_you_sure'),
403
- text: i18next.t('text.are_you_sure_to_x_user', {
404
- x: i18next.t('button.delete')
405
- }),
406
- confirmButton: { text: i18next.t('button.delete') },
407
- cancelButton: { text: i18next.t('button.cancel') }
408
- })
409
-
410
- if (!answer.value) return
411
-
412
399
  if (user.owner) {
413
- await CustomAlert({
400
+ await OxPrompt.open({
414
401
  type: 'warning',
415
402
  title: i18next.t('text.cannot_delete'),
416
403
  text: i18next.t('text.x_cannot_delete', {
@@ -422,24 +409,35 @@ class UserRoleEditor extends connect(store)(LitElement) {
422
409
  return
423
410
  }
424
411
 
425
- const response = await client.mutate({
426
- mutation: gql`
427
- mutation deleteDomaineUser($email: String!) {
428
- deleteDomainUser(email: $email)
429
- }
430
- `,
431
- variables: { email: user.email },
432
- context: gqlContext()
433
- })
434
-
435
- if (!response.errors) {
436
- await CustomAlert({
437
- type: 'success',
438
- title: i18next.t('text.completed'),
439
- confirmButton: { text: i18next.t('button.confirm') }
412
+ if (
413
+ await OxPrompt.open({
414
+ title: i18next.t('text.are_you_sure'),
415
+ text: i18next.t('text.are_you_sure_to_x_user', {
416
+ x: i18next.t('button.delete')
417
+ }),
418
+ confirmButton: { text: i18next.t('button.delete') },
419
+ cancelButton: { text: i18next.t('button.cancel') }
420
+ })
421
+ ) {
422
+ const response = await client.mutate({
423
+ mutation: gql`
424
+ mutation deleteDomaineUser($email: String!) {
425
+ deleteDomainUser(email: $email)
426
+ }
427
+ `,
428
+ variables: { email: user.email },
429
+ context: gqlContext()
440
430
  })
441
431
 
442
- this.dispatchUserUpdated()
432
+ if (!response.errors) {
433
+ await OxPrompt.open({
434
+ type: 'success',
435
+ title: i18next.t('text.completed'),
436
+ confirmButton: { text: i18next.t('button.confirm') }
437
+ })
438
+
439
+ this.dispatchUserUpdated()
440
+ }
443
441
  }
444
442
  }
445
443
 
@@ -459,32 +457,32 @@ class UserRoleEditor extends connect(store)(LitElement) {
459
457
  }
460
458
 
461
459
  async onResetPassword(user) {
462
- const answer = await CustomAlert({
463
- title: i18next.t('text.are_you_sure'),
464
- text: i18next.t('text.are_you_sure_to_x', { x: i18next.t('title.reset password') }),
465
- confirmButton: { text: i18next.t('button.confirm') },
466
- cancelButton: { text: i18next.t('button.cancel') }
467
- })
468
-
469
- if (!answer.value) return
470
-
471
- const response = await client.mutate({
472
- mutation: gql`
473
- mutation resetPasswordToDefault($userId: String!) {
474
- resetPasswordToDefault(userId: $userId)
475
- }
476
- `,
477
- variables: { userId: user.id },
478
- context: gqlContext()
479
- })
480
-
481
- if (!response.errors) {
482
- await CustomAlert({
483
- type: 'success',
484
- title: i18next.t('text.completed'),
485
- text: i18next.t('text.password reset succeed'),
486
- confirmButton: { text: i18next.t('button.confirm') }
460
+ if (
461
+ await OxPrompt.open({
462
+ title: i18next.t('text.are_you_sure'),
463
+ text: i18next.t('text.are_you_sure_to_x', { x: i18next.t('title.reset password') }),
464
+ confirmButton: { text: i18next.t('button.confirm') },
465
+ cancelButton: { text: i18next.t('button.cancel') }
466
+ })
467
+ ) {
468
+ const response = await client.mutate({
469
+ mutation: gql`
470
+ mutation resetPasswordToDefault($userId: String!) {
471
+ resetPasswordToDefault(userId: $userId)
472
+ }
473
+ `,
474
+ variables: { userId: user.id },
475
+ context: gqlContext()
487
476
  })
477
+
478
+ if (!response.errors) {
479
+ await OxPrompt.open({
480
+ type: 'success',
481
+ title: i18next.t('text.completed'),
482
+ text: i18next.t('text.password reset succeed'),
483
+ confirmButton: { text: i18next.t('button.confirm') }
484
+ })
485
+ }
488
486
  }
489
487
  }
490
488
 
@@ -31,7 +31,7 @@ export class ForgotPassword extends AbstractAuthPage {
31
31
  <mwc-textfield
32
32
  name="email"
33
33
  type="email"
34
- label=${i18next.t('label.email')}
34
+ label=${String(i18next.t('label.email'))}
35
35
  .value=${email}
36
36
  required
37
37
  @input=${e => {
@@ -28,32 +28,38 @@ export class AuthSignup extends AbstractSign {
28
28
 
29
29
  return html`
30
30
  <div class="field">
31
- <mwc-textfield name="name" type="text" label=${i18next.t('field.name')} .value=${name} required></mwc-textfield>
31
+ <mwc-textfield
32
+ name="name"
33
+ type="text"
34
+ label=${String(i18next.t('field.name'))}
35
+ .value=${name}
36
+ required
37
+ ></mwc-textfield>
32
38
  </div>
33
39
  <div class="field">
34
40
  <mwc-textfield
35
41
  name="email"
36
42
  type="email"
37
- label=${i18next.t('field.email')}
43
+ label=${String(i18next.t('field.email'))}
38
44
  required
39
45
  .value=${email}
40
- .validationMessage=${i18next.t('text.invalid-email')}
46
+ .validationMessage=${String(i18next.t('text.invalid-email'))}
41
47
  ></mwc-textfield>
42
48
  </div>
43
49
  <div class="field">
44
50
  <mwc-textfield
45
51
  name="password"
46
52
  type="password"
47
- label=${i18next.t('field.password')}
48
- .pattern=${this.passwordPattern}
49
- helper=${this.passwordHelp}
53
+ label=${String(i18next.t('field.password'))}
54
+ .pattern=${this.passwordPattern || ''}
55
+ helper=${this.passwordHelp || ''}
50
56
  helperPersistent
51
57
  required
52
58
  @input=${e => {
53
59
  var val = e.target.value
54
60
  this.confirmPass.setAttribute('pattern', val.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '[$&]'))
55
61
  }}
56
- .validationMessage=${this.passwordHelp}
62
+ .validationMessage=${this.passwordHelp || ''}
57
63
  ></mwc-textfield>
58
64
  </div>
59
65
  <div class="field">
@@ -61,9 +67,9 @@ export class AuthSignup extends AbstractSign {
61
67
  id="confirm-password"
62
68
  name="confirm-password"
63
69
  type="password"
64
- label=${i18next.t('field.confirm password')}
70
+ label=${String(i18next.t('field.confirm password'))}
65
71
  required
66
- .validationMessage=${i18next.t('text.passwords do not match')}
72
+ .validationMessage=${String(i18next.t('text.passwords do not match'))}
67
73
  ></mwc-textfield>
68
74
  </div>
69
75
  <mwc-button class="ui button" raised @click=${e => this._onSubmit(e)}>
@@ -7,7 +7,7 @@ import { customElement, property, query } from 'lit/decorators.js'
7
7
 
8
8
  import { client } from '@operato/graphql'
9
9
  import { i18next } from '@operato/i18n'
10
- import { CustomAlert } from '@things-factory/shell/client'
10
+ import { OxPrompt } from '@operato/popup/ox-prompt.js'
11
11
 
12
12
  @customElement('oauth2-decision')
13
13
  class OAuth2DecisionPage extends LitElement {
@@ -152,7 +152,7 @@ class OAuth2DecisionPage extends LitElement {
152
152
  async decision(allowOrCancel) {
153
153
  const selectedRoles = this.selectedRoles()
154
154
  if (allowOrCancel && !selectedRoles?.length) {
155
- CustomAlert({
155
+ await OxPrompt.open({
156
156
  title: i18next.t('title.nothing selected'),
157
157
  text: i18next.t('text.should select at least one of x', { x: i18next.t('label.role') }),
158
158
  confirmButton: { text: i18next.t('button.confirm') }
@@ -67,7 +67,6 @@ class RoleManagement extends connect(store)(PageView) {
67
67
 
68
68
  return html`
69
69
  <h2>Roles</h2>
70
- <div subtitle>${i18next.t('text.create role')}</div>
71
70
  <create-role
72
71
  @fetch-roles=${async () => {
73
72
  this.roles = await this.fetchRoles()
@@ -11,7 +11,7 @@ import { customElement, property, query } from 'lit/decorators.js'
11
11
  import { client, gqlContext } from '@operato/graphql'
12
12
  import { i18next } from '@operato/i18n'
13
13
  import { PageView } from '@operato/shell'
14
- import { CustomAlert } from '@things-factory/shell/client'
14
+ import { OxPrompt } from '@operato/popup/ox-prompt.js'
15
15
 
16
16
  @customElement('user-management')
17
17
  class UserManagement extends PageView {
@@ -196,34 +196,34 @@ class UserManagement extends PageView {
196
196
  }
197
197
 
198
198
  async createUser(user) {
199
- const result = await CustomAlert({
200
- title: i18next.t('text.are_you_sure'),
201
- text: i18next.t('text.are_you_sure_to_x_user', { x: i18next.t('button.create') }),
202
- confirmButton: { text: i18next.t('button.confirm') },
203
- cancelButton: { text: i18next.t('button.cancel') }
204
- })
205
-
206
- if (!result.value) return
207
-
208
- const response = await client.mutate({
209
- mutation: gql`
210
- mutation createUser($user: NewUser!) {
211
- createUser(user: $user) {
212
- name
199
+ if (
200
+ await OxPrompt.open({
201
+ title: i18next.t('text.are_you_sure'),
202
+ text: i18next.t('text.are_you_sure_to_x_user', { x: i18next.t('button.create') }),
203
+ confirmButton: { text: i18next.t('button.confirm') },
204
+ cancelButton: { text: i18next.t('button.cancel') }
205
+ })
206
+ ) {
207
+ const response = await client.mutate({
208
+ mutation: gql`
209
+ mutation createUser($user: NewUser!) {
210
+ createUser(user: $user) {
211
+ name
212
+ }
213
213
  }
214
- }
215
- `,
216
- variables: { user },
217
- context: gqlContext()
218
- })
219
-
220
- if (!response.errors) {
221
- await CustomAlert({
222
- title: i18next.t('text.completed'),
223
- confirmButton: { text: i18next.t('button.confirm') }
214
+ `,
215
+ variables: { user },
216
+ context: gqlContext()
224
217
  })
225
218
 
226
- await this.refreshUsers()
219
+ if (!response.errors) {
220
+ await OxPrompt.open({
221
+ title: i18next.t('text.completed'),
222
+ confirmButton: { text: i18next.t('button.confirm') }
223
+ })
224
+
225
+ await this.refreshUsers()
226
+ }
227
227
  }
228
228
  }
229
229
 
@@ -7,7 +7,7 @@ import '@operato/lottie-player';
7
7
  import '@operato/i18n/ox-i18n.js';
8
8
  import '@operato/i18n/ox-i18n-selector.js';
9
9
  import '@operato/layout/ox-snack-bar.js';
10
- import { css, html, LitElement } from 'lit';
10
+ import { css, html, LitElement, nothing } from 'lit';
11
11
  import { property, query } from 'lit/decorators.js';
12
12
  import { i18next, localize } from '@operato/i18n';
13
13
  import { ScrollbarStyles } from '@operato/styles';
@@ -31,7 +31,7 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
31
31
  <form
32
32
  id="form"
33
33
  action="${this.actionUrl}"
34
- method="POST"
34
+ method="post"
35
35
  @keypress=${e => {
36
36
  if (e.key == 'Enter')
37
37
  this._onSubmit(e);
@@ -97,10 +97,10 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
97
97
  <mwc-textfield
98
98
  name="email"
99
99
  type="email"
100
- label=${i18next.t('field.email')}
100
+ label=${String(i18next.t('field.email'))}
101
101
  required
102
102
  .value=${email}
103
- .validationMessage=${i18next.t('text.invalid-email')}
103
+ .validationMessage=${String(i18next.t('text.invalid-email'))}
104
104
  autocomplete="username"
105
105
  autocapitalize="off"
106
106
  ></mwc-textfield>
@@ -109,7 +109,7 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
109
109
  <mwc-textfield
110
110
  name="password"
111
111
  type="password"
112
- label=${i18next.t('field.password')}
112
+ label=${String(i18next.t('field.password'))}
113
113
  autocomplete="current-password"
114
114
  required
115
115
  ></mwc-textfield>
@@ -121,16 +121,18 @@ export class AbstractAuthPage extends localize(i18next)(LitElement) {
121
121
  `;
122
122
  }
123
123
  get links() {
124
- var _a;
125
- const ssoLinks = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.ssoLinks) || [];
124
+ const { userSignupProcess = true, ssoLinks = [] } = this.data || {};
126
125
  return html `
127
- <a class="link" href="/auth/signup">
128
- <mwc-button icon="add_task"><ox-i18n msgid="field.sign up"></ox-i18n></mwc-button>
129
- </a>
130
- <a class="link" href="/auth/forgot-password">
131
- <mwc-button icon="lock_open"><ox-i18n msgid="field.forgot-password"></ox-i18n></mwc-button>
132
- </a>
133
-
126
+ ${userSignupProcess
127
+ ? html `
128
+ <a class="link" href="/auth/signup">
129
+ <mwc-button icon="add_task"><ox-i18n msgid="field.sign up"></ox-i18n></mwc-button>
130
+ </a>
131
+ <a class="link" href="/auth/forgot-password">
132
+ <mwc-button icon="lock_open"><ox-i18n msgid="field.forgot-password"></ox-i18n></mwc-button>
133
+ </a>
134
+ `
135
+ : nothing}
134
136
  ${ssoLinks.map(sso => html `
135
137
  <a class="link" href=${sso.link}>
136
138
  <mwc-button icon="badge">${i18next.t('label.signin with', { title: sso.title })}</mwc-button>
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-auth-page.js","sourceRoot":"","sources":["../../client/components/abstract-auth-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-button'\nimport '@material/mwc-icon'\nimport '@material/mwc-icon-button'\nimport '@material/mwc-textfield'\nimport '@operato/lottie-player'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isSafari } from '@operato/utils'\n\nimport { AUTH_STYLE_SIGN } from '../auth-style-sign.js'\n\nexport abstract class AbstractAuthPage extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n position: relative;\n overflow: hidden;\n\n display: flex;\n flex-direction: row;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n }\n .content {\n flex: 1;\n overflow: auto;\n }\n\n [home] {\n position: absolute;\n top: 10px;\n left: 10px;\n font-size: 2em;\n color: white;\n }\n\n [hidden] {\n display: none;\n }\n\n #snackbar {\n width: 100%;\n z-index: 10;\n }\n\n @media print {\n :host {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n min-height: 100dvh;\n }\n }\n `,\n AUTH_STYLE_SIGN\n ]\n\n @property({ type: Object }) data: any\n @property({ type: String }) message?: string\n @property({ type: Object }) detail: any\n @property({ type: String }) redirectTo?: string\n\n @query('#form') formEl!: HTMLFormElement\n\n private _applicationMeta?: {\n icon: string\n title: string\n description: string\n }\n\n render() {\n var { icon, title, description } = this.applicationMeta\n\n return html`\n <div class=\"content\">\n <div class=\"wrap\">\n <div class=\"auth-brand\">\n <img src=${icon} />\n <strong class=\"name\">${title}</strong>\n <span class=\"welcome-msg\">${description}</span>\n </div>\n\n <div class=\"auth-form\">\n <h3><ox-i18n msgid=\"title.${this.pageName}\"></ox-i18n></h3>\n\n <form\n id=\"form\"\n action=\"${this.actionUrl}\"\n method=\"POST\"\n @keypress=${e => {\n if (e.key == 'Enter') this._onSubmit(e)\n }}\n >\n ${this.formfields}\n </form>\n ${this.links}\n <div id=\"locale-area\">\n <label for=\"locale-selector\"><mwc-icon>language</mwc-icon></label>\n <ox-i18n-selector\n id=\"locale-selector\"\n value=${i18next.language || 'en-US'}\n @change=${e => {\n var locale = e.detail\n if (!locale) return\n\n i18next.changeLanguage(locale)\n }}\n ></ox-i18n-selector>\n </div>\n </div>\n </div>\n\n <mwc-icon-button home icon=\"home\" @click=${e => (window.location.href = '/')}></mwc-icon-button>\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n\n ${isSafari()\n ? html``\n : html`\n <div class=\"lottie-container\">\n <lottie-player autoplay loop src=\"../../assets/images/background-animation.json\"></lottie-player>\n </div>\n `}\n </div>\n `\n }\n\n firstUpdated() {\n setTimeout(() => {\n ;(this.renderRoot.querySelector('mwc-textfield') as any).focus()\n }, 100)\n\n this.formEl.reset = () => {\n this.formElements.filter(el => !(el.hidden || el.type == 'hidden')).forEach(el => (el.value = ''))\n }\n }\n\n updated(changed) {\n if (changed.has('data') && this.data) {\n this.message = this.data.message\n this.redirectTo = this.data.redirectTo\n }\n }\n\n abstract get pageName(): string\n abstract get actionUrl(): string\n\n get formElements(): HTMLInputElement[] {\n return Array.from(this.formEl.querySelectorAll('[name]'))\n }\n\n get formfields() {\n const email = this.data?.email || ''\n\n return html`\n <input id=\"redirectTo\" type=\"hidden\" name=\"redirectTo\" .value=${this.redirectTo || '/'} />\n\n <div class=\"field\">\n <mwc-textfield\n name=\"email\"\n type=\"email\"\n label=${i18next.t('field.email')}\n required\n .value=${email}\n .validationMessage=${i18next.t('text.invalid-email')}\n autocomplete=\"username\"\n autocapitalize=\"off\"\n ></mwc-textfield>\n </div>\n <div class=\"field\">\n <mwc-textfield\n name=\"password\"\n type=\"password\"\n label=${i18next.t('field.password')}\n autocomplete=\"current-password\"\n required\n ></mwc-textfield>\n </div>\n\n <mwc-button class=\"ui\" type=\"submit\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </mwc-button>\n `\n }\n\n get links() {\n const ssoLinks = this.data?.ssoLinks || []\n\n return html`\n <a class=\"link\" href=\"/auth/signup\">\n <mwc-button icon=\"add_task\"><ox-i18n msgid=\"field.sign up\"></ox-i18n></mwc-button>\n </a>\n <a class=\"link\" href=\"/auth/forgot-password\">\n <mwc-button icon=\"lock_open\"><ox-i18n msgid=\"field.forgot-password\"></ox-i18n></mwc-button>\n </a>\n\n ${ssoLinks.map(\n sso => html`\n <a class=\"link\" href=${sso.link}>\n <mwc-button icon=\"badge\">${i18next.t('label.signin with', { title: sso.title })}</mwc-button>\n </a>\n `\n )}\n `\n }\n\n async _onSubmit(e) {\n if (this.checkValidity()) {\n this.submit()\n }\n }\n\n checkValidity() {\n return this.formElements.every(el => el.checkValidity())\n }\n\n abstract submit()\n\n showSnackbar({ level, message, timer = 3000 }: { level?: string; message?: string; timer?: number } = {}) {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n if (level) snackbar.level = level\n if (message) snackbar.message = message\n snackbar.active = true\n\n if (timer > -1)\n setTimeout(() => {\n this.hideSnackbar()\n }, timer)\n }\n\n hideSnackbar() {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n snackbar.active = false\n }\n\n get applicationMeta() {\n if (!this._applicationMeta) {\n var iconLink: HTMLLinkElement | null = document.querySelector('link[rel=\"application-icon\"]')\n var titleMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-name\"]')\n var descriptionMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-description\"]')\n\n this._applicationMeta = {\n icon: iconLink?.href || '',\n title: titleMeta?.content || 'Things Factory',\n description: descriptionMeta?.content || 'Reimagining Software'\n }\n }\n\n return this._applicationMeta\n }\n}\n"]}
1
+ {"version":3,"file":"abstract-auth-page.js","sourceRoot":"","sources":["../../client/components/abstract-auth-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-button'\nimport '@material/mwc-icon'\nimport '@material/mwc-icon-button'\nimport '@material/mwc-textfield'\nimport '@operato/lottie-player'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport '@operato/layout/ox-snack-bar.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport { property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { isSafari } from '@operato/utils'\n\nimport { AUTH_STYLE_SIGN } from '../auth-style-sign.js'\n\nexport abstract class AbstractAuthPage extends localize(i18next)(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n position: relative;\n overflow: hidden;\n\n display: flex;\n flex-direction: row;\n\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n }\n .content {\n flex: 1;\n overflow: auto;\n }\n\n [home] {\n position: absolute;\n top: 10px;\n left: 10px;\n font-size: 2em;\n color: white;\n }\n\n [hidden] {\n display: none;\n }\n\n #snackbar {\n width: 100%;\n z-index: 10;\n }\n\n @media print {\n :host {\n width: 100%;\n height: 100%;\n min-height: 100vh;\n min-height: 100dvh;\n }\n }\n `,\n AUTH_STYLE_SIGN\n ]\n\n @property({ type: Object }) data: any\n @property({ type: String }) message?: string\n @property({ type: Object }) detail: any\n @property({ type: String }) redirectTo?: string\n\n @query('#form') formEl!: HTMLFormElement\n\n private _applicationMeta?: {\n icon: string\n title: string\n description: string\n }\n\n render() {\n var { icon, title, description } = this.applicationMeta\n\n return html`\n <div class=\"content\">\n <div class=\"wrap\">\n <div class=\"auth-brand\">\n <img src=${icon} />\n <strong class=\"name\">${title}</strong>\n <span class=\"welcome-msg\">${description}</span>\n </div>\n\n <div class=\"auth-form\">\n <h3><ox-i18n msgid=\"title.${this.pageName}\"></ox-i18n></h3>\n\n <form\n id=\"form\"\n action=\"${this.actionUrl}\"\n method=\"post\"\n @keypress=${e => {\n if (e.key == 'Enter') this._onSubmit(e)\n }}\n >\n ${this.formfields}\n </form>\n ${this.links}\n <div id=\"locale-area\">\n <label for=\"locale-selector\"><mwc-icon>language</mwc-icon></label>\n <ox-i18n-selector\n id=\"locale-selector\"\n value=${i18next.language || 'en-US'}\n @change=${e => {\n var locale = e.detail\n if (!locale) return\n\n i18next.changeLanguage(locale)\n }}\n ></ox-i18n-selector>\n </div>\n </div>\n </div>\n\n <mwc-icon-button home icon=\"home\" @click=${e => (window.location.href = '/')}></mwc-icon-button>\n <ox-snack-bar id=\"snackbar\" level=\"error\" .message=${this.message}></ox-snack-bar>\n\n ${isSafari()\n ? html``\n : html`\n <div class=\"lottie-container\">\n <lottie-player autoplay loop src=\"../../assets/images/background-animation.json\"></lottie-player>\n </div>\n `}\n </div>\n `\n }\n\n firstUpdated() {\n setTimeout(() => {\n ;(this.renderRoot.querySelector('mwc-textfield') as any).focus()\n }, 100)\n\n this.formEl.reset = () => {\n this.formElements.filter(el => !(el.hidden || el.type == 'hidden')).forEach(el => (el.value = ''))\n }\n }\n\n updated(changed) {\n if (changed.has('data') && this.data) {\n this.message = this.data.message\n this.redirectTo = this.data.redirectTo\n }\n }\n\n abstract get pageName(): string\n abstract get actionUrl(): string\n\n get formElements(): HTMLInputElement[] {\n return Array.from(this.formEl.querySelectorAll('[name]'))\n }\n\n get formfields() {\n const email = this.data?.email || ''\n\n return html`\n <input id=\"redirectTo\" type=\"hidden\" name=\"redirectTo\" .value=${this.redirectTo || '/'} />\n\n <div class=\"field\">\n <mwc-textfield\n name=\"email\"\n type=\"email\"\n label=${String(i18next.t('field.email'))}\n required\n .value=${email}\n .validationMessage=${String(i18next.t('text.invalid-email'))}\n autocomplete=\"username\"\n autocapitalize=\"off\"\n ></mwc-textfield>\n </div>\n <div class=\"field\">\n <mwc-textfield\n name=\"password\"\n type=\"password\"\n label=${String(i18next.t('field.password'))}\n autocomplete=\"current-password\"\n required\n ></mwc-textfield>\n </div>\n\n <mwc-button class=\"ui\" type=\"submit\" raised @click=${e => this._onSubmit(e)}>\n <ox-i18n msgid=\"field.${this.pageName}\"> </ox-i18n>\n </mwc-button>\n `\n }\n\n get links() {\n const { userSignupProcess = true, ssoLinks = [] } = this.data || {}\n\n return html`\n ${userSignupProcess\n ? html`\n <a class=\"link\" href=\"/auth/signup\">\n <mwc-button icon=\"add_task\"><ox-i18n msgid=\"field.sign up\"></ox-i18n></mwc-button>\n </a>\n <a class=\"link\" href=\"/auth/forgot-password\">\n <mwc-button icon=\"lock_open\"><ox-i18n msgid=\"field.forgot-password\"></ox-i18n></mwc-button>\n </a>\n `\n : nothing}\n ${ssoLinks.map(\n sso => html`\n <a class=\"link\" href=${sso.link}>\n <mwc-button icon=\"badge\">${i18next.t('label.signin with', { title: sso.title })}</mwc-button>\n </a>\n `\n )}\n `\n }\n\n async _onSubmit(e) {\n if (this.checkValidity()) {\n this.submit()\n }\n }\n\n checkValidity() {\n return this.formElements.every(el => el.checkValidity())\n }\n\n abstract submit()\n\n showSnackbar({ level, message, timer = 3000 }: { level?: string; message?: string; timer?: number } = {}) {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n if (level) snackbar.level = level\n if (message) snackbar.message = message\n snackbar.active = true\n\n if (timer > -1)\n setTimeout(() => {\n this.hideSnackbar()\n }, timer)\n }\n\n hideSnackbar() {\n const snackbar = this.renderRoot.querySelector('#snackbar') as HTMLElement & {\n level: string\n message: string\n active: boolean\n }\n\n snackbar.active = false\n }\n\n get applicationMeta() {\n if (!this._applicationMeta) {\n var iconLink: HTMLLinkElement | null = document.querySelector('link[rel=\"application-icon\"]')\n var titleMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-name\"]')\n var descriptionMeta: HTMLMetaElement | null = document.querySelector('meta[name=\"application-description\"]')\n\n this._applicationMeta = {\n icon: iconLink?.href || '',\n title: titleMeta?.content || 'Things Factory',\n description: descriptionMeta?.content || 'Reimagining Software'\n }\n }\n\n return this._applicationMeta\n }\n}\n"]}
@@ -5,7 +5,7 @@ import { css, html, LitElement } from 'lit';
5
5
  import { customElement, query } from 'lit/decorators.js';
6
6
  import { client } from '@operato/graphql';
7
7
  import { i18next, localize } from '@operato/i18n';
8
- import { CustomAlert } from '@things-factory/shell/client';
8
+ import { OxPrompt } from '@operato/popup/ox-prompt.js';
9
9
  let CreateDomainPopup = class CreateDomainPopup extends localize(i18next)(LitElement) {
10
10
  render() {
11
11
  return html `
@@ -63,7 +63,7 @@ let CreateDomainPopup = class CreateDomainPopup extends localize(i18next)(LitEle
63
63
  variables: { domainInput }
64
64
  });
65
65
  if (!response.errors) {
66
- await CustomAlert({
66
+ await OxPrompt.open({
67
67
  type: 'success',
68
68
  title: i18next.t('text.completed'),
69
69
  text: i18next.t('text.x_created_successfully', { x: i18next.t('label.domain') }),