@ynput/ayon-frontend-shared 0.7.5 → 0.7.6

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.
Files changed (37) hide show
  1. package/dist/DetailsPanel.es.js +376 -380
  2. package/dist/ListTable.es.js +2 -2
  3. package/dist/NewEntity.es.js +26 -26
  4. package/dist/ProjectTreeTable.es.js +2521 -2510
  5. package/dist/ProjectsTable.es.js +3 -3
  6. package/dist/Slicer.es.js +32 -32
  7. package/dist/Views.es.js +1 -1
  8. package/dist/chunks/ColumnDropIndicator.es.js +2 -2
  9. package/dist/chunks/ColumnHeaderMenuUI.es.js +1 -1
  10. package/dist/chunks/EntityPath.es.js +1 -1
  11. package/dist/chunks/EntityPickerDialog.es.js +481 -460
  12. package/dist/chunks/EntityTooltip.es.js +1 -1
  13. package/dist/chunks/Feed.es.js +11 -10
  14. package/dist/chunks/FilterErrorActions.es.js +1 -1
  15. package/dist/chunks/GroupSettingsFallback.es.js +2 -2
  16. package/dist/chunks/Menu.es.js +250 -247
  17. package/dist/chunks/MetaWidget.es.js +2 -2
  18. package/dist/chunks/PlayableIcon.es.js +368 -368
  19. package/dist/chunks/ProjectFoldersContext.es.js +237 -0
  20. package/dist/chunks/ReviewablesSelector.es.js +1223 -1170
  21. package/dist/chunks/SimpleTable.es.js +301 -296
  22. package/dist/chunks/Slicer.es.js +418 -410
  23. package/dist/chunks/TableExportContextInstance.es.js +428 -382
  24. package/dist/chunks/ThumbnailUploaderContext.es.js +48 -0
  25. package/dist/chunks/Watchers.es.js +2 -2
  26. package/dist/chunks/{ColumnDropIndicator.styled.es.js → addonColumnTags.es.js} +60 -47
  27. package/dist/components.es.js +1404 -1274
  28. package/dist/context.es.js +559 -657
  29. package/dist/hooks.es.js +2 -2
  30. package/dist/index.es.js +2 -2
  31. package/dist/types/EntityPickerDialog.d.ts +45 -2
  32. package/dist/types/ProjectTreeTable.d.ts +119 -17
  33. package/dist/types/components.d.ts +210 -23
  34. package/dist/types/context.d.ts +8 -0
  35. package/package.json +3 -3
  36. package/dist/chunks/ProjectContext.es.js +0 -158
  37. package/dist/chunks/useQueryArgumentChangeLoading.es.js +0 -11
@@ -198,7 +198,7 @@ export declare interface AddonButtonProps<S extends ButtonSlot> {
198
198
  context: Omit<SlotMap[S]['context'], 'navigate'>;
199
199
  /** the host's button; not called for a `component` item, which draws itself */
200
200
  renderButton: (props: AddonButtonRenderProps) => ReactNode;
201
- /** dev shell: open the dialog right away */
201
+ /** dev shell: open the dialog or popover right away */
202
202
  autoOpen?: boolean;
203
203
  /** dev shell: the context the item's code gets */
204
204
  onContext?: (context: object) => void;
@@ -206,7 +206,7 @@ export declare interface AddonButtonProps<S extends ButtonSlot> {
206
206
 
207
207
  export declare interface AddonButtonRenderProps {
208
208
  ref: (element: HTMLElement | null) => void;
209
- /** its dialog or menu is open */
209
+ /** its dialog, menu or popover is open */
210
210
  active: boolean;
211
211
  onClick: () => void;
212
212
  onMouseEnter: () => void;
@@ -224,6 +224,8 @@ export declare interface AddonDialogProps<S extends SlotName> {
224
224
  };
225
225
  }
226
226
 
227
+ export declare const AddonEntityPicker: ({ projectName, entityType, multiSelect, initialSelection, onSubmit, onClose, }: EntityPickerProps) => JSX_2.Element;
228
+
227
229
  /** The addon a contribution came from. */
228
230
  declare interface AddonInfo {
229
231
  /** addon name, as on the server */
@@ -255,6 +257,28 @@ declare type AddonMenuItem =
255
257
  danger?: boolean
256
258
  }
257
259
 
260
+ export declare const AddonMoreMenu: ({ items, icon, label, tooltip, variant, align, disabled, className, onError, "data-testid": testId, }: HostMoreMenuProps) => JSX_2.Element;
261
+
262
+ export declare const AddonServices: ({ projectName }: {
263
+ projectName: string | null;
264
+ }) => JSX_2.Element;
265
+
266
+ /** The signed-in user, as addons see it: in every slot's context (`user`) and from `useUser`. */
267
+ declare interface AddonUser {
268
+ name: string
269
+ fullName?: string
270
+ email?: string
271
+ /** admins, and service users (the server treats them as admins) */
272
+ isAdmin: boolean
273
+ /** managers and admins */
274
+ isManager: boolean
275
+ isGuest: boolean
276
+ /** a service user: an API key session (services, agents, CI) */
277
+ isService: boolean
278
+ /** developer mode is on */
279
+ isDeveloper: boolean
280
+ }
281
+
258
282
  declare type AlignType = 'left' | 'right';
259
283
 
260
284
  declare type Anatomy = {
@@ -288,6 +312,18 @@ declare interface AnyContribution {
288
312
  [field: string]: unknown
289
313
  }
290
314
 
315
+ /** Context of a service. */
316
+ declare interface AppServiceContext {
317
+ /** the project whose page is open, else `null` */
318
+ projectName: string | null
319
+ }
320
+
321
+ /** Description of an `app.service` contribution. */
322
+ declare interface AppServiceMeta {
323
+ /** unique among the addon's services */
324
+ id: string
325
+ }
326
+
291
327
  export declare type AttributeData = {
292
328
  id: string;
293
329
  isExpanded: boolean;
@@ -436,8 +472,11 @@ declare const Button: IStyledComponentBase<"web", FastOmit<Omit< ButtonProps & R
436
472
  ref?: ((instance: HTMLButtonElement | null) => void | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | RefObject<HTMLButtonElement> | null | undefined;
437
473
  }, never>>> & string & Omit< ForwardRefExoticComponent< ButtonProps & RefAttributes<HTMLButtonElement>>, keyof Component<any, {}, any>>;
438
474
 
439
- /** What a button contribution does on click: exactly one is set (checked when the manifest loads). */
440
- export declare type ButtonAction = 'to' | 'run' | 'dialog' | 'menu' | 'component';
475
+ /**
476
+ * What a button contribution does on click: exactly one is set (checked when the manifest loads),
477
+ * except that a `component` may be a `popover`'s button (the action is then `popover`).
478
+ */
479
+ export declare type ButtonAction = 'to' | 'run' | 'dialog' | 'menu' | 'popover' | 'component';
441
480
 
442
481
  /** Description fields of a button the host draws (header and toolbar items). */
443
482
  declare interface ButtonMeta {
@@ -463,8 +502,20 @@ declare interface ButtonPieces<S extends SlotName> {
463
502
  dialog?: Loader<ComponentType<SlotProps<S> & DialogScope>>
464
503
  /** the items of a menu the host opens under the button, like the header's help menu */
465
504
  menu?: Loader<MenuPiece<S>>
466
- /** the addon's own component instead of the host's button: a dropdown, a toggle, anything */
467
- component?: Loader<ComponentType<SlotProps<S>>>
505
+ /**
506
+ * the content of a popover the host opens under the button, like the header's menus: the host
507
+ * positions it and closes it on a click outside or Escape (an Escape or click inside a menu or
508
+ * dialog opened from the popover closes only that). It gets `close`
509
+ */
510
+ popover?: Loader<ComponentType<SlotProps<S> & PopoverScope>>
511
+ /**
512
+ * the addon's own component instead of the host's button: a dropdown, a toggle, anything. With
513
+ * `popover`, it is the popover's button (its icon, a badge, a tooltip of its own) and gets
514
+ * `popoverOpen` and `togglePopover`
515
+ */
516
+ component?:
517
+ | Loader<ComponentType<SlotProps<S>>>
518
+ | Loader<ComponentType<SlotProps<S> & PopoverButtonScope>>
468
519
  }
469
520
 
470
521
  /** Context of a button's code (`run`, `dialog`, `menu`, `component`) besides the slot's own. */
@@ -1024,11 +1075,7 @@ declare type DetailsPanelFolderFragmentFragment = {
1024
1075
  };
1025
1076
 
1026
1077
  /** Context of a details panel menu item. */
1027
- declare interface DetailsPanelMenuItemContext extends ProjectNameScope {
1028
- entityType: string
1029
- /** the entities the panel shows */
1030
- selectedEntities: EntityRef[]
1031
- }
1078
+ declare interface DetailsPanelMenuItemContext extends ProjectNameScope, EntityScope {}
1032
1079
 
1033
1080
  /** Description of a `detailsPanel.menuItem` contribution. */
1034
1081
  declare interface DetailsPanelMenuItemMeta extends MenuItemMeta {
@@ -1340,6 +1387,30 @@ export declare interface EntityPathProps {
1340
1387
  scope: string;
1341
1388
  }
1342
1389
 
1390
+ declare interface EntityPickerProps {
1391
+ /** the project to pick from */
1392
+ projectName: string
1393
+ /**
1394
+ * What to pick. The picker also shows the types above it to narrow the list down, e.g. folders
1395
+ * then tasks for `task`, folders, products then versions for `version`.
1396
+ */
1397
+ entityType: PickableEntityType
1398
+ /** let the user pick several; one by default */
1399
+ multiSelect?: boolean
1400
+ /**
1401
+ * Selected when the picker opens: entities of `entityType`, or of a type above it to narrow the
1402
+ * list (a folder opens the folder tree at it). `EntityRef`s from a slot context fit as they are.
1403
+ */
1404
+ initialSelection?: Pick<EntityRef, 'id' | 'entityType'>[]
1405
+ /**
1406
+ * The picked entities, of `entityType` in this project. `name` and `label` are set when the
1407
+ * picker has loaded them. The picker stays open until you stop rendering it: close it here.
1408
+ */
1409
+ onSubmit: (entities: EntityRef[]) => void
1410
+ /** the user closed the picker without picking (its close button or Escape) */
1411
+ onClose: () => void
1412
+ }
1413
+
1343
1414
  /** An entity a slot is about: its id and type, and its name when the host has it. */
1344
1415
  declare interface EntityRef {
1345
1416
  id: string
@@ -1352,7 +1423,9 @@ declare interface EntityRef {
1352
1423
 
1353
1424
  /** Slots about one or more entities of one type. */
1354
1425
  declare interface EntityScope {
1426
+ /** the type of every entity in `entities` */
1355
1427
  entityType: string
1428
+ /** the entities the slot is about, e.g. the ones the details panel shows */
1356
1429
  entities: EntityRef[]
1357
1430
  }
1358
1431
 
@@ -2018,6 +2091,12 @@ declare type HeroTemplate = {
2018
2091
  file: string;
2019
2092
  };
2020
2093
 
2094
+ /** What the host's `MoreMenu` gets: the addon's props and where to report a failing item. */
2095
+ declare interface HostMoreMenuProps extends MoreMenuProps {
2096
+ /** a failing `onClick`: shown as a toast naming the addon */
2097
+ onError: (error: unknown) => void
2098
+ }
2099
+
2021
2100
  declare type IconInputPt = Partial<React.ComponentProps<typeof Styled.IconSelect>>;
2022
2101
 
2023
2102
  declare type IconModel = {
@@ -2484,6 +2563,10 @@ declare interface MenuContainerProps {
2484
2563
  targetId?: string;
2485
2564
  align?: AlignType;
2486
2565
  theme?: ThemeType;
2566
+ /** open state kept by the caller instead of the app's one open menu (`menuOpen === id`) */
2567
+ isOpen?: boolean;
2568
+ /** with `isOpen`: called to close it (`onClose` stays the dialog's own event) */
2569
+ onDismiss?: () => void;
2487
2570
  children: ReactNode;
2488
2571
  [key: string]: any;
2489
2572
  }
@@ -2580,6 +2663,26 @@ declare interface MenuProps {
2580
2663
  footer?: string;
2581
2664
  }
2582
2665
 
2666
+ declare interface MoreMenuProps {
2667
+ /** the menu's entries: the same items a `menu` piece returns (dividers, submenus, `danger`, ...) */
2668
+ items: AddonMenuItem[]
2669
+ /** a Material Symbols icon name; `more_horiz` (AYON's "more" button) when not set */
2670
+ icon?: string
2671
+ /** shown next to the icon; an icon-only button when not set */
2672
+ label?: string
2673
+ /** shown on hover and read by screen readers; the label, or `More`, when not set */
2674
+ tooltip?: string
2675
+ /** the button's look, as AYON's `Button`: `text` (default), `surface`, `tonal`, `filled`, `nav` */
2676
+ variant?: 'text' | 'surface' | 'tonal' | 'filled' | 'nav' | 'tertiary' | 'danger'
2677
+ /** which edge of the button the menu lines up with: `right` (default) or `left` */
2678
+ align?: 'left' | 'right'
2679
+ disabled?: boolean
2680
+ /** on the button */
2681
+ className?: string
2682
+ /** on the button, for tests */
2683
+ 'data-testid'?: string
2684
+ }
2685
+
2583
2686
  export declare const NO_DATE = "no-date";
2584
2687
 
2585
2688
  export declare type NormalizedData = {
@@ -2774,12 +2877,32 @@ export declare type PathSegment = {
2774
2877
  id: string;
2775
2878
  };
2776
2879
 
2880
+ /** What `EntityPicker` picks. */
2881
+ declare type PickableEntityType = 'folder' | 'task' | 'product' | 'version' | 'representation' | 'workfile'
2882
+
2777
2883
  export declare const Placeholder: IStyledComponentBase<"web", FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick< DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
2778
2884
 
2779
2885
  declare const Placeholder_2: IStyledComponentBase<"web", FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick< DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
2780
2886
 
2781
2887
  declare const PlaceholderWrapper: IStyledComponentBase<"web", FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick< DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
2782
2888
 
2889
+ /**
2890
+ * What a `component` gets besides the slot context when it draws the button of a `popover`. The
2891
+ * host anchors the popover on the component's box.
2892
+ */
2893
+ declare interface PopoverButtonScope {
2894
+ /** the popover is open: show the button as active (`aria-expanded`) */
2895
+ popoverOpen: boolean
2896
+ /** opens or closes the popover: the button's `onClick` */
2897
+ togglePopover: () => void
2898
+ }
2899
+
2900
+ /** What a `popover` piece gets besides the slot context. */
2901
+ declare interface PopoverScope {
2902
+ /** closes the popover */
2903
+ close: () => void
2904
+ }
2905
+
2783
2906
  export declare const PowerpackButton: ForwardRefExoticComponent<PowerpackButtonProps & RefAttributes<HTMLButtonElement>>;
2784
2907
 
2785
2908
  export declare interface PowerpackButtonProps extends Omit<ButtonProps, 'variant'> {
@@ -3207,6 +3330,12 @@ export declare const renderYouTubeParagraph: (props: {
3207
3330
  node?: HastNode;
3208
3331
  }) => ReactNode | null;
3209
3332
 
3333
+ export declare const ReportCrash: ({ contribution, error, onReported, }: {
3334
+ contribution: AnyContribution;
3335
+ error: Error;
3336
+ onReported: () => void;
3337
+ }) => null;
3338
+
3210
3339
  export declare interface ReportsLoadingScreenProps extends HTMLAttributes<HTMLDivElement> {
3211
3340
  showSidebar?: boolean;
3212
3341
  sidebarConfig?: SidebarConfig;
@@ -3594,6 +3723,12 @@ export declare interface ShareOptionIconProps {
3594
3723
  withTooltip?: boolean;
3595
3724
  }
3596
3725
 
3726
+ /**
3727
+ * The entities of a shortcut's rows: every row of the project tables is one (list items resolve
3728
+ * to theirs). The panels' rows are not all entities (the lists panel's are lists), so none there.
3729
+ */
3730
+ export declare const shortcutEntities: (table: ShortcutTable, projectName: string | null, rows: TableRowRef[]) => EntityRef[];
3731
+
3597
3732
  declare type ShortcutKeyEvent = Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'metaKey' | 'altKey' | 'shiftKey' | 'repeat'> & {
3598
3733
  preventDefault: () => void;
3599
3734
  stopPropagation: () => void;
@@ -3696,6 +3831,8 @@ declare interface SlicerMenuItemContext extends ProjectNameScope {
3696
3831
  sliceType: string
3697
3832
  /** the rows it acts on: the selected ones, or the right-clicked one */
3698
3833
  selected: SlicerRowRef[]
3834
+ /** `hierarchy`: the folders and tasks of `selected`; empty for the other slice types */
3835
+ entities: EntityRef[]
3699
3836
  menu: MenuKind
3700
3837
  }
3701
3838
 
@@ -3738,9 +3875,12 @@ declare type SlideOut = {
3738
3875
  projectName: string;
3739
3876
  };
3740
3877
 
3741
- /** What the code of a contribution to slot `S` gets: `{ slot: S, ...context }`. */
3878
+ /**
3879
+ * What the code of a contribution to slot `S` gets: `{ slot: S, user, ...context }`. The host
3880
+ * passes the slot's own context; `ContributionView` and `runContribution` add `slot` and `user`.
3881
+ */
3742
3882
  declare type SlotContext<S extends SlotName> = S extends SlotName
3743
- ? { slot: S } & SlotMap[S]['context']
3883
+ ? { slot: S } & UserScope & SlotMap[S]['context']
3744
3884
  : never
3745
3885
 
3746
3886
  /**
@@ -3771,8 +3911,9 @@ declare interface SlotMap {
3771
3911
  }
3772
3912
  /**
3773
3913
  * A button in the main header, drawn by the host like its own buttons. What a click does is the
3774
- * addon's: navigate (`to`), run code (`run`), open a dialog (`dialog`) or a menu (`menu`); or the
3775
- * addon draws the item itself (`component`, loaded with the header). Set exactly one.
3914
+ * addon's: navigate (`to`), run code (`run`), open a dialog (`dialog`), a menu (`menu`) or a
3915
+ * popover (`popover`); or the addon draws the item itself (`component`, loaded with the header).
3916
+ * Set exactly one, except that `component` may draw the button of a `popover`.
3776
3917
  */
3777
3918
  'header.item': {
3778
3919
  version: 1
@@ -3833,8 +3974,9 @@ declare interface SlotMap {
3833
3974
  /**
3834
3975
  * A button in the project tables' toolbar, before Customize (Overview, Products, Lists), drawn
3835
3976
  * by the host like the toolbar's own. What a click does is the addon's: navigate (`to`), run code
3836
- * (`run`), open a dialog (`dialog`) or a menu (`menu`); or the addon draws the item itself
3837
- * (`component`, loaded with the toolbar). Set exactly one.
3977
+ * (`run`), open a dialog (`dialog`), a menu (`menu`) or a popover (`popover`); or the addon draws
3978
+ * the item itself (`component`, loaded with the toolbar). Set exactly one, except that
3979
+ * `component` may draw the button of a `popover`.
3838
3980
  */
3839
3981
  'projectTable.toolbarItem': {
3840
3982
  version: 1
@@ -3857,7 +3999,9 @@ declare interface SlotMap {
3857
3999
  * settings from the description; `cell` and `fetchValues` load with the table. The host draws
3858
4000
  * the cell box (padding, selection, focus), so `cell` renders only its content; selecting, the
3859
4001
  * right-click menu and Copy (the cell's `value` as text) work as in other columns. Not sortable,
3860
- * and pasting into it changes nothing.
4002
+ * and pasting into it changes nothing. When the values depend on data your mutations change, list
4003
+ * its cache tags in `providesTags` and the column refreshes itself when they are invalidated:
4004
+ * `tableColumn({ id, label, cell, fetchValues, providesTags: [{ type: 'myaddonLog', id: 'LIST' }] })`.
3861
4005
  */
3862
4006
  tableColumn: {
3863
4007
  version: 1
@@ -3881,6 +4025,19 @@ declare interface SlotMap {
3881
4025
  context: TableShortcutContext
3882
4026
  pieces: TableShortcutPieces
3883
4027
  }
4028
+ /**
4029
+ * Code with no UI that runs while AYON is open, whatever the page: keeping a state, listening to
4030
+ * websocket events, registering a store listener. `component` loads at startup and is mounted
4031
+ * once for the whole app, under AYON's providers (store, router, contexts), so it can use hooks;
4032
+ * it renders nothing (`return null`). Clean up in its effects. A crash unmounts it and shows a
4033
+ * toast; the rest of AYON keeps working.
4034
+ */
4035
+ 'app.service': {
4036
+ version: 1
4037
+ meta: AppServiceMeta
4038
+ context: AppServiceContext
4039
+ pieces: { component: Loader<ComponentType<SlotProps<'app.service'>>> }
4040
+ }
3884
4041
  }
3885
4042
 
3886
4043
  /** The name of a slot, e.g. `'project.page'`. */
@@ -4100,7 +4257,8 @@ declare interface TableCellContext extends ProjectNameScope {
4100
4257
  * Gets a column's values, by entity id; each cell gets its own as `value`. AYON calls it with
4101
4258
  * the rows that come on screen and that it has no value for yet, in batches once scrolling
4102
4259
  * pauses, and keeps what it returns: scrolling back costs nothing. A row whose entity changes
4103
- * (here or by someone else) is asked for again; `refreshTableColumn(id)` asks again for all.
4260
+ * (here or by someone else) is asked for again; for anything else the values depend on, list its
4261
+ * cache tags in the column's `providesTags`, or call `refreshTableColumn(id)` to ask again for all.
4104
4262
  * When it throws, those cells show the error and are tried again when they next come on
4105
4263
  * screen. Fetch through AYON's store (`dispatch(api.endpoints.x.initiate(...))`) to share its
4106
4264
  * cache.
@@ -4135,8 +4293,23 @@ declare interface TableColumnMeta {
4135
4293
  * `false` for the menu's top level
4136
4294
  */
4137
4295
  menu?: string | false
4296
+ /**
4297
+ * cache tags of AYON's api that the values depend on: when one is invalidated (by your
4298
+ * mutations or AYON's), the values are fetched again as with `refreshTableColumn`. Needs
4299
+ * `fetchValues`. Names as you register them (`enhanceEndpoints({ addTagTypes })`, prefixed with
4300
+ * your addon name) or AYON's own. A plain name follows invalidations of the whole type only: to
4301
+ * follow `{ type, id }`, such as a list tag, give that tag
4302
+ */
4303
+ providesTags?: TableColumnTag[]
4138
4304
  }
4139
4305
 
4306
+ /**
4307
+ * A cache tag a `tableColumn` depends on (`providesTags`), as in RTK Query: a tag type, or a type
4308
+ * and id. Invalidating `'x'` refreshes columns that list `'x'` or `{ type: 'x', id }`;
4309
+ * invalidating `{ type: 'x', id: 'LIST' }` refreshes only columns that list that tag.
4310
+ */
4311
+ declare type TableColumnTag = string | { type: string; id?: string | number }
4312
+
4140
4313
  export declare const TableGridSwitch: ForwardRefExoticComponent<TableGridSwitchProps & RefAttributes<HTMLDivElement>>;
4141
4314
 
4142
4315
  declare interface TableGridSwitchProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
@@ -4190,6 +4363,11 @@ declare interface TableShortcutContext {
4190
4363
  projectName: string | null
4191
4364
  /** the rows it acts on: the selected ones when the key was pressed in one of them, else its row */
4192
4365
  rows: TableRowRef[]
4366
+ /**
4367
+ * the entities of `rows` in the project tables (list items resolve to their entity); empty in
4368
+ * the panels' tables, whose rows are not all entities: read `rows` there
4369
+ */
4370
+ entities: EntityRef[]
4193
4371
  /** where the key was pressed: the row's id, and the column's in the project tables */
4194
4372
  focused: { rowId: string; columnId?: string }
4195
4373
  /** project tables: the selected cells, by row (entity) and column id; empty elsewhere */
@@ -4227,6 +4405,9 @@ declare interface TableShortcutPieces {
4227
4405
  dialog?: Loader<ComponentType<SlotProps<'table.shortcut'> & DialogScope>>
4228
4406
  }
4229
4407
 
4408
+ /** The context without `entities`: the hook adds them from the rows. */
4409
+ export declare type TableShortcutRows = Omit<TableShortcutContext, 'entities'>;
4410
+
4230
4411
  declare interface TabStateByScope {
4231
4412
  [scope: string]: DetailsPanelTab;
4232
4413
  }
@@ -4395,9 +4576,10 @@ export declare const toggleBlockFormat: (editor: LexicalEditor, format: BlockFor
4395
4576
 
4396
4577
  /**
4397
4578
  * An addon's menu entries as the shared Menu's items: `to` and `href` become links (the Menu
4398
- * follows them), and a failing `onClick` is reported as a toast naming the addon.
4579
+ * follows them), and a failing `onClick` goes to `onError` (`reportContributionError`: a toast
4580
+ * naming the addon). Used by `menu` buttons and `MoreMenu`.
4399
4581
  */
4400
- export declare const toMenuItems: (items: AddonMenuItem[], contribution: AnyContribution) => MenuItemType[];
4582
+ export declare const toMenuItems: (items: AddonMenuItem[], onError: (error: unknown) => void) => MenuItemType[];
4401
4583
 
4402
4584
  export declare type ToolbarItem = 'h1' | 'h2' | 'h3' | 'bold' | 'italic' | 'strikethrough' | 'code' | 'link' | 'codeBlock' | 'quote' | 'numberList' | 'bulletList' | 'checkList';
4403
4585
 
@@ -4472,8 +4654,8 @@ export declare const useAddonCustomizeSections: (page: ProjectTablePage) => Sett
4472
4654
  /** `table`: which table this is; no shortcuts when not set. */
4473
4655
  export declare const useAddonTableShortcuts: (table: ShortcutTable | undefined) => {
4474
4656
  hasShortcuts: boolean;
4475
- handleShortcut: (event: ShortcutKeyEvent, getContext: () => Omit<TableShortcutContext, "table"> | undefined) => boolean;
4476
- runShortcut: (contribution: Contribution<"table.shortcut">, context: TableShortcutContext) => void;
4657
+ handleShortcut: (event: ShortcutKeyEvent, getContext: () => Omit<TableShortcutRows, "table"> | undefined) => boolean;
4658
+ runShortcut: (contribution: Contribution<"table.shortcut">, rowsContext: TableShortcutRows) => void;
4477
4659
  dialog: OpenAddonShortcutDialog | null;
4478
4660
  };
4479
4661
 
@@ -4570,6 +4752,11 @@ declare type UserModel = {
4570
4752
  updatedAt?: string;
4571
4753
  };
4572
4754
 
4755
+ /** Every slot: the signed-in user. The host adds it; AYON renders addons only once signed in. */
4756
+ declare interface UserScope {
4757
+ user: AddonUser
4758
+ }
4759
+
4573
4760
  declare type UserSuggestionItem = {
4574
4761
  /** The date and time when the suggested entity was created */
4575
4762
  createdAt?: string;
@@ -77,6 +77,10 @@ declare interface AddonDevOverride {
77
77
 
78
78
  export declare type AddonDevState = {
79
79
  status: 'off';
80
+ } | {
81
+ status: 'rejected';
82
+ request: string;
83
+ reason: string;
80
84
  } | {
81
85
  status: 'loading';
82
86
  override: AddonDevOverride;
@@ -84,6 +88,7 @@ export declare type AddonDevState = {
84
88
  status: 'active';
85
89
  override: AddonDevOverride;
86
90
  info: AddonDevInfo;
91
+ error?: string;
87
92
  } | {
88
93
  status: 'error';
89
94
  override: AddonDevOverride;
@@ -1159,6 +1164,7 @@ export declare const ProjectFoldersContext: Context<ProjectFoldersContextValue |
1159
1164
  export declare const ProjectFoldersContextProvider: React.FC<ProjectFoldersProviderProps>;
1160
1165
 
1161
1166
  export declare interface ProjectFoldersContextValue {
1167
+ projectName: string;
1162
1168
  folders: FolderListItem[];
1163
1169
  getFolderById: (id: string) => FolderListItem | undefined;
1164
1170
  findNonInheritedValues: (folderId: string | undefined, attribNames: string[], projectAttrib?: Record<string, any>) => Record<string, any>;
@@ -1990,6 +1996,8 @@ export declare const useMenuContext: () => MenuContextType;
1990
1996
 
1991
1997
  export declare const useOptionalProjectContext: () => ProjectContextValue | undefined;
1992
1998
 
1999
+ export declare const useOptionalProjectFoldersContext: () => ProjectFoldersContextValue | undefined;
2000
+
1993
2001
  export declare function usePiPWindow(): PiPContextType;
1994
2002
 
1995
2003
  export declare const usePowerpack: () => PowerpackContextType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynput/ayon-frontend-shared",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "Shared React components for AYON frontend",
5
5
  "repository": {
6
6
  "type": "git",
@@ -104,8 +104,8 @@
104
104
  "@reduxjs/toolkit": "2.11.2",
105
105
  "@rtk-query/graphql-request-base-query": "2.3.2",
106
106
  "@tanstack/react-table": "8.21.3",
107
- "@ynput/ayon-addon": "^0.1.1",
108
- "@ynput/ayon-react-components": "^1.24.0",
107
+ "@ynput/ayon-addon": "0.2.0",
108
+ "@ynput/ayon-react-components": "^1.25.0",
109
109
  "graphql-request": "7.4.0",
110
110
  "react": "18.3.1",
111
111
  "react-dom": "18.3.1",
@@ -1,158 +0,0 @@
1
- import { jsx as P } from "react/jsx-runtime";
2
- import { useState as M, useCallback as u } from "react";
3
- import { u as F } from "./useCreateContextMenu.es.js";
4
- import { T as S, P as _ } from "./TableExportContextInstance.es.js";
5
- import "./searchTerms.es.js";
6
- import { ca as w, c7 as B, dI as G } from "./getUris.es.js";
7
- import "primereact/confirmdialog";
8
- import "lodash";
9
- import "react-toastify";
10
- import { g as m } from "./getEntityTypeIcon.es.js";
11
- import "uuid";
12
- import "axios";
13
- const X = ({
14
- children: t,
15
- thumbnailInputRef: c,
16
- versionsInputRef: e,
17
- canUploadVersion: r = !1
18
- }) => {
19
- const [, a] = M(!1), [T] = F(), f = () => a(!1), d = () => {
20
- c?.current && (c.current.click(), a(!0));
21
- }, i = () => {
22
- e?.current && (e.current.click(), a(!0));
23
- }, l = (y) => {
24
- const s = [
25
- {
26
- label: "Upload thumbnail",
27
- icon: "add_photo_alternate",
28
- command: d
29
- },
30
- ...r ? [
31
- {
32
- label: "Upload version",
33
- icon: "upload",
34
- command: i
35
- }
36
- ] : []
37
- ];
38
- T(y, s);
39
- };
40
- return /* @__PURE__ */ P(
41
- S.Provider,
42
- {
43
- value: {
44
- resetFileUploadState: f,
45
- triggerThumbnailUpload: d,
46
- triggerVersionUpload: i,
47
- canUploadVersion: r,
48
- onContextMenu: l
49
- },
50
- children: t
51
- }
52
- );
53
- }, Q = {
54
- name: "",
55
- code: "",
56
- productTypes: [],
57
- folderTypes: [],
58
- taskTypes: [],
59
- tags: [],
60
- statuses: [],
61
- createdAt: "",
62
- updatedAt: "",
63
- active: !0,
64
- attrib: {},
65
- data: {},
66
- config: {},
67
- library: !1,
68
- linkTypes: [],
69
- ownAttrib: []
70
- };
71
- function j(t) {
72
- if (!t)
73
- return { productTypes: [], productBaseTypes: [] };
74
- const c = t.productTypes || [], e = /* @__PURE__ */ new Map();
75
- return c.forEach((r) => {
76
- e.has(r.baseType) || e.set(r.baseType, {
77
- name: r.baseType,
78
- icon: r.icon,
79
- color: r.color
80
- });
81
- }), {
82
- productTypes: c,
83
- productBaseTypes: Array.from(e.values())
84
- };
85
- }
86
- const Y = ({
87
- projectName: t,
88
- children: c
89
- }) => {
90
- const {
91
- data: e,
92
- isLoading: r,
93
- isFetching: a,
94
- isSuccess: T,
95
- isUninitialized: f,
96
- error: d,
97
- refetch: i
98
- } = w({ projectName: t }, { skip: !t }), { data: l = {}, refetch: y } = B(
99
- { projectName: t },
100
- { skip: !t }
101
- ), s = l.product_base_types?.default, { data: g } = G(
102
- { projectName: t },
103
- {
104
- skip: !t
105
- }
106
- ), { productTypes: p, productBaseTypes: b } = j(g), h = u(
107
- (n) => e?.folderTypes?.find((o) => o.name === n),
108
- [e]
109
- ), k = u(
110
- (n) => e?.taskTypes?.find((o) => o.name === n),
111
- [e]
112
- ), v = u(
113
- (n) => {
114
- const o = p.find((C) => C.name === n);
115
- return {
116
- icon: o?.icon || s?.icon || m("product"),
117
- color: o?.color || s?.color
118
- };
119
- },
120
- [p, s]
121
- ), x = u(() => p.map((o) => ({
122
- value: o.name,
123
- label: o.name,
124
- icon: o.icon || s?.icon || m("product"),
125
- color: o.color || s?.color || ""
126
- })), [p, s]), U = u(() => {
127
- i(), y();
128
- }, [i, y]), A = {
129
- getFolderType: h,
130
- getTaskType: k,
131
- getProductType: v,
132
- getProductTypeOptions: x,
133
- refetch: U
134
- };
135
- return /* @__PURE__ */ P(
136
- _.Provider,
137
- {
138
- value: {
139
- ...Q,
140
- ...e,
141
- projectName: t,
142
- productTypes: p,
143
- productBaseTypes: b,
144
- anatomy: l,
145
- isLoading: r || a,
146
- isSuccess: T,
147
- isUninitialized: f,
148
- error: d,
149
- ...A
150
- },
151
- children: c
152
- }
153
- );
154
- };
155
- export {
156
- Y as P,
157
- X as T
158
- };
@@ -1,11 +0,0 @@
1
- import { useRef as a, useState as c, useEffect as f } from "react";
2
- const g = (e, n) => {
3
- const o = a(null), [u, r] = c(!1);
4
- return f(() => {
5
- const t = o.current;
6
- !t || Object.keys(e).some((s) => t[s] !== e[s]) || Object.keys(t).some((s) => t[s] !== e[s]) ? (o.current = { ...e }, r(n)) : n || r(!1);
7
- }, [Object.values(e).join(","), n]), u;
8
- };
9
- export {
10
- g as u
11
- };