@securancy/file-explorer 1.0.3 → 1.0.5
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 +67 -7
- package/dist/components/FileExplorer.svelte.d.ts +21 -11
- package/dist/components/FileExplorerCreateDirectory.svelte +12 -14
- package/dist/components/FileExplorerCreateDirectory.svelte.d.ts +1 -1
- package/dist/components/FileExplorerDirectory.svelte +8 -2
- package/dist/components/FileExplorerDirectoryColumn.svelte +5 -6
- package/dist/components/FileExplorerDirectoryIndex.svelte +5 -6
- package/dist/components/FileExplorerDisplayModeSwitcher.svelte +3 -6
- package/dist/components/FileExplorerDisplayModeSwitcher.svelte.d.ts +2 -1
- package/dist/components/FileExplorerFileDetailColumn.svelte +1 -1
- package/dist/models/translations.d.ts +21 -11
- package/dist/models/translations.js +21 -11
- package/dist/utilities/file-utilities.d.ts +1 -1
- package/dist/utilities/file-utilities.js +4 -5
- package/package.json +4 -5
|
@@ -29,6 +29,9 @@ let createDirectoryModalOpen = false;
|
|
|
29
29
|
let deleteFileModalOpen = false;
|
|
30
30
|
let deleteFileEvent;
|
|
31
31
|
let deleting = false;
|
|
32
|
+
let overrideFilesModalOpen = false;
|
|
33
|
+
let overrideFiles = [];
|
|
34
|
+
let uploadFilesRequest;
|
|
32
35
|
$: if (filePath) tick().then(() => scrollToRight());
|
|
33
36
|
async function scrollToRight() {
|
|
34
37
|
if (!fileExplorerContentContainer) return;
|
|
@@ -49,23 +52,21 @@ function handleScrollBack() {
|
|
|
49
52
|
async function handleUploadFile(event) {
|
|
50
53
|
if (uploadFiles) {
|
|
51
54
|
if (event.detail.files) {
|
|
52
|
-
await
|
|
55
|
+
await uploadFilesInternal({
|
|
53
56
|
path: event.detail.path,
|
|
54
57
|
files: event.detail.files
|
|
55
58
|
});
|
|
56
|
-
documents.refresh();
|
|
57
59
|
} else {
|
|
58
60
|
const input = document.createElement("input");
|
|
59
61
|
input.type = "file";
|
|
60
62
|
input.multiple = true;
|
|
61
63
|
input.click();
|
|
62
|
-
input.addEventListener("change", async (
|
|
63
|
-
if (input.files
|
|
64
|
-
await
|
|
64
|
+
input.addEventListener("change", async () => {
|
|
65
|
+
if (input.files) {
|
|
66
|
+
await uploadFilesInternal({
|
|
65
67
|
path: event.detail.path,
|
|
66
68
|
files: input.files
|
|
67
69
|
});
|
|
68
|
-
documents.refresh();
|
|
69
70
|
}
|
|
70
71
|
});
|
|
71
72
|
}
|
|
@@ -73,6 +74,30 @@ async function handleUploadFile(event) {
|
|
|
73
74
|
dispatch("upload-file", event.detail);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
77
|
+
async function uploadFilesInternal(request) {
|
|
78
|
+
const filesInDirectory = Array.from(flattenedFiles($documents)).filter((x) => x.path === request.path);
|
|
79
|
+
const existingFiles = Array.from(request.files).filter((file) => filesInDirectory.some((document2) => document2.name === file.name));
|
|
80
|
+
if (existingFiles.length > 0) {
|
|
81
|
+
overrideFiles = existingFiles;
|
|
82
|
+
overrideFilesModalOpen = true;
|
|
83
|
+
uploadFilesRequest = request;
|
|
84
|
+
} else {
|
|
85
|
+
await uploadFiles(request);
|
|
86
|
+
documents.refresh();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function confirmOverrideFiles() {
|
|
90
|
+
await uploadFiles(uploadFilesRequest);
|
|
91
|
+
documents.refresh();
|
|
92
|
+
overrideFilesModalOpen = false;
|
|
93
|
+
overrideFiles = [];
|
|
94
|
+
uploadFilesRequest = void 0;
|
|
95
|
+
}
|
|
96
|
+
async function cancelOverrideFiles() {
|
|
97
|
+
overrideFilesModalOpen = false;
|
|
98
|
+
overrideFiles = [];
|
|
99
|
+
uploadFilesRequest = void 0;
|
|
100
|
+
}
|
|
76
101
|
function handleCreateDirectory(event) {
|
|
77
102
|
if (createDirectory) {
|
|
78
103
|
createDirectoryPath = event.detail.path;
|
|
@@ -106,12 +131,21 @@ function deleteFileInternal() {
|
|
|
106
131
|
});
|
|
107
132
|
}
|
|
108
133
|
}
|
|
134
|
+
function* flattenedFiles(documents2) {
|
|
135
|
+
for (const document2 of documents2) {
|
|
136
|
+
if (document2.type === "file") {
|
|
137
|
+
yield document2;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
yield* flattenedFiles(document2.children);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
109
143
|
</script>
|
|
110
144
|
|
|
111
145
|
<div class="file-explorer file-explorer--display-mode-{displayMode}">
|
|
112
146
|
<div class="file-explorer__controls">
|
|
113
147
|
<FileExplorerBreadcrumb {filePath} {routePrefix} />
|
|
114
|
-
<FileExplorerDisplayModeSwitcher bind:displayMode />
|
|
148
|
+
<FileExplorerDisplayModeSwitcher {translations} bind:displayMode />
|
|
115
149
|
</div>
|
|
116
150
|
{#if $$slots.search}
|
|
117
151
|
<div class="file-explorer__search">
|
|
@@ -201,6 +235,32 @@ function deleteFileInternal() {
|
|
|
201
235
|
</Modal>
|
|
202
236
|
{/if}
|
|
203
237
|
|
|
238
|
+
{#if overrideFilesModalOpen}
|
|
239
|
+
<Modal
|
|
240
|
+
title={translations.overrideFiles}
|
|
241
|
+
bind:opened={overrideFilesModalOpen}
|
|
242
|
+
>
|
|
243
|
+
<div>
|
|
244
|
+
{translations.overrideFilesConfirmation}
|
|
245
|
+
</div>
|
|
246
|
+
<div class="file-explorer__text file-explorer__text--semi-bold">
|
|
247
|
+
{overrideFiles.map((file) => file.name).join(', ')}
|
|
248
|
+
</div>
|
|
249
|
+
<svelte:fragment slot="footer">
|
|
250
|
+
<Button
|
|
251
|
+
color="soft"
|
|
252
|
+
fill="clear"
|
|
253
|
+
on:click={cancelOverrideFiles}
|
|
254
|
+
>
|
|
255
|
+
{translations.cancel}
|
|
256
|
+
</Button>
|
|
257
|
+
<Button color="danger" on:click={confirmOverrideFiles}>
|
|
258
|
+
{translations.override}
|
|
259
|
+
</Button>
|
|
260
|
+
</svelte:fragment>
|
|
261
|
+
</Modal>
|
|
262
|
+
{/if}
|
|
263
|
+
|
|
204
264
|
<style>/* eslint-disable */
|
|
205
265
|
/**
|
|
206
266
|
* Media queries and devices
|
|
@@ -21,24 +21,34 @@ declare const __propDef: {
|
|
|
21
21
|
routePrefix: string;
|
|
22
22
|
canEdit: boolean | ((fileItem: FileSystemItem) => boolean);
|
|
23
23
|
translations?: {
|
|
24
|
-
createDirectoryModalTitle: string;
|
|
25
24
|
cancel: string;
|
|
26
25
|
create: string;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
createDirectory: string;
|
|
27
|
+
createDirectoryModalTitle: string;
|
|
28
|
+
createDirectoryPlaceholder: string;
|
|
29
|
+
createItemTitle: string;
|
|
31
30
|
createdAt: string;
|
|
32
|
-
|
|
31
|
+
creating: string;
|
|
32
|
+
delete: string;
|
|
33
33
|
deleteFile: string;
|
|
34
34
|
deleteFileConfirmation: string;
|
|
35
35
|
deleting: string;
|
|
36
|
-
delete: string;
|
|
37
|
-
createDirectory: string;
|
|
38
|
-
uploadFile: string;
|
|
39
|
-
size: string;
|
|
40
|
-
items: string;
|
|
41
36
|
directoryAlreadyExists: string;
|
|
37
|
+
displayModeLabels: {
|
|
38
|
+
columns: string;
|
|
39
|
+
index: string;
|
|
40
|
+
};
|
|
41
|
+
displayModeSwitch: string;
|
|
42
|
+
emptyDirectory: string;
|
|
43
|
+
itemTitle: (item: FileSystemItem) => string;
|
|
44
|
+
items: string;
|
|
45
|
+
modifiedAt: string;
|
|
46
|
+
override: string;
|
|
47
|
+
overrideFiles: string;
|
|
48
|
+
overrideFilesConfirmation: string;
|
|
49
|
+
previewFile: string;
|
|
50
|
+
size: string;
|
|
51
|
+
uploadFile: string;
|
|
42
52
|
};
|
|
43
53
|
getFilePreview: (fileItem: FileItem) => Promise<FilePreview>;
|
|
44
54
|
createDirectory?: ((request: CreateDirectoryRequest) => Promise<void>) | undefined;
|
|
@@ -4,20 +4,13 @@ export let createDirectoryModalOpen = false;
|
|
|
4
4
|
export let documents;
|
|
5
5
|
export let createDirectory;
|
|
6
6
|
export let translations;
|
|
7
|
-
|
|
8
|
-
$: directoryAlreadyExists = existingFoldersInPath.some((x) => x.name === request.name);
|
|
9
|
-
let request;
|
|
7
|
+
let request = { path: "", name: "" };
|
|
10
8
|
let submitting = false;
|
|
11
9
|
let input = void 0;
|
|
12
|
-
|
|
13
|
-
$:
|
|
10
|
+
$: existingFoldersInPath = getExistingFoldersInPath(createDirectoryPath, $documents);
|
|
11
|
+
$: directoryAlreadyExists = existingFoldersInPath.some((x) => x.name === request.name);
|
|
12
|
+
$: request.path = createDirectoryPath ?? "";
|
|
14
13
|
$: if (input) input.focus();
|
|
15
|
-
function initDocumentUpload() {
|
|
16
|
-
request = {
|
|
17
|
-
path: createDirectoryPath,
|
|
18
|
-
name: ""
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
14
|
async function submitFiles() {
|
|
22
15
|
submitting = true;
|
|
23
16
|
await createDirectory(request).then(() => {
|
|
@@ -28,8 +21,7 @@ async function submitFiles() {
|
|
|
28
21
|
documents.refresh();
|
|
29
22
|
}
|
|
30
23
|
function getExistingFoldersInPath(path, documents2) {
|
|
31
|
-
|
|
32
|
-
const pathParts = path.split("/");
|
|
24
|
+
const pathParts = path ? path.split("/") : [];
|
|
33
25
|
let existingFoldersInPath2 = documents2.filter((x) => x.type === "directory");
|
|
34
26
|
for (const pathPart of pathParts) {
|
|
35
27
|
const currentFolder = existingFoldersInPath2.find((document) => document.name === pathPart);
|
|
@@ -50,7 +42,13 @@ function getExistingFoldersInPath(path, documents2) {
|
|
|
50
42
|
error={directoryAlreadyExists ? translations.directoryAlreadyExists : undefined}
|
|
51
43
|
floatError
|
|
52
44
|
>
|
|
53
|
-
<input
|
|
45
|
+
<input
|
|
46
|
+
bind:this={input}
|
|
47
|
+
id="file-explorer-create-directory-name"
|
|
48
|
+
placeholder={translations.createDirectoryPlaceholder}
|
|
49
|
+
type="text"
|
|
50
|
+
bind:value={request.name}
|
|
51
|
+
/>
|
|
54
52
|
</FormElement>
|
|
55
53
|
</div>
|
|
56
54
|
<svelte:fragment slot="footer">
|
|
@@ -3,7 +3,7 @@ import type { Refreshable } from '@securancy/svelte-utilities';
|
|
|
3
3
|
import type { CreateDirectoryRequest, DocumentTranslations, FileSystemItem } from '../models/index.js';
|
|
4
4
|
declare const __propDef: {
|
|
5
5
|
props: {
|
|
6
|
-
createDirectoryPath: string;
|
|
6
|
+
createDirectoryPath: string | undefined;
|
|
7
7
|
createDirectoryModalOpen?: boolean;
|
|
8
8
|
documents: Refreshable<FileSystemItem[]>;
|
|
9
9
|
createDirectory: (request: CreateDirectoryRequest) => Promise<void>;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import FileExplorerDirectoryColumn from "./FileExplorerDirectoryColumn.svelte";
|
|
3
3
|
import FileExplorerFileDetailColumn from "./FileExplorerFileDetailColumn.svelte";
|
|
4
4
|
import FileExplorerDirectoryIndex from "./FileExplorerDirectoryIndex.svelte";
|
|
5
|
-
import { joinPaths } from "../utilities";
|
|
6
5
|
export let item;
|
|
7
6
|
export let translations;
|
|
8
7
|
export let routePrefix;
|
|
@@ -10,7 +9,14 @@ export let currentPath;
|
|
|
10
9
|
export let canEdit;
|
|
11
10
|
export let displayMode;
|
|
12
11
|
export let getFilePreview;
|
|
13
|
-
$:
|
|
12
|
+
$: currentPathParts = currentPath.split("/");
|
|
13
|
+
$: activeFileItem = item.children.find((fileItem) => {
|
|
14
|
+
const parts = [
|
|
15
|
+
...fileItem.path.split("/").filter((part) => part !== ""),
|
|
16
|
+
fileItem.name
|
|
17
|
+
];
|
|
18
|
+
return parts.every((part, index) => currentPathParts[index] === part);
|
|
19
|
+
});
|
|
14
20
|
function canEditItem(item2, canEdit2) {
|
|
15
21
|
return typeof canEdit2 === "function" ? canEdit2(item2) : canEdit2 === true;
|
|
16
22
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {} from "..";
|
|
3
3
|
import { resize, ResizeDirections } from "@securancy/svelte-utilities";
|
|
4
4
|
import { Icon, Popover, PopoverItem } from "@securancy/svelte-components";
|
|
5
|
-
import { getExtension,
|
|
5
|
+
import { getExtension, getItemHref } from "../utilities/index.js";
|
|
6
6
|
import FileIcon from "./FileIcon.svelte";
|
|
7
7
|
import { joinPaths } from "../utilities/index.js";
|
|
8
8
|
const dispatch = createEventDispatcher();
|
|
@@ -79,7 +79,7 @@ function handleDragOver(event) {
|
|
|
79
79
|
</span>
|
|
80
80
|
{#if canEdit}
|
|
81
81
|
<Popover placement="bottom-end" trigger="click">
|
|
82
|
-
<button slot="trigger" type="button">
|
|
82
|
+
<button slot="trigger" title={translations.createItemTitle} type="button">
|
|
83
83
|
<Icon class="fa-solid fa-add" />
|
|
84
84
|
</button>
|
|
85
85
|
<PopoverItem closeOnClick on:click={createDirectory}>{translations.createDirectory}</PopoverItem>
|
|
@@ -89,12 +89,11 @@ function handleDragOver(event) {
|
|
|
89
89
|
</div>
|
|
90
90
|
{#if item.children.length > 0}
|
|
91
91
|
{#each item.children as child}
|
|
92
|
-
<
|
|
92
|
+
<a
|
|
93
93
|
class="file-explorer__list-item"
|
|
94
94
|
class:file-explorer__list-item--active={activeFileItem === child}
|
|
95
|
+
href={getItemHref(child, routePrefix)}
|
|
95
96
|
title={translations.itemTitle(child)}
|
|
96
|
-
type="button"
|
|
97
|
-
on:click={() => openItem(child, routePrefix)}
|
|
98
97
|
>
|
|
99
98
|
{#if child.type === 'directory'}
|
|
100
99
|
<Icon class="fa-light fa-folder{activeFileItem === child ? '-open' : ''}" />
|
|
@@ -105,7 +104,7 @@ function handleDragOver(event) {
|
|
|
105
104
|
{#if child.type === 'directory'}
|
|
106
105
|
<Icon class="fa-light fa-sm fa-chevron-right" size="custom" />
|
|
107
106
|
{/if}
|
|
108
|
-
</
|
|
107
|
+
</a>
|
|
109
108
|
{/each}
|
|
110
109
|
{:else}
|
|
111
110
|
<p class="file-explorer__message">
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createEventDispatcher } from "svelte";
|
|
3
3
|
import { resize, ResizeDirections } from "@securancy/svelte-utilities";
|
|
4
4
|
import { Icon, Popover, PopoverItem } from "@securancy/svelte-components";
|
|
5
|
-
import { getExtension,
|
|
5
|
+
import { getExtension, getItemHref, joinPaths } from "../utilities/index.js";
|
|
6
6
|
const dispatch = createEventDispatcher();
|
|
7
7
|
export let item;
|
|
8
8
|
export let routePrefix;
|
|
@@ -38,7 +38,7 @@ function createDirectory() {
|
|
|
38
38
|
{#if canEdit}
|
|
39
39
|
<div class="inline-block">
|
|
40
40
|
<Popover placement="bottom-end" trigger="click">
|
|
41
|
-
<button slot="trigger" type="button">
|
|
41
|
+
<button slot="trigger" title={translations.createItemTitle} type="button">
|
|
42
42
|
<Icon class="fa-solid fa-add" />
|
|
43
43
|
</button>
|
|
44
44
|
<PopoverItem closeOnClick on:click={createDirectory}>{translations.createDirectory}</PopoverItem>
|
|
@@ -48,12 +48,11 @@ function createDirectory() {
|
|
|
48
48
|
{/if}
|
|
49
49
|
</div>
|
|
50
50
|
{#each item.children as child}
|
|
51
|
-
<
|
|
51
|
+
<a
|
|
52
52
|
class="file-explorer__grid-item"
|
|
53
53
|
class:file-explorer__grid-item--active={activeFileItem === child}
|
|
54
|
+
href={getItemHref(child, routePrefix)}
|
|
54
55
|
title={translations.itemTitle(child)}
|
|
55
|
-
type="button"
|
|
56
|
-
on:click={() => openItem(child, routePrefix)}
|
|
57
56
|
>
|
|
58
57
|
{#if child.type === 'directory'}
|
|
59
58
|
<Icon
|
|
@@ -64,7 +63,7 @@ function createDirectory() {
|
|
|
64
63
|
<FileIcon extension={getExtension(child.name)} size="grid" />
|
|
65
64
|
{/if}
|
|
66
65
|
<span>{child.name}</span>
|
|
67
|
-
</
|
|
66
|
+
</a>
|
|
68
67
|
{:else}
|
|
69
68
|
<p class="file-explorer__message">
|
|
70
69
|
{translations.emptyDirectory}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
<script>import { FileExplorerDisplayMode } from "../index.js";
|
|
2
2
|
import { Icon } from "@securancy/svelte-components";
|
|
3
3
|
export let displayMode;
|
|
4
|
+
export let translations;
|
|
4
5
|
let modes = Object.values(FileExplorerDisplayMode);
|
|
5
|
-
const modeLabels = {
|
|
6
|
-
columns: "Columns",
|
|
7
|
-
index: "Full directory"
|
|
8
|
-
};
|
|
9
6
|
const modeIcons = {
|
|
10
7
|
columns: "fa-columns-3",
|
|
11
8
|
index: "fa-grid"
|
|
@@ -15,8 +12,8 @@ const modeIcons = {
|
|
|
15
12
|
<div class="file-explorer__display-mode-switcher">
|
|
16
13
|
{#each modes as mode}
|
|
17
14
|
<label
|
|
18
|
-
aria-label={
|
|
19
|
-
title="
|
|
15
|
+
aria-label={translations.displayModeLabels[mode]}
|
|
16
|
+
title="{translations.displayModeSwitch} {translations.displayModeLabels[mode].toLowerCase()}"
|
|
20
17
|
>
|
|
21
18
|
<input
|
|
22
19
|
name="displayMode"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import { FileExplorerDisplayMode } from '../index.js';
|
|
2
|
+
import { type DocumentTranslations, FileExplorerDisplayMode } from '../index.js';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: {
|
|
5
5
|
displayMode: FileExplorerDisplayMode;
|
|
6
|
+
translations: DocumentTranslations;
|
|
6
7
|
};
|
|
7
8
|
events: {
|
|
8
9
|
[evt: string]: CustomEvent<any>;
|
|
@@ -74,7 +74,7 @@ async function refresh(_fileItem) {
|
|
|
74
74
|
{/if}
|
|
75
75
|
{#if canEdit}
|
|
76
76
|
<div class="file-explorer-preview__info">
|
|
77
|
-
<button type="button" on:click={() => dispatch('delete-file', fileItem)}>
|
|
77
|
+
<button id="file-explorer-delete-file" type="button" on:click={() => dispatch('delete-file', fileItem)}>
|
|
78
78
|
<Icon class="fa-solid fa-trash" />
|
|
79
79
|
</button>
|
|
80
80
|
</div>
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import type { FileSystemItem } from './file-item.js';
|
|
2
2
|
export declare const defaultTranslations: {
|
|
3
|
-
createDirectoryModalTitle: string;
|
|
4
3
|
cancel: string;
|
|
5
4
|
create: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
createDirectory: string;
|
|
6
|
+
createDirectoryModalTitle: string;
|
|
7
|
+
createDirectoryPlaceholder: string;
|
|
8
|
+
createItemTitle: string;
|
|
10
9
|
createdAt: string;
|
|
11
|
-
|
|
10
|
+
creating: string;
|
|
11
|
+
delete: string;
|
|
12
12
|
deleteFile: string;
|
|
13
13
|
deleteFileConfirmation: string;
|
|
14
14
|
deleting: string;
|
|
15
|
-
delete: string;
|
|
16
|
-
createDirectory: string;
|
|
17
|
-
uploadFile: string;
|
|
18
|
-
size: string;
|
|
19
|
-
items: string;
|
|
20
15
|
directoryAlreadyExists: string;
|
|
16
|
+
displayModeLabels: {
|
|
17
|
+
columns: string;
|
|
18
|
+
index: string;
|
|
19
|
+
};
|
|
20
|
+
displayModeSwitch: string;
|
|
21
|
+
emptyDirectory: string;
|
|
22
|
+
itemTitle: (item: FileSystemItem) => string;
|
|
23
|
+
items: string;
|
|
24
|
+
modifiedAt: string;
|
|
25
|
+
override: string;
|
|
26
|
+
overrideFiles: string;
|
|
27
|
+
overrideFilesConfirmation: string;
|
|
28
|
+
previewFile: string;
|
|
29
|
+
size: string;
|
|
30
|
+
uploadFile: string;
|
|
21
31
|
};
|
|
22
32
|
export type DocumentTranslations = typeof defaultTranslations;
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
export const defaultTranslations = {
|
|
2
|
-
createDirectoryModalTitle: 'Create new directory',
|
|
3
2
|
cancel: 'Cancel',
|
|
4
3
|
create: 'Create',
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
createDirectory: 'Create directory',
|
|
5
|
+
createDirectoryModalTitle: 'Create new directory',
|
|
6
|
+
createDirectoryPlaceholder: 'Name',
|
|
7
|
+
createItemTitle: 'Create directory or upload file',
|
|
9
8
|
createdAt: 'Created at',
|
|
10
|
-
|
|
9
|
+
creating: 'Creating...',
|
|
10
|
+
delete: 'Delete',
|
|
11
11
|
deleteFile: 'Delete file',
|
|
12
12
|
deleteFileConfirmation: 'Are you sure you want to delete:',
|
|
13
13
|
deleting: 'Deleting...',
|
|
14
|
-
delete: 'Delete',
|
|
15
|
-
createDirectory: 'Create directory',
|
|
16
|
-
uploadFile: 'Upload file',
|
|
17
|
-
size: 'Size',
|
|
18
|
-
items: 'Items',
|
|
19
14
|
directoryAlreadyExists: 'Directory already exists',
|
|
15
|
+
displayModeLabels: {
|
|
16
|
+
columns: 'Columns',
|
|
17
|
+
index: 'Full directory',
|
|
18
|
+
},
|
|
19
|
+
displayModeSwitch: 'Switch display mode to',
|
|
20
|
+
emptyDirectory: 'Empty directory',
|
|
21
|
+
itemTitle: (item) => `Open ${item.type === 'directory' ? 'directory' : 'file'} ${item.name}`,
|
|
22
|
+
items: 'Items',
|
|
23
|
+
modifiedAt: 'Last modified at',
|
|
24
|
+
override: 'Override',
|
|
25
|
+
overrideFiles: 'Override files',
|
|
26
|
+
overrideFilesConfirmation: 'These files already exist, do you want to override them?',
|
|
27
|
+
previewFile: 'Preview file',
|
|
28
|
+
size: 'Size',
|
|
29
|
+
uploadFile: 'Upload file',
|
|
20
30
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FileSystemItem } from '../models/file-item.js';
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function getItemHref(item: FileSystemItem, routePrefix: string): string;
|
|
3
3
|
export declare function getExtension(path: string): string;
|
|
4
4
|
export declare const imageExtensions: string[];
|
|
5
5
|
export declare const videoExtensions: string[];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export async function openItem(item, routePrefix) {
|
|
1
|
+
export function getItemHref(item, routePrefix) {
|
|
3
2
|
const itemPath = [
|
|
4
3
|
...routePrefix.split('/'),
|
|
5
4
|
...item.path.split('/'),
|
|
@@ -8,7 +7,7 @@ export async function openItem(item, routePrefix) {
|
|
|
8
7
|
.filter((node) => node !== '')
|
|
9
8
|
.map(encodeURIComponent)
|
|
10
9
|
.join('/');
|
|
11
|
-
|
|
10
|
+
return itemPath.startsWith('/') ? itemPath : `/${itemPath}`;
|
|
12
11
|
}
|
|
13
12
|
export function getExtension(path) {
|
|
14
13
|
// extract file name from full path (supports `\\` and `/` separators)
|
|
@@ -48,7 +47,7 @@ export function formatBytesParts(bytes, decimals = 2) {
|
|
|
48
47
|
return [Number.parseFloat((bytes / Math.pow(k, index)).toFixed(dm)), sizes[index]];
|
|
49
48
|
}
|
|
50
49
|
export function joinPaths(...paths) {
|
|
51
|
-
return paths
|
|
52
|
-
.
|
|
50
|
+
return '/' + paths
|
|
51
|
+
.map((path) => path.split('/').filter((part) => part !== '').join('/'))
|
|
53
52
|
.join('/');
|
|
54
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@securancy/file-explorer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -47,13 +47,12 @@
|
|
|
47
47
|
"vite": "^5.3.4",
|
|
48
48
|
"zod": "^3.23.8",
|
|
49
49
|
"@securancy/eslint-config": "0.2.1",
|
|
50
|
+
"@securancy/svelte-components": "4.3.1",
|
|
50
51
|
"@securancy/stylelint-config": "0.1.2",
|
|
51
|
-
"@securancy/svelte-
|
|
52
|
-
"@securancy/svelte-utilities": "2.0.1"
|
|
52
|
+
"@securancy/svelte-utilities": "2.0.2"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"svelte": "^4.2.18"
|
|
56
|
-
"@sveltejs/kit": "^2.5.18"
|
|
55
|
+
"svelte": "^4.2.18"
|
|
57
56
|
},
|
|
58
57
|
"scripts": {
|
|
59
58
|
"dev": "vite dev",
|