@gallop.software/studio 0.1.78 → 0.1.79

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.
@@ -1719,11 +1719,15 @@ var styles4 = {
1719
1719
  flex: 1;
1720
1720
  min-width: 0;
1721
1721
  `,
1722
- copyBtn: _react3.css`
1722
+ actionBtns: _react3.css`
1723
1723
  position: absolute;
1724
1724
  top: 4px;
1725
1725
  right: 4px;
1726
1726
  z-index: 10;
1727
+ display: flex;
1728
+ gap: 2px;
1729
+ `,
1730
+ copyBtn: _react3.css`
1727
1731
  height: 28px;
1728
1732
  width: 28px;
1729
1733
  color: ${_chunkUFCWGUAGjs.colors.textMuted};
@@ -1736,6 +1740,7 @@ var styles4 = {
1736
1740
  display: flex;
1737
1741
  align-items: center;
1738
1742
  justify-content: center;
1743
+ position: relative;
1739
1744
 
1740
1745
  &:hover {
1741
1746
  color: ${_chunkUFCWGUAGjs.colors.text};
@@ -1841,6 +1846,7 @@ function StudioFileGrid() {
1841
1846
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh, searchQuery } = useStudio();
1842
1847
  const [items, setItems] = _react.useState.call(void 0, []);
1843
1848
  const [loading, setLoading] = _react.useState.call(void 0, true);
1849
+ const [renameItem, setRenameItem] = _react.useState.call(void 0, null);
1844
1850
  const isInitialLoad = _react.useRef.call(void 0, true);
1845
1851
  const lastPath = _react.useRef.call(void 0, currentPath);
1846
1852
  _react.useEffect.call(void 0, () => {
@@ -1909,6 +1915,22 @@ function StudioFileGrid() {
1909
1915
  console.error("Failed to generate thumbnail:", error);
1910
1916
  }
1911
1917
  };
1918
+ const handleRename = async (newName) => {
1919
+ if (!renameItem) return;
1920
+ setRenameItem(null);
1921
+ try {
1922
+ const response = await fetch("/api/studio/rename", {
1923
+ method: "POST",
1924
+ headers: { "Content-Type": "application/json" },
1925
+ body: JSON.stringify({ oldPath: renameItem.path, newName })
1926
+ });
1927
+ if (response.ok) {
1928
+ triggerRefresh();
1929
+ }
1930
+ } catch (error) {
1931
+ console.error("Failed to rename:", error);
1932
+ }
1933
+ };
1912
1934
  const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
1913
1935
  const someItemsSelected = sortedItems.some((item) => selectedItems.has(item.path));
1914
1936
  const handleSelectAll = () => {
@@ -1919,6 +1941,18 @@ function StudioFileGrid() {
1919
1941
  }
1920
1942
  };
1921
1943
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1944
+ renameItem && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1945
+ InputModal,
1946
+ {
1947
+ title: renameItem.type === "folder" ? "Rename Folder" : "Rename File",
1948
+ message: "Enter a new name:",
1949
+ placeholder: renameItem.name,
1950
+ defaultValue: renameItem.name,
1951
+ confirmLabel: "Rename",
1952
+ onConfirm: handleRename,
1953
+ onCancel: () => setRenameItem(null)
1954
+ }
1955
+ ),
1922
1956
  sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles4.selectAllLabel, children: [
1923
1957
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1924
1958
  "input",
@@ -1958,14 +1992,15 @@ function StudioFileGrid() {
1958
1992
  isSelected: selectedItems.has(item.path),
1959
1993
  onClick: (e) => handleItemClick(item, e),
1960
1994
  onOpen: () => handleOpen(item),
1961
- onGenerateThumbnail: () => handleGenerateThumbnail(item)
1995
+ onGenerateThumbnail: () => handleGenerateThumbnail(item),
1996
+ onRename: () => setRenameItem(item)
1962
1997
  },
1963
1998
  item.path
1964
1999
  ))
1965
2000
  ] })
1966
2001
  ] });
1967
2002
  }
1968
- function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2003
+ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail, onRename }) {
1969
2004
  const [showCopied, setShowCopied] = _react.useState.call(void 0, false);
1970
2005
  const isFolder = item.type === "folder";
1971
2006
  const isImage = !isFolder && item.thumbnail !== void 0;
@@ -2001,18 +2036,32 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2001
2036
  ),
2002
2037
  item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnBadge, children: "CDN" }),
2003
2038
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.content, children: [
2004
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2005
- "button",
2006
- {
2007
- css: styles4.copyBtn,
2008
- onClick: handleCopyPath,
2009
- title: "Copy file path",
2010
- children: [
2011
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
2012
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2013
- ]
2014
- }
2015
- ),
2039
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.actionBtns, children: [
2040
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2041
+ "button",
2042
+ {
2043
+ css: styles4.copyBtn,
2044
+ onClick: handleCopyPath,
2045
+ title: "Copy file path",
2046
+ children: [
2047
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
2048
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2049
+ ]
2050
+ }
2051
+ ),
2052
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2053
+ "button",
2054
+ {
2055
+ css: styles4.copyBtn,
2056
+ onClick: (e) => {
2057
+ e.stopPropagation();
2058
+ onRename();
2059
+ },
2060
+ title: "Rename",
2061
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) })
2062
+ }
2063
+ )
2064
+ ] }),
2016
2065
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2017
2066
  "button",
2018
2067
  {
@@ -2398,6 +2447,7 @@ function StudioFileList() {
2398
2447
  const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh, searchQuery } = useStudio();
2399
2448
  const [items, setItems] = _react.useState.call(void 0, []);
2400
2449
  const [loading, setLoading] = _react.useState.call(void 0, true);
2450
+ const [renameItem, setRenameItem] = _react.useState.call(void 0, null);
2401
2451
  const isInitialLoad = _react.useRef.call(void 0, true);
2402
2452
  const lastPath = _react.useRef.call(void 0, currentPath);
2403
2453
  _react.useEffect.call(void 0, () => {
@@ -2462,6 +2512,22 @@ function StudioFileList() {
2462
2512
  console.error("Failed to generate thumbnail:", error);
2463
2513
  }
2464
2514
  };
2515
+ const handleRename = async (newName) => {
2516
+ if (!renameItem) return;
2517
+ setRenameItem(null);
2518
+ try {
2519
+ const response = await fetch("/api/studio/rename", {
2520
+ method: "POST",
2521
+ headers: { "Content-Type": "application/json" },
2522
+ body: JSON.stringify({ oldPath: renameItem.path, newName })
2523
+ });
2524
+ if (response.ok) {
2525
+ triggerRefresh();
2526
+ }
2527
+ } catch (error) {
2528
+ console.error("Failed to rename:", error);
2529
+ }
2530
+ };
2465
2531
  const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
2466
2532
  const someItemsSelected = sortedItems.some((item) => selectedItems.has(item.path));
2467
2533
  const handleSelectAll = () => {
@@ -2471,51 +2537,66 @@ function StudioFileList() {
2471
2537
  selectAll(sortedItems);
2472
2538
  }
2473
2539
  };
2474
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles5.table, children: [
2475
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
2476
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2477
- "input",
2478
- {
2479
- type: "checkbox",
2480
- css: styles5.checkbox,
2481
- checked: allItemsSelected,
2482
- ref: (el) => {
2483
- if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
2540
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.tableWrapper, children: [
2541
+ renameItem && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2542
+ InputModal,
2543
+ {
2544
+ title: renameItem.type === "folder" ? "Rename Folder" : "Rename File",
2545
+ message: "Enter a new name:",
2546
+ placeholder: renameItem.name,
2547
+ defaultValue: renameItem.name,
2548
+ confirmLabel: "Rename",
2549
+ onConfirm: handleRename,
2550
+ onCancel: () => setRenameItem(null)
2551
+ }
2552
+ ),
2553
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles5.table, children: [
2554
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
2555
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2556
+ "input",
2557
+ {
2558
+ type: "checkbox",
2559
+ css: styles5.checkbox,
2560
+ checked: allItemsSelected,
2561
+ ref: (el) => {
2562
+ if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
2563
+ },
2564
+ onChange: handleSelectAll
2565
+ }
2566
+ ) }),
2567
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles5.th, children: "Name" }),
2568
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thSize], children: "Size" }),
2569
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
2570
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
2571
+ ] }) }),
2572
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles5.tbody, children: [
2573
+ !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles5.parentRow, onClick: navigateUp, children: [
2574
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td }),
2575
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2576
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
2577
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, children: ".." })
2578
+ ] }) }),
2579
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "--" }),
2580
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "Parent folder" }),
2581
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: "--" })
2582
+ ] }),
2583
+ sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2584
+ ListRow,
2585
+ {
2586
+ item,
2587
+ isSelected: selectedItems.has(item.path),
2588
+ onClick: (e) => handleItemClick(item, e),
2589
+ onOpen: () => handleOpen(item),
2590
+ onGenerateThumbnail: () => handleGenerateThumbnail(item),
2591
+ onRename: () => setRenameItem(item)
2484
2592
  },
2485
- onChange: handleSelectAll
2486
- }
2487
- ) }),
2488
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles5.th, children: "Name" }),
2489
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thSize], children: "Size" }),
2490
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
2491
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
2492
- ] }) }),
2493
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles5.tbody, children: [
2494
- !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles5.parentRow, onClick: navigateUp, children: [
2495
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td }),
2496
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2497
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
2498
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, children: ".." })
2499
- ] }) }),
2500
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "--" }),
2501
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "Parent folder" }),
2502
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: "--" })
2503
- ] }),
2504
- sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2505
- ListRow,
2506
- {
2507
- item,
2508
- isSelected: selectedItems.has(item.path),
2509
- onClick: (e) => handleItemClick(item, e),
2510
- onOpen: () => handleOpen(item),
2511
- onGenerateThumbnail: () => handleGenerateThumbnail(item)
2512
- },
2513
- item.path
2514
- ))
2593
+ item.path
2594
+ ))
2595
+ ] })
2515
2596
  ] })
2516
- ] }) });
2597
+ ] });
2517
2598
  }
2518
- function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2599
+ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail, onRename }) {
2519
2600
  const [showCopied, setShowCopied] = _react.useState.call(void 0, false);
2520
2601
  const isFolder = item.type === "folder";
2521
2602
  const isImage = !isFolder && item.thumbnail !== void 0;
@@ -2579,6 +2660,18 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2579
2660
  ]
2580
2661
  }
2581
2662
  ),
2663
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2664
+ "button",
2665
+ {
2666
+ css: styles5.copyBtn,
2667
+ onClick: (e) => {
2668
+ e.stopPropagation();
2669
+ onRename();
2670
+ },
2671
+ title: "Rename",
2672
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) })
2673
+ }
2674
+ ),
2582
2675
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2583
2676
  "button",
2584
2677
  {
@@ -3837,4 +3930,4 @@ var StudioUI_default = StudioUI;
3837
3930
 
3838
3931
 
3839
3932
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
3840
- //# sourceMappingURL=StudioUI-5P7Y3LQK.js.map
3933
+ //# sourceMappingURL=StudioUI-JGKWCQSR.js.map