@ynput/ayon-frontend-shared 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/ProjectTreeTable.cjs.js +16 -0
  2. package/dist/ProjectTreeTable.cjs.js.map +1 -1
  3. package/dist/ProjectTreeTable.es.js +16 -0
  4. package/dist/ProjectTreeTable.es.js.map +1 -1
  5. package/dist/_virtual/index.cjs10.js +3 -5
  6. package/dist/_virtual/index.cjs10.js.map +1 -1
  7. package/dist/_virtual/index.cjs4.js +4 -4
  8. package/dist/_virtual/index.cjs5.js +2 -2
  9. package/dist/_virtual/index.cjs6.js +4 -4
  10. package/dist/_virtual/index.cjs7.js +5 -3
  11. package/dist/_virtual/index.cjs7.js.map +1 -1
  12. package/dist/_virtual/index.cjs8.js +4 -4
  13. package/dist/_virtual/index.cjs9.js +4 -4
  14. package/dist/_virtual/index.es10.js +2 -5
  15. package/dist/_virtual/index.es10.js.map +1 -1
  16. package/dist/_virtual/index.es4.js +4 -4
  17. package/dist/_virtual/index.es5.js +2 -2
  18. package/dist/_virtual/index.es6.js +4 -4
  19. package/dist/_virtual/index.es7.js +5 -2
  20. package/dist/_virtual/index.es7.js.map +1 -1
  21. package/dist/_virtual/index.es8.js +4 -4
  22. package/dist/_virtual/index.es9.js +4 -4
  23. package/dist/node_modules/match-sorter/dist/match-sorter.esm.cjs.js +1 -1
  24. package/dist/node_modules/match-sorter/dist/match-sorter.esm.es.js +1 -1
  25. package/dist/node_modules/parse-numeric-range/index.cjs.js +1 -1
  26. package/dist/node_modules/parse-numeric-range/index.es.js +1 -1
  27. package/dist/node_modules/rehype/node_modules/unified/lib/index.cjs.js +2 -2
  28. package/dist/node_modules/rehype/node_modules/unified/lib/index.es.js +2 -2
  29. package/dist/node_modules/rehype-parse/lib/index.cjs.js +1 -1
  30. package/dist/node_modules/rehype-parse/lib/index.es.js +1 -1
  31. package/dist/node_modules/rehype-prism-plus/dist/index.es.cjs.js +1 -1
  32. package/dist/node_modules/rehype-prism-plus/dist/index.es.es.js +1 -1
  33. package/dist/node_modules/remove-accents/index.cjs.js +1 -1
  34. package/dist/node_modules/remove-accents/index.es.js +1 -1
  35. package/dist/node_modules/vfile/lib/index.cjs.js +1 -1
  36. package/dist/node_modules/vfile/lib/index.es.js +1 -1
  37. package/dist/shared/src/api/generated/actions.cjs.js.map +1 -1
  38. package/dist/shared/src/api/generated/actions.es.js.map +1 -1
  39. package/dist/shared/src/components/AttributeEditor/AttributeEditor.cjs.js +1 -1
  40. package/dist/shared/src/components/AttributeEditor/AttributeEditor.cjs.js.map +1 -1
  41. package/dist/shared/src/components/AttributeEditor/AttributeEditor.es.js +1 -1
  42. package/dist/shared/src/components/AttributeEditor/AttributeEditor.es.js.map +1 -1
  43. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js +1 -0
  44. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.cjs.js.map +1 -1
  45. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js +1 -0
  46. package/dist/shared/src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.es.js.map +1 -1
  47. package/dist/shared/src/containers/Feed/context/FeedContext.cjs.js +2 -2
  48. package/dist/shared/src/containers/Feed/context/FeedContext.cjs.js.map +1 -1
  49. package/dist/shared/src/containers/Feed/context/FeedContext.es.js +2 -2
  50. package/dist/shared/src/containers/Feed/context/FeedContext.es.js.map +1 -1
  51. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js +1 -7
  52. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.cjs.js.map +1 -1
  53. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js +1 -7
  54. package/dist/shared/src/containers/ProjectTreeTable/ProjectTreeTable.es.js.map +1 -1
  55. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js +0 -1
  56. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js.map +1 -1
  57. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js +0 -1
  58. package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js.map +1 -1
  59. package/dist/shared/src/hooks/useLoadModules.cjs.js +9 -2
  60. package/dist/shared/src/hooks/useLoadModules.cjs.js.map +1 -1
  61. package/dist/shared/src/hooks/useLoadModules.es.js +9 -2
  62. package/dist/shared/src/hooks/useLoadModules.es.js.map +1 -1
  63. package/dist/shared/src/util/confirmDelete.cjs.js.map +1 -1
  64. package/dist/shared/src/util/confirmDelete.es.js.map +1 -1
  65. package/dist/types/api/generated/actions.d.ts +1 -1
  66. package/dist/types/containers/ProjectTreeTable/index.d.ts +1 -0
  67. package/dist/types/util/confirmDelete.d.ts +1 -2
  68. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AttributeEditor.cjs.js","sources":["../../../../../src/components/AttributeEditor/AttributeEditor.tsx"],"sourcesContent":["import { FC, useEffect, useState } from 'react'\nimport {\n SaveButton,\n Spacer,\n FormLayout,\n FormRow,\n InputText,\n InputSwitch,\n LockedInput,\n Dropdown,\n Dialog,\n Button,\n} from '@ynput/ayon-react-components'\nimport { camelCase, upperFirst } from 'lodash'\nimport { MinMaxField } from './components'\nimport { EnumEditor } from '@shared/components/EnumEditor'\nimport { AttributeData, AttributeModel, AttributeEnumItem } from '@shared/api'\n\nconst SCOPE_OPTIONS = [\n { value: 'project', label: 'Project' },\n { value: 'folder', label: 'Folder' },\n { value: 'task', label: 'Task' },\n { value: 'product', label: 'Product' },\n { value: 'version', label: 'Version' },\n { value: 'representation', label: 'Representation' },\n { value: 'user', label: 'User' },\n]\n\n// Define types for constants\ninterface GlobalFieldEntry {\n value: keyof AttributeData\n scope: (AttributeModel['scope'] | '')[] | null\n}\n\nconst GLOBAL_FIELDS: GlobalFieldEntry[] = [\n { value: 'description', scope: null },\n { value: 'example', scope: null },\n // @ts-expect-error - project is not a scope?\n { value: 'default', scope: ['project'] },\n { value: 'inherit', scope: null },\n]\n\ninterface TypeOptionDef {\n value: AttributeData['type']\n label: string\n fields: (keyof AttributeData)[]\n exclude?: (keyof AttributeData)[]\n}\n\ninterface TypeOptionsMap {\n [key: string]: TypeOptionDef\n}\n\nconst TYPE_OPTIONS: TypeOptionsMap = {\n string: {\n value: 'string',\n label: 'String',\n fields: ['minLength', 'maxLength', 'enum', 'regex'],\n },\n integer: {\n value: 'integer',\n label: 'Integer',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n float: {\n value: 'float',\n label: 'Decimal number',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n list_of_strings: {\n value: 'list_of_strings',\n label: 'List Of Strings',\n fields: ['minItems', 'maxItems', 'enum'],\n },\n boolean: {\n value: 'boolean',\n label: 'Boolean',\n fields: [],\n exclude: ['example'],\n },\n}\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type AttributeForm = PartialBy<AttributeModel, 'scope' | 'position'>\ntype Excludes = (keyof Omit<AttributeModel, 'data'> | keyof AttributeData)[]\n\nconst initFormData: AttributeForm = {\n name: '',\n scope: ['folder', 'task'],\n builtin: false,\n position: 0,\n data: {\n type: 'string',\n title: '',\n description: '',\n example: '',\n default: undefined,\n enum: [],\n minLength: undefined,\n maxLength: undefined,\n regex: '',\n minItems: undefined,\n maxItems: undefined,\n ge: undefined,\n gt: undefined,\n le: undefined,\n lt: undefined,\n },\n}\n\n// build the form data based on excludes and to update any data\nconst buildInitFormData = (excludes: Excludes, data?: Partial<AttributeForm>) => {\n // Create a deep clone of init form data\n const formData = JSON.parse(JSON.stringify(initFormData)) as AttributeForm\n\n // Filter out top-level excludes if not in required\n const required = ['name']\n Object.keys(formData).forEach((key) => {\n if (\n !required.includes(key) &&\n excludes.includes(key as keyof Omit<AttributeModel, 'data'>) &&\n key !== 'data'\n ) {\n delete formData[key as keyof AttributeForm]\n }\n })\n\n // Filter out data field excludes if not in in required\n const requiredData = ['title']\n if (formData.data) {\n Object.keys(formData.data).forEach((key) => {\n if (!requiredData.includes(key) && excludes.includes(key as keyof AttributeData)) {\n delete formData.data[key as keyof AttributeData]\n }\n })\n }\n\n // Merge with provided data if any\n if (data) {\n // Merge top-level fields\n Object.keys(data).forEach((key) => {\n const typedKey = key as keyof AttributeForm\n if (typedKey !== 'data' && excludes.includes(typedKey)) return\n\n if (typedKey === 'data' && data.data && formData.data) {\n // Deep merge of data fields\n formData.data = { ...formData.data, ...data.data }\n } else if (data[typedKey] !== undefined) {\n // @ts-ignore - We know these properties exist\n formData[typedKey] = data[typedKey]\n }\n })\n }\n\n return formData\n}\n\nexport interface AttributeEditorProps {\n attribute: AttributeForm | null\n existingNames: string[]\n error?: string\n isUpdating?: boolean\n excludes?: Excludes\n onHide: () => void\n onEdit: (attribute: AttributeForm) => void\n onDelete?: () => void\n}\n\nexport const AttributeEditor: FC<AttributeEditorProps> = ({\n attribute,\n existingNames,\n error = '',\n isUpdating,\n excludes = [],\n onHide,\n onEdit,\n onDelete,\n}) => {\n const initForm = buildInitFormData(excludes, { position: existingNames.length })\n const [formData, setFormData] = useState<AttributeForm | null>(attribute || initForm)\n\n useEffect(() => {\n if (!!attribute) setFormData(attribute)\n }, [attribute])\n\n const isNew = !attribute\n\n // const setTopLevelData = (key: string, value: string) => {\n const setTopLevelData = <K extends keyof Omit<AttributeModel, 'data'>>(\n key: K,\n value: AttributeModel[K],\n ) => {\n setFormData((d) => {\n if (!d) {\n return d\n }\n return { ...d, [key]: value }\n })\n }\n\n // const setData = (key, value) => {\n const setData = <K extends keyof AttributeData>(key: K, value: AttributeData[K]) => {\n setFormData((d) => {\n // Add a check for d and d.data\n if (!d || !d.data) {\n return d\n }\n const dt = { ...d.data, [key]: value }\n return { ...d, data: dt }\n })\n }\n\n let internalError = ''\n if (formData) {\n if (isNew) {\n if (existingNames.includes(formData.name)) internalError = 'This attribute already exists'\n else if (!formData.name.match('^[a-zA-Z_]{2,20}$')) internalError = 'Invalid attribute name'\n } // name validation\n }\n\n const handleSubmit = () => {\n if (formData) {\n onEdit(formData)\n }\n }\n\n const footer = (\n <div style={{ display: 'flex', width: '100%', flexDirection: 'row' }}>\n {onDelete && attribute && (\n <Button\n variant=\"danger\"\n label={'Delete attribute'}\n icon={'delete'}\n disabled={isUpdating}\n onClick={onDelete}\n />\n )}\n <Spacer />\n <SaveButton\n label={isNew ? 'Create Attribute' : 'Save Attribute'}\n icon={'check'}\n disabled={!!internalError || !formData}\n active={!internalError && !!formData}\n saving={isUpdating}\n onClick={handleSubmit}\n />\n </div>\n )\n\n let dataFields: (keyof AttributeData)[] = []\n\n // add global fields, only if scope are null (all) or the scope is included\n GLOBAL_FIELDS.forEach((globalField) => {\n // @ts-expect-error - project scope will never be found here?\n if (!globalField?.scope || globalField?.scope?.some((s) => formData?.scope?.includes(s))) {\n dataFields.push(globalField.value)\n }\n })\n\n if (formData?.data.type && TYPE_OPTIONS[formData.data.type]) {\n const typeOpt = TYPE_OPTIONS[formData.data.type]\n dataFields = [...dataFields, ...typeOpt.fields].filter((f) => !typeOpt.exclude?.includes(f))\n }\n\n type CustomFieldRenderer = (value: any, onChange: (newValue: any) => void) => JSX.Element | null\n const customFields: {\n enum: CustomFieldRenderer\n inherit: CustomFieldRenderer\n booleanDefault: CustomFieldRenderer\n } = {\n enum: (value = [], onChange) => (\n <EnumEditor\n values={value as AttributeEnumItem[]}\n onChange={(val) => {\n onChange(val)\n }}\n />\n ),\n inherit: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n booleanDefault: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n }\n\n const handleTitleChange = (e: React.ChangeEvent) => {\n const v = (e.target as HTMLInputElement).value\n setData('title', v)\n\n if (isNew) {\n setTopLevelData('name', camelCase(v))\n }\n }\n\n return (\n <Dialog\n header={formData?.data?.title || formData?.name || 'New attribute'}\n footer={footer}\n onClose={onHide}\n isOpen={true}\n style={{ width: 700, zIndex: 999 }}\n size=\"full\"\n onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n handleSubmit()\n }\n }}\n >\n {formData && (\n <FormLayout>\n {!excludes.includes('title') && (\n <FormRow label={'Title'} key={'title'}>\n <InputText value={formData?.data['title']} onChange={handleTitleChange} autoFocus />\n </FormRow>\n )}\n {!excludes.includes('name') && (\n <FormRow label={'Name'} key={'name'}>\n <LockedInput\n value={formData.name}\n disabled={!isNew}\n onSubmit={(v) => setTopLevelData('name', v)}\n label=\"name\"\n />\n </FormRow>\n )}\n {!excludes.includes('scope') && (\n <FormRow label=\"Scope\">\n <Dropdown\n options={SCOPE_OPTIONS}\n disabled={formData.builtin}\n value={formData.scope || []}\n onChange={(v) => setTopLevelData('scope', v as AttributeModel['scope'])}\n multiSelect\n widthExpand\n />\n </FormRow>\n )}\n {!excludes.includes('type') && (\n <FormRow label=\"Type\">\n <Dropdown\n value={[formData?.data?.type]}\n disabled={formData.builtin}\n options={Object.values(TYPE_OPTIONS)}\n onChange={(v) => setData('type', v[0] as AttributeData['type'])}\n minSelected={1}\n widthExpand\n />\n </FormRow>\n )}\n {dataFields.map((field) => {\n // skip if field is excluded\n if (excludes.includes(field)) return null\n\n let fieldComp = null\n let fieldLabel = upperFirst(field)\n\n if (field === 'enum' || field === 'inherit') {\n const renderer = customFields[field as 'enum' | 'inherit']\n fieldComp = renderer(formData?.data[field], (value) => setData(field, value))\n } else if (field === 'default' && formData?.data?.type === 'boolean') {\n fieldComp = customFields['booleanDefault'](\n formData?.data[field] as boolean,\n (value) => setData(field, value as AttributeData['default']),\n )\n } else if (['ge', 'gt', 'le', 'lt'].includes(field)) {\n // ignore gt and lt\n if (['gt', 'lt'].includes(field)) return null\n fieldComp = (\n <MinMaxField\n value={formData?.data}\n isMin={field === 'ge'}\n isFloat={formData?.data?.type === 'float'}\n onChange={(v) => {\n const geValue = v.ge !== undefined ? Number(v.ge) : undefined\n const leValue = v.le !== undefined ? Number(v.le) : undefined\n\n if (\n // @ts-expect-error\n (v.ge !== undefined && isNaN(geValue)) ||\n // @ts-expect-error\n (v.le !== undefined && isNaN(leValue))\n ) {\n // Do not update the form if the value is not a valid number\n return\n }\n\n setFormData((d) => {\n if (!d || !d.data) return d\n const dt = { ...d.data, ...v }\n return { ...d, data: dt }\n })\n }}\n />\n )\n\n // rewrite field to min or max for display label\n fieldLabel = field === 'ge' ? 'Min' : 'Max'\n } else {\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const strValue = e.target.value\n switch (field) {\n case 'minLength':\n case 'maxLength':\n case 'minItems':\n case 'maxItems': {\n const num = parseInt(strValue, 10)\n setData(field, isNaN(num) ? undefined : num)\n break\n }\n default:\n // For string fields ('description', 'regex') or 'any' type fields ('example', 'default')\n setData(field, strValue as AttributeData[typeof field])\n break\n }\n }\n\n fieldComp = (\n <InputText\n value={String(formData?.data[field] ?? '')}\n onChange={handleInputChange}\n />\n )\n }\n\n return (\n <FormRow\n label={fieldLabel}\n key={field}\n style={{\n alignItems: 'flex-start',\n }}\n >\n {fieldComp}\n </FormRow>\n )\n })}\n <span>\n {(internalError || error) && (\n <span className=\"form-error-text\">{internalError || error}</span>\n )}\n </span>\n </FormLayout>\n )}\n </Dialog>\n )\n}\n"],"names":["useState","useEffect","jsxs","jsx","Button","Spacer","SaveButton","_a","EnumEditor","InputSwitch","camelCase","Dialog","FormLayout","FormRow","InputText","LockedInput","Dropdown","upperFirst","MinMaxField","_b"],"mappings":"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"}
1
+ {"version":3,"file":"AttributeEditor.cjs.js","sources":["../../../../../src/components/AttributeEditor/AttributeEditor.tsx"],"sourcesContent":["import { FC, useEffect, useState } from 'react'\nimport {\n SaveButton,\n Spacer,\n FormLayout,\n FormRow,\n InputText,\n InputSwitch,\n LockedInput,\n Dropdown,\n Dialog,\n Button,\n} from '@ynput/ayon-react-components'\nimport { camelCase, upperFirst } from 'lodash'\nimport { MinMaxField } from './components'\nimport { EnumEditor } from '@shared/components/EnumEditor'\nimport { AttributeData, AttributeModel, AttributeEnumItem } from '@shared/api'\n\nconst SCOPE_OPTIONS = [\n { value: 'project', label: 'Project' },\n { value: 'folder', label: 'Folder' },\n { value: 'task', label: 'Task' },\n { value: 'product', label: 'Product' },\n { value: 'version', label: 'Version' },\n { value: 'representation', label: 'Representation' },\n { value: 'user', label: 'User' },\n]\n\n// Define types for constants\ninterface GlobalFieldEntry {\n value: keyof AttributeData\n scope: (AttributeModel['scope'] | '')[] | null\n}\n\nconst GLOBAL_FIELDS: GlobalFieldEntry[] = [\n { value: 'description', scope: null },\n { value: 'example', scope: null },\n // @ts-expect-error - project is not a scope?\n { value: 'default', scope: ['project'] },\n { value: 'inherit', scope: null },\n]\n\ninterface TypeOptionDef {\n value: AttributeData['type']\n label: string\n fields: (keyof AttributeData)[]\n exclude?: (keyof AttributeData)[]\n}\n\ninterface TypeOptionsMap {\n [key: string]: TypeOptionDef\n}\n\nconst TYPE_OPTIONS: TypeOptionsMap = {\n string: {\n value: 'string',\n label: 'String',\n fields: ['minLength', 'maxLength', 'enum', 'regex'],\n },\n integer: {\n value: 'integer',\n label: 'Integer',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n float: {\n value: 'float',\n label: 'Decimal number',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n list_of_strings: {\n value: 'list_of_strings',\n label: 'List Of Strings',\n fields: ['minItems', 'maxItems', 'enum'],\n },\n boolean: {\n value: 'boolean',\n label: 'Boolean',\n fields: [],\n exclude: ['example'],\n },\n}\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type AttributeForm = PartialBy<AttributeModel, 'scope' | 'position'>\ntype Excludes = (keyof Omit<AttributeModel, 'data'> | keyof AttributeData)[]\n\nconst initFormData: AttributeForm = {\n name: '',\n scope: ['folder', 'task'],\n builtin: false,\n position: 0,\n data: {\n type: 'string',\n title: '',\n description: '',\n example: '',\n default: undefined,\n enum: [],\n minLength: undefined,\n maxLength: undefined,\n regex: '',\n minItems: undefined,\n maxItems: undefined,\n ge: undefined,\n gt: undefined,\n le: undefined,\n lt: undefined,\n },\n}\n\n// build the form data based on excludes and to update any data\nconst buildInitFormData = (excludes: Excludes, data?: Partial<AttributeForm>) => {\n // Create a deep clone of init form data\n const formData = JSON.parse(JSON.stringify(initFormData)) as AttributeForm\n\n // Filter out top-level excludes if not in required\n const required = ['name']\n Object.keys(formData).forEach((key) => {\n if (\n !required.includes(key) &&\n excludes.includes(key as keyof Omit<AttributeModel, 'data'>) &&\n key !== 'data'\n ) {\n delete formData[key as keyof AttributeForm]\n }\n })\n\n // Filter out data field excludes if not in in required\n const requiredData = ['title']\n if (formData.data) {\n Object.keys(formData.data).forEach((key) => {\n if (!requiredData.includes(key) && excludes.includes(key as keyof AttributeData)) {\n delete formData.data[key as keyof AttributeData]\n }\n })\n }\n\n // Merge with provided data if any\n if (data) {\n // Merge top-level fields\n Object.keys(data).forEach((key) => {\n const typedKey = key as keyof AttributeForm\n if (typedKey !== 'data' && excludes.includes(typedKey)) return\n\n if (typedKey === 'data' && data.data && formData.data) {\n // Deep merge of data fields\n formData.data = { ...formData.data, ...data.data }\n } else if (data[typedKey] !== undefined) {\n // @ts-ignore - We know these properties exist\n formData[typedKey] = data[typedKey]\n }\n })\n }\n\n return formData\n}\n\nexport interface AttributeEditorProps {\n attribute: AttributeForm | null\n existingNames: string[]\n error?: string\n isUpdating?: boolean\n excludes?: Excludes\n onHide: () => void\n onEdit: (attribute: AttributeForm) => void\n onDelete?: () => void\n}\n\nexport const AttributeEditor: FC<AttributeEditorProps> = ({\n attribute,\n existingNames,\n error = '',\n isUpdating,\n excludes = [],\n onHide,\n onEdit,\n onDelete,\n}) => {\n const initForm = buildInitFormData(excludes, { position: existingNames.length })\n const [formData, setFormData] = useState<AttributeForm | null>(attribute || initForm)\n\n useEffect(() => {\n if (!!attribute) setFormData(attribute)\n }, [attribute])\n\n const isNew = !attribute\n\n // const setTopLevelData = (key: string, value: string) => {\n const setTopLevelData = <K extends keyof Omit<AttributeModel, 'data'>>(\n key: K,\n value: AttributeModel[K],\n ) => {\n setFormData((d) => {\n if (!d) {\n return d\n }\n return { ...d, [key]: value }\n })\n }\n\n // const setData = (key, value) => {\n const setData = <K extends keyof AttributeData>(key: K, value: AttributeData[K]) => {\n setFormData((d) => {\n // Add a check for d and d.data\n if (!d || !d.data) {\n return d\n }\n const dt = { ...d.data, [key]: value }\n return { ...d, data: dt }\n })\n }\n\n let internalError = ''\n if (formData) {\n if (isNew) {\n if (existingNames.includes(formData.name)) internalError = 'This attribute already exists'\n else if (!formData.name.match('^[a-zA-Z_]{2,64}$')) error = 'Invalid attribute name'\n } // name validation\n }\n\n const handleSubmit = () => {\n if (formData) {\n onEdit(formData)\n }\n }\n\n const footer = (\n <div style={{ display: 'flex', width: '100%', flexDirection: 'row' }}>\n {onDelete && attribute && (\n <Button\n variant=\"danger\"\n label={'Delete attribute'}\n icon={'delete'}\n disabled={isUpdating}\n onClick={onDelete}\n />\n )}\n <Spacer />\n <SaveButton\n label={isNew ? 'Create Attribute' : 'Save Attribute'}\n icon={'check'}\n disabled={!!internalError || !formData}\n active={!internalError && !!formData}\n saving={isUpdating}\n onClick={handleSubmit}\n />\n </div>\n )\n\n let dataFields: (keyof AttributeData)[] = []\n\n // add global fields, only if scope are null (all) or the scope is included\n GLOBAL_FIELDS.forEach((globalField) => {\n // @ts-expect-error - project scope will never be found here?\n if (!globalField?.scope || globalField?.scope?.some((s) => formData?.scope?.includes(s))) {\n dataFields.push(globalField.value)\n }\n })\n\n if (formData?.data.type && TYPE_OPTIONS[formData.data.type]) {\n const typeOpt = TYPE_OPTIONS[formData.data.type]\n dataFields = [...dataFields, ...typeOpt.fields].filter((f) => !typeOpt.exclude?.includes(f))\n }\n\n type CustomFieldRenderer = (value: any, onChange: (newValue: any) => void) => JSX.Element | null\n const customFields: {\n enum: CustomFieldRenderer\n inherit: CustomFieldRenderer\n booleanDefault: CustomFieldRenderer\n } = {\n enum: (value = [], onChange) => (\n <EnumEditor\n values={value as AttributeEnumItem[]}\n onChange={(val) => {\n onChange(val)\n }}\n />\n ),\n inherit: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n booleanDefault: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n }\n\n const handleTitleChange = (e: React.ChangeEvent) => {\n const v = (e.target as HTMLInputElement).value\n setData('title', v)\n\n if (isNew) {\n setTopLevelData('name', camelCase(v))\n }\n }\n\n return (\n <Dialog\n header={formData?.data?.title || formData?.name || 'New attribute'}\n footer={footer}\n onClose={onHide}\n isOpen={true}\n style={{ width: 700, zIndex: 999 }}\n size=\"full\"\n onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n handleSubmit()\n }\n }}\n >\n {formData && (\n <FormLayout>\n {!excludes.includes('title') && (\n <FormRow label={'Title'} key={'title'}>\n <InputText value={formData?.data['title']} onChange={handleTitleChange} autoFocus />\n </FormRow>\n )}\n {!excludes.includes('name') && (\n <FormRow label={'Name'} key={'name'}>\n <LockedInput\n value={formData.name}\n disabled={!isNew}\n onSubmit={(v) => setTopLevelData('name', v)}\n label=\"name\"\n />\n </FormRow>\n )}\n {!excludes.includes('scope') && (\n <FormRow label=\"Scope\">\n <Dropdown\n options={SCOPE_OPTIONS}\n disabled={formData.builtin}\n value={formData.scope || []}\n onChange={(v) => setTopLevelData('scope', v as AttributeModel['scope'])}\n multiSelect\n widthExpand\n />\n </FormRow>\n )}\n {!excludes.includes('type') && (\n <FormRow label=\"Type\">\n <Dropdown\n value={[formData?.data?.type]}\n disabled={formData.builtin}\n options={Object.values(TYPE_OPTIONS)}\n onChange={(v) => setData('type', v[0] as AttributeData['type'])}\n minSelected={1}\n widthExpand\n />\n </FormRow>\n )}\n {dataFields.map((field) => {\n // skip if field is excluded\n if (excludes.includes(field)) return null\n\n let fieldComp = null\n let fieldLabel = upperFirst(field)\n\n if (field === 'enum' || field === 'inherit') {\n const renderer = customFields[field as 'enum' | 'inherit']\n fieldComp = renderer(formData?.data[field], (value) => setData(field, value))\n } else if (field === 'default' && formData?.data?.type === 'boolean') {\n fieldComp = customFields['booleanDefault'](\n formData?.data[field] as boolean,\n (value) => setData(field, value as AttributeData['default']),\n )\n } else if (['ge', 'gt', 'le', 'lt'].includes(field)) {\n // ignore gt and lt\n if (['gt', 'lt'].includes(field)) return null\n fieldComp = (\n <MinMaxField\n value={formData?.data}\n isMin={field === 'ge'}\n isFloat={formData?.data?.type === 'float'}\n onChange={(v) => {\n const geValue = v.ge !== undefined ? Number(v.ge) : undefined\n const leValue = v.le !== undefined ? Number(v.le) : undefined\n\n if (\n // @ts-expect-error\n (v.ge !== undefined && isNaN(geValue)) ||\n // @ts-expect-error\n (v.le !== undefined && isNaN(leValue))\n ) {\n // Do not update the form if the value is not a valid number\n return\n }\n\n setFormData((d) => {\n if (!d || !d.data) return d\n const dt = { ...d.data, ...v }\n return { ...d, data: dt }\n })\n }}\n />\n )\n\n // rewrite field to min or max for display label\n fieldLabel = field === 'ge' ? 'Min' : 'Max'\n } else {\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const strValue = e.target.value\n switch (field) {\n case 'minLength':\n case 'maxLength':\n case 'minItems':\n case 'maxItems': {\n const num = parseInt(strValue, 10)\n setData(field, isNaN(num) ? undefined : num)\n break\n }\n default:\n // For string fields ('description', 'regex') or 'any' type fields ('example', 'default')\n setData(field, strValue as AttributeData[typeof field])\n break\n }\n }\n\n fieldComp = (\n <InputText\n value={String(formData?.data[field] ?? '')}\n onChange={handleInputChange}\n />\n )\n }\n\n return (\n <FormRow\n label={fieldLabel}\n key={field}\n style={{\n alignItems: 'flex-start',\n }}\n >\n {fieldComp}\n </FormRow>\n )\n })}\n <span>\n {(internalError || error) && (\n <span className=\"form-error-text\">{internalError || error}</span>\n )}\n </span>\n </FormLayout>\n )}\n </Dialog>\n )\n}\n"],"names":["useState","useEffect","jsxs","jsx","Button","Spacer","SaveButton","_a","EnumEditor","InputSwitch","camelCase","Dialog","FormLayout","FormRow","InputText","LockedInput","Dropdown","upperFirst","MinMaxField","_b"],"mappings":"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"}
@@ -138,7 +138,7 @@ const AttributeEditor = ({
138
138
  if (formData) {
139
139
  if (isNew) {
140
140
  if (existingNames.includes(formData.name)) internalError = "This attribute already exists";
141
- else if (!formData.name.match("^[a-zA-Z_]{2,20}$")) internalError = "Invalid attribute name";
141
+ else if (!formData.name.match("^[a-zA-Z_]{2,64}$")) error = "Invalid attribute name";
142
142
  }
143
143
  }
144
144
  const handleSubmit = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"AttributeEditor.es.js","sources":["../../../../../src/components/AttributeEditor/AttributeEditor.tsx"],"sourcesContent":["import { FC, useEffect, useState } from 'react'\nimport {\n SaveButton,\n Spacer,\n FormLayout,\n FormRow,\n InputText,\n InputSwitch,\n LockedInput,\n Dropdown,\n Dialog,\n Button,\n} from '@ynput/ayon-react-components'\nimport { camelCase, upperFirst } from 'lodash'\nimport { MinMaxField } from './components'\nimport { EnumEditor } from '@shared/components/EnumEditor'\nimport { AttributeData, AttributeModel, AttributeEnumItem } from '@shared/api'\n\nconst SCOPE_OPTIONS = [\n { value: 'project', label: 'Project' },\n { value: 'folder', label: 'Folder' },\n { value: 'task', label: 'Task' },\n { value: 'product', label: 'Product' },\n { value: 'version', label: 'Version' },\n { value: 'representation', label: 'Representation' },\n { value: 'user', label: 'User' },\n]\n\n// Define types for constants\ninterface GlobalFieldEntry {\n value: keyof AttributeData\n scope: (AttributeModel['scope'] | '')[] | null\n}\n\nconst GLOBAL_FIELDS: GlobalFieldEntry[] = [\n { value: 'description', scope: null },\n { value: 'example', scope: null },\n // @ts-expect-error - project is not a scope?\n { value: 'default', scope: ['project'] },\n { value: 'inherit', scope: null },\n]\n\ninterface TypeOptionDef {\n value: AttributeData['type']\n label: string\n fields: (keyof AttributeData)[]\n exclude?: (keyof AttributeData)[]\n}\n\ninterface TypeOptionsMap {\n [key: string]: TypeOptionDef\n}\n\nconst TYPE_OPTIONS: TypeOptionsMap = {\n string: {\n value: 'string',\n label: 'String',\n fields: ['minLength', 'maxLength', 'enum', 'regex'],\n },\n integer: {\n value: 'integer',\n label: 'Integer',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n float: {\n value: 'float',\n label: 'Decimal number',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n list_of_strings: {\n value: 'list_of_strings',\n label: 'List Of Strings',\n fields: ['minItems', 'maxItems', 'enum'],\n },\n boolean: {\n value: 'boolean',\n label: 'Boolean',\n fields: [],\n exclude: ['example'],\n },\n}\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type AttributeForm = PartialBy<AttributeModel, 'scope' | 'position'>\ntype Excludes = (keyof Omit<AttributeModel, 'data'> | keyof AttributeData)[]\n\nconst initFormData: AttributeForm = {\n name: '',\n scope: ['folder', 'task'],\n builtin: false,\n position: 0,\n data: {\n type: 'string',\n title: '',\n description: '',\n example: '',\n default: undefined,\n enum: [],\n minLength: undefined,\n maxLength: undefined,\n regex: '',\n minItems: undefined,\n maxItems: undefined,\n ge: undefined,\n gt: undefined,\n le: undefined,\n lt: undefined,\n },\n}\n\n// build the form data based on excludes and to update any data\nconst buildInitFormData = (excludes: Excludes, data?: Partial<AttributeForm>) => {\n // Create a deep clone of init form data\n const formData = JSON.parse(JSON.stringify(initFormData)) as AttributeForm\n\n // Filter out top-level excludes if not in required\n const required = ['name']\n Object.keys(formData).forEach((key) => {\n if (\n !required.includes(key) &&\n excludes.includes(key as keyof Omit<AttributeModel, 'data'>) &&\n key !== 'data'\n ) {\n delete formData[key as keyof AttributeForm]\n }\n })\n\n // Filter out data field excludes if not in in required\n const requiredData = ['title']\n if (formData.data) {\n Object.keys(formData.data).forEach((key) => {\n if (!requiredData.includes(key) && excludes.includes(key as keyof AttributeData)) {\n delete formData.data[key as keyof AttributeData]\n }\n })\n }\n\n // Merge with provided data if any\n if (data) {\n // Merge top-level fields\n Object.keys(data).forEach((key) => {\n const typedKey = key as keyof AttributeForm\n if (typedKey !== 'data' && excludes.includes(typedKey)) return\n\n if (typedKey === 'data' && data.data && formData.data) {\n // Deep merge of data fields\n formData.data = { ...formData.data, ...data.data }\n } else if (data[typedKey] !== undefined) {\n // @ts-ignore - We know these properties exist\n formData[typedKey] = data[typedKey]\n }\n })\n }\n\n return formData\n}\n\nexport interface AttributeEditorProps {\n attribute: AttributeForm | null\n existingNames: string[]\n error?: string\n isUpdating?: boolean\n excludes?: Excludes\n onHide: () => void\n onEdit: (attribute: AttributeForm) => void\n onDelete?: () => void\n}\n\nexport const AttributeEditor: FC<AttributeEditorProps> = ({\n attribute,\n existingNames,\n error = '',\n isUpdating,\n excludes = [],\n onHide,\n onEdit,\n onDelete,\n}) => {\n const initForm = buildInitFormData(excludes, { position: existingNames.length })\n const [formData, setFormData] = useState<AttributeForm | null>(attribute || initForm)\n\n useEffect(() => {\n if (!!attribute) setFormData(attribute)\n }, [attribute])\n\n const isNew = !attribute\n\n // const setTopLevelData = (key: string, value: string) => {\n const setTopLevelData = <K extends keyof Omit<AttributeModel, 'data'>>(\n key: K,\n value: AttributeModel[K],\n ) => {\n setFormData((d) => {\n if (!d) {\n return d\n }\n return { ...d, [key]: value }\n })\n }\n\n // const setData = (key, value) => {\n const setData = <K extends keyof AttributeData>(key: K, value: AttributeData[K]) => {\n setFormData((d) => {\n // Add a check for d and d.data\n if (!d || !d.data) {\n return d\n }\n const dt = { ...d.data, [key]: value }\n return { ...d, data: dt }\n })\n }\n\n let internalError = ''\n if (formData) {\n if (isNew) {\n if (existingNames.includes(formData.name)) internalError = 'This attribute already exists'\n else if (!formData.name.match('^[a-zA-Z_]{2,20}$')) internalError = 'Invalid attribute name'\n } // name validation\n }\n\n const handleSubmit = () => {\n if (formData) {\n onEdit(formData)\n }\n }\n\n const footer = (\n <div style={{ display: 'flex', width: '100%', flexDirection: 'row' }}>\n {onDelete && attribute && (\n <Button\n variant=\"danger\"\n label={'Delete attribute'}\n icon={'delete'}\n disabled={isUpdating}\n onClick={onDelete}\n />\n )}\n <Spacer />\n <SaveButton\n label={isNew ? 'Create Attribute' : 'Save Attribute'}\n icon={'check'}\n disabled={!!internalError || !formData}\n active={!internalError && !!formData}\n saving={isUpdating}\n onClick={handleSubmit}\n />\n </div>\n )\n\n let dataFields: (keyof AttributeData)[] = []\n\n // add global fields, only if scope are null (all) or the scope is included\n GLOBAL_FIELDS.forEach((globalField) => {\n // @ts-expect-error - project scope will never be found here?\n if (!globalField?.scope || globalField?.scope?.some((s) => formData?.scope?.includes(s))) {\n dataFields.push(globalField.value)\n }\n })\n\n if (formData?.data.type && TYPE_OPTIONS[formData.data.type]) {\n const typeOpt = TYPE_OPTIONS[formData.data.type]\n dataFields = [...dataFields, ...typeOpt.fields].filter((f) => !typeOpt.exclude?.includes(f))\n }\n\n type CustomFieldRenderer = (value: any, onChange: (newValue: any) => void) => JSX.Element | null\n const customFields: {\n enum: CustomFieldRenderer\n inherit: CustomFieldRenderer\n booleanDefault: CustomFieldRenderer\n } = {\n enum: (value = [], onChange) => (\n <EnumEditor\n values={value as AttributeEnumItem[]}\n onChange={(val) => {\n onChange(val)\n }}\n />\n ),\n inherit: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n booleanDefault: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n }\n\n const handleTitleChange = (e: React.ChangeEvent) => {\n const v = (e.target as HTMLInputElement).value\n setData('title', v)\n\n if (isNew) {\n setTopLevelData('name', camelCase(v))\n }\n }\n\n return (\n <Dialog\n header={formData?.data?.title || formData?.name || 'New attribute'}\n footer={footer}\n onClose={onHide}\n isOpen={true}\n style={{ width: 700, zIndex: 999 }}\n size=\"full\"\n onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n handleSubmit()\n }\n }}\n >\n {formData && (\n <FormLayout>\n {!excludes.includes('title') && (\n <FormRow label={'Title'} key={'title'}>\n <InputText value={formData?.data['title']} onChange={handleTitleChange} autoFocus />\n </FormRow>\n )}\n {!excludes.includes('name') && (\n <FormRow label={'Name'} key={'name'}>\n <LockedInput\n value={formData.name}\n disabled={!isNew}\n onSubmit={(v) => setTopLevelData('name', v)}\n label=\"name\"\n />\n </FormRow>\n )}\n {!excludes.includes('scope') && (\n <FormRow label=\"Scope\">\n <Dropdown\n options={SCOPE_OPTIONS}\n disabled={formData.builtin}\n value={formData.scope || []}\n onChange={(v) => setTopLevelData('scope', v as AttributeModel['scope'])}\n multiSelect\n widthExpand\n />\n </FormRow>\n )}\n {!excludes.includes('type') && (\n <FormRow label=\"Type\">\n <Dropdown\n value={[formData?.data?.type]}\n disabled={formData.builtin}\n options={Object.values(TYPE_OPTIONS)}\n onChange={(v) => setData('type', v[0] as AttributeData['type'])}\n minSelected={1}\n widthExpand\n />\n </FormRow>\n )}\n {dataFields.map((field) => {\n // skip if field is excluded\n if (excludes.includes(field)) return null\n\n let fieldComp = null\n let fieldLabel = upperFirst(field)\n\n if (field === 'enum' || field === 'inherit') {\n const renderer = customFields[field as 'enum' | 'inherit']\n fieldComp = renderer(formData?.data[field], (value) => setData(field, value))\n } else if (field === 'default' && formData?.data?.type === 'boolean') {\n fieldComp = customFields['booleanDefault'](\n formData?.data[field] as boolean,\n (value) => setData(field, value as AttributeData['default']),\n )\n } else if (['ge', 'gt', 'le', 'lt'].includes(field)) {\n // ignore gt and lt\n if (['gt', 'lt'].includes(field)) return null\n fieldComp = (\n <MinMaxField\n value={formData?.data}\n isMin={field === 'ge'}\n isFloat={formData?.data?.type === 'float'}\n onChange={(v) => {\n const geValue = v.ge !== undefined ? Number(v.ge) : undefined\n const leValue = v.le !== undefined ? Number(v.le) : undefined\n\n if (\n // @ts-expect-error\n (v.ge !== undefined && isNaN(geValue)) ||\n // @ts-expect-error\n (v.le !== undefined && isNaN(leValue))\n ) {\n // Do not update the form if the value is not a valid number\n return\n }\n\n setFormData((d) => {\n if (!d || !d.data) return d\n const dt = { ...d.data, ...v }\n return { ...d, data: dt }\n })\n }}\n />\n )\n\n // rewrite field to min or max for display label\n fieldLabel = field === 'ge' ? 'Min' : 'Max'\n } else {\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const strValue = e.target.value\n switch (field) {\n case 'minLength':\n case 'maxLength':\n case 'minItems':\n case 'maxItems': {\n const num = parseInt(strValue, 10)\n setData(field, isNaN(num) ? undefined : num)\n break\n }\n default:\n // For string fields ('description', 'regex') or 'any' type fields ('example', 'default')\n setData(field, strValue as AttributeData[typeof field])\n break\n }\n }\n\n fieldComp = (\n <InputText\n value={String(formData?.data[field] ?? '')}\n onChange={handleInputChange}\n />\n )\n }\n\n return (\n <FormRow\n label={fieldLabel}\n key={field}\n style={{\n alignItems: 'flex-start',\n }}\n >\n {fieldComp}\n </FormRow>\n )\n })}\n <span>\n {(internalError || error) && (\n <span className=\"form-error-text\">{internalError || error}</span>\n )}\n </span>\n </FormLayout>\n )}\n </Dialog>\n )\n}\n"],"names":["jsxs","jsx","_a","_b"],"mappings":"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"}
1
+ {"version":3,"file":"AttributeEditor.es.js","sources":["../../../../../src/components/AttributeEditor/AttributeEditor.tsx"],"sourcesContent":["import { FC, useEffect, useState } from 'react'\nimport {\n SaveButton,\n Spacer,\n FormLayout,\n FormRow,\n InputText,\n InputSwitch,\n LockedInput,\n Dropdown,\n Dialog,\n Button,\n} from '@ynput/ayon-react-components'\nimport { camelCase, upperFirst } from 'lodash'\nimport { MinMaxField } from './components'\nimport { EnumEditor } from '@shared/components/EnumEditor'\nimport { AttributeData, AttributeModel, AttributeEnumItem } from '@shared/api'\n\nconst SCOPE_OPTIONS = [\n { value: 'project', label: 'Project' },\n { value: 'folder', label: 'Folder' },\n { value: 'task', label: 'Task' },\n { value: 'product', label: 'Product' },\n { value: 'version', label: 'Version' },\n { value: 'representation', label: 'Representation' },\n { value: 'user', label: 'User' },\n]\n\n// Define types for constants\ninterface GlobalFieldEntry {\n value: keyof AttributeData\n scope: (AttributeModel['scope'] | '')[] | null\n}\n\nconst GLOBAL_FIELDS: GlobalFieldEntry[] = [\n { value: 'description', scope: null },\n { value: 'example', scope: null },\n // @ts-expect-error - project is not a scope?\n { value: 'default', scope: ['project'] },\n { value: 'inherit', scope: null },\n]\n\ninterface TypeOptionDef {\n value: AttributeData['type']\n label: string\n fields: (keyof AttributeData)[]\n exclude?: (keyof AttributeData)[]\n}\n\ninterface TypeOptionsMap {\n [key: string]: TypeOptionDef\n}\n\nconst TYPE_OPTIONS: TypeOptionsMap = {\n string: {\n value: 'string',\n label: 'String',\n fields: ['minLength', 'maxLength', 'enum', 'regex'],\n },\n integer: {\n value: 'integer',\n label: 'Integer',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n float: {\n value: 'float',\n label: 'Decimal number',\n fields: ['ge', 'gt', 'le', 'lt'],\n },\n list_of_strings: {\n value: 'list_of_strings',\n label: 'List Of Strings',\n fields: ['minItems', 'maxItems', 'enum'],\n },\n boolean: {\n value: 'boolean',\n label: 'Boolean',\n fields: [],\n exclude: ['example'],\n },\n}\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type AttributeForm = PartialBy<AttributeModel, 'scope' | 'position'>\ntype Excludes = (keyof Omit<AttributeModel, 'data'> | keyof AttributeData)[]\n\nconst initFormData: AttributeForm = {\n name: '',\n scope: ['folder', 'task'],\n builtin: false,\n position: 0,\n data: {\n type: 'string',\n title: '',\n description: '',\n example: '',\n default: undefined,\n enum: [],\n minLength: undefined,\n maxLength: undefined,\n regex: '',\n minItems: undefined,\n maxItems: undefined,\n ge: undefined,\n gt: undefined,\n le: undefined,\n lt: undefined,\n },\n}\n\n// build the form data based on excludes and to update any data\nconst buildInitFormData = (excludes: Excludes, data?: Partial<AttributeForm>) => {\n // Create a deep clone of init form data\n const formData = JSON.parse(JSON.stringify(initFormData)) as AttributeForm\n\n // Filter out top-level excludes if not in required\n const required = ['name']\n Object.keys(formData).forEach((key) => {\n if (\n !required.includes(key) &&\n excludes.includes(key as keyof Omit<AttributeModel, 'data'>) &&\n key !== 'data'\n ) {\n delete formData[key as keyof AttributeForm]\n }\n })\n\n // Filter out data field excludes if not in in required\n const requiredData = ['title']\n if (formData.data) {\n Object.keys(formData.data).forEach((key) => {\n if (!requiredData.includes(key) && excludes.includes(key as keyof AttributeData)) {\n delete formData.data[key as keyof AttributeData]\n }\n })\n }\n\n // Merge with provided data if any\n if (data) {\n // Merge top-level fields\n Object.keys(data).forEach((key) => {\n const typedKey = key as keyof AttributeForm\n if (typedKey !== 'data' && excludes.includes(typedKey)) return\n\n if (typedKey === 'data' && data.data && formData.data) {\n // Deep merge of data fields\n formData.data = { ...formData.data, ...data.data }\n } else if (data[typedKey] !== undefined) {\n // @ts-ignore - We know these properties exist\n formData[typedKey] = data[typedKey]\n }\n })\n }\n\n return formData\n}\n\nexport interface AttributeEditorProps {\n attribute: AttributeForm | null\n existingNames: string[]\n error?: string\n isUpdating?: boolean\n excludes?: Excludes\n onHide: () => void\n onEdit: (attribute: AttributeForm) => void\n onDelete?: () => void\n}\n\nexport const AttributeEditor: FC<AttributeEditorProps> = ({\n attribute,\n existingNames,\n error = '',\n isUpdating,\n excludes = [],\n onHide,\n onEdit,\n onDelete,\n}) => {\n const initForm = buildInitFormData(excludes, { position: existingNames.length })\n const [formData, setFormData] = useState<AttributeForm | null>(attribute || initForm)\n\n useEffect(() => {\n if (!!attribute) setFormData(attribute)\n }, [attribute])\n\n const isNew = !attribute\n\n // const setTopLevelData = (key: string, value: string) => {\n const setTopLevelData = <K extends keyof Omit<AttributeModel, 'data'>>(\n key: K,\n value: AttributeModel[K],\n ) => {\n setFormData((d) => {\n if (!d) {\n return d\n }\n return { ...d, [key]: value }\n })\n }\n\n // const setData = (key, value) => {\n const setData = <K extends keyof AttributeData>(key: K, value: AttributeData[K]) => {\n setFormData((d) => {\n // Add a check for d and d.data\n if (!d || !d.data) {\n return d\n }\n const dt = { ...d.data, [key]: value }\n return { ...d, data: dt }\n })\n }\n\n let internalError = ''\n if (formData) {\n if (isNew) {\n if (existingNames.includes(formData.name)) internalError = 'This attribute already exists'\n else if (!formData.name.match('^[a-zA-Z_]{2,64}$')) error = 'Invalid attribute name'\n } // name validation\n }\n\n const handleSubmit = () => {\n if (formData) {\n onEdit(formData)\n }\n }\n\n const footer = (\n <div style={{ display: 'flex', width: '100%', flexDirection: 'row' }}>\n {onDelete && attribute && (\n <Button\n variant=\"danger\"\n label={'Delete attribute'}\n icon={'delete'}\n disabled={isUpdating}\n onClick={onDelete}\n />\n )}\n <Spacer />\n <SaveButton\n label={isNew ? 'Create Attribute' : 'Save Attribute'}\n icon={'check'}\n disabled={!!internalError || !formData}\n active={!internalError && !!formData}\n saving={isUpdating}\n onClick={handleSubmit}\n />\n </div>\n )\n\n let dataFields: (keyof AttributeData)[] = []\n\n // add global fields, only if scope are null (all) or the scope is included\n GLOBAL_FIELDS.forEach((globalField) => {\n // @ts-expect-error - project scope will never be found here?\n if (!globalField?.scope || globalField?.scope?.some((s) => formData?.scope?.includes(s))) {\n dataFields.push(globalField.value)\n }\n })\n\n if (formData?.data.type && TYPE_OPTIONS[formData.data.type]) {\n const typeOpt = TYPE_OPTIONS[formData.data.type]\n dataFields = [...dataFields, ...typeOpt.fields].filter((f) => !typeOpt.exclude?.includes(f))\n }\n\n type CustomFieldRenderer = (value: any, onChange: (newValue: any) => void) => JSX.Element | null\n const customFields: {\n enum: CustomFieldRenderer\n inherit: CustomFieldRenderer\n booleanDefault: CustomFieldRenderer\n } = {\n enum: (value = [], onChange) => (\n <EnumEditor\n values={value as AttributeEnumItem[]}\n onChange={(val) => {\n onChange(val)\n }}\n />\n ),\n inherit: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n booleanDefault: (value, onChange) => (\n <InputSwitch\n checked={value}\n onChange={(e) => onChange((e.target as HTMLInputElement).checked)}\n />\n ),\n }\n\n const handleTitleChange = (e: React.ChangeEvent) => {\n const v = (e.target as HTMLInputElement).value\n setData('title', v)\n\n if (isNew) {\n setTopLevelData('name', camelCase(v))\n }\n }\n\n return (\n <Dialog\n header={formData?.data?.title || formData?.name || 'New attribute'}\n footer={footer}\n onClose={onHide}\n isOpen={true}\n style={{ width: 700, zIndex: 999 }}\n size=\"full\"\n onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n handleSubmit()\n }\n }}\n >\n {formData && (\n <FormLayout>\n {!excludes.includes('title') && (\n <FormRow label={'Title'} key={'title'}>\n <InputText value={formData?.data['title']} onChange={handleTitleChange} autoFocus />\n </FormRow>\n )}\n {!excludes.includes('name') && (\n <FormRow label={'Name'} key={'name'}>\n <LockedInput\n value={formData.name}\n disabled={!isNew}\n onSubmit={(v) => setTopLevelData('name', v)}\n label=\"name\"\n />\n </FormRow>\n )}\n {!excludes.includes('scope') && (\n <FormRow label=\"Scope\">\n <Dropdown\n options={SCOPE_OPTIONS}\n disabled={formData.builtin}\n value={formData.scope || []}\n onChange={(v) => setTopLevelData('scope', v as AttributeModel['scope'])}\n multiSelect\n widthExpand\n />\n </FormRow>\n )}\n {!excludes.includes('type') && (\n <FormRow label=\"Type\">\n <Dropdown\n value={[formData?.data?.type]}\n disabled={formData.builtin}\n options={Object.values(TYPE_OPTIONS)}\n onChange={(v) => setData('type', v[0] as AttributeData['type'])}\n minSelected={1}\n widthExpand\n />\n </FormRow>\n )}\n {dataFields.map((field) => {\n // skip if field is excluded\n if (excludes.includes(field)) return null\n\n let fieldComp = null\n let fieldLabel = upperFirst(field)\n\n if (field === 'enum' || field === 'inherit') {\n const renderer = customFields[field as 'enum' | 'inherit']\n fieldComp = renderer(formData?.data[field], (value) => setData(field, value))\n } else if (field === 'default' && formData?.data?.type === 'boolean') {\n fieldComp = customFields['booleanDefault'](\n formData?.data[field] as boolean,\n (value) => setData(field, value as AttributeData['default']),\n )\n } else if (['ge', 'gt', 'le', 'lt'].includes(field)) {\n // ignore gt and lt\n if (['gt', 'lt'].includes(field)) return null\n fieldComp = (\n <MinMaxField\n value={formData?.data}\n isMin={field === 'ge'}\n isFloat={formData?.data?.type === 'float'}\n onChange={(v) => {\n const geValue = v.ge !== undefined ? Number(v.ge) : undefined\n const leValue = v.le !== undefined ? Number(v.le) : undefined\n\n if (\n // @ts-expect-error\n (v.ge !== undefined && isNaN(geValue)) ||\n // @ts-expect-error\n (v.le !== undefined && isNaN(leValue))\n ) {\n // Do not update the form if the value is not a valid number\n return\n }\n\n setFormData((d) => {\n if (!d || !d.data) return d\n const dt = { ...d.data, ...v }\n return { ...d, data: dt }\n })\n }}\n />\n )\n\n // rewrite field to min or max for display label\n fieldLabel = field === 'ge' ? 'Min' : 'Max'\n } else {\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const strValue = e.target.value\n switch (field) {\n case 'minLength':\n case 'maxLength':\n case 'minItems':\n case 'maxItems': {\n const num = parseInt(strValue, 10)\n setData(field, isNaN(num) ? undefined : num)\n break\n }\n default:\n // For string fields ('description', 'regex') or 'any' type fields ('example', 'default')\n setData(field, strValue as AttributeData[typeof field])\n break\n }\n }\n\n fieldComp = (\n <InputText\n value={String(formData?.data[field] ?? '')}\n onChange={handleInputChange}\n />\n )\n }\n\n return (\n <FormRow\n label={fieldLabel}\n key={field}\n style={{\n alignItems: 'flex-start',\n }}\n >\n {fieldComp}\n </FormRow>\n )\n })}\n <span>\n {(internalError || error) && (\n <span className=\"form-error-text\">{internalError || error}</span>\n )}\n </span>\n </FormLayout>\n )}\n </Dialog>\n )\n}\n"],"names":["jsxs","jsx","_a","_b"],"mappings":"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"}
@@ -6,6 +6,7 @@ const StyledDropdown = styled(ayonReactComponents.Dropdown)`
6
6
  height: unset;
7
7
  button {
8
8
  background-color: var(--md-sys-color-surface-container-highest);
9
+ min-height: 32px;
9
10
  & > div {
10
11
  padding: 0;
11
12
  border: 0;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsDropdown.styled.cjs.js","sources":["../../../../../../src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.ts"],"sourcesContent":["import { Dropdown } from '@ynput/ayon-react-components'\nimport styled from 'styled-components'\n\nexport const StyledDropdown = styled(Dropdown)`\n height: unset;\n button {\n background-color: var(--md-sys-color-surface-container-highest);\n & > div {\n padding: 0;\n border: 0;\n padding: 0 6px;\n gap: 0;\n }\n * {\n opacity: 1 !important;\n }\n\n .icon {\n vertical-align: middle;\n }\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-highest-hover);\n }\n }\n`\n\nexport const DropdownItem = styled.div`\n display: flex;\n gap: var(--base-gap-large);\n\n padding: 6px;\n padding-right: 12px;\n\n img {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n`\n\nexport const DropdownHeader = styled.div`\n color: var(--md-sys-color-outline);\n padding: 4px 6px;\n`\n"],"names":["Dropdown"],"mappings":";;;;AAGa,MAAA,iBAAiB,OAAOA,4BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBtC,MAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc5B,MAAM,iBAAiB,OAAO;AAAA;AAAA;AAAA;;;;"}
1
+ {"version":3,"file":"ActionsDropdown.styled.cjs.js","sources":["../../../../../../src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.ts"],"sourcesContent":["import { Dropdown } from '@ynput/ayon-react-components'\nimport styled from 'styled-components'\n\nexport const StyledDropdown = styled(Dropdown)`\n height: unset;\n button {\n background-color: var(--md-sys-color-surface-container-highest);\n min-height: 32px;\n & > div {\n padding: 0;\n border: 0;\n padding: 0 6px;\n gap: 0;\n }\n * {\n opacity: 1 !important;\n }\n\n .icon {\n vertical-align: middle;\n }\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-highest-hover);\n }\n }\n`\n\nexport const DropdownItem = styled.div`\n display: flex;\n gap: var(--base-gap-large);\n\n padding: 6px;\n padding-right: 12px;\n\n img {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n`\n\nexport const DropdownHeader = styled.div`\n color: var(--md-sys-color-outline);\n padding: 4px 6px;\n`\n"],"names":["Dropdown"],"mappings":";;;;AAGa,MAAA,iBAAiB,OAAOA,4BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBtC,MAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc5B,MAAM,iBAAiB,OAAO;AAAA;AAAA;AAAA;;;;"}
@@ -4,6 +4,7 @@ const StyledDropdown = styled(Dropdown)`
4
4
  height: unset;
5
5
  button {
6
6
  background-color: var(--md-sys-color-surface-container-highest);
7
+ min-height: 32px;
7
8
  & > div {
8
9
  padding: 0;
9
10
  border: 0;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsDropdown.styled.es.js","sources":["../../../../../../src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.ts"],"sourcesContent":["import { Dropdown } from '@ynput/ayon-react-components'\nimport styled from 'styled-components'\n\nexport const StyledDropdown = styled(Dropdown)`\n height: unset;\n button {\n background-color: var(--md-sys-color-surface-container-highest);\n & > div {\n padding: 0;\n border: 0;\n padding: 0 6px;\n gap: 0;\n }\n * {\n opacity: 1 !important;\n }\n\n .icon {\n vertical-align: middle;\n }\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-highest-hover);\n }\n }\n`\n\nexport const DropdownItem = styled.div`\n display: flex;\n gap: var(--base-gap-large);\n\n padding: 6px;\n padding-right: 12px;\n\n img {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n`\n\nexport const DropdownHeader = styled.div`\n color: var(--md-sys-color-outline);\n padding: 4px 6px;\n`\n"],"names":[],"mappings":";;AAGa,MAAA,iBAAiB,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBtC,MAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc5B,MAAM,iBAAiB,OAAO;AAAA;AAAA;AAAA;"}
1
+ {"version":3,"file":"ActionsDropdown.styled.es.js","sources":["../../../../../../src/containers/Actions/ActionsDropdown/ActionsDropdown.styled.ts"],"sourcesContent":["import { Dropdown } from '@ynput/ayon-react-components'\nimport styled from 'styled-components'\n\nexport const StyledDropdown = styled(Dropdown)`\n height: unset;\n button {\n background-color: var(--md-sys-color-surface-container-highest);\n min-height: 32px;\n & > div {\n padding: 0;\n border: 0;\n padding: 0 6px;\n gap: 0;\n }\n * {\n opacity: 1 !important;\n }\n\n .icon {\n vertical-align: middle;\n }\n\n &:hover {\n background-color: var(--md-sys-color-surface-container-highest-hover);\n }\n }\n`\n\nexport const DropdownItem = styled.div`\n display: flex;\n gap: var(--base-gap-large);\n\n padding: 6px;\n padding-right: 12px;\n\n img {\n width: 20px;\n height: 20px;\n object-fit: contain;\n }\n`\n\nexport const DropdownHeader = styled.div`\n color: var(--md-sys-color-outline);\n padding: 4px 6px;\n`\n"],"names":[],"mappings":";;AAGa,MAAA,iBAAiB,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBtC,MAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc5B,MAAM,iBAAiB,OAAO;AAAA;AAAA;AAAA;"}
@@ -101,9 +101,9 @@ const FeedProvider = ({ children, ...props }) => {
101
101
  entityType: props.entityType
102
102
  });
103
103
  const [refTooltip, setRefTooltip] = React.useState(null);
104
- const skip = !props.projectName || !(refTooltip == null ? void 0 : refTooltip.id);
104
+ const skip = !props.projectName || !(refTooltip == null ? void 0 : refTooltip.id) || refTooltip.type === "user";
105
105
  const { data: entityTooltipData, isFetching: isFetchingTooltip } = getActivities.useGetEntityTooltipQuery(
106
- { entityType: props.entityType, entityId: refTooltip == null ? void 0 : refTooltip.id, projectName: props.projectName },
106
+ { entityType: refTooltip == null ? void 0 : refTooltip.type, entityId: refTooltip == null ? void 0 : refTooltip.id, projectName: props.projectName },
107
107
  { skip }
108
108
  );
109
109
  const { data: mentionSuggestionsData = {} } = getMentions.useGetEntityMentionsQuery(
@@ -1 +1 @@
1
- {"version":3,"file":"FeedContext.cjs.js","sources":["../../../../../../src/containers/Feed/context/FeedContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useState } from 'react'\nimport useGetFeedActivitiesData from '../hooks/useGetFeedActivitiesData'\n\n// Queries\nimport {\n useCreateEntityActivityMutation,\n useDeleteActivityMutation,\n useUpdateActivityMutation,\n useCreateReactionToActivityMutation,\n useDeleteReactionToActivityMutation,\n useGetActivityUsersQuery,\n useGetEntityMentionsQuery,\n useGetEntityTooltipQuery,\n} from '@shared/api'\nimport type { SuggestRequest, SuggestResponse } from '@shared/api'\nimport { ActivityUser } from '../helpers/groupMinorActivities'\nimport { DetailsPanelTab, useScopedDetailsPanel } from '@shared/context'\nimport { getFilterActivityTypes } from '@shared/api'\n\nexport const FEED_NEW_COMMENT = '__new__' as const\n\nexport type EditingState = null | typeof FEED_NEW_COMMENT | string\n\n// Add type for the refTooltip\nexport interface RefTooltip {\n id: string | null\n type: string\n name: string\n label: string\n pos: {\n top: number\n left: number\n }\n}\n\nexport type FeedContextProps = {\n children: React.ReactNode\n projectName: string\n entityType: string\n activityTypes?: string[] | null\n entities: any[]\n projectInfo: any\n scope: string\n userName: string\n userFullName: string\n\n // annotations\n annotations?: Record<string, any>\n removeAnnotation?: (id: string) => void\n exportAnnotationComposite?: (id: string) => Promise<Blob | null>\n // editingId state and functions\n editingId: EditingState\n setEditingId: (id: EditingState) => void\n}\n\ninterface FeedContextType extends Omit<FeedContextProps, 'children'> {\n currentTab: DetailsPanelTab\n // activities data props\n activitiesData: any[]\n isLoadingActivities: boolean\n isLoadingNew: boolean\n isLoadingNextPage: boolean\n hasNextPage: boolean\n loadNextPage?: () => Promise<any>\n // refTooltip state and functions\n refTooltip: RefTooltip | null\n setRefTooltip: (tooltip: RefTooltip | null) => void\n // tooltip data\n entityTooltipData: any\n isFetchingTooltip: boolean\n // query functions\n createEntityActivity: (args: any) => Promise<any>\n updateActivity: (args: any) => Promise<any>\n deleteActivity: (args: any) => Promise<any>\n createReaction: (args: any) => Promise<any>\n deleteReaction: (args: any) => Promise<any>\n isUpdatingActivity: boolean\n // users data\n users: ActivityUser[]\n // mentions data\n mentionSuggestionsData: SuggestResponse\n}\n\nconst FeedContext = createContext<FeedContextType | undefined>(undefined)\n\nexport const FeedProvider = ({ children, ...props }: FeedContextProps) => {\n const { data: users = [] } = useGetActivityUsersQuery({ projects: [props.projectName] })\n const { currentTab } = useScopedDetailsPanel(props.scope)\n\n // queries\n const [createEntityActivityMutation, { isLoading: isLoadingCreate }] =\n useCreateEntityActivityMutation()\n const [updateActivityMutation, { isLoading: isLoadingUpdate }] = useUpdateActivityMutation()\n const [deleteActivityMutation, { isLoading: isLoadingDelete }] = useDeleteActivityMutation()\n const isUpdatingActivity = isLoadingCreate || isLoadingUpdate || isLoadingDelete\n\n const createEntityActivity: FeedContextType['createEntityActivity'] = async (args) =>\n await createEntityActivityMutation(args).unwrap()\n const updateActivity: FeedContextType['updateActivity'] = async (args) =>\n await updateActivityMutation(args).unwrap()\n const deleteActivity: FeedContextType['deleteActivity'] = async (args) =>\n await deleteActivityMutation(args).unwrap()\n\n const [createReactionToActivity] = useCreateReactionToActivityMutation()\n const [deleteReactionToActivity] = useDeleteReactionToActivityMutation()\n\n const createReaction: FeedContextType['createReaction'] = async (args) =>\n await createReactionToActivity(args).unwrap()\n const deleteReaction: FeedContextType['deleteReaction'] = async (args) =>\n await deleteReactionToActivity(args).unwrap()\n\n const activityTypes = getFilterActivityTypes(currentTab)\n\n const activitiesDataProps = useGetFeedActivitiesData({\n entities: props.entities,\n filter: currentTab,\n activityTypes: activityTypes,\n projectName: props.projectName,\n entityType: props.entityType,\n })\n\n const [refTooltip, setRefTooltip] = useState<RefTooltip | null>(null)\n const skip = !props.projectName || !refTooltip?.id\n const { data: entityTooltipData, isFetching: isFetchingTooltip } = useGetEntityTooltipQuery(\n { entityType: props.entityType, entityId: refTooltip?.id, projectName: props.projectName },\n { skip: skip },\n )\n\n // get all versions that can be mentioned\n const { data: mentionSuggestionsData = {} } = useGetEntityMentionsQuery(\n {\n suggestRequest: {\n entityType: props.entityType as SuggestRequest['entityType'],\n entityId: props.entities[0]?.id,\n },\n projectName: props.projectName,\n },\n { skip: !props.editingId },\n )\n\n return (\n <FeedContext.Provider\n value={{\n ...props,\n ...activitiesDataProps,\n mentionSuggestionsData,\n users,\n isUpdatingActivity,\n entityTooltipData,\n isFetchingTooltip,\n refTooltip,\n activityTypes,\n currentTab,\n setRefTooltip,\n // Query functions\n createEntityActivity,\n updateActivity,\n deleteActivity,\n createReaction,\n deleteReaction,\n }}\n >\n {children}\n </FeedContext.Provider>\n )\n}\n\nexport const useFeedContext = () => {\n const context = useContext(FeedContext)\n if (!context) {\n throw new Error('useFeedContext must be used within a FeedProvider')\n }\n return context\n}\n"],"names":["createContext","useGetActivityUsersQuery","useScopedDetailsPanel","useCreateEntityActivityMutation","useUpdateActivityMutation","useDeleteActivityMutation","useCreateReactionToActivityMutation","useDeleteReactionToActivityMutation","getFilterActivityTypes","useState","useGetEntityTooltipQuery","useGetEntityMentionsQuery","jsx","useContext"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,mBAAmB;AAgEhC,MAAM,cAAcA,oBAA2C,MAAS;AAEjE,MAAM,eAAe,CAAC,EAAE,UAAU,GAAG,YAA8B;;AACxE,QAAM,EAAE,MAAM,QAAQ,CAAA,MAAOC,cAAAA,yBAAyB,EAAE,UAAU,CAAC,MAAM,WAAW,GAAG;AACvF,QAAM,EAAE,WAAe,IAAAC,0CAAsB,MAAM,KAAK;AAGxD,QAAM,CAAC,8BAA8B,EAAE,WAAW,gBAAiB,CAAA,IACjEC,iBAAAA,gCAAgC;AAClC,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAIC,iBAAAA,0BAA0B;AAC3F,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAIC,iBAAAA,0BAA0B;AACrF,QAAA,qBAAqB,mBAAmB,mBAAmB;AAEjE,QAAM,uBAAgE,OAAO,SAC3E,MAAM,6BAA6B,IAAI,EAAE,OAAO;AAClD,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAC5C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAEtC,QAAA,CAAC,wBAAwB,IAAIC,mDAAoC;AACjE,QAAA,CAAC,wBAAwB,IAAIC,mDAAoC;AAEvE,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAC9C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAExC,QAAA,gBAAgBC,yCAAuB,UAAU;AAEvD,QAAM,sBAAsB,yBAAyB;AAAA,IACnD,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,YAAY,MAAM;AAAA,EAAA,CACnB;AAED,QAAM,CAAC,YAAY,aAAa,IAAIC,MAAAA,SAA4B,IAAI;AACpE,QAAM,OAAO,CAAC,MAAM,eAAe,EAAC,yCAAY;AAChD,QAAM,EAAE,MAAM,mBAAmB,YAAY,kBAAsB,IAAAC,cAAA;AAAA,IACjE,EAAE,YAAY,MAAM,YAAY,UAAU,yCAAY,IAAI,aAAa,MAAM,YAAY;AAAA,IACzF,EAAE,KAAW;AAAA,EACf;AAGA,QAAM,EAAE,MAAM,yBAAyB,CAAA,EAAO,IAAAC,YAAA;AAAA,IAC5C;AAAA,MACE,gBAAgB;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,WAAU,WAAM,SAAS,CAAC,MAAhB,mBAAmB;AAAA,MAC/B;AAAA,MACA,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,CAAC,MAAM,UAAU;AAAA,EAC3B;AAGE,SAAAC,2BAAA,kBAAA;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA,IAAA;AAAA,EACH;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAC5B,QAAA,UAAUC,iBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mDAAmD;AAAA,EAAA;AAE9D,SAAA;AACT;;;;"}
1
+ {"version":3,"file":"FeedContext.cjs.js","sources":["../../../../../../src/containers/Feed/context/FeedContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useState } from 'react'\nimport useGetFeedActivitiesData from '../hooks/useGetFeedActivitiesData'\n\n// Queries\nimport {\n useCreateEntityActivityMutation,\n useDeleteActivityMutation,\n useUpdateActivityMutation,\n useCreateReactionToActivityMutation,\n useDeleteReactionToActivityMutation,\n useGetActivityUsersQuery,\n useGetEntityMentionsQuery,\n useGetEntityTooltipQuery,\n} from '@shared/api'\nimport type { SuggestRequest, SuggestResponse } from '@shared/api'\nimport { ActivityUser } from '../helpers/groupMinorActivities'\nimport { DetailsPanelTab, useScopedDetailsPanel } from '@shared/context'\nimport { getFilterActivityTypes } from '@shared/api'\n\nexport const FEED_NEW_COMMENT = '__new__' as const\n\nexport type EditingState = null | typeof FEED_NEW_COMMENT | string\n\n// Add type for the refTooltip\nexport interface RefTooltip {\n id: string | null\n type: string\n name: string\n label: string\n pos: {\n top: number\n left: number\n }\n}\n\nexport type FeedContextProps = {\n children: React.ReactNode\n projectName: string\n entityType: string\n activityTypes?: string[] | null\n entities: any[]\n projectInfo: any\n scope: string\n userName: string\n userFullName: string\n\n // annotations\n annotations?: Record<string, any>\n removeAnnotation?: (id: string) => void\n exportAnnotationComposite?: (id: string) => Promise<Blob | null>\n // editingId state and functions\n editingId: EditingState\n setEditingId: (id: EditingState) => void\n}\n\ninterface FeedContextType extends Omit<FeedContextProps, 'children'> {\n currentTab: DetailsPanelTab\n // activities data props\n activitiesData: any[]\n isLoadingActivities: boolean\n isLoadingNew: boolean\n isLoadingNextPage: boolean\n hasNextPage: boolean\n loadNextPage?: () => Promise<any>\n // refTooltip state and functions\n refTooltip: RefTooltip | null\n setRefTooltip: (tooltip: RefTooltip | null) => void\n // tooltip data\n entityTooltipData: any\n isFetchingTooltip: boolean\n // query functions\n createEntityActivity: (args: any) => Promise<any>\n updateActivity: (args: any) => Promise<any>\n deleteActivity: (args: any) => Promise<any>\n createReaction: (args: any) => Promise<any>\n deleteReaction: (args: any) => Promise<any>\n isUpdatingActivity: boolean\n // users data\n users: ActivityUser[]\n // mentions data\n mentionSuggestionsData: SuggestResponse\n}\n\nconst FeedContext = createContext<FeedContextType | undefined>(undefined)\n\nexport const FeedProvider = ({ children, ...props }: FeedContextProps) => {\n const { data: users = [] } = useGetActivityUsersQuery({ projects: [props.projectName] })\n const { currentTab } = useScopedDetailsPanel(props.scope)\n\n // queries\n const [createEntityActivityMutation, { isLoading: isLoadingCreate }] =\n useCreateEntityActivityMutation()\n const [updateActivityMutation, { isLoading: isLoadingUpdate }] = useUpdateActivityMutation()\n const [deleteActivityMutation, { isLoading: isLoadingDelete }] = useDeleteActivityMutation()\n const isUpdatingActivity = isLoadingCreate || isLoadingUpdate || isLoadingDelete\n\n const createEntityActivity: FeedContextType['createEntityActivity'] = async (args) =>\n await createEntityActivityMutation(args).unwrap()\n const updateActivity: FeedContextType['updateActivity'] = async (args) =>\n await updateActivityMutation(args).unwrap()\n const deleteActivity: FeedContextType['deleteActivity'] = async (args) =>\n await deleteActivityMutation(args).unwrap()\n\n const [createReactionToActivity] = useCreateReactionToActivityMutation()\n const [deleteReactionToActivity] = useDeleteReactionToActivityMutation()\n\n const createReaction: FeedContextType['createReaction'] = async (args) =>\n await createReactionToActivity(args).unwrap()\n const deleteReaction: FeedContextType['deleteReaction'] = async (args) =>\n await deleteReactionToActivity(args).unwrap()\n\n const activityTypes = getFilterActivityTypes(currentTab)\n\n const activitiesDataProps = useGetFeedActivitiesData({\n entities: props.entities,\n filter: currentTab,\n activityTypes: activityTypes,\n projectName: props.projectName,\n entityType: props.entityType,\n })\n\n const [refTooltip, setRefTooltip] = useState<RefTooltip | null>(null)\n const skip = !props.projectName || !refTooltip?.id || refTooltip.type === 'user'\n const { data: entityTooltipData, isFetching: isFetchingTooltip } = useGetEntityTooltipQuery(\n { entityType: refTooltip?.type, entityId: refTooltip?.id, projectName: props.projectName },\n { skip: skip },\n )\n\n // get all versions that can be mentioned\n const { data: mentionSuggestionsData = {} } = useGetEntityMentionsQuery(\n {\n suggestRequest: {\n entityType: props.entityType as SuggestRequest['entityType'],\n entityId: props.entities[0]?.id,\n },\n projectName: props.projectName,\n },\n { skip: !props.editingId },\n )\n\n return (\n <FeedContext.Provider\n value={{\n ...props,\n ...activitiesDataProps,\n mentionSuggestionsData,\n users,\n isUpdatingActivity,\n entityTooltipData,\n isFetchingTooltip,\n refTooltip,\n activityTypes,\n currentTab,\n setRefTooltip,\n // Query functions\n createEntityActivity,\n updateActivity,\n deleteActivity,\n createReaction,\n deleteReaction,\n }}\n >\n {children}\n </FeedContext.Provider>\n )\n}\n\nexport const useFeedContext = () => {\n const context = useContext(FeedContext)\n if (!context) {\n throw new Error('useFeedContext must be used within a FeedProvider')\n }\n return context\n}\n"],"names":["createContext","useGetActivityUsersQuery","useScopedDetailsPanel","useCreateEntityActivityMutation","useUpdateActivityMutation","useDeleteActivityMutation","useCreateReactionToActivityMutation","useDeleteReactionToActivityMutation","getFilterActivityTypes","useState","useGetEntityTooltipQuery","useGetEntityMentionsQuery","jsx","useContext"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,mBAAmB;AAgEhC,MAAM,cAAcA,oBAA2C,MAAS;AAEjE,MAAM,eAAe,CAAC,EAAE,UAAU,GAAG,YAA8B;;AACxE,QAAM,EAAE,MAAM,QAAQ,CAAA,MAAOC,cAAAA,yBAAyB,EAAE,UAAU,CAAC,MAAM,WAAW,GAAG;AACvF,QAAM,EAAE,WAAe,IAAAC,0CAAsB,MAAM,KAAK;AAGxD,QAAM,CAAC,8BAA8B,EAAE,WAAW,gBAAiB,CAAA,IACjEC,iBAAAA,gCAAgC;AAClC,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAIC,iBAAAA,0BAA0B;AAC3F,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAIC,iBAAAA,0BAA0B;AACrF,QAAA,qBAAqB,mBAAmB,mBAAmB;AAEjE,QAAM,uBAAgE,OAAO,SAC3E,MAAM,6BAA6B,IAAI,EAAE,OAAO;AAClD,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAC5C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAEtC,QAAA,CAAC,wBAAwB,IAAIC,mDAAoC;AACjE,QAAA,CAAC,wBAAwB,IAAIC,mDAAoC;AAEvE,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAC9C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAExC,QAAA,gBAAgBC,yCAAuB,UAAU;AAEvD,QAAM,sBAAsB,yBAAyB;AAAA,IACnD,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,YAAY,MAAM;AAAA,EAAA,CACnB;AAED,QAAM,CAAC,YAAY,aAAa,IAAIC,MAAAA,SAA4B,IAAI;AAC9D,QAAA,OAAO,CAAC,MAAM,eAAe,EAAC,yCAAY,OAAM,WAAW,SAAS;AAC1E,QAAM,EAAE,MAAM,mBAAmB,YAAY,kBAAsB,IAAAC,cAAA;AAAA,IACjE,EAAE,YAAY,yCAAY,MAAM,UAAU,yCAAY,IAAI,aAAa,MAAM,YAAY;AAAA,IACzF,EAAE,KAAW;AAAA,EACf;AAGA,QAAM,EAAE,MAAM,yBAAyB,CAAA,EAAO,IAAAC,YAAA;AAAA,IAC5C;AAAA,MACE,gBAAgB;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,WAAU,WAAM,SAAS,CAAC,MAAhB,mBAAmB;AAAA,MAC/B;AAAA,MACA,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,CAAC,MAAM,UAAU;AAAA,EAC3B;AAGE,SAAAC,2BAAA,kBAAA;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA,IAAA;AAAA,EACH;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAC5B,QAAA,UAAUC,iBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mDAAmD;AAAA,EAAA;AAE9D,SAAA;AACT;;;;"}
@@ -99,9 +99,9 @@ const FeedProvider = ({ children, ...props }) => {
99
99
  entityType: props.entityType
100
100
  });
101
101
  const [refTooltip, setRefTooltip] = useState(null);
102
- const skip = !props.projectName || !(refTooltip == null ? void 0 : refTooltip.id);
102
+ const skip = !props.projectName || !(refTooltip == null ? void 0 : refTooltip.id) || refTooltip.type === "user";
103
103
  const { data: entityTooltipData, isFetching: isFetchingTooltip } = useGetEntityTooltipQuery(
104
- { entityType: props.entityType, entityId: refTooltip == null ? void 0 : refTooltip.id, projectName: props.projectName },
104
+ { entityType: refTooltip == null ? void 0 : refTooltip.type, entityId: refTooltip == null ? void 0 : refTooltip.id, projectName: props.projectName },
105
105
  { skip }
106
106
  );
107
107
  const { data: mentionSuggestionsData = {} } = useGetEntityMentionsQuery(
@@ -1 +1 @@
1
- {"version":3,"file":"FeedContext.es.js","sources":["../../../../../../src/containers/Feed/context/FeedContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useState } from 'react'\nimport useGetFeedActivitiesData from '../hooks/useGetFeedActivitiesData'\n\n// Queries\nimport {\n useCreateEntityActivityMutation,\n useDeleteActivityMutation,\n useUpdateActivityMutation,\n useCreateReactionToActivityMutation,\n useDeleteReactionToActivityMutation,\n useGetActivityUsersQuery,\n useGetEntityMentionsQuery,\n useGetEntityTooltipQuery,\n} from '@shared/api'\nimport type { SuggestRequest, SuggestResponse } from '@shared/api'\nimport { ActivityUser } from '../helpers/groupMinorActivities'\nimport { DetailsPanelTab, useScopedDetailsPanel } from '@shared/context'\nimport { getFilterActivityTypes } from '@shared/api'\n\nexport const FEED_NEW_COMMENT = '__new__' as const\n\nexport type EditingState = null | typeof FEED_NEW_COMMENT | string\n\n// Add type for the refTooltip\nexport interface RefTooltip {\n id: string | null\n type: string\n name: string\n label: string\n pos: {\n top: number\n left: number\n }\n}\n\nexport type FeedContextProps = {\n children: React.ReactNode\n projectName: string\n entityType: string\n activityTypes?: string[] | null\n entities: any[]\n projectInfo: any\n scope: string\n userName: string\n userFullName: string\n\n // annotations\n annotations?: Record<string, any>\n removeAnnotation?: (id: string) => void\n exportAnnotationComposite?: (id: string) => Promise<Blob | null>\n // editingId state and functions\n editingId: EditingState\n setEditingId: (id: EditingState) => void\n}\n\ninterface FeedContextType extends Omit<FeedContextProps, 'children'> {\n currentTab: DetailsPanelTab\n // activities data props\n activitiesData: any[]\n isLoadingActivities: boolean\n isLoadingNew: boolean\n isLoadingNextPage: boolean\n hasNextPage: boolean\n loadNextPage?: () => Promise<any>\n // refTooltip state and functions\n refTooltip: RefTooltip | null\n setRefTooltip: (tooltip: RefTooltip | null) => void\n // tooltip data\n entityTooltipData: any\n isFetchingTooltip: boolean\n // query functions\n createEntityActivity: (args: any) => Promise<any>\n updateActivity: (args: any) => Promise<any>\n deleteActivity: (args: any) => Promise<any>\n createReaction: (args: any) => Promise<any>\n deleteReaction: (args: any) => Promise<any>\n isUpdatingActivity: boolean\n // users data\n users: ActivityUser[]\n // mentions data\n mentionSuggestionsData: SuggestResponse\n}\n\nconst FeedContext = createContext<FeedContextType | undefined>(undefined)\n\nexport const FeedProvider = ({ children, ...props }: FeedContextProps) => {\n const { data: users = [] } = useGetActivityUsersQuery({ projects: [props.projectName] })\n const { currentTab } = useScopedDetailsPanel(props.scope)\n\n // queries\n const [createEntityActivityMutation, { isLoading: isLoadingCreate }] =\n useCreateEntityActivityMutation()\n const [updateActivityMutation, { isLoading: isLoadingUpdate }] = useUpdateActivityMutation()\n const [deleteActivityMutation, { isLoading: isLoadingDelete }] = useDeleteActivityMutation()\n const isUpdatingActivity = isLoadingCreate || isLoadingUpdate || isLoadingDelete\n\n const createEntityActivity: FeedContextType['createEntityActivity'] = async (args) =>\n await createEntityActivityMutation(args).unwrap()\n const updateActivity: FeedContextType['updateActivity'] = async (args) =>\n await updateActivityMutation(args).unwrap()\n const deleteActivity: FeedContextType['deleteActivity'] = async (args) =>\n await deleteActivityMutation(args).unwrap()\n\n const [createReactionToActivity] = useCreateReactionToActivityMutation()\n const [deleteReactionToActivity] = useDeleteReactionToActivityMutation()\n\n const createReaction: FeedContextType['createReaction'] = async (args) =>\n await createReactionToActivity(args).unwrap()\n const deleteReaction: FeedContextType['deleteReaction'] = async (args) =>\n await deleteReactionToActivity(args).unwrap()\n\n const activityTypes = getFilterActivityTypes(currentTab)\n\n const activitiesDataProps = useGetFeedActivitiesData({\n entities: props.entities,\n filter: currentTab,\n activityTypes: activityTypes,\n projectName: props.projectName,\n entityType: props.entityType,\n })\n\n const [refTooltip, setRefTooltip] = useState<RefTooltip | null>(null)\n const skip = !props.projectName || !refTooltip?.id\n const { data: entityTooltipData, isFetching: isFetchingTooltip } = useGetEntityTooltipQuery(\n { entityType: props.entityType, entityId: refTooltip?.id, projectName: props.projectName },\n { skip: skip },\n )\n\n // get all versions that can be mentioned\n const { data: mentionSuggestionsData = {} } = useGetEntityMentionsQuery(\n {\n suggestRequest: {\n entityType: props.entityType as SuggestRequest['entityType'],\n entityId: props.entities[0]?.id,\n },\n projectName: props.projectName,\n },\n { skip: !props.editingId },\n )\n\n return (\n <FeedContext.Provider\n value={{\n ...props,\n ...activitiesDataProps,\n mentionSuggestionsData,\n users,\n isUpdatingActivity,\n entityTooltipData,\n isFetchingTooltip,\n refTooltip,\n activityTypes,\n currentTab,\n setRefTooltip,\n // Query functions\n createEntityActivity,\n updateActivity,\n deleteActivity,\n createReaction,\n deleteReaction,\n }}\n >\n {children}\n </FeedContext.Provider>\n )\n}\n\nexport const useFeedContext = () => {\n const context = useContext(FeedContext)\n if (!context) {\n throw new Error('useFeedContext must be used within a FeedProvider')\n }\n return context\n}\n"],"names":["jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,mBAAmB;AAgEhC,MAAM,cAAc,cAA2C,MAAS;AAEjE,MAAM,eAAe,CAAC,EAAE,UAAU,GAAG,YAA8B;;AACxE,QAAM,EAAE,MAAM,QAAQ,CAAA,MAAO,yBAAyB,EAAE,UAAU,CAAC,MAAM,WAAW,GAAG;AACvF,QAAM,EAAE,WAAe,IAAA,sBAAsB,MAAM,KAAK;AAGxD,QAAM,CAAC,8BAA8B,EAAE,WAAW,gBAAiB,CAAA,IACjE,gCAAgC;AAClC,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAI,0BAA0B;AAC3F,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAI,0BAA0B;AACrF,QAAA,qBAAqB,mBAAmB,mBAAmB;AAEjE,QAAM,uBAAgE,OAAO,SAC3E,MAAM,6BAA6B,IAAI,EAAE,OAAO;AAClD,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAC5C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAEtC,QAAA,CAAC,wBAAwB,IAAI,oCAAoC;AACjE,QAAA,CAAC,wBAAwB,IAAI,oCAAoC;AAEvE,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAC9C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAExC,QAAA,gBAAgB,uBAAuB,UAAU;AAEvD,QAAM,sBAAsB,yBAAyB;AAAA,IACnD,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,YAAY,MAAM;AAAA,EAAA,CACnB;AAED,QAAM,CAAC,YAAY,aAAa,IAAI,SAA4B,IAAI;AACpE,QAAM,OAAO,CAAC,MAAM,eAAe,EAAC,yCAAY;AAChD,QAAM,EAAE,MAAM,mBAAmB,YAAY,kBAAsB,IAAA;AAAA,IACjE,EAAE,YAAY,MAAM,YAAY,UAAU,yCAAY,IAAI,aAAa,MAAM,YAAY;AAAA,IACzF,EAAE,KAAW;AAAA,EACf;AAGA,QAAM,EAAE,MAAM,yBAAyB,CAAA,EAAO,IAAA;AAAA,IAC5C;AAAA,MACE,gBAAgB;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,WAAU,WAAM,SAAS,CAAC,MAAhB,mBAAmB;AAAA,MAC/B;AAAA,MACA,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,CAAC,MAAM,UAAU;AAAA,EAC3B;AAGE,SAAAA,kCAAA;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA,IAAA;AAAA,EACH;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAC5B,QAAA,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mDAAmD;AAAA,EAAA;AAE9D,SAAA;AACT;"}
1
+ {"version":3,"file":"FeedContext.es.js","sources":["../../../../../../src/containers/Feed/context/FeedContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useState } from 'react'\nimport useGetFeedActivitiesData from '../hooks/useGetFeedActivitiesData'\n\n// Queries\nimport {\n useCreateEntityActivityMutation,\n useDeleteActivityMutation,\n useUpdateActivityMutation,\n useCreateReactionToActivityMutation,\n useDeleteReactionToActivityMutation,\n useGetActivityUsersQuery,\n useGetEntityMentionsQuery,\n useGetEntityTooltipQuery,\n} from '@shared/api'\nimport type { SuggestRequest, SuggestResponse } from '@shared/api'\nimport { ActivityUser } from '../helpers/groupMinorActivities'\nimport { DetailsPanelTab, useScopedDetailsPanel } from '@shared/context'\nimport { getFilterActivityTypes } from '@shared/api'\n\nexport const FEED_NEW_COMMENT = '__new__' as const\n\nexport type EditingState = null | typeof FEED_NEW_COMMENT | string\n\n// Add type for the refTooltip\nexport interface RefTooltip {\n id: string | null\n type: string\n name: string\n label: string\n pos: {\n top: number\n left: number\n }\n}\n\nexport type FeedContextProps = {\n children: React.ReactNode\n projectName: string\n entityType: string\n activityTypes?: string[] | null\n entities: any[]\n projectInfo: any\n scope: string\n userName: string\n userFullName: string\n\n // annotations\n annotations?: Record<string, any>\n removeAnnotation?: (id: string) => void\n exportAnnotationComposite?: (id: string) => Promise<Blob | null>\n // editingId state and functions\n editingId: EditingState\n setEditingId: (id: EditingState) => void\n}\n\ninterface FeedContextType extends Omit<FeedContextProps, 'children'> {\n currentTab: DetailsPanelTab\n // activities data props\n activitiesData: any[]\n isLoadingActivities: boolean\n isLoadingNew: boolean\n isLoadingNextPage: boolean\n hasNextPage: boolean\n loadNextPage?: () => Promise<any>\n // refTooltip state and functions\n refTooltip: RefTooltip | null\n setRefTooltip: (tooltip: RefTooltip | null) => void\n // tooltip data\n entityTooltipData: any\n isFetchingTooltip: boolean\n // query functions\n createEntityActivity: (args: any) => Promise<any>\n updateActivity: (args: any) => Promise<any>\n deleteActivity: (args: any) => Promise<any>\n createReaction: (args: any) => Promise<any>\n deleteReaction: (args: any) => Promise<any>\n isUpdatingActivity: boolean\n // users data\n users: ActivityUser[]\n // mentions data\n mentionSuggestionsData: SuggestResponse\n}\n\nconst FeedContext = createContext<FeedContextType | undefined>(undefined)\n\nexport const FeedProvider = ({ children, ...props }: FeedContextProps) => {\n const { data: users = [] } = useGetActivityUsersQuery({ projects: [props.projectName] })\n const { currentTab } = useScopedDetailsPanel(props.scope)\n\n // queries\n const [createEntityActivityMutation, { isLoading: isLoadingCreate }] =\n useCreateEntityActivityMutation()\n const [updateActivityMutation, { isLoading: isLoadingUpdate }] = useUpdateActivityMutation()\n const [deleteActivityMutation, { isLoading: isLoadingDelete }] = useDeleteActivityMutation()\n const isUpdatingActivity = isLoadingCreate || isLoadingUpdate || isLoadingDelete\n\n const createEntityActivity: FeedContextType['createEntityActivity'] = async (args) =>\n await createEntityActivityMutation(args).unwrap()\n const updateActivity: FeedContextType['updateActivity'] = async (args) =>\n await updateActivityMutation(args).unwrap()\n const deleteActivity: FeedContextType['deleteActivity'] = async (args) =>\n await deleteActivityMutation(args).unwrap()\n\n const [createReactionToActivity] = useCreateReactionToActivityMutation()\n const [deleteReactionToActivity] = useDeleteReactionToActivityMutation()\n\n const createReaction: FeedContextType['createReaction'] = async (args) =>\n await createReactionToActivity(args).unwrap()\n const deleteReaction: FeedContextType['deleteReaction'] = async (args) =>\n await deleteReactionToActivity(args).unwrap()\n\n const activityTypes = getFilterActivityTypes(currentTab)\n\n const activitiesDataProps = useGetFeedActivitiesData({\n entities: props.entities,\n filter: currentTab,\n activityTypes: activityTypes,\n projectName: props.projectName,\n entityType: props.entityType,\n })\n\n const [refTooltip, setRefTooltip] = useState<RefTooltip | null>(null)\n const skip = !props.projectName || !refTooltip?.id || refTooltip.type === 'user'\n const { data: entityTooltipData, isFetching: isFetchingTooltip } = useGetEntityTooltipQuery(\n { entityType: refTooltip?.type, entityId: refTooltip?.id, projectName: props.projectName },\n { skip: skip },\n )\n\n // get all versions that can be mentioned\n const { data: mentionSuggestionsData = {} } = useGetEntityMentionsQuery(\n {\n suggestRequest: {\n entityType: props.entityType as SuggestRequest['entityType'],\n entityId: props.entities[0]?.id,\n },\n projectName: props.projectName,\n },\n { skip: !props.editingId },\n )\n\n return (\n <FeedContext.Provider\n value={{\n ...props,\n ...activitiesDataProps,\n mentionSuggestionsData,\n users,\n isUpdatingActivity,\n entityTooltipData,\n isFetchingTooltip,\n refTooltip,\n activityTypes,\n currentTab,\n setRefTooltip,\n // Query functions\n createEntityActivity,\n updateActivity,\n deleteActivity,\n createReaction,\n deleteReaction,\n }}\n >\n {children}\n </FeedContext.Provider>\n )\n}\n\nexport const useFeedContext = () => {\n const context = useContext(FeedContext)\n if (!context) {\n throw new Error('useFeedContext must be used within a FeedProvider')\n }\n return context\n}\n"],"names":["jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,MAAM,mBAAmB;AAgEhC,MAAM,cAAc,cAA2C,MAAS;AAEjE,MAAM,eAAe,CAAC,EAAE,UAAU,GAAG,YAA8B;;AACxE,QAAM,EAAE,MAAM,QAAQ,CAAA,MAAO,yBAAyB,EAAE,UAAU,CAAC,MAAM,WAAW,GAAG;AACvF,QAAM,EAAE,WAAe,IAAA,sBAAsB,MAAM,KAAK;AAGxD,QAAM,CAAC,8BAA8B,EAAE,WAAW,gBAAiB,CAAA,IACjE,gCAAgC;AAClC,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAI,0BAA0B;AAC3F,QAAM,CAAC,wBAAwB,EAAE,WAAW,gBAAiB,CAAA,IAAI,0BAA0B;AACrF,QAAA,qBAAqB,mBAAmB,mBAAmB;AAEjE,QAAM,uBAAgE,OAAO,SAC3E,MAAM,6BAA6B,IAAI,EAAE,OAAO;AAClD,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAC5C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,uBAAuB,IAAI,EAAE,OAAO;AAEtC,QAAA,CAAC,wBAAwB,IAAI,oCAAoC;AACjE,QAAA,CAAC,wBAAwB,IAAI,oCAAoC;AAEvE,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAC9C,QAAM,iBAAoD,OAAO,SAC/D,MAAM,yBAAyB,IAAI,EAAE,OAAO;AAExC,QAAA,gBAAgB,uBAAuB,UAAU;AAEvD,QAAM,sBAAsB,yBAAyB;AAAA,IACnD,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,YAAY,MAAM;AAAA,EAAA,CACnB;AAED,QAAM,CAAC,YAAY,aAAa,IAAI,SAA4B,IAAI;AAC9D,QAAA,OAAO,CAAC,MAAM,eAAe,EAAC,yCAAY,OAAM,WAAW,SAAS;AAC1E,QAAM,EAAE,MAAM,mBAAmB,YAAY,kBAAsB,IAAA;AAAA,IACjE,EAAE,YAAY,yCAAY,MAAM,UAAU,yCAAY,IAAI,aAAa,MAAM,YAAY;AAAA,IACzF,EAAE,KAAW;AAAA,EACf;AAGA,QAAM,EAAE,MAAM,yBAAyB,CAAA,EAAO,IAAA;AAAA,IAC5C;AAAA,MACE,gBAAgB;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,WAAU,WAAM,SAAS,CAAC,MAAhB,mBAAmB;AAAA,MAC/B;AAAA,MACA,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,CAAC,MAAM,UAAU;AAAA,EAC3B;AAGE,SAAAA,kCAAA;AAAA,IAAC,YAAY;AAAA,IAAZ;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MAEC;AAAA,IAAA;AAAA,EACH;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAC5B,QAAA,UAAU,WAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACN,UAAA,IAAI,MAAM,mDAAmD;AAAA,EAAA;AAE9D,SAAA;AACT;"}
@@ -119,13 +119,7 @@ const ProjectTreeTable = ({
119
119
  extraColumns,
120
120
  excluded: excludedColumns
121
121
  }),
122
- [
123
- // columnAttribs,
124
- // showHierarchy,
125
- // options,
126
- extraColumns
127
- // excludedColumns
128
- ]
122
+ [columnAttribs, showHierarchy, options, extraColumns, excludedColumns]
129
123
  );
130
124
  const table = reactTable.useReactTable({
131
125
  data: showLoadingRows ? loadingRows : tableData,
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectTreeTable.cjs.js","sources":["../../../../../src/containers/ProjectTreeTable/ProjectTreeTable.tsx"],"sourcesContent":["import { useMemo, useRef, useEffect, memo, CSSProperties } from 'react'\nimport { useVirtualizer, VirtualItem, Virtualizer } from '@tanstack/react-virtual'\n// TanStack Table imports\nimport {\n useReactTable,\n getCoreRowModel,\n getFilteredRowModel,\n getExpandedRowModel,\n filterFns,\n flexRender,\n Row,\n getSortedRowModel,\n Cell,\n Column,\n Table,\n Header,\n HeaderGroup,\n RowData,\n} from '@tanstack/react-table'\n\n// Utility imports\nimport clsx from 'clsx'\n\n// Type imports\nimport type { TableRow } from './types/table'\n\n// Component imports\nimport buildTreeTableColumns, {\n BuildTreeTableColumnsProps,\n DefaultColumns,\n TreeTableExtraColumn,\n} from './buildTreeTableColumns'\nimport * as Styled from './ProjectTreeTable.styled'\nimport HeaderActionButton from './components/HeaderActionButton'\nimport EmptyPlaceholder from '../../components/EmptyPlaceholder'\n\n// Context imports\nimport { useCellEditing } from './context/CellEditingContext'\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './context/SelectionCellsContext'\nimport { ClipboardProvider } from './context/ClipboardContext'\nimport { useSelectedRowsContext } from './context/SelectedRowsContext'\nimport { useColumnSettingsContext } from './context/ColumnSettingsContext'\n\n// Hook imports\nimport useCustomColumnWidthVars from './hooks/useCustomColumnWidthVars'\nimport usePrefetchFolderTasks from './hooks/usePrefetchFolderTasks'\nimport useCellContextMenu from './hooks/useCellContextMenu'\nimport useColumnVirtualization from './hooks/useColumnVirtualization'\nimport useKeyboardNavigation from './hooks/useKeyboardNavigation'\n\n// Utility function imports\nimport { getCellId } from './utils/cellUtils'\nimport { generateLoadingRows, generateDummyAttributes } from './utils/loadingUtils'\nimport { createPortal } from 'react-dom'\nimport { Icon } from '@ynput/ayon-react-components'\nimport { AttributeEnumItem, ProjectTableAttribute, BuiltInFieldOptions } from './types'\nimport { ToggleExpandAll, useProjectTableContext } from './context/ProjectTableContext'\nimport { getReadOnlyLists, getTableFieldOptions } from './utils'\nimport { UpdateTableEntities } from './hooks/useUpdateTableData'\n\ndeclare module '@tanstack/react-table' {\n interface TableMeta<TData extends RowData> {\n options: BuiltInFieldOptions\n readOnly: ProjectTreeTableProps['readOnly']\n projectName: string\n updateEntities: UpdateTableEntities\n toggleExpandAll: ToggleExpandAll\n }\n}\n\n//These are the important styles to make sticky column pinning work!\n//Apply styles like this using your CSS strategy of choice with this kind of logic to head cells, data cells, footer cells, etc.\n//View the index.css file for more needed styles such as border-collapse: separate\nconst getCommonPinningStyles = (column: Column<TableRow, unknown>): CSSProperties => {\n const isPinned = column.getIsPinned()\n\n return {\n left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n position: isPinned ? 'sticky' : 'relative',\n width: column.getSize(),\n zIndex: isPinned ? 100 : 0,\n }\n}\n\nexport interface ProjectTreeTableProps extends React.HTMLAttributes<HTMLDivElement> {\n scope: string\n sliceId: string\n fetchMoreOnBottomReached: (element: HTMLDivElement | null) => void\n onOpenNew?: (type: 'folder' | 'task') => void\n readOnly?: (DefaultColumns | string)[]\n excludedColumns?: (DefaultColumns | string)[]\n extraColumns?: TreeTableExtraColumn[]\n pt?: {\n container?: React.HTMLAttributes<HTMLDivElement>\n head?: Partial<TableHeadProps>\n }\n}\n\nexport const ProjectTreeTable = ({\n scope,\n sliceId,\n fetchMoreOnBottomReached,\n onOpenNew,\n readOnly,\n excludedColumns,\n extraColumns,\n pt,\n ...props\n}: ProjectTreeTableProps) => {\n const {\n columnVisibility,\n columnVisibilityUpdater,\n columnPinning,\n columnPinningUpdater,\n columnOrder,\n columnOrderUpdater,\n columnSizing,\n columnSizingUpdater,\n } = useColumnSettingsContext()\n\n const {\n projectInfo,\n tableData,\n attribFields,\n entitiesMap,\n users,\n isLoading,\n isInitialized,\n expanded,\n projectName,\n updateExpanded,\n toggleExpandAll,\n sorting,\n updateSorting,\n showHierarchy,\n } = useProjectTableContext()\n\n const { statuses = [], folderTypes = [], taskTypes = [], tags = [] } = projectInfo || {}\n const options: BuiltInFieldOptions = useMemo(\n () =>\n getTableFieldOptions({\n users,\n statuses,\n folderTypes,\n taskTypes,\n tags,\n }),\n [users, statuses, folderTypes, taskTypes],\n )\n\n //The virtualizer needs to know the scrollable container element\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n // Selection context\n const { registerGrid } = useSelectionCellsContext()\n\n //a check on mount and after a fetch to see if the table is already scrolled to the bottom and immediately needs to fetch more data\n useEffect(() => {\n fetchMoreOnBottomReached(tableContainerRef.current)\n }, [fetchMoreOnBottomReached])\n\n // generate loading attrib and rows\n const { loadingAttrib, loadingRows } = useMemo(() => {\n // count the number of children in tbody\n const tableRowsCount = tableContainerRef.current?.querySelectorAll('tbody tr').length || 0\n const loadingAttrib = generateDummyAttributes()\n const loadingRows = generateLoadingRows(\n attribFields,\n showHierarchy && tableData.length > 0 ? Math.min(tableRowsCount, 50) : 50,\n )\n return { loadingAttrib, loadingRows }\n }, [attribFields, tableData, showHierarchy, tableContainerRef.current])\n\n const showLoadingRows = !isInitialized || isLoading\n\n // Format readonly columns and attributes\n const { readOnlyColumns, readOnlyAttribs } = useMemo(\n () => getReadOnlyLists(attribFields, readOnly),\n [attribFields, readOnly],\n )\n\n const { updateEntities } = useCellEditing()\n\n const columnAttribs = useMemo(\n () => (isInitialized ? attribFields : loadingAttrib),\n [attribFields, loadingAttrib, isInitialized],\n )\n const columns = useMemo(\n () =>\n buildTreeTableColumns({\n attribs: columnAttribs,\n showHierarchy,\n options,\n extraColumns,\n excluded: excludedColumns,\n }),\n [\n // columnAttribs,\n // showHierarchy,\n // options,\n extraColumns,\n // excludedColumns\n ],\n )\n\n const table = useReactTable({\n data: showLoadingRows ? loadingRows : tableData,\n columns,\n defaultColumn: {\n minSize: 50,\n size: 150,\n },\n enableRowSelection: true, //enable row selection for all rows\n getRowId: (row) => row.id,\n enableSubRowSelection: false, //disable sub row selection\n getSubRows: (row) => row.subRows,\n getRowCanExpand: () => true,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n filterFromLeafRows: true,\n // EXPANDABLE\n onExpandedChange: updateExpanded,\n // SORTING\n getSortedRowModel: getSortedRowModel(),\n onSortingChange: updateSorting,\n columnResizeMode: 'onChange',\n onColumnPinningChange: columnPinningUpdater,\n onColumnSizingChange: columnSizingUpdater,\n onColumnVisibilityChange: columnVisibilityUpdater,\n onColumnOrderChange: columnOrderUpdater,\n // @ts-ignore\n filterFns,\n state: {\n expanded,\n sorting,\n columnPinning: {\n left: [ROW_SELECTION_COLUMN_ID, ...(columnPinning.left || [])],\n right: columnPinning.right,\n },\n columnSizing,\n columnVisibility,\n columnOrder,\n },\n enableSorting: true,\n meta: {\n projectName,\n options,\n readOnly: readOnlyColumns,\n updateEntities,\n toggleExpandAll,\n },\n })\n\n const { rows } = table.getRowModel()\n\n // Register grid structure with selection context when rows or columns change\n useEffect(() => {\n const rowIds = rows.map((row) => row.id)\n const colIds = table.getAllLeafColumns().map((col) => col.id)\n const colIdsSortedByPinning = [...colIds].sort((a, b) => {\n if (ROW_SELECTION_COLUMN_ID === b) return 1\n const colA = columnPinning.left?.includes(a) ? 0 : 1\n const colB = columnPinning.left?.includes(b) ? 0 : 1\n return colA - colB\n })\n\n registerGrid(rowIds, colIdsSortedByPinning)\n }, [rows, table.getAllLeafColumns(), columnPinning, ROW_SELECTION_COLUMN_ID, registerGrid])\n\n const visibleColumns = table.getVisibleLeafColumns()\n\n // Use the column virtualization hook\n const { columnVirtualizer, virtualPaddingLeft, virtualPaddingRight } = useColumnVirtualization({\n visibleColumns,\n tableContainerRef,\n columnPinning,\n })\n\n const columnSizeVars = useCustomColumnWidthVars(table, columnSizing)\n\n const attribByField = useMemo(() => {\n return attribFields.reduce((acc: Record<string, AttributeEnumItem[]>, attrib) => {\n if (attrib.data?.enum?.length) {\n acc[attrib.name] = attrib.data?.enum\n }\n return acc\n }, {})\n }, [attribFields])\n\n return (\n <ClipboardProvider\n entitiesMap={entitiesMap}\n columnEnums={{ ...options, ...attribByField }}\n columnReadOnly={readOnlyAttribs}\n >\n <Styled.TableWrapper {...props}>\n <Styled.TableContainer\n ref={tableContainerRef}\n style={{ height: '100%', padding: 0 }}\n onScroll={(e) => fetchMoreOnBottomReached(e.currentTarget)}\n {...pt?.container}\n className={clsx('table-container', pt?.container?.className)}\n >\n <table\n style={{\n display: 'grid',\n borderCollapse: 'collapse',\n userSelect: 'none',\n ...columnSizeVars,\n width: table.getTotalSize(),\n }}\n >\n <TableHead\n columnVirtualizer={columnVirtualizer}\n table={table}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n {...pt?.head}\n />\n <TableBody\n columnVirtualizer={columnVirtualizer}\n table={table}\n tableContainerRef={tableContainerRef}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n showHierarchy={showHierarchy}\n attribs={attribFields}\n onOpenNew={onOpenNew}\n />\n </table>\n </Styled.TableContainer>\n </Styled.TableWrapper>\n </ClipboardProvider>\n )\n}\n\ninterface TableHeadProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHead = ({\n columnVirtualizer,\n table,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n ...props\n}: TableHeadProps) => {\n return (\n <Styled.TableHeader {...props}>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableHeadRow\n key={headerGroup.id}\n columnVirtualizer={columnVirtualizer}\n headerGroup={headerGroup}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n />\n ))}\n </Styled.TableHeader>\n )\n}\n\ninterface TableHeadRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n headerGroup: HeaderGroup<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHeadRow = ({\n columnVirtualizer,\n headerGroup,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n}: TableHeadRowProps) => {\n const virtualColumns = columnVirtualizer.getVirtualItems()\n return (\n <Styled.ColumnHeader key={headerGroup.id} style={{ display: 'flex' }}>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((virtualColumn) => {\n const header = headerGroup.headers[virtualColumn.index]\n\n return (\n <TableHeadCell\n key={header.id}\n header={header}\n isLoading={isLoading}\n isReadOnly={readOnlyColumns?.includes(header.id)}\n canSort={header.column.getCanSort()}\n canFilter={header.column.getCanFilter()}\n canHide={header.column.getCanHide()}\n canPin={header.column.getCanPin()}\n canResize={header.column.getCanResize()}\n />\n )\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.ColumnHeader>\n )\n}\n\ninterface TableHeadCellProps {\n header: Header<TableRow, unknown>\n isLoading: boolean\n canSort?: boolean\n canFilter?: boolean\n canHide?: boolean\n canPin?: boolean\n canResize?: boolean\n isReadOnly?: boolean\n}\n\nconst TableHeadCell = ({\n header,\n isLoading,\n canFilter,\n canHide,\n canSort,\n canPin,\n canResize,\n isReadOnly,\n}: TableHeadCellProps) => {\n const { column } = header\n\n return (\n <Styled.HeaderCell\n className={clsx(header.id, 'shimmer-dark', {\n loading: isLoading,\n 'last-pinned-left': column.getIsPinned() === 'left' && column.getIsLastColumn('left'),\n })}\n key={header.id}\n style={{\n ...getCommonPinningStyles(column),\n width: `calc(var(--header-${header?.id}-size) * 1px)`,\n }}\n >\n {header.isPlaceholder ? null : (\n <Styled.TableCellContent className={clsx('bold')}>\n {flexRender(column.columnDef.header, header.getContext())}\n {isReadOnly && (\n <Icon icon=\"lock\" data-tooltip={'You only have permission to read this column.'} />\n )}\n\n <Styled.HeaderButtons className=\"actions\">\n {/* COLUMN HIDING */}\n {canHide && (\n <HeaderActionButton\n icon=\"visibility_off\"\n selected={!column.getIsVisible()}\n onClick={column.getToggleVisibilityHandler()}\n />\n )}\n {/* COLUMN PINNING */}\n {canPin && (\n <HeaderActionButton\n icon=\"push_pin\"\n selected={header.column.getIsPinned() === 'left'}\n onClick={() => {\n if (header.column.getIsPinned() === 'left') {\n header.column.pin(false)\n } else {\n header.column.pin('left')\n }\n }}\n />\n )}\n\n {/* COLUMN SORTING */}\n {canSort && (\n <HeaderActionButton\n icon={'sort'}\n style={{\n transform: (column.getIsSorted() as string) === 'asc' ? 'scaleY(-1)' : undefined,\n }}\n onClick={column.getToggleSortingHandler()}\n selected={!!column.getIsSorted()}\n />\n )}\n </Styled.HeaderButtons>\n {canResize && (\n <Styled.ResizedHandler\n {...{\n onDoubleClick: () => column.resetSize(),\n onMouseDown: header.getResizeHandler(),\n onTouchStart: header.getResizeHandler(),\n className: clsx('resize-handle', {\n resizing: column.getIsResizing(),\n }),\n }}\n />\n )}\n </Styled.TableCellContent>\n )}\n </Styled.HeaderCell>\n )\n}\n\ninterface TableBodyProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n tableContainerRef: React.RefObject<HTMLDivElement>\n showHierarchy: boolean\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n attribs: ProjectTableAttribute[]\n onOpenNew?: (type: 'folder' | 'task') => void\n}\n\nconst TableBody = ({\n columnVirtualizer,\n table,\n tableContainerRef,\n showHierarchy,\n virtualPaddingLeft,\n virtualPaddingRight,\n attribs,\n onOpenNew,\n}: TableBodyProps) => {\n const { handleTableBodyContextMenu } = useCellContextMenu({ attribs, onOpenNew })\n\n const { handlePreFetchTasks } = usePrefetchFolderTasks()\n\n const { rows } = table.getRowModel()\n\n const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({\n count: rows.length,\n estimateSize: () => (showHierarchy ? 36 : 40), //estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n //measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const virtualRows = rowVirtualizer.getVirtualItems()\n\n useKeyboardNavigation()\n\n return virtualRows.length ? (\n <tbody\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n position: 'relative',\n display: 'grid',\n }}\n onContextMenu={handleTableBodyContextMenu}\n onMouseOver={(e) => {\n handlePreFetchTasks(e)\n }}\n >\n {virtualRows.map((virtualRow) => {\n const row = rows[virtualRow.index] as Row<TableRow>\n return (\n <TableBodyRow\n key={row.id}\n columnVirtualizer={columnVirtualizer}\n row={row}\n rowVirtualizer={rowVirtualizer}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n virtualRow={virtualRow}\n showHierarchy={showHierarchy}\n />\n )\n })}\n </tbody>\n ) : (\n tableContainerRef.current &&\n createPortal(<EmptyPlaceholder message=\"No items found\" />, tableContainerRef.current)\n )\n}\n\ninterface TableBodyRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n row: Row<TableRow>\n rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n virtualRow: VirtualItem\n showHierarchy: boolean\n}\n\nconst TableBodyRow = ({\n columnVirtualizer,\n row,\n rowVirtualizer,\n virtualPaddingLeft,\n virtualPaddingRight,\n virtualRow,\n showHierarchy,\n}: TableBodyRowProps) => {\n // We should do this so that we don't re-render every time anything in projectTableContext changes\n const visibleCells = row.getVisibleCells()\n const virtualColumns = columnVirtualizer.getVirtualItems()\n\n return (\n <Styled.TR\n data-index={virtualRow.index} //needed for dynamic row height measurement\n ref={(node) => rowVirtualizer.measureElement(node)} //measure dynamic row height\n key={row.id}\n style={{\n transform: `translateY(${virtualRow.start}px)`, //this should always be a `style` as it changes on scroll\n }}\n >\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((vc) => {\n const cell = visibleCells[vc.index]\n const cellId = getCellId(row.id, cell.column.id)\n return (\n <TableCellMemo\n cell={cell}\n cellId={cellId}\n rowId={row.id}\n key={cell.id}\n showHierarchy={showHierarchy}\n />\n )\n })}\n\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.TR>\n )\n}\n\ninterface TableCellProps {\n cell: Cell<TableRow, unknown>\n cellId: string\n rowId: string\n className?: string\n showHierarchy: boolean\n}\n\nconst TableCell = ({ cell, rowId, cellId, className, showHierarchy, ...props }: TableCellProps) => {\n const {\n isCellSelected,\n isCellFocused,\n startSelection,\n extendSelection,\n endSelection,\n selectCell,\n getCellBorderClasses,\n } = useSelectionCellsContext()\n\n const { isRowSelected } = useSelectedRowsContext()\n\n const { isEditing } = useCellEditing()\n\n const borderClasses = getCellBorderClasses(cellId)\n\n const isPinned = cell.column.getIsPinned()\n const isLastLeftPinnedColumn = isPinned === 'left' && cell.column.getIsLastColumn('left')\n const isRowSelectionColumn = cell.column.id === ROW_SELECTION_COLUMN_ID\n\n return (\n <Styled.TableCell\n {...props}\n tabIndex={0}\n key={cell.id}\n $isLastPinned={isLastLeftPinnedColumn} // is this column the last pinned column? Custom styling for borders.\n className={clsx(\n cell.column.id,\n {\n selected: isCellSelected(cellId),\n focused: isCellFocused(cellId),\n editing: isEditing(cellId),\n 'last-pinned-left': isLastLeftPinnedColumn,\n 'selected-row': isRowSelected(rowId),\n task: cell.row.original.entityType === 'task',\n },\n className,\n ...borderClasses,\n )}\n style={{\n ...getCommonPinningStyles(cell.column),\n width: `calc(var(--col-${cell.column.id}-size) * 1px)`,\n height: showHierarchy ? 36 : 40,\n }}\n onMouseDown={(e) => {\n // Only process left clicks (button 0), ignore right clicks\n if (e.button !== 0) return\n\n // check we are not clicking on expander\n if ((e.target as HTMLElement).closest('.expander')) return\n const additive = e.metaKey || e.ctrlKey || isRowSelectionColumn\n if (e.shiftKey) {\n // Shift+click extends selection from anchor cell\n selectCell(cellId, additive, true) // true for range selection\n } else {\n // Normal click starts a new selection\n startSelection(cellId, additive)\n }\n }}\n onMouseOver={(e) => {\n if (e.buttons === 1) {\n // Left button is pressed during mouse move - drag selection\n extendSelection(cellId, isRowSelectionColumn)\n }\n }}\n onMouseUp={() => {\n endSelection(cellId)\n }}\n onDoubleClick={(e) => {\n if (cell.column.id === 'name') {\n // select the row by selecting the row-selection cell\n const rowSelectionCellId = getCellId(cell.row.id, ROW_SELECTION_COLUMN_ID)\n if (!isCellSelected(rowSelectionCellId)) {\n const additive = e.metaKey || e.ctrlKey\n selectCell(rowSelectionCellId, additive, false)\n }\n }\n }}\n onContextMenu={(e) => {\n e.preventDefault()\n // if the cell is not selected, select it and deselect all others\n if (!isCellSelected(cellId)) {\n selectCell(cellId, false, false)\n }\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Styled.TableCell>\n )\n}\n\nconst TableCellMemo = memo(TableCell)\n"],"names":["useColumnSettingsContext","useProjectTableContext","useMemo","getTableFieldOptions","useRef","useSelectionCellsContext","useEffect","_a","loadingAttrib","generateDummyAttributes","loadingRows","generateLoadingRows","getReadOnlyLists","useCellEditing","buildTreeTableColumns","useReactTable","getCoreRowModel","getFilteredRowModel","getExpandedRowModel","getSortedRowModel","filterFns","ROW_SELECTION_COLUMN_ID","jsx","ClipboardProvider","Styled.TableWrapper","Styled.TableContainer","jsxs","Styled.TableHeader","Styled.ColumnHeader","Styled.HeaderCell","Styled.TableCellContent","flexRender","Icon","Styled.HeaderButtons","Styled.ResizedHandler","usePrefetchFolderTasks","useVirtualizer","createPortal","EmptyPlaceholder","Styled.TR","getCellId","useSelectedRowsContext","createElement","Styled.TableCell","memo"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectTreeTable.cjs.js","sources":["../../../../../src/containers/ProjectTreeTable/ProjectTreeTable.tsx"],"sourcesContent":["import { useMemo, useRef, useEffect, memo, CSSProperties } from 'react'\nimport { useVirtualizer, VirtualItem, Virtualizer } from '@tanstack/react-virtual'\n// TanStack Table imports\nimport {\n useReactTable,\n getCoreRowModel,\n getFilteredRowModel,\n getExpandedRowModel,\n filterFns,\n flexRender,\n Row,\n getSortedRowModel,\n Cell,\n Column,\n Table,\n Header,\n HeaderGroup,\n RowData,\n} from '@tanstack/react-table'\n\n// Utility imports\nimport clsx from 'clsx'\n\n// Type imports\nimport type { TableRow } from './types/table'\n\n// Component imports\nimport buildTreeTableColumns, {\n BuildTreeTableColumnsProps,\n DefaultColumns,\n TreeTableExtraColumn,\n} from './buildTreeTableColumns'\nimport * as Styled from './ProjectTreeTable.styled'\nimport HeaderActionButton from './components/HeaderActionButton'\nimport EmptyPlaceholder from '../../components/EmptyPlaceholder'\n\n// Context imports\nimport { useCellEditing } from './context/CellEditingContext'\nimport { ROW_SELECTION_COLUMN_ID, useSelectionCellsContext } from './context/SelectionCellsContext'\nimport { ClipboardProvider } from './context/ClipboardContext'\nimport { useSelectedRowsContext } from './context/SelectedRowsContext'\nimport { useColumnSettingsContext } from './context/ColumnSettingsContext'\n\n// Hook imports\nimport useCustomColumnWidthVars from './hooks/useCustomColumnWidthVars'\nimport usePrefetchFolderTasks from './hooks/usePrefetchFolderTasks'\nimport useCellContextMenu from './hooks/useCellContextMenu'\nimport useColumnVirtualization from './hooks/useColumnVirtualization'\nimport useKeyboardNavigation from './hooks/useKeyboardNavigation'\n\n// Utility function imports\nimport { getCellId } from './utils/cellUtils'\nimport { generateLoadingRows, generateDummyAttributes } from './utils/loadingUtils'\nimport { createPortal } from 'react-dom'\nimport { Icon } from '@ynput/ayon-react-components'\nimport { AttributeEnumItem, ProjectTableAttribute, BuiltInFieldOptions } from './types'\nimport { ToggleExpandAll, useProjectTableContext } from './context/ProjectTableContext'\nimport { getReadOnlyLists, getTableFieldOptions } from './utils'\nimport { UpdateTableEntities } from './hooks/useUpdateTableData'\n\ndeclare module '@tanstack/react-table' {\n interface TableMeta<TData extends RowData> {\n options: BuiltInFieldOptions\n readOnly: ProjectTreeTableProps['readOnly']\n projectName: string\n updateEntities: UpdateTableEntities\n toggleExpandAll: ToggleExpandAll\n }\n}\n\n//These are the important styles to make sticky column pinning work!\n//Apply styles like this using your CSS strategy of choice with this kind of logic to head cells, data cells, footer cells, etc.\n//View the index.css file for more needed styles such as border-collapse: separate\nconst getCommonPinningStyles = (column: Column<TableRow, unknown>): CSSProperties => {\n const isPinned = column.getIsPinned()\n\n return {\n left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined,\n right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined,\n position: isPinned ? 'sticky' : 'relative',\n width: column.getSize(),\n zIndex: isPinned ? 100 : 0,\n }\n}\n\nexport interface ProjectTreeTableProps extends React.HTMLAttributes<HTMLDivElement> {\n scope: string\n sliceId: string\n fetchMoreOnBottomReached: (element: HTMLDivElement | null) => void\n onOpenNew?: (type: 'folder' | 'task') => void\n readOnly?: (DefaultColumns | string)[]\n excludedColumns?: (DefaultColumns | string)[]\n extraColumns?: TreeTableExtraColumn[]\n pt?: {\n container?: React.HTMLAttributes<HTMLDivElement>\n head?: Partial<TableHeadProps>\n }\n}\n\nexport const ProjectTreeTable = ({\n scope,\n sliceId,\n fetchMoreOnBottomReached,\n onOpenNew,\n readOnly,\n excludedColumns,\n extraColumns,\n pt,\n ...props\n}: ProjectTreeTableProps) => {\n const {\n columnVisibility,\n columnVisibilityUpdater,\n columnPinning,\n columnPinningUpdater,\n columnOrder,\n columnOrderUpdater,\n columnSizing,\n columnSizingUpdater,\n } = useColumnSettingsContext()\n\n const {\n projectInfo,\n tableData,\n attribFields,\n entitiesMap,\n users,\n isLoading,\n isInitialized,\n expanded,\n projectName,\n updateExpanded,\n toggleExpandAll,\n sorting,\n updateSorting,\n showHierarchy,\n } = useProjectTableContext()\n\n const { statuses = [], folderTypes = [], taskTypes = [], tags = [] } = projectInfo || {}\n const options: BuiltInFieldOptions = useMemo(\n () =>\n getTableFieldOptions({\n users,\n statuses,\n folderTypes,\n taskTypes,\n tags,\n }),\n [users, statuses, folderTypes, taskTypes],\n )\n\n //The virtualizer needs to know the scrollable container element\n const tableContainerRef = useRef<HTMLDivElement>(null)\n\n // Selection context\n const { registerGrid } = useSelectionCellsContext()\n\n //a check on mount and after a fetch to see if the table is already scrolled to the bottom and immediately needs to fetch more data\n useEffect(() => {\n fetchMoreOnBottomReached(tableContainerRef.current)\n }, [fetchMoreOnBottomReached])\n\n // generate loading attrib and rows\n const { loadingAttrib, loadingRows } = useMemo(() => {\n // count the number of children in tbody\n const tableRowsCount = tableContainerRef.current?.querySelectorAll('tbody tr').length || 0\n const loadingAttrib = generateDummyAttributes()\n const loadingRows = generateLoadingRows(\n attribFields,\n showHierarchy && tableData.length > 0 ? Math.min(tableRowsCount, 50) : 50,\n )\n return { loadingAttrib, loadingRows }\n }, [attribFields, tableData, showHierarchy, tableContainerRef.current])\n\n const showLoadingRows = !isInitialized || isLoading\n\n // Format readonly columns and attributes\n const { readOnlyColumns, readOnlyAttribs } = useMemo(\n () => getReadOnlyLists(attribFields, readOnly),\n [attribFields, readOnly],\n )\n\n const { updateEntities } = useCellEditing()\n\n const columnAttribs = useMemo(\n () => (isInitialized ? attribFields : loadingAttrib),\n [attribFields, loadingAttrib, isInitialized],\n )\n const columns = useMemo(\n () =>\n buildTreeTableColumns({\n attribs: columnAttribs,\n showHierarchy,\n options,\n extraColumns,\n excluded: excludedColumns,\n }),\n [columnAttribs, showHierarchy, options, extraColumns, excludedColumns],\n )\n\n const table = useReactTable({\n data: showLoadingRows ? loadingRows : tableData,\n columns,\n defaultColumn: {\n minSize: 50,\n size: 150,\n },\n enableRowSelection: true, //enable row selection for all rows\n getRowId: (row) => row.id,\n enableSubRowSelection: false, //disable sub row selection\n getSubRows: (row) => row.subRows,\n getRowCanExpand: () => true,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getExpandedRowModel: getExpandedRowModel(),\n filterFromLeafRows: true,\n // EXPANDABLE\n onExpandedChange: updateExpanded,\n // SORTING\n getSortedRowModel: getSortedRowModel(),\n onSortingChange: updateSorting,\n columnResizeMode: 'onChange',\n onColumnPinningChange: columnPinningUpdater,\n onColumnSizingChange: columnSizingUpdater,\n onColumnVisibilityChange: columnVisibilityUpdater,\n onColumnOrderChange: columnOrderUpdater,\n // @ts-ignore\n filterFns,\n state: {\n expanded,\n sorting,\n columnPinning: {\n left: [ROW_SELECTION_COLUMN_ID, ...(columnPinning.left || [])],\n right: columnPinning.right,\n },\n columnSizing,\n columnVisibility,\n columnOrder,\n },\n enableSorting: true,\n meta: {\n projectName,\n options,\n readOnly: readOnlyColumns,\n updateEntities,\n toggleExpandAll,\n },\n })\n\n const { rows } = table.getRowModel()\n\n // Register grid structure with selection context when rows or columns change\n useEffect(() => {\n const rowIds = rows.map((row) => row.id)\n const colIds = table.getAllLeafColumns().map((col) => col.id)\n const colIdsSortedByPinning = [...colIds].sort((a, b) => {\n if (ROW_SELECTION_COLUMN_ID === b) return 1\n const colA = columnPinning.left?.includes(a) ? 0 : 1\n const colB = columnPinning.left?.includes(b) ? 0 : 1\n return colA - colB\n })\n\n registerGrid(rowIds, colIdsSortedByPinning)\n }, [rows, table.getAllLeafColumns(), columnPinning, ROW_SELECTION_COLUMN_ID, registerGrid])\n\n const visibleColumns = table.getVisibleLeafColumns()\n\n // Use the column virtualization hook\n const { columnVirtualizer, virtualPaddingLeft, virtualPaddingRight } = useColumnVirtualization({\n visibleColumns,\n tableContainerRef,\n columnPinning,\n })\n\n const columnSizeVars = useCustomColumnWidthVars(table, columnSizing)\n\n const attribByField = useMemo(() => {\n return attribFields.reduce((acc: Record<string, AttributeEnumItem[]>, attrib) => {\n if (attrib.data?.enum?.length) {\n acc[attrib.name] = attrib.data?.enum\n }\n return acc\n }, {})\n }, [attribFields])\n\n return (\n <ClipboardProvider\n entitiesMap={entitiesMap}\n columnEnums={{ ...options, ...attribByField }}\n columnReadOnly={readOnlyAttribs}\n >\n <Styled.TableWrapper {...props}>\n <Styled.TableContainer\n ref={tableContainerRef}\n style={{ height: '100%', padding: 0 }}\n onScroll={(e) => fetchMoreOnBottomReached(e.currentTarget)}\n {...pt?.container}\n className={clsx('table-container', pt?.container?.className)}\n >\n <table\n style={{\n display: 'grid',\n borderCollapse: 'collapse',\n userSelect: 'none',\n ...columnSizeVars,\n width: table.getTotalSize(),\n }}\n >\n <TableHead\n columnVirtualizer={columnVirtualizer}\n table={table}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n {...pt?.head}\n />\n <TableBody\n columnVirtualizer={columnVirtualizer}\n table={table}\n tableContainerRef={tableContainerRef}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n showHierarchy={showHierarchy}\n attribs={attribFields}\n onOpenNew={onOpenNew}\n />\n </table>\n </Styled.TableContainer>\n </Styled.TableWrapper>\n </ClipboardProvider>\n )\n}\n\ninterface TableHeadProps extends React.HTMLAttributes<HTMLTableSectionElement> {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHead = ({\n columnVirtualizer,\n table,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n ...props\n}: TableHeadProps) => {\n return (\n <Styled.TableHeader {...props}>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableHeadRow\n key={headerGroup.id}\n columnVirtualizer={columnVirtualizer}\n headerGroup={headerGroup}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n isLoading={isLoading}\n readOnlyColumns={readOnlyColumns}\n />\n ))}\n </Styled.TableHeader>\n )\n}\n\ninterface TableHeadRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n headerGroup: HeaderGroup<TableRow>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n isLoading: boolean\n readOnlyColumns?: string[]\n}\n\nconst TableHeadRow = ({\n columnVirtualizer,\n headerGroup,\n virtualPaddingLeft,\n virtualPaddingRight,\n isLoading,\n readOnlyColumns,\n}: TableHeadRowProps) => {\n const virtualColumns = columnVirtualizer.getVirtualItems()\n return (\n <Styled.ColumnHeader key={headerGroup.id} style={{ display: 'flex' }}>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((virtualColumn) => {\n const header = headerGroup.headers[virtualColumn.index]\n\n return (\n <TableHeadCell\n key={header.id}\n header={header}\n isLoading={isLoading}\n isReadOnly={readOnlyColumns?.includes(header.id)}\n canSort={header.column.getCanSort()}\n canFilter={header.column.getCanFilter()}\n canHide={header.column.getCanHide()}\n canPin={header.column.getCanPin()}\n canResize={header.column.getCanResize()}\n />\n )\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <th style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.ColumnHeader>\n )\n}\n\ninterface TableHeadCellProps {\n header: Header<TableRow, unknown>\n isLoading: boolean\n canSort?: boolean\n canFilter?: boolean\n canHide?: boolean\n canPin?: boolean\n canResize?: boolean\n isReadOnly?: boolean\n}\n\nconst TableHeadCell = ({\n header,\n isLoading,\n canFilter,\n canHide,\n canSort,\n canPin,\n canResize,\n isReadOnly,\n}: TableHeadCellProps) => {\n const { column } = header\n\n return (\n <Styled.HeaderCell\n className={clsx(header.id, 'shimmer-dark', {\n loading: isLoading,\n 'last-pinned-left': column.getIsPinned() === 'left' && column.getIsLastColumn('left'),\n })}\n key={header.id}\n style={{\n ...getCommonPinningStyles(column),\n width: `calc(var(--header-${header?.id}-size) * 1px)`,\n }}\n >\n {header.isPlaceholder ? null : (\n <Styled.TableCellContent className={clsx('bold')}>\n {flexRender(column.columnDef.header, header.getContext())}\n {isReadOnly && (\n <Icon icon=\"lock\" data-tooltip={'You only have permission to read this column.'} />\n )}\n\n <Styled.HeaderButtons className=\"actions\">\n {/* COLUMN HIDING */}\n {canHide && (\n <HeaderActionButton\n icon=\"visibility_off\"\n selected={!column.getIsVisible()}\n onClick={column.getToggleVisibilityHandler()}\n />\n )}\n {/* COLUMN PINNING */}\n {canPin && (\n <HeaderActionButton\n icon=\"push_pin\"\n selected={header.column.getIsPinned() === 'left'}\n onClick={() => {\n if (header.column.getIsPinned() === 'left') {\n header.column.pin(false)\n } else {\n header.column.pin('left')\n }\n }}\n />\n )}\n\n {/* COLUMN SORTING */}\n {canSort && (\n <HeaderActionButton\n icon={'sort'}\n style={{\n transform: (column.getIsSorted() as string) === 'asc' ? 'scaleY(-1)' : undefined,\n }}\n onClick={column.getToggleSortingHandler()}\n selected={!!column.getIsSorted()}\n />\n )}\n </Styled.HeaderButtons>\n {canResize && (\n <Styled.ResizedHandler\n {...{\n onDoubleClick: () => column.resetSize(),\n onMouseDown: header.getResizeHandler(),\n onTouchStart: header.getResizeHandler(),\n className: clsx('resize-handle', {\n resizing: column.getIsResizing(),\n }),\n }}\n />\n )}\n </Styled.TableCellContent>\n )}\n </Styled.HeaderCell>\n )\n}\n\ninterface TableBodyProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n table: Table<TableRow>\n tableContainerRef: React.RefObject<HTMLDivElement>\n showHierarchy: boolean\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n attribs: ProjectTableAttribute[]\n onOpenNew?: (type: 'folder' | 'task') => void\n}\n\nconst TableBody = ({\n columnVirtualizer,\n table,\n tableContainerRef,\n showHierarchy,\n virtualPaddingLeft,\n virtualPaddingRight,\n attribs,\n onOpenNew,\n}: TableBodyProps) => {\n const { handleTableBodyContextMenu } = useCellContextMenu({ attribs, onOpenNew })\n\n const { handlePreFetchTasks } = usePrefetchFolderTasks()\n\n const { rows } = table.getRowModel()\n\n const rowVirtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({\n count: rows.length,\n estimateSize: () => (showHierarchy ? 36 : 40), //estimate row height for accurate scrollbar dragging\n getScrollElement: () => tableContainerRef.current,\n //measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n })\n\n const virtualRows = rowVirtualizer.getVirtualItems()\n\n useKeyboardNavigation()\n\n return virtualRows.length ? (\n <tbody\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n position: 'relative',\n display: 'grid',\n }}\n onContextMenu={handleTableBodyContextMenu}\n onMouseOver={(e) => {\n handlePreFetchTasks(e)\n }}\n >\n {virtualRows.map((virtualRow) => {\n const row = rows[virtualRow.index] as Row<TableRow>\n return (\n <TableBodyRow\n key={row.id}\n columnVirtualizer={columnVirtualizer}\n row={row}\n rowVirtualizer={rowVirtualizer}\n virtualPaddingLeft={virtualPaddingLeft}\n virtualPaddingRight={virtualPaddingRight}\n virtualRow={virtualRow}\n showHierarchy={showHierarchy}\n />\n )\n })}\n </tbody>\n ) : (\n tableContainerRef.current &&\n createPortal(<EmptyPlaceholder message=\"No items found\" />, tableContainerRef.current)\n )\n}\n\ninterface TableBodyRowProps {\n columnVirtualizer: Virtualizer<HTMLDivElement, HTMLTableCellElement>\n row: Row<TableRow>\n rowVirtualizer: Virtualizer<HTMLDivElement, HTMLTableRowElement>\n virtualPaddingLeft: number | undefined\n virtualPaddingRight: number | undefined\n virtualRow: VirtualItem\n showHierarchy: boolean\n}\n\nconst TableBodyRow = ({\n columnVirtualizer,\n row,\n rowVirtualizer,\n virtualPaddingLeft,\n virtualPaddingRight,\n virtualRow,\n showHierarchy,\n}: TableBodyRowProps) => {\n // We should do this so that we don't re-render every time anything in projectTableContext changes\n const visibleCells = row.getVisibleCells()\n const virtualColumns = columnVirtualizer.getVirtualItems()\n\n return (\n <Styled.TR\n data-index={virtualRow.index} //needed for dynamic row height measurement\n ref={(node) => rowVirtualizer.measureElement(node)} //measure dynamic row height\n key={row.id}\n style={{\n transform: `translateY(${virtualRow.start}px)`, //this should always be a `style` as it changes on scroll\n }}\n >\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingLeft }} />\n ) : null}\n {virtualColumns.map((vc) => {\n const cell = visibleCells[vc.index]\n const cellId = getCellId(row.id, cell.column.id)\n return (\n <TableCellMemo\n cell={cell}\n cellId={cellId}\n rowId={row.id}\n key={cell.id}\n showHierarchy={showHierarchy}\n />\n )\n })}\n\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <td style={{ display: 'flex', width: virtualPaddingRight }} />\n ) : null}\n </Styled.TR>\n )\n}\n\ninterface TableCellProps {\n cell: Cell<TableRow, unknown>\n cellId: string\n rowId: string\n className?: string\n showHierarchy: boolean\n}\n\nconst TableCell = ({ cell, rowId, cellId, className, showHierarchy, ...props }: TableCellProps) => {\n const {\n isCellSelected,\n isCellFocused,\n startSelection,\n extendSelection,\n endSelection,\n selectCell,\n getCellBorderClasses,\n } = useSelectionCellsContext()\n\n const { isRowSelected } = useSelectedRowsContext()\n\n const { isEditing } = useCellEditing()\n\n const borderClasses = getCellBorderClasses(cellId)\n\n const isPinned = cell.column.getIsPinned()\n const isLastLeftPinnedColumn = isPinned === 'left' && cell.column.getIsLastColumn('left')\n const isRowSelectionColumn = cell.column.id === ROW_SELECTION_COLUMN_ID\n\n return (\n <Styled.TableCell\n {...props}\n tabIndex={0}\n key={cell.id}\n $isLastPinned={isLastLeftPinnedColumn} // is this column the last pinned column? Custom styling for borders.\n className={clsx(\n cell.column.id,\n {\n selected: isCellSelected(cellId),\n focused: isCellFocused(cellId),\n editing: isEditing(cellId),\n 'last-pinned-left': isLastLeftPinnedColumn,\n 'selected-row': isRowSelected(rowId),\n task: cell.row.original.entityType === 'task',\n },\n className,\n ...borderClasses,\n )}\n style={{\n ...getCommonPinningStyles(cell.column),\n width: `calc(var(--col-${cell.column.id}-size) * 1px)`,\n height: showHierarchy ? 36 : 40,\n }}\n onMouseDown={(e) => {\n // Only process left clicks (button 0), ignore right clicks\n if (e.button !== 0) return\n\n // check we are not clicking on expander\n if ((e.target as HTMLElement).closest('.expander')) return\n const additive = e.metaKey || e.ctrlKey || isRowSelectionColumn\n if (e.shiftKey) {\n // Shift+click extends selection from anchor cell\n selectCell(cellId, additive, true) // true for range selection\n } else {\n // Normal click starts a new selection\n startSelection(cellId, additive)\n }\n }}\n onMouseOver={(e) => {\n if (e.buttons === 1) {\n // Left button is pressed during mouse move - drag selection\n extendSelection(cellId, isRowSelectionColumn)\n }\n }}\n onMouseUp={() => {\n endSelection(cellId)\n }}\n onDoubleClick={(e) => {\n if (cell.column.id === 'name') {\n // select the row by selecting the row-selection cell\n const rowSelectionCellId = getCellId(cell.row.id, ROW_SELECTION_COLUMN_ID)\n if (!isCellSelected(rowSelectionCellId)) {\n const additive = e.metaKey || e.ctrlKey\n selectCell(rowSelectionCellId, additive, false)\n }\n }\n }}\n onContextMenu={(e) => {\n e.preventDefault()\n // if the cell is not selected, select it and deselect all others\n if (!isCellSelected(cellId)) {\n selectCell(cellId, false, false)\n }\n }}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Styled.TableCell>\n )\n}\n\nconst TableCellMemo = memo(TableCell)\n"],"names":["useColumnSettingsContext","useProjectTableContext","useMemo","getTableFieldOptions","useRef","useSelectionCellsContext","useEffect","_a","loadingAttrib","generateDummyAttributes","loadingRows","generateLoadingRows","getReadOnlyLists","useCellEditing","buildTreeTableColumns","useReactTable","getCoreRowModel","getFilteredRowModel","getExpandedRowModel","getSortedRowModel","filterFns","ROW_SELECTION_COLUMN_ID","jsx","ClipboardProvider","Styled.TableWrapper","Styled.TableContainer","jsxs","Styled.TableHeader","Styled.ColumnHeader","Styled.HeaderCell","Styled.TableCellContent","flexRender","Icon","Styled.HeaderButtons","Styled.ResizedHandler","usePrefetchFolderTasks","useVirtualizer","createPortal","EmptyPlaceholder","Styled.TR","getCellId","useSelectedRowsContext","createElement","Styled.TableCell","memo"],"mappings":"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"}