diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-preview/dot-file-field-preview.component.html b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-preview/dot-file-field-preview.component.html
index 53ca070f3268..d3b04b77a7a3 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-preview/dot-file-field-preview.component.html
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-preview/dot-file-field-preview.component.html
@@ -1,5 +1,6 @@
@let previewFile = $previewFile();
@let metadata = $metadata();
+@let downloadLink = $downloadLink();
@@ -34,12 +35,21 @@
}
}
+
+
+ @if (downloadLink) {
+
+ }
+
+ @for (sourceLink of $resourceLinks(); track $index) {
+
+
{{ sourceLink.key | dm }}:
+
+
+ }
({ alias: 'previewFile' });
removeFile = output();
$showDialog = signal(false);
@@ -46,7 +57,79 @@ export class DotFileFieldPreviewComponent {
return getFileMetadata(previewFile.file);
});
+ $downloadLink = computed(() => {
+ const previewFile = this.$previewFile();
+ if (previewFile.source === 'contentlet') {
+ const file = previewFile.file;
+
+ return `/contentAsset/raw-data/${file.inode}/asset?byInode=true&force_download=true`;
+ }
+
+ return null;
+ });
+
+ $resourceLinks = signal([]);
+
+ ngOnInit() {
+ const previewFile = this.$previewFile();
+
+ if (previewFile.source === 'contentlet') {
+ this.fetchResourceLinks(previewFile.file);
+ }
+ }
+
toggleShowDialog() {
this.$showDialog.set(!this.$showDialog());
}
+
+ downloadAsset(link: string): void {
+ window.open(link, '_self');
+ }
+
+ private fetchResourceLinks(contentlet: DotCMSContentlet): void {
+ this.#dotResourceLinksService
+ .getFileResourceLinks({
+ fieldVariable: 'asset',
+ inodeOrIdentifier: contentlet.identifier
+ })
+ .pipe(
+ catchError(() => {
+ return of({
+ configuredImageURL: '',
+ text: '',
+ versionPath: '',
+ idPath: ''
+ });
+ })
+ )
+ .subscribe(({ configuredImageURL, text, versionPath, idPath }) => {
+ const fileLink = configuredImageURL
+ ? `${window.location.origin}${configuredImageURL}`
+ : '';
+
+ const options = [
+ {
+ key: 'FileLink',
+ value: fileLink,
+ },
+ {
+ key: 'VersionPath',
+ value: versionPath,
+ },
+ {
+ key: 'IdPath',
+ value: idPath,
+ }
+ ];
+
+ if (contentlet.baseType === DotCMSBaseTypesContentTypes.FILEASSET) {
+ options.push({
+ key: 'Resource-Link',
+ value: text,
+ });
+ }
+
+ this.$resourceLinks.set(options);
+ });
+ }
}
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-ui-message/dot-file-field-ui-message.component.scss b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-ui-message/dot-file-field-ui-message.component.scss
index fccd0d7f5e15..fbd0b6ef596d 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-ui-message/dot-file-field-ui-message.component.scss
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/components/dot-file-field-ui-message/dot-file-field-ui-message.component.scss
@@ -33,4 +33,5 @@
.text {
text-align: center;
line-height: 140%;
+ font-size: $font-size-default;
}
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.html b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.html
index 8de4c3bce53e..d8de8e40c5bc 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.html
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.component.html
@@ -10,7 +10,7 @@
void) {
this.onChange = fn;
@@ -111,6 +111,16 @@ export class DotEditContentFileFieldComponent implements ControlValueAccessor, O
this.store.handleUploadFile(file);
}
+ fileSelected(files: FileList) {
+ const file = files[0];
+
+ if (!file) {
+ return;
+ }
+
+ this.store.handleUploadFile(file);
+ }
+
private handleFileDropError({ errorsType }: DropZoneFileValidity): void {
const errorType = errorsType[0];
const uiMessage = getUiMessage(errorType);
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.const.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.const.ts
index 0f9c5f932871..796aa5997f6f 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.const.ts
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/dot-edit-content-file-field.const.ts
@@ -18,7 +18,7 @@ export const INPUT_CONFIG: ConfigActions = {
allowCreateFile: true,
allowGenerateImg: false,
acceptedFiles: [],
- maxFileSize: 1024
+ maxFileSize: null
},
Image: {
allowExistingFile: true,
@@ -26,7 +26,7 @@ export const INPUT_CONFIG: ConfigActions = {
allowCreateFile: false,
allowGenerateImg: true,
acceptedFiles: ['image/*'],
- maxFileSize: 0
+ maxFileSize: null
},
Binary: {
allowExistingFile: false,
@@ -34,6 +34,6 @@ export const INPUT_CONFIG: ConfigActions = {
allowCreateFile: true,
allowGenerateImg: true,
acceptedFiles: [],
- maxFileSize: 0
+ maxFileSize: null
}
};
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/models/index.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/models/index.ts
index fd20a59884d7..23ca92371b74 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/models/index.ts
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/models/index.ts
@@ -29,3 +29,8 @@ export type PreviewFile =
source: 'contentlet';
file: DotCMSContentlet;
};
+
+ export interface DotPreviewResourceLink {
+ key: string;
+ value: string;
+ }
\ No newline at end of file
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/store/file-field.store.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/store/file-field.store.ts
index fcfcd74a870f..da9afd1535be 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/store/file-field.store.ts
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/store/file-field.store.ts
@@ -5,11 +5,12 @@ import { pipe } from 'rxjs';
import { computed, inject } from '@angular/core';
-import { switchMap, tap } from 'rxjs/operators';
+import { filter, switchMap, tap } from 'rxjs/operators';
import { DotUploadFileService } from '@dotcms/data-access';
import { DotCMSContentlet, DotCMSTempFile } from '@dotcms/dotcms-models';
+import { DotEditContentService } from '../../../services/dot-edit-content.service';
import { INPUT_CONFIG } from '../dot-edit-content-file-field.const';
import { INPUT_TYPES, FILE_STATUS, UIMessage, PreviewFile } from '../models';
import { getUiMessage } from '../utils/messages';
@@ -29,7 +30,7 @@ export interface FileFieldState {
allowCreateFile: boolean;
uiMessage: UIMessage;
acceptedFiles: string[];
- maxFileSize: number;
+ maxFileSize: number | null;
fieldVariable: string;
previewFile: PreviewFile | null;
}
@@ -49,7 +50,7 @@ const initialState: FileFieldState = {
allowCreateFile: false,
uiMessage: getUiMessage('DEFAULT'),
acceptedFiles: [],
- maxFileSize: 0,
+ maxFileSize: null,
fieldVariable: '',
previewFile: null
};
@@ -68,84 +69,131 @@ export const FileFieldStore = signalStore(
return currentStatus === 'uploading';
})
})),
- withMethods((store, fileService = inject(DotUploadFileService)) => ({
- initLoad: (initState: {
- inputType: FileFieldState['inputType'];
- fieldVariable: FileFieldState['fieldVariable'];
- }) => {
- const { inputType, fieldVariable } = initState;
+ withMethods(
+ (
+ store,
+ fileService = inject(DotUploadFileService),
+ contentService = inject(DotEditContentService)
+ ) => ({
+ initLoad: (initState: {
+ inputType: FileFieldState['inputType'];
+ fieldVariable: FileFieldState['fieldVariable'];
+ }) => {
+ const { inputType, fieldVariable } = initState;
- const actions = INPUT_CONFIG[inputType] || {};
+ const actions = INPUT_CONFIG[inputType] || {};
- patchState(store, {
- inputType,
- fieldVariable,
- ...actions
- });
- },
- setValue: (value: string) => {
- patchState(store, { value });
- },
- setUIMessage: (uiMessage: UIMessage) => {
- const acceptedFiles = store.acceptedFiles();
- const maxFileSize = store.maxFileSize();
+ patchState(store, {
+ inputType,
+ fieldVariable,
+ ...actions
+ });
+ },
+ setUIMessage: (uiMessage: UIMessage) => {
+ const acceptedFiles = store.acceptedFiles();
+ const maxFileSize = store.maxFileSize();
- patchState(store, {
- uiMessage: {
- ...uiMessage,
- args: [acceptedFiles.join(', '), `${maxFileSize}`]
- }
- });
- },
- removeFile: () => {
- patchState(store, {
- contentlet: null,
- tempFile: null,
- value: '',
- fileStatus: 'init'
- });
- },
- setDropZoneState: (state: boolean) => {
- patchState(store, {
- dropZoneActive: state
- });
- },
- setUploading: () => {
- patchState(store, {
- dropZoneActive: false,
- fileStatus: 'uploading'
- });
- },
- handleUploadFile: rxMethod(
- pipe(
- tap(() =>
- patchState(store, {
- dropZoneActive: false,
- fileStatus: 'uploading'
+ patchState(store, {
+ uiMessage: {
+ ...uiMessage,
+ args: [`${maxFileSize}`, acceptedFiles.join(', ')]
+ }
+ });
+ },
+ removeFile: () => {
+ patchState(store, {
+ contentlet: null,
+ tempFile: null,
+ value: '',
+ fileStatus: 'init',
+ uiMessage: getUiMessage('DEFAULT')
+ });
+ },
+ setDropZoneState: (state: boolean) => {
+ patchState(store, {
+ dropZoneActive: state
+ });
+ },
+ setUploading: () => {
+ patchState(store, {
+ dropZoneActive: false,
+ fileStatus: 'uploading'
+ });
+ },
+ handleUploadFile: rxMethod(
+ pipe(
+ tap(() => {
+ patchState(store, {
+ dropZoneActive: false,
+ fileStatus: 'uploading'
+ });
+ }),
+ filter((file) => {
+ const maxFileSize = store.maxFileSize();
+
+ if (maxFileSize && file.size > maxFileSize) {
+ patchState(store, {
+ fileStatus: 'init',
+ dropZoneActive: true,
+ uiMessage: {
+ ...getUiMessage('MAX_FILE_SIZE_EXCEEDED'),
+ args: [`${maxFileSize}`]
+ }
+ });
+
+ return false;
+ }
+
+ return true;
+ }),
+ switchMap((file) => {
+ return fileService.uploadDotAsset(file).pipe(
+ tapResponse({
+ next: (file) => {
+ patchState(store, {
+ tempFile: null,
+ contentlet: file,
+ fileStatus: 'preview',
+ value: file.identifier,
+ previewFile: { source: 'contentlet', file }
+ });
+ },
+ error: () => {
+ patchState(store, {
+ fileStatus: 'init',
+ uiMessage: getUiMessage('SERVER_ERROR')
+ });
+ }
+ })
+ );
})
- ),
- switchMap((file) => {
- return fileService.uploadDotAsset(file).pipe(
- tapResponse({
- next: (file) => {
- patchState(store, {
- tempFile: null,
- contentlet: file,
- fileStatus: 'preview',
- value: file.identifier,
- previewFile: { source: 'contentlet', file: file }
- });
- },
- error: () => {
- patchState(store, {
- fileStatus: 'init',
- uiMessage: getUiMessage('SERVER_ERROR')
- });
- }
- })
- );
- })
+ )
+ ),
+ getAssetData: rxMethod(
+ pipe(
+ switchMap((identifier) => {
+ return contentService.getContentById(identifier).pipe(
+ tapResponse({
+ next: (file) => {
+ patchState(store, {
+ tempFile: null,
+ contentlet: file,
+ fileStatus: 'preview',
+ value: file.identifier,
+ previewFile: { source: 'contentlet', file }
+ });
+ },
+ error: () => {
+ patchState(store, {
+ fileStatus: 'init',
+ uiMessage: getUiMessage('SERVER_ERROR')
+ });
+ }
+ })
+ );
+ })
+ )
)
- )
- }))
+ })
+ )
);
diff --git a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/utils/index.ts b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/utils/index.ts
index cfb667ae0067..8460e5c042c1 100644
--- a/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/utils/index.ts
+++ b/core-web/libs/edit-content/src/lib/fields/dot-edit-content-file-field/utils/index.ts
@@ -1,8 +1,6 @@
import { DotCMSContentlet, DotFileMetadata } from '@dotcms/dotcms-models';
export const getFileMetadata = (contentlet: DotCMSContentlet): DotFileMetadata => {
- console.log('contentlet', contentlet);
-
const { metaData } = contentlet;
const metadata = metaData || contentlet[`assetMetaData`];