@strapi/upload 5.33.3 → 5.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js +2 -2
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.js.map +1 -1
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs +2 -2
- package/dist/admin/components/MediaLibraryDialog/MediaLibraryDialog.mjs.map +1 -1
- package/dist/admin/future/App.js +45 -0
- package/dist/admin/future/App.js.map +1 -0
- package/dist/admin/future/App.mjs +43 -0
- package/dist/admin/future/App.mjs.map +1 -0
- package/dist/admin/future/pages/AIGenerationPage.js +24 -0
- package/dist/admin/future/pages/AIGenerationPage.js.map +1 -0
- package/dist/admin/future/pages/AIGenerationPage.mjs +22 -0
- package/dist/admin/future/pages/AIGenerationPage.mjs.map +1 -0
- package/dist/admin/future/pages/MediaLibraryPage.js +55 -0
- package/dist/admin/future/pages/MediaLibraryPage.js.map +1 -0
- package/dist/admin/future/pages/MediaLibraryPage.mjs +53 -0
- package/dist/admin/future/pages/MediaLibraryPage.mjs.map +1 -0
- package/dist/admin/hooks/useAIMetadataJob.js +114 -0
- package/dist/admin/hooks/useAIMetadataJob.js.map +1 -0
- package/dist/admin/hooks/useAIMetadataJob.mjs +93 -0
- package/dist/admin/hooks/useAIMetadataJob.mjs.map +1 -0
- package/dist/admin/index.js +23 -4
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +24 -5
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/package.json.js +8 -7
- package/dist/admin/package.json.js.map +1 -1
- package/dist/admin/package.json.mjs +8 -7
- package/dist/admin/package.json.mjs.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js +1 -0
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.js.map +1 -1
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs +1 -0
- package/dist/admin/pages/App/ConfigureTheView/ConfigureTheView.mjs.map +1 -1
- package/dist/admin/pages/App/components/Header.js +3 -0
- package/dist/admin/pages/App/components/Header.js.map +1 -1
- package/dist/admin/pages/App/components/Header.mjs +3 -0
- package/dist/admin/pages/App/components/Header.mjs.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.js +252 -67
- package/dist/admin/pages/SettingsPage/SettingsPage.js.map +1 -1
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs +256 -71
- package/dist/admin/pages/SettingsPage/SettingsPage.mjs.map +1 -1
- package/dist/admin/src/components/MediaLibraryDialog/MediaLibraryDialog.d.ts +2 -1
- package/dist/admin/src/future/App.d.ts +1 -0
- package/dist/admin/src/future/pages/AIGenerationPage.d.ts +1 -0
- package/dist/admin/src/future/pages/MediaLibraryPage.d.ts +1 -0
- package/dist/admin/src/future/services/api.d.ts +2 -0
- package/dist/admin/src/future/services/settings.d.ts +2 -0
- package/dist/admin/src/hooks/useAIMetadataJob.d.ts +9 -0
- package/dist/admin/translations/de.json.js +44 -1
- package/dist/admin/translations/de.json.js.map +1 -1
- package/dist/admin/translations/de.json.mjs +44 -1
- package/dist/admin/translations/de.json.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +9 -0
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +9 -0
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/server/bootstrap.js +1 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +1 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/admin-file.js +86 -0
- package/dist/server/controllers/admin-file.js.map +1 -1
- package/dist/server/controllers/admin-file.mjs +86 -0
- package/dist/server/controllers/admin-file.mjs.map +1 -1
- package/dist/server/controllers/admin-upload.js +3 -23
- package/dist/server/controllers/admin-upload.js.map +1 -1
- package/dist/server/controllers/admin-upload.mjs +3 -23
- package/dist/server/controllers/admin-upload.mjs.map +1 -1
- package/dist/server/models/ai-metadata-job.js +36 -0
- package/dist/server/models/ai-metadata-job.js.map +1 -0
- package/dist/server/models/ai-metadata-job.mjs +33 -0
- package/dist/server/models/ai-metadata-job.mjs.map +1 -0
- package/dist/server/register.js +3 -0
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +3 -0
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/routes/admin.js +46 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +46 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-metadata-jobs.js +72 -0
- package/dist/server/services/ai-metadata-jobs.js.map +1 -0
- package/dist/server/services/ai-metadata-jobs.mjs +70 -0
- package/dist/server/services/ai-metadata-jobs.mjs.map +1 -0
- package/dist/server/services/ai-metadata.js +170 -20
- package/dist/server/services/ai-metadata.js.map +1 -1
- package/dist/server/services/ai-metadata.mjs +170 -20
- package/dist/server/services/ai-metadata.mjs.map +1 -1
- package/dist/server/services/index.js +3 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs +3 -1
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-file.d.ts +3 -0
- package/dist/server/src/controllers/admin-file.d.ts.map +1 -1
- package/dist/server/src/controllers/admin-upload.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +3 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +27 -1
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/models/ai-metadata-job.d.ts +5 -0
- package/dist/server/src/models/ai-metadata-job.d.ts.map +1 -0
- package/dist/server/src/models/index.d.ts +5 -0
- package/dist/server/src/models/index.d.ts.map +1 -0
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-metadata-jobs.d.ts +14 -0
- package/dist/server/src/services/ai-metadata-jobs.d.ts.map +1 -0
- package/dist/server/src/services/ai-metadata.d.ts +25 -2
- package/dist/server/src/services/ai-metadata.d.ts.map +1 -1
- package/dist/server/src/services/index.d.ts +24 -1
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/utils/images.d.ts +7 -0
- package/dist/server/src/utils/images.d.ts.map +1 -0
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/utils/images.js +35 -0
- package/dist/server/utils/images.js.map +1 -0
- package/dist/server/utils/images.mjs +33 -0
- package/dist/server/utils/images.mjs.map +1 -0
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/contracts/ai-metadata-jobs.d.ts +53 -0
- package/dist/shared/contracts/ai-metadata-jobs.d.ts.map +1 -0
- package/dist/shared/contracts/files.d.ts +33 -0
- package/package.json +8 -7
|
@@ -36,7 +36,7 @@ const MediaLibraryDialog = ({ onClose, onSelectAssets, allowedTypes = [
|
|
|
36
36
|
'images',
|
|
37
37
|
'videos',
|
|
38
38
|
'audios'
|
|
39
|
-
] })=>{
|
|
39
|
+
], multiple = true })=>{
|
|
40
40
|
const [step, setStep] = React__namespace.useState(STEPS.AssetSelect);
|
|
41
41
|
const [folderId, setFolderId] = React__namespace.useState(null);
|
|
42
42
|
switch(step){
|
|
@@ -50,7 +50,7 @@ const MediaLibraryDialog = ({ onClose, onSelectAssets, allowedTypes = [
|
|
|
50
50
|
onAddAsset: ()=>setStep(STEPS.AssetUpload),
|
|
51
51
|
onAddFolder: ()=>setStep(STEPS.FolderCreate),
|
|
52
52
|
onChangeFolder: (folderId)=>setFolderId(folderId),
|
|
53
|
-
multiple:
|
|
53
|
+
multiple: multiple
|
|
54
54
|
});
|
|
55
55
|
case STEPS.FolderCreate:
|
|
56
56
|
return /*#__PURE__*/ jsxRuntime.jsx(EditFolderDialog.EditFolderDialog, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaLibraryDialog.js","sources":["../../../../admin/src/components/MediaLibraryDialog/MediaLibraryDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { AssetDialog } from '../AssetDialog/AssetDialog';\nimport { EditFolderDialog } from '../EditFolderDialog/EditFolderDialog';\nimport { UploadAssetDialog } from '../UploadAssetDialog/UploadAssetDialog';\n\nconst STEPS = {\n AssetSelect: 'SelectAsset',\n AssetUpload: 'UploadAsset',\n FolderCreate: 'FolderCreate',\n};\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\nexport interface MediaLibraryDialogProps {\n allowedTypes?: AllowedTypes[];\n onClose: () => void;\n onSelectAssets: (selectedAssets: File[]) => void;\n}\n\nexport const MediaLibraryDialog = ({\n onClose,\n onSelectAssets,\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n}: MediaLibraryDialogProps) => {\n const [step, setStep] = React.useState(STEPS.AssetSelect);\n const [folderId, setFolderId] = React.useState<number | null>(null);\n\n switch (step) {\n case STEPS.AssetSelect:\n return (\n <AssetDialog\n allowedTypes={allowedTypes}\n folderId={folderId}\n open\n onClose={onClose}\n onValidate={onSelectAssets}\n onAddAsset={() => setStep(STEPS.AssetUpload)}\n onAddFolder={() => setStep(STEPS.FolderCreate)}\n onChangeFolder={(folderId) => setFolderId(folderId)}\n multiple\n />\n );\n\n case STEPS.FolderCreate:\n return (\n <EditFolderDialog\n open\n onClose={() => setStep(STEPS.AssetSelect)}\n parentFolderId={folderId}\n />\n );\n\n default:\n return (\n <UploadAssetDialog open onClose={() => setStep(STEPS.AssetSelect)} folderId={folderId} />\n );\n }\n};\n"],"names":["STEPS","AssetSelect","AssetUpload","FolderCreate","MediaLibraryDialog","onClose","onSelectAssets","allowedTypes","step","setStep","React","useState","folderId","setFolderId","_jsx","AssetDialog","open","onValidate","onAddAsset","onAddFolder","onChangeFolder","
|
|
1
|
+
{"version":3,"file":"MediaLibraryDialog.js","sources":["../../../../admin/src/components/MediaLibraryDialog/MediaLibraryDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { AssetDialog } from '../AssetDialog/AssetDialog';\nimport { EditFolderDialog } from '../EditFolderDialog/EditFolderDialog';\nimport { UploadAssetDialog } from '../UploadAssetDialog/UploadAssetDialog';\n\nconst STEPS = {\n AssetSelect: 'SelectAsset',\n AssetUpload: 'UploadAsset',\n FolderCreate: 'FolderCreate',\n};\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\nexport interface MediaLibraryDialogProps {\n allowedTypes?: AllowedTypes[];\n multiple?: boolean;\n onClose: () => void;\n onSelectAssets: (selectedAssets: File[]) => void;\n}\n\nexport const MediaLibraryDialog = ({\n onClose,\n onSelectAssets,\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n multiple = true,\n}: MediaLibraryDialogProps) => {\n const [step, setStep] = React.useState(STEPS.AssetSelect);\n const [folderId, setFolderId] = React.useState<number | null>(null);\n\n switch (step) {\n case STEPS.AssetSelect:\n return (\n <AssetDialog\n allowedTypes={allowedTypes}\n folderId={folderId}\n open\n onClose={onClose}\n onValidate={onSelectAssets}\n onAddAsset={() => setStep(STEPS.AssetUpload)}\n onAddFolder={() => setStep(STEPS.FolderCreate)}\n onChangeFolder={(folderId) => setFolderId(folderId)}\n multiple={multiple}\n />\n );\n\n case STEPS.FolderCreate:\n return (\n <EditFolderDialog\n open\n onClose={() => setStep(STEPS.AssetSelect)}\n parentFolderId={folderId}\n />\n );\n\n default:\n return (\n <UploadAssetDialog open onClose={() => setStep(STEPS.AssetSelect)} folderId={folderId} />\n );\n }\n};\n"],"names":["STEPS","AssetSelect","AssetUpload","FolderCreate","MediaLibraryDialog","onClose","onSelectAssets","allowedTypes","multiple","step","setStep","React","useState","folderId","setFolderId","_jsx","AssetDialog","open","onValidate","onAddAsset","onAddFolder","onChangeFolder","EditFolderDialog","parentFolderId","UploadAssetDialog"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAOA,MAAMA,KAAQ,GAAA;IACZC,WAAa,EAAA,aAAA;IACbC,WAAa,EAAA,aAAA;IACbC,YAAc,EAAA;AAChB,CAAA;AAWO,MAAMC,qBAAqB,CAAC,EACjCC,OAAO,EACPC,cAAc,EACdC,YAAe,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA;CAAS,EACtDC,QAAAA,GAAW,IAAI,EACS,GAAA;IACxB,MAAM,CAACC,MAAMC,OAAQ,CAAA,GAAGC,iBAAMC,QAAQ,CAACZ,MAAMC,WAAW,CAAA;AACxD,IAAA,MAAM,CAACY,QAAUC,EAAAA,WAAAA,CAAY,GAAGH,gBAAAA,CAAMC,QAAQ,CAAgB,IAAA,CAAA;IAE9D,OAAQH,IAAAA;AACN,QAAA,KAAKT,MAAMC,WAAW;AACpB,YAAA,qBACEc,cAACC,CAAAA,uBAAAA,EAAAA;gBACCT,YAAcA,EAAAA,YAAAA;gBACdM,QAAUA,EAAAA,QAAAA;gBACVI,IAAI,EAAA,IAAA;gBACJZ,OAASA,EAAAA,OAAAA;gBACTa,UAAYZ,EAAAA,cAAAA;gBACZa,UAAY,EAAA,IAAMT,OAAQV,CAAAA,KAAAA,CAAME,WAAW,CAAA;gBAC3CkB,WAAa,EAAA,IAAMV,OAAQV,CAAAA,KAAAA,CAAMG,YAAY,CAAA;gBAC7CkB,cAAgB,EAAA,CAACR,WAAaC,WAAYD,CAAAA,QAAAA,CAAAA;gBAC1CL,QAAUA,EAAAA;;AAIhB,QAAA,KAAKR,MAAMG,YAAY;AACrB,YAAA,qBACEY,cAACO,CAAAA,iCAAAA,EAAAA;gBACCL,IAAI,EAAA,IAAA;gBACJZ,OAAS,EAAA,IAAMK,OAAQV,CAAAA,KAAAA,CAAMC,WAAW,CAAA;gBACxCsB,cAAgBV,EAAAA;;AAItB,QAAA;AACE,YAAA,qBACEE,cAACS,CAAAA,mCAAAA,EAAAA;gBAAkBP,IAAI,EAAA,IAAA;gBAACZ,OAAS,EAAA,IAAMK,OAAQV,CAAAA,KAAAA,CAAMC,WAAW,CAAA;gBAAGY,QAAUA,EAAAA;;AAEnF;AACF;;;;"}
|
|
@@ -15,7 +15,7 @@ const MediaLibraryDialog = ({ onClose, onSelectAssets, allowedTypes = [
|
|
|
15
15
|
'images',
|
|
16
16
|
'videos',
|
|
17
17
|
'audios'
|
|
18
|
-
] })=>{
|
|
18
|
+
], multiple = true })=>{
|
|
19
19
|
const [step, setStep] = React.useState(STEPS.AssetSelect);
|
|
20
20
|
const [folderId, setFolderId] = React.useState(null);
|
|
21
21
|
switch(step){
|
|
@@ -29,7 +29,7 @@ const MediaLibraryDialog = ({ onClose, onSelectAssets, allowedTypes = [
|
|
|
29
29
|
onAddAsset: ()=>setStep(STEPS.AssetUpload),
|
|
30
30
|
onAddFolder: ()=>setStep(STEPS.FolderCreate),
|
|
31
31
|
onChangeFolder: (folderId)=>setFolderId(folderId),
|
|
32
|
-
multiple:
|
|
32
|
+
multiple: multiple
|
|
33
33
|
});
|
|
34
34
|
case STEPS.FolderCreate:
|
|
35
35
|
return /*#__PURE__*/ jsx(EditFolderDialog, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaLibraryDialog.mjs","sources":["../../../../admin/src/components/MediaLibraryDialog/MediaLibraryDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { AssetDialog } from '../AssetDialog/AssetDialog';\nimport { EditFolderDialog } from '../EditFolderDialog/EditFolderDialog';\nimport { UploadAssetDialog } from '../UploadAssetDialog/UploadAssetDialog';\n\nconst STEPS = {\n AssetSelect: 'SelectAsset',\n AssetUpload: 'UploadAsset',\n FolderCreate: 'FolderCreate',\n};\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\nexport interface MediaLibraryDialogProps {\n allowedTypes?: AllowedTypes[];\n onClose: () => void;\n onSelectAssets: (selectedAssets: File[]) => void;\n}\n\nexport const MediaLibraryDialog = ({\n onClose,\n onSelectAssets,\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n}: MediaLibraryDialogProps) => {\n const [step, setStep] = React.useState(STEPS.AssetSelect);\n const [folderId, setFolderId] = React.useState<number | null>(null);\n\n switch (step) {\n case STEPS.AssetSelect:\n return (\n <AssetDialog\n allowedTypes={allowedTypes}\n folderId={folderId}\n open\n onClose={onClose}\n onValidate={onSelectAssets}\n onAddAsset={() => setStep(STEPS.AssetUpload)}\n onAddFolder={() => setStep(STEPS.FolderCreate)}\n onChangeFolder={(folderId) => setFolderId(folderId)}\n multiple\n />\n );\n\n case STEPS.FolderCreate:\n return (\n <EditFolderDialog\n open\n onClose={() => setStep(STEPS.AssetSelect)}\n parentFolderId={folderId}\n />\n );\n\n default:\n return (\n <UploadAssetDialog open onClose={() => setStep(STEPS.AssetSelect)} folderId={folderId} />\n );\n }\n};\n"],"names":["STEPS","AssetSelect","AssetUpload","FolderCreate","MediaLibraryDialog","onClose","onSelectAssets","allowedTypes","step","setStep","React","useState","folderId","setFolderId","_jsx","AssetDialog","open","onValidate","onAddAsset","onAddFolder","onChangeFolder","
|
|
1
|
+
{"version":3,"file":"MediaLibraryDialog.mjs","sources":["../../../../admin/src/components/MediaLibraryDialog/MediaLibraryDialog.tsx"],"sourcesContent":["// TODO: find a better naming convention for the file that was an index file before\nimport * as React from 'react';\n\nimport { AssetDialog } from '../AssetDialog/AssetDialog';\nimport { EditFolderDialog } from '../EditFolderDialog/EditFolderDialog';\nimport { UploadAssetDialog } from '../UploadAssetDialog/UploadAssetDialog';\n\nconst STEPS = {\n AssetSelect: 'SelectAsset',\n AssetUpload: 'UploadAsset',\n FolderCreate: 'FolderCreate',\n};\n\nimport type { File } from '../../../../shared/contracts/files';\nimport type { AllowedTypes } from '../AssetCard/AssetCard';\nexport interface MediaLibraryDialogProps {\n allowedTypes?: AllowedTypes[];\n multiple?: boolean;\n onClose: () => void;\n onSelectAssets: (selectedAssets: File[]) => void;\n}\n\nexport const MediaLibraryDialog = ({\n onClose,\n onSelectAssets,\n allowedTypes = ['files', 'images', 'videos', 'audios'],\n multiple = true,\n}: MediaLibraryDialogProps) => {\n const [step, setStep] = React.useState(STEPS.AssetSelect);\n const [folderId, setFolderId] = React.useState<number | null>(null);\n\n switch (step) {\n case STEPS.AssetSelect:\n return (\n <AssetDialog\n allowedTypes={allowedTypes}\n folderId={folderId}\n open\n onClose={onClose}\n onValidate={onSelectAssets}\n onAddAsset={() => setStep(STEPS.AssetUpload)}\n onAddFolder={() => setStep(STEPS.FolderCreate)}\n onChangeFolder={(folderId) => setFolderId(folderId)}\n multiple={multiple}\n />\n );\n\n case STEPS.FolderCreate:\n return (\n <EditFolderDialog\n open\n onClose={() => setStep(STEPS.AssetSelect)}\n parentFolderId={folderId}\n />\n );\n\n default:\n return (\n <UploadAssetDialog open onClose={() => setStep(STEPS.AssetSelect)} folderId={folderId} />\n );\n }\n};\n"],"names":["STEPS","AssetSelect","AssetUpload","FolderCreate","MediaLibraryDialog","onClose","onSelectAssets","allowedTypes","multiple","step","setStep","React","useState","folderId","setFolderId","_jsx","AssetDialog","open","onValidate","onAddAsset","onAddFolder","onChangeFolder","EditFolderDialog","parentFolderId","UploadAssetDialog"],"mappings":";;;;;;AAAA;AAOA,MAAMA,KAAQ,GAAA;IACZC,WAAa,EAAA,aAAA;IACbC,WAAa,EAAA,aAAA;IACbC,YAAc,EAAA;AAChB,CAAA;AAWO,MAAMC,qBAAqB,CAAC,EACjCC,OAAO,EACPC,cAAc,EACdC,YAAe,GAAA;AAAC,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA;CAAS,EACtDC,QAAAA,GAAW,IAAI,EACS,GAAA;IACxB,MAAM,CAACC,MAAMC,OAAQ,CAAA,GAAGC,MAAMC,QAAQ,CAACZ,MAAMC,WAAW,CAAA;AACxD,IAAA,MAAM,CAACY,QAAUC,EAAAA,WAAAA,CAAY,GAAGH,KAAAA,CAAMC,QAAQ,CAAgB,IAAA,CAAA;IAE9D,OAAQH,IAAAA;AACN,QAAA,KAAKT,MAAMC,WAAW;AACpB,YAAA,qBACEc,GAACC,CAAAA,WAAAA,EAAAA;gBACCT,YAAcA,EAAAA,YAAAA;gBACdM,QAAUA,EAAAA,QAAAA;gBACVI,IAAI,EAAA,IAAA;gBACJZ,OAASA,EAAAA,OAAAA;gBACTa,UAAYZ,EAAAA,cAAAA;gBACZa,UAAY,EAAA,IAAMT,OAAQV,CAAAA,KAAAA,CAAME,WAAW,CAAA;gBAC3CkB,WAAa,EAAA,IAAMV,OAAQV,CAAAA,KAAAA,CAAMG,YAAY,CAAA;gBAC7CkB,cAAgB,EAAA,CAACR,WAAaC,WAAYD,CAAAA,QAAAA,CAAAA;gBAC1CL,QAAUA,EAAAA;;AAIhB,QAAA,KAAKR,MAAMG,YAAY;AACrB,YAAA,qBACEY,GAACO,CAAAA,gBAAAA,EAAAA;gBACCL,IAAI,EAAA,IAAA;gBACJZ,OAAS,EAAA,IAAMK,OAAQV,CAAAA,KAAAA,CAAMC,WAAW,CAAA;gBACxCsB,cAAgBV,EAAAA;;AAItB,QAAA;AACE,YAAA,qBACEE,GAACS,CAAAA,iBAAAA,EAAAA;gBAAkBP,IAAI,EAAA,IAAA;gBAACZ,OAAS,EAAA,IAAMK,OAAQV,CAAAA,KAAAA,CAAMC,WAAW,CAAA;gBAAGY,QAAUA,EAAAA;;AAEnF;AACF;;;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
require('react');
|
|
5
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
6
|
+
var reactIntl = require('react-intl');
|
|
7
|
+
var reactRouterDom = require('react-router-dom');
|
|
8
|
+
require('byte-size');
|
|
9
|
+
require('date-fns');
|
|
10
|
+
var getTrad = require('../utils/getTrad.js');
|
|
11
|
+
require('qs');
|
|
12
|
+
require('../utils/typeFromMime.js');
|
|
13
|
+
require('../utils/urlYupSchema.js');
|
|
14
|
+
var AIGenerationPage = require('./pages/AIGenerationPage.js');
|
|
15
|
+
var MediaLibraryPage = require('./pages/MediaLibraryPage.js');
|
|
16
|
+
|
|
17
|
+
const UnstableMediaLibraryPage = ()=>{
|
|
18
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
19
|
+
const title = formatMessage({
|
|
20
|
+
id: getTrad.getTrad('plugin.name'),
|
|
21
|
+
defaultMessage: 'Media Library'
|
|
22
|
+
});
|
|
23
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Page.Main, {
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Page.Title, {
|
|
26
|
+
children: title
|
|
27
|
+
}),
|
|
28
|
+
/*#__PURE__*/ jsxRuntime.jsxs(reactRouterDom.Routes, {
|
|
29
|
+
children: [
|
|
30
|
+
/*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
|
|
31
|
+
index: true,
|
|
32
|
+
element: /*#__PURE__*/ jsxRuntime.jsx(MediaLibraryPage.MediaLibraryPage, {})
|
|
33
|
+
}),
|
|
34
|
+
/*#__PURE__*/ jsxRuntime.jsx(reactRouterDom.Route, {
|
|
35
|
+
path: "ai-generation",
|
|
36
|
+
element: /*#__PURE__*/ jsxRuntime.jsx(AIGenerationPage.AIGenerationPage, {})
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
})
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
exports.UnstableMediaLibraryPage = UnstableMediaLibraryPage;
|
|
45
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { getTrad } from '../utils';\n\nimport { AIGenerationPage } from './pages/AIGenerationPage';\nimport { MediaLibraryPage } from './pages/MediaLibraryPage';\n\nexport const UnstableMediaLibraryPage = () => {\n const { formatMessage } = useIntl();\n const title = formatMessage({ id: getTrad('plugin.name'), defaultMessage: 'Media Library' });\n\n return (\n <Page.Main>\n <Page.Title>{title}</Page.Title>\n\n <Routes>\n <Route index element={<MediaLibraryPage />} />\n <Route path=\"ai-generation\" element={<AIGenerationPage />} />\n </Routes>\n </Page.Main>\n );\n};\n"],"names":["UnstableMediaLibraryPage","formatMessage","useIntl","title","id","getTrad","defaultMessage","_jsxs","Page","Main","_jsx","Title","Routes","Route","index","element","MediaLibraryPage","path","AIGenerationPage"],"mappings":";;;;;;;;;;;;;;;;MAWaA,wBAA2B,GAAA,IAAA;IACtC,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQF,aAAc,CAAA;AAAEG,QAAAA,EAAAA,EAAIC,eAAQ,CAAA,aAAA,CAAA;QAAgBC,cAAgB,EAAA;AAAgB,KAAA,CAAA;IAE1F,qBACEC,eAAA,CAACC,iBAAKC,IAAI,EAAA;;AACR,0BAAAC,cAAA,CAACF,iBAAKG,KAAK,EAAA;AAAER,gBAAAA,QAAAA,EAAAA;;0BAEbI,eAACK,CAAAA,qBAAAA,EAAAA;;kCACCF,cAACG,CAAAA,oBAAAA,EAAAA;wBAAMC,KAAK,EAAA,IAAA;AAACC,wBAAAA,OAAAA,gBAASL,cAACM,CAAAA,iCAAAA,EAAAA,EAAAA;;kCACvBN,cAACG,CAAAA,oBAAAA,EAAAA;wBAAMI,IAAK,EAAA,eAAA;AAAgBF,wBAAAA,OAAAA,gBAASL,cAACQ,CAAAA,iCAAAA,EAAAA,EAAAA;;;;;;AAI9C;;;;"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import 'react';
|
|
3
|
+
import { Page } from '@strapi/admin/strapi-admin';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { Routes, Route } from 'react-router-dom';
|
|
6
|
+
import 'byte-size';
|
|
7
|
+
import 'date-fns';
|
|
8
|
+
import { getTrad } from '../utils/getTrad.mjs';
|
|
9
|
+
import 'qs';
|
|
10
|
+
import '../utils/typeFromMime.mjs';
|
|
11
|
+
import '../utils/urlYupSchema.mjs';
|
|
12
|
+
import { AIGenerationPage } from './pages/AIGenerationPage.mjs';
|
|
13
|
+
import { MediaLibraryPage } from './pages/MediaLibraryPage.mjs';
|
|
14
|
+
|
|
15
|
+
const UnstableMediaLibraryPage = ()=>{
|
|
16
|
+
const { formatMessage } = useIntl();
|
|
17
|
+
const title = formatMessage({
|
|
18
|
+
id: getTrad('plugin.name'),
|
|
19
|
+
defaultMessage: 'Media Library'
|
|
20
|
+
});
|
|
21
|
+
return /*#__PURE__*/ jsxs(Page.Main, {
|
|
22
|
+
children: [
|
|
23
|
+
/*#__PURE__*/ jsx(Page.Title, {
|
|
24
|
+
children: title
|
|
25
|
+
}),
|
|
26
|
+
/*#__PURE__*/ jsxs(Routes, {
|
|
27
|
+
children: [
|
|
28
|
+
/*#__PURE__*/ jsx(Route, {
|
|
29
|
+
index: true,
|
|
30
|
+
element: /*#__PURE__*/ jsx(MediaLibraryPage, {})
|
|
31
|
+
}),
|
|
32
|
+
/*#__PURE__*/ jsx(Route, {
|
|
33
|
+
path: "ai-generation",
|
|
34
|
+
element: /*#__PURE__*/ jsx(AIGenerationPage, {})
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { UnstableMediaLibraryPage };
|
|
43
|
+
//# sourceMappingURL=App.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.mjs","sources":["../../../admin/src/future/App.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { Route, Routes } from 'react-router-dom';\n\nimport { getTrad } from '../utils';\n\nimport { AIGenerationPage } from './pages/AIGenerationPage';\nimport { MediaLibraryPage } from './pages/MediaLibraryPage';\n\nexport const UnstableMediaLibraryPage = () => {\n const { formatMessage } = useIntl();\n const title = formatMessage({ id: getTrad('plugin.name'), defaultMessage: 'Media Library' });\n\n return (\n <Page.Main>\n <Page.Title>{title}</Page.Title>\n\n <Routes>\n <Route index element={<MediaLibraryPage />} />\n <Route path=\"ai-generation\" element={<AIGenerationPage />} />\n </Routes>\n </Page.Main>\n );\n};\n"],"names":["UnstableMediaLibraryPage","formatMessage","useIntl","title","id","getTrad","defaultMessage","_jsxs","Page","Main","_jsx","Title","Routes","Route","index","element","MediaLibraryPage","path","AIGenerationPage"],"mappings":";;;;;;;;;;;;;;MAWaA,wBAA2B,GAAA,IAAA;IACtC,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,QAAQF,aAAc,CAAA;AAAEG,QAAAA,EAAAA,EAAIC,OAAQ,CAAA,aAAA,CAAA;QAAgBC,cAAgB,EAAA;AAAgB,KAAA,CAAA;IAE1F,qBACEC,IAAA,CAACC,KAAKC,IAAI,EAAA;;AACR,0BAAAC,GAAA,CAACF,KAAKG,KAAK,EAAA;AAAER,gBAAAA,QAAAA,EAAAA;;0BAEbI,IAACK,CAAAA,MAAAA,EAAAA;;kCACCF,GAACG,CAAAA,KAAAA,EAAAA;wBAAMC,KAAK,EAAA,IAAA;AAACC,wBAAAA,OAAAA,gBAASL,GAACM,CAAAA,gBAAAA,EAAAA,EAAAA;;kCACvBN,GAACG,CAAAA,KAAAA,EAAAA;wBAAMI,IAAK,EAAA,eAAA;AAAgBF,wBAAAA,OAAAA,gBAASL,GAACQ,CAAAA,gBAAAA,EAAAA,EAAAA;;;;;;AAI9C;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
5
|
+
var designSystem = require('@strapi/design-system');
|
|
6
|
+
|
|
7
|
+
const AIGenerationPage = ()=>{
|
|
8
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Layouts.Root, {
|
|
9
|
+
children: [
|
|
10
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Header, {
|
|
11
|
+
title: "AI Generation",
|
|
12
|
+
primaryAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
13
|
+
children: "TODO: Generate"
|
|
14
|
+
})
|
|
15
|
+
}),
|
|
16
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Content, {
|
|
17
|
+
children: "TODO: AI ListView"
|
|
18
|
+
})
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
exports.AIGenerationPage = AIGenerationPage;
|
|
24
|
+
//# sourceMappingURL=AIGenerationPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIGenerationPage.js","sources":["../../../../admin/src/future/pages/AIGenerationPage.tsx"],"sourcesContent":["import { Layouts } from '@strapi/admin/strapi-admin';\nimport { Button } from '@strapi/design-system';\n\nexport const AIGenerationPage = () => {\n return (\n <Layouts.Root>\n <Layouts.Header title=\"AI Generation\" primaryAction={<Button>TODO: Generate</Button>} />\n\n <Layouts.Content>TODO: AI ListView</Layouts.Content>\n </Layouts.Root>\n );\n};\n"],"names":["AIGenerationPage","_jsxs","Layouts","Root","_jsx","Header","title","primaryAction","Button","Content"],"mappings":";;;;;;MAGaA,gBAAmB,GAAA,IAAA;IAC9B,qBACEC,eAAA,CAACC,oBAAQC,IAAI,EAAA;;AACX,0BAAAC,cAAA,CAACF,oBAAQG,MAAM,EAAA;gBAACC,KAAM,EAAA,eAAA;AAAgBC,gBAAAA,aAAAA,gBAAeH,cAACI,CAAAA,mBAAAA,EAAAA;AAAO,oBAAA,QAAA,EAAA;;;AAE7D,0BAAAJ,cAAA,CAACF,oBAAQO,OAAO,EAAA;AAAC,gBAAA,QAAA,EAAA;;;;AAGvB;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Layouts } from '@strapi/admin/strapi-admin';
|
|
3
|
+
import { Button } from '@strapi/design-system';
|
|
4
|
+
|
|
5
|
+
const AIGenerationPage = ()=>{
|
|
6
|
+
return /*#__PURE__*/ jsxs(Layouts.Root, {
|
|
7
|
+
children: [
|
|
8
|
+
/*#__PURE__*/ jsx(Layouts.Header, {
|
|
9
|
+
title: "AI Generation",
|
|
10
|
+
primaryAction: /*#__PURE__*/ jsx(Button, {
|
|
11
|
+
children: "TODO: Generate"
|
|
12
|
+
})
|
|
13
|
+
}),
|
|
14
|
+
/*#__PURE__*/ jsx(Layouts.Content, {
|
|
15
|
+
children: "TODO: AI ListView"
|
|
16
|
+
})
|
|
17
|
+
]
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { AIGenerationPage };
|
|
22
|
+
//# sourceMappingURL=AIGenerationPage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIGenerationPage.mjs","sources":["../../../../admin/src/future/pages/AIGenerationPage.tsx"],"sourcesContent":["import { Layouts } from '@strapi/admin/strapi-admin';\nimport { Button } from '@strapi/design-system';\n\nexport const AIGenerationPage = () => {\n return (\n <Layouts.Root>\n <Layouts.Header title=\"AI Generation\" primaryAction={<Button>TODO: Generate</Button>} />\n\n <Layouts.Content>TODO: AI ListView</Layouts.Content>\n </Layouts.Root>\n );\n};\n"],"names":["AIGenerationPage","_jsxs","Layouts","Root","_jsx","Header","title","primaryAction","Button","Content"],"mappings":";;;;MAGaA,gBAAmB,GAAA,IAAA;IAC9B,qBACEC,IAAA,CAACC,QAAQC,IAAI,EAAA;;AACX,0BAAAC,GAAA,CAACF,QAAQG,MAAM,EAAA;gBAACC,KAAM,EAAA,eAAA;AAAgBC,gBAAAA,aAAAA,gBAAeH,GAACI,CAAAA,MAAAA,EAAAA;AAAO,oBAAA,QAAA,EAAA;;;AAE7D,0BAAAJ,GAAA,CAACF,QAAQO,OAAO,EAAA;AAAC,gBAAA,QAAA,EAAA;;;;AAGvB;;;;"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
require('react');
|
|
5
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
6
|
+
var designSystem = require('@strapi/design-system');
|
|
7
|
+
var reactIntl = require('react-intl');
|
|
8
|
+
require('byte-size');
|
|
9
|
+
require('date-fns');
|
|
10
|
+
var getTrad = require('../../utils/getTrad.js');
|
|
11
|
+
require('qs');
|
|
12
|
+
require('../../utils/typeFromMime.js');
|
|
13
|
+
require('../../utils/urlYupSchema.js');
|
|
14
|
+
|
|
15
|
+
const MediaLibraryPage = ()=>{
|
|
16
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
17
|
+
return(/**
|
|
18
|
+
* NOTE:
|
|
19
|
+
*
|
|
20
|
+
* The design differs from our current Layouts component.
|
|
21
|
+
* Either we find a way to make it work with our current Layouts component
|
|
22
|
+
* or we will have to write our own custom layout.
|
|
23
|
+
*/ /*#__PURE__*/ jsxRuntime.jsxs(strapiAdmin.Layouts.Root, {
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Header, {
|
|
26
|
+
navigationAction: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
27
|
+
children: "TODO: Breadcrumbs"
|
|
28
|
+
}),
|
|
29
|
+
title: "TODO: Folder location",
|
|
30
|
+
primaryAction: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
31
|
+
gap: 2,
|
|
32
|
+
children: [
|
|
33
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.SearchInput, {
|
|
34
|
+
label: formatMessage({
|
|
35
|
+
id: getTrad.getTrad('search.label'),
|
|
36
|
+
defaultMessage: 'Search for an asset'
|
|
37
|
+
}),
|
|
38
|
+
trackedEvent: "didSearchMediaLibraryElements",
|
|
39
|
+
trackedEventDetails: {
|
|
40
|
+
location: 'upload'
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
"TODO: Toolbar"
|
|
44
|
+
]
|
|
45
|
+
})
|
|
46
|
+
}),
|
|
47
|
+
/*#__PURE__*/ jsxRuntime.jsx(strapiAdmin.Layouts.Content, {
|
|
48
|
+
children: "TODO: List/Grid views"
|
|
49
|
+
})
|
|
50
|
+
]
|
|
51
|
+
}));
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
exports.MediaLibraryPage = MediaLibraryPage;
|
|
55
|
+
//# sourceMappingURL=MediaLibraryPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaLibraryPage.js","sources":["../../../../admin/src/future/pages/MediaLibraryPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Layouts, SearchInput } from '@strapi/admin/strapi-admin';\nimport { Box, Flex } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../utils';\n\nexport const MediaLibraryPage = () => {\n const { formatMessage } = useIntl();\n\n return (\n /**\n * NOTE:\n *\n * The design differs from our current Layouts component.\n * Either we find a way to make it work with our current Layouts component\n * or we will have to write our own custom layout.\n */\n <Layouts.Root>\n <Layouts.Header\n navigationAction={<Box>TODO: Breadcrumbs</Box>}\n title=\"TODO: Folder location\"\n primaryAction={\n <Flex gap={2}>\n <SearchInput\n label={formatMessage({\n id: getTrad('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n trackedEvent=\"didSearchMediaLibraryElements\"\n trackedEventDetails={{ location: 'upload' }}\n />\n TODO: Toolbar\n </Flex>\n }\n />\n\n <Layouts.Content>TODO: List/Grid views</Layouts.Content>\n </Layouts.Root>\n );\n};\n"],"names":["MediaLibraryPage","formatMessage","useIntl","_jsxs","Layouts","Root","_jsx","Header","navigationAction","Box","title","primaryAction","Flex","gap","SearchInput","label","id","getTrad","defaultMessage","trackedEvent","trackedEventDetails","location","Content"],"mappings":";;;;;;;;;;;;;;MAQaA,gBAAmB,GAAA,IAAA;IAC9B,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;IAE1B;;;;;;sBAQEC,eAAA,CAACC,oBAAQC,IAAI,EAAA;;AACX,0BAAAC,cAAA,CAACF,oBAAQG,MAAM,EAAA;AACbC,gBAAAA,gBAAAA,gBAAkBF,cAACG,CAAAA,gBAAAA,EAAAA;AAAI,oBAAA,QAAA,EAAA;;gBACvBC,KAAM,EAAA,uBAAA;AACNC,gBAAAA,aAAAA,gBACER,eAACS,CAAAA,iBAAAA,EAAAA;oBAAKC,GAAK,EAAA,CAAA;;sCACTP,cAACQ,CAAAA,uBAAAA,EAAAA;AACCC,4BAAAA,KAAAA,EAAOd,aAAc,CAAA;AACnBe,gCAAAA,EAAAA,EAAIC,eAAQ,CAAA,cAAA,CAAA;gCACZC,cAAgB,EAAA;AAClB,6BAAA,CAAA;4BACAC,YAAa,EAAA,+BAAA;4BACbC,mBAAqB,EAAA;gCAAEC,QAAU,EAAA;AAAS;;AAC1C,wBAAA;;;;AAMR,0BAAAf,cAAA,CAACF,oBAAQkB,OAAO,EAAA;AAAC,gBAAA,QAAA,EAAA;;;;AAGvB;;;;"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import 'react';
|
|
3
|
+
import { Layouts, SearchInput } from '@strapi/admin/strapi-admin';
|
|
4
|
+
import { Box, Flex } from '@strapi/design-system';
|
|
5
|
+
import { useIntl } from 'react-intl';
|
|
6
|
+
import 'byte-size';
|
|
7
|
+
import 'date-fns';
|
|
8
|
+
import { getTrad } from '../../utils/getTrad.mjs';
|
|
9
|
+
import 'qs';
|
|
10
|
+
import '../../utils/typeFromMime.mjs';
|
|
11
|
+
import '../../utils/urlYupSchema.mjs';
|
|
12
|
+
|
|
13
|
+
const MediaLibraryPage = ()=>{
|
|
14
|
+
const { formatMessage } = useIntl();
|
|
15
|
+
return(/**
|
|
16
|
+
* NOTE:
|
|
17
|
+
*
|
|
18
|
+
* The design differs from our current Layouts component.
|
|
19
|
+
* Either we find a way to make it work with our current Layouts component
|
|
20
|
+
* or we will have to write our own custom layout.
|
|
21
|
+
*/ /*#__PURE__*/ jsxs(Layouts.Root, {
|
|
22
|
+
children: [
|
|
23
|
+
/*#__PURE__*/ jsx(Layouts.Header, {
|
|
24
|
+
navigationAction: /*#__PURE__*/ jsx(Box, {
|
|
25
|
+
children: "TODO: Breadcrumbs"
|
|
26
|
+
}),
|
|
27
|
+
title: "TODO: Folder location",
|
|
28
|
+
primaryAction: /*#__PURE__*/ jsxs(Flex, {
|
|
29
|
+
gap: 2,
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ jsx(SearchInput, {
|
|
32
|
+
label: formatMessage({
|
|
33
|
+
id: getTrad('search.label'),
|
|
34
|
+
defaultMessage: 'Search for an asset'
|
|
35
|
+
}),
|
|
36
|
+
trackedEvent: "didSearchMediaLibraryElements",
|
|
37
|
+
trackedEventDetails: {
|
|
38
|
+
location: 'upload'
|
|
39
|
+
}
|
|
40
|
+
}),
|
|
41
|
+
"TODO: Toolbar"
|
|
42
|
+
]
|
|
43
|
+
})
|
|
44
|
+
}),
|
|
45
|
+
/*#__PURE__*/ jsx(Layouts.Content, {
|
|
46
|
+
children: "TODO: List/Grid views"
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
}));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { MediaLibraryPage };
|
|
53
|
+
//# sourceMappingURL=MediaLibraryPage.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaLibraryPage.mjs","sources":["../../../../admin/src/future/pages/MediaLibraryPage.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Layouts, SearchInput } from '@strapi/admin/strapi-admin';\nimport { Box, Flex } from '@strapi/design-system';\nimport { useIntl } from 'react-intl';\n\nimport { getTrad } from '../../utils';\n\nexport const MediaLibraryPage = () => {\n const { formatMessage } = useIntl();\n\n return (\n /**\n * NOTE:\n *\n * The design differs from our current Layouts component.\n * Either we find a way to make it work with our current Layouts component\n * or we will have to write our own custom layout.\n */\n <Layouts.Root>\n <Layouts.Header\n navigationAction={<Box>TODO: Breadcrumbs</Box>}\n title=\"TODO: Folder location\"\n primaryAction={\n <Flex gap={2}>\n <SearchInput\n label={formatMessage({\n id: getTrad('search.label'),\n defaultMessage: 'Search for an asset',\n })}\n trackedEvent=\"didSearchMediaLibraryElements\"\n trackedEventDetails={{ location: 'upload' }}\n />\n TODO: Toolbar\n </Flex>\n }\n />\n\n <Layouts.Content>TODO: List/Grid views</Layouts.Content>\n </Layouts.Root>\n );\n};\n"],"names":["MediaLibraryPage","formatMessage","useIntl","_jsxs","Layouts","Root","_jsx","Header","navigationAction","Box","title","primaryAction","Flex","gap","SearchInput","label","id","getTrad","defaultMessage","trackedEvent","trackedEventDetails","location","Content"],"mappings":";;;;;;;;;;;;MAQaA,gBAAmB,GAAA,IAAA;IAC9B,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;IAE1B;;;;;;sBAQEC,IAAA,CAACC,QAAQC,IAAI,EAAA;;AACX,0BAAAC,GAAA,CAACF,QAAQG,MAAM,EAAA;AACbC,gBAAAA,gBAAAA,gBAAkBF,GAACG,CAAAA,GAAAA,EAAAA;AAAI,oBAAA,QAAA,EAAA;;gBACvBC,KAAM,EAAA,uBAAA;AACNC,gBAAAA,aAAAA,gBACER,IAACS,CAAAA,IAAAA,EAAAA;oBAAKC,GAAK,EAAA,CAAA;;sCACTP,GAACQ,CAAAA,WAAAA,EAAAA;AACCC,4BAAAA,KAAAA,EAAOd,aAAc,CAAA;AACnBe,gCAAAA,EAAAA,EAAIC,OAAQ,CAAA,cAAA,CAAA;gCACZC,cAAgB,EAAA;AAClB,6BAAA,CAAA;4BACAC,YAAa,EAAA,+BAAA;4BACbC,mBAAqB,EAAA;gCAAEC,QAAU,EAAA;AAAS;;AAC1C,wBAAA;;;;AAMR,0BAAAf,GAAA,CAACF,QAAQkB,OAAO,EAAA;AAAC,gBAAA,QAAA,EAAA;;;;AAGvB;;;;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var strapiAdmin = require('@strapi/admin/strapi-admin');
|
|
5
|
+
var reactIntl = require('react-intl');
|
|
6
|
+
var reactQuery = require('react-query');
|
|
7
|
+
require('byte-size');
|
|
8
|
+
require('date-fns');
|
|
9
|
+
var getTrad = require('../utils/getTrad.js');
|
|
10
|
+
require('qs');
|
|
11
|
+
require('../utils/typeFromMime.js');
|
|
12
|
+
require('../utils/urlYupSchema.js');
|
|
13
|
+
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
15
|
+
var n = Object.create(null);
|
|
16
|
+
if (e) {
|
|
17
|
+
Object.keys(e).forEach(function (k) {
|
|
18
|
+
if (k !== 'default') {
|
|
19
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return e[k]; }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
32
|
+
|
|
33
|
+
const fetchLatestJob = async (get)=>{
|
|
34
|
+
try {
|
|
35
|
+
const { data } = await get('/upload/actions/generate-ai-metadata/latest');
|
|
36
|
+
return data;
|
|
37
|
+
} catch {
|
|
38
|
+
// Return null on any error - UI treats this as "no active job"
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const useAIMetadataJob = (options)=>{
|
|
43
|
+
const { get } = strapiAdmin.useFetchClient();
|
|
44
|
+
const { toggleNotification } = strapiAdmin.useNotification();
|
|
45
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
46
|
+
const queryClient = reactQuery.useQueryClient();
|
|
47
|
+
const enabled = options?.enabled ?? true;
|
|
48
|
+
const [previousJobStatus, setPreviousJobStatus] = React__namespace.useState(null);
|
|
49
|
+
// Single query with conditional polling
|
|
50
|
+
const { data: job, refetch } = reactQuery.useQuery([
|
|
51
|
+
'ai-metadata-latest-job'
|
|
52
|
+
], ()=>fetchLatestJob(get), {
|
|
53
|
+
enabled,
|
|
54
|
+
// Poll every second when job is processing
|
|
55
|
+
refetchInterval: (data)=>{
|
|
56
|
+
// If no data yet, don't poll
|
|
57
|
+
if (!data) return false;
|
|
58
|
+
// Poll while processing
|
|
59
|
+
if (data.status === 'processing') {
|
|
60
|
+
return 1000;
|
|
61
|
+
}
|
|
62
|
+
// Stop polling when completed or failed
|
|
63
|
+
return false;
|
|
64
|
+
},
|
|
65
|
+
retry: false,
|
|
66
|
+
refetchOnWindowFocus: false
|
|
67
|
+
});
|
|
68
|
+
const currentJobStatus = job?.status ?? null;
|
|
69
|
+
// Detect status transitions and show notifications
|
|
70
|
+
React__namespace.useEffect(()=>{
|
|
71
|
+
if (!currentJobStatus) return;
|
|
72
|
+
// Detect transition from active state to completed
|
|
73
|
+
if (previousJobStatus === 'processing' && currentJobStatus === 'completed') {
|
|
74
|
+
toggleNotification({
|
|
75
|
+
type: 'success',
|
|
76
|
+
message: formatMessage({
|
|
77
|
+
id: getTrad.getTrad('settings.form.aiMetadata.job-completed'),
|
|
78
|
+
defaultMessage: 'Successfully generated metadata'
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
// Invalidate metadata count query to refresh the count
|
|
82
|
+
queryClient.invalidateQueries([
|
|
83
|
+
'ai-metadata-count'
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
// Detect transition from active state to failed
|
|
87
|
+
if (previousJobStatus === 'processing' && currentJobStatus === 'failed') {
|
|
88
|
+
toggleNotification({
|
|
89
|
+
type: 'danger',
|
|
90
|
+
message: formatMessage({
|
|
91
|
+
id: getTrad.getTrad('settings.form.aiMetadata.job-failed'),
|
|
92
|
+
defaultMessage: 'Failed to generate metadata. Please try again.'
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Update previous status if it changed
|
|
97
|
+
if (previousJobStatus !== currentJobStatus) {
|
|
98
|
+
setPreviousJobStatus(currentJobStatus);
|
|
99
|
+
}
|
|
100
|
+
}, [
|
|
101
|
+
currentJobStatus,
|
|
102
|
+
previousJobStatus,
|
|
103
|
+
toggleNotification,
|
|
104
|
+
formatMessage,
|
|
105
|
+
queryClient
|
|
106
|
+
]);
|
|
107
|
+
return {
|
|
108
|
+
data: job,
|
|
109
|
+
refetch
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
exports.useAIMetadataJob = useAIMetadataJob;
|
|
114
|
+
//# sourceMappingURL=useAIMetadataJob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAIMetadataJob.js","sources":["../../../admin/src/hooks/useAIMetadataJob.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useFetchClient, useNotification } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useQueryClient } from 'react-query';\n\nimport { AIMetadataJob } from '../../../shared/contracts/ai-metadata-jobs';\nimport { getTrad } from '../utils';\n\nconst fetchLatestJob = async (\n get: ReturnType<typeof useFetchClient>['get']\n): Promise<AIMetadataJob | null> => {\n try {\n const { data } = await get('/upload/actions/generate-ai-metadata/latest');\n return data;\n } catch {\n // Return null on any error - UI treats this as \"no active job\"\n return null;\n }\n};\n\nexport const useAIMetadataJob = (options?: { enabled?: boolean }) => {\n const { get } = useFetchClient();\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const queryClient = useQueryClient();\n const enabled = options?.enabled ?? true;\n\n const [previousJobStatus, setPreviousJobStatus] = React.useState<AIMetadataJob['status'] | null>(\n null\n );\n\n // Single query with conditional polling\n const { data: job, refetch } = useQuery<AIMetadataJob | null, { message: string }>(\n ['ai-metadata-latest-job'],\n () => fetchLatestJob(get),\n {\n enabled,\n // Poll every second when job is processing\n refetchInterval: (data) => {\n // If no data yet, don't poll\n if (!data) return false;\n\n // Poll while processing\n if (data.status === 'processing') {\n return 1000;\n }\n\n // Stop polling when completed or failed\n return false;\n },\n retry: false,\n refetchOnWindowFocus: false,\n }\n );\n\n const currentJobStatus = job?.status ?? null;\n\n // Detect status transitions and show notifications\n React.useEffect(() => {\n if (!currentJobStatus) return;\n\n // Detect transition from active state to completed\n if (previousJobStatus === 'processing' && currentJobStatus === 'completed') {\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('settings.form.aiMetadata.job-completed'),\n defaultMessage: 'Successfully generated metadata',\n }),\n });\n // Invalidate metadata count query to refresh the count\n queryClient.invalidateQueries(['ai-metadata-count']);\n }\n\n // Detect transition from active state to failed\n if (previousJobStatus === 'processing' && currentJobStatus === 'failed') {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTrad('settings.form.aiMetadata.job-failed'),\n defaultMessage: 'Failed to generate metadata. Please try again.',\n }),\n });\n }\n\n // Update previous status if it changed\n if (previousJobStatus !== currentJobStatus) {\n setPreviousJobStatus(currentJobStatus);\n }\n }, [currentJobStatus, previousJobStatus, toggleNotification, formatMessage, queryClient]);\n\n return {\n data: job,\n refetch,\n };\n};\n"],"names":["fetchLatestJob","get","data","useAIMetadataJob","options","useFetchClient","toggleNotification","useNotification","formatMessage","useIntl","queryClient","useQueryClient","enabled","previousJobStatus","setPreviousJobStatus","React","useState","job","refetch","useQuery","refetchInterval","status","retry","refetchOnWindowFocus","currentJobStatus","useEffect","type","message","id","getTrad","defaultMessage","invalidateQueries"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAMA,iBAAiB,OACrBC,GAAAA,GAAAA;IAEA,IAAI;AACF,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAG,MAAMD,GAAI,CAAA,6CAAA,CAAA;QAC3B,OAAOC,IAAAA;AACT,KAAA,CAAE,OAAM;;QAEN,OAAO,IAAA;AACT;AACF,CAAA;AAEO,MAAMC,mBAAmB,CAACC,OAAAA,GAAAA;IAC/B,MAAM,EAAEH,GAAG,EAAE,GAAGI,0BAAAA,EAAAA;IAChB,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,2BAAAA,EAAAA;IAC/B,MAAM,EAAEC,aAAa,EAAE,GAAGC,iBAAAA,EAAAA;AAC1B,IAAA,MAAMC,WAAcC,GAAAA,yBAAAA,EAAAA;IACpB,MAAMC,OAAAA,GAAUR,SAASQ,OAAW,IAAA,IAAA;AAEpC,IAAA,MAAM,CAACC,iBAAmBC,EAAAA,oBAAAA,CAAqB,GAAGC,gBAAAA,CAAMC,QAAQ,CAC9D,IAAA,CAAA;;AAIF,IAAA,MAAM,EAAEd,IAAMe,EAAAA,GAAG,EAAEC,OAAO,EAAE,GAAGC,mBAC7B,CAAA;AAAC,QAAA;KAAyB,EAC1B,IAAMnB,eAAeC,GACrB,CAAA,EAAA;AACEW,QAAAA,OAAAA;;AAEAQ,QAAAA,eAAAA,EAAiB,CAAClB,IAAAA,GAAAA;;YAEhB,IAAI,CAACA,MAAM,OAAO,KAAA;;YAGlB,IAAIA,IAAAA,CAAKmB,MAAM,KAAK,YAAc,EAAA;gBAChC,OAAO,IAAA;AACT;;YAGA,OAAO,KAAA;AACT,SAAA;QACAC,KAAO,EAAA,KAAA;QACPC,oBAAsB,EAAA;AACxB,KAAA,CAAA;IAGF,MAAMC,gBAAAA,GAAmBP,KAAKI,MAAU,IAAA,IAAA;;AAGxCN,IAAAA,gBAAAA,CAAMU,SAAS,CAAC,IAAA;AACd,QAAA,IAAI,CAACD,gBAAkB,EAAA;;QAGvB,IAAIX,iBAAAA,KAAsB,YAAgBW,IAAAA,gBAAAA,KAAqB,WAAa,EAAA;YAC1ElB,kBAAmB,CAAA;gBACjBoB,IAAM,EAAA,SAAA;AACNC,gBAAAA,OAAAA,EAASnB,aAAc,CAAA;AACrBoB,oBAAAA,EAAAA,EAAIC,eAAQ,CAAA,wCAAA,CAAA;oBACZC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;;AAEApB,YAAAA,WAAAA,CAAYqB,iBAAiB,CAAC;AAAC,gBAAA;AAAoB,aAAA,CAAA;AACrD;;QAGA,IAAIlB,iBAAAA,KAAsB,YAAgBW,IAAAA,gBAAAA,KAAqB,QAAU,EAAA;YACvElB,kBAAmB,CAAA;gBACjBoB,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASnB,aAAc,CAAA;AACrBoB,oBAAAA,EAAAA,EAAIC,eAAQ,CAAA,qCAAA,CAAA;oBACZC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;AACF;;AAGA,QAAA,IAAIjB,sBAAsBW,gBAAkB,EAAA;YAC1CV,oBAAqBU,CAAAA,gBAAAA,CAAAA;AACvB;KACC,EAAA;AAACA,QAAAA,gBAAAA;AAAkBX,QAAAA,iBAAAA;AAAmBP,QAAAA,kBAAAA;AAAoBE,QAAAA,aAAAA;AAAeE,QAAAA;AAAY,KAAA,CAAA;IAExF,OAAO;QACLR,IAAMe,EAAAA,GAAAA;AACNC,QAAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useFetchClient, useNotification } from '@strapi/admin/strapi-admin';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import { useQueryClient, useQuery } from 'react-query';
|
|
5
|
+
import 'byte-size';
|
|
6
|
+
import 'date-fns';
|
|
7
|
+
import { getTrad } from '../utils/getTrad.mjs';
|
|
8
|
+
import 'qs';
|
|
9
|
+
import '../utils/typeFromMime.mjs';
|
|
10
|
+
import '../utils/urlYupSchema.mjs';
|
|
11
|
+
|
|
12
|
+
const fetchLatestJob = async (get)=>{
|
|
13
|
+
try {
|
|
14
|
+
const { data } = await get('/upload/actions/generate-ai-metadata/latest');
|
|
15
|
+
return data;
|
|
16
|
+
} catch {
|
|
17
|
+
// Return null on any error - UI treats this as "no active job"
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const useAIMetadataJob = (options)=>{
|
|
22
|
+
const { get } = useFetchClient();
|
|
23
|
+
const { toggleNotification } = useNotification();
|
|
24
|
+
const { formatMessage } = useIntl();
|
|
25
|
+
const queryClient = useQueryClient();
|
|
26
|
+
const enabled = options?.enabled ?? true;
|
|
27
|
+
const [previousJobStatus, setPreviousJobStatus] = React.useState(null);
|
|
28
|
+
// Single query with conditional polling
|
|
29
|
+
const { data: job, refetch } = useQuery([
|
|
30
|
+
'ai-metadata-latest-job'
|
|
31
|
+
], ()=>fetchLatestJob(get), {
|
|
32
|
+
enabled,
|
|
33
|
+
// Poll every second when job is processing
|
|
34
|
+
refetchInterval: (data)=>{
|
|
35
|
+
// If no data yet, don't poll
|
|
36
|
+
if (!data) return false;
|
|
37
|
+
// Poll while processing
|
|
38
|
+
if (data.status === 'processing') {
|
|
39
|
+
return 1000;
|
|
40
|
+
}
|
|
41
|
+
// Stop polling when completed or failed
|
|
42
|
+
return false;
|
|
43
|
+
},
|
|
44
|
+
retry: false,
|
|
45
|
+
refetchOnWindowFocus: false
|
|
46
|
+
});
|
|
47
|
+
const currentJobStatus = job?.status ?? null;
|
|
48
|
+
// Detect status transitions and show notifications
|
|
49
|
+
React.useEffect(()=>{
|
|
50
|
+
if (!currentJobStatus) return;
|
|
51
|
+
// Detect transition from active state to completed
|
|
52
|
+
if (previousJobStatus === 'processing' && currentJobStatus === 'completed') {
|
|
53
|
+
toggleNotification({
|
|
54
|
+
type: 'success',
|
|
55
|
+
message: formatMessage({
|
|
56
|
+
id: getTrad('settings.form.aiMetadata.job-completed'),
|
|
57
|
+
defaultMessage: 'Successfully generated metadata'
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
// Invalidate metadata count query to refresh the count
|
|
61
|
+
queryClient.invalidateQueries([
|
|
62
|
+
'ai-metadata-count'
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
// Detect transition from active state to failed
|
|
66
|
+
if (previousJobStatus === 'processing' && currentJobStatus === 'failed') {
|
|
67
|
+
toggleNotification({
|
|
68
|
+
type: 'danger',
|
|
69
|
+
message: formatMessage({
|
|
70
|
+
id: getTrad('settings.form.aiMetadata.job-failed'),
|
|
71
|
+
defaultMessage: 'Failed to generate metadata. Please try again.'
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Update previous status if it changed
|
|
76
|
+
if (previousJobStatus !== currentJobStatus) {
|
|
77
|
+
setPreviousJobStatus(currentJobStatus);
|
|
78
|
+
}
|
|
79
|
+
}, [
|
|
80
|
+
currentJobStatus,
|
|
81
|
+
previousJobStatus,
|
|
82
|
+
toggleNotification,
|
|
83
|
+
formatMessage,
|
|
84
|
+
queryClient
|
|
85
|
+
]);
|
|
86
|
+
return {
|
|
87
|
+
data: job,
|
|
88
|
+
refetch
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export { useAIMetadataJob };
|
|
93
|
+
//# sourceMappingURL=useAIMetadataJob.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAIMetadataJob.mjs","sources":["../../../admin/src/hooks/useAIMetadataJob.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useFetchClient, useNotification } from '@strapi/admin/strapi-admin';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useQueryClient } from 'react-query';\n\nimport { AIMetadataJob } from '../../../shared/contracts/ai-metadata-jobs';\nimport { getTrad } from '../utils';\n\nconst fetchLatestJob = async (\n get: ReturnType<typeof useFetchClient>['get']\n): Promise<AIMetadataJob | null> => {\n try {\n const { data } = await get('/upload/actions/generate-ai-metadata/latest');\n return data;\n } catch {\n // Return null on any error - UI treats this as \"no active job\"\n return null;\n }\n};\n\nexport const useAIMetadataJob = (options?: { enabled?: boolean }) => {\n const { get } = useFetchClient();\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const queryClient = useQueryClient();\n const enabled = options?.enabled ?? true;\n\n const [previousJobStatus, setPreviousJobStatus] = React.useState<AIMetadataJob['status'] | null>(\n null\n );\n\n // Single query with conditional polling\n const { data: job, refetch } = useQuery<AIMetadataJob | null, { message: string }>(\n ['ai-metadata-latest-job'],\n () => fetchLatestJob(get),\n {\n enabled,\n // Poll every second when job is processing\n refetchInterval: (data) => {\n // If no data yet, don't poll\n if (!data) return false;\n\n // Poll while processing\n if (data.status === 'processing') {\n return 1000;\n }\n\n // Stop polling when completed or failed\n return false;\n },\n retry: false,\n refetchOnWindowFocus: false,\n }\n );\n\n const currentJobStatus = job?.status ?? null;\n\n // Detect status transitions and show notifications\n React.useEffect(() => {\n if (!currentJobStatus) return;\n\n // Detect transition from active state to completed\n if (previousJobStatus === 'processing' && currentJobStatus === 'completed') {\n toggleNotification({\n type: 'success',\n message: formatMessage({\n id: getTrad('settings.form.aiMetadata.job-completed'),\n defaultMessage: 'Successfully generated metadata',\n }),\n });\n // Invalidate metadata count query to refresh the count\n queryClient.invalidateQueries(['ai-metadata-count']);\n }\n\n // Detect transition from active state to failed\n if (previousJobStatus === 'processing' && currentJobStatus === 'failed') {\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: getTrad('settings.form.aiMetadata.job-failed'),\n defaultMessage: 'Failed to generate metadata. Please try again.',\n }),\n });\n }\n\n // Update previous status if it changed\n if (previousJobStatus !== currentJobStatus) {\n setPreviousJobStatus(currentJobStatus);\n }\n }, [currentJobStatus, previousJobStatus, toggleNotification, formatMessage, queryClient]);\n\n return {\n data: job,\n refetch,\n };\n};\n"],"names":["fetchLatestJob","get","data","useAIMetadataJob","options","useFetchClient","toggleNotification","useNotification","formatMessage","useIntl","queryClient","useQueryClient","enabled","previousJobStatus","setPreviousJobStatus","React","useState","job","refetch","useQuery","refetchInterval","status","retry","refetchOnWindowFocus","currentJobStatus","useEffect","type","message","id","getTrad","defaultMessage","invalidateQueries"],"mappings":";;;;;;;;;;;AASA,MAAMA,iBAAiB,OACrBC,GAAAA,GAAAA;IAEA,IAAI;AACF,QAAA,MAAM,EAAEC,IAAI,EAAE,GAAG,MAAMD,GAAI,CAAA,6CAAA,CAAA;QAC3B,OAAOC,IAAAA;AACT,KAAA,CAAE,OAAM;;QAEN,OAAO,IAAA;AACT;AACF,CAAA;AAEO,MAAMC,mBAAmB,CAACC,OAAAA,GAAAA;IAC/B,MAAM,EAAEH,GAAG,EAAE,GAAGI,cAAAA,EAAAA;IAChB,MAAM,EAAEC,kBAAkB,EAAE,GAAGC,eAAAA,EAAAA;IAC/B,MAAM,EAAEC,aAAa,EAAE,GAAGC,OAAAA,EAAAA;AAC1B,IAAA,MAAMC,WAAcC,GAAAA,cAAAA,EAAAA;IACpB,MAAMC,OAAAA,GAAUR,SAASQ,OAAW,IAAA,IAAA;AAEpC,IAAA,MAAM,CAACC,iBAAmBC,EAAAA,oBAAAA,CAAqB,GAAGC,KAAAA,CAAMC,QAAQ,CAC9D,IAAA,CAAA;;AAIF,IAAA,MAAM,EAAEd,IAAMe,EAAAA,GAAG,EAAEC,OAAO,EAAE,GAAGC,QAC7B,CAAA;AAAC,QAAA;KAAyB,EAC1B,IAAMnB,eAAeC,GACrB,CAAA,EAAA;AACEW,QAAAA,OAAAA;;AAEAQ,QAAAA,eAAAA,EAAiB,CAAClB,IAAAA,GAAAA;;YAEhB,IAAI,CAACA,MAAM,OAAO,KAAA;;YAGlB,IAAIA,IAAAA,CAAKmB,MAAM,KAAK,YAAc,EAAA;gBAChC,OAAO,IAAA;AACT;;YAGA,OAAO,KAAA;AACT,SAAA;QACAC,KAAO,EAAA,KAAA;QACPC,oBAAsB,EAAA;AACxB,KAAA,CAAA;IAGF,MAAMC,gBAAAA,GAAmBP,KAAKI,MAAU,IAAA,IAAA;;AAGxCN,IAAAA,KAAAA,CAAMU,SAAS,CAAC,IAAA;AACd,QAAA,IAAI,CAACD,gBAAkB,EAAA;;QAGvB,IAAIX,iBAAAA,KAAsB,YAAgBW,IAAAA,gBAAAA,KAAqB,WAAa,EAAA;YAC1ElB,kBAAmB,CAAA;gBACjBoB,IAAM,EAAA,SAAA;AACNC,gBAAAA,OAAAA,EAASnB,aAAc,CAAA;AACrBoB,oBAAAA,EAAAA,EAAIC,OAAQ,CAAA,wCAAA,CAAA;oBACZC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;;AAEApB,YAAAA,WAAAA,CAAYqB,iBAAiB,CAAC;AAAC,gBAAA;AAAoB,aAAA,CAAA;AACrD;;QAGA,IAAIlB,iBAAAA,KAAsB,YAAgBW,IAAAA,gBAAAA,KAAqB,QAAU,EAAA;YACvElB,kBAAmB,CAAA;gBACjBoB,IAAM,EAAA,QAAA;AACNC,gBAAAA,OAAAA,EAASnB,aAAc,CAAA;AACrBoB,oBAAAA,EAAAA,EAAIC,OAAQ,CAAA,qCAAA,CAAA;oBACZC,cAAgB,EAAA;AAClB,iBAAA;AACF,aAAA,CAAA;AACF;;AAGA,QAAA,IAAIjB,sBAAsBW,gBAAkB,EAAA;YAC1CV,oBAAqBU,CAAAA,gBAAAA,CAAAA;AACvB;KACC,EAAA;AAACA,QAAAA,gBAAAA;AAAkBX,QAAAA,iBAAAA;AAAmBP,QAAAA,kBAAAA;AAAoBE,QAAAA,aAAAA;AAAeE,QAAAA;AAAY,KAAA,CAAA;IAExF,OAAO;QACLR,IAAMe,EAAAA,GAAAA;AACNC,QAAAA;AACF,KAAA;AACF;;;;"}
|