react-os-shell 0.3.9 → 0.3.10

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/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { W as WindowRegistry } from './types-D_4ifuf-.js';
2
2
  export { M as ModalRegistryEntry, P as PageRegistryEntry, a as WindowRegistryEntry, i as isEntityEntry, b as isPageEntry, s as setShellWindowRegistry } from './types-D_4ifuf-.js';
3
3
  import * as react from 'react';
4
- import { ReactNode, CSSProperties, RefObject } from 'react';
4
+ import react__default, { ReactNode, CSSProperties, Dispatch, SetStateAction, RefObject } from 'react';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import * as _tanstack_query_core from '@tanstack/query-core';
6
7
  import { AxiosInstance } from 'axios';
7
8
 
8
9
  /**
@@ -736,6 +737,217 @@ declare function StartMenu({ open, onClose, openPage, profile, user, onLogout, t
736
737
 
737
738
  declare function Customization(): react_jsx_runtime.JSX.Element;
738
739
 
740
+ interface EntityListColumn {
741
+ key: string;
742
+ label: string;
743
+ defaultWidth?: number;
744
+ minWidth?: number;
745
+ defaultHidden?: boolean;
746
+ sortField?: string;
747
+ headerNode?: ReactNode;
748
+ }
749
+ interface EntityListProps<T> {
750
+ items: T[];
751
+ isLoading: boolean;
752
+ emptyState: ReactNode;
753
+ totalCount?: number;
754
+ tableId: string;
755
+ columns: EntityListColumn[];
756
+ renderCell: (item: T, colKey: string) => ReactNode;
757
+ getRowId?: (item: T) => string | number;
758
+ sort?: {
759
+ field: string;
760
+ direction: 'asc' | 'desc';
761
+ };
762
+ onSort?: (field: string) => void;
763
+ selected: Set<string | number>;
764
+ setSelected: Dispatch<SetStateAction<Set<string | number>>>;
765
+ onRowClick: (item: T) => void;
766
+ onRowHover?: (item: T) => void;
767
+ getRowClassName?: (item: T) => string;
768
+ footerLabel: string;
769
+ footerExtra?: ReactNode;
770
+ sentinelRef?: RefObject<any>;
771
+ isFetchingNextPage?: boolean;
772
+ /** Perm codenames that gate "Save as default for all users" in the column
773
+ * picker. Defaults to `['change_numberingconfig']` (admin-portal's proxy
774
+ * for admin access). Pass `[]` to hide the link entirely. */
775
+ saveDefaultPerms?: string[];
776
+ }
777
+ /**
778
+ * The canonical pageless data grid for both portals. Wraps `<ResizableTable>`
779
+ * with selection-checkbox logic, keyboard navigation, the standardized list
780
+ * footer, and an infinite-scroll sentinel hook-up.
781
+ *
782
+ * Usage:
783
+ *
784
+ * const { sort, onSort } = useSort('mid');
785
+ * const { items, totalCount, isLoading, isFetchingNextPage, sentinelRef } =
786
+ * useInfiniteScroll<Supplier>({ queryKey: ['suppliers', filters],
787
+ * fetchFn: (p) => getSuppliers(p) });
788
+ *
789
+ * <EntityList
790
+ * items={items}
791
+ * totalCount={totalCount}
792
+ * isLoading={isLoading}
793
+ * sentinelRef={sentinelRef}
794
+ * isFetchingNextPage={isFetchingNextPage}
795
+ * tableId="suppliers"
796
+ * columns={SUPPLIER_COLUMNS}
797
+ * renderCell={(s, k) => …}
798
+ * sort={sort} onSort={onSort}
799
+ * selected={selected} setSelected={setSelected}
800
+ * onRowClick={(s) => openEntity('supplier', s.id, s, s.mid, '/suppliers')}
801
+ * footerLabel="suppliers"
802
+ * emptyState={<EmptyState message="No suppliers yet." />}
803
+ * />
804
+ */
805
+ declare function EntityList<T>(props: EntityListProps<T>): react_jsx_runtime.JSX.Element;
806
+
807
+ interface PaginatedResponse<T> {
808
+ count: number;
809
+ next: string | null;
810
+ previous: string | null;
811
+ results: T[];
812
+ }
813
+ interface ColumnDef {
814
+ key: string;
815
+ label: string;
816
+ defaultWidth?: number;
817
+ minWidth?: number;
818
+ defaultHidden?: boolean;
819
+ /** Optional rich header node (e.g. icon-only column). Falls back to label. */
820
+ headerNode?: React.ReactNode;
821
+ /** Optional override for the field used to sort against. */
822
+ sortField?: string;
823
+ }
824
+ interface SortState {
825
+ field: string;
826
+ direction: 'asc' | 'desc';
827
+ }
828
+
829
+ interface ResizableTableProps {
830
+ tableId: string;
831
+ columns: ColumnDef[];
832
+ sort?: SortState;
833
+ onSort?: (field: string) => void;
834
+ footer?: React.ReactNode;
835
+ afterBody?: React.ReactNode;
836
+ /** Permission codename(s) that gate the "Save as default for all users" link
837
+ * in the column picker. The shell's `useShellAuth().hasAnyPerm` is queried
838
+ * against this list. Defaults to a single placeholder permission; consumers
839
+ * with no admin gate can pass `[]` to hide the link entirely. */
840
+ saveDefaultPerms?: string[];
841
+ children: (orderedColumns: (ColumnDef & {
842
+ width: number;
843
+ })[]) => React.ReactNode;
844
+ }
845
+ /**
846
+ * Sticky-header, scrollable-body table primitive with:
847
+ * - drag-to-reorder columns (with a blue drop-indicator line)
848
+ * - resize columns by the right-edge handle
849
+ * - hide/show columns via a glass popover picker
850
+ * - admin-only "Save as default for all users" link in the picker
851
+ * - per-user persistence (via the shell-registered apiClient)
852
+ * - mobile-aware selection mode toggle
853
+ */
854
+ declare function ResizableTable({ tableId, columns, sort, onSort, footer, afterBody, saveDefaultPerms, children, }: ResizableTableProps): react_jsx_runtime.JSX.Element;
855
+
856
+ interface ListFooterProps {
857
+ selectedCount: number;
858
+ loadedCount: number;
859
+ totalCount?: number;
860
+ label: string;
861
+ isFetchingMore?: boolean;
862
+ extra?: ReactNode;
863
+ }
864
+ /**
865
+ * Standardized footer for `EntityList`. Shows:
866
+ * "[X selected — ] Y records"
867
+ * "Y of Z records · Loading more..."
868
+ * "All N records loaded"
869
+ */
870
+ declare function ListFooter({ selectedCount, loadedCount, totalCount, label, isFetchingMore, extra, }: ListFooterProps): react_jsx_runtime.JSX.Element;
871
+
872
+ /**
873
+ * Keyboard + shift-click navigation for table rows.
874
+ *
875
+ * - J/K or Arrow keys to move focus
876
+ * - Enter to open the focused row (calls `onSelect`)
877
+ * - Space to toggle the focused row's checkbox (calls `onToggle`)
878
+ * - Shift+J/K to extend selection while moving
879
+ * - Shift+click to range-select (calls `onSelectRange`)
880
+ * - Cmd/Ctrl+A to select/deselect all (calls `onSelectAll`)
881
+ *
882
+ * Each list instance gates its document-level listeners on `useModalActive`
883
+ * so two open lists don't both react to the same shift-click.
884
+ */
885
+ declare function useTableNav<T>(items: T[], onSelect: (item: T) => void, onToggle?: (item: T) => void, onSelectAll?: () => void, onSelectRange?: (from: number, to: number) => void): number;
886
+
887
+ /**
888
+ * Resizable + reorderable + hideable column state for `<ResizableTable>`.
889
+ *
890
+ * Persists per-user via `PATCH /auth/me/` (`preferences.columns_{tableId}`)
891
+ * with a 1-second debounce, and per-viewport admin defaults via
892
+ * `GET /auth/default-columns/{tableId}?viewport=…`. The consumer wires these
893
+ * endpoints on its backend; the shell's `apiClient` proxy resolves to the
894
+ * consumer-registered axios instance (`setShellApiClient`).
895
+ */
896
+ declare function useColumnConfig(tableId: string, defaultColumns: ColumnDef[]): {
897
+ orderedColumns: {
898
+ width: number;
899
+ key: string;
900
+ label: string;
901
+ defaultWidth?: number;
902
+ minWidth?: number;
903
+ defaultHidden?: boolean;
904
+ headerNode?: react__default.ReactNode;
905
+ sortField?: string;
906
+ }[];
907
+ allColumns: {
908
+ key: string;
909
+ label: string;
910
+ hidden: boolean;
911
+ }[];
912
+ onResizeStart: (idx: number, e: react__default.MouseEvent) => void;
913
+ onDragStart: (idx: number) => void;
914
+ onDragOver: (visIdx: number, e: react__default.DragEvent) => void;
915
+ onDrop: (_visIdx: number, e: react__default.DragEvent) => void;
916
+ onDragEnd: () => void;
917
+ toggleColumn: (key: string) => void;
918
+ resetColumns: () => void;
919
+ draggedIdx: number | null;
920
+ dropGap: number | null;
921
+ };
922
+
923
+ interface UseInfiniteScrollOptions<T> {
924
+ /** queryKey segments — arbitrary cache shapes (filters often include booleans,
925
+ * dates, undefined). Callers pass their natural filter shape. */
926
+ queryKey: (string | Record<string, unknown>)[];
927
+ fetchFn: (params: Record<string, string>) => Promise<PaginatedResponse<T>>;
928
+ /** Extra query-string params. Undefined values are dropped so axios doesn't
929
+ * serialise them as "?key=undefined". */
930
+ extraParams?: Record<string, string | undefined>;
931
+ pageSize?: number;
932
+ }
933
+ /**
934
+ * Wraps TanStack `useInfiniteQuery` with an IntersectionObserver-driven
935
+ * sentinel so attaching `sentinelRef` to a div near the bottom of a scrollable
936
+ * container auto-fires `fetchNextPage` as the user scrolls.
937
+ *
938
+ * Works inside modal windows too — the observer roots itself on the nearest
939
+ * scrollable ancestor rather than the viewport.
940
+ */
941
+ declare function useInfiniteScroll<T>({ queryKey, fetchFn, extraParams, pageSize: _pageSize, }: UseInfiniteScrollOptions<T>): {
942
+ items: T[];
943
+ totalCount: number;
944
+ isLoading: boolean;
945
+ isFetchingNextPage: boolean;
946
+ hasNextPage: boolean;
947
+ sentinelRef: react.RefObject<HTMLDivElement>;
948
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<_tanstack_query_core.InfiniteData<PaginatedResponse<T>, unknown>, Error>>;
949
+ };
950
+
739
951
  /** Package version, injected by tsup at build time. Stays as an empty
740
952
  * string when the source is consumed without a build (e.g. tests). */
741
953
  declare const VERSION: string;
@@ -905,4 +1117,4 @@ declare function useNewHotkey(callback: () => void): void;
905
1117
  */
906
1118
  declare function useEditHotkey(callback: (() => void) | null): void;
907
1119
 
908
- export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, ConfirmProvider, CopyButton, Customization, Desktop, type DesktopHostConfig, DesktopHostProvider, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, Layout, type LayoutProps, type LoginPayload, MOD, type MailCapabilities, MailConnectModal, type MailUser, Modal, ModalActions, NotificationBell, type NotificationsConfig, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, VERSION, WindowManagerProvider, WindowRegistry, WindowTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, glassStyle, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellMailServer, setShellNavIcons, setWindowDefaultPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useDesktopHost, useEditHotkey, useLocalStoragePrefs, useMailAuth, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
1120
+ export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, type BugReport, type BugReportConfig, BugReportConfigProvider, BugReportDetail, type BugReportExtraField, type BugReportExtraSelectField, BugReportProvider, type BugReportSubmission, type BugReportSubmitPayload, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, CancelButton, type CellStyle, type ChangelogEntry, type ColumnDef, ConfirmProvider, CopyButton, Customization, Desktop, type DesktopHostConfig, DesktopHostProvider, DocFavStar, ENTER, EditableGrid, type EditableGridProps, type EntityFetcher, EntityList, type EntityListColumn, type EntityListProps, GLASS_DIVIDER, GLASS_INPUT_BG, GlobalSearch, type GridColumn, Layout, type LayoutProps, ListFooter, type LoginPayload, MOD, type MailCapabilities, MailConnectModal, type MailUser, Modal, ModalActions, NotificationBell, type NotificationsConfig, type PaginatedResponse, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, type ReportType, ResizableTable, SHIFT, type SearchConfig, type SearchProvider, type SearchResult, type SemanticGroup, type ShellAuth, ShellAuthProvider, ShellEntityFetcherProvider, type ShellNotification, type ShellPrefsAdapter, ShellPrefsProvider, ShortcutHelp, type SortState, StartMenu, StatusBadge, StatusBadgeProvider, type StickyEntityRef, type StickyResolver, VERSION, WindowManagerProvider, WindowRegistry, WindowTitle, commitExposeHighlight, confirm, confirmDestructive, createWindowRegistry, exitExposeMode, formatDate, getActiveWindowRoute, getExposeHighlight, glassStyle, isMac, openBugReportDialog, prompt, reportBug, setExposeHighlight, setShellApiClient, setShellAuthBridge, setShellMailServer, setShellNavIcons, setWindowDefaultPosition, subscribeExposeHighlight, toast, toggleExposeMode, useBugReport, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useInfiniteScroll, useLocalStoragePrefs, useMailAuth, useModalActive, useNewHotkey, useShellAuth, useShellEntityFetcher, useShellPrefs, useTableNav, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };