@api-client/ui 0.0.12 → 0.0.13

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 (141) hide show
  1. package/demo/elements/authorization/cc.ts +56 -27
  2. package/dist/bindings/base/FileBindings.d.ts +4 -0
  3. package/dist/bindings/base/FileBindings.d.ts.map +1 -1
  4. package/dist/bindings/base/FileBindings.js +21 -1
  5. package/dist/bindings/base/FileBindings.js.map +1 -1
  6. package/dist/bindings/base/StoreBindings.d.ts +1 -17
  7. package/dist/bindings/base/StoreBindings.d.ts.map +1 -1
  8. package/dist/bindings/base/StoreBindings.js +0 -59
  9. package/dist/bindings/base/StoreBindings.js.map +1 -1
  10. package/dist/bindings/web/WebFileBindings.js +1 -1
  11. package/dist/bindings/web/WebFileBindings.js.map +1 -1
  12. package/dist/define/http/certificate-add.d.ts +9 -0
  13. package/dist/define/http/certificate-add.d.ts.map +1 -0
  14. package/dist/define/http/certificate-add.js +10 -0
  15. package/dist/define/http/certificate-add.js.map +1 -0
  16. package/dist/define/ui/ui-segmented-button-set.d.ts +1 -1
  17. package/dist/define/ui/ui-segmented-button-set.d.ts.map +1 -1
  18. package/dist/define/ui/ui-segmented-button-set.js.map +1 -1
  19. package/dist/elements/authorization/ui/CC.styles.d.ts.map +1 -1
  20. package/dist/elements/authorization/ui/CC.styles.js +4 -9
  21. package/dist/elements/authorization/ui/CC.styles.js.map +1 -1
  22. package/dist/elements/authorization/ui/CcAuthorization.d.ts +14 -29
  23. package/dist/elements/authorization/ui/CcAuthorization.d.ts.map +1 -1
  24. package/dist/elements/authorization/ui/CcAuthorization.js +67 -158
  25. package/dist/elements/authorization/ui/CcAuthorization.js.map +1 -1
  26. package/dist/elements/http/CertificateAdd.element.d.ts +91 -0
  27. package/dist/elements/http/CertificateAdd.element.d.ts.map +1 -0
  28. package/dist/elements/http/CertificateAdd.element.js +389 -0
  29. package/dist/elements/http/CertificateAdd.element.js.map +1 -0
  30. package/dist/elements/http/CertificateAdd.styles.d.ts +3 -0
  31. package/dist/elements/http/CertificateAdd.styles.d.ts.map +1 -0
  32. package/dist/elements/http/CertificateAdd.styles.js +61 -0
  33. package/dist/elements/http/CertificateAdd.styles.js.map +1 -0
  34. package/dist/elements/project/ProjectRunReport.d.ts +2 -1
  35. package/dist/elements/project/ProjectRunReport.d.ts.map +1 -1
  36. package/dist/elements/project/ProjectRunReport.js.map +1 -1
  37. package/dist/elements/store/FilePicker.styles.d.ts.map +1 -1
  38. package/dist/elements/store/FilePicker.styles.js +1 -0
  39. package/dist/elements/store/FilePicker.styles.js.map +1 -1
  40. package/dist/events/EventTypes.d.ts +6 -7
  41. package/dist/events/EventTypes.d.ts.map +1 -1
  42. package/dist/events/EventTypes.js +7 -7
  43. package/dist/events/EventTypes.js.map +1 -1
  44. package/dist/events/Events.d.ts +6 -1
  45. package/dist/events/Events.d.ts.map +1 -1
  46. package/dist/events/Events.js +2 -0
  47. package/dist/events/Events.js.map +1 -1
  48. package/dist/events/FilesystemEvents.d.ts +8 -0
  49. package/dist/events/FilesystemEvents.d.ts.map +1 -0
  50. package/dist/events/FilesystemEvents.js +59 -0
  51. package/dist/events/FilesystemEvents.js.map +1 -0
  52. package/dist/events/HttpClientEvents.d.ts +0 -2
  53. package/dist/events/HttpClientEvents.d.ts.map +1 -1
  54. package/dist/events/HttpClientEvents.js +0 -2
  55. package/dist/events/HttpClientEvents.js.map +1 -1
  56. package/dist/http-client/idb/Arc18DataUpgrade.d.ts +0 -8
  57. package/dist/http-client/idb/Arc18DataUpgrade.d.ts.map +1 -1
  58. package/dist/http-client/idb/Arc18DataUpgrade.js +11 -206
  59. package/dist/http-client/idb/Arc18DataUpgrade.js.map +1 -1
  60. package/dist/http-client/store/StoreBroadcast.d.ts +0 -5
  61. package/dist/http-client/store/StoreBroadcast.d.ts.map +1 -1
  62. package/dist/http-client/store/StoreBroadcast.js +0 -7
  63. package/dist/http-client/store/StoreBroadcast.js.map +1 -1
  64. package/dist/lib/files/FileUtils.d.ts +9 -0
  65. package/dist/lib/files/FileUtils.d.ts.map +1 -0
  66. package/dist/lib/files/FileUtils.js +13 -0
  67. package/dist/lib/files/FileUtils.js.map +1 -0
  68. package/dist/mixins/RouteMixin.d.ts +4 -0
  69. package/dist/mixins/RouteMixin.d.ts.map +1 -1
  70. package/dist/mixins/RouteMixin.js +1 -0
  71. package/dist/mixins/RouteMixin.js.map +1 -1
  72. package/dist/pages/api-client/ApiClient.screen.d.ts +4 -0
  73. package/dist/pages/api-client/ApiClient.screen.d.ts.map +1 -1
  74. package/dist/pages/api-client/ApiClient.screen.js +23 -2
  75. package/dist/pages/api-client/ApiClient.screen.js.map +1 -1
  76. package/dist/pages/api-client/ApiClient.styles.d.ts.map +1 -1
  77. package/dist/pages/api-client/ApiClient.styles.js +0 -12
  78. package/dist/pages/api-client/ApiClient.styles.js.map +1 -1
  79. package/dist/pages/api-client/pages/Files.page.d.ts.map +1 -1
  80. package/dist/pages/api-client/pages/Files.page.js +13 -0
  81. package/dist/pages/api-client/pages/Files.page.js.map +1 -1
  82. package/dist/ui/button/SegmentedButtonsSet.d.ts +14 -0
  83. package/dist/ui/button/SegmentedButtonsSet.d.ts.map +1 -1
  84. package/dist/ui/button/SegmentedButtonsSet.js.map +1 -1
  85. package/dist/ui/notification/SnackNotifications.d.ts +1 -0
  86. package/dist/ui/notification/SnackNotifications.d.ts.map +1 -1
  87. package/dist/ui/notification/SnackNotifications.js +7 -0
  88. package/dist/ui/notification/SnackNotifications.js.map +1 -1
  89. package/package.json +1 -1
  90. package/src/bindings/base/FileBindings.ts +25 -1
  91. package/src/bindings/base/StoreBindings.ts +1 -73
  92. package/src/bindings/web/WebFileBindings.ts +1 -1
  93. package/src/define/http/certificate-add.ts +12 -0
  94. package/src/define/ui/ui-segmented-button-set.ts +1 -1
  95. package/src/elements/authorization/ui/CC.styles.ts +4 -9
  96. package/src/elements/authorization/ui/CcAuthorization.ts +67 -167
  97. package/src/elements/http/CertificateAdd.element.ts +443 -0
  98. package/src/elements/http/CertificateAdd.styles.ts +61 -0
  99. package/src/elements/project/ProjectRunReport.ts +2 -1
  100. package/src/elements/store/FilePicker.styles.ts +1 -0
  101. package/src/events/EventTypes.ts +7 -7
  102. package/src/events/Events.ts +2 -0
  103. package/src/events/FilesystemEvents.ts +63 -0
  104. package/src/events/HttpClientEvents.ts +0 -2
  105. package/src/http-client/idb/Arc18DataUpgrade.ts +84 -84
  106. package/src/http-client/store/StoreBroadcast.ts +0 -8
  107. package/src/lib/files/FileUtils.ts +12 -0
  108. package/src/mixins/RouteMixin.ts +8 -1
  109. package/src/pages/api-client/ApiClient.screen.ts +26 -2
  110. package/src/pages/api-client/ApiClient.styles.ts +0 -12
  111. package/src/pages/api-client/pages/Files.page.ts +11 -0
  112. package/src/ui/button/SegmentedButtonsSet.ts +16 -1
  113. package/src/ui/notification/SnackNotifications.ts +8 -0
  114. package/test/elements/http/BodyFormdataEditorElement.test.ts +458 -454
  115. package/test/elements/http/BodyMultipartEditorElement.test.ts +609 -605
  116. package/test/elements/http/BodyRawEditorElement.test.ts +60 -56
  117. package/test/elements/http/CertificateAdd.test.ts +430 -0
  118. package/test/events/EventTypes.test.ts +0 -22
  119. package/test/helpers/UiMock.ts +19 -2
  120. package/web-test-runner.config.mjs +4 -3
  121. package/dist/events/http-client/models/CertificatesEvents.d.ts +0 -12
  122. package/dist/events/http-client/models/CertificatesEvents.d.ts.map +0 -1
  123. package/dist/events/http-client/models/CertificatesEvents.js +0 -18
  124. package/dist/events/http-client/models/CertificatesEvents.js.map +0 -1
  125. package/dist/http-client/idb/AuthDataModel.d.ts +0 -60
  126. package/dist/http-client/idb/AuthDataModel.d.ts.map +0 -1
  127. package/dist/http-client/idb/AuthDataModel.js +0 -150
  128. package/dist/http-client/idb/AuthDataModel.js.map +0 -1
  129. package/dist/http-client/idb/HostsModel.d.ts +0 -25
  130. package/dist/http-client/idb/HostsModel.d.ts.map +0 -1
  131. package/dist/http-client/idb/HostsModel.js +0 -82
  132. package/dist/http-client/idb/HostsModel.js.map +0 -1
  133. package/dist/http-client/idb/LegacyMockedStore.d.ts +0 -214
  134. package/dist/http-client/idb/LegacyMockedStore.d.ts.map +0 -1
  135. package/dist/http-client/idb/LegacyMockedStore.js +0 -486
  136. package/dist/http-client/idb/LegacyMockedStore.js.map +0 -1
  137. package/src/events/http-client/models/CertificatesEvents.ts +0 -23
  138. package/src/http-client/idb/AuthDataModel.ts +0 -175
  139. package/src/http-client/idb/HostsModel.ts +0 -125
  140. package/src/http-client/idb/LegacyMockedStore.ts +0 -544
  141. package/test/apic-ui.test.ts +0 -31
@@ -1,14 +1,14 @@
1
1
  /* eslint-disable class-methods-use-this */
2
2
  import 'pouchdb/dist/pouchdb.js';
3
- import { get, set } from 'idb-keyval';
4
- import { IAuthorizationData, IHostRule, HostRuleKind, } from '@api-client/core/build/browser.js'; // Certificate, HttpProject
5
- import { ARCAuthData, HostRule as LegacyHostRule } from '@api-client/core/build/legacy.js'; // Normalizer, ARCProject, ARCSavedRequest, ARCCertificateIndex, ARCRequestCertificate,
3
+ import { get } from 'idb-keyval';
4
+ // import { IAuthorizationData, IHostRule, HostRuleKind, } from '@api-client/core/build/browser.js'; // Certificate, HttpProject
5
+ // import { ARCAuthData, HostRule as LegacyHostRule } from '@api-client/core/build/legacy.js'; // Normalizer, ARCProject, ARCSavedRequest, ARCCertificateIndex, ARCRequestCertificate,
6
6
  // import { LegacyBodyProcessor } from './LegacyBodyProcessor.js';
7
7
  // import { HistoryModel } from './HistoryModel.js';
8
8
  // import { ProjectModel } from './ProjectModel.js';
9
- import { AuthDataModel } from './AuthDataModel.js';
9
+ // import { AuthDataModel } from './AuthDataModel.js';
10
10
  // import { CertificateModel } from './CertificateModel.js';
11
- import { HostsModel } from './HostsModel.js';
11
+ // import { HostsModel } from './HostsModel.js';
12
12
 
13
13
  const upgradeKey = 'CHL5v3fUMx';
14
14
 
@@ -27,38 +27,38 @@ export default class Arc18DataUpgrade {
27
27
  }
28
28
 
29
29
  static async runIfNeeded(): Promise<void> {
30
- const needed = await Arc18DataUpgrade.needsUpgrade();
31
- if (!needed) {
32
- return undefined;
33
- }
34
- const instance = new Arc18DataUpgrade();
35
- return instance.run();
30
+ // const needed = await Arc18DataUpgrade.needsUpgrade();
31
+ // if (!needed) {
32
+ // return undefined;
33
+ // }
34
+ // const instance = new Arc18DataUpgrade();
35
+ // return instance.run();
36
36
  }
37
37
 
38
- /**
39
- * Sets a flag sealing the upgrade. Next call to the `run()` will result with no operation.
40
- */
41
- async seal(): Promise<void> {
42
- await set(upgradeKey, true);
43
- }
38
+ // /**
39
+ // * Sets a flag sealing the upgrade. Next call to the `run()` will result with no operation.
40
+ // */
41
+ // async seal(): Promise<void> {
42
+ // await set(upgradeKey, true);
43
+ // }
44
44
 
45
- async run(): Promise<void> {
46
- await this.upgradeHistory();
47
- // await this.upgradeProjects();
48
- // await this.upgradeSaved();
49
- await this.upgradeAuthData();
50
- // await this.upgradeCertificates();
51
- await this.hostRules();
45
+ // async run(): Promise<void> {
46
+ // await this.upgradeHistory();
47
+ // await this.upgradeProjects();
48
+ // await this.upgradeSaved();
49
+ // await this.upgradeAuthData();
50
+ // await this.upgradeCertificates();
51
+ // await this.hostRules();
52
52
 
53
- await this.seal();
54
- }
53
+ // await this.seal();
54
+ // }
55
55
 
56
- async upgradeHistory(): Promise<void> {
57
- const sourceDb = new PouchDB('history-requests');
58
- await sourceDb.compact();
59
- // const targetDb = new HistoryModel();
60
- // await this._upgradeHistoryPage(sourceDb, targetDb);
61
- }
56
+ // async upgradeHistory(): Promise<void> {
57
+ // const sourceDb = new PouchDB('history-requests');
58
+ // await sourceDb.compact();
59
+ // const targetDb = new HistoryModel();
60
+ // await this._upgradeHistoryPage(sourceDb, targetDb);
61
+ // }
62
62
 
63
63
  // async upgradeProjects(): Promise<void> {
64
64
  // const projectsDb = new PouchDB<ARCProject>('legacy-projects');
@@ -128,32 +128,32 @@ export default class Arc18DataUpgrade {
128
128
  // await targetDb.put(project.toJSON());
129
129
  // }
130
130
 
131
- async upgradeAuthData(): Promise<void> {
132
- const src = new PouchDB<ARCAuthData>('auth-data');
133
- const response = await src.allDocs({ include_docs: true });
134
- const items: IAuthorizationData[] = [];
135
- response.rows.forEach(item => {
136
- const { doc } = item;
137
- if (!doc) {
138
- return;
139
- }
140
- const transformed: IAuthorizationData = {
141
- key: doc._id,
142
- };
143
- if (doc.domain) {
144
- transformed.domain = doc.domain;
145
- }
146
- if (doc.password) {
147
- transformed.password = doc.password;
148
- }
149
- if (doc.password) {
150
- transformed.password = doc.password;
151
- }
152
- items.push(transformed);
153
- });
154
- const model = new AuthDataModel();
155
- await model.putBulk(items);
156
- }
131
+ // async upgradeAuthData(): Promise<void> {
132
+ // const src = new PouchDB<ARCAuthData>('auth-data');
133
+ // const response = await src.allDocs({ include_docs: true });
134
+ // const items: IAuthorizationData[] = [];
135
+ // response.rows.forEach(item => {
136
+ // const { doc } = item;
137
+ // if (!doc) {
138
+ // return;
139
+ // }
140
+ // const transformed: IAuthorizationData = {
141
+ // key: doc._id,
142
+ // };
143
+ // if (doc.domain) {
144
+ // transformed.domain = doc.domain;
145
+ // }
146
+ // if (doc.password) {
147
+ // transformed.password = doc.password;
148
+ // }
149
+ // if (doc.password) {
150
+ // transformed.password = doc.password;
151
+ // }
152
+ // items.push(transformed);
153
+ // });
154
+ // const model = new AuthDataModel();
155
+ // await model.putBulk(items);
156
+ // }
157
157
 
158
158
  // protected async _upgradeHistoryPage(sourceDb: PouchDB.Database, targetDb: HistoryModel, lastKey?: string): Promise<void> {
159
159
  // const opts: PouchDB.Core.AllDocsOptions | PouchDB.Core.AllDocsWithinRangeOptions = {
@@ -216,30 +216,30 @@ export default class Arc18DataUpgrade {
216
216
  // await model.putBulk(upgrades);
217
217
  // }
218
218
 
219
- async hostRules(): Promise<void> {
220
- const srcDb = new PouchDB<LegacyHostRule>('host-rules');
221
- const response = await srcDb.allDocs({ include_docs: true });
222
- const items: IHostRule[] = [];
223
- response.rows.forEach(item => {
224
- const { doc } = item;
225
- if (!doc) {
226
- return;
227
- }
228
- const transformed: IHostRule = {
229
- kind: HostRuleKind,
230
- from: doc.from,
231
- to: doc.to,
232
- key: doc._id,
233
- };
234
- if (doc.comment) {
235
- transformed.comment = doc.comment;
236
- }
237
- if (typeof doc.enabled === 'boolean') {
238
- transformed.enabled = doc.enabled;
239
- }
240
- items.push(transformed);
241
- });
242
- const model = new HostsModel();
243
- await model.putBulk(items);
244
- }
219
+ // async hostRules(): Promise<void> {
220
+ // const srcDb = new PouchDB<LegacyHostRule>('host-rules');
221
+ // const response = await srcDb.allDocs({ include_docs: true });
222
+ // const items: IHostRule[] = [];
223
+ // response.rows.forEach(item => {
224
+ // const { doc } = item;
225
+ // if (!doc) {
226
+ // return;
227
+ // }
228
+ // const transformed: IHostRule = {
229
+ // kind: HostRuleKind,
230
+ // from: doc.from,
231
+ // to: doc.to,
232
+ // key: doc._id,
233
+ // };
234
+ // if (doc.comment) {
235
+ // transformed.comment = doc.comment;
236
+ // }
237
+ // if (typeof doc.enabled === 'boolean') {
238
+ // transformed.enabled = doc.enabled;
239
+ // }
240
+ // items.push(transformed);
241
+ // });
242
+ // const model = new HostsModel();
243
+ // await model.putBulk(items);
244
+ // }
245
245
  }
@@ -55,14 +55,6 @@ export class StoreBroadcast {
55
55
  return '/store/history/ws';
56
56
  }
57
57
 
58
- /**
59
- * The path used to construct a `BroadcastChannel` (or similar)
60
- * to communicate changes between contexts for the Certificates store.
61
- */
62
- static get certificates(): string {
63
- return '/store/certificates';
64
- }
65
-
66
58
  /**
67
59
  * The path used to construct a `BroadcastChannel` (or similar)
68
60
  * to communicate changes between contexts for the History store.
@@ -0,0 +1,12 @@
1
+ export class FileUtils {
2
+ /**
3
+ * Reads the last segment of the file path and returns it as a file name.
4
+ *
5
+ * @param path THe file path.
6
+ */
7
+ static getFileName(path: string): string {
8
+ const delimiter = path.includes('/') ? '/' : '\\';
9
+ const last = path.split(delimiter).pop();
10
+ return last || '';
11
+ }
12
+ }
@@ -101,6 +101,11 @@ export declare class RouteMixinInterface {
101
101
  */
102
102
  static get routes(): IRoute[];
103
103
 
104
+ /**
105
+ * The current route parameters. This is the same what is passed to the route handler.
106
+ */
107
+ protected currentRoute?: IRouteResult;
108
+
104
109
  /**
105
110
  * Initializes the routing.
106
111
  */
@@ -119,6 +124,8 @@ export function RouteMixin<T extends Constructor<Object>>(superClass: T): Constr
119
124
  return []
120
125
  }
121
126
 
127
+ protected currentRoute?: IRouteResult;
128
+
122
129
  constructor(...args: any[]) {
123
130
  super(...args);
124
131
  this._routeHandler = this._routeHandler.bind(this);
@@ -159,7 +166,7 @@ export function RouteMixin<T extends Constructor<Object>>(superClass: T): Constr
159
166
  argument.params = params;
160
167
  }
161
168
  }
162
-
169
+ this.currentRoute = argument;
163
170
  this._callRoute(activeRoute, argument);
164
171
  if (activeRoute.title) {
165
172
  document.title = activeRoute.title;
@@ -6,6 +6,7 @@ import { IRoute, IRouteResult } from '../../mixins/RouteMixin.js';
6
6
  import pageStyles from './ApiClient.styles.js';
7
7
  import globalStyles from '../../styles/global-styles.js';
8
8
  import typography from '../../styles/m3/typography.module.js';
9
+ import surface from '../../styles/m3/surface.module.js';
9
10
  import dialogStyles from '../../styles/m3/dialog.module.js';
10
11
  import { navigate } from '../../lib/route.js';
11
12
  import { reactive } from '../../lib/decorators.js';
@@ -27,6 +28,7 @@ import '../../define/ui/ui-icon-button.js';
27
28
  import '../../define/ui/ui-text-field.js';
28
29
  import '../../define/ui/ui-dropdown-list.js';
29
30
  import '../../define/ui/ui-divider.js';
31
+ import '../../define/http/certificate-add.js';
30
32
 
31
33
  export interface PageInit extends ApplicationInit {
32
34
  idb: HttpClientStoreBindings;
@@ -48,11 +50,12 @@ export default class ApiClientScreen extends ApplicationScreen {
48
50
  { pattern: '/shared/(?<key>.*)', method: 'sharedRoute', name: 'Shares', title: 'Shared with you' },
49
51
  { pattern: '/trash', method: 'trashRoute', name: 'Trash', title: 'Trash' },
50
52
  { pattern: '/settings', method: 'settingsRoute', name: 'Settings', title: 'Settings' },
53
+ { pattern: '/certificates/add/?(?<parent>.*)', method: 'addCertRoute', name: 'Add certificate', title: 'Add certificate' },
51
54
  ];
52
55
  }
53
56
 
54
57
  static get styles(): CSSResult[] {
55
- return [globalStyles, pageStyles, typography, dialogStyles, DataTable.styles];
58
+ return [globalStyles, pageStyles, typography, dialogStyles, DataTable.styles, surface];
56
59
  }
57
60
 
58
61
  /**
@@ -365,6 +368,15 @@ export default class ApiClientScreen extends ApplicationScreen {
365
368
  this.page = 'settings';
366
369
  }
367
370
 
371
+ protected addCertRoute(): void {
372
+ this.resetRoute();
373
+ this.page = 'add-cert';
374
+ }
375
+
376
+ protected handleCertificateClose(): void {
377
+ window.history.back();
378
+ }
379
+
368
380
  protected mainNavHandler(e: Event): void {
369
381
  const target = e.target as HTMLElement;
370
382
  const { page } = target.dataset;
@@ -622,7 +634,7 @@ export default class ApiClientScreen extends ApplicationScreen {
622
634
  protected override mainTemplate(): TemplateResult {
623
635
  return html`
624
636
  <main class="body-medium">
625
- <div class="content">
637
+ <div class="content surface1">
626
638
  ${this.renderPage()}
627
639
  </div>
628
640
  </main>
@@ -638,6 +650,7 @@ export default class ApiClientScreen extends ApplicationScreen {
638
650
  case 'shared': return this.shared.render();
639
651
  case 'trash': return this.trash.render();
640
652
  case 'settings': return this.settings.render();
653
+ case 'add-cert': return this.renderAddCertificate();
641
654
  default: return this.render404();
642
655
  }
643
656
  }
@@ -724,4 +737,15 @@ export default class ApiClientScreen extends ApplicationScreen {
724
737
  </dialog>
725
738
  `;
726
739
  }
740
+
741
+ protected renderAddCertificate(): TemplateResult {
742
+ const { currentRoute, currentSpace } = this;
743
+ const parent = currentRoute && currentRoute.params && currentRoute.params.parent as string | undefined;
744
+ const space = currentSpace && currentSpace.key;
745
+ return html`
746
+ <h2 class="headline-small">Add Certificate</h2>
747
+ <p class="body-medium">Import a certificate to use it in your HTTP projects. Note, imported certificate cannot be changed.</p>
748
+ <certificate-add .folder="${parent}" .space="${space}" @close="${this.handleCertificateClose}"></certificate-add>
749
+ `;
750
+ }
727
751
  }
@@ -174,8 +174,6 @@ main {
174
174
 
175
175
  main .content {
176
176
  padding: 20px;
177
- position: relative;
178
- z-index: 0;
179
177
  border-radius: inherit;
180
178
 
181
179
  flex: 1;
@@ -184,16 +182,6 @@ main .content {
184
182
 
185
183
  overflow: hidden;
186
184
  }
187
-
188
- main .content::before {
189
- content: '';
190
- background-color: var(--md-sys-color-primary);
191
- opacity: .05;
192
- position: absolute;
193
- inset: 0;
194
- border-radius: inherit;
195
- }
196
-
197
185
  main .content > * {
198
186
  position: relative;
199
187
  z-index: 1;
@@ -241,6 +241,13 @@ export class FilesPage {
241
241
  this.screen.openDialog('createProjectDialog');
242
242
  } else if (option === 'schema') {
243
243
  this.screen.openDialog('createSchemaDialog');
244
+ } else if (option === 'certificate') {
245
+ const { parent } = this.fs;
246
+ if (parent) {
247
+ navigate('certificates', 'add', parent);
248
+ } else {
249
+ navigate('certificates', 'add');
250
+ }
244
251
  }
245
252
  }
246
253
 
@@ -573,6 +580,10 @@ export class FilesPage {
573
580
  <ui-icon icon="schema" slot="start"></ui-icon>
574
581
  Data schema
575
582
  </ui-list-item>
583
+ <ui-list-item image="icon" data-option="certificate" role="menuitem">
584
+ <ui-icon icon="certificate" slot="start"></ui-icon>
585
+ Certificate
586
+ </ui-list-item>
576
587
  <ui-divider></ui-divider>
577
588
  <ui-list-item image="icon" data-option="folder" role="menuitem">
578
589
  <ui-icon icon="folder" slot="start"></ui-icon>
@@ -3,6 +3,21 @@ import { property, queryAssignedElements } from "lit/decorators.js";
3
3
  import { UiElement } from "../UiElement.js";
4
4
  import SegmentedButton from "./SegmentedButton.js";
5
5
 
6
+ export interface ISegmentedButtonSelectionDetail {
7
+ /**
8
+ * A reference to the selected button.
9
+ */
10
+ button: SegmentedButton;
11
+ /**
12
+ * Whether the button is selected.
13
+ */
14
+ selected: boolean;
15
+ /**
16
+ * The index of the selected button.
17
+ */
18
+ index: number;
19
+ }
20
+
6
21
  /**
7
22
  * @fires select - When button's selection change.
8
23
  */
@@ -80,7 +95,7 @@ export default class SegmentedButtonsSet extends UiElement {
80
95
  }
81
96
 
82
97
  private dispatchSelected(index: number): void {
83
- this.dispatchEvent(new CustomEvent('select', {
98
+ this.dispatchEvent(new CustomEvent<ISegmentedButtonSelectionDetail>('select', {
84
99
  detail: {
85
100
  button: this.buttons[index],
86
101
  selected: this.buttons[index].selected,
@@ -199,4 +199,12 @@ export class SnackNotifications {
199
199
  }
200
200
  }
201
201
  }
202
+
203
+ static clear(): void {
204
+ this.stack = [];
205
+ if (this.current) {
206
+ this.current.element.parentElement?.removeChild(this.current.element);
207
+ this.current = undefined;
208
+ }
209
+ }
202
210
  }