@things-factory/auth-ui 10.1.16 → 10.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/components/app-binding-detail.d.ts +46 -0
- package/dist-client/components/app-binding-detail.js +384 -0
- package/dist-client/components/app-binding-detail.js.map +1 -0
- package/dist-client/components/appliance-editor.d.ts +37 -0
- package/dist-client/components/appliance-editor.js +489 -0
- package/dist-client/components/appliance-editor.js.map +1 -0
- package/dist-client/components/application-editor.d.ts +31 -0
- package/dist-client/components/application-editor.js +491 -0
- package/dist-client/components/application-editor.js.map +1 -0
- package/dist-client/components/profile-component.js +28 -11
- package/dist-client/components/profile-component.js.map +1 -1
- package/dist-client/components/secret-field.d.ts +35 -0
- package/dist-client/components/secret-field.js +149 -0
- package/dist-client/components/secret-field.js.map +1 -0
- package/dist-client/constants/application-type-parity.test.js +62 -0
- package/dist-client/constants/application-type-parity.test.js.map +1 -0
- package/dist-client/constants/application.d.ts +17 -7
- package/dist-client/constants/application.js +18 -8
- package/dist-client/constants/application.js.map +1 -1
- package/dist-client/pages/app-binding/app-binding-list-query.test.js +46 -0
- package/dist-client/pages/app-binding/app-binding-list-query.test.js.map +1 -0
- package/dist-client/pages/app-binding/app-bindings.d.ts +65 -2
- package/dist-client/pages/app-binding/app-bindings.js +217 -117
- package/dist-client/pages/app-binding/app-bindings.js.map +1 -1
- package/dist-client/pages/appliance/appliance-list-query.test.d.ts +1 -0
- package/dist-client/pages/appliance/appliance-list-query.test.js +58 -0
- package/dist-client/pages/appliance/appliance-list-query.test.js.map +1 -0
- package/dist-client/pages/appliance/home.d.ts +63 -2
- package/dist-client/pages/appliance/home.js +219 -123
- package/dist-client/pages/appliance/home.js.map +1 -1
- package/dist-client/pages/application/applications.d.ts +63 -2
- package/dist-client/pages/application/applications.js +212 -129
- package/dist-client/pages/application/applications.js.map +1 -1
- package/dist-client/pages/auth-provider/auth-provider-management.d.ts +4 -2
- package/dist-client/pages/auth-provider/auth-provider-management.js +35 -6
- package/dist-client/pages/auth-provider/auth-provider-management.js.map +1 -1
- package/dist-client/pages/domain-owner/domain-owner-management.d.ts +2 -0
- package/dist-client/pages/domain-owner/domain-owner-management.js +34 -7
- package/dist-client/pages/domain-owner/domain-owner-management.js.map +1 -1
- package/dist-client/pages/secrets-are-not-printed.test.d.ts +1 -0
- package/dist-client/pages/secrets-are-not-printed.test.js +88 -0
- package/dist-client/pages/secrets-are-not-printed.test.js.map +1 -0
- package/dist-client/route.js +0 -15
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/application-status.d.ts +32 -0
- package/dist-client/utils/application-status.js +45 -0
- package/dist-client/utils/application-status.js.map +1 -0
- package/dist-client/utils/application-status.test.d.ts +1 -0
- package/dist-client/utils/application-status.test.js +45 -0
- package/dist-client/utils/application-status.test.js.map +1 -0
- package/dist-client/utils/form-values.d.ts +71 -0
- package/dist-client/utils/form-values.js +102 -0
- package/dist-client/utils/form-values.js.map +1 -0
- package/dist-client/utils/form-values.test.d.ts +1 -0
- package/dist-client/utils/form-values.test.js +120 -0
- package/dist-client/utils/form-values.test.js.map +1 -0
- package/dist-client/utils/list-result.d.ts +62 -0
- package/dist-client/utils/list-result.js +92 -0
- package/dist-client/utils/list-result.js.map +1 -0
- package/dist-client/utils/list-result.test.d.ts +1 -0
- package/dist-client/utils/list-result.test.js +160 -0
- package/dist-client/utils/list-result.test.js.map +1 -0
- package/dist-client/utils/secret-display.d.ts +51 -0
- package/dist-client/utils/secret-display.js +61 -0
- package/dist-client/utils/secret-display.js.map +1 -0
- package/dist-client/utils/secret-display.test.d.ts +1 -0
- package/dist-client/utils/secret-display.test.js +59 -0
- package/dist-client/utils/secret-display.test.js.map +1 -0
- package/dist-client/utils/webauthn-verification.d.ts +56 -0
- package/dist-client/utils/webauthn-verification.js +79 -0
- package/dist-client/utils/webauthn-verification.js.map +1 -0
- package/dist-client/utils/webauthn-verification.test.d.ts +1 -0
- package/dist-client/utils/webauthn-verification.test.js +79 -0
- package/dist-client/utils/webauthn-verification.test.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/things-factory.config.js +0 -5
- package/translations/en.json +56 -0
- package/translations/ja.json +57 -0
- package/translations/ko.json +56 -0
- package/translations/ms.json +57 -0
- package/translations/zh.json +57 -0
- package/dist-client/pages/app-binding/app-binding.d.ts +0 -1
- package/dist-client/pages/app-binding/app-binding.js +0 -371
- package/dist-client/pages/app-binding/app-binding.js.map +0 -1
- package/dist-client/pages/appliance/appliance.d.ts +0 -1
- package/dist-client/pages/appliance/appliance.js +0 -392
- package/dist-client/pages/appliance/appliance.js.map +0 -1
- package/dist-client/pages/appliance/register.js +0 -166
- package/dist-client/pages/appliance/register.js.map +0 -1
- package/dist-client/pages/application/application.d.ts +0 -1
- package/dist-client/pages/application/application.js +0 -377
- package/dist-client/pages/application/application.js.map +0 -1
- package/dist-client/pages/application/register.js +0 -192
- package/dist-client/pages/application/register.js.map +0 -1
- /package/dist-client/{pages/appliance/register.d.ts → constants/application-type-parity.test.d.ts} +0 -0
- /package/dist-client/pages/{application/register.d.ts → app-binding/app-binding-list-query.test.d.ts} +0 -0
|
@@ -1,154 +1,250 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import '@material/web/
|
|
3
|
-
import '@
|
|
2
|
+
import '@material/web/icon/icon.js';
|
|
3
|
+
import '@operato/data-grist/ox-grist.js';
|
|
4
|
+
import '@operato/context/ox-context-page-toolbar.js';
|
|
4
5
|
import gql from 'graphql-tag';
|
|
5
6
|
import { css, html } from 'lit';
|
|
6
|
-
import { customElement, property } from 'lit/decorators.js';
|
|
7
|
-
import { client } from '@operato/graphql';
|
|
8
|
-
import {
|
|
9
|
-
|
|
7
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
8
|
+
import { client, gqlContext } from '@operato/graphql';
|
|
9
|
+
import { i18next, localize } from '@operato/i18n';
|
|
10
|
+
import { openPopup } from '@operato/layout';
|
|
11
|
+
import { PageView } from '@operato/shell';
|
|
12
|
+
import { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles';
|
|
13
|
+
import { isMobileDevice } from '@operato/utils';
|
|
14
|
+
import { p13n } from '@operato/p13n';
|
|
15
|
+
import '../../components/appliance-editor.js';
|
|
16
|
+
import { listOutcome, pageFromResponse } from '../../utils/list-result.js';
|
|
17
|
+
/**
|
|
18
|
+
* Registered appliances.
|
|
19
|
+
*
|
|
20
|
+
* ── What this screen looked like before ──────────────────────────────────────
|
|
21
|
+
* A hand-written table with no paging, sorting or search, and three columns that were not
|
|
22
|
+
* data: "API health" printed OK, "Installs" printed 1, "status" printed draft, identical on
|
|
23
|
+
* every row. An appliance that had never checked in read exactly like one reporting fine.
|
|
24
|
+
* Those are gone — Appliance declares none of the three — and the columns here are the
|
|
25
|
+
* fields it does declare.
|
|
26
|
+
*
|
|
27
|
+
* ── ⚠ The access token is not asked for, and a test holds that ──────────────
|
|
28
|
+
* `Appliance.accessToken` carries its own
|
|
29
|
+
* `@privilege(category: "security", privilege: "query", domainOwnerGranted: true)`. A list
|
|
30
|
+
* is the wrong place for it regardless of who may read it: a token in a grid cell is a token
|
|
31
|
+
* in plain text beside a name, visible to everyone who can open the screen and to anyone
|
|
32
|
+
* looking over their shoulder. The screens that genuinely need it ask one record at a time.
|
|
33
|
+
*
|
|
34
|
+
* `appliance-list-query.test.ts` fails if the word reappears here.
|
|
35
|
+
*/
|
|
36
|
+
let Appliances = class Appliances extends p13n(localize(i18next)(PageView)) {
|
|
10
37
|
constructor() {
|
|
11
38
|
super(...arguments);
|
|
12
|
-
this.
|
|
39
|
+
this.active = false;
|
|
40
|
+
this.mode = isMobileDevice() ? 'CARD' : 'GRID';
|
|
41
|
+
/** The last fetch did not answer. Distinct from answering with nothing. */
|
|
42
|
+
this.failed = false;
|
|
13
43
|
}
|
|
14
44
|
static { this.styles = [
|
|
45
|
+
CommonGristStyles,
|
|
46
|
+
CommonHeaderStyles,
|
|
47
|
+
ScrollbarStyles,
|
|
15
48
|
css `
|
|
16
|
-
:host {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
overflow:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
color: var(--title-text-color);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
[page-description] { margin: var(--page-description-margin);
|
|
36
|
-
font: var(--page-description-font);
|
|
37
|
-
color: var(--page-description-color);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
table { width: 100%;
|
|
41
|
-
margin: var(--spacing-large) 0;
|
|
42
|
-
border-collapse: collapse;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
tr { background-color: var(--tr-background-color);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
tr:nth-child(odd) { background-color: var(--tr-background-odd-color);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
tr:hover { background-color: var(--tr-background-hover-color);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
th { border-top: var(--th-border-top);
|
|
55
|
-
border-bottom: var(--td-border-bottom);
|
|
56
|
-
padding: var(--th-padding);
|
|
57
|
-
|
|
58
|
-
font: var(--th-font);
|
|
59
|
-
color: var(--th-color);
|
|
60
|
-
text-transform: var(--th-text-transform);
|
|
61
|
-
text-align: left;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
td { padding: var(--td-padding);
|
|
65
|
-
border-bottom: var(--td-border-bottom);
|
|
66
|
-
font: var(--td-font);
|
|
67
|
-
color: var(--td-color);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
td a { color: var(--md-sys-color-primary);
|
|
71
|
-
font: bold 16px var(--theme-font);
|
|
72
|
-
|
|
73
|
-
display: block;
|
|
74
|
-
text-decoration: none;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.text-align-center { text-align: center;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.text-align-right { text-align: right;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@media screen and (max-width: 480px) { :host { padding: var(--spacing-medium);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
49
|
+
:host {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
ox-grist {
|
|
56
|
+
overflow-y: auto;
|
|
57
|
+
flex: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[failed] {
|
|
61
|
+
padding: var(--spacing-medium);
|
|
62
|
+
color: var(--md-sys-color-error);
|
|
63
|
+
font: var(--label-font, inherit);
|
|
64
|
+
}
|
|
86
65
|
`
|
|
87
66
|
]; }
|
|
88
67
|
get context() {
|
|
89
|
-
return {
|
|
90
|
-
|
|
68
|
+
return {
|
|
69
|
+
title: i18next.t('text.appliances'),
|
|
70
|
+
help: 'auth/appliance',
|
|
71
|
+
search: {
|
|
72
|
+
handler: (search) => {
|
|
73
|
+
this.grist.searchText = search;
|
|
74
|
+
},
|
|
75
|
+
value: this.grist?.searchText || ''
|
|
76
|
+
},
|
|
77
|
+
actions: [
|
|
78
|
+
{
|
|
79
|
+
title: i18next.t('button.register'),
|
|
80
|
+
action: () => this.openEditor(),
|
|
81
|
+
icon: 'add'
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
toolbar: false
|
|
91
85
|
};
|
|
92
86
|
}
|
|
93
87
|
render() {
|
|
94
|
-
var appliances = this.appliances || [];
|
|
95
88
|
return html `
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<th>API health</th>
|
|
109
|
-
<th>Installs</th>
|
|
110
|
-
<th>status</th>
|
|
111
|
-
</tr>
|
|
112
|
-
${appliances.map(appliance => html `
|
|
113
|
-
<tr>
|
|
114
|
-
<td>
|
|
115
|
-
<a href=${`appliance/${appliance.id}`}>${appliance.name}</a>
|
|
116
|
-
${appliance.description}
|
|
117
|
-
</td>
|
|
118
|
-
<td>OK</td>
|
|
119
|
-
<td class="text-align-center">1</td>
|
|
120
|
-
<td>draft</td>
|
|
121
|
-
</tr>
|
|
122
|
-
`)}
|
|
123
|
-
</table>
|
|
89
|
+
<ox-grist
|
|
90
|
+
.mode=${this.mode}
|
|
91
|
+
.config=${this.config}
|
|
92
|
+
.fetchHandler=${this.fetchHandler.bind(this)}
|
|
93
|
+
.personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')}
|
|
94
|
+
>
|
|
95
|
+
<div slot="headroom" class="header">
|
|
96
|
+
<ox-context-page-toolbar class="actions" .context=${this.context}></ox-context-page-toolbar>
|
|
97
|
+
</div>
|
|
98
|
+
</ox-grist>
|
|
99
|
+
|
|
100
|
+
${this.failed ? html `<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}
|
|
124
101
|
`;
|
|
125
102
|
}
|
|
126
|
-
async
|
|
103
|
+
async pageInitialized() {
|
|
104
|
+
this.config = {
|
|
105
|
+
rows: { appendable: false, selectable: { multiple: false } },
|
|
106
|
+
columns: [
|
|
107
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
108
|
+
{
|
|
109
|
+
type: 'gutter',
|
|
110
|
+
gutterName: 'button',
|
|
111
|
+
icon: 'chevron_right',
|
|
112
|
+
title: i18next.t('button.detail'),
|
|
113
|
+
handlers: {
|
|
114
|
+
click: (_columns, _data, _column, record) => {
|
|
115
|
+
if (record?.id) {
|
|
116
|
+
this.openEditor(record.id);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: 'string',
|
|
123
|
+
name: 'name',
|
|
124
|
+
header: i18next.t('field.name'),
|
|
125
|
+
record: { editable: false },
|
|
126
|
+
sortable: true,
|
|
127
|
+
width: 180
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: 'string',
|
|
131
|
+
name: 'serialNo',
|
|
132
|
+
header: i18next.t('field.serial-no'),
|
|
133
|
+
record: { editable: false },
|
|
134
|
+
sortable: true,
|
|
135
|
+
width: 160
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'string',
|
|
139
|
+
name: 'brand',
|
|
140
|
+
header: i18next.t('field.brand'),
|
|
141
|
+
record: { editable: false },
|
|
142
|
+
sortable: true,
|
|
143
|
+
width: 140
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'string',
|
|
147
|
+
name: 'model',
|
|
148
|
+
header: i18next.t('field.model'),
|
|
149
|
+
record: { editable: false },
|
|
150
|
+
sortable: true,
|
|
151
|
+
width: 140
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'string',
|
|
155
|
+
name: 'netmask',
|
|
156
|
+
header: i18next.t('field.netmask'),
|
|
157
|
+
record: { editable: false },
|
|
158
|
+
width: 160
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'string',
|
|
162
|
+
name: 'description',
|
|
163
|
+
header: i18next.t('field.description'),
|
|
164
|
+
record: { editable: false },
|
|
165
|
+
width: 240
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: 'datetime',
|
|
169
|
+
name: 'updatedAt',
|
|
170
|
+
header: i18next.t('field.updated at'),
|
|
171
|
+
sortable: true,
|
|
172
|
+
width: 180
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/*
|
|
178
|
+
* Registering and editing both happen here, over the list, the way every other resource in
|
|
179
|
+
* this package works. `appliance-register` and `appliance/{id}` were routes; nothing outside
|
|
180
|
+
* auth-ui linked to either.
|
|
181
|
+
*/
|
|
182
|
+
openEditor(applianceId) {
|
|
183
|
+
const popup = openPopup(html `<appliance-editor
|
|
184
|
+
.applianceId=${applianceId}
|
|
185
|
+
@appliance-changed=${() => this.grist.fetch()}
|
|
186
|
+
@close=${() => popup.close()}
|
|
187
|
+
></appliance-editor>`, {
|
|
188
|
+
backdrop: true,
|
|
189
|
+
size: 'medium',
|
|
190
|
+
title: applianceId ? i18next.t('text.appliance') : i18next.t('text.register new appliance')
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
async pageUpdated(_changes, _lifecycle) {
|
|
127
194
|
if (this.active) {
|
|
128
|
-
|
|
195
|
+
await this.updateComplete;
|
|
196
|
+
this.grist.fetch();
|
|
129
197
|
}
|
|
130
198
|
}
|
|
131
|
-
async
|
|
132
|
-
const response = await client.query({
|
|
133
|
-
|
|
199
|
+
async fetchHandler({ page, limit, sortings = [], filters = [] }) {
|
|
200
|
+
const response = await client.query({
|
|
201
|
+
query: gql `
|
|
202
|
+
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
203
|
+
appliances(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
204
|
+
items {
|
|
205
|
+
id
|
|
134
206
|
name
|
|
207
|
+
serialNo
|
|
208
|
+
brand
|
|
209
|
+
model
|
|
210
|
+
netmask
|
|
135
211
|
description
|
|
136
|
-
|
|
212
|
+
updatedAt
|
|
213
|
+
}
|
|
137
214
|
total
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
`
|
|
141
|
-
});
|
|
142
|
-
if (!response.errors) {
|
|
143
|
-
return response.data.appliances;
|
|
215
|
+
}
|
|
144
216
|
}
|
|
217
|
+
`,
|
|
218
|
+
variables: { filters, pagination: { page, limit }, sortings },
|
|
219
|
+
context: gqlContext()
|
|
220
|
+
});
|
|
221
|
+
const { items, total, failed } = listOutcome(pageFromResponse(response, 'appliances'));
|
|
222
|
+
this.failed = failed;
|
|
223
|
+
return { total, records: items };
|
|
145
224
|
}
|
|
146
225
|
};
|
|
147
226
|
__decorate([
|
|
148
|
-
property({ type:
|
|
149
|
-
__metadata("design:type",
|
|
150
|
-
], Appliances.prototype, "
|
|
227
|
+
property({ type: Boolean }),
|
|
228
|
+
__metadata("design:type", Boolean)
|
|
229
|
+
], Appliances.prototype, "active", void 0);
|
|
230
|
+
__decorate([
|
|
231
|
+
property({ type: Object }),
|
|
232
|
+
__metadata("design:type", Object)
|
|
233
|
+
], Appliances.prototype, "config", void 0);
|
|
234
|
+
__decorate([
|
|
235
|
+
property({ type: String }),
|
|
236
|
+
__metadata("design:type", String)
|
|
237
|
+
], Appliances.prototype, "mode", void 0);
|
|
238
|
+
__decorate([
|
|
239
|
+
property({ type: Boolean }),
|
|
240
|
+
__metadata("design:type", Boolean)
|
|
241
|
+
], Appliances.prototype, "failed", void 0);
|
|
242
|
+
__decorate([
|
|
243
|
+
query('ox-grist'),
|
|
244
|
+
__metadata("design:type", Function)
|
|
245
|
+
], Appliances.prototype, "grist", void 0);
|
|
151
246
|
Appliances = __decorate([
|
|
152
247
|
customElement('appliance-home')
|
|
153
248
|
], Appliances);
|
|
249
|
+
export { Appliances };
|
|
154
250
|
//# sourceMappingURL=home.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home.js","sourceRoot":"","sources":["../../../client/pages/appliance/home.ts"],"names":[],"mappings":";AAAA,OAAO,yCAAyC,CAAA;AAChD,OAAO,yCAAyC,CAAA;AAEhD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGnD,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,QAAQ;IAAjC;;QA2E6B,eAAU,GAAU,EAAE,CAAA;IA6DnD,CAAC;aAxI4C,WAAM,GAAG;QAClD,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuEF;KACF,AAzEgD,CAyEhD;IAID,IAAI,OAAO;QAAS,OAAO,EAAQ,KAAK,EAAE,gBAAgB;YACtD,IAAI,EAAE,gBAAgB;SAC1B,CAAA;IACD,CAAC;IAEA,MAAM;QAAS,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAA;QAEnD,OAAO,IAAI,CAAA;;;;;;;qCAOsB,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;;;;;;;;;;UAU9D,UAAU,CAAC,GAAG,CACd,SAAS,CAAC,EAAE,CAAC,IAAI,CAAA;;;0BAGD,aAAa,SAAS,CAAC,EAAE,EAAE,IAAI,SAAS,CAAC,IAAI;kBACrD,SAAS,CAAC,WAAW;;;;;;WAM5B,CACF;;KAEJ,CAAA;IACJ,CAAC;IAEA,KAAK,CAAC,WAAW;QAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAAO,IAAI,CAAC,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,KAAK,CAAA;QAC1G,CAAC;IACD,CAAC;IAEA,KAAK,CAAC,eAAe;QAAS,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAQ,KAAK,EAAE,GAAG,CAAA;;;;;;;;OAQ/E;SACL,CAAC,CAAA;QAEC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAAO,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAA;QAChE,CAAC;IACD,CAAC;;AA5D2B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;8CAAuB;AA3E7C,UAAU;IADf,aAAa,CAAC,gBAAgB,CAAC;GAC1B,UAAU,CAwIf","sourcesContent":["import '@material/web/button/elevated-button.js'\nimport '@material/web/button/outlined-button.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { navigate, PageView } from '@operato/shell'\n\n@customElement('appliance-home')\nclass Appliances extends PageView { static styles = [\n css`\n :host { background-color: var(--md-sys-color-background);\n padding: var(--spacing-large);\n\n overflow: auto;\n }\n\n md-elevated-button { text-transform: capitalize;\n }\n\n md-outlined-button { float: right;\n margin-top: var(--spacing-medium);\n text-transform: capitalize;\n }\n\n h2 { margin: var(--title-margin);\n font: var(--title-font);\n color: var(--title-text-color);\n }\n\n [page-description] { margin: var(--page-description-margin);\n font: var(--page-description-font);\n color: var(--page-description-color);\n }\n\n table { width: 100%;\n margin: var(--spacing-large) 0;\n border-collapse: collapse;\n }\n\n tr { background-color: var(--tr-background-color);\n }\n\n tr:nth-child(odd) { background-color: var(--tr-background-odd-color);\n }\n\n tr:hover { background-color: var(--tr-background-hover-color);\n }\n\n th { border-top: var(--th-border-top);\n border-bottom: var(--td-border-bottom);\n padding: var(--th-padding);\n\n font: var(--th-font);\n color: var(--th-color);\n text-transform: var(--th-text-transform);\n text-align: left;\n }\n\n td { padding: var(--td-padding);\n border-bottom: var(--td-border-bottom);\n font: var(--td-font);\n color: var(--td-color);\n }\n\n td a { color: var(--md-sys-color-primary);\n font: bold 16px var(--theme-font);\n\n display: block;\n text-decoration: none;\n }\n\n .text-align-center { text-align: center;\n }\n\n .text-align-right { text-align: right;\n }\n\n @media screen and (max-width: 480px) { :host { padding: var(--spacing-medium);\n }\n }\n `\n ]\n\n @property({ type: Array }) appliances: any[] = []\n\n get context() { return { title: `appliance home`,\n help: 'auth/appliance'\n }\n }\n\n render() { var appliances = this.appliances || []\n\n return html`\n <div>\n <h2>Registered Appliances</h2>\n <p page-description>\n What type of appliance are you building?<br />Choose the app type that best suits the audience you’re building\n for. The appliance type can’t be changed after it’s created.\n </p>\n <md-elevated-button @click=${e => navigate('appliance-register')}>register new appliance</md-elevated-button>\n </div>\n\n <table>\n <tr>\n <th>appliance name</th>\n <th>API health</th>\n <th>Installs</th>\n <th>status</th>\n </tr>\n ${appliances.map(\n appliance => html`\n <tr>\n <td>\n <a href=${`appliance/${appliance.id}`}>${appliance.name}</a>\n ${appliance.description}\n </td>\n <td>OK</td>\n <td class=\"text-align-center\">1</td>\n <td>draft</td>\n </tr>\n `\n )}\n </table>\n `\n }\n\n async pageUpdated() { if (this.active) { this.appliances = (await this.fetchAppliances()).items\n }\n }\n\n async fetchAppliances() { const response = await client.query({ query: gql`\n query { appliances { items { id\n name\n description\n }\n total\n }\n }\n `\n })\n\n if (!response.errors) { return response.data.appliances\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"home.js","sourceRoot":"","sources":["../../../client/pages/appliance/home.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport '@operato/data-grist/ox-grist.js'\nimport '@operato/context/ox-context-page-toolbar.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport type { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client, gqlContext } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\nimport { p13n } from '@operato/p13n'\n\nimport '../../components/appliance-editor.js'\nimport { listOutcome, pageFromResponse } from '../../utils/list-result.js'\n\n/**\n * Registered appliances.\n *\n * ── What this screen looked like before ──────────────────────────────────────\n * A hand-written table with no paging, sorting or search, and three columns that were not\n * data: \"API health\" printed OK, \"Installs\" printed 1, \"status\" printed draft, identical on\n * every row. An appliance that had never checked in read exactly like one reporting fine.\n * Those are gone — Appliance declares none of the three — and the columns here are the\n * fields it does declare.\n *\n * ── ⚠ The access token is not asked for, and a test holds that ──────────────\n * `Appliance.accessToken` carries its own\n * `@privilege(category: \"security\", privilege: \"query\", domainOwnerGranted: true)`. A list\n * is the wrong place for it regardless of who may read it: a token in a grid cell is a token\n * in plain text beside a name, visible to everyone who can open the screen and to anyone\n * looking over their shoulder. The screens that genuinely need it ask one record at a time.\n *\n * `appliance-list-query.test.ts` fails if the word reappears here.\n */\n@customElement('appliance-home')\nexport class Appliances extends p13n(localize(i18next)(PageView)) {\n static styles = [\n CommonGristStyles,\n CommonHeaderStyles,\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n ox-grist {\n overflow-y: auto;\n flex: 1;\n }\n\n [failed] {\n padding: var(--spacing-medium);\n color: var(--md-sys-color-error);\n font: var(--label-font, inherit);\n }\n `\n ]\n\n @property({ type: Boolean }) active: boolean = false\n @property({ type: Object }) config: any\n @property({ type: String }) mode: 'CARD' | 'LIST' | 'GRID' = isMobileDevice() ? 'CARD' : 'GRID'\n\n /** The last fetch did not answer. Distinct from answering with nothing. */\n @property({ type: Boolean }) failed: boolean = false\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n title: i18next.t('text.appliances'),\n help: 'auth/appliance',\n search: {\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n actions: [\n {\n title: i18next.t('button.register'),\n action: () => this.openEditor(),\n icon: 'add'\n }\n ],\n toolbar: false\n }\n }\n\n render() {\n return html`\n <ox-grist\n .mode=${this.mode}\n .config=${this.config}\n .fetchHandler=${this.fetchHandler.bind(this)}\n .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')!}\n >\n <div slot=\"headroom\" class=\"header\">\n <ox-context-page-toolbar class=\"actions\" .context=${this.context}></ox-context-page-toolbar>\n </div>\n </ox-grist>\n\n ${this.failed ? html`<div failed>${i18next.t('text.the list could not be loaded')}</div>` : ''}\n `\n }\n\n async pageInitialized() {\n this.config = {\n rows: { appendable: false, selectable: { multiple: false } },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n {\n type: 'gutter',\n gutterName: 'button',\n icon: 'chevron_right',\n title: i18next.t('button.detail'),\n handlers: {\n click: (_columns: any, _data: any, _column: any, record: any) => {\n if (record?.id) {\n this.openEditor(record.id)\n }\n }\n }\n },\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: { editable: false },\n sortable: true,\n width: 180\n },\n {\n type: 'string',\n name: 'serialNo',\n header: i18next.t('field.serial-no'),\n record: { editable: false },\n sortable: true,\n width: 160\n },\n {\n type: 'string',\n name: 'brand',\n header: i18next.t('field.brand'),\n record: { editable: false },\n sortable: true,\n width: 140\n },\n {\n type: 'string',\n name: 'model',\n header: i18next.t('field.model'),\n record: { editable: false },\n sortable: true,\n width: 140\n },\n {\n type: 'string',\n name: 'netmask',\n header: i18next.t('field.netmask'),\n record: { editable: false },\n width: 160\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: false },\n width: 240\n },\n {\n type: 'datetime',\n name: 'updatedAt',\n header: i18next.t('field.updated at'),\n sortable: true,\n width: 180\n }\n ]\n }\n }\n\n /*\n * Registering and editing both happen here, over the list, the way every other resource in\n * this package works. `appliance-register` and `appliance/{id}` were routes; nothing outside\n * auth-ui linked to either.\n */\n private openEditor(applianceId?: string) {\n const popup = openPopup(\n html`<appliance-editor\n .applianceId=${applianceId}\n @appliance-changed=${() => this.grist.fetch()}\n @close=${() => popup.close()}\n ></appliance-editor>`,\n {\n backdrop: true,\n size: 'medium',\n title: applianceId ? i18next.t('text.appliance') : i18next.t('text.register new appliance')\n }\n )\n }\n\n async pageUpdated(_changes: any, _lifecycle: any) {\n if (this.active) {\n await this.updateComplete\n this.grist.fetch()\n }\n }\n\n async fetchHandler({ page, limit, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n appliances(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n serialNo\n brand\n model\n netmask\n description\n updatedAt\n }\n total\n }\n }\n `,\n variables: { filters, pagination: { page, limit }, sortings },\n context: gqlContext()\n })\n\n const { items, total, failed } = listOutcome(pageFromResponse(response, 'appliances'))\n\n this.failed = failed\n\n return { total, records: items }\n }\n}\n"]}
|
|
@@ -1,2 +1,63 @@
|
|
|
1
|
-
import '@material/web/
|
|
2
|
-
import '@
|
|
1
|
+
import '@material/web/icon/icon.js';
|
|
2
|
+
import '@operato/data-grist/ox-grist.js';
|
|
3
|
+
import '@operato/context/ox-context-page-toolbar.js';
|
|
4
|
+
import type { FetchOption } from '@operato/data-grist';
|
|
5
|
+
import { PageView } from '@operato/shell';
|
|
6
|
+
import '../../components/application-editor.js';
|
|
7
|
+
declare const Applications_base: (new (...args: any[]) => {
|
|
8
|
+
__preferenceProviders: {
|
|
9
|
+
[element: string]: import("@operato/p13n").PagePreferenceProvider;
|
|
10
|
+
};
|
|
11
|
+
getPagePreferenceProvider(element: string): import("@operato/p13n").PagePreferenceProvider | undefined;
|
|
12
|
+
}) & (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
|
|
13
|
+
/**
|
|
14
|
+
* Registered applications.
|
|
15
|
+
*
|
|
16
|
+
* ── What this screen looked like before ──────────────────────────────────────
|
|
17
|
+
* A hand-written `<table>` with no paging, no sort and no search, and three columns that
|
|
18
|
+
* were not data at all: "API health" printed OK, "Installs" printed 1, "status" printed
|
|
19
|
+
* draft — written into the markup, identical on every row. The previous commit removed the
|
|
20
|
+
* two the server cannot answer and made status real. This one gives the list the same shape
|
|
21
|
+
* as every other list in the product.
|
|
22
|
+
*
|
|
23
|
+
* The server was already ready for it: `applications` takes ListParam and declares
|
|
24
|
+
* `searchables: ['name', 'description']`, so paging, sorting and the header's search box all
|
|
25
|
+
* work by passing the grist's own options through.
|
|
26
|
+
*
|
|
27
|
+
* ── Why the row does not carry health or install counts ──────────────────────
|
|
28
|
+
* Because Application does not declare them. If they arrive one day, they are columns; until
|
|
29
|
+
* then the screen says what it knows. See `utils/application-status.ts` for the matching rule
|
|
30
|
+
* on values the screen has no word for.
|
|
31
|
+
*/
|
|
32
|
+
export declare class Applications extends Applications_base {
|
|
33
|
+
static styles: import("lit").CSSResult[];
|
|
34
|
+
active: boolean;
|
|
35
|
+
config: any;
|
|
36
|
+
mode: 'CARD' | 'LIST' | 'GRID';
|
|
37
|
+
/** The last fetch did not answer. Distinct from answering with nothing. */
|
|
38
|
+
failed: boolean;
|
|
39
|
+
private grist;
|
|
40
|
+
get context(): {
|
|
41
|
+
title: string;
|
|
42
|
+
help: string;
|
|
43
|
+
search: {
|
|
44
|
+
handler: (search: string) => void;
|
|
45
|
+
value: string;
|
|
46
|
+
};
|
|
47
|
+
actions: {
|
|
48
|
+
title: string;
|
|
49
|
+
action: () => void;
|
|
50
|
+
icon: string;
|
|
51
|
+
}[];
|
|
52
|
+
toolbar: boolean;
|
|
53
|
+
};
|
|
54
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
55
|
+
pageInitialized(): Promise<void>;
|
|
56
|
+
private openEditor;
|
|
57
|
+
pageUpdated(_changes: any, _lifecycle: any): Promise<void>;
|
|
58
|
+
fetchHandler({ page, limit, sortings, filters }: FetchOption): Promise<{
|
|
59
|
+
total: number;
|
|
60
|
+
records: any[];
|
|
61
|
+
}>;
|
|
62
|
+
}
|
|
63
|
+
export {};
|