@ynput/ayon-frontend-shared 0.2.5 → 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.
- package/dist/ProjectTreeTable.cjs.js +16 -0
- package/dist/ProjectTreeTable.cjs.js.map +1 -1
- package/dist/ProjectTreeTable.es.js +16 -0
- package/dist/ProjectTreeTable.es.js.map +1 -1
- package/dist/_virtual/index.cjs5.js +5 -3
- package/dist/_virtual/index.cjs5.js.map +1 -1
- package/dist/_virtual/index.cjs6.js +3 -5
- package/dist/_virtual/index.cjs6.js.map +1 -1
- package/dist/_virtual/index.es5.js +5 -2
- package/dist/_virtual/index.es5.js.map +1 -1
- package/dist/_virtual/index.es6.js +2 -5
- package/dist/_virtual/index.es6.js.map +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
- package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
- package/dist/node_modules/remove-accents/index.cjs.js +1 -1
- package/dist/node_modules/remove-accents/index.es.js +1 -1
- package/dist/shared/src/api/generated/actions.cjs.js.map +1 -1
- package/dist/shared/src/api/generated/actions.es.js.map +1 -1
- package/dist/shared/src/api/generated/graphql.cjs.js +2 -0
- package/dist/shared/src/api/generated/graphql.cjs.js.map +1 -1
- package/dist/shared/src/api/generated/graphql.es.js +2 -0
- package/dist/shared/src/api/generated/graphql.es.js.map +1 -1
- package/dist/shared/src/components/AttributeEditor/AttributeEditor.cjs.js +1 -1
- package/dist/shared/src/components/AttributeEditor/AttributeEditor.cjs.js.map +1 -1
- package/dist/shared/src/components/AttributeEditor/AttributeEditor.es.js +1 -1
- package/dist/shared/src/components/AttributeEditor/AttributeEditor.es.js.map +1 -1
- package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js +0 -1
- package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.cjs.js.map +1 -1
- package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js +0 -1
- package/dist/shared/src/components/DetailsPanelAttributes/DetailsPanelAttributes.es.js.map +1 -1
- package/dist/shared/src/containers/Actions/Actions.cjs.js +5 -2
- package/dist/shared/src/containers/Actions/Actions.cjs.js.map +1 -1
- package/dist/shared/src/containers/Actions/Actions.es.js +5 -2
- package/dist/shared/src/containers/Actions/Actions.es.js.map +1 -1
- package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js +1 -0
- package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js.map +1 -1
- package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js +1 -0
- package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js.map +1 -1
- package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js +9 -3
- package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.cjs.js.map +1 -1
- package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js +9 -3
- package/dist/shared/src/containers/DetailsPanel/DetailsPanelHeader/DetailsPanelHeader.es.js.map +1 -1
- package/dist/shared/src/containers/Feed/context/FeedContext.cjs.js +2 -2
- package/dist/shared/src/containers/Feed/context/FeedContext.cjs.js.map +1 -1
- package/dist/shared/src/containers/Feed/context/FeedContext.es.js +2 -2
- package/dist/shared/src/containers/Feed/context/FeedContext.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js +4 -8
- package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js +4 -8
- package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js +0 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js +0 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.es.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.es.js.map +1 -1
- package/dist/shared/src/context/DetailsPanelContext.cjs.js +0 -1
- package/dist/shared/src/context/DetailsPanelContext.cjs.js.map +1 -1
- package/dist/shared/src/context/DetailsPanelContext.es.js +0 -1
- package/dist/shared/src/context/DetailsPanelContext.es.js.map +1 -1
- package/dist/shared/src/hooks/useActionTriggers.cjs.js +7 -6
- package/dist/shared/src/hooks/useActionTriggers.cjs.js.map +1 -1
- package/dist/shared/src/hooks/useActionTriggers.es.js +7 -6
- package/dist/shared/src/hooks/useActionTriggers.es.js.map +1 -1
- package/dist/shared/src/hooks/useLoadModules.cjs.js +9 -2
- package/dist/shared/src/hooks/useLoadModules.cjs.js.map +1 -1
- package/dist/shared/src/hooks/useLoadModules.es.js +9 -2
- package/dist/shared/src/hooks/useLoadModules.es.js.map +1 -1
- package/dist/shared/src/util/confirmDelete.cjs.js.map +1 -1
- package/dist/shared/src/util/confirmDelete.es.js.map +1 -1
- package/dist/types/SimpleTable/SimpleTable.d.ts +9 -2
- package/dist/types/SimpleTable/SimpleTableRowTemplate.d.ts +7 -0
- package/dist/types/api/generated/actions.d.ts +1 -1
- package/dist/types/api/generated/graphql.d.ts +3 -1
- package/dist/types/containers/Actions/Actions.d.ts +4 -3
- package/dist/types/containers/ProjectTreeTable/ProjectTreeTable.d.ts +7 -6
- package/dist/types/containers/ProjectTreeTable/index.d.ts +1 -0
- package/dist/types/context/DetailsPanelContext.d.ts +8 -2
- package/dist/types/hooks/useActionTriggers.d.ts +6 -1
- package/dist/types/util/confirmDelete.d.ts +1 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildTreeTableColumns.es.js","sources":["../../../../../src/containers/ProjectTreeTable/buildTreeTableColumns.tsx"],"sourcesContent":["import { ColumnDef, FilterFnOption, Row, SortingFn, sortingFns } from '@tanstack/react-table'\nimport { TableRow } from './types/table'\nimport { AttributeData, ProjectTableAttribute, BuiltInFieldOptions } from './types'\nimport { CellWidget, EntityNameWidget, ThumbnailWidget } from './widgets'\nimport { getCellId, getCellValue } from './utils/cellUtils'\nimport { TableCellContent } from './ProjectTreeTable.styled'\nimport clsx from 'clsx'\nimport { SelectionCell } from './components/SelectionCell'\nimport RowSelectionHeader from './components/RowSelectionHeader'\nimport { ROW_SELECTION_COLUMN_ID } from './context/SelectionCellsContext'\n\n// Wrapper function for sorting that pushes isLoading rows to the bottom\nconst withLoadingStateSort = (sortFn: SortingFn<any>): SortingFn<any> => {\n return (rowA, rowB, ...args) => {\n // If row loading states differ, prioritize non-loading rows\n if (rowA.original.isLoading !== rowB.original.isLoading) {\n return rowA.original.isLoading ? 1 : -1\n }\n // Otherwise, use the original sort function\n return sortFn(rowA, rowB, ...args)\n }\n}\n\nconst nameSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.label || rowA.original.name\n const labelB = rowB.original.label || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\nconst pathSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.path || rowA.original.name\n const labelB = rowB.original.path || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\n\ntype AttribSortingFn = (rowA: any, rowB: any, columnId: string, attribute?: AttributeData) => number\n// sort by the order of the enum options\nconst attribSort: AttribSortingFn = (rowA, rowB, columnId, attrib) => {\n const valueA = getCellValue(rowA.original, columnId)\n const valueB = getCellValue(rowB.original, columnId)\n // if attrib is defined and has enum options, use them\n if (attrib && attrib.enum) {\n const indexA = attrib.enum.findIndex((o) => o.value === valueA)\n const indexB = attrib.enum.findIndex((o) => o.value === valueB)\n return indexA - indexB < 0 ? 1 : -1\n } else if (attrib?.type === 'datetime') {\n return sortingFns.datetime(rowA, rowB, columnId)\n } else if (attrib?.type === 'boolean') {\n const boolA = valueA === true ? 1 : 0\n const boolB = valueB === true ? 1 : 0\n return boolA - boolB\n } else {\n // default sorting\n return sortingFns.alphanumeric(rowA, rowB, columnId)\n }\n}\n\nexport type DefaultColumns =\n | typeof ROW_SELECTION_COLUMN_ID\n | 'thumbnail'\n | 'name'\n | 'status'\n | 'subType'\n | 'assignees'\n | 'tags'\n\nexport type TreeTableExtraColumn = { column: ColumnDef<TableRow>; position?: number }\n\nexport type BuildTreeTableColumnsProps = {\n attribs: ProjectTableAttribute[]\n showHierarchy: boolean\n options: BuiltInFieldOptions\n excluded?: (DefaultColumns | string)[]\n extraColumns?: TreeTableExtraColumn[]\n}\n\nconst buildTreeTableColumns = ({\n attribs,\n showHierarchy,\n options,\n excluded,\n extraColumns,\n}: BuildTreeTableColumnsProps) => {\n console.log('building columns')\n const staticColumns: ColumnDef<TableRow>[] = []\n\n // Helper to check if a column should be included\n const isIncluded = (id: DefaultColumns | string) => !excluded?.includes(id)\n\n // Conditionally add static columns\n if (isIncluded(ROW_SELECTION_COLUMN_ID)) {\n staticColumns.push({\n id: ROW_SELECTION_COLUMN_ID,\n enableResizing: false,\n enableSorting: false,\n enablePinning: false,\n enableHiding: false,\n\n header: () => <RowSelectionHeader />,\n cell: () => <SelectionCell />,\n size: 20,\n })\n }\n\n if (isIncluded('thumbnail')) {\n staticColumns.push({\n id: 'thumbnail',\n header: '',\n size: 63,\n minSize: 64,\n enableResizing: true,\n enableSorting: false,\n cell: ({ row, table }) => {\n const meta = table.options.meta\n if (!meta) return null\n return (\n <ThumbnailWidget\n entityId={row.original.entityId || row.id}\n entityType={row.original.entityType}\n updatedAt={row.original.updatedAt}\n icon={row.original.icon}\n projectName={meta?.projectName}\n />\n )\n },\n })\n }\n\n if (isIncluded('name')) {\n staticColumns.push({\n id: 'name',\n accessorKey: 'name',\n header: () => 'Folder / Task',\n sortingFn: withLoadingStateSort(showHierarchy ? nameSort : pathSort),\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const cellId = getCellId(row.id, column.id)\n return (\n <TableCellContent\n id={cellId}\n className={clsx('large', row.original.entityType, {\n loading: row.original.isLoading,\n hierarchy: showHierarchy,\n })}\n style={{\n paddingLeft: `calc(${row.depth * 1}rem + 8px)`,\n }}\n tabIndex={0}\n >\n <EntityNameWidget\n id={row.id}\n label={row.original.label}\n name={row.original.name}\n path={!showHierarchy ? row.original.path : undefined}\n showHierarchy={showHierarchy}\n icon={row.original.icon}\n type={row.original.entityType}\n isExpanded={row.getIsExpanded()}\n toggleExpandAll={() => meta?.toggleExpandAll([row.id])}\n toggleExpanded={row.getToggleExpandedHandler()}\n />\n </TableCellContent>\n )\n },\n })\n }\n\n if (isIncluded('status')) {\n staticColumns.push({\n id: 'status',\n accessorKey: 'status',\n header: () => 'Status',\n sortingFn: withLoadingStateSort((a, b, c) =>\n attribSort(a, b, c, { enum: options.status, type: 'string' }),\n ),\n sortDescFirst: true,\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n const meta = table.options.meta\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('status', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={meta?.options.status.filter((s) => s.scope?.includes(type))}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n />\n )\n },\n })\n }\n\n if (isIncluded('subType')) {\n staticColumns.push({\n id: 'subType',\n accessorKey: 'subType',\n header: () => 'Type',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n const fieldId = type === 'folder' ? 'folderType' : 'taskType'\n const meta = table.options.meta\n return (\n <CellWidget\n rowId={id}\n className={clsx('subType', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={\n type === 'folder'\n ? meta?.options.folderType\n : type === 'task'\n ? meta?.options.taskType\n : []\n }\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: fieldId, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n />\n )\n },\n })\n }\n\n if (isIncluded('assignees')) {\n staticColumns.push({\n id: 'assignees',\n accessorKey: 'assignees',\n header: () => 'Assignees',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const { value, id, type } = getValueIdType(row, column.id)\n if (type === 'folder')\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value=\"\"\n isPlaceholder\n />\n )\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={meta?.options.assignee}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n pt={{\n enum: {\n multiSelectClose: value?.length === 0, // close the dropdown on first assignment\n search: true, // enable search at all times\n multipleOverride: false,\n },\n }}\n />\n )\n },\n })\n }\n\n if (isIncluded('tags')) {\n staticColumns.push({\n id: 'tags',\n accessorKey: 'tags',\n header: () => 'Tags',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const { value, id, type } = getValueIdType(row, column.id)\n return (\n <CellWidget\n rowId={id}\n className={clsx('tags', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={meta?.options.tag}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n enableCustomValues\n />\n )\n },\n })\n }\n\n const attributeColumns: ColumnDef<TableRow>[] = attribs\n .filter((attrib) => {\n const columnId = 'attrib_' + attrib.name\n // Check if the specific attribute column is excluded\n // or if all built-in attributes are excluded and this is a built-in attribute\n if (excluded?.includes(columnId)) return false\n if (attrib.builtin && excluded?.includes('attrib')) return false\n return true\n })\n .map((attrib) => {\n const attribColumn: ColumnDef<TableRow> = {\n id: 'attrib_' + attrib.name,\n accessorKey: 'attrib.' + attrib.name,\n header: () => attrib.data.title || attrib.name,\n filterFn: 'fuzzy' as FilterFnOption<TableRow>,\n sortingFn: withLoadingStateSort((a, b, c) => attribSort(a, b, c, attrib.data)),\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const columnIdParsed = column.id.replace('attrib_', '')\n const { value, id, type } = getValueIdType(row, columnIdParsed, 'attrib')\n const isInherited = !row.original.ownAttrib.includes(columnIdParsed)\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('attrib', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: attrib.data.type || 'string' }}\n options={attrib.data.enum || []}\n isCollapsed={!!row.original.childOnlyMatch}\n isInherited={isInherited && ['folder', 'task'].includes(type)}\n isReadOnly={\n attrib.readOnly ||\n meta?.readOnly?.some(\n (id) => id === columnIdParsed || (id === 'attrib' && attrib.builtin),\n )\n }\n onChange={(value) =>\n meta?.updateEntities([\n { field: columnIdParsed, value, id, type, isAttrib: true, rowId: row.id },\n ])\n }\n />\n )\n },\n }\n return attribColumn\n })\n\n const allColumns = [...staticColumns, ...attributeColumns]\n\n // Add extra columns if provided\n if (extraColumns) {\n extraColumns.forEach(({ column, position = -1 }) => {\n if (position >= 0 && position < allColumns.length) {\n allColumns.splice(position, 0, column)\n } else {\n allColumns.push(column)\n }\n })\n }\n\n return allColumns\n}\n\nexport default buildTreeTableColumns\n\nexport const getValueIdType = (\n row: Row<TableRow>,\n field: string,\n nestedField?: keyof TableRow,\n): {\n value: any\n id: string\n type: string\n} => ({\n value: nestedField\n ? (row.original[nestedField as keyof TableRow] as any)?.[field]\n : (row.original[field as keyof TableRow] as any),\n id: row.id,\n type: row.original.entityType,\n})\n"],"names":["jsx","_a","value","id"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"buildTreeTableColumns.es.js","sources":["../../../../../src/containers/ProjectTreeTable/buildTreeTableColumns.tsx"],"sourcesContent":["import { ColumnDef, FilterFnOption, Row, SortingFn, sortingFns } from '@tanstack/react-table'\nimport { TableRow } from './types/table'\nimport { AttributeData, ProjectTableAttribute, BuiltInFieldOptions } from './types'\nimport { CellWidget, EntityNameWidget, ThumbnailWidget } from './widgets'\nimport { getCellId, getCellValue } from './utils/cellUtils'\nimport { TableCellContent } from './ProjectTreeTable.styled'\nimport clsx from 'clsx'\nimport { SelectionCell } from './components/SelectionCell'\nimport RowSelectionHeader from './components/RowSelectionHeader'\nimport { ROW_SELECTION_COLUMN_ID } from './context/SelectionCellsContext'\n\n// Wrapper function for sorting that pushes isLoading rows to the bottom\nconst withLoadingStateSort = (sortFn: SortingFn<any>): SortingFn<any> => {\n return (rowA, rowB, ...args) => {\n // If row loading states differ, prioritize non-loading rows\n if (rowA.original.isLoading !== rowB.original.isLoading) {\n return rowA.original.isLoading ? 1 : -1\n }\n // Otherwise, use the original sort function\n return sortFn(rowA, rowB, ...args)\n }\n}\n\nconst nameSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.label || rowA.original.name\n const labelB = rowB.original.label || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\nconst pathSort: SortingFn<any> = (rowA, rowB) => {\n const labelA = rowA.original.path || rowA.original.name\n const labelB = rowB.original.path || rowB.original.name\n // sort alphabetically by label\n return labelA.localeCompare(labelB)\n}\n\ntype AttribSortingFn = (rowA: any, rowB: any, columnId: string, attribute?: AttributeData) => number\n// sort by the order of the enum options\nconst attribSort: AttribSortingFn = (rowA, rowB, columnId, attrib) => {\n const valueA = getCellValue(rowA.original, columnId)\n const valueB = getCellValue(rowB.original, columnId)\n // if attrib is defined and has enum options, use them\n if (attrib && attrib.enum) {\n const indexA = attrib.enum.findIndex((o) => o.value === valueA)\n const indexB = attrib.enum.findIndex((o) => o.value === valueB)\n return indexA - indexB < 0 ? 1 : -1\n } else if (attrib?.type === 'datetime') {\n return sortingFns.datetime(rowA, rowB, columnId)\n } else if (attrib?.type === 'boolean') {\n const boolA = valueA === true ? 1 : 0\n const boolB = valueB === true ? 1 : 0\n return boolA - boolB\n } else {\n // default sorting\n return sortingFns.alphanumeric(rowA, rowB, columnId)\n }\n}\n\nexport type DefaultColumns =\n | typeof ROW_SELECTION_COLUMN_ID\n | 'thumbnail'\n | 'name'\n | 'status'\n | 'subType'\n | 'assignees'\n | 'tags'\n\nexport type TreeTableExtraColumn = { column: ColumnDef<TableRow>; position?: number }\n\nexport type BuildTreeTableColumnsProps = {\n attribs: ProjectTableAttribute[]\n showHierarchy: boolean\n options: BuiltInFieldOptions\n excluded?: (DefaultColumns | string)[]\n extraColumns?: TreeTableExtraColumn[]\n}\n\nconst buildTreeTableColumns = ({\n attribs,\n showHierarchy,\n options,\n excluded,\n extraColumns,\n}: BuildTreeTableColumnsProps) => {\n const staticColumns: ColumnDef<TableRow>[] = []\n\n // Helper to check if a column should be included\n const isIncluded = (id: DefaultColumns | string) => !excluded?.includes(id)\n\n // Conditionally add static columns\n if (isIncluded(ROW_SELECTION_COLUMN_ID)) {\n staticColumns.push({\n id: ROW_SELECTION_COLUMN_ID,\n enableResizing: false,\n enableSorting: false,\n enablePinning: false,\n enableHiding: false,\n\n header: () => <RowSelectionHeader />,\n cell: () => <SelectionCell />,\n size: 20,\n })\n }\n\n if (isIncluded('thumbnail')) {\n staticColumns.push({\n id: 'thumbnail',\n header: '',\n size: 63,\n minSize: 64,\n enableResizing: true,\n enableSorting: false,\n cell: ({ row, table }) => {\n const meta = table.options.meta\n if (!meta) return null\n return (\n <ThumbnailWidget\n entityId={row.original.entityId || row.id}\n entityType={row.original.entityType}\n updatedAt={row.original.updatedAt}\n icon={row.original.icon}\n projectName={meta?.projectName}\n />\n )\n },\n })\n }\n\n if (isIncluded('name')) {\n staticColumns.push({\n id: 'name',\n accessorKey: 'name',\n header: () => 'Folder / Task',\n sortingFn: withLoadingStateSort(showHierarchy ? nameSort : pathSort),\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const cellId = getCellId(row.id, column.id)\n return (\n <TableCellContent\n id={cellId}\n className={clsx('large', row.original.entityType, {\n loading: row.original.isLoading,\n hierarchy: showHierarchy,\n })}\n style={{\n paddingLeft: `calc(${row.depth * 1}rem + 8px)`,\n }}\n tabIndex={0}\n >\n <EntityNameWidget\n id={row.id}\n label={row.original.label}\n name={row.original.name}\n path={!showHierarchy ? row.original.path : undefined}\n showHierarchy={showHierarchy}\n icon={row.original.icon}\n type={row.original.entityType}\n isExpanded={row.getIsExpanded()}\n toggleExpandAll={() => meta?.toggleExpandAll([row.id])}\n toggleExpanded={row.getToggleExpandedHandler()}\n />\n </TableCellContent>\n )\n },\n })\n }\n\n if (isIncluded('status')) {\n staticColumns.push({\n id: 'status',\n accessorKey: 'status',\n header: () => 'Status',\n sortingFn: withLoadingStateSort((a, b, c) =>\n attribSort(a, b, c, { enum: options.status, type: 'string' }),\n ),\n sortDescFirst: true,\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n const meta = table.options.meta\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('status', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={meta?.options.status.filter((s) => s.scope?.includes(type))}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n />\n )\n },\n })\n }\n\n if (isIncluded('subType')) {\n staticColumns.push({\n id: 'subType',\n accessorKey: 'subType',\n header: () => 'Type',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const { value, id, type } = getValueIdType(row, column.id)\n const fieldId = type === 'folder' ? 'folderType' : 'taskType'\n const meta = table.options.meta\n return (\n <CellWidget\n rowId={id}\n className={clsx('subType', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'string' }}\n options={\n type === 'folder'\n ? meta?.options.folderType\n : type === 'task'\n ? meta?.options.taskType\n : []\n }\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: fieldId, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n />\n )\n },\n })\n }\n\n if (isIncluded('assignees')) {\n staticColumns.push({\n id: 'assignees',\n accessorKey: 'assignees',\n header: () => 'Assignees',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const { value, id, type } = getValueIdType(row, column.id)\n if (type === 'folder')\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value=\"\"\n isPlaceholder\n />\n )\n return (\n <CellWidget\n rowId={id}\n className={clsx('assignees', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={meta?.options.assignee}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n pt={{\n enum: {\n multiSelectClose: value?.length === 0, // close the dropdown on first assignment\n search: true, // enable search at all times\n multipleOverride: false,\n },\n }}\n />\n )\n },\n })\n }\n\n if (isIncluded('tags')) {\n staticColumns.push({\n id: 'tags',\n accessorKey: 'tags',\n header: () => 'Tags',\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const { value, id, type } = getValueIdType(row, column.id)\n return (\n <CellWidget\n rowId={id}\n className={clsx('tags', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: 'list_of_strings' }}\n options={meta?.options.tag}\n isCollapsed={!!row.original.childOnlyMatch}\n onChange={(value) =>\n meta?.updateEntities([{ field: column.id, value, id, type, rowId: row.id }])\n }\n isReadOnly={meta?.readOnly?.includes(column.id)}\n enableCustomValues\n />\n )\n },\n })\n }\n\n const attributeColumns: ColumnDef<TableRow>[] = attribs\n .filter((attrib) => {\n const columnId = 'attrib_' + attrib.name\n // Check if the specific attribute column is excluded\n // or if all built-in attributes are excluded and this is a built-in attribute\n if (excluded?.includes(columnId)) return false\n if (attrib.builtin && excluded?.includes('attrib')) return false\n return true\n })\n .map((attrib) => {\n const attribColumn: ColumnDef<TableRow> = {\n id: 'attrib_' + attrib.name,\n accessorKey: 'attrib.' + attrib.name,\n header: () => attrib.data.title || attrib.name,\n filterFn: 'fuzzy' as FilterFnOption<TableRow>,\n sortingFn: withLoadingStateSort((a, b, c) => attribSort(a, b, c, attrib.data)),\n enableSorting: true,\n enableResizing: true,\n enablePinning: true,\n enableHiding: true,\n cell: ({ row, column, table }) => {\n const meta = table.options.meta\n const columnIdParsed = column.id.replace('attrib_', '')\n const { value, id, type } = getValueIdType(row, columnIdParsed, 'attrib')\n const isInherited = !row.original.ownAttrib.includes(columnIdParsed)\n\n return (\n <CellWidget\n rowId={id}\n className={clsx('attrib', { loading: row.original.isLoading })}\n columnId={column.id}\n value={value}\n attributeData={{ type: attrib.data.type || 'string' }}\n options={attrib.data.enum || []}\n isCollapsed={!!row.original.childOnlyMatch}\n isInherited={isInherited && ['folder', 'task'].includes(type)}\n isReadOnly={\n attrib.readOnly ||\n meta?.readOnly?.some(\n (id) => id === columnIdParsed || (id === 'attrib' && attrib.builtin),\n )\n }\n onChange={(value) =>\n meta?.updateEntities([\n { field: columnIdParsed, value, id, type, isAttrib: true, rowId: row.id },\n ])\n }\n />\n )\n },\n }\n return attribColumn\n })\n\n const allColumns = [...staticColumns, ...attributeColumns]\n\n // Add extra columns if provided\n if (extraColumns) {\n extraColumns.forEach(({ column, position = -1 }) => {\n if (position >= 0 && position < allColumns.length) {\n allColumns.splice(position, 0, column)\n } else {\n allColumns.push(column)\n }\n })\n }\n\n return allColumns\n}\n\nexport default buildTreeTableColumns\n\nexport const getValueIdType = (\n row: Row<TableRow>,\n field: string,\n nestedField?: keyof TableRow,\n): {\n value: any\n id: string\n type: string\n} => ({\n value: nestedField\n ? (row.original[nestedField as keyof TableRow] as any)?.[field]\n : (row.original[field as keyof TableRow] as any),\n id: row.id,\n type: row.original.entityType,\n})\n"],"names":["jsx","_a","value","id"],"mappings":";;;;;;;;;;;;;;;;AAYA,MAAM,uBAAuB,CAAC,WAA2C;AAChE,SAAA,CAAC,MAAM,SAAS,SAAS;AAE9B,QAAI,KAAK,SAAS,cAAc,KAAK,SAAS,WAAW;AAChD,aAAA,KAAK,SAAS,YAAY,IAAI;AAAA,IAAA;AAGvC,WAAO,OAAO,MAAM,MAAM,GAAG,IAAI;AAAA,EACnC;AACF;AAEA,MAAM,WAA2B,CAAC,MAAM,SAAS;AAC/C,QAAM,SAAS,KAAK,SAAS,SAAS,KAAK,SAAS;AACpD,QAAM,SAAS,KAAK,SAAS,SAAS,KAAK,SAAS;AAE7C,SAAA,OAAO,cAAc,MAAM;AACpC;AACA,MAAM,WAA2B,CAAC,MAAM,SAAS;AAC/C,QAAM,SAAS,KAAK,SAAS,QAAQ,KAAK,SAAS;AACnD,QAAM,SAAS,KAAK,SAAS,QAAQ,KAAK,SAAS;AAE5C,SAAA,OAAO,cAAc,MAAM;AACpC;AAIA,MAAM,aAA8B,CAAC,MAAM,MAAM,UAAU,WAAW;AACpE,QAAM,SAAS,aAAa,KAAK,UAAU,QAAQ;AACnD,QAAM,SAAS,aAAa,KAAK,UAAU,QAAQ;AAE/C,MAAA,UAAU,OAAO,MAAM;AACnB,UAAA,SAAS,OAAO,KAAK,UAAU,CAAC,MAAM,EAAE,UAAU,MAAM;AACxD,UAAA,SAAS,OAAO,KAAK,UAAU,CAAC,MAAM,EAAE,UAAU,MAAM;AACvD,WAAA,SAAS,SAAS,IAAI,IAAI;AAAA,EAAA,YACxB,iCAAQ,UAAS,YAAY;AACtC,WAAO,WAAW,SAAS,MAAM,MAAM,QAAQ;AAAA,EAAA,YACtC,iCAAQ,UAAS,WAAW;AAC/B,UAAA,QAAQ,WAAW,OAAO,IAAI;AAC9B,UAAA,QAAQ,WAAW,OAAO,IAAI;AACpC,WAAO,QAAQ;AAAA,EAAA,OACV;AAEL,WAAO,WAAW,aAAa,MAAM,MAAM,QAAQ;AAAA,EAAA;AAEvD;AAqBA,MAAM,wBAAwB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAkC;AAChC,QAAM,gBAAuC,CAAC;AAG9C,QAAM,aAAa,CAAC,OAAgC,EAAC,qCAAU,SAAS;AAGpE,MAAA,WAAW,uBAAuB,GAAG;AACvC,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,cAAc;AAAA,MAEd,QAAQ,MAAMA,kCAAAA,IAAC,oBAAmB,EAAA;AAAA,MAClC,MAAM,MAAMA,kCAAAA,IAAC,eAAc,EAAA;AAAA,MAC3B,MAAM;AAAA,IAAA,CACP;AAAA,EAAA;AAGC,MAAA,WAAW,WAAW,GAAG;AAC3B,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,MAAM,CAAC,EAAE,KAAK,YAAY;AAClB,cAAA,OAAO,MAAM,QAAQ;AACvB,YAAA,CAAC,KAAa,QAAA;AAEhB,eAAAA,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,UAAU,IAAI,SAAS,YAAY,IAAI;AAAA,YACvC,YAAY,IAAI,SAAS;AAAA,YACzB,WAAW,IAAI,SAAS;AAAA,YACxB,MAAM,IAAI,SAAS;AAAA,YACnB,aAAa,6BAAM;AAAA,UAAA;AAAA,QACrB;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGC,MAAA,WAAW,MAAM,GAAG;AACtB,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,WAAW,qBAAqB,gBAAgB,WAAW,QAAQ;AAAA,MACnE,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;AAC1B,cAAA,OAAO,MAAM,QAAQ;AAC3B,cAAM,SAAS,UAAU,IAAI,IAAI,OAAO,EAAE;AAExC,eAAAA,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,IAAI;AAAA,YACJ,WAAW,KAAK,SAAS,IAAI,SAAS,YAAY;AAAA,cAChD,SAAS,IAAI,SAAS;AAAA,cACtB,WAAW;AAAA,YAAA,CACZ;AAAA,YACD,OAAO;AAAA,cACL,aAAa,QAAQ,IAAI,QAAQ,CAAC;AAAA,YACpC;AAAA,YACA,UAAU;AAAA,YAEV,UAAAA,kCAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,IAAI,IAAI;AAAA,gBACR,OAAO,IAAI,SAAS;AAAA,gBACpB,MAAM,IAAI,SAAS;AAAA,gBACnB,MAAM,CAAC,gBAAgB,IAAI,SAAS,OAAO;AAAA,gBAC3C;AAAA,gBACA,MAAM,IAAI,SAAS;AAAA,gBACnB,MAAM,IAAI,SAAS;AAAA,gBACnB,YAAY,IAAI,cAAc;AAAA,gBAC9B,iBAAiB,MAAM,6BAAM,gBAAgB,CAAC,IAAI,EAAE;AAAA,gBACpD,gBAAgB,IAAI,yBAAyB;AAAA,cAAA;AAAA,YAAA;AAAA,UAC/C;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGC,MAAA,WAAW,QAAQ,GAAG;AACxB,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,WAAW;AAAA,QAAqB,CAAC,GAAG,GAAG,MACrC,WAAW,GAAG,GAAG,GAAG,EAAE,MAAM,QAAQ,QAAQ,MAAM,SAAU,CAAA;AAAA,MAC9D;AAAA,MACA,eAAe;AAAA,MACf,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;;AAC1B,cAAA,EAAE,OAAO,IAAI,KAAA,IAAS,eAAe,KAAK,OAAO,EAAE;AACnD,cAAA,OAAO,MAAM,QAAQ;AAGzB,eAAAA,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,WAAW,KAAK,UAAU,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,YAC7D,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,eAAe,EAAE,MAAM,SAAS;AAAA,YAChC,SAAS,6BAAM,QAAQ,OAAO,OAAO,CAAC,MAAA;;AAAM,sBAAAC,MAAA,EAAE,UAAF,gBAAAA,IAAS,SAAS;AAAA;AAAA,YAC9D,aAAa,CAAC,CAAC,IAAI,SAAS;AAAA,YAC5B,UAAU,CAACC,WACT,6BAAM,eAAe,CAAC,EAAE,OAAO,OAAO,IAAI,OAAAA,QAAO,IAAI,MAAM,OAAO,GAAA,CAAI;AAAA,YAExE,aAAY,kCAAM,aAAN,mBAAgB,SAAS,OAAO;AAAA,UAAE;AAAA,QAChD;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGC,MAAA,WAAW,SAAS,GAAG;AACzB,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;;AAC1B,cAAA,EAAE,OAAO,IAAI,KAAA,IAAS,eAAe,KAAK,OAAO,EAAE;AACnD,cAAA,UAAU,SAAS,WAAW,eAAe;AAC7C,cAAA,OAAO,MAAM,QAAQ;AAEzB,eAAAF,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,WAAW,KAAK,WAAW,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,YAC9D,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,eAAe,EAAE,MAAM,SAAS;AAAA,YAChC,SACE,SAAS,WACL,6BAAM,QAAQ,aACd,SAAS,SACT,6BAAM,QAAQ,WACd,CAAC;AAAA,YAEP,aAAa,CAAC,CAAC,IAAI,SAAS;AAAA,YAC5B,UAAU,CAACE,WACT,6BAAM,eAAe,CAAC,EAAE,OAAO,SAAS,OAAAA,QAAO,IAAI,MAAM,OAAO,IAAI,GAAA,CAAI;AAAA,YAE1E,aAAY,kCAAM,aAAN,mBAAgB,SAAS,OAAO;AAAA,UAAE;AAAA,QAChD;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGC,MAAA,WAAW,WAAW,GAAG;AAC3B,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;;AAC1B,cAAA,OAAO,MAAM,QAAQ;AACrB,cAAA,EAAE,OAAO,IAAI,KAAA,IAAS,eAAe,KAAK,OAAO,EAAE;AACzD,YAAI,SAAS;AAET,iBAAAF,kCAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO;AAAA,cACP,WAAW,KAAK,aAAa,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,cAChE,UAAU,OAAO;AAAA,cACjB,OAAM;AAAA,cACN,eAAa;AAAA,YAAA;AAAA,UACf;AAGF,eAAAA,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,WAAW,KAAK,aAAa,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,YAChE,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,eAAe,EAAE,MAAM,kBAAkB;AAAA,YACzC,SAAS,6BAAM,QAAQ;AAAA,YACvB,aAAa,CAAC,CAAC,IAAI,SAAS;AAAA,YAC5B,UAAU,CAACE,WACT,6BAAM,eAAe,CAAC,EAAE,OAAO,OAAO,IAAI,OAAAA,QAAO,IAAI,MAAM,OAAO,IAAI,GAAA,CAAI;AAAA,YAE5E,aAAY,kCAAM,aAAN,mBAAgB,SAAS,OAAO;AAAA,YAC5C,IAAI;AAAA,cACF,MAAM;AAAA,gBACJ,mBAAkB,+BAAO,YAAW;AAAA;AAAA,gBACpC,QAAQ;AAAA;AAAA,gBACR,kBAAkB;AAAA,cAAA;AAAA,YACpB;AAAA,UACF;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGC,MAAA,WAAW,MAAM,GAAG;AACtB,kBAAc,KAAK;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;;AAC1B,cAAA,OAAO,MAAM,QAAQ;AACrB,cAAA,EAAE,OAAO,IAAI,KAAA,IAAS,eAAe,KAAK,OAAO,EAAE;AAEvD,eAAAF,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,WAAW,KAAK,QAAQ,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,YAC3D,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,eAAe,EAAE,MAAM,kBAAkB;AAAA,YACzC,SAAS,6BAAM,QAAQ;AAAA,YACvB,aAAa,CAAC,CAAC,IAAI,SAAS;AAAA,YAC5B,UAAU,CAACE,WACT,6BAAM,eAAe,CAAC,EAAE,OAAO,OAAO,IAAI,OAAAA,QAAO,IAAI,MAAM,OAAO,IAAI,GAAA,CAAI;AAAA,YAE5E,aAAY,kCAAM,aAAN,mBAAgB,SAAS,OAAO;AAAA,YAC5C,oBAAkB;AAAA,UAAA;AAAA,QACpB;AAAA,MAAA;AAAA,IAEJ,CACD;AAAA,EAAA;AAGH,QAAM,mBAA0C,QAC7C,OAAO,CAAC,WAAW;AACZ,UAAA,WAAW,YAAY,OAAO;AAGpC,QAAI,qCAAU,SAAS,UAAkB,QAAA;AACzC,QAAI,OAAO,YAAW,qCAAU,SAAS,WAAkB,QAAA;AACpD,WAAA;AAAA,EAAA,CACR,EACA,IAAI,CAAC,WAAW;AACf,UAAM,eAAoC;AAAA,MACxC,IAAI,YAAY,OAAO;AAAA,MACvB,aAAa,YAAY,OAAO;AAAA,MAChC,QAAQ,MAAM,OAAO,KAAK,SAAS,OAAO;AAAA,MAC1C,UAAU;AAAA,MACV,WAAW,qBAAqB,CAAC,GAAG,GAAG,MAAM,WAAW,GAAG,GAAG,GAAG,OAAO,IAAI,CAAC;AAAA,MAC7E,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,cAAc;AAAA,MACd,MAAM,CAAC,EAAE,KAAK,QAAQ,YAAY;;AAC1B,cAAA,OAAO,MAAM,QAAQ;AAC3B,cAAM,iBAAiB,OAAO,GAAG,QAAQ,WAAW,EAAE;AAChD,cAAA,EAAE,OAAO,IAAI,KAAA,IAAS,eAAe,KAAK,gBAAgB,QAAQ;AACxE,cAAM,cAAc,CAAC,IAAI,SAAS,UAAU,SAAS,cAAc;AAGjE,eAAAF,kCAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,WAAW,KAAK,UAAU,EAAE,SAAS,IAAI,SAAS,WAAW;AAAA,YAC7D,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,eAAe,EAAE,MAAM,OAAO,KAAK,QAAQ,SAAS;AAAA,YACpD,SAAS,OAAO,KAAK,QAAQ,CAAC;AAAA,YAC9B,aAAa,CAAC,CAAC,IAAI,SAAS;AAAA,YAC5B,aAAa,eAAe,CAAC,UAAU,MAAM,EAAE,SAAS,IAAI;AAAA,YAC5D,YACE,OAAO,cACP,kCAAM,aAAN,mBAAgB;AAAA,cACd,CAACG,QAAOA,QAAO,kBAAmBA,QAAO,YAAY,OAAO;AAAA;AAAA,YAGhE,UAAU,CAACD,WACT,6BAAM,eAAe;AAAA,cACnB,EAAE,OAAO,gBAAgB,OAAAA,QAAO,IAAI,MAAM,UAAU,MAAM,OAAO,IAAI,GAAG;AAAA,YACzE;AAAA,UAAA;AAAA,QAEL;AAAA,MAAA;AAAA,IAGN;AACO,WAAA;AAAA,EAAA,CACR;AAEH,QAAM,aAAa,CAAC,GAAG,eAAe,GAAG,gBAAgB;AAGzD,MAAI,cAAc;AAChB,iBAAa,QAAQ,CAAC,EAAE,QAAQ,WAAW,SAAS;AAClD,UAAI,YAAY,KAAK,WAAW,WAAW,QAAQ;AACtC,mBAAA,OAAO,UAAU,GAAG,MAAM;AAAA,MAAA,OAChC;AACL,mBAAW,KAAK,MAAM;AAAA,MAAA;AAAA,IACxB,CACD;AAAA,EAAA;AAGI,SAAA;AACT;AAIO,MAAM,iBAAiB,CAC5B,KACA,OACA,gBAKI;;AAAA;AAAA,IACJ,OAAO,eACF,SAAI,SAAS,WAA6B,MAA1C,mBAAsD,SACtD,IAAI,SAAS,KAAuB;AAAA,IACzC,IAAI,IAAI;AAAA,IACR,MAAM,IAAI,SAAS;AAAA,EACrB;AAAA;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
3
|
const ayonReactComponents = require("@ynput/ayon-react-components");
|
|
4
|
-
const NO_DATE = "
|
|
4
|
+
const NO_DATE = "no-date";
|
|
5
5
|
const clientFilterToQueryFilter = (filters) => {
|
|
6
6
|
if (!filters || filters.length === 0) {
|
|
7
7
|
return {};
|
package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientFilterToQueryFilter.cjs.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\
|
|
1
|
+
{"version":3,"file":"clientFilterToQueryFilter.cjs.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":["getFilterFromId"],"mappings":";;;AAEA,MAAM,UAAU;AAYH,MAAA,4BAA4B,CAAC,YAA2C;AAEnF,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,CAAC;AAAA,EAAA;AAIV,QAAM,aAA+C,QAClD,OAAO,CAAC,MAAM;;AAAA,YAAC,GAAC,OAAE,WAAF,mBAAU;AAAA,GAAM,EAChC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,MAAM,CAAC,EACpC,OAAO,CAAC,MAAM,EAAE,OAAO,WAAW,EAClC,QAAQ,CAAC,WAAW,yBAAyB,MAAM,CAAC;AAGhD,SAAA;AAAA,IACL;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAGA,MAAM,2BAA2B,CAAC,WAA2C;;AAErE,QAAA,MAAMA,oBAAAA,gBAAgB,OAAO,EAAE;AAGjC,MAAA;AAGJ,QAAM,eACJ,MAAM,QAAQ,OAAO,MAAM,OAAK,YAAO,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,MAA7B,mBAAgC,SAAS;AAC3E,QAAM,aACJ,MAAM,QAAQ,OAAO,MAAM,OAAK,YAAO,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,MAA7B,mBAAgC,SAAS;AAE3E,MAAI,OAAO,UAAU,OAAO,OAAO,SAAS,GAAG;AAC7C,QAAI,OAAO,cAAc;AAEvB,cAAQ,mBAAmB,OAAO,OAAO,CAAC,EAAE,IAAI,OAAO,IAAI;AAAA,IAAA,OACtD;AAEG,cAAA,OAAO,OAAO,IAAI,CAAC,MAAM,mBAAmB,EAAE,IAAI,OAAO,IAAI,CAAC;AAAA,IAAA;AAAA,EACxE;AAIF,QAAM,gBACJ,YAAO,SAAP,mBAAa,WAAW,gBAAe,IAAI,SAAS,MAAM,KAAK,IAAI,SAAS,WAAW;AACnF,QAAA,cAAc,OAAO,SAAS;AAC9B,QAAA,iBAAiB,OAAO,SAAS;AAGvC,MAAI,WAAuC;AAG3C,MAAI,UAAU,QAAW;AACZ,eAAA,OAAO,WAAW,YAAY;AAClC,WAAA,EAAE,KAAK,SAAS;AAAA,EAAA;AAIzB,MAAI,cAAc;AAER,YAAA,cAAc,CAAA,IAAK;AAC3B,eAAW,cACP,OAAO,WACL,OACA,OACF,OAAO,WACP,WACA;AAAA,aACK,YAAY;AAEb,YAAA,cAAc,CAAA,IAAK;AAC3B,eAAW,cACP,OAAO,WACL,OACA,OACF,OAAO,WACP,YACA;AAAA,aACK,aAAa;AACtB,QAAI,OAAO,UAAU;AACR,iBAAA,OAAO,aAAa,QAAQ,gBAAgB;AAAA,IAAA,OAClD;AACM,iBAAA,OAAO,aAAa,QAAQ,gBAAgB;AAAA,IAAA;AAAA,aAEhD,aAAa;AAEtB,QAAI,OAAO,UAAU,OAAO,OAAO,SAAS,GAAG;AAEvC,YAAA,iBAAmC,OAAO,OAAO;AAAA,QACrD,CAAC,gBAAgC;AAC/B,gBAAM,aAA+B,CAAC;AACtC,gBAAM,aAAa,YAAY;AAG3B,eAAA,yCAAa,QAAO,WAAa,yCAAa,GAAG,QAAO,SAAS;AACnE,uBAAW,KAAK;AAAA,cACd;AAAA,cACA,UAAU,OAAO,WAAW,QAAQ;AAAA,cACpC,OAAO,WAAW,CAAC,EAAE;AAAA,YAAA,CACtB;AAAA,UAAA;AAIC,eAAA,yCAAa,QAAO,WAAa,yCAAa,GAAG,QAAO,SAAS;AACnE,uBAAW,KAAK;AAAA,cACd;AAAA,cACA,UAAU,OAAO,WAAW,QAAQ;AAAA,cACpC,OAAO,WAAW,CAAC,EAAE;AAAA,YAAA,CACtB;AAAA,UAAA;AAGI,iBAAA;AAAA,QAAA;AAAA,MAEX;AAGI,UAAA,eAAe,SAAS,GAAG;AAEtB,eAAA;AAAA,UACL,YAAY;AAAA,UACZ,UAAU,OAAO,WAAW,OAAO;AAAA,QACrC;AAAA,MAAA;AAAA,IACF;AAIS,eAAA,OAAO,WAAW,OAAO;AAAA,aAC3B,gBAAgB;AACd,eAAA,OAAO,WAAW,OAAO;AAAA,EAAA,OAC/B;AAEM,eAAA,OAAO,WAAW,UAAU;AAAA,EAAA;AAGlC,SAAA,EAAE,KAAK,OAAO,SAAS;AAChC;AAGA,MAAM,qBAAqB,CAAC,OAAe,SAA6C;AAClF,MAAA,CAAC,KAAa,QAAA;AAElB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACI,aAAA,SAAS,OAAO,EAAE;AAAA,IAC3B,KAAK;AACH,aAAO,WAAW,KAAK;AAAA,IACzB,KAAK;AACI,aAAA,MAAM,kBAAkB;AAAA,IACjC;AACS,aAAA;AAAA,EAAA;AAEb;;;"}
|
package/dist/shared/src/containers/ProjectTreeTable/utils/clientFilterToQueryFilter.es.js.map
CHANGED
|
@@ -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\
|
|
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[]
|
|
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[]
|
|
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
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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;"}
|
|
@@ -8,7 +8,7 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
8
8
|
const [results, setResults] = React.useState(
|
|
9
9
|
() => initializeResults(moduleSpecs)
|
|
10
10
|
);
|
|
11
|
-
const [isLoading, setIsLoading] = React.useState(
|
|
11
|
+
const [isLoading, setIsLoading] = React.useState(modules.length > 0 && !skip);
|
|
12
12
|
React.useEffect(() => {
|
|
13
13
|
if (skip) return;
|
|
14
14
|
processedModules.current = /* @__PURE__ */ new Set();
|
|
@@ -26,7 +26,10 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
React.useEffect(() => {
|
|
29
|
-
if (skip)
|
|
29
|
+
if (skip) {
|
|
30
|
+
setIsLoading(false);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
30
33
|
console.log("loading modules");
|
|
31
34
|
const promises = [];
|
|
32
35
|
moduleSpecs.forEach((spec, index) => {
|
|
@@ -63,6 +66,10 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
63
66
|
}
|
|
64
67
|
promises.push(loadModule(remote, module2, addon, fallback, minVersion));
|
|
65
68
|
});
|
|
69
|
+
if (!promises.length) {
|
|
70
|
+
setIsLoading(false);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
66
73
|
setIsLoading(true);
|
|
67
74
|
Promise.all(promises).then(() => {
|
|
68
75
|
setIsLoading(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLoadModules.cjs.js","sources":["../../../../src/hooks/useLoadModules.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useLoadModules.cjs.js","sources":["../../../../src/hooks/useLoadModules.ts"],"sourcesContent":["import { loadRemote } from '@module-federation/enhanced/runtime'\nimport { useEffect, useRef, useState } from 'react'\nimport semver from 'semver'\nimport { FrontendModuleListItem } from '@shared/api'\n\nexport interface ModuleSpec<T> {\n addon: string\n remote: string\n module: string\n fallback?: T\n debug?: boolean\n minVersion?: string\n}\n\ntype ModuleResult<T> = [\n T,\n {\n isLoaded: boolean\n addon: string\n remote: string\n module: string\n minVersion?: string\n outdated?: {\n current: string\n required: string\n }\n },\n]\n\nexport const useLoadModules = <T extends any[]>(\n moduleSpecs: ModuleSpec<T[number]>[],\n modules: FrontendModuleListItem[],\n skip: boolean,\n): { modules: ModuleResult<T[number]>[]; isLoading: boolean } => {\n // Use a ref to track which modules have been processed\n const processedModules = useRef<Set<string>>(new Set())\n\n // Initialize results state\n const [results, setResults] = useState<ModuleResult<T[number]>[]>(() =>\n initializeResults(moduleSpecs),\n )\n const [isLoading, setIsLoading] = useState(modules.length > 0 && !skip)\n\n // Reset and reinitialize when moduleSpecs change\n useEffect(() => {\n if (skip) return\n // Reset the processed modules tracker\n processedModules.current = new Set()\n\n // Initialize results with proper structure\n setResults(initializeResults(moduleSpecs))\n }, [JSON.stringify(moduleSpecs), skip])\n\n const loadModule = async (\n remote: string,\n module: string,\n addon: string,\n fallback: T[number] | undefined,\n minVersion?: string,\n ) => {\n try {\n const result = await loadRemote<{ default: T[number] }>(`${remote}/${module}`, {\n from: 'runtime',\n })\n updateResultWithLoaded(addon, remote, module, result?.default || fallback, minVersion)\n } catch (error) {\n console.error('Error loading remote module', remote, module, error)\n throw error\n }\n }\n\n // Load modules when remotes are initialized\n useEffect(() => {\n if (skip) {\n setIsLoading(false)\n return\n }\n\n console.log('loading modules')\n\n const promises: Promise<void>[] = []\n moduleSpecs.forEach((spec, index) => {\n const { addon, remote, module, fallback, minVersion } = spec\n\n if (!addon || !remote || !module) return\n\n // Create a unique key for this module\n const moduleKey = `${addon}/${remote}/${module}`\n\n // Skip if already processed\n if (processedModules.current.has(moduleKey)) return\n\n // Check if this module is already loaded in our results\n if (results[index]?.[1]?.isLoaded) {\n processedModules.current.add(moduleKey)\n return\n }\n\n // Mark as processed\n processedModules.current.add(moduleKey)\n\n const addonInfo = modules.find((m) => m.addonName === addon)\n\n // Handle missing addon\n if (!addonInfo) {\n console.log('Addon not found', { addon, remote, module })\n return\n }\n\n // Check version requirements\n if (minVersion && !semver.gte(addonInfo.addonVersion, minVersion)) {\n updateResultWithOutdated(\n index,\n addon,\n remote,\n module,\n fallback,\n minVersion,\n addonInfo.addonVersion,\n )\n return\n }\n\n // Check if module exists\n if (!addonInfo.modules[remote]) {\n console.log('Module not found', { addon, remote, module })\n return\n }\n\n promises.push(loadModule(remote, module, addon, fallback, minVersion))\n })\n\n if (!promises.length) {\n setIsLoading(false)\n return\n }\n\n // Wait for all promises to resolve\n setIsLoading(true)\n Promise.all(promises)\n .then(() => {\n // all modules loaded\n setIsLoading(false)\n })\n .catch((error) => {\n console.error('Error loading modules', error)\n setIsLoading(false)\n })\n }, [skip, modules, JSON.stringify(moduleSpecs)])\n\n // Helper function to initialize results\n function initializeResults(specs: ModuleSpec<T[number]>[]): ModuleResult<T[number]>[] {\n return specs.map(\n ({ addon = '', remote = '', module = '', fallback, minVersion }): ModuleResult<T[number]> => [\n fallback as T[number],\n {\n isLoaded: false,\n addon,\n remote,\n module,\n minVersion,\n outdated: undefined,\n },\n ],\n )\n }\n\n // Helper to update a result with outdated status\n function updateResultWithOutdated(\n index: number,\n addon: string,\n remote: string,\n module: string,\n fallback: T[number] | undefined,\n requiredVersion: string,\n currentVersion: string,\n ) {\n setResults((prev) => {\n const updated = [...prev]\n if (index >= 0 && index < updated.length) {\n updated[index] = [\n fallback,\n {\n isLoaded: false,\n addon,\n remote,\n module,\n minVersion: requiredVersion,\n outdated: {\n current: currentVersion,\n required: requiredVersion,\n },\n },\n ]\n }\n return updated\n })\n }\n\n // Helper to update a result when module is loaded\n function updateResultWithLoaded(\n addon: string,\n remote: string,\n module: string,\n loadedModule: T[number] | undefined,\n minVersion?: string,\n ) {\n setResults((prev) => {\n const updated = [...prev]\n // Find the corresponding module spec\n const index = moduleSpecs.findIndex(\n (spec) => spec.addon === addon && spec.remote === remote && spec.module === module,\n )\n\n if (index >= 0 && index < updated.length) {\n updated[index] = [\n loadedModule,\n {\n isLoaded: true,\n addon,\n remote,\n module,\n minVersion,\n outdated: undefined,\n },\n ]\n }\n return updated\n })\n }\n\n return { modules: results, isLoading }\n}\n"],"names":["useRef","useState","useEffect","module","loadRemote"],"mappings":";;;;;AA6BO,MAAM,iBAAiB,CAC5B,aACA,SACA,SAC+D;AAE/D,QAAM,mBAAmBA,MAAAA,OAAwB,oBAAA,KAAK;AAGhD,QAAA,CAAC,SAAS,UAAU,IAAIC,MAAA;AAAA,IAAoC,MAChE,kBAAkB,WAAW;AAAA,EAC/B;AACM,QAAA,CAAC,WAAW,YAAY,IAAIA,MAAAA,SAAS,QAAQ,SAAS,KAAK,CAAC,IAAI;AAGtEC,QAAAA,UAAU,MAAM;AACd,QAAI,KAAM;AAEO,qBAAA,8BAAc,IAAI;AAGxB,eAAA,kBAAkB,WAAW,CAAC;AAAA,KACxC,CAAC,KAAK,UAAU,WAAW,GAAG,IAAI,CAAC;AAEtC,QAAM,aAAa,OACjB,QACAC,SACA,OACA,UACA,eACG;AACC,QAAA;AACF,YAAM,SAAS,MAAMC,kCAAmC,GAAG,MAAM,IAAID,OAAM,IAAI;AAAA,QAC7E,MAAM;AAAA,MAAA,CACP;AACD,6BAAuB,OAAO,QAAQA,UAAQ,iCAAQ,YAAW,UAAU,UAAU;AAAA,aAC9E,OAAO;AACd,cAAQ,MAAM,+BAA+B,QAAQA,SAAQ,KAAK;AAC5D,YAAA;AAAA,IAAA;AAAA,EAEV;AAGAD,QAAAA,UAAU,MAAM;AACd,QAAI,MAAM;AACR,mBAAa,KAAK;AAClB;AAAA,IAAA;AAGF,YAAQ,IAAI,iBAAiB;AAE7B,UAAM,WAA4B,CAAC;AACvB,gBAAA,QAAQ,CAAC,MAAM,UAAU;;AACnC,YAAM,EAAE,OAAO,QAAQ,QAAAC,SAAQ,UAAU,eAAe;AAExD,UAAI,CAAC,SAAS,CAAC,UAAU,CAACA,QAAQ;AAGlC,YAAM,YAAY,GAAG,KAAK,IAAI,MAAM,IAAIA,OAAM;AAG9C,UAAI,iBAAiB,QAAQ,IAAI,SAAS,EAAG;AAG7C,WAAI,mBAAQ,KAAK,MAAb,mBAAiB,OAAjB,mBAAqB,UAAU;AAChB,yBAAA,QAAQ,IAAI,SAAS;AACtC;AAAA,MAAA;AAIe,uBAAA,QAAQ,IAAI,SAAS;AAEtC,YAAM,YAAY,QAAQ,KAAK,CAAC,MAAM,EAAE,cAAc,KAAK;AAG3D,UAAI,CAAC,WAAW;AACd,gBAAQ,IAAI,mBAAmB,EAAE,OAAO,QAAQ,QAAAA,SAAQ;AACxD;AAAA,MAAA;AAIF,UAAI,cAAc,CAAC,OAAO,IAAI,UAAU,cAAc,UAAU,GAAG;AACjE;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACAA;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QACZ;AACA;AAAA,MAAA;AAIF,UAAI,CAAC,UAAU,QAAQ,MAAM,GAAG;AAC9B,gBAAQ,IAAI,oBAAoB,EAAE,OAAO,QAAQ,QAAAA,SAAQ;AACzD;AAAA,MAAA;AAGF,eAAS,KAAK,WAAW,QAAQA,SAAQ,OAAO,UAAU,UAAU,CAAC;AAAA,IAAA,CACtE;AAEG,QAAA,CAAC,SAAS,QAAQ;AACpB,mBAAa,KAAK;AAClB;AAAA,IAAA;AAIF,iBAAa,IAAI;AACjB,YAAQ,IAAI,QAAQ,EACjB,KAAK,MAAM;AAEV,mBAAa,KAAK;AAAA,IAAA,CACnB,EACA,MAAM,CAAC,UAAU;AACR,cAAA,MAAM,yBAAyB,KAAK;AAC5C,mBAAa,KAAK;AAAA,IAAA,CACnB;AAAA,EAAA,GACF,CAAC,MAAM,SAAS,KAAK,UAAU,WAAW,CAAC,CAAC;AAG/C,WAAS,kBAAkB,OAA2D;AACpF,WAAO,MAAM;AAAA,MACX,CAAC,EAAE,QAAQ,IAAI,SAAS,IAAI,QAAAA,UAAS,IAAI,UAAU,iBAA0C;AAAA,QAC3F;AAAA,QACA;AAAA,UACE,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,QAAAA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QAAA;AAAA,MACZ;AAAA,IAEJ;AAAA,EAAA;AAIF,WAAS,yBACP,OACA,OACA,QACAA,SACA,UACA,iBACA,gBACA;AACA,eAAW,CAAC,SAAS;AACb,YAAA,UAAU,CAAC,GAAG,IAAI;AACxB,UAAI,SAAS,KAAK,QAAQ,QAAQ,QAAQ;AACxC,gBAAQ,KAAK,IAAI;AAAA,UACf;AAAA,UACA;AAAA,YACE,UAAU;AAAA,YACV;AAAA,YACA;AAAA,YACA,QAAAA;AAAA,YACA,YAAY;AAAA,YACZ,UAAU;AAAA,cACR,SAAS;AAAA,cACT,UAAU;AAAA,YAAA;AAAA,UACZ;AAAA,QAEJ;AAAA,MAAA;AAEK,aAAA;AAAA,IAAA,CACR;AAAA,EAAA;AAIH,WAAS,uBACP,OACA,QACAA,SACA,cACA,YACA;AACA,eAAW,CAAC,SAAS;AACb,YAAA,UAAU,CAAC,GAAG,IAAI;AAExB,YAAM,QAAQ,YAAY;AAAA,QACxB,CAAC,SAAS,KAAK,UAAU,SAAS,KAAK,WAAW,UAAU,KAAK,WAAWA;AAAA,MAC9E;AAEA,UAAI,SAAS,KAAK,QAAQ,QAAQ,QAAQ;AACxC,gBAAQ,KAAK,IAAI;AAAA,UACf;AAAA,UACA;AAAA,YACE,UAAU;AAAA,YACV;AAAA,YACA;AAAA,YACA,QAAAA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,UAAA;AAAA,QAEd;AAAA,MAAA;AAEK,aAAA;AAAA,IAAA,CACR;AAAA,EAAA;AAGI,SAAA,EAAE,SAAS,SAAS,UAAU;AACvC;;"}
|
|
@@ -6,7 +6,7 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
6
6
|
const [results, setResults] = useState(
|
|
7
7
|
() => initializeResults(moduleSpecs)
|
|
8
8
|
);
|
|
9
|
-
const [isLoading, setIsLoading] = useState(
|
|
9
|
+
const [isLoading, setIsLoading] = useState(modules.length > 0 && !skip);
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
if (skip) return;
|
|
12
12
|
processedModules.current = /* @__PURE__ */ new Set();
|
|
@@ -24,7 +24,10 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
useEffect(() => {
|
|
27
|
-
if (skip)
|
|
27
|
+
if (skip) {
|
|
28
|
+
setIsLoading(false);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
28
31
|
console.log("loading modules");
|
|
29
32
|
const promises = [];
|
|
30
33
|
moduleSpecs.forEach((spec, index) => {
|
|
@@ -61,6 +64,10 @@ const useLoadModules = (moduleSpecs, modules, skip) => {
|
|
|
61
64
|
}
|
|
62
65
|
promises.push(loadModule(remote, module, addon, fallback, minVersion));
|
|
63
66
|
});
|
|
67
|
+
if (!promises.length) {
|
|
68
|
+
setIsLoading(false);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
64
71
|
setIsLoading(true);
|
|
65
72
|
Promise.all(promises).then(() => {
|
|
66
73
|
setIsLoading(false);
|