@ynput/ayon-frontend-shared 0.2.6 → 0.2.7

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 (76) hide show
  1. package/dist/_virtual/index.cjs10.js +5 -3
  2. package/dist/_virtual/index.cjs10.js.map +1 -1
  3. package/dist/_virtual/index.cjs4.js +4 -4
  4. package/dist/_virtual/index.cjs5.js +5 -3
  5. package/dist/_virtual/index.cjs5.js.map +1 -1
  6. package/dist/_virtual/index.cjs6.js +3 -5
  7. package/dist/_virtual/index.cjs6.js.map +1 -1
  8. package/dist/_virtual/index.cjs7.js +3 -5
  9. package/dist/_virtual/index.cjs7.js.map +1 -1
  10. package/dist/_virtual/index.cjs8.js +4 -4
  11. package/dist/_virtual/index.cjs9.js +4 -4
  12. package/dist/_virtual/index.es10.js +5 -2
  13. package/dist/_virtual/index.es10.js.map +1 -1
  14. package/dist/_virtual/index.es4.js +4 -4
  15. package/dist/_virtual/index.es5.js +5 -2
  16. package/dist/_virtual/index.es5.js.map +1 -1
  17. package/dist/_virtual/index.es6.js +2 -5
  18. package/dist/_virtual/index.es6.js.map +1 -1
  19. package/dist/_virtual/index.es7.js +2 -5
  20. package/dist/_virtual/index.es7.js.map +1 -1
  21. package/dist/_virtual/index.es8.js +4 -4
  22. package/dist/_virtual/index.es9.js +4 -4
  23. package/dist/node_modules/match-sorter/dist/match-sorter.esm.cjs.js +1 -1
  24. package/dist/node_modules/match-sorter/dist/match-sorter.esm.es.js +1 -1
  25. package/dist/node_modules/parse-numeric-range/index.cjs.js +1 -1
  26. package/dist/node_modules/parse-numeric-range/index.es.js +1 -1
  27. package/dist/node_modules/rehype/node_modules/unified/lib/index.cjs.js +2 -2
  28. package/dist/node_modules/rehype/node_modules/unified/lib/index.es.js +2 -2
  29. package/dist/node_modules/rehype-parse/lib/index.cjs.js +1 -1
  30. package/dist/node_modules/rehype-parse/lib/index.es.js +1 -1
  31. package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
  32. package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
  33. package/dist/node_modules/remove-accents/index.cjs.js +1 -1
  34. package/dist/node_modules/remove-accents/index.es.js +1 -1
  35. package/dist/node_modules/vfile/lib/index.cjs.js +1 -1
  36. package/dist/node_modules/vfile/lib/index.es.js +1 -1
  37. package/dist/shared/src/api/generated/graphql.cjs.js +2 -0
  38. package/dist/shared/src/api/generated/graphql.cjs.js.map +1 -1
  39. package/dist/shared/src/api/generated/graphql.es.js +2 -0
  40. package/dist/shared/src/api/generated/graphql.es.js.map +1 -1
  41. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js +0 -1
  42. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js.map +1 -1
  43. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js +0 -1
  44. package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js.map +1 -1
  45. package/dist/shared/src/containers/Actions/Actions.cjs.js +5 -2
  46. package/dist/shared/src/containers/Actions/Actions.cjs.js.map +1 -1
  47. package/dist/shared/src/containers/Actions/Actions.es.js +5 -2
  48. package/dist/shared/src/containers/Actions/Actions.es.js.map +1 -1
  49. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js +9 -3
  50. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js.map +1 -1
  51. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js +9 -3
  52. package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js.map +1 -1
  53. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js +3 -1
  54. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js.map +1 -1
  55. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js +3 -1
  56. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js.map +1 -1
  57. package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.cjs.js +1 -1
  58. package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.cjs.js.map +1 -1
  59. package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.es.js +1 -1
  60. package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.es.js.map +1 -1
  61. package/dist/shared/src/context/DetailsPanelContext.cjs.js +0 -1
  62. package/dist/shared/src/context/DetailsPanelContext.cjs.js.map +1 -1
  63. package/dist/shared/src/context/DetailsPanelContext.es.js +0 -1
  64. package/dist/shared/src/context/DetailsPanelContext.es.js.map +1 -1
  65. package/dist/shared/src/hooks/useActionTriggers.cjs.js +7 -6
  66. package/dist/shared/src/hooks/useActionTriggers.cjs.js.map +1 -1
  67. package/dist/shared/src/hooks/useActionTriggers.es.js +7 -6
  68. package/dist/shared/src/hooks/useActionTriggers.es.js.map +1 -1
  69. package/dist/types/SimpleTable/SimpleTable.d.ts +9 -2
  70. package/dist/types/SimpleTable/SimpleTableRowTemplate.d.ts +7 -0
  71. package/dist/types/api/generated/graphql.d.ts +3 -1
  72. package/dist/types/containers/Actions/Actions.d.ts +4 -3
  73. package/dist/types/containers/ProjectTreeTable/ProjectTreeTable.d.ts +7 -6
  74. package/dist/types/context/DetailsPanelContext.d.ts +8 -2
  75. package/dist/types/hooks/useActionTriggers.d.ts +6 -1
  76. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"clientFilterToQueryFilter.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.ts"],"sourcesContent":["import { FILTER_SEPARATOR, getFilterFromId } from '@ynput/ayon-react-components'\nimport { QueryCondition, QueryFilter } from '../types/operations'\n\n// New type that cherry picks only the needed fields from Filter\nexport type FilterForQuery = {\n id: string\n values?: { id: string; values?: { id: string }[] }[]\n type?: string\n singleSelect?: boolean\n inverted?: boolean\n operator?: string\n}\n\nconst NO_DATE = 'no_date'\nexport const clientFilterToQueryFilter = (filters: FilterForQuery[]): QueryFilter => {\n // If there are no filters, return an empty filter\n if (!filters || filters.length === 0) {\n return {}\n }\n\n // Process each filter as its own condition\n const conditions: (QueryCondition | QueryFilter)[] = filters\n .filter((f) => !!f.values?.length)\n .filter((f) => !f.id.includes('text')) // remove text search filters as they are handled separately\n .filter((f) => f.id !== 'hierarchy') // remove hierarchy filter as it is handled separately\n .flatMap((filter) => convertFilterToCondition(filter))\n\n // Return the QueryFilter with all conditions combined with AND\n return {\n conditions,\n operator: 'and',\n }\n}\n\n// Helper function to convert a single Filter to a QueryCondition\nconst convertFilterToCondition = (filter: FilterForQuery): QueryCondition => {\n // Extract key from filter ID (split by underscore if needed)\n const key = getFilterFromId(filter.id)\n\n // Handle values based on filter type\n let value: QueryCondition['value']\n\n // there is any value\n const hasSomeValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('hasValue')\n const hasNoValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('noValue')\n\n if (filter.values && filter.values.length > 0) {\n if (filter.singleSelect) {\n // @ts-expect-error\n value = convertValueByType(filter.values[0].id, filter.type)\n } else {\n // @ts-expect-error\n value = filter.values.map((v) => convertValueByType(v.id, filter.type))\n }\n }\n\n // Determine if this is likely a list field based on filter type\n const isListField =\n filter.type?.startsWith('list_of_') || key.includes('tags') || key.includes('assignees')\n const isDateField = filter.type === 'datetime'\n const isBooleanField = filter.type === 'boolean'\n\n // Determine the appropriate operator based on filter properties and type\n let operator: QueryCondition['operator'] = 'eq'\n\n // Handling NULL values\n if (value === undefined) {\n operator = filter.inverted ? 'notnull' : 'isnull'\n return { key, operator }\n }\n\n // Handle different filter types\n if (hasSomeValue) {\n // we set the value to the empty state and then say it should not be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'eq'\n : 'ne'\n : filter.inverted\n ? 'isnull'\n : 'notnull'\n } else if (hasNoValue) {\n // we set the value to the empty state and then say it should be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'ne'\n : 'eq'\n : filter.inverted\n ? 'notnull'\n : 'isnull'\n } else if (isListField) {\n if (filter.inverted) {\n operator = filter.operator === 'AND' ? 'excludesall' : 'excludesany'\n } else {\n operator = filter.operator === 'AND' ? 'includesall' : 'includesany'\n }\n } else if (isDateField) {\n // For date filters, we need to return a complete query filter with conditions\n if (filter.values && filter.values.length > 0) {\n // Create a flat list of all date conditions from all filter values\n const dateConditions: QueryCondition[] = filter.values.flatMap(\n (filterValue: FilterForQuery) => {\n const conditions: QueryCondition[] = []\n const dateValues = filterValue.values\n\n // First value is greater than (start date)\n if (dateValues?.[0] !== undefined && dateValues?.[0].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'lte' : 'gte',\n value: dateValues[0].id,\n })\n }\n\n // Second value is less than (end date)\n if (dateValues?.[1] !== undefined && dateValues?.[1].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'gte' : 'lte',\n value: dateValues[1].id,\n })\n }\n\n return conditions\n },\n )\n\n // If we have date conditions, return them as a nested filter instead of continuing\n if (dateConditions.length > 0) {\n // @ts-expect-error\n return {\n conditions: dateConditions,\n operator: filter.inverted ? 'or' : 'and',\n } as QueryFilter\n }\n }\n\n // If no date conditions were created, fall back to a basic equality check\n operator = filter.inverted ? 'ne' : 'eq'\n } else if (isBooleanField) {\n operator = filter.inverted ? 'ne' : 'eq'\n } else {\n // DEFAULT for other scalar fields\n operator = filter.inverted ? 'notin' : 'in'\n }\n\n return { key, value, operator }\n}\n\n// Helper function to convert values based on the filter type\nconst convertValueByType = (value: string, type?: string): string | number | boolean => {\n if (!type) return value\n\n switch (type) {\n case 'integer':\n return parseInt(value, 10)\n case 'float':\n return parseFloat(value)\n case 'boolean':\n return value.toLowerCase() === 'true'\n default:\n return value\n }\n}\n\nexport default clientFilterToQueryFilter\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"clientFilterToQueryFilter.es.js","sources":["../../../../../../src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.ts"],"sourcesContent":["import { FILTER_SEPARATOR, getFilterFromId } from '@ynput/ayon-react-components'\nimport { QueryCondition, QueryFilter } from '../types/operations'\nconst NO_DATE = 'no-date'\n\n// New type that cherry picks only the needed fields from Filter\nexport type FilterForQuery = {\n id: string\n values?: { id: string; values?: { id: string }[] }[]\n type?: string\n singleSelect?: boolean\n inverted?: boolean\n operator?: string\n}\n\nexport const clientFilterToQueryFilter = (filters: FilterForQuery[]): QueryFilter => {\n // If there are no filters, return an empty filter\n if (!filters || filters.length === 0) {\n return {}\n }\n\n // Process each filter as its own condition\n const conditions: (QueryCondition | QueryFilter)[] = filters\n .filter((f) => !!f.values?.length)\n .filter((f) => !f.id.includes('text')) // remove text search filters as they are handled separately\n .filter((f) => f.id !== 'hierarchy') // remove hierarchy filter as it is handled separately\n .flatMap((filter) => convertFilterToCondition(filter))\n\n // Return the QueryFilter with all conditions combined with AND\n return {\n conditions,\n operator: 'and',\n }\n}\n\n// Helper function to convert a single Filter to a QueryCondition\nconst convertFilterToCondition = (filter: FilterForQuery): QueryCondition => {\n // Extract key from filter ID (split by underscore if needed)\n const key = getFilterFromId(filter.id)\n\n // Handle values based on filter type\n let value: QueryCondition['value']\n\n // there is any value\n const hasSomeValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('hasValue')\n const hasNoValue =\n Array.isArray(filter.values) && filter.values.map((v) => v.id)?.includes('noValue')\n\n if (filter.values && filter.values.length > 0) {\n if (filter.singleSelect) {\n // @ts-expect-error\n value = convertValueByType(filter.values[0].id, filter.type)\n } else {\n // @ts-expect-error\n value = filter.values.map((v) => convertValueByType(v.id, filter.type))\n }\n }\n\n // Determine if this is likely a list field based on filter type\n const isListField =\n filter.type?.startsWith('list_of_') || key.includes('tags') || key.includes('assignees')\n const isDateField = filter.type === 'datetime'\n const isBooleanField = filter.type === 'boolean'\n\n // Determine the appropriate operator based on filter properties and type\n let operator: QueryCondition['operator'] = 'eq'\n\n // Handling NULL values\n if (value === undefined) {\n operator = filter.inverted ? 'notnull' : 'isnull'\n return { key, operator }\n }\n\n // Handle different filter types\n if (hasSomeValue) {\n // we set the value to the empty state and then say it should not be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'eq'\n : 'ne'\n : filter.inverted\n ? 'isnull'\n : 'notnull'\n } else if (hasNoValue) {\n // we set the value to the empty state and then say it should be that\n value = isListField ? [] : undefined\n operator = isListField\n ? filter.inverted\n ? 'ne'\n : 'eq'\n : filter.inverted\n ? 'notnull'\n : 'isnull'\n } else if (isListField) {\n if (filter.inverted) {\n operator = filter.operator === 'AND' ? 'excludesall' : 'excludesany'\n } else {\n operator = filter.operator === 'AND' ? 'includesall' : 'includesany'\n }\n } else if (isDateField) {\n // For date filters, we need to return a complete query filter with conditions\n if (filter.values && filter.values.length > 0) {\n // Create a flat list of all date conditions from all filter values\n const dateConditions: QueryCondition[] = filter.values.flatMap(\n (filterValue: FilterForQuery) => {\n const conditions: QueryCondition[] = []\n const dateValues = filterValue.values\n\n // First value is greater than (start date)\n if (dateValues?.[0] !== undefined && dateValues?.[0].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'lte' : 'gte',\n value: dateValues[0].id,\n })\n }\n\n // Second value is less than (end date)\n if (dateValues?.[1] !== undefined && dateValues?.[1].id !== NO_DATE) {\n conditions.push({\n key,\n operator: filter.inverted ? 'gte' : 'lte',\n value: dateValues[1].id,\n })\n }\n\n return conditions\n },\n )\n\n // If we have date conditions, return them as a nested filter instead of continuing\n if (dateConditions.length > 0) {\n // @ts-expect-error\n return {\n conditions: dateConditions,\n operator: filter.inverted ? 'or' : 'and',\n } as QueryFilter\n }\n }\n\n // If no date conditions were created, fall back to a basic equality check\n operator = filter.inverted ? 'ne' : 'eq'\n } else if (isBooleanField) {\n operator = filter.inverted ? 'ne' : 'eq'\n } else {\n // DEFAULT for other scalar fields\n operator = filter.inverted ? 'notin' : 'in'\n }\n\n return { key, value, operator }\n}\n\n// Helper function to convert values based on the filter type\nconst convertValueByType = (value: string, type?: string): string | number | boolean => {\n if (!type) return value\n\n switch (type) {\n case 'integer':\n return parseInt(value, 10)\n case 'float':\n return parseFloat(value)\n case 'boolean':\n return value.toLowerCase() === 'true'\n default:\n return value\n }\n}\n\nexport default clientFilterToQueryFilter\n"],"names":[],"mappings":"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"}
@@ -77,7 +77,6 @@ require("./SettingsPanelContext.cjs.js");
77
77
  require("./pip/PiPProvider.cjs.js");
78
78
  require("react-dom");
79
79
  require("./pip/PiPWrapper.cjs.js");
80
- require("react-router-dom");
81
80
  require("custom-protocol-check");
82
81
  const DetailsPanelContext = React.createContext(void 0);
83
82
  const DetailsPanelProvider = ({
@@ -1 +1 @@
1
- {"version":3,"file":"DetailsPanelContext.cjs.js","sources":["../../../../src/context/DetailsPanelContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, ReactNode, useState } from 'react'\nimport { useLocalStorage } from '@shared/hooks'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport type { UserModel } from '@shared/api'\n\nexport type FeedFilters = 'activity' | 'comments' | 'versions' | 'checklists'\n\nexport type DetailsPanelTab = FeedFilters | 'attribs' | 'files'\n\nexport type SlideOut = {\n entityId: string\n entityType: DetailsPanelEntityType\n projectName: string\n}\n\nexport type DetailsPanelPip = {\n entityType: DetailsPanelEntityType\n entities: { id: string; projectName: string }[]\n scope: string\n}\n\nexport interface OpenStateByScope {\n [scope: string]: boolean\n}\n\n// Create a new interface for managing tab state by scope\nexport interface TabStateByScope {\n [scope: string]: DetailsPanelTab\n}\n\n// these props get forwarded to the details panel value\n// it's mainly redux callbacks that cannot be used in shared library\nexport interface DetailsPanelContextProps {\n dispatch?: any // this is a redux dispatch function and it's quite annoying we need to do this\n user: UserModel\n viewer?: {\n reviewableIds: string[]\n taskId?: string\n folderId?: string\n }\n // redux callback actions\n onOpenImage?: (args: any) => void\n onGoToFrame?: (frame: number) => void\n onOpenViewer?: (args: any) => void\n onUpdateEntity?: (data: { operations: any[], entityType: string }) => void\n}\n\n// Interface for our simplified context\nexport interface DetailsPanelContextType extends DetailsPanelContextProps {\n // Open state for the panel by scope\n panelOpenByScope: OpenStateByScope\n getOpenForScope: (scope: string) => boolean\n setPanelOpen: (scope: string, isOpen: boolean) => void\n setPanelOpenByScope: (newState: OpenStateByScope) => void\n\n // Tab preferences by scope\n tabsByScope: TabStateByScope\n getTabForScope: (scope: string) => DetailsPanelTab\n setTab: (scope: string, tab: DetailsPanelTab) => void\n\n // Slide out state\n slideOut: null | SlideOut\n openSlideOut: (slideOut: SlideOut) => void\n closeSlideOut: () => void\n\n // Highlighted activities\n highlightedActivities: string[]\n setHighlightedActivities: (activities: string[]) => void\n\n // PiP state\n pip: DetailsPanelPip | null\n openPip: (pip: DetailsPanelPip) => void\n closePip: () => void\n}\n\n// Create the context\nconst DetailsPanelContext = createContext<DetailsPanelContextType | undefined>(undefined)\n\n// Provider component\nexport interface DetailsPanelProviderProps extends DetailsPanelContextProps {\n children: ReactNode\n defaultTab?: DetailsPanelTab\n}\n\nexport const DetailsPanelProvider: React.FC<DetailsPanelProviderProps> = ({\n children,\n defaultTab = 'activity',\n ...forwardedProps\n}) => {\n // keep track of the currently open panel by scope\n const [panelOpenByScope, setPanelOpenByScope] = useState<OpenStateByScope>({})\n\n // get the current open state for a specific scope\n const getOpenForScope = useCallback(\n (scope: string): boolean => {\n // Check if we have a saved preference for this scope\n if (panelOpenByScope[scope]) {\n return panelOpenByScope[scope]\n }\n\n // Fall back to default\n return false\n },\n [panelOpenByScope],\n )\n // Set open state for a scope\n const setPanelOpen = useCallback(\n (scope: string, isOpen: boolean) => {\n // Create a new state object based on current open state\n const newState = { ...panelOpenByScope }\n newState[scope] = isOpen\n\n // Update the state with the new object\n setPanelOpenByScope(newState)\n },\n [panelOpenByScope],\n )\n\n // Use localStorage to persist tab preferences by scope\n const [tabsByScope, setTabsByScope] = useLocalStorage<TabStateByScope>(\n 'details/tabs-by-scope',\n {},\n )\n\n // Get the current tab for a specific scope\n const getTabForScope = useCallback(\n (scope: string): DetailsPanelTab => {\n // Check if we have a saved preference for this scope\n if (tabsByScope[scope]) {\n return tabsByScope[scope]\n }\n\n // Fall back to default\n return defaultTab\n },\n [tabsByScope, defaultTab],\n )\n\n // Set tab for a scope\n const setTab = useCallback(\n (scope: string, tab: DetailsPanelTab) => {\n // Create a new state object based on current tabsByScope\n const newState = { ...tabsByScope }\n newState[scope] = tab\n\n // Update the state with the new object\n setTabsByScope(newState)\n },\n [tabsByScope, setTabsByScope],\n )\n\n // is the slide out open?\n const [slideOut, setSlideOut] = useState<null | SlideOut>(null)\n\n // open the slide out\n const openSlideOut = useCallback<DetailsPanelContextType['openSlideOut']>((params) => {\n setSlideOut(params)\n }, [])\n\n // close the slide out\n const closeSlideOut = useCallback(() => {\n setSlideOut(null)\n setHighlightedActivities([])\n }, [])\n\n const [pip, setPip] = useState<DetailsPanelPip | null>(null)\n\n const openPip = useCallback((pip: DetailsPanelPip) => {\n setPip(pip)\n }, [])\n const closePip = useCallback(() => {\n setPip(null)\n }, [])\n\n const [highlightedActivities, setHighlightedActivities] = useState<string[]>([])\n\n const value = {\n // open state for the panel by scope\n panelOpenByScope,\n getOpenForScope,\n setPanelOpen,\n setPanelOpenByScope,\n // tab preferences\n tabsByScope,\n getTabForScope,\n setTab,\n // slide out state\n slideOut,\n openSlideOut,\n closeSlideOut,\n // highlighted activities\n highlightedActivities,\n setHighlightedActivities,\n // PiP state\n pip,\n openPip,\n closePip,\n ...forwardedProps,\n }\n\n return <DetailsPanelContext.Provider value={value}>{children}</DetailsPanelContext.Provider>\n}\n\n// Custom hook to use the details context\nexport const useDetailsPanelContext = (): DetailsPanelContextType => {\n const context = useContext(DetailsPanelContext)\n if (context === undefined) {\n throw new Error('useDetailsPanel must be used within a DetailsProvider')\n }\n return context\n}\n\n// Add a specialized hook for using a panel in a specific scope\nexport const useScopedDetailsPanel = (scope: string) => {\n const { getTabForScope, setTab, getOpenForScope, setPanelOpen } = useDetailsPanelContext()\n\n return {\n isOpen: getOpenForScope(scope),\n setOpen: (isOpen: boolean) => setPanelOpen(scope, isOpen),\n currentTab: getTabForScope(scope),\n setTab: (tab: DetailsPanelTab) => setTab(scope, tab),\n isFeed: ['activity', 'comments', 'versions', 'checklists'].includes(getTabForScope(scope)),\n }\n}\n"],"names":["createContext","useState","useCallback","useLocalStorage","pip","jsx","useContext"],"mappings":"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"}
1
+ {"version":3,"file":"DetailsPanelContext.cjs.js","sources":["../../../../src/context/DetailsPanelContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, ReactNode, useState } from 'react'\nimport { useLocalStorage } from '@shared/hooks'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport type { UserModel } from '@shared/api'\nimport { useLocation, useNavigate, useParams } from 'react-router'\nimport { useSearchParams } from 'react-router-dom'\n\nexport type FeedFilters = 'activity' | 'comments' | 'versions' | 'checklists'\n\nexport type DetailsPanelTab = FeedFilters | 'attribs' | 'files'\n\nexport type SlideOut = {\n entityId: string\n entityType: DetailsPanelEntityType\n projectName: string\n}\n\nexport type DetailsPanelPip = {\n entityType: DetailsPanelEntityType\n entities: { id: string; projectName: string }[]\n scope: string\n}\n\nexport interface OpenStateByScope {\n [scope: string]: boolean\n}\n\n// Create a new interface for managing tab state by scope\nexport interface TabStateByScope {\n [scope: string]: DetailsPanelTab\n}\n\n// these props get forwarded to the details panel value\n// it's mainly redux callbacks that cannot be used in shared library\nexport interface DetailsPanelContextProps {\n dispatch?: any // this is a redux dispatch function and it's quite annoying we need to do this\n user: UserModel\n viewer?: {\n reviewableIds: string[]\n taskId?: string | null\n folderId?: string | null\n }\n // redux callback actions\n onOpenImage?: (args: any) => void\n onGoToFrame?: (frame: number) => void\n onOpenViewer?: (args: any) => void\n onUpdateEntity?: (data: { operations: any[]; entityType: string }) => void\n // route hooks\n useParams: typeof useParams\n useNavigate: typeof useNavigate\n useLocation: typeof useLocation\n useSearchParams: typeof useSearchParams\n}\n\n// Interface for our simplified context\nexport interface DetailsPanelContextType extends DetailsPanelContextProps {\n // Open state for the panel by scope\n panelOpenByScope: OpenStateByScope\n getOpenForScope: (scope: string) => boolean\n setPanelOpen: (scope: string, isOpen: boolean) => void\n setPanelOpenByScope: (newState: OpenStateByScope) => void\n\n // Tab preferences by scope\n tabsByScope: TabStateByScope\n getTabForScope: (scope: string) => DetailsPanelTab\n setTab: (scope: string, tab: DetailsPanelTab) => void\n\n // Slide out state\n slideOut: null | SlideOut\n openSlideOut: (slideOut: SlideOut) => void\n closeSlideOut: () => void\n\n // Highlighted activities\n highlightedActivities: string[]\n setHighlightedActivities: (activities: string[]) => void\n\n // PiP state\n pip: DetailsPanelPip | null\n openPip: (pip: DetailsPanelPip) => void\n closePip: () => void\n}\n\n// Create the context\nconst DetailsPanelContext = createContext<DetailsPanelContextType | undefined>(undefined)\n\n// Provider component\nexport interface DetailsPanelProviderProps extends DetailsPanelContextProps {\n children: ReactNode\n defaultTab?: DetailsPanelTab\n}\n\nexport const DetailsPanelProvider: React.FC<DetailsPanelProviderProps> = ({\n children,\n defaultTab = 'activity',\n ...forwardedProps\n}) => {\n // keep track of the currently open panel by scope\n const [panelOpenByScope, setPanelOpenByScope] = useState<OpenStateByScope>({})\n\n // get the current open state for a specific scope\n const getOpenForScope = useCallback(\n (scope: string): boolean => {\n // Check if we have a saved preference for this scope\n if (panelOpenByScope[scope]) {\n return panelOpenByScope[scope]\n }\n\n // Fall back to default\n return false\n },\n [panelOpenByScope],\n )\n // Set open state for a scope\n const setPanelOpen = useCallback(\n (scope: string, isOpen: boolean) => {\n // Create a new state object based on current open state\n const newState = { ...panelOpenByScope }\n newState[scope] = isOpen\n\n // Update the state with the new object\n setPanelOpenByScope(newState)\n },\n [panelOpenByScope],\n )\n\n // Use localStorage to persist tab preferences by scope\n const [tabsByScope, setTabsByScope] = useLocalStorage<TabStateByScope>(\n 'details/tabs-by-scope',\n {},\n )\n\n // Get the current tab for a specific scope\n const getTabForScope = useCallback(\n (scope: string): DetailsPanelTab => {\n // Check if we have a saved preference for this scope\n if (tabsByScope[scope]) {\n return tabsByScope[scope]\n }\n\n // Fall back to default\n return defaultTab\n },\n [tabsByScope, defaultTab],\n )\n\n // Set tab for a scope\n const setTab = useCallback(\n (scope: string, tab: DetailsPanelTab) => {\n // Create a new state object based on current tabsByScope\n const newState = { ...tabsByScope }\n newState[scope] = tab\n\n // Update the state with the new object\n setTabsByScope(newState)\n },\n [tabsByScope, setTabsByScope],\n )\n\n // is the slide out open?\n const [slideOut, setSlideOut] = useState<null | SlideOut>(null)\n\n // open the slide out\n const openSlideOut = useCallback<DetailsPanelContextType['openSlideOut']>((params) => {\n setSlideOut(params)\n }, [])\n\n // close the slide out\n const closeSlideOut = useCallback(() => {\n setSlideOut(null)\n setHighlightedActivities([])\n }, [])\n\n const [pip, setPip] = useState<DetailsPanelPip | null>(null)\n\n const openPip = useCallback((pip: DetailsPanelPip) => {\n setPip(pip)\n }, [])\n const closePip = useCallback(() => {\n setPip(null)\n }, [])\n\n const [highlightedActivities, setHighlightedActivities] = useState<string[]>([])\n\n const value = {\n // open state for the panel by scope\n panelOpenByScope,\n getOpenForScope,\n setPanelOpen,\n setPanelOpenByScope,\n // tab preferences\n tabsByScope,\n getTabForScope,\n setTab,\n // slide out state\n slideOut,\n openSlideOut,\n closeSlideOut,\n // highlighted activities\n highlightedActivities,\n setHighlightedActivities,\n // PiP state\n pip,\n openPip,\n closePip,\n ...forwardedProps,\n }\n\n return <DetailsPanelContext.Provider value={value}>{children}</DetailsPanelContext.Provider>\n}\n\n// Custom hook to use the details context\nexport const useDetailsPanelContext = (): DetailsPanelContextType => {\n const context = useContext(DetailsPanelContext)\n if (context === undefined) {\n throw new Error('useDetailsPanel must be used within a DetailsProvider')\n }\n return context\n}\n\n// Add a specialized hook for using a panel in a specific scope\nexport const useScopedDetailsPanel = (scope: string) => {\n const { getTabForScope, setTab, getOpenForScope, setPanelOpen } = useDetailsPanelContext()\n\n return {\n isOpen: getOpenForScope(scope),\n setOpen: (isOpen: boolean) => setPanelOpen(scope, isOpen),\n currentTab: getTabForScope(scope),\n setTab: (tab: DetailsPanelTab) => setTab(scope, tab),\n isFeed: ['activity', 'comments', 'versions', 'checklists'].includes(getTabForScope(scope)),\n }\n}\n"],"names":["createContext","useState","useCallback","useLocalStorage","pip","jsx","useContext"],"mappings":"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"}
@@ -75,7 +75,6 @@ import "./SettingsPanelContext.es.js";
75
75
  import "./pip/PiPProvider.es.js";
76
76
  import "react-dom";
77
77
  import "./pip/PiPWrapper.es.js";
78
- import "react-router-dom";
79
78
  import "custom-protocol-check";
80
79
  const DetailsPanelContext = createContext(void 0);
81
80
  const DetailsPanelProvider = ({
@@ -1 +1 @@
1
- {"version":3,"file":"DetailsPanelContext.es.js","sources":["../../../../src/context/DetailsPanelContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, ReactNode, useState } from 'react'\nimport { useLocalStorage } from '@shared/hooks'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport type { UserModel } from '@shared/api'\n\nexport type FeedFilters = 'activity' | 'comments' | 'versions' | 'checklists'\n\nexport type DetailsPanelTab = FeedFilters | 'attribs' | 'files'\n\nexport type SlideOut = {\n entityId: string\n entityType: DetailsPanelEntityType\n projectName: string\n}\n\nexport type DetailsPanelPip = {\n entityType: DetailsPanelEntityType\n entities: { id: string; projectName: string }[]\n scope: string\n}\n\nexport interface OpenStateByScope {\n [scope: string]: boolean\n}\n\n// Create a new interface for managing tab state by scope\nexport interface TabStateByScope {\n [scope: string]: DetailsPanelTab\n}\n\n// these props get forwarded to the details panel value\n// it's mainly redux callbacks that cannot be used in shared library\nexport interface DetailsPanelContextProps {\n dispatch?: any // this is a redux dispatch function and it's quite annoying we need to do this\n user: UserModel\n viewer?: {\n reviewableIds: string[]\n taskId?: string\n folderId?: string\n }\n // redux callback actions\n onOpenImage?: (args: any) => void\n onGoToFrame?: (frame: number) => void\n onOpenViewer?: (args: any) => void\n onUpdateEntity?: (data: { operations: any[], entityType: string }) => void\n}\n\n// Interface for our simplified context\nexport interface DetailsPanelContextType extends DetailsPanelContextProps {\n // Open state for the panel by scope\n panelOpenByScope: OpenStateByScope\n getOpenForScope: (scope: string) => boolean\n setPanelOpen: (scope: string, isOpen: boolean) => void\n setPanelOpenByScope: (newState: OpenStateByScope) => void\n\n // Tab preferences by scope\n tabsByScope: TabStateByScope\n getTabForScope: (scope: string) => DetailsPanelTab\n setTab: (scope: string, tab: DetailsPanelTab) => void\n\n // Slide out state\n slideOut: null | SlideOut\n openSlideOut: (slideOut: SlideOut) => void\n closeSlideOut: () => void\n\n // Highlighted activities\n highlightedActivities: string[]\n setHighlightedActivities: (activities: string[]) => void\n\n // PiP state\n pip: DetailsPanelPip | null\n openPip: (pip: DetailsPanelPip) => void\n closePip: () => void\n}\n\n// Create the context\nconst DetailsPanelContext = createContext<DetailsPanelContextType | undefined>(undefined)\n\n// Provider component\nexport interface DetailsPanelProviderProps extends DetailsPanelContextProps {\n children: ReactNode\n defaultTab?: DetailsPanelTab\n}\n\nexport const DetailsPanelProvider: React.FC<DetailsPanelProviderProps> = ({\n children,\n defaultTab = 'activity',\n ...forwardedProps\n}) => {\n // keep track of the currently open panel by scope\n const [panelOpenByScope, setPanelOpenByScope] = useState<OpenStateByScope>({})\n\n // get the current open state for a specific scope\n const getOpenForScope = useCallback(\n (scope: string): boolean => {\n // Check if we have a saved preference for this scope\n if (panelOpenByScope[scope]) {\n return panelOpenByScope[scope]\n }\n\n // Fall back to default\n return false\n },\n [panelOpenByScope],\n )\n // Set open state for a scope\n const setPanelOpen = useCallback(\n (scope: string, isOpen: boolean) => {\n // Create a new state object based on current open state\n const newState = { ...panelOpenByScope }\n newState[scope] = isOpen\n\n // Update the state with the new object\n setPanelOpenByScope(newState)\n },\n [panelOpenByScope],\n )\n\n // Use localStorage to persist tab preferences by scope\n const [tabsByScope, setTabsByScope] = useLocalStorage<TabStateByScope>(\n 'details/tabs-by-scope',\n {},\n )\n\n // Get the current tab for a specific scope\n const getTabForScope = useCallback(\n (scope: string): DetailsPanelTab => {\n // Check if we have a saved preference for this scope\n if (tabsByScope[scope]) {\n return tabsByScope[scope]\n }\n\n // Fall back to default\n return defaultTab\n },\n [tabsByScope, defaultTab],\n )\n\n // Set tab for a scope\n const setTab = useCallback(\n (scope: string, tab: DetailsPanelTab) => {\n // Create a new state object based on current tabsByScope\n const newState = { ...tabsByScope }\n newState[scope] = tab\n\n // Update the state with the new object\n setTabsByScope(newState)\n },\n [tabsByScope, setTabsByScope],\n )\n\n // is the slide out open?\n const [slideOut, setSlideOut] = useState<null | SlideOut>(null)\n\n // open the slide out\n const openSlideOut = useCallback<DetailsPanelContextType['openSlideOut']>((params) => {\n setSlideOut(params)\n }, [])\n\n // close the slide out\n const closeSlideOut = useCallback(() => {\n setSlideOut(null)\n setHighlightedActivities([])\n }, [])\n\n const [pip, setPip] = useState<DetailsPanelPip | null>(null)\n\n const openPip = useCallback((pip: DetailsPanelPip) => {\n setPip(pip)\n }, [])\n const closePip = useCallback(() => {\n setPip(null)\n }, [])\n\n const [highlightedActivities, setHighlightedActivities] = useState<string[]>([])\n\n const value = {\n // open state for the panel by scope\n panelOpenByScope,\n getOpenForScope,\n setPanelOpen,\n setPanelOpenByScope,\n // tab preferences\n tabsByScope,\n getTabForScope,\n setTab,\n // slide out state\n slideOut,\n openSlideOut,\n closeSlideOut,\n // highlighted activities\n highlightedActivities,\n setHighlightedActivities,\n // PiP state\n pip,\n openPip,\n closePip,\n ...forwardedProps,\n }\n\n return <DetailsPanelContext.Provider value={value}>{children}</DetailsPanelContext.Provider>\n}\n\n// Custom hook to use the details context\nexport const useDetailsPanelContext = (): DetailsPanelContextType => {\n const context = useContext(DetailsPanelContext)\n if (context === undefined) {\n throw new Error('useDetailsPanel must be used within a DetailsProvider')\n }\n return context\n}\n\n// Add a specialized hook for using a panel in a specific scope\nexport const useScopedDetailsPanel = (scope: string) => {\n const { getTabForScope, setTab, getOpenForScope, setPanelOpen } = useDetailsPanelContext()\n\n return {\n isOpen: getOpenForScope(scope),\n setOpen: (isOpen: boolean) => setPanelOpen(scope, isOpen),\n currentTab: getTabForScope(scope),\n setTab: (tab: DetailsPanelTab) => setTab(scope, tab),\n isFeed: ['activity', 'comments', 'versions', 'checklists'].includes(getTabForScope(scope)),\n }\n}\n"],"names":["pip","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DetailsPanelContext.es.js","sources":["../../../../src/context/DetailsPanelContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useCallback, ReactNode, useState } from 'react'\nimport { useLocalStorage } from '@shared/hooks'\nimport { DetailsPanelEntityType } from '@shared/api'\nimport type { UserModel } from '@shared/api'\nimport { useLocation, useNavigate, useParams } from 'react-router'\nimport { useSearchParams } from 'react-router-dom'\n\nexport type FeedFilters = 'activity' | 'comments' | 'versions' | 'checklists'\n\nexport type DetailsPanelTab = FeedFilters | 'attribs' | 'files'\n\nexport type SlideOut = {\n entityId: string\n entityType: DetailsPanelEntityType\n projectName: string\n}\n\nexport type DetailsPanelPip = {\n entityType: DetailsPanelEntityType\n entities: { id: string; projectName: string }[]\n scope: string\n}\n\nexport interface OpenStateByScope {\n [scope: string]: boolean\n}\n\n// Create a new interface for managing tab state by scope\nexport interface TabStateByScope {\n [scope: string]: DetailsPanelTab\n}\n\n// these props get forwarded to the details panel value\n// it's mainly redux callbacks that cannot be used in shared library\nexport interface DetailsPanelContextProps {\n dispatch?: any // this is a redux dispatch function and it's quite annoying we need to do this\n user: UserModel\n viewer?: {\n reviewableIds: string[]\n taskId?: string | null\n folderId?: string | null\n }\n // redux callback actions\n onOpenImage?: (args: any) => void\n onGoToFrame?: (frame: number) => void\n onOpenViewer?: (args: any) => void\n onUpdateEntity?: (data: { operations: any[]; entityType: string }) => void\n // route hooks\n useParams: typeof useParams\n useNavigate: typeof useNavigate\n useLocation: typeof useLocation\n useSearchParams: typeof useSearchParams\n}\n\n// Interface for our simplified context\nexport interface DetailsPanelContextType extends DetailsPanelContextProps {\n // Open state for the panel by scope\n panelOpenByScope: OpenStateByScope\n getOpenForScope: (scope: string) => boolean\n setPanelOpen: (scope: string, isOpen: boolean) => void\n setPanelOpenByScope: (newState: OpenStateByScope) => void\n\n // Tab preferences by scope\n tabsByScope: TabStateByScope\n getTabForScope: (scope: string) => DetailsPanelTab\n setTab: (scope: string, tab: DetailsPanelTab) => void\n\n // Slide out state\n slideOut: null | SlideOut\n openSlideOut: (slideOut: SlideOut) => void\n closeSlideOut: () => void\n\n // Highlighted activities\n highlightedActivities: string[]\n setHighlightedActivities: (activities: string[]) => void\n\n // PiP state\n pip: DetailsPanelPip | null\n openPip: (pip: DetailsPanelPip) => void\n closePip: () => void\n}\n\n// Create the context\nconst DetailsPanelContext = createContext<DetailsPanelContextType | undefined>(undefined)\n\n// Provider component\nexport interface DetailsPanelProviderProps extends DetailsPanelContextProps {\n children: ReactNode\n defaultTab?: DetailsPanelTab\n}\n\nexport const DetailsPanelProvider: React.FC<DetailsPanelProviderProps> = ({\n children,\n defaultTab = 'activity',\n ...forwardedProps\n}) => {\n // keep track of the currently open panel by scope\n const [panelOpenByScope, setPanelOpenByScope] = useState<OpenStateByScope>({})\n\n // get the current open state for a specific scope\n const getOpenForScope = useCallback(\n (scope: string): boolean => {\n // Check if we have a saved preference for this scope\n if (panelOpenByScope[scope]) {\n return panelOpenByScope[scope]\n }\n\n // Fall back to default\n return false\n },\n [panelOpenByScope],\n )\n // Set open state for a scope\n const setPanelOpen = useCallback(\n (scope: string, isOpen: boolean) => {\n // Create a new state object based on current open state\n const newState = { ...panelOpenByScope }\n newState[scope] = isOpen\n\n // Update the state with the new object\n setPanelOpenByScope(newState)\n },\n [panelOpenByScope],\n )\n\n // Use localStorage to persist tab preferences by scope\n const [tabsByScope, setTabsByScope] = useLocalStorage<TabStateByScope>(\n 'details/tabs-by-scope',\n {},\n )\n\n // Get the current tab for a specific scope\n const getTabForScope = useCallback(\n (scope: string): DetailsPanelTab => {\n // Check if we have a saved preference for this scope\n if (tabsByScope[scope]) {\n return tabsByScope[scope]\n }\n\n // Fall back to default\n return defaultTab\n },\n [tabsByScope, defaultTab],\n )\n\n // Set tab for a scope\n const setTab = useCallback(\n (scope: string, tab: DetailsPanelTab) => {\n // Create a new state object based on current tabsByScope\n const newState = { ...tabsByScope }\n newState[scope] = tab\n\n // Update the state with the new object\n setTabsByScope(newState)\n },\n [tabsByScope, setTabsByScope],\n )\n\n // is the slide out open?\n const [slideOut, setSlideOut] = useState<null | SlideOut>(null)\n\n // open the slide out\n const openSlideOut = useCallback<DetailsPanelContextType['openSlideOut']>((params) => {\n setSlideOut(params)\n }, [])\n\n // close the slide out\n const closeSlideOut = useCallback(() => {\n setSlideOut(null)\n setHighlightedActivities([])\n }, [])\n\n const [pip, setPip] = useState<DetailsPanelPip | null>(null)\n\n const openPip = useCallback((pip: DetailsPanelPip) => {\n setPip(pip)\n }, [])\n const closePip = useCallback(() => {\n setPip(null)\n }, [])\n\n const [highlightedActivities, setHighlightedActivities] = useState<string[]>([])\n\n const value = {\n // open state for the panel by scope\n panelOpenByScope,\n getOpenForScope,\n setPanelOpen,\n setPanelOpenByScope,\n // tab preferences\n tabsByScope,\n getTabForScope,\n setTab,\n // slide out state\n slideOut,\n openSlideOut,\n closeSlideOut,\n // highlighted activities\n highlightedActivities,\n setHighlightedActivities,\n // PiP state\n pip,\n openPip,\n closePip,\n ...forwardedProps,\n }\n\n return <DetailsPanelContext.Provider value={value}>{children}</DetailsPanelContext.Provider>\n}\n\n// Custom hook to use the details context\nexport const useDetailsPanelContext = (): DetailsPanelContextType => {\n const context = useContext(DetailsPanelContext)\n if (context === undefined) {\n throw new Error('useDetailsPanel must be used within a DetailsProvider')\n }\n return context\n}\n\n// Add a specialized hook for using a panel in a specific scope\nexport const useScopedDetailsPanel = (scope: string) => {\n const { getTabForScope, setTab, getOpenForScope, setPanelOpen } = useDetailsPanelContext()\n\n return {\n isOpen: getOpenForScope(scope),\n setOpen: (isOpen: boolean) => setPanelOpen(scope, isOpen),\n currentTab: getTabForScope(scope),\n setTab: (tab: DetailsPanelTab) => setTab(scope, tab),\n isFeed: ['activity', 'comments', 'versions', 'checklists'].includes(getTabForScope(scope)),\n }\n}\n"],"names":["pip","jsx"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const reactRouterDom = require("react-router-dom");
4
3
  const customProtocolCheck = require("custom-protocol-check");
5
- const useActionTriggers = () => {
6
- const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
7
- const navigate = reactRouterDom.useNavigate();
4
+ const useActionTriggers = ({
5
+ searchParams,
6
+ onSetSearchParams,
7
+ onNavigate
8
+ }) => {
8
9
  const handleActionPayload = (actionType, payload) => {
9
10
  if (!payload) return;
10
11
  if (actionType === "launcher") {
@@ -28,13 +29,13 @@ const useActionTriggers = () => {
28
29
  for (const [key, value] of Object.entries(payload.query)) {
29
30
  searchParams.set(key, value);
30
31
  }
31
- setSearchParams(searchParams);
32
+ onSetSearchParams(searchParams);
32
33
  }
33
34
  } else if (actionType === "navigate") {
34
35
  if (typeof payload.uri !== "string") {
35
36
  throw new Error("Invalid payload: navigate");
36
37
  } else {
37
- navigate(payload.uri);
38
+ onNavigate(payload.uri);
38
39
  }
39
40
  } else if (actionType === "redirect") {
40
41
  if (typeof payload.uri !== "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"useActionTriggers.cjs.js","sources":["../../../../src/hooks/useActionTriggers.ts"],"sourcesContent":["import { useNavigate, useSearchParams } from 'react-router-dom'\nimport customProtocolCheck from 'custom-protocol-check'\n\ninterface QueryParams {\n [key: string]: string\n}\n\ninterface ActionPayload {\n query?: QueryParams // adds query params to the URL\n uri?: string // navigates to a different page\n new_tab?: boolean // opens a new tab\n extra_download?: string // triggers a file download from a URL\n extra_clipboard?: string // copies string content to clipboard\n [key: string]: any\n}\n\nexport const useActionTriggers = () => {\n const [searchParams, setSearchParams] = useSearchParams()\n const navigate = useNavigate()\n\n const handleActionPayload = (actionType: string, payload: ActionPayload | null): void => {\n if (!payload) return\n\n if (actionType === 'launcher') {\n if (payload?.uri) {\n customProtocolCheck(\n payload.uri,\n () => {},\n () => {},\n 2000,\n )\n }\n } else if (actionType === 'query') {\n // Validate it is an object of key:value pairs with value being string\n const isValid = Object.values(payload.query as QueryParams).every((value) => {\n return typeof value === 'string'\n })\n\n if (!isValid) {\n throw new Error('Invalid payload: query')\n } else {\n // Add query params to URL\n for (const [key, value] of Object.entries(payload.query as QueryParams)) {\n searchParams.set(key, value)\n }\n setSearchParams(searchParams)\n }\n } else if (actionType === 'navigate') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: navigate')\n } else {\n // Navigate to the specified page\n navigate(payload.uri)\n }\n } else if (actionType === 'redirect') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: redirect')\n } else {\n const newTab = payload?.new_tab || false\n window.open(payload.uri, newTab ? '_blank' : '_self')\n }\n }\n\n //\n // Sub-actions\n //\n\n if ('extra_download' in payload) {\n // Validate it is a string\n if (typeof payload.extra_download !== 'string') {\n throw new Error('Invalid payload: extra_download')\n } else {\n // Trigger file download from the URL\n const downloadUrl = new URL(payload.extra_download, window.location.origin).href\n console.log(downloadUrl)\n // Create a hidden anchor element\n const link = document.createElement('a')\n link.href = downloadUrl\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n // Set download attribute if it's a direct file download\n // If it's an API endpoint that handles the download, this is still good\n link.download = ''\n // Append to document, click and then remove\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n }\n }\n\n if ('extra_clipboard' in payload) {\n // Validate it is a string\n if (typeof payload.extra_clipboard !== 'string') {\n throw new Error('Invalid payload: extra_clipboard')\n } else {\n // Copy content to clipboard\n navigator.clipboard.writeText(payload.extra_clipboard).catch((err) => {\n console.error('Failed to copy text to clipboard:', err)\n })\n }\n }\n }\n\n return { handleActionPayload }\n}\n"],"names":["useSearchParams","useNavigate"],"mappings":";;;;AAgBO,MAAM,oBAAoB,MAAM;AACrC,QAAM,CAAC,cAAc,eAAe,IAAIA,+BAAgB;AACxD,QAAM,WAAWC,eAAAA,YAAY;AAEvB,QAAA,sBAAsB,CAAC,YAAoB,YAAwC;AACvF,QAAI,CAAC,QAAS;AAEd,QAAI,eAAe,YAAY;AAC7B,UAAI,mCAAS,KAAK;AAChB;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UAAC;AAAA,UACP,MAAM;AAAA,UAAC;AAAA,UACP;AAAA,QACF;AAAA,MAAA;AAAA,IACF,WACS,eAAe,SAAS;AAE3B,YAAA,UAAU,OAAO,OAAO,QAAQ,KAAoB,EAAE,MAAM,CAAC,UAAU;AAC3E,eAAO,OAAO,UAAU;AAAA,MAAA,CACzB;AAED,UAAI,CAAC,SAAS;AACN,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA,OACnC;AAEM,mBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAoB,GAAG;AAC1D,uBAAA,IAAI,KAAK,KAAK;AAAA,QAAA;AAE7B,wBAAgB,YAAY;AAAA,MAAA;AAAA,IAC9B,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AAEL,iBAAS,QAAQ,GAAG;AAAA,MAAA;AAAA,IACtB,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AACC,cAAA,UAAS,mCAAS,YAAW;AACnC,eAAO,KAAK,QAAQ,KAAK,SAAS,WAAW,OAAO;AAAA,MAAA;AAAA,IACtD;AAOF,QAAI,oBAAoB,SAAS;AAE3B,UAAA,OAAO,QAAQ,mBAAmB,UAAU;AACxC,cAAA,IAAI,MAAM,iCAAiC;AAAA,MAAA,OAC5C;AAEC,cAAA,cAAc,IAAI,IAAI,QAAQ,gBAAgB,OAAO,SAAS,MAAM,EAAE;AAC5E,gBAAQ,IAAI,WAAW;AAEjB,cAAA,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,OAAO;AACZ,aAAK,SAAS;AACd,aAAK,MAAM;AAGX,aAAK,WAAW;AAEP,iBAAA,KAAK,YAAY,IAAI;AAC9B,aAAK,MAAM;AACF,iBAAA,KAAK,YAAY,IAAI;AAAA,MAAA;AAAA,IAChC;AAGF,QAAI,qBAAqB,SAAS;AAE5B,UAAA,OAAO,QAAQ,oBAAoB,UAAU;AACzC,cAAA,IAAI,MAAM,kCAAkC;AAAA,MAAA,OAC7C;AAEL,kBAAU,UAAU,UAAU,QAAQ,eAAe,EAAE,MAAM,CAAC,QAAQ;AAC5D,kBAAA,MAAM,qCAAqC,GAAG;AAAA,QAAA,CACvD;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,EAAE,oBAAoB;AAC/B;;"}
1
+ {"version":3,"file":"useActionTriggers.cjs.js","sources":["../../../../src/hooks/useActionTriggers.ts"],"sourcesContent":["import customProtocolCheck from 'custom-protocol-check'\n\nexport type ActionTriggersProps = {\n searchParams: URLSearchParams\n onSetSearchParams: (params: URLSearchParams) => void\n onNavigate: (uri: string) => void\n}\n\ninterface QueryParams {\n [key: string]: string\n}\n\ninterface ActionPayload {\n query?: QueryParams // adds query params to the URL\n uri?: string // navigates to a different page\n new_tab?: boolean // opens a new tab\n extra_download?: string // triggers a file download from a URL\n extra_clipboard?: string // copies string content to clipboard\n [key: string]: any\n}\n\nexport const useActionTriggers = ({\n searchParams,\n onSetSearchParams,\n onNavigate,\n}: ActionTriggersProps) => {\n const handleActionPayload = (actionType: string, payload: ActionPayload | null): void => {\n if (!payload) return\n\n if (actionType === 'launcher') {\n if (payload?.uri) {\n customProtocolCheck(\n payload.uri,\n () => {},\n () => {},\n 2000,\n )\n }\n } else if (actionType === 'query') {\n // Validate it is an object of key:value pairs with value being string\n const isValid = Object.values(payload.query as QueryParams).every((value) => {\n return typeof value === 'string'\n })\n\n if (!isValid) {\n throw new Error('Invalid payload: query')\n } else {\n // Add query params to URL\n for (const [key, value] of Object.entries(payload.query as QueryParams)) {\n searchParams.set(key, value)\n }\n onSetSearchParams(searchParams)\n }\n } else if (actionType === 'navigate') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: navigate')\n } else {\n // Navigate to the specified page\n onNavigate(payload.uri)\n }\n } else if (actionType === 'redirect') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: redirect')\n } else {\n const newTab = payload?.new_tab || false\n window.open(payload.uri, newTab ? '_blank' : '_self')\n }\n }\n\n //\n // Sub-actions\n //\n\n if ('extra_download' in payload) {\n // Validate it is a string\n if (typeof payload.extra_download !== 'string') {\n throw new Error('Invalid payload: extra_download')\n } else {\n // Trigger file download from the URL\n const downloadUrl = new URL(payload.extra_download, window.location.origin).href\n console.log(downloadUrl)\n // Create a hidden anchor element\n const link = document.createElement('a')\n link.href = downloadUrl\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n // Set download attribute if it's a direct file download\n // If it's an API endpoint that handles the download, this is still good\n link.download = ''\n // Append to document, click and then remove\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n }\n }\n\n if ('extra_clipboard' in payload) {\n // Validate it is a string\n if (typeof payload.extra_clipboard !== 'string') {\n throw new Error('Invalid payload: extra_clipboard')\n } else {\n // Copy content to clipboard\n navigator.clipboard.writeText(payload.extra_clipboard).catch((err) => {\n console.error('Failed to copy text to clipboard:', err)\n })\n }\n }\n }\n\n return { handleActionPayload }\n}\n"],"names":[],"mappings":";;;AAqBO,MAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,MAA2B;AACnB,QAAA,sBAAsB,CAAC,YAAoB,YAAwC;AACvF,QAAI,CAAC,QAAS;AAEd,QAAI,eAAe,YAAY;AAC7B,UAAI,mCAAS,KAAK;AAChB;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UAAC;AAAA,UACP,MAAM;AAAA,UAAC;AAAA,UACP;AAAA,QACF;AAAA,MAAA;AAAA,IACF,WACS,eAAe,SAAS;AAE3B,YAAA,UAAU,OAAO,OAAO,QAAQ,KAAoB,EAAE,MAAM,CAAC,UAAU;AAC3E,eAAO,OAAO,UAAU;AAAA,MAAA,CACzB;AAED,UAAI,CAAC,SAAS;AACN,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA,OACnC;AAEM,mBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAoB,GAAG;AAC1D,uBAAA,IAAI,KAAK,KAAK;AAAA,QAAA;AAE7B,0BAAkB,YAAY;AAAA,MAAA;AAAA,IAChC,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AAEL,mBAAW,QAAQ,GAAG;AAAA,MAAA;AAAA,IACxB,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AACC,cAAA,UAAS,mCAAS,YAAW;AACnC,eAAO,KAAK,QAAQ,KAAK,SAAS,WAAW,OAAO;AAAA,MAAA;AAAA,IACtD;AAOF,QAAI,oBAAoB,SAAS;AAE3B,UAAA,OAAO,QAAQ,mBAAmB,UAAU;AACxC,cAAA,IAAI,MAAM,iCAAiC;AAAA,MAAA,OAC5C;AAEC,cAAA,cAAc,IAAI,IAAI,QAAQ,gBAAgB,OAAO,SAAS,MAAM,EAAE;AAC5E,gBAAQ,IAAI,WAAW;AAEjB,cAAA,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,OAAO;AACZ,aAAK,SAAS;AACd,aAAK,MAAM;AAGX,aAAK,WAAW;AAEP,iBAAA,KAAK,YAAY,IAAI;AAC9B,aAAK,MAAM;AACF,iBAAA,KAAK,YAAY,IAAI;AAAA,MAAA;AAAA,IAChC;AAGF,QAAI,qBAAqB,SAAS;AAE5B,UAAA,OAAO,QAAQ,oBAAoB,UAAU;AACzC,cAAA,IAAI,MAAM,kCAAkC;AAAA,MAAA,OAC7C;AAEL,kBAAU,UAAU,UAAU,QAAQ,eAAe,EAAE,MAAM,CAAC,QAAQ;AAC5D,kBAAA,MAAM,qCAAqC,GAAG;AAAA,QAAA,CACvD;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,EAAE,oBAAoB;AAC/B;;"}
@@ -1,8 +1,9 @@
1
- import { useSearchParams, useNavigate } from "react-router-dom";
2
1
  import customProtocolCheck from "custom-protocol-check";
3
- const useActionTriggers = () => {
4
- const [searchParams, setSearchParams] = useSearchParams();
5
- const navigate = useNavigate();
2
+ const useActionTriggers = ({
3
+ searchParams,
4
+ onSetSearchParams,
5
+ onNavigate
6
+ }) => {
6
7
  const handleActionPayload = (actionType, payload) => {
7
8
  if (!payload) return;
8
9
  if (actionType === "launcher") {
@@ -26,13 +27,13 @@ const useActionTriggers = () => {
26
27
  for (const [key, value] of Object.entries(payload.query)) {
27
28
  searchParams.set(key, value);
28
29
  }
29
- setSearchParams(searchParams);
30
+ onSetSearchParams(searchParams);
30
31
  }
31
32
  } else if (actionType === "navigate") {
32
33
  if (typeof payload.uri !== "string") {
33
34
  throw new Error("Invalid payload: navigate");
34
35
  } else {
35
- navigate(payload.uri);
36
+ onNavigate(payload.uri);
36
37
  }
37
38
  } else if (actionType === "redirect") {
38
39
  if (typeof payload.uri !== "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"useActionTriggers.es.js","sources":["../../../../src/hooks/useActionTriggers.ts"],"sourcesContent":["import { useNavigate, useSearchParams } from 'react-router-dom'\nimport customProtocolCheck from 'custom-protocol-check'\n\ninterface QueryParams {\n [key: string]: string\n}\n\ninterface ActionPayload {\n query?: QueryParams // adds query params to the URL\n uri?: string // navigates to a different page\n new_tab?: boolean // opens a new tab\n extra_download?: string // triggers a file download from a URL\n extra_clipboard?: string // copies string content to clipboard\n [key: string]: any\n}\n\nexport const useActionTriggers = () => {\n const [searchParams, setSearchParams] = useSearchParams()\n const navigate = useNavigate()\n\n const handleActionPayload = (actionType: string, payload: ActionPayload | null): void => {\n if (!payload) return\n\n if (actionType === 'launcher') {\n if (payload?.uri) {\n customProtocolCheck(\n payload.uri,\n () => {},\n () => {},\n 2000,\n )\n }\n } else if (actionType === 'query') {\n // Validate it is an object of key:value pairs with value being string\n const isValid = Object.values(payload.query as QueryParams).every((value) => {\n return typeof value === 'string'\n })\n\n if (!isValid) {\n throw new Error('Invalid payload: query')\n } else {\n // Add query params to URL\n for (const [key, value] of Object.entries(payload.query as QueryParams)) {\n searchParams.set(key, value)\n }\n setSearchParams(searchParams)\n }\n } else if (actionType === 'navigate') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: navigate')\n } else {\n // Navigate to the specified page\n navigate(payload.uri)\n }\n } else if (actionType === 'redirect') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: redirect')\n } else {\n const newTab = payload?.new_tab || false\n window.open(payload.uri, newTab ? '_blank' : '_self')\n }\n }\n\n //\n // Sub-actions\n //\n\n if ('extra_download' in payload) {\n // Validate it is a string\n if (typeof payload.extra_download !== 'string') {\n throw new Error('Invalid payload: extra_download')\n } else {\n // Trigger file download from the URL\n const downloadUrl = new URL(payload.extra_download, window.location.origin).href\n console.log(downloadUrl)\n // Create a hidden anchor element\n const link = document.createElement('a')\n link.href = downloadUrl\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n // Set download attribute if it's a direct file download\n // If it's an API endpoint that handles the download, this is still good\n link.download = ''\n // Append to document, click and then remove\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n }\n }\n\n if ('extra_clipboard' in payload) {\n // Validate it is a string\n if (typeof payload.extra_clipboard !== 'string') {\n throw new Error('Invalid payload: extra_clipboard')\n } else {\n // Copy content to clipboard\n navigator.clipboard.writeText(payload.extra_clipboard).catch((err) => {\n console.error('Failed to copy text to clipboard:', err)\n })\n }\n }\n }\n\n return { handleActionPayload }\n}\n"],"names":[],"mappings":";;AAgBO,MAAM,oBAAoB,MAAM;AACrC,QAAM,CAAC,cAAc,eAAe,IAAI,gBAAgB;AACxD,QAAM,WAAW,YAAY;AAEvB,QAAA,sBAAsB,CAAC,YAAoB,YAAwC;AACvF,QAAI,CAAC,QAAS;AAEd,QAAI,eAAe,YAAY;AAC7B,UAAI,mCAAS,KAAK;AAChB;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UAAC;AAAA,UACP,MAAM;AAAA,UAAC;AAAA,UACP;AAAA,QACF;AAAA,MAAA;AAAA,IACF,WACS,eAAe,SAAS;AAE3B,YAAA,UAAU,OAAO,OAAO,QAAQ,KAAoB,EAAE,MAAM,CAAC,UAAU;AAC3E,eAAO,OAAO,UAAU;AAAA,MAAA,CACzB;AAED,UAAI,CAAC,SAAS;AACN,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA,OACnC;AAEM,mBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAoB,GAAG;AAC1D,uBAAA,IAAI,KAAK,KAAK;AAAA,QAAA;AAE7B,wBAAgB,YAAY;AAAA,MAAA;AAAA,IAC9B,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AAEL,iBAAS,QAAQ,GAAG;AAAA,MAAA;AAAA,IACtB,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AACC,cAAA,UAAS,mCAAS,YAAW;AACnC,eAAO,KAAK,QAAQ,KAAK,SAAS,WAAW,OAAO;AAAA,MAAA;AAAA,IACtD;AAOF,QAAI,oBAAoB,SAAS;AAE3B,UAAA,OAAO,QAAQ,mBAAmB,UAAU;AACxC,cAAA,IAAI,MAAM,iCAAiC;AAAA,MAAA,OAC5C;AAEC,cAAA,cAAc,IAAI,IAAI,QAAQ,gBAAgB,OAAO,SAAS,MAAM,EAAE;AAC5E,gBAAQ,IAAI,WAAW;AAEjB,cAAA,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,OAAO;AACZ,aAAK,SAAS;AACd,aAAK,MAAM;AAGX,aAAK,WAAW;AAEP,iBAAA,KAAK,YAAY,IAAI;AAC9B,aAAK,MAAM;AACF,iBAAA,KAAK,YAAY,IAAI;AAAA,MAAA;AAAA,IAChC;AAGF,QAAI,qBAAqB,SAAS;AAE5B,UAAA,OAAO,QAAQ,oBAAoB,UAAU;AACzC,cAAA,IAAI,MAAM,kCAAkC;AAAA,MAAA,OAC7C;AAEL,kBAAU,UAAU,UAAU,QAAQ,eAAe,EAAE,MAAM,CAAC,QAAQ;AAC5D,kBAAA,MAAM,qCAAqC,GAAG;AAAA,QAAA,CACvD;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,EAAE,oBAAoB;AAC/B;"}
1
+ {"version":3,"file":"useActionTriggers.es.js","sources":["../../../../src/hooks/useActionTriggers.ts"],"sourcesContent":["import customProtocolCheck from 'custom-protocol-check'\n\nexport type ActionTriggersProps = {\n searchParams: URLSearchParams\n onSetSearchParams: (params: URLSearchParams) => void\n onNavigate: (uri: string) => void\n}\n\ninterface QueryParams {\n [key: string]: string\n}\n\ninterface ActionPayload {\n query?: QueryParams // adds query params to the URL\n uri?: string // navigates to a different page\n new_tab?: boolean // opens a new tab\n extra_download?: string // triggers a file download from a URL\n extra_clipboard?: string // copies string content to clipboard\n [key: string]: any\n}\n\nexport const useActionTriggers = ({\n searchParams,\n onSetSearchParams,\n onNavigate,\n}: ActionTriggersProps) => {\n const handleActionPayload = (actionType: string, payload: ActionPayload | null): void => {\n if (!payload) return\n\n if (actionType === 'launcher') {\n if (payload?.uri) {\n customProtocolCheck(\n payload.uri,\n () => {},\n () => {},\n 2000,\n )\n }\n } else if (actionType === 'query') {\n // Validate it is an object of key:value pairs with value being string\n const isValid = Object.values(payload.query as QueryParams).every((value) => {\n return typeof value === 'string'\n })\n\n if (!isValid) {\n throw new Error('Invalid payload: query')\n } else {\n // Add query params to URL\n for (const [key, value] of Object.entries(payload.query as QueryParams)) {\n searchParams.set(key, value)\n }\n onSetSearchParams(searchParams)\n }\n } else if (actionType === 'navigate') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: navigate')\n } else {\n // Navigate to the specified page\n onNavigate(payload.uri)\n }\n } else if (actionType === 'redirect') {\n // Validate it is a string\n if (typeof payload.uri !== 'string') {\n throw new Error('Invalid payload: redirect')\n } else {\n const newTab = payload?.new_tab || false\n window.open(payload.uri, newTab ? '_blank' : '_self')\n }\n }\n\n //\n // Sub-actions\n //\n\n if ('extra_download' in payload) {\n // Validate it is a string\n if (typeof payload.extra_download !== 'string') {\n throw new Error('Invalid payload: extra_download')\n } else {\n // Trigger file download from the URL\n const downloadUrl = new URL(payload.extra_download, window.location.origin).href\n console.log(downloadUrl)\n // Create a hidden anchor element\n const link = document.createElement('a')\n link.href = downloadUrl\n link.target = '_blank'\n link.rel = 'noopener noreferrer'\n // Set download attribute if it's a direct file download\n // If it's an API endpoint that handles the download, this is still good\n link.download = ''\n // Append to document, click and then remove\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n }\n }\n\n if ('extra_clipboard' in payload) {\n // Validate it is a string\n if (typeof payload.extra_clipboard !== 'string') {\n throw new Error('Invalid payload: extra_clipboard')\n } else {\n // Copy content to clipboard\n navigator.clipboard.writeText(payload.extra_clipboard).catch((err) => {\n console.error('Failed to copy text to clipboard:', err)\n })\n }\n }\n }\n\n return { handleActionPayload }\n}\n"],"names":[],"mappings":";AAqBO,MAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,MAA2B;AACnB,QAAA,sBAAsB,CAAC,YAAoB,YAAwC;AACvF,QAAI,CAAC,QAAS;AAEd,QAAI,eAAe,YAAY;AAC7B,UAAI,mCAAS,KAAK;AAChB;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UAAC;AAAA,UACP,MAAM;AAAA,UAAC;AAAA,UACP;AAAA,QACF;AAAA,MAAA;AAAA,IACF,WACS,eAAe,SAAS;AAE3B,YAAA,UAAU,OAAO,OAAO,QAAQ,KAAoB,EAAE,MAAM,CAAC,UAAU;AAC3E,eAAO,OAAO,UAAU;AAAA,MAAA,CACzB;AAED,UAAI,CAAC,SAAS;AACN,cAAA,IAAI,MAAM,wBAAwB;AAAA,MAAA,OACnC;AAEM,mBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAoB,GAAG;AAC1D,uBAAA,IAAI,KAAK,KAAK;AAAA,QAAA;AAE7B,0BAAkB,YAAY;AAAA,MAAA;AAAA,IAChC,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AAEL,mBAAW,QAAQ,GAAG;AAAA,MAAA;AAAA,IACxB,WACS,eAAe,YAAY;AAEhC,UAAA,OAAO,QAAQ,QAAQ,UAAU;AAC7B,cAAA,IAAI,MAAM,2BAA2B;AAAA,MAAA,OACtC;AACC,cAAA,UAAS,mCAAS,YAAW;AACnC,eAAO,KAAK,QAAQ,KAAK,SAAS,WAAW,OAAO;AAAA,MAAA;AAAA,IACtD;AAOF,QAAI,oBAAoB,SAAS;AAE3B,UAAA,OAAO,QAAQ,mBAAmB,UAAU;AACxC,cAAA,IAAI,MAAM,iCAAiC;AAAA,MAAA,OAC5C;AAEC,cAAA,cAAc,IAAI,IAAI,QAAQ,gBAAgB,OAAO,SAAS,MAAM,EAAE;AAC5E,gBAAQ,IAAI,WAAW;AAEjB,cAAA,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,OAAO;AACZ,aAAK,SAAS;AACd,aAAK,MAAM;AAGX,aAAK,WAAW;AAEP,iBAAA,KAAK,YAAY,IAAI;AAC9B,aAAK,MAAM;AACF,iBAAA,KAAK,YAAY,IAAI;AAAA,MAAA;AAAA,IAChC;AAGF,QAAI,qBAAqB,SAAS;AAE5B,UAAA,OAAO,QAAQ,oBAAoB,UAAU;AACzC,cAAA,IAAI,MAAM,kCAAkC;AAAA,MAAA,OAC7C;AAEL,kBAAU,UAAU,UAAU,QAAQ,eAAe,EAAE,MAAM,CAAC,QAAQ;AAC5D,kBAAA,MAAM,qCAAqC,GAAG;AAAA,QAAA,CACvD;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,EAAE,oBAAoB;AAC/B;"}
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { Row, FilterFn } from '@tanstack/react-table';
2
+ import { Row, FilterFn, RowData, Table } from '@tanstack/react-table';
3
3
  import { RankingInfo } from '@tanstack/match-sorter-utils';
4
4
  import { SimpleTableCellTemplateProps } from './SimpleTableRowTemplate';
5
5
  declare module '@tanstack/react-table' {
@@ -9,6 +9,12 @@ declare module '@tanstack/react-table' {
9
9
  interface FilterMeta {
10
10
  itemRank: RankingInfo;
11
11
  }
12
+ interface TableMeta<TData extends RowData> {
13
+ isExpandable?: boolean;
14
+ isLoading?: boolean;
15
+ children?: (props: SimpleTableCellTemplateProps, row: Row<TData>, table: Table<SimpleTableRow>) => JSX.Element;
16
+ [key: string]: any;
17
+ }
12
18
  }
13
19
  export type RowItemData = {
14
20
  id: string;
@@ -37,7 +43,8 @@ export interface SimpleTableProps {
37
43
  isExpandable?: boolean;
38
44
  forceUpdateTable?: any;
39
45
  globalFilter?: string;
40
- children?: (props: SimpleTableCellTemplateProps, row: Row<SimpleTableRow>) => JSX.Element;
46
+ meta?: Record<string, any>;
47
+ children?: (props: SimpleTableCellTemplateProps, row: Row<SimpleTableRow>, table: Table<SimpleTableRow>) => JSX.Element;
41
48
  }
42
49
  declare const SimpleTable: FC<SimpleTableProps>;
43
50
  export default SimpleTable;
@@ -1,3 +1,10 @@
1
+ export type RowExpanderProps = {
2
+ isRowExpandable?: boolean;
3
+ isRowExpanded?: boolean;
4
+ isTableExpandable?: boolean;
5
+ onExpandClick?: () => void;
6
+ };
7
+ export declare const RowExpander: ({ isRowExpandable, isRowExpanded, isTableExpandable, onExpandClick, }: RowExpanderProps) => false | import("react/jsx-runtime").JSX.Element | undefined;
1
8
  export interface SimpleTableCellTemplateProps extends React.HTMLAttributes<HTMLDivElement> {
2
9
  value: string;
3
10
  icon?: string;
@@ -1967,6 +1967,8 @@ export type GetListsQuery = {
1967
1967
  id: string;
1968
1968
  label: string;
1969
1969
  entityListType: string;
1970
+ tags: Array<string>;
1971
+ data: string;
1970
1972
  entityType: string;
1971
1973
  active: boolean;
1972
1974
  createdAt: any;
@@ -2672,7 +2674,7 @@ export declare const GetDetailsPanelTaskDocument = "\n query GetDetailsPanelT
2672
2674
  export declare const GetDetailsPanelVersionDocument = "\n query GetDetailsPanelVersion($projectName: String!, $entityId: String!) {\n project(name: $projectName) {\n projectName\n code\n version(id: $entityId) {\n id\n version\n name\n author\n status\n tags\n updatedAt\n createdAt\n thumbnailId\n hasReviewables\n product {\n ...DetailsPanelProductFragment\n folder {\n ...DetailsPanelFolderFragment\n }\n }\n task {\n ...DetailsPanelTaskFragment\n }\n allAttrib\n representations {\n edges {\n node {\n ...DetailsPanelRepresentationFragment\n }\n }\n }\n }\n }\n}\n \n fragment DetailsPanelProductFragment on ProductNode {\n id\n name\n productType\n}\n \n\n fragment DetailsPanelFolderFragment on FolderNode {\n id\n name\n label\n path\n folderType\n}\n \n\n fragment DetailsPanelTaskFragment on TaskNode {\n id\n name\n label\n assignees\n taskType\n}\n \n\n fragment DetailsPanelRepresentationFragment on RepresentationNode {\n id\n name\n fileCount\n}\n ";
2673
2675
  export declare const GetProductVersionsDocument = "\n query GetProductVersions($projectName: String!, $productId: String!) {\n project(name: $projectName) {\n product(id: $productId) {\n versionList {\n id\n name\n version\n }\n }\n }\n}\n ";
2674
2676
  export declare const GetListItemsDocument = "\n query GetListItems($projectName: String!, $listId: String!, $first: Int, $after: String, $before: String, $last: Int, $sortBy: String, $filter: String) {\n project(name: $projectName) {\n entityLists(ids: [$listId]) {\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n node {\n id\n active\n items(\n first: $first\n after: $after\n before: $before\n last: $last\n sortBy: $sortBy\n filter: $filter\n ) {\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n id\n entityId\n entityType\n allAttrib\n ownAttrib\n node {\n active\n name\n updatedAt\n ...ListItemFragment\n }\n }\n }\n }\n }\n }\n }\n}\n \n fragment ListItemFragment on BaseNode {\n ... on TaskNode {\n name\n label\n status\n tags\n taskType\n assignees\n folder {\n path\n folderType\n }\n }\n ... on FolderNode {\n name\n label\n status\n tags\n folderType\n path\n }\n ... on ProductNode {\n name\n status\n tags\n productType\n folder {\n path\n folderType\n }\n }\n ... on VersionNode {\n name\n status\n tags\n product {\n name\n productType\n folder {\n path\n folderType\n }\n }\n task {\n name\n taskType\n }\n }\n}\n ";
2675
- export declare const GetListsDocument = "\n query GetLists($projectName: String!, $first: Int!, $after: String, $filter: String) {\n project(name: $projectName) {\n entityLists(first: $first, after: $after, filter: $filter) {\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n node {\n id\n label\n entityListType\n entityType\n active\n createdAt\n updatedAt\n active\n owner\n count\n }\n }\n }\n }\n}\n ";
2677
+ export declare const GetListsDocument = "\n query GetLists($projectName: String!, $first: Int!, $after: String, $filter: String) {\n project(name: $projectName) {\n entityLists(first: $first, after: $after, filter: $filter) {\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n node {\n id\n label\n entityListType\n tags\n data\n entityType\n active\n createdAt\n updatedAt\n active\n owner\n count\n }\n }\n }\n }\n}\n ";
2676
2678
  export declare const GetTasksByParentDocument = "\n query GetTasksByParent($projectName: String!, $parentIds: [String!]!, $filter: String, $search: String) {\n project(name: $projectName) {\n name\n tasks(folderIds: $parentIds, filter: $filter, search: $search) {\n edges {\n node {\n ...TaskPropsFragment\n }\n }\n }\n }\n}\n \n fragment TaskPropsFragment on TaskNode {\n id\n folderId\n label\n name\n ownAttrib\n status\n tags\n taskType\n updatedAt\n active\n assignees\n allAttrib\n folder {\n path\n }\n}\n ";
2677
2679
  export declare const GetTasksListDocument = "\n query GetTasksList($projectName: String!, $folderIds: [String!], $filter: String, $search: String, $after: String, $first: Int, $before: String, $last: Int, $sortBy: String) {\n project(name: $projectName) {\n name\n tasks(\n filter: $filter\n search: $search\n folderIds: $folderIds\n after: $after\n first: $first\n before: $before\n last: $last\n sortBy: $sortBy\n ) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n edges {\n cursor\n node {\n ...TaskPropsFragment\n }\n }\n }\n }\n}\n \n fragment TaskPropsFragment on TaskNode {\n id\n folderId\n label\n name\n ownAttrib\n status\n tags\n taskType\n updatedAt\n active\n assignees\n allAttrib\n folder {\n path\n }\n}\n ";
2678
2680
  export declare const GetProjectLatestDocument = "\n query GetProjectLatest($projectName: String!) {\n project(name: $projectName) {\n name\n }\n}\n ";
@@ -1,5 +1,6 @@
1
1
  import { ActionContext } from '../../api';
2
- type ActionsProps = {
2
+ import { ActionTriggersProps } from '../../hooks';
3
+ interface ActionsProps extends ActionTriggersProps {
3
4
  entities: {
4
5
  id: string;
5
6
  projectName: string;
@@ -8,6 +9,6 @@ type ActionsProps = {
8
9
  entityType: ActionContext['entityType'];
9
10
  entitySubTypes?: string[];
10
11
  isLoadingEntity: boolean;
11
- };
12
- export declare const Actions: ({ entities, entityType, entitySubTypes, isLoadingEntity, }: ActionsProps) => import("react/jsx-runtime").JSX.Element;
12
+ }
13
+ export declare const Actions: ({ entities, entityType, entitySubTypes, isLoadingEntity, searchParams, onNavigate, onSetSearchParams, }: ActionsProps) => import("react/jsx-runtime").JSX.Element;
13
14
  export {};
@@ -7,11 +7,11 @@ import { ToggleExpandAll } from './context/ProjectTableContext';
7
7
  import { UpdateTableEntities } from './hooks/useUpdateTableData';
8
8
  declare module '@tanstack/react-table' {
9
9
  interface TableMeta<TData extends RowData> {
10
- options: BuiltInFieldOptions;
11
- readOnly: ProjectTreeTableProps['readOnly'];
12
- projectName: string;
13
- updateEntities: UpdateTableEntities;
14
- toggleExpandAll: ToggleExpandAll;
10
+ options?: BuiltInFieldOptions;
11
+ readOnly?: ProjectTreeTableProps['readOnly'];
12
+ projectName?: string;
13
+ updateEntities?: UpdateTableEntities;
14
+ toggleExpandAll?: ToggleExpandAll;
15
15
  }
16
16
  }
17
17
  export interface ProjectTreeTableProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -22,12 +22,13 @@ export interface ProjectTreeTableProps extends React.HTMLAttributes<HTMLDivEleme
22
22
  readOnly?: (DefaultColumns | string)[];
23
23
  excludedColumns?: (DefaultColumns | string)[];
24
24
  extraColumns?: TreeTableExtraColumn[];
25
+ isLoading?: boolean;
25
26
  pt?: {
26
27
  container?: React.HTMLAttributes<HTMLDivElement>;
27
28
  head?: Partial<TableHeadProps>;
28
29
  };
29
30
  }
30
- export declare const ProjectTreeTable: ({ scope, sliceId, fetchMoreOnBottomReached, onOpenNew, readOnly, excludedColumns, extraColumns, pt, ...props }: ProjectTreeTableProps) => import("react/jsx-runtime").JSX.Element;
31
+ export declare const ProjectTreeTable: ({ scope, sliceId, fetchMoreOnBottomReached, onOpenNew, readOnly, excludedColumns, extraColumns, isLoading: isLoadingProp, pt, ...props }: ProjectTreeTableProps) => import("react/jsx-runtime").JSX.Element;
31
32
  interface TableHeadProps extends React.HTMLAttributes<HTMLTableSectionElement> {
32
33
  columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>;
33
34
  table: Table<TableRow>;
@@ -1,5 +1,7 @@
1
1
  import { default as React, ReactNode } from 'react';
2
2
  import { DetailsPanelEntityType, UserModel } from '../api';
3
+ import { useLocation, useNavigate, useParams } from 'react-router';
4
+ import { useSearchParams } from 'react-router-dom';
3
5
  export type FeedFilters = 'activity' | 'comments' | 'versions' | 'checklists';
4
6
  export type DetailsPanelTab = FeedFilters | 'attribs' | 'files';
5
7
  export type SlideOut = {
@@ -26,8 +28,8 @@ export interface DetailsPanelContextProps {
26
28
  user: UserModel;
27
29
  viewer?: {
28
30
  reviewableIds: string[];
29
- taskId?: string;
30
- folderId?: string;
31
+ taskId?: string | null;
32
+ folderId?: string | null;
31
33
  };
32
34
  onOpenImage?: (args: any) => void;
33
35
  onGoToFrame?: (frame: number) => void;
@@ -36,6 +38,10 @@ export interface DetailsPanelContextProps {
36
38
  operations: any[];
37
39
  entityType: string;
38
40
  }) => void;
41
+ useParams: typeof useParams;
42
+ useNavigate: typeof useNavigate;
43
+ useLocation: typeof useLocation;
44
+ useSearchParams: typeof useSearchParams;
39
45
  }
40
46
  export interface DetailsPanelContextType extends DetailsPanelContextProps {
41
47
  panelOpenByScope: OpenStateByScope;
@@ -1,3 +1,8 @@
1
+ export type ActionTriggersProps = {
2
+ searchParams: URLSearchParams;
3
+ onSetSearchParams: (params: URLSearchParams) => void;
4
+ onNavigate: (uri: string) => void;
5
+ };
1
6
  interface QueryParams {
2
7
  [key: string]: string;
3
8
  }
@@ -9,7 +14,7 @@ interface ActionPayload {
9
14
  extra_clipboard?: string;
10
15
  [key: string]: any;
11
16
  }
12
- export declare const useActionTriggers: () => {
17
+ export declare const useActionTriggers: ({ searchParams, onSetSearchParams, onNavigate, }: ActionTriggersProps) => {
13
18
  handleActionPayload: (actionType: string, payload: ActionPayload | null) => void;
14
19
  };
15
20
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynput/ayon-frontend-shared",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Shared React components for AYON frontend",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",