@things-factory/auth-ui 6.0.0-zeta.8 → 6.0.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.
@@ -2,7 +2,7 @@ import '@material/mwc-button'
2
2
 
3
3
  import gql from 'graphql-tag'
4
4
  import { css, html, LitElement } from 'lit'
5
- import { customElement } from 'lit/decorators.js'
5
+ import { customElement, query } from 'lit/decorators.js'
6
6
 
7
7
  import { client } from '@operato/graphql'
8
8
  import { i18next, localize } from '@operato/i18n'
@@ -53,6 +53,8 @@ class CreateDomainPopup extends localize(i18next)(LitElement) {
53
53
  `
54
54
  ]
55
55
 
56
+ @query('input[name="name"]') nameInput!: HTMLInputElement
57
+
56
58
  render() {
57
59
  return html`
58
60
  <div field grid-span>
@@ -61,6 +63,7 @@ class CreateDomainPopup extends localize(i18next)(LitElement) {
61
63
  type="text"
62
64
  name="name"
63
65
  @input=${this.checkValidation}
66
+ autofocus
64
67
  /></label>
65
68
  </div>
66
69
 
@@ -74,6 +77,10 @@ class CreateDomainPopup extends localize(i18next)(LitElement) {
74
77
  `
75
78
  }
76
79
 
80
+ firstUpdated() {
81
+ this.nameInput.focus() // autofocus
82
+ }
83
+
77
84
  get inputData() {
78
85
  return this.renderRoot.querySelectorAll('input')
79
86
  }
@@ -149,13 +149,6 @@ export class ProfileComponent extends localize(i18next)(LitElement) {
149
149
  raised
150
150
  @click=${this.openLoginHistory.bind(this)}
151
151
  ></mwc-button>
152
- <mwc-button
153
- id="delete-user-button"
154
- label=${i18next.t('label.delete account')}
155
- raised
156
- danger
157
- @click=${e => this.deleteUser()}
158
- ></mwc-button>
159
152
  </div>
160
153
  </div>
161
154
  `
@@ -3,7 +3,7 @@ import './role-selector'
3
3
 
4
4
  import gql from 'graphql-tag'
5
5
  import { css, html, LitElement } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
6
+ import { customElement, property, state } from 'lit/decorators.js'
7
7
  import { connect } from 'pwa-helpers/connect-mixin'
8
8
 
9
9
  import { client, gqlContext } from '@operato/graphql'
@@ -86,14 +86,15 @@ class UserRoleEditor extends connect(store)(LitElement) {
86
86
  ]
87
87
 
88
88
  @property({ type: Object }) user: any = {}
89
- @property({ type: Array }) domainRoles: any[] = []
90
- @property({ type: Object }) grantedRoles: any = {}
91
- @property({ type: Array }) userRoles: any[] = []
92
- @property({ type: Boolean }) isSuperOwner: boolean = false
93
- @property({ type: Boolean }) isDomainOwner: boolean = false
94
89
  @property({ type: Boolean }) activate: boolean = false
95
90
  @property({ type: Object }) domainOwner: any
96
91
 
92
+ @state() domainRoles: any[] = []
93
+ @state() grantedRoles: any = {}
94
+ @state() userRoles: any[] = []
95
+ @state() isSuperOwner: boolean = false
96
+ @state() isDomainOwner: boolean = false
97
+
97
98
  private me: any
98
99
 
99
100
  render() {
@@ -170,7 +171,7 @@ class UserRoleEditor extends connect(store)(LitElement) {
170
171
  )
171
172
  this.onSave(user, availableRoles, selectedRoles)
172
173
  }}
173
- label="${i18next.t('button.save')}"
174
+ label=${String(i18next.t('button.save'))}
174
175
  ></mwc-button>`
175
176
  : ''}
176
177
  ${user.userType === 'user'
@@ -181,7 +182,7 @@ class UserRoleEditor extends connect(store)(LitElement) {
181
182
  raised
182
183
  danger
183
184
  @click=${() => this.onTransfer(user)}
184
- label="${i18next.t('button.transfer owner')}"
185
+ label=${String(i18next.t('button.transfer owner'))}
185
186
  ></mwc-button>
186
187
  `
187
188
  : ''}
@@ -190,7 +191,7 @@ class UserRoleEditor extends connect(store)(LitElement) {
190
191
  raised
191
192
  danger
192
193
  @click="${() => this.onResetPassword(user)}"
193
- label="${i18next.t('title.reset password')}"
194
+ label=${String(i18next.t('title.reset password'))}
194
195
  ></mwc-button>`
195
196
  : ''}
196
197
  `
@@ -200,14 +201,17 @@ class UserRoleEditor extends connect(store)(LitElement) {
200
201
  <mwc-button
201
202
  raised
202
203
  danger
203
- label="${i18next.t('button.delete user')}"
204
+ label=${String(i18next.t('button.delete user'))}
204
205
  @click=${() => this.onDelete(user)}
205
206
  ></mwc-button>
206
207
  `
207
208
  : ''}
208
- ${!this.activate
209
- ? html`<mwc-button raised label="activate" @click=${() => this.onActivate(user)}></mwc-button>`
210
- : ``}
209
+ ${this.isActivatable(user)
210
+ ? html`<mwc-button raised danger @click="${() => this.onActivate(user)}" label="activate"></mwc-button>`
211
+ : ''}
212
+ ${this.isInactivatable(user)
213
+ ? html`<mwc-button raised danger @click="${() => this.onInactivate(user)}" label="inactivate"></mwc-button>`
214
+ : ''}
211
215
  </div>
212
216
  `
213
217
  }
@@ -217,7 +221,7 @@ class UserRoleEditor extends connect(store)(LitElement) {
217
221
  }
218
222
 
219
223
  isTransferable(user) {
220
- return this.isDomainOwner && user.email !== this.me.email && !user.owner
224
+ return (this.isSuperOwner || this.isDomainOwner) && !user.owner
221
225
  }
222
226
 
223
227
  isRoleEditable() {
@@ -228,6 +232,19 @@ class UserRoleEditor extends connect(store)(LitElement) {
228
232
  return (this.isSuperOwner || this.isDomainOwner) && user.email !== this.me.email
229
233
  }
230
234
 
235
+ isActivatable(user) {
236
+ return (this.isSuperOwner || this.isDomainOwner) && !this.activate
237
+ }
238
+
239
+ isInactivatable(user) {
240
+ return (
241
+ (this.isSuperOwner || this.isDomainOwner) &&
242
+ user.id !== this.domainOwner.id &&
243
+ user.userType !== 'admin' &&
244
+ this.activate
245
+ )
246
+ }
247
+
231
248
  async updated(changedProps) {
232
249
  if (changedProps.has('user')) {
233
250
  this.fetchAvailableRoles()
@@ -347,18 +364,29 @@ class UserRoleEditor extends connect(store)(LitElement) {
347
364
  async onActivate(user) {
348
365
  const response = await client.mutate({
349
366
  mutation: gql`
350
- mutation updateUser($email: String!, $patch: UserPatch!) {
351
- updateUser(email: $email, patch: $patch) {
352
- id
353
- name
354
- email
355
- userType
356
- status
357
- owner
358
- }
367
+ mutation activateUser($userId: String!) {
368
+ activateUser(userId: $userId)
359
369
  }
360
370
  `,
361
- variables: { email: user.email, patch: { status: 'activated' } },
371
+ variables: { userId: user.id },
372
+ context: gqlContext()
373
+ })
374
+
375
+ if (!response.errors) {
376
+ this.showToast(i18next.t('text.user activated successfully'))
377
+
378
+ this.dispatchUserUpdated()
379
+ }
380
+ }
381
+
382
+ async onInactivate(user) {
383
+ const response = await client.mutate({
384
+ mutation: gql`
385
+ mutation inactivateUser($userId: String!) {
386
+ inactivateUser(userId: $userId)
387
+ }
388
+ `,
389
+ variables: { userId: user.id },
362
390
  context: gqlContext()
363
391
  })
364
392
 
@@ -39,11 +39,22 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
39
39
  @property({ type: Object }) config: any
40
40
  @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'
41
41
 
42
- @query('ox-grist') dataGrist!: DataGrist
42
+ @query('ox-grist') grist!: DataGrist
43
43
 
44
44
  get context() {
45
45
  return {
46
- title: i18next.t('text.domain management'),
46
+ search: {
47
+ handler: (search: string) => {
48
+ this.grist.searchText = search
49
+ },
50
+ placeholder: i18next.t('text.domain management'),
51
+ value: this.grist.searchText
52
+ },
53
+ filter: {
54
+ handler: () => {
55
+ this.grist.toggleHeadroom()
56
+ }
57
+ },
47
58
  actions: [
48
59
  {
49
60
  title: i18next.t('button.save'),
@@ -59,7 +70,7 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
59
70
  <ox-grist .mode=${this.mode} .config=${this.config} .fetchHandler=${this.fetchHandler.bind(this)}>
60
71
  <div slot="headroom">
61
72
  <div id="filters">
62
- <ox-filters-form autofocus></ox-filters-form>
73
+ <ox-filters-form autofocus without-search></ox-filters-form>
63
74
  </div>
64
75
 
65
76
  <div id="sorters">
@@ -146,6 +157,17 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
146
157
  filter: 'search',
147
158
  width: 200
148
159
  },
160
+ {
161
+ type: 'resource-object',
162
+ name: 'ownerUser',
163
+ header: i18next.t('field.owner-user'),
164
+ record: {
165
+ options: {
166
+ descriptionField: 'email'
167
+ }
168
+ },
169
+ width: 140
170
+ },
149
171
  {
150
172
  type: 'select',
151
173
  name: 'extType',
@@ -177,14 +199,14 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
177
199
 
178
200
  await this.updateComplete
179
201
 
180
- this.dataGrist.fetch()
202
+ this.grist.fetch()
181
203
  }
182
204
 
183
205
  async pageUpdated(changes, lifecycle) {
184
206
  if (this.active) {
185
207
  await this.updateComplete
186
208
 
187
- this.dataGrist.fetch()
209
+ this.grist.fetch()
188
210
  }
189
211
  }
190
212
 
@@ -198,6 +220,10 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
198
220
  name
199
221
  description
200
222
  subdomain
223
+ ownerUser {
224
+ name
225
+ email
226
+ }
201
227
  extType
202
228
  timezone
203
229
  updatedAt
@@ -220,7 +246,7 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
220
246
  }
221
247
 
222
248
  async onUpdateDomains() {
223
- let patches = this.dataGrist.dirtyRecords
249
+ let patches = this.grist.dirtyRecords
224
250
 
225
251
  if (patches && patches.length) {
226
252
  patches = patches.map(domain => {
@@ -245,7 +271,7 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
245
271
  })
246
272
 
247
273
  if (!response.errors) {
248
- this.dataGrist.fetch()
274
+ this.grist.fetch()
249
275
  return this.showToast(i18next.t('text.updated_successfully'))
250
276
  }
251
277
  }
@@ -256,7 +282,7 @@ export class DomainManagement extends connect(store)(localize(i18next)(PageView)
256
282
  html`
257
283
  <create-domain-popup
258
284
  @fetch-data=${async () => {
259
- this.dataGrist.fetch()
285
+ this.grist.fetch()
260
286
  }}
261
287
  ></create-domain-popup>
262
288
  `,
@@ -61,13 +61,16 @@ class UserManagement extends PageView {
61
61
  const groupingUser = (this.domainUsers || []).reduce(
62
62
  (groupingUser, user) => {
63
63
  const userType = user.userType
64
- if (!groupingUser[userType]) groupingUser[userType] = []
65
- user.activated = user.status !== 'inactive'
64
+ if (!groupingUser[userType]) {
65
+ groupingUser[userType] = []
66
+ }
67
+ user.activated = user.status === 'activated'
66
68
  groupingUser[userType].push(user)
67
69
 
68
70
  return groupingUser
69
71
  },
70
72
  {
73
+ admin: [],
71
74
  user: [],
72
75
  application: [],
73
76
  appliance: []
@@ -81,7 +84,7 @@ class UserManagement extends PageView {
81
84
  }
82
85
 
83
86
  const userSet = {
84
- [USER_TYPES.USER]: groupingUser.user,
87
+ [USER_TYPES.USER]: [...groupingUser.user, ...groupingUser.admin],
85
88
  [USER_TYPES.APPLICATION]: groupingUser.application,
86
89
  [USER_TYPES.APPLIANCE]: groupingUser.appliance
87
90
  }
@@ -1,8 +1,8 @@
1
- import { __decorate } from "tslib";
1
+ import { __decorate, __metadata } from "tslib";
2
2
  import '@material/mwc-button';
3
3
  import gql from 'graphql-tag';
4
4
  import { css, html, LitElement } from 'lit';
5
- import { customElement } from 'lit/decorators.js';
5
+ import { customElement, query } from 'lit/decorators.js';
6
6
  import { client } from '@operato/graphql';
7
7
  import { i18next, localize } from '@operato/i18n';
8
8
  import { CustomAlert } from '@things-factory/shell/client';
@@ -15,6 +15,7 @@ let CreateDomainPopup = class CreateDomainPopup extends localize(i18next)(LitEle
15
15
  type="text"
16
16
  name="name"
17
17
  @input=${this.checkValidation}
18
+ autofocus
18
19
  /></label>
19
20
  </div>
20
21
 
@@ -27,6 +28,9 @@ let CreateDomainPopup = class CreateDomainPopup extends localize(i18next)(LitEle
27
28
  </div>
28
29
  `;
29
30
  }
31
+ firstUpdated() {
32
+ this.nameInput.focus(); // autofocus
33
+ }
30
34
  get inputData() {
31
35
  return this.renderRoot.querySelectorAll('input');
32
36
  }
@@ -115,6 +119,10 @@ CreateDomainPopup.styles = [
115
119
  }
116
120
  `
117
121
  ];
122
+ __decorate([
123
+ query('input[name="name"]'),
124
+ __metadata("design:type", HTMLInputElement)
125
+ ], CreateDomainPopup.prototype, "nameInput", void 0);
118
126
  CreateDomainPopup = __decorate([
119
127
  customElement('create-domain-popup')
120
128
  ], CreateDomainPopup);
@@ -1 +1 @@
1
- {"version":3,"file":"create-domain-popup.js","sourceRoot":"","sources":["../../client/components/create-domain-popup.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-button'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { CustomAlert } from '@things-factory/shell/client'\n\n@customElement('create-domain-popup')\nclass CreateDomainPopup extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n background-color: var(--main-section-background-color);\n padding: var(--padding-wide);\n overflow: auto;\n }\n input.checkValidName {\n background-color: #fce6e6;\n }\n mwc-button {\n display: flex;\n justify-content: center;\n }\n label {\n display: flex;\n flex-direction: column;\n\n font: var(--label-font);\n color: var(--label-color);\n text-transform: var(--label-text-transform);\n }\n input {\n border: var(--border-dark-color);\n border-radius: var(--border-radius);\n margin: var(--input-margin);\n padding: var(--input-padding);\n background-color: var(--theme-white-color);\n font: var(--input-font);\n\n flex: 1;\n }\n [field] {\n grid-column: span 2;\n }\n [buttons] {\n margin-top: auto;\n }\n `\n ]\n\n render() {\n return html`\n <div field grid-span>\n <label\n >${i18next.t('label.x name', { x: i18next.t('label.domain') })}<input\n type=\"text\"\n name=\"name\"\n @input=${this.checkValidation}\n /></label>\n </div>\n\n <div field grid-span>\n <label>${i18next.t('label.description')}<input type=\"text\" name=\"description\" /></label>\n </div>\n\n <div buttons>\n <mwc-button raised @click=${e => this.onCreateDomain()}>${i18next.t('button.create')}</mwc-button>\n </div>\n `\n }\n\n get inputData() {\n return this.renderRoot.querySelectorAll('input')\n }\n\n checkValidation(e) {\n const currentInput = e.currentTarget\n const regExp = /^[a-zA-Z ]+$/\n\n if (!regExp.test(currentInput.value)) {\n currentInput.classList.add('checkValidName')\n } else {\n currentInput.classList.remove('checkValidName')\n }\n }\n\n async onCreateDomain() {\n const domainInput: { [prop: string]: string } = {}\n this.inputData.forEach(data => (domainInput[data.name] = data.value))\n const regExp = /^[a-zA-z ]+$/\n\n if (!regExp.test(domainInput.name)) {\n return this.showToast(i18next.t('error: domain name should consist only of letters or dashes'))\n }\n\n const response = await client.mutate({\n mutation: gql`\n mutation domainRegister($domainInput: DomainGeneratorInput!) {\n domainRegister(domainInput: $domainInput) {\n id\n name\n }\n }\n `,\n variables: { domainInput }\n })\n\n if (!response.errors) {\n await CustomAlert({\n type: 'success',\n title: i18next.t('text.completed'),\n text: i18next.t('text.x_created_successfully', { x: i18next.t('label.domain') }),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n\n history.back()\n\n this.dispatchEvent(new CustomEvent('fetch-data'))\n }\n }\n\n showToast(message) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))\n }\n}\n"]}
1
+ {"version":3,"file":"create-domain-popup.js","sourceRoot":"","sources":["../../client/components/create-domain-popup.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-button'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, query } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { CustomAlert } from '@things-factory/shell/client'\n\n@customElement('create-domain-popup')\nclass CreateDomainPopup extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n background-color: var(--main-section-background-color);\n padding: var(--padding-wide);\n overflow: auto;\n }\n input.checkValidName {\n background-color: #fce6e6;\n }\n mwc-button {\n display: flex;\n justify-content: center;\n }\n label {\n display: flex;\n flex-direction: column;\n\n font: var(--label-font);\n color: var(--label-color);\n text-transform: var(--label-text-transform);\n }\n input {\n border: var(--border-dark-color);\n border-radius: var(--border-radius);\n margin: var(--input-margin);\n padding: var(--input-padding);\n background-color: var(--theme-white-color);\n font: var(--input-font);\n\n flex: 1;\n }\n [field] {\n grid-column: span 2;\n }\n [buttons] {\n margin-top: auto;\n }\n `\n ]\n\n @query('input[name=\"name\"]') nameInput!: HTMLInputElement\n\n render() {\n return html`\n <div field grid-span>\n <label\n >${i18next.t('label.x name', { x: i18next.t('label.domain') })}<input\n type=\"text\"\n name=\"name\"\n @input=${this.checkValidation}\n autofocus\n /></label>\n </div>\n\n <div field grid-span>\n <label>${i18next.t('label.description')}<input type=\"text\" name=\"description\" /></label>\n </div>\n\n <div buttons>\n <mwc-button raised @click=${e => this.onCreateDomain()}>${i18next.t('button.create')}</mwc-button>\n </div>\n `\n }\n\n firstUpdated() {\n this.nameInput.focus() // autofocus\n }\n\n get inputData() {\n return this.renderRoot.querySelectorAll('input')\n }\n\n checkValidation(e) {\n const currentInput = e.currentTarget\n const regExp = /^[a-zA-Z ]+$/\n\n if (!regExp.test(currentInput.value)) {\n currentInput.classList.add('checkValidName')\n } else {\n currentInput.classList.remove('checkValidName')\n }\n }\n\n async onCreateDomain() {\n const domainInput: { [prop: string]: string } = {}\n this.inputData.forEach(data => (domainInput[data.name] = data.value))\n const regExp = /^[a-zA-z ]+$/\n\n if (!regExp.test(domainInput.name)) {\n return this.showToast(i18next.t('error: domain name should consist only of letters or dashes'))\n }\n\n const response = await client.mutate({\n mutation: gql`\n mutation domainRegister($domainInput: DomainGeneratorInput!) {\n domainRegister(domainInput: $domainInput) {\n id\n name\n }\n }\n `,\n variables: { domainInput }\n })\n\n if (!response.errors) {\n await CustomAlert({\n type: 'success',\n title: i18next.t('text.completed'),\n text: i18next.t('text.x_created_successfully', { x: i18next.t('label.domain') }),\n confirmButton: { text: i18next.t('button.confirm') }\n })\n\n history.back()\n\n this.dispatchEvent(new CustomEvent('fetch-data'))\n }\n }\n\n showToast(message) {\n document.dispatchEvent(new CustomEvent('notify', { detail: { message } }))\n }\n}\n"]}
@@ -54,13 +54,6 @@ let ProfileComponent = class ProfileComponent extends localize(i18next)(LitEleme
54
54
  raised
55
55
  @click=${this.openLoginHistory.bind(this)}
56
56
  ></mwc-button>
57
- <mwc-button
58
- id="delete-user-button"
59
- label=${i18next.t('label.delete account')}
60
- raised
61
- danger
62
- @click=${e => this.deleteUser()}
63
- ></mwc-button>
64
57
  </div>
65
58
  </div>
66
59
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"profile-component.js","sourceRoot":"","sources":["../../client/components/profile-component.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport './change-password'\nimport './delete-user-popup'\nimport './my-login-history'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport { auth } from '@things-factory/auth-base/dist-client'\n\n@customElement('profile-component')\nexport class ProfileComponent extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: block;\n background-color: var(--main-section-background-color);\n padding: 15px 0;\n }\n .wrap {\n max-width: var(--profile-wrap-max-width, 400px);\n margin: auto;\n display: grid;\n grid-template-columns: 1fr 1fr;\n }\n\n * {\n box-sizing: border-box;\n }\n\n *:focus {\n outline: none;\n }\n\n input {\n margin: var(--change-password-field-margin);\n border: var(--input-field-border);\n padding: var(--input-padding);\n border-radius: var(--border-radius);\n font: var(--input-font);\n width: var(--change-password-field-width);\n }\n input:focus {\n border: 1px solid var(--focus-background-color);\n }\n\n .user {\n background: url(/assets/images/icon-profile.png) center top no-repeat;\n margin: var(--profile-icon-margin);\n padding: 180px 20px 20px 20px;\n color: var(--secondary-color);\n font: var(--header-bar-title);\n text-align: center;\n }\n\n hr {\n width: 100%;\n border: dotted 1px rgba(0, 0, 0, 0.1);\n }\n\n .wrap * {\n grid-column: span 2;\n }\n\n label {\n font: bold 14px var(--theme-font);\n color: var(--primary-color);\n text-transform: capitalize;\n grid-column: 1;\n }\n\n .wrap *.inline {\n grid-column: unset;\n }\n\n i18n-selector {\n --i18n-selector-field-width: var(--auth-input-field-width);\n --i18n-selector-field-margin: var(--change-password-field-margin);\n --i18n-selector-field-padding: var(--padding-default);\n --i18n-selector-field-border-radius: var(--border-radius);\n margin: var(--change-password-field-margin);\n }\n\n [danger] {\n --mdc-theme-primary: var(--mdc-danger-button-primary-color);\n }\n .button-container {\n display: flex;\n gap: var(--padding-default);\n }\n .button-container > mwc-button:first-child {\n margin: auto 0px auto auto;\n }\n `\n ]\n\n @property({ type: String }) email?: string\n @property({ type: String }) name?: string\n\n @query('#name') nameEl!: HTMLInputElement\n @query('#locale') localeEl!: HTMLInputElement\n\n firstUpdated() {\n auth.on('profile', ({ credential }) => {\n this.setCredential(credential)\n })\n\n this.setCredential(auth.credential)\n }\n\n setCredential(credential) {\n if (credential) {\n this.name = credential.name\n this.email = credential.email\n } else {\n this.name = ''\n this.email = ''\n }\n }\n\n render() {\n return html`\n <div class=\"wrap\">\n <div class=\"user\">${this.email || ''}</div>\n\n <label for=\"name\"><ox-i18n slot=\"title\" msgid=\"label.name\"></ox-i18n></label>\n <input id=\"name\" @change=${e => this.onNameChanged(e.target.value)} .value=${this.name || ''} />\n\n <hr />\n\n <label for=\"locale\"><ox-i18n slot=\"title\" msgid=\"label.language\"></ox-i18n></label>\n <ox-i18n-selector id=\"locale\" @change=${e => this.onLocaleChanged(e.detail)}></ox-i18n-selector>\n\n <hr />\n\n <label for=\"change-password\">\n <ox-i18n msgid=\"label.password\"></ox-i18n>\n </label>\n\n <change-password id=\"change-password\"></change-password>\n\n <div class=\"button-container\">\n <mwc-button\n id=\"login-history-button\"\n label=${i18next.t('label.login_history')}\n raised\n @click=${this.openLoginHistory.bind(this)}\n ></mwc-button>\n <mwc-button\n id=\"delete-user-button\"\n label=${i18next.t('label.delete account')}\n raised\n danger\n @click=${e => this.deleteUser()}\n ></mwc-button>\n </div>\n </div>\n `\n }\n\n async onNameChanged(name) {\n if (!name) return\n\n var oldName = this.name\n\n try {\n const message = await auth.updateProfile({\n name\n })\n\n notify({\n level: 'info',\n message\n })\n } catch (e: any) {\n this.nameEl.value = oldName || ''\n\n notify({\n level: 'error',\n message: 'message' in e ? e.message : e\n })\n }\n }\n\n async onLocaleChanged(value) {\n if (!value) return\n\n var oldLocale = i18next.language\n\n try {\n const message = await auth.updateProfile({\n locale: value\n })\n\n i18next.changeLanguage(value)\n\n notify({\n level: 'info',\n message\n })\n } catch (e: any) {\n this.localeEl.value = oldLocale\n\n notify({\n level: 'error',\n message: 'message' in e ? e.message : e\n })\n }\n }\n\n openLoginHistory() {\n openPopup(html` <my-login-history></my-login-history> `, {\n title: i18next.t('label.login_history')\n })\n }\n\n deleteUser() {\n openPopup(html` <delete-user-popup></delete-user-popup> `, {\n title: i18next.t('label.delete account')\n })\n }\n}\n"]}
1
+ {"version":3,"file":"profile-component.js","sourceRoot":"","sources":["../../client/components/profile-component.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/i18n/ox-i18n.js'\nimport '@operato/i18n/ox-i18n-selector.js'\nimport './change-password'\nimport './delete-user-popup'\nimport './my-login-history'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { notify, openPopup } from '@operato/layout'\nimport { auth } from '@things-factory/auth-base/dist-client'\n\n@customElement('profile-component')\nexport class ProfileComponent extends localize(i18next)(LitElement) {\n static styles = [\n css`\n :host {\n display: block;\n background-color: var(--main-section-background-color);\n padding: 15px 0;\n }\n .wrap {\n max-width: var(--profile-wrap-max-width, 400px);\n margin: auto;\n display: grid;\n grid-template-columns: 1fr 1fr;\n }\n\n * {\n box-sizing: border-box;\n }\n\n *:focus {\n outline: none;\n }\n\n input {\n margin: var(--change-password-field-margin);\n border: var(--input-field-border);\n padding: var(--input-padding);\n border-radius: var(--border-radius);\n font: var(--input-font);\n width: var(--change-password-field-width);\n }\n input:focus {\n border: 1px solid var(--focus-background-color);\n }\n\n .user {\n background: url(/assets/images/icon-profile.png) center top no-repeat;\n margin: var(--profile-icon-margin);\n padding: 180px 20px 20px 20px;\n color: var(--secondary-color);\n font: var(--header-bar-title);\n text-align: center;\n }\n\n hr {\n width: 100%;\n border: dotted 1px rgba(0, 0, 0, 0.1);\n }\n\n .wrap * {\n grid-column: span 2;\n }\n\n label {\n font: bold 14px var(--theme-font);\n color: var(--primary-color);\n text-transform: capitalize;\n grid-column: 1;\n }\n\n .wrap *.inline {\n grid-column: unset;\n }\n\n i18n-selector {\n --i18n-selector-field-width: var(--auth-input-field-width);\n --i18n-selector-field-margin: var(--change-password-field-margin);\n --i18n-selector-field-padding: var(--padding-default);\n --i18n-selector-field-border-radius: var(--border-radius);\n margin: var(--change-password-field-margin);\n }\n\n [danger] {\n --mdc-theme-primary: var(--mdc-danger-button-primary-color);\n }\n .button-container {\n display: flex;\n gap: var(--padding-default);\n }\n .button-container > mwc-button:first-child {\n margin: auto 0px auto auto;\n }\n `\n ]\n\n @property({ type: String }) email?: string\n @property({ type: String }) name?: string\n\n @query('#name') nameEl!: HTMLInputElement\n @query('#locale') localeEl!: HTMLInputElement\n\n firstUpdated() {\n auth.on('profile', ({ credential }) => {\n this.setCredential(credential)\n })\n\n this.setCredential(auth.credential)\n }\n\n setCredential(credential) {\n if (credential) {\n this.name = credential.name\n this.email = credential.email\n } else {\n this.name = ''\n this.email = ''\n }\n }\n\n render() {\n return html`\n <div class=\"wrap\">\n <div class=\"user\">${this.email || ''}</div>\n\n <label for=\"name\"><ox-i18n slot=\"title\" msgid=\"label.name\"></ox-i18n></label>\n <input id=\"name\" @change=${e => this.onNameChanged(e.target.value)} .value=${this.name || ''} />\n\n <hr />\n\n <label for=\"locale\"><ox-i18n slot=\"title\" msgid=\"label.language\"></ox-i18n></label>\n <ox-i18n-selector id=\"locale\" @change=${e => this.onLocaleChanged(e.detail)}></ox-i18n-selector>\n\n <hr />\n\n <label for=\"change-password\">\n <ox-i18n msgid=\"label.password\"></ox-i18n>\n </label>\n\n <change-password id=\"change-password\"></change-password>\n\n <div class=\"button-container\">\n <mwc-button\n id=\"login-history-button\"\n label=${i18next.t('label.login_history')}\n raised\n @click=${this.openLoginHistory.bind(this)}\n ></mwc-button>\n </div>\n </div>\n `\n }\n\n async onNameChanged(name) {\n if (!name) return\n\n var oldName = this.name\n\n try {\n const message = await auth.updateProfile({\n name\n })\n\n notify({\n level: 'info',\n message\n })\n } catch (e: any) {\n this.nameEl.value = oldName || ''\n\n notify({\n level: 'error',\n message: 'message' in e ? e.message : e\n })\n }\n }\n\n async onLocaleChanged(value) {\n if (!value) return\n\n var oldLocale = i18next.language\n\n try {\n const message = await auth.updateProfile({\n locale: value\n })\n\n i18next.changeLanguage(value)\n\n notify({\n level: 'info',\n message\n })\n } catch (e: any) {\n this.localeEl.value = oldLocale\n\n notify({\n level: 'error',\n message: 'message' in e ? e.message : e\n })\n }\n }\n\n openLoginHistory() {\n openPopup(html` <my-login-history></my-login-history> `, {\n title: i18next.t('label.login_history')\n })\n }\n\n deleteUser() {\n openPopup(html` <delete-user-popup></delete-user-popup> `, {\n title: i18next.t('label.delete account')\n })\n }\n}\n"]}
@@ -3,7 +3,7 @@ import './ownership-transfer-popup';
3
3
  import './role-selector';
4
4
  import gql from 'graphql-tag';
5
5
  import { css, html, LitElement } from 'lit';
6
- import { customElement, property } from 'lit/decorators.js';
6
+ import { customElement, property, state } from 'lit/decorators.js';
7
7
  import { connect } from 'pwa-helpers/connect-mixin';
8
8
  import { client, gqlContext } from '@operato/graphql';
9
9
  import { i18next } from '@operato/i18n';
@@ -14,12 +14,12 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
14
14
  constructor() {
15
15
  super(...arguments);
16
16
  this.user = {};
17
+ this.activate = false;
17
18
  this.domainRoles = [];
18
19
  this.grantedRoles = {};
19
20
  this.userRoles = [];
20
21
  this.isSuperOwner = false;
21
22
  this.isDomainOwner = false;
22
- this.activate = false;
23
23
  }
24
24
  render() {
25
25
  const user = this.user || {};
@@ -83,7 +83,7 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
83
83
  }, { availableRoles: [], selectedRoles: [] });
84
84
  this.onSave(user, availableRoles, selectedRoles);
85
85
  }}
86
- label="${i18next.t('button.save')}"
86
+ label=${String(i18next.t('button.save'))}
87
87
  ></mwc-button>`
88
88
  : ''}
89
89
  ${user.userType === 'user'
@@ -94,7 +94,7 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
94
94
  raised
95
95
  danger
96
96
  @click=${() => this.onTransfer(user)}
97
- label="${i18next.t('button.transfer owner')}"
97
+ label=${String(i18next.t('button.transfer owner'))}
98
98
  ></mwc-button>
99
99
  `
100
100
  : ''}
@@ -103,7 +103,7 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
103
103
  raised
104
104
  danger
105
105
  @click="${() => this.onResetPassword(user)}"
106
- label="${i18next.t('title.reset password')}"
106
+ label=${String(i18next.t('title.reset password'))}
107
107
  ></mwc-button>`
108
108
  : ''}
109
109
  `
@@ -113,14 +113,17 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
113
113
  <mwc-button
114
114
  raised
115
115
  danger
116
- label="${i18next.t('button.delete user')}"
116
+ label=${String(i18next.t('button.delete user'))}
117
117
  @click=${() => this.onDelete(user)}
118
118
  ></mwc-button>
119
119
  `
120
120
  : ''}
121
- ${!this.activate
122
- ? html `<mwc-button raised label="activate" @click=${() => this.onActivate(user)}></mwc-button>`
123
- : ``}
121
+ ${this.isActivatable(user)
122
+ ? html `<mwc-button raised danger @click="${() => this.onActivate(user)}" label="activate"></mwc-button>`
123
+ : ''}
124
+ ${this.isInactivatable(user)
125
+ ? html `<mwc-button raised danger @click="${() => this.onInactivate(user)}" label="inactivate"></mwc-button>`
126
+ : ''}
124
127
  </div>
125
128
  `;
126
129
  }
@@ -128,7 +131,7 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
128
131
  return this.isDomainOwner && user.email !== this.me.email && !user.owner;
129
132
  }
130
133
  isTransferable(user) {
131
- return this.isDomainOwner && user.email !== this.me.email && !user.owner;
134
+ return (this.isSuperOwner || this.isDomainOwner) && !user.owner;
132
135
  }
133
136
  isRoleEditable() {
134
137
  var _a;
@@ -137,6 +140,15 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
137
140
  isPasswordResettable(user) {
138
141
  return (this.isSuperOwner || this.isDomainOwner) && user.email !== this.me.email;
139
142
  }
143
+ isActivatable(user) {
144
+ return (this.isSuperOwner || this.isDomainOwner) && !this.activate;
145
+ }
146
+ isInactivatable(user) {
147
+ return ((this.isSuperOwner || this.isDomainOwner) &&
148
+ user.id !== this.domainOwner.id &&
149
+ user.userType !== 'admin' &&
150
+ this.activate);
151
+ }
140
152
  async updated(changedProps) {
141
153
  var _a;
142
154
  if (changedProps.has('user')) {
@@ -253,18 +265,26 @@ let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
253
265
  async onActivate(user) {
254
266
  const response = await client.mutate({
255
267
  mutation: gql `
256
- mutation updateUser($email: String!, $patch: UserPatch!) {
257
- updateUser(email: $email, patch: $patch) {
258
- id
259
- name
260
- email
261
- userType
262
- status
263
- owner
264
- }
268
+ mutation activateUser($userId: String!) {
269
+ activateUser(userId: $userId)
265
270
  }
266
271
  `,
267
- variables: { email: user.email, patch: { status: 'activated' } },
272
+ variables: { userId: user.id },
273
+ context: gqlContext()
274
+ });
275
+ if (!response.errors) {
276
+ this.showToast(i18next.t('text.user activated successfully'));
277
+ this.dispatchUserUpdated();
278
+ }
279
+ }
280
+ async onInactivate(user) {
281
+ const response = await client.mutate({
282
+ mutation: gql `
283
+ mutation inactivateUser($userId: String!) {
284
+ inactivateUser(userId: $userId)
285
+ }
286
+ `,
287
+ variables: { userId: user.id },
268
288
  context: gqlContext()
269
289
  });
270
290
  if (!response.errors) {
@@ -439,33 +459,33 @@ __decorate([
439
459
  __metadata("design:type", Object)
440
460
  ], UserRoleEditor.prototype, "user", void 0);
441
461
  __decorate([
442
- property({ type: Array }),
462
+ property({ type: Boolean }),
463
+ __metadata("design:type", Boolean)
464
+ ], UserRoleEditor.prototype, "activate", void 0);
465
+ __decorate([
466
+ property({ type: Object }),
467
+ __metadata("design:type", Object)
468
+ ], UserRoleEditor.prototype, "domainOwner", void 0);
469
+ __decorate([
470
+ state(),
443
471
  __metadata("design:type", Array)
444
472
  ], UserRoleEditor.prototype, "domainRoles", void 0);
445
473
  __decorate([
446
- property({ type: Object }),
474
+ state(),
447
475
  __metadata("design:type", Object)
448
476
  ], UserRoleEditor.prototype, "grantedRoles", void 0);
449
477
  __decorate([
450
- property({ type: Array }),
478
+ state(),
451
479
  __metadata("design:type", Array)
452
480
  ], UserRoleEditor.prototype, "userRoles", void 0);
453
481
  __decorate([
454
- property({ type: Boolean }),
482
+ state(),
455
483
  __metadata("design:type", Boolean)
456
484
  ], UserRoleEditor.prototype, "isSuperOwner", void 0);
457
485
  __decorate([
458
- property({ type: Boolean }),
486
+ state(),
459
487
  __metadata("design:type", Boolean)
460
488
  ], UserRoleEditor.prototype, "isDomainOwner", void 0);
461
- __decorate([
462
- property({ type: Boolean }),
463
- __metadata("design:type", Boolean)
464
- ], UserRoleEditor.prototype, "activate", void 0);
465
- __decorate([
466
- property({ type: Object }),
467
- __metadata("design:type", Object)
468
- ], UserRoleEditor.prototype, "domainOwner", void 0);
469
489
  UserRoleEditor = __decorate([
470
490
  customElement('user-role-editor')
471
491
  ], UserRoleEditor);