feat: add file block with drag-and-drop support - Implemented file upload block with preview support for images, videos, PDFs, text, code, and DOCX files - Added drag-and-drop directive for files with visual drop indicators in root and column contexts - Created file icon component with FontAwesome integration for 50+ file type icons ```
144 lines
5.6 KiB
TypeScript
144 lines
5.6 KiB
TypeScript
// file-icon.component.ts
|
|
import { Component, Input } from '@angular/core';
|
|
import { FontAwesomeModule, IconDefinition } from '@fortawesome/angular-fontawesome';
|
|
import {
|
|
faFilePdf, faFileWord, faFileExcel, faFilePowerpoint,
|
|
faFileImage, faFileVideo, faFileAudio, faFileArchive,
|
|
faFileCode, faFileLines, faFolder, faPaperclip,
|
|
faTerminal, faGem, faDatabase
|
|
} from '@fortawesome/free-solid-svg-icons';
|
|
import {
|
|
faJs, faHtml5, faCss3Alt, faPython, faJava,
|
|
faDocker, faReact, faVuejs, faSass, faMarkdown, faPhp,
|
|
faWindows
|
|
} from '@fortawesome/free-brands-svg-icons';
|
|
|
|
@Component({
|
|
selector: 'app-file-icon',
|
|
standalone: true,
|
|
imports: [FontAwesomeModule],
|
|
template: `<fa-icon [icon]="icon" [style.color]="color" size="lg"></fa-icon>`,
|
|
styles: [`:host { display: inline-flex; align-items: center; }`]
|
|
})
|
|
export class FileIconComponent {
|
|
@Input() set ext(value: string | undefined) {
|
|
this.updateIcon(value || '', '');
|
|
}
|
|
@Input() set kind(value: string | undefined) {
|
|
this.updateIcon('', value || '');
|
|
}
|
|
|
|
icon: IconDefinition = faPaperclip;
|
|
color: string = '#6c757d';
|
|
|
|
private updateIcon(ext: string, kind: string) {
|
|
const e = ext.toLowerCase();
|
|
const iconMap: Record<string, { icon: IconDefinition; color: string }> = {
|
|
// Extensions populaires
|
|
pdf: { icon: faFilePdf, color: '#dc3545' },
|
|
doc: { icon: faFileWord, color: '#0d6efd' },
|
|
docx: { icon: faFileWord, color: '#0d6efd' },
|
|
xls: { icon: faFileExcel, color: '#198754' },
|
|
xlsx: { icon: faFileExcel, color: '#198754' },
|
|
ppt: { icon: faFilePowerpoint, color: '#fd7e14' },
|
|
pptx: { icon: faFilePowerpoint, color: '#fd7e14' },
|
|
txt: { icon: faFileLines, color: '#6c757d' },
|
|
md: { icon: faMarkdown, color: '#000000' },
|
|
csv: { icon: faFileExcel, color: '#198754' },
|
|
|
|
// Images
|
|
jpg: { icon: faFileImage, color: '#20c997' },
|
|
jpeg: { icon: faFileImage, color: '#20c997' },
|
|
png: { icon: faFileImage, color: '#20c997' },
|
|
gif: { icon: faFileImage, color: '#20c997' },
|
|
svg: { icon: faFileImage, color: '#20c997' },
|
|
webp: { icon: faFileImage, color: '#20c997' },
|
|
|
|
// Vidéos
|
|
mp4: { icon: faFileVideo, color: '#6f42c1' },
|
|
avi: { icon: faFileVideo, color: '#6f42c1' },
|
|
mov: { icon: faFileVideo, color: '#6f42c1' },
|
|
|
|
// Code
|
|
js: { icon: faJs, color: '#f7df1e' },
|
|
mjs: { icon: faJs, color: '#f7df1e' },
|
|
ts: { icon: faJs, color: '#3178c6' },
|
|
html: { icon: faHtml5, color: '#e34c26' },
|
|
htm: { icon: faHtml5, color: '#e34c26' },
|
|
css: { icon: faCss3Alt, color: '#1572b6' },
|
|
scss: { icon: faSass, color: '#cc6699' },
|
|
sass: { icon: faSass, color: '#cc6699' },
|
|
less: { icon: faCss3Alt, color: '#1d365d' },
|
|
php: { icon: faPhp, color: '#777bb4' },
|
|
py: { icon: faPython, color: '#3776ab' },
|
|
java: { icon: faJava, color: '#ed8b00' },
|
|
class: { icon: faJava, color: '#ed8b00' },
|
|
jar: { icon: faJava, color: '#ed8b00' },
|
|
c: { icon: faFileCode, color: '#a8b9cc' },
|
|
cpp: { icon: faFileCode, color: '#00599c' },
|
|
cs: { icon: faFileCode, color: '#239120' },
|
|
h: { icon: faFileCode, color: '#a8b9cc' },
|
|
go: { icon: faFileCode, color: '#00add8' },
|
|
rs: { icon: faFileCode, color: '#dea584' },
|
|
rb: { icon: faGem, color: '#cc342d' },
|
|
swift: { icon: faFileCode, color: '#fa7343' },
|
|
kt: { icon: faFileCode, color: '#7f52ff' },
|
|
vue: { icon: faVuejs, color: '#4fc08d' },
|
|
jsx: { icon: faReact, color: '#61dafb' },
|
|
tsx: { icon: faReact, color: '#61dafb' },
|
|
sql: { icon: faDatabase, color: '#336791' },
|
|
json: { icon: faFileCode, color: '#000000' },
|
|
xml: { icon: faFileCode, color: '#000000' },
|
|
yml: { icon: faFileCode, color: '#ff0000' },
|
|
yaml: { icon: faFileCode, color: '#ff0000' },
|
|
|
|
// Scripts
|
|
sh: { icon: faTerminal, color: '#000000' },
|
|
bash: { icon: faTerminal, color: '#000000' },
|
|
zsh: { icon: faTerminal, color: '#000000' },
|
|
ps1: { icon: faTerminal, color: '#000000' },
|
|
bat: { icon: faWindows, color: '#0078d4' },
|
|
|
|
// Archives
|
|
zip: { icon: faFileArchive, color: '#ffc107' },
|
|
rar: { icon: faFileArchive, color: '#ffc107' },
|
|
'7z': { icon: faFileArchive, color: '#ffc107' },
|
|
tar: { icon: faFileArchive, color: '#ffc107' },
|
|
gz: { icon: faFileArchive, color: '#ffc107' },
|
|
|
|
// Config
|
|
ini: { icon: faFileLines, color: '#6c757d' },
|
|
cfg: { icon: faFileLines, color: '#6c757d' },
|
|
conf: { icon: faFileLines, color: '#6c757d' },
|
|
env: { icon: faFileLines, color: '#6c757d' },
|
|
lock: { icon: faFileLines, color: '#6c757d' },
|
|
|
|
// Docker
|
|
dockerfile: { icon: faDocker, color: '#2496ed' },
|
|
};
|
|
|
|
// Priorité à l'extension
|
|
if (iconMap[e]) {
|
|
this.icon = iconMap[e].icon;
|
|
this.color = iconMap[e].color;
|
|
return;
|
|
}
|
|
|
|
// Fallback sur le type
|
|
const kindMap: Record<string, { icon: IconDefinition; color: string }> = {
|
|
image: { icon: faFileImage, color: '#20c997' },
|
|
video: { icon: faFileVideo, color: '#6f42c1' },
|
|
audio: { icon: faFileAudio, color: '#6f42c1' },
|
|
pdf: { icon: faFilePdf, color: '#dc3545' },
|
|
text: { icon: faFileLines, color: '#6c757d' },
|
|
code: { icon: faFileCode, color: '#6c757d' },
|
|
doc: { icon: faFileWord, color: '#0d6efd' },
|
|
archive: { icon: faFileArchive, color: '#ffc107' },
|
|
folder: { icon: faFolder, color: '#ffc107' },
|
|
};
|
|
|
|
const kindIcon = kindMap[kind] || { icon: faPaperclip, color: '#6c757d' };
|
|
this.icon = kindIcon.icon;
|
|
this.color = kindIcon.color;
|
|
}
|
|
} |