@lvce-editor/explorer-view 4.7.0 → 4.9.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.
|
@@ -1727,6 +1727,23 @@ const getPathPartsChildren = async pathparts => {
|
|
|
1727
1727
|
return orderedPathParts;
|
|
1728
1728
|
};
|
|
1729
1729
|
|
|
1730
|
+
const getSiblingFileNames = (items, focusedIndex, root, pathSeparator) => {
|
|
1731
|
+
if (focusedIndex < 0 || focusedIndex >= items.length) {
|
|
1732
|
+
// If no focused item or invalid index, get root level items
|
|
1733
|
+
return items.filter(item => item.depth === 0).map(item => item.name);
|
|
1734
|
+
}
|
|
1735
|
+
const focusedItem = items[focusedIndex];
|
|
1736
|
+
const nameLength = focusedItem.name ? focusedItem.name.length + 1 : 0;
|
|
1737
|
+
const focusedItemParentPath = focusedItem.path.slice(0, -nameLength);
|
|
1738
|
+
|
|
1739
|
+
// Find all items that are direct children of the same parent as the focused item
|
|
1740
|
+
const siblingItems = items.filter(item => {
|
|
1741
|
+
const itemParentPath = item.path.slice(0, -nameLength);
|
|
1742
|
+
return itemParentPath === focusedItemParentPath;
|
|
1743
|
+
});
|
|
1744
|
+
return siblingItems.map(item => item.name);
|
|
1745
|
+
};
|
|
1746
|
+
|
|
1730
1747
|
const mergeTrees = (a, b) => {
|
|
1731
1748
|
return {
|
|
1732
1749
|
...a,
|
|
@@ -1788,6 +1805,7 @@ const CopyRelativePath = 'Copy Relative Path';
|
|
|
1788
1805
|
const Cut = 'Cut';
|
|
1789
1806
|
const Delete = 'Delete';
|
|
1790
1807
|
const FileNameCannotStartWithSlash = 'A file or folder name cannot start with a slash.';
|
|
1808
|
+
const FileOrFolderAlreadyExists = 'A file or folder **{0}** already exists at this location. Please choose a different name.';
|
|
1791
1809
|
const FileOrFolderNameMustBeProvider = 'A file or folder name must be provided.';
|
|
1792
1810
|
const FileCannotStartWithDot = 'A file or folder name cannot start with a dot.';
|
|
1793
1811
|
const FileCannotStartWithBackSlash = 'A file or folder name cannot start with a backslash.';
|
|
@@ -1866,8 +1884,11 @@ const fileCannotStartWithBackSlash = () => {
|
|
|
1866
1884
|
const typeAFileName = () => {
|
|
1867
1885
|
return i18nString(TypeAFileName);
|
|
1868
1886
|
};
|
|
1887
|
+
const fileOrFolderAlreadyExists = () => {
|
|
1888
|
+
return i18nString(FileOrFolderAlreadyExists);
|
|
1889
|
+
};
|
|
1869
1890
|
|
|
1870
|
-
const validateFileName2 = name => {
|
|
1891
|
+
const validateFileName2 = (name, siblingFileNames = []) => {
|
|
1871
1892
|
if (!name) {
|
|
1872
1893
|
const editingErrorMessage = fileOrFolderNameMustBeProvided();
|
|
1873
1894
|
return editingErrorMessage;
|
|
@@ -1881,6 +1902,11 @@ const validateFileName2 = name => {
|
|
|
1881
1902
|
if (name.startsWith(BackSlash)) {
|
|
1882
1903
|
return fileCannotStartWithBackSlash();
|
|
1883
1904
|
}
|
|
1905
|
+
|
|
1906
|
+
// Check if file already exists
|
|
1907
|
+
if (siblingFileNames.includes(name)) {
|
|
1908
|
+
return fileOrFolderAlreadyExists();
|
|
1909
|
+
}
|
|
1884
1910
|
return '';
|
|
1885
1911
|
};
|
|
1886
1912
|
|
|
@@ -1893,7 +1919,8 @@ const acceptCreate = async (state, newDirentType) => {
|
|
|
1893
1919
|
items
|
|
1894
1920
|
} = state;
|
|
1895
1921
|
const newFileName = editingValue;
|
|
1896
|
-
const
|
|
1922
|
+
const siblingFileNames = getSiblingFileNames(items, focusedIndex);
|
|
1923
|
+
const editingErrorMessage = validateFileName2(newFileName, siblingFileNames);
|
|
1897
1924
|
if (editingErrorMessage) {
|
|
1898
1925
|
return {
|
|
1899
1926
|
...state,
|
|
@@ -5077,10 +5104,12 @@ const renameDirent = async state => {
|
|
|
5077
5104
|
};
|
|
5078
5105
|
};
|
|
5079
5106
|
|
|
5080
|
-
const getCss = (scrollBarHeight, uniqueIndents) => {
|
|
5107
|
+
const getCss = (scrollBarHeight, uniqueIndents, errorMessageLeft, errorMessageTop) => {
|
|
5081
5108
|
// TODO each visible item should have an indent property
|
|
5082
5109
|
const rules = [`.Explorer {
|
|
5083
5110
|
--ScrollBarThumbHeight: ${scrollBarHeight}px;
|
|
5111
|
+
--ErrorMessageTop: ${errorMessageTop}px;
|
|
5112
|
+
--ErrorMessageLeft: ${errorMessageLeft}px;
|
|
5084
5113
|
}`];
|
|
5085
5114
|
for (const item of uniqueIndents) {
|
|
5086
5115
|
rules.push(`.Indent-${item} {
|
|
@@ -5105,11 +5134,13 @@ const renderCss = (oldState, newState) => {
|
|
|
5105
5134
|
const {
|
|
5106
5135
|
scrollBarHeight,
|
|
5107
5136
|
uid,
|
|
5108
|
-
visibleExplorerItems
|
|
5137
|
+
visibleExplorerItems,
|
|
5138
|
+
errorMessageLeft,
|
|
5139
|
+
errorMessageTop
|
|
5109
5140
|
} = newState;
|
|
5110
5141
|
const indents = visibleExplorerItems.map(item => item.indent);
|
|
5111
5142
|
const uniqueIndents = getUnique(indents);
|
|
5112
|
-
const css = getCss(scrollBarHeight, uniqueIndents);
|
|
5143
|
+
const css = getCss(scrollBarHeight, uniqueIndents, errorMessageLeft, errorMessageTop);
|
|
5113
5144
|
return [SetCss, uid, css];
|
|
5114
5145
|
};
|
|
5115
5146
|
|
|
@@ -5963,10 +5994,17 @@ const updateEditingValue = async (state, value, inputSource = User) => {
|
|
|
5963
5994
|
const {
|
|
5964
5995
|
editingType,
|
|
5965
5996
|
items,
|
|
5966
|
-
editingIndex
|
|
5997
|
+
editingIndex,
|
|
5998
|
+
focusedIndex
|
|
5967
5999
|
} = state;
|
|
5968
6000
|
const editingIcon = await getEditingIcon(editingType, value, items[editingIndex]?.type);
|
|
5969
|
-
|
|
6001
|
+
|
|
6002
|
+
// Get sibling file names for validation during file/folder creation
|
|
6003
|
+
let siblingFileNames = [];
|
|
6004
|
+
if (editingType === CreateFile || editingType === CreateFolder) {
|
|
6005
|
+
siblingFileNames = getSiblingFileNames(items, focusedIndex);
|
|
6006
|
+
}
|
|
6007
|
+
const editingErrorMessage = validateFileName2(value, siblingFileNames);
|
|
5970
6008
|
return {
|
|
5971
6009
|
...state,
|
|
5972
6010
|
editingValue: value,
|