@nextop-os/workspace-issue-manager 0.0.26 → 0.0.27

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.
@@ -25,7 +25,7 @@ import {
25
25
  toContextRefInput,
26
26
  toIssueManagerWorkspaceFileLinkInput,
27
27
  uniqueIssueManagerFileReferences
28
- } from "./chunk-34KSO5F6.js";
28
+ } from "./chunk-LJQG24Y2.js";
29
29
  import {
30
30
  appendIssueManagerWorkspaceFileLinksToContent,
31
31
  clampIssueManagerSidebarWidth,
@@ -36,7 +36,7 @@ import {
36
36
  issueManagerSidebarMinWidth,
37
37
  normalizeIssueManagerContent,
38
38
  shouldAutoCollapseIssueManagerSidebar
39
- } from "./chunk-RJ6HZRQU.js";
39
+ } from "./chunk-MCVRP7RR.js";
40
40
 
41
41
  // src/ui/react/internal/shell/IssueManagerNodeState.ts
42
42
  import { useEffect, useEffectEvent, useState } from "react";
@@ -1402,6 +1402,10 @@ function useIssueManagerNodeView({
1402
1402
 
1403
1403
  // src/ui/react/internal/reference/useIssueManagerReferencePickerView.ts
1404
1404
  import { useEffect as useEffect3, useEffectEvent as useEffectEvent2, useMemo as useMemo3, useState as useState2 } from "react";
1405
+ import {
1406
+ createWorkspaceFilePreviewLoadedState,
1407
+ resolveWorkspaceFilePreviewReadiness
1408
+ } from "@nextop-os/workspace-file-preview";
1405
1409
  var defaultDirectoryPath = "/";
1406
1410
  function useIssueManagerReferencePickerView({
1407
1411
  fileAdapter,
@@ -1420,6 +1424,7 @@ function useIssueManagerReferencePickerView({
1420
1424
  const [selectedRefs, setSelectedRefs] = useState2(
1421
1425
  []
1422
1426
  );
1427
+ const [previewState, setPreviewState] = useState2({ status: "empty" });
1423
1428
  const supportsSearch = hasFileAdapterMethod2(fileAdapter, "searchReferences");
1424
1429
  const supportsTreeSnapshot = hasFileAdapterMethod2(
1425
1430
  fileAdapter,
@@ -1579,6 +1584,73 @@ function useIssueManagerReferencePickerView({
1579
1584
  });
1580
1585
  }, [open, visibleEntries]);
1581
1586
  const focusedEntry = visibleEntries.find((entry) => entry.path === focusedPath) ?? selectedRefs.find((entry) => entry.path === focusedPath) ?? null;
1587
+ useEffect3(() => {
1588
+ if (!open || !focusedEntry) {
1589
+ setPreviewState({ status: "empty" });
1590
+ return;
1591
+ }
1592
+ const readiness = resolveWorkspaceFilePreviewReadiness(focusedEntry);
1593
+ if (readiness.status === "directory") {
1594
+ setPreviewState({ reference: focusedEntry, status: "directory" });
1595
+ return;
1596
+ }
1597
+ if (readiness.status === "unsupported") {
1598
+ setPreviewState({ reference: focusedEntry, status: "unsupported" });
1599
+ return;
1600
+ }
1601
+ if (readiness.status === "readonly") {
1602
+ setPreviewState({
1603
+ maxSizeBytes: readiness.maxSizeBytes,
1604
+ reason: readiness.reason,
1605
+ reference: focusedEntry,
1606
+ status: "readonly"
1607
+ });
1608
+ return;
1609
+ }
1610
+ if (!fileAdapter?.readReferencePreview) {
1611
+ setPreviewState({ reference: focusedEntry, status: "unavailable" });
1612
+ return;
1613
+ }
1614
+ const previewTarget = readiness.target;
1615
+ let canceled = false;
1616
+ let objectUrl = null;
1617
+ setPreviewState({ reference: focusedEntry, status: "loading" });
1618
+ const load = async () => {
1619
+ try {
1620
+ const preview = await fileAdapter.readReferencePreview?.({
1621
+ reference: focusedEntry,
1622
+ workspaceId
1623
+ });
1624
+ if (canceled) {
1625
+ return;
1626
+ }
1627
+ if (!preview) {
1628
+ setPreviewState({ reference: focusedEntry, status: "unsupported" });
1629
+ return;
1630
+ }
1631
+ const nextState = createReferencePreviewState(
1632
+ focusedEntry,
1633
+ previewTarget,
1634
+ preview
1635
+ );
1636
+ if (nextState.status === "image") {
1637
+ objectUrl = nextState.objectUrl;
1638
+ }
1639
+ setPreviewState(nextState);
1640
+ } catch {
1641
+ if (!canceled) {
1642
+ setPreviewState({ reference: focusedEntry, status: "error" });
1643
+ }
1644
+ }
1645
+ };
1646
+ void load();
1647
+ return () => {
1648
+ canceled = true;
1649
+ if (objectUrl) {
1650
+ URL.revokeObjectURL(objectUrl);
1651
+ }
1652
+ };
1653
+ }, [fileAdapter, focusedEntry, open, workspaceId]);
1582
1654
  const toggleRef = (ref) => {
1583
1655
  setSelectedRefs((current) => {
1584
1656
  const existing = current.some((item) => item.path === ref.path);
@@ -1645,6 +1717,7 @@ function useIssueManagerReferencePickerView({
1645
1717
  focusedPath,
1646
1718
  isLoading,
1647
1719
  mode,
1720
+ previewState,
1648
1721
  searchQuery,
1649
1722
  selectedRefs,
1650
1723
  visibleEntries,
@@ -1654,6 +1727,41 @@ function useIssueManagerReferencePickerView({
1654
1727
  toggleRef
1655
1728
  };
1656
1729
  }
1730
+ function createReferencePreviewState(reference, target, preview) {
1731
+ const loadedState = createWorkspaceFilePreviewLoadedState({
1732
+ bytes: preview.bytes,
1733
+ contentType: preview.contentType,
1734
+ entry: reference,
1735
+ target: {
1736
+ ...target,
1737
+ fileKind: preview.kind
1738
+ }
1739
+ });
1740
+ if (loadedState.status === "image") {
1741
+ return {
1742
+ objectUrl: URL.createObjectURL(
1743
+ new Blob([loadedState.bytes], {
1744
+ type: loadedState.contentType
1745
+ })
1746
+ ),
1747
+ reference,
1748
+ status: "image"
1749
+ };
1750
+ }
1751
+ if (loadedState.status === "text") {
1752
+ return {
1753
+ content: loadedState.content,
1754
+ reference,
1755
+ status: "text"
1756
+ };
1757
+ }
1758
+ return {
1759
+ maxSizeBytes: loadedState.maxSizeBytes,
1760
+ reason: loadedState.reason,
1761
+ reference,
1762
+ status: "readonly"
1763
+ };
1764
+ }
1657
1765
  function hasFileAdapterMethod2(fileAdapter, methodName) {
1658
1766
  return typeof Reflect.get(fileAdapter ?? {}, methodName) === "function";
1659
1767
  }
@@ -1678,8 +1786,11 @@ import {
1678
1786
  Badge,
1679
1787
  Button as Button2,
1680
1788
  FileIcon as FileIcon2,
1681
- FolderFilledIcon as FolderFilledIcon2
1789
+ FolderFilledIcon as FolderFilledIcon2,
1790
+ LoadingIcon
1682
1791
  } from "@nextop-os/ui-system";
1792
+ import { formatWorkspacePreviewByteLimit } from "@nextop-os/workspace-file-preview";
1793
+ import { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from "@nextop-os/workspace-file-preview/react";
1683
1794
 
1684
1795
  // src/ui/internal/reference/IssueManagerReferencePickerTree.tsx
1685
1796
  import { useEffect as useEffect4, useState as useState3 } from "react";
@@ -1980,19 +2091,123 @@ var issueManagerReferencePickerSelectedBadgeClassName = "max-w-[14rem] rounded-[
1980
2091
  function IssueManagerReferencePickerPreviewPane({
1981
2092
  copy,
1982
2093
  focusedEntry,
1983
- mode
2094
+ mode,
2095
+ previewState
1984
2096
  }) {
1985
2097
  return /* @__PURE__ */ jsx2("aside", { className: "flex shrink-0 flex-col border-t border-[var(--line-1)] bg-[var(--background-fronted)] lg:min-h-0 lg:flex-1 lg:border-t-0", children: /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col px-4 py-4 sm:px-5 lg:py-5", children: focusedEntry ? /* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-col gap-4 lg:flex-1 lg:gap-5", children: [
1986
- /* @__PURE__ */ jsxs2("div", { className: "flex min-h-32 flex-col items-center justify-center space-y-4 rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] px-5 py-8 text-center sm:min-h-40 sm:py-10 lg:min-h-56 lg:py-14", children: [
1987
- focusedEntry.kind === "folder" ? /* @__PURE__ */ jsx2(FolderFilledIcon2, { className: "mx-auto size-9 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx2(FileIcon2, { className: "mx-auto size-9 text-[var(--text-tertiary)]" }),
1988
- /* @__PURE__ */ jsx2("p", { className: "mx-auto max-w-[24ch] text-sm leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.kind === "folder" ? focusedEntry.path : resolveIssueManagerReferenceLabel(focusedEntry) })
1989
- ] }),
2098
+ /* @__PURE__ */ jsx2(
2099
+ IssueManagerReferencePreviewSurface,
2100
+ {
2101
+ copy,
2102
+ focusedEntry,
2103
+ previewState
2104
+ }
2105
+ ),
1990
2106
  /* @__PURE__ */ jsx2("div", { className: "space-y-2 lg:space-y-3", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", children: [
1991
2107
  /* @__PURE__ */ jsx2("p", { className: "truncate text-[15px] font-semibold text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(focusedEntry) }),
1992
2108
  /* @__PURE__ */ jsx2("p", { className: "line-clamp-3 text-sm text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.path })
1993
2109
  ] }) })
1994
2110
  ] }) : /* @__PURE__ */ jsx2(IssueManagerReferencePickerFeedback2, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) }) });
1995
2111
  }
2112
+ function IssueManagerReferencePreviewSurface({
2113
+ copy,
2114
+ focusedEntry,
2115
+ previewState
2116
+ }) {
2117
+ return /* @__PURE__ */ jsx2(
2118
+ SharedWorkspaceFilePreviewSurface,
2119
+ {
2120
+ directoryMessage: copy.t("referencePicker.previewFolder"),
2121
+ emptyMessage: copy.t("referencePicker.previewUnavailable"),
2122
+ frameClassName: "flex min-h-32 flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] px-5 py-8 text-center sm:min-h-40 sm:py-10 lg:min-h-56 lg:py-14",
2123
+ imageAlt: resolveIssueManagerReferenceLabel,
2124
+ imageFrameClassName: "p-4",
2125
+ loadingIndicator: /* @__PURE__ */ jsx2("span", { className: "mx-auto grid size-11 place-items-center rounded-[6px] bg-[var(--transparency-block)]", children: /* @__PURE__ */ jsx2(LoadingIcon, { className: "size-4 animate-spin" }) }),
2126
+ loadingMessage: copy.t("referencePicker.previewLoading"),
2127
+ messageClassName: "mx-auto max-w-[24ch] text-sm leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]",
2128
+ renderIcon: (entry) => entry.kind === "folder" ? /* @__PURE__ */ jsx2(FolderFilledIcon2, { className: "mx-auto size-9 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx2(FileIcon2, { className: "mx-auto size-9 text-[var(--text-tertiary)]" }),
2129
+ state: resolveIssueManagerReferenceSurfaceState(
2130
+ copy,
2131
+ focusedEntry,
2132
+ previewState
2133
+ ),
2134
+ textClassName: "h-full overflow-auto p-4 text-left text-xs leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]",
2135
+ textFrameClassName: "items-stretch justify-stretch"
2136
+ }
2137
+ );
2138
+ }
2139
+ function resolveIssueManagerReferenceSurfaceState(copy, focusedEntry, previewState) {
2140
+ if (focusedEntry.kind === "folder") {
2141
+ return {
2142
+ entry: focusedEntry,
2143
+ status: "directory"
2144
+ };
2145
+ }
2146
+ if (!("reference" in previewState) || previewState.reference.path !== focusedEntry.path) {
2147
+ return {
2148
+ entry: focusedEntry,
2149
+ message: focusedEntry.path,
2150
+ status: "unsupported"
2151
+ };
2152
+ }
2153
+ switch (previewState.status) {
2154
+ case "loading":
2155
+ case "image":
2156
+ case "text":
2157
+ return {
2158
+ ...previewState,
2159
+ entry: focusedEntry
2160
+ };
2161
+ case "readonly":
2162
+ return {
2163
+ entry: focusedEntry,
2164
+ message: resolveIssueManagerReferencePreviewReadonlyMessage(
2165
+ copy,
2166
+ previewState
2167
+ ),
2168
+ status: "readonly"
2169
+ };
2170
+ case "error":
2171
+ return {
2172
+ entry: focusedEntry,
2173
+ message: copy.t("referencePicker.previewError"),
2174
+ status: "error"
2175
+ };
2176
+ case "unsupported":
2177
+ return {
2178
+ entry: focusedEntry,
2179
+ message: copy.t("referencePicker.previewUnsupported"),
2180
+ status: "unsupported"
2181
+ };
2182
+ case "unavailable":
2183
+ return {
2184
+ entry: focusedEntry,
2185
+ message: copy.t("referencePicker.previewUnavailable"),
2186
+ status: "unsupported"
2187
+ };
2188
+ case "directory":
2189
+ return {
2190
+ entry: focusedEntry,
2191
+ status: "directory"
2192
+ };
2193
+ }
2194
+ }
2195
+ function resolveIssueManagerReferencePreviewReadonlyMessage(copy, previewState) {
2196
+ switch (previewState.reason) {
2197
+ case "binary":
2198
+ return copy.t("referencePicker.previewBinary");
2199
+ case "decode_failed":
2200
+ return copy.t("referencePicker.previewDecodeFailed");
2201
+ case "file_too_large":
2202
+ return copy.t("referencePicker.previewFileTooLarge", {
2203
+ maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
2204
+ });
2205
+ case "text_too_large":
2206
+ return copy.t("referencePicker.previewTextTooLarge", {
2207
+ maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
2208
+ });
2209
+ }
2210
+ }
1996
2211
  function IssueManagerReferencePickerFooter({
1997
2212
  copy,
1998
2213
  onClose,
@@ -2065,6 +2280,7 @@ function IssueManagerReferencePicker({
2065
2280
  focusedPath,
2066
2281
  isLoading,
2067
2282
  mode,
2283
+ previewState,
2068
2284
  searchQuery,
2069
2285
  selectedRefs,
2070
2286
  visibleEntries,
@@ -2141,7 +2357,8 @@ function IssueManagerReferencePicker({
2141
2357
  {
2142
2358
  copy,
2143
2359
  focusedEntry,
2144
- mode
2360
+ mode,
2361
+ previewState
2145
2362
  }
2146
2363
  )
2147
2364
  ] }),
@@ -4509,4 +4726,4 @@ export {
4509
4726
  IssueManagerNode,
4510
4727
  IssueManagerNodeHeader
4511
4728
  };
4512
- //# sourceMappingURL=chunk-K3F67IRA.js.map
4729
+ //# sourceMappingURL=chunk-5V4DIEWZ.js.map