diff --git a/library/package.json b/library/package.json index 47ffdda..f33eb69 100644 --- a/library/package.json +++ b/library/package.json @@ -1,6 +1,6 @@ { "name": "@irontec/ivoz-ui", - "version": "1.4.3", + "version": "1.4.4", "description": "UI library used in ivozprovider", "license": "GPL-3.0", "main": "index.js", diff --git a/library/src/components/List/Content/ListContentValue.tsx b/library/src/components/List/Content/ListContentValue.tsx index 6738646..5493025 100644 --- a/library/src/components/List/Content/ListContentValue.tsx +++ b/library/src/components/List/Content/ListContentValue.tsx @@ -13,6 +13,7 @@ import { StyledCheckBoxOutlineBlankIcon, StyledTableRowFkLink, } from './Table/ContentTable.styles'; +import DownloadFile from '../DownloadFile'; interface ListContentValueProps { columnName: string; @@ -23,12 +24,12 @@ interface ListContentValueProps { const ListContentValue = (props: ListContentValueProps): JSX.Element => { const { column, columnName, row, entityService } = props; - const routes = useStoreState((state) => state.routes.routes); const ListDecorator = entityService.getListDecorator(); const customComponent = (column as ScalarProperty).component; - + const isDownloadable = (column as ScalarProperty).downloadable; + const isFileType = (column as ScalarProperty).type === 'file'; const isFk = isPropertyFk(column); const loadingFk = isFk && @@ -97,6 +98,16 @@ const ListContentValue = (props: ListContentValueProps): JSX.Element => { response = ; } + if (isDownloadable && isFileType) { + response = ( + + ); + } + const prefix = column?.prefix || ''; return ( diff --git a/library/src/components/List/DownloadFile.styles.tsx b/library/src/components/List/DownloadFile.styles.tsx new file mode 100644 index 0000000..5479a76 --- /dev/null +++ b/library/src/components/List/DownloadFile.styles.tsx @@ -0,0 +1,21 @@ +import styled from '@emotion/styled'; +import DownloadIcon from '@mui/icons-material/Download'; + +export const StyledPdfIcon = styled(DownloadIcon)(() => { + return { + color: '#5b5b5b', + verticalAlign: 'bottom', + fontSize: '1.3em', + cursor: 'pointer', + }; +}); + +export const StyledFileName = styled.span(() => { + return { + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + maxWidth: '60px', + display: 'inline-flex', + }; +}); diff --git a/library/src/components/List/DownloadFile.tsx b/library/src/components/List/DownloadFile.tsx new file mode 100644 index 0000000..1acfc72 --- /dev/null +++ b/library/src/components/List/DownloadFile.tsx @@ -0,0 +1,38 @@ +import { useStoreActions } from 'store'; +import { StyledPdfIcon, StyledFileName } from './DownloadFile.styles'; +import { saveAs } from 'file-saver'; + +export interface DownloadFileProps { + row: Record; + path: string; + fileType: string; +} + +export default function DownloadFile(props: DownloadFileProps): JSX.Element { + const { row, path, fileType } = props; + + const apiDownload = useStoreActions((actions) => { + return actions.api.download; + }); + + const download = () => { + apiDownload({ + path: `${path}/${row.id}/${fileType}`, + params: {}, + successCallback: async (data: any, headers: any) => { + const fileName = headers['content-disposition'] + ?.split('filename=') + ?.pop(); + + saveAs(data, fileName || 'download'); + }, + }); + }; + + return ( + <> + + {row[fileType].baseName} + + ); +} diff --git a/library/src/services/api/ParsedApiSpecInterface.ts b/library/src/services/api/ParsedApiSpecInterface.ts index e9f907a..87ce208 100644 --- a/library/src/services/api/ParsedApiSpecInterface.ts +++ b/library/src/services/api/ParsedApiSpecInterface.ts @@ -86,6 +86,7 @@ export interface ScalarProperty { required: boolean; pattern?: RegExp; helpText?: string | React.ReactElement; + downloadable?: boolean; } export interface EmbeddableProperty {