@securancy/file-explorer 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/FileExplorer.svelte +122 -104
- package/dist/components/FileExplorer.svelte.d.ts +8 -10
- package/dist/components/FileExplorerBreadcrumb.svelte +15 -14
- package/dist/components/FileExplorerBreadcrumb.svelte.d.ts +2 -4
- package/dist/components/FileExplorerCreateDirectory.svelte +25 -23
- package/dist/components/FileExplorerCreateDirectory.svelte.d.ts +2 -4
- package/dist/components/FileExplorerDirectory.svelte +16 -18
- package/dist/components/FileExplorerDirectory.svelte.d.ts +2 -4
- package/dist/components/FileExplorerDirectoryColumn.svelte +33 -35
- package/dist/components/FileExplorerDirectoryColumn.svelte.d.ts +3 -5
- package/dist/components/FileExplorerDirectoryIndex.svelte +11 -13
- package/dist/components/FileExplorerDirectoryIndex.svelte.d.ts +2 -4
- package/dist/components/FileExplorerDisplayModeSwitcher.svelte +8 -10
- package/dist/components/FileExplorerDisplayModeSwitcher.svelte.d.ts +2 -4
- package/dist/components/FileExplorerFileDetailColumn.svelte +17 -18
- package/dist/components/FileExplorerFileDetailColumn.svelte.d.ts +2 -4
- package/dist/components/FileIcon.svelte +41 -41
- package/dist/components/FileIcon.svelte.d.ts +2 -4
- package/dist/file-explorer.pcss +2 -3
- package/dist/models/file-item.d.ts +2 -2
- package/dist/utilities/file-utilities.d.ts +1 -1
- package/dist/utilities/file-utilities.js +11 -5
- package/package.json +20 -32
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
<script context="module"
|
|
1
|
+
<script context="module">export {};
|
|
2
|
+
</script>
|
|
2
3
|
|
|
3
|
-
<script>import { createEventDispatcher, tick } from
|
|
4
|
-
import FileExplorerBreadcrumb from
|
|
5
|
-
import FileExplorerDisplayModeSwitcher from
|
|
6
|
-
import { defaultTranslations, FileExplorerDisplayMode } from
|
|
7
|
-
import FileExplorerCreateDirectory from
|
|
8
|
-
import { Button, Modal } from
|
|
9
|
-
import FileExplorerDirectory from
|
|
10
|
-
import { Icon } from
|
|
11
|
-
import { fade } from
|
|
4
|
+
<script>import { createEventDispatcher, tick } from 'svelte';
|
|
5
|
+
import FileExplorerBreadcrumb from './FileExplorerBreadcrumb.svelte';
|
|
6
|
+
import FileExplorerDisplayModeSwitcher from './FileExplorerDisplayModeSwitcher.svelte';
|
|
7
|
+
import { defaultTranslations, FileExplorerDisplayMode } from '../index.js';
|
|
8
|
+
import FileExplorerCreateDirectory from './FileExplorerCreateDirectory.svelte';
|
|
9
|
+
import { Button, Modal } from '@securancy/svelte-components';
|
|
10
|
+
import FileExplorerDirectory from './FileExplorerDirectory.svelte';
|
|
11
|
+
import { Icon } from '@securancy/svelte-components';
|
|
12
|
+
import { fade } from 'svelte/transition';
|
|
13
|
+
import { pathsEqual } from '../utilities';
|
|
12
14
|
export let displayMode = FileExplorerDisplayMode.Columns;
|
|
13
15
|
export let filePath;
|
|
14
16
|
export let documents;
|
|
@@ -17,128 +19,146 @@ export let routePrefix;
|
|
|
17
19
|
export let canEdit;
|
|
18
20
|
export let translations = defaultTranslations;
|
|
19
21
|
export let getFilePreview;
|
|
20
|
-
|
|
21
|
-
export let
|
|
22
|
-
|
|
22
|
+
// When provided, it will use the default implementation for creating directories, otherwise it will dispatch an event
|
|
23
|
+
export let createDirectory = undefined;
|
|
24
|
+
// When provided, it will use the default implementation for uploading files, otherwise it will dispatch an event
|
|
25
|
+
export let uploadFiles = undefined;
|
|
26
|
+
// When provided, it will use the default implementation for deleting files, otherwise it will dispatch an event
|
|
27
|
+
export let deleteFile = undefined;
|
|
23
28
|
const dispatch = createEventDispatcher();
|
|
24
29
|
const scrollBackButtonThreshold = 200;
|
|
25
30
|
let fileExplorerContentContainer;
|
|
26
31
|
let showScrollBackButton = false;
|
|
32
|
+
// Create directory state
|
|
27
33
|
let createDirectoryPath;
|
|
28
34
|
let createDirectoryModalOpen = false;
|
|
35
|
+
// Delete item state
|
|
29
36
|
let deleteFileModalOpen = false;
|
|
30
37
|
let deleteFileEvent;
|
|
31
38
|
let deleting = false;
|
|
32
39
|
let overrideFilesModalOpen = false;
|
|
33
40
|
let overrideFiles = [];
|
|
34
41
|
let uploadFilesRequest;
|
|
35
|
-
|
|
42
|
+
// If the route changes, always scroll to the right to show the new column
|
|
43
|
+
$: if (filePath)
|
|
44
|
+
tick().then(() => scrollToRight());
|
|
36
45
|
async function scrollToRight() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
if (!fileExplorerContentContainer)
|
|
47
|
+
return;
|
|
48
|
+
fileExplorerContentContainer.scroll({
|
|
49
|
+
left: fileExplorerContentContainer.scrollWidth,
|
|
50
|
+
behavior: 'smooth',
|
|
51
|
+
});
|
|
42
52
|
}
|
|
43
53
|
function handleScroll() {
|
|
44
|
-
|
|
54
|
+
showScrollBackButton = fileExplorerContentContainer.scrollLeft > scrollBackButtonThreshold;
|
|
45
55
|
}
|
|
46
56
|
function handleScrollBack() {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
fileExplorerContentContainer.scroll({
|
|
58
|
+
left: 0,
|
|
59
|
+
behavior: 'smooth',
|
|
60
|
+
});
|
|
51
61
|
}
|
|
52
62
|
async function handleUploadFile(event) {
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
// When the uploadFiles function is set, use the default implementation
|
|
64
|
+
if (uploadFiles) {
|
|
65
|
+
// If the user has dropped files, upload them
|
|
66
|
+
if (event.detail.files) {
|
|
67
|
+
await uploadFilesInternal({
|
|
68
|
+
path: event.detail.path,
|
|
69
|
+
files: event.detail.files,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// When the user has not dropped files, allow the user to select files from their filesystem
|
|
74
|
+
const input = document.createElement('input');
|
|
75
|
+
input.type = 'file';
|
|
76
|
+
input.multiple = true;
|
|
77
|
+
input.click();
|
|
78
|
+
input.addEventListener('change', async () => {
|
|
79
|
+
if (input.files) {
|
|
80
|
+
await uploadFilesInternal({
|
|
81
|
+
path: event.detail.path,
|
|
82
|
+
files: input.files,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
70
86
|
}
|
|
71
|
-
});
|
|
72
87
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
else {
|
|
89
|
+
// Otherwise, dispatch an event
|
|
90
|
+
dispatch('upload-file', event.detail);
|
|
91
|
+
}
|
|
76
92
|
}
|
|
77
93
|
async function uploadFilesInternal(request) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
const filesInDirectory = Array.from(flattenedFiles($documents)).filter(x => pathsEqual(x.path, request.path));
|
|
95
|
+
const existingFiles = Array.from(request.files).filter(file => filesInDirectory.some(document => document.name === file.name));
|
|
96
|
+
if (existingFiles.length > 0) {
|
|
97
|
+
overrideFiles = existingFiles;
|
|
98
|
+
overrideFilesModalOpen = true;
|
|
99
|
+
uploadFilesRequest = request;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
await uploadFiles(request);
|
|
103
|
+
documents.refresh();
|
|
104
|
+
}
|
|
88
105
|
}
|
|
89
106
|
async function confirmOverrideFiles() {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
await uploadFiles(uploadFilesRequest);
|
|
108
|
+
documents.refresh();
|
|
109
|
+
overrideFilesModalOpen = false;
|
|
110
|
+
overrideFiles = [];
|
|
111
|
+
uploadFilesRequest = undefined;
|
|
95
112
|
}
|
|
96
113
|
async function cancelOverrideFiles() {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
overrideFilesModalOpen = false;
|
|
115
|
+
overrideFiles = [];
|
|
116
|
+
uploadFilesRequest = undefined;
|
|
100
117
|
}
|
|
101
118
|
function handleCreateDirectory(event) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
if (createDirectory) {
|
|
120
|
+
createDirectoryPath = event.detail.path;
|
|
121
|
+
// To avoid closing the modal immediately
|
|
122
|
+
setTimeout(() => createDirectoryModalOpen = true);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
dispatch('create-directory', event.detail);
|
|
126
|
+
}
|
|
108
127
|
}
|
|
109
128
|
function handleDeleteFile(event) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
129
|
+
if (deleteFile) {
|
|
130
|
+
deleteFileEvent = event.detail;
|
|
131
|
+
deleteFileModalOpen = true;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
dispatch('delete-file', event.detail);
|
|
135
|
+
}
|
|
116
136
|
}
|
|
117
137
|
function deleteFileInternal() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
if (deleteFile && deleteFileEvent) {
|
|
139
|
+
deleting = true;
|
|
140
|
+
deleteFile({
|
|
141
|
+
type: 'file',
|
|
142
|
+
...deleteFileEvent,
|
|
143
|
+
}).then(() => {
|
|
144
|
+
documents.refresh();
|
|
145
|
+
deleteFileModalOpen = false;
|
|
146
|
+
}).catch((error) => {
|
|
147
|
+
console.error('Failed to delete item.', error);
|
|
148
|
+
}).finally(() => {
|
|
149
|
+
deleting = false;
|
|
150
|
+
deleteFileModalOpen = false;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
133
153
|
}
|
|
134
|
-
function* flattenedFiles(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
154
|
+
function* flattenedFiles(documents) {
|
|
155
|
+
for (const document of documents) {
|
|
156
|
+
if (document.type === 'file') {
|
|
157
|
+
yield document;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
yield* flattenedFiles(document.children);
|
|
139
161
|
}
|
|
140
|
-
yield* flattenedFiles(document2.children);
|
|
141
|
-
}
|
|
142
162
|
}
|
|
143
163
|
</script>
|
|
144
164
|
|
|
@@ -244,7 +264,7 @@ function* flattenedFiles(documents2) {
|
|
|
244
264
|
{translations.overrideFilesConfirmation}
|
|
245
265
|
</div>
|
|
246
266
|
<div class="file-explorer__text file-explorer__text--semi-bold">
|
|
247
|
-
{overrideFiles.map(
|
|
267
|
+
{overrideFiles.map(file => file.name).join(', ')}
|
|
248
268
|
</div>
|
|
249
269
|
<svelte:fragment slot="footer">
|
|
250
270
|
<Button
|
|
@@ -261,8 +281,7 @@ function* flattenedFiles(documents2) {
|
|
|
261
281
|
</Modal>
|
|
262
282
|
{/if}
|
|
263
283
|
|
|
264
|
-
<style
|
|
265
|
-
/**
|
|
284
|
+
<style>/**
|
|
266
285
|
* Media queries and devices
|
|
267
286
|
*/
|
|
268
287
|
/**
|
|
@@ -322,7 +341,7 @@ function* flattenedFiles(documents2) {
|
|
|
322
341
|
z-index: 1;
|
|
323
342
|
}
|
|
324
343
|
.file-explorer__column::after {
|
|
325
|
-
content:
|
|
344
|
+
content: "";
|
|
326
345
|
position: absolute;
|
|
327
346
|
inset: 0;
|
|
328
347
|
pointer-events: none;
|
|
@@ -369,7 +388,7 @@ function* flattenedFiles(documents2) {
|
|
|
369
388
|
margin-left: auto;
|
|
370
389
|
}
|
|
371
390
|
.file-explorer__search {
|
|
372
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
391
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
373
392
|
}
|
|
374
393
|
.file-explorer__list {
|
|
375
394
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -517,5 +536,4 @@ function* flattenedFiles(documents2) {
|
|
|
517
536
|
min-height: 50px;
|
|
518
537
|
height: 100%;
|
|
519
538
|
font-size: 25px;
|
|
520
|
-
}
|
|
521
|
-
</style>
|
|
539
|
+
}</style>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
export interface UploadFileEvent {
|
|
3
3
|
path: string;
|
|
4
4
|
files?: FileList;
|
|
5
|
-
}
|
|
6
|
-
export
|
|
5
|
+
}
|
|
6
|
+
export interface CreateDirectoryEvent {
|
|
7
7
|
path: string;
|
|
8
|
-
}
|
|
9
|
-
export
|
|
8
|
+
}
|
|
9
|
+
export interface DeleteFileEvent {
|
|
10
10
|
path: string;
|
|
11
11
|
name: string;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
import type { Refreshable } from '@securancy/svelte-utilities';
|
|
14
14
|
import { type CreateDirectoryRequest, FileExplorerDisplayMode, type FileItem, type FilePreview, type FileSystemItem, type UploadFilesRequest } from '../index.js';
|
|
15
15
|
declare const __propDef: {
|
|
@@ -65,12 +65,10 @@ declare const __propDef: {
|
|
|
65
65
|
slots: {
|
|
66
66
|
search: {};
|
|
67
67
|
};
|
|
68
|
-
exports?: {} | undefined;
|
|
69
|
-
bindings?: string | undefined;
|
|
70
68
|
};
|
|
71
69
|
export type FileExplorerProps = typeof __propDef.props;
|
|
72
70
|
export type FileExplorerEvents = typeof __propDef.events;
|
|
73
71
|
export type FileExplorerSlots = typeof __propDef.slots;
|
|
74
|
-
export default class FileExplorer extends
|
|
72
|
+
export default class FileExplorer extends SvelteComponentTyped<FileExplorerProps, FileExplorerEvents, FileExplorerSlots> {
|
|
75
73
|
}
|
|
76
74
|
export {};
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
<script>import { Icon } from
|
|
1
|
+
<script>import { Icon } from '@securancy/svelte-components';
|
|
2
2
|
export let filePath;
|
|
3
3
|
export let routePrefix;
|
|
4
|
-
$: parts = filePath.split(
|
|
5
|
-
function getHref(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
$: parts = filePath.split('/');
|
|
5
|
+
function getHref(parts, index, routePrefix) {
|
|
6
|
+
const href = [
|
|
7
|
+
...routePrefix.split('/'),
|
|
8
|
+
...parts.slice(0, index + 1),
|
|
9
|
+
]
|
|
10
|
+
.filter(node => node !== '')
|
|
11
|
+
.map(encodeURIComponent)
|
|
12
|
+
.join('/');
|
|
13
|
+
return '/' + href;
|
|
11
14
|
}
|
|
12
15
|
</script>
|
|
13
16
|
|
|
@@ -23,8 +26,7 @@ function getHref(parts2, index, routePrefix2) {
|
|
|
23
26
|
{/each}
|
|
24
27
|
</div>
|
|
25
28
|
|
|
26
|
-
<style
|
|
27
|
-
/**
|
|
29
|
+
<style>/**
|
|
28
30
|
* Media queries and devices
|
|
29
31
|
*/
|
|
30
32
|
/**
|
|
@@ -84,7 +86,7 @@ function getHref(parts2, index, routePrefix2) {
|
|
|
84
86
|
z-index: 1;
|
|
85
87
|
}
|
|
86
88
|
.file-explorer__column::after {
|
|
87
|
-
content:
|
|
89
|
+
content: "";
|
|
88
90
|
position: absolute;
|
|
89
91
|
inset: 0;
|
|
90
92
|
pointer-events: none;
|
|
@@ -131,7 +133,7 @@ function getHref(parts2, index, routePrefix2) {
|
|
|
131
133
|
margin-left: auto;
|
|
132
134
|
}
|
|
133
135
|
.file-explorer__search {
|
|
134
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
136
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
135
137
|
}
|
|
136
138
|
.file-explorer__list {
|
|
137
139
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -279,5 +281,4 @@ function getHref(parts2, index, routePrefix2) {
|
|
|
279
281
|
min-height: 50px;
|
|
280
282
|
height: 100%;
|
|
281
283
|
font-size: 25px;
|
|
282
|
-
}
|
|
283
|
-
</style>
|
|
284
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
filePath: string;
|
|
@@ -8,12 +8,10 @@ declare const __propDef: {
|
|
|
8
8
|
[evt: string]: CustomEvent<any>;
|
|
9
9
|
};
|
|
10
10
|
slots: {};
|
|
11
|
-
exports?: {} | undefined;
|
|
12
|
-
bindings?: string | undefined;
|
|
13
11
|
};
|
|
14
12
|
export type FileExplorerBreadcrumbProps = typeof __propDef.props;
|
|
15
13
|
export type FileExplorerBreadcrumbEvents = typeof __propDef.events;
|
|
16
14
|
export type FileExplorerBreadcrumbSlots = typeof __propDef.slots;
|
|
17
|
-
export default class FileExplorerBreadcrumb extends
|
|
15
|
+
export default class FileExplorerBreadcrumb extends SvelteComponentTyped<FileExplorerBreadcrumbProps, FileExplorerBreadcrumbEvents, FileExplorerBreadcrumbSlots> {
|
|
18
16
|
}
|
|
19
17
|
export {};
|
|
@@ -1,33 +1,36 @@
|
|
|
1
|
-
<script>import { Button, FormElement, Modal } from
|
|
1
|
+
<script>import { Button, FormElement, Modal } from '@securancy/svelte-components';
|
|
2
2
|
export let createDirectoryPath;
|
|
3
3
|
export let createDirectoryModalOpen = false;
|
|
4
4
|
export let documents;
|
|
5
5
|
export let createDirectory;
|
|
6
6
|
export let translations;
|
|
7
|
-
let request = { path:
|
|
7
|
+
let request = { path: '', name: '' };
|
|
8
8
|
let submitting = false;
|
|
9
|
-
let input =
|
|
9
|
+
let input = undefined;
|
|
10
10
|
$: existingFoldersInPath = getExistingFoldersInPath(createDirectoryPath, $documents);
|
|
11
|
-
$: directoryAlreadyExists = existingFoldersInPath.some(
|
|
12
|
-
$: request.path = createDirectoryPath ??
|
|
13
|
-
|
|
11
|
+
$: directoryAlreadyExists = existingFoldersInPath.some(x => x.name === request.name);
|
|
12
|
+
$: request.path = createDirectoryPath ?? '';
|
|
13
|
+
// Clear inputs when modal is opened
|
|
14
|
+
$: if (input)
|
|
15
|
+
input.focus();
|
|
14
16
|
async function submitFiles() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
submitting = true;
|
|
18
|
+
await createDirectory(request)
|
|
19
|
+
.then(() => {
|
|
20
|
+
createDirectoryModalOpen = false;
|
|
21
|
+
}).finally(() => {
|
|
22
|
+
submitting = false;
|
|
23
|
+
});
|
|
24
|
+
documents.refresh();
|
|
22
25
|
}
|
|
23
|
-
function getExistingFoldersInPath(path,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
function getExistingFoldersInPath(path, documents) {
|
|
27
|
+
const pathParts = path ? path.split('/') : [];
|
|
28
|
+
let existingFoldersInPath = documents.filter(x => x.type === 'directory');
|
|
29
|
+
for (const pathPart of pathParts) {
|
|
30
|
+
const currentFolder = existingFoldersInPath.find(document => document.name === pathPart);
|
|
31
|
+
existingFoldersInPath = currentFolder ? currentFolder.children.filter(x => x.type === 'directory') : [];
|
|
32
|
+
}
|
|
33
|
+
return existingFoldersInPath;
|
|
31
34
|
}
|
|
32
35
|
</script>
|
|
33
36
|
|
|
@@ -87,5 +90,4 @@ function getExistingFoldersInPath(path, documents2) {
|
|
|
87
90
|
border: 1px solid var(--file-explorer-create-directory-border);
|
|
88
91
|
border-radius: var(--file-explorer-create-directory-border-radius);
|
|
89
92
|
padding: 10px;
|
|
90
|
-
}
|
|
91
|
-
</style>
|
|
93
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { Refreshable } from '@securancy/svelte-utilities';
|
|
3
3
|
import type { CreateDirectoryRequest, DocumentTranslations, FileSystemItem } from '../models/index.js';
|
|
4
4
|
declare const __propDef: {
|
|
@@ -13,12 +13,10 @@ declare const __propDef: {
|
|
|
13
13
|
[evt: string]: CustomEvent<any>;
|
|
14
14
|
};
|
|
15
15
|
slots: {};
|
|
16
|
-
exports?: {} | undefined;
|
|
17
|
-
bindings?: string | undefined;
|
|
18
16
|
};
|
|
19
17
|
export type FileExplorerCreateDirectoryProps = typeof __propDef.props;
|
|
20
18
|
export type FileExplorerCreateDirectoryEvents = typeof __propDef.events;
|
|
21
19
|
export type FileExplorerCreateDirectorySlots = typeof __propDef.slots;
|
|
22
|
-
export default class FileExplorerCreateDirectory extends
|
|
20
|
+
export default class FileExplorerCreateDirectory extends SvelteComponentTyped<FileExplorerCreateDirectoryProps, FileExplorerCreateDirectoryEvents, FileExplorerCreateDirectorySlots> {
|
|
23
21
|
}
|
|
24
22
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<script>import {} from
|
|
2
|
-
import FileExplorerDirectoryColumn from
|
|
3
|
-
import FileExplorerFileDetailColumn from
|
|
4
|
-
import FileExplorerDirectoryIndex from
|
|
1
|
+
<script>import {} from '..';
|
|
2
|
+
import FileExplorerDirectoryColumn from './FileExplorerDirectoryColumn.svelte';
|
|
3
|
+
import FileExplorerFileDetailColumn from './FileExplorerFileDetailColumn.svelte';
|
|
4
|
+
import FileExplorerDirectoryIndex from './FileExplorerDirectoryIndex.svelte';
|
|
5
5
|
export let item;
|
|
6
6
|
export let translations;
|
|
7
7
|
export let routePrefix;
|
|
@@ -9,16 +9,16 @@ export let currentPath;
|
|
|
9
9
|
export let canEdit;
|
|
10
10
|
export let displayMode;
|
|
11
11
|
export let getFilePreview;
|
|
12
|
-
$: currentPathParts = currentPath.split(
|
|
12
|
+
$: currentPathParts = currentPath.split('/');
|
|
13
13
|
$: activeFileItem = item.children.find((fileItem) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const parts = [
|
|
15
|
+
...fileItem.path.split('/').filter(part => part !== ''),
|
|
16
|
+
fileItem.name,
|
|
17
|
+
];
|
|
18
|
+
return parts.every((part, index) => currentPathParts[index] === part);
|
|
19
19
|
});
|
|
20
|
-
function canEditItem(
|
|
21
|
-
|
|
20
|
+
function canEditItem(item, canEdit) {
|
|
21
|
+
return typeof canEdit === 'function' ? canEdit(item) : canEdit === true;
|
|
22
22
|
}
|
|
23
23
|
</script>
|
|
24
24
|
|
|
@@ -69,8 +69,7 @@ function canEditItem(item2, canEdit2) {
|
|
|
69
69
|
/>
|
|
70
70
|
{/if}
|
|
71
71
|
{/if}
|
|
72
|
-
<style
|
|
73
|
-
/**
|
|
72
|
+
<style>/**
|
|
74
73
|
* Media queries and devices
|
|
75
74
|
*/
|
|
76
75
|
/**
|
|
@@ -130,7 +129,7 @@ function canEditItem(item2, canEdit2) {
|
|
|
130
129
|
z-index: 1;
|
|
131
130
|
}
|
|
132
131
|
.file-explorer__column::after {
|
|
133
|
-
content:
|
|
132
|
+
content: "";
|
|
134
133
|
position: absolute;
|
|
135
134
|
inset: 0;
|
|
136
135
|
pointer-events: none;
|
|
@@ -177,7 +176,7 @@ function canEditItem(item2, canEdit2) {
|
|
|
177
176
|
margin-left: auto;
|
|
178
177
|
}
|
|
179
178
|
.file-explorer__search {
|
|
180
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
179
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
181
180
|
}
|
|
182
181
|
.file-explorer__list {
|
|
183
182
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -325,5 +324,4 @@ function canEditItem(item2, canEdit2) {
|
|
|
325
324
|
min-height: 50px;
|
|
326
325
|
height: 100%;
|
|
327
326
|
font-size: 25px;
|
|
328
|
-
}
|
|
329
|
-
</style>
|
|
327
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { FileExplorerDisplayMode, FileSystemItem } from '..';
|
|
3
3
|
import { type DirectoryItem, type DocumentTranslations, type FileItem, type FilePreview } from '..';
|
|
4
4
|
declare const __propDef: {
|
|
@@ -19,12 +19,10 @@ declare const __propDef: {
|
|
|
19
19
|
[evt: string]: CustomEvent<any>;
|
|
20
20
|
};
|
|
21
21
|
slots: {};
|
|
22
|
-
exports?: {} | undefined;
|
|
23
|
-
bindings?: string | undefined;
|
|
24
22
|
};
|
|
25
23
|
export type FileExplorerDirectoryProps = typeof __propDef.props;
|
|
26
24
|
export type FileExplorerDirectoryEvents = typeof __propDef.events;
|
|
27
25
|
export type FileExplorerDirectorySlots = typeof __propDef.slots;
|
|
28
|
-
export default class FileExplorerDirectory extends
|
|
26
|
+
export default class FileExplorerDirectory extends SvelteComponentTyped<FileExplorerDirectoryProps, FileExplorerDirectoryEvents, FileExplorerDirectorySlots> {
|
|
29
27
|
}
|
|
30
28
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<script>import { createEventDispatcher } from
|
|
2
|
-
import {} from
|
|
3
|
-
import { resize, ResizeDirections } from
|
|
4
|
-
import { Icon, Popover, PopoverItem } from
|
|
5
|
-
import { getExtension, getItemHref } from
|
|
6
|
-
import FileIcon from
|
|
7
|
-
import { joinPaths } from
|
|
1
|
+
<script>import { createEventDispatcher } from 'svelte';
|
|
2
|
+
import {} from '..';
|
|
3
|
+
import { resize, ResizeDirections } from '@securancy/svelte-utilities';
|
|
4
|
+
import { Icon, Popover, PopoverItem } from '@securancy/svelte-components';
|
|
5
|
+
import { getExtension, getItemHref } from '../utilities/index.js';
|
|
6
|
+
import FileIcon from './FileIcon.svelte';
|
|
7
|
+
import { joinPaths } from '../utilities/index.js';
|
|
8
8
|
const dispatch = createEventDispatcher();
|
|
9
9
|
export let item;
|
|
10
10
|
export let sticky = false;
|
|
@@ -12,42 +12,42 @@ export let routePrefix;
|
|
|
12
12
|
export let canEdit;
|
|
13
13
|
export let translations;
|
|
14
14
|
export let activeFileItem;
|
|
15
|
-
let dragoverIndex = 0;
|
|
15
|
+
let dragoverIndex = 0; // Incremented/decremented when entering/leaving a child element of the column
|
|
16
16
|
let innerWidth = 0;
|
|
17
17
|
function addItem() {
|
|
18
|
-
|
|
18
|
+
dispatch('upload-file', { path: joinPaths(item.path, item.name) });
|
|
19
19
|
}
|
|
20
20
|
function createDirectory() {
|
|
21
|
-
|
|
21
|
+
dispatch('create-directory', { path: joinPaths(item.path, item.name) });
|
|
22
22
|
}
|
|
23
23
|
function handleDragEnter(event) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
dragoverIndex++;
|
|
27
27
|
}
|
|
28
28
|
function handleDrop(event) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
event.preventDefault();
|
|
30
|
+
event.stopPropagation();
|
|
31
|
+
dragoverIndex = 0;
|
|
32
|
+
const eventData = { path: joinPaths(item.path, item.name) };
|
|
33
|
+
if (event.dataTransfer?.files && event.dataTransfer.files.length > 0) {
|
|
34
|
+
eventData.files = event.dataTransfer.files;
|
|
35
|
+
}
|
|
36
|
+
dispatch('upload-file', eventData);
|
|
37
37
|
}
|
|
38
38
|
function handleDragLeave(event) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
event.preventDefault();
|
|
40
|
+
event.stopPropagation();
|
|
41
|
+
dragoverIndex--;
|
|
42
42
|
}
|
|
43
43
|
function handleDragEnd(event) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
event.stopPropagation();
|
|
46
|
+
dragoverIndex = 0;
|
|
47
47
|
}
|
|
48
48
|
function handleDragOver(event) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
event.stopPropagation();
|
|
51
51
|
}
|
|
52
52
|
</script>
|
|
53
53
|
|
|
@@ -115,8 +115,7 @@ function handleDragOver(event) {
|
|
|
115
115
|
</div>
|
|
116
116
|
</div>
|
|
117
117
|
|
|
118
|
-
<style
|
|
119
|
-
/**
|
|
118
|
+
<style>/**
|
|
120
119
|
* Media queries and devices
|
|
121
120
|
*/
|
|
122
121
|
/**
|
|
@@ -176,7 +175,7 @@ function handleDragOver(event) {
|
|
|
176
175
|
z-index: 1;
|
|
177
176
|
}
|
|
178
177
|
.file-explorer__column::after {
|
|
179
|
-
content:
|
|
178
|
+
content: "";
|
|
180
179
|
position: absolute;
|
|
181
180
|
inset: 0;
|
|
182
181
|
pointer-events: none;
|
|
@@ -223,7 +222,7 @@ function handleDragOver(event) {
|
|
|
223
222
|
margin-left: auto;
|
|
224
223
|
}
|
|
225
224
|
.file-explorer__search {
|
|
226
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
225
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
227
226
|
}
|
|
228
227
|
.file-explorer__list {
|
|
229
228
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -371,5 +370,4 @@ function handleDragOver(event) {
|
|
|
371
370
|
min-height: 50px;
|
|
372
371
|
height: 100%;
|
|
373
372
|
font-size: 25px;
|
|
374
|
-
}
|
|
375
|
-
</style>
|
|
373
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { UploadFileEvent } from './FileExplorer.svelte';
|
|
3
3
|
import { type DirectoryItem, type DocumentTranslations, type FileSystemItem } from '..';
|
|
4
4
|
import type { CreateDirectoryEvent } from './FileExplorer.svelte';
|
|
@@ -12,19 +12,17 @@ declare const __propDef: {
|
|
|
12
12
|
activeFileItem: FileSystemItem | undefined;
|
|
13
13
|
};
|
|
14
14
|
events: {
|
|
15
|
-
'scroll-back': CustomEvent<
|
|
15
|
+
'scroll-back': CustomEvent<undefined>;
|
|
16
16
|
'upload-file': CustomEvent<UploadFileEvent>;
|
|
17
17
|
'create-directory': CustomEvent<CreateDirectoryEvent>;
|
|
18
18
|
} & {
|
|
19
19
|
[evt: string]: CustomEvent<any>;
|
|
20
20
|
};
|
|
21
21
|
slots: {};
|
|
22
|
-
exports?: {} | undefined;
|
|
23
|
-
bindings?: string | undefined;
|
|
24
22
|
};
|
|
25
23
|
export type FileExplorerDirectoryColumnProps = typeof __propDef.props;
|
|
26
24
|
export type FileExplorerDirectoryColumnEvents = typeof __propDef.events;
|
|
27
25
|
export type FileExplorerDirectoryColumnSlots = typeof __propDef.slots;
|
|
28
|
-
export default class FileExplorerDirectoryColumn extends
|
|
26
|
+
export default class FileExplorerDirectoryColumn extends SvelteComponentTyped<FileExplorerDirectoryColumnProps, FileExplorerDirectoryColumnEvents, FileExplorerDirectoryColumnSlots> {
|
|
29
27
|
}
|
|
30
28
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<script>import FileIcon from
|
|
2
|
-
import { createEventDispatcher } from
|
|
3
|
-
import { resize, ResizeDirections } from
|
|
4
|
-
import { Icon, Popover, PopoverItem } from
|
|
5
|
-
import { getExtension, getItemHref, joinPaths } from
|
|
1
|
+
<script>import FileIcon from './FileIcon.svelte';
|
|
2
|
+
import { createEventDispatcher } from 'svelte';
|
|
3
|
+
import { resize, ResizeDirections } from '@securancy/svelte-utilities';
|
|
4
|
+
import { Icon, Popover, PopoverItem } from '@securancy/svelte-components';
|
|
5
|
+
import { getExtension, getItemHref, joinPaths } from '../utilities/index.js';
|
|
6
6
|
const dispatch = createEventDispatcher();
|
|
7
7
|
export let item;
|
|
8
8
|
export let routePrefix;
|
|
@@ -11,10 +11,10 @@ export let canEdit;
|
|
|
11
11
|
export let activeFileItem;
|
|
12
12
|
let innerWidth = 0;
|
|
13
13
|
function addItem() {
|
|
14
|
-
|
|
14
|
+
dispatch('upload-file', { path: joinPaths(item.path, item.name) });
|
|
15
15
|
}
|
|
16
16
|
function createDirectory() {
|
|
17
|
-
|
|
17
|
+
dispatch('create-directory', { path: joinPaths(item.path, item.name) });
|
|
18
18
|
}
|
|
19
19
|
</script>
|
|
20
20
|
|
|
@@ -74,8 +74,7 @@ function createDirectory() {
|
|
|
74
74
|
</div>
|
|
75
75
|
{/if}
|
|
76
76
|
|
|
77
|
-
<style
|
|
78
|
-
/**
|
|
77
|
+
<style>/**
|
|
79
78
|
* Media queries and devices
|
|
80
79
|
*/
|
|
81
80
|
/**
|
|
@@ -135,7 +134,7 @@ function createDirectory() {
|
|
|
135
134
|
z-index: 1;
|
|
136
135
|
}
|
|
137
136
|
.file-explorer__column::after {
|
|
138
|
-
content:
|
|
137
|
+
content: "";
|
|
139
138
|
position: absolute;
|
|
140
139
|
inset: 0;
|
|
141
140
|
pointer-events: none;
|
|
@@ -182,7 +181,7 @@ function createDirectory() {
|
|
|
182
181
|
margin-left: auto;
|
|
183
182
|
}
|
|
184
183
|
.file-explorer__search {
|
|
185
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
184
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
186
185
|
}
|
|
187
186
|
.file-explorer__list {
|
|
188
187
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -330,5 +329,4 @@ function createDirectory() {
|
|
|
330
329
|
min-height: 50px;
|
|
331
330
|
height: 100%;
|
|
332
331
|
font-size: 25px;
|
|
333
|
-
}
|
|
334
|
-
</style>
|
|
332
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { DirectoryItem, DocumentTranslations, FileSystemItem } from '../index.js';
|
|
3
3
|
import type { CreateDirectoryEvent, UploadFileEvent } from './FileExplorer.svelte';
|
|
4
4
|
declare const __propDef: {
|
|
@@ -16,12 +16,10 @@ declare const __propDef: {
|
|
|
16
16
|
[evt: string]: CustomEvent<any>;
|
|
17
17
|
};
|
|
18
18
|
slots: {};
|
|
19
|
-
exports?: {} | undefined;
|
|
20
|
-
bindings?: string | undefined;
|
|
21
19
|
};
|
|
22
20
|
export type FileExplorerDirectoryIndexProps = typeof __propDef.props;
|
|
23
21
|
export type FileExplorerDirectoryIndexEvents = typeof __propDef.events;
|
|
24
22
|
export type FileExplorerDirectoryIndexSlots = typeof __propDef.slots;
|
|
25
|
-
export default class FileExplorerDirectoryIndex extends
|
|
23
|
+
export default class FileExplorerDirectoryIndex extends SvelteComponentTyped<FileExplorerDirectoryIndexProps, FileExplorerDirectoryIndexEvents, FileExplorerDirectoryIndexSlots> {
|
|
26
24
|
}
|
|
27
25
|
export {};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<script>import { FileExplorerDisplayMode } from
|
|
2
|
-
import { Icon } from
|
|
1
|
+
<script>import { FileExplorerDisplayMode } from '../index.js';
|
|
2
|
+
import { Icon } from '@securancy/svelte-components';
|
|
3
3
|
export let displayMode;
|
|
4
4
|
export let translations;
|
|
5
5
|
let modes = Object.values(FileExplorerDisplayMode);
|
|
6
6
|
const modeIcons = {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
columns: 'fa-columns-3',
|
|
8
|
+
index: 'fa-grid',
|
|
9
9
|
};
|
|
10
10
|
</script>
|
|
11
11
|
|
|
@@ -25,8 +25,7 @@ const modeIcons = {
|
|
|
25
25
|
{/each}
|
|
26
26
|
</div>
|
|
27
27
|
|
|
28
|
-
<style
|
|
29
|
-
/**
|
|
28
|
+
<style>/**
|
|
30
29
|
* Media queries and devices
|
|
31
30
|
*/
|
|
32
31
|
/**
|
|
@@ -86,7 +85,7 @@ const modeIcons = {
|
|
|
86
85
|
z-index: 1;
|
|
87
86
|
}
|
|
88
87
|
.file-explorer__column::after {
|
|
89
|
-
content:
|
|
88
|
+
content: "";
|
|
90
89
|
position: absolute;
|
|
91
90
|
inset: 0;
|
|
92
91
|
pointer-events: none;
|
|
@@ -133,7 +132,7 @@ const modeIcons = {
|
|
|
133
132
|
margin-left: auto;
|
|
134
133
|
}
|
|
135
134
|
.file-explorer__search {
|
|
136
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
135
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
137
136
|
}
|
|
138
137
|
.file-explorer__list {
|
|
139
138
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -296,5 +295,4 @@ input[type="radio"] {
|
|
|
296
295
|
}
|
|
297
296
|
input[type="radio"]:checked + :global(i) {
|
|
298
297
|
color: var(--file-explorer-action-primary-color);
|
|
299
|
-
}
|
|
300
|
-
</style>
|
|
298
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import { type DocumentTranslations, FileExplorerDisplayMode } from '../index.js';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
@@ -9,12 +9,10 @@ declare const __propDef: {
|
|
|
9
9
|
[evt: string]: CustomEvent<any>;
|
|
10
10
|
};
|
|
11
11
|
slots: {};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
12
|
};
|
|
15
13
|
export type FileExplorerDisplayModeSwitcherProps = typeof __propDef.props;
|
|
16
14
|
export type FileExplorerDisplayModeSwitcherEvents = typeof __propDef.events;
|
|
17
15
|
export type FileExplorerDisplayModeSwitcherSlots = typeof __propDef.slots;
|
|
18
|
-
export default class FileExplorerDisplayModeSwitcher extends
|
|
16
|
+
export default class FileExplorerDisplayModeSwitcher extends SvelteComponentTyped<FileExplorerDisplayModeSwitcherProps, FileExplorerDisplayModeSwitcherEvents, FileExplorerDisplayModeSwitcherSlots> {
|
|
19
17
|
}
|
|
20
18
|
export {};
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
<script>import { Card, Icon } from
|
|
2
|
-
import FileIcon from
|
|
3
|
-
import { resize, ResizeDirections } from
|
|
4
|
-
import { formatBytes, getExtension, isImage } from
|
|
5
|
-
import { DateTime } from
|
|
6
|
-
import { createEventDispatcher } from
|
|
1
|
+
<script>import { Card, Icon } from '@securancy/svelte-components';
|
|
2
|
+
import FileIcon from './FileIcon.svelte';
|
|
3
|
+
import { resize, ResizeDirections } from '@securancy/svelte-utilities';
|
|
4
|
+
import { formatBytes, getExtension, isImage } from '../utilities/index.js';
|
|
5
|
+
import { DateTime } from 'luxon';
|
|
6
|
+
import { createEventDispatcher } from 'svelte';
|
|
7
7
|
export let fileItem;
|
|
8
8
|
export let getFilePreview;
|
|
9
9
|
export let translations;
|
|
10
10
|
export let canEdit;
|
|
11
11
|
const dispatch = createEventDispatcher();
|
|
12
|
-
const fileDateFormat =
|
|
12
|
+
const fileDateFormat = 'cccc FF';
|
|
13
13
|
let filePreview;
|
|
14
14
|
let extension;
|
|
15
15
|
$: refresh(fileItem);
|
|
16
16
|
async function refresh(_fileItem) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
filePreview = await getFilePreview(_fileItem)
|
|
18
|
+
.catch((error) => {
|
|
19
|
+
console.error(error);
|
|
20
|
+
return undefined;
|
|
21
|
+
});
|
|
22
|
+
extension = getExtension(_fileItem.name);
|
|
22
23
|
}
|
|
23
24
|
</script>
|
|
24
25
|
|
|
@@ -86,8 +87,7 @@ async function refresh(_fileItem) {
|
|
|
86
87
|
</div>
|
|
87
88
|
</div>
|
|
88
89
|
|
|
89
|
-
<style
|
|
90
|
-
/**
|
|
90
|
+
<style>/**
|
|
91
91
|
* Media queries and devices
|
|
92
92
|
*/
|
|
93
93
|
/**
|
|
@@ -147,7 +147,7 @@ async function refresh(_fileItem) {
|
|
|
147
147
|
z-index: 1;
|
|
148
148
|
}
|
|
149
149
|
.file-explorer__column::after {
|
|
150
|
-
content:
|
|
150
|
+
content: "";
|
|
151
151
|
position: absolute;
|
|
152
152
|
inset: 0;
|
|
153
153
|
pointer-events: none;
|
|
@@ -194,7 +194,7 @@ async function refresh(_fileItem) {
|
|
|
194
194
|
margin-left: auto;
|
|
195
195
|
}
|
|
196
196
|
.file-explorer__search {
|
|
197
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
197
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
198
198
|
}
|
|
199
199
|
.file-explorer__list {
|
|
200
200
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -342,5 +342,4 @@ async function refresh(_fileItem) {
|
|
|
342
342
|
min-height: 50px;
|
|
343
343
|
height: 100%;
|
|
344
344
|
font-size: 25px;
|
|
345
|
-
}
|
|
346
|
-
</style>
|
|
345
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
import type { DocumentTranslations, FileItem, FilePreview } from '..';
|
|
3
3
|
import type { DeleteFileEvent } from './FileExplorer.svelte';
|
|
4
4
|
declare const __propDef: {
|
|
@@ -14,12 +14,10 @@ declare const __propDef: {
|
|
|
14
14
|
[evt: string]: CustomEvent<any>;
|
|
15
15
|
};
|
|
16
16
|
slots: {};
|
|
17
|
-
exports?: {} | undefined;
|
|
18
|
-
bindings?: string | undefined;
|
|
19
17
|
};
|
|
20
18
|
export type FileExplorerFileDetailColumnProps = typeof __propDef.props;
|
|
21
19
|
export type FileExplorerFileDetailColumnEvents = typeof __propDef.events;
|
|
22
20
|
export type FileExplorerFileDetailColumnSlots = typeof __propDef.slots;
|
|
23
|
-
export default class FileExplorerFileDetailColumn extends
|
|
21
|
+
export default class FileExplorerFileDetailColumn extends SvelteComponentTyped<FileExplorerFileDetailColumnProps, FileExplorerFileDetailColumnEvents, FileExplorerFileDetailColumnSlots> {
|
|
24
22
|
}
|
|
25
23
|
export {};
|
|
@@ -1,43 +1,45 @@
|
|
|
1
|
-
<script>import { Icon } from
|
|
2
|
-
import { imageExtensions, videoExtensions } from
|
|
1
|
+
<script>import { Icon } from '@securancy/svelte-components';
|
|
2
|
+
import { imageExtensions, videoExtensions } from '../utilities/index.js';
|
|
3
3
|
export let extension;
|
|
4
|
-
export let size =
|
|
4
|
+
export let size = 'default';
|
|
5
5
|
let iconClass;
|
|
6
6
|
$: iconClass = determineIconString(extension);
|
|
7
7
|
function determineIconString(_extension) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
if (imageExtensions.includes(_extension))
|
|
9
|
+
return 'fa-file-image';
|
|
10
|
+
if (videoExtensions.includes(_extension))
|
|
11
|
+
return 'fa-file-video';
|
|
12
|
+
switch (_extension) {
|
|
13
|
+
case 'pdf': {
|
|
14
|
+
return 'fa-file-pdf';
|
|
15
|
+
}
|
|
16
|
+
case 'doc':
|
|
17
|
+
case 'docx': {
|
|
18
|
+
return 'fa-file-word';
|
|
19
|
+
}
|
|
20
|
+
case 'xls':
|
|
21
|
+
case 'xlsx': {
|
|
22
|
+
return 'fa-file-spreadsheet';
|
|
23
|
+
}
|
|
24
|
+
case 'ppt':
|
|
25
|
+
case 'pptx': {
|
|
26
|
+
return 'fa-file-powerpoint';
|
|
27
|
+
}
|
|
28
|
+
case 'csv': {
|
|
29
|
+
return 'fa-file-csv';
|
|
30
|
+
}
|
|
31
|
+
case 'txt': {
|
|
32
|
+
return 'fa-file-lines';
|
|
33
|
+
}
|
|
34
|
+
case 'zip':
|
|
35
|
+
case 'tar':
|
|
36
|
+
case 'rar': {
|
|
37
|
+
return 'fa-file-zipper';
|
|
38
|
+
}
|
|
39
|
+
default: {
|
|
40
|
+
return 'fa-file';
|
|
41
|
+
}
|
|
13
42
|
}
|
|
14
|
-
case "doc":
|
|
15
|
-
case "docx": {
|
|
16
|
-
return "fa-file-word";
|
|
17
|
-
}
|
|
18
|
-
case "xls":
|
|
19
|
-
case "xlsx": {
|
|
20
|
-
return "fa-file-spreadsheet";
|
|
21
|
-
}
|
|
22
|
-
case "ppt":
|
|
23
|
-
case "pptx": {
|
|
24
|
-
return "fa-file-powerpoint";
|
|
25
|
-
}
|
|
26
|
-
case "csv": {
|
|
27
|
-
return "fa-file-csv";
|
|
28
|
-
}
|
|
29
|
-
case "txt": {
|
|
30
|
-
return "fa-file-lines";
|
|
31
|
-
}
|
|
32
|
-
case "zip":
|
|
33
|
-
case "tar":
|
|
34
|
-
case "rar": {
|
|
35
|
-
return "fa-file-zipper";
|
|
36
|
-
}
|
|
37
|
-
default: {
|
|
38
|
-
return "fa-file";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
43
|
}
|
|
42
44
|
</script>
|
|
43
45
|
|
|
@@ -53,8 +55,7 @@ function determineIconString(_extension) {
|
|
|
53
55
|
{/if}
|
|
54
56
|
{/if}
|
|
55
57
|
|
|
56
|
-
<style
|
|
57
|
-
/**
|
|
58
|
+
<style>/**
|
|
58
59
|
* Media queries and devices
|
|
59
60
|
*/
|
|
60
61
|
/**
|
|
@@ -114,7 +115,7 @@ function determineIconString(_extension) {
|
|
|
114
115
|
z-index: 1;
|
|
115
116
|
}
|
|
116
117
|
.file-explorer__column::after {
|
|
117
|
-
content:
|
|
118
|
+
content: "";
|
|
118
119
|
position: absolute;
|
|
119
120
|
inset: 0;
|
|
120
121
|
pointer-events: none;
|
|
@@ -161,7 +162,7 @@ function determineIconString(_extension) {
|
|
|
161
162
|
margin-left: auto;
|
|
162
163
|
}
|
|
163
164
|
.file-explorer__search {
|
|
164
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
165
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
165
166
|
}
|
|
166
167
|
.file-explorer__list {
|
|
167
168
|
margin-bottom: var(--file-explorer-default-spacing);
|
|
@@ -309,5 +310,4 @@ function determineIconString(_extension) {
|
|
|
309
310
|
min-height: 50px;
|
|
310
311
|
height: 100%;
|
|
311
312
|
font-size: 25px;
|
|
312
|
-
}
|
|
313
|
-
</style>
|
|
313
|
+
}</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
extension: string;
|
|
@@ -8,12 +8,10 @@ declare const __propDef: {
|
|
|
8
8
|
[evt: string]: CustomEvent<any>;
|
|
9
9
|
};
|
|
10
10
|
slots: {};
|
|
11
|
-
exports?: {} | undefined;
|
|
12
|
-
bindings?: string | undefined;
|
|
13
11
|
};
|
|
14
12
|
export type FileIconProps = typeof __propDef.props;
|
|
15
13
|
export type FileIconEvents = typeof __propDef.events;
|
|
16
14
|
export type FileIconSlots = typeof __propDef.slots;
|
|
17
|
-
export default class FileIcon extends
|
|
15
|
+
export default class FileIcon extends SvelteComponentTyped<FileIconProps, FileIconEvents, FileIconSlots> {
|
|
18
16
|
}
|
|
19
17
|
export {};
|
package/dist/file-explorer.pcss
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
1
|
@import url("@securancy/svelte-components/styles/custom-media.pcss");
|
|
3
2
|
|
|
4
3
|
.file-explorer {
|
|
@@ -64,7 +63,7 @@
|
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
&::after {
|
|
67
|
-
content:
|
|
66
|
+
content: "";
|
|
68
67
|
position: absolute;
|
|
69
68
|
inset: 0;
|
|
70
69
|
pointer-events: none;
|
|
@@ -121,7 +120,7 @@
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
&__search {
|
|
124
|
-
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0
|
|
123
|
+
padding: calc(var(--file-explorer-default-spacing) * 0.5) calc(var(--file-explorer-default-spacing) * 0.5) 0;
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
&__list {
|
|
@@ -5,5 +5,5 @@ export declare const imageExtensions: string[];
|
|
|
5
5
|
export declare const videoExtensions: string[];
|
|
6
6
|
export declare function isImage(path: string): boolean;
|
|
7
7
|
export declare function formatBytes(bytes: number, decimals?: number): string;
|
|
8
|
-
export declare function formatBytesParts(bytes: number, decimals?: number): [number, string];
|
|
9
8
|
export declare function joinPaths(...paths: string[]): string;
|
|
9
|
+
export declare function pathsEqual(path1: string, path2: string): boolean;
|
|
@@ -4,7 +4,7 @@ export function getItemHref(item, routePrefix) {
|
|
|
4
4
|
...item.path.split('/'),
|
|
5
5
|
item.name,
|
|
6
6
|
]
|
|
7
|
-
.filter(
|
|
7
|
+
.filter(node => node !== '')
|
|
8
8
|
.map(encodeURIComponent)
|
|
9
9
|
.join('/');
|
|
10
10
|
return itemPath.startsWith('/') ? itemPath : `/${itemPath}`;
|
|
@@ -37,17 +37,23 @@ export function formatBytes(bytes, decimals = 2) {
|
|
|
37
37
|
const values = formatBytesParts(bytes, decimals);
|
|
38
38
|
return `${values[0]} ${values[1]}`;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
function formatBytesParts(bytes, decimals = 2) {
|
|
41
41
|
if (bytes === 0)
|
|
42
42
|
return [0, 'Bytes'];
|
|
43
43
|
const k = 1000;
|
|
44
|
-
const dm = decimals
|
|
44
|
+
const dm = Math.max(decimals, 0);
|
|
45
45
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
46
46
|
const index = Math.floor(Math.log(bytes) / Math.log(k));
|
|
47
47
|
return [Number.parseFloat((bytes / Math.pow(k, index)).toFixed(dm)), sizes[index]];
|
|
48
48
|
}
|
|
49
49
|
export function joinPaths(...paths) {
|
|
50
|
-
return
|
|
51
|
-
.map(
|
|
50
|
+
return paths
|
|
51
|
+
.map(path => path.split('/').filter(part => part !== '').join('/'))
|
|
52
|
+
.filter(path => path !== '')
|
|
52
53
|
.join('/');
|
|
53
54
|
}
|
|
55
|
+
export function pathsEqual(path1, path2) {
|
|
56
|
+
const path1Parts = path1.split('/').filter(part => part !== '');
|
|
57
|
+
const path2Parts = path2.split('/').filter(part => part !== '');
|
|
58
|
+
return path1Parts.length === path2Parts.length && path1Parts.every((part, index) => part === path2Parts[index]);
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@securancy/file-explorer",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -19,40 +19,32 @@
|
|
|
19
19
|
"!dist/**/*.spec.*"
|
|
20
20
|
],
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@faker-js/faker": "^
|
|
23
|
-
"@sveltejs/adapter-auto": "^3.2.
|
|
24
|
-
"@sveltejs/kit": "^2.
|
|
25
|
-
"@sveltejs/package": "^2.3.
|
|
26
|
-
"@sveltejs/vite-plugin-svelte": "^3.1.
|
|
22
|
+
"@faker-js/faker": "^9.0.3",
|
|
23
|
+
"@sveltejs/adapter-auto": "^3.2.5",
|
|
24
|
+
"@sveltejs/kit": "^2.7.2",
|
|
25
|
+
"@sveltejs/package": "^2.3.5",
|
|
26
|
+
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
|
27
27
|
"@types/luxon": "^3.4.2",
|
|
28
|
-
"autoprefixer": "^10.4.
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"postcss": "^8.4.39",
|
|
33
|
-
"postcss-custom-media": "^10.0.8",
|
|
28
|
+
"autoprefixer": "^10.4.20",
|
|
29
|
+
"luxon": "^3.5.0",
|
|
30
|
+
"postcss": "^8.4.47",
|
|
31
|
+
"postcss-custom-media": "^11.0.3",
|
|
34
32
|
"postcss-each": "^1.1.0",
|
|
35
33
|
"postcss-easy-import": "^4.0.0",
|
|
36
34
|
"postcss-extend": "^1.0.5",
|
|
37
35
|
"postcss-for": "^2.1.1",
|
|
38
|
-
"postcss-mixins": "^
|
|
36
|
+
"postcss-mixins": "^11.0.3",
|
|
39
37
|
"postcss-nested": "^6.2.0",
|
|
40
38
|
"postcss-nested-ancestors": "^3.0.0",
|
|
41
|
-
"publint": "^0.2.
|
|
42
|
-
"svelte": "^4.2.
|
|
43
|
-
"svelte-check": "^
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"typescript": "^5.
|
|
47
|
-
"vite": "^5.
|
|
48
|
-
"
|
|
49
|
-
"@securancy/
|
|
50
|
-
"@securancy/svelte-components": "4.3.1",
|
|
51
|
-
"@securancy/stylelint-config": "0.1.2",
|
|
52
|
-
"@securancy/svelte-utilities": "2.0.2"
|
|
53
|
-
},
|
|
54
|
-
"peerDependencies": {
|
|
55
|
-
"svelte": "^4.2.18"
|
|
39
|
+
"publint": "^0.2.11",
|
|
40
|
+
"svelte": "^4.2.19",
|
|
41
|
+
"svelte-check": "^4.0.5",
|
|
42
|
+
"svelte-preprocess": "^6.0.3",
|
|
43
|
+
"the-new-css-reset": "^1.11.3",
|
|
44
|
+
"typescript": "^5.6.3",
|
|
45
|
+
"vite": "^5.4.9",
|
|
46
|
+
"@securancy/svelte-components": "4.5.0",
|
|
47
|
+
"@securancy/svelte-utilities": "2.2.0"
|
|
56
48
|
},
|
|
57
49
|
"scripts": {
|
|
58
50
|
"dev": "vite dev",
|
|
@@ -62,10 +54,6 @@
|
|
|
62
54
|
"preview": "vite preview",
|
|
63
55
|
"package": "svelte-package && publint",
|
|
64
56
|
"package-watch": "svelte-package -w",
|
|
65
|
-
"lint": "eslint \"./**/*.*{ts,js,svelte,json}\" --config ../../.eslintrc.json --ignore-path ../../.eslintignore",
|
|
66
|
-
"lint-fix": "npm run lint -- --fix",
|
|
67
|
-
"stylelint": "stylelint \"src/**/*.{pcss,svelte,css}\" --config ../../.stylelintrc.json",
|
|
68
|
-
"stylelint-fix": "npm run stylelint -- --fix",
|
|
69
57
|
"svelte-check": "svelte-check --fail-on-warnings --compiler-warnings \"css-unused-selector:ignore\""
|
|
70
58
|
}
|
|
71
59
|
}
|