@api-client/ui 0.0.11 → 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.
- package/.eslintrc +8 -0
- package/demo/elements/authorization/cc.ts +56 -27
- package/demo/elements/index.html +3 -0
- package/demo/elements/store/file-picker.html +15 -0
- package/demo/elements/store/file-picker.ts +134 -0
- package/demo/elements/store/index.html +19 -0
- package/demo/store/StorePlugin.js +1 -0
- package/dist/bindings/base/FileBindings.d.ts +4 -0
- package/dist/bindings/base/FileBindings.d.ts.map +1 -1
- package/dist/bindings/base/FileBindings.js +21 -1
- package/dist/bindings/base/FileBindings.js.map +1 -1
- package/dist/bindings/base/StoreBindings.d.ts +6 -17
- package/dist/bindings/base/StoreBindings.d.ts.map +1 -1
- package/dist/bindings/base/StoreBindings.js +15 -60
- package/dist/bindings/base/StoreBindings.js.map +1 -1
- package/dist/bindings/web/WebFileBindings.js +1 -1
- package/dist/bindings/web/WebFileBindings.js.map +1 -1
- package/dist/define/http/certificate-add.d.ts +9 -0
- package/dist/define/http/certificate-add.d.ts.map +1 -0
- package/dist/define/http/certificate-add.js +10 -0
- package/dist/define/http/certificate-add.js.map +1 -0
- package/dist/define/store/file-picker.d.ts +9 -0
- package/dist/define/store/file-picker.d.ts.map +1 -0
- package/dist/define/store/file-picker.js +10 -0
- package/dist/define/store/file-picker.js.map +1 -0
- package/dist/define/{files → store}/share-file.d.ts +1 -1
- package/dist/define/store/share-file.d.ts.map +1 -0
- package/dist/define/{files → store}/share-file.js +2 -2
- package/dist/define/store/share-file.js.map +1 -0
- package/dist/define/ui/ui-segmented-button-set.d.ts +1 -1
- package/dist/define/ui/ui-segmented-button-set.d.ts.map +1 -1
- package/dist/define/ui/ui-segmented-button-set.js.map +1 -1
- package/dist/elements/authorization/ui/CC.styles.d.ts.map +1 -1
- package/dist/elements/authorization/ui/CC.styles.js +4 -9
- package/dist/elements/authorization/ui/CC.styles.js.map +1 -1
- package/dist/elements/authorization/ui/CcAuthorization.d.ts +14 -29
- package/dist/elements/authorization/ui/CcAuthorization.d.ts.map +1 -1
- package/dist/elements/authorization/ui/CcAuthorization.js +67 -158
- package/dist/elements/authorization/ui/CcAuthorization.js.map +1 -1
- package/dist/elements/http/CertificateAdd.element.d.ts +91 -0
- package/dist/elements/http/CertificateAdd.element.d.ts.map +1 -0
- package/dist/elements/http/CertificateAdd.element.js +389 -0
- package/dist/elements/http/CertificateAdd.element.js.map +1 -0
- package/dist/elements/http/CertificateAdd.styles.d.ts +3 -0
- package/dist/elements/http/CertificateAdd.styles.d.ts.map +1 -0
- package/dist/elements/http/CertificateAdd.styles.js +61 -0
- package/dist/elements/http/CertificateAdd.styles.js.map +1 -0
- package/dist/elements/project/ProjectRunReport.d.ts +2 -1
- package/dist/elements/project/ProjectRunReport.d.ts.map +1 -1
- package/dist/elements/project/ProjectRunReport.js.map +1 -1
- package/dist/elements/store/FilePicker.element.d.ts +87 -0
- package/dist/elements/store/FilePicker.element.d.ts.map +1 -0
- package/dist/elements/store/FilePicker.element.js +263 -0
- package/dist/elements/store/FilePicker.element.js.map +1 -0
- package/dist/elements/store/FilePicker.styles.d.ts +3 -0
- package/dist/elements/store/FilePicker.styles.d.ts.map +1 -0
- package/dist/elements/store/FilePicker.styles.js +73 -0
- package/dist/elements/store/FilePicker.styles.js.map +1 -0
- package/dist/elements/store/FilesLib.d.ts +10 -0
- package/dist/elements/store/FilesLib.d.ts.map +1 -0
- package/dist/elements/store/FilesLib.js +38 -0
- package/dist/elements/store/FilesLib.js.map +1 -0
- package/dist/elements/{files/ShareFile.d.ts → store/ShareFile.element.d.ts} +1 -1
- package/dist/elements/store/ShareFile.element.d.ts.map +1 -0
- package/dist/elements/{files/ShareFile.js → store/ShareFile.element.js} +1 -1
- package/dist/elements/store/ShareFile.element.js.map +1 -0
- package/dist/elements/store/ShareFile.styles.d.ts.map +1 -0
- package/dist/elements/{files → store}/ShareFile.styles.js.map +1 -1
- package/dist/events/EventTypes.d.ts +7 -7
- package/dist/events/EventTypes.d.ts.map +1 -1
- package/dist/events/EventTypes.js +8 -7
- package/dist/events/EventTypes.js.map +1 -1
- package/dist/events/Events.d.ts +7 -1
- package/dist/events/Events.d.ts.map +1 -1
- package/dist/events/Events.js +2 -0
- package/dist/events/Events.js.map +1 -1
- package/dist/events/FilesystemEvents.d.ts +8 -0
- package/dist/events/FilesystemEvents.d.ts.map +1 -0
- package/dist/events/FilesystemEvents.js +59 -0
- package/dist/events/FilesystemEvents.js.map +1 -0
- package/dist/events/HttpClientEvents.d.ts +0 -2
- package/dist/events/HttpClientEvents.d.ts.map +1 -1
- package/dist/events/HttpClientEvents.js +0 -2
- package/dist/events/HttpClientEvents.js.map +1 -1
- package/dist/events/StoreEvents.d.ts +8 -1
- package/dist/events/StoreEvents.d.ts.map +1 -1
- package/dist/events/StoreEvents.js +19 -0
- package/dist/events/StoreEvents.js.map +1 -1
- package/dist/http-client/idb/Arc18DataUpgrade.d.ts +0 -8
- package/dist/http-client/idb/Arc18DataUpgrade.d.ts.map +1 -1
- package/dist/http-client/idb/Arc18DataUpgrade.js +11 -206
- package/dist/http-client/idb/Arc18DataUpgrade.js.map +1 -1
- package/dist/http-client/store/StoreBroadcast.d.ts +0 -5
- package/dist/http-client/store/StoreBroadcast.d.ts.map +1 -1
- package/dist/http-client/store/StoreBroadcast.js +0 -7
- package/dist/http-client/store/StoreBroadcast.js.map +1 -1
- package/dist/lib/files/FileUtils.d.ts +9 -0
- package/dist/lib/files/FileUtils.d.ts.map +1 -0
- package/dist/lib/files/FileUtils.js +13 -0
- package/dist/lib/files/FileUtils.js.map +1 -0
- package/dist/mixins/RouteMixin.d.ts +4 -0
- package/dist/mixins/RouteMixin.d.ts.map +1 -1
- package/dist/mixins/RouteMixin.js +1 -0
- package/dist/mixins/RouteMixin.js.map +1 -1
- package/dist/pages/ApplicationScreen.d.ts +1 -1
- package/dist/pages/ApplicationScreen.d.ts.map +1 -1
- package/dist/pages/ApplicationScreen.js +4 -2
- package/dist/pages/ApplicationScreen.js.map +1 -1
- package/dist/pages/api-client/ApiClient.screen.d.ts +4 -6
- package/dist/pages/api-client/ApiClient.screen.d.ts.map +1 -1
- package/dist/pages/api-client/ApiClient.screen.js +39 -31
- package/dist/pages/api-client/ApiClient.screen.js.map +1 -1
- package/dist/pages/api-client/ApiClient.styles.d.ts.map +1 -1
- package/dist/pages/api-client/ApiClient.styles.js +0 -12
- package/dist/pages/api-client/ApiClient.styles.js.map +1 -1
- package/dist/pages/api-client/Authenticate.screen.d.ts +1 -1
- package/dist/pages/api-client/Authenticate.screen.d.ts.map +1 -1
- package/dist/pages/api-client/Authenticate.screen.js +2 -2
- package/dist/pages/api-client/Authenticate.screen.js.map +1 -1
- package/dist/pages/api-client/pages/Files.page.d.ts +6 -35
- package/dist/pages/api-client/pages/Files.page.d.ts.map +1 -1
- package/dist/pages/api-client/pages/Files.page.js +45 -141
- package/dist/pages/api-client/pages/Files.page.js.map +1 -1
- package/dist/pages/api-client/pages/Shared.page.d.ts +1 -5
- package/dist/pages/api-client/pages/Shared.page.d.ts.map +1 -1
- package/dist/pages/api-client/pages/Shared.page.js +1 -40
- package/dist/pages/api-client/pages/Shared.page.js.map +1 -1
- package/dist/pages/demo/DemoPage.d.ts +7 -0
- package/dist/pages/demo/DemoPage.d.ts.map +1 -1
- package/dist/pages/demo/DemoPage.js +14 -0
- package/dist/pages/demo/DemoPage.js.map +1 -1
- package/dist/store/FileSystem.d.ts +90 -0
- package/dist/store/FileSystem.d.ts.map +1 -0
- package/dist/store/FileSystem.js +260 -0
- package/dist/store/FileSystem.js.map +1 -0
- package/dist/styles/global-styles.d.ts.map +1 -1
- package/dist/styles/global-styles.js +7 -0
- package/dist/styles/global-styles.js.map +1 -1
- package/dist/ui/button/SegmentedButtonsSet.d.ts +14 -0
- package/dist/ui/button/SegmentedButtonsSet.d.ts.map +1 -1
- package/dist/ui/button/SegmentedButtonsSet.js.map +1 -1
- package/dist/ui/icons/Icons.d.ts +2 -1
- package/dist/ui/icons/Icons.d.ts.map +1 -1
- package/dist/ui/icons/Icons.js +1 -0
- package/dist/ui/icons/Icons.js.map +1 -1
- package/dist/ui/list/UiDropdownList.d.ts +9 -1
- package/dist/ui/list/UiDropdownList.d.ts.map +1 -1
- package/dist/ui/list/UiDropdownList.js +39 -17
- package/dist/ui/list/UiDropdownList.js.map +1 -1
- package/dist/ui/list/UiList.d.ts +6 -1
- package/dist/ui/list/UiList.d.ts.map +1 -1
- package/dist/ui/list/UiList.js +24 -9
- package/dist/ui/list/UiList.js.map +1 -1
- package/dist/ui/notification/SnackNotifications.d.ts +1 -0
- package/dist/ui/notification/SnackNotifications.d.ts.map +1 -1
- package/dist/ui/notification/SnackNotifications.js +7 -0
- package/dist/ui/notification/SnackNotifications.js.map +1 -1
- package/dist/ui/table/DataTable.d.ts +4 -0
- package/dist/ui/table/DataTable.d.ts.map +1 -1
- package/dist/ui/table/DataTable.js +23 -1
- package/dist/ui/table/DataTable.js.map +1 -1
- package/package.json +1 -1
- package/src/bindings/base/FileBindings.ts +25 -1
- package/src/bindings/base/StoreBindings.ts +16 -73
- package/src/bindings/web/WebFileBindings.ts +1 -1
- package/src/define/http/certificate-add.ts +12 -0
- package/src/define/store/file-picker.ts +12 -0
- package/src/define/{files → store}/share-file.ts +2 -2
- package/src/define/ui/ui-segmented-button-set.ts +1 -1
- package/src/elements/authorization/ui/CC.styles.ts +4 -9
- package/src/elements/authorization/ui/CcAuthorization.ts +67 -167
- package/src/elements/http/CertificateAdd.element.ts +443 -0
- package/src/elements/http/CertificateAdd.styles.ts +61 -0
- package/src/elements/project/ProjectRunReport.ts +2 -1
- package/src/elements/store/FilePicker.element.ts +297 -0
- package/src/elements/store/FilePicker.styles.ts +73 -0
- package/src/elements/store/FilesLib.ts +32 -0
- package/src/events/EventTypes.ts +8 -7
- package/src/events/Events.ts +2 -0
- package/src/events/FilesystemEvents.ts +63 -0
- package/src/events/HttpClientEvents.ts +0 -2
- package/src/events/StoreEvents.ts +21 -1
- package/src/http-client/idb/Arc18DataUpgrade.ts +84 -84
- package/src/http-client/store/StoreBroadcast.ts +0 -8
- package/src/lib/files/FileUtils.ts +12 -0
- package/src/mixins/RouteMixin.ts +8 -1
- package/src/pages/ApplicationScreen.ts +5 -3
- package/src/pages/api-client/ApiClient.screen.ts +42 -33
- package/src/pages/api-client/ApiClient.styles.ts +0 -12
- package/src/pages/api-client/Authenticate.screen.ts +2 -2
- package/src/pages/api-client/pages/Files.page.ts +48 -164
- package/src/pages/api-client/pages/Shared.page.ts +2 -40
- package/src/pages/demo/DemoPage.ts +17 -0
- package/src/store/FileSystem.ts +325 -0
- package/src/styles/global-styles.ts +7 -0
- package/src/ui/button/SegmentedButtonsSet.ts +16 -1
- package/src/ui/icons/Icons.ts +2 -1
- package/src/ui/list/UiDropdownList.ts +44 -17
- package/src/ui/list/UiList.ts +26 -10
- package/src/ui/notification/SnackNotifications.ts +8 -0
- package/src/ui/table/DataTable.ts +29 -3
- package/test/elements/http/BodyFormdataEditorElement.test.ts +458 -454
- package/test/elements/http/BodyMultipartEditorElement.test.ts +609 -605
- package/test/elements/http/BodyRawEditorElement.test.ts +60 -56
- package/test/elements/http/CertificateAdd.test.ts +430 -0
- package/test/elements/store/FilePicker.test.ts +241 -0
- package/test/env.js +3 -0
- package/test/events/EventTypes.test.ts +0 -22
- package/test/helpers/StoreHelper.ts +390 -0
- package/test/helpers/UiMock.ts +19 -2
- package/tsconfig.eslint.json +3 -1
- package/web-test-runner.config.mjs +50 -3
- package/dist/define/files/share-file.d.ts.map +0 -1
- package/dist/define/files/share-file.js.map +0 -1
- package/dist/elements/files/ShareFile.d.ts.map +0 -1
- package/dist/elements/files/ShareFile.js.map +0 -1
- package/dist/elements/files/ShareFile.styles.d.ts.map +0 -1
- package/dist/events/http-client/models/CertificatesEvents.d.ts +0 -12
- package/dist/events/http-client/models/CertificatesEvents.d.ts.map +0 -1
- package/dist/events/http-client/models/CertificatesEvents.js +0 -18
- package/dist/events/http-client/models/CertificatesEvents.js.map +0 -1
- package/dist/http-client/idb/AuthDataModel.d.ts +0 -60
- package/dist/http-client/idb/AuthDataModel.d.ts.map +0 -1
- package/dist/http-client/idb/AuthDataModel.js +0 -150
- package/dist/http-client/idb/AuthDataModel.js.map +0 -1
- package/dist/http-client/idb/HostsModel.d.ts +0 -25
- package/dist/http-client/idb/HostsModel.d.ts.map +0 -1
- package/dist/http-client/idb/HostsModel.js +0 -82
- package/dist/http-client/idb/HostsModel.js.map +0 -1
- package/dist/http-client/idb/LegacyMockedStore.d.ts +0 -214
- package/dist/http-client/idb/LegacyMockedStore.d.ts.map +0 -1
- package/dist/http-client/idb/LegacyMockedStore.js +0 -486
- package/dist/http-client/idb/LegacyMockedStore.js.map +0 -1
- package/src/events/http-client/models/CertificatesEvents.ts +0 -23
- package/src/http-client/idb/AuthDataModel.ts +0 -175
- package/src/http-client/idb/HostsModel.ts +0 -125
- package/src/http-client/idb/LegacyMockedStore.ts +0 -544
- package/test/apic-ui.test.ts +0 -31
- /package/dist/elements/{files → store}/ShareFile.styles.d.ts +0 -0
- /package/dist/elements/{files → store}/ShareFile.styles.js +0 -0
- /package/src/elements/{files/ShareFile.ts → store/ShareFile.element.ts} +0 -0
- /package/src/elements/{files → store}/ShareFile.styles.ts +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FolderKind, IFile,
|
|
3
|
+
ListFileKind
|
|
4
|
+
} from "@api-client/core/build/browser.js";
|
|
5
|
+
import { CSSResult, html, nothing, TemplateResult } from "lit";
|
|
6
|
+
import { eventOptions, property, query, state } from "lit/decorators.js";
|
|
7
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
8
|
+
import ApiElement from "../ApiElement.js";
|
|
9
|
+
import styles from './FilePicker.styles.js';
|
|
10
|
+
import { fileIcon } from "./FilesLib.js";
|
|
11
|
+
import type UiList from "../../ui/list/UiList.js";
|
|
12
|
+
import type { UiListSelection } from "../../ui/list/UiList.js";
|
|
13
|
+
import { FileSystem } from "../../store/FileSystem.js";
|
|
14
|
+
import '../../define/ui/ui-divider.js';
|
|
15
|
+
import '../../define/ui/ui-button.js';
|
|
16
|
+
import '../../define/ui/ui-icon-button.js';
|
|
17
|
+
import '../../define/ui/ui-icon.js';
|
|
18
|
+
import '../../define/ui/ui-list.js';
|
|
19
|
+
import '../../define/ui/ui-list-item.js';
|
|
20
|
+
import '../../define/ui/ui-progress.js';
|
|
21
|
+
|
|
22
|
+
export interface FilePickerClosingReason {
|
|
23
|
+
/**
|
|
24
|
+
* Whether the picker was canceled.
|
|
25
|
+
*/
|
|
26
|
+
canceled: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The file selected by the user. This is always and only selected when the `canceled` is false.
|
|
29
|
+
*/
|
|
30
|
+
file?: IFile;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A portable element that allow to pick a file from the Store.
|
|
35
|
+
*
|
|
36
|
+
* @fires close - When a file is selected or the user cancelled the dialog. The detail object is the picked file object. Note, this event bubbles.
|
|
37
|
+
* @fires querycomplete - When the page of results was loaded.
|
|
38
|
+
*/
|
|
39
|
+
export default class FilePicker extends ApiElement {
|
|
40
|
+
static override get styles(): CSSResult[] {
|
|
41
|
+
return styles;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The key of the parent folder to query for files.
|
|
46
|
+
* @attribute
|
|
47
|
+
*/
|
|
48
|
+
@property({ type: String, hasChanged: () => false })
|
|
49
|
+
get folder(): string | undefined {
|
|
50
|
+
return this.fs.parent;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set folder(value: string | undefined) {
|
|
54
|
+
this.fs.selectFolder(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The page limit. Defaults to the store defaults.
|
|
59
|
+
* @attribute
|
|
60
|
+
*/
|
|
61
|
+
@property({ type: Number, hasChanged: () => false })
|
|
62
|
+
set limit(value: number | undefined) {
|
|
63
|
+
this.fs.limit = value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
get limit(): number | undefined {
|
|
67
|
+
return this.fs.limit;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The timeout for the page query debouncer.
|
|
72
|
+
* @attribute
|
|
73
|
+
*/
|
|
74
|
+
@property({ type: Number, hasChanged: () => false })
|
|
75
|
+
get debounceTimeout(): number {
|
|
76
|
+
return this.fs.debounceTimeout;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
set debounceTimeout(value: number) {
|
|
80
|
+
this.fs.debounceTimeout = value || 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The list of file kinds to list.
|
|
85
|
+
* Folders are always included.
|
|
86
|
+
*/
|
|
87
|
+
@property({ type: Array, hasChanged: () => false })
|
|
88
|
+
get kinds(): ListFileKind[] | undefined {
|
|
89
|
+
return this.fs.kinds;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
set kinds(value: ListFileKind[] | undefined) {
|
|
93
|
+
this.fs.kinds = value;
|
|
94
|
+
this.fs.resetList();
|
|
95
|
+
this.fs.debounceQuery();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@query('ui-list') protected list?: UiList;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The currently selected in the picker file.
|
|
102
|
+
*/
|
|
103
|
+
@state() protected selectedFile?: IFile;
|
|
104
|
+
|
|
105
|
+
@state() errorMessage?: string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* When set it does not query for files when attached to the DOM.
|
|
109
|
+
* It will still query for files when attributes change. This is primarily used in tests.
|
|
110
|
+
* @attribute
|
|
111
|
+
*/
|
|
112
|
+
@property({ type: Boolean }) manualQuery?: boolean;
|
|
113
|
+
|
|
114
|
+
get selectedKey(): string | undefined {
|
|
115
|
+
return this.selectedFile?.key;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
fs = new FileSystem();
|
|
119
|
+
|
|
120
|
+
constructor() {
|
|
121
|
+
super();
|
|
122
|
+
this.fs.eventsTarget = this;
|
|
123
|
+
this.fs.addEventListener('change', () => this.requestUpdate());
|
|
124
|
+
this.fs.addEventListener('error', (e: Event) => {
|
|
125
|
+
const event = e as CustomEvent<string>;
|
|
126
|
+
this.errorMessage = event.detail;
|
|
127
|
+
});
|
|
128
|
+
this.fs.addEventListener('querycomplete', () => {
|
|
129
|
+
this.dispatchEvent(new Event('querycomplete'));
|
|
130
|
+
});
|
|
131
|
+
this.fs.addEventListener('delete', (e: Event) => {
|
|
132
|
+
const event = e as CustomEvent<string>;
|
|
133
|
+
if (this.selectedFile && this.selectedFile.key === event.detail) {
|
|
134
|
+
this.selectedFile = undefined;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
override connectedCallback(): void {
|
|
140
|
+
super.connectedCallback();
|
|
141
|
+
this.fs.observe();
|
|
142
|
+
if (!this.manualQuery) {
|
|
143
|
+
this.fs.debounceQuery();
|
|
144
|
+
}
|
|
145
|
+
if (!this.hasAttribute('tabindex')) {
|
|
146
|
+
this.setAttribute('tabindex', '0');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
override disconnectedCallback(): void {
|
|
151
|
+
super.disconnectedCallback();
|
|
152
|
+
this.fs.unobserve();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
override focus(options?: FocusOptions | undefined): void {
|
|
156
|
+
const { list } = this;
|
|
157
|
+
if (list) {
|
|
158
|
+
list.focus(options);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
protected handleFileSelect(e: CustomEvent<UiListSelection>): void {
|
|
163
|
+
// this prevents the dropdown list to close the UI.
|
|
164
|
+
e.preventDefault();
|
|
165
|
+
const file = this.fs.files[e.detail.index];
|
|
166
|
+
if (!file) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (file.kind === FolderKind) {
|
|
170
|
+
this.fs.selectFolder(file.key);
|
|
171
|
+
this.selectedFile = undefined;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
this.selectedFile = file;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
protected handleParentUp(): void {
|
|
178
|
+
this.fs.parentUp();
|
|
179
|
+
this.selectedFile = undefined;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
protected notifyClose(canceled: boolean): void {
|
|
183
|
+
if (!canceled && !this.selectedFile) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const detail: FilePickerClosingReason = {
|
|
187
|
+
canceled,
|
|
188
|
+
};
|
|
189
|
+
if (!canceled) {
|
|
190
|
+
detail.file = this.selectedFile;
|
|
191
|
+
}
|
|
192
|
+
// this event bubbles so any dropdown on the way can close itself.
|
|
193
|
+
const e = new CustomEvent<FilePickerClosingReason>('close', {
|
|
194
|
+
bubbles: true,
|
|
195
|
+
cancelable: true,
|
|
196
|
+
composed: true,
|
|
197
|
+
detail,
|
|
198
|
+
});
|
|
199
|
+
this.dispatchEvent(e);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
protected handleSelect(): void {
|
|
203
|
+
this.notifyClose(false);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
protected handleCancel(): void {
|
|
207
|
+
this.notifyClose(true);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@eventOptions({ passive: true })
|
|
211
|
+
protected handleListScroll(e: Event): void {
|
|
212
|
+
const list = e.target as UiList;
|
|
213
|
+
if (this.fs.isListEnd(list)) {
|
|
214
|
+
this.fs.debounceQuery();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
protected override render(): TemplateResult {
|
|
219
|
+
return html`
|
|
220
|
+
<div class="content">
|
|
221
|
+
${this.renderHeader()}
|
|
222
|
+
<ui-divider></ui-divider>
|
|
223
|
+
${this.renderFiles()}
|
|
224
|
+
${this.errorMessage ? html`<p class="error">${this.errorMessage}</p>` : nothing}
|
|
225
|
+
<ui-divider></ui-divider>
|
|
226
|
+
${this.renderActions()}
|
|
227
|
+
</div>
|
|
228
|
+
`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
protected renderHeader(): TemplateResult {
|
|
232
|
+
const { breadcrumbs = [], reading } = this.fs;
|
|
233
|
+
let content: TemplateResult;
|
|
234
|
+
let withIcon = false;
|
|
235
|
+
if (!breadcrumbs.length) {
|
|
236
|
+
content = html`<span class="title-large label">My files</span>`;
|
|
237
|
+
} else {
|
|
238
|
+
withIcon = true;
|
|
239
|
+
const [parent] = breadcrumbs;
|
|
240
|
+
content = html`
|
|
241
|
+
<ui-icon-button aria-label="Open parent folder" @click="${this.handleParentUp}" class="back-button">
|
|
242
|
+
<ui-icon role="presentation" icon="arrowBack"></ui-icon>
|
|
243
|
+
</ui-icon-button>
|
|
244
|
+
<span class="title-large label">${parent.name}</span>
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
const classes = {
|
|
248
|
+
header: true,
|
|
249
|
+
withIcon,
|
|
250
|
+
}
|
|
251
|
+
return html`
|
|
252
|
+
<div class="${classMap(classes)}">
|
|
253
|
+
${content}
|
|
254
|
+
${reading ? html`<ui-progress indeterminate class="progress"></ui-progress>` : nothing}
|
|
255
|
+
</div>
|
|
256
|
+
`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
protected renderFiles(): TemplateResult {
|
|
260
|
+
const { files } = this.fs;
|
|
261
|
+
if (!files || !files.length) {
|
|
262
|
+
return this.renderEmptyList();
|
|
263
|
+
}
|
|
264
|
+
return html`
|
|
265
|
+
<ui-list class="list" role="menu" @select="${this.handleFileSelect}" selectActive @scroll="${this.handleListScroll}">
|
|
266
|
+
${files.map(item => this.renderFileItem(item))}
|
|
267
|
+
</ui-list>
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
protected renderEmptyList(): TemplateResult {
|
|
272
|
+
return html`
|
|
273
|
+
<p class="no-files body-large">No files in this view.</p>
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
protected renderFileItem(item: IFile): TemplateResult {
|
|
278
|
+
const icon = fileIcon(item);
|
|
279
|
+
return html`
|
|
280
|
+
<ui-list-item role="menuitem" data-key="${item.key}" data-kind="${item.kind}">
|
|
281
|
+
${icon ? html`<ui-icon icon="${icon}" class="file-icon"></ui-icon>` : nothing}
|
|
282
|
+
${item.info.name || 'Unnamed file'}
|
|
283
|
+
</ui-list-item>
|
|
284
|
+
`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
protected renderActions(): TemplateResult {
|
|
288
|
+
const { selectedFile } = this;
|
|
289
|
+
const disableSelect = !selectedFile;
|
|
290
|
+
return html`
|
|
291
|
+
<div class="actions">
|
|
292
|
+
<ui-button type="text" @click="${this.handleCancel}" value="cancel">Cancel</ui-button>
|
|
293
|
+
<ui-button type="tonal" ?disabled="${disableSelect}" @click="${this.handleSelect}" value="select">Select</ui-button>
|
|
294
|
+
</div>
|
|
295
|
+
`;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
import typography from '../../styles/m3/typography.module.js';
|
|
3
|
+
|
|
4
|
+
export default [typography, css`
|
|
5
|
+
:host {
|
|
6
|
+
display: block;
|
|
7
|
+
|
|
8
|
+
width: 420px;
|
|
9
|
+
height: 400px;
|
|
10
|
+
|
|
11
|
+
background-color: var(--md-sys-color-background);
|
|
12
|
+
color: var(--md-sys-color-on-background);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.content {
|
|
16
|
+
height: 100%;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.header {
|
|
22
|
+
height: 56px;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
position: relative;
|
|
26
|
+
margin: 0 16px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.header.withIcon {
|
|
30
|
+
margin: 0 16px 0 4px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.header .label {
|
|
34
|
+
display: block;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.progress {
|
|
38
|
+
position: absolute;
|
|
39
|
+
bottom: -10px; /* aligns with the divider */
|
|
40
|
+
width: 100%;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.list {
|
|
44
|
+
overflow-y: auto;
|
|
45
|
+
flex: 1;
|
|
46
|
+
margin: 0;
|
|
47
|
+
padding: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.actions {
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: flex-end;
|
|
54
|
+
margin: 0 16px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.file-icon {
|
|
58
|
+
margin-right: 12px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.error {
|
|
62
|
+
background-color: var(--md-sys-color-error-container);
|
|
63
|
+
color: var(--md-sys-color-on-error-container);
|
|
64
|
+
display: block;
|
|
65
|
+
padding: 8px 12px;
|
|
66
|
+
border-radius: var(--md-sys-shape-corner-small);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.no-files {
|
|
70
|
+
flex: 1;
|
|
71
|
+
margin-left: 16px;
|
|
72
|
+
}
|
|
73
|
+
`];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CertificateFileKind, DataFileKind, FolderKind, IFile, ProjectKind } from "@api-client/core/build/browser.js";
|
|
2
|
+
import { IconType } from "../../ui/icons/Icons.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sorts files on the list.
|
|
6
|
+
*
|
|
7
|
+
* Folders are always on top.
|
|
8
|
+
*/
|
|
9
|
+
export function filesSortFunction(a: IFile, b: IFile): number {
|
|
10
|
+
if (a.kind !== b.kind) {
|
|
11
|
+
if (a.kind === FolderKind) {
|
|
12
|
+
return -1;
|
|
13
|
+
}
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
if (a.kind === b.kind && a.kind === FolderKind) {
|
|
17
|
+
return (a.info.name || '').localeCompare(b.info.name || '');
|
|
18
|
+
}
|
|
19
|
+
return b.lastModified.time - a.lastModified.time;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function fileIcon(item: IFile): IconType | undefined {
|
|
23
|
+
let icon: IconType | undefined;
|
|
24
|
+
switch (item.kind) {
|
|
25
|
+
case DataFileKind: icon = 'schema'; break;
|
|
26
|
+
case FolderKind: icon = 'folder'; break;
|
|
27
|
+
case ProjectKind: icon = 'collectionsBookmark'; break;
|
|
28
|
+
case CertificateFileKind: icon = 'certificate'; break;
|
|
29
|
+
default:
|
|
30
|
+
}
|
|
31
|
+
return icon;
|
|
32
|
+
}
|
package/src/events/EventTypes.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const EventTypes = Object.freeze({
|
|
|
21
21
|
delete: 'storefilesdelete',
|
|
22
22
|
patchUsers: 'storefilespatchusers',
|
|
23
23
|
listUsers: 'storefileslistusers',
|
|
24
|
+
breadcrumbs: 'storefilesbreadcrumbs',
|
|
24
25
|
}),
|
|
25
26
|
User: Object.freeze({
|
|
26
27
|
me: 'storeuserme',
|
|
@@ -48,13 +49,6 @@ export const EventTypes = Object.freeze({
|
|
|
48
49
|
clearProject: 'storeprojectrunsclearproject',
|
|
49
50
|
clearParent: 'storeprojectrunsclearparent',
|
|
50
51
|
}),
|
|
51
|
-
Certificate: Object.freeze({
|
|
52
|
-
read: 'storeclientcertificateread',
|
|
53
|
-
list: 'storeclientcertificatelist',
|
|
54
|
-
delete: 'storeclientcertificatedelete',
|
|
55
|
-
update: 'storeclientcertificateupdate',
|
|
56
|
-
insert: 'storeclientcertificateinsert',
|
|
57
|
-
}),
|
|
58
52
|
}),
|
|
59
53
|
Config: Object.freeze({
|
|
60
54
|
Environment: Object.freeze({
|
|
@@ -181,4 +175,11 @@ export const EventTypes = Object.freeze({
|
|
|
181
175
|
}),
|
|
182
176
|
}),
|
|
183
177
|
}),
|
|
178
|
+
// Filesystem access
|
|
179
|
+
Filesystem: Object.freeze({
|
|
180
|
+
requestSaveFile: 'filesystemrequestsavefile',
|
|
181
|
+
requestOpenFile: 'filesystemrequestopenfile',
|
|
182
|
+
writeFile: 'filesystemwritefile',
|
|
183
|
+
readFile: 'filesystemreadfile',
|
|
184
|
+
}),
|
|
184
185
|
});
|
package/src/events/Events.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { HttpProjectEvents } from './HttpProjectEvents.js';
|
|
|
5
5
|
import { SchemaDesignEvents } from './SchemaDesignEvents.js';
|
|
6
6
|
import { HttpClientEvents } from './HttpClientEvents.js';
|
|
7
7
|
import { HttpEvents } from './HttpEvents.js';
|
|
8
|
+
import { FilesystemEvents } from './FilesystemEvents.js';
|
|
8
9
|
|
|
9
10
|
export const Events = Object.freeze({
|
|
10
11
|
Config: ConfigEvents,
|
|
@@ -14,4 +15,5 @@ export const Events = Object.freeze({
|
|
|
14
15
|
HttpClient: HttpClientEvents,
|
|
15
16
|
SchemaDesign: SchemaDesignEvents,
|
|
16
17
|
Http: HttpEvents,
|
|
18
|
+
Filesystem: FilesystemEvents,
|
|
17
19
|
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { FileReadOptions, FileWriteOptions, IOpenFileDialogInit, IOpenFileDialogResult, ISaveFileDialogInit, ISaveFileDialogResult } from "../bindings/base/FileBindings.js";
|
|
2
|
+
import { EventTypes } from "./EventTypes.js";
|
|
3
|
+
|
|
4
|
+
export const FilesystemEvents = Object.freeze({
|
|
5
|
+
requestSaveFile: async (opts?: ISaveFileDialogInit, target: EventTarget = document.body): Promise<ISaveFileDialogResult | undefined> => {
|
|
6
|
+
const e = new CustomEvent(EventTypes.Filesystem.requestSaveFile, {
|
|
7
|
+
bubbles: true,
|
|
8
|
+
composed: true,
|
|
9
|
+
cancelable: true,
|
|
10
|
+
detail: {
|
|
11
|
+
options: opts,
|
|
12
|
+
result: undefined,
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
target.dispatchEvent(e);
|
|
16
|
+
return ((e.detail.result as unknown) as Promise<ISaveFileDialogResult>);
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
requestOpenFile: async (opts?: IOpenFileDialogInit, target: EventTarget = document.body): Promise<IOpenFileDialogResult | undefined> => {
|
|
20
|
+
const e = new CustomEvent(EventTypes.Filesystem.requestOpenFile, {
|
|
21
|
+
bubbles: true,
|
|
22
|
+
composed: true,
|
|
23
|
+
cancelable: true,
|
|
24
|
+
detail: {
|
|
25
|
+
options: opts,
|
|
26
|
+
result: undefined,
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
target.dispatchEvent(e);
|
|
30
|
+
return ((e.detail.result as unknown) as Promise<IOpenFileDialogResult>);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
writeFile: async (path: string, contents: BufferSource | Blob | string | Buffer, opts?: FileWriteOptions, target: EventTarget = document.body): Promise<void> => {
|
|
34
|
+
const e = new CustomEvent(EventTypes.Filesystem.writeFile, {
|
|
35
|
+
bubbles: true,
|
|
36
|
+
composed: true,
|
|
37
|
+
cancelable: true,
|
|
38
|
+
detail: {
|
|
39
|
+
path,
|
|
40
|
+
contents,
|
|
41
|
+
options: opts,
|
|
42
|
+
result: undefined,
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
target.dispatchEvent(e);
|
|
46
|
+
await ((e.detail.result as unknown) as Promise<void>);
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
readFile: async (path: string, opts?: FileReadOptions, target: EventTarget = document.body): Promise<Buffer | ArrayBuffer | string | undefined> => {
|
|
50
|
+
const e = new CustomEvent(EventTypes.Filesystem.readFile, {
|
|
51
|
+
bubbles: true,
|
|
52
|
+
composed: true,
|
|
53
|
+
cancelable: true,
|
|
54
|
+
detail: {
|
|
55
|
+
path,
|
|
56
|
+
options: opts,
|
|
57
|
+
result: undefined,
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
target.dispatchEvent(e);
|
|
61
|
+
return ((e.detail.result as unknown) as Promise<Buffer | ArrayBuffer | string>);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ContextDeleteEvent, ContextQueryEvent, IQueryResponse, IRequestUiMeta, IUrl } from '@api-client/core/build/browser.js';
|
|
2
2
|
import { EventTypes } from './EventTypes.js';
|
|
3
|
-
import { CertificatesEvents } from './http-client/models/CertificatesEvents.js';
|
|
4
3
|
|
|
5
4
|
export interface IRequestUiInsertDetail {
|
|
6
5
|
pid: string;
|
|
@@ -10,7 +9,6 @@ export interface IRequestUiInsertDetail {
|
|
|
10
9
|
|
|
11
10
|
export const HttpClientEvents = Object.freeze({
|
|
12
11
|
Model: Object.freeze({
|
|
13
|
-
Certificate: CertificatesEvents,
|
|
14
12
|
UrlHistory: Object.freeze({
|
|
15
13
|
/**
|
|
16
14
|
* Adds a new URL to the URL history store.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
IBackendInfo, IFile, IFileCreateOptions,
|
|
4
4
|
ListFileKind, AccessOperation, IUser, IPatchRevision, IApplication, IHttpHistory, IHttpHistoryBulkAdd, HistoryListOptions,
|
|
5
|
-
ContextChangeRecord, ContextDeleteEvent, ContextDeleteBulkEvent, ContextListOptions, ContextListResult, IProjectExecution, IProjectExecutionListOptions, IBulkOperationResult,
|
|
5
|
+
ContextChangeRecord, ContextDeleteEvent, ContextDeleteBulkEvent, ContextListOptions, ContextListResult, IProjectExecution, IProjectExecutionListOptions, IBulkOperationResult, FileBreadcrumb,
|
|
6
6
|
} from '@api-client/core/build/browser.js';
|
|
7
7
|
import { Patch } from '@api-client/json';
|
|
8
8
|
import { IConfigEnvironment, IConfigInit } from '../lib/config/Config.js';
|
|
@@ -371,6 +371,26 @@ export const StoreEvents = Object.freeze({
|
|
|
371
371
|
target.dispatchEvent(e);
|
|
372
372
|
return ((e.detail.result as unknown) as Promise<ContextListResult<IUser>>);
|
|
373
373
|
},
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Lists breadcrumbs to the file.
|
|
377
|
+
*
|
|
378
|
+
* @param fileOrFolder The if of the file or folder to query for.
|
|
379
|
+
* @param options Optional query options.
|
|
380
|
+
*/
|
|
381
|
+
breadcrumbs: async (fileOrFolder: string, target: EventTarget = document.body): Promise<ContextListResult<FileBreadcrumb>> => {
|
|
382
|
+
const e = new CustomEvent(EventTypes.Store.File.breadcrumbs, {
|
|
383
|
+
bubbles: true,
|
|
384
|
+
cancelable: true,
|
|
385
|
+
composed: true,
|
|
386
|
+
detail: {
|
|
387
|
+
key: fileOrFolder,
|
|
388
|
+
result: undefined,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
target.dispatchEvent(e);
|
|
392
|
+
return ((e.detail.result as unknown) as Promise<ContextListResult<FileBreadcrumb>>);
|
|
393
|
+
},
|
|
374
394
|
}),
|
|
375
395
|
/**
|
|
376
396
|
* Reads the current user.
|